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 { initRenderer } from './modules/simulationRenderer/helpers/initRenderer'
|
||||
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
|
||||
|
@ -18,7 +19,7 @@ export const start = async () => {
|
|||
// This will resolve at the first render
|
||||
const result = loadSubject
|
||||
.pipe(
|
||||
filter(a => a),
|
||||
filter((a) => a),
|
||||
take(1)
|
||||
)
|
||||
.toPromise()
|
||||
|
@ -41,6 +42,9 @@ export const start = async () => {
|
|||
// Update the logic gates in local storage
|
||||
updateLogicGateList()
|
||||
|
||||
// start the autosaving stuff
|
||||
initAutoSave()
|
||||
|
||||
// Render app component
|
||||
render(<App />, document.getElementById('app'))
|
||||
|
||||
|
|
|
@ -2,7 +2,6 @@ import { SimulationState } from '../../saving/types/SimulationSave'
|
|||
import { SimulationError } from '../../errors/classes/SimulationError'
|
||||
import {
|
||||
GateTemplate,
|
||||
Property,
|
||||
PropGroup,
|
||||
isGroup
|
||||
} from '../../simulation/types/GateTemplate'
|
||||
|
@ -24,9 +23,10 @@ import { getTemplateSafely } from '../../logic-gates/helpers/getTemplateSafely'
|
|||
* Compiles a simulation into a logicGate
|
||||
*
|
||||
* @param simulaton The simulation to compile
|
||||
* @param log Allow disabling logging
|
||||
*/
|
||||
export const compileIc = (state: SimulationState) => {
|
||||
const { mode, name, gates } = state
|
||||
export const compileIc = (state: SimulationState, log = false) => {
|
||||
const { mode, name } = state
|
||||
|
||||
if (mode === 'project') {
|
||||
throw new SimulationError('Cannot compile project')
|
||||
|
@ -82,10 +82,13 @@ export const compileIc = (state: SimulationState) => {
|
|||
}
|
||||
|
||||
templateStore.set(name, result)
|
||||
toast(
|
||||
...createToastArguments(
|
||||
translation.messages.compiledIc(name),
|
||||
'markunread_mailbox'
|
||||
|
||||
if (log) {
|
||||
toast(
|
||||
...createToastArguments(
|
||||
translation.messages.compiledIc(name),
|
||||
'markunread_mailbox'
|
||||
)
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -40,15 +40,16 @@ export const EnglishTranslation: Translation = {
|
|||
'delete simulation': 'Delete simulation'
|
||||
},
|
||||
messages: {
|
||||
createdSimulation: name => `Succesfully created simulation '${name}'`,
|
||||
switchedToSimulation: name =>
|
||||
autoSave: 'The sim saves your work automatically :D',
|
||||
createdSimulation: (name) => `Succesfully created simulation '${name}'`,
|
||||
switchedToSimulation: (name) =>
|
||||
`Succesfully switched to simulation '${name}'`,
|
||||
savedSimulation: name => `Succesfully saved simulation '${name}'`,
|
||||
compiledIc: name => `Succesfully compiled circuit '${name}'`,
|
||||
cleaned: name => `Succesfully cleaned simulation '${name}'`,
|
||||
refreshed: name => `Succesfully refreshed simulation '${name}'`,
|
||||
undone: name => `Succesfully undone simulation '${name}'`,
|
||||
deletedSimulation: name => `Succesfully deleted simulation '${name}'`,
|
||||
addedGate: name => `Succesfully added gate '${name}'`
|
||||
savedSimulation: (name) => `Succesfully saved simulation '${name}'`,
|
||||
compiledIc: (name) => `Succesfully compiled circuit '${name}'`,
|
||||
cleaned: (name) => `Succesfully cleaned simulation '${name}'`,
|
||||
refreshed: (name) => `Succesfully refreshed simulation '${name}'`,
|
||||
undone: (name) => `Succesfully undone simulation '${name}'`,
|
||||
deletedSimulation: (name) => `Succesfully deleted simulation '${name}'`,
|
||||
addedGate: (name) => `Succesfully added gate '${name}'`
|
||||
}
|
||||
}
|
||||
|
|
|
@ -29,6 +29,7 @@ export interface Translation {
|
|||
}
|
||||
}
|
||||
messages: {
|
||||
autoSave?: string
|
||||
createdSimulation: NameSentence
|
||||
switchedToSimulation: NameSentence
|
||||
savedSimulation: NameSentence
|
||||
|
|
|
@ -7,6 +7,20 @@ import { toast } from 'react-toastify'
|
|||
import { createToastArguments } from '../../toasts/helpers/createToastArguments'
|
||||
import { CurrentLanguage } from '../../internalisation/stores/currentLanguage'
|
||||
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,
|
||||
|
@ -22,20 +36,11 @@ export const save = (renderer: SimulationRenderer) => {
|
|||
|
||||
if (current) {
|
||||
const state = getRendererState(renderer)
|
||||
const translation = CurrentLanguage.getTranslation()
|
||||
|
||||
saveStore.set(current, state)
|
||||
|
||||
if (state.simulation.mode === 'ic') {
|
||||
compileIc(state.simulation)
|
||||
}
|
||||
|
||||
toast(
|
||||
...createToastArguments(
|
||||
translation.messages.savedSimulation(current),
|
||||
'save'
|
||||
)
|
||||
)
|
||||
} else {
|
||||
throw new SimulationError(
|
||||
'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 { dumpSimulation } from './dumpSimulation'
|
||||
import { CurrentLanguage } from '../../internalisation/stores/currentLanguage'
|
||||
import { compileIc } from '../../integrated-circuits/helpers/compileIc'
|
||||
import { getRendererState } from './getState'
|
||||
|
||||
/**
|
||||
* Used to switch to a simulation
|
||||
|
@ -22,6 +24,12 @@ export const switchTo = (simulationName: string = 'default') => {
|
|||
if (rendererSubject.value) {
|
||||
const renderer = rendererSubject.value
|
||||
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)
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import { SidebarAction } from './types/SidebarAction'
|
||||
import { possibleAction } from './types/possibleAction'
|
||||
import { save } from '../saving/helpers/save'
|
||||
import { save, notifyAboutAutosave } from '../saving/helpers/save'
|
||||
import { refresh } from './helpers/refresh'
|
||||
import { undo } from './helpers/undo'
|
||||
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
|
||||
*/
|
||||
export const SidebarActions: Record<possibleAction, SidebarAction> = {
|
||||
...createActionConfig('save', save, ['control', 's']),
|
||||
...createActionConfig('save', notifyAboutAutosave, ['control', 's']),
|
||||
...createActionConfig(
|
||||
'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