feat: autosaving

This commit is contained in:
Matei Adriel 2020-04-15 18:14:00 +03:00
parent 8c8502d15d
commit e0c267559c
8 changed files with 63 additions and 29 deletions

View file

@ -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'))

View file

@ -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,6 +82,8 @@ export const compileIc = (state: SimulationState) => {
}
templateStore.set(name, result)
if (log) {
toast(
...createToastArguments(
translation.messages.compiledIc(name),
@ -89,3 +91,4 @@ export const compileIc = (state: SimulationState) => {
)
)
}
}

View file

@ -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}'`
}
}

View file

@ -29,6 +29,7 @@ export interface Translation {
}
}
messages: {
autoSave?: string
createdSimulation: NameSentence
switchedToSimulation: NameSentence
savedSimulation: NameSentence

View file

@ -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'

View file

@ -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)

View file

@ -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',
{

View 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)
})
}