feat: redesign retrieve workspace
This commit is contained in:
@@ -1,10 +1,10 @@
|
||||
import { ref, watch } from 'vue'
|
||||
import { computed, ref, watch } from 'vue'
|
||||
import { useI18n } from 'vue-i18n'
|
||||
import { storeToRefs } from 'pinia'
|
||||
import { FileService } from '@/services'
|
||||
import { useAlertStore } from '@/stores/alertStore'
|
||||
import { useFileDataStore } from '@/stores/fileData'
|
||||
import type { ReceivedFileRecord } from '@/types'
|
||||
import type { ReceivedFileRecord, ShareMetadataResponse, ShareSelectResponse } from '@/types'
|
||||
import { copyToClipboard } from '@/utils/clipboard'
|
||||
import { getErrorMessage } from '@/utils/common'
|
||||
import { renderMarkdownPreview } from '@/utils/content-preview'
|
||||
@@ -22,6 +22,9 @@ export function useRetrieveFlow() {
|
||||
const { receiveData: records } = storeToRefs(fileStore)
|
||||
|
||||
const code = ref('')
|
||||
const inspectedFile = ref<ShareMetadataResponse | null>(null)
|
||||
const isInspecting = ref(false)
|
||||
const isRetrieving = ref(false)
|
||||
const inputStatus = ref<InputStatus>({
|
||||
readonly: false,
|
||||
loading: false
|
||||
@@ -31,6 +34,9 @@ export function useRetrieveFlow() {
|
||||
const showDrawer = ref(false)
|
||||
const showPreview = ref(false)
|
||||
const renderedContent = ref('')
|
||||
const normalizedCode = computed(() => code.value.trim())
|
||||
const isWorking = computed(() => isInspecting.value || isRetrieving.value)
|
||||
const hasValidCode = computed(() => normalizedCode.value.length === 5)
|
||||
|
||||
const formatFileSize = (bytes: number) => {
|
||||
if (bytes === 0) return '0 ' + t('fileSize.bytes')
|
||||
@@ -46,52 +52,103 @@ export function useRetrieveFlow() {
|
||||
return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i]
|
||||
}
|
||||
|
||||
const createRecord = (detail: {
|
||||
code: string
|
||||
name: string
|
||||
text: string
|
||||
size: number
|
||||
}): ReceivedFileRecord => {
|
||||
const isFile = detail.text.startsWith('/share/download') || detail.name !== 'Text'
|
||||
const createRecord = (detail: ShareSelectResponse): ReceivedFileRecord => {
|
||||
const isText =
|
||||
typeof detail.is_text === 'boolean'
|
||||
? detail.is_text
|
||||
: detail.type
|
||||
? detail.type === 'text'
|
||||
: detail.name === 'Text' && !detail.text.startsWith('/share/download')
|
||||
const content = isText ? (detail.content ?? detail.text) : null
|
||||
const downloadUrl = isText ? null : (detail.download_url ?? detail.text)
|
||||
|
||||
return {
|
||||
id: Date.now(),
|
||||
code: detail.code,
|
||||
filename: detail.name,
|
||||
size: formatFileSize(detail.size),
|
||||
downloadUrl: isFile ? detail.text : null,
|
||||
content: isFile ? null : detail.text,
|
||||
date: new Date().toLocaleString()
|
||||
downloadUrl,
|
||||
content,
|
||||
date: new Date().toLocaleString(),
|
||||
type: isText ? 'text' : 'file',
|
||||
remainingDownloads: detail.remaining_downloads
|
||||
}
|
||||
}
|
||||
|
||||
const handleSubmit = async () => {
|
||||
if (code.value.length !== 5) {
|
||||
const resetInspection = () => {
|
||||
inspectedFile.value = null
|
||||
error.value = ''
|
||||
}
|
||||
|
||||
const inspectCode = async () => {
|
||||
if (!hasValidCode.value) {
|
||||
alertStore.showAlert(t('retrieve.messages.invalidCode'), 'error')
|
||||
return
|
||||
}
|
||||
|
||||
isInspecting.value = true
|
||||
inputStatus.value.readonly = true
|
||||
inputStatus.value.loading = true
|
||||
error.value = ''
|
||||
|
||||
try {
|
||||
const res = await FileService.selectFile(code.value)
|
||||
const res = await FileService.inspectFile(normalizedCode.value)
|
||||
if (res.code === 200 && res.detail) {
|
||||
inspectedFile.value = res.detail
|
||||
} else {
|
||||
inspectedFile.value = null
|
||||
error.value = String(res.detail || res.message || '')
|
||||
alertStore.showAlert(t('retrieve.messages.retrieveFailure') + error.value, 'error')
|
||||
}
|
||||
} catch {
|
||||
inspectedFile.value = null
|
||||
error.value = t('retrieve.messages.previewUnavailable')
|
||||
alertStore.showAlert(error.value, 'warning')
|
||||
} finally {
|
||||
isInspecting.value = false
|
||||
inputStatus.value.readonly = false
|
||||
inputStatus.value.loading = false
|
||||
}
|
||||
}
|
||||
|
||||
const handleSubmit = async () => {
|
||||
if (!hasValidCode.value) {
|
||||
alertStore.showAlert(t('retrieve.messages.invalidCode'), 'error')
|
||||
return
|
||||
}
|
||||
|
||||
isRetrieving.value = true
|
||||
inputStatus.value.readonly = true
|
||||
inputStatus.value.loading = true
|
||||
error.value = ''
|
||||
|
||||
try {
|
||||
const res = await FileService.selectFile(normalizedCode.value)
|
||||
if (res.code === 200 && res.detail) {
|
||||
const newFileData = createRecord(res.detail)
|
||||
if (!fileStore.receiveData.some((file) => file.code === newFileData.code)) {
|
||||
fileStore.addReceiveData(newFileData)
|
||||
const existingIndex = fileStore.receiveData.findIndex(
|
||||
(file) => file.code === newFileData.code
|
||||
)
|
||||
if (existingIndex !== -1) {
|
||||
fileStore.deleteReceiveData(existingIndex)
|
||||
}
|
||||
fileStore.addReceiveData(newFileData)
|
||||
selectedRecord.value = newFileData
|
||||
if (newFileData.content) {
|
||||
showPreview.value = true
|
||||
}
|
||||
inspectedFile.value = null
|
||||
alertStore.showAlert(t('retrieve.messages.retrieveSuccess'), 'success')
|
||||
} else {
|
||||
alertStore.showAlert(t('retrieve.messages.retrieveFailure') + res.detail, 'error')
|
||||
error.value = String(res.detail || '')
|
||||
alertStore.showAlert(t('retrieve.messages.retrieveFailure') + error.value, 'error')
|
||||
}
|
||||
} catch (err: unknown) {
|
||||
const errorMessage = getErrorMessage(err, t('retrieve.messages.unknownError'))
|
||||
error.value = errorMessage
|
||||
alertStore.showAlert(t('retrieve.messages.networkError') + errorMessage, 'error')
|
||||
} finally {
|
||||
isRetrieving.value = false
|
||||
inputStatus.value.readonly = false
|
||||
inputStatus.value.loading = false
|
||||
code.value = ''
|
||||
@@ -151,8 +208,23 @@ export function useRetrieveFlow() {
|
||||
{ immediate: true }
|
||||
)
|
||||
|
||||
watch(normalizedCode, (nextCode) => {
|
||||
if (inspectedFile.value && inspectedFile.value.code !== nextCode) {
|
||||
resetInspection()
|
||||
}
|
||||
|
||||
if (nextCode.length < 5 && error.value) {
|
||||
error.value = ''
|
||||
}
|
||||
})
|
||||
|
||||
return {
|
||||
code,
|
||||
inspectedFile,
|
||||
isInspecting,
|
||||
isRetrieving,
|
||||
isWorking,
|
||||
hasValidCode,
|
||||
inputStatus,
|
||||
error,
|
||||
records,
|
||||
@@ -166,6 +238,8 @@ export function useRetrieveFlow() {
|
||||
deleteRecord,
|
||||
downloadRecord,
|
||||
handleSubmit,
|
||||
inspectCode,
|
||||
resetInspection,
|
||||
showContentPreview,
|
||||
toggleDrawer,
|
||||
viewDetails
|
||||
|
||||
Reference in New Issue
Block a user