Merge branch 'dev' into refactor-message-listeners

This commit is contained in:
Hakadao
2024-04-11 16:57:44 +08:00
parent 38b9dfe227
commit 1a3bafb284
43 changed files with 784 additions and 145 deletions

View File

@@ -257,7 +257,10 @@ function handleUnfavorite(favoriteResource: FavoriteResource) {
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%)" bg="$bew-fill-4" />
<div
absolute w-full h-full backdrop-blur-40px
bg="$bew-fill-4" mix-blend-luminosity
/>
<img
v-if="activatedCategoryCover"
:src="removeHttpFromUrl(`${activatedCategoryCover}@480w_270h_1c`)"
@@ -289,7 +292,7 @@ function handleUnfavorite(favoriteResource: FavoriteResource) {
<template #left>
<tabler:player-play />
</template>
{{ t('watch_later.play_all') }}
{{ t('common.play_all') }}
</Button>
</p>
<ul class="category-list" h-full overflow-overlay border="1 color-[rgba(255,255,255,.2)]" rounded="$bew-radius">

View File

@@ -1,13 +1,15 @@
<script setup lang="ts">
import type { Ref } from 'vue'
import { onClickOutside } from '@vueuse/core'
import { onKeyStroke } from '@vueuse/core'
import { useToast } from 'vue-toastification'
import { Type as ThreePointV2Type } from '~/models/video/appForYou'
import type { AppForYouResult, Item as AppVideoItem, ThreePointV2 } from '~/models/video/appForYou'
import type { Item as VideoItem, forYouResult } from '~/models/video/forYou'
import type { GridLayout } from '~/logic'
import { accessKey, settings } from '~/logic'
import { LanguageType } from '~/enums/appEnums'
import { TVAppKey } from '~/utils/authProvider'
import API from '~/background/msg.define'
import { TVAppKey, getTvSign } from '~/utils/authProvider'
const props = defineProps<{
gridLayout: GridLayout
@@ -26,6 +28,8 @@ const gridValue = computed((): string => {
return '~ cols-1 gap-4'
})
const toast = useToast()
const videoList = reactive<VideoItem[]>([])
const appVideoList = reactive<AppVideoItem[]>([])
const isLoading = ref<boolean>(true)
@@ -37,19 +41,44 @@ const { handleReachBottom, handlePageRefresh, scrollbarRef } = useBewlyApp()
const showVideoOptions = ref<boolean>(false)
const videoOptions = ref<ThreePointV2[] | undefined>([])
const videoOptionsPosition = reactive<{ top: string, left: string }>({ top: '0', left: '0' })
// const activatedVideoId = ref<number>(0)
const activatedVideoIdx = ref<number>(0)
const activatedVideo = ref<AppVideoItem | null>()
const videoCardRef = ref(null)
const dislikedVideoIds = ref<number[]>([])
const dislikedVideoUniqueKeys = ref<string[]>([])
const showDislikeDialog = ref<boolean>(false)
const selectedDislikeReason = ref<number>(1)
const loadingDislikeDialog = ref<boolean>(false)
onKeyStroke((e: KeyboardEvent) => {
if (showDislikeDialog.value) {
const dislikeReasons = activatedVideo.value?.three_point_v2?.find(option => option.type === ThreePointV2Type.Dislike)?.reasons || []
if (e.key >= '0' && e.key <= '9') {
e.preventDefault()
dislikeReasons.forEach((reason) => {
if (dislikeReasons[Number(e.key) - 1] && reason.id === dislikeReasons[Number(e.key) - 1].id)
selectedDislikeReason.value = reason.id
})
}
else if (e.key === 'ArrowUp') {
e.preventDefault()
const currentIndex = dislikeReasons.findIndex(reason => selectedDislikeReason.value === reason.id)
if (currentIndex > 0)
selectedDislikeReason.value = dislikeReasons[currentIndex - 1].id
}
else if (e.key === 'ArrowDown') {
e.preventDefault()
const currentIndex = dislikeReasons.findIndex(reason => selectedDislikeReason.value === reason.id)
if (currentIndex < dislikeReasons.length - 1)
selectedDislikeReason.value = dislikeReasons[currentIndex + 1].id
}
}
})
watch(() => settings.value.recommendationMode, () => {
initData()
})
onClickOutside(videoCardRef, () => {
closeVideoOptions()
})
onMounted(async () => {
// Delay by 0.2 seconds to obtain the `settings.value.recommendationMode` value
// otherwise the `settings.value.recommendationMode` value will be undefined
@@ -181,12 +210,13 @@ async function getAppRecommendVideos() {
}
function handleMoreClick(e: MouseEvent, data: AppVideoItem) {
if (activatedVideo.value && activatedVideo.value.idx === data.idx) {
if (activatedVideo.value && activatedVideoIdx.value === data.idx) {
closeVideoOptions()
return
}
showVideoOptions.value = true
// activatedVideo.value.idx = data.idx
activatedVideoIdx.value = data.idx
activatedVideo.value = data
const osInstance = scrollbarRef.value?.osInstance()
const scrollTop = osInstance.elements().viewport.scrollTop || 0
@@ -195,26 +225,96 @@ function handleMoreClick(e: MouseEvent, data: AppVideoItem) {
videoOptionsPosition.left = `${e.clientX}px`
}
function handleMoreCommand(command: string) {
if (activatedVideo.value)
dislikedVideoIds.value.push(activatedVideo.value.idx)
function handleMoreCommand(command: ThreePointV2Type) {
closeVideoOptions()
// eslint-disable-next-line no-empty
switch (command) {}
// if (command === 'close')
// closeVideoOptions()
switch (command) {
case ThreePointV2Type.Feedback:
break
case ThreePointV2Type.Dislike:
openDislikeDialog()
break
}
}
function closeVideoOptions() {
showVideoOptions.value = false
activatedVideo.value = null
activatedVideoIdx.value = 0
}
// function handleVideoOptionsCommand(command: string) {
// if (command === 'close')
// closeVideoOptions()
// }
function openDislikeDialog() {
selectedDislikeReason.value = 1
showDislikeDialog.value = true
}
function closeDislikeDialog() {
showDislikeDialog.value = false
}
function handleDislike() {
loadingDislikeDialog.value = true
const params = {
access_key: accessKey.value,
goto: activatedVideo.value?.goto,
id: activatedVideo.value?.param,
// https://github.com/magicdawn/bilibili-app-recommend/blob/cb51f75f415f48235ce048537f2013122c16b56b/src/components/VideoCard/card.service.ts#L115
idx: (Date.now() / 1000).toFixed(0),
reason_id: selectedDislikeReason.value,
build: 74800100,
device: 'pad',
mobi_app: 'iphone',
appkey: TVAppKey.appkey,
}
browser.runtime.sendMessage({
contentScriptQuery: 'dislikeVideo',
...params,
sign: getTvSign(params),
})
.then((res) => {
if (res.code === 0)
activatedVideo.value && dislikedVideoUniqueKeys.value.push(getVideoUniqueKey(activatedVideo.value))
else
toast.error(res.message)
})
.finally(() => {
loadingDislikeDialog.value = false
})
}
function handleUndoDislike(video: AppVideoItem) {
const params = {
access_key: accessKey.value,
goto: video.goto,
id: video.param,
// https://github.com/magicdawn/bilibili-app-recommend/blob/cb51f75f415f48235ce048537f2013122c16b56b/src/components/VideoCard/card.service.ts#L115
idx: (Date.now() / 1000).toFixed(0),
reason_id: selectedDislikeReason.value, // 1 means dislike, e.g. {"id": 1, "name": "不感兴趣","toast": "将减少相似内容推荐"}
build: 74800100,
device: 'pad',
mobi_app: 'iphone',
appkey: TVAppKey.appkey,
}
browser.runtime.sendMessage({
contentScriptQuery: 'undoDislikeVideo',
...params,
sign: getTvSign(params),
}).then((res) => {
if (res.code === 0) {
dislikedVideoUniqueKeys.value = dislikedVideoUniqueKeys.value.filter(currentKey =>
currentKey !== (activatedVideo.value ? getVideoUniqueKey(activatedVideo.value) : ''),
)
}
else {
toast.error(res.message)
}
})
}
function getVideoUniqueKey(video: AppVideoItem) {
return video.idx + (video.bvid || video.uri || '')
}
function jumpToLoginPage() {
location.href = 'https://passport.bilibili.com/login'
@@ -230,8 +330,12 @@ defineExpose({ initData })
<div hidden grid="~ cols-1 xl:cols-2 gap-4" />
<div hidden grid="~ cols-1 gap-4" />
<!-- dislike popup -->
<!-- more popup -->
<div v-show="showVideoOptions">
<div
pos="fixed top-0 left-0" w-full h-full z-1
@click="closeVideoOptions"
/>
<div
style="backdrop-filter: var(--bew-filter-glass-1);"
:style="{ transform: `translate(${videoOptionsPosition.left}, ${videoOptionsPosition.top})` }"
@@ -240,17 +344,53 @@ defineExpose({ initData })
shadow="$bew-shadow-1" z-10
>
<ul flex="~ col gap-1">
<li
v-for="option in videoOptions" :key="option.type"
bg="hover:$bew-fill-2" p="x-4 y-2" rounded="$bew-radius-half" cursor-pointer
@click="handleMoreCommand('')"
>
{{ option.title }}
</li>
<template v-for="option in videoOptions" :key="option.type">
<li
v-if="option.type !== ThreePointV2Type.WatchLater && option.type !== ThreePointV2Type.Feedback"
bg="hover:$bew-fill-2" p="x-4 y-2" rounded="$bew-radius-half" cursor-pointer
@click="handleMoreCommand(option.type)"
>
<span v-if="option.type === ThreePointV2Type.Dislike">{{ $t('home.not_interested') }}</span>
<span v-else>{{ option.title }}</span>
</li>
</template>
</ul>
</div>
</div>
<!-- dislike dialog -->
<Dialog
v-if="showDislikeDialog"
:title="$t('home.tell_us_why')"
width="400px"
append-to-bewly-body
:loading="loadingDislikeDialog"
@close="closeDislikeDialog"
@confirm="handleDislike"
>
<ul flex="~ col gap-2">
<li
v-for="(reason, index) in activatedVideo?.three_point_v2?.find(option => option.type === ThreePointV2Type.Dislike)?.reasons"
:key="reason.id"
:class="{ 'activated-dislike-reason': selectedDislikeReason === reason.id }"
p="x-6 y-4" rounded="$bew-radius" cursor-pointer bg="$bew-fill-1 hover:$bew-fill-2"
flex="~ gap-2 items-center justify-between"
@click="selectedDislikeReason = reason.id"
>
<div flex="~ gap-2">
<div
bg="$bew-theme-color" color-white w-20px h-20px rounded-10
flex="~ justify-center items-center"
>
{{ index + 1 }}
</div>
{{ reason.name }}
</div>
<line-md:confirm v-if="selectedDislikeReason === reason.id" />
</li>
</ul>
</Dialog>
<Empty v-if="needToLoginFirst" mt-6 :description="$t('common.please_log_in_first')">
<Button type="primary" @click="jumpToLoginPage()">
{{ $t('common.login') }}
@@ -305,10 +445,13 @@ defineExpose({ initData })
show-preview
:horizontal="gridLayout !== 'adaptive'"
more-btn
:more-btn-active="video.idx === activatedVideo?.idx"
:show-dislike-options="dislikedVideoIds.includes(video.idx)"
:more-btn-active="video.idx === activatedVideoIdx"
:removed="dislikedVideoUniqueKeys.includes(getVideoUniqueKey(video))"
:dislike-reasons="video.three_point_v2?.find(option => option.type === ThreePointV2Type.Dislike)?.reasons || []"
@more-click="(e) => handleMoreClick(e, video)"
@undo="handleUndoDislike(video)"
/>
<!-- :more-options="video.three_point_v2" -->
</template>
<!-- skeleton -->
@@ -330,4 +473,7 @@ defineExpose({ initData })
</template>
<style lang="scss" scoped>
.activated-dislike-reason {
--at-apply: bg-$bew-theme-color-20 color-$bew-theme-color;
}
</style>

View File

@@ -271,7 +271,10 @@ function jumpToLoginPage() {
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%)" bg="$bew-fill-4" />
<div
absolute w-full h-full backdrop-blur-40px
bg="$bew-fill-4" mix-blend-luminosity
/>
<img
v-if="watchLaterList[0]"
:src="removeHttpFromUrl(`${watchLaterList[0].pic}@480w_270h_1c`)"
@@ -300,7 +303,7 @@ function jumpToLoginPage() {
<template #left>
<tabler:player-play />
</template>
{{ t('watch_later.play_all') }}
{{ t('common.play_all') }}
</Button>
<Button
color="rgba(255,255,255,.35)" block text-color="white" strong flex-1