Compare commits

..

25 Commits

Author SHA1 Message Date
jxxghp
556dbd8d78 fix bug 2024-02-08 20:07:23 +08:00
jxxghp
6695fd8c14 add ace-editor 2024-02-08 19:56:28 +08:00
jxxghp
3ab0229275 fix ui 2024-02-08 13:43:37 +08:00
jxxghp
99467127a0 更新 package.json 2024-02-08 13:28:11 +08:00
jxxghp
90d73b7bd5 Merge pull request #73 from cikezhu/main 2024-02-08 13:27:40 +08:00
叮叮当
2e326e1798 fix 全部日志url反向代理时被serviceWorker拦截 2024-02-08 12:45:52 +08:00
jxxghp
251eac93c7 更新 package.json 2024-02-08 07:11:49 +08:00
jxxghp
c74d70808c Merge pull request #72 from cikezhu/main 2024-02-08 07:10:48 +08:00
叮叮当
e63b2d7152 新窗口打开全部日志 2024-02-08 00:06:52 +08:00
jxxghp
16b29b56a5 更新 package.json 2024-01-29 23:11:57 +08:00
jxxghp
6d79c4fe2f Merge pull request #71 from cikezhu/main 2024-01-29 23:11:34 +08:00
叮叮当
4b1fb60ee3 fix 媒体信息页面person跳转问题 2024-01-29 23:01:22 +08:00
jxxghp
1d2be54f9e 更新 package.json 2024-01-29 11:05:38 +08:00
jxxghp
83547e32db Merge pull request #70 from cikezhu/main 2024-01-29 11:05:10 +08:00
叮叮当
70ddb929f2 fix plugin_icon 2024-01-28 00:47:37 +08:00
叮叮当
8b22961394 支持基于路径的反向代理 2024-01-27 14:47:00 +08:00
jxxghp
c15d42c179 Merge pull request #69 from falling/main 2024-01-24 18:43:37 +08:00
falling
098e473cab 从qbt后台的返回值来更新下载状态 2024-01-21 19:48:47 +08:00
jxxghp
f6f3d9368a fix bug 2024-01-08 13:22:42 +08:00
jxxghp
9558a420e9 fix image proxy 2024-01-08 12:25:06 +08:00
jxxghp
4d3b69ca34 更新 package.json 2024-01-08 11:33:32 +08:00
jxxghp
fdcc4a44c8 Merge pull request #68 from jjjokin/feat-auto-switch-theme 2024-01-08 11:01:26 +08:00
jokin
5de0494538 增加主题自适应选项 2024-01-07 22:17:11 +08:00
jxxghp
2045f833e4 fix bug 2024-01-06 11:07:23 +08:00
jxxghp
cc4f89aac1 fix 2024-01-06 11:02:03 +08:00
20 changed files with 161 additions and 33 deletions

View File

@@ -1 +1 @@
VITE_API_BASE_URL=/api/v1/
VITE_API_BASE_URL=api/v1/

View File

@@ -1,6 +1,6 @@
{
"name": "moviepilot",
"version": "1.5.7-3",
"version": "1.6.1-3",
"private": true,
"bin": "dist/service.js",
"scripts": {
@@ -24,6 +24,7 @@
"@floating-ui/dom": "1.2.8",
"@vueuse/core": "^10.1.2",
"@vueuse/math": "^10.1.2",
"ace-builds": "^1.32.6",
"apexcharts-clevision": "^3.28.5",
"axios": "1.4.0",
"axios-mock-adapter": "^1.21.4",
@@ -48,6 +49,7 @@
"vue-prism-component": "^2.0.0",
"vue-router": "^4.2.0",
"vue-toast-notification": "^3",
"vue3-ace-editor": "^2.2.4",
"vue3-apexcharts": "^1.4.1",
"vue3-perfect-scrollbar": "^1.6.0",
"vuetify": "3.3.5",

View File

@@ -1,5 +1,5 @@
<script setup lang="ts">
import { ref, watch } from 'vue'
import { ref } from 'vue'
import { useTheme } from 'vuetify'
import type { ThemeSwitcherTheme } from '@layouts/types'
@@ -20,26 +20,30 @@ const {
{ initialValue: savedTheme.value },
)
function changeTheme() {
const nextTheme = getNextThemeName()
globalTheme.name.value = nextTheme
savedTheme.value = nextTheme
localStorage.setItem('theme', nextTheme)
function updateTheme() {
const autoTheme = window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light'
const theme = currentThemeName.value === 'auto' ? autoTheme : currentThemeName.value
globalTheme.name.value = theme
savedTheme.value = theme
// 修改载入时背景色
localStorage.setItem('materio-initial-loader-bg', globalTheme.current.value.colors.background)
themeTransition()
}
// Update icon if theme is changed from other sources
// 监听系统主题变化
window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', updateTheme)
watch(
() => globalTheme.name.value,
(val) => {
currentThemeName.value = val
},
() => currentThemeName.value,
() => updateTheme(),
)
function changeTheme() {
const nextTheme = getNextThemeName()
currentThemeName.value = nextTheme
localStorage.setItem('theme', nextTheme)
}
// Apply saved theme on page load
// onMounted(() => {
// globalTheme.name.value = savedTheme.value

View File

@@ -3,9 +3,15 @@ import { useToast } from 'vue-toast-notification'
import { useTheme } from 'vuetify'
import store from './store'
function setTheme() {
const { global: globalTheme } = useTheme()
let theme = localStorage.getItem('theme') || 'light'
if (theme === 'auto')
theme = window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light'
globalTheme.name.value = theme
}
// 第一时间应用主题
const { global: globalTheme } = useTheme()
globalTheme.name.value = localStorage.getItem('theme') || 'light'
setTheme()
// 提示框
const $toast = useToast()

54
src/ace-config.ts Normal file
View File

@@ -0,0 +1,54 @@
import ace from 'ace-builds'
import modeJsonUrl from 'ace-builds/src-noconflict/mode-json?url'
import modeJavascriptUrl from 'ace-builds/src-noconflict/mode-javascript?url'
import modeHtmlUrl from 'ace-builds/src-noconflict/mode-html?url'
import modeYamlUrl from 'ace-builds/src-noconflict/mode-yaml?url'
import themeGithubUrl from 'ace-builds/src-noconflict/theme-github?url'
import themeChromeUrl from 'ace-builds/src-noconflict/theme-chrome?url'
import themeMonokaiUrl from 'ace-builds/src-noconflict/theme-monokai?url'
import workerBaseUrl from 'ace-builds/src-noconflict/worker-base?url'
import workerJsonUrl from 'ace-builds/src-noconflict/worker-json?url'
import workerJavascriptUrl from 'ace-builds/src-noconflict/worker-javascript?url'
import workerHtmlUrl from 'ace-builds/src-noconflict/worker-html?url'
import workerYamlUrl from 'ace-builds/src-noconflict/worker-yaml?url'
import snippetsHtmlUrl from 'ace-builds/src-noconflict/snippets/html?url'
import snippetsJsUrl from 'ace-builds/src-noconflict/snippets/javascript?url'
import snippetsYamlUrl from 'ace-builds/src-noconflict/snippets/yaml?url'
import snippetsJsonUrl from 'ace-builds/src-noconflict/snippets/json?url'
import 'ace-builds/src-noconflict/ext-language_tools'
ace.config.setModuleUrl('ace/mode/json', modeJsonUrl)
ace.config.setModuleUrl('ace/mode/javascript', modeJavascriptUrl)
ace.config.setModuleUrl('ace/mode/html', modeHtmlUrl)
ace.config.setModuleUrl('ace/mode/yaml', modeYamlUrl)
ace.config.setModuleUrl('ace/theme/github', themeGithubUrl)
ace.config.setModuleUrl('ace/theme/chrome', themeChromeUrl)
ace.config.setModuleUrl('ace/theme/monokai', themeMonokaiUrl)
ace.config.setModuleUrl('ace/mode/base', workerBaseUrl)
ace.config.setModuleUrl('ace/mode/json_worker', workerJsonUrl)
ace.config.setModuleUrl('ace/mode/javascript_worker', workerJavascriptUrl)
ace.config.setModuleUrl('ace/mode/html_worker', workerHtmlUrl)
ace.config.setModuleUrl('ace/mode/yaml_worker', workerYamlUrl)
ace.config.setModuleUrl('ace/snippets/html', snippetsHtmlUrl)
ace.config.setModuleUrl('ace/snippets/javascript', snippetsJsUrl)
ace.config.setModuleUrl('ace/snippets/javascript', snippetsYamlUrl)
ace.config.setModuleUrl('ace/snippets/json', snippetsJsonUrl)
ace.require('ace/ext/language_tools')

View File

@@ -25,7 +25,7 @@ function goPlay() {
// 计算图片地址
const getImgUrl = computed(() => {
const image = props.media?.image || ''
return `${import.meta.env.VITE_API_BASE_URL}system/img/${encodeURIComponent(image)}`
return `${import.meta.env.VITE_API_BASE_URL}system/img/${encodeURIComponent(image)}/0`
})
</script>

View File

@@ -23,6 +23,11 @@ function getSpeedText() {
// 下载状态
const isDownloading = ref(props.info?.state === 'downloading')
// 监听props.info?.state的变化
watch(() => props.info?.state, (newValue) => {
isDownloading.value = newValue === 'downloading';
});
// 图片是否加载完成
const imageLoaded = ref(false)

View File

@@ -56,7 +56,7 @@ function getImgUrl(url: string) {
if (!url)
return getDefaultImage()
else
return `${import.meta.env.VITE_API_BASE_URL}system/proxy?url=${encodeURIComponent(url)}`
return `${import.meta.env.VITE_API_BASE_URL}system/img/${encodeURIComponent(url)}/0`
}
// 根据多张图片生成媒体库封面
@@ -68,7 +68,7 @@ async function drawImages(imageList: string[]) {
// 为所有图片添加system/img前缀
for (let i = 0; i < IMAGES.length; i++)
IMAGES[i] = `${import.meta.env.VITE_API_BASE_URL}system/img/${encodeURIComponent(IMAGES[i])}`
IMAGES[i] = `${import.meta.env.VITE_API_BASE_URL}system/img/${encodeURIComponent(IMAGES[i])}/0`
// canvas
const canvas = canvasRef.value

View File

@@ -85,9 +85,9 @@ const iconPath: Ref<string> = computed(() => {
return noImage
// 如果是网络图片则使用代理后返回
if (props.plugin?.plugin_icon?.startsWith('http'))
return `${import.meta.env.VITE_API_BASE_URL}system/img/${encodeURIComponent(props.plugin?.plugin_icon)}`
return `${import.meta.env.VITE_API_BASE_URL}system/img/${encodeURIComponent(props.plugin?.plugin_icon)}/1`
return `/plugin_icon/${props.plugin?.plugin_icon}`
return `./plugin_icon/${props.plugin?.plugin_icon}`
})
// 访问插件页面

View File

@@ -181,9 +181,9 @@ const iconPath: Ref<string> = computed(() => {
return noImage
// 如果是网络图片则使用代理后返回
if (props.plugin?.plugin_icon?.startsWith('http'))
return `${import.meta.env.VITE_API_BASE_URL}system/img/${encodeURIComponent(props.plugin?.plugin_icon)}`
return `${import.meta.env.VITE_API_BASE_URL}system/img/${encodeURIComponent(props.plugin?.plugin_icon)}/1`
return `/plugin_icon/${props.plugin?.plugin_icon}`
return `./plugin_icon/${props.plugin?.plugin_icon}`
})
// 重置插件

View File

@@ -31,7 +31,7 @@ const getImgUrl = computed(() => {
if (imageLoadError.value)
return noImage
const image = props.media?.image || ''
return `${import.meta.env.VITE_API_BASE_URL}system/img/${encodeURIComponent(image)}`
return `${import.meta.env.VITE_API_BASE_URL}system/img/${encodeURIComponent(image)}/0`
})
// 跳转播放

View File

@@ -326,7 +326,6 @@ watchEffect(() => {
<VRow>
<VCol
cols="12"
md="4"
>
<VTextField
v-model="subscribeForm.save_path"

View File

@@ -35,12 +35,14 @@ const formData = ref<any>(elementProps.form || {})
v-if="!formItem.html"
v-bind="formItem.props"
v-model="formData[formItem.props?.model || '']"
v-model:value="formData[formItem.props?.modelvalue]"
>
{{ formItem.text }}
<FormRender
v-for="(innerItem, innerIndex) in (formItem.content || [])"
:key="innerIndex"
v-model="formData[innerItem.props?.model || '']"
v-model:value="formData[formItem.props?.modelvalue]"
:config="innerItem"
:form="formData"
/>

View File

@@ -14,6 +14,10 @@ const themes: ThemeSwitcherTheme[] = [
name: 'purple',
icon: 'mdi-brightness-4',
},
{
name: 'auto',
icon: 'mdi-brightness-auto',
},
]
</script>

View File

@@ -3,6 +3,7 @@ import NameTestView from '@/views/system/NameTestView.vue'
import NetTestView from '@/views/system/NetTestView.vue'
import LoggingView from '@/views/system/LoggingView.vue'
import RuleTestView from '@/views/system/RuleTestView.vue'
import store from '@/store'
// App捷径
const appsMenu = ref(false)
@@ -18,6 +19,12 @@ const loggingDialog = ref(false)
// 过滤规则弹窗
const ruleTestDialog = ref(false)
// 拼接全部日志url
function allLoggingUrl() {
const token = store.state.auth.token
return `${import.meta.env.VITE_API_BASE_URL}system/logging?token=${token}&length=-1`
}
</script>
<template>
@@ -171,8 +178,19 @@ const ruleTestDialog = ref(false)
class="w-full lg:w-4/5"
scrollable
>
<VCard title="实时日志">
<VCard>
<DialogCloseBtn @click="loggingDialog = false" />
<VCardItem>
<VCardTitle class="inline-flex">
实时日志
<a class="mx-2 inline-flex items-center justify-center" :href="allLoggingUrl()" target="_blank">
<div class="inline-flex cursor-pointer items-center rounded-full bg-gray-600 px-2 text-sm text-gray-200 ring-1 ring-gray-500 transition hover:bg-gray-700">
<VIcon icon="mdi-open-in-new" />
<span class="ms-1">在新窗口中打开</span>
</div>
</a>
</VCardTitle>
</VCardItem>
<VCardText>
<LoggingView />
</VCardText>

View File

@@ -1,7 +1,9 @@
import { VAceEditor } from 'vue3-ace-editor'
import { createApp } from 'vue'
import '@/@iconify/icons-bundle'
import ToastPlugin from 'vue-toast-notification'
import VuetifyUseDialog from 'vuetify-use-dialog'
import './ace-config'
import { removeEl } from './@core/utils/dom'
import App from '@/App.vue'
import vuetify from '@/plugins/vuetify'
@@ -15,10 +17,13 @@ import 'vue-toast-notification/dist/theme-bootstrap.css'
loadFonts()
// Create vue app
// 创建Vue实例
const app = createApp(App)
// Use plugins Mount vue app
// 注册全局组件
app.component('VAceEditor', VAceEditor)
// 注册插件
app
.use(vuetify)
.use(router)

View File

@@ -1,4 +1,4 @@
import { createRouter, createWebHistory } from 'vue-router'
import { createRouter, createWebHashHistory } from 'vue-router'
import { configureNProgress, doneNProgress, startNProgress } from '@/api/nprogress'
import store from '@/store'
@@ -7,7 +7,7 @@ configureNProgress()
// Router
const router = createRouter({
history: createWebHistory(import.meta.env.BASE_URL),
history: createWebHashHistory(import.meta.env.BASE_URL),
scrollBehavior(to, from, savedPosition) {
// 如果页面有缓存那么恢复其位置, 否则始终滚动到顶部
if (to.meta.keepAlive && savedPosition)

View File

@@ -544,7 +544,9 @@ onBeforeMount(() => {
<ul v-if="mediaDetail.tmdb_id" class="media-crew">
<li v-for="director in mediaDetail.directors" :key="director.id">
<span>{{ director.job }}</span>
<a class="crew-name" :href="`person?personid=${director.id}`" target="_blank">{{ director.name }}</a>
<RouterLink :to="`/person?personid=${director.id}`" class="crew-name" target="_blank">
{{ director.name }}
</RouterLink>
</li>
</ul>
<ul v-if="!mediaDetail.tmdb_id && mediaDetail.douban_id" class="media-crew">

View File

@@ -9,6 +9,7 @@ import vuetify from 'vite-plugin-vuetify'
// https://vitejs.dev/config/
export default defineConfig({
base: './',
plugins: [
vue(),
vueJsx(),
@@ -27,7 +28,16 @@ export default defineConfig({
imports: ['vue', 'vue-router', '@vueuse/core', '@vueuse/math', 'vuex'],
vueTemplate: true,
}),
VitePWA({ registerType: 'autoUpdate', injectRegister: 'script', manifest: false }),
VitePWA({
registerType: 'autoUpdate',
injectRegister: 'script',
manifest: false,
workbox: {
navigateFallbackDenylist: [
/.*\/api\/v\d+\/system\/logging.*/,
],
},
}),
],
define: { 'process.env': {} },
resolve: {

View File

@@ -2422,6 +2422,11 @@ accepts@~1.3.8:
mime-types "~2.1.34"
negotiator "0.6.3"
ace-builds@^1.32.6:
version "1.32.6"
resolved "https://registry.yarnpkg.com/ace-builds/-/ace-builds-1.32.6.tgz#454ec8bc9235fbb960b8d8b86e698f941c104de2"
integrity sha512-dO5BnyDOhCnznhOpILzXq4jqkbhRXxNkf3BuVTmyxGyRLrhddfdyk6xXgy+7A8LENrcYoFi/sIxMuH3qjNUN4w==
acorn-jsx@^5.2.0, acorn-jsx@^5.3.2:
version "5.3.2"
resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-5.3.2.tgz#7ed5bb55908b3b2f1bc55c6af1653bada7f07937"
@@ -6651,6 +6656,11 @@ require-from-string@^2.0.2:
resolved "https://registry.yarnpkg.com/require-from-string/-/require-from-string-2.0.2.tgz#89a7fdd938261267318eafe14f9c32e598c36909"
integrity sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==
resize-observer-polyfill@^1.5.1:
version "1.5.1"
resolved "https://registry.yarnpkg.com/resize-observer-polyfill/-/resize-observer-polyfill-1.5.1.tgz#0e9020dd3d21024458d4ebd27e23e40269810464"
integrity sha512-LwZrotdHOo12nQuZlHEmtuXdqGoOD0OhaxopaNFxWzInpEgaLWoVuAMbTzixuosCx2nEG58ngzW3vxdWoxIgdg==
resolve-from@^4.0.0:
version "4.0.0"
resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-4.0.0.tgz#4abcd852ad32dd7baabfe9b40e00a36db5f392e6"
@@ -7912,6 +7922,13 @@ vue-tsc@^1.6.5:
"@volar/vue-typescript" "1.6.5"
semver "^7.3.8"
vue3-ace-editor@^2.2.4:
version "2.2.4"
resolved "https://registry.yarnpkg.com/vue3-ace-editor/-/vue3-ace-editor-2.2.4.tgz#1f2a787f91cf7979f27fab29e0e0604bb3ee1c17"
integrity sha512-FZkEyfpbH068BwjhMyNROxfEI8135Sc+x8ouxkMdCNkuj/Tuw83VP/gStFQqZHqljyX9/VfMTCdTqtOnJZGN8g==
dependencies:
resize-observer-polyfill "^1.5.1"
vue3-apexcharts@^1.4.1:
version "1.4.1"
resolved "https://registry.yarnpkg.com/vue3-apexcharts/-/vue3-apexcharts-1.4.1.tgz#ea561308430a1c5213b7f17c44ba3c845f6c490d"