From 29777ff928051540d1fbcc55ba49237bb2207084 Mon Sep 17 00:00:00 2001 From: arabcoders Date: Wed, 22 Apr 2026 20:55:29 +0300 Subject: [PATCH 1/6] refactor: remove ui_update_title and standardize page title --- FAQ.md | 1 - app/library/config.py | 5 ----- ui/app/components/VideoPlayer.vue | 12 +++--------- ui/app/composables/useYtpConfig.ts | 1 - ui/app/layouts/default.vue | 16 ++++++++++++---- ui/app/pages/browser/[...slug].vue | 8 ++++++-- ui/app/pages/changelog.vue | 2 -- ui/app/pages/console.vue | 2 -- ui/app/pages/docs/[...slug].vue | 3 ++- ui/app/pages/index.vue | 25 +------------------------ ui/app/pages/logs.vue | 2 -- ui/app/types/config.d.ts | 2 -- ui/app/utils/index.ts | 13 +++++++++++++ 13 files changed, 37 insertions(+), 55 deletions(-) diff --git a/FAQ.md b/FAQ.md index 72e31a93..c4f53db4 100644 --- a/FAQ.md +++ b/FAQ.md @@ -30,7 +30,6 @@ or the `environment:` section in `compose.yaml` file. | YTP_DEBUG | Whether to turn on debug mode | `false` | | YTP_DEBUGPY_PORT | The port to use for the debugpy debugger | `5678` | | YTP_EXTRACT_INFO_TIMEOUT | The timeout for extracting video information | `70` | -| YTP_UI_UPDATE_TITLE | Whether to update the title of the page with the current stats | `true` | | YTP_PIP_PACKAGES | A space separated list of pip packages to install | `(not_set)` | | YTP_PIP_IGNORE_UPDATES | Do not update the custom pip packages | `false` | | YTP_PICTURES_BACKENDS | A comma separated list of pictures urls to use | `(not_set)` | diff --git a/app/library/config.py b/app/library/config.py index b153bcf7..b2619d18 100644 --- a/app/library/config.py +++ b/app/library/config.py @@ -129,9 +129,6 @@ class Config(metaclass=Singleton): apprise_config: str = "{config_path}{os_sep}apprise.yml" """The path to the Apprise configuration file.""" - ui_update_title: bool = True - """Update the title of the browser tab with the current status.""" - pip_packages: str = "" """The pip packages to install.""" @@ -284,7 +281,6 @@ class Config(metaclass=Singleton): "access_log", "remove_files", "ignore_ui", - "ui_update_title", "pip_ignore_updates", "file_logging", "console_enabled", @@ -308,7 +304,6 @@ class Config(metaclass=Singleton): "output_template", "started", "remove_files", - "ui_update_title", "max_workers", "max_workers_per_extractor", "default_preset", diff --git a/ui/app/components/VideoPlayer.vue b/ui/app/components/VideoPlayer.vue index bf8f0c05..cfa67869 100644 --- a/ui/app/components/VideoPlayer.vue +++ b/ui/app/components/VideoPlayer.vue @@ -285,7 +285,7 @@ import { useStorage } from '@vueuse/core'; import { watch } from 'vue'; import Hls from 'hls.js'; -import { disableOpacity, enableOpacity } from '~/utils'; +import { disableOpacity, enableOpacity, formatPageTitle } from '~/utils'; import { useKeyboardShortcuts } from '~/composables/useKeyboardShortcuts'; import type { StoreItem } from '~/types/store'; @@ -319,6 +319,8 @@ const havePoster = ref(false); const showHelp = ref(false); const usingHls = ref(false); +useHead(() => (title.value ? { title: formatPageTitle(`Playing: ${title.value}`) } : {})); + let unbindMediaSessionListeners: null | (() => void) = null; let hls: Hls | null = null; let cleanupKeyboardShortcuts: null | (() => void) = null; @@ -679,10 +681,6 @@ onBeforeUnmount(() => { unbindMediaSessionListeners = null; } - if (title.value) { - window.document.title = 'YTPTube'; - } - if (!video.value) { return; } @@ -706,10 +704,6 @@ const prepareVideoPlayer = () => { applyMediaSessionMetadata(); - if (title.value) { - window.document.title = `YTPTube - Playing: ${title.value}`; - } - if (!video.value) { return; } diff --git a/ui/app/composables/useYtpConfig.ts b/ui/app/composables/useYtpConfig.ts index 1c2f302e..b66f71dd 100644 --- a/ui/app/composables/useYtpConfig.ts +++ b/ui/app/composables/useYtpConfig.ts @@ -15,7 +15,6 @@ const state = reactive({ app: { download_path: '/downloads', remove_files: false, - ui_update_title: true, output_template: '', ytdlp_version: '', max_workers: 20, diff --git a/ui/app/layouts/default.vue b/ui/app/layouts/default.vue index 1bf96a0c..dfe6c4a6 100644 --- a/ui/app/layouts/default.vue +++ b/ui/app/layouts/default.vue @@ -497,6 +497,7 @@ import { useStorage } from '@vueuse/core'; import moment from 'moment'; import { useMediaQuery } from '~/composables/useMediaQuery'; import type { toastPosition } from '~/composables/useNotification'; +import { formatPageTitle } from '~/utils'; import type { YTDLPOption } from '~/types/ytdlp'; import { useDialog } from '~/composables/useDialog'; import Dialog from '~/components/Dialog.vue'; @@ -750,10 +751,17 @@ const sidebarItems = computed< .filter((section) => section.items.some((group) => group.length > 0)); }); -const pageTitle = computed(() => { - const match = getActiveNavItem(route, navigationAvailability.value); - return match?.navbarTitle || match?.label || 'YTPTube'; -}); +const activeNavItem = computed(() => getActiveNavItem(route, navigationAvailability.value)); + +const pageTitle = computed( + () => activeNavItem.value?.navbarTitle || activeNavItem.value?.label || 'YTPTube', +); + +const documentTitle = computed(() => activeNavItem.value?.pageLabel || pageTitle.value); + +useHead(() => ({ + title: formatPageTitle(documentTitle.value), +})); const buildTooltip = computed( () => diff --git a/ui/app/pages/browser/[...slug].vue b/ui/app/pages/browser/[...slug].vue index 959d8feb..ba126a06 100644 --- a/ui/app/pages/browser/[...slug].vue +++ b/ui/app/pages/browser/[...slug].vue @@ -527,6 +527,7 @@ import moment from 'moment'; import { useStorage } from '@vueuse/core'; import type { DropdownMenuItem } from '@nuxt/ui'; import type { FileItem } from '~/types/filebrowser'; +import { formatPageTitle } from '~/utils'; import { requirePageShell } from '~/utils/topLevelNavigation'; const route = useRoute(); @@ -559,6 +560,7 @@ const pageShell = requirePageShell('files'); const hasItems = computed(() => filteredItems.value.length > 0); const hasSelected = computed(() => selectedElms.value.length > 0); const displayedItemPaths = computed(() => filteredItems.value.map((item) => item.path)); +const browserPageTitle = computed(() => `File Browser: /${sTrim(browserPath.value || '/', '/')}`); const currentDirectoryName = computed( () => breadcrumbItems.value[breadcrumbItems.value.length - 1]?.name || 'Home', ); @@ -752,6 +754,10 @@ const itemSizeLabel = (item: FileItem): string => { return item.type === 'file' ? formatBytes(item.size) : ucFirst(item.type); }; +useHead(() => ({ + title: formatPageTitle(decodeURIComponent(browserPageTitle.value)), +})); + const updateUrl = (dir: string, page?: number): void => { const normalizedDir = dir.replace(/^\/+/, '').replace(/\/+$/, ''); const displayDir = normalizedDir ? normalizedDir : '/'; @@ -762,8 +768,6 @@ const updateUrl = (dir: string, page?: number): void => { if (fullUrl !== window.location.href) { history.replaceState({ path: normalizedDir || '/', title }, title, stateUrl); } - - useHead({ title: decodeURIComponent(title) }); }; const handleClick = (item: FileItem): void => { diff --git a/ui/app/pages/changelog.vue b/ui/app/pages/changelog.vue index 573b3147..d282ca84 100644 --- a/ui/app/pages/changelog.vue +++ b/ui/app/pages/changelog.vue @@ -193,8 +193,6 @@ const toast = useNotification(); const config = useYtpConfig(); const pageShell = requirePageShell('changelog'); -useHead({ title: 'CHANGELOG' }); - const PROJECT = 'ytptube'; const REPO = `https://github.com/arabcoders/${PROJECT}`; const REPO_URL = `https://arabcoders.github.io/${PROJECT}/CHANGELOG.json?version={version}`; diff --git a/ui/app/pages/console.vue b/ui/app/pages/console.vue index 03f2b101..3fc2d9a1 100644 --- a/ui/app/pages/console.vue +++ b/ui/app/pages/console.vue @@ -327,8 +327,6 @@ import type { AutoCompleteOptions } from '~/types/autocomplete'; import { disableOpacity, enableOpacity } from '~/utils'; import { requirePageShell } from '~/utils/topLevelNavigation'; -useHead({ title: 'Console' }); - const MAX_HISTORY_ITEMS = 50; const ACTIVE_SESSION_STATUSES = ['starting', 'running', 'reconnecting']; diff --git a/ui/app/pages/docs/[...slug].vue b/ui/app/pages/docs/[...slug].vue index ae485004..e829c993 100644 --- a/ui/app/pages/docs/[...slug].vue +++ b/ui/app/pages/docs/[...slug].vue @@ -49,6 +49,7 @@