var LifeStore = Fluxxor.createStore({ initialize() { this.state = {}; this.state.height = 10; this.state.width = 10; this.state.speed = 1000; this.state.active = true; this.board = [[]] this.createBoard() this.bindActions( constants.TOGGLE_CELL, this.toggleCell, constants.TOGGLE_ACTIVE, this.toggleActive, constants.UPDATE_BOARD, this.updateBoard ) }, createBoard() { this.board = []; for(var x = 0; x < this.state.height; x++){ this.board[x] = []; for(var y = 0; y < this.state.width; y++){ this.board[x][y] = false; } } this.emit("change"); }, cellsAdj(p) { var adj = [ this.board[p.x+1][p.y], this.board[p.x-1][p.y], this.board[p.x][p.y+1], this.board[p.x][p.y-1] ] return _.compact(adj).length }, iterateBoard(cb) { for(var y=0;y<this.board.length;y++){ for(var x=0;x<this.board[y].length;x++){ cb({x: x, y: y}) } } }, updateBoard() { if(this.state.active){ var b = this.board this.iterateBoard(function(p){ }.bind(this)) this.emit("change"); } }, toggleActive() { this.state.active = !this.state.active; }, toggleCell(p){ this.board[p.y][p.x] = !this.board[p.y][p.x] this.emit("change"); } })
var Fluxxor = require('fluxxor'); var events = require('../constants.js').events; // var actions = require('../actions/actions.js'); var ServerStore = Fluxxor.createStore({ initialize: function() { this.servers = null; this.bindActions( events.SERVERS_CHANGED, this._serversChanged ); }, _serversChanged: function(payload) { this.servers = payload; this.emit('change'); }, getServers: function() { return this.servers; } }); module.exports = ServerStore;
module.exports = Fluxxor.createStore({ /** * Load institutions. */ initialize: function() { var self = this; this.institutions = null; request .get('/institutions/load') .end(function(err, res) { self.institutions = res.body.institutions; self.emit('change'); }); }, /** * Provide state to components. */ getState: function() { return { institutions: this.institutions }; }, });
var AppStore = Fluxxor.createStore({ actions: { OPEN_PATH: 'handleOpenBrowser', OPEN_DIRECTORY: 'handleOpenBrowser', OPEN_PAGE: 'handleOpenEditor', PUBLISH_SITE: 'handlePublishSite', }, initialize: function () { this.state = Immutable.fromJS({ route: 'BROWSER', }); }, handleOpenBrowser: function () { this.state = this.state.set('route', 'BROWSER'); this.emit('change'); }, handleOpenEditor: function () { this.state = this.state.set('route', 'EDITOR'); this.emit('change'); }, handlePublishSite: function () { api.publishSite().then(function (res) { console.log(res); }); }, });
var ComponentSpecStore = Fluxxor.createStore({ initialize: function(options) { this.loading = false; this.spec = null; this.xml = null; this.comments = []; this.activeView = Constants.INFO_VIEW_SPEC; this.expansionState = {}; this.linkedComponents = {}; this.newComment = null; this.bindActions( Constants.LOAD_COMPONENT_SPEC, this.handleLoadSpec, Constants.LOAD_COMPONENT_SPEC_SUCCES, this.handleLoadSpecSuccess, Constants.LOAD_COMPONENT_SPEC_XML_SUCCES, this.handleLoadSpecXmlSuccess, Constants.LOAD_COMPONENT_SPEC_FAILURE, this.handleLoadSpecFailure, Constants.TOGGLE_ITEM_EXPANSION, this.handleToggleItemExpansion, Constants.SET_ITEM_EXPANSION, this.handleSetItemExpansion, Constants.LINKED_COMPONENTS_LOADED, this.handleLinkedComponentsLoaded, Constants.COMPONENT_SPEC_UPDATED, this.handleSpecUpdate, Constants.LOAD_COMMENTS, this.handleLoadComments, Constants.LOAD_COMMENTS_SUCCESS, this.handleLoadCommentsSuccess, Constants.LOAD_COMMENTS_FAILURE, this.handleLoadCommentsFailure, Constants.SAVE_COMMENT, this.handleSaveComment, Constants.SAVE_COMMENT_SUCCESS, this.handleSaveCommentSuccess, Constants.SAVE_COMMENT_FAILURE, this.handleSaveCommentFailure, Constants.DELETE_COMMENT_SUCCESS, this.handleDeleteCommentSuccess ); }, getState: function() { return { loading: this.loading, activeView: this.activeView, spec: this.spec, xml: this.xml, comments: this.comments, newComment: this.newComment, expansionState: this.expansionState, // object that has a boolean value for each component 'appId' to indicate expansion linkedComponents : this.linkedComponents }; }, handleLoadSpec: function() { // loading a spec (XML or JSON) this.loading = true; this.emit("change"); }, handleLoadSpecSuccess: function(result) { var spec = result.spec; var linkedComponents = result.linkedComponents; // JSON spec loaded this.loading = false; this.spec = spec; // reset view state this.activeView = Constants.INFO_VIEW_SPEC; // reset expansion state this.expansionState = changeObj(spec.Component._appId, true); // reset linked components state if(linkedComponents == undefined) { this.linkedComponents = {}; } else { this.linkedComponents = linkedComponents; } this.emit("change"); }, handleSpecUpdate: function(spec) { this.spec = spec; this.emit("change"); }, handleLoadSpecXmlSuccess: function(xml) { // XML spec loaded this.loading = false; this.xml = xml; this.activeView = Constants.INFO_VIEW_XML; this.emit("change"); }, handleLoadSpecFailure: function() { // loading failed (XML or JSON) this.loading = false; this.emit("change"); }, handleToggleItemExpansion: function(obj) { var itemId = obj.itemId; var defaultState = obj.defaultState; // toggle boolean value in expansion state object (default when undefined is false) var currentState = ExpansionState.isExpanded(this.expansionState, itemId, defaultState); console.trace("Toggling", itemId, "currently", currentState); this.expansionState = ExpansionState.setChildState(this.expansionState, itemId, !currentState); console.trace("New expansion state: ", this.expansionState); this.emit("change"); }, handleSetItemExpansion: function(obj) { var itemIds = obj.itemIds; for(var i=0;i<(itemIds.length);i++) { this.expansionState = ExpansionState.setChildState(this.expansionState, itemIds[i], obj.expansionState); } this.emit("change"); }, handleLinkedComponentsLoaded: function(linkedComponents) { // additional linked components have been loaded - merge with current set this.linkedComponents = update(this.linkedComponents, {$merge: linkedComponents}); this.emit("change"); }, handleLoadComments: function() { this.loading = true; this.comments = []; this.emit("change"); }, handleLoadCommentsSuccess: function(comments) { this.loading = false; if($.isArray(comments)) { this.comments = comments; } else { this.comments = [comments]; } this.activeView = Constants.INFO_VIEW_COMMENTS; this.emit("change"); }, handleLoadCommentsFailure: function() { this.loading = false; }, handleSaveComment: function(comments) { log.debug("Saving comment", comments); //store form value (in case save action fails) this.newComment = comments; //push temporary comment (optimistic update) var comment = { canDelete: false, userName: "******", commentDate: null, comments: comments }; if($.isArray(this.comments)) { this.comments = update(this.comments, {$push: [comment]}); } else { this.comments = [comments]; } this.emit("change"); }, handleSaveCommentSuccess: function(comment) { log.debug("Saved comment", comment); //form value can be removed, form should be blank this.newComment = ""; //replace temporary comment with actual result comment = update(comment, {$merge: {canDelete: "true"}}); this.comments = update(this.comments, {$splice: [[this.comments.length-1, 1, comment]]}); this.emit("change"); }, handleSaveCommentFailure: function() { //remove temporary comment this.comments = update(this.comments, {$splice: [[this.comments.length-1, 1]]}); this.emit("change"); }, handleDeleteCommentSuccess: function(id) { // look up the comment in the current comments list var index = -1; if($.isArray(this.comments)) { for(i=0;i<this.comments.length;i++) { if(this.comments[i].id == id) { index = i; } } } // and remove it (if found) if(index >=0) { this.comments = update(this.comments, {$splice: [[index, 1]]}); } else { log.warn("Did not find comment with id", id, "to remove, display state may be inaccurate"); } this.emit("change"); } });
var SuggestionStore = module.exports = Fluxxor.createStore({ initialize: function() { this.models = []; this.timer = null; this.timeout = 1; this.isLoading = false; this.error = null; this.bindActions( constants.PERSON_LOAD_PENDING, this.handleLoadPending, constants.PERSON_LOAD_COMPLETE, this.handleLoadComplete ); log('INIT', this); }, handleLoadPending: Common.handleLoadPending, handleLoadComplete(payload) { if (Array.isArray(payload.models) && payload.models.length === 0) { this.timeout = Math.min(this.timeout * 2 + 1000, 1000 * 60); } else { this.timeout = 1; } return Common.handleLoadComplete.call(this, payload); }, get: Common.get, getAll: Common.getAll, getState: Common.getState, length() { return this.models.length; }, peek(n) { return this.models.slice(0, n); }, shift() { this.models.shift(); this.emit('change'); }, });
var AuthStore = Fluxxor.createStore({ initialize: function(params) { this.state = { token: null, trainer: null }; this.bindActions( CONSTANTS.AUTH.INIT, this.authInitialize, CONSTANTS.AUTH.AUTHO.GET, this.autho.getTrainer, CONSTANTS.AUTH.AUTHO.LOCK, this.autho.createLock, CONSTANTS.AUTH.AUTHO.SHOW, this.autho.show, CONSTANTS.AUTH.AUTHO.LOGOUT, this.autho.logout, CONSTANTS.AUTH.SPOTTER.GET, this.spotter.getTrainer, CONSTANTS.TRAINER.UPDATE, this.spotter.updateTrainer, CONSTANTS.TRAINER.IMAGE.ADD, this.spotter.updateTrainerImage, CONSTANTS.TRAINER.IMAGE.UPLOADED, this.spotter.uploadedTrainerImage ); }, authInitialize: function() { var token = localStorage.getItem('token'); if (token && window.location.hash.search('access_token') === -1) { this.state.token = token; SpotterAPI.getTrainer(function(data) { if (data.id) { this.state.trainer = data; this.flux.actions.page.update({ page: 'home' }); this.flux.actions.clients.get(); } else { setTimeout(function() { this.flux.actions.auth.autho.lock(); this.flux.actions.auth.autho.show(); }.bind(this)); } }.bind(this)); } else { setTimeout(function() { this.flux.actions.auth.autho.lock(); this.flux.actions.auth.autho.show(); }.bind(this)); } }, autho: { createLock: function() { this.state.lock = new Auth0Lock('YDvRFV8XQoX3fuF1X65l8RqMSmCKHGOg', 'fitflow.eu.auth0.com',{ container: 'auth', allowedConnections: ['google-oauth2', 'facebook'], avatar: null, languageDictionary: { title: 'Log in' }, theme: { logo: window.location.pathname + 'images/loader.png', primaryColor: 'white' }, auth: { redirect: true, responseType: 'token' } }); this.state.lock.on('authenticated', function(authResult) { this.state.lock.getProfile(authResult.idToken, function(error, profile) { if (error) { this.signOut(); return; } this.autho.getTrainer.bind(this)(authResult, profile); }.bind(this)); }.bind(this)); }, show: function() { this.state.lock.show(); }, getTrainer: function(authResult, profile) { if (!authResult.idToken) { return; } try { localStorage.setItem('token', authResult.idToken); } catch (e) {} this.state.token = authResult.idToken; if (this.state.token) { setTimeout(function() { this.flux.actions.auth.spotter.get(); }.bind(this), 0); } }, logout: function() { try { localStorage.clear(); } catch(e) { } window.location.href = 'https://fitflow.eu.auth0.com/v2/logout?returnTo=' + encodeURI(window.location.origin) + '&client_id=YDvRFV8XQoX3fuF1X65l8RqMSmCKHGOg'; } }, spotter: { getTrainer: function() { SpotterAPI.getTrainer(function(data) { if (data.id) { this.state.trainer = data; this.flux.actions.page.update({ page: 'home' }); this.flux.actions.clients.get(); } else if (data.code && data.description) { alert(data.description); } else { alert('Sorry, something has gone wrong!'); } }.bind(this)); }, updateTrainer: function(payload) { payload.trainer.name = payload.trainer.fname + ' ' + payload.trainer.lname; SpotterAPI.updateTrainer(payload.trainer, function(data) { console.log('updateTrainer', data); }); }, updateTrainerImage: function(payload) { SpotterAPI.imageTrainer(payload.file, function(data) { this.flux.actions.trainer.image.uploaded({ id: payload.id, url: data.url }); }.bind(this)); }, uploadedTrainerImage: function(payload) { this.state.trainer.picture = payload.url + '?cachebust=' + Math.floor(Math.random() * 20); this.emit('change:trainerImageUploaded'); this.emit('change'); } }, signOut: function() { localStorage.clear(); this.state.token = null; this.state.trainer = null; }, getState: function(){ return this.state; } });
var Fluxxor = require('fluxxor'); var ec = require('../eventConstants.js'); var LocationStore = Fluxxor.createStore({ initialize() { this.location = {}; this.bindActions( ec.server.CHANGE_LOCATION, this.handleChangeLocation ); }, handleChangeLocation(location) { this.location = location; this.emit('change'); }, getLocation() { return JSON.parse(JSON.stringify(this.location)); } }); module.exports = LocationStore;
const MainStore = Fluxxor.createStore({ initialize() { this.event = { atViget : true, name : 'Boulder Refresh', date : 'Jan. 1', time : '12:00AM', description : 'Loading...' } this.weather = { currently : 0, currentlyIcon : 'clear-day', later : 0, laterIcon : 'clear-day', muchLater : 0, muchLaterIcon : 'clear-day' } this.bindActions( 'UPDATE_WEATHER', this.onUpdateWeather, 'UPDATE_EVENT', this.onUpdateEvent, 'UPDATE_BUSES', this.onUpdateBuses ) }, onUpdateWeather(payload) { this.weather = payload this.emit('change') }, onUpdateEvent(payload) { this.event = payload this.emit('change') }, onUpdateBuses(payload) { this.buses = payload this.emit('change') }, getState() { return { event : this.event, weather : this.weather, buses : this.buses } } })
var CommentsStore = Fluxxor.createStore({ self: this, initialize: function(){ this.loading = false; this.commentsMap = {}; this.bindActions( constants.LOAD_COMMENTS, this.startLoading, constants.LOAD_COMMENTS_SUCCESS, this.loadCommentsSuccess, constants.LOAD_COMMENTS_FAIL, this.stopLoading, constants.CREATE_COMMENT, this.startLoading, constants.CREATE_COMMENT_SUCCESS, this.createCommentSuccess, constants.CREATE_COMMENT_FAIL, this.stopLoading, constants.UPDATE_COMMENT, this.startLoading, constants.UPDATE_COMMENT_SUCCESS, this.updateCommentSuccess, constants.UPDATE_COMMENT_FAIL, this.stopLoading, constants.DELETE_COMMENT, this.startLoading, constants.DELETE_COMMENT_SUCCESS, this.deleteCommentSuccess, constants.DELETE_COMMENT_FAIL, this.stopLoading ); }, deleteCommentSuccess: function(payload){ this.loading = false; this.commentsMap[payload.id] = undefined; this.emit('change'); }, updateCommentSuccess: function(payload){ this.loading = false; this.consumeComments([payload.comment]); this.emit('change'); }, createCommentSuccess: function(payload){ this.loading = false; this.consumeComments([payload.comment]); this.emit('change'); }, consumeComments: function(comments){ if (comments == undefined){ return; } for (var i in comments){ this.commentsMap[comments[i].id] = comments[i]; } }, loadCommentsSuccess: function(payload){ this.loading = false; this.consumeComments(payload.comments); this.emit('change'); }, startLoading: function(){ this.loading = true; this.emit('change'); }, stopLoading: function(){ this.loading = false; this.emit('change'); }, getParentComments: function(parentId){ var arr = []; var map = this.commentsMap; for (var key in map){ var c = map[key]; if (c.parentId == parentId){ arr.push(c); } } arr.sort(function(a, b){ return (a.timestamp - b.timestamp); }); return arr; }, getComment: function(commentId){ if (commentId == undefined){ return undefined; } return this.commentsMap[commentId]; } });
var ScoreEditorStore = Fluxxor.createStore({ initialize: function() { this.id = null; this.selectedPane = "General"; this.scoreTitle = ""; this.message = ""; this.score = null; this.selectedNode = null; this.menuItems = ["General", "Assets", "Configure"]; this.parentOperations = [ { value: 0, name: "" }, { value: "SUM", name: "SUM" }, { value: "DIFFERENCE", name: "DIFFERENCE" }, { value: "DIVIDE", name: "DIVIDE" }, { value: "MULTIPLY", name: "MULTIPLY" }]; this.dataPointList = []; this.bindActions( constants.SCORE_NODE_CHANGED, this.onScoreNodeChanged, constants.SCORE_PANE_CHANGED, this.onScorePaneChanged, constants.UPDATE_SCORE_TITLE, this.onUpdateScoreTitle, constants.UPDATE_NODE_NAME, this.onUpdateNodeName, constants.UPDATE_NODE_WEIGHT, this.onUpdateNodeWeight, constants.UPDATE_NODE_MODE, this.onUpdateNodeMode, constants.LOAD_DATA_SUCCESS, this.onLoadDataSuccess, constants.UPDATE_NODE_OPERATION, this.onUpdateNodeOperation, constants.UPDATE_NODE_DATA, this.onUpdateNodeData, constants.SAVE_SCORE, this.onSaveScore, constants.SAVE_SCORE_SUCCESS, this.onSaveScoreSuccess, constants.SAVE_SCORE_FAIL, this.onSaveScoreFail, constants.RESET_SCORE_EDITOR, this.onResetScoreEditor, constants.LOAD_SAVED_SCORE, this.onLoadSavedScore ) }, onResetScoreEditor: function() { this.score = null; this.selectedNode = null; this.scoreTitle = ""; this.id = null; this.emit("change"); }, onLoadSavedScore: function(payload) { this.scoreTitle = payload.score.name, this.score = payload.score, this.id = payload.score.id, //myDiagram && load(e.score), this.emit("change") }, onSaveScoreSuccess: function(e) { this.score = e.score, this.message = "Score Saved!", // ReactRouter.HistoryLocation.push("/apt/editor_score/" + e.score.id), this.emit("change") }, onSaveScoreFail: function() {}, onSaveScore: function(e) {}, onUpdateNodeData: function(e) { var t = myDiagram.model, a = this.findSelectedData(e.data_id); t.startTransaction("update data"), t.setDataProperty(this.selectedNode, "name", a.icon), t.setDataProperty(this.selectedNode, "dataname", a.point), t.commitTransaction("update data"), this.emit("change") }, findSelectedData: function(e) { for (var t = 0; t < this.dataPointList.length; t++) if (parseInt(e) === this.dataPointList[t].id) return this.dataPointList[t] }, onUpdateNodeOperation: function(e) { var t = myDiagram.model; t.startTransaction("update operation"), t.setDataProperty(this.selectedNode, "operation", e.operation);//parseInt(e.operation)), t.setDataProperty(this.selectedNode, "name", e.operation); // t.setDataProperty(this.selectedNode, "name", this.parentOperations[parseInt(e.operation)].name), t.commitTransaction("update operation"), save(), this.emit("change") }, onUpdateNodeMode: function(e) { var t = myDiagram.model; t.startTransaction("update mode"); t.setDataProperty(this.selectedNode, "mode", e.mode); t.commitTransaction("update mode"); save(); this.emit("change"); }, onUpdateNodeWeight: function(e) { var t = myDiagram.model; t.startTransaction("update weight"), t.setDataProperty(this.selectedNode, "weight", e.weight), t.commitTransaction("update weight"), save(), this.emit("change") }, onUpdateNodeName: function(e) { var t = myDiagram.model; t.startTransaction("update name"); t.setDataProperty(this.selectedNode, "component", e.name); t.commitTransaction("update name"); save(); this.emit("change"); }, onUpdateScoreTitle: function(e) { this.scoreTitle = e.title, this.emit("change") }, onScorePaneChanged: function(e) { this.selectedPane = e.pane, this.emit("change") }, onScoreNodeChanged: function(e) { null === e.node ? (this.selectedNode = null, this.selectedPane = "General") : (this.selectedNode = e.node.data, this.selectedPane = "Configure"), this.emit("change") }, onLoadDataSuccess: function(payload) { this.dataPointList = payload.data; this.emit("change"); }, createDataPointList: function() { var list = []; for (var i = 0; i < this.dataPointList.length; i++) { var item = this.dataPointList[i]; list.push(item.point.split("_").join(" ")) } return list; }, getState: function() { return { selectedPane: this.selectedPane, selectedNode: this.selectedNode, menuItems: this.menuItems, scoreTitle: this.scoreTitle, parentOperations: this.parentOperations, dataPointList: this.dataPointList, dataPointNames: this.createDataPointList(), message: this.message, score: this.score, id: this.id } } });
var PuserStore = Fluxxor.createStore({ self: this, initialize: function(){ this.initPusher(); this.messages = []; this.bindActions( constants.SEND_PUSHER_MESSAGE, this.sendPusherMessage ); }, initPusher: function(){ console.log('initPusher: Pusher = ', Pusher); if (this.pusher != undefined){ return; } //this.pusherServer = new PusherServer({ // appId: '161086', // key: '3eed46933cb0fc3713a7', // secret: 'bd4302b0235cbb6c1692' //}); var channelName = ''; var sessionToken = ParseAPI.getSessionToken(); console.log('Session Token = ' + sessionToken); this.pusher = new Pusher('3eed46933cb0fc3713a7', { //authEndpoint: 'https://api.parse.com/1/functions/authorizePusherChannel', authEndpoint: 'http://sportstracker.parseapp.com/pusherAuth', auth: { headers: { 'X-Parse-Session-Token': sessionToken, 'X-Parse-Application-Id': "DY9RPeNTtxZoi4rkuHU5VQpx6iZiqVj0EPdTPUDE", 'X-Parse-REST-API-Key': "nXBiK8HpMx3I0cheUm41WMEKKWUpoKV0QOhqy7VN" } } }); this.channel = this.pusher.subscribe('private-sabir'); this.channel.bind('pusher:subscription_succeeded', function() { //alert('pusher:subscription_succeeded success callback '); //var triggered = channel.trigger('client-someeventname', { your: data }); }); this.channel.bind('client-sabir', function(data) { this.consumeMessage(data.message); this.emit('change'); }.bind(this)); }, consumeMessage: function(message){ console.log('consume message: message = ', message); if (message == undefined){ return; } this.messages.push(message); }, getLastMessage: function(){ var messages = this.messages; if (messages == undefined || messages.length == 0){ return undefined; } return messages[messages.length - 1]; }, sendPusherMessage: function(payload){ //if (this.pusher == undefined){ // return; //} //var channel = this.pusher.subscribe(payload.channel); //this.pusherServer.trigger(payload.channel, payload.event, { message: payload.message }); var eventName = 'client-' + payload.event; this.consumeMessage(payload.message); this.channel.trigger('client-sabir', { message: payload.message }); this.emit('change'); } });
DataStore = Fluxxor.createStore({ initialize: function() { this.data = []; this.dataLoaded = false; this.loading = false; this.bindActions( constants.LOAD_DATA_SUCCESS, this.onLoadDataSuccess, constants.LOAD_DATA, this.onLoadData ) }, onLoadData: function() { this.loading = true; }, onLoadDataSuccess: function(payload) { this.data = payload.data; this.dataLoaded = true; this.loading = false; this.emit("change"); }, getState: function() { return { data: this.data, loading: this.loading, loaded: this.dataLoaded } } }); module.exports = DataStore;
define(function (require, exports, module) { "use strict"; var Fluxxor = require("fluxxor"), _ = require("lodash"); var events = require("../events"), log = require("js/util/log"); /** * Panel/column identifiers. * * @const * @type {object} */ var UI_COMPONENTS = Object.freeze({ LAYERS_LIBRARY_COL: "layersLibrariesVisible", PROPERTIES_COL: "propertiesVisible", TRANSFORM_PANEL: "transformVisible", STYLES_PANEL: "stylesVisible", APPEARANCE_PANEL: "appearanceVisible", EFFECTS_PANEL: "effectsVisible", EXPORT_PANEL: "exportVisible", LAYERS_PANEL: "layersVisible", LIBRARIES_PANEL: "libraryVisible" }); var PanelStore = Fluxxor.createStore({ /** * Flag to tell whether Scrim should draw any of the SVG overlays or not * * @private * @type {boolean} */ _overlaysEnabled: null, /** * A count of current number of requests to disable the overlays. * * @private * @type {number} */ _overlayCount: 0, /** * Flag to tell if the scrim should be drawing a marquee * * @private * @type {boolean} */ _marqueeEnabled: null, /** * Marquee start location * * @private * @type {{x: number, y: number}} */ _marqueeStart: null, /** * Panel set width * * @private * @type {number} */ _panelWidth: null, /** * Icon bar width * * @private * @type {number} */ _iconBarWidth: null, /** * Document header height * * @private * @type {number} */ _headerHeight: null, /** * Toolbar width, 0 if it's not pinned * * @private * @type {number} */ _toolbarWidth: null, /** * Constants used to refer to different panels/columns. * * @const * @type {object} */ components: UI_COMPONENTS, /** * Reference point for a layer when adjusting W and H * Default is "lt" for left, top * * @private * @type {string} */ _referencePoint: null, /** * UI color stop. Must be one of "ORIGINAL", "LIGHT", "MEDIUM" or "DARK". * * @private * @type {string} */ _colorStop: null, /** * The coordinates of the current mouse position if it's being tracked; otherwise null. * * @private * @type {?{currentMouseX: number, currentMouseY: number}} */ _currentMousePosition: null, /** * A bound, debounced version of _setOverlays, * * @type {function} */ _enableOverlaysDebounced: null, initialize: function () { this.bindActions( events.RESET, this._handleReset, events.panel.PANELS_RESIZED, this._handlePanelResize, events.panel.SUPERSELECT_MARQUEE, this._handleMarqueeStart, events.panel.REFERENCE_POINT_CHANGED, this._handleReferencePointChanged, events.panel.COLOR_STOP_CHANGED, this._handleColorStopChanged, events.panel.MOUSE_POSITION_CHANGED, this._handleMousePositionChanged, events.panel.START_CANVAS_UPDATE, this._handleStartCanvasUpdate, events.panel.END_CANVAS_UPDATE, this._handleEndCanvasUpdate ); this._enableOverlaysDebounced = _.debounce(this._setOverlays.bind(this), 100); // HACK: Do not reset panel sizes because they should remain constant. this._panelWidth = -1; this._columnCount = -1; this._iconBarWidth = -1; this._headerHeight = -1; this._toolbarWidth = -1; this._handleReset(); }, /** * Reset or initialize store state. * * @private */ _handleReset: function () { this._overlayCount = 0; this._overlaysEnabled = true; this._marqueeEnabled = false; this._marqueeStart = null; this._referencePoint = "lt"; this._colorStop = null; this._currentMousePosition = null; }, /** @ignore */ getState: function () { var panelsInitialized = this._panelWidth >= 0 && this._columnCount >= 0 && this._iconBarWidth >= 0 && this._headerHeight >= 0 && this._toolbarWidth >= 0; return { centerOffsets: this.getCenterOffsets(), overlaysEnabled: this._overlaysEnabled, marqueeEnabled: this._marqueeEnabled, marqueeStart: this._marqueeStart, referencePoint: this._referencePoint, panelsInitialized: panelsInitialized }; }, /** * Calculate the overlay offsets, optionally taking into account a * (future) number of open columns. * * @return {{top: number, right: number, bottom: number, left: number}} */ getCenterOffsets: function (columns) { var preferences = this.flux.store("preferences").getState(), singleColumn = preferences.get("singleColumnModeEnabled", false), right = (columns !== undefined && singleColumn) ? 0 : this._iconBarWidth; if (singleColumn) { right += this._panelWidth; } else if (columns === undefined || columns === this._columnCount) { right += this._panelWidth; } else if (columns > 0) { if (columns === 1 && this._columnCount === 2) { right += (this._panelWidth / 2); } else if (columns === 2 && this._columnCount === 1) { right += (this._panelWidth * 2); } else { log.warn("Unable to infer enter offsets for " + columns + " columns from " + this._columnCount); } } return { top: this._headerHeight, right: right, left: this._toolbarWidth, bottom: 0 }; }, /** * Get the current cloaking rectangle, which omits the static UI. * * @return {?{top: number, right: number, left: number, bottom: number}} */ getCloakRect: function () { var centerOffsets = this.getCenterOffsets(), windowWidth = window.document.body.clientWidth, windowHeight = window.document.body.clientHeight; return { left: centerOffsets.left, top: centerOffsets.top, bottom: windowHeight - centerOffsets.bottom, right: windowWidth - centerOffsets.right }; }, /** * Updates the center offsets when they change. * * @private * @param {{panelWidth: number=, headerHeight: number=, toolbarWidth: number=}} payload */ _handlePanelResize: function (payload) { var changed; if (payload.hasOwnProperty("panelWidth") && payload.panelWidth !== this._panelWidth) { this._panelWidth = payload.panelWidth; changed = true; } if (payload.hasOwnProperty("columnCount") && payload.columnCount !== this._columnCount) { this._columnCount = payload.columnCount; changed = true; } if (payload.hasOwnProperty("iconBarWidth") && payload.iconBarWidth !== this._iconBarWidth) { this._iconBarWidth = payload.iconBarWidth; changed = true; } if (payload.hasOwnProperty("headerHeight") && payload.headerHeight !== this._headerHeight) { this._headerHeight = payload.headerHeight; changed = true; } if (payload.hasOwnProperty("toolbarWidth") && payload.toolbarWidth !== this._toolbarWidth) { this._toolbarWidth = payload.toolbarWidth; changed = true; } if (changed) { this.emit("change"); } }, /** * Update the overlaysEnabled property based on the current overlayCount. * * @private */ _setOverlays: function () { var nextEnabled = this._overlayCount === 0; if (nextEnabled !== this._overlaysEnabled) { this._overlaysEnabled = nextEnabled; this.emit("change"); } }, /** * Increase the overlay count and immediately update overlaysEnabled * when starting a canvas update. * * @private */ _handleStartCanvasUpdate: function () { this._overlayCount++; this._setOverlays(); this._enableOverlaysDebounced.cancel(); }, /** * Decrease the overlay count and update overlaysEnabled once the * overlay count has quiesced. * * @private */ _handleEndCanvasUpdate: function () { if (this._overlayCount === 0) { return; } this._overlayCount--; this._enableOverlaysDebounced(); }, /** * Updates the marquee start location and flag * * @param {{x: number, y: number, enabled: boolean}} payload */ _handleMarqueeStart: function (payload) { this._marqueeEnabled = payload.enabled; this._marqueeStart = payload.enabled ? { x: payload.x, y: payload.y } : null; this.emit("change"); }, /** * Set the size-adjustment reference point. * * @private * @param {{referencePoint: string}} payload */ _handleReferencePointChanged: function (payload) { this._referencePoint = payload.referencePoint; this.emit("change"); }, /** * Set the UI color stop. * * @private * @param {{stop: string}} payload */ _handleColorStopChanged: function (payload) { this._colorStop = payload.stop; this.emit("change"); }, /** * Update the current mouse position. * * @private * @param {?{currentMouseX: number, currentMouseY: number}} payload */ _handleMousePositionChanged: function (payload) { this._currentMousePosition = payload; }, /** * Get the current mouse position if it's being tracked; otherwise null. * * @return {?{currentMouseX: number, currentMouseY: number}} */ getCurrentMousePosition: function () { return this._currentMousePosition; }, /** * Get the current UI color stop. * * @return {?string} An element of the enum appLib.colorStops */ getColorStop: function () { return this._colorStop; } }); module.exports = PanelStore; });
define(function (require, exports, module) { "use strict"; var Fluxxor = require("fluxxor"), Immutable = require("immutable"), _ = require("lodash"); var events = require("../events"), DocumentIndex = require("js/models/documentindex"); var ApplicationStore = Fluxxor.createStore({ // Photoshop Version _hostVersion: null, /** * Set of boolean values designating when portions of the application have been initialized * * @type {Immutable.Set.<string>} */ _initialized: Immutable.Set(), /** * List of paths for recent files opened in Photoshop * @private * @type {Immutable.List.<string>} */ _recentFiles: Immutable.List(), /** * Index of currently open documents in Photoshop. * * @private * @type {DocumentIndex} */ _documentIndex: new DocumentIndex(), initialize: function () { this.bindActions( events.RESET, this._handleReset, events.application.HOST_VERSION, this.setHostVersion, events.application.INITIALIZED, this._setInitialized, events.application.UPDATE_RECENT_FILES, this._updateRecentFileList, events.document.DOCUMENT_UPDATED, this._updateDocument, events.document.CLOSE_DOCUMENT, this._closeDocument, events.document.SELECT_DOCUMENT, this._documentSelected ); }, /** * Reset or initialize store state. * * @private */ _handleReset: function () { this._documentIndex = new DocumentIndex(); this._hostVersion = null; this._recentFiles = Immutable.List(); this._initialized = Immutable.Set(); this.emit("reset"); }, getState: function () { var documentIndex = this._documentIndex; return { hostVersion: this._hostVersion, activeDocumentInitialized: this._initialized.get("activeDocument"), inactiveDocumentsInitialized: this._initialized.get("inactiveDocuments"), recentFilesInitialized: this._initialized.get("recentFiles"), recentFiles: this._recentFiles, documentIDs: documentIndex.openDocumentIDs, selectedDocumentIndex: documentIndex.activeDocumentIndex, selectedDocumentID: documentIndex.activeDocumentID }; }, /** * Returns the id of currently active document, null if there is none * * @return {number} */ getCurrentDocumentID: function () { return this._documentIndex.activeDocumentID; }, /** * Get the list of open document IDs * * @return {Immutable.List.<number>} */ getOpenDocumentIDs: function () { return this._documentIndex.openDocumentIDs; }, /** * Returns the list of recent document paths * * @return {Immutable.List.<string>} */ getRecentFiles: function () { return this._recentFiles; }, /** * Get the currently active document model, or null if there are none. * * @return {?Document} */ getCurrentDocument: function () { var documentStore = this.flux.store("document"); return documentStore.getDocument(this._documentIndex.activeDocumentID); }, /** * Get the currently active document models * * @return {Immutable.List.<Document>} */ getOpenDocuments: function () { var documentStore = this.flux.store("document"), documents = this._documentIndex.openDocumentIDs .map(function (id) { return documentStore.getDocument(id); }) .filter(function (document) { return document; }); return documents; }, /** * Get the list of open but uninitialized document models. * * @return {Immutable.List.<Document>} */ getInitializedDocuments: function () { return this.getOpenDocuments() .filter(function (document) { return document.layers; }); }, /** * Get the list of open but uninitialized document models. * * @return {Immutable.List.<Document>} */ getUninitializedDocuments: function () { return this.getOpenDocuments() .filterNot(function (document) { return document.layers; }); }, /** * The number of currently open documents; * * @return {number} */ getDocumentCount: function () { return this._documentIndex.openDocumentIDs.size; }, /** * Find the next document in the document index. * * @return {?Document} */ getNextDocument: function () { var documentStore = this.flux.store("document"), nextDocumentID = this._documentIndex.nextID; return documentStore.getDocument(nextDocumentID); }, /** * Find the previous document in the document index. * * @return {?Document} */ getPreviousDocument: function () { var documentStore = this.flux.store("document"), previousDocumentID = this._documentIndex.previousID; return documentStore.getDocument(previousDocumentID); }, /** @ignore */ setHostVersion: function (payload) { var parts = [ payload.versionMajor, payload.versionMinor, payload.versionFix ]; this._hostVersion = parts.join("."); this.emit("change"); }, /** * Sets the initialized flag to true and emits a change * @private * @param {{item: string}} payload includes name of the item/module that has been initialized */ _setInitialized: function (payload) { var item = payload.item; if (item && !this._initialized.get(item)) { this._initialized = this._initialized.add(item); this.emit("change"); } }, /** * Updates the recent file list * * @private * @param {{recentFiles: Array.<string>}} payload */ _updateRecentFileList: function (payload) { // If a file has been deleted, PS sends us an empty string for that file // So we have to filter it out this._recentFiles = Immutable.List(_.compact(payload.recentFiles)); this.emit("change"); }, /** * Set or reset the position of the given document in the document index. * * @private * @param {{document: object, layers: Array.<object>}} payload */ _updateDocument: function (payload) { this.waitFor(["document"], function () { var rawDocument = payload.document, documentID = rawDocument.documentID, itemIndex = rawDocument.itemIndex - 1, // doc indices start at 1 current = payload.current; this._documentIndex = this._documentIndex.setPosition(documentID, itemIndex, current); this.emit("change"); }); }, /** * Remove the given document ID from the document index, and set a new * selected document ID and index. * * @private * @param {{document: object, layers: Array.<object>}} payload */ _closeDocument: function (payload) { this.waitFor(["document"], function () { var documentID = payload.documentID, selectedDocumentID = payload.selectedDocumentID; this._documentIndex = this._documentIndex.remove(documentID, selectedDocumentID); this.emit("change"); }); }, /** * Set the currently active document. * * @private * @param {{selectedDocumentID: number}} payload */ _documentSelected: function (payload) { var selectedDocumentID = payload.selectedDocumentID; this._documentIndex = this._documentIndex.setActive(selectedDocumentID); this.emit("change"); } }); module.exports = ApplicationStore; });
var AuthenticationStore = Fluxxor.createStore({ initialize: function(options) { this.authState = {authenticated: false}; this.lastChecked = null; this.bindActions( Constants.LOGIN_SUCCESS, this.handleLoginState, Constants.CHECK_AUTH_STATE, this.handleLoginState ); }, getState: function() { return { authState: this.authState, lastChecked: this.lastChecked }; }, handleLoginState: function(newValues) { var newState; if(newValues.uid != undefined && newValues.uid != null) { // uid set -> user authenticated newState = { authenticated: true, uid: newValues.uid, displayName: newValues.displayName, isAdmin: newValues.isAdmin, userId: newValues.userId }; } else { // uid not set -> user not authenticated newState = { authenticated: false, isAdmin: false }; } this.lastChecked = Date.now(); if(JSON.stringify(this.authState) !== JSON.stringify(newState)) { log.info("Authentication state changed to", newState); this.authState = newState; this.emit("change"); } } });
var PageStore = Fluxxor.createStore({ init() { this._username = undefined; this._isLoggedIn = false; }, initialize() { this.init(); this.bindActions( EC.SERVER.LOGIN, this.handleLogin, EC.SERVER.LOGOUT, this.handleLogout ); }, /*========== getters ==========*/ getUsername() { return this._username; }, isLoggedIn() { return this._isLoggedIn; }, /*========== handlers ==========*/ handleLogin({username, isLoggedIn}) { this._username = username; this._isLoggedIn = isLoggedIn; this.emit("change"); }, handleLogout() { this.init(); this.emit("change"); } });
define(function (require, exports, module) { "use strict"; var Fluxxor = require("fluxxor"), Immutable = require("immutable"), _ = require("lodash"); var MenuBar = require("js/models/menubar"), events = require("../events"); /** * The Menu store keeps track of the application menu * and the state of items in it * * @constructor */ var MenuStore = Fluxxor.createStore({ /** * Current application menubar * * @private * @type {MenuBar} */ _applicationMenu: null, /** * Initialize the policy sets */ initialize: function () { this.bindActions( events.RESET, this._handleReset, events.application.UPDATE_RECENT_FILES, this._updateRecentFiles, events.menus.INIT_MENUS, this._handleMenuInitialize, events.menus.UPDATE_MENUS, this._updateMenuItems, events.document.SELECT_DOCUMENT, this._updateMenuItems, events.document.DOCUMENT_UPDATED, this._updateMenuItems, events.document.SAVE_DOCUMENT, this._updateMenuItems, events.document.DOCUMENT_RENAMED, this._updateMenuItems, events.document.CLOSE_DOCUMENT, this._updateMenuItems, events.document.history.nonOptimistic.ADD_LAYERS, this._updateMenuItems, events.document.GUIDES_VISIBILITY_CHANGED, this._updateMenuItems, events.document.RESET_LAYERS, this._updateMenuItems, events.document.RESET_LAYERS_BY_INDEX, this._updateMenuItems, events.document.history.nonOptimistic.RESET_BOUNDS, this._updateMenuItems, events.document.history.optimistic.REORDER_LAYERS, this._updateMenuItems, events.document.SELECT_LAYERS_BY_ID, this._updateMenuItems, events.document.SELECT_LAYERS_BY_INDEX, this._updateMenuItems, events.document.VISIBILITY_CHANGED, this._updateMenuItems, events.document.history.optimistic.LOCK_CHANGED, this._updateMenuItems, events.document.history.optimistic.OPACITY_CHANGED, this._updateMenuItems, events.document.history.optimistic.BLEND_MODE_CHANGED, this._updateMenuItems, events.document.history.optimistic.RENAME_LAYER, this._updateMenuItems, events.document.history.optimistic.DELETE_LAYERS, this._updateMenuItems, events.document.history.nonOptimistic.DELETE_LAYERS, this._updateMenuItems, events.document.history.optimistic.GROUP_SELECTED, this._updateMenuItems, events.document.history.optimistic.REPOSITION_LAYERS, this._updateMenuItems, events.document.TRANSLATE_LAYERS, this._updateMenuItems, events.document.history.optimistic.RESIZE_LAYERS, this._updateMenuItems, events.document.history.optimistic.SET_LAYERS_PROPORTIONAL, this._updateMenuItems, events.document.history.optimistic.RESIZE_DOCUMENT, this._updateMenuItems, events.document.history.optimistic.RADII_CHANGED, this._updateMenuItems, events.document.history.optimistic.FILL_COLOR_CHANGED, this._updateMenuItems, events.document.history.optimistic.FILL_OPACITY_CHANGED, this._updateMenuItems, events.document.history.optimistic.FILL_ADDED, this._updateMenuItems, events.document.STROKE_ALIGNMENT_CHANGED, this._updateMenuItems, events.document.STROKE_ENABLED_CHANGED, this._updateMenuItems, events.document.STROKE_WIDTH_CHANGED, this._updateMenuItems, events.document.history.optimistic.STROKE_COLOR_CHANGED, this._updateMenuItems, events.document.history.optimistic.STROKE_OPACITY_CHANGED, this._updateMenuItems, events.document.history.nonOptimistic.STROKE_ADDED, this._updateMenuItems, events.document.history.optimistic.LAYER_EFFECT_CHANGED, this._updateMenuItems, events.document.TYPE_FACE_CHANGED, this._updateMenuItems, events.document.TYPE_SIZE_CHANGED, this._updateMenuItems, events.document.history.optimistic.TYPE_COLOR_CHANGED, this._updateMenuItems, events.document.TYPE_TRACKING_CHANGED, this._updateMenuItems, events.document.TYPE_LEADING_CHANGED, this._updateMenuItems, events.document.TYPE_ALIGNMENT_CHANGED, this._updateMenuItems, events.dialog.OPEN_DIALOG, this._updateMenuItems, events.dialog.CLOSE_DIALOG, this._updateMenuItems, events.history.LOAD_HISTORY_STATE, this._updateMenuItems, events.history.LOAD_HISTORY_STATE_REVERT, this._updateMenuItems, events.document.GUIDES_VISIBILITY_CHANGED, this._updateViewMenu, events.preferences.SET_PREFERENCE, this._updateNonDocWindowMenu ); this._handleReset(); }, /** * Reset or initialize store state. * * @private */ _handleReset: function () { this._applicationMenu = new MenuBar(); }, /** * Returns the current application menu object * * @return {MenuBar} */ getApplicationMenu: function () { return this._applicationMenu; }, /** * Dispatched by menu actions when json files are first loaded * Initializes the menus in a MenuBar object * * Menu actions listen to the change event from this store, * and send a installMenu call to Photoshop. * * This is unique to this situation, because we skip the * React component in the Flux cycle * * @private * @param {{menus: object, actions: object, templates: Array.<object>}} payload */ _handleMenuInitialize: function (payload) { var menus = payload.menus, actions = payload.actions, templates = payload.templates; this._applicationMenu = MenuBar.fromJSONObjects(menus, actions, templates); this.emit("change"); }, /** * Helper function to update menu items once the document and application * store have updated. NOTE: this is throttled because the underlying operation * is relatively expensive. * * @private * @param {DocumentStore} docStore * @param {ApplicationStore} appStore */ _updateMenuItemsHelper: _.debounce(function (docStore, appStore, dialogStore, preferencesStore, historyStore) { var document = appStore.getCurrentDocument(), openDocuments = docStore.getAllDocuments(), appIsModal = dialogStore.getState().appIsModal, hasPreviousHistoryState = document && historyStore.hasPreviousState(document.id), hasNextHistoryState = document && historyStore.hasNextState(document.id), preferences = preferencesStore.getState(), oldMenu = this._applicationMenu; this._applicationMenu = this._applicationMenu.updateMenuItems(openDocuments, document, hasPreviousHistoryState, hasNextHistoryState, appIsModal); this._applicationMenu = this._applicationMenu.updateOpenDocuments(openDocuments, document, appIsModal); // Note: this only needs to be called when the active document is loaded/reset, // We could have two levels of "update menu" handler ... but that's not really scalable? // Alternately, we could build this logic into the menubar.updateMenuItems process, // but that's non-trivial this._applicationMenu = this._applicationMenu.updateViewMenuItems(document); this._applicationMenu = this._applicationMenu.updateNonDocWindowMenuItems(preferences); if (!Immutable.is(oldMenu, this._applicationMenu)) { this.emit("change"); } }, 200), /** * This is our main listener for most of the events in the app * that cause a change in document or selection that would cause * a menu item to be disabled * * @private */ _updateMenuItems: function () { this.waitFor(["document", "application", "dialog", "preferences", "history"], this._updateMenuItemsHelper); }, /** * Updates the recent files menu * @private */ _updateRecentFiles: function () { this.waitFor(["application"], function (appStore) { var recentFiles = appStore.getRecentFiles(), oldMenu = this._applicationMenu; this._applicationMenu = this._applicationMenu.updateRecentFiles(recentFiles); if (!Immutable.is(oldMenu, this._applicationMenu)) { this.emit("change"); } }.bind(this)); }, /** * Updates the view menu only * @private */ _updateViewMenu: function () { this.waitFor(["document", "application"], function (docStore, appStore) { var document = appStore.getCurrentDocument(), oldMenu = this._applicationMenu; this._applicationMenu = this._applicationMenu.updateViewMenuItems(document); if (!Immutable.is(oldMenu, this._applicationMenu)) { this.emit("change"); } }.bind(this)); }, /** * Updates the Non-Document entries of the Window menu only * @private */ _updateNonDocWindowMenu: function () { this.waitFor(["preferences"], function (preferencesStore) { var preferences = preferencesStore.getState(), oldMenu = this._applicationMenu; this._applicationMenu = this._applicationMenu.updateNonDocWindowMenuItems(preferences); if (!Immutable.is(oldMenu, this._applicationMenu)) { this.emit("change"); } }.bind(this)); } }); module.exports = MenuStore; });
module.exports = Fluxxor.createStore({ initialize: function () { // This is where you would initialize properties of your store. If you are // initializing attributes asynchronously, then you may consider calling // `this.emit('change')`. // // Example: // // this.someAttribute = []; // // request('/some-resource', function (err, res) { // this.someAttrubte = JSON.parse(res.data); // this.emit('change'); // }.bind(this)); // You may also want to bind some actions. // // Example: // // this.bindActions( // 'DO_SOMETHING', this.doSomething // ); }, // If you bound some actions in the `initialize` method, then it may be best // to have those actions refer to a method in this class. In this case, create // the method here. Example: // // doSomething: function () { // // Maybe do something with `this.someAttribute`? // // // Call this if you've made some changes to this store. // this.emit('change'); // }, getState: function () { return { // Whatever attributes you initialized in the `intialize` method, you // should have it be returned here, like so: // // someAttribute: this.someAttribute } } });
var PixelatorStore = Fluxxor.createStore({ initialize: function(options) { this.colorsVisible = true; this.brushesVisible = false; this.colors = [ [255,128,64,1] ]; this.selectedColor = 0; this.inRGB = true; this.bindActions( Const.TOGGLE_BRUSHES, this.handleToggleBrushes , Const.TOGGLE_COLORS, this.handleToggleColors , Const.TOGGLE_RGB_HSV, this.handleToggleRGBHSV , Const.CHANGE_COLOR, this.handleChangeColor , Const.NEW_COLOR, this.handleNewColor , Const.SELECT_COLOR, this.handleSelectColor , Const.DELETE_COLOR, this.handleDeleteColor ); }, getState: function() { return { brushesVisible: this.brushesVisible , colorsVisible: this.colorsVisible , colors: this.colors , selectedColor: this.selectedColor , currentRGBA: this._getRGBA() , inRGB: this.inRGB }; }, _getRGBA: function() { var c = this.colors[this.selectedColor]; return ("rgba(" + c[0] + ", " + c[1] + ", " + c[2] + ", " + c[3] + ")"); }, handleToggleBrushes: function() { this.brushesVisible = !this.brushesVisible; this.emit("change"); }, handleToggleColors: function() { this.colorsVisible = !this.colorsVisible; this.emit("change"); }, handleToggleRGBHSV: function() { this.inRGB = !this.inRGB; this.emit("change"); }, handleChangeColor: function(c) { this.colors[this.selectedColor] = c; this.emit("change"); }, handleNewColor: function(c) { // adding a new color in the position of the current selected color this.colors.splice(this.selectedColor, 0, c); this.emit("change"); }, handleSelectColor: function(cid) { this.selectedColor = cid; this.emit("change"); }, handleDeleteColor: function() { this.colors.splice(this.selectedColor, 1); if(this.colors.length === this.selectedColor) { this.selectedColor--; // last item removed, adjust the selected color } this.emit("change"); } });
var PocketQueueStore = Fluxxor.createStore({ init() { this._queue = []; }, initialize() { this.init(); this.bindActions( EC.UI.DELAY_ACTION, this.handleDelayAction, EC.SERVER.REMOVE_DELAYED_ACTION, this.handleRemoveDelayedAction, EC.SERVER.LOGIN, this.handleLogin, ); }, /*========== getters ==========*/ getQueue() { return this._queue; }, /*========== handlers ==========*/ handleDelayAction({id, action}) { // keep only one last action for each id // if there is action in the quey with same id, we want to remove it this._queue = this._queue.filter(action => action.item_id !== id); this._queue.push({ item_id: id, action: action }); this._saveQueueForOfflineMode(); this.emit("change"); }, handleRemoveDelayedAction(action_results) { // var actionsToRemoveFromQueue = []; // action_results.forEach((res, index) => { // if (res) { // actionsToRemoveFromQueue.push(index) // } // }); // this._multisplice.apply(this, [this._queue].concat(actionsToRemoveFromQueue)); this._queue = []; this._saveQueueForOfflineMode(); this.emit("change"); }, handleLogin({username}) { var base64name = Base64.encode(username); AsyncStorage.getItem(`${base64name}_QUEUE`) .then((value) => { if (value !== null){ this._queue = JSON.parse(value); this.emit("change"); } }); }, _saveQueueForOfflineMode() { var base64name = Base64.encode(this.flux.stores.user.getUsername()); AsyncStorage.setItem(`${base64name}_QUEUE`, JSON.stringify(this._queue)) .then(() => console.log("Saved QUEUE to disk")) .catch((error) => console.log("AsyncStorage error: ", error.message)) .done(); }, /*========== Helpers ==========*/ _multisplice(array /*, ...args */){ var args = Array.apply(null, arguments).slice(1); args.sort(function(a, b){ return a - b; }); for(var i = 0; i < args.length; i++){ var index = args[i] - i; array.splice(index, 1); } } });
var GraphStore = Fluxxor.createStore({ initialize: function() { this.loading = false; this.error = null; this.graphData = {}; this.bindActions( constants.LOAD_GRAPH, this.onLoadGraph, constants.LOAD_GRAPH_SUCCESS, this.onLoadGraphSuccess, constants.LOAD_GRAPH_FAIL, this.onLoadGraphFail ); }, onLoadGraph: function() { this.loading = true; this.emit("change"); }, onLoadGraphSuccess: function(payload) { console.log(payload) var person = payload[0]._person var options = { legend: 'top' }; var columns = [ { 'type': 'string', 'label' : 'truthiness' }, { 'type' : 'number', 'label' : 'Amount' } ]; var rows = payload.map(function(stat) { console.log(stat) return [stat[1].tVal, stat[1].total] }) this.loading = false; this.error = null; this.graphData = { rows : rows, columns : columns, options : options, } this.emit("change"); }, onLoadGraphFail: function(payload) { this.loading = false; this.error = payload.error; this.emit("change"); }, });
module.exports = Fluxxor.createStore({ actions: { 'REFRESH_DATA': 'onRefreshData', 'SET_BILL_PAYED': 'onSetPayed' }, initialize: function() { this.data = { busy: false, ok: true, bills: [] }; this.setBusy = changeBillsData(this, true, true, null); this.setResults = changeBillsData(this, false, true, null); this.setError = function(err) { return changeBillsData(this, false, false, err.message); }; }, onSetPayed: function(code) { var self = this; var findBillByCode = R.find(function(b) { return b.code === code; }); var actualBill = findBillByCode(self.data.bills); function reloadData() { actualBill.pagata = true; self.emit('change'); self.onRefreshData(false); } function saveFt(bill) { bill.pagata = true; return couch.update(bill); } couch.init(options); var loadData = shepperd.cascade( this.setError, login, getFt(code), saveFt, reloadData ); loadData(); }, onRefreshData: function(changeBusyStatus) { var setState = R.pipe( R.each(function(bill) { bill.data = moment(bill.data, 'DD/MM/YYYY'); }), this.setResults ); couch.init(options); var loadData = shepperd.cascade( this.setError, login, getList, setState ); var setBusyAndLoad = R.pipe( this.setBusy, loadData ); if (changeBusyStatus) { setTimeout(setBusyAndLoad, 100); } else { loadData(); } }, getState: function() { return this.data; } });
module.exports = Fluxxor.createStore({ symbolSelectionCallback: false, initialize: function() { this.resetState(); this.bindActions( constants.UNLOAD, this.onUnload, constants.LOAD, this.onLoad, constants.LOAD_DEFAULT, this.onLoad, constants.ATTACH_INPUT, this.onAttachInput, constants.SET_INPUT_CURSOR, this.onSetInputCursor, constants.SET_INPUT_VALUE, this.onSetInputValue, constants.SELECT_SYMBOL, this.onSelectSymbol, constants.GAMEPAD_EVENT, this.onGamepadEvent ); }, resetState: function() { this.originalEl = {}; this.value = ''; this.cursor = 0; this.emit('change'); }, getState: function() { return { originalEl: this.originalEl, value: this.value, cursor: this.cursor } }, onSetInputValue: function(value) { this.value = value; this.emit('change'); }, onSetInputCursor: function(cursorPos) { this.cursor = cursorPos; this.emit('change'); }, onAttachInput: function(el) { this.originalEl = el; this.emit('change'); }, onUnload: function() { this.originalEl.value = this.value; this.originalEl.readOnly = false; Utils.setCursor(this.originalEl, this.cursor); this.emit('change'); }, onLoad: function(callback) { this.value = this.originalEl.value; this.cursor = this.value.length; //Theres a bug in chrome where getCursor returns 0 onFocus, so just set it to the end of the string: http://stackoverflow.com/questions/14974913/selectionstart-of-textarea-returns-wrong-value this.originalEl.readOnly = true; this.originalEl.blur(); if (callback) { this.symbolSelectionCallback = callback; } this.emit('change'); }, onSelectSymbol: function(symbol) { this.waitFor(['SymbolsStore'], _.bind(function(SymbolsStore) { if (SymbolsStore.defaultSymbolSelection) { this.addSymbolToValue(symbol); } }, this)); }, getValueDivision: function() { var value = this.value + ''; var firstStrPart = value.substring(0, this.cursor), secondStrPart = value.substring(this.cursor, value.length); return { start: firstStrPart, end: secondStrPart } }, addSymbolToValue: function(symbol) { if (this.value.length >= 81) { return; } var valueParts = this.getValueDivision(); this.value = valueParts.start + symbol + valueParts.end; this.cursor++; this.emit('change'); }, onGamepadEvent: function() { this.waitFor(['GamepadStore', 'SymbolsStore'], _.bind(function(GamepadStore, SymbolsStore) { var gamepadState = GamepadStore.getState(); var symbolsState = SymbolsStore.getState(); var selectedSymbol = symbolsState.selectedSymbol; var defaultSymbolSelection = symbolsState.defaultSymbolSelection; var dPadDirection = gamepadState.dPadDirection; var otherButtons = gamepadState.otherButtons; switch (dPadDirection) { case 'dPadUp': this.cursor = 0; break; case 'dPadDown': this.cursor = this.value.length; break; case 'dPadLeft': this.cursor--; break; case 'dPadRight': this.cursor++; break; } _.map(otherButtons, _.bind(function(button, name) { switch (name) { case 'leftBumper': this.onBackspace(); break; case 'rightBumper': this.onSpace(); break; } }, this)); if (selectedSymbol) { if (defaultSymbolSelection) { this.addSymbolToValue(selectedSymbol); } else { this.symbolSelectionCallback(selectedSymbol); } } this.emit('change'); }, this)); }, onBackspace: function() { var valueParts = this.getValueDivision(); var start = valueParts.start; start = start.substring(0, start.length - 1); this.value = start + valueParts.end; if (this.cursor > 0) { this.cursor--; } this.emit('change'); }, onSpace: function() { this.addSymbolToValue(' '); } });
var Fluxxor = require("fluxxor"); var actions = require("./actions"); var RouteStore = Fluxxor.createStore({ initialize: function(options) { this.router = options.router; this.bindActions( actions.constants.ROUTE.TRANSITION, this.handleRouteTransition ); }, handleRouteTransition: function(payload) { var path = payload.path, params = payload.params; this.router.transitionTo(path, params); } }); module.exports = RouteStore;
var Fluxxor = require('fluxxor'); var _ = require('lodash'); module.exports = Fluxxor.createStore({ initialize: function(socket) { this.connected = false; this.websocket = socket; socket.on('connect', function() { this.connected = true; this.emit('change'); }.bind(this)); socket.on('disconnect', function() { this.connected = false; this.emit('change'); }.bind(this)); } });
var CollectionStore = Fluxxor.createStore({ initialize() { this.state = { gold: [], normal: [] }; this.bindActions( constants.ADD_CARD_TO_COLLECTION, this.onAddCard, constants.REMOVE_CARD_FROM_COLLECTION, this.onRemoveCard ); }, onAddCard(payload) { payload.gold ? this.state.gold.push(payload.cardID) : this.state.normal.push(payload.cardID); this.emit("change"); }, onRemoveCard(payload) { payload.gold ? this.state.gold = _.without(this.state.gold, payload.cardID) : this.state.normal = _.without(this.state.normal, payload.cardID); this.emit("change"); }, getCount(card, gold) { var cards = gold ? this.state.gold : this.state.normal; return cards.filter(c => c === card.id).length } });
define(function (require, exports, module) { "use strict"; var _ = require("lodash"), Fluxxor = require("fluxxor"); var events = require("../events"); var ApplicationStore = Fluxxor.createStore({ // Photoshop Version _hostVersion: null, /** * Set of boolean values designating when portions of the application have been initialized * * @type {Map.<string, boolean>} */ _initialized: null, /** * An ordered list of document IDs * @private * @type {Array.<number>} */ _documentIDs: null, /** * The index of the currently active document, or null if there are none * @private * @type {?number} */ _selectedDocumentIndex: null, /** * The ID of the currently active document, or null if there are none * @private * @type {?number} */ _selectedDocumentID: null, /** * List of paths for recent files opened in Photoshop * @private * @type {Array.<string>} */ _recentFiles: null, initialize: function () { this.bindActions( events.RESET, this._handleReset, events.application.HOST_VERSION, this.setHostVersion, events.application.INITIALIZED, this._setInitialized, events.application.UPDATE_RECENT_FILES, this._updateRecentFileList, events.document.DOCUMENT_UPDATED, this._updateDocument, events.document.CLOSE_DOCUMENT, this._closeDocument, events.document.SELECT_DOCUMENT, this._documentSelected ); this._handleReset(); }, /** * Reset or initialize store state. * * @private */ _handleReset: function () { this._hostVersion = null; this._selectedDocumentIndex = null; this._selectedDocumentID = null; this._documentIDs = []; this._recentFiles = []; this._initialized = new Map(); }, getState: function () { return { hostVersion: this._hostVersion, activeDocumentInitialized: this._initialized.get("activeDocument"), recentFilesInitialized: this._initialized.get("recentFiles"), documentIDs: this._documentIDs, selectedDocumentIndex: this._selectedDocumentIndex, selectedDocumentID: this._documentIDs[this._selectedDocumentIndex] }; }, /** * Returns the id of currently active document, null if there is none * * @return {number} */ getCurrentDocumentID: function () { return this._selectedDocumentID; }, /** * Get the list of open document IDs * * @return {Array.<numbet>} */ getOpenDocumentIDs: function () { return this._documentIDs; }, /** * Returns the list of recent document paths * * @return {Array.<string>} */ getRecentFiles: function () { return this._recentFiles; }, /** * Get the currently active document model, or null if there are none. * * @return {?Document} */ getCurrentDocument: function () { var documentStore = this.flux.store("document"); return documentStore.getDocument(this._selectedDocumentID); }, /** * The number of currently open documents; * * @return {number} */ getDocumentCount: function () { return this._documentIDs.length; }, /** * Find either the next or previous document in the document index. * * @private * @param {boolean} next Whether to find the next or previous document * @return {?Document} */ _getNextPrevDocument: function (next) { if (this._selectedDocumentID === null) { return null; } var increment = next ? 1 : -1, nextDocumentIndex = this._selectedDocumentIndex + increment; if (nextDocumentIndex === this._documentIDs.length) { nextDocumentIndex = 0; } else if (nextDocumentIndex === -1) { nextDocumentIndex = this._documentIDs.length - 1; } var documentStore = this.flux.store("document"), nextDocmentID = this._documentIDs[nextDocumentIndex]; return documentStore.getDocument(nextDocmentID); }, /** * Find the next document in the document index. * * @return {?Document} */ getNextDocument: function () { return this._getNextPrevDocument(true); }, /** * Find the previous document in the document index. * * @return {?Document} */ getPreviousDocument: function () { return this._getNextPrevDocument(false); }, setHostVersion: function (payload) { var parts = [ payload.hostVersion.versionMajor, payload.hostVersion.versionMinor, payload.hostVersion.versionFix ]; this._hostVersion = parts.join("."); this.emit("change"); }, /** * Sets the initialized flag to true and emits a change * @private * @param {{item: string}} payload includes name of the item/module that has been initialized */ _setInitialized: function (payload) { var item = payload.item; if (item && !this._initialized.get(item)) { this._initialized.set(item, true); this.emit("change"); } }, /** * Set the position of the given document ID in the document index. * * @private * @param {number} documentID * @param {number} itemIndex */ _updateDocumentPosition: function (documentID, itemIndex) { // find the document in the array of indices var currentIndex = -1; this._documentIDs.some(function (id, index) { if (id === documentID) { currentIndex = index; return true; } }); // remove it from the array if (currentIndex > -1) { this._documentIDs.splice(currentIndex, 1); } // add it back at the correct index this._documentIDs.splice(itemIndex, 0, documentID); }, /** * Updates the recent file list * * @private * @param {{recentFiles: Array.<string>}} payload */ _updateRecentFileList: function (payload) { // If a file has been deleted, PS sends us an empty string for that file // So we have to filter it out this._recentFiles = _.compact(payload.recentFiles); this.emit("change"); }, /** * Set or reset the position of the given document in the document index. * * @private * @param {{document: object, layers: Array.<object>}} payload */ _updateDocument: function (payload) { this.waitFor(["document"], function () { var rawDocument = payload.document, documentID = rawDocument.documentID, itemIndex = rawDocument.itemIndex - 1; // doc indices start at 1 this._updateDocumentPosition(documentID, itemIndex); if (payload.current) { this._selectedDocumentID = documentID; this._selectedDocumentIndex = itemIndex; } this.emit("change"); }); }, /** * Remove the given document ID from the document index, and set a new * selected document ID and index. * * @private * @param {{document: object, layers: Array.<object>}} payload */ _closeDocument: function (payload) { this.waitFor(["document"], function () { var documentID = payload.documentID, selectedDocumentID = payload.selectedDocumentID; var documentIndex = this._documentIDs.indexOf(documentID); if (documentIndex === -1) { throw new Error("Closed document ID not found in index: " + documentID); } this._documentIDs.splice(documentIndex, 1); var openDocumentCount = this._documentIDs.length; if ((openDocumentCount === 0) !== (selectedDocumentID === null)) { throw new Error("Next selected document ID should be null iff there are no open documents"); } if (openDocumentCount === 0) { this._selectedDocumentID = null; this._selectedDocumentIndex = null; return; } var selectedDocumentIndex = this._documentIDs.indexOf(selectedDocumentID); if (selectedDocumentIndex === -1) { throw new Error("Selected document ID not found in index: " + documentID); } this._selectedDocumentID = selectedDocumentID; this._selectedDocumentIndex = selectedDocumentIndex; this.emit("change"); }); }, /** * Set the currently active document. * * @private * @param {{selectedDocumentID: number}} payload */ _documentSelected: function (payload) { this._selectedDocumentID = payload.selectedDocumentID; this._selectedDocumentIndex = this._documentIDs.indexOf(payload.selectedDocumentID); this.emit("change"); } }); module.exports = ApplicationStore; });
var MenuStore = Fluxxor.createStore({ initialize: function() { this._all = Config.menus; this._active = this._all[0]; this.bindActions( Constants.Actions.MENU_SELECTED, this._onMenuSelected, Constants.Actions.START_DOWNLOAD, this._onDownloadStarted); }, _onMenuSelected: function(payload) { this._active = _.find(this._all, function(m) { return m.name === payload.name; }); this._active.notifications = 0; this.emit("change"); }, _onDownloadStarted: function(payload) { var downloadsMenu = _.find(this._all, function(m) { return m.name === 'Downloads'; }); downloadsMenu.notifications++; downloadsMenu.enabled = true; this.emit('change'); }, getState: function() { return { all: this._all, active: this._active }; } });
var Fluxxor = require('fluxxor'), constants = require('../constants'); var ActionTypes = constants.ActionTypes; var LeaderboardStore = Fluxxor.createStore({ initialize: function() { this.leaderboard = []; this.bindActions(ActionTypes.RECEIVE_LEADERBOARD, this.onReceiveLeaderboard); }, onReceiveLeaderboard: function(payload) { this.leaderboard = payload; this.emit('change'); }, getState: function() { return this.leaderboard; } }); module.exports = LeaderboardStore;