新增在线自定义源导入功能,允许通过http/https链接导入自定义源

This commit is contained in:
lyswhut
2024-03-12 14:33:21 +08:00
parent 53245e9e4f
commit b14883c9af
6 changed files with 182 additions and 11 deletions
@@ -23,8 +23,10 @@ material-modal(:show="modelValue" bg-close teleport="#view" @close="handleClose"
span.hover.underline(aria-label="https://lxmusic.toside.cn/desktop/custom-source" @click="handleOpenUrl('https://lyswhut.github.io/lx-music-doc/desktop/custom-source')") FAQ
p {{ $t('user_api__note') }}
div(:class="$style.footer")
base-btn(:class="$style.footerBtn" @click="isShowOnlineImportModal = true") {{ $t('user_api__btn_import_online') }}
base-btn(:class="$style.footerBtn" @click="handleImport") {{ $t('user_api__btn_import') }}
//- base-btn(:class="$style.footerBtn" @click="handleExport") {{ $t('user_api__btn_export') }}
UserApiOnlineImportModal(v-model:show="isShowOnlineImportModal" @import="importUserApi")
</template>
<script>
@@ -34,8 +36,15 @@ import { openUrl } from '@common/utils/electron'
import apiSourceInfo from '@renderer/utils/musicSdk/api-source-info'
import { userApi } from '@renderer/store'
import { appSetting, updateSetting } from '@renderer/store/setting'
import { ref } from '@common/utils/vueTools'
import { dialog } from '@renderer/plugins/Dialog'
import UserApiOnlineImportModal from './UserApiOnlineImportModal.vue'
export default {
components: {
UserApiOnlineImportModal,
},
props: {
modelValue: {
type: Boolean,
@@ -44,9 +53,11 @@ export default {
},
emits: ['update:modelValue'],
setup() {
const isShowOnlineImportModal = ref(false)
return {
userApi,
appSetting,
isShowOnlineImportModal,
}
},
computed: {
@@ -55,6 +66,13 @@ export default {
},
},
methods: {
async importUserApi(script) {
return importUserApi(script).then(({ apiList }) => {
userApi.list = apiList
}).catch((err) => {
void dialog(this.$t('user_api_import__failed', { message: err.message }))
})
},
handleImport() {
if (this.userApi.list.length > 20) {
this.$dialog({
@@ -73,9 +91,7 @@ export default {
}).then(async result => {
if (result.canceled) return
return readFile(result.filePaths[0]).then(async data => {
return importUserApi(data.toString()).then(({ apiList }) => {
userApi.list = apiList
})
return this.importUserApi(data.toString())
})
})
},
@@ -110,8 +126,8 @@ export default {
@import '@renderer/assets/styles/layout.less';
.main {
padding: 15px;
max-width: 400px;
padding: 15px 8px;
max-width: 550px;
min-width: 300px;
display: flex;
flex-flow: column nowrap;
@@ -142,6 +158,7 @@ export default {
min-height: 100px;
max-height: 100%;
margin-top: 15px;
padding: 0 7px;
}
.listItem {
display: flex;
@@ -201,6 +218,7 @@ export default {
}
}
.note {
padding: 0 7px;
margin-top: 15px;
font-size: 12px;
line-height: 1.25;
@@ -212,6 +230,7 @@ export default {
}
}
.footer {
padding: 0 7px;
margin-top: 15px;
display: flex;
flex-flow: row nowrap;
@@ -0,0 +1,130 @@
<template>
<material-modal :show="show" teleport="#view" @close="handleClose" @after-enter="$refs.input.focus()">
<main :class="$style.main">
<h2>{{ $t('user_api_import_online__title') }}</h2>
<base-input
ref="input"
v-model="url"
:class="$style.input"
type="url"
:placeholder="$t('user_api_import_online__input_tip')"
@submit="handleSubmit" @blur="verify"
/>
<div :class="$style.footer">
<base-btn :class="$style.btn" @click="handleClose">{{ $t('btn_close') }}</base-btn>
<base-btn :class="$style.btn" :disabled="disabled" @click="handleSubmit">{{ btnText }}</base-btn>
</div>
</main>
</material-modal>
</template>
<script>
import { dialog } from '@renderer/plugins/Dialog'
import { httpFetch } from '@renderer/utils/request'
export default {
props: {
show: {
type: Boolean,
default: false,
},
},
emits: ['update:show', 'import'],
data() {
return {
url: '',
disabled: false,
btnText: '',
}
},
watch: {
show(n) {
if (n) {
this.url = ''
this.disabled = false
this.btnText = this.$t('user_api_import_online__input_confirm')
}
},
},
methods: {
handleClose() {
this.$emit('update:show', false)
},
verify() {
if (!/^https?:\/\//.test(this.url)) this.url = ''
return this.url
},
async handleSubmit() {
let url = this.verify()
if (!url) return
this.disabled = true
this.btnText = this.$t('user_api_import_online__input_loading')
let script
try {
script = await httpFetch(url, { follow_max: 3 }).promise.then(resp => resp.body)
} catch (err) {
void dialog(this.$t('user_api_import__failed', { message: err.message }))
return
} finally {
this.disabled = false
this.btnText = this.$t('user_api_import_online__input_confirm')
}
if (script.length > 90000) {
void dialog(this.$t('user_api_import__failed', { message: 'Too large script' }))
return
}
this.$emit('import', script)
this.handleClose()
},
},
}
</script>
<style lang="less" module>
@import '@renderer/assets/styles/layout.less';
.main {
padding: 0 15px;
width: 450px;
min-width: 280px;
display: flex;
flex-flow: column nowrap;
min-height: 0;
// max-height: 100%;
// overflow: hidden;
h2 {
font-size: 13px;
color: var(--color-font);
line-height: 1.3;
word-break: break-all;
// text-align: center;
padding: 15px 0 8px;
}
}
.input {
// width: 100%;
// height: 26px;
padding: 8px 8px;
}
.footer {
margin: 20px 0 15px auto;
}
.btn {
// box-sizing: border-box;
// margin-left: 15px;
// margin-bottom: 15px;
// height: 36px;
// line-height: 36px;
// padding: 0 10px !important;
min-width: 70px;
// .mixin-ellipsis-1;
+.btn {
margin-left: 10px;
}
}
</style>