mirror of
https://github.com/jxxghp/MoviePilot-Frontend.git
synced 2026-09-05 23:56:42 +08:00
统一图标导入方式
This commit is contained in:
@@ -4,9 +4,7 @@ import { formatFileSize } from '@/@core/utils/formatters'
|
|||||||
import { DownloaderConf } from '@/api/types'
|
import { DownloaderConf } from '@/api/types'
|
||||||
import { useToast } from 'vue-toastification'
|
import { useToast } from 'vue-toastification'
|
||||||
import type { DownloaderInfo } from '@/api/types'
|
import type { DownloaderInfo } from '@/api/types'
|
||||||
import qbittorrent_image from '@images/logos/qbittorrent.png'
|
import { getLogoUrl } from '@/utils/imageUtils'
|
||||||
import transmission_image from '@images/logos/transmission.png'
|
|
||||||
import custom_image from '@images/logos/downloader.png'
|
|
||||||
import { cloneDeep } from 'lodash-es'
|
import { cloneDeep } from 'lodash-es'
|
||||||
import { useI18n } from 'vue-i18n'
|
import { useI18n } from 'vue-i18n'
|
||||||
import { downloaderDict } from '@/api/constants'
|
import { downloaderDict } from '@/api/constants'
|
||||||
@@ -128,11 +126,11 @@ function saveDownloaderInfo() {
|
|||||||
const getIcon = computed(() => {
|
const getIcon = computed(() => {
|
||||||
switch (props.downloader.type) {
|
switch (props.downloader.type) {
|
||||||
case 'qbittorrent':
|
case 'qbittorrent':
|
||||||
return qbittorrent_image
|
return getLogoUrl('qbittorrent')
|
||||||
case 'transmission':
|
case 'transmission':
|
||||||
return transmission_image
|
return getLogoUrl('transmission')
|
||||||
default:
|
default:
|
||||||
return custom_image
|
return getLogoUrl('downloader')
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ import type { MediaServerLibrary } from '@/api/types'
|
|||||||
import plex from '@images/misc/plex.png'
|
import plex from '@images/misc/plex.png'
|
||||||
import emby from '@images/misc/emby.png'
|
import emby from '@images/misc/emby.png'
|
||||||
import jellyfin from '@images/misc/jellyfin.png'
|
import jellyfin from '@images/misc/jellyfin.png'
|
||||||
import trimemedia from '@images/logos/trimemedia.png'
|
import { getLogoUrl } from '@/utils/imageUtils'
|
||||||
import { openMediaServerWithAutoDetect } from '@/utils/appDeepLink'
|
import { openMediaServerWithAutoDetect } from '@/utils/appDeepLink'
|
||||||
|
|
||||||
// 输入参数
|
// 输入参数
|
||||||
@@ -40,7 +40,7 @@ function getDefaultImage() {
|
|||||||
if (props.media?.server_type === 'plex') return plex
|
if (props.media?.server_type === 'plex') return plex
|
||||||
else if (props.media?.server_type === 'emby') return emby
|
else if (props.media?.server_type === 'emby') return emby
|
||||||
else if (props.media?.server_type === 'jellyfin') return jellyfin
|
else if (props.media?.server_type === 'jellyfin') return jellyfin
|
||||||
else if (props.media?.server_type === 'trimemedia') return trimemedia
|
else if (props.media?.server_type === 'trimemedia') return getLogoUrl('trimemedia')
|
||||||
else return plex
|
else return plex
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -72,11 +72,11 @@ async function drawImages(imageList: string[]) {
|
|||||||
if (!canvas) return getDefaultImage()
|
if (!canvas) return getDefaultImage()
|
||||||
|
|
||||||
// 画布参数
|
// 画布参数
|
||||||
const POSTER_WIDTH = (canvas.width - 40) / 4 // 左右边框8px + 3个间隔24px = 40px
|
const POSTER_WIDTH = (canvas.width - 40) / 4 // 左右边框8px + 3个间隔24px = 40px
|
||||||
const POSTER_HEIGHT = 256 // 上方海报高256
|
const POSTER_HEIGHT = 256 // 上方海报高256
|
||||||
const MARGIN_WIDTH = 8 // 左右间隔为8
|
const MARGIN_WIDTH = 8 // 左右间隔为8
|
||||||
const MARGIN_HEIGHT = 4 // 海报和倒影之间的间隔为4
|
const MARGIN_HEIGHT = 4 // 海报和倒影之间的间隔为4
|
||||||
const REFLECTION_HEIGHT = canvas.height - POSTER_HEIGHT - MARGIN_HEIGHT // 下方倒影使用剩余全部高度
|
const REFLECTION_HEIGHT = canvas.height - POSTER_HEIGHT - MARGIN_HEIGHT // 下方倒影使用剩余全部高度
|
||||||
|
|
||||||
// 获取画布上下文
|
// 获取画布上下文
|
||||||
const ctx = canvas.getContext('2d')
|
const ctx = canvas.getContext('2d')
|
||||||
@@ -107,30 +107,20 @@ async function drawImages(imageList: string[]) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const x = MARGIN_WIDTH * index + POSTER_WIDTH * (index - 1)
|
const x = MARGIN_WIDTH * index + POSTER_WIDTH * (index - 1)
|
||||||
const y = 0 // 海报紧贴顶部
|
const y = 0 // 海报紧贴顶部
|
||||||
|
|
||||||
ctx.drawImage(img, x, y, POSTER_WIDTH, POSTER_HEIGHT)
|
ctx.drawImage(img, x, y, POSTER_WIDTH, POSTER_HEIGHT)
|
||||||
|
|
||||||
ctx.save()
|
ctx.save()
|
||||||
ctx.translate(0, canvas.height)
|
ctx.translate(0, canvas.height)
|
||||||
ctx.scale(1, -1)
|
ctx.scale(1, -1)
|
||||||
ctx.drawImage(
|
ctx.drawImage(img, 0, 0, img.width, img.height, x, 0, POSTER_WIDTH, REFLECTION_HEIGHT)
|
||||||
img,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
img.width,
|
|
||||||
img.height,
|
|
||||||
x,
|
|
||||||
0,
|
|
||||||
POSTER_WIDTH,
|
|
||||||
REFLECTION_HEIGHT,
|
|
||||||
)
|
|
||||||
|
|
||||||
const gradient = ctx.createLinearGradient(0, 0, 0, canvas.height - (POSTER_HEIGHT + MARGIN_HEIGHT))
|
const gradient = ctx.createLinearGradient(0, 0, 0, canvas.height - (POSTER_HEIGHT + MARGIN_HEIGHT))
|
||||||
|
|
||||||
gradient.addColorStop(0, 'rgba(0, 0, 0, 1)')
|
gradient.addColorStop(0, 'rgba(0, 0, 0, 1)')
|
||||||
gradient.addColorStop(1, 'rgba(0, 0, 0, 0.7)')
|
gradient.addColorStop(1, 'rgba(0, 0, 0, 0.7)')
|
||||||
ctx.globalCompositeOperation = 'destination-out';
|
ctx.globalCompositeOperation = 'destination-out'
|
||||||
ctx.fillStyle = gradient
|
ctx.fillStyle = gradient
|
||||||
ctx.fillRect(x, 0, POSTER_WIDTH, REFLECTION_HEIGHT)
|
ctx.fillRect(x, 0, POSTER_WIDTH, REFLECTION_HEIGHT)
|
||||||
|
|
||||||
|
|||||||
@@ -1,8 +1,6 @@
|
|||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import noImage from '@images/no-image.jpeg'
|
import noImage from '@images/no-image.jpeg'
|
||||||
import tmdbImage from '@images/logos/tmdb.png'
|
import { getLogoUrl } from '@/utils/imageUtils'
|
||||||
import doubanImage from '@images/logos/douban-black.png'
|
|
||||||
import bangumiImage from '@images/logos/bangumi.png'
|
|
||||||
import api from '@/api'
|
import api from '@/api'
|
||||||
import { useToast } from 'vue-toastification'
|
import { useToast } from 'vue-toastification'
|
||||||
import { formatSeason, formatRating } from '@/@core/utils/formatters'
|
import { formatSeason, formatRating } from '@/@core/utils/formatters'
|
||||||
@@ -64,9 +62,9 @@ const seasonsSelected = ref<MediaSeason[]>([])
|
|||||||
|
|
||||||
// 来源角标字典
|
// 来源角标字典
|
||||||
const sourceIconDict: { [key: string]: any } = {
|
const sourceIconDict: { [key: string]: any } = {
|
||||||
themoviedb: tmdbImage,
|
themoviedb: getLogoUrl('tmdb'),
|
||||||
douban: doubanImage,
|
douban: getLogoUrl('douban-black'),
|
||||||
bangumi: bangumiImage,
|
bangumi: getLogoUrl('bangumi'),
|
||||||
}
|
}
|
||||||
|
|
||||||
// 绑定MediaCard元素
|
// 绑定MediaCard元素
|
||||||
|
|||||||
@@ -1,11 +1,7 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { MediaServerConf, MediaServerLibrary, MediaStatistic } from '@/api/types'
|
import { MediaServerConf, MediaServerLibrary, MediaStatistic } from '@/api/types'
|
||||||
import { useToast } from 'vue-toastification'
|
import { useToast } from 'vue-toastification'
|
||||||
import emby_image from '@images/logos/emby.png'
|
import { getLogoUrl } from '@/utils/imageUtils'
|
||||||
import jellyfin_image from '@images/logos/jellyfin.png'
|
|
||||||
import plex_image from '@images/logos/plex.png'
|
|
||||||
import trimemedia_image from '@images/logos/trimemedia.png'
|
|
||||||
import custom_image from '@images/logos/mediaserver.png'
|
|
||||||
import api from '@/api'
|
import api from '@/api'
|
||||||
import { cloneDeep } from 'lodash-es'
|
import { cloneDeep } from 'lodash-es'
|
||||||
import { useI18n } from 'vue-i18n'
|
import { useI18n } from 'vue-i18n'
|
||||||
@@ -109,15 +105,15 @@ function saveMediaServerInfo() {
|
|||||||
const getIcon = computed(() => {
|
const getIcon = computed(() => {
|
||||||
switch (props.mediaserver.type) {
|
switch (props.mediaserver.type) {
|
||||||
case 'emby':
|
case 'emby':
|
||||||
return emby_image
|
return getLogoUrl('emby')
|
||||||
case 'jellyfin':
|
case 'jellyfin':
|
||||||
return jellyfin_image
|
return getLogoUrl('jellyfin')
|
||||||
case 'trimemedia':
|
case 'trimemedia':
|
||||||
return trimemedia_image
|
return getLogoUrl('trimemedia')
|
||||||
case 'plex':
|
case 'plex':
|
||||||
return plex_image
|
return getLogoUrl('plex')
|
||||||
default:
|
default:
|
||||||
return custom_image
|
return getLogoUrl('mediaserver')
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|||||||
@@ -1,12 +1,6 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { NotificationConf } from '@/api/types'
|
import { NotificationConf } from '@/api/types'
|
||||||
import wechat_image from '@images/logos/wechat.png'
|
import { getLogoUrl } from '@/utils/imageUtils'
|
||||||
import telegram_image from '@images/logos/telegram.webp'
|
|
||||||
import vocechat_image from '@images/logos/vocechat.png'
|
|
||||||
import synologychat_image from '@images/logos/synologychat.png'
|
|
||||||
import slack_image from '@images/logos/slack.webp'
|
|
||||||
import chrome_image from '@images/logos/chrome.png'
|
|
||||||
import custom_image from '@images/logos/notification.png'
|
|
||||||
import { useToast } from 'vue-toastification'
|
import { useToast } from 'vue-toastification'
|
||||||
import { cloneDeep } from 'lodash-es'
|
import { cloneDeep } from 'lodash-es'
|
||||||
import { useI18n } from 'vue-i18n'
|
import { useI18n } from 'vue-i18n'
|
||||||
@@ -99,19 +93,19 @@ function saveNotificationInfo() {
|
|||||||
const getIcon = computed(() => {
|
const getIcon = computed(() => {
|
||||||
switch (props.notification.type) {
|
switch (props.notification.type) {
|
||||||
case 'wechat':
|
case 'wechat':
|
||||||
return wechat_image
|
return getLogoUrl('wechat')
|
||||||
case 'telegram':
|
case 'telegram':
|
||||||
return telegram_image
|
return getLogoUrl('telegram')
|
||||||
case 'vocechat':
|
case 'vocechat':
|
||||||
return vocechat_image
|
return getLogoUrl('vocechat')
|
||||||
case 'synologychat':
|
case 'synologychat':
|
||||||
return synologychat_image
|
return getLogoUrl('synologychat')
|
||||||
case 'slack':
|
case 'slack':
|
||||||
return slack_image
|
return getLogoUrl('slack')
|
||||||
case 'webpush':
|
case 'webpush':
|
||||||
return chrome_image
|
return getLogoUrl('chrome')
|
||||||
default:
|
default:
|
||||||
return custom_image
|
return getLogoUrl('notification')
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ import { useToast } from 'vue-toastification'
|
|||||||
import VersionHistory from '../misc/VersionHistory.vue'
|
import VersionHistory from '../misc/VersionHistory.vue'
|
||||||
import api from '@/api'
|
import api from '@/api'
|
||||||
import type { Plugin } from '@/api/types'
|
import type { Plugin } from '@/api/types'
|
||||||
import noImage from '@images/logos/plugin.png'
|
import { getLogoUrl } from '@/utils/imageUtils'
|
||||||
import { getDominantColor } from '@/@core/utils/image'
|
import { getDominantColor } from '@/@core/utils/image'
|
||||||
import { isNullOrEmptyObject } from '@/@core/utils'
|
import { isNullOrEmptyObject } from '@/@core/utils'
|
||||||
import ProgressDialog from '@/components/dialog/ProgressDialog.vue'
|
import ProgressDialog from '@/components/dialog/ProgressDialog.vue'
|
||||||
@@ -103,7 +103,7 @@ async function installPlugin() {
|
|||||||
|
|
||||||
// 计算图标路径
|
// 计算图标路径
|
||||||
const iconPath: Ref<string> = computed(() => {
|
const iconPath: Ref<string> = computed(() => {
|
||||||
if (imageLoadError.value) return noImage
|
if (imageLoadError.value) return getLogoUrl('plugin')
|
||||||
// 如果是网络图片则使用代理后返回
|
// 如果是网络图片则使用代理后返回
|
||||||
if (props.plugin?.plugin_icon?.startsWith('http'))
|
if (props.plugin?.plugin_icon?.startsWith('http'))
|
||||||
return `${import.meta.env.VITE_API_BASE_URL}system/img/1?imgurl=${encodeURIComponent(
|
return `${import.meta.env.VITE_API_BASE_URL}system/img/1?imgurl=${encodeURIComponent(
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ import { useConfirm } from '@/composables/useConfirm'
|
|||||||
import api from '@/api'
|
import api from '@/api'
|
||||||
import type { Plugin } from '@/api/types'
|
import type { Plugin } from '@/api/types'
|
||||||
import { isNullOrEmptyObject } from '@core/utils'
|
import { isNullOrEmptyObject } from '@core/utils'
|
||||||
import noImage from '@images/logos/plugin.png'
|
import { getLogoUrl } from '@/utils/imageUtils'
|
||||||
import { getDominantColor } from '@/@core/utils/image'
|
import { getDominantColor } from '@/@core/utils/image'
|
||||||
import VersionHistory from '@/components/misc/VersionHistory.vue'
|
import VersionHistory from '@/components/misc/VersionHistory.vue'
|
||||||
import ProgressDialog from '../dialog/ProgressDialog.vue'
|
import ProgressDialog from '../dialog/ProgressDialog.vue'
|
||||||
@@ -167,7 +167,7 @@ async function showPluginConfig() {
|
|||||||
|
|
||||||
// 计算图标路径
|
// 计算图标路径
|
||||||
const iconPath: Ref<string> = computed(() => {
|
const iconPath: Ref<string> = computed(() => {
|
||||||
if (imageLoadError.value) return noImage
|
if (imageLoadError.value) return getLogoUrl('plugin')
|
||||||
// 如果是网络图片则使用代理后返回
|
// 如果是网络图片则使用代理后返回
|
||||||
if (props.plugin?.plugin_icon?.startsWith('http'))
|
if (props.plugin?.plugin_icon?.startsWith('http'))
|
||||||
return `${import.meta.env.VITE_API_BASE_URL}system/img/1?imgurl=${encodeURIComponent(
|
return `${import.meta.env.VITE_API_BASE_URL}system/img/1?imgurl=${encodeURIComponent(
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import type { PropType } from 'vue'
|
import type { PropType } from 'vue'
|
||||||
import noImage from '@images/logos/site.webp'
|
import { getLogoUrl } from '@/utils/imageUtils'
|
||||||
import { useToast } from 'vue-toastification'
|
import { useToast } from 'vue-toastification'
|
||||||
import { useI18n } from 'vue-i18n'
|
import { useI18n } from 'vue-i18n'
|
||||||
import SiteAddEditDialog from '../dialog/SiteAddEditDialog.vue'
|
import SiteAddEditDialog from '../dialog/SiteAddEditDialog.vue'
|
||||||
@@ -62,7 +62,7 @@ async function getSiteIcon() {
|
|||||||
try {
|
try {
|
||||||
siteIcon.value = (await api.get(`site/icon/${cardProps.site?.id}`)).data.icon
|
siteIcon.value = (await api.get(`site/icon/${cardProps.site?.id}`)).data.icon
|
||||||
if (!siteIcon.value) {
|
if (!siteIcon.value) {
|
||||||
siteIcon.value = noImage
|
siteIcon.value = getLogoUrl('site')
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error(error)
|
console.error(error)
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import api from '@/api'
|
import api from '@/api'
|
||||||
import type { Plugin } from '@/api/types'
|
import type { Plugin } from '@/api/types'
|
||||||
import noImage from '@images/logos/plugin.png'
|
import { getLogoUrl } from '@/utils/imageUtils'
|
||||||
import { useI18n } from 'vue-i18n'
|
import { useI18n } from 'vue-i18n'
|
||||||
import { useRecentPlugins } from '@/composables/useRecentPlugins'
|
import { useRecentPlugins } from '@/composables/useRecentPlugins'
|
||||||
import PluginDataDialog from '@/components/dialog/PluginDataDialog.vue'
|
import PluginDataDialog from '@/components/dialog/PluginDataDialog.vue'
|
||||||
@@ -137,8 +137,8 @@ const componentOpacity = computed(() => {
|
|||||||
|
|
||||||
// 计算插件图标路径
|
// 计算插件图标路径
|
||||||
function getPluginIcon(plugin: Plugin): string {
|
function getPluginIcon(plugin: Plugin): string {
|
||||||
if (!plugin.plugin_icon) return noImage
|
if (!plugin.plugin_icon) return getLogoUrl('plugin')
|
||||||
if (pluginIconLoadError.value[plugin.id]) return noImage
|
if (pluginIconLoadError.value[plugin.id]) return getLogoUrl('plugin')
|
||||||
|
|
||||||
// 如果是网络图片则使用代理后返回
|
// 如果是网络图片则使用代理后返回
|
||||||
if (plugin?.plugin_icon?.startsWith('http'))
|
if (plugin?.plugin_icon?.startsWith('http'))
|
||||||
|
|||||||
@@ -1233,7 +1233,7 @@ export default {
|
|||||||
apiTokenLength: 'API Token must be at least 16 characters',
|
apiTokenLength: 'API Token must be at least 16 characters',
|
||||||
githubToken: 'Github Token',
|
githubToken: 'Github Token',
|
||||||
githubTokenFormat: 'ghp_**** or github_pat_****',
|
githubTokenFormat: 'ghp_**** or github_pat_****',
|
||||||
githubTokenHint: 'Used to increase the rate limit threshold when plugins access Github API',
|
githubTokenHint: 'Used to increase the rate limit threshold when plugins access Github API,it is recommended to configure, otherwise plugins may not work properly',
|
||||||
ocrHost: 'OCR Server',
|
ocrHost: 'OCR Server',
|
||||||
ocrHostHint: 'Used for site check-in, updating site cookies and other captcha recognition',
|
ocrHostHint: 'Used for site check-in, updating site cookies and other captcha recognition',
|
||||||
advancedSettings: 'Advanced Settings',
|
advancedSettings: 'Advanced Settings',
|
||||||
@@ -2943,7 +2943,7 @@ export default {
|
|||||||
recognizeSource: 'Recognize Source',
|
recognizeSource: 'Recognize Source',
|
||||||
recognizeSourceHint: 'Set the default media info recognition data source',
|
recognizeSourceHint: 'Set the default media info recognition data source',
|
||||||
apiToken: 'API Token',
|
apiToken: 'API Token',
|
||||||
apiTokenHint: 'System automatically generated API access token',
|
apiTokenHint: 'API Token required for accessing MoviePilot API, please record it for subsequent use',
|
||||||
currentUserHint: 'Current user, cannot be modified',
|
currentUserHint: 'Current user, cannot be modified',
|
||||||
passwordOptionalHint: 'Leave blank to keep current password',
|
passwordOptionalHint: 'Leave blank to keep current password',
|
||||||
confirmPasswordHint: 'Confirm new password',
|
confirmPasswordHint: 'Confirm new password',
|
||||||
|
|||||||
@@ -1229,7 +1229,7 @@ export default {
|
|||||||
apiTokenLength: 'API Token不得低于16位',
|
apiTokenLength: 'API Token不得低于16位',
|
||||||
githubToken: 'Github Token',
|
githubToken: 'Github Token',
|
||||||
githubTokenFormat: 'ghp_**** 或 github_pat_****',
|
githubTokenFormat: 'ghp_**** 或 github_pat_****',
|
||||||
githubTokenHint: '用于提高插件等访问Github API时的限流阈值',
|
githubTokenHint: '用于提高插件等访问Github API时的限流阈值,建议配置,否则插件可能无法正常使用',
|
||||||
ocrHost: '验证码识别服务器',
|
ocrHost: '验证码识别服务器',
|
||||||
ocrHostHint: '用于站点签到、更新站点Cookie等识别验证码',
|
ocrHostHint: '用于站点签到、更新站点Cookie等识别验证码',
|
||||||
advancedSettings: '高级设置',
|
advancedSettings: '高级设置',
|
||||||
@@ -2930,7 +2930,7 @@ export default {
|
|||||||
recognizeSource: '识别数据源',
|
recognizeSource: '识别数据源',
|
||||||
recognizeSourceHint: '设置默认媒体信息识别数据源',
|
recognizeSourceHint: '设置默认媒体信息识别数据源',
|
||||||
apiToken: 'API 令牌',
|
apiToken: 'API 令牌',
|
||||||
apiTokenHint: '系统自动生成的 API 访问令牌',
|
apiTokenHint: '访问MoviePilot API 需要的访问令牌,请记录下来以便后续使用',
|
||||||
currentUserHint: '当前用户,不可修改',
|
currentUserHint: '当前用户,不可修改',
|
||||||
passwordOptionalHint: '留空表示不修改密码',
|
passwordOptionalHint: '留空表示不修改密码',
|
||||||
confirmPasswordHint: '确认新密码',
|
confirmPasswordHint: '确认新密码',
|
||||||
|
|||||||
@@ -1217,7 +1217,7 @@ export default {
|
|||||||
apiTokenLength: 'API Token不得低於16位',
|
apiTokenLength: 'API Token不得低於16位',
|
||||||
githubToken: 'Github Token',
|
githubToken: 'Github Token',
|
||||||
githubTokenFormat: 'ghp_**** 或 github_pat_****',
|
githubTokenFormat: 'ghp_**** 或 github_pat_****',
|
||||||
githubTokenHint: '用於提高插件等訪問Github API時的限流閾值',
|
githubTokenHint: '用於提高插件等訪問Github API時的限流閾值,建議配置,否則插件可能無法正常使用',
|
||||||
ocrHost: '驗證碼識別服務器',
|
ocrHost: '驗證碼識別服務器',
|
||||||
ocrHostHint: '用於站點簽到、更新站點Cookie等識別驗證碼',
|
ocrHostHint: '用於站點簽到、更新站點Cookie等識別驗證碼',
|
||||||
advancedSettings: '高級設置',
|
advancedSettings: '高級設置',
|
||||||
@@ -2898,7 +2898,7 @@ export default {
|
|||||||
recognizeSource: '識別資料來源',
|
recognizeSource: '識別資料來源',
|
||||||
recognizeSourceHint: '設定預設媒體資訊識別資料來源',
|
recognizeSourceHint: '設定預設媒體資訊識別資料來源',
|
||||||
apiToken: 'API 權杖',
|
apiToken: 'API 權杖',
|
||||||
apiTokenHint: '系統自動產生的 API 存取權杖',
|
apiTokenHint: '訪問MoviePilot API 需要的訪問令牌,請記錄下來以便後續使用',
|
||||||
currentUserHint: '目前使用者,不可修改',
|
currentUserHint: '目前使用者,不可修改',
|
||||||
passwordOptionalHint: '留空表示不修改密碼',
|
passwordOptionalHint: '留空表示不修改密碼',
|
||||||
confirmPasswordHint: '確認新密碼',
|
confirmPasswordHint: '確認新密碼',
|
||||||
|
|||||||
@@ -0,0 +1,84 @@
|
|||||||
|
/**
|
||||||
|
* 静态资源导入工具函数
|
||||||
|
* 用于在生产环境中正确引用静态资源
|
||||||
|
*/
|
||||||
|
|
||||||
|
// 导入所有 logo 图标
|
||||||
|
import qbittorrentLogo from '@/assets/images/logos/qbittorrent.png'
|
||||||
|
import transmissionLogo from '@/assets/images/logos/transmission.png'
|
||||||
|
import embyLogo from '@/assets/images/logos/emby.png'
|
||||||
|
import jellyfinLogo from '@/assets/images/logos/jellyfin.png'
|
||||||
|
import plexLogo from '@/assets/images/logos/plex.png'
|
||||||
|
import trimemediaLogo from '@/assets/images/logos/trimemedia.png'
|
||||||
|
import wechatLogo from '@/assets/images/logos/wechat.png'
|
||||||
|
import telegramLogo from '@/assets/images/logos/telegram.webp'
|
||||||
|
import slackLogo from '@/assets/images/logos/slack.webp'
|
||||||
|
import synologychatLogo from '@/assets/images/logos/synologychat.png'
|
||||||
|
import vocechatLogo from '@/assets/images/logos/vocechat.png'
|
||||||
|
import downloaderLogo from '@/assets/images/logos/downloader.png'
|
||||||
|
import mediaserverLogo from '@/assets/images/logos/mediaserver.png'
|
||||||
|
import notificationLogo from '@/assets/images/logos/notification.png'
|
||||||
|
import chromeLogo from '@/assets/images/logos/chrome.png'
|
||||||
|
import doubanLogo from '@/assets/images/logos/douban.png'
|
||||||
|
import githubLogo from '@/assets/images/logos/github.png'
|
||||||
|
import tmdbLogo from '@/assets/images/logos/tmdb.png'
|
||||||
|
import fanartLogo from '@/assets/images/logos/fanart.webp'
|
||||||
|
import pythonLogo from '@/assets/images/logos/python.png'
|
||||||
|
import pluginLogo from '@/assets/images/logos/plugin.png'
|
||||||
|
import siteLogo from '@/assets/images/logos/site.webp'
|
||||||
|
import bangumiLogo from '@/assets/images/logos/bangumi.png'
|
||||||
|
import doubanBlackLogo from '@/assets/images/logos/douban-black.png'
|
||||||
|
|
||||||
|
// 图标映射表
|
||||||
|
const logoMap: Record<string, string> = {
|
||||||
|
qbittorrent: qbittorrentLogo,
|
||||||
|
transmission: transmissionLogo,
|
||||||
|
emby: embyLogo,
|
||||||
|
jellyfin: jellyfinLogo,
|
||||||
|
plex: plexLogo,
|
||||||
|
trimemedia: trimemediaLogo,
|
||||||
|
wechat: wechatLogo,
|
||||||
|
telegram: telegramLogo,
|
||||||
|
slack: slackLogo,
|
||||||
|
synologychat: synologychatLogo,
|
||||||
|
vocechat: vocechatLogo,
|
||||||
|
downloader: downloaderLogo,
|
||||||
|
mediaserver: mediaserverLogo,
|
||||||
|
notification: notificationLogo,
|
||||||
|
chrome: chromeLogo,
|
||||||
|
douban: doubanLogo,
|
||||||
|
github: githubLogo,
|
||||||
|
tmdb: tmdbLogo,
|
||||||
|
fanart: fanartLogo,
|
||||||
|
python: pythonLogo,
|
||||||
|
plugin: pluginLogo,
|
||||||
|
site: siteLogo,
|
||||||
|
bangumi: bangumiLogo,
|
||||||
|
'douban-black': doubanBlackLogo,
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取图标 URL
|
||||||
|
* @param logoName 图标名称
|
||||||
|
* @returns 图标的 URL
|
||||||
|
*/
|
||||||
|
export function getLogoUrl(logoName: string): string {
|
||||||
|
return logoMap[logoName] || ''
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取所有可用的图标名称
|
||||||
|
* @returns 图标名称数组
|
||||||
|
*/
|
||||||
|
export function getAvailableLogos(): string[] {
|
||||||
|
return Object.keys(logoMap)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 检查图标是否存在
|
||||||
|
* @param logoName 图标名称
|
||||||
|
* @returns 是否存在
|
||||||
|
*/
|
||||||
|
export function hasLogo(logoName: string): boolean {
|
||||||
|
return logoName in logoMap
|
||||||
|
}
|
||||||
@@ -5,7 +5,7 @@ import api from '@/api'
|
|||||||
import type { Plugin } from '@/api/types'
|
import type { Plugin } from '@/api/types'
|
||||||
import NoDataFound from '@/components/NoDataFound.vue'
|
import NoDataFound from '@/components/NoDataFound.vue'
|
||||||
import PluginAppCard from '@/components/cards/PluginAppCard.vue'
|
import PluginAppCard from '@/components/cards/PluginAppCard.vue'
|
||||||
import noImage from '@images/logos/plugin.png'
|
import { getLogoUrl } from '@/utils/imageUtils'
|
||||||
import { useDisplay } from 'vuetify'
|
import { useDisplay } from 'vuetify'
|
||||||
import { isNullOrEmptyObject } from '@/@core/utils'
|
import { isNullOrEmptyObject } from '@/@core/utils'
|
||||||
import { getPluginTabs } from '@/router/i18n-menu'
|
import { getPluginTabs } from '@/router/i18n-menu'
|
||||||
@@ -675,7 +675,7 @@ function pluginIconError(item: Plugin) {
|
|||||||
// 插件图标地址
|
// 插件图标地址
|
||||||
function pluginIcon(item: Plugin) {
|
function pluginIcon(item: Plugin) {
|
||||||
// 如果图片加载错误
|
// 如果图片加载错误
|
||||||
if (pluginIconLoaded.value[item.id || '0'] === false) return noImage
|
if (pluginIconLoaded.value[item.id || '0'] === false) return getLogoUrl('plugin')
|
||||||
// 如果是网络图片则使用代理后返回
|
// 如果是网络图片则使用代理后返回
|
||||||
if (item?.plugin_icon?.startsWith('http'))
|
if (item?.plugin_icon?.startsWith('http'))
|
||||||
return `${import.meta.env.VITE_API_BASE_URL}system/img/1?imgurl=${encodeURIComponent(item?.plugin_icon)}&cache=true`
|
return `${import.meta.env.VITE_API_BASE_URL}system/img/1?imgurl=${encodeURIComponent(item?.plugin_icon)}&cache=true`
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { useI18n } from 'vue-i18n'
|
import { useI18n } from 'vue-i18n'
|
||||||
import { useSetupWizard } from '@/composables/useSetupWizard'
|
import { useSetupWizard } from '@/composables/useSetupWizard'
|
||||||
|
import { getLogoUrl } from '@/utils/imageUtils'
|
||||||
|
|
||||||
const { t } = useI18n()
|
const { t } = useI18n()
|
||||||
const { wizardData, selectDownloader, validationErrors } = useSetupWizard()
|
const { wizardData, selectDownloader, validationErrors } = useSetupWizard()
|
||||||
@@ -34,7 +35,7 @@ const { wizardData, selectDownloader, validationErrors } = useSetupWizard()
|
|||||||
@click="selectDownloader('qbittorrent')"
|
@click="selectDownloader('qbittorrent')"
|
||||||
>
|
>
|
||||||
<VCardText class="text-center">
|
<VCardText class="text-center">
|
||||||
<VImg src="/src/assets/images/logos/qbittorrent.png" height="48" width="48" class="mx-auto mb-2" />
|
<VImg :src="getLogoUrl('qbittorrent')" height="48" width="48" class="mx-auto mb-2" />
|
||||||
<div class="text-h6">qBittorrent</div>
|
<div class="text-h6">qBittorrent</div>
|
||||||
</VCardText>
|
</VCardText>
|
||||||
</VCard>
|
</VCard>
|
||||||
@@ -47,7 +48,7 @@ const { wizardData, selectDownloader, validationErrors } = useSetupWizard()
|
|||||||
@click="selectDownloader('transmission')"
|
@click="selectDownloader('transmission')"
|
||||||
>
|
>
|
||||||
<VCardText class="text-center">
|
<VCardText class="text-center">
|
||||||
<VImg src="/src/assets/images/logos/transmission.png" height="48" width="48" class="mx-auto mb-2" />
|
<VImg :src="getLogoUrl('transmission')" height="48" width="48" class="mx-auto mb-2" />
|
||||||
<div class="text-h6">Transmission</div>
|
<div class="text-h6">Transmission</div>
|
||||||
</VCardText>
|
</VCardText>
|
||||||
</VCard>
|
</VCard>
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
import { useI18n } from 'vue-i18n'
|
import { useI18n } from 'vue-i18n'
|
||||||
import { useSetupWizard } from '@/composables/useSetupWizard'
|
import { useSetupWizard } from '@/composables/useSetupWizard'
|
||||||
import api from '@/api'
|
import api from '@/api'
|
||||||
|
import { getLogoUrl } from '@/utils/imageUtils'
|
||||||
|
|
||||||
const { t } = useI18n()
|
const { t } = useI18n()
|
||||||
const { wizardData, selectMediaServer, validationErrors } = useSetupWizard()
|
const { wizardData, selectMediaServer, validationErrors } = useSetupWizard()
|
||||||
@@ -96,7 +97,7 @@ watch(
|
|||||||
@click="selectMediaServerWithLibrary('emby')"
|
@click="selectMediaServerWithLibrary('emby')"
|
||||||
>
|
>
|
||||||
<VCardText class="text-center">
|
<VCardText class="text-center">
|
||||||
<VImg src="/src/assets/images/logos/emby.png" height="48" width="48" class="mx-auto mb-2" />
|
<VImg :src="getLogoUrl('emby')" height="48" width="48" class="mx-auto mb-2" />
|
||||||
<div class="text-h6">Emby</div>
|
<div class="text-h6">Emby</div>
|
||||||
</VCardText>
|
</VCardText>
|
||||||
</VCard>
|
</VCard>
|
||||||
@@ -109,7 +110,7 @@ watch(
|
|||||||
@click="selectMediaServerWithLibrary('jellyfin')"
|
@click="selectMediaServerWithLibrary('jellyfin')"
|
||||||
>
|
>
|
||||||
<VCardText class="text-center">
|
<VCardText class="text-center">
|
||||||
<VImg src="/src/assets/images/logos/jellyfin.png" height="48" width="48" class="mx-auto mb-2" />
|
<VImg :src="getLogoUrl('jellyfin')" height="48" width="48" class="mx-auto mb-2" />
|
||||||
<div class="text-h6">Jellyfin</div>
|
<div class="text-h6">Jellyfin</div>
|
||||||
</VCardText>
|
</VCardText>
|
||||||
</VCard>
|
</VCard>
|
||||||
@@ -122,7 +123,7 @@ watch(
|
|||||||
@click="selectMediaServerWithLibrary('plex')"
|
@click="selectMediaServerWithLibrary('plex')"
|
||||||
>
|
>
|
||||||
<VCardText class="text-center">
|
<VCardText class="text-center">
|
||||||
<VImg src="/src/assets/images/logos/plex.png" height="48" width="48" class="mx-auto mb-2" />
|
<VImg :src="getLogoUrl('plex')" height="48" width="48" class="mx-auto mb-2" />
|
||||||
<div class="text-h6">Plex</div>
|
<div class="text-h6">Plex</div>
|
||||||
</VCardText>
|
</VCardText>
|
||||||
</VCard>
|
</VCard>
|
||||||
@@ -135,7 +136,7 @@ watch(
|
|||||||
@click="selectMediaServerWithLibrary('trimemedia')"
|
@click="selectMediaServerWithLibrary('trimemedia')"
|
||||||
>
|
>
|
||||||
<VCardText class="text-center">
|
<VCardText class="text-center">
|
||||||
<VImg src="/src/assets/images/logos/trimemedia.png" height="48" width="48" class="mx-auto mb-2" />
|
<VImg :src="getLogoUrl('trimemedia')" height="48" width="48" class="mx-auto mb-2" />
|
||||||
<div class="text-h6">飞牛影视</div>
|
<div class="text-h6">飞牛影视</div>
|
||||||
</VCardText>
|
</VCardText>
|
||||||
</VCard>
|
</VCard>
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { useI18n } from 'vue-i18n'
|
import { useI18n } from 'vue-i18n'
|
||||||
import { useSetupWizard } from '@/composables/useSetupWizard'
|
import { useSetupWizard } from '@/composables/useSetupWizard'
|
||||||
|
import { getLogoUrl } from '@/utils/imageUtils'
|
||||||
|
|
||||||
const { t } = useI18n()
|
const { t } = useI18n()
|
||||||
const { wizardData, selectNotification, validationErrors } = useSetupWizard()
|
const { wizardData, selectNotification, validationErrors } = useSetupWizard()
|
||||||
@@ -46,7 +47,7 @@ const notificationTypes = [
|
|||||||
@click="selectNotification('wechat')"
|
@click="selectNotification('wechat')"
|
||||||
>
|
>
|
||||||
<VCardText class="text-center">
|
<VCardText class="text-center">
|
||||||
<VImg src="/src/assets/images/logos/wechat.png" height="48" width="48" class="mx-auto mb-2" />
|
<VImg :src="getLogoUrl('wechat')" height="48" width="48" class="mx-auto mb-2" />
|
||||||
<div class="text-h6">微信</div>
|
<div class="text-h6">微信</div>
|
||||||
</VCardText>
|
</VCardText>
|
||||||
</VCard>
|
</VCard>
|
||||||
@@ -59,7 +60,7 @@ const notificationTypes = [
|
|||||||
@click="selectNotification('telegram')"
|
@click="selectNotification('telegram')"
|
||||||
>
|
>
|
||||||
<VCardText class="text-center">
|
<VCardText class="text-center">
|
||||||
<VImg src="/src/assets/images/logos/telegram.webp" height="48" width="48" class="mx-auto mb-2" />
|
<VImg :src="getLogoUrl('telegram')" height="48" width="48" class="mx-auto mb-2" />
|
||||||
<div class="text-h6">Telegram</div>
|
<div class="text-h6">Telegram</div>
|
||||||
</VCardText>
|
</VCardText>
|
||||||
</VCard>
|
</VCard>
|
||||||
@@ -72,7 +73,7 @@ const notificationTypes = [
|
|||||||
@click="selectNotification('slack')"
|
@click="selectNotification('slack')"
|
||||||
>
|
>
|
||||||
<VCardText class="text-center">
|
<VCardText class="text-center">
|
||||||
<VImg src="/src/assets/images/logos/slack.webp" height="48" width="48" class="mx-auto mb-2" />
|
<VImg :src="getLogoUrl('slack')" height="48" width="48" class="mx-auto mb-2" />
|
||||||
<div class="text-h6">Slack</div>
|
<div class="text-h6">Slack</div>
|
||||||
</VCardText>
|
</VCardText>
|
||||||
</VCard>
|
</VCard>
|
||||||
@@ -85,7 +86,7 @@ const notificationTypes = [
|
|||||||
@click="selectNotification('synologychat')"
|
@click="selectNotification('synologychat')"
|
||||||
>
|
>
|
||||||
<VCardText class="text-center">
|
<VCardText class="text-center">
|
||||||
<VImg src="/src/assets/images/logos/synologychat.png" height="48" width="48" class="mx-auto mb-2" />
|
<VImg :src="getLogoUrl('synologychat')" height="48" width="48" class="mx-auto mb-2" />
|
||||||
<div class="text-h6">Synology Chat</div>
|
<div class="text-h6">Synology Chat</div>
|
||||||
</VCardText>
|
</VCardText>
|
||||||
</VCard>
|
</VCard>
|
||||||
@@ -98,7 +99,7 @@ const notificationTypes = [
|
|||||||
@click="selectNotification('vocechat')"
|
@click="selectNotification('vocechat')"
|
||||||
>
|
>
|
||||||
<VCardText class="text-center">
|
<VCardText class="text-center">
|
||||||
<VImg src="/src/assets/images/logos/vocechat.png" height="48" width="48" class="mx-auto mb-2" />
|
<VImg :src="getLogoUrl('vocechat')" height="48" width="48" class="mx-auto mb-2" />
|
||||||
<div class="text-h6">VoceChat</div>
|
<div class="text-h6">VoceChat</div>
|
||||||
</VCardText>
|
</VCardText>
|
||||||
</VCard>
|
</VCard>
|
||||||
|
|||||||
@@ -1,14 +1,7 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import api from '@/api'
|
import api from '@/api'
|
||||||
import douban from '@images/logos/douban.png'
|
import { getLogoUrl } from '@/utils/imageUtils'
|
||||||
import github from '@images/logos/github.png'
|
|
||||||
import slack from '@images/logos/slack.webp'
|
|
||||||
import telegram from '@images/logos/telegram.webp'
|
|
||||||
import tmdb from '@images/logos/tmdb.png'
|
|
||||||
import wechat from '@images/logos/wechat.png'
|
|
||||||
import fanart from '@images/logos/fanart.webp'
|
|
||||||
import tvdb from '@images/logos/thetvdb.jpeg'
|
import tvdb from '@images/logos/thetvdb.jpeg'
|
||||||
import python from '@images/logos/python.png'
|
|
||||||
import { useI18n } from 'vue-i18n'
|
import { useI18n } from 'vue-i18n'
|
||||||
|
|
||||||
// 国际化
|
// 国际化
|
||||||
@@ -36,7 +29,7 @@ interface Address {
|
|||||||
// 测试集
|
// 测试集
|
||||||
const targets = ref<Address[]>([
|
const targets = ref<Address[]>([
|
||||||
{
|
{
|
||||||
image: tmdb,
|
image: getLogoUrl('tmdb'),
|
||||||
name: 'api.themoviedb.org',
|
name: 'api.themoviedb.org',
|
||||||
url: 'https://api.themoviedb.org/3/movie/550?api_key={TMDBAPIKEY}',
|
url: 'https://api.themoviedb.org/3/movie/550?api_key={TMDBAPIKEY}',
|
||||||
proxy: true,
|
proxy: true,
|
||||||
@@ -46,7 +39,7 @@ const targets = ref<Address[]>([
|
|||||||
btndisable: false,
|
btndisable: false,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
image: tmdb,
|
image: getLogoUrl('tmdb'),
|
||||||
name: 'api.tmdb.org',
|
name: 'api.tmdb.org',
|
||||||
url: 'https://api.tmdb.org/3/movie/550?api_key={TMDBAPIKEY}',
|
url: 'https://api.tmdb.org/3/movie/550?api_key={TMDBAPIKEY}',
|
||||||
proxy: true,
|
proxy: true,
|
||||||
@@ -56,7 +49,7 @@ const targets = ref<Address[]>([
|
|||||||
btndisable: false,
|
btndisable: false,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
image: tmdb,
|
image: getLogoUrl('tmdb'),
|
||||||
name: 'www.themoviedb.org',
|
name: 'www.themoviedb.org',
|
||||||
url: 'https://www.themoviedb.org',
|
url: 'https://www.themoviedb.org',
|
||||||
proxy: true,
|
proxy: true,
|
||||||
@@ -76,7 +69,7 @@ const targets = ref<Address[]>([
|
|||||||
btndisable: false,
|
btndisable: false,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
image: fanart,
|
image: getLogoUrl('fanart'),
|
||||||
name: 'webservice.fanart.tv',
|
name: 'webservice.fanart.tv',
|
||||||
url: 'https://webservice.fanart.tv',
|
url: 'https://webservice.fanart.tv',
|
||||||
proxy: true,
|
proxy: true,
|
||||||
@@ -86,7 +79,7 @@ const targets = ref<Address[]>([
|
|||||||
btndisable: false,
|
btndisable: false,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
image: telegram,
|
image: getLogoUrl('telegram'),
|
||||||
name: 'api.telegram.org',
|
name: 'api.telegram.org',
|
||||||
url: 'https://api.telegram.org',
|
url: 'https://api.telegram.org',
|
||||||
proxy: true,
|
proxy: true,
|
||||||
@@ -96,7 +89,7 @@ const targets = ref<Address[]>([
|
|||||||
btndisable: false,
|
btndisable: false,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
image: wechat,
|
image: getLogoUrl('wechat'),
|
||||||
name: 'qyapi.weixin.qq.com',
|
name: 'qyapi.weixin.qq.com',
|
||||||
url: 'https://qyapi.weixin.qq.com/cgi-bin/gettoken',
|
url: 'https://qyapi.weixin.qq.com/cgi-bin/gettoken',
|
||||||
proxy: false,
|
proxy: false,
|
||||||
@@ -106,7 +99,7 @@ const targets = ref<Address[]>([
|
|||||||
btndisable: false,
|
btndisable: false,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
image: douban,
|
image: getLogoUrl('douban'),
|
||||||
name: 'frodo.douban.com',
|
name: 'frodo.douban.com',
|
||||||
url: 'https://frodo.douban.com',
|
url: 'https://frodo.douban.com',
|
||||||
proxy: false,
|
proxy: false,
|
||||||
@@ -116,7 +109,7 @@ const targets = ref<Address[]>([
|
|||||||
btndisable: false,
|
btndisable: false,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
image: slack,
|
image: getLogoUrl('slack'),
|
||||||
name: 'slack.com',
|
name: 'slack.com',
|
||||||
url: 'https://slack.com',
|
url: 'https://slack.com',
|
||||||
proxy: false,
|
proxy: false,
|
||||||
@@ -126,7 +119,7 @@ const targets = ref<Address[]>([
|
|||||||
btndisable: false,
|
btndisable: false,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
image: python,
|
image: getLogoUrl('python'),
|
||||||
name: 'pypi.org',
|
name: 'pypi.org',
|
||||||
url: '{PIP_PROXY}rsa/',
|
url: '{PIP_PROXY}rsa/',
|
||||||
proxy: true,
|
proxy: true,
|
||||||
@@ -137,7 +130,7 @@ const targets = ref<Address[]>([
|
|||||||
include: 'pypi:repository-version',
|
include: 'pypi:repository-version',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
image: github,
|
image: getLogoUrl('github'),
|
||||||
name: 'github.com',
|
name: 'github.com',
|
||||||
url: '{GITHUB_PROXY}https://github.com/jxxghp/MoviePilot/blob/v2/README.md',
|
url: '{GITHUB_PROXY}https://github.com/jxxghp/MoviePilot/blob/v2/README.md',
|
||||||
proxy: true,
|
proxy: true,
|
||||||
@@ -148,7 +141,7 @@ const targets = ref<Address[]>([
|
|||||||
include: 'MoviePilot',
|
include: 'MoviePilot',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
image: github,
|
image: getLogoUrl('github'),
|
||||||
name: 'codeload.github.com',
|
name: 'codeload.github.com',
|
||||||
url: 'https://codeload.github.com',
|
url: 'https://codeload.github.com',
|
||||||
proxy: true,
|
proxy: true,
|
||||||
@@ -158,7 +151,7 @@ const targets = ref<Address[]>([
|
|||||||
btndisable: false,
|
btndisable: false,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
image: github,
|
image: getLogoUrl('github'),
|
||||||
name: 'api.github.com',
|
name: 'api.github.com',
|
||||||
url: 'https://api.github.com',
|
url: 'https://api.github.com',
|
||||||
proxy: true,
|
proxy: true,
|
||||||
@@ -168,7 +161,7 @@ const targets = ref<Address[]>([
|
|||||||
btndisable: false,
|
btndisable: false,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
image: github,
|
image: getLogoUrl('github'),
|
||||||
name: 'raw.githubusercontent.com',
|
name: 'raw.githubusercontent.com',
|
||||||
url: '{GITHUB_PROXY}https://raw.githubusercontent.com/jxxghp/MoviePilot/v2/README.md',
|
url: '{GITHUB_PROXY}https://raw.githubusercontent.com/jxxghp/MoviePilot/v2/README.md',
|
||||||
proxy: true,
|
proxy: true,
|
||||||
@@ -188,7 +181,7 @@ const resolveStatusColor: Status = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const abortControllers = new Set<AbortController>()
|
const abortControllers = new Set<AbortController>()
|
||||||
const isUnmounting = ref(false);
|
const isUnmounting = ref(false)
|
||||||
|
|
||||||
// 调用API测试网络连接
|
// 调用API测试网络连接
|
||||||
async function netTest(index: number) {
|
async function netTest(index: number) {
|
||||||
@@ -229,17 +222,16 @@ async function netTest(index: number) {
|
|||||||
|
|
||||||
// 加载时测试所有连接
|
// 加载时测试所有连接
|
||||||
onMounted(async () => {
|
onMounted(async () => {
|
||||||
isUnmounting.value = false;
|
isUnmounting.value = false
|
||||||
for (let i = 0; !isUnmounting.value && i < targets.value.length; i++)
|
for (let i = 0; !isUnmounting.value && i < targets.value.length; i++) await netTest(i)
|
||||||
await netTest(i)
|
|
||||||
})
|
})
|
||||||
onBeforeUnmount(() => {
|
onBeforeUnmount(() => {
|
||||||
isUnmounting.value = true;
|
isUnmounting.value = true
|
||||||
for (const controller of abortControllers) {
|
for (const controller of abortControllers) {
|
||||||
controller.abort()
|
controller.abort()
|
||||||
}
|
}
|
||||||
abortControllers.clear()
|
abortControllers.clear()
|
||||||
});
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
|
|||||||
Reference in New Issue
Block a user