feat: history page

This commit is contained in:
Hakadao
2023-02-07 01:57:41 +08:00
parent 599e90dd0a
commit 67d35f2b75
4 changed files with 213 additions and 1 deletions

View File

@@ -6,6 +6,7 @@ import browser from 'webextension-polyfill'
import Home from './Home/Home.vue'
import Search from './Search/Search.vue'
import Anime from './Anime/Anime.vue'
import History from './History/History.vue'
import { activatedPage, isShowTopbar } from '~/logic/storage'
import { language } from '~/logic'
import '~/styles/index.ts'
@@ -15,7 +16,7 @@ const { locale } = useI18n()
const [showSettings, toggle] = useToggle(false)
const isDark = useDark()
const toggleDark = useToggle(isDark)
const pages = { Home, Search, Anime }
const pages = { Home, Search, Anime, History }
watch(() => activatedPage.value, (newValue, oldValue) => {
window.scrollTo({ top: 0, behavior: 'smooth' })
@@ -91,6 +92,14 @@ function changeActivatePage(pageName: AppPage) {
<tabler:device-tv />
</button>
<button
class="tab-item"
:class="{ active: activatedPage === AppPage.History }"
@click="changeActivatePage(AppPage.History)"
>
<tabler:clock />
</button>
<!-- dividing line -->
<div my-4 w-full h-2px bg="$bew-fill-2" />

View File

@@ -0,0 +1,173 @@
<script setup lang="ts">
import { useDateFormat } from '@vueuse/core'
import type { HistoryItem } from './types'
import { calcCurrentTime, removeHttpFromUrl } from '~/utils'
const isLoading = ref<boolean>()
const noMoreContent = ref<boolean>()
const historyList = reactive<Array<HistoryItem>>([])
onMounted(() => {
getHistoryList()
window.onscroll = () => {
if (
window.innerHeight + window.scrollY
>= document.body.scrollHeight - 20
) {
if (isLoading.value)
return
getHistoryList()
}
}
})
onUnmounted(() => {
// remove the global window.onscroll event
window.onscroll = () => {}
})
/**
* Get history list
*/
function getHistoryList() {
isLoading.value = true
browser.runtime
.sendMessage({
contentScriptQuery: 'getHistoryList',
type: 'all',
viewAt: historyList.length > 0 ? historyList[historyList.length - 1].view_at : 0,
})
.then((res) => {
if (res.code === 0) {
if (historyList.length !== 0 && res.data.list.length < 20) {
isLoading.value = false
noMoreContent.value = true
return
}
res.data.list.forEach((item: HistoryItem) => {
historyList.push(item)
})
noMoreContent.value = false
}
isLoading.value = false
})
}
/**
* Return the URL of the history item
* @param item history item
* @return {string} url
*/
function getHistoryUrl(item: HistoryItem) {
// Video
// if (activatedTab.value === 0)
// return item.history.bvid
// // Live
// else if (activatedTab.value === 1)
// return `//live.bilibili.com/${item.history.oid}`
// // Article
// else if (activatedTab.value === 2)
// return `/read/cv${item.history.oid}`
return ''
}
</script>
<template>
<div>
<!-- historyList -->
<transition-group name="list">
<a
v-for="historyItem in historyList"
:key="historyItem.kid"
:href="getHistoryUrl(historyItem)"
target="_blank"
hover:bg="$bew-fill-2"
rounded="$bew-radius"
p="2"
m="first:t-50px last:b-4"
class="group"
transition="duration"
duration-300
>
<section flex="~ gap-4" item-start>
<!-- Video cover, live cover, ariticle cover -->
<div
bg="$bew-fill-1"
w="300px"
flex="shrink-0"
border="rounded-$bew-radius-half"
overflow="hidden"
>
<!-- Video -->
<div pos="relative">
<img
w="300px"
class="aspect-video"
:src="`${removeHttpFromUrl(historyItem.cover)}@672w_378h_1c`"
:alt="historyItem.title"
bg="contain"
>
<div
pos="absolute bottom-0 right-0"
bg="black opacity-60"
m="1"
p="x-2 y-1"
text="white xs"
border="rounded-full"
>
<!-- When progress = -1 means that the user watched the full video -->
{{
`${historyItem.progress === -1 ? calcCurrentTime(historyItem.duration) : calcCurrentTime(historyItem.progress)} /
${calcCurrentTime(historyItem.duration)}`
}}
</div>
</div>
<Progress
:percentage="
(historyItem.progress / historyItem.duration) * 100
"
/>
</div>
<!-- Description -->
<div>
<h3
class="keep-two-lines"
overflow="hidden"
text="overflow-ellipsis"
>
{{ historyItem.title }}
</h3>
<div text="$bew-text-2 sm" m="t-4" flex="~" align="items-center">
{{ historyItem.author_name }}
<span
v-if="historyItem.live_status === 1"
text="$bew-theme-color"
m="l-2"
><tabler:live-photo />
Live
</span>
</div>
<p text="$bew-text-2 sm">
{{
useDateFormat(
historyItem.view_at * 1000,
'YYYY-MM-DD HH:mm:ss',
).value
}}
</p>
</div>
</section>
</a>
</transition-group>
<!-- loading -->
<loading v-if="isLoading && historyList.length !== 0" m="-t-4" />
</div>
</template>

View File

@@ -0,0 +1,29 @@
// https://github.com/SocialSisterYi/bilibili-API-collect/blob/master/history&toview/history.md#%E8%8E%B7%E5%8F%96%E5%8E%86%E5%8F%B2%E8%AE%B0%E5%BD%95%E5%88%97%E8%A1%A8_web%E7%AB%AF
export enum HistoryType {
Archive = 'archive', // archive稿件
PGC = 'pgc', // pgc剧集 (番剧 / 影视)
Live = 'live', // live直播
ArticleList = 'article-list', // article-list文集
Article = 'article', // article文章
}
export interface HistoryItem {
title: string
cover: string
covers?: Array<string>
history: {
business: HistoryType
epid?: number
bvid?: string
part?: string
oid: number
}
author_name: string
author_face: string
author_mid: string
view_at: number
progress: number
duration: number
kid: number
live_status: 0 | 1 // 0未开播 1已开播
}