mirror of
https://github.com/jxxghp/MoviePilot-Frontend.git
synced 2026-09-06 16:16:42 +08:00
fix 规则导入
This commit is contained in:
@@ -1,13 +1,10 @@
|
|||||||
// 请求和获取剪切板内容
|
// 请求和获取剪贴板内容
|
||||||
export async function getClipboardContent() {
|
export async function getClipboardContent() {
|
||||||
try {
|
if (navigator.clipboard && window.isSecureContext) {
|
||||||
return await navigator.clipboard.readText()
|
return await navigator.clipboard.readText()
|
||||||
}
|
}
|
||||||
catch (error) {
|
else {
|
||||||
console.error('Unable to read clipboard using navigator.clipboard:', error)
|
const input = document.createElement('textarea')
|
||||||
|
|
||||||
// Fallback for older browsers or non-secure context
|
|
||||||
const input = document.createElement('input')
|
|
||||||
document.body.appendChild(input)
|
document.body.appendChild(input)
|
||||||
input.select()
|
input.select()
|
||||||
document.execCommand('paste')
|
document.execCommand('paste')
|
||||||
@@ -17,16 +14,13 @@ export async function getClipboardContent() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 将内容复制到剪切板,兼容非安全域场景
|
// 将内容复制到剪贴板,兼容非安全域场景
|
||||||
export async function copyToClipboard(content: string) {
|
export async function copyToClipboard(content: string) {
|
||||||
try {
|
if (navigator.clipboard && window.isSecureContext) {
|
||||||
await navigator.clipboard.writeText(content)
|
await navigator.clipboard.writeText(content)
|
||||||
}
|
}
|
||||||
catch (error) {
|
else {
|
||||||
console.error('Unable to write to clipboard using navigator.clipboard:', error)
|
const input = document.createElement('textarea')
|
||||||
|
|
||||||
// Fallback for older browsers or non-secure context
|
|
||||||
const input = document.createElement('input')
|
|
||||||
input.value = content
|
input.value = content
|
||||||
document.body.appendChild(input)
|
document.body.appendChild(input)
|
||||||
input.select()
|
input.select()
|
||||||
|
|||||||
@@ -25,7 +25,6 @@ const tmdbKeyword = ref<HTMLElement | null>(null)
|
|||||||
|
|
||||||
// 选中条目
|
// 选中条目
|
||||||
function selectMedia(item: TmdbItem) {
|
function selectMedia(item: TmdbItem) {
|
||||||
console.log(item)
|
|
||||||
emit('update:modelValue', item.tmdbid)
|
emit('update:modelValue', item.tmdbid)
|
||||||
emit('close')
|
emit('close')
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,39 @@
|
|||||||
|
<script lang="ts" setup>
|
||||||
|
// 输入参数
|
||||||
|
const props = defineProps({
|
||||||
|
title: String,
|
||||||
|
})
|
||||||
|
|
||||||
|
// 定义事件
|
||||||
|
const emit = defineEmits(['update:modelValue', 'close'])
|
||||||
|
|
||||||
|
// 代码
|
||||||
|
const codeString = ref('')
|
||||||
|
|
||||||
|
// 导入
|
||||||
|
function handleImport() {
|
||||||
|
emit('update:modelValue', codeString.value)
|
||||||
|
emit('close')
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<VCard
|
||||||
|
:title="props.title"
|
||||||
|
class="rounded-t"
|
||||||
|
>
|
||||||
|
<DialogCloseBtn @click="emit('close')" />
|
||||||
|
<VCardText class="pt-2">
|
||||||
|
<VTextarea v-model="codeString" />
|
||||||
|
</VCardText>
|
||||||
|
<VCardActions>
|
||||||
|
<VSpacer />
|
||||||
|
<VBtn
|
||||||
|
variant="tonal"
|
||||||
|
@click="handleImport"
|
||||||
|
>
|
||||||
|
导入
|
||||||
|
</VBtn>
|
||||||
|
</VCardActions>
|
||||||
|
</VCard>
|
||||||
|
</template>
|
||||||
@@ -3,7 +3,8 @@ import { useToast } from 'vue-toast-notification'
|
|||||||
import api from '@/api'
|
import api from '@/api'
|
||||||
import FilterRuleCard from '@/components/cards/FilterRuleCard.vue'
|
import FilterRuleCard from '@/components/cards/FilterRuleCard.vue'
|
||||||
import type { Site } from '@/api/types'
|
import type { Site } from '@/api/types'
|
||||||
import { copyToClipboard, getClipboardContent } from '@/@core/utils/navigator'
|
import { copyToClipboard } from '@/@core/utils/navigator'
|
||||||
|
import ImportCodeForm from '@/components/form/ImportCodeForm.vue'
|
||||||
|
|
||||||
// 规则卡片类型
|
// 规则卡片类型
|
||||||
interface FilterCard {
|
interface FilterCard {
|
||||||
@@ -31,6 +32,12 @@ const defaultFilterRules = ref({
|
|||||||
exclude: '',
|
exclude: '',
|
||||||
})
|
})
|
||||||
|
|
||||||
|
// 导入代码弹窗
|
||||||
|
const importCodeDialog = ref(false)
|
||||||
|
|
||||||
|
// 导入的代码
|
||||||
|
const importCodeString = ref('')
|
||||||
|
|
||||||
// 查询已设置优先级规则
|
// 查询已设置优先级规则
|
||||||
async function queryCustomFilters() {
|
async function queryCustomFilters() {
|
||||||
try {
|
try {
|
||||||
@@ -240,35 +247,30 @@ function shareRules() {
|
|||||||
.map(card => card.rules.join('&'))
|
.map(card => card.rules.join('&'))
|
||||||
.join('>')
|
.join('>')
|
||||||
|
|
||||||
// 复制到剪切板
|
// 复制到剪贴板
|
||||||
try {
|
try {
|
||||||
copyToClipboard(value)
|
copyToClipboard(value)
|
||||||
$toast.success('优先级规则已复制到剪切板')
|
$toast.success('优先级规则已复制到剪贴板')
|
||||||
}
|
}
|
||||||
catch (error) {
|
catch (error) {
|
||||||
$toast.error('优先级规则复制失败!')
|
$toast.error('优先级规则复制失败!')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 导入规则
|
// 监听导入代码变化
|
||||||
async function importRules() {
|
watchEffect(() => {
|
||||||
try {
|
if (!importCodeString.value)
|
||||||
// 从剪切板读取
|
return
|
||||||
const value = await getClipboardContent()
|
|
||||||
// 分割成数组
|
// 将导入的代码转换为规则卡片
|
||||||
const groups = value.split('>')
|
const groups = importCodeString.value.split('>')
|
||||||
// 生成规则卡片
|
filterCards.value = groups.map((group: string, index: number) => {
|
||||||
filterCards.value = groups?.map((group: string, index: number) => {
|
return {
|
||||||
return {
|
pri: (index + 1).toString(),
|
||||||
pri: (index + 1).toString(),
|
rules: group.split('&'),
|
||||||
rules: group.split('&'),
|
}
|
||||||
}
|
})
|
||||||
})
|
})
|
||||||
}
|
|
||||||
catch (error) {
|
|
||||||
$toast.error('从剪切板读取数据失败!')
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
queryCustomFilters()
|
queryCustomFilters()
|
||||||
@@ -322,16 +324,16 @@ onMounted(() => {
|
|||||||
<template #prepend>
|
<template #prepend>
|
||||||
<VIcon icon="mdi-share" />
|
<VIcon icon="mdi-share" />
|
||||||
</template>
|
</template>
|
||||||
<VListItemTitle>分享规则</VListItemTitle>
|
<VListItemTitle>分享</VListItemTitle>
|
||||||
</VListItem>
|
</VListItem>
|
||||||
<VListItem
|
<VListItem
|
||||||
variant="plain"
|
variant="plain"
|
||||||
@click="importRules"
|
@click="importCodeDialog = true"
|
||||||
>
|
>
|
||||||
<template #prepend>
|
<template #prepend>
|
||||||
<VIcon icon="mdi-import" />
|
<VIcon icon="mdi-import" />
|
||||||
</template>
|
</template>
|
||||||
<VListItemTitle>从剪切板导入</VListItemTitle>
|
<VListItemTitle>导入</VListItemTitle>
|
||||||
</VListItem>
|
</VListItem>
|
||||||
</VList>
|
</VList>
|
||||||
</VMenu>
|
</VMenu>
|
||||||
@@ -405,6 +407,17 @@ onMounted(() => {
|
|||||||
</VCard>
|
</VCard>
|
||||||
</VCol>
|
</VCol>
|
||||||
</VRow>
|
</VRow>
|
||||||
|
<VDialog
|
||||||
|
v-model="importCodeDialog"
|
||||||
|
width="60rem"
|
||||||
|
scrollable
|
||||||
|
>
|
||||||
|
<ImportCodeForm
|
||||||
|
v-model="importCodeString"
|
||||||
|
title="导入优先级规则"
|
||||||
|
@close="importCodeDialog = false"
|
||||||
|
/>
|
||||||
|
</VDialog>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<style lang="scss">
|
<style lang="scss">
|
||||||
|
|||||||
@@ -3,7 +3,8 @@ import { useToast } from 'vue-toast-notification'
|
|||||||
import api from '@/api'
|
import api from '@/api'
|
||||||
import FilterRuleCard from '@/components/cards/FilterRuleCard.vue'
|
import FilterRuleCard from '@/components/cards/FilterRuleCard.vue'
|
||||||
import type { Site } from '@/api/types'
|
import type { Site } from '@/api/types'
|
||||||
import { copyToClipboard, getClipboardContent } from '@/@core/utils/navigator'
|
import { copyToClipboard } from '@/@core/utils/navigator'
|
||||||
|
import ImportCodeForm from '@/components/form/ImportCodeForm.vue'
|
||||||
|
|
||||||
// 规则卡片类型
|
// 规则卡片类型
|
||||||
interface FilterCard {
|
interface FilterCard {
|
||||||
@@ -28,12 +29,21 @@ const allSites = ref<Site[]>([])
|
|||||||
// 选中订阅站点
|
// 选中订阅站点
|
||||||
const selectedRssSites = ref<number[]>([])
|
const selectedRssSites = ref<number[]>([])
|
||||||
|
|
||||||
|
// 当前规则类型
|
||||||
|
const currentRuleType = ref('SubscribeFilterRules')
|
||||||
|
|
||||||
// 包含与排除规则
|
// 包含与排除规则
|
||||||
const defaultFilterRules = ref({
|
const defaultFilterRules = ref({
|
||||||
include: '',
|
include: '',
|
||||||
exclude: '',
|
exclude: '',
|
||||||
})
|
})
|
||||||
|
|
||||||
|
// 导入代码弹窗
|
||||||
|
const importCodeDialog = ref(false)
|
||||||
|
|
||||||
|
// 导入的代码
|
||||||
|
const importCodeString = ref('')
|
||||||
|
|
||||||
// 查询用户选中的订阅站点
|
// 查询用户选中的订阅站点
|
||||||
async function querySelectedRssSites() {
|
async function querySelectedRssSites() {
|
||||||
try {
|
try {
|
||||||
@@ -262,10 +272,10 @@ function shareRules(ruleType: string) {
|
|||||||
.map(card => card.rules.join('&'))
|
.map(card => card.rules.join('&'))
|
||||||
.join('>')
|
.join('>')
|
||||||
|
|
||||||
// 复制到剪切板
|
// 复制到剪贴板
|
||||||
try {
|
try {
|
||||||
copyToClipboard(value)
|
copyToClipboard(value)
|
||||||
$toast.success('优先级规则已复制到剪切板')
|
$toast.success('优先级规则已复制到剪贴板')
|
||||||
}
|
}
|
||||||
catch (error) {
|
catch (error) {
|
||||||
$toast.error('优先级规则复制失败!')
|
$toast.error('优先级规则复制失败!')
|
||||||
@@ -274,28 +284,31 @@ function shareRules(ruleType: string) {
|
|||||||
|
|
||||||
// 导入规则
|
// 导入规则
|
||||||
async function importRules(ruleType: string) {
|
async function importRules(ruleType: string) {
|
||||||
|
currentRuleType.value = ruleType
|
||||||
|
importCodeString.value = ''
|
||||||
|
importCodeDialog.value = true
|
||||||
|
}
|
||||||
|
|
||||||
|
// 监听导入代码变化
|
||||||
|
watchEffect(() => {
|
||||||
|
if (!importCodeString.value)
|
||||||
|
return
|
||||||
|
if (!currentRuleType.value)
|
||||||
|
return
|
||||||
let filterCards: Ref<FilterCard[]>
|
let filterCards: Ref<FilterCard[]>
|
||||||
if (ruleType === 'SubscribeFilterRules')
|
if (currentRuleType.value === 'SubscribeFilterRules')
|
||||||
filterCards = subscribeFilterCards
|
filterCards = subscribeFilterCards
|
||||||
else
|
else
|
||||||
filterCards = bestVersionFilterCards
|
filterCards = bestVersionFilterCards
|
||||||
try {
|
// 将导入的代码转换为规则卡片
|
||||||
// 从剪切板读取
|
const groups = importCodeString.value.split('>')
|
||||||
const value = await getClipboardContent()
|
filterCards.value = groups.map((group: string, index: number) => {
|
||||||
// 分割成数组
|
return {
|
||||||
const groups = value.split('>')
|
pri: (index + 1).toString(),
|
||||||
// 生成规则卡片
|
rules: group.split('&'),
|
||||||
filterCards.value = groups?.map((group: string, index: number) => {
|
}
|
||||||
return {
|
})
|
||||||
pri: (index + 1).toString(),
|
})
|
||||||
rules: group.split('&'),
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
catch (error) {
|
|
||||||
$toast.error('从剪切板读取数据失败!')
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
querySites()
|
querySites()
|
||||||
@@ -350,7 +363,7 @@ onMounted(() => {
|
|||||||
<template #prepend>
|
<template #prepend>
|
||||||
<VIcon icon="mdi-share" />
|
<VIcon icon="mdi-share" />
|
||||||
</template>
|
</template>
|
||||||
<VListItemTitle>分享规则</VListItemTitle>
|
<VListItemTitle>分享</VListItemTitle>
|
||||||
</VListItem>
|
</VListItem>
|
||||||
<VListItem
|
<VListItem
|
||||||
variant="plain"
|
variant="plain"
|
||||||
@@ -359,7 +372,7 @@ onMounted(() => {
|
|||||||
<template #prepend>
|
<template #prepend>
|
||||||
<VIcon icon="mdi-import" />
|
<VIcon icon="mdi-import" />
|
||||||
</template>
|
</template>
|
||||||
<VListItemTitle>从剪切板导入</VListItemTitle>
|
<VListItemTitle>导入</VListItemTitle>
|
||||||
</VListItem>
|
</VListItem>
|
||||||
</VList>
|
</VList>
|
||||||
</VMenu>
|
</VMenu>
|
||||||
@@ -416,7 +429,7 @@ onMounted(() => {
|
|||||||
<template #prepend>
|
<template #prepend>
|
||||||
<VIcon icon="mdi-share" />
|
<VIcon icon="mdi-share" />
|
||||||
</template>
|
</template>
|
||||||
<VListItemTitle>分享规则</VListItemTitle>
|
<VListItemTitle>分享</VListItemTitle>
|
||||||
</VListItem>
|
</VListItem>
|
||||||
<VListItem
|
<VListItem
|
||||||
variant="plain"
|
variant="plain"
|
||||||
@@ -425,7 +438,7 @@ onMounted(() => {
|
|||||||
<template #prepend>
|
<template #prepend>
|
||||||
<VIcon icon="mdi-import" />
|
<VIcon icon="mdi-import" />
|
||||||
</template>
|
</template>
|
||||||
<VListItemTitle>从剪切板导入</VListItemTitle>
|
<VListItemTitle>导入</VListItemTitle>
|
||||||
</VListItem>
|
</VListItem>
|
||||||
</VList>
|
</VList>
|
||||||
</VMenu>
|
</VMenu>
|
||||||
@@ -499,6 +512,17 @@ onMounted(() => {
|
|||||||
</VCard>
|
</VCard>
|
||||||
</VCol>
|
</VCol>
|
||||||
</VRow>
|
</VRow>
|
||||||
|
<VDialog
|
||||||
|
v-model="importCodeDialog"
|
||||||
|
width="60rem"
|
||||||
|
scrollable
|
||||||
|
>
|
||||||
|
<ImportCodeForm
|
||||||
|
v-model="importCodeString"
|
||||||
|
title="导入优先级规则"
|
||||||
|
@close="importCodeDialog = false"
|
||||||
|
/>
|
||||||
|
</VDialog>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<style lang="scss">
|
<style lang="scss">
|
||||||
|
|||||||
Reference in New Issue
Block a user