diff --git a/webui/package.json b/webui/package.json index f423c373..3f577809 100644 --- a/webui/package.json +++ b/webui/package.json @@ -29,6 +29,7 @@ "vue": "^3.3.4", "vue-i18n": "^9.2.2", "vue-inline-svg": "^3.1.2", + "vue-mobile-detection": "^2.0.1", "vue-router": "^4.2.1" }, "devDependencies": { diff --git a/webui/pnpm-lock.yaml b/webui/pnpm-lock.yaml index 21ca7efd..d39a52d2 100644 --- a/webui/pnpm-lock.yaml +++ b/webui/pnpm-lock.yaml @@ -38,6 +38,9 @@ dependencies: vue-inline-svg: specifier: ^3.1.2 version: 3.1.2(vue@3.3.4) + vue-mobile-detection: + specifier: ^2.0.1 + version: 2.0.1 vue-router: specifier: ^4.2.1 version: 4.2.1(vue@3.3.4) @@ -9847,6 +9850,12 @@ packages: vue: 3.3.4 dev: false + /vue-mobile-detection@2.0.1: + resolution: {integrity: sha512-ziB0Rp8Snp08+p7E+WCRzeYYYp0ddPaqHlFxWN0kpLAddB5D/PRwgIv18P08hkhwNFRgBQ71T19jNIbttR7P0g==} + dependencies: + vue: 3.3.4 + dev: false + /vue-router@4.2.1(vue@3.3.4): resolution: {integrity: sha512-nW28EeifEp8Abc5AfmAShy5ZKGsGzjcnZ3L1yc2DYUo+MqbBClrRP9yda3dIekM4I50/KnEwo1wkBLf7kHH5Cw==} peerDependencies: diff --git a/webui/src/components/layout/ab-bottombar.vue b/webui/src/components/layout/ab-bottombar.vue new file mode 100644 index 00000000..6c357071 --- /dev/null +++ b/webui/src/components/layout/ab-bottombar.vue @@ -0,0 +1,25 @@ + + + + + diff --git a/webui/src/components/layout/ab-topbar.vue b/webui/src/components/layout/ab-topbar.vue index 1ed9c44b..4771499e 100644 --- a/webui/src/components/layout/ab-topbar.vue +++ b/webui/src/components/layout/ab-topbar.vue @@ -7,9 +7,15 @@ import { Power, Refresh, } from '@icon-park/vue-next'; -import { ruleTemplate } from "#/bangumi"; +import {ruleTemplate} from "#/bangumi"; import type {BangumiRule} from "#/bangumi"; +defineProps( + { + mobile: Boolean, + }, +); + const {t, changeLocale} = useMyI18n(); const {running, onUpdate, offUpdate} = useAppInfo(); @@ -87,7 +93,7 @@ onUnmounted(() => { diff --git a/webui/src/main.ts b/webui/src/main.ts index 2d2b0dad..dc17b04b 100644 --- a/webui/src/main.ts +++ b/webui/src/main.ts @@ -16,3 +16,4 @@ app.use(router); app.use(pinia); app.use(i18n); app.mount('#app'); + diff --git a/webui/src/pages/index.vue b/webui/src/pages/index.vue index 7ef43097..b92c134e 100644 --- a/webui/src/pages/index.vue +++ b/webui/src/pages/index.vue @@ -1,26 +1,41 @@ diff --git a/webui/src/pages/login.vue b/webui/src/pages/login.vue index 55d4c43d..2f658b21 100644 --- a/webui/src/pages/login.vue +++ b/webui/src/pages/login.vue @@ -1,31 +1,34 @@ diff --git a/webui/src/utils/mobile.ts b/webui/src/utils/mobile.ts new file mode 100644 index 00000000..236eea3d --- /dev/null +++ b/webui/src/utils/mobile.ts @@ -0,0 +1,3 @@ +export function isMobile() { + return window.innerWidth <= 768 || /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent) +} \ No newline at end of file diff --git a/webui/types/dts/auto-imports.d.ts b/webui/types/dts/auto-imports.d.ts index f68e10ba..eb123aae 100644 --- a/webui/types/dts/auto-imports.d.ts +++ b/webui/types/dts/auto-imports.d.ts @@ -56,6 +56,7 @@ declare global { const ignorableWatch: typeof import('@vueuse/core')['ignorableWatch'] const inject: typeof import('vue')['inject'] const isDefined: typeof import('@vueuse/core')['isDefined'] + const isMobile: typeof import('../../src/utils/mobile')['isMobile'] const isProxy: typeof import('vue')['isProxy'] const isReactive: typeof import('vue')['isReactive'] const isReadonly: typeof import('vue')['isReadonly'] diff --git a/webui/types/dts/components.d.ts b/webui/types/dts/components.d.ts index cc313003..20b5c151 100644 --- a/webui/types/dts/components.d.ts +++ b/webui/types/dts/components.d.ts @@ -12,6 +12,7 @@ declare module '@vue/runtime-core' { AbAdd: typeof import('./../../src/components/basic/ab-add.vue')['default'] AbAddRss: typeof import('./../../src/components/ab-add-rss.vue')['default'] AbBangumiCard: typeof import('./../../src/components/ab-bangumi-card.vue')['default'] + AbBottombar: typeof import('./../../src/components/layout/ab-bottombar.vue')['default'] AbButton: typeof import('./../../src/components/basic/ab-button.vue')['default'] AbChangeAccount: typeof import('./../../src/components/ab-change-account.vue')['default'] AbCheckbox: typeof import('./../../src/components/basic/ab-checkbox.vue')['default'] diff --git a/webui/unocss.config.ts b/webui/unocss.config.ts index 2c24c0e7..24216c35 100644 --- a/webui/unocss.config.ts +++ b/webui/unocss.config.ts @@ -7,49 +7,49 @@ import { import presetRemToPx from '@unocss/preset-rem-to-px'; export default defineConfig({ - presets: [ - presetUno(), - presetRemToPx(), - presetAttributify(), - presetIcons({ cdn: 'https://esm.sh/' }), - ], - theme: { - colors: { - primary: '#493475', - running: '#A3D491', - stopped: '#DF7F91', - page: '#F0F0F0', + presets: [ + presetUno(), + presetRemToPx(), + presetAttributify(), + presetIcons({cdn: 'https://esm.sh/'}), + ], + theme: { + colors: { + primary: '#493475', + running: '#A3D491', + stopped: '#DF7F91', + page: '#F0F0F0', + }, }, - }, - rules: [ - [ - 'bg-theme-row', - { - background: 'linear-gradient(90.5deg, #492897 1.53%, #783674 96.48%)', - }, + rules: [ + [ + 'bg-theme-row', + { + background: 'linear-gradient(90.5deg, #492897 1.53%, #783674 96.48%)', + }, + ], + [ + 'bg-theme-col', + { + background: 'linear-gradient(180deg, #492897 0%, #783674 100%)', + }, + ], + [ + 'poster-shandow', + { + filter: 'drop-shadow(2px 2px 2px rgba(0, 0, 0, 0.1))', + }, + ], + [ + 'poster-pen-active', + { + background: '#B4ABC6', + 'box-shadow': '2px 2px 4px rgba(0, 0, 0, 0.25)', + }, + ], ], - [ - 'bg-theme-col', - { - background: 'linear-gradient(180deg, #492897 0%, #783674 100%)', - }, - ], - [ - 'poster-shandow', - { - filter: 'drop-shadow(2px 2px 2px rgba(0, 0, 0, 0.1))', - }, - ], - [ - 'poster-pen-active', - { - background: '#B4ABC6', - 'box-shadow': '2px 2px 4px rgba(0, 0, 0, 0.25)', - }, - ], - ], - shortcuts: [ - [/^wh-(.*)$/, ([, t]) => `w-${t} h-${t}`], + shortcuts: [ + [/^wh-(.*)$/, ([, t]) => `w-${t} h-${t}`], [ 'layout-container', @@ -60,6 +60,8 @@ export default defineConfig({ 'flex space-x-20px overflow-hidden h-[calc(100vh_-_2_*_16px_-_60px_-_12px)]', ], ['layout-content', 'overflow-hidden h-full flex flex-col flex-1'], + ['layout-container-mobile', + 'wh-screen flex flex-col max-w-768px p-16px space-y-12px f-cer flex-col bg-theme-row'], ['rel', 'relative'], ['abs', 'absolute'],