feat: recommendation mode filter setting (#840)

* feat: Add filter options for view count and duration in settings

* chore: update styles && rename func.ts to useFilter.ts

* feat: Add scrollbar check to determine if the viewport has a scrollbar

* feat: app recommendation filters

* chore: update

* feat: i18n support

---------

Co-authored-by: pengyunfei <pengyunfei@360.cn>
This commit is contained in:
Hakadao
2024-07-01 01:05:18 +08:00
committed by GitHub
parent b7d7c4bab5
commit 06382e10e2
11 changed files with 218 additions and 11 deletions

View File

@@ -279,6 +279,17 @@ function handleReduceFrostedGlassBlur() {
// window.open(`https://www.bilibili.com/video/${bvid}`, '_self')
// }
/**
* Checks if the current viewport has a scrollbar.
* @returns {boolean} Returns true if the viewport has a scrollbar, false otherwise.
*/
function haveScrollbar() {
const osInstance = scrollbarRef.value?.osInstance()
const { viewport } = osInstance.elements()
const { scrollHeight } = viewport // get scroll offset
return scrollHeight > window.innerHeight
}
provide<BewlyAppProvider>('BEWLY_APP', {
activatedPage,
mainAppRef,
@@ -287,6 +298,7 @@ provide<BewlyAppProvider>('BEWLY_APP', {
handleBackToTop,
handlePageRefresh,
handleReachBottom,
haveScrollbar,
})
</script>

View File

@@ -11,6 +11,7 @@ import Empty from '~/components/Empty.vue'
import VideoCard from '~/components/VideoCard/VideoCard.vue'
import { useApiClient } from '~/composables/api'
import { useBewlyApp } from '~/composables/useAppProvider'
import { FilterType, useFilter } from '~/composables/useFilter'
import { LanguageType } from '~/enums/appEnums'
import type { GridLayout } from '~/logic'
import { accessKey, settings } from '~/logic'
@@ -29,6 +30,9 @@ const emit = defineEmits<{
(e: 'afterLoading'): void
}>()
const filterFunc = useFilter([FilterType.duration, FilterType.viewCount], [['duration'], ['stat', 'view']])
const appFilterFunc = useFilter([FilterType.duration, FilterType.viewCountStr], [['player_args', 'duration'], ['cover_left_text_1']])
const { t } = useI18n()
// https://github.com/starknt/BewlyBewly/blob/fad999c2e482095dc3840bb291af53d15ff44130/src/contentScripts/views/Home/components/ForYou.vue#L16
@@ -59,7 +63,7 @@ const needToLoginFirst = ref<boolean>(false)
const containerRef = ref<HTMLElement>() as Ref<HTMLElement>
const refreshIdx = ref<number>(1)
const noMoreContent = ref<boolean>(false)
const { handleReachBottom, handlePageRefresh, scrollbarRef } = useBewlyApp()
const { handleReachBottom, handlePageRefresh, scrollbarRef, haveScrollbar } = useBewlyApp()
const showVideoOptions = ref<boolean>(false)
const appVideoOptions = ref<ThreePointV2[] | undefined>([])
const videoOptions = reactive<{ id: number, name: string }[]>([
@@ -189,7 +193,10 @@ async function getRecommendVideos() {
const resData = [] as VideoItem[]
response.data.item.forEach((item: VideoItem) => {
resData.push(item)
if (!filterFunc.value || filterFunc.value(item))
resData.push(item)
// resData.push(item)
})
// when videoList has length property, it means it is the first time to load
@@ -204,12 +211,16 @@ async function getRecommendVideos() {
}
})
}
if (!haveScrollbar()) {
getRecommendVideos()
}
}
else if (response.code === 62011) {
needToLoginFirst.value = true
}
}
catch {
finally {
videoList.value = videoList.value.filter(video => video.item)
}
}
@@ -236,7 +247,7 @@ async function getAppRecommendVideos() {
response.data.items.forEach((item: AppVideoItem) => {
// Remove banner & ad cards
if (!item.card_type.includes('banner') && item.card_type !== 'cm_v1')
if (!item.card_type.includes('banner') && item.card_type !== 'cm_v1' && (!appFilterFunc.value || appFilterFunc.value(item)))
resData.push(item)
})
@@ -252,6 +263,10 @@ async function getAppRecommendVideos() {
}
})
}
if (!haveScrollbar()) {
getAppRecommendVideos()
}
}
else if (response.code === 62011) {
needToLoginFirst.value = true