From f764279a51f61d1d2dc50d3933b01fe94f11af09 Mon Sep 17 00:00:00 2001 From: Estrella Pan Date: Sun, 25 Jan 2026 23:09:53 +0100 Subject: [PATCH] fix(webui): improve mobile UI/UX layout and responsiveness MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Mobile Layout Fixes: - Fix config page horizontal overflow by adding min-width: 0 constraints - Fix sticky action buttons positioning on config page - Add loading states to config save/cancel buttons - Reduce topbar padding and icon spacing for mobile - Make search button fill space between logo and action icons - Fix search modal header layout with close button visibility Component Improvements: - ab-topbar: Flex search button with "Click to search" text on mobile - ab-status-bar: Reduce button sizes and gaps on mobile - ab-fold-panel: Add max-width and overflow constraints - ab-setting: Add max-width: 100% to prevent input overflow - ab-search-modal: Reduce padding and element sizes on mobile - ab-mobile-nav: Increase label font-size from 10px to 11px - ab-sidebar: Fix toggle animation (rotateY → rotate) Calendar & Bangumi Pages: - Add lazy loading to poster images for better performance - Move unknown air day items to separate section below grid - Add actionable CTA button to empty state with useAddRss hook Login Page: - Add will-change: transform for background animation performance i18n: - Add click_to_search translation key for mobile search button - Add add_rss_btn translation for empty state CTA Co-Authored-By: Claude Opus 4.5 --- webui/src/components/ab-fold-panel.vue | 3 + webui/src/components/ab-setting.vue | 8 + webui/src/components/ab-status-bar.vue | 16 +- webui/src/components/layout/ab-mobile-nav.vue | 2 +- webui/src/components/layout/ab-sidebar.vue | 2 +- webui/src/components/layout/ab-topbar.vue | 116 ++++++++++--- .../src/components/search/ab-search-modal.vue | 46 +++-- webui/src/hooks/useAddRss.ts | 23 +++ webui/src/i18n/en.json | 6 +- webui/src/i18n/zh-CN.json | 6 +- webui/src/pages/index/bangumi.vue | 11 ++ webui/src/pages/index/calendar.vue | 161 +++++++++++++----- webui/src/pages/index/config.vue | 81 +++++++-- webui/src/pages/login.vue | 1 + webui/types/dts/auto-imports.d.ts | 1 + webui/types/dts/components.d.ts | 1 + 16 files changed, 379 insertions(+), 105 deletions(-) create mode 100644 webui/src/hooks/useAddRss.ts diff --git a/webui/src/components/ab-fold-panel.vue b/webui/src/components/ab-fold-panel.vue index 17d7c3d4..f19d0242 100644 --- a/webui/src/components/ab-fold-panel.vue +++ b/webui/src/components/ab-fold-panel.vue @@ -36,6 +36,8 @@ withDefaults( border-radius: var(--radius-md); border: 1px solid var(--color-border); transition: border-color var(--transition-normal); + min-width: 0; // Allow panel to shrink below content size + max-width: 100%; } .fold-panel-header { @@ -64,6 +66,7 @@ withDefaults( padding: 12px 14px; font-size: 14px; color: var(--color-text); + overflow-x: hidden; transition: background-color var(--transition-normal), color var(--transition-normal); } diff --git a/webui/src/components/ab-setting.vue b/webui/src/components/ab-setting.vue index 02cf23c8..23e527b8 100644 --- a/webui/src/components/ab-setting.vue +++ b/webui/src/components/ab-setting.vue @@ -48,6 +48,14 @@ const data = defineModel('data'); diff --git a/webui/src/pages/login.vue b/webui/src/pages/login.vue index e1016faf..7f08f172 100644 --- a/webui/src/pages/login.vue +++ b/webui/src/pages/login.vue @@ -153,6 +153,7 @@ async function handleLogin() { filter: blur(100px); opacity: 0.6; animation: float 20s ease-in-out infinite; + will-change: transform; } &::before { diff --git a/webui/types/dts/auto-imports.d.ts b/webui/types/dts/auto-imports.d.ts index 3302430e..4e6726c8 100644 --- a/webui/types/dts/auto-imports.d.ts +++ b/webui/types/dts/auto-imports.d.ts @@ -86,6 +86,7 @@ declare global { const toRefs: typeof import('vue')['toRefs'] const triggerRef: typeof import('vue')['triggerRef'] const unref: typeof import('vue')['unref'] + const useAddRss: typeof import('../../src/hooks/useAddRss')['useAddRss'] const useApi: typeof import('../../src/hooks/useApi')['useApi'] const useAppInfo: typeof import('../../src/hooks/useAppInfo')['useAppInfo'] const useAttrs: typeof import('vue')['useAttrs'] diff --git a/webui/types/dts/components.d.ts b/webui/types/dts/components.d.ts index 8a4c8a96..be154161 100644 --- a/webui/types/dts/components.d.ts +++ b/webui/types/dts/components.d.ts @@ -54,6 +54,7 @@ declare module '@vue/runtime-core' { ConfigPasskey: typeof import('./../../src/components/setting/config-passkey.vue')['default'] ConfigPlayer: typeof import('./../../src/components/setting/config-player.vue')['default'] ConfigProxy: typeof import('./../../src/components/setting/config-proxy.vue')['default'] + ConfigSearchProvider: typeof import('./../../src/components/setting/config-search-provider.vue')['default'] MediaQuery: typeof import('./../../src/components/media-query.vue')['default'] RouterLink: typeof import('vue-router')['RouterLink'] RouterView: typeof import('vue-router')['RouterView']