feat: app index

v3
veypi 4 weeks ago
parent 6a85c9a7c4
commit 877b2a2021

@ -33,6 +33,9 @@ class davWraper {
this.prefix = prefix
this.token = token
this.client = webdav.createClient(host + prefix)
if (this.prefix.endsWith('/')) {
this.prefix = this.prefix.slice(0, -1)
}
}
set(k: 'host' | 'token', value: string) {
if (value !== this[k]) {
@ -58,6 +61,19 @@ class davWraper {
stat(path: string, options?: webdav.StatOptions) {
return this.retry(() => this.client.stat(path, options))
}
urlwrap(path: string) {
if (path.startsWith('/')) {
return this.prefix + path
} else {
return this.prefix + '/' + path
}
}
urlunwrap(url: string) {
if (url.startsWith(this.prefix)) {
return url.slice(this.prefix.length)
}
return url
}
private retry<T>(fn: () => Promise<T>): Promise<T> {
let retries = 0;
function attempt(): Promise<T> {

@ -13,6 +13,10 @@ import api from './api'
import fs from './fs'
export {
fs
}
export default new class {
private ui?: ui
constructor() {

@ -5,8 +5,10 @@
* Distributed under terms of the MIT license.
-->
<template>
<div class="w-full h-full">
<!-- <div class="absolute bg-red-400 left-0 top-0 w-full h-full"></div> -->
<div class="w-full h-full relative">
<OneIcon v-if='modelValue' @click="emits('update:modelValue', false)" class="go-edit" name='edit-square'>plus
</OneIcon>
<div class="w-full h-full veditor" :id="eid"></div>
</div>
</template>
@ -36,20 +38,15 @@ let props = withDefaults(defineProps<{
)
watch(computed(() => props.modelValue), (e) => {
set_mode(e)
editor.switchModel(e ? 'previewOnly' : 'edit&preview')
})
watch(computed(() => props.content), (e) => {
if (e) {
console.log(e)
editor.setValue(e)
}
})
const set_mode = (preview: boolean) => {
editor.switchModel(preview ? 'previewOnly' : 'edit&preview')
}
const fileUpload = (f: File, cb: (url: string, params: any) => void) => {
/**
* @param params.name 回填的alt信息
@ -86,7 +83,7 @@ const init = () => {
let config = {
value: props.content,
id: props.eid,
// isPreviewOnly: true,
isPreviewOnly: props.modelValue,
callback: {
},
fileUpload: fileUpload,
@ -96,7 +93,6 @@ const init = () => {
// @ts-ignore
options.toolbars.customMenu.backMenu = backMenu
editor = new Cherry(Object.assign({}, options, config));
set_mode(props.modelValue)
}
@ -106,6 +102,20 @@ onMounted(() => {
</script>
<style lang="scss">
.go-edit {
position: absolute;
right: 2rem;
top: 1rem;
opacity: 0.5;
font-size: 1.5rem;
z-index: 10;
cursor: pointer;
&:hover {
opacity: 1;
}
}
.cherry-dialog {
.cherry-dialog--body {
bottom: 45px !important;

@ -187,15 +187,20 @@ const basicConfig: CherryOptions = {
insert: ['image', 'audio', 'video', 'link', 'hr', 'br', 'code', 'formula', 'toc', 'table', 'pdf', 'word', 'ruby'],
},
'graph',
'togglePreview',
'export',
],
toolbarRight: [
// @ts-ignore
'saveMenu', 'backMenu'
'backMenu', 'saveMenu',
'export',
'togglePreview',
],
// toolbarRight: [],
bubble: ['bold', 'italic', 'underline', 'strikethrough', 'sub', 'sup', 'quote', 'ruby', '|', 'size', 'color'], // array or false
// sidebar: false,
// float: false
toc: {
updateLocationHash: false, // 要不要更新URL的hash
defaultModel: 'pure', // pure: 精简模式/缩略模式,只有一排小点; full: 完整模式,会展示所有标题
},
customMenu: {
} as any,
},

@ -106,6 +106,7 @@ const responseFailed = (error: AxiosError) => {
} else if (response?.status == 500) {
needRetry = false
}
console.log(data, response?.status)
if (!needRetry) {
return Promise.reject(data || response)
};

@ -6,9 +6,6 @@
-->
<template>
<div>
<div class="vbtn" v-if="preview_mode" @click="preview_mode = false">
<OneIcon name='edit-square'>plus</OneIcon>
</div>
<Editor style="" v-if="core.id" :eid="core.id + '.des'" v-model="preview_mode" :content="content" @save="save">
</Editor>
</div>
@ -16,7 +13,7 @@
<script lang="ts" setup>
import type { models } from '#imports';
import oaer from '@veypi/oaer'
import { fs } from '@veypi/oaer'
let props = withDefaults(defineProps<{
@ -27,40 +24,37 @@ let props = withDefaults(defineProps<{
let preview_mode = ref(true)
let content = ref('编辑')
watch(computed(() => props.core.id), () => {
sync()
})
let content = ref('')
const sync = () => {
if (props.core.des) {
console.log(props.core.des)
oaer.fs().app.getFileContents("/net/go.mod", { format: 'text' }).then((e) => {
fs.app.getFileContents(fs.app.urlunwrap(props.core.des), { format: 'text' }).then((e) => {
content.value = e as string
})
}
}
watch(computed(() => props.core.id), () => {
sync()
}, { immediate: true })
const save = (des: string) => {
oaer.fs().app.putFileContents("/info/des.md", des).then((e) => {
console.log(e)
let furl = `/info/appdes/${props.core.id}.md`
fs.app.putFileContents(furl, des).then((e) => {
furl = fs.app.urlwrap(furl)
if (props.core.des !== furl) {
api.app.Patch(props.core.id, { des: furl }).then((e) => {
preview_mode.value = true
props.core.des = furl
})
} else {
preview_mode.value = true
}
})
// oafs.upload([a], props.core.id).then(url => {
// api.app.update(props.core.id, { des: url[0] }).then(e => {
// preview_mode.value = true
// props.core.des = url[0]
// }).catch(e => {
// // msg.Warn(": " + e)
// })
// }).catch(e => {
// // msg.Warn(": " + e)
// })
}
onMounted(() => {
sync()
})
</script>

Loading…
Cancel
Save