feat: autosaving
This commit is contained in:
parent
8c8502d15d
commit
e0c267559c
|
@ -10,6 +10,7 @@ import { take, filter } from 'rxjs/operators'
|
||||||
import { logWelcome } from './modules/core/helpers/logWelcome'
|
import { logWelcome } from './modules/core/helpers/logWelcome'
|
||||||
import { initRenderer } from './modules/simulationRenderer/helpers/initRenderer'
|
import { initRenderer } from './modules/simulationRenderer/helpers/initRenderer'
|
||||||
import { updateLogicGateList } from './modules/logic-gates/subjects/LogicGateList'
|
import { updateLogicGateList } from './modules/logic-gates/subjects/LogicGateList'
|
||||||
|
import { initAutoSave } from './modules/simulation-actions/helpers/initAutoSave'
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The function wich does the heavy lifting for starting the app
|
* The function wich does the heavy lifting for starting the app
|
||||||
|
@ -18,7 +19,7 @@ export const start = async () => {
|
||||||
// This will resolve at the first render
|
// This will resolve at the first render
|
||||||
const result = loadSubject
|
const result = loadSubject
|
||||||
.pipe(
|
.pipe(
|
||||||
filter(a => a),
|
filter((a) => a),
|
||||||
take(1)
|
take(1)
|
||||||
)
|
)
|
||||||
.toPromise()
|
.toPromise()
|
||||||
|
@ -41,6 +42,9 @@ export const start = async () => {
|
||||||
// Update the logic gates in local storage
|
// Update the logic gates in local storage
|
||||||
updateLogicGateList()
|
updateLogicGateList()
|
||||||
|
|
||||||
|
// start the autosaving stuff
|
||||||
|
initAutoSave()
|
||||||
|
|
||||||
// Render app component
|
// Render app component
|
||||||
render(<App />, document.getElementById('app'))
|
render(<App />, document.getElementById('app'))
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,6 @@ import { SimulationState } from '../../saving/types/SimulationSave'
|
||||||
import { SimulationError } from '../../errors/classes/SimulationError'
|
import { SimulationError } from '../../errors/classes/SimulationError'
|
||||||
import {
|
import {
|
||||||
GateTemplate,
|
GateTemplate,
|
||||||
Property,
|
|
||||||
PropGroup,
|
PropGroup,
|
||||||
isGroup
|
isGroup
|
||||||
} from '../../simulation/types/GateTemplate'
|
} from '../../simulation/types/GateTemplate'
|
||||||
|
@ -24,9 +23,10 @@ import { getTemplateSafely } from '../../logic-gates/helpers/getTemplateSafely'
|
||||||
* Compiles a simulation into a logicGate
|
* Compiles a simulation into a logicGate
|
||||||
*
|
*
|
||||||
* @param simulaton The simulation to compile
|
* @param simulaton The simulation to compile
|
||||||
|
* @param log Allow disabling logging
|
||||||
*/
|
*/
|
||||||
export const compileIc = (state: SimulationState) => {
|
export const compileIc = (state: SimulationState, log = false) => {
|
||||||
const { mode, name, gates } = state
|
const { mode, name } = state
|
||||||
|
|
||||||
if (mode === 'project') {
|
if (mode === 'project') {
|
||||||
throw new SimulationError('Cannot compile project')
|
throw new SimulationError('Cannot compile project')
|
||||||
|
@ -82,10 +82,13 @@ export const compileIc = (state: SimulationState) => {
|
||||||
}
|
}
|
||||||
|
|
||||||
templateStore.set(name, result)
|
templateStore.set(name, result)
|
||||||
|
|
||||||
|
if (log) {
|
||||||
toast(
|
toast(
|
||||||
...createToastArguments(
|
...createToastArguments(
|
||||||
translation.messages.compiledIc(name),
|
translation.messages.compiledIc(name),
|
||||||
'markunread_mailbox'
|
'markunread_mailbox'
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -40,15 +40,16 @@ export const EnglishTranslation: Translation = {
|
||||||
'delete simulation': 'Delete simulation'
|
'delete simulation': 'Delete simulation'
|
||||||
},
|
},
|
||||||
messages: {
|
messages: {
|
||||||
createdSimulation: name => `Succesfully created simulation '${name}'`,
|
autoSave: 'The sim saves your work automatically :D',
|
||||||
switchedToSimulation: name =>
|
createdSimulation: (name) => `Succesfully created simulation '${name}'`,
|
||||||
|
switchedToSimulation: (name) =>
|
||||||
`Succesfully switched to simulation '${name}'`,
|
`Succesfully switched to simulation '${name}'`,
|
||||||
savedSimulation: name => `Succesfully saved simulation '${name}'`,
|
savedSimulation: (name) => `Succesfully saved simulation '${name}'`,
|
||||||
compiledIc: name => `Succesfully compiled circuit '${name}'`,
|
compiledIc: (name) => `Succesfully compiled circuit '${name}'`,
|
||||||
cleaned: name => `Succesfully cleaned simulation '${name}'`,
|
cleaned: (name) => `Succesfully cleaned simulation '${name}'`,
|
||||||
refreshed: name => `Succesfully refreshed simulation '${name}'`,
|
refreshed: (name) => `Succesfully refreshed simulation '${name}'`,
|
||||||
undone: name => `Succesfully undone simulation '${name}'`,
|
undone: (name) => `Succesfully undone simulation '${name}'`,
|
||||||
deletedSimulation: name => `Succesfully deleted simulation '${name}'`,
|
deletedSimulation: (name) => `Succesfully deleted simulation '${name}'`,
|
||||||
addedGate: name => `Succesfully added gate '${name}'`
|
addedGate: (name) => `Succesfully added gate '${name}'`
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,6 +29,7 @@ export interface Translation {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
messages: {
|
messages: {
|
||||||
|
autoSave?: string
|
||||||
createdSimulation: NameSentence
|
createdSimulation: NameSentence
|
||||||
switchedToSimulation: NameSentence
|
switchedToSimulation: NameSentence
|
||||||
savedSimulation: NameSentence
|
savedSimulation: NameSentence
|
||||||
|
|
|
@ -7,6 +7,20 @@ import { toast } from 'react-toastify'
|
||||||
import { createToastArguments } from '../../toasts/helpers/createToastArguments'
|
import { createToastArguments } from '../../toasts/helpers/createToastArguments'
|
||||||
import { CurrentLanguage } from '../../internalisation/stores/currentLanguage'
|
import { CurrentLanguage } from '../../internalisation/stores/currentLanguage'
|
||||||
import { compileIc } from '../../integrated-circuits/helpers/compileIc'
|
import { compileIc } from '../../integrated-circuits/helpers/compileIc'
|
||||||
|
import { EnglishTranslation } from '../../internalisation/translations/english'
|
||||||
|
|
||||||
|
export const notifyAboutAutosave = () => {
|
||||||
|
const translation = CurrentLanguage.getTranslation()
|
||||||
|
|
||||||
|
toast(
|
||||||
|
...createToastArguments(
|
||||||
|
translation.messages.autoSave ||
|
||||||
|
EnglishTranslation.messages.autoSave ||
|
||||||
|
'this sentence was not translated yet',
|
||||||
|
'save'
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Saves the state from a renderer in localStorage,
|
* Saves the state from a renderer in localStorage,
|
||||||
|
@ -22,20 +36,11 @@ export const save = (renderer: SimulationRenderer) => {
|
||||||
|
|
||||||
if (current) {
|
if (current) {
|
||||||
const state = getRendererState(renderer)
|
const state = getRendererState(renderer)
|
||||||
const translation = CurrentLanguage.getTranslation()
|
|
||||||
|
|
||||||
saveStore.set(current, state)
|
saveStore.set(current, state)
|
||||||
|
|
||||||
if (state.simulation.mode === 'ic') {
|
if (state.simulation.mode === 'ic') {
|
||||||
compileIc(state.simulation)
|
compileIc(state.simulation)
|
||||||
}
|
}
|
||||||
|
|
||||||
toast(
|
|
||||||
...createToastArguments(
|
|
||||||
translation.messages.savedSimulation(current),
|
|
||||||
'save'
|
|
||||||
)
|
|
||||||
)
|
|
||||||
} else {
|
} else {
|
||||||
throw new SimulationError(
|
throw new SimulationError(
|
||||||
'Cannot save without knowing the name of the active simulation'
|
'Cannot save without knowing the name of the active simulation'
|
||||||
|
|
|
@ -5,6 +5,8 @@ import { toast } from 'react-toastify'
|
||||||
import { createToastArguments } from '../../toasts/helpers/createToastArguments'
|
import { createToastArguments } from '../../toasts/helpers/createToastArguments'
|
||||||
import { dumpSimulation } from './dumpSimulation'
|
import { dumpSimulation } from './dumpSimulation'
|
||||||
import { CurrentLanguage } from '../../internalisation/stores/currentLanguage'
|
import { CurrentLanguage } from '../../internalisation/stores/currentLanguage'
|
||||||
|
import { compileIc } from '../../integrated-circuits/helpers/compileIc'
|
||||||
|
import { getRendererState } from './getState'
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Used to switch to a simulation
|
* Used to switch to a simulation
|
||||||
|
@ -22,6 +24,12 @@ export const switchTo = (simulationName: string = 'default') => {
|
||||||
if (rendererSubject.value) {
|
if (rendererSubject.value) {
|
||||||
const renderer = rendererSubject.value
|
const renderer = rendererSubject.value
|
||||||
const translation = CurrentLanguage.getTranslation()
|
const translation = CurrentLanguage.getTranslation()
|
||||||
|
const state = getRendererState(renderer)
|
||||||
|
|
||||||
|
// compile the ic just in case
|
||||||
|
if (state.simulation.mode === 'ic') {
|
||||||
|
compileIc(state.simulation, true)
|
||||||
|
}
|
||||||
|
|
||||||
dumpSimulation(renderer)
|
dumpSimulation(renderer)
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import { SidebarAction } from './types/SidebarAction'
|
import { SidebarAction } from './types/SidebarAction'
|
||||||
import { possibleAction } from './types/possibleAction'
|
import { possibleAction } from './types/possibleAction'
|
||||||
import { save } from '../saving/helpers/save'
|
import { save, notifyAboutAutosave } from '../saving/helpers/save'
|
||||||
import { refresh } from './helpers/refresh'
|
import { refresh } from './helpers/refresh'
|
||||||
import { undo } from './helpers/undo'
|
import { undo } from './helpers/undo'
|
||||||
import { createActionConfig } from './helpers/createActionConfig'
|
import { createActionConfig } from './helpers/createActionConfig'
|
||||||
|
@ -30,7 +30,7 @@ export const actionIcons: Record<possibleAction, string> = {
|
||||||
* Array with all the actions for the SimulationAction component to render
|
* Array with all the actions for the SimulationAction component to render
|
||||||
*/
|
*/
|
||||||
export const SidebarActions: Record<possibleAction, SidebarAction> = {
|
export const SidebarActions: Record<possibleAction, SidebarAction> = {
|
||||||
...createActionConfig('save', save, ['control', 's']),
|
...createActionConfig('save', notifyAboutAutosave, ['control', 's']),
|
||||||
...createActionConfig(
|
...createActionConfig(
|
||||||
'refresh',
|
'refresh',
|
||||||
{
|
{
|
||||||
|
|
12
src/modules/simulation-actions/helpers/initAutoSave.ts
Normal file
12
src/modules/simulation-actions/helpers/initAutoSave.ts
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
import { interval } from 'rxjs'
|
||||||
|
import { save } from '../../saving/helpers/save'
|
||||||
|
import { getRendererSafely } from '../../logic-gates/helpers/getRendererSafely'
|
||||||
|
|
||||||
|
const everySecond = interval(1000)
|
||||||
|
|
||||||
|
export const initAutoSave = () => {
|
||||||
|
everySecond.subscribe(() => {
|
||||||
|
const renderer = getRendererSafely()
|
||||||
|
save(renderer)
|
||||||
|
})
|
||||||
|
}
|
Loading…
Reference in a new issue