mirror of
https://github.com/the1812/Bilibili-Evolved.git
synced 2025-11-04 21:22:45 +08:00
parent
c658cd67e5
commit
9dc2ad58f4
@ -155,6 +155,8 @@ export default Vue.extend({
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
@import 'common';
|
||||
|
||||
.custom-navbar-item {
|
||||
color: inherit;
|
||||
position: relative;
|
||||
@ -216,7 +218,7 @@ export default Vue.extend({
|
||||
}
|
||||
|
||||
&.active .main-content {
|
||||
font-weight: bold;
|
||||
@include semi-bold();
|
||||
font-size: 11pt;
|
||||
}
|
||||
|
||||
|
||||
@ -409,7 +409,7 @@ export default Vue.extend({
|
||||
.title {
|
||||
grid-area: title;
|
||||
font-size: 13px;
|
||||
font-weight: bold;
|
||||
@include semi-bold();
|
||||
@include max-line(2);
|
||||
-webkit-box-align: start;
|
||||
margin: 0;
|
||||
|
||||
@ -25,15 +25,15 @@
|
||||
<div class="row-title">过滤:</div>
|
||||
<div class="type-filters">
|
||||
<div v-for="t of types" :key="t.name" class="type-filter">
|
||||
<VButton
|
||||
round
|
||||
<RadioButton
|
||||
:title="(t.checked ? '不显示' : '显示') + t.displayName"
|
||||
:class="{ checked: t.checked }"
|
||||
@click="toggleTypeFilter(t)"
|
||||
:checked="t.checked"
|
||||
:disabled="loading"
|
||||
@change="toggleTypeFilter(t)"
|
||||
>
|
||||
<VIcon :icon="t.icon" :size="18"></VIcon>
|
||||
{{ t.displayName }}
|
||||
</VButton>
|
||||
</RadioButton>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@ -108,14 +108,24 @@
|
||||
import { bilibiliApi, getJsonWithCredentials, postTextWithCredentials } from '@/core/ajax'
|
||||
import { formData, getCsrf } from '@/core/utils'
|
||||
import { descendingSort } from '@/core/utils/sort'
|
||||
import { VButton, VIcon, TextBox, VLoading, VEmpty, ScrollTrigger, DpiImage } from '@/ui'
|
||||
import {
|
||||
VButton,
|
||||
VIcon,
|
||||
RadioButton,
|
||||
TextBox,
|
||||
VLoading,
|
||||
VEmpty,
|
||||
ScrollTrigger,
|
||||
DpiImage,
|
||||
} from '@/ui'
|
||||
import { popperMixin } from '../mixins'
|
||||
import { types, TypeFilter, HistoryItem, getHistoryItems, group } from './types'
|
||||
import { types, TypeFilter, HistoryItem, getHistoryItems, group, HistoryType } from './types'
|
||||
|
||||
export default Vue.extend({
|
||||
components: {
|
||||
VButton,
|
||||
VIcon,
|
||||
RadioButton,
|
||||
TextBox,
|
||||
VLoading,
|
||||
VEmpty,
|
||||
@ -137,17 +147,12 @@ export default Vue.extend({
|
||||
},
|
||||
computed: {
|
||||
canNextPage() {
|
||||
return (
|
||||
this.search === '' &&
|
||||
!this.loading &&
|
||||
this.hasMorePage &&
|
||||
this.types.every((t: TypeFilter) => t.checked)
|
||||
)
|
||||
return this.search === '' && !this.loading && this.hasMorePage
|
||||
},
|
||||
},
|
||||
watch: {
|
||||
search: lodash.debounce(function search() {
|
||||
this.updateGroups()
|
||||
this.reloadHistoryItems()
|
||||
}, 200),
|
||||
},
|
||||
async created() {
|
||||
@ -159,11 +164,22 @@ export default Vue.extend({
|
||||
},
|
||||
methods: {
|
||||
toggleTypeFilter(typeFilter: TypeFilter) {
|
||||
typeFilter.checked = !typeFilter.checked
|
||||
this.updateGroups()
|
||||
types.forEach(t => (t.checked = t.name === typeFilter.name))
|
||||
this.reloadHistoryItems()
|
||||
},
|
||||
async reloadHistoryItems() {
|
||||
this.viewTime = 0
|
||||
this.hasMorePage = true
|
||||
this.loading = true
|
||||
try {
|
||||
await this.nextPage()
|
||||
} finally {
|
||||
this.loading = false
|
||||
}
|
||||
},
|
||||
filterFunc(item: HistoryItem) {
|
||||
if (types.some(t => t.name === item.type && !t.checked)) {
|
||||
const isAllType = types.find(it => it.name === HistoryType.All).checked
|
||||
if (!isAllType && types.some(t => t.name === item.type && !t.checked)) {
|
||||
return false
|
||||
}
|
||||
if (
|
||||
@ -178,7 +194,10 @@ export default Vue.extend({
|
||||
this.groups = group(this.cards.filter(this.filterFunc))
|
||||
},
|
||||
async nextPage() {
|
||||
const items = await getHistoryItems(this.viewTime)
|
||||
const items = await getHistoryItems(
|
||||
this.viewTime,
|
||||
types.find(t => t.checked),
|
||||
)
|
||||
const cards: HistoryItem[] = lodash.uniqBy(
|
||||
this.cards.concat(items).sort(descendingSort((item: HistoryItem) => item.viewAt)),
|
||||
item => item.id,
|
||||
@ -188,7 +207,10 @@ export default Vue.extend({
|
||||
if (cards.length > 0) {
|
||||
this.viewTime = lodash.last(cards).viewAt
|
||||
}
|
||||
this.hasMorePage = cards.length !== 0
|
||||
this.hasMorePage = items.length !== 0
|
||||
if (this.hasMorePage && this.groups.length === 0) {
|
||||
await this.nextPage()
|
||||
}
|
||||
},
|
||||
async updateHistoryPauseState() {
|
||||
const result = await bilibiliApi(
|
||||
@ -223,7 +245,7 @@ export default Vue.extend({
|
||||
@import '../popup';
|
||||
|
||||
.custom-navbar-history-list {
|
||||
width: 350px;
|
||||
width: 400px;
|
||||
@include navbar-popup-height();
|
||||
font-size: 12px;
|
||||
padding: 0;
|
||||
@ -251,23 +273,22 @@ export default Vue.extend({
|
||||
margin: 16px 12px 4px 12px;
|
||||
.header-row {
|
||||
@include h-stretch(8px);
|
||||
justify-content: space-between;
|
||||
.row-title {
|
||||
@include h-center();
|
||||
}
|
||||
}
|
||||
.type-filters {
|
||||
@include h-center(8px);
|
||||
@include h-center(6px);
|
||||
.type-filter {
|
||||
.be-button {
|
||||
padding: 4px 8px 4px 6px;
|
||||
color: #8888;
|
||||
.be-icon {
|
||||
margin-right: 6px;
|
||||
}
|
||||
&.checked {
|
||||
color: inherit;
|
||||
}
|
||||
// color: #8888;
|
||||
// .be-icon {
|
||||
// margin-right: 6px;
|
||||
// }
|
||||
// &.checked {
|
||||
// color: inherit;
|
||||
// }
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -402,8 +423,8 @@ export default Vue.extend({
|
||||
}
|
||||
}
|
||||
.title {
|
||||
@include semi-bold();
|
||||
grid-area: title;
|
||||
font-weight: bold;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
|
||||
@ -11,7 +11,7 @@ export const history: CustomNavbarItemInit = {
|
||||
active: document.URL.replace(/\?.*$/, '') === href,
|
||||
loginRequired: true,
|
||||
|
||||
boundingWidth: 350,
|
||||
boundingWidth: 400,
|
||||
noPopupPadding: true,
|
||||
popupContent: () => import('./NavbarHistory.vue').then(m => m.default),
|
||||
}
|
||||
|
||||
@ -4,6 +4,7 @@ import { formatDuration } from '@/core/utils/formatters'
|
||||
|
||||
/** 历史项目类型, 值为 API 中的 `history.business` */
|
||||
export enum HistoryType {
|
||||
All = 'all',
|
||||
Video = 'archive',
|
||||
Live = 'live',
|
||||
Article = 'article',
|
||||
@ -48,32 +49,44 @@ export interface TypeFilter {
|
||||
displayName: string
|
||||
icon: string
|
||||
checked: boolean
|
||||
apiType: string
|
||||
}
|
||||
/** 所有的历史记录类型 */
|
||||
export const types = [
|
||||
{
|
||||
name: HistoryType.All,
|
||||
displayName: '全部',
|
||||
icon: '',
|
||||
checked: true,
|
||||
apiType: '',
|
||||
},
|
||||
{
|
||||
name: HistoryType.Video,
|
||||
displayName: '视频',
|
||||
icon: 'mdi-play-circle-outline',
|
||||
checked: true,
|
||||
checked: false,
|
||||
apiType: 'archive',
|
||||
},
|
||||
{
|
||||
name: HistoryType.Bangumi,
|
||||
displayName: '番剧',
|
||||
icon: 'mdi-television-classic',
|
||||
checked: true,
|
||||
checked: false,
|
||||
apiType: 'archive',
|
||||
},
|
||||
{
|
||||
name: HistoryType.Live,
|
||||
displayName: '直播',
|
||||
icon: 'mdi-video-wireless-outline',
|
||||
checked: true,
|
||||
checked: false,
|
||||
apiType: 'live',
|
||||
},
|
||||
{
|
||||
name: HistoryType.Article,
|
||||
displayName: '专栏',
|
||||
icon: 'mdi-newspaper-variant-outline',
|
||||
checked: true,
|
||||
checked: false,
|
||||
apiType: 'article',
|
||||
},
|
||||
] as TypeFilter[]
|
||||
|
||||
@ -188,12 +201,17 @@ const parseHistoryItem = (item: any): HistoryItem => {
|
||||
* 获取指定观看时间之前的一页历史记录, 不指定则返回最新的历史记录
|
||||
* @param viewTime 观看时间
|
||||
*/
|
||||
export const getHistoryItems = async (viewTime?: number) => {
|
||||
let api = 'https://api.bilibili.com/x/web-interface/history/cursor'
|
||||
export const getHistoryItems = async (viewTime?: number, type?: TypeFilter) => {
|
||||
const api = 'https://api.bilibili.com/x/web-interface/history/cursor'
|
||||
const params = new URLSearchParams()
|
||||
if (viewTime) {
|
||||
api += `?view_at=${Math.round(viewTime / 1000)}`
|
||||
params.set('view_at', Math.round(viewTime / 1000).toString())
|
||||
}
|
||||
const { list } = await bilibiliApi(getJsonWithCredentials(api), '获取历史记录失败')
|
||||
params.set('type', type?.apiType ?? '')
|
||||
const { list } = await bilibiliApi(
|
||||
getJsonWithCredentials(`${api}?${params.toString()}`),
|
||||
'获取历史记录失败',
|
||||
)
|
||||
if (!Array.isArray(list)) {
|
||||
return []
|
||||
}
|
||||
|
||||
@ -186,7 +186,7 @@ export default Vue.extend({
|
||||
.title {
|
||||
margin-left: 6px;
|
||||
font-size: 18px;
|
||||
font-weight: bold;
|
||||
@include semi-bold();
|
||||
}
|
||||
.grow {
|
||||
flex: 1;
|
||||
|
||||
@ -233,7 +233,7 @@ export default Vue.extend({
|
||||
}
|
||||
.title {
|
||||
font-size: 14px;
|
||||
font-weight: bold;
|
||||
@include semi-bold();
|
||||
padding-top: 4px;
|
||||
color: inherit;
|
||||
white-space: nowrap;
|
||||
|
||||
@ -325,6 +325,8 @@ export default Vue.extend({
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
@import 'common';
|
||||
|
||||
.user-info-panel {
|
||||
border-radius: 8px;
|
||||
overflow: hidden;
|
||||
@ -441,7 +443,7 @@ export default Vue.extend({
|
||||
.welcome,
|
||||
.name {
|
||||
font-size: 16px;
|
||||
font-weight: bold;
|
||||
@include semi-bold();
|
||||
margin: 46px 0 16px 0;
|
||||
text-align: center;
|
||||
color: inherit;
|
||||
@ -495,7 +497,7 @@ export default Vue.extend({
|
||||
color: var(--theme-color) !important;
|
||||
}
|
||||
.stats-number {
|
||||
font-weight: bold;
|
||||
@include semi-bold();
|
||||
margin-bottom: 4px;
|
||||
font-size: 14px;
|
||||
transition: none;
|
||||
|
||||
@ -326,7 +326,7 @@ export default Vue.extend({
|
||||
.title {
|
||||
grid-area: title;
|
||||
font-size: 13px;
|
||||
font-weight: bold;
|
||||
@include semi-bold();
|
||||
margin: 0;
|
||||
margin-top: 8px;
|
||||
padding: 0 10px;
|
||||
|
||||
@ -91,7 +91,7 @@ export default Vue.extend({
|
||||
&.left-icon {
|
||||
.icon-container {
|
||||
order: -1;
|
||||
margin: 2px 8px 2px 0;
|
||||
margin: 2px 6px 2px 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user