mirror of
https://github.com/jxxghp/MoviePilot-Frontend.git
synced 2026-05-10 17:42:50 +08:00
fix pwa
This commit is contained in:
98
index.html
98
index.html
@@ -4,51 +4,79 @@
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<link rel="icon" href="/favicon.ico" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<meta name="viewport"
|
||||
content="width=device-width, initial-scale=1, maximum-scale=1, viewport-fit=cover, user-scalable=0" />
|
||||
<title>MoviePilot</title>
|
||||
<meta name="Robots" content="noindex,nofollow,noarchive">
|
||||
<link rel="icon" type="image/png" href="/logo.png">
|
||||
<link rel="apple-touch-icon" href="/apple-touch-icon.png">
|
||||
<link rel="apple-touch-startup-image" href="/splash/apple-splash-2048-2732.png" media="(device-width: 1024px) and (device-height: 1366px) and (-webkit-device-pixel-ratio: 2) and (orientation: portrait)">
|
||||
<link rel="apple-touch-startup-image" href="/splash/apple-splash-2732-2048.png" media="(device-width: 1024px) and (device-height: 1366px) and (-webkit-device-pixel-ratio: 2) and (orientation: landscape)">
|
||||
<link rel="apple-touch-startup-image" href="/splash/apple-splash-1668-2388.png" media="(device-width: 834px) and (device-height: 1194px) and (-webkit-device-pixel-ratio: 2) and (orientation: portrait)">
|
||||
<link rel="apple-touch-startup-image" href="/splash/apple-splash-2388-1668.png" media="(device-width: 834px) and (device-height: 1194px) and (-webkit-device-pixel-ratio: 2) and (orientation: landscape)">
|
||||
<link rel="apple-touch-startup-image" href="/splash/apple-splash-1536-2048.png" media="(device-width: 768px) and (device-height: 1024px) and (-webkit-device-pixel-ratio: 2) and (orientation: portrait)">
|
||||
<link rel="apple-touch-startup-image" href="/splash/apple-splash-2048-1536.png" media="(device-width: 768px) and (device-height: 1024px) and (-webkit-device-pixel-ratio: 2) and (orientation: landscape)">
|
||||
<link rel="apple-touch-startup-image" href="/splash/apple-splash-1668-2224.png" media="(device-width: 834px) and (device-height: 1112px) and (-webkit-device-pixel-ratio: 2) and (orientation: portrait)">
|
||||
<link rel="apple-touch-startup-image" href="/splash/apple-splash-2224-1668.png" media="(device-width: 834px) and (device-height: 1112px) and (-webkit-device-pixel-ratio: 2) and (orientation: landscape)">
|
||||
<link rel="apple-touch-startup-image" href="/splash/apple-splash-1620-2160.png" media="(device-width: 810px) and (device-height: 1080px) and (-webkit-device-pixel-ratio: 2) and (orientation: portrait)">
|
||||
<link rel="apple-touch-startup-image" href="/splash/apple-splash-2160-1620.png" media="(device-width: 810px) and (device-height: 1080px) and (-webkit-device-pixel-ratio: 2) and (orientation: landscape)">
|
||||
<link rel="apple-touch-startup-image" href="/splash/apple-splash-1284-2778.png" media="(device-width: 428px) and (device-height: 926px) and (-webkit-device-pixel-ratio: 3) and (orientation: portrait)">
|
||||
<link rel="apple-touch-startup-image" href="/splash/apple-splash-2778-1284.png" media="(device-width: 428px) and (device-height: 926px) and (-webkit-device-pixel-ratio: 3) and (orientation: landscape)">
|
||||
<link rel="apple-touch-startup-image" href="/splash/apple-splash-1170-2532.png" media="(device-width: 390px) and (device-height: 844px) and (-webkit-device-pixel-ratio: 3) and (orientation: portrait)">
|
||||
<link rel="apple-touch-startup-image" href="/splash/apple-splash-2532-1170.png" media="(device-width: 390px) and (device-height: 844px) and (-webkit-device-pixel-ratio: 3) and (orientation: landscape)">
|
||||
<link rel="apple-touch-startup-image" href="/splash/apple-splash-1125-2436.png" media="(device-width: 375px) and (device-height: 812px) and (-webkit-device-pixel-ratio: 3) and (orientation: portrait)">
|
||||
<link rel="apple-touch-startup-image" href="/splash/apple-splash-2436-1125.png" media="(device-width: 375px) and (device-height: 812px) and (-webkit-device-pixel-ratio: 3) and (orientation: landscape)">
|
||||
<link rel="apple-touch-startup-image" href="/splash/apple-splash-1242-2688.png" media="(device-width: 414px) and (device-height: 896px) and (-webkit-device-pixel-ratio: 3) and (orientation: portrait)">
|
||||
<link rel="apple-touch-startup-image" href="/splash/apple-splash-2688-1242.png" media="(device-width: 414px) and (device-height: 896px) and (-webkit-device-pixel-ratio: 3) and (orientation: landscape)">
|
||||
<link rel="apple-touch-startup-image" href="/splash/apple-splash-828-1792.png" media="(device-width: 414px) and (device-height: 896px) and (-webkit-device-pixel-ratio: 2) and (orientation: portrait)">
|
||||
<link rel="apple-touch-startup-image" href="/splash/apple-splash-1792-828.png" media="(device-width: 414px) and (device-height: 896px) and (-webkit-device-pixel-ratio: 2) and (orientation: landscape)">
|
||||
<link rel="apple-touch-startup-image" href="/splash/apple-splash-1242-2208.png" media="(device-width: 414px) and (device-height: 736px) and (-webkit-device-pixel-ratio: 3) and (orientation: portrait)">
|
||||
<link rel="apple-touch-startup-image" href="/splash/apple-splash-2208-1242.png" media="(device-width: 414px) and (device-height: 736px) and (-webkit-device-pixel-ratio: 3) and (orientation: landscape)">
|
||||
<link rel="apple-touch-startup-image" href="/splash/apple-splash-750-1334.png" media="(device-width: 375px) and (device-height: 667px) and (-webkit-device-pixel-ratio: 2) and (orientation: portrait)">
|
||||
<link rel="apple-touch-startup-image" href="/splash/apple-splash-1334-750.png" media="(device-width: 375px) and (device-height: 667px) and (-webkit-device-pixel-ratio: 2) and (orientation: landscape)">
|
||||
<link rel="apple-touch-startup-image" href="/splash/apple-splash-640-1136.png" media="(device-width: 320px) and (device-height: 568px) and (-webkit-device-pixel-ratio: 2) and (orientation: portrait)">
|
||||
<link rel="apple-touch-startup-image" href="/splash/apple-splash-1136-640.png" media="(device-width: 320px) and (device-height: 568px) and (-webkit-device-pixel-ratio: 2) and (orientation: landscape)">
|
||||
<link rel="apple-touch-startup-image" href="/splash/apple-splash-750-1334.png">
|
||||
<link rel="apple-touch-startup-image" href="/splash/apple-splash-2048-2732.png"
|
||||
media="(device-width: 1024px) and (device-height: 1366px) and (-webkit-device-pixel-ratio: 2) and (orientation: portrait)">
|
||||
<link rel="apple-touch-startup-image" href="/splash/apple-splash-2732-2048.png"
|
||||
media="(device-width: 1024px) and (device-height: 1366px) and (-webkit-device-pixel-ratio: 2) and (orientation: landscape)">
|
||||
<link rel="apple-touch-startup-image" href="/splash/apple-splash-1668-2388.png"
|
||||
media="(device-width: 834px) and (device-height: 1194px) and (-webkit-device-pixel-ratio: 2) and (orientation: portrait)">
|
||||
<link rel="apple-touch-startup-image" href="/splash/apple-splash-2388-1668.png"
|
||||
media="(device-width: 834px) and (device-height: 1194px) and (-webkit-device-pixel-ratio: 2) and (orientation: landscape)">
|
||||
<link rel="apple-touch-startup-image" href="/splash/apple-splash-1536-2048.png"
|
||||
media="(device-width: 768px) and (device-height: 1024px) and (-webkit-device-pixel-ratio: 2) and (orientation: portrait)">
|
||||
<link rel="apple-touch-startup-image" href="/splash/apple-splash-2048-1536.png"
|
||||
media="(device-width: 768px) and (device-height: 1024px) and (-webkit-device-pixel-ratio: 2) and (orientation: landscape)">
|
||||
<link rel="apple-touch-startup-image" href="/splash/apple-splash-1668-2224.png"
|
||||
media="(device-width: 834px) and (device-height: 1112px) and (-webkit-device-pixel-ratio: 2) and (orientation: portrait)">
|
||||
<link rel="apple-touch-startup-image" href="/splash/apple-splash-2224-1668.png"
|
||||
media="(device-width: 834px) and (device-height: 1112px) and (-webkit-device-pixel-ratio: 2) and (orientation: landscape)">
|
||||
<link rel="apple-touch-startup-image" href="/splash/apple-splash-1620-2160.png"
|
||||
media="(device-width: 810px) and (device-height: 1080px) and (-webkit-device-pixel-ratio: 2) and (orientation: portrait)">
|
||||
<link rel="apple-touch-startup-image" href="/splash/apple-splash-2160-1620.png"
|
||||
media="(device-width: 810px) and (device-height: 1080px) and (-webkit-device-pixel-ratio: 2) and (orientation: landscape)">
|
||||
<link rel="apple-touch-startup-image" href="/splash/apple-splash-1284-2778.png"
|
||||
media="(device-width: 428px) and (device-height: 926px) and (-webkit-device-pixel-ratio: 3) and (orientation: portrait)">
|
||||
<link rel="apple-touch-startup-image" href="/splash/apple-splash-2778-1284.png"
|
||||
media="(device-width: 428px) and (device-height: 926px) and (-webkit-device-pixel-ratio: 3) and (orientation: landscape)">
|
||||
<link rel="apple-touch-startup-image" href="/splash/apple-splash-1170-2532.png"
|
||||
media="(device-width: 390px) and (device-height: 844px) and (-webkit-device-pixel-ratio: 3) and (orientation: portrait)">
|
||||
<link rel="apple-touch-startup-image" href="/splash/apple-splash-2532-1170.png"
|
||||
media="(device-width: 390px) and (device-height: 844px) and (-webkit-device-pixel-ratio: 3) and (orientation: landscape)">
|
||||
<link rel="apple-touch-startup-image" href="/splash/apple-splash-1125-2436.png"
|
||||
media="(device-width: 375px) and (device-height: 812px) and (-webkit-device-pixel-ratio: 3) and (orientation: portrait)">
|
||||
<link rel="apple-touch-startup-image" href="/splash/apple-splash-2436-1125.png"
|
||||
media="(device-width: 375px) and (device-height: 812px) and (-webkit-device-pixel-ratio: 3) and (orientation: landscape)">
|
||||
<link rel="apple-touch-startup-image" href="/splash/apple-splash-1242-2688.png"
|
||||
media="(device-width: 414px) and (device-height: 896px) and (-webkit-device-pixel-ratio: 3) and (orientation: portrait)">
|
||||
<link rel="apple-touch-startup-image" href="/splash/apple-splash-2688-1242.png"
|
||||
media="(device-width: 414px) and (device-height: 896px) and (-webkit-device-pixel-ratio: 3) and (orientation: landscape)">
|
||||
<link rel="apple-touch-startup-image" href="/splash/apple-splash-828-1792.png"
|
||||
media="(device-width: 414px) and (device-height: 896px) and (-webkit-device-pixel-ratio: 2) and (orientation: portrait)">
|
||||
<link rel="apple-touch-startup-image" href="/splash/apple-splash-1792-828.png"
|
||||
media="(device-width: 414px) and (device-height: 896px) and (-webkit-device-pixel-ratio: 2) and (orientation: landscape)">
|
||||
<link rel="apple-touch-startup-image" href="/splash/apple-splash-1242-2208.png"
|
||||
media="(device-width: 414px) and (device-height: 736px) and (-webkit-device-pixel-ratio: 3) and (orientation: portrait)">
|
||||
<link rel="apple-touch-startup-image" href="/splash/apple-splash-2208-1242.png"
|
||||
media="(device-width: 414px) and (device-height: 736px) and (-webkit-device-pixel-ratio: 3) and (orientation: landscape)">
|
||||
<link rel="apple-touch-startup-image" href="/splash/apple-splash-750-1334.png"
|
||||
media="(device-width: 375px) and (device-height: 667px) and (-webkit-device-pixel-ratio: 2) and (orientation: portrait)">
|
||||
<link rel="apple-touch-startup-image" href="/splash/apple-splash-1334-750.png"
|
||||
media="(device-width: 375px) and (device-height: 667px) and (-webkit-device-pixel-ratio: 2) and (orientation: landscape)">
|
||||
<link rel="apple-touch-startup-image" href="/splash/apple-splash-640-1136.png"
|
||||
media="(device-width: 320px) and (device-height: 568px) and (-webkit-device-pixel-ratio: 2) and (orientation: portrait)">
|
||||
<link rel="apple-touch-startup-image" href="/splash/apple-splash-1136-640.png"
|
||||
media="(device-width: 320px) and (device-height: 568px) and (-webkit-device-pixel-ratio: 2) and (orientation: landscape)">
|
||||
<link rel="shortcut icon" href="/favicon.ico" type="image/x-icon">
|
||||
<link rel="manifest" href="/manifest.json" crossorigin="use-credentials">
|
||||
<meta name="mobile-web-app-capable" content="yes"/>
|
||||
<meta name="apple-mobile-web-app-capable" content="yes"/>
|
||||
<meta name="mobile-web-app-capable" content="yes" />
|
||||
<meta name="apple-mobile-web-app-capable" content="yes" />
|
||||
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent">
|
||||
<meta name="apple-mobile-web-app-title" content="NAStool">
|
||||
<meta name="description" content="MoviePilot">
|
||||
<meta name="format-detection" content="telephone=no">
|
||||
<meta name="referrer" content="never">
|
||||
<meta name="msapplication-TileColor" content="#F4F5FA"/>
|
||||
<meta name="theme-color" content="#28243D" media="(prefers-color-scheme: dark)">
|
||||
<meta name="theme-color" content="#F4F5FA" media="(prefers-color-scheme: light)">
|
||||
<meta name="HandheldFriendly" content="True"/>
|
||||
<meta name="MobileOptimized" content="320"/>
|
||||
<meta name="msapplication-TileColor" content="#F1F2F9" />
|
||||
<meta name="theme-color" content="#1E1A2E" media="(prefers-color-scheme: dark)">
|
||||
<meta name="theme-color" content="#F1F2F9" media="(prefers-color-scheme: light)">
|
||||
<meta name="HandheldFriendly" content="True" />
|
||||
<meta name="MobileOptimized" content="320" />
|
||||
<link rel="stylesheet" type="text/css" href="/loader.css" />
|
||||
</head>
|
||||
|
||||
@@ -93,4 +121,4 @@
|
||||
</script>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
</html>
|
||||
@@ -28,8 +28,8 @@
|
||||
"purpose": "maskable"
|
||||
}
|
||||
],
|
||||
"theme_color": "#28243D",
|
||||
"background_color": "#28243D",
|
||||
"theme_color": "#7D34FD",
|
||||
"background_color": "#1E1A2E",
|
||||
"display": "standalone",
|
||||
"shortcuts": [
|
||||
{
|
||||
@@ -77,4 +77,4 @@
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
@@ -54,7 +54,7 @@ $card-spacer-content: 16px;
|
||||
}
|
||||
|
||||
.bg-var-theme-background {
|
||||
background-color: rgba(var(--v-theme-on-background), var(--v-hover-opacity)) !important;
|
||||
background-color: rgba(var(--v-theme-background), var(--v-hover-opacity)) !important;
|
||||
}
|
||||
|
||||
// [/^bg-light-(\w+)$/, ([, w]) => ({ backgroundColor: `rgba(var(--v-theme-${w}), var(--v-activated-opacity))` })],
|
||||
|
||||
@@ -27,7 +27,6 @@ h6,
|
||||
color: rgba(var(--v-theme-on-background), var(--v-high-emphasis-opacity));
|
||||
}
|
||||
|
||||
.v-application,
|
||||
.text-body-1,
|
||||
.text-body-2,
|
||||
.text-subtitle-1,
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
|
||||
// If navbar is contained => Squeeze navbar content on scroll
|
||||
@if variables.$layout-vertical-nav-navbar-is-contained {
|
||||
padding-inline: 1.2rem;
|
||||
padding-inline: 1rem;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -27,7 +27,6 @@ h6,
|
||||
color: rgba(var(--v-theme-on-background), var(--v-high-emphasis-opacity));
|
||||
}
|
||||
|
||||
.v-application,
|
||||
.text-body-1,
|
||||
.text-body-2,
|
||||
.text-subtitle-1,
|
||||
|
||||
@@ -1,27 +1,27 @@
|
||||
<script lang="ts">
|
||||
import VerticalNav from '@layouts/components/VerticalNav.vue'
|
||||
import { useDisplay } from 'vuetify'
|
||||
import VerticalNav from "@layouts/components/VerticalNav.vue";
|
||||
import { useDisplay } from "vuetify";
|
||||
|
||||
export default defineComponent({
|
||||
setup(props, { slots }) {
|
||||
const isOverlayNavActive = ref(false)
|
||||
const isLayoutOverlayVisible = ref(false)
|
||||
const toggleIsOverlayNavActive = useToggle(isOverlayNavActive)
|
||||
const isOverlayNavActive = ref(false);
|
||||
const isLayoutOverlayVisible = ref(false);
|
||||
const toggleIsOverlayNavActive = useToggle(isOverlayNavActive);
|
||||
|
||||
const route = useRoute()
|
||||
const { mdAndDown } = useDisplay()
|
||||
const route = useRoute();
|
||||
const { mdAndDown } = useDisplay();
|
||||
|
||||
// ℹ️ This is alternative to below two commented watcher
|
||||
// We want to show overlay if overlay nav is visible and want to hide overlay if overlay is hidden and vice versa.
|
||||
syncRef(isOverlayNavActive, isLayoutOverlayVisible)
|
||||
syncRef(isOverlayNavActive, isLayoutOverlayVisible);
|
||||
|
||||
const scrollDistance = ref(window.scrollY)
|
||||
const scrollDistance = ref(window.scrollY);
|
||||
|
||||
onMounted(() => {
|
||||
window.addEventListener('scroll', () => {
|
||||
scrollDistance.value = window.scrollY
|
||||
})
|
||||
})
|
||||
window.addEventListener("scroll", () => {
|
||||
scrollDistance.value = window.scrollY;
|
||||
});
|
||||
});
|
||||
|
||||
return () => {
|
||||
// 👉 Vertical nav
|
||||
@@ -29,84 +29,63 @@ export default defineComponent({
|
||||
VerticalNav,
|
||||
{ isOverlayNavActive: isOverlayNavActive.value, toggleIsOverlayNavActive },
|
||||
{
|
||||
'nav-header': () => slots['vertical-nav-header']?.(),
|
||||
'before-nav-items': () => slots['before-vertical-nav-items']?.(),
|
||||
'default': () => slots['vertical-nav-content']?.(),
|
||||
'after-nav-items': () => slots['after-vertical-nav-items']?.(),
|
||||
},
|
||||
)
|
||||
"nav-header": () => slots["vertical-nav-header"]?.(),
|
||||
"before-nav-items": () => slots["before-vertical-nav-items"]?.(),
|
||||
default: () => slots["vertical-nav-content"]?.(),
|
||||
"after-nav-items": () => slots["after-vertical-nav-items"]?.(),
|
||||
}
|
||||
);
|
||||
|
||||
// 👉 Navbar
|
||||
const navbar = h(
|
||||
'header',
|
||||
{ class: ['layout-navbar navbar-blur'] },
|
||||
[
|
||||
h(
|
||||
'div',
|
||||
{ class: 'navbar-content-container' },
|
||||
slots.navbar?.({
|
||||
toggleVerticalOverlayNavActive: toggleIsOverlayNavActive,
|
||||
}),
|
||||
),
|
||||
],
|
||||
)
|
||||
const navbar = h("header", { class: ["layout-navbar navbar-blur"] }, [
|
||||
h(
|
||||
"div",
|
||||
{ class: "navbar-content-container" },
|
||||
slots.navbar?.({
|
||||
toggleVerticalOverlayNavActive: toggleIsOverlayNavActive,
|
||||
})
|
||||
),
|
||||
]);
|
||||
|
||||
const main = h(
|
||||
'main',
|
||||
{ class: 'layout-page-content' },
|
||||
h('div', { class: 'page-content-container' }, slots.default?.()),
|
||||
)
|
||||
"main",
|
||||
{ class: "layout-page-content" },
|
||||
h("div", { class: "page-content-container" }, slots.default?.())
|
||||
);
|
||||
|
||||
// 👉 Footer
|
||||
const footer = h(
|
||||
'footer',
|
||||
{ class: 'layout-footer' },
|
||||
[
|
||||
h(
|
||||
'div',
|
||||
{ class: 'footer-content-container' },
|
||||
slots.footer?.(),
|
||||
),
|
||||
],
|
||||
)
|
||||
const footer = h("footer", { class: "layout-footer" }, [
|
||||
h("div", { class: "footer-content-container" }, slots.footer?.()),
|
||||
]);
|
||||
|
||||
// 👉 Overlay
|
||||
const layoutOverlay = h(
|
||||
'div',
|
||||
{
|
||||
class: ['layout-overlay', { visible: isLayoutOverlayVisible.value }],
|
||||
onClick: () => { isLayoutOverlayVisible.value = !isLayoutOverlayVisible.value },
|
||||
const layoutOverlay = h("div", {
|
||||
class: ["layout-overlay", { visible: isLayoutOverlayVisible.value }],
|
||||
onClick: () => {
|
||||
isLayoutOverlayVisible.value = !isLayoutOverlayVisible.value;
|
||||
},
|
||||
)
|
||||
});
|
||||
|
||||
return h(
|
||||
'div',
|
||||
"div",
|
||||
{
|
||||
class: [
|
||||
'layout-wrapper layout-nav-type-vertical layout-navbar-static layout-footer-static layout-content-width-fluid',
|
||||
'layout-navbar-sticky',
|
||||
mdAndDown.value && 'layout-overlay-nav',
|
||||
"layout-wrapper layout-nav-type-vertical layout-navbar-static layout-footer-static layout-content-width-fluid",
|
||||
"layout-navbar-sticky",
|
||||
mdAndDown.value && "layout-overlay-nav",
|
||||
route.meta.layoutWrapperClasses,
|
||||
(scrollDistance.value > 20) && 'window-scrolled',
|
||||
scrollDistance.value > 20 && "window-scrolled",
|
||||
],
|
||||
},
|
||||
[
|
||||
verticalNav,
|
||||
h(
|
||||
'div',
|
||||
{ class: 'layout-content-wrapper' },
|
||||
[
|
||||
navbar,
|
||||
main,
|
||||
footer,
|
||||
],
|
||||
),
|
||||
h("div", { class: "layout-content-wrapper" }, [navbar, main, footer]),
|
||||
layoutOverlay,
|
||||
],
|
||||
)
|
||||
}
|
||||
]
|
||||
);
|
||||
};
|
||||
},
|
||||
})
|
||||
});
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
|
||||
@@ -5,11 +5,17 @@
|
||||
@use "@configured-variables" as variables;
|
||||
|
||||
html {
|
||||
min-height: calc(100% + env(safe-area-inset-top))
|
||||
min-height: calc(100% + env(safe-area-inset-top));
|
||||
}
|
||||
|
||||
body, #app {
|
||||
min-block-size: 100%;
|
||||
body,
|
||||
#app,
|
||||
.v-application {
|
||||
min-height: 100%;
|
||||
}
|
||||
|
||||
.layout-vertical-nav, .layout-navbar {
|
||||
padding-top: env(safe-area-inset-top);
|
||||
}
|
||||
|
||||
.layout-page-content {
|
||||
|
||||
@@ -7,4 +7,5 @@
|
||||
|
||||
html {
|
||||
box-sizing: border-box;
|
||||
min-height: calc(100% + env(safe-area-inset-top))
|
||||
}
|
||||
|
||||
@@ -17,7 +17,7 @@ import UserProfile from "@/layouts/components/UserProfile.vue";
|
||||
<template #navbar="{ toggleVerticalOverlayNavActive }">
|
||||
<div class="d-flex h-100 align-center">
|
||||
<!-- 👉 Vertical nav toggle in overlay mode -->
|
||||
<IconBtn class="ms-n3 d-lg-none" @click="toggleVerticalOverlayNavActive(true)">
|
||||
<IconBtn class="ms-n2 d-lg-none" @click="toggleVerticalOverlayNavActive(true)">
|
||||
<VIcon icon="mdi-menu" />
|
||||
</IconBtn>
|
||||
|
||||
@@ -29,7 +29,7 @@ import UserProfile from "@/layouts/components/UserProfile.vue";
|
||||
</IconBtn>
|
||||
|
||||
<span class="d-none d-md-flex align-center text-disabled">
|
||||
<span class="me-3">Search</span>
|
||||
<span class="me-3">搜索</span>
|
||||
<span class="meta-key">⌘K</span>
|
||||
</span>
|
||||
</div>
|
||||
|
||||
@@ -1,119 +1,111 @@
|
||||
<script setup lang="ts">
|
||||
import { requiredValidator } from '@/@validators';
|
||||
import api from '@/api';
|
||||
import router from '@/router';
|
||||
import logo from '@images/logo.svg?raw';
|
||||
import type { VForm } from 'vuetify/components/VForm';
|
||||
import { useStore } from 'vuex';
|
||||
import { requiredValidator } from "@/@validators";
|
||||
import api from "@/api";
|
||||
import router from "@/router";
|
||||
import logo from "@images/logo.svg?raw";
|
||||
import type { VForm } from "vuetify/components/VForm";
|
||||
import { useStore } from "vuex";
|
||||
|
||||
// Vuex Store
|
||||
const store = useStore()
|
||||
const store = useStore();
|
||||
|
||||
// 表单
|
||||
const form = ref({
|
||||
username: '',
|
||||
password: '',
|
||||
username: "",
|
||||
password: "",
|
||||
remember: true,
|
||||
})
|
||||
const refForm = ref<InstanceType<typeof VForm> | null>(null)
|
||||
});
|
||||
const refForm = ref<InstanceType<typeof VForm> | null>(null);
|
||||
|
||||
// 密码输入
|
||||
const isPasswordVisible = ref(false)
|
||||
const isPasswordVisible = ref(false);
|
||||
|
||||
// 错误信息
|
||||
const errorMessage = ref('')
|
||||
const errorMessage = ref("");
|
||||
|
||||
// 背景图片
|
||||
const backgroundImageUrl = ref('')
|
||||
const backgroundImageUrl = ref("");
|
||||
|
||||
// 获取背景图片
|
||||
const fetchBackgroundImage = async () => {
|
||||
api
|
||||
.get('/login/wallpaper')
|
||||
.get("/login/wallpaper")
|
||||
.then((response: any) => {
|
||||
backgroundImageUrl.value = response.message
|
||||
backgroundImageUrl.value = response.message;
|
||||
})
|
||||
.catch((error: any) => {
|
||||
console.log(error)
|
||||
})
|
||||
}
|
||||
console.log(error);
|
||||
});
|
||||
};
|
||||
|
||||
// 登录获取token事件
|
||||
const login = () => {
|
||||
errorMessage.value = ''
|
||||
errorMessage.value = "";
|
||||
// 进行表单校验
|
||||
if (!form.value.username || !form.value.password) {
|
||||
return
|
||||
return;
|
||||
}
|
||||
|
||||
// 用户名密码
|
||||
const formData = new FormData()
|
||||
const formData = new FormData();
|
||||
|
||||
formData.append('username', form.value.username)
|
||||
formData.append('password', form.value.password)
|
||||
formData.append("username", form.value.username);
|
||||
formData.append("password", form.value.password);
|
||||
|
||||
// 请求token
|
||||
api
|
||||
.post('/login/access-token', formData, {
|
||||
.post("/login/access-token", formData, {
|
||||
headers: {
|
||||
Accept: 'application/json', // 设置 Accept 类型
|
||||
Accept: "application/json", // 设置 Accept 类型
|
||||
},
|
||||
})
|
||||
.then((response: any) => {
|
||||
// 获取token
|
||||
const token = response.access_token
|
||||
const token = response.access_token;
|
||||
|
||||
// 更新token和remember状态到Vuex Store
|
||||
store.dispatch('auth/updateToken', token)
|
||||
store.dispatch('auth/updateRemember', form.value.remember)
|
||||
store.dispatch("auth/updateToken", token);
|
||||
store.dispatch("auth/updateRemember", form.value.remember);
|
||||
|
||||
// 跳转到首页
|
||||
router.push('/')
|
||||
router.push("/");
|
||||
})
|
||||
.catch((error: any) => {
|
||||
// 登录失败,显示错误提示
|
||||
if (!error.response)
|
||||
errorMessage.value = '登录失败,请检查网络连接'
|
||||
|
||||
if (!error.response) errorMessage.value = "登录失败,请检查网络连接";
|
||||
else if (error.response.status === 401)
|
||||
errorMessage.value = '登录失败,请检查用户名和密码是否正确'
|
||||
|
||||
errorMessage.value = "登录失败,请检查用户名和密码是否正确";
|
||||
else if (error.response.status === 403)
|
||||
errorMessage.value = '登录失败,您没有权限访问'
|
||||
|
||||
else if (error.response.status === 500)
|
||||
errorMessage.value = '登录失败,服务器错误'
|
||||
|
||||
errorMessage.value = "登录失败,您没有权限访问";
|
||||
else if (error.response.status === 500) errorMessage.value = "登录失败,服务器错误";
|
||||
else
|
||||
errorMessage.value = `登录失败 ${error.response.status},请检查用户名和密码是否正确`
|
||||
})
|
||||
}
|
||||
errorMessage.value = `登录失败 ${error.response.status},请检查用户名和密码是否正确`;
|
||||
});
|
||||
};
|
||||
|
||||
// 自动登录
|
||||
onMounted(() => {
|
||||
// 从Vuex Store中获取token和remember状态
|
||||
const token = store.state.auth.token
|
||||
const remember = store.state.auth.remember
|
||||
const token = store.state.auth.token;
|
||||
const remember = store.state.auth.remember;
|
||||
|
||||
// 如果token存在,且保持登录状态为true,则跳转到首页
|
||||
if (token && remember) {
|
||||
router.push('/')
|
||||
router.push("/");
|
||||
} else {
|
||||
// 获取背景图片
|
||||
fetchBackgroundImage();
|
||||
}
|
||||
else {
|
||||
// 获取背景图片
|
||||
fetchBackgroundImage()
|
||||
}
|
||||
},
|
||||
)
|
||||
});
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div
|
||||
class="auth-wrapper d-flex align-center justify-center pa-4 fade-in"
|
||||
class="auth-wrapper d-flex align-center justify-center pa-4 fade-in w-full h-full overflow-hidden"
|
||||
:style="{ backgroundImage: `url(${backgroundImageUrl})` }"
|
||||
>
|
||||
<VCard class="auth-card pa-7">
|
||||
<VCardItem class="justify-center">
|
||||
<VCard class="auth-card pa-7" width="25rem">
|
||||
<VCardItem class="justify-center mb-7">
|
||||
<template #prepend>
|
||||
<div class="d-flex">
|
||||
<div v-html="logo" />
|
||||
@@ -125,17 +117,8 @@ onMounted(() => {
|
||||
</VCardTitle>
|
||||
</VCardItem>
|
||||
|
||||
<VCardText class="pt-2">
|
||||
<h5 class="text-h5 font-weight-semibold mb-1">
|
||||
欢迎使用 MoviePilot! 👋🏻
|
||||
</h5>
|
||||
<p class="mb-0">
|
||||
请输入用户名密码登录
|
||||
</p>
|
||||
</VCardText>
|
||||
|
||||
<VCardText>
|
||||
<VForm @submit.prevent="()=>{}" ref="refForm">
|
||||
<VForm @submit.prevent="() => {}" ref="refForm">
|
||||
<VRow>
|
||||
<!-- username -->
|
||||
<VCol cols="12">
|
||||
@@ -160,30 +143,17 @@ onMounted(() => {
|
||||
@click:append-inner="isPasswordVisible = !isPasswordVisible"
|
||||
/>
|
||||
|
||||
<div
|
||||
v-if="errorMessage"
|
||||
class="text-error mt-1"
|
||||
>
|
||||
<div v-if="errorMessage" class="text-error mt-1">
|
||||
{{ errorMessage }}
|
||||
</div>
|
||||
|
||||
<!-- remember me checkbox -->
|
||||
<div class="d-flex align-center justify-space-between flex-wrap mt-1 mb-4">
|
||||
<VCheckbox
|
||||
v-model="form.remember"
|
||||
label="保持登录"
|
||||
required
|
||||
/>
|
||||
<VCheckbox v-model="form.remember" label="保持登录" required />
|
||||
</div>
|
||||
|
||||
<!-- login button -->
|
||||
<VBtn
|
||||
block
|
||||
type="submit"
|
||||
@click="login"
|
||||
>
|
||||
登录
|
||||
</VBtn>
|
||||
<VBtn block type="submit" @click="login"> 登录 </VBtn>
|
||||
</VCol>
|
||||
</VRow>
|
||||
</VForm>
|
||||
|
||||
@@ -27,7 +27,7 @@ export default defineConfig({
|
||||
imports: ['vue', 'vue-router', '@vueuse/core', '@vueuse/math', 'vuex'],
|
||||
vueTemplate: true,
|
||||
}),
|
||||
VitePWA({ registerType: 'autoUpdate', injectRegister: 'auto', srcDir: 'public' }),
|
||||
VitePWA({ registerType: 'autoUpdate', injectRegister: 'auto', srcDir: 'public'}),
|
||||
],
|
||||
define: { 'process.env': {} },
|
||||
resolve: {
|
||||
|
||||
Reference in New Issue
Block a user