webui: init mobile view.

This commit is contained in:
EstrellaXD
2023-09-11 18:43:38 +08:00
parent 82e6cce8cd
commit a9a57d5210
11 changed files with 168 additions and 64 deletions

View File

@@ -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": {

9
webui/pnpm-lock.yaml generated
View File

@@ -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:

View File

@@ -0,0 +1,25 @@
<script lang="ts" setup>
import { Home } from "@icon-park/vue-next";
</script>
<template>
<div class="flex w-full bg-white shadow">
<div class="flex-1 flex justify-center items-center">
<router-link to="/bangumi">
<Home size={24} />
</router-link>
</div>
<div class="flex-1 flex justify-center items-center">
<router-link to="/setting">
<Home size={24} />
</router-link>
</div>
<div class="flex-1 flex justify-center items-center">
<router-link to="/about">
<Home size={24} />
</router-link>
</div>
</div>
</template>

View File

@@ -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(() => {
</script>
<template>
<div h-60px bg-theme-row text-white rounded-16px fx-cer px-24px>
<div v-if="!mobile" h-60px bg-theme-row text-white rounded-16px fx-cer px-24px>
<div flex space-x-16px>
<div fx-cer space-x-16px>
<img src="/images/logo-light.svg" alt="favicon" wh-24px/>
@@ -108,4 +114,11 @@ onUnmounted(() => {
<ab-change-account v-model:show="showAccount"></ab-change-account>
<ab-add-rss v-model:show="showAddRSS" v-model:rule="searchRule"></ab-add-rss>
</div>
<div v-else px-16px>
<div f-cer rounded-16px p-16px space-x-12px bg-theme-row>
<img src="/images/logo-light.svg" alt="favicon" wh-24px/>
<img v-show="onSearchFocus === false" src="/images/AutoBangumi.svg" alt="AutoBangumi" h-24px rel top-2px/>
</div>
</div>
</template>

View File

@@ -16,3 +16,4 @@ app.use(router);
app.use(pinia);
app.use(i18n);
app.mount('#app');

View File

@@ -1,26 +1,41 @@
<script lang="ts" setup>
definePage({
name: 'Index',
redirect: '/bangumi',
});
// isMobile is a computed property
const mobile = isMobile();
</script>
<template>
<div layout-container>
<ab-topbar />
<div v-if="!mobile" layout-container>
<ab-topbar/>
<main layout-main>
<ab-sidebar />
<ab-sidebar/>
<div layout-content>
<ab-page-title :title="$route.name"></ab-page-title>
<RouterView v-slot="{ Component }">
<KeepAlive>
<component :is="Component" />
<component :is="Component"/>
</KeepAlive>
</RouterView>
</div>
</main>
</div>
<div v-else wh-screen bg-page>
<!-- <RouterView v-slot="{ Component }">-->
<!-- <KeepAlive>-->
<!-- <component :is="Component"/>-->
<!-- </KeepAlive>-->
<!-- </RouterView>-->
<div flex-col justify-between>
<ab-topbar :mobile="true"/>
<ab-bottombar/>
</div>
</div>
</template>

View File

@@ -1,31 +1,34 @@
<script lang="ts" setup>
const { user, login } = useAuth();
const {user, login} = useAuth();
definePage({
name: 'Login',
});
const mobile = isMobile();
</script>
<template>
<div f-cer layout-container>
<div v-if="!mobile" f-cer layout-container>
<ab-container :title="$t('login.title')" w-365px>
<div space-y-16px>
<ab-label :label="$t('login.username')">
<input
v-model="user.username"
type="text"
placeholder="username"
ab-input
v-model="user.username"
type="text"
placeholder="username"
ab-input
/>
</ab-label>
<ab-label :label="$t('login.password')">
<input
v-model="user.password"
type="password"
placeholder="password"
ab-input
@keyup.enter="login"
v-model="user.password"
type="password"
placeholder="password"
ab-input
@keyup.enter="login"
/>
</ab-label>
@@ -33,14 +36,44 @@ definePage({
<div flex="~ justify-end">
<ab-button size="small" @click="login">{{
$t('login.login_btn')
}}</ab-button>
$t('login.login_btn')
}}
</ab-button>
</div>
</div>
</ab-container>
</div>
<div v-else layout-container-mobile>
<ab-container :title="$t('login.title')" w-300px>
<div space-y-16px>
<ab-label :label="$t('login.username')">
<input
v-model="user.username"
type="text"
placeholder="username"
ab-input
/>
</ab-label>
<!-- <div bg="#C7C4AB" text-white rounded-4px py-4px px-2em text-main> -->
<!-- <div>{{ $t('login.default') }}: admin adminadmin</div> -->
<!-- </div> -->
<ab-label :label="$t('login.password')">
<input
v-model="user.password"
type="password"
placeholder="password"
ab-input
@keyup.enter="login"
/>
</ab-label>
<div line></div>
<div f-cer>
<ab-button size="normal" @click="login">{{
$t('login.login_btn')
}}
</ab-button>
</div>
</div>
</ab-container>
</div>
</template>

View File

@@ -0,0 +1,3 @@
export function isMobile() {
return window.innerWidth <= 768 || /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent)
}

View File

@@ -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']

View File

@@ -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']

View File

@@ -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'],