mirror of
https://github.com/pipipi-pikachu/PPTist.git
synced 2025-04-15 02:20:00 +08:00
update
This commit is contained in:
parent
5461dde2c8
commit
a1fba0dbea
11
package-lock.json
generated
11
package-lock.json
generated
@ -5986,6 +5986,11 @@
|
|||||||
"integrity": "sha1-AU7o+PZpxcWAI9pkuBecCDooxGw=",
|
"integrity": "sha1-AU7o+PZpxcWAI9pkuBecCDooxGw=",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"dexie": {
|
||||||
|
"version": "3.0.3",
|
||||||
|
"resolved": "https://registry.npm.taobao.org/dexie/download/dexie-3.0.3.tgz",
|
||||||
|
"integrity": "sha1-7eY4Sd/l8H4T6Zu3KgQOisHSnas="
|
||||||
|
},
|
||||||
"diff": {
|
"diff": {
|
||||||
"version": "4.0.2",
|
"version": "4.0.2",
|
||||||
"resolved": "https://registry.npm.taobao.org/diff/download/diff-4.0.2.tgz?cache=0&sync_timestamp=1604803633979&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fdiff%2Fdownload%2Fdiff-4.0.2.tgz",
|
"resolved": "https://registry.npm.taobao.org/diff/download/diff-4.0.2.tgz?cache=0&sync_timestamp=1604803633979&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fdiff%2Fdownload%2Fdiff-4.0.2.tgz",
|
||||||
@ -7319,7 +7324,7 @@
|
|||||||
},
|
},
|
||||||
"fork-ts-checker-webpack-plugin-v5": {
|
"fork-ts-checker-webpack-plugin-v5": {
|
||||||
"version": "npm:fork-ts-checker-webpack-plugin@5.2.1",
|
"version": "npm:fork-ts-checker-webpack-plugin@5.2.1",
|
||||||
"resolved": "https://registry.npm.taobao.org/fork-ts-checker-webpack-plugin/download/fork-ts-checker-webpack-plugin-5.2.1.tgz?cache=0&sync_timestamp=1608028579163&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Ffork-ts-checker-webpack-plugin%2Fdownload%2Ffork-ts-checker-webpack-plugin-5.2.1.tgz",
|
"resolved": "https://registry.npm.taobao.org/fork-ts-checker-webpack-plugin/download/fork-ts-checker-webpack-plugin-5.2.1.tgz?cache=0&sync_timestamp=1607084938170&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Ffork-ts-checker-webpack-plugin%2Fdownload%2Ffork-ts-checker-webpack-plugin-5.2.1.tgz",
|
||||||
"integrity": "sha1-eTJthpeXkG+osk4qvPlCH8gFRQ0=",
|
"integrity": "sha1-eTJthpeXkG+osk4qvPlCH8gFRQ0=",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"optional": true,
|
"optional": true,
|
||||||
@ -7416,7 +7421,7 @@
|
|||||||
},
|
},
|
||||||
"supports-color": {
|
"supports-color": {
|
||||||
"version": "7.2.0",
|
"version": "7.2.0",
|
||||||
"resolved": "https://registry.npm.taobao.org/supports-color/download/supports-color-7.2.0.tgz",
|
"resolved": "https://registry.npm.taobao.org/supports-color/download/supports-color-7.2.0.tgz?cache=0&sync_timestamp=1606205010380&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fsupports-color%2Fdownload%2Fsupports-color-7.2.0.tgz",
|
||||||
"integrity": "sha1-G33NyzK4E4gBs+R4umpRyqiWSNo=",
|
"integrity": "sha1-G33NyzK4E4gBs+R4umpRyqiWSNo=",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"optional": true,
|
"optional": true,
|
||||||
@ -15944,7 +15949,7 @@
|
|||||||
},
|
},
|
||||||
"supports-color": {
|
"supports-color": {
|
||||||
"version": "7.2.0",
|
"version": "7.2.0",
|
||||||
"resolved": "https://registry.npm.taobao.org/supports-color/download/supports-color-7.2.0.tgz",
|
"resolved": "https://registry.npm.taobao.org/supports-color/download/supports-color-7.2.0.tgz?cache=0&sync_timestamp=1606205010380&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fsupports-color%2Fdownload%2Fsupports-color-7.2.0.tgz",
|
||||||
"integrity": "sha1-G33NyzK4E4gBs+R4umpRyqiWSNo=",
|
"integrity": "sha1-G33NyzK4E4gBs+R4umpRyqiWSNo=",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"optional": true,
|
"optional": true,
|
||||||
|
@ -13,6 +13,7 @@
|
|||||||
"clipboard": "^2.0.6",
|
"clipboard": "^2.0.6",
|
||||||
"core-js": "^3.6.5",
|
"core-js": "^3.6.5",
|
||||||
"crypto-js": "^4.0.0",
|
"crypto-js": "^4.0.0",
|
||||||
|
"dexie": "^3.0.3",
|
||||||
"lodash": "^4.17.20",
|
"lodash": "^4.17.20",
|
||||||
"store2": "^2.12.0",
|
"store2": "^2.12.0",
|
||||||
"vue": "^3.0.0",
|
"vue": "^3.0.0",
|
||||||
|
@ -2,17 +2,19 @@
|
|||||||
<router-view/>
|
<router-view/>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script lang="ts">
|
||||||
import { defineComponent, onMounted } from 'vue'
|
import { defineComponent, onMounted } from 'vue'
|
||||||
import { useStore } from 'vuex'
|
import { useStore } from 'vuex'
|
||||||
import { MutationTypes } from '@/store'
|
import { MutationTypes, ActionTypes, State } from '@/store'
|
||||||
|
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
name: 'app',
|
name: 'app',
|
||||||
setup() {
|
setup() {
|
||||||
const store = useStore()
|
const store = useStore<State>()
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
store.commit(MutationTypes.SET_AVAILABLE_FONTS)
|
store.commit(MutationTypes.SET_AVAILABLE_FONTS)
|
||||||
|
store.dispatch(ActionTypes.INIT_SNAPSHOT_DATABASE)
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
15
src/hooks/useAddHistorySnapshot.ts
Normal file
15
src/hooks/useAddHistorySnapshot.ts
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
import { useStore } from 'vuex'
|
||||||
|
import debounce from 'lodash/debounce'
|
||||||
|
import { State, ActionTypes } from '@/store'
|
||||||
|
|
||||||
|
export default () => {
|
||||||
|
const store = useStore<State>()
|
||||||
|
|
||||||
|
const addHistorySnapshot = debounce(function() {
|
||||||
|
store.dispatch(ActionTypes.ADD_SNAPSHOT)
|
||||||
|
}, 300, { trailing: true })
|
||||||
|
|
||||||
|
return {
|
||||||
|
addHistorySnapshot,
|
||||||
|
}
|
||||||
|
}
|
20
src/hooks/useRedoAndUndo.ts
Normal file
20
src/hooks/useRedoAndUndo.ts
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
import { useStore } from 'vuex'
|
||||||
|
import throttle from 'lodash/throttle'
|
||||||
|
import { State, ActionTypes } from '@/store'
|
||||||
|
|
||||||
|
export default () => {
|
||||||
|
const store = useStore<State>()
|
||||||
|
|
||||||
|
const redo = throttle(function() {
|
||||||
|
store.dispatch(ActionTypes.RE_DO)
|
||||||
|
}, 100, { leading: true, trailing: false })
|
||||||
|
|
||||||
|
const undo = throttle(function() {
|
||||||
|
store.dispatch(ActionTypes.UN_DO)
|
||||||
|
}, 100, { leading: true, trailing: false })
|
||||||
|
|
||||||
|
return {
|
||||||
|
redo,
|
||||||
|
undo,
|
||||||
|
}
|
||||||
|
}
|
73
src/store/actions.ts
Normal file
73
src/store/actions.ts
Normal file
@ -0,0 +1,73 @@
|
|||||||
|
import { ActionTree } from 'vuex'
|
||||||
|
import { IndexableTypeArray } from 'dexie'
|
||||||
|
import { State } from './index'
|
||||||
|
import { ActionTypes, MutationTypes } from './constants'
|
||||||
|
import db, { Snapshot } from '@/utils/database'
|
||||||
|
|
||||||
|
export const actions: ActionTree<State, State> = {
|
||||||
|
async [ActionTypes.INIT_SNAPSHOT_DATABASE]({ commit }) {
|
||||||
|
const snapshots: Snapshot[] = await db.snapshots.orderBy('id').toArray()
|
||||||
|
const snapshot = snapshots.slice(-1)[0]
|
||||||
|
|
||||||
|
if(snapshot) {
|
||||||
|
db.snapshots.clear()
|
||||||
|
commit(MutationTypes.SET_SLIDES, snapshot.slides)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
async [ActionTypes.ADD_SNAPSHOT]({ state, commit }) {
|
||||||
|
const allKeys = await db.snapshots.orderBy('id').keys()
|
||||||
|
|
||||||
|
let needDeleteKeys: IndexableTypeArray = []
|
||||||
|
|
||||||
|
if(state.snapshotCursor >= 0 && state.snapshotCursor < allKeys.length - 1) {
|
||||||
|
needDeleteKeys = allKeys.slice(state.snapshotCursor + 1)
|
||||||
|
}
|
||||||
|
|
||||||
|
const snapshot = {
|
||||||
|
index: state.slideIndex,
|
||||||
|
slides: state.slides,
|
||||||
|
}
|
||||||
|
await db.snapshots.add(snapshot)
|
||||||
|
|
||||||
|
let snapshotLength = allKeys.length - needDeleteKeys.length + 1
|
||||||
|
|
||||||
|
if(snapshotLength > 20) {
|
||||||
|
needDeleteKeys.push(allKeys[0])
|
||||||
|
snapshotLength--
|
||||||
|
}
|
||||||
|
|
||||||
|
await db.snapshots.bulkDelete(needDeleteKeys)
|
||||||
|
|
||||||
|
commit(MutationTypes.SET_SNAPSHOT_CURSOR, snapshotLength - 1)
|
||||||
|
commit(MutationTypes.SET_SNAPSHOT_LENGTH, snapshotLength)
|
||||||
|
},
|
||||||
|
|
||||||
|
async [ActionTypes.UN_DO]({ state, commit }) {
|
||||||
|
if(state.snapshotCursor > 0) return
|
||||||
|
|
||||||
|
const snapshotCursor = state.snapshotCursor - 1
|
||||||
|
const snapshots: Snapshot[] = await db.snapshots.orderBy('id').toArray()
|
||||||
|
const snapshot = snapshots[snapshotCursor]
|
||||||
|
const { index, slides } = snapshot
|
||||||
|
|
||||||
|
commit(MutationTypes.SET_SLIDES, slides)
|
||||||
|
commit(MutationTypes.UPDATE_SLIDE_INDEX, index)
|
||||||
|
commit(MutationTypes.SET_SNAPSHOT_CURSOR, snapshotCursor)
|
||||||
|
commit(MutationTypes.SET_ACTIVE_ELEMENT_ID_LIST, [])
|
||||||
|
},
|
||||||
|
|
||||||
|
async [ActionTypes.RE_DO]({ state, commit }) {
|
||||||
|
if(state.snapshotCursor < state.snapshotLength - 1) return
|
||||||
|
|
||||||
|
const snapshotCursor = state.snapshotCursor + 1
|
||||||
|
const snapshots: Snapshot[] = await db.snapshots.orderBy('id').toArray()
|
||||||
|
const snapshot = snapshots[snapshotCursor]
|
||||||
|
const { index, slides } = snapshot
|
||||||
|
|
||||||
|
commit(MutationTypes.SET_SLIDES, slides)
|
||||||
|
commit(MutationTypes.UPDATE_SLIDE_INDEX, index)
|
||||||
|
commit(MutationTypes.SET_SNAPSHOT_CURSOR, snapshotCursor)
|
||||||
|
commit(MutationTypes.SET_ACTIVE_ELEMENT_ID_LIST, [])
|
||||||
|
},
|
||||||
|
}
|
@ -18,13 +18,18 @@ export enum MutationTypes {
|
|||||||
ADD_ELEMENT = 'addElement',
|
ADD_ELEMENT = 'addElement',
|
||||||
UPDATE_ELEMENT = 'updateElement',
|
UPDATE_ELEMENT = 'updateElement',
|
||||||
|
|
||||||
// history
|
// snapshot
|
||||||
SET_CURSOR = 'setCursor',
|
SET_SNAPSHOT_CURSOR = 'setSnapshotCursor',
|
||||||
UNDO = 'undo',
|
SET_SNAPSHOT_LENGTH = 'setSnapshotLength',
|
||||||
REDO = 'redo',
|
|
||||||
SET_HISTORY_RECORD_LENGTH = 'setHistoryRecordLength',
|
|
||||||
|
|
||||||
// keyboard
|
// keyboard
|
||||||
SET_CTRL_KEY_STATE = 'setCtrlKeyState',
|
SET_CTRL_KEY_STATE = 'setCtrlKeyState',
|
||||||
SET_SHIFT_KEY_STATE = 'setShiftKeyState',
|
SET_SHIFT_KEY_STATE = 'setShiftKeyState',
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export enum ActionTypes {
|
||||||
|
INIT_SNAPSHOT_DATABASE = 'initSnapshotDatabase',
|
||||||
|
ADD_SNAPSHOT = 'addSnapshot',
|
||||||
|
UN_DO = 'undo',
|
||||||
|
RE_DO = 'redo',
|
||||||
|
}
|
@ -30,11 +30,11 @@ export const getters: GetterTree<State, State> = {
|
|||||||
},
|
},
|
||||||
|
|
||||||
canUndo(state) {
|
canUndo(state) {
|
||||||
return state.cursor > 0
|
return state.snapshotCursor > 0
|
||||||
},
|
},
|
||||||
|
|
||||||
canRedo(state) {
|
canRedo(state) {
|
||||||
return state.cursor < state.historyRecordLength - 1
|
return state.snapshotCursor < state.snapshotLength - 1
|
||||||
},
|
},
|
||||||
|
|
||||||
ctrlOrShiftKeyActive(state) {
|
ctrlOrShiftKeyActive(state) {
|
||||||
|
@ -1,13 +1,14 @@
|
|||||||
import { createStore } from 'vuex'
|
import { createStore } from 'vuex'
|
||||||
import { mutations } from './mutations'
|
|
||||||
import { getters } from './getters'
|
import { getters } from './getters'
|
||||||
import { MutationTypes } from './constants'
|
import { actions } from './actions'
|
||||||
|
import { mutations } from './mutations'
|
||||||
|
import { MutationTypes, ActionTypes } from './constants'
|
||||||
|
|
||||||
import { Slide } from '@/types/slides'
|
import { Slide } from '@/types/slides'
|
||||||
import { slides } from '@/mocks/index'
|
import { slides } from '@/mocks/index'
|
||||||
import { FontName } from '@/configs/fontName'
|
import { FontName } from '@/configs/fontName'
|
||||||
|
|
||||||
export { MutationTypes }
|
export { MutationTypes, ActionTypes }
|
||||||
|
|
||||||
export interface State {
|
export interface State {
|
||||||
activeElementIdList: string[];
|
activeElementIdList: string[];
|
||||||
@ -19,8 +20,8 @@ export interface State {
|
|||||||
availableFonts: FontName[];
|
availableFonts: FontName[];
|
||||||
slides: Slide[];
|
slides: Slide[];
|
||||||
slideIndex: number;
|
slideIndex: number;
|
||||||
cursor: number;
|
snapshotCursor: number;
|
||||||
historyRecordLength: number;
|
snapshotLength: number;
|
||||||
ctrlKeyState: boolean;
|
ctrlKeyState: boolean;
|
||||||
shiftKeyState: boolean;
|
shiftKeyState: boolean;
|
||||||
}
|
}
|
||||||
@ -35,8 +36,8 @@ const state: State = {
|
|||||||
availableFonts: [],
|
availableFonts: [],
|
||||||
slides: slides,
|
slides: slides,
|
||||||
slideIndex: 0,
|
slideIndex: 0,
|
||||||
cursor: -1,
|
snapshotCursor: -1,
|
||||||
historyRecordLength: 0,
|
snapshotLength: 0,
|
||||||
ctrlKeyState: false,
|
ctrlKeyState: false,
|
||||||
shiftKeyState: false,
|
shiftKeyState: false,
|
||||||
}
|
}
|
||||||
@ -45,4 +46,5 @@ export default createStore({
|
|||||||
state,
|
state,
|
||||||
getters,
|
getters,
|
||||||
mutations,
|
mutations,
|
||||||
|
actions,
|
||||||
})
|
})
|
||||||
|
@ -101,22 +101,14 @@ export const mutations: MutationTree<State> = {
|
|||||||
state.slides[slideIndex].elements = (elements as PPTElement[])
|
state.slides[slideIndex].elements = (elements as PPTElement[])
|
||||||
},
|
},
|
||||||
|
|
||||||
// history
|
// snapshot
|
||||||
|
|
||||||
[MutationTypes.SET_CURSOR](state, cursor: number) {
|
[MutationTypes.SET_SNAPSHOT_CURSOR](state, cursor: number) {
|
||||||
state.cursor = cursor
|
state.snapshotCursor = cursor
|
||||||
},
|
},
|
||||||
|
|
||||||
[MutationTypes.UNDO](state) {
|
[MutationTypes.SET_SNAPSHOT_LENGTH](state, length: number) {
|
||||||
state.cursor -= 1
|
state.snapshotLength = length
|
||||||
},
|
|
||||||
|
|
||||||
[MutationTypes.REDO](state) {
|
|
||||||
state.cursor += 1
|
|
||||||
},
|
|
||||||
|
|
||||||
[MutationTypes.SET_HISTORY_RECORD_LENGTH](state, length: number) {
|
|
||||||
state.historyRecordLength = length
|
|
||||||
},
|
},
|
||||||
|
|
||||||
// keyBoard
|
// keyBoard
|
||||||
|
21
src/utils/database.ts
Normal file
21
src/utils/database.ts
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
import Dexie from 'dexie'
|
||||||
|
import { Slide } from '@/types/slides'
|
||||||
|
|
||||||
|
export interface Snapshot {
|
||||||
|
index: number;
|
||||||
|
slides: Slide[];
|
||||||
|
}
|
||||||
|
|
||||||
|
class SnapshotDatabase extends Dexie {
|
||||||
|
public snapshots: Dexie.Table<Snapshot, number>
|
||||||
|
|
||||||
|
public constructor() {
|
||||||
|
super('SnapshotDatabase')
|
||||||
|
this.version(1).stores({
|
||||||
|
snapshots: '++id'
|
||||||
|
})
|
||||||
|
this.snapshots = this.table('snapshots')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default new SnapshotDatabase()
|
Loading…
x
Reference in New Issue
Block a user