File size: 4,401 Bytes
89ce340 |
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 |
import { defineStore } from 'pinia'
import type { IndexableTypeArray } from 'dexie'
import { db, type Snapshot } from '@/utils/database'
import { useSlidesStore } from './slides'
import { useMainStore } from './main'
export interface ScreenState {
snapshotCursor: number
snapshotLength: number
}
export const useSnapshotStore = defineStore('snapshot', {
state: (): ScreenState => ({
snapshotCursor: -1, // 历史快照指针
snapshotLength: 0, // 历史快照长度
}),
getters: {
canUndo(state) {
return state.snapshotCursor > 0
},
canRedo(state) {
return state.snapshotCursor < state.snapshotLength - 1
},
},
actions: {
setSnapshotCursor(cursor: number) {
this.snapshotCursor = cursor
},
setSnapshotLength(length: number) {
this.snapshotLength = length
},
async initSnapshotDatabase() {
const slidesStore = useSlidesStore()
const newFirstSnapshot = {
index: slidesStore.slideIndex,
slides: JSON.parse(JSON.stringify(slidesStore.slides)),
}
await db.snapshots.add(newFirstSnapshot)
this.setSnapshotCursor(0)
this.setSnapshotLength(1)
},
async addSnapshot() {
const slidesStore = useSlidesStore()
// 获取当前indexeddb中全部快照的ID
const allKeys = await db.snapshots.orderBy('id').keys()
let needDeleteKeys: IndexableTypeArray = []
// 记录需要删除的快照ID
// 若当前快照指针不处在最后一位,那么再添加快照时,应该将当前指针位置后面的快照全部删除,对应的实际情况是:
// 用户撤回多次后,再进行操作(添加快照),此时原先被撤销的快照都应该被删除
if (this.snapshotCursor >= 0 && this.snapshotCursor < allKeys.length - 1) {
needDeleteKeys = allKeys.slice(this.snapshotCursor + 1)
}
// 添加新快照
const snapshot = {
index: slidesStore.slideIndex,
slides: JSON.parse(JSON.stringify(slidesStore.slides)),
}
await db.snapshots.add(snapshot)
// 计算当前快照长度,用于设置快照指针的位置(此时指针应该处在最后一位,即:快照长度 - 1)
let snapshotLength = allKeys.length - needDeleteKeys.length + 1
// 快照数量超过长度限制时,应该将头部多余的快照删除
const snapshotLengthLimit = 20
if (snapshotLength > snapshotLengthLimit) {
needDeleteKeys.push(allKeys[0])
snapshotLength--
}
// 快照数大于1时,需要保证撤回操作后维持页面焦点不变:也就是将倒数第二个快照对应的索引设置为当前页的索引
// https://github.com/pipipi-pikachu/PPTist/issues/27
if (snapshotLength >= 2) {
db.snapshots.update(allKeys[snapshotLength - 2] as number, { index: slidesStore.slideIndex })
}
await db.snapshots.bulkDelete(needDeleteKeys as number[])
this.setSnapshotCursor(snapshotLength - 1)
this.setSnapshotLength(snapshotLength)
},
async unDo() {
if (this.snapshotCursor <= 0) return
const slidesStore = useSlidesStore()
const mainStore = useMainStore()
const snapshotCursor = this.snapshotCursor - 1
const snapshots: Snapshot[] = await db.snapshots.orderBy('id').toArray()
const snapshot = snapshots[snapshotCursor]
const { index, slides } = snapshot
const slideIndex = index > slides.length - 1 ? slides.length - 1 : index
slidesStore.setSlides(slides)
slidesStore.updateSlideIndex(slideIndex)
this.setSnapshotCursor(snapshotCursor)
mainStore.setActiveElementIdList([])
},
async reDo() {
if (this.snapshotCursor >= this.snapshotLength - 1) return
const slidesStore = useSlidesStore()
const mainStore = useMainStore()
const snapshotCursor = this.snapshotCursor + 1
const snapshots: Snapshot[] = await db.snapshots.orderBy('id').toArray()
const snapshot = snapshots[snapshotCursor]
const { index, slides } = snapshot
const slideIndex = index > slides.length - 1 ? slides.length - 1 : index
slidesStore.setSlides(slides)
slidesStore.updateSlideIndex(slideIndex)
this.setSnapshotCursor(snapshotCursor)
mainStore.setActiveElementIdList([])
},
},
}) |