From 58b10199348fdf9b03e1820355824e8ba56da3e7 Mon Sep 17 00:00:00 2001 From: Scott Erickson <sderickson@gmail.com> Date: Tue, 15 Apr 2014 15:09:36 -0700 Subject: [PATCH 01/17] Switched listen to watch (would have been confusing with eye-con, and listenTo function in Backbone). Added watch button and patch badge to level editor. --- app/locale/en.coffee | 2 ++ app/models/CocoModel.coffee | 6 ++++++ app/schemas/schemas.coffee | 2 +- app/styles/base.sass | 5 +++++ app/templates/editor/level/edit.jade | 15 ++++++++++++-- app/views/editor/level/edit.coffee | 6 ++++++ server/commons/Handler.coffee | 15 ++++++++------ test/server/functional/patch.spec.coffee | 26 ++++++++++++------------ 8 files changed, 55 insertions(+), 22 deletions(-) diff --git a/app/locale/en.coffee b/app/locale/en.coffee index 9cd29d8d2..5229e180c 100644 --- a/app/locale/en.coffee +++ b/app/locale/en.coffee @@ -15,6 +15,8 @@ fork: "Fork" play: "Play" retry: "Retry" + watch: "Watch" + unwatch: "Unwatch" units: second: "second" diff --git a/app/models/CocoModel.coffee b/app/models/CocoModel.coffee index c93708ee2..a99f48fd4 100644 --- a/app/models/CocoModel.coffee +++ b/app/models/CocoModel.coffee @@ -225,5 +225,11 @@ class CocoModel extends Backbone.Model @acceptedPatches ?= [] @acceptedPatches.push patch @acceptedPatches = _.uniq(@acceptedPatches, false, (p) -> p.id) + + watch: (doWatch=true) -> + $.ajax("#{@urlRoot}/#{@id}/watch", {type:'PUT', data:{on:doWatch}}) + + watching: -> + return me.id in @get('watchers') or [] module.exports = CocoModel diff --git a/app/schemas/schemas.coffee b/app/schemas/schemas.coffee index 2d7ae0603..9c20c9ba2 100644 --- a/app/schemas/schemas.coffee +++ b/app/schemas/schemas.coffee @@ -63,7 +63,7 @@ patchableProps = -> status: { enum: ['pending', 'accepted', 'rejected', 'cancelled']} }) allowPatches: { type: 'boolean' } - listeners: me.array({title:'Listeners'}, + watchers: me.array({title:'Watchers'}, me.objectId(links: [{rel: 'extra', href: "/db/user/{($)}"}])) me.extendPatchableProperties = (schema) -> diff --git a/app/styles/base.sass b/app/styles/base.sass index 0425ba2d6..afa9fbcc9 100644 --- a/app/styles/base.sass +++ b/app/styles/base.sass @@ -265,3 +265,8 @@ body[lang='ja'] font-family: 'Glyphicons Halflings' src: url("/fonts/glyphicons-halflings-regular.eot") src: url("/fonts/glyphicons-halflings-regular.eot?#iefix") format("embedded-opentype"), url("/fonts/glyphicons-halflings-regular.woff") format("woff"), url("/fonts/glyphicons-halflings-regular.ttf") format("truetype"), url("/fonts/glyphicons-halflings-regular.svg#glyphicons-halflingsregular") format("svg") + +.spr:after + content: " " +.spl:before + content: " " \ No newline at end of file diff --git a/app/templates/editor/level/edit.jade b/app/templates/editor/level/edit.jade index ba69b27fd..873d881b4 100644 --- a/app/templates/editor/level/edit.jade +++ b/app/templates/editor/level/edit.jade @@ -27,10 +27,21 @@ block outer_content li a(href="#editor-level-systems-tab-view", data-toggle="tab", data-i18n="editor.level_tab_systems") Systems li - a(href="#editor-level-patches", data-toggle="tab", data-i18n="resources.patches")#patches-tab Patches - + a(href="#editor-level-patches", data-toggle="tab")#patches-tab + span(data-i18n="resources.patches").spr Patches + - var patches = level.get('patches') + - patches = [1,2,3,3,4,5,6] + if patches && patches.length + span.badge= patches.length ul.nav.navbar-nav.navbar-right + li#watch-button.btn.btn-primary.navbar-btn + span.watch + span.spr Watch + span.glyphicon.glyphicon-eye-open + span.unwatch.secret + span.spr Unwatch + span.glyphicon.glyphicon-eye-close li(data-toggle="coco-modal", data-target="modal/revert", data-i18n="editor.revert", disabled=authorized === true ? undefined : "true").btn.btn-primary.navbar-btn#revert-button Revert if authorized li(data-i18n="common.save").btn.btn-primary.navbar-btn#commit-level-start-button Save diff --git a/app/views/editor/level/edit.coffee b/app/views/editor/level/edit.coffee index e28f87247..ee704c10e 100644 --- a/app/views/editor/level/edit.coffee +++ b/app/views/editor/level/edit.coffee @@ -30,6 +30,7 @@ module.exports = class EditorLevelView extends View 'click #history-button': 'showVersionHistory' 'click #patches-tab': -> @patchesView.load() 'click #commit-level-patch-button': 'startPatchingLevel' + 'click #watch-button': 'toggleWatchLevel' constructor: (options, @levelID) -> super options @@ -125,3 +126,8 @@ module.exports = class EditorLevelView extends View versionHistoryView = new VersionHistoryView level:@level, @levelID @openModalView versionHistoryView Backbone.Mediator.publish 'level:view-switched', e + + toggleWatchLevel: -> + button = @$el.find('#watch-button') + @level.watch(button.find('.watch').is(':visible')) + button.find('> span').toggleClass('secret') \ No newline at end of file diff --git a/server/commons/Handler.coffee b/server/commons/Handler.coffee index b486b79b0..a7822f9e5 100644 --- a/server/commons/Handler.coffee +++ b/server/commons/Handler.coffee @@ -95,7 +95,7 @@ module.exports = class Handler # this handler should be overwritten by subclasses if @modelClass.schema.is_patchable return @getPatchesFor(req, res, args[0]) if req.route.method is 'get' and args[1] is 'patches' - return @setListening(req, res, args[0]) if req.route.method is 'put' and args[1] is 'listen' + return @setWatching(req, res, args[0]) if req.route.method is 'put' and args[1] is 'watch' return @sendNotFoundError(res) getPatchesFor: (req, res, id) -> @@ -105,16 +105,19 @@ module.exports = class Handler patches = (patch.toObject() for patch in patches) @sendSuccess(res, patches) - setListening: (req, res, id) -> + setWatching: (req, res, id) -> @getDocumentForIdOrSlug id, (err, document) => return @sendUnauthorizedError(res) unless @hasAccessToDocument(req, document, 'get') return @sendDatabaseError(res, err) if err return @sendNotFoundError(res) unless document? - listeners = document.get('listeners') or [] + watchers = document.get('watchers') or [] me = req.user.get('_id') - listeners = (l for l in listeners when not l.equals(me)) - listeners.push me if req.body.on - document.set 'listeners', listeners + console.log 'watchers?', me, watchers + watchers = (l for l in watchers when not l.equals(me)) + console.log 'new watchers is', watchers, req.body.on, req.body + watchers.push me if req.body.on and req.body.on isnt 'false' + console.log 'watchers is actually now', watchers + document.set 'watchers', watchers document.save (err, document) => return @sendDatabaseError(res, err) if err @sendSuccess(res, @formatEntity(req, document)) diff --git a/test/server/functional/patch.spec.coffee b/test/server/functional/patch.spec.coffee index d8694baf0..4666c5353 100644 --- a/test/server/functional/patch.spec.coffee +++ b/test/server/functional/patch.spec.coffee @@ -53,27 +53,27 @@ describe '/db/patch', -> expect(body.length).toBe(1) done() - it 'allows you to set yourself as listening', (done) -> - listeningURL = getURL("/db/article/#{articles[0]._id}/listen") - request.put {uri: listeningURL, json: {on:true}}, (err, res, body) -> - expect(body.listeners[0]).toBeDefined() + it 'allows you to set yourself as watching', (done) -> + watchingURL = getURL("/db/article/#{articles[0]._id}/watch") + request.put {uri: watchingURL, json: {on:true}}, (err, res, body) -> + expect(body.watchers[0]).toBeDefined() done() - it 'added the listener to the target document', (done) -> + it 'added the watcher to the target document', (done) -> Article.findOne({}).exec (err, article) -> - expect(article.toObject().listeners[0]).toBeDefined() + expect(article.toObject().watchers[0]).toBeDefined() done() - it 'does not add duplicate listeners', (done) -> - listeningURL = getURL("/db/article/#{articles[0]._id}/listen") - request.put {uri: listeningURL, json: {on:true}}, (err, res, body) -> - expect(body.listeners.length).toBe(1) + it 'does not add duplicate watchers', (done) -> + watchingURL = getURL("/db/article/#{articles[0]._id}/watch") + request.put {uri: watchingURL, json: {on:true}}, (err, res, body) -> + expect(body.watchers.length).toBe(1) done() it 'allows removing yourself', (done) -> - listeningURL = getURL("/db/article/#{articles[0]._id}/listen") - request.put {uri: listeningURL, json: {on:false}}, (err, res, body) -> - expect(body.listeners.length).toBe(0) + watchingURL = getURL("/db/article/#{articles[0]._id}/watch") + request.put {uri: watchingURL, json: {on:false}}, (err, res, body) -> + expect(body.watchers.length).toBe(0) done() it 'allows the submitter to withdraw the pull request', (done) -> From f88e0ac0abd0024e595154568c8060b3fb833138 Mon Sep 17 00:00:00 2001 From: Scott Erickson <sderickson@gmail.com> Date: Wed, 16 Apr 2014 10:42:32 -0700 Subject: [PATCH 02/17] Set up patches for components. --- app/models/CocoModel.coffee | 11 ++++++----- app/models/Patch.coffee | 5 ++++- app/styles/editor/level/component/edit.sass | 7 +++++++ app/templates/editor/level/component/edit.jade | 6 +++++- app/templates/editor/level/edit.jade | 3 +-- app/views/editor/level/component/edit.coffee | 13 ++++++++++--- app/views/editor/level/save_view.coffee | 2 +- app/views/editor/level/thangs_tab_view.coffee | 2 +- app/views/modal/save_version_modal.coffee | 13 +++++++------ 9 files changed, 42 insertions(+), 20 deletions(-) diff --git a/app/models/CocoModel.coffee b/app/models/CocoModel.coffee index a99f48fd4..838b30530 100644 --- a/app/models/CocoModel.coffee +++ b/app/models/CocoModel.coffee @@ -68,7 +68,8 @@ class CocoModel extends Backbone.Model @markToRevert() @clearBackup() @trigger "save", @ - patch.setStatus 'accepted' for patch in @acceptedPatches or [] + PatchModel = require 'models/Patch' + PatchModel.setStatus id, 'accepted' for id in @get('acceptedPatches') or [] return super attrs, options fetch: -> @@ -95,7 +96,6 @@ class CocoModel extends Backbone.Model cloneNewMinorVersion: -> newData = $.extend(null, {}, @attributes) clone = new @constructor(newData) - clone.acceptedPatches = @acceptedPatches clone cloneNewMajorVersion: -> @@ -222,9 +222,10 @@ class CocoModel extends Backbone.Model deltasLib.expandDelta(delta, @_revertAttributes, @schema()) addPatchToAcceptOnSave: (patch) -> - @acceptedPatches ?= [] - @acceptedPatches.push patch - @acceptedPatches = _.uniq(@acceptedPatches, false, (p) -> p.id) + acceptedPatches = @get('acceptedPatches') or [] # not actually stored on the db + acceptedPatches.push patch.id + acceptedPatches = _.uniq(acceptedPatches) + @set 'acceptedPatches', acceptedPatches watch: (doWatch=true) -> $.ajax("#{@urlRoot}/#{@id}/watch", {type:'PUT', data:{on:doWatch}}) diff --git a/app/models/Patch.coffee b/app/models/Patch.coffee index 68b62eca9..c505c93c0 100644 --- a/app/models/Patch.coffee +++ b/app/models/Patch.coffee @@ -5,4 +5,7 @@ module.exports = class PatchModel extends CocoModel urlRoot: "/db/patch" setStatus: (status) -> - $.ajax("/db/patch/#{@id}/status", {type:"PUT", data: {status:status}}) \ No newline at end of file + PatchModel.setStatus @id, status + + @setStatus: (id, status) -> + $.ajax("/db/patch/#{id}/status", {type:"PUT", data: {status:status}}) \ No newline at end of file diff --git a/app/styles/editor/level/component/edit.sass b/app/styles/editor/level/component/edit.sass index 5c9deda4c..2cd8e5d4f 100644 --- a/app/styles/editor/level/component/edit.sass +++ b/app/styles/editor/level/component/edit.sass @@ -1,4 +1,11 @@ #editor-level-component-edit-view + nav + margin-bottom: 0 + + #component-patches + padding: 0 10px 10px + background: white + .navbar-text float: left diff --git a/app/templates/editor/level/component/edit.jade b/app/templates/editor/level/component/edit.jade index 23c24cf6c..1a6d74d38 100644 --- a/app/templates/editor/level/component/edit.jade +++ b/app/templates/editor/level/component/edit.jade @@ -14,10 +14,12 @@ nav.navbar.navbar-default(role='navigation') a(href="#component-config-schema" data-toggle="tab" data-i18n="editor.level_component_config_schema") Config Schema li a(href="#component-settings" data-toggle="tab" data-i18n="editor.level_component_settings") Settings + li + a(href="#component-patches" data-toggle="tab" data-i18n="resources.patches")#component-patches-tab Patches ul.nav.navbar-nav.navbar-left li(data-i18n="general.version_history").btn.btn-primary.navbar-btn#history-button Version History - ul.nav.navbar-nav.navbar-right li(data-i18n="editor.level_component_btn_new").btn.btn-primary.navbar-btn#create-new-component-button Create New Component + li.btn.btn-primary.navbar-btn#patch-component-button Patch .tab-content .tab-pane.active#component-code @@ -26,3 +28,5 @@ nav.navbar.navbar-default(role='navigation') #config-schema-treema .tab-pane#component-settings #edit-component-treema + .tab-pane#component-patches + .patches-view \ No newline at end of file diff --git a/app/templates/editor/level/edit.jade b/app/templates/editor/level/edit.jade index 873d881b4..297d000f8 100644 --- a/app/templates/editor/level/edit.jade +++ b/app/templates/editor/level/edit.jade @@ -30,7 +30,6 @@ block outer_content a(href="#editor-level-patches", data-toggle="tab")#patches-tab span(data-i18n="resources.patches").spr Patches - var patches = level.get('patches') - - patches = [1,2,3,3,4,5,6] if patches && patches.length span.badge= patches.length @@ -42,7 +41,7 @@ block outer_content span.unwatch.secret span.spr Unwatch span.glyphicon.glyphicon-eye-close - li(data-toggle="coco-modal", data-target="modal/revert", data-i18n="editor.revert", disabled=authorized === true ? undefined : "true").btn.btn-primary.navbar-btn#revert-button Revert + li(data-toggle="coco-modal", data-target="modal/revert", data-i18n="editor.revert", disabled=anonymous ? "true": undefined).btn.btn-primary.navbar-btn#revert-button Revert if authorized li(data-i18n="common.save").btn.btn-primary.navbar-btn#commit-level-start-button Save else diff --git a/app/views/editor/level/component/edit.coffee b/app/views/editor/level/component/edit.coffee index 3f91f1467..caf2340e5 100644 --- a/app/views/editor/level/component/edit.coffee +++ b/app/views/editor/level/component/edit.coffee @@ -2,6 +2,8 @@ View = require 'views/kinds/CocoView' VersionHistoryView = require 'views/editor/component/versions_view' template = require 'templates/editor/level/component/edit' LevelComponent = require 'models/LevelComponent' +PatchesView = require 'views/editor/patches_view' +SaveVersionModal = require 'views/modal/save_version_modal' module.exports = class LevelComponentEditView extends View id: "editor-level-component-edit-view" @@ -12,6 +14,8 @@ module.exports = class LevelComponentEditView extends View 'click #done-editing-component-button': 'endEditing' 'click #history-button': 'showVersionHistory' 'click .nav a': (e) -> $(e.target).tab('show') + 'click #component-patches-tab': -> @patchesView.load() + 'click #patch-component-button': 'startPatchingComponent' constructor: (options) -> super options @@ -21,6 +25,7 @@ module.exports = class LevelComponentEditView extends View getRenderData: (context={}) -> context = super(context) context.editTitle = "#{@levelComponent.get('system')}.#{@levelComponent.get('name')}" + context.component = @levelComponent context afterRender: -> @@ -28,6 +33,7 @@ module.exports = class LevelComponentEditView extends View @buildSettingsTreema() @buildConfigSchemaTreema() @buildCodeEditor() + @patchesView = @insertSubView(new PatchesView(@levelComponent), @$el.find('.patches-view')) buildSettingsTreema: -> data = _.pick @levelComponent.attributes, (value, key) => key in @editableSettings @@ -40,7 +46,6 @@ module.exports = class LevelComponentEditView extends View schema: schema data: data callbacks: {change: @onComponentSettingsEdited} - treemaOptions.readOnly = true unless me.isAdmin() @componentSettingsTreema = @$el.find('#edit-component-treema').treema treemaOptions @componentSettingsTreema.build() @componentSettingsTreema.open() @@ -58,7 +63,6 @@ module.exports = class LevelComponentEditView extends View schema: LevelComponent.schema.properties.configSchema data: @levelComponent.get 'configSchema' callbacks: {change: @onConfigSchemaEdited} - treemaOptions.readOnly = true unless me.isAdmin() @configSchemaTreema = @$el.find('#config-schema-treema').treema treemaOptions @configSchemaTreema.build() @configSchemaTreema.open() @@ -73,7 +77,6 @@ module.exports = class LevelComponentEditView extends View editorEl = @$el.find '#component-code-editor' editorEl.text @levelComponent.get('code') @editor = ace.edit(editorEl[0]) - @editor.setReadOnly(not me.isAdmin()) session = @editor.getSession() session.setMode 'ace/mode/coffee' session.setTabSize 2 @@ -97,4 +100,8 @@ module.exports = class LevelComponentEditView extends View showVersionHistory: (e) -> versionHistoryView = new VersionHistoryView component:@levelComponent, @levelComponent.id @openModalView versionHistoryView + Backbone.Mediator.publish 'level:view-switched', e + + startPatchingComponent: (e) -> + @openModalView new SaveVersionModal({model:@levelComponent}) Backbone.Mediator.publish 'level:view-switched', e \ No newline at end of file diff --git a/app/views/editor/level/save_view.coffee b/app/views/editor/level/save_view.coffee index f47b07657..86ba7e96b 100644 --- a/app/views/editor/level/save_view.coffee +++ b/app/views/editor/level/save_view.coffee @@ -30,7 +30,7 @@ module.exports = class LevelSaveView extends SaveVersionModal context afterRender: -> - super() + super(false) changeEls = @$el.find('.changes-stub') models = if @lastContext.levelNeedsSave then [@level] else [] models = models.concat @lastContext.modifiedComponents diff --git a/app/views/editor/level/thangs_tab_view.coffee b/app/views/editor/level/thangs_tab_view.coffee index 5c5ca8dbd..3e0ed6583 100644 --- a/app/views/editor/level/thangs_tab_view.coffee +++ b/app/views/editor/level/thangs_tab_view.coffee @@ -255,7 +255,7 @@ module.exports = class ThangsTabView extends View # @thangsTreema.deselectAll() selectAddThang: (e) => - return unless $(e.target).closest('.editor-level-thangs-tab-view').length + return unless (not e) or $(e.target).closest('.editor-level-thangs-tab-view').length if e then target = $(e.target) else target = @$el.find('.add-thangs-palette') # pretend to click on background if no event return true if target.attr('id') is 'surface' target = target.closest('.add-thang-palette-icon') diff --git a/app/views/modal/save_version_modal.coffee b/app/views/modal/save_version_modal.coffee index fda6b3951..d06aef707 100644 --- a/app/views/modal/save_version_modal.coffee +++ b/app/views/modal/save_version_modal.coffee @@ -27,15 +27,16 @@ module.exports = class SaveVersionModal extends ModalView c.hasChanges = @model.hasLocalChanges() c - afterRender: -> + afterRender: (insertDeltaView=true) -> super() @$el.find(if me.get('signedCLA') then '#accept-cla-wrapper' else '#save-version-button').hide() changeEl = @$el.find('.changes-stub') - try - deltaView = new DeltaView({model:@model}) - @insertSubView(deltaView, changeEl) - catch e - console.error "Couldn't create delta view:", e + if insertDeltaView + try + deltaView = new DeltaView({model:@model}) + @insertSubView(deltaView, changeEl) + catch e + console.error "Couldn't create delta view:", e @$el.find('.commit-message input').attr('placeholder', $.i18n.t('general.commit_msg')) onClickSaveButton: -> From 02a7381fa9bb71c7fcf230166aa1f5b9bb018117 Mon Sep 17 00:00:00 2001 From: Scott Erickson <sderickson@gmail.com> Date: Wed, 16 Apr 2014 11:02:40 -0700 Subject: [PATCH 03/17] Fixed the watch buttons for levels and components. --- app/models/CocoModel.coffee | 3 +- .../editor/level/component/edit.jade | 7 + app/templates/editor/level/edit.jade | 156 +++++++++--------- app/views/editor/level/component/edit.coffee | 18 +- app/views/editor/level/edit.coffee | 1 + server/commons/Handler.coffee | 3 - 6 files changed, 105 insertions(+), 83 deletions(-) diff --git a/app/models/CocoModel.coffee b/app/models/CocoModel.coffee index 838b30530..6ccfae775 100644 --- a/app/models/CocoModel.coffee +++ b/app/models/CocoModel.coffee @@ -229,8 +229,9 @@ class CocoModel extends Backbone.Model watch: (doWatch=true) -> $.ajax("#{@urlRoot}/#{@id}/watch", {type:'PUT', data:{on:doWatch}}) + @watching = -> doWatch watching: -> - return me.id in @get('watchers') or [] + return me.id in (@get('watchers') or []) module.exports = CocoModel diff --git a/app/templates/editor/level/component/edit.jade b/app/templates/editor/level/component/edit.jade index 1a6d74d38..843ef6b15 100644 --- a/app/templates/editor/level/component/edit.jade +++ b/app/templates/editor/level/component/edit.jade @@ -20,6 +20,13 @@ nav.navbar.navbar-default(role='navigation') li(data-i18n="general.version_history").btn.btn-primary.navbar-btn#history-button Version History li(data-i18n="editor.level_component_btn_new").btn.btn-primary.navbar-btn#create-new-component-button Create New Component li.btn.btn-primary.navbar-btn#patch-component-button Patch + li#watch-component-button.btn.btn-primary.navbar-btn + span.watch + span.spr Watch + span.glyphicon.glyphicon-eye-open + span.unwatch.secret + span.spr Unwatch + span.glyphicon.glyphicon-eye-close .tab-content .tab-pane.active#component-code diff --git a/app/templates/editor/level/edit.jade b/app/templates/editor/level/edit.jade index 297d000f8..ff7ecf3e8 100644 --- a/app/templates/editor/level/edit.jade +++ b/app/templates/editor/level/edit.jade @@ -2,82 +2,90 @@ extends /templates/base block outer_content .outer-content - - nav.navbar.navbar-default(role='navigation')#level-editor-top-nav - .container-fluid - ul.nav.navbar-nav - li - a(href="/editor/level", data-i18n="editor.back") Back - .navbar-header - span.navbar-brand - span(data-i18n="editor.level_title") Level Editor - span : - span.level-title #{level.attributes.name} - .collapse.navbar-collapse - ul.nav.navbar-nav.nav-tabs - - li.active - a(href="#editor-level-thangs-tab-view", data-toggle="tab", data-i18n="editor.level_tab_thangs") Thangs + + if level.loading + nav.navbar.navbar-default(role='navigation')#level-editor-top-nav + .container-fluid + ul.nav.navbar-nav li - a(href="#editor-level-scripts-tab-view", data-toggle="tab", data-i18n="editor.level_tab_scripts") Scripts + a(href="/editor/level", data-i18n="editor.back") Back + + else + nav.navbar.navbar-default(role='navigation')#level-editor-top-nav + .container-fluid + ul.nav.navbar-nav li - a(href="#editor-level-settings-tab-view", data-toggle="tab", data-i18n="editor.level_tab_settings") Settings - li - a(href="#editor-level-components-tab-view", data-toggle="tab", data-i18n="editor.level_tab_components") Components - li - a(href="#editor-level-systems-tab-view", data-toggle="tab", data-i18n="editor.level_tab_systems") Systems - li - a(href="#editor-level-patches", data-toggle="tab")#patches-tab - span(data-i18n="resources.patches").spr Patches - - var patches = level.get('patches') - if patches && patches.length - span.badge= patches.length - - ul.nav.navbar-nav.navbar-right - li#watch-button.btn.btn-primary.navbar-btn - span.watch - span.spr Watch - span.glyphicon.glyphicon-eye-open - span.unwatch.secret - span.spr Unwatch - span.glyphicon.glyphicon-eye-close - li(data-toggle="coco-modal", data-target="modal/revert", data-i18n="editor.revert", disabled=anonymous ? "true": undefined).btn.btn-primary.navbar-btn#revert-button Revert - if authorized - li(data-i18n="common.save").btn.btn-primary.navbar-btn#commit-level-start-button Save - else - li(data-i18n="common.patch").btn.btn-primary.navbar-btn#commit-level-patch-button Patch - li(data-i18n="common.fork", disabled=anonymous ? "true": undefined).btn.btn-primary.navbar-btn#fork-level-start-button Fork - li(title="⌃↩ or ⌘↩: Play preview of current level", data-i18n="common.play")#play-button.btn.btn-inverse.banner.navbar-btn Play! - - li.divider - - li.dropdown - a.dropdown-toggle(href='#', data-toggle='dropdown', data-i18n="editor.more") - | More - b.caret - ul.dropdown-menu - li#history-button - a(href='#', data-i18n="general.version_history") Version History - li - a(href='https://github.com/codecombat/codecombat/wiki/Artisan-Home', data-i18n="editor.wiki") Wiki - li - a(href='http://www.hipchat.com/g3plnOKqa', data-i18n="editor.live_chat") Live Chat - li - a(href='http://discourse.codecombat.com/category/artisan', data-i18n="nav.forum") Forum - li - a(data-toggle="coco-modal", data-target="modal/contact", data-i18n="nav.contact") Email - - - - ul.dropdown-menu - li - span(data-i18n="editor.level_some_options").dropdown-menu-header Some Options? - li.divider - li - a(data-delay="1000", href="#", data-i18n="common.delay_1_sec") 1 second - a(data-delay="3000", href="#", data-i18n="common.delay_3_sec") 3 seconds - a(data-delay="5000", href="#", data-i18n="common.delay_5_sec") 5 seconds - a(data-delay="90019001", href="#", data-i18n="common.manual") Manual + a(href="/editor/level", data-i18n="editor.back") Back + .navbar-header + span.navbar-brand + span(data-i18n="editor.level_title") Level Editor + span : + span.level-title #{level.attributes.name} + .collapse.navbar-collapse + ul.nav.navbar-nav.nav-tabs + + li.active + a(href="#editor-level-thangs-tab-view", data-toggle="tab", data-i18n="editor.level_tab_thangs") Thangs + li + a(href="#editor-level-scripts-tab-view", data-toggle="tab", data-i18n="editor.level_tab_scripts") Scripts + li + a(href="#editor-level-settings-tab-view", data-toggle="tab", data-i18n="editor.level_tab_settings") Settings + li + a(href="#editor-level-components-tab-view", data-toggle="tab", data-i18n="editor.level_tab_components") Components + li + a(href="#editor-level-systems-tab-view", data-toggle="tab", data-i18n="editor.level_tab_systems") Systems + li + a(href="#editor-level-patches", data-toggle="tab")#patches-tab + span(data-i18n="resources.patches").spr Patches + - var patches = level.get('patches') + if patches && patches.length + span.badge= patches.length + + ul.nav.navbar-nav.navbar-right + li#watch-button.btn.btn-primary.navbar-btn + span.watch + span.spr Watch + span.glyphicon.glyphicon-eye-open + span.unwatch.secret + span.spr Unwatch + span.glyphicon.glyphicon-eye-close + li(data-toggle="coco-modal", data-target="modal/revert", data-i18n="editor.revert", disabled=anonymous ? "true": undefined).btn.btn-primary.navbar-btn#revert-button Revert + if authorized + li(data-i18n="common.save").btn.btn-primary.navbar-btn#commit-level-start-button Save + else + li(data-i18n="common.patch").btn.btn-primary.navbar-btn#commit-level-patch-button Patch + li(data-i18n="common.fork", disabled=anonymous ? "true": undefined).btn.btn-primary.navbar-btn#fork-level-start-button Fork + li(title="⌃↩ or ⌘↩: Play preview of current level", data-i18n="common.play")#play-button.btn.btn-inverse.banner.navbar-btn Play! + + li.divider + + li.dropdown + a.dropdown-toggle(href='#', data-toggle='dropdown', data-i18n="editor.more") + | More + b.caret + ul.dropdown-menu + li#history-button + a(href='#', data-i18n="general.version_history") Version History + li + a(href='https://github.com/codecombat/codecombat/wiki/Artisan-Home', data-i18n="editor.wiki") Wiki + li + a(href='http://www.hipchat.com/g3plnOKqa', data-i18n="editor.live_chat") Live Chat + li + a(href='http://discourse.codecombat.com/category/artisan', data-i18n="nav.forum") Forum + li + a(data-toggle="coco-modal", data-target="modal/contact", data-i18n="nav.contact") Email + + + + ul.dropdown-menu + li + span(data-i18n="editor.level_some_options").dropdown-menu-header Some Options? + li.divider + li + a(data-delay="1000", href="#", data-i18n="common.delay_1_sec") 1 second + a(data-delay="3000", href="#", data-i18n="common.delay_3_sec") 3 seconds + a(data-delay="5000", href="#", data-i18n="common.delay_5_sec") 5 seconds + a(data-delay="90019001", href="#", data-i18n="common.manual") Manual div.tab-content#level-editor-tabs div.tab-pane.active#editor-level-thangs-tab-view diff --git a/app/views/editor/level/component/edit.coffee b/app/views/editor/level/component/edit.coffee index caf2340e5..fa2f3609f 100644 --- a/app/views/editor/level/component/edit.coffee +++ b/app/views/editor/level/component/edit.coffee @@ -16,6 +16,7 @@ module.exports = class LevelComponentEditView extends View 'click .nav a': (e) -> $(e.target).tab('show') 'click #component-patches-tab': -> @patchesView.load() 'click #patch-component-button': 'startPatchingComponent' + 'click #watch-component-button': 'toggleWatchComponent' constructor: (options) -> super options @@ -34,6 +35,7 @@ module.exports = class LevelComponentEditView extends View @buildConfigSchemaTreema() @buildCodeEditor() @patchesView = @insertSubView(new PatchesView(@levelComponent), @$el.find('.patches-view')) + @$el.find('#watch-component-button').find('> span').toggleClass('secret') if @levelComponent.watching() buildSettingsTreema: -> data = _.pick @levelComponent.attributes, (value, key) => key in @editableSettings @@ -93,10 +95,6 @@ module.exports = class LevelComponentEditView extends View Backbone.Mediator.publish 'level-component-editing-ended', levelComponent: @levelComponent null - destroy: -> - @editor?.destroy() - super() - showVersionHistory: (e) -> versionHistoryView = new VersionHistoryView component:@levelComponent, @levelComponent.id @openModalView versionHistoryView @@ -104,4 +102,14 @@ module.exports = class LevelComponentEditView extends View startPatchingComponent: (e) -> @openModalView new SaveVersionModal({model:@levelComponent}) - Backbone.Mediator.publish 'level:view-switched', e \ No newline at end of file + Backbone.Mediator.publish 'level:view-switched', e + + toggleWatchComponent: -> + button = @$el.find('#watch-component-button') + @levelComponent.watch(button.find('.watch').is(':visible')) + button.find('> span').toggleClass('secret') + + destroy: -> + @editor?.destroy() + super() + diff --git a/app/views/editor/level/edit.coffee b/app/views/editor/level/edit.coffee index a97f59be6..26808a742 100644 --- a/app/views/editor/level/edit.coffee +++ b/app/views/editor/level/edit.coffee @@ -94,6 +94,7 @@ module.exports = class EditorLevelView extends View Backbone.Mediator.publish 'level-loaded', level: @level @showReadOnly() if me.get('anonymous') @patchesView = @insertSubView(new PatchesView(@level), @$el.find('.patches-view')) + @$el.find('#watch-button').find('> span').toggleClass('secret') if @level.watching() onPlayLevel: (e) -> sendLevel = => diff --git a/server/commons/Handler.coffee b/server/commons/Handler.coffee index a7822f9e5..99c28e71c 100644 --- a/server/commons/Handler.coffee +++ b/server/commons/Handler.coffee @@ -112,11 +112,8 @@ module.exports = class Handler return @sendNotFoundError(res) unless document? watchers = document.get('watchers') or [] me = req.user.get('_id') - console.log 'watchers?', me, watchers watchers = (l for l in watchers when not l.equals(me)) - console.log 'new watchers is', watchers, req.body.on, req.body watchers.push me if req.body.on and req.body.on isnt 'false' - console.log 'watchers is actually now', watchers document.set 'watchers', watchers document.save (err, document) => return @sendDatabaseError(res, err) if err From 8859405e182bb6b34d07085945b7abd42e97b2a4 Mon Sep 17 00:00:00 2001 From: Scott Erickson <sderickson@gmail.com> Date: Thu, 17 Apr 2014 11:02:00 -0700 Subject: [PATCH 04/17] Reworked the nav bars in the level editor. --- app/locale/en.coffee | 1 + app/styles/editor/level/component/edit.sass | 7 +- app/styles/editor/level/components_tab.sass | 8 +- app/styles/editor/level/edit.sass | 46 ++++-- app/styles/editor/level/system/edit.sass | 5 +- app/styles/editor/level/systems_tab.sass | 6 +- .../editor/level/component/edit.jade | 68 +++++---- .../editor/level/components_tab.jade | 2 +- app/templates/editor/level/edit.jade | 144 +++++++++--------- app/templates/editor/level/system/edit.jade | 51 ++++--- .../editor/level/components_tab_view.coffee | 1 + .../editor/level/systems_tab_view.coffee | 1 + 12 files changed, 198 insertions(+), 142 deletions(-) diff --git a/app/locale/en.coffee b/app/locale/en.coffee index 335d9887f..83bb2e67f 100644 --- a/app/locale/en.coffee +++ b/app/locale/en.coffee @@ -17,6 +17,7 @@ retry: "Retry" watch: "Watch" unwatch: "Unwatch" + submit_patch: "Submit Patch" units: second: "second" diff --git a/app/styles/editor/level/component/edit.sass b/app/styles/editor/level/component/edit.sass index 2cd8e5d4f..beca326ff 100644 --- a/app/styles/editor/level/component/edit.sass +++ b/app/styles/editor/level/component/edit.sass @@ -14,9 +14,6 @@ left: 0 right: 0 bottom: 0 - top: 50px + top: 35px border: 2px solid black - border-top: none - - .active > a, .active > a:hover, .active > a:focus - background-color: white !important \ No newline at end of file + border-top: none \ No newline at end of file diff --git a/app/styles/editor/level/components_tab.sass b/app/styles/editor/level/components_tab.sass index b8a029a5b..c70a5f4d6 100644 --- a/app/styles/editor/level/components_tab.sass +++ b/app/styles/editor/level/components_tab.sass @@ -1,4 +1,6 @@ #editor-level-components-tab-view + h3 + margin-top: 0 .components-container position: absolute @@ -7,7 +9,7 @@ .treema-root position: absolute - top: 50px + top: 35px bottom: 0 width: 250px overflow: scroll @@ -25,13 +27,13 @@ .treema-root position: absolute - top: 50px + top: 35px right: 0 left: 0px bottom: 0 overflow: scroll - #create-new-component-button + #create-new-component-button-no-select position: absolute top: 0 right: 0 diff --git a/app/styles/editor/level/edit.sass b/app/styles/editor/level/edit.sass index f1cfc2303..339b199c2 100644 --- a/app/styles/editor/level/edit.sass +++ b/app/styles/editor/level/edit.sass @@ -4,7 +4,7 @@ #top-nav display: none - + position: absolute top: 0px left: 0px @@ -12,17 +12,45 @@ bottom: 0px $BG: rgba(228, 207, 140, 1.0) + $NAVBG: #2f261d li.navbar-btn margin-right: 5px - #level-editor-top-nav - .nav-tabs - border-bottom: 0 !important - .active > a, .active > a:hover, .active > a:focus - background-color: $BG !important - border-color: darken($BG, 50%) - border-bottom: 0 + // custom navbar height rules + .navbar-nav > li > a + padding: 7px 8px 8px + &:hover + background-color: lighten($NAVBG, 10%) + .navbar + min-height: 0px + border-radius: 0 + .navbar-right // not sure why bootstrap puts a big negative margin in, but this overrides it + margin-right: 10px + + // custom navbar styling + .navbar-brand + padding-top: 7px + padding-bottom: 7px + color: lighten(gold, 30%) + .navbar-header + border-left: 2px solid lighten($NAVBG, 20%) + border-right: 2px solid lighten($NAVBG, 20%) + background: lighten($NAVBG, 10%) + margin-left: 20px + .nav-tabs + margin-left: 5px + border-bottom: 0 !important + .active > a, .active > a:hover, .active > a:focus + background-color: $BG !important + border-color: darken($BG, 50%) + border-bottom: 0 + a + padding: 7px 5px !important + .dropdown-menu a + cursor: pointer + &:hover + background-color: #d3d3d3 .outer-content background-color: $BG @@ -47,7 +75,7 @@ position: absolute left: 20px right: 20px - top: 66px + top: 46px bottom: 20px .treema-root diff --git a/app/styles/editor/level/system/edit.sass b/app/styles/editor/level/system/edit.sass index e86dc5a46..e648e3e64 100644 --- a/app/styles/editor/level/system/edit.sass +++ b/app/styles/editor/level/system/edit.sass @@ -7,9 +7,6 @@ left: 0 right: 0 bottom: 0 - top: 50px + top: 35px border: 2px solid black border-top: none - - .active > a, .active > a:hover, .active > a:focus - background-color: white !important \ No newline at end of file diff --git a/app/styles/editor/level/systems_tab.sass b/app/styles/editor/level/systems_tab.sass index 88585504d..0d1aa6b33 100644 --- a/app/styles/editor/level/systems_tab.sass +++ b/app/styles/editor/level/systems_tab.sass @@ -1,4 +1,6 @@ #editor-level-systems-tab-view + h3 + margin-top: 0 .systems-container position: absolute @@ -7,7 +9,7 @@ .treema-root position: absolute - top: 50px + top: 35px bottom: 0 width: 250px overflow: scroll @@ -30,7 +32,7 @@ .treema-root position: absolute - top: 50px + top: 35px right: 0 left: 0px bottom: 0 diff --git a/app/templates/editor/level/component/edit.jade b/app/templates/editor/level/component/edit.jade index 843ef6b15..74d90e625 100644 --- a/app/templates/editor/level/component/edit.jade +++ b/app/templates/editor/level/component/edit.jade @@ -1,32 +1,44 @@ nav.navbar.navbar-default(role='navigation') - .container-fluid - .navbar-header - span.navbar-brand - span(data-i18n="editor.level_component_edit_title") - | Edit Component - span : - | "#{editTitle}" - .collapse.navbar-collapse - ul.nav.navbar-nav.nav-tabs - li.active - a(href="#component-code" data-toggle="tab" data-i18n="general.code") Code - li - a(href="#component-config-schema" data-toggle="tab" data-i18n="editor.level_component_config_schema") Config Schema - li - a(href="#component-settings" data-toggle="tab" data-i18n="editor.level_component_settings") Settings - li - a(href="#component-patches" data-toggle="tab" data-i18n="resources.patches")#component-patches-tab Patches - ul.nav.navbar-nav.navbar-left - li(data-i18n="general.version_history").btn.btn-primary.navbar-btn#history-button Version History - li(data-i18n="editor.level_component_btn_new").btn.btn-primary.navbar-btn#create-new-component-button Create New Component - li.btn.btn-primary.navbar-btn#patch-component-button Patch - li#watch-component-button.btn.btn-primary.navbar-btn - span.watch - span.spr Watch - span.glyphicon.glyphicon-eye-open - span.unwatch.secret - span.spr Unwatch - span.glyphicon.glyphicon-eye-close + ul.nav.navbar-nav.nav-tabs + li.active + a(href="#component-code" data-toggle="tab" data-i18n="general.code") Code + li + a(href="#component-config-schema" data-toggle="tab" data-i18n="editor.level_component_config_schema") Config Schema + li + a(href="#component-settings" data-toggle="tab" data-i18n="editor.level_component_settings") Settings + li + a(href="#component-patches" data-toggle="tab" data-i18n="resources.patches")#component-patches-tab Patches + + .navbar-header + span.navbar-brand= editTitle + + ul.nav.navbar-nav.navbar-right + li.dropdown + a(data-toggle='dropdown') + span.glyphicon-chevron-down.glyphicon + + ul.dropdown-menu + li.dropdown-header Actions + li#watch-component-button + a + span.watch + span.glyphicon.glyphicon-eye-open + span.spl Watch + span.unwatch.secret + span.glyphicon.glyphicon-eye-close + span.spl Unwatch + + li#patch-component-button + a(data-i18n="common.submit_patch") Submit Patch + + li#create-new-component-button + a(data-i18n="editor.level_component_btn_new") Create New Component + + li.divider + li.dropdown-header Info + + li#history-button + a(data-i18n="general.version_history") Version History .tab-content .tab-pane.active#component-code diff --git a/app/templates/editor/level/components_tab.jade b/app/templates/editor/level/components_tab.jade index e97f47aa4..9cd86545e 100644 --- a/app/templates/editor/level/components_tab.jade +++ b/app/templates/editor/level/components_tab.jade @@ -4,6 +4,6 @@ .edit-component-container if me.isAdmin() - button(data-i18n="editor.level_component_btn_new").btn.btn-primary#create-new-component-button Create New Component + button(data-i18n="editor.level_component_btn_new").btn.btn-primary#create-new-component-button-no-select Create New Component #editor-level-component-edit-view diff --git a/app/templates/editor/level/edit.jade b/app/templates/editor/level/edit.jade index ff7ecf3e8..5c21fb45e 100644 --- a/app/templates/editor/level/edit.jade +++ b/app/templates/editor/level/edit.jade @@ -3,90 +3,88 @@ extends /templates/base block outer_content .outer-content - if level.loading + if false nav.navbar.navbar-default(role='navigation')#level-editor-top-nav .container-fluid ul.nav.navbar-nav li - a(href="/editor/level", data-i18n="editor.back") Back + a(href="/editor/level") + span.glyphicon-home.glyphicon else nav.navbar.navbar-default(role='navigation')#level-editor-top-nav - .container-fluid - ul.nav.navbar-nav - li - a(href="/editor/level", data-i18n="editor.back") Back - .navbar-header - span.navbar-brand - span(data-i18n="editor.level_title") Level Editor - span : - span.level-title #{level.attributes.name} - .collapse.navbar-collapse - ul.nav.navbar-nav.nav-tabs - - li.active - a(href="#editor-level-thangs-tab-view", data-toggle="tab", data-i18n="editor.level_tab_thangs") Thangs - li - a(href="#editor-level-scripts-tab-view", data-toggle="tab", data-i18n="editor.level_tab_scripts") Scripts - li - a(href="#editor-level-settings-tab-view", data-toggle="tab", data-i18n="editor.level_tab_settings") Settings - li - a(href="#editor-level-components-tab-view", data-toggle="tab", data-i18n="editor.level_tab_components") Components - li - a(href="#editor-level-systems-tab-view", data-toggle="tab", data-i18n="editor.level_tab_systems") Systems - li - a(href="#editor-level-patches", data-toggle="tab")#patches-tab - span(data-i18n="resources.patches").spr Patches - - var patches = level.get('patches') - if patches && patches.length - span.badge= patches.length - - ul.nav.navbar-nav.navbar-right - li#watch-button.btn.btn-primary.navbar-btn - span.watch - span.spr Watch - span.glyphicon.glyphicon-eye-open - span.unwatch.secret - span.spr Unwatch - span.glyphicon.glyphicon-eye-close - li(data-toggle="coco-modal", data-target="modal/revert", data-i18n="editor.revert", disabled=anonymous ? "true": undefined).btn.btn-primary.navbar-btn#revert-button Revert - if authorized - li(data-i18n="common.save").btn.btn-primary.navbar-btn#commit-level-start-button Save - else - li(data-i18n="common.patch").btn.btn-primary.navbar-btn#commit-level-patch-button Patch - li(data-i18n="common.fork", disabled=anonymous ? "true": undefined).btn.btn-primary.navbar-btn#fork-level-start-button Fork - li(title="⌃↩ or ⌘↩: Play preview of current level", data-i18n="common.play")#play-button.btn.btn-inverse.banner.navbar-btn Play! - - li.divider - - li.dropdown - a.dropdown-toggle(href='#', data-toggle='dropdown', data-i18n="editor.more") - | More - b.caret - ul.dropdown-menu - li#history-button - a(href='#', data-i18n="general.version_history") Version History - li - a(href='https://github.com/codecombat/codecombat/wiki/Artisan-Home', data-i18n="editor.wiki") Wiki - li - a(href='http://www.hipchat.com/g3plnOKqa', data-i18n="editor.live_chat") Live Chat - li - a(href='http://discourse.codecombat.com/category/artisan', data-i18n="nav.forum") Forum - li - a(data-toggle="coco-modal", data-target="modal/contact", data-i18n="nav.contact") Email - - + ul.nav.navbar-nav + li + a(href="/editor/level") + span.glyphicon-home.glyphicon + ul.nav.navbar-nav.nav-tabs + li.active + a(href="#editor-level-thangs-tab-view", data-toggle="tab", data-i18n="editor.level_tab_thangs") Thangs + li + a(href="#editor-level-scripts-tab-view", data-toggle="tab", data-i18n="editor.level_tab_scripts") Scripts + li + a(href="#editor-level-settings-tab-view", data-toggle="tab", data-i18n="editor.level_tab_settings") Settings + li + a(href="#editor-level-components-tab-view", data-toggle="tab", data-i18n="editor.level_tab_components") Components + li + a(href="#editor-level-systems-tab-view", data-toggle="tab", data-i18n="editor.level_tab_systems") Systems + li + a(href="#editor-level-patches", data-toggle="tab")#patches-tab + span(data-i18n="resources.patches").spr Patches + - var patches = level.get('patches') + if patches && patches.length + span.badge= patches.length + + .navbar-header + span.navbar-brand #{level.attributes.name} + + ul.nav.navbar-nav.navbar-right + if authorized + li + a + span.glyphicon-floppy-disk.glyphicon + else + li + a + span.glyphicon-floppy-disk.glyphicon + + li(title="⌃↩ or ⌘↩: Play preview of current level") + a + span.glyphicon-play.glyphicon + li.dropdown + a(data-toggle='dropdown') + span.glyphicon-chevron-down.glyphicon ul.dropdown-menu - li - span(data-i18n="editor.level_some_options").dropdown-menu-header Some Options? + li.dropdown-header Actions + li#watch-button + a + span.watch + span.glyphicon.glyphicon-eye-open + span.spl Watch + span.unwatch.secret + span.glyphicon.glyphicon-eye-close + span.spl Unwatch + + li(class=anonymous ? "disabled": "") + a(data-i18n="common.fork")#fork-level-start-button Fork + li(class=anonymous ? "disabled": "") + a(data-toggle="coco-modal", data-target="modal/revert", data-i18n="editor.revert")#revert-button Revert li.divider + li.dropdown-header Info + li#history-button + a(href='#', data-i18n="general.version_history") Version History + li.divider + li.dropdown-header Help li - a(data-delay="1000", href="#", data-i18n="common.delay_1_sec") 1 second - a(data-delay="3000", href="#", data-i18n="common.delay_3_sec") 3 seconds - a(data-delay="5000", href="#", data-i18n="common.delay_5_sec") 5 seconds - a(data-delay="90019001", href="#", data-i18n="common.manual") Manual - + a(href='https://github.com/codecombat/codecombat/wiki/Artisan-Home', data-i18n="editor.wiki", target="_blank") Wiki + li + a(href='http://www.hipchat.com/g3plnOKqa', data-i18n="editor.live_chat", target="_blank") Live Chat + li + a(href='http://discourse.codecombat.com/category/artisan', data-i18n="nav.forum", target="_blank") Forum + li + a(data-toggle="coco-modal", data-target="modal/contact", data-i18n="nav.contact") Email + div.tab-content#level-editor-tabs div.tab-pane.active#editor-level-thangs-tab-view diff --git a/app/templates/editor/level/system/edit.jade b/app/templates/editor/level/system/edit.jade index db20287b6..d1aed8a93 100644 --- a/app/templates/editor/level/system/edit.jade +++ b/app/templates/editor/level/system/edit.jade @@ -1,21 +1,38 @@ nav.navbar.navbar-default(role='navigation') - .container-fluid - .navbar-header - span.navbar-brand - span(data-i18n="editor.level_system_edit_title") - | Edit System - span : - | "#{editTitle}" - .collapse.navbar-collapse - ul.nav.navbar-nav.nav-tabs - li.active - a(href="#system-code" data-toggle="tab") Code - li - a(href="#system-config-schema" data-toggle="tab") Config Schema - li - a(href="#system-settings" data-toggle="tab") Settings - ul.nav.navbar-nav.navbar-right - li(data-i18n="editor.level_system_btn_new").btn.btn-primary.navbar-btn#create-new-system-button Create New System + + ul.nav.navbar-nav.nav-tabs + li.active + a(href="#system-code" data-toggle="tab") Code + li + a(href="#system-config-schema" data-toggle="tab") Config Schema + li + a(href="#system-settings" data-toggle="tab") Settings + + ul.nav.navbar-nav.navbar-right + li.dropdown + a(data-toggle='dropdown') + span.glyphicon-chevron-down.glyphicon + ul.dropdown-menu + li.dropdown-header Actions + li#watch-component-button + a + span.watch + span.glyphicon.glyphicon-eye-open + span.spl Watch + span.unwatch.secret + span.glyphicon.glyphicon-eye-close + span.spl Unwatch + li#patch-component-button + a(data-i18n="common.submit_patch") Submit Patch + li#create-new-system + a(data-i18n="editor.level_system_btn_new") Create New System + li.divider + li.dropdown-header Info + li#system-history-button + a(data-i18n="general.version_history") Version History + + .navbar-header + span.navbar-brand= editTitle .tab-content .tab-pane.active#system-code diff --git a/app/views/editor/level/components_tab_view.coffee b/app/views/editor/level/components_tab_view.coffee index 823bebed1..0a6ab8518 100644 --- a/app/views/editor/level/components_tab_view.coffee +++ b/app/views/editor/level/components_tab_view.coffee @@ -21,6 +21,7 @@ module.exports = class ComponentsTabView extends View events: 'click #create-new-component-button': 'createNewLevelComponent' + 'click #create-new-component-button-no-select': 'createNewLevelComponent' onLevelThangsChanged: (e) -> thangsData = e.thangsData diff --git a/app/views/editor/level/systems_tab_view.coffee b/app/views/editor/level/systems_tab_view.coffee index eb4747b0e..e3f4fa626 100644 --- a/app/views/editor/level/systems_tab_view.coffee +++ b/app/views/editor/level/systems_tab_view.coffee @@ -23,6 +23,7 @@ module.exports = class SystemsTabView extends View events: 'click #add-system-button': 'addLevelSystem' 'click #create-new-system-button': 'createNewLevelSystem' + 'click #create-new-system': 'createNewLevelSystem' constructor: (options) -> super options From 8a2b762446d7747caa8c235fc9d50171df0b7d94 Mon Sep 17 00:00:00 2001 From: Scott Erickson <sderickson@gmail.com> Date: Thu, 17 Apr 2014 11:12:09 -0700 Subject: [PATCH 05/17] Fixed a bug where opening a modal by data attributes would sometimes open it multiple times. --- app/views/kinds/CocoView.coffee | 1 + 1 file changed, 1 insertion(+) diff --git a/app/views/kinds/CocoView.coffee b/app/views/kinds/CocoView.coffee index b368f51ab..5e9275ca3 100644 --- a/app/views/kinds/CocoView.coffee +++ b/app/views/kinds/CocoView.coffee @@ -207,6 +207,7 @@ class CocoView extends Backbone.View # Modals toggleModal: (e) -> + return if visibleModal if $(e.currentTarget).prop('target') is '_blank' return true # special handler for opening modals that are dynamically loaded, rather than static in the page. It works (or should work) like Bootstrap's modals, except use coco-modal for the data-toggle value. From 4c1143f026ead682daa6592538195ef5c6298641 Mon Sep 17 00:00:00 2001 From: Scott Erickson <sderickson@gmail.com> Date: Thu, 17 Apr 2014 11:22:33 -0700 Subject: [PATCH 06/17] Tweaked the versions history modal. --- app/templates/modal/versions.jade | 2 +- app/views/modal/versions_modal.coffee | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/app/templates/modal/versions.jade b/app/templates/modal/versions.jade index bd5b099eb..af78e7fcd 100755 --- a/app/templates/modal/versions.jade +++ b/app/templates/modal/versions.jade @@ -8,7 +8,7 @@ block modal-header-content block modal-body-content if dataList - table.table + table.table.table-condensed tr th(data-i18n="general.name") Name th(data-i18n="general.version") Version diff --git a/app/views/modal/versions_modal.coffee b/app/views/modal/versions_modal.coffee index 97aeafb33..6bf511396 100755 --- a/app/views/modal/versions_modal.coffee +++ b/app/views/modal/versions_modal.coffee @@ -13,6 +13,8 @@ class VersionsViewCollection extends Backbone.Collection module.exports = class VersionsModalView extends ModalView template: template startsLoading: true + plain: true + modalWidthPercent: 80 # needs to be overwritten by child id: "" From 6057bd94b93ca827e9c918269a44d5443fea5d09 Mon Sep 17 00:00:00 2001 From: Scott Erickson <sderickson@gmail.com> Date: Thu, 17 Apr 2014 11:27:20 -0700 Subject: [PATCH 07/17] Refactored how the editor sets up its special nav through base.jade. --- app/styles/editor/level/edit.sass | 16 +-- app/templates/editor/level/edit.jade | 156 +++++++++++++-------------- 2 files changed, 86 insertions(+), 86 deletions(-) diff --git a/app/styles/editor/level/edit.sass b/app/styles/editor/level/edit.sass index 339b199c2..a4f27c597 100644 --- a/app/styles/editor/level/edit.sass +++ b/app/styles/editor/level/edit.sass @@ -1,10 +1,10 @@ #editor-level-view + &, #level-editor-top-nav + min-width: 1024px + a font-family: helvetica, arial, sans serif - #top-nav - display: none - position: absolute top: 0px left: 0px @@ -55,7 +55,7 @@ .outer-content background-color: $BG position: absolute - top: 0 + top: 35px bottom: 0 left: 0 right: 0 @@ -73,10 +73,10 @@ #level-editor-tabs position: absolute - left: 20px - right: 20px - top: 46px - bottom: 20px + left: 15px + right: 15px + top: 15px + bottom: 15px .treema-root background-color: white diff --git a/app/templates/editor/level/edit.jade b/app/templates/editor/level/edit.jade index 5c21fb45e..ea902d695 100644 --- a/app/templates/editor/level/edit.jade +++ b/app/templates/editor/level/edit.jade @@ -1,90 +1,90 @@ extends /templates/base -block outer_content - .outer-content - - if false - nav.navbar.navbar-default(role='navigation')#level-editor-top-nav - .container-fluid - ul.nav.navbar-nav - li - a(href="/editor/level") - span.glyphicon-home.glyphicon - - else - nav.navbar.navbar-default(role='navigation')#level-editor-top-nav +block header + if false + nav.navbar.navbar-default(role='navigation')#level-editor-top-nav + .container-fluid ul.nav.navbar-nav li a(href="/editor/level") span.glyphicon-home.glyphicon - ul.nav.navbar-nav.nav-tabs - - li.active - a(href="#editor-level-thangs-tab-view", data-toggle="tab", data-i18n="editor.level_tab_thangs") Thangs - li - a(href="#editor-level-scripts-tab-view", data-toggle="tab", data-i18n="editor.level_tab_scripts") Scripts - li - a(href="#editor-level-settings-tab-view", data-toggle="tab", data-i18n="editor.level_tab_settings") Settings - li - a(href="#editor-level-components-tab-view", data-toggle="tab", data-i18n="editor.level_tab_components") Components - li - a(href="#editor-level-systems-tab-view", data-toggle="tab", data-i18n="editor.level_tab_systems") Systems - li - a(href="#editor-level-patches", data-toggle="tab")#patches-tab - span(data-i18n="resources.patches").spr Patches - - var patches = level.get('patches') - if patches && patches.length - span.badge= patches.length - - .navbar-header - span.navbar-brand #{level.attributes.name} + + else + nav.navbar.navbar-default(role='navigation')#level-editor-top-nav + ul.nav.navbar-nav + li + a(href="/editor/level") + span.glyphicon-home.glyphicon + ul.nav.navbar-nav.nav-tabs + + li.active + a(href="#editor-level-thangs-tab-view", data-toggle="tab", data-i18n="editor.level_tab_thangs") Thangs + li + a(href="#editor-level-scripts-tab-view", data-toggle="tab", data-i18n="editor.level_tab_scripts") Scripts + li + a(href="#editor-level-settings-tab-view", data-toggle="tab", data-i18n="editor.level_tab_settings") Settings + li + a(href="#editor-level-components-tab-view", data-toggle="tab", data-i18n="editor.level_tab_components") Components + li + a(href="#editor-level-systems-tab-view", data-toggle="tab", data-i18n="editor.level_tab_systems") Systems + li + a(href="#editor-level-patches", data-toggle="tab")#patches-tab + span(data-i18n="resources.patches").spr Patches + - var patches = level.get('patches') + if patches && patches.length + span.badge= patches.length + + .navbar-header + span.navbar-brand #{level.attributes.name} - ul.nav.navbar-nav.navbar-right - if authorized - li - a - span.glyphicon-floppy-disk.glyphicon - else - li - a - span.glyphicon-floppy-disk.glyphicon - - li(title="⌃↩ or ⌘↩: Play preview of current level") + ul.nav.navbar-nav.navbar-right + if authorized + li a - span.glyphicon-play.glyphicon - li.dropdown - a(data-toggle='dropdown') - span.glyphicon-chevron-down.glyphicon - ul.dropdown-menu - li.dropdown-header Actions - li#watch-button - a - span.watch - span.glyphicon.glyphicon-eye-open - span.spl Watch - span.unwatch.secret - span.glyphicon.glyphicon-eye-close - span.spl Unwatch - - li(class=anonymous ? "disabled": "") - a(data-i18n="common.fork")#fork-level-start-button Fork - li(class=anonymous ? "disabled": "") - a(data-toggle="coco-modal", data-target="modal/revert", data-i18n="editor.revert")#revert-button Revert - li.divider - li.dropdown-header Info - li#history-button - a(href='#', data-i18n="general.version_history") Version History - li.divider - li.dropdown-header Help - li - a(href='https://github.com/codecombat/codecombat/wiki/Artisan-Home', data-i18n="editor.wiki", target="_blank") Wiki - li - a(href='http://www.hipchat.com/g3plnOKqa', data-i18n="editor.live_chat", target="_blank") Live Chat - li - a(href='http://discourse.codecombat.com/category/artisan', data-i18n="nav.forum", target="_blank") Forum - li - a(data-toggle="coco-modal", data-target="modal/contact", data-i18n="nav.contact") Email + span.glyphicon-floppy-disk.glyphicon + else + li + a + span.glyphicon-floppy-disk.glyphicon + + li(title="⌃↩ or ⌘↩: Play preview of current level") + a + span.glyphicon-play.glyphicon + li.dropdown + a(data-toggle='dropdown') + span.glyphicon-chevron-down.glyphicon + ul.dropdown-menu + li.dropdown-header Actions + li#watch-button + a + span.watch + span.glyphicon.glyphicon-eye-open + span.spl Watch + span.unwatch.secret + span.glyphicon.glyphicon-eye-close + span.spl Unwatch + + li(class=anonymous ? "disabled": "") + a(data-i18n="common.fork")#fork-level-start-button Fork + li(class=anonymous ? "disabled": "") + a(data-toggle="coco-modal", data-target="modal/revert", data-i18n="editor.revert")#revert-button Revert + li.divider + li.dropdown-header Info + li#history-button + a(href='#', data-i18n="general.version_history") Version History + li.divider + li.dropdown-header Help + li + a(href='https://github.com/codecombat/codecombat/wiki/Artisan-Home', data-i18n="editor.wiki", target="_blank") Wiki + li + a(href='http://www.hipchat.com/g3plnOKqa', data-i18n="editor.live_chat", target="_blank") Live Chat + li + a(href='http://discourse.codecombat.com/category/artisan', data-i18n="nav.forum", target="_blank") Forum + li + a(data-toggle="coco-modal", data-target="modal/contact", data-i18n="nav.contact") Email +block outer_content + .outer-content div.tab-content#level-editor-tabs div.tab-pane.active#editor-level-thangs-tab-view From 8f4535853b81b5b02f314e20365e103bf74ed2b7 Mon Sep 17 00:00:00 2001 From: Scott Erickson <sderickson@gmail.com> Date: Thu, 17 Apr 2014 11:29:12 -0700 Subject: [PATCH 08/17] Fixed the component history button. --- app/templates/editor/level/component/edit.jade | 2 +- app/templates/editor/level/edit.jade | 2 +- app/views/editor/level/component/edit.coffee | 2 +- app/views/editor/level/edit.coffee | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/app/templates/editor/level/component/edit.jade b/app/templates/editor/level/component/edit.jade index 74d90e625..655ac818f 100644 --- a/app/templates/editor/level/component/edit.jade +++ b/app/templates/editor/level/component/edit.jade @@ -37,7 +37,7 @@ nav.navbar.navbar-default(role='navigation') li.divider li.dropdown-header Info - li#history-button + li#component-history-button a(data-i18n="general.version_history") Version History .tab-content diff --git a/app/templates/editor/level/edit.jade b/app/templates/editor/level/edit.jade index ea902d695..20898abf6 100644 --- a/app/templates/editor/level/edit.jade +++ b/app/templates/editor/level/edit.jade @@ -70,7 +70,7 @@ block header a(data-toggle="coco-modal", data-target="modal/revert", data-i18n="editor.revert")#revert-button Revert li.divider li.dropdown-header Info - li#history-button + li#level-history-button a(href='#', data-i18n="general.version_history") Version History li.divider li.dropdown-header Help diff --git a/app/views/editor/level/component/edit.coffee b/app/views/editor/level/component/edit.coffee index fa2f3609f..7fc326b88 100644 --- a/app/views/editor/level/component/edit.coffee +++ b/app/views/editor/level/component/edit.coffee @@ -12,7 +12,7 @@ module.exports = class LevelComponentEditView extends View events: 'click #done-editing-component-button': 'endEditing' - 'click #history-button': 'showVersionHistory' + 'click #component-history-button': 'showVersionHistory' 'click .nav a': (e) -> $(e.target).tab('show') 'click #component-patches-tab': -> @patchesView.load() 'click #patch-component-button': 'startPatchingComponent' diff --git a/app/views/editor/level/edit.coffee b/app/views/editor/level/edit.coffee index 26808a742..fdc4727aa 100644 --- a/app/views/editor/level/edit.coffee +++ b/app/views/editor/level/edit.coffee @@ -27,7 +27,7 @@ module.exports = class EditorLevelView extends View 'click #play-button': 'onPlayLevel' 'click #commit-level-start-button': 'startCommittingLevel' 'click #fork-level-start-button': 'startForkingLevel' - 'click #history-button': 'showVersionHistory' + 'click #level-history-button': 'showVersionHistory' 'click #patches-tab': -> @patchesView.load() 'click #commit-level-patch-button': 'startPatchingLevel' 'click #watch-button': 'toggleWatchLevel' From 7bc9bb53282b52d241661e482aa5c61066cb4463 Mon Sep 17 00:00:00 2001 From: dpen2000 <davidpendray@gmail.com> Date: Thu, 17 Apr 2014 14:32:35 -0400 Subject: [PATCH 09/17] Fix javascript error occuring when e is null/undefined --- app/views/editor/level/thangs_tab_view.coffee | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/views/editor/level/thangs_tab_view.coffee b/app/views/editor/level/thangs_tab_view.coffee index 5c5ca8dbd..b11c616db 100644 --- a/app/views/editor/level/thangs_tab_view.coffee +++ b/app/views/editor/level/thangs_tab_view.coffee @@ -255,7 +255,7 @@ module.exports = class ThangsTabView extends View # @thangsTreema.deselectAll() selectAddThang: (e) => - return unless $(e.target).closest('.editor-level-thangs-tab-view').length + return unless e? and $(e.target).closest('.editor-level-thangs-tab-view').length if e then target = $(e.target) else target = @$el.find('.add-thangs-palette') # pretend to click on background if no event return true if target.attr('id') is 'surface' target = target.closest('.add-thang-palette-icon') From 9eff958dcb728c7404b1ac64904f19db06a5f32c Mon Sep 17 00:00:00 2001 From: Scott Erickson <sderickson@gmail.com> Date: Thu, 17 Apr 2014 11:35:09 -0700 Subject: [PATCH 10/17] Fixed the level and component watch buttons. --- app/templates/editor/level/component/edit.jade | 4 ++-- app/templates/editor/level/edit.jade | 6 +++--- app/templates/editor/level/system/edit.jade | 2 +- app/views/editor/level/component/edit.coffee | 6 +++--- app/views/editor/level/edit.coffee | 6 +++--- 5 files changed, 12 insertions(+), 12 deletions(-) diff --git a/app/templates/editor/level/component/edit.jade b/app/templates/editor/level/component/edit.jade index 655ac818f..d5ec68c93 100644 --- a/app/templates/editor/level/component/edit.jade +++ b/app/templates/editor/level/component/edit.jade @@ -19,8 +19,8 @@ nav.navbar.navbar-default(role='navigation') ul.dropdown-menu li.dropdown-header Actions - li#watch-component-button - a + li + a#component-watch-button span.watch span.glyphicon.glyphicon-eye-open span.spl Watch diff --git a/app/templates/editor/level/edit.jade b/app/templates/editor/level/edit.jade index 20898abf6..ecfebecf9 100644 --- a/app/templates/editor/level/edit.jade +++ b/app/templates/editor/level/edit.jade @@ -1,7 +1,7 @@ extends /templates/base block header - if false + if level.loading nav.navbar.navbar-default(role='navigation')#level-editor-top-nav .container-fluid ul.nav.navbar-nav @@ -55,8 +55,8 @@ block header span.glyphicon-chevron-down.glyphicon ul.dropdown-menu li.dropdown-header Actions - li#watch-button - a + li + a#level-watch-button span.watch span.glyphicon.glyphicon-eye-open span.spl Watch diff --git a/app/templates/editor/level/system/edit.jade b/app/templates/editor/level/system/edit.jade index d1aed8a93..ad4bc1e62 100644 --- a/app/templates/editor/level/system/edit.jade +++ b/app/templates/editor/level/system/edit.jade @@ -14,7 +14,7 @@ nav.navbar.navbar-default(role='navigation') span.glyphicon-chevron-down.glyphicon ul.dropdown-menu li.dropdown-header Actions - li#watch-component-button + li#component-watch-button a span.watch span.glyphicon.glyphicon-eye-open diff --git a/app/views/editor/level/component/edit.coffee b/app/views/editor/level/component/edit.coffee index 7fc326b88..1b842942a 100644 --- a/app/views/editor/level/component/edit.coffee +++ b/app/views/editor/level/component/edit.coffee @@ -16,7 +16,7 @@ module.exports = class LevelComponentEditView extends View 'click .nav a': (e) -> $(e.target).tab('show') 'click #component-patches-tab': -> @patchesView.load() 'click #patch-component-button': 'startPatchingComponent' - 'click #watch-component-button': 'toggleWatchComponent' + 'click #component-watch-button': 'toggleWatchComponent' constructor: (options) -> super options @@ -35,7 +35,7 @@ module.exports = class LevelComponentEditView extends View @buildConfigSchemaTreema() @buildCodeEditor() @patchesView = @insertSubView(new PatchesView(@levelComponent), @$el.find('.patches-view')) - @$el.find('#watch-component-button').find('> span').toggleClass('secret') if @levelComponent.watching() + @$el.find('#component-watch-button').find('> span').toggleClass('secret') if @levelComponent.watching() buildSettingsTreema: -> data = _.pick @levelComponent.attributes, (value, key) => key in @editableSettings @@ -105,7 +105,7 @@ module.exports = class LevelComponentEditView extends View Backbone.Mediator.publish 'level:view-switched', e toggleWatchComponent: -> - button = @$el.find('#watch-component-button') + button = @$el.find('#component-watch-button') @levelComponent.watch(button.find('.watch').is(':visible')) button.find('> span').toggleClass('secret') diff --git a/app/views/editor/level/edit.coffee b/app/views/editor/level/edit.coffee index fdc4727aa..9ba419b47 100644 --- a/app/views/editor/level/edit.coffee +++ b/app/views/editor/level/edit.coffee @@ -30,7 +30,7 @@ module.exports = class EditorLevelView extends View 'click #level-history-button': 'showVersionHistory' 'click #patches-tab': -> @patchesView.load() 'click #commit-level-patch-button': 'startPatchingLevel' - 'click #watch-button': 'toggleWatchLevel' + 'click #level-watch-button': 'toggleWatchLevel' constructor: (options, @levelID) -> super options @@ -94,7 +94,7 @@ module.exports = class EditorLevelView extends View Backbone.Mediator.publish 'level-loaded', level: @level @showReadOnly() if me.get('anonymous') @patchesView = @insertSubView(new PatchesView(@level), @$el.find('.patches-view')) - @$el.find('#watch-button').find('> span').toggleClass('secret') if @level.watching() + @$el.find('#level-watch-button').find('> span').toggleClass('secret') if @level.watching() onPlayLevel: (e) -> sendLevel = => @@ -128,6 +128,6 @@ module.exports = class EditorLevelView extends View Backbone.Mediator.publish 'level:view-switched', e toggleWatchLevel: -> - button = @$el.find('#watch-button') + button = @$el.find('#level-watch-button') @level.watch(button.find('.watch').is(':visible')) button.find('> span').toggleClass('secret') From b5406b01494246dda047f741d0164127729f459c Mon Sep 17 00:00:00 2001 From: Scott Erickson <sderickson@gmail.com> Date: Thu, 17 Apr 2014 13:24:17 -0700 Subject: [PATCH 11/17] Set up the rest of the component/system buttons and nav bars. --- app/templates/editor/level/system/edit.jade | 10 ++++++--- app/views/editor/level/component/edit.coffee | 6 ++--- app/views/editor/level/system/edit.coffee | 23 ++++++++++++++++++++ app/views/editor/system/versions_view.coffee | 9 ++++++++ 4 files changed, 42 insertions(+), 6 deletions(-) create mode 100755 app/views/editor/system/versions_view.coffee diff --git a/app/templates/editor/level/system/edit.jade b/app/templates/editor/level/system/edit.jade index ad4bc1e62..cc35a29b5 100644 --- a/app/templates/editor/level/system/edit.jade +++ b/app/templates/editor/level/system/edit.jade @@ -7,6 +7,8 @@ nav.navbar.navbar-default(role='navigation') a(href="#system-config-schema" data-toggle="tab") Config Schema li a(href="#system-settings" data-toggle="tab") Settings + li + a(href="#system-patches" data-toggle="tab" data-i18n="resources.patches")#system-patches-tab Patches ul.nav.navbar-nav.navbar-right li.dropdown @@ -14,15 +16,15 @@ nav.navbar.navbar-default(role='navigation') span.glyphicon-chevron-down.glyphicon ul.dropdown-menu li.dropdown-header Actions - li#component-watch-button - a + li + a#system-watch-button span.watch span.glyphicon.glyphicon-eye-open span.spl Watch span.unwatch.secret span.glyphicon.glyphicon-eye-close span.spl Unwatch - li#patch-component-button + li#patch-system-button a(data-i18n="common.submit_patch") Submit Patch li#create-new-system a(data-i18n="editor.level_system_btn_new") Create New System @@ -41,3 +43,5 @@ nav.navbar.navbar-default(role='navigation') #config-schema-treema .tab-pane#system-settings #edit-system-treema + .tab-pane#system-patches + .patches-view \ No newline at end of file diff --git a/app/views/editor/level/component/edit.coffee b/app/views/editor/level/component/edit.coffee index 1b842942a..ba8c01d48 100644 --- a/app/views/editor/level/component/edit.coffee +++ b/app/views/editor/level/component/edit.coffee @@ -1,7 +1,7 @@ View = require 'views/kinds/CocoView' -VersionHistoryView = require 'views/editor/component/versions_view' template = require 'templates/editor/level/component/edit' LevelComponent = require 'models/LevelComponent' +VersionHistoryView = require 'views/editor/component/versions_view' PatchesView = require 'views/editor/patches_view' SaveVersionModal = require 'views/modal/save_version_modal' @@ -12,9 +12,9 @@ module.exports = class LevelComponentEditView extends View events: 'click #done-editing-component-button': 'endEditing' - 'click #component-history-button': 'showVersionHistory' 'click .nav a': (e) -> $(e.target).tab('show') 'click #component-patches-tab': -> @patchesView.load() + 'click #component-history-button': 'showVersionHistory' 'click #patch-component-button': 'startPatchingComponent' 'click #component-watch-button': 'toggleWatchComponent' @@ -96,7 +96,7 @@ module.exports = class LevelComponentEditView extends View null showVersionHistory: (e) -> - versionHistoryView = new VersionHistoryView component:@levelComponent, @levelComponent.id + versionHistoryView = new VersionHistoryView {}, @levelComponent.id @openModalView versionHistoryView Backbone.Mediator.publish 'level:view-switched', e diff --git a/app/views/editor/level/system/edit.coffee b/app/views/editor/level/system/edit.coffee index 338ede1e5..365910d38 100644 --- a/app/views/editor/level/system/edit.coffee +++ b/app/views/editor/level/system/edit.coffee @@ -1,6 +1,9 @@ View = require 'views/kinds/CocoView' template = require 'templates/editor/level/system/edit' LevelSystem = require 'models/LevelSystem' +VersionHistoryView = require 'views/editor/system/versions_view' +PatchesView = require 'views/editor/patches_view' +SaveVersionModal = require 'views/modal/save_version_modal' module.exports = class LevelSystemEditView extends View id: "editor-level-system-edit-view" @@ -10,6 +13,10 @@ module.exports = class LevelSystemEditView extends View events: 'click #done-editing-system-button': 'endEditing' 'click .nav a': (e) -> $(e.target).tab('show') + 'click #system-patches-tab': -> @patchesView.load() + 'click #system-history-button': 'showVersionHistory' + 'click #patch-system-button': 'startPatchingSystem' + 'click #system-watch-button': 'toggleWatchSystem' constructor: (options) -> super options @@ -26,6 +33,7 @@ module.exports = class LevelSystemEditView extends View @buildSettingsTreema() @buildConfigSchemaTreema() @buildCodeEditor() + @patchesView = @insertSubView(new PatchesView(@levelSystem), @$el.find('.patches-view')) buildSettingsTreema: -> data = _.pick @levelSystem.attributes, (value, key) => key in @editableSettings @@ -88,6 +96,21 @@ module.exports = class LevelSystemEditView extends View Backbone.Mediator.publish 'level-system-editing-ended', levelSystem: @levelSystem null + showVersionHistory: (e) -> + versionHistoryView = new VersionHistoryView {}, @levelSystem.id + @openModalView versionHistoryView + Backbone.Mediator.publish 'level:view-switched', e + + startPatchingSystem: (e) -> + @openModalView new SaveVersionModal({model:@levelSystem}) + Backbone.Mediator.publish 'level:view-switched', e + + toggleWatchSystem: -> + console.log 'toggle watch system?' + button = @$el.find('#system-watch-button') + @levelSystem.watch(button.find('.watch').is(':visible')) + button.find('> span').toggleClass('secret') + destroy: -> @editor?.destroy() super() diff --git a/app/views/editor/system/versions_view.coffee b/app/views/editor/system/versions_view.coffee new file mode 100755 index 000000000..562d134ad --- /dev/null +++ b/app/views/editor/system/versions_view.coffee @@ -0,0 +1,9 @@ +VersionsModalView = require 'views/modal/versions_modal' + +module.exports = class SystemVersionsView extends VersionsModalView + id: "editor-system-versions-view" + url: "/db/level.system/" + page: "system" + + constructor: (options, @ID) -> + super options, ID, require 'models/LevelSystem' \ No newline at end of file From 781a8ec913139892ff227b43b6ae238a37540311 Mon Sep 17 00:00:00 2001 From: Scott Erickson <sderickson@gmail.com> Date: Thu, 17 Apr 2014 13:37:08 -0700 Subject: [PATCH 12/17] Fixed the play and save buttons. --- app/styles/editor/level/edit.sass | 4 ++-- app/templates/editor/level/edit.jade | 6 +++--- app/views/editor/level/edit.coffee | 2 +- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/app/styles/editor/level/edit.sass b/app/styles/editor/level/edit.sass index a4f27c597..3e747368f 100644 --- a/app/styles/editor/level/edit.sass +++ b/app/styles/editor/level/edit.sass @@ -20,6 +20,7 @@ // custom navbar height rules .navbar-nav > li > a padding: 7px 8px 8px + cursor: pointer &:hover background-color: lighten($NAVBG, 10%) .navbar @@ -80,5 +81,4 @@ .treema-root background-color: white - border-radius: 4px - + border-radius: 4px \ No newline at end of file diff --git a/app/templates/editor/level/edit.jade b/app/templates/editor/level/edit.jade index ecfebecf9..6b010912d 100644 --- a/app/templates/editor/level/edit.jade +++ b/app/templates/editor/level/edit.jade @@ -39,15 +39,15 @@ block header ul.nav.navbar-nav.navbar-right if authorized - li + li#commit-level-start-button a span.glyphicon-floppy-disk.glyphicon else - li + li#level-patch-button a span.glyphicon-floppy-disk.glyphicon - li(title="⌃↩ or ⌘↩: Play preview of current level") + li(title="⌃↩ or ⌘↩: Play preview of current level")#play-button a span.glyphicon-play.glyphicon li.dropdown diff --git a/app/views/editor/level/edit.coffee b/app/views/editor/level/edit.coffee index 9ba419b47..9a83172ac 100644 --- a/app/views/editor/level/edit.coffee +++ b/app/views/editor/level/edit.coffee @@ -29,7 +29,7 @@ module.exports = class EditorLevelView extends View 'click #fork-level-start-button': 'startForkingLevel' 'click #level-history-button': 'showVersionHistory' 'click #patches-tab': -> @patchesView.load() - 'click #commit-level-patch-button': 'startPatchingLevel' + 'click #level-patch-button': 'startPatchingLevel' 'click #level-watch-button': 'toggleWatchLevel' constructor: (options, @levelID) -> From cdaf2ebfaf01719a30adab337a3403846584e9ea Mon Sep 17 00:00:00 2001 From: Scott Erickson <sderickson@gmail.com> Date: Thu, 17 Apr 2014 14:23:33 -0700 Subject: [PATCH 13/17] Set up the tabs and views in the level editor to reload so that when patches are applied, their changes are visible. --- app/styles/editor/level/component/edit.sass | 9 ++++++++- app/styles/editor/level/system/edit.sass | 7 +++++++ app/styles/editor/patches.sass | 2 +- app/templates/editor/level/component/edit.jade | 6 +++--- app/templates/editor/level/system/edit.jade | 6 +++--- app/templates/editor/patch_modal.jade | 1 + app/views/editor/level/component/edit.coffee | 8 ++++++-- app/views/editor/level/edit.coffee | 8 ++++++++ app/views/editor/level/system/edit.coffee | 8 ++++++-- app/views/editor/patch_modal.coffee | 9 +++++++-- app/views/editor/patches_view.coffee | 3 ++- app/views/modal/save_version_modal.coffee | 1 + 12 files changed, 53 insertions(+), 15 deletions(-) diff --git a/app/styles/editor/level/component/edit.sass b/app/styles/editor/level/component/edit.sass index beca326ff..7a78534ed 100644 --- a/app/styles/editor/level/component/edit.sass +++ b/app/styles/editor/level/component/edit.sass @@ -16,4 +16,11 @@ bottom: 0 top: 35px border: 2px solid black - border-top: none \ No newline at end of file + border-top: none + + .inner-editor + position: absolute + left: 0 + right: 0 + bottom: 0 + top: 0px \ No newline at end of file diff --git a/app/styles/editor/level/system/edit.sass b/app/styles/editor/level/system/edit.sass index e648e3e64..567ff5b27 100644 --- a/app/styles/editor/level/system/edit.sass +++ b/app/styles/editor/level/system/edit.sass @@ -10,3 +10,10 @@ top: 35px border: 2px solid black border-top: none + + .inner-editor + position: absolute + left: 0 + right: 0 + bottom: 0 + top: 0px \ No newline at end of file diff --git a/app/styles/editor/patches.sass b/app/styles/editor/patches.sass index 87c22728e..110370137 100644 --- a/app/styles/editor/patches.sass +++ b/app/styles/editor/patches.sass @@ -1,3 +1,3 @@ .patches-view .status-buttons - margin: 10px 0 + margin-bottom: 10px diff --git a/app/templates/editor/level/component/edit.jade b/app/templates/editor/level/component/edit.jade index d5ec68c93..7228ff914 100644 --- a/app/templates/editor/level/component/edit.jade +++ b/app/templates/editor/level/component/edit.jade @@ -1,11 +1,11 @@ nav.navbar.navbar-default(role='navigation') ul.nav.navbar-nav.nav-tabs li.active - a(href="#component-code" data-toggle="tab" data-i18n="general.code") Code + a(href="#component-code" data-toggle="tab" data-i18n="general.code")#component-code-tab Code li - a(href="#component-config-schema" data-toggle="tab" data-i18n="editor.level_component_config_schema") Config Schema + a(href="#component-config-schema" data-toggle="tab" data-i18n="editor.level_component_config_schema")#component-config-schema-tab Config Schema li - a(href="#component-settings" data-toggle="tab" data-i18n="editor.level_component_settings") Settings + a(href="#component-settings" data-toggle="tab" data-i18n="editor.level_component_settings")#component-settings-tab Settings li a(href="#component-patches" data-toggle="tab" data-i18n="resources.patches")#component-patches-tab Patches diff --git a/app/templates/editor/level/system/edit.jade b/app/templates/editor/level/system/edit.jade index cc35a29b5..267993ea5 100644 --- a/app/templates/editor/level/system/edit.jade +++ b/app/templates/editor/level/system/edit.jade @@ -2,11 +2,11 @@ nav.navbar.navbar-default(role='navigation') ul.nav.navbar-nav.nav-tabs li.active - a(href="#system-code" data-toggle="tab") Code + a(href="#system-code" data-toggle="tab")#system-code-tab Code li - a(href="#system-config-schema" data-toggle="tab") Config Schema + a(href="#system-config-schema" data-toggle="tab")#system-config-schema-tab Config Schema li - a(href="#system-settings" data-toggle="tab") Settings + a(href="#system-settings" data-toggle="tab")#system-settings-tab Settings li a(href="#system-patches" data-toggle="tab" data-i18n="resources.patches")#system-patches-tab Patches diff --git a/app/templates/editor/patch_modal.jade b/app/templates/editor/patch_modal.jade index 68fed43f7..4d46d8cb5 100644 --- a/app/templates/editor/patch_modal.jade +++ b/app/templates/editor/patch_modal.jade @@ -6,6 +6,7 @@ block modal-header-content block modal-body-content .modal-body + p= patch.get('commitMessage') .changes-stub diff --git a/app/views/editor/level/component/edit.coffee b/app/views/editor/level/component/edit.coffee index ba8c01d48..74c23b567 100644 --- a/app/views/editor/level/component/edit.coffee +++ b/app/views/editor/level/component/edit.coffee @@ -14,6 +14,9 @@ module.exports = class LevelComponentEditView extends View 'click #done-editing-component-button': 'endEditing' 'click .nav a': (e) -> $(e.target).tab('show') 'click #component-patches-tab': -> @patchesView.load() + 'click #component-code-tab': 'buildCodeEditor' + 'click #component-config-schema-tab': 'buildConfigSchemaTreema' + 'click #component-settings-tab': 'buildSettingsTreema' 'click #component-history-button': 'showVersionHistory' 'click #patch-component-button': 'startPatchingComponent' 'click #component-watch-button': 'toggleWatchComponent' @@ -76,8 +79,9 @@ module.exports = class LevelComponentEditView extends View Backbone.Mediator.publish 'level-component-edited', levelComponent: @levelComponent buildCodeEditor: -> - editorEl = @$el.find '#component-code-editor' - editorEl.text @levelComponent.get('code') + @editor?.destroy() + editorEl = $('<div></div>').text(@levelComponent.get('code')).addClass('inner-editor') + @$el.find('#component-code-editor').empty().append(editorEl) @editor = ace.edit(editorEl[0]) session = @editor.getSession() session.setMode 'ace/mode/coffee' diff --git a/app/views/editor/level/edit.coffee b/app/views/editor/level/edit.coffee index 9a83172ac..f0f15828b 100644 --- a/app/views/editor/level/edit.coffee +++ b/app/views/editor/level/edit.coffee @@ -31,7 +31,14 @@ module.exports = class EditorLevelView extends View 'click #patches-tab': -> @patchesView.load() 'click #level-patch-button': 'startPatchingLevel' 'click #level-watch-button': 'toggleWatchLevel' + + subscriptions: + 'refresh-level-editor': 'rerenderAllViews' + rerenderAllViews: -> + for view in [@thangsTab, @settingsTab, @scriptsTab, @componentsTab, @systemsTab, @patchesView] + view.render() + constructor: (options, @levelID) -> super options @listenToOnce(@supermodel, 'loaded-all', @onAllLoaded) @@ -94,6 +101,7 @@ module.exports = class EditorLevelView extends View Backbone.Mediator.publish 'level-loaded', level: @level @showReadOnly() if me.get('anonymous') @patchesView = @insertSubView(new PatchesView(@level), @$el.find('.patches-view')) + @listenTo @patchesView, 'accepted-patch', -> location.reload() @$el.find('#level-watch-button').find('> span').toggleClass('secret') if @level.watching() onPlayLevel: (e) -> diff --git a/app/views/editor/level/system/edit.coffee b/app/views/editor/level/system/edit.coffee index 365910d38..a7699b316 100644 --- a/app/views/editor/level/system/edit.coffee +++ b/app/views/editor/level/system/edit.coffee @@ -14,6 +14,9 @@ module.exports = class LevelSystemEditView extends View 'click #done-editing-system-button': 'endEditing' 'click .nav a': (e) -> $(e.target).tab('show') 'click #system-patches-tab': -> @patchesView.load() + 'click #system-code-tab': 'buildCodeEditor' + 'click #system-config-schema-tab': 'buildConfigSchemaTreema' + 'click #system-settings-tab': 'buildSettingsTreema' 'click #system-history-button': 'showVersionHistory' 'click #patch-system-button': 'startPatchingSystem' 'click #system-watch-button': 'toggleWatchSystem' @@ -76,8 +79,9 @@ module.exports = class LevelSystemEditView extends View Backbone.Mediator.publish 'level-system-edited', levelSystem: @levelSystem buildCodeEditor: -> - editorEl = @$el.find '#system-code-editor' - editorEl.text @levelSystem.get('code') + @editor?.destroy() + editorEl = $('<div></div>').text(@levelSystem.get('code')).addClass('inner-editor') + @$el.find('#system-code-editor').empty().append(editorEl) @editor = ace.edit(editorEl[0]) @editor.setReadOnly(not me.isAdmin()) session = @editor.getSession() diff --git a/app/views/editor/patch_modal.coffee b/app/views/editor/patch_modal.coffee index 19f3ebfe6..88a5bec86 100644 --- a/app/views/editor/patch_modal.coffee +++ b/app/views/editor/patch_modal.coffee @@ -7,6 +7,7 @@ module.exports = class PatchModal extends ModalView id: "patch-modal" template: template plain: true + modalWidthPercent: 60 events: 'click #withdraw-button': 'withdrawPatch' @@ -30,12 +31,15 @@ module.exports = class PatchModal extends ModalView c.isPatchCreator = @patch.get('creator') is auth.me.id c.isPatchRecipient = @targetModel.hasWriteAccess() c.status = @patch.get 'status' + c.patch = @patch c afterRender: -> return if @originalSource.loading - headModel = @originalSource.clone(false) - headModel.set(@targetModel.attributes) + headModel = null + if @targetModel.hasWriteAccess() + headModel = @originalSource.clone(false) + headModel.set(@targetModel.attributes) pendingModel = @originalSource.clone(false) pendingModel.applyDelta(@patch.get('delta')) @@ -49,6 +53,7 @@ module.exports = class PatchModal extends ModalView delta = @deltaView.getApplicableDelta() @targetModel.applyDelta(delta) @targetModel.addPatchToAcceptOnSave(@patch) + @trigger 'accepted-patch' @hide() rejectPatch: -> diff --git a/app/views/editor/patches_view.coffee b/app/views/editor/patches_view.coffee index f8dd4fa15..ce9512caf 100644 --- a/app/views/editor/patches_view.coffee +++ b/app/views/editor/patches_view.coffee @@ -53,4 +53,5 @@ module.exports = class PatchesView extends CocoView openPatchModal: (e) -> patch = _.find @patches.models, {id:$(e.target).data('patch-id')} modal = new PatchModal(patch, @model) - @openModalView(modal) \ No newline at end of file + @openModalView(modal) + @listenTo modal, 'accepted-patch', -> @trigger 'accepted-patch' \ No newline at end of file diff --git a/app/views/modal/save_version_modal.coffee b/app/views/modal/save_version_modal.coffee index 13dbecda5..22fba1216 100644 --- a/app/views/modal/save_version_modal.coffee +++ b/app/views/modal/save_version_modal.coffee @@ -8,6 +8,7 @@ module.exports = class SaveVersionModal extends ModalView id: 'save-version-modal' template: template plain: true + modalWidthPercent: 60 events: 'click #save-version-button': 'onClickSaveButton' From 7ccaa8c843dd8b013d481f03b5a7e63273735ce2 Mon Sep 17 00:00:00 2001 From: Scott Erickson <sderickson@gmail.com> Date: Thu, 17 Apr 2014 14:39:52 -0700 Subject: [PATCH 14/17] Fixed a bug, colored a badge. --- app/styles/editor/level/edit.sass | 3 +++ app/views/editor/delta.coffee | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/app/styles/editor/level/edit.sass b/app/styles/editor/level/edit.sass index 3e747368f..7d2b5b962 100644 --- a/app/styles/editor/level/edit.sass +++ b/app/styles/editor/level/edit.sass @@ -52,6 +52,9 @@ cursor: pointer &:hover background-color: #d3d3d3 + + .badge + background-color: green .outer-content background-color: $BG diff --git a/app/views/editor/delta.coffee b/app/views/editor/delta.coffee index 09c0981a6..b79b1cda5 100644 --- a/app/views/editor/delta.coffee +++ b/app/views/editor/delta.coffee @@ -21,12 +21,12 @@ module.exports = class DeltaView extends CocoView if @headModel @headDeltas = @headModel.getExpandedDelta() @conflicts = deltasLib.getConflicts(@headDeltas, @expandedDeltas) - DeltaView.deltaCounter += @expandedDeltas.length getRenderData: -> c = super() c.deltas = @expandedDeltas c.counter = DeltaView.deltaCounter + DeltaView.deltaCounter += @expandedDeltas.length c afterRender: -> From 21e8d7b26f132fa45a451dda13b4401fcaac974f Mon Sep 17 00:00:00 2001 From: Scott Erickson <sderickson@gmail.com> Date: Thu, 17 Apr 2014 15:44:19 -0700 Subject: [PATCH 15/17] Fixed patches denormalization. --- app/models/CocoModel.coffee | 8 -------- app/views/editor/level/edit.coffee | 2 +- app/views/editor/patch_modal.coffee | 2 +- app/views/editor/patches_view.coffee | 11 +++++++++-- app/views/kinds/ModalView.coffee | 2 ++ server/patches/Patch.coffee | 3 ++- 6 files changed, 15 insertions(+), 13 deletions(-) diff --git a/app/models/CocoModel.coffee b/app/models/CocoModel.coffee index 6ccfae775..a4c031869 100644 --- a/app/models/CocoModel.coffee +++ b/app/models/CocoModel.coffee @@ -68,8 +68,6 @@ class CocoModel extends Backbone.Model @markToRevert() @clearBackup() @trigger "save", @ - PatchModel = require 'models/Patch' - PatchModel.setStatus id, 'accepted' for id in @get('acceptedPatches') or [] return super attrs, options fetch: -> @@ -221,12 +219,6 @@ class CocoModel extends Backbone.Model delta = @getDelta() deltasLib.expandDelta(delta, @_revertAttributes, @schema()) - addPatchToAcceptOnSave: (patch) -> - acceptedPatches = @get('acceptedPatches') or [] # not actually stored on the db - acceptedPatches.push patch.id - acceptedPatches = _.uniq(acceptedPatches) - @set 'acceptedPatches', acceptedPatches - watch: (doWatch=true) -> $.ajax("#{@urlRoot}/#{@id}/watch", {type:'PUT', data:{on:doWatch}}) @watching = -> doWatch diff --git a/app/views/editor/level/edit.coffee b/app/views/editor/level/edit.coffee index f0f15828b..88d50be62 100644 --- a/app/views/editor/level/edit.coffee +++ b/app/views/editor/level/edit.coffee @@ -101,7 +101,7 @@ module.exports = class EditorLevelView extends View Backbone.Mediator.publish 'level-loaded', level: @level @showReadOnly() if me.get('anonymous') @patchesView = @insertSubView(new PatchesView(@level), @$el.find('.patches-view')) - @listenTo @patchesView, 'accepted-patch', -> location.reload() + @listenTo @patchesView, 'accepted-patch', -> setTimeout "location.reload()", 400 @$el.find('#level-watch-button').find('> span').toggleClass('secret') if @level.watching() onPlayLevel: (e) -> diff --git a/app/views/editor/patch_modal.coffee b/app/views/editor/patch_modal.coffee index 88a5bec86..f5dc339cf 100644 --- a/app/views/editor/patch_modal.coffee +++ b/app/views/editor/patch_modal.coffee @@ -52,7 +52,7 @@ module.exports = class PatchModal extends ModalView acceptPatch: -> delta = @deltaView.getApplicableDelta() @targetModel.applyDelta(delta) - @targetModel.addPatchToAcceptOnSave(@patch) + @patch.setStatus('accepted') @trigger 'accepted-patch' @hide() diff --git a/app/views/editor/patches_view.coffee b/app/views/editor/patches_view.coffee index ce9512caf..8887b44bb 100644 --- a/app/views/editor/patches_view.coffee +++ b/app/views/editor/patches_view.coffee @@ -44,8 +44,11 @@ module.exports = class PatchesView extends CocoView @$el.find(".#{@status}").addClass 'active' onStatusButtonsChanged: (e) -> - @loaded = false @status = $(e.target).val() + @reloadPatches() + + reloadPatches: -> + @loaded = false @initPatches() @load() @render() @@ -54,4 +57,8 @@ module.exports = class PatchesView extends CocoView patch = _.find @patches.models, {id:$(e.target).data('patch-id')} modal = new PatchModal(patch, @model) @openModalView(modal) - @listenTo modal, 'accepted-patch', -> @trigger 'accepted-patch' \ No newline at end of file + @listenTo modal, 'accepted-patch', -> @trigger 'accepted-patch' + @listenTo modal, 'hide', -> + f = => @reloadPatches() + setTimeout(f, 400) + @stopListening modal \ No newline at end of file diff --git a/app/views/kinds/ModalView.coffee b/app/views/kinds/ModalView.coffee index 2bf6ee8db..26a32081a 100644 --- a/app/views/kinds/ModalView.coffee +++ b/app/views/kinds/ModalView.coffee @@ -45,9 +45,11 @@ module.exports = class ModalView extends CocoView super($el) hide: -> + @trigger 'hide' @$el.removeClass('fade').modal "hide" onHidden: -> + @trigger 'hidden' destroy: -> @hide() unless @hidden diff --git a/server/patches/Patch.coffee b/server/patches/Patch.coffee index df621f2a4..47b6aefa9 100644 --- a/server/patches/Patch.coffee +++ b/server/patches/Patch.coffee @@ -39,8 +39,9 @@ PatchSchema.pre 'save', (next) -> target.original = targetID patches = document.get('patches') or [] + patches = _.clone patches patches.push @_id - document.set 'patches', patches + document.set 'patches', patches, {strict: false} document.save (err) -> next(err) module.exports = mongoose.model('patch', PatchSchema) From ed0c7e1412a402a2fd743d34523f28484df6fd07 Mon Sep 17 00:00:00 2001 From: Scott Erickson <sderickson@gmail.com> Date: Thu, 17 Apr 2014 17:09:01 -0700 Subject: [PATCH 16/17] Creators of documents are automatically added as watchers. Added a patch creation email for watchers. --- app/views/modal/save_version_modal.coffee | 1 + server/commons/Handler.coffee | 8 ++++++-- server/patches/Patch.coffee | 1 + server/patches/patch_handler.coffee | 25 +++++++++++++++++++++++ server/sendwithus.coffee | 1 + test/server/common.coffee | 10 ++++----- test/server/functional/patch.spec.coffee | 11 +++++----- test/server/functional/user.spec.coffee | 2 +- 8 files changed, 46 insertions(+), 13 deletions(-) diff --git a/app/views/modal/save_version_modal.coffee b/app/views/modal/save_version_modal.coffee index 22fba1216..d95fc4166 100644 --- a/app/views/modal/save_version_modal.coffee +++ b/app/views/modal/save_version_modal.coffee @@ -56,6 +56,7 @@ module.exports = class SaveVersionModal extends ModalView } errors = patch.validate() forms.applyErrorsToForm(@$el, errors) if errors + patch.set 'editPath', document.location.pathname res = patch.save() return unless res @enableModalInProgress(@$el) diff --git a/server/commons/Handler.coffee b/server/commons/Handler.coffee index 99c28e71c..4ce1c6b93 100644 --- a/server/commons/Handler.coffee +++ b/server/commons/Handler.coffee @@ -233,6 +233,9 @@ module.exports = class Handler return @sendBadInputError(res, err.errors) if err?.valid is false return @sendDatabaseError(res, err) if err @sendSuccess(res, @formatEntity(req, document)) + @onPostSuccess(req, document) + + onPostSuccess: (req, doc) -> ### TODO: think about pulling some common stuff out of postFirstVersion/postNewVersion @@ -248,7 +251,6 @@ module.exports = class Handler document.set('original', document._id) document.set('creator', req.user._id) @saveChangesToDocument req, document, (err) => - console.log 'saved new version', document.toObject() return @sendBadInputError(res, err.errors) if err?.valid is false return @sendDatabaseError(res, err) if err @sendSuccess(res, @formatEntity(req, document)) @@ -299,7 +301,9 @@ module.exports = class Handler parentDocument.makeNewMajorVersion(updatedObject, done) makeNewInstance: (req) -> - new @modelClass({}) + model = new @modelClass({}) + model.set 'watchers', [req.user.get('_id')] if @modelClass.schema.is_patchable + model validateDocumentInput: (input) -> tv4 = require('tv4').tv4 diff --git a/server/patches/Patch.coffee b/server/patches/Patch.coffee index 47b6aefa9..3e12638cf 100644 --- a/server/patches/Patch.coffee +++ b/server/patches/Patch.coffee @@ -42,6 +42,7 @@ PatchSchema.pre 'save', (next) -> patches = _.clone patches patches.push @_id document.set 'patches', patches, {strict: false} + @targetLoaded = document document.save (err) -> next(err) module.exports = mongoose.model('patch', PatchSchema) diff --git a/server/patches/patch_handler.coffee b/server/patches/patch_handler.coffee index 12a68ed9a..6262936f6 100644 --- a/server/patches/patch_handler.coffee +++ b/server/patches/patch_handler.coffee @@ -1,8 +1,11 @@ Patch = require('./Patch') +User = require '../users/User' Handler = require('../commons/Handler') schema = require '../../app/schemas/models/patch' {handlers} = require '../commons/mapping' mongoose = require('mongoose') +log = require 'winston' +sendwithus = require '../sendwithus' PatchHandler = class PatchHandler extends Handler modelClass: Patch @@ -50,6 +53,28 @@ PatchHandler = class PatchHandler extends Handler patch.update {$set:{status:newStatus}}, {}, -> target.update {$pull:{patches:patch.get('_id')}}, {}, -> @sendSuccess(res, null) + + onPostSuccess: (req, doc) -> + log.error "Error sending patch created: could not find the loaded target on the patch object." unless doc.targetLoaded + return unless doc.targetLoaded + watchers = doc.targetLoaded.get('watchers') + return unless watchers?.length + User.find({_id:{$in:watchers}}).select({email:1, name:1}).exec (err, watchers) => + for watcher in watchers + @sendPatchCreatedEmail req.user, watcher, doc, doc.targetLoaded, req.body.editPath + sendPatchCreatedEmail: (patchCreator, watcher, patch, target, editPath) -> +# return if watcher._id is patchCreator._id + context = + email_id: sendwithus.templates.patch_created + recipient: + address: watcher.get('email') + name: watcher.get('name') + email_data: + doc_name: target.get('name') or '???' + submitter_name: patchCreator.get('name') or '???' + doc_link: "http://codecombat.com#{editPath}" + commit_message: patch.get('commitMessage') + sendwithus.api.send context, (err, result) -> module.exports = new PatchHandler() diff --git a/server/sendwithus.coffee b/server/sendwithus.coffee index bda58d896..41fbd4062 100644 --- a/server/sendwithus.coffee +++ b/server/sendwithus.coffee @@ -14,3 +14,4 @@ if config.unittest module.exports.templates = welcome_email: 'utnGaBHuSU4Hmsi7qrAypU' ladder_update_email: 'JzaZxf39A4cKMxpPZUfWy4' + patch_created: 'tem_xhxuNosLALsizTNojBjNcL' diff --git a/test/server/common.coffee b/test/server/common.coffee index e68c27b72..80aa6e47e 100644 --- a/test/server/common.coffee +++ b/test/server/common.coffee @@ -64,13 +64,13 @@ GLOBAL.unittest = {} unittest.users = unittest.users or {} unittest.getNormalJoe = (done, force) -> - unittest.getUser('normal@jo.com', 'food', done, force) + unittest.getUser('Joe', 'normal@jo.com', 'food', done, force) unittest.getOtherSam = (done, force) -> - unittest.getUser('other@sam.com', 'beer', done, force) + unittest.getUser('Sam', 'other@sam.com', 'beer', done, force) unittest.getAdmin = (done, force) -> - unittest.getUser('admin@afc.com', '80yqxpb38j', done, force) + unittest.getUser('Admin', 'admin@afc.com', '80yqxpb38j', done, force) -unittest.getUser = (email, password, done, force) -> +unittest.getUser = (name, email, password, done, force) -> # Creates the user if it doesn't already exist. return done(unittest.users[email]) if unittest.users[email] and not force @@ -81,6 +81,7 @@ unittest.getUser = (email, password, done, force) -> throw err if err User.findOne({email:email}).exec((err, user) -> user.set('permissions', if password is '80yqxpb38j' then [ 'admin' ] else []) + user.set('name', name) user.save (err) -> wrapUpGetUser(email, user, done) ) @@ -88,7 +89,6 @@ unittest.getUser = (email, password, done, force) -> form = req.form() form.append('email', email) form.append('password', password) - wrapUpGetUser = (email, user, done) -> unittest.users[email] = user diff --git a/test/server/functional/patch.spec.coffee b/test/server/functional/patch.spec.coffee index 4666c5353..9f35cb37d 100644 --- a/test/server/functional/patch.spec.coffee +++ b/test/server/functional/patch.spec.coffee @@ -16,13 +16,14 @@ describe '/db/patch', -> patch = commitMessage: 'Accept this patch!' delta: {name:['test']} + editPath: '/who/knows/yes' target: id:null collection: 'article' it 'creates an Article to patch', (done) -> loginAdmin -> - request.post {uri:articleURL, json:patch}, (err, res, body) -> + request.post {uri:articleURL, json:article}, (err, res, body) -> articles[0] = body patch.target.id = articles[0]._id done() @@ -56,24 +57,24 @@ describe '/db/patch', -> it 'allows you to set yourself as watching', (done) -> watchingURL = getURL("/db/article/#{articles[0]._id}/watch") request.put {uri: watchingURL, json: {on:true}}, (err, res, body) -> - expect(body.watchers[0]).toBeDefined() + expect(body.watchers[1]).toBeDefined() done() it 'added the watcher to the target document', (done) -> Article.findOne({}).exec (err, article) -> - expect(article.toObject().watchers[0]).toBeDefined() + expect(article.toObject().watchers[1]).toBeDefined() done() it 'does not add duplicate watchers', (done) -> watchingURL = getURL("/db/article/#{articles[0]._id}/watch") request.put {uri: watchingURL, json: {on:true}}, (err, res, body) -> - expect(body.watchers.length).toBe(1) + expect(body.watchers.length).toBe(2) done() it 'allows removing yourself', (done) -> watchingURL = getURL("/db/article/#{articles[0]._id}/watch") request.put {uri: watchingURL, json: {on:false}}, (err, res, body) -> - expect(body.watchers.length).toBe(0) + expect(body.watchers.length).toBe(1) done() it 'allows the submitter to withdraw the pull request', (done) -> diff --git a/test/server/functional/user.spec.coffee b/test/server/functional/user.spec.coffee index 29e1360a9..0ee2ff364 100644 --- a/test/server/functional/user.spec.coffee +++ b/test/server/functional/user.spec.coffee @@ -112,7 +112,7 @@ ghlfarghlarghlfarghlarghlfarghlarghlfarghlarghlfarghlarghlfarghlarghlfarghlarghl unittest.getNormalJoe (joe) -> req = request.put getURL(urlUser), (err, res) -> expect(res.statusCode).toBe(200) - unittest.getUser('New@email.com', 'null', (joe) -> + unittest.getUser('Wilhelm', 'New@email.com', 'null', (joe) -> expect(joe.get('name')).toBe('Wilhelm') expect(joe.get('emailLower')).toBe('new@email.com') expect(joe.get('email')).toBe('New@email.com') From 8adca4a1dae1913d9a2047b3a58085679a1b4418 Mon Sep 17 00:00:00 2001 From: Scott Erickson <sderickson@gmail.com> Date: Thu, 17 Apr 2014 17:30:55 -0700 Subject: [PATCH 17/17] Added a transactional email for when changes are made, to notify watchers. --- app/models/CocoModel.coffee | 1 + server/commons/Handler.coffee | 24 ++++++++++++++++++++++++ server/patches/patch_handler.coffee | 3 ++- server/sendwithus.coffee | 1 + test/server/functional/patch.spec.coffee | 2 +- 5 files changed, 29 insertions(+), 2 deletions(-) diff --git a/app/models/CocoModel.coffee b/app/models/CocoModel.coffee index a4c031869..b33177a3a 100644 --- a/app/models/CocoModel.coffee +++ b/app/models/CocoModel.coffee @@ -60,6 +60,7 @@ class CocoModel extends Backbone.Model return result.errors unless result.valid save: (attrs, options) -> + @set 'editPath', document.location.pathname options ?= {} success = options.success options.success = (resp) => diff --git a/server/commons/Handler.coffee b/server/commons/Handler.coffee index 4ce1c6b93..aed496fd8 100644 --- a/server/commons/Handler.coffee +++ b/server/commons/Handler.coffee @@ -4,6 +4,8 @@ Grid = require 'gridfs-stream' errors = require './errors' log = require 'winston' Patch = require '../patches/Patch' +User = require '../users/User' +sendwithus = require '../sendwithus' PROJECT = {original:1, name:1, version:1, description: 1, slug:1, kind: 1} FETCH_LIMIT = 200 @@ -293,6 +295,7 @@ module.exports = class Handler newDocument.save (err) => return @sendDatabaseError(res, err) if err @sendSuccess(res, @formatEntity(req, newDocument)) + @notifyWatchersOfChange(req.user, newDocument, req.body.editPath) if @modelClass.schema.is_patchable if major? parentDocument.makeNewMinorVersion(updatedObject, major, done) @@ -300,6 +303,27 @@ module.exports = class Handler else parentDocument.makeNewMajorVersion(updatedObject, done) + notifyWatchersOfChange: (editor, changedDocument, editPath) -> + watchers = changedDocument.get('watchers') or [] + watchers = (w for w in watchers when not w.equals(editor.get('_id'))) + return unless watchers.length + User.find({_id:{$in:watchers}}).select({email:1, name:1}).exec (err, watchers) => + for watcher in watchers + @notifyWatcherOfChange editor, watcher, changedDocument, editPath + + notifyWatcherOfChange: (editor, watcher, changedDocument, editPath) -> + context = + email_id: sendwithus.templates.change_made_notify_watcher + recipient: + address: watcher.get('email') + name: watcher.get('name') + email_data: + doc_name: changedDocument.get('name') or '???' + submitter_name: editor.get('name') or '???' + doc_link: if editPath then "http://codecombat.com#{editPath}" else null + commit_message: changedDocument.get('commitMessage') + sendwithus.api.send context, (err, result) -> + makeNewInstance: (req) -> model = new @modelClass({}) model.set 'watchers', [req.user.get('_id')] if @modelClass.schema.is_patchable diff --git a/server/patches/patch_handler.coffee b/server/patches/patch_handler.coffee index 6262936f6..4e134d73d 100644 --- a/server/patches/patch_handler.coffee +++ b/server/patches/patch_handler.coffee @@ -57,7 +57,8 @@ PatchHandler = class PatchHandler extends Handler onPostSuccess: (req, doc) -> log.error "Error sending patch created: could not find the loaded target on the patch object." unless doc.targetLoaded return unless doc.targetLoaded - watchers = doc.targetLoaded.get('watchers') + watchers = doc.targetLoaded.get('watchers') or [] + watchers = (w for w in watchers when not w.equals(editor.get('_id'))) return unless watchers?.length User.find({_id:{$in:watchers}}).select({email:1, name:1}).exec (err, watchers) => for watcher in watchers diff --git a/server/sendwithus.coffee b/server/sendwithus.coffee index 41fbd4062..04d8205c3 100644 --- a/server/sendwithus.coffee +++ b/server/sendwithus.coffee @@ -15,3 +15,4 @@ module.exports.templates = welcome_email: 'utnGaBHuSU4Hmsi7qrAypU' ladder_update_email: 'JzaZxf39A4cKMxpPZUfWy4' patch_created: 'tem_xhxuNosLALsizTNojBjNcL' + change_made_notify_watcher: 'tem_7KVkfmv9SZETb25dtHbUtG' diff --git a/test/server/functional/patch.spec.coffee b/test/server/functional/patch.spec.coffee index 9f35cb37d..9d0f4265d 100644 --- a/test/server/functional/patch.spec.coffee +++ b/test/server/functional/patch.spec.coffee @@ -52,7 +52,7 @@ describe '/db/patch', -> body = JSON.parse(body) expect(res.statusCode).toBe(200) expect(body.length).toBe(1) - done() + done() it 'allows you to set yourself as watching', (done) -> watchingURL = getURL("/db/article/#{articles[0]._id}/watch")