diff --git a/internal_packages/thread-list/lib/thread-list.cjsx b/internal_packages/thread-list/lib/thread-list.cjsx index fefefdd58..515b63c94 100644 --- a/internal_packages/thread-list/lib/thread-list.cjsx +++ b/internal_packages/thread-list/lib/thread-list.cjsx @@ -57,6 +57,7 @@ class ThreadList extends React.Component constructor: (@props) -> @state = style: 'unknown' + task: null componentWillMount: => c1 = new ListTabular.Column @@ -169,33 +170,42 @@ class ThreadList extends React.Component render: => if @state.style is 'wide' - +
+ +
else if @state.style is 'narrow' - +
+ +
else
+ # _renderUndoRedo: => + # if @state.task + # + _threadIdAtPoint: (x, y) -> item = document.elementFromPoint(event.clientX, event.clientY).closest('.list-item') return null unless item diff --git a/internal_packages/undo-redo/lib/main.cjsx b/internal_packages/undo-redo/lib/main.cjsx new file mode 100644 index 000000000..c450c6fe0 --- /dev/null +++ b/internal_packages/undo-redo/lib/main.cjsx @@ -0,0 +1,13 @@ +{ComponentRegistry, WorkspaceStore} = require 'nylas-exports' + +module.exports = + activate: (@state={}) -> + UndoRedoComponent = require "./undo-redo-component" + + ComponentRegistry.register UndoRedoComponent, + location: WorkspaceStore.Location.ThreadList + + deactivate: -> + ComponentRegistry.unregister UndoRedoComponent + + serialize: -> @state \ No newline at end of file diff --git a/internal_packages/undo-redo/lib/undo-redo-component.cjsx b/internal_packages/undo-redo/lib/undo-redo-component.cjsx new file mode 100644 index 000000000..734b54dda --- /dev/null +++ b/internal_packages/undo-redo/lib/undo-redo-component.cjsx @@ -0,0 +1,90 @@ +_ = require 'underscore' +path = require 'path' +React = require 'react' +classNames = require 'classnames' +{RetinaImg, TimeoutTransitionGroup} = require 'nylas-component-kit' +{Actions, +Utils, +ComponentRegistry, +UndoRedoStore, +NamespaceStore} = require 'nylas-exports' + +class UndoRedoComponent extends React.Component + @displayName: 'UndoRedoComponent' + + @propTypes: + task: React.PropTypes.object.isRequired + show: React.PropTypes.bool + + constructor: (@props) -> + @state = @_getStateFromStores() + @_timeout = null + + _onChange: => + @setState(@_getStateFromStores(), => + @_setNewTimeout()) + + _clearTimeout: => + clearTimeout(@_timeout) + + _setNewTimeout: => + clearTimeout(@_timeout) + @_timeout = setTimeout (=> + @_hide() + return + ), 3000 + + _getStateFromStores: -> + t = UndoRedoStore.getMostRecentTask() + s = false + if t + s = true + + return {show: s, task: t} + + componentWillMount: -> + @unsub = UndoRedoStore.listen(@_onChange) + + componentWillUnmount: -> + @unsub() + + render: => + items = [].concat(@_renderUndoRedoManager()) + + names = classNames + "undo-redo-manager": true + + + {items} + + + _renderUndoRedoManager: => + if @state.show +
+
+

{@_formatMessage()}

+
+
+ +

Undo

+
+
+ else + [] + + _undoTask: => + atom.commands.dispatch(document.querySelector('body'), 'core:undo') + @_hide() + + _formatMessage: => + return @state.task.description() + + _hide: => + @setState({show: false, task: null}) + +module.exports = UndoRedoComponent diff --git a/internal_packages/undo-redo/package.json b/internal_packages/undo-redo/package.json new file mode 100644 index 000000000..d5522323c --- /dev/null +++ b/internal_packages/undo-redo/package.json @@ -0,0 +1,13 @@ +{ + "name": "undo-redo", + "version": "0.1.0", + "main": "./lib/main", + "description": "Undo modal button", + "license": "Proprietary", + "private": true, + "engines": { + "atom": "*" + }, + "dependencies": { + } +} \ No newline at end of file diff --git a/internal_packages/undo-redo/stylesheets/undo-redo.less b/internal_packages/undo-redo/stylesheets/undo-redo.less new file mode 100644 index 000000000..c720eadc5 --- /dev/null +++ b/internal_packages/undo-redo/stylesheets/undo-redo.less @@ -0,0 +1,53 @@ +@import "ui-variables"; +@import "ui-mixins"; + +.undo-redo{ + position: absolute; + height: 45px; + bottom: 10px; + left: 39%; + padding-top: 12px; + opacity: 0.9; + border-radius: @border-radius-base; + background: @gray-darker; + + .undo-redo-message-wrapper{ + display: inline-block; + margin-left: 15px; + margin-right: 30px; + + .undo-redo-message{ + color: lighten(@gray-base, 70%);; + } + } + + .undo-redo-action-wrapper{ + float: right; + display: inline-block; + margin-right: 15px; + + .undo-redo-action-text{ + margin-left: 5px; + display: inline-block; + color: @white; + } + } +} + +.undo-redo-item-enter { + opacity: 0.01; + transition: all .3s ease-out; +} + +.undo-redo-item-enter.undo-redo-item-enter-active { + opacity: 1; +} + +.undo-redo-item-leave { + opacity: 1; + transition: all .3s ease-in; +} + +.undo-redo-item-leave.undo-redo-item-leave-active { + opacity: 0.01; +} \ No newline at end of file diff --git a/src/flux/stores/undo-redo-store.coffee b/src/flux/stores/undo-redo-store.coffee index 018ca8519..41c52ca19 100644 --- a/src/flux/stores/undo-redo-store.coffee +++ b/src/flux/stores/undo-redo-store.coffee @@ -25,11 +25,12 @@ class UndoRedoStore if task.canBeUndone() and not task.isUndo() @_redo = [] @_undo.push(task) + @trigger() unless task._isReverting undo: => topTask = @_undo.pop() return unless topTask - + @trigger() Actions.queueTask(topTask.createUndoTask()) @_redo.push(topTask.createIdenticalTask()) @@ -38,6 +39,10 @@ class UndoRedoStore return unless redoTask Actions.queueTask(redoTask) + getMostRecentTask: => + for idx in [@_undo.length-1...-1] + return @_undo[idx] unless @_undo[idx]._isReverting + print: -> console.log("Undo Stack") console.log(@_undo) diff --git a/src/flux/tasks/change-folder-task.coffee b/src/flux/tasks/change-folder-task.coffee index 962368f42..2654a23f3 100644 --- a/src/flux/tasks/change-folder-task.coffee +++ b/src/flux/tasks/change-folder-task.coffee @@ -23,6 +23,19 @@ class ChangeFolderTask extends ChangeCategoryTask label: -> "Moving to folder…" + description: -> + folderName = @folderOrId.displayName + if @threadIds.length > 0 + if @threadIds.length > 1 + return "Moving " + @threadIds.length + " threads to \"" + folderName + "\"" + return "Moving 1 thread to \"" + folderName + "\"" + else if @messageIds.length > 0 + if @messageIds.length > 1 + return "Moving " + @messageIds.length + "messages to \"" + folderName + "\"" + return "Moving 1 message to \"" + folderName + "\"" + else + return "Moving objects to \"" + folderName + "\"" + collectCategories: -> if @folderOrId instanceof Folder return Promise.props diff --git a/src/flux/tasks/change-labels-task.coffee b/src/flux/tasks/change-labels-task.coffee index 0471a93ab..eb472b6cf 100644 --- a/src/flux/tasks/change-labels-task.coffee +++ b/src/flux/tasks/change-labels-task.coffee @@ -23,6 +23,12 @@ class ChangeLabelsTask extends ChangeCategoryTask label: -> "Applying labels…" + description: -> + addingMessage = "Adding " + @labelsToAdd.length + " labels" + removingMessage = "Removing " + @labelsToRemove.length + " labels" + + return addingMessage + " " + removingMessage + collectCategories: -> labelOrIdPromiseMapper = (labelOrId) -> if labelOrId instanceof Label diff --git a/src/flux/tasks/update-nylas-objects-task.coffee b/src/flux/tasks/update-nylas-objects-task.coffee index 91ffe37e3..6a6d73bcf 100644 --- a/src/flux/tasks/update-nylas-objects-task.coffee +++ b/src/flux/tasks/update-nylas-objects-task.coffee @@ -20,6 +20,10 @@ class UpdateNylasObjectsTask extends Task endpoint: (obj) -> inflection.pluralize(obj.constructor.name.toLowerCase()) + # OVERRIDE ME + description: -> + 'Updating Nylas object' + performLocal: ({reverting}={}) -> if reverting or @isUndo() Promise.map @objects, (obj) => diff --git a/src/task.coffee b/src/task.coffee index 080c0b61e..9bf460cf2 100644 --- a/src/task.coffee +++ b/src/task.coffee @@ -134,6 +134,11 @@ class Task throw new Error('Cannot send message to terminated process') undefined + # Public: Describe the function of the task. Each task should override this + # to explain its individual function + description: -> + '' + # Public: Call a function when an event is emitted by the child process # # * `eventName` The {String} name of the event to handle. diff --git a/static/images/thread-list/undo-icon@2x.png b/static/images/thread-list/undo-icon@2x.png new file mode 100644 index 000000000..c0b85e8b1 Binary files /dev/null and b/static/images/thread-list/undo-icon@2x.png differ