feat: implement all Watch later page features

* feat: add new configuration options to `Button` component
This commit is contained in:
Hakadao
2023-06-05 02:34:48 +08:00
parent e9cf9b0723
commit f08340b6e8
9 changed files with 302 additions and 199 deletions

View File

@@ -13,6 +13,7 @@ common:
second: 秒前
please_log_in_first: 请先登录
login: 登录
save_to_watch_later: 稍后再看
settings:
title: 设置
select_language: 界面语文
@@ -132,10 +133,12 @@ dock:
history: 观看历史
dark_mode: 暗色模式
light_mode: 亮色模式
watch_later: 稍后再看
settings: 设置
home:
not_interested_in: 对哪方面不感兴趣?
video_removed: 视频已移除
save_to_watch_later: 添加到稍后再看
anime:
total_episodes: 全 {ep} 话
update_to_n_episodes: 更新至 {ep} 话
@@ -169,3 +172,14 @@ history:
turn_on_watch_history_confirm: |-
要开启观看历史吗?
你确定要开启观看历史吗?
watch_later:
title: 稍后再看
play_all: 播放全部
clear_all: 清空稍后再看
clear_all_confirm: |-
要清空稍后再看吗?
该操作无法撤销,你确定要清空稍后再看吗?
remove_watched_videos: 清除已观看的视频
remove_watched_videos_confirm: |-
要清除已观看的视频吗?
该操作无法撤销,你确定要清除已观看的视频吗?

View File

@@ -13,6 +13,7 @@ common:
second: 秒前
please_log_in_first: 請先登入
login: 登入
save_to_watch_later: 稍後觀看
settings:
title: 設定
select_language: 介面語文
@@ -130,6 +131,7 @@ dock:
home: 首頁
anime: 動畫
history: 觀看記錄
watch_later: 稍後觀看
dark_mode: 深色模式
light_mode: 淺色模式
settings: 設定
@@ -169,3 +171,14 @@ history:
turn_on_watch_history_confirm: |-
要啟用觀看記錄嗎?
你確定要啟用觀看記錄嗎?
watch_later:
title: 稍後觀看
play_all: 全部播放
clear_all: 清空稍後觀看
clear_all_confirm: |-
要清空稍後觀看的影片嗎?
此操作無法撤消,你確定要清空稍後觀看的影片嗎?
remove_watched_videos: 移除看過的影片
remove_watched_videos_confirm: |-
要移除看過的影片嗎?
此操作無法撤消,你確定要移除看過的影片嗎?

View File

@@ -13,6 +13,7 @@ common:
second: second ago | seconds ago
please_log_in_first: Please log in first
login: Login
save_to_watch_later: Save to Watch later
settings:
title: Settings
select_language: Language
@@ -131,6 +132,7 @@ dock:
home: Home
anime: Anime
history: History
watch_later: Watch later
dark_mode: Dark Mode
light_mode: Light Mode
settings: Settings
@@ -159,14 +161,24 @@ history:
title: Watch History
search_watch_history: Search watch history
clear_all_watch_history: Clear all watch history
clear_all_watch_history_confirm: >-
Clear all watch history?
This operation cannot be reversed. Are you sure you want to clear all watch
history?
clear_all_watch_history_confirm: |-
Clear all watch history?
This operation cannot be reversed. Are you sure you want to clear all watch history?
pause_watch_history: Pause watch history
pause_watch_history_confirm: |-
Pause watch history?
Pause watch history?
Are you sure you want to pause watch history?
turn_on_watch_history: Turn on watch history
turn_on_watch_history_confirm: Turn on watch history? Are you sure you want to turn on watch history?
watch_later:
title: Watch Later
play_all: Play all
clear_all: Clear all watch later
clear_all_confirm: |-
Clear all watch later?
This operation cannot be reversed. Are you sure you want to clear all watch later?
remove_watched_videos: Remove watched videos
remove_watched_videos_confirm: |-
Remove watched videos?
This operation cannot be reversed. Are you sure you want to remove watched videos?

View File

@@ -13,6 +13,7 @@ common:
second: 秒前
please_log_in_first: 唔該登入先
login: 登入
save_to_watch_later: 陣間至睇
settings:
title: 校做
select_language: 介面語文
@@ -130,6 +131,7 @@ dock:
home: 主頁
anime: 動畫
history: 收睇記錄
watch_later: 陣間至睇
dark_mode: 深色模式
light_mode: 淺色模式
settings: 校做
@@ -160,12 +162,23 @@ history:
pause_watch_history: 暫停進行收睇記錄
clear_all_watch_history: 剷晒啲收睇記錄
clear_all_watch_history_confirm: |-
諗住剷晒啲收睇記錄?
係咪要剷晒啲收睇記錄
噉做冇得返轉頭噃,你確定要剷晒啲收睇記錄?
pause_watch_history_confirm: |-
諗住暫停進行收睇記錄?
係咪要暫停進行收睇記錄
你確定要暫停暫停進行收睇記錄?
search_watch_history: 搵吓收睇記錄
turn_on_watch_history_confirm: |-
諗住開返收睇記錄?
係咪要開返收睇記錄
你確定要開返收睇記錄?
watch_later:
title: 陣間至睇
play_all: 播晒佢哋
clear_all: 剷曬陣間至睇啲片
clear_all_confirm: |-
係咪要剷曬陣間至睇啲片呀?
噉做冇得返轉頭噃,你確定要剷曬陣間至睇啲片?
remove_watched_videos: 剷走睇過啲片
remove_watched_videos_confirm: |-
係咪要剷走你睇過啲片呀?
噉做冇得返轉頭噃,你確定要剷走你睇過啲片?

View File

@@ -19,12 +19,13 @@ export const setupWatchLaterMsgLstnr = () => {
}
// https://github.com/SocialSisterYi/bilibili-API-collect/blob/master/docs/history&toview/toview.md#%E5%88%A0%E9%99%A4%E7%A8%8D%E5%90%8E%E5%86%8D%E7%9C%8B%E8%A7%86%E9%A2%91
else if (message.contentScriptQuery === 'removeFromWatchLater') {
const url = 'https://api.bilibili.com/x/v2/history/toview/del'
const url = `https://api.bilibili.com/x/v2/history/toview/del?${message.aid ? `aid=${message.aid}` : ''}`
return fetch(url, {
method: 'POST',
body: new URLSearchParams({
csrf: message.csrf,
aid: message.aid,
// aid: message.aid,
viewed: message.viewed,
}),
})
.then(response => response.json())
@@ -39,6 +40,19 @@ export const setupWatchLaterMsgLstnr = () => {
.then(data => data)
.catch(error => console.error(error))
}
// https://github.com/SocialSisterYi/bilibili-API-collect/blob/master/docs/history&toview/toview.md#%E6%B8%85%E7%A9%BA%E7%A8%8D%E5%90%8E%E5%86%8D%E7%9C%8B%E8%A7%86%E9%A2%91%E5%88%97%E8%A1%A8
else if (message.contentScriptQuery === 'clearAllWatchLater') {
const url = 'https://api.bilibili.com/x/v2/history/toview/clear'
return fetch(url, {
method: 'POST',
body: new URLSearchParams({
csrf: message.csrf,
}),
})
.then(response => response.json())
.then(data => data)
.catch(error => console.error(error))
}
})
})
}

View File

@@ -10,6 +10,10 @@ interface Props {
size?: 'small' | 'medium' | 'large'
/** @description enable frosted glass effect */
frosted?: boolean
secondary?: boolean
color?: string
textColor?: string
strong?: boolean
}
// const props = withDefaults(defineProps<Props>(), {})
@@ -26,10 +30,14 @@ const handleClick = (evt: MouseEvent) => {
<button
class="b-button"
:class="`
b-button--type-${props.type ?? 'default'}
b-button--size-${props.size ?? 'medium'}
${props.frosted ? 'frosted-glass' : ''}
b-button--type-${type ?? 'default'}
b-button--size-${size ?? 'medium'}
${frosted ? 'frosted-glass' : ''}
${secondary ? 'b-button--secondary' : ''}
${strong ? 'b-button--strong' : ''}
${color || textColor ? 'b-button--custom-color' : ''}
`"
:style="{ backgroundColor: color, color: textColor }"
@click="handleClick"
>
<slot name="left" />
@@ -89,5 +97,20 @@ const handleClick = (evt: MouseEvent) => {
--b-font-size: 15px;
--b-icon-size: 16px;
}
&--custom-color {
--at-apply: hover:opacity-80;
}
&--secondary {
--b-color: var(--bew-fill-2);
--b-color-hover: var(--bew-fill-4);
--b-text-color: var(--bew-text-1);
}
&--strong {
--at-apply: fw-800;
}
}
</style>

View File

@@ -179,7 +179,7 @@ function toggleWatchLater() {
opacity="0 group-hover:100"
@click.stop="toggleWatchLater"
>
<Tooltip v-if="!isInWatchLater" content="Save to Watch later" placement="bottom">
<Tooltip v-if="!isInWatchLater" :content="$t('common.save_to_watch_later')" placement="bottom">
<tabler:playlist-add />
</Tooltip>
<Tooltip v-else content="Added" placement="bottom">

View File

@@ -206,7 +206,7 @@ function setAppAppearance() {
</button>
</Tooltip>
<Tooltip content="Watch later" :placement="tooltipPlacement">
<Tooltip :content="$t('dock.watch_later')" :placement="tooltipPlacement">
<button
class="dock-item"
:class="{ active: activatedPage === AppPage.WatchLater && !isVideoPage }"

View File

@@ -10,9 +10,6 @@ const { t } = useI18n()
const isLoading = ref<boolean>()
const noMoreContent = ref<boolean>()
const watchLaterList = reactive<Array<WatchLaterModel>>([])
const currentPageNum = ref<number>(1)
const keyword = ref<string>()
const historyStatus = ref<boolean>()
onMounted(() => {
getAllWatchLaterList()
@@ -24,10 +21,11 @@ onUnmounted(() => {
})
/**
* Get history list
* Get watch later list
*/
function getAllWatchLaterList() {
isLoading.value = true
watchLaterList.length = 0
browser.runtime
.sendMessage({
contentScriptQuery: 'getAllWatchLaterList',
@@ -53,56 +51,46 @@ function deleteWatchLaterItem(index: number, aid: number) {
})
}
function setHistoryPauseStatus(isPause: boolean) {
browser.runtime
.sendMessage({
contentScriptQuery: 'setHistoryPauseStatus',
function handleClearAllWatchLater() {
// eslint-disable-next-line no-alert
const result = confirm(
t('watch_later.clear_all_confirm'),
)
if (result) {
isLoading.value = true
browser.runtime.sendMessage({
contentScriptQuery: 'clearAllWatchLater',
csrf: getCSRF(),
switch: isPause,
})
.then((res) => {
}).then((res) => {
if (res.code === 0)
getHistoryPauseStatus()
getAllWatchLaterList()
}).finally(() => {
isLoading.value = false
})
}
}
function clearAllHistory() {
browser.runtime
.sendMessage({
contentScriptQuery: 'clearAllHistory',
csrf: getCSRF(),
})
.then((res) => {
if (res.code === 0)
watchLaterList.length = 0
})
}
function handleClearAllWatchHistory() {
function handleRemoveWatchedVideos() {
// eslint-disable-next-line no-alert
const result = confirm(
t('history.clear_all_watch_history_confirm'),
t('watch_later.remove_watched_videos_confirm'),
)
if (result)
clearAllHistory()
if (result) {
browser.runtime
.sendMessage({
contentScriptQuery: 'removeFromWatchLater',
viewed: true,
csrf: getCSRF(),
})
.then((res) => {
if (res.code === 0)
getAllWatchLaterList()
})
}
}
function handlePauseWatchHistory() {
// eslint-disable-next-line no-alert
const result = confirm(
t('history.pause_watch_history_confirm'),
)
if (result)
setHistoryPauseStatus(true)
}
function handleTurnOnWatchHistory() {
// eslint-disable-next-line no-alert
const result = confirm(
t('history.turn_on_watch_history_confirm'),
)
if (result)
setHistoryPauseStatus(false)
function handlePlayAll() {
openLinkToNewTab('https://www.bilibili.com/list/watchlater')
}
function jumpToLoginPage() {
@@ -114,128 +102,161 @@ function jumpToLoginPage() {
<div v-if="getCSRF()" flex="~ col md:row lg:row" gap-4>
<main w="full md:60% lg:70% xl:75%" order="2 md:1 lg:1" mb-6>
<h3 text="3xl $bew-text-1" font-bold mb-6>
Watch later ({{ watchLaterList.length }}/100)
{{ t('watch_later.title') }} ({{ watchLaterList.length }}/100)
</h3>
<!-- historyList -->
<transition-group name="list">
<a
v-for="(item, index) in watchLaterList"
:key="item.aid"
block
class="group"
flex
cursor-pointer
@click="openLinkToNewTab(removeHttpFromUrl(`https://www.bilibili.com/list/watchlater?bvid=${item.bvid}`))"
>
<section
rounded="$bew-radius"
flex="~ gap-6 col md:col lg:row"
item-start
relative
group-hover:bg="$bew-fill-2"
duration-300
w-full
p-2
m-1
<Empty v-if="watchLaterList.length === 0 && !isLoading" />
<template v-else>
<!-- watcher later list -->
<transition-group name="list">
<a
v-for="(item, index) in watchLaterList"
:key="item.aid"
block
class="group"
flex
cursor-pointer
@click="openLinkToNewTab(`https://www.bilibili.com/list/watchlater?bvid=${item.bvid}`)"
>
<!-- Cover -->
<div
pos="relative"
bg="$bew-fill-5"
w="full md:full lg:250px"
flex="shrink-0"
<section
rounded="$bew-radius"
overflow-hidden
aspect-video
flex="~ gap-6 col md:col lg:row"
item-start
relative
group-hover:bg="$bew-fill-2"
duration-300
w-full
p-2
m-1
>
<img
w="full"
aspect-video
:src="removeHttpFromUrl(`${item.pic}@480w_270h_1c`)"
:alt="item.title"
object-cover
>
<!-- Cover -->
<div
pos="absolute bottom-0 right-0"
bg="black opacity-60"
m="2"
p="x-2 y-1"
text="white xs"
rounded-8
pos="relative"
bg="$bew-fill-5"
w="full md:full lg:250px"
flex="shrink-0"
rounded="$bew-radius"
overflow-hidden
aspect-video
>
{{ calcCurrentTime(item.duration) }}
</div>
</div>
<img
w="full"
aspect-video
:src="removeHttpFromUrl(`${item.pic}@480w_270h_1c`)"
:alt="item.title"
object-cover
>
<!-- Description -->
<div flex justify-between w-full>
<div flex="~ col">
<a
class="keep-two-lines"
overflow="hidden"
un-text="lg overflow-ellipsis"
:href="removeHttpFromUrl(`https://www.bilibili.com/list/watchlater?bvid=${item.bvid}`)" target="_blank"
@click.stop=""
<!-- <div
pos="absolute bottom-0 right-0"
bg="black opacity-60"
m="2"
p="x-2 y-1"
text="white xs"
rounded-8
>
{{ item.title }}
</a>
<a
un-text="$bew-text-2 sm"
m="t-4 b-2"
flex="~"
items-center
cursor-pointer
w-fit
rounded="$bew-radius-half"
hover:color="$bew-theme-color"
hover:bg="$bew-theme-color-10"
duration-300
pr-2
:href="`//space.bilibili.com/${item.owner.mid}`" target="_blank"
@click.stop=""
{{ calcCurrentTime(item.duration) }}
</div> -->
<div
pos="absolute bottom-0 right-0"
bg="black opacity-60"
m="2"
p="x-2 y-1"
text="white xs"
rounded-8
>
<img
:src="removeHttpFromUrl(`${item.owner.face}@80w_80h_1c`)"
w-30px
aspect-square
object-cover
alt=""
rounded="$bew-radius-half"
mr-2
>
{{ item.owner.name }}
</a>
<p display="block xl:none" text="$bew-text-3 sm" mt-auto mb-2>
<!-- When progress = -1 means that the user watched the full video -->
{{
useDateFormat(item.pubdate * 1000, 'YYYY-MM-DD HH:mm:ss')
.value
`${
item.progress === -1
? calcCurrentTime(item.duration)
: calcCurrentTime(item.progress)
} /
${calcCurrentTime(item.duration)}`
}}
</p>
</div>
<div w-full pos="absolute bottom-0" bg="white opacity-60">
<Progress
:percentage="
(item.progress / item.duration) * 100
"
/>
</div>
</div>
<button
text="2xl $bew-text-3"
hover:color="$bew-theme-color"
opacity="0 group-hover:100"
p-2
duration-300
@click.stop="deleteWatchLaterItem(index, item.aid)"
>
<tabler:trash />
</button>
</div>
</section>
</a>
</transition-group>
<!-- loading -->
<Transition name="fade">
<loading
v-if="isLoading && watchLaterList.length !== 0 && !noMoreContent"
m="-t-4"
/>
</Transition>
<!-- Description -->
<div flex justify-between w-full>
<div flex="~ col">
<a
class="keep-two-lines"
overflow="hidden"
un-text="lg overflow-ellipsis"
:href="removeHttpFromUrl(`https://www.bilibili.com/list/watchlater?bvid=${item.bvid}`)" target="_blank"
@click.stop=""
>
{{ item.title }}
</a>
<a
un-text="$bew-text-2 sm"
m="t-4 b-2"
flex="~"
items-center
cursor-pointer
w-fit
rounded="$bew-radius-half"
hover:color="$bew-theme-color"
hover:bg="$bew-theme-color-10"
duration-300
pr-2
:href="`//space.bilibili.com/${item.owner.mid}`" target="_blank"
@click.stop=""
>
<img
:src="removeHttpFromUrl(`${item.owner.face}@80w_80h_1c`)"
w-30px
aspect-square
object-cover
alt=""
rounded="$bew-radius-half"
mr-2
>
{{ item.owner.name }}
</a>
<p display="block xl:none" text="$bew-text-3 sm" mt-auto mb-2>
{{
useDateFormat(item.pubdate * 1000, 'YYYY-MM-DD HH:mm:ss')
.value
}}
</p>
</div>
<div flex items-center>
<!-- <span>{{ item.progress === -1 ? $t('watch_later.watched') : '' }}</span> -->
<button
text="2xl $bew-text-3"
hover:color="$bew-theme-color"
opacity="0 group-hover:100"
p-2
duration-300
@click.stop="deleteWatchLaterItem(index, item.aid)"
>
<tabler:trash />
</button>
</div>
</div>
</section>
</a>
</transition-group>
<!-- loading -->
<Transition name="fade">
<loading
v-if="isLoading && watchLaterList.length !== 0 && !noMoreContent"
m="-t-4"
/>
</Transition>
</template>
</main>
<aside relative w="full md:40% lg:30% xl:25%" order="1 md:2 lg:2">
@@ -254,55 +275,48 @@ function jumpToLoginPage() {
</picture>
<h3 text="3xl white" fw-600 style="text-shadow: 0 0 12px rgba(0,0,0,.3)">
Watch later ({{ watchLaterList.length }}/100)
{{ t('watch_later.title') }} ({{ watchLaterList.length }}/100)
</h3>
<p flex="~ col" gap-4>
<Button flex-1>
<p v-if="watchLaterList.length > 0" flex="~ col" gap-4>
<Button
color="rgba(255,255,255,.35)" text-color="white" strong flex-1
@click="handlePlayAll"
>
<template #left>
<tabler:player-play />
</template>
Play all
{{ t('watch_later.play_all') }}
</Button>
<Button flex-1>
<Button
color="rgba(255,255,255,.35)" text-color="white" strong flex-1
@click="handleClearAllWatchLater"
>
<template #left>
<tabler:trash />
</template>
Clear all watch later
{{ t('watch_later.clear_all') }}
</Button>
<Button
color="rgba(255,255,255,.35)" text-color="white" strong flex-1
@click="handleRemoveWatchedVideos"
>
<template #left>
<tabler:circle-minus />
</template>
{{ t('watch_later.remove_watched_videos') }}
</Button>
</p>
<div
v-if="watchLaterList[0]"
pos="absolute top-0 left-0" w-full h-full bg-cover bg-center z--1 opacity="80 dark:70"
pos="absolute top-0 left-0" w-full h-full bg-cover bg-center z--1
>
<div absolute w-full h-full style="backdrop-filter: blur(60px) saturate(180%)" />
<div absolute w-full h-full style="backdrop-filter: blur(60px) saturate(180%)" bg="$bew-fill-1" />
<img
v-if="watchLaterList[0]"
:src="removeHttpFromUrl(`${watchLaterList[0].pic}@480w_270h_1c`)"
w-full h-full object="cover center"
>
</div>
<!-- <Button shadow="$bew-shadow-1" @click="handleClearAllWatchHistory">
<template #left>
<tabler:trash />
</template>
{{ $t('history.clear_all_watch_history') }}
</Button>
<Button
v-if="!historyStatus"
shadow="$bew-shadow-1"
@click="handlePauseWatchHistory"
>
<template #left>
<ph:pause-circle-bold />
</template>
{{ $t('history.pause_watch_history') }}
</Button>
<Button v-else shadow="$bew-shadow-1" @click="handleTurnOnWatchHistory">
<template #left>
<ph:play-circle-bold />
</template>
{{ $t('history.turn_on_watch_history') }}
</Button> -->
</div>
</aside>
</div>