Skip to content

Commit

Permalink
put undo redo back into new ux
Browse files Browse the repository at this point in the history
  • Loading branch information
FranzPoize committed Aug 1, 2016
1 parent b9dcd18 commit 681519c
Show file tree
Hide file tree
Showing 13 changed files with 160 additions and 140 deletions.
1 change: 1 addition & 0 deletions .babelrc
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
"syntax-async-functions",
"transform-regenerator",
"transform-class-properties",
"transform-object-rest-spread",
["babel-project-relative-import", {
"sourceDir": "app/scripts/"
}]
Expand Down
88 changes: 87 additions & 1 deletion app/scripts/actions/font.actions.jsx
Original file line number Diff line number Diff line change
@@ -1,23 +1,46 @@
import XXHash from 'xxhashjs';
import slug from 'slug';

import {prototypoStore} from '../stores/creation.stores.jsx';
import {prototypoStore, undoableStore} from '../stores/creation.stores.jsx';
import LocalServer from '../stores/local-server.stores.jsx';
import LocalClient from '../stores/local-client.stores.jsx';
import {Typefaces} from '../services/typefaces.services.js';
import {copyFontValues, loadFontValues, saveAppValues} from '../helpers/loadValues.helpers.js';
import {setupFontInstance, mapGlyphForApp} from '../helpers/font.helpers.js';
import {FontValues} from '../services/values.services.js';
import {delayAfterCall} from '../helpers/animation.helpers.js';
import {BatchUpdate} from '../helpers/undo-stack.helpers.js';

slug.defaults.mode = 'rfc3986';
slug.defaults.modes.rfc3986.remove = /[-_\/\\\.]/g;
let localServer;
let localClient;
let undoWatcher;

const debouncedSave = _.throttle((values, db) => {
FontValues.save({
typeface: db || 'default',
values,
});
}, 300);

window.addEventListener('fluxServer.setup', () => {
localClient = LocalClient.instance();
localServer = LocalServer.instance;

undoWatcher = new BatchUpdate(
undoableStore,
'/undoableStore',
'controlsValues',
localClient,
localServer.lifespan,
(name) => {
return `modifier ${name}`;
},
(headJS) => {
debouncedSave(headJS.controlsValues);
}
);
});

const hasher = XXHash(0xDEADBEEF);
Expand Down Expand Up @@ -94,6 +117,7 @@ export default {
mapGlyphForApp
));
localClient.dispatchAction('/load-tags', typedata.fontinfo.tags);
localClient.dispatchAction('/clear-undo-stack');

loadFontValues(typedata, db);
},
Expand Down Expand Up @@ -434,4 +458,66 @@ export default {

localServer.dispatchUpdate('/prototypoStore', patch);
},
'/change-param': ({values, value, name, force, label}) => {
const indivMode = prototypoStore.get('indivMode');
const indivEdit = prototypoStore.get('indivEditingParams');
const db = (prototypoStore.get('variant') || {}).db;
const currentGroupName = (prototypoStore.get('indivCurrentGroup') || {}).name;
let newParams = {...undoableStore.get('controlsValues')};

if (indivMode && indivEdit && !values) {
if (newParams.indiv_group_param[currentGroupName][name]) {
newParams.indiv_group_param[currentGroupName][name].value = value;
}
else {
newParams.indiv_group_param[currentGroupName][name] = {
state: 'relative',
value,
};
}
}
else if (values) {
newParams = {...newParams, ...values};
}
else {
newParams[name] = value;
}

const patch = undoableStore.set('controlsValues', newParams).commit();

localServer.dispatchUpdate('/undoableStore', patch);

debouncedSave(newParams, db);
if (force) {
//TODO(franz): This SHOULD totally end up being in a flux store on hoodie
undoWatcher.forceUpdate(patch, label);
}
else {
undoWatcher.update(patch, label);
}

},
'/change-param-state': ({name, state, force, label}) => {
const db = prototypoStore.get('variant').db;
const currentGroupName = prototypoStore.get('indivCurrentGroup').name;
const newParams = {...undoableStore.get('controlsValues')};

newParams.indiv_group_param[currentGroupName][name] = {
state,
value: state === 'relative' ? 1 : 0,
};

const patch = undoableStore.set('controlsValues', newParams).commit();

localServer.dispatchUpdate('/undoableStore', patch);
debouncedSave(newParams, db);

if (force) {
//TODO(franz): This SHOULD totally end up being in a flux store on hoodie
undoWatcher.forceUpdate(patch, label);
}
else {
undoWatcher.update(patch, label);
}
},
};
8 changes: 4 additions & 4 deletions app/scripts/actions/fontControls.actions.jsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import {prototypoStore} from '../stores/creation.stores.jsx';
import {prototypoStore, undoableStore} from '../stores/creation.stores.jsx';
import LocalServer from '../stores/local-server.stores.jsx';
import LocalClient from '../stores/local-client.stores.jsx';

Expand All @@ -12,12 +12,12 @@ window.addEventListener('fluxServer.setup', () => {

export default {
'/load-values': (params) => {
const patch = prototypoStore
const patch = undoableStore
.set('controlsValues', params)
.commit();

localServer.dispatchUpdate('/prototypoStore', patch);
localClient.dispatchAction('/store-action', {store: '/prototypoStore', patch});
localServer.dispatchUpdate('/undoableStore', patch);
localClient.dispatchAction('/store-action', {store: '/undoableStore', patch});
localClient.dispatchAction('/update-font', params);
},
};
50 changes: 26 additions & 24 deletions app/scripts/actions/indiv.actions.jsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import {prototypoStore} from '../stores/creation.stores.jsx';
import {prototypoStore, undoableStore} from '../stores/creation.stores.jsx';
import Log from '../services/log.services.js';
import LocalServer from '../stores/local-server.stores.jsx';
import LocalClient from '../stores/local-client.stores.jsx';
Expand All @@ -14,8 +14,8 @@ window.addEventListener('fluxServer.setup', () => {

function getGroupsAndGlyphsFromGroups(groups) {
return _.sortBy(_.map(groups, (name) => {
const glyphs = _.keys(prototypoStore.get('controlsValues').indiv_glyphs).filter((key) => {
return prototypoStore.get('controlsValues').indiv_glyphs[key] === name;
const glyphs = _.keys(undoableStore.get('controlsValues').indiv_glyphs).filter((key) => {
return undoableStore.get('controlsValues').indiv_glyphs[key] === name;
});

return {name, glyphs};
Expand All @@ -40,7 +40,7 @@ function toggleGlyphSelection(isSelected, selected, unicode) {

export default {
'/load-indiv-groups': () => {
const groups = Object.keys(prototypoStore.get('controlsValues').indiv_group_param || {});
const groups = Object.keys(undoableStore.get('controlsValues').indiv_group_param || {});
const groupsAndGlyphs = getGroupsAndGlyphsFromGroups(groups);
const patch = prototypoStore
.set('indivGroups', groupsAndGlyphs).commit();
Expand All @@ -50,7 +50,7 @@ export default {
'/toggle-individualize': ({targetIndivValue}) => {
const oldValue = prototypoStore.get('indivMode');

const groups = Object.keys(prototypoStore.get('controlsValues').indiv_group_param || {});
const groups = Object.keys(undoableStore.get('controlsValues').indiv_group_param || {});
const groupsAndGlyphs = getGroupsAndGlyphsFromGroups(groups);
prototypoStore
.set('indivMode', targetIndivValue || !oldValue)
Expand Down Expand Up @@ -92,7 +92,7 @@ export default {
Log.ui('GroupParam.selectIndivTag');
},
'/create-param-group': ({name, selected}) => {
const oldValues = prototypoStore.get('controlsValues');
const oldValues = undoableStore.get('controlsValues');
const alreadyInGroup = [];

if (!name) {
Expand Down Expand Up @@ -148,18 +148,20 @@ export default {
oldValues.indiv_group_param[name] = {};
}

const patch = prototypoStore.set('controlsValues', oldValues).commit();
const patch = undoableStore.set('controlsValues', oldValues).commit();

localServer.dispatchUpdate('/prototypoStore', patch);
localServer.dispatchUpdate('/undoableStore', patch);

const endCreatePatch = prototypoStore
.set('indivCreate', false)
.set('indivEdit', true)
.set('indivEdit', false)
.set('indivEditingParams', true)
.set('indivSelected', [])
.set('indivCurrentGroup', {name, glyphs: selected})
.set('indivErrorMessage', undefined)
.set('indivGlyphGrid', false)
.set('indivGlyphs', _.keys(prototypoStore.get('controlsValues').indiv_glyphs).filter((key) => {
return prototypoStore.get('controlsValues').indiv_glyphs[key] === name;
.set('indivGlyphs', _.keys(undoableStore.get('controlsValues').indiv_glyphs).filter((key) => {
return undoableStore.get('controlsValues').indiv_glyphs[key] === name;
}))
.set('indivEditGroup', false)
.set('indivErrorGlyphs', [])
Expand All @@ -174,7 +176,7 @@ export default {
Log.ui('GroupParam.create');
},
'/cancel-indiv-mode': () => {
const oldValues = _.cloneDeep(prototypoStore.get('controlsValues'));
const oldValues = _.cloneDeep(undoableStore.get('controlsValues'));

const endCreatePatch = prototypoStore
.set('indivCreate', false)
Expand All @@ -194,8 +196,8 @@ export default {

},
'/edit-param-group': (state) => {
const otherGroups = _.keys(prototypoStore.get('controlsValues').indiv_glyphs).filter((key) => {
return !!prototypoStore.get('controlsValues').indiv_glyphs[key] && prototypoStore.get('controlsValues').indiv_glyphs[key] !== prototypoStore.get('indivCurrentGroup');
const otherGroups = _.keys(undoableStore.get('controlsValues').indiv_glyphs).filter((key) => {
return !!undoableStore.get('controlsValues').indiv_glyphs[key] && undoableStore.get('controlsValues').indiv_glyphs[key] !== prototypoStore.get('indivCurrentGroup');
});
const patch = prototypoStore
.set('indivEditGroup', state)
Expand All @@ -213,16 +215,16 @@ export default {
.set('indivPreDelete', state)
.set('indivEditGroup', false)
.set('indivGlyphGrid', false)
.set('indivSelected', _.keys(prototypoStore.get('controlsValues').indiv_glyphs).filter((key) => {
return prototypoStore.get('controlsValues').indiv_glyphs[key] === prototypoStore.get('indivCurrentGroup');
.set('indivSelected', _.keys(undoableStore.get('controlsValues').indiv_glyphs).filter((key) => {
return undoableStore.get('controlsValues').indiv_glyphs[key] === prototypoStore.get('indivCurrentGroup');
}))
.commit();

localServer.dispatchUpdate('/prototypoStore', patch);
Log.ui('GroupParam.startDelete');
},
'/delete-param-group': ({name}) => {
const oldValues = _.cloneDeep(prototypoStore.get('controlsValues'));
const oldValues = _.cloneDeep(undoableStore.get('controlsValues'));

delete oldValues.indiv_group_param[name];

Expand All @@ -247,9 +249,9 @@ export default {

localServer.dispatchUpdate('/prototypoStore', endDeletePatch);

const patch = prototypoStore.set('controlsValues', oldValues).commit();
const patch = undoableStore.set('controlsValues', oldValues).commit();

localServer.dispatchUpdate('/prototypoStore', patch);
localServer.dispatchUpdate('/undoableStore', patch);

const variant = prototypoStore.get('variant');

Expand All @@ -270,7 +272,7 @@ export default {
Log.ui('GroupParam.removeGlyph');
},
'/save-param-group': ({newName}) => {
const oldValues = _.cloneDeep(prototypoStore.get('controlsValues'));
const oldValues = _.cloneDeep(undoableStore.get('controlsValues'));
const currentGroup = prototypoStore.get('indivCurrentGroup') || {};
const currentGroupName = currentGroup.name;
const glyphSelected = currentGroupName
Expand Down Expand Up @@ -314,9 +316,9 @@ export default {

oldValues.indiv_group_param[newName] = oldParams;

const patch = prototypoStore.set('controlsValues', oldValues).commit();
const patch = undoableStore.set('controlsValues', oldValues).commit();

localServer.dispatchUpdate('/prototypoStore', patch);
localServer.dispatchUpdate('/undoableStore', patch);

const indivPatch = prototypoStore
.set('indivCurrentGroup', {name: newName, glyphs: currentGroup.glyphs})
Expand All @@ -335,7 +337,7 @@ export default {
Log.ui('GroupParam.saveEdit');
},
'/create-mode-param-group': () => {
const values = _.cloneDeep(prototypoStore.get('controlsValues'));
const values = _.cloneDeep(undoableStore.get('controlsValues'));

const indivPatch = prototypoStore
.set('indivMode', true)
Expand All @@ -354,7 +356,7 @@ export default {
Log.ui('GroupParam.switchToCreateGroupParam');
},
'/edit-mode-param-group': ({group}) => {
const values = _.cloneDeep(prototypoStore.get('controlsValues'));
const values = _.cloneDeep(undoableStore.get('controlsValues'));
const indivPatch = prototypoStore
.set('indivMode', true)
.set('indivCreate', false)
Expand Down
13 changes: 11 additions & 2 deletions app/scripts/actions/undoStack.actions.jsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import Remutable from 'remutable';
const {Patch} = Remutable;

import {prototypoStore} from '../stores/creation.stores.jsx';
import {prototypoStore, undoableStore} from '../stores/creation.stores.jsx';
import LocalServer from '../stores/local-server.stores.jsx';

let localServer;
Expand Down Expand Up @@ -61,9 +61,18 @@ export default {
label,
});
const eventPatch = prototypoStore.set('undoEventList', newEventList)
.set('undoto', undefined)
.set('undoTo', undefined)
.set('undoFrom', newEventList.length - 1).commit();

localServer.dispatchUpdate('/prototypoStore', eventPatch);
},
'/clear-undo-stack': () => {
const patch = prototypoStore
.set('undoEventList', [])
.set('undoFrom', 0)
.set('undoTo', 0)
.commit();

localServer.dispatchUpdate('/prototypoStore', patch);
},
};
Loading

0 comments on commit 681519c

Please sign in to comment.