File size: 4,629 Bytes
3dabe4a |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 |
import { Button, Input, Modal, message } from 'ant-design-vue'
import { ref } from 'vue'
import * as Path from '@/util/path'
import { FileNodeInfo, mkdirs } from '@/api/files'
import { setTargetFrameAsCover } from '@/api'
import { t } from '@/i18n'
import { downloadFiles, globalEvents, toRawFileUrl, toStreamVideoUrl } from '@/util'
import { DownloadOutlined } from '@/icon'
import { isStandalone } from '@/util/env'
import { rebuildImageIndex, renameFile } from '@/api/db'
import { useTagStore } from '@/store/useTagStore'
import { useGlobalStore } from '@/store/useGlobalStore'
import { base64ToFile, video2base64 } from '@/util/video'
export const openCreateFlodersModal = (base: string) => {
const floderName = ref('')
return new Promise<void>((resolve) => {
Modal.confirm({
title: t('inputFolderName'),
content: () => <Input v-model:value={floderName.value} />,
async onOk() {
if (!floderName.value) {
return
}
const dest = Path.join(base, floderName.value)
await mkdirs(dest)
resolve()
}
})
})
}
export const MultiSelectTips = () => (
<p
style={{
background: 'var(--zp-secondary-background)',
padding: '8px',
borderLeft: '4px solid var(--primary-color)'
}}
>
Tips: {t('multiSelectTips')}
</p>
)
export const openVideoModal = (file: FileNodeInfo, onTagClick?: (id: string| number) => void) => {
const tagStore = useTagStore()
const global = useGlobalStore()
const isSelected = (id: string | number) => {
return !!tagStore.tagMap.get(file.fullpath)?.some(v => v.id === id)
}
const videoRef = ref<HTMLVideoElement | null>(null)
const onSetCurrFrameAsVideoPoster = async () => {
if (!videoRef.value) {
return
}
const video = videoRef.value
video.pause()
const base64 = video2base64(video)
await setTargetFrameAsCover({ path: file.fullpath, base64_img: base64, updated_time: file.date } )
file.cover_url = URL.createObjectURL(await base64ToFile(base64, 'cover'))
message.success(t('success') + '! ' + t('clearCacheIfNotTakeEffect'))
}
Modal.confirm({
width: '80vw',
title: file.name,
icon: null,
content: () => (
<div
style={{
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
flexDirection: 'column'
}}
>
<video ref={videoRef} style={{ maxHeight: isStandalone ? '80vh' : '60vh', maxWidth: '100%', minWidth: '70%' }} src={toStreamVideoUrl(file)} controls autoplay></video>
<div style={{ marginTop: '4px' }}>
{global.conf!.all_custom_tags.map((tag) =>
<div key={tag.id} onClick={() => onTagClick?.(tag.id)} style={{
background: isSelected(tag.id) ? tagStore.getColor(tag.name) : 'var(--zp-primary-background)',
color: !isSelected(tag.id) ? tagStore.getColor(tag.name) : 'white',
margin: '2px',
padding: '2px 16px',
'border-radius': '4px',
display: 'inline-block',
cursor: 'pointer',
'font-weight': 'bold',
transition: '.5s all ease',
border: `2px solid ${tagStore.getColor(tag.name)}`,
'user-select': 'none',
}}>
{ tag.name }
</div>)}
</div>
<div class="actions" style={{ marginTop: '16px' }}>
<Button onClick={() => downloadFiles([toRawFileUrl(file, true)])}>
{{
icon: <DownloadOutlined/>,
default: t('download')
}}
</Button>
<Button onClick={onSetCurrFrameAsVideoPoster}>
{{
default: t('setCurrFrameAsVideoPoster')
}}
</Button>
</div>
</div>
),
maskClosable: true,
wrapClassName: 'hidden-antd-btns-modal'
})
}
export const openRebuildImageIndexModal = () => {
Modal.confirm({
title: t('confirmRebuildImageIndex'),
onOk: async () => {
await rebuildImageIndex()
globalEvents.emit('searchIndexExpired')
message.success(t('rebuildComplete'))
}
})
}
export const openRenameFileModal = (path: string) => {
const name = ref(path.split(/[\\/]/).pop() ?? '')
return new Promise<string>((resolve) => {
Modal.confirm({
title: t('rename'),
content: () => <Input v-model:value={name.value} />,
async onOk() {
if (!name.value) {
return
}
const resp = await renameFile({ path, name: name.value })
resolve(resp.new_path)
}
})
})
}
|