From 2acb885c727050f773cf736dd4f7f5b7f0a97ead Mon Sep 17 00:00:00 2001 From: Joe <33972521+hnb-ku@users.noreply.github.com> Date: Mon, 15 Oct 2018 10:59:49 +0800 Subject: [PATCH] FEATURE: fullscreen composer mode on desktop Adds keyboard shortcut and icon that allows expanding composer to full screen. --- .../components/composer-messages.js.es6 | 2 +- .../components/composer-toggles.js.es6 | 28 ++-- .../discourse/controllers/composer.js.es6 | 27 +++- .../discourse/lib/keyboard-shortcuts.js.es6 | 8 + .../discourse/models/composer.js.es6 | 22 ++- .../templates/components/composer-toggles.hbs | 10 +- .../discourse/templates/composer.hbs | 146 +++++++++--------- .../modal/keyboard-shortcuts-help.hbs | 1 + .../stylesheets/common/base/compose.scss | 2 +- app/assets/stylesheets/desktop/compose.scss | 50 ++++++ config/locales/client.en.yml | 3 + 11 files changed, 209 insertions(+), 90 deletions(-) diff --git a/app/assets/javascripts/discourse/components/composer-messages.js.es6 b/app/assets/javascripts/discourse/components/composer-messages.js.es6 index cf0fdaad8fc..1ac68616f8e 100644 --- a/app/assets/javascripts/discourse/components/composer-messages.js.es6 +++ b/app/assets/javascripts/discourse/components/composer-messages.js.es6 @@ -13,7 +13,7 @@ export default Ember.Component.extend({ _yourselfConfirm: null, similarTopics: null, - hidden: Ember.computed.not("composer.viewOpen"), + hidden: Ember.computed.not("composer.viewOpenOrFullscreen"), didInsertElement() { this._super(); diff --git a/app/assets/javascripts/discourse/components/composer-toggles.js.es6 b/app/assets/javascripts/discourse/components/composer-toggles.js.es6 index 918cfe2baba..e1172df2e29 100644 --- a/app/assets/javascripts/discourse/components/composer-toggles.js.es6 +++ b/app/assets/javascripts/discourse/components/composer-toggles.js.es6 @@ -4,18 +4,28 @@ export default Ember.Component.extend({ tagName: "", @computed("composeState") - title(composeState) { - if (composeState === "draft" || composeState === "saving") { - return "composer.abandon"; - } - return "composer.collapse"; + toggleTitle(composeState) { + return composeState === "draft" || composeState === "saving" + ? "composer.abandon" + : "composer.collapse"; + }, + + @computed("composeState") + fullscreenTitle(composeState) { + return composeState === "fullscreen" + ? "composer.exit_fullscreen" + : "composer.enter_fullscreen"; }, @computed("composeState") toggleIcon(composeState) { - if (composeState === "draft" || composeState === "saving") { - return "times"; - } - return "chevron-down"; + return composeState === "draft" || composeState === "saving" + ? "times" + : "chevron-down"; + }, + + @computed("composeState") + fullscreenIcon(composeState) { + return composeState === "fullscreen" ? "compress" : "expand"; } }); diff --git a/app/assets/javascripts/discourse/controllers/composer.js.es6 b/app/assets/javascripts/discourse/controllers/composer.js.es6 index 1a6bf47dd0f..8a0946c5e9d 100644 --- a/app/assets/javascripts/discourse/controllers/composer.js.es6 +++ b/app/assets/javascripts/discourse/controllers/composer.js.es6 @@ -231,7 +231,7 @@ export default Ember.Controller.extend({ @computed("model.composeState", "model.creatingTopic") popupMenuOptions(composeState) { - if (composeState === "open") { + if (composeState === "open" || composeState === "fullscreen") { let options = []; options.push( @@ -386,7 +386,10 @@ export default Ember.Controller.extend({ ) { this.close(); } else { - if (this.get("model.composeState") === Composer.OPEN) { + if ( + this.get("model.composeState") === Composer.OPEN || + this.get("model.composeState") === Composer.FULLSCREEN + ) { this.shrink(); } else { this.cancelComposer(); @@ -396,6 +399,11 @@ export default Ember.Controller.extend({ return false; }, + fullscreenComposer() { + this.toggleFullscreen(); + return false; + }, + // Import a quote from the post importQuote(toolbarEvent) { const postStream = this.get("topic.postStream"); @@ -457,7 +465,7 @@ export default Ember.Controller.extend({ return; } - if (this.get("model.viewOpen")) { + if (this.get("model.viewOpen") || this.get("model.viewFullscreen")) { this.shrink(); } }, @@ -881,6 +889,10 @@ export default Ember.Controller.extend({ } ]); } else { + // in case the composer is + // cancelled while in fullscreen + $("html").removeClass("fullscreen-composer"); + // it is possible there is some sort of crazy draft with no body ... just give up on it this.destroyDraft(); this.get("model").clearState(); @@ -947,6 +959,15 @@ export default Ember.Controller.extend({ this.set("model.composeState", Composer.DRAFT); }, + toggleFullscreen() { + this._saveDraft(); + if (this.get("model.composeState") === Composer.FULLSCREEN) { + this.set("model.composeState", Composer.OPEN); + } else { + this.set("model.composeState", Composer.FULLSCREEN); + } + }, + close() { this.setProperties({ model: null, lastValidatedAt: null }); }, diff --git a/app/assets/javascripts/discourse/lib/keyboard-shortcuts.js.es6 b/app/assets/javascripts/discourse/lib/keyboard-shortcuts.js.es6 index 01b9e3372e3..31f1c9a2140 100644 --- a/app/assets/javascripts/discourse/lib/keyboard-shortcuts.js.es6 +++ b/app/assets/javascripts/discourse/lib/keyboard-shortcuts.js.es6 @@ -65,6 +65,7 @@ const bindings = { "shift+s": { click: "#topic-footer-buttons button.share", anonymous: true }, // share topic "shift+u": { handler: "goToUnreadPost" }, "shift+z shift+z": { handler: "logout" }, + "shift+f11": { handler: "fullscreenComposer" }, t: { postAction: "replyAsNewTopic" }, u: { handler: "goBack", anonymous: true }, "x r": { @@ -212,6 +213,13 @@ export default { } }, + fullscreenComposer() { + const composer = this.container.lookup("controller:composer"); + if (composer.get("model")) { + composer.toggleFullscreen(); + } + }, + pinUnpinTopic() { this.container.lookup("controller:topic").togglePinnedState(); }, diff --git a/app/assets/javascripts/discourse/models/composer.js.es6 b/app/assets/javascripts/discourse/models/composer.js.es6 index 483bb66eef7..a86e48de2d3 100644 --- a/app/assets/javascripts/discourse/models/composer.js.es6 +++ b/app/assets/javascripts/discourse/models/composer.js.es6 @@ -26,6 +26,7 @@ const CLOSED = "closed", SAVING = "saving", OPEN = "open", DRAFT = "draft", + FULLSCREEN = "fullscreen", // When creating, these fields are moved into the post model from the composer model _create_serializer = { raw: "reply", @@ -144,15 +145,24 @@ const Composer = RestModel.extend({ viewOpen: Em.computed.equal("composeState", OPEN), viewDraft: Em.computed.equal("composeState", DRAFT), + viewFullscreen: Em.computed.equal("composeState", FULLSCREEN), + viewOpenOrFullscreen: Em.computed.or("viewOpen", "viewFullscreen"), composeStateChanged: function() { - var oldOpen = this.get("composerOpened"); + let oldOpen = this.get("composerOpened"), + elem = $("html"); + + if (this.get("composeState") === FULLSCREEN) { + elem.addClass("fullscreen-composer"); + } else { + elem.removeClass("fullscreen-composer"); + } if (this.get("composeState") === OPEN) { this.set("composerOpened", oldOpen || new Date()); } else { if (oldOpen) { - var oldTotal = this.get("composerTotalOpened") || 0; + let oldTotal = this.get("composerTotalOpened") || 0; this.set("composerTotalOpened", oldTotal + (new Date() - oldOpen)); } this.set("composerOpened", null); @@ -160,9 +170,8 @@ const Composer = RestModel.extend({ }.observes("composeState"), composerTime: function() { - var total = this.get("composerTotalOpened") || 0; - - var oldOpen = this.get("composerOpened"); + let total = this.get("composerTotalOpened") || 0, + oldOpen = this.get("composerOpened"); if (oldOpen) { total += new Date() - oldOpen; } @@ -183,7 +192,7 @@ const Composer = RestModel.extend({ // view detected user is typing typing: _.throttle( function() { - var typingTime = this.get("typingTime") || 0; + let typingTime = this.get("typingTime") || 0; this.set("typingTime", typingTime + 100); }, 100, @@ -1041,6 +1050,7 @@ Composer.reopenClass({ SAVING, OPEN, DRAFT, + FULLSCREEN, // The actions the composer can take CREATE_TOPIC, diff --git a/app/assets/javascripts/discourse/templates/components/composer-toggles.hbs b/app/assets/javascripts/discourse/templates/components/composer-toggles.hbs index 93263ae3cbe..a9efe1f6d58 100644 --- a/app/assets/javascripts/discourse/templates/components/composer-toggles.hbs +++ b/app/assets/javascripts/discourse/templates/components/composer-toggles.hbs @@ -10,5 +10,13 @@ class="toggler" icon=toggleIcon action=toggleComposer - title=title}} + title=toggleTitle}} + + {{#unless site.mobileView}} + {{flat-button + class="toggle-fullscreen" + icon=fullscreenIcon + action=toggleFullscreen + title=fullscreenTitle}} + {{/unless}} diff --git a/app/assets/javascripts/discourse/templates/composer.hbs b/app/assets/javascripts/discourse/templates/composer.hbs index dc71db36f76..d60ed2e804d 100644 --- a/app/assets/javascripts/discourse/templates/composer.hbs +++ b/app/assets/javascripts/discourse/templates/composer.hbs @@ -9,73 +9,77 @@ {{composer-messages composer=model messageCount=messageCount addLinkLookup="addLinkLookup"}} - {{#if model.viewOpen}} + {{#if model.viewOpenOrFullscreen}}