mirror of
https://git.mirrors.martin98.com/https://github.com/sub-store-org/Sub-Store.git
synced 2025-08-12 02:39:03 +08:00
feat: add preview specific platform feature (#131)
This commit is contained in:
parent
013b2173fd
commit
9202437f05
14065
backend/package-lock.json
generated
14065
backend/package-lock.json
generated
File diff suppressed because it is too large
Load Diff
2
web/.gitignore
vendored
2
web/.gitignore
vendored
@ -1,7 +1,7 @@
|
||||
.DS_Store
|
||||
node_modules
|
||||
/dist
|
||||
|
||||
yarn.lock
|
||||
|
||||
# local env files
|
||||
.env.local
|
||||
|
3
web/.prettierignore
Normal file
3
web/.prettierignore
Normal file
@ -0,0 +1,3 @@
|
||||
# Ignore artifacts:
|
||||
build
|
||||
coverage
|
47
web/.prettierrc.yaml
Normal file
47
web/.prettierrc.yaml
Normal file
@ -0,0 +1,47 @@
|
||||
printWidth : 80 # 显示宽度
|
||||
tabWidth : 2 # tab 宽度
|
||||
useTabs : false # 使用 tab 而不是空格
|
||||
semi : false # 使用分号
|
||||
singleQuote : true # 使用单引号
|
||||
jsxSingleQuote : false # 在 JSX 中使用单引号而不是双引号
|
||||
bracketSpacing : true # 在对象花括号内打印空格 true { foo: bar } false {foo: bar}
|
||||
arrowParens : "avoid" # 箭头函数只有一个参数的时候的周围的括号 "always" - (x) => x "avoid" - x => x
|
||||
embeddedLanguageFormatting : "auto" # "auto" - 嵌入代码如果 Prettier 可以识别则格式化它 "off" - 永远不要自动格式化
|
||||
bracketSameLine : false # 多行属性的 HTML(HTML、JSX、Vue、Angular)标签的 ">" 放在最后一行的末尾,而不是单独在下一行(不适用于自闭合元素)
|
||||
#htmlWhitespaceSensitivity : "strict"
|
||||
vueIndentScriptAndStyle : true # 在 Vue 文件中缩进 <script> 和 <style> 标签
|
||||
insertPragma : false # 是否插入一个特殊 @format 标记指定文件已使用 Prettier 格式化
|
||||
|
||||
# 行尾风格
|
||||
# "lf" – 仅换行 ( \n),常见于 Linux 和 macOS 以及 git repos 内部
|
||||
# "crlf" - 回车 + 换行字符 ( \r\n),常见于 Windows
|
||||
# "cr" - 仅回车字符 ( \r),很少使用
|
||||
# "auto" - 保持现有的行尾(一个文件中的混合值通过查看第一行之后使用的内容进行标准化)
|
||||
endOfLine : "lf"
|
||||
|
||||
# 需要提供注释才允许格式化
|
||||
# /**
|
||||
# * @prettier 或 @format
|
||||
# */
|
||||
requirePragma : false
|
||||
|
||||
# 对象属性的引号风格
|
||||
# "as-needed" 仅在需要时在对象属性周围添加引号
|
||||
# "consistent" 如果对象中至少一个属性需要引号,则所有属性都使用引号
|
||||
# "preserve" 尊重对象属性中的引号
|
||||
quoteProps : "consistent"
|
||||
|
||||
# 在多行逗号分隔的句法结构中尽可能打印尾随逗号
|
||||
# "es5" 在 ES5 中有效的尾随逗号(对象、数组等),TypeScript 中的类型参数中没有尾随逗号
|
||||
# "none" 没有尾随逗号。
|
||||
# "all" 尽可能使用尾随逗号(包括函数参数和调用)。要运行,以这种方式格式化的 JavaScript 代码需要一个支持 ES2017(Node.js 8+ 或现代浏览器)或下级编译的引擎。这还可以在 TypeScript 中的类型参数中启用尾随逗号(自 2018 年 1 月发布的 TypeScript 2.7 起支持)
|
||||
trailingComma : "es5"
|
||||
|
||||
# 例外配置覆盖
|
||||
overrides :
|
||||
- files :
|
||||
- "*.ts"
|
||||
- "*.tsx"
|
||||
options :
|
||||
semi : true
|
||||
arrowParens : "always"
|
@ -1,70 +1,64 @@
|
||||
<template>
|
||||
<div class="float-menu-switch-wrapper" ref = "floatMenuSwitch">
|
||||
<v-speed-dial
|
||||
v-model="fab"
|
||||
:direction="direction"
|
||||
:transition="transition"
|
||||
>
|
||||
<template v-slot:activator>
|
||||
<v-btn v-model="fab" color="primary" fab>
|
||||
<v-icon v-if="fab"> mdi-close</v-icon>
|
||||
<v-icon v-else> mdi-gesture-double-tap</v-icon>
|
||||
</v-btn>
|
||||
</template>
|
||||
<slot></slot>
|
||||
</v-speed-dial>
|
||||
<div class = "float-menu-switch-wrapper" ref = "floatMenuSwitch">
|
||||
<v-speed-dial v-model = "fab" :direction = "direction" :transition = "transition"
|
||||
>
|
||||
<template v-slot:activator>
|
||||
<v-btn v-model = "fab" color = "primary" fab>
|
||||
<v-icon v-if = "fab"> mdi-close</v-icon>
|
||||
<v-icon v-else> mdi-gesture-double-tap</v-icon>
|
||||
</v-btn>
|
||||
</template>
|
||||
<slot></slot>
|
||||
</v-speed-dial>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
export default {
|
||||
name: "FloatMenu",
|
||||
data() {
|
||||
return {
|
||||
direction: "top",
|
||||
fab: false,
|
||||
fling: false,
|
||||
hover: false,
|
||||
tabs: null,
|
||||
transition: "scale-transition",
|
||||
};
|
||||
},
|
||||
|
||||
updated (){
|
||||
const floatMenuSwitch = this.$refs.floatMenuSwitch;
|
||||
console.log(floatMenuSwitch);
|
||||
floatMenuSwitch.style.bottom = 2*this.bottomNavBarHeight + "px";
|
||||
},
|
||||
|
||||
computed : {
|
||||
bottomNavBarHeight (){
|
||||
return this.$store.state.bottomNavBarHeight;
|
||||
export default {
|
||||
name : "FloatMenu",
|
||||
data (){
|
||||
return {
|
||||
direction : "top",
|
||||
fab : false,
|
||||
fling : false,
|
||||
hover : false,
|
||||
tabs : null,
|
||||
transition : "scale-transition",
|
||||
};
|
||||
},
|
||||
},
|
||||
};
|
||||
updated (){
|
||||
const floatMenuSwitch = this.$refs.floatMenuSwitch;
|
||||
floatMenuSwitch.style.bottom = 2 * this.bottomNavBarHeight + "px";
|
||||
},
|
||||
computed : {
|
||||
bottomNavBarHeight (){
|
||||
return this.$store.state.bottomNavBarHeight;
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
<style lang = "scss" scoped>
|
||||
.float-menu-switch-wrapper {
|
||||
position : fixed;
|
||||
right: 16px;;
|
||||
right : 16px;;
|
||||
z-index : 99;
|
||||
|
||||
.v-speed-dial > button.v-btn.v-btn--round {
|
||||
margin-right : 0;
|
||||
width : 40px;
|
||||
height : 40px;
|
||||
}
|
||||
margin-right : 0;
|
||||
width : 40px;
|
||||
height : 40px;
|
||||
}
|
||||
|
||||
::v-deep .v-speed-dial__list button.theme--light.v-btn {
|
||||
margin-right : 0;
|
||||
}
|
||||
}
|
||||
::v-deep .v-speed-dial__list button.theme--light.v-btn {
|
||||
margin-right : 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* This is for documentation purposes and will not be needed in your application */
|
||||
#create .v-speed-dial {
|
||||
position: absolute;
|
||||
}
|
||||
/* This is for documentation purposes and will not be needed in your application */
|
||||
#create .v-speed-dial {
|
||||
position : absolute;
|
||||
}
|
||||
|
||||
#create .v-btn--floating {
|
||||
position: relative;
|
||||
}
|
||||
#create .v-btn--floating {
|
||||
position : relative;
|
||||
}
|
||||
</style>
|
||||
|
@ -1,39 +1,74 @@
|
||||
<template>
|
||||
<v-container fluid>
|
||||
<v-dialog v-model = "showPreviewDialog" scrollable>
|
||||
<v-card>
|
||||
<v-card-title>预览转换结果</v-card-title>
|
||||
<v-divider></v-divider>
|
||||
<v-list flat>
|
||||
<v-list-item v-for = "platform in platformList" :key = "platform.name"
|
||||
@click = "previewSpecificPlatform(platform.path)"
|
||||
>
|
||||
|
||||
<v-list-item-avatar>
|
||||
<v-img :class = "getIconClass('#invert')" :src = "platform.icon"
|
||||
/>
|
||||
</v-list-item-avatar>
|
||||
<v-list-item-content>
|
||||
<v-list-item-title v-text = "platform.name"></v-list-item-title>
|
||||
</v-list-item-content>
|
||||
</v-list-item>
|
||||
</v-list>
|
||||
<v-card-actions>
|
||||
<v-spacer></v-spacer>
|
||||
<v-btn text @click = "showPreviewDialog = false">取消</v-btn>
|
||||
</v-card-actions>
|
||||
</v-card>
|
||||
</v-dialog>
|
||||
|
||||
<v-card>
|
||||
<v-card-title>
|
||||
<v-icon left>local_airport</v-icon>
|
||||
单个订阅
|
||||
<v-spacer></v-spacer>
|
||||
<v-btn icon @click="createSub">
|
||||
<v-icon color="primary">mdi-plus-circle</v-icon>
|
||||
<v-btn icon @click = "createSub">
|
||||
<v-icon color = "primary">mdi-plus-circle</v-icon>
|
||||
</v-btn>
|
||||
</v-card-title>
|
||||
<v-card-text>
|
||||
<v-list dense>
|
||||
<v-list-item v-for="sub in subscriptions" :key="sub.name" @click="preview(sub)">
|
||||
<v-list-item v-for = "sub in subscriptions" :key = "sub.name"
|
||||
@click = "preview(sub)"
|
||||
>
|
||||
<v-list-item-avatar>
|
||||
<v-icon v-if="!sub.icon" color="teal darken-1">mdi-cloud</v-icon>
|
||||
<v-img v-else :class="getIconClass(sub.icon)" :src="sub.icon" />
|
||||
<v-icon v-if = "!sub.icon" color = "teal darken-1">mdi-cloud
|
||||
</v-icon>
|
||||
<v-img v-else :class = "getIconClass(sub.icon)"
|
||||
:src = "sub.icon"
|
||||
/>
|
||||
</v-list-item-avatar>
|
||||
|
||||
<v-list-item-content>
|
||||
<v-list-item-title class="font-weight-medium" v-text="sub['display-name'] || sub.name">
|
||||
</v-list-item-title>
|
||||
<v-list-item-title v-text="sub.url"></v-list-item-title>
|
||||
<v-list-item-title class = "font-weight-medium"
|
||||
v-text = "sub['display-name'] || sub.name"
|
||||
></v-list-item-title>
|
||||
<v-list-item-title v-text = "sub.url"></v-list-item-title>
|
||||
</v-list-item-content>
|
||||
<v-list-item-action>
|
||||
<v-menu bottom left>
|
||||
<template v-slot:activator="{ on, attrs }">
|
||||
<v-btn v-bind="attrs" v-on="on" icon>
|
||||
<template v-slot:activator = "{ on, attrs }">
|
||||
<v-btn v-bind = "attrs" v-on = "on" icon>
|
||||
<v-icon>mdi-dots-vertical</v-icon>
|
||||
</v-btn>
|
||||
</template>
|
||||
|
||||
<v-list>
|
||||
<v-list-item v-for="(menuItem, i) in editMenu" :key="i"
|
||||
@click="subscriptionMenu(menuItem.action, sub)">
|
||||
<v-list-item-content>{{ menuItem.title }}</v-list-item-content>
|
||||
<v-list-item v-for = "(menuItem, i) in editMenu" :key = "i"
|
||||
@click = "subscriptionMenu(menuItem.action, sub)"
|
||||
>
|
||||
<v-list-item-content>{{
|
||||
menuItem.title
|
||||
}}
|
||||
</v-list-item-content>
|
||||
</v-list-item>
|
||||
</v-list>
|
||||
</v-menu>
|
||||
@ -48,39 +83,52 @@
|
||||
<v-icon left>work_outline</v-icon>
|
||||
组合订阅
|
||||
<v-spacer></v-spacer>
|
||||
<v-btn icon @click="createCol">
|
||||
<v-icon color="primary">mdi-plus-circle</v-icon>
|
||||
<v-btn icon @click = "createCol">
|
||||
<v-icon color = "primary">mdi-plus-circle</v-icon>
|
||||
</v-btn>
|
||||
</v-card-title>
|
||||
<v-card-text>
|
||||
<v-list dense>
|
||||
<v-list-item v-for="collection in collections" :key="collection.name" dense
|
||||
@click="preview(collection, type='collection')">
|
||||
<v-list-item v-for = "collection in collections"
|
||||
:key = "collection.name" dense
|
||||
@click = "preview(collection, type='collection')"
|
||||
>
|
||||
<v-list-item-avatar>
|
||||
<v-icon v-if="!collection.icon" color="teal darken-1">mdi-cloud</v-icon>
|
||||
<v-img v-else :class="getIconClass(collection.icon)" :src="collection.icon" />
|
||||
<v-icon v-if = "!collection.icon" color = "teal darken-1">
|
||||
mdi-cloud
|
||||
</v-icon>
|
||||
<v-img v-else :class = "getIconClass(collection.icon)"
|
||||
:src = "collection.icon"
|
||||
/>
|
||||
</v-list-item-avatar>
|
||||
<v-list-item-content>
|
||||
<v-list-item-title class="font-weight-medium" v-text="collection['display-name'] || collection.name">
|
||||
</v-list-item-title>
|
||||
<v-list-item-title class = "font-weight-medium"
|
||||
v-text = "collection['display-name'] || collection.name"
|
||||
></v-list-item-title>
|
||||
<v-chip-group column>
|
||||
<v-chip v-for="subs in collection.subsInfo" :key="subs.name" class="ma-2 ml-0 mr-1 pa-2" label small>
|
||||
{{ subs['display-name'] || subs.name}}
|
||||
<v-chip v-for = "subs in collection.subsInfo" :key = "subs.name"
|
||||
class = "ma-2 ml-0 mr-1 pa-2" label small
|
||||
>
|
||||
{{ subs['display-name'] || subs.name }}
|
||||
</v-chip>
|
||||
</v-chip-group>
|
||||
</v-list-item-content>
|
||||
<v-list-item-action>
|
||||
<v-menu bottom left>
|
||||
<template v-slot:activator="{ on, attrs }">
|
||||
<v-btn v-bind="attrs" v-on="on" icon>
|
||||
<template v-slot:activator = "{ on, attrs }">
|
||||
<v-btn v-bind = "attrs" v-on = "on" icon>
|
||||
<v-icon>mdi-dots-vertical</v-icon>
|
||||
</v-btn>
|
||||
</template>
|
||||
|
||||
<v-list>
|
||||
<v-list-item v-for="(menuItem, i) in editMenu" :key="i"
|
||||
@click="collectionMenu(menuItem.action, collection)">
|
||||
<v-list-item-content>{{ menuItem.title }}</v-list-item-content>
|
||||
<v-list-item v-for = "(menuItem, i) in editMenu" :key = "i"
|
||||
@click = "collectionMenu(menuItem.action, collection)"
|
||||
>
|
||||
<v-list-item-content>{{
|
||||
menuItem.title
|
||||
}}
|
||||
</v-list-item-content>
|
||||
</v-list-item>
|
||||
</v-list>
|
||||
</v-menu>
|
||||
@ -89,9 +137,11 @@
|
||||
</v-list>
|
||||
</v-card-text>
|
||||
</v-card>
|
||||
<v-dialog v-model="showProxyList" fullscreen hide-overlay scrollable transition="dialog-bottom-transition">
|
||||
<v-dialog v-model = "showProxyList" fullscreen hide-overlay scrollable
|
||||
transition = "dialog-bottom-transition"
|
||||
>
|
||||
<v-card fluid>
|
||||
<v-toolbar class="flex-grow-0">
|
||||
<v-toolbar class = "flex-grow-0">
|
||||
<v-icon>mdi-dns</v-icon>
|
||||
<v-spacer></v-spacer>
|
||||
<v-toolbar-title>
|
||||
@ -99,29 +149,33 @@
|
||||
</v-toolbar-title>
|
||||
<v-spacer></v-spacer>
|
||||
<v-toolbar-items>
|
||||
<v-btn icon @click="showProxyList = false">
|
||||
<v-btn icon @click = "showProxyList = false">
|
||||
<v-icon>mdi-close</v-icon>
|
||||
</v-btn>
|
||||
</v-toolbar-items>
|
||||
<template v-slot:extension>
|
||||
<v-tabs v-model="tab" centered grow>
|
||||
<v-tabs-slider color="primary" />
|
||||
<v-tab key="raw">
|
||||
<v-tabs v-model = "tab" centered grow>
|
||||
<v-tabs-slider color = "primary" />
|
||||
<v-tab key = "raw">
|
||||
<h4>原始节点</h4>
|
||||
</v-tab>
|
||||
<v-tab key="processed">
|
||||
<v-tab key = "processed">
|
||||
<h4>生成节点</h4>
|
||||
</v-tab>
|
||||
</v-tabs>
|
||||
</template>
|
||||
</v-toolbar>
|
||||
<v-card-text>
|
||||
<v-tabs-items v-model="tab">
|
||||
<v-tab-item key="raw">
|
||||
<proxy-list :key="url + 'raw'" ref="proxyList" :raw="true" :sub="sub" :url="url"></proxy-list>
|
||||
<v-tabs-items v-model = "tab">
|
||||
<v-tab-item key = "raw">
|
||||
<proxy-list :key = "url + 'raw'" ref = "proxyList" :raw = "true"
|
||||
:sub = "sub" :url = "url"
|
||||
></proxy-list>
|
||||
</v-tab-item>
|
||||
<v-tab-item key="processed">
|
||||
<proxy-list :key="url" ref="proxyList" :sub="sub" :url="url"></proxy-list>
|
||||
<v-tab-item key = "processed">
|
||||
<proxy-list :key = "url" ref = "proxyList" :sub = "sub"
|
||||
:url = "url"
|
||||
></proxy-list>
|
||||
</v-tab-item>
|
||||
</v-tabs-items>
|
||||
</v-card-text>
|
||||
@ -131,129 +185,187 @@
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import ProxyList from "@/components/ProxyList";
|
||||
import {BACKEND_BASE} from "@/config";
|
||||
import ProxyList from '@/components/ProxyList'
|
||||
import { BACKEND_BASE } from '@/config'
|
||||
|
||||
export default {
|
||||
components: {ProxyList},
|
||||
data: () => {
|
||||
return {
|
||||
opened: false,
|
||||
showProxyList: false,
|
||||
url: "",
|
||||
sub: [],
|
||||
tab: 1,
|
||||
editMenu: [
|
||||
{
|
||||
title: "链接",
|
||||
action: "COPY"
|
||||
},
|
||||
{
|
||||
title: "编辑",
|
||||
action: "EDIT"
|
||||
},
|
||||
{
|
||||
title: "删除",
|
||||
action: "DELETE"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
export default {
|
||||
components : { ProxyList },
|
||||
data : () => {
|
||||
return {
|
||||
opened : false,
|
||||
showProxyList : false,
|
||||
showPreviewDialog : false,
|
||||
previewSubName : '',
|
||||
isCollectionPreview : false,
|
||||
url : '',
|
||||
sub : [],
|
||||
tab : 1,
|
||||
platformList : [
|
||||
{
|
||||
name : 'Clash',
|
||||
path : 'Clash',
|
||||
icon : 'https://raw.githubusercontent.com/58xinian/icon/master/clash_mini.png',
|
||||
},
|
||||
{
|
||||
name : 'Quantumult X',
|
||||
path : 'QX',
|
||||
icon : 'https://raw.githubusercontent.com/Orz-3/mini/none/quanX.png',
|
||||
},
|
||||
{
|
||||
name : 'Surge',
|
||||
path : 'Surge',
|
||||
icon : 'https://raw.githubusercontent.com/Orz-3/mini/none/surge.png',
|
||||
},
|
||||
{
|
||||
name : 'Loon',
|
||||
path : 'Loon',
|
||||
icon : 'https://raw.githubusercontent.com/Orz-3/mini/none/loon.png',
|
||||
},
|
||||
|
||||
computed: {
|
||||
subscriptionBaseURL() {
|
||||
return BACKEND_BASE;
|
||||
{
|
||||
name : 'Stash',
|
||||
path : 'Stash',
|
||||
icon : 'https://raw.githubusercontent.com/Orz-3/mini/master/Alpha/stash.png',
|
||||
}
|
||||
|
||||
],
|
||||
editMenu : [
|
||||
{
|
||||
title : '链接',
|
||||
action : 'COPY'
|
||||
},
|
||||
{
|
||||
title : '编辑',
|
||||
action : 'EDIT'
|
||||
},
|
||||
{
|
||||
title : '预览',
|
||||
action : 'PREVIEW'
|
||||
},
|
||||
{
|
||||
title : '删除',
|
||||
action : 'DELETE'
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
subscriptions: {
|
||||
get() {
|
||||
const subs = this.$store.state.subscriptions;
|
||||
return Object.keys(subs).map(k => subs[k]);
|
||||
|
||||
computed : {
|
||||
subscriptionBaseURL (){
|
||||
return BACKEND_BASE
|
||||
},
|
||||
set() {
|
||||
subscriptions : {
|
||||
get (){
|
||||
const subs = this.$store.state.subscriptions
|
||||
return Object.keys(subs).map(k => subs[k])
|
||||
},
|
||||
set (){
|
||||
|
||||
}
|
||||
}
|
||||
},
|
||||
collections (){
|
||||
const cols = this.$store.state.collections
|
||||
const collections = Object.keys(cols).map(k => cols[k])
|
||||
const subscriptions = this.$store.state.subscriptions
|
||||
collections.map(item => {
|
||||
item.subsInfo = []
|
||||
item.subscriptions.map(sub => item.subsInfo.push(subscriptions[sub]))
|
||||
})
|
||||
return collections
|
||||
},
|
||||
},
|
||||
collections() {
|
||||
const cols = this.$store.state.collections;
|
||||
const collections = Object.keys(cols).map(k => cols[k]);
|
||||
const subscriptions = this.$store.state.subscriptions;
|
||||
collections.map(item => {
|
||||
item.subsInfo = []
|
||||
item.subscriptions.map(sub => item.subsInfo.push(subscriptions[sub]))
|
||||
})
|
||||
return collections
|
||||
},
|
||||
},
|
||||
|
||||
methods: {
|
||||
subscriptionMenu(action, sub) {
|
||||
console.log(`${action} --> ${sub.name}`);
|
||||
switch (action) {
|
||||
case 'COPY':
|
||||
this.$clipboard(`${this.subscriptionBaseURL}/download/${encodeURIComponent(sub.name)}`);
|
||||
this.$store.commit("SET_SUCCESS_MESSAGE", "成功复制订阅链接");
|
||||
break
|
||||
case 'EDIT':
|
||||
this.$router.push(`/sub-edit/${encodeURIComponent(sub.name)}`);
|
||||
break
|
||||
case 'DELETE':
|
||||
this.$store.dispatch("DELETE_SUBSCRIPTION", encodeURIComponent(sub.name));
|
||||
break
|
||||
methods : {
|
||||
previewSpecificPlatform (path){
|
||||
window.open(`${this.subscriptionBaseURL}/download/${this.isCollectionPreview ? 'collection/' : ''}${this.previewSubName}?target=${path}`)
|
||||
this.showPreviewDialog = false
|
||||
},
|
||||
subscriptionMenu (action, sub){
|
||||
console.log(`${action} --> ${sub.name}`)
|
||||
switch (action){
|
||||
case 'COPY':
|
||||
this.$clipboard(
|
||||
`${this.subscriptionBaseURL}/download/${encodeURIComponent(
|
||||
sub.name)}`)
|
||||
this.$store.commit('SET_SUCCESS_MESSAGE', '成功复制订阅链接')
|
||||
break
|
||||
case 'EDIT':
|
||||
this.$router.push(`/sub-edit/${encodeURIComponent(sub.name)}`)
|
||||
break
|
||||
case 'PREVIEW':
|
||||
this.previewSubName = sub.name
|
||||
this.isCollectionPreview = false
|
||||
this.showPreviewDialog = true
|
||||
break
|
||||
case 'DELETE':
|
||||
this.$store.dispatch(
|
||||
'DELETE_SUBSCRIPTION', encodeURIComponent(sub.name))
|
||||
break
|
||||
}
|
||||
},
|
||||
collectionMenu (action, collection){
|
||||
console.log(`${action} --> ${collection.name}`)
|
||||
switch (action){
|
||||
case 'COPY':
|
||||
this.$clipboard(
|
||||
`${this.subscriptionBaseURL}/download/collection/${encodeURIComponent(
|
||||
collection.name)}`)
|
||||
this.$store.commit('SET_SUCCESS_MESSAGE', '成功复制订阅链接')
|
||||
break
|
||||
case 'EDIT':
|
||||
this.$router.push(`/collection-edit/${collection.name}`)
|
||||
break
|
||||
case 'PREVIEW':
|
||||
this.previewSubName = collection.name
|
||||
this.isCollectionPreview = true
|
||||
this.showPreviewDialog = true
|
||||
break
|
||||
case 'DELETE':
|
||||
this.$store.dispatch('DELETE_COLLECTION', collection.name)
|
||||
break
|
||||
}
|
||||
},
|
||||
preview (item, type = 'sub'){
|
||||
if (type === 'sub'){
|
||||
this.url = `${BACKEND_BASE}/download/${encodeURIComponent(
|
||||
item.name)}`
|
||||
this.sub = item.url
|
||||
} else{
|
||||
this.url = `${BACKEND_BASE}/download/collection/${encodeURIComponent(
|
||||
item.name)}`
|
||||
}
|
||||
this.showProxyList = true
|
||||
},
|
||||
createSub (){
|
||||
this.$router.push('/sub-edit/UNTITLED')
|
||||
},
|
||||
createCol (){
|
||||
this.$router.push('/collection-edit/UNTITLED')
|
||||
},
|
||||
async refreshProxyList (){
|
||||
try{
|
||||
await this.$refs.proxyList.refresh()
|
||||
this.$store.commit('SET_SUCCESS_MESSAGE', '刷新成功!')
|
||||
} catch (err){
|
||||
this.$store.commit('SET_ERROR_MESSAGE', err.response.data.message)
|
||||
}
|
||||
},
|
||||
getIconClass (url){
|
||||
return url.indexOf(
|
||||
'#invert') !== - 1 && !this.$vuetify.theme.dark ? 'invert' : ''
|
||||
}
|
||||
},
|
||||
collectionMenu(action, collection) {
|
||||
console.log(`${action} --> ${collection.name}`);
|
||||
switch (action) {
|
||||
case 'COPY':
|
||||
this.$clipboard(`${this.subscriptionBaseURL}/download/collection/${encodeURIComponent(collection.name)}`);
|
||||
this.$store.commit("SET_SUCCESS_MESSAGE", "成功复制订阅链接");
|
||||
break
|
||||
case 'EDIT':
|
||||
this.$router.push(`/collection-edit/${collection.name}`);
|
||||
break
|
||||
case 'DELETE':
|
||||
this.$store.dispatch("DELETE_COLLECTION", collection.name);
|
||||
break
|
||||
}
|
||||
},
|
||||
preview(item, type = 'sub') {
|
||||
if (type === 'sub') {
|
||||
this.url = `${BACKEND_BASE}/download/${encodeURIComponent(item.name)}`;
|
||||
this.sub = item.url;
|
||||
} else {
|
||||
this.url = `${BACKEND_BASE}/download/collection/${encodeURIComponent(item.name)}`
|
||||
}
|
||||
this.showProxyList = true;
|
||||
},
|
||||
createSub() {
|
||||
this.$router.push("/sub-edit/UNTITLED");
|
||||
},
|
||||
createCol() {
|
||||
this.$router.push("/collection-edit/UNTITLED")
|
||||
},
|
||||
async refreshProxyList() {
|
||||
try {
|
||||
await this.$refs.proxyList.refresh();
|
||||
this.$store.commit("SET_SUCCESS_MESSAGE", "刷新成功!");
|
||||
} catch (err) {
|
||||
this.$store.commit("SET_ERROR_MESSAGE", err.response.data.message);
|
||||
}
|
||||
},
|
||||
getIconClass(url) {
|
||||
return url.indexOf('#invert') !== -1 && !this.$vuetify.theme.dark ? 'invert' : ''
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.invert {
|
||||
filter: invert(100%);
|
||||
}
|
||||
.invert {
|
||||
filter : invert(100%);
|
||||
}
|
||||
|
||||
.v-dialog > .v-card > .v-toolbar {
|
||||
position: sticky;
|
||||
top: 0;
|
||||
z-index: 999;
|
||||
}
|
||||
</style>
|
||||
.v-dialog > .v-card > .v-toolbar {
|
||||
position : sticky;
|
||||
top : 0;
|
||||
z-index : 999;
|
||||
}
|
||||
</style>
|
||||
|
Loading…
x
Reference in New Issue
Block a user