mirror of
https://github.com/jellyfin/jellyfin-vue.git
synced 2024-12-04 12:23:29 +00:00
chore(vite): switch to Vue 3
This commit is contained in:
parent
0232a3f1f3
commit
e515e20cfb
@ -2,8 +2,7 @@
|
||||
<html lang="en">
|
||||
<head>
|
||||
<style>
|
||||
body > .splashLogo,
|
||||
html > .splashLogo {
|
||||
html > body > div#app > div.splashLogo {
|
||||
background: #111827;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
@ -18,7 +17,7 @@
|
||||
width: 30%;
|
||||
height: 30%;
|
||||
/* This file is in the 'static' folder, so it will be placed at the root when the client is built */
|
||||
background-image: url(/icon.png);
|
||||
background-image: url(icon.png);
|
||||
background-position: center center;
|
||||
background-repeat: no-repeat;
|
||||
background-size: contain;
|
||||
@ -26,13 +25,16 @@
|
||||
</style>
|
||||
<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, minimum-scale=1, maximum-scale=1, user-scalable=no, viewport-fit=cover"
|
||||
/>
|
||||
<title>Jellyfin</title>
|
||||
<script type="module" src="/src/main.ts"></script>
|
||||
</head>
|
||||
<body>
|
||||
<div id="app">
|
||||
<div class="splashLogo"></div>
|
||||
</div>
|
||||
<script type="module" src="/src/main.ts"></script>
|
||||
</body>
|
||||
</html>
|
||||
|
@ -28,6 +28,7 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"@jellyfin/client-axios": "10.7.8",
|
||||
"@vueuse/components": "9.2.0",
|
||||
"@vueuse/core": "9.2.0",
|
||||
"axios": "0.27.2",
|
||||
"blurhash": "1.1.5",
|
||||
@ -41,17 +42,12 @@
|
||||
"pinia": "2.0.14",
|
||||
"screenfull": "6.0.1",
|
||||
"shaka-player": "4.1.1",
|
||||
"simple-icons": "7.4.0",
|
||||
"swiper": "5.x",
|
||||
"swiper": "8.3.2",
|
||||
"uuid": "8.3.2",
|
||||
"vee-validate": "3.4.14",
|
||||
"vue": "2.7.10",
|
||||
"vue-awesome-swiper": "4.1.1",
|
||||
"vue-i18n": "8.27.2",
|
||||
"vue-router": "3.6.5",
|
||||
"vue-virtual-scroller": "1.0.10",
|
||||
"vuedraggable": "2.24.3",
|
||||
"vuetify": "2.6.9"
|
||||
"vee-validate": "4.6.7",
|
||||
"vue": "3.2.39",
|
||||
"vue-i18n": "9.2.2",
|
||||
"vue-router": "4.1.5"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@iconify/json": "2.1.104",
|
||||
@ -62,6 +58,7 @@
|
||||
"@types/swiper": "5.4.3",
|
||||
"@types/tizen-tv-webapis": "2.0.1",
|
||||
"@types/uuid": "8.3.4",
|
||||
"@vitejs/plugin-vue": "3.1.0",
|
||||
"confusing-browser-globals": "1.0.11",
|
||||
"sass": "1.54.9",
|
||||
"typescript": "4.8.2",
|
||||
@ -71,7 +68,7 @@
|
||||
"vite-plugin-pages": "0.26.0",
|
||||
"vite-plugin-pwa": "0.12.7",
|
||||
"vite-plugin-vue-layouts": "0.7.0",
|
||||
"vite-plugin-vue2": "2.0.2",
|
||||
"vite-plugin-vuetify": "1.0.0-alpha.16",
|
||||
"vue-i18n-extract": "2.0.7",
|
||||
"vue-tsc": "0.34.16"
|
||||
},
|
||||
|
@ -1,5 +1,3 @@
|
||||
@import '~vuetify/src/styles/styles.sass';
|
||||
|
||||
.default-icon {
|
||||
display: flex;
|
||||
align-content: center;
|
||||
|
@ -1,6 +1,6 @@
|
||||
<script lang="ts">
|
||||
import Vue from 'vue';
|
||||
import { VDialog } from 'vuetify/lib';
|
||||
import { VDialog } from 'vuetify/components';
|
||||
// @ts-expect-error - These typings are not declared
|
||||
import { keyCodes } from 'vuetify/lib/util/helpers';
|
||||
|
||||
|
@ -19,7 +19,7 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import RouteLocationNormalized from 'vue-router';
|
||||
import { RouteLocationNormalized } from 'vue-router';
|
||||
|
||||
interface Props {
|
||||
/**
|
||||
@ -39,8 +39,8 @@ const props = withDefaults(defineProps<Props>(), {
|
||||
|
||||
function getKey(route: RouteLocationNormalized) {
|
||||
if (props.isRoot) {
|
||||
return String(route.currentRoute.meta?.layout) || 'default';
|
||||
return String(route.meta.layout) || 'default';
|
||||
}
|
||||
return String(route.currentRoute.name);
|
||||
return String(route.name);
|
||||
}
|
||||
</script>
|
||||
|
@ -1,31 +1,15 @@
|
||||
import { createPinia, PiniaVuePlugin } from 'pinia';
|
||||
import Vue from 'vue';
|
||||
import { createPinia } from 'pinia';
|
||||
import { createApp } from 'vue';
|
||||
/**
|
||||
* Main imports
|
||||
*/
|
||||
import App from '@/App.vue';
|
||||
import Root from '@/App.vue';
|
||||
import router from '@/plugins/vue/router';
|
||||
import {
|
||||
messages,
|
||||
DEFAULT_LANGUAGE,
|
||||
BROWSER_LANGUAGE
|
||||
} from '@/plugins/vue/i18n';
|
||||
import i18n from '@/plugins/vue/i18n';
|
||||
import vuetify from '@/plugins/vue/vuetify';
|
||||
import { hideDirective } from '@/plugins/vue/directives';
|
||||
import piniaPlugins from '@/plugins/store';
|
||||
import axiosInstance from '@/plugins/axios';
|
||||
import Vuetify from 'vuetify/lib';
|
||||
import VueRouter from 'vue-router';
|
||||
import VueI18n from 'vue-i18n';
|
||||
/**
|
||||
* Component imports
|
||||
*/
|
||||
import { ValidationProvider, ValidationObserver } from 'vee-validate';
|
||||
import draggable from 'vuedraggable';
|
||||
// @ts-expect-error - target typing doesn't exist as we declared it in params.
|
||||
import { DynamicScroller, DynamicScrollerItem } from 'vue-virtual-scroller';
|
||||
import 'vue-virtual-scroller/dist/vue-virtual-scroller.css';
|
||||
import VueAwesomeSwiper from 'vue-awesome-swiper';
|
||||
import 'swiper/css/swiper.css';
|
||||
/**
|
||||
* CSS Imports
|
||||
*/
|
||||
@ -40,60 +24,18 @@ const pinia = createPinia();
|
||||
pinia.use(piniaPlugins);
|
||||
|
||||
/**
|
||||
* Vue global config
|
||||
* App initialization
|
||||
*/
|
||||
Vue.config.performance = true;
|
||||
const app = createApp(Root);
|
||||
|
||||
/**
|
||||
* Vue.use statements
|
||||
*
|
||||
* TODO: This can be removed in Vue 3. We need to merge all these statements in this file because if we don't do this, we're creating multiple
|
||||
* Vue instances.
|
||||
*/
|
||||
Vue.use(Vuetify);
|
||||
Vue.use(PiniaVuePlugin);
|
||||
Vue.use(VueRouter);
|
||||
Vue.use(VueI18n);
|
||||
// Components
|
||||
Vue.use(VueAwesomeSwiper);
|
||||
Vue.component('ValidationProvider', ValidationProvider);
|
||||
Vue.component('ValidationObserver', ValidationObserver);
|
||||
Vue.component('Draggable', draggable);
|
||||
Vue.component('DynamicScroller', DynamicScroller);
|
||||
Vue.component('DynamicScrollerItem', DynamicScrollerItem);
|
||||
|
||||
const i18n = new VueI18n({
|
||||
locale: Object.keys(messages).includes(BROWSER_LANGUAGE)
|
||||
? BROWSER_LANGUAGE
|
||||
: DEFAULT_LANGUAGE,
|
||||
fallbackLocale: DEFAULT_LANGUAGE,
|
||||
messages
|
||||
});
|
||||
app.use(router);
|
||||
app.use(pinia);
|
||||
app.use(vuetify);
|
||||
app.use(i18n);
|
||||
|
||||
/**
|
||||
* Vue directives
|
||||
*/
|
||||
app.directive('hide', hideDirective);
|
||||
|
||||
// Toggles the CSS 'visibility' property of an element.
|
||||
Vue.directive('hide', (el, binding) => {
|
||||
if (el) {
|
||||
if (binding.value === true) {
|
||||
el.style.visibility = 'hidden';
|
||||
} else {
|
||||
el.style.visibility = 'visible';
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* App initialization
|
||||
*/
|
||||
const app = new Vue({
|
||||
router,
|
||||
pinia,
|
||||
vuetify,
|
||||
i18n,
|
||||
render: (h) => h(App)
|
||||
});
|
||||
Vue.prototype.$axios = axiosInstance;
|
||||
app.$mount('#app');
|
||||
app.mount('#app');
|
||||
|
17
frontend/src/plugins/vue/directives.ts
Normal file
17
frontend/src/plugins/vue/directives.ts
Normal file
@ -0,0 +1,17 @@
|
||||
import Vue from 'vue';
|
||||
|
||||
/**
|
||||
* Toggles the CSS 'visibility' property of an element.
|
||||
*/
|
||||
export function hideDirective(
|
||||
el: HTMLElement,
|
||||
binding: Vue.DirectiveBinding<any>
|
||||
) {
|
||||
if (el) {
|
||||
if (binding.value === true) {
|
||||
el.style.visibility = 'hidden';
|
||||
} else {
|
||||
el.style.visibility = 'visible';
|
||||
}
|
||||
}
|
||||
}
|
@ -1,10 +1,10 @@
|
||||
import VueI18n from 'vue-i18n';
|
||||
import { createI18n } from 'vue-i18n';
|
||||
|
||||
export const DEFAULT_LANGUAGE = 'en';
|
||||
export const BROWSER_LANGUAGE = navigator?.language?.split('-')[0];
|
||||
const DEFAULT_LANGUAGE = 'en';
|
||||
const BROWSER_LANGUAGE = navigator?.language?.split('-')[0];
|
||||
|
||||
function getMessages() {
|
||||
const messages: VueI18n.LocaleMessages = {};
|
||||
const messages: any = {};
|
||||
// See: https://vitejs.dev/guide/features.html#glob-import
|
||||
const localeFiles = import.meta.glob('../../locales/*.json');
|
||||
for (const path in localeFiles) {
|
||||
@ -19,4 +19,14 @@ function getMessages() {
|
||||
return messages;
|
||||
}
|
||||
|
||||
export const messages = getMessages();
|
||||
const messages = getMessages();
|
||||
const i18n = createI18n({
|
||||
locale: Object.keys(messages).includes(BROWSER_LANGUAGE)
|
||||
? BROWSER_LANGUAGE
|
||||
: DEFAULT_LANGUAGE,
|
||||
fallbackLocale: DEFAULT_LANGUAGE,
|
||||
legacy: true, // Enables $t(), $tc(), etc in templates
|
||||
messages
|
||||
});
|
||||
|
||||
export default i18n;
|
||||
|
@ -1,9 +1,9 @@
|
||||
import VueRouter from 'vue-router';
|
||||
import { createRouter, createWebHistory } from 'vue-router';
|
||||
import { setupLayouts } from 'virtual:generated-layouts';
|
||||
import generatedRoutes from '~pages';
|
||||
|
||||
const router = new VueRouter({
|
||||
fallback: true,
|
||||
const router = createRouter({
|
||||
history: createWebHistory(),
|
||||
routes: setupLayouts(generatedRoutes)
|
||||
});
|
||||
|
||||
|
@ -1,11 +1,8 @@
|
||||
/** Vuetify Plugin */
|
||||
import type { UserVuetifyPreset } from 'vuetify';
|
||||
import variables from '@/assets/styles/variables.scss';
|
||||
import Vuetify from 'vuetify';
|
||||
import { createVuetify } from 'vuetify';
|
||||
|
||||
export default createVuetify({
|
||||
customVariables: [variables],
|
||||
treeShake: true,
|
||||
defaultAssets: false,
|
||||
theme: {
|
||||
dark: true,
|
||||
@ -13,6 +10,7 @@ export default createVuetify({
|
||||
disable: false,
|
||||
themes: {
|
||||
dark: {
|
||||
name: 'dark',
|
||||
primary: '#9d37c2',
|
||||
secondary: '#2f3951',
|
||||
accent: '#FF4081',
|
||||
@ -42,8 +40,3 @@ export default createVuetify({
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
/** Create Vuetify */
|
||||
export function createVuetify(options: UserVuetifyPreset): Vuetify {
|
||||
return new Vuetify(options);
|
||||
}
|
||||
|
@ -28,8 +28,5 @@
|
||||
"vue"
|
||||
]
|
||||
},
|
||||
"vueCompilerOptions": {
|
||||
"target": 2.7
|
||||
},
|
||||
"include": ["src/**/*.ts", "src/**/*.d.ts", "src/**/*.vue", "./*.d.ts"]
|
||||
}
|
||||
|
@ -1,12 +1,15 @@
|
||||
import { defineConfig } from 'vite';
|
||||
import { createVuePlugin } from 'vite-plugin-vue2';
|
||||
import vue from '@vitejs/plugin-vue';
|
||||
import path from 'path';
|
||||
import Pages from 'vite-plugin-pages';
|
||||
import Layouts from 'vite-plugin-vue-layouts';
|
||||
import Icons from 'unplugin-icons/vite';
|
||||
import IconsResolver from 'unplugin-icons/resolver';
|
||||
import Components from 'unplugin-vue-components/vite';
|
||||
import { VuetifyResolver } from 'unplugin-vue-components/resolvers';
|
||||
import {
|
||||
Vuetify3Resolver,
|
||||
VueUseComponentsResolver
|
||||
} from 'unplugin-vue-components/resolvers';
|
||||
import { VitePWA } from 'vite-plugin-pwa';
|
||||
|
||||
// https://vitejs.dev/config/
|
||||
@ -20,7 +23,7 @@ export default defineConfig({
|
||||
)
|
||||
},
|
||||
plugins: [
|
||||
createVuePlugin(),
|
||||
vue(),
|
||||
Pages({
|
||||
routeStyle: 'nuxt'
|
||||
}),
|
||||
@ -31,27 +34,21 @@ export default defineConfig({
|
||||
* The icons resolver finds icons components from 'unplugin-icons' using this convenction:
|
||||
* {prefix}-{collection}-{icon} e.g. <i-mdi-thumb-up />
|
||||
*/
|
||||
resolvers: [IconsResolver(), VuetifyResolver()]
|
||||
resolvers: [
|
||||
IconsResolver(),
|
||||
Vuetify3Resolver(),
|
||||
VueUseComponentsResolver()
|
||||
]
|
||||
}),
|
||||
/**
|
||||
* This plugin allows to use all icons from Iconify as vue components
|
||||
* See: https://github.com/antfu/unplugin-icons
|
||||
*/
|
||||
Icons({
|
||||
compiler: 'vue2'
|
||||
compiler: 'vue3'
|
||||
}),
|
||||
VitePWA()
|
||||
],
|
||||
/**
|
||||
* Import Vuetify SASS variables so they're available globally, even in scoped CSS
|
||||
*/
|
||||
css: {
|
||||
preprocessorOptions: {
|
||||
scss: {
|
||||
additionalData: "\n@import 'vuetify/src/styles/styles.sass';\n"
|
||||
}
|
||||
}
|
||||
},
|
||||
resolve: {
|
||||
alias: {
|
||||
'@/': `${path.resolve(__dirname, './src')}/`,
|
||||
|
1261
package-lock.json
generated
1261
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user