diff --git a/src/common/ipc-channels.js b/src/common/ipc-channels.js index 51ca088..869c54b 100644 --- a/src/common/ipc-channels.js +++ b/src/common/ipc-channels.js @@ -3,5 +3,8 @@ export default { RECEIVE_RESPONSE: 'receive-response', UNEXPECTED_ERROR: 'unexpected-exception', CANCEL_REQUEST: 'cancel-request', - REQUEST_CANCELLED: 'request-cancelled' + REQUEST_CANCELLED: 'request-cancelled', + NEXT_STATE: 'next-state', + PREVIOUS_STATE: 'previous-state', + SET_STATE: 'set-state' }; diff --git a/src/main/history.js b/src/main/history.js new file mode 100644 index 0000000..1282737 --- /dev/null +++ b/src/main/history.js @@ -0,0 +1,48 @@ +import { clone, equals } from 'ramda'; +import { initialState } from '../renderer/store/index'; + +class StateHistory { + constructor() { + this.states = []; + this.id = 0; + this.states.push(clone(initialState)); + } + + getCurrentState() { + return this.states[this.id]; + } + + currentEquals(state) { + return equals(state.request, this.getCurrentState().request) && equals(state.auth, this.getCurrentState().auth); + } + + push(state) { + this.states.push(state); + this.id = this.states.length - 1; + } + + length() { + return this.states.length; + } + + previousState() { + if (this.id > 0) this.id -= 1; + return this.states[this.id]; + } + + nextState() { + if (this.id < this.states.length - 1) this.id += 1; + return this.states[this.id]; + } + + getStates() { + return this.states; + } + + setStates(states) { + this.states = states; + this.id = this.states.length - 1; + } +} + +export default StateHistory; diff --git a/src/main/index.js b/src/main/index.js index 85b80c3..83f779d 100644 --- a/src/main/index.js +++ b/src/main/index.js @@ -1,6 +1,10 @@ +import { clone, equals } from 'ramda'; +import fs from 'fs'; import { app, BrowserWindow, ipcMain, Menu } from 'electron'; // eslint-disable-line import/no-extraneous-dependencies import Channels from '../common/ipc-channels'; import RequestDispatcher from './request-dispatcher'; +import StateHistory from './history'; +import { initialState } from '../renderer/store'; /** * Set `__static` path to static files in production @@ -12,6 +16,8 @@ if (process.env.NODE_ENV !== 'development') { let mainWindow; const winURL = process.env.NODE_ENV === 'development' ? 'http://localhost:9080' : `file://${__dirname}/index.html`; +const stateHistory = new StateHistory(); +const historyPath = '/tmp/.requestRockerHistory.json'; function createWindow() { /** @@ -26,7 +32,9 @@ function createWindow() { mainWindow.loadURL(winURL); mainWindow.on('closed', () => { - mainWindow = null; + fs.writeFile(historyPath, JSON.stringify(stateHistory.getStates()), err => { + if (!err) mainWindow = null; + }); }); const template = [ @@ -59,7 +67,15 @@ function createWindow() { Menu.setApplicationMenu(Menu.buildFromTemplate(template)); } -app.on('ready', createWindow); +app.on('ready', () => { + createWindow(); + fs.access(historyPath, fs.F_OK, err => { + if (!err) { + const rawdata = fs.readFileSync(historyPath); + stateHistory.setStates(JSON.parse(rawdata)); + } + }); +}); app.on('window-all-closed', () => { if (process.platform !== 'darwin') { @@ -90,6 +106,31 @@ ipcMain.on(Channels.CANCEL_REQUEST, async event => { } }); +ipcMain.on(Channels.NEXT_STATE, async (event, state, forcePush = false) => { + let newState; + if ( + (!stateHistory.currentEquals(state) && !equals(state, initialState)) || + (forcePush && !equals(state, initialState)) + ) { + stateHistory.push(clone(state)); + newState = stateHistory.nextState(); + } else { + newState = stateHistory.nextState(); + } + event.sender.send(Channels.SET_STATE, newState); +}); + +ipcMain.on(Channels.PREVIOUS_STATE, async (event, state) => { + let newState; + if (!stateHistory.currentEquals(state) && !equals(state, initialState)) { + stateHistory.push(clone(state)); + newState = stateHistory.previousState(); + } else { + newState = stateHistory.previousState(); + } + event.sender.send(Channels.SET_STATE, newState); +}); + /** * Auto Updater * diff --git a/src/renderer/components/request-editor-title.vue b/src/renderer/components/request-editor-title.vue index 30b4c3c..0a49198 100644 --- a/src/renderer/components/request-editor-title.vue +++ b/src/renderer/components/request-editor-title.vue @@ -2,6 +2,16 @@