feat: custom home tab (#314)

* feat: custom home tab

* fix: init home tab

* fix: init homePageTabVisibilityList

* fix: delete default page opions

* fix: change text and reset

---------

Co-authored-by: pengyunfei <pengyunfei@360.cn>
This commit is contained in:
cloudflypeng
2024-02-25 19:16:23 +08:00
committed by GitHub
parent 641f87e0ec
commit 1a5c7cecea
6 changed files with 137 additions and 24 deletions

View File

@@ -45,6 +45,7 @@ settings:
group_search_bar: 搜索栏
group_recommendation_mode: 推荐模式
group_search_page_mode: 搜索页模式
group_home_tabs: 首页标签栏
# Settings buttons
btn:
@@ -123,6 +124,8 @@ settings:
settings_shared_with_the_search_page: 与搜索页共用的配置
settings_shared_with_the_search_page_desc: 这些设置都与搜索页共用
search_page_mode_wallpaper_fixed: 将搜索页模式的壁纸固定
home_tabs_adjustment: 标签栏调整
home_tabs_adjustment_desc: 第一个激活的 Tab 项是默认界面
# Compatibility
# Common

View File

@@ -45,6 +45,7 @@ settings:
group_search_bar: Search Bar
group_recommendation_mode: Recommendation Mode
group_search_page_mode: Search Page Mode
group_home_tabs: Home Tabs
# Settings buttons
btn:
@@ -124,6 +125,8 @@ settings:
settings_shared_with_the_search_page: Settings shared with the search page
settings_shared_with_the_search_page_desc: Those settings are used in common with the search page
search_page_mode_wallpaper_fixed: Make the wallpaper of the search page mode fixed
home_tabs_adjustment: Tabs adjustment
home_tabs_adjustment_desc: The first activated tab is the default page
# Compatibility
# Common

View File

@@ -2,10 +2,16 @@
import type { Ref } from 'vue'
import QRCodeVue from 'qrcode.vue'
import { useToast } from 'vue-toastification'
import { useI18n } from 'vue-i18n'
import draggable from 'vuedraggable'
import SearchPage from './SearchPage.vue'
import type { HomeTab } from '~/contentScripts/views/Home/types.ts'
import { HomeSubPage } from '~/contentScripts/views/Home/types'
import { getTVLoginQRCode, pollTVLoginQRCode, revokeAccessKey } from '~/utils/authProvider'
import { accessKey, settings } from '~/logic'
const { t } = useI18n()
const toast = useToast()
const showSearchPageModeSharedSettings = ref<boolean>(false)
@@ -95,6 +101,40 @@ function handleCloseSearchPageModeSharedSettings() {
showSearchPageModeSharedSettings.value = false
preventCloseSettings.value = false
}
const homeTabs = computed((): HomeTab[] => {
return [
{
label: t('home.for_you'),
value: HomeSubPage.ForYou,
},
{
label: t('home.following'),
value: HomeSubPage.Following,
},
{
label: t('home.subscribed_series'),
value: HomeSubPage.SubscribedSeries,
},
{
label: t('home.trending'),
value: HomeSubPage.Trending,
},
{
label: t('home.ranking'),
value: HomeSubPage.Ranking,
},
]
})
function resetHomeTabs() {
settings.value.homePageTabVisibilityList = homeTabs.value.map((tab) => {
return {
page: tab.value,
visible: true,
}
})
}
</script>
<template>
@@ -176,6 +216,42 @@ function handleCloseSearchPageModeSharedSettings() {
</div>
</ChildSettingsDialog>
</SettingsItemGroup>
<SettingsItemGroup
:title="$t('settings.group_home_tabs')"
>
<SettingsItem next-line :desc="$t('settings.home_tabs_adjustment_desc')">
<template #title>
<div flex="~ gap-4 items-center">
{{ $t('settings.home_tabs_adjustment') }}
<Button size="small" type="secondary" @click="resetHomeTabs">
<template #left>
<mingcute:back-line />
</template>
{{ $t('common.reset') }}
</Button>
</div>
</template>
<draggable
v-model="settings.homePageTabVisibilityList"
item-key="page"
:component-data="{ style: 'display: flex; gap: 0.5rem; flex-wrap: wrap;' }"
>
<template #item="{ element }">
<div
flex="~ gap-2 items-center" p="x-4 y-2" bg="$bew-fill-1" rounded="$bew-radius" cursor-all-scroll
duration-300
:style="{
background: element.visible ? 'var(--bew-theme-color)' : 'var(--bew-fill-1)',
color: element.visible ? 'white' : 'var(--bew-text-1)',
}"
@click="element.visible = !element.visible"
>
{{ homeTabs.find(tab => tab.value === element.page)?.label }}
</div>
</template>
</draggable>
</SettingsItem>
</SettingsItemGroup>
<SettingsItemGroup :title="$t('settings.group_search_page_mode')">
<SettingsItem :title="$t('settings.use_search_page_mode')">

View File

@@ -23,35 +23,57 @@ const showSearchPageMode = ref<boolean>(false)
const shouldMoveTabsUp = ref<boolean>(false)
const tabContentLoading = ref<boolean>(false)
const tabs = computed((): HomeTab[] => {
return [
{
label: t('home.for_you'),
value: HomeSubPage.ForYou,
},
{
label: t('home.following'),
value: HomeSubPage.Following,
},
{
label: t('home.subscribed_series'),
value: HomeSubPage.SubscribedSeries,
},
{
label: t('home.trending'),
value: HomeSubPage.Trending,
},
{
label: t('home.ranking'),
value: HomeSubPage.Ranking,
},
]
})
const tabs = ref<HomeTab[]>([])
const defaultTabs = [
{
label: t('home.for_you'),
value: HomeSubPage.ForYou,
},
{
label: t('home.following'),
value: HomeSubPage.Following,
},
{
label: t('home.subscribed_series'),
value: HomeSubPage.SubscribedSeries,
},
{
label: t('home.trending'),
value: HomeSubPage.Trending,
},
{
label: t('home.ranking'),
value: HomeSubPage.Ranking,
},
]
watch(() => activatedPage.value, () => {
handleBackToTop(settings.value.useSearchPageModeOnHomePage ? 510 : 0)
})
// use Json stringify to watch the changes of the array item properties
watch(() => JSON.stringify(settings.value.homePageTabVisibilityList), () => {
tabs.value = computeTabs()
})
function computeTabs() {
// if homePageTabVisibilityList not fresh , set it to default
if (!settings.value.homePageTabVisibilityList.length || settings.value.homePageTabVisibilityList.length !== defaultTabs.length)
settings.value.homePageTabVisibilityList = defaultTabs.map(tab => ({ page: tab.value, visible: true }))
const targetTabs: HomeTab[] = []
for (const tab of settings.value.homePageTabVisibilityList) {
tab.visible && targetTabs.push({
label: (defaultTabs.find(defaultTab => defaultTab.value === tab.page) || {})?.label || tab.page,
value: tab.page,
})
}
return targetTabs
}
onMounted(() => {
showSearchPageMode.value = true
emitter.off('topBarVisibleChange')
@@ -69,6 +91,9 @@ onMounted(() => {
shouldMoveTabsUp.value = true
}
})
tabs.value = computeTabs()
activatedPage.value = tabs.value[0].value
})
onUnmounted(() => {

View File

@@ -1,5 +1,6 @@
import { useStorageLocal } from '~/composables/useStorageLocal'
import type { AppPage } from '~/enums/appEnums'
import type { HomeSubPage } from '~/contentScripts/views/Home/types'
// TODO: refactor: implement storage functionality using pinia + useStorageLocal()
@@ -41,6 +42,7 @@ export interface Settings {
recommendationMode: 'web' | 'app'
useSearchPageModeOnHomePage: boolean
searchPageModeWallpaperFixed: boolean
homePageTabVisibilityList: { page: HomeSubPage, visible: boolean }[]
adaptToOtherPageStyles: boolean
showTopBar: boolean
@@ -81,6 +83,7 @@ export const settings = useStorageLocal('settings', ref<Settings>({
recommendationMode: 'web',
useSearchPageModeOnHomePage: false,
searchPageModeWallpaperFixed: false,
homePageTabVisibilityList: [],
adaptToOtherPageStyles: true,
showTopBar: true,

View File

@@ -1,6 +1,7 @@
import { defineStore } from 'pinia'
import { useStorageLocal } from '~/composables/useStorageLocal'
import { AppPage } from '~/enums/appEnums'
import type { HomeSubPage } from '~/contentScripts/views/Home/types'
interface Settings {
language: string
@@ -38,6 +39,7 @@ interface Settings {
recommendationMode: 'web' | 'app'
useSearchPageModeOnHomePage: boolean
searchPageModeWallpaperFixed: boolean
homePageTabVisibilityList: { page: HomeSubPage, visible: boolean }[]
}
export const useSettingsStore = defineStore('settings', () => {
@@ -78,6 +80,7 @@ export const useSettingsStore = defineStore('settings', () => {
recommendationMode: 'web',
useSearchPageModeOnHomePage: false,
searchPageModeWallpaperFixed: false,
homePageTabVisibilityList: [],
}), { mergeDefaults: true })
function updateSettingsItem<T extends keyof Settings>(key: T, value: Settings[T]) {