import { ref } from 'vue' import { togetherCallback } from '@/utils' import { autoSetModeCallback, createTemploraryID } from './sys' import { defaultStyle, getTaggingStyle, initialTaggingStyles, lastUseStyle } from './tagging-style' import { initTaggingPositionsByTagging, saveTaggingPositions, recoverTaggingPositions, backupTaggingPositions, taggingPositions, getTaggingPositions, getTaggingPositionIsShow } from './tagging-positions' import { saveTaggingStyles, recoverTaggingStyles, backupTaggingStyles, taggingStyles } from './tagging-style' import { fetchTaggings, postAddTagging, postDeleteTagging, postUpdateTagging, TaggingPositionType, uploadFile } from '@/api' import { deleteStoreItem, addStoreItem, updateStoreItem, fetchStoreItems, saveStoreItems, recoverStoreItems } from '@/utils' import type { Tagging as STagging } from '@/api' import type { TaggingStyle } from './tagging-style' export type Tagging = LocalMode, 'audio'> export type Taggings = Tagging[] export const taggings = ref([]) export const getTagging = (id: Tagging['id']) => taggings.value.find(tagging => tagging.id === id) export const getTaggingIsShow = (tagging: Tagging) => getTaggingPositions(tagging).some(getTaggingPositionIsShow) export const createTagging = (tagging: Partial = {}): Tagging => { return { id: createTemploraryID(), title: ``, styleId: '', desc: '', part: '', method: '', show3dTitle: false, audioName: '', principal: '', audio: '', images: [], ...tagging } } let bcTaggings: Taggings = [] export const getBackupTaggings = () => bcTaggings export const backupTaggings = () => { bcTaggings = taggings.value.map(tagging => ({ ...tagging, images: [...tagging.images], })) } export const transformTagging = async (tagging: Tagging): Promise => { const images: string[] = [] const uploadImages = tagging.images.map((file, index) => uploadFile(file).then(url => images[index] = url) ) let audio: string const uploadAudio = tagging.audio && uploadFile(tagging.audio).then((url) => { audio = url }) await Promise.all([...uploadImages, uploadAudio]) return { ...tagging, images, audio: audio! } } export const recoverTaggings = recoverStoreItems(taggings, () => bcTaggings) export const addTagging = addStoreItem(taggings, async (localTagging) => { const positions = getTaggingPositions(localTagging) const serviceTagging = await postAddTagging(localTagging) for (const position of positions) { position.taggingId = serviceTagging.id } return serviceTagging }, transformTagging) export const deleteTagging = deleteStoreItem(taggings, async tagging => { const positions = getTaggingPositions(tagging) await postDeleteTagging(tagging.id) taggingPositions.value.filter(position => !positions.includes(position)) }) export const updateTagging = updateStoreItem(taggings, postUpdateTagging, transformTagging) export const initialTaggings = fetchStoreItems(taggings, async () => { const taggings = await fetchTaggings() await Promise.all(taggings.map(initTaggingPositionsByTagging)) return taggings }, backupTaggings) export const saveTaggings = saveStoreItems( taggings, getBackupTaggings, { add: addTagging, update: updateTagging, delete: deleteTagging, } ) export const autoSaveTaggings = autoSetModeCallback([taggings, taggingPositions, taggingStyles], { backup: togetherCallback([backupTaggings, backupTaggingPositions, backupTaggingStyles]), recovery: togetherCallback([recoverTaggings, recoverTaggingPositions, recoverTaggingStyles]), save: async () => { const styles = taggings.value.map(tagging => getTaggingStyle(tagging.styleId)) await saveTaggingStyles() for (let i = 0; i < styles.length; i++) { if (styles[i]) { taggings.value[i].styleId = (styles[i] as TaggingStyle).id } } await saveTaggings() await saveTaggingPositions() await initialTaggingStyles() }, })