diff --git a/app/assets/javascripts/discourse/components/topic-navigation.js.es6 b/app/assets/javascripts/discourse/components/topic-navigation.js.es6 index 945d14420e0..72313abb533 100644 --- a/app/assets/javascripts/discourse/components/topic-navigation.js.es6 +++ b/app/assets/javascripts/discourse/components/topic-navigation.js.es6 @@ -1,17 +1,65 @@ +import { observes } from 'ember-addons/ember-computed-decorators'; + export default Ember.Component.extend({ composerOpen: null, - classNameBindings: ['composerOpen'], - showTimeline: null, - info: null, + info: Em.Object.create(), _checkSize() { - const renderTimeline = $(window).width() > 960; - this.set('info', { renderTimeline, showTimeline: renderTimeline && !this.get('composerOpen') }); + let info = this.get('info'); + + if (info.get('topicProgressExpanded')) { + + info.setProperties({ + renderTimeline: true, + renderAdminMenuButton: true + }); + + } else { + + let renderTimeline = !this.site.mobileView; + + if (renderTimeline) { + + const width = $(window).width(); + let height = $(window).height(); + + if (this.get('composerOpen')) { + height -= $('#reply-control').height(); + } + + renderTimeline = width > 960 && height > 520; + } + + info.setProperties({ + renderTimeline, + renderAdminMenuButton: !renderTimeline + }); + } + }, + + // we need to store this so topic progress has something to init with + _topicScrolled(event) { + this.set('info.prevEvent', event); + }, + + @observes('info.topicProgressExpanded') + _expanded() { + if (this.get('info.topicProgressExpanded')) { + $(window).on('click.hide-fullscreen', (e) => { + if (!$(e.target).parents().is('.timeline-container, #topic-progress-wrapper')) { + this._collapseFullscreen(); + } + }); + } else { + $(window).off('click.hide-fullscreen'); + } + this._checkSize(); }, composerOpened() { this.set('composerOpen', true); - this._checkSize(); + // we need to do the check after animation is done + setTimeout(()=>this._checkSize(), 500); }, composerClosed() { @@ -19,25 +67,66 @@ export default Ember.Component.extend({ this._checkSize(); }, + _collapseFullscreen() { + if (this.get('info.topicProgressExpanded')) { + $('.timeline-fullscreen').removeClass('show'); + setTimeout(() => { + this.set('info.topicProgressExpanded', false); + this._checkSize(); + },500); + } + }, + + keyboardTrigger(e) { + if(e.type === "jump") { + bootbox.prompt(I18n.t('topic.progress.jump_prompt_long'), postIndex => { + if (postIndex === null) { return; } + this.sendAction('jumpToIndex', postIndex); + }); + + // this is insanely hacky, for some reason shown event never fires, + // something is bust in bootbox + // TODO upgrade bootbox to see if this hack can be removed + setTimeout(()=>{ + $('.bootbox.modal').trigger('shown'); + },50); + + } + }, + didInsertElement() { this._super(); + this.appEvents + .on('topic:current-post-scrolled', this, this._topicScrolled) + .on('topic:jump-to-post', this, this._collapseFullscreen) + .on('topic:keyboard-trigger', this, this.keyboardTrigger); + if (!this.site.mobileView) { $(window).on('resize.discourse-topic-navigation', () => this._checkSize()); this.appEvents.on('composer:will-open', this, this.composerOpened); this.appEvents.on('composer:will-close', this, this.composerClosed); - this._checkSize(); - } else { - this.set('info', null); + $('#reply-control').on('div-resized.discourse-topic-navigation', () => this._checkSize()); } + + this._checkSize(); }, willDestroyElement() { this._super(); + + this.appEvents + .off('topic:current-post-scrolled', this, this._topicScrolled) + .off('topic:jump-to-post', this, this._collapseFullscreen) + .off('topic:keyboard-trigger', this, this.keyboardTrigger); + + $(window).off('click.hide-fullscreen'); + if (!this.site.mobileView) { $(window).off('resize.discourse-topic-navigation'); this.appEvents.off('composer:will-open', this, this.composerOpened); this.appEvents.off('composer:will-close', this, this.composerClosed); + $('#reply-control').off('div-resized.discourse-topic-navigation'); } } }); diff --git a/app/assets/javascripts/discourse/components/topic-progress.js.es6 b/app/assets/javascripts/discourse/components/topic-progress.js.es6 index 86533ed6a65..768ad10356b 100644 --- a/app/assets/javascripts/discourse/components/topic-progress.js.es6 +++ b/app/assets/javascripts/discourse/components/topic-progress.js.es6 @@ -2,13 +2,11 @@ import { default as computed, observes } from 'ember-addons/ember-computed-decor export default Ember.Component.extend({ elementId: 'topic-progress-wrapper', - classNameBindings: ['docked', 'hidden'], + classNameBindings: ['docked'], expanded: false, - toPostIndex: null, docked: false, progressPosition: null, postStream: Ember.computed.alias('topic.postStream'), - userWantsToJump: null, _streamPercentage: null, init() { @@ -16,26 +14,6 @@ export default Ember.Component.extend({ (this.get('delegated') || []).forEach(m => this.set(m, m)); }, - @computed('userWantsToJump', 'showTimeline') - hidden(userWantsToJump, showTimeline) { - return !userWantsToJump && showTimeline; - }, - - @observes('hidden') - visibilityChanged() { - if (!this.get('hidden')) { - this._updateBar(); - } - }, - - keyboardTrigger(kbdEvent) { - if (kbdEvent.type === 'jump') { - this.set('expanded', true); - this.set('userWantsToJump', true); - Ember.run.scheduleOnce('afterRender', () => this.$('.jump-form input').focus()); - } - }, - @computed('progressPosition') jumpTopDisabled(progressPosition) { return progressPosition <= 3; @@ -83,10 +61,15 @@ export default Ember.Component.extend({ .on("composer:resized", this, this._dock) .on('composer:closed', this, this._dock) .on("topic:scrolled", this, this._dock) - .on('topic:current-post-scrolled', this, this._topicScrolled) - .on('topic-progress:keyboard-trigger', this, this.keyboardTrigger); + .on('topic:current-post-scrolled', this, this._topicScrolled); - Ember.run.scheduleOnce('afterRender', this, this._updateProgressBar); + const prevEvent = this.get('prevEvent'); + if (prevEvent) { + this._topicScrolled(prevEvent); + } else { + Ember.run.scheduleOnce('afterRender', this, this._updateProgressBar); + } + Ember.run.scheduleOnce('afterRender', this, this._dock); }, willDestroyElement() { @@ -95,12 +78,11 @@ export default Ember.Component.extend({ .off("composer:resized", this, this._dock) .off('composer:closed', this, this._dock) .off('topic:scrolled', this, this._dock) - .off('topic:current-post-scrolled', this, this._topicScrolled) - .off('topic-progress:keyboard-trigger'); + .off('topic:current-post-scrolled', this, this._topicScrolled); }, _updateProgressBar() { - if (this.isDestroyed || this.isDestroying || this.get('hidden')) { return; } + if (this.isDestroyed || this.isDestroying) { return; } const $topicProgress = this.$('#topic-progress'); // speeds up stuff, bypass jquery slowness and extra checks @@ -127,6 +109,10 @@ export default Ember.Component.extend({ offset = window.pageYOffset || $('html').scrollTop(), topicProgressHeight = $('#topic-progress').height(); + if (!$topicProgressWrapper || $topicProgressWrapper.length === 0) { + return; + } + let isDocked = false; if (maximumOffset) { const threshold = maximumOffset.top; @@ -156,71 +142,11 @@ export default Ember.Component.extend({ } }, - keyDown(e) { - if (this.get('expanded')) { - if (e.keyCode === 13) { - this.$('input').blur(); - this.send('jumpPost'); - } else if (e.keyCode === 27) { - this.send('toggleExpansion'); - this.set('userWantsToJump', false); - } - } - }, - - _jumpTo(postIndex) { - postIndex = parseInt(postIndex, 10); - - // Validate the post index first - if (isNaN(postIndex) || postIndex < 1) { - postIndex = 1; - } - if (postIndex > this.get('postStream.filteredPostsCount')) { - postIndex = this.get('postStream.filteredPostsCount'); - } - this.set('toPostIndex', postIndex); - this._beforeJump(); - this.sendAction('jumpToIndex', postIndex); - }, actions: { - toggleExpansion(opts) { + toggleExpansion() { this.toggleProperty('expanded'); - if (this.get('expanded')) { - this.set('userWantsToJump', false); - this.set('toPostIndex', this.get('progressPosition')); - if (opts && opts.highlight) { - Ember.run.next(() => $('.jump-form input').select().focus()); - } - if (!this.site.mobileView && !this.capabilities.isIOS) { - Ember.run.schedule('afterRender', () => this.$('input').focus()); - } - } - }, - - jumpPrompt() { - const postIndex = prompt(I18n.t('topic.progress.jump_prompt_long')); - if (postIndex === null) { return; } - this._jumpTo(postIndex); - }, - - jumpPost() { - this._jumpTo(this.get('toPostIndex')); - }, - - jumpTop() { - this._beforeJump(); - this.sendAction('jumpTop'); - }, - - jumpBottom() { - this._beforeJump(); - this.sendAction('jumpBottom'); } }, - _beforeJump() { - this.set('expanded', false); - this.set('userWantsToJump', false); - } }); diff --git a/app/assets/javascripts/discourse/components/topic-timeline.js.es6 b/app/assets/javascripts/discourse/components/topic-timeline.js.es6 index ee77495b2ae..eaa065857cb 100644 --- a/app/assets/javascripts/discourse/components/topic-timeline.js.es6 +++ b/app/assets/javascripts/discourse/components/topic-timeline.js.es6 @@ -10,12 +10,28 @@ export default MountWidget.extend(Docking, { dockAt: null, buildArgs() { - return { topic: this.get('topic'), - topicTrackingState: this.topicTrackingState, - enteredIndex: this.get('enteredIndex'), - dockAt: this.dockAt, - top: this.dockAt || FIXED_POS, - dockBottom: this.dockBottom }; + let attrs = { + topic: this.get('topic'), + topicTrackingState: this.topicTrackingState, + enteredIndex: this.get('enteredIndex'), + dockBottom: this.dockBottom, + mobileView: this.get('site.mobileView') + }; + + let event = this.get('prevEvent'); + if (event) { + attrs.enteredIndex = event.postIndex-1; + } + + if (this.get('fullscreen')) { + attrs.fullScreen = true; + attrs.addShowClass = this.get('addShowClass'); + } else { + attrs.dockAt = this.dockAt; + attrs.top = this.dockAt || FIXED_POS; + } + + return attrs; }, @observes('topic.highest_post_number', 'loading') @@ -54,6 +70,14 @@ export default MountWidget.extend(Docking, { didInsertElement() { this._super(); + + if (this.get('fullscreen') && !this.get('addShowClass')) { + Em.run.next(()=>{ + this.set('addShowClass', true); + this.queueRerender(); + }); + } + this.dispatch('topic:current-post-scrolled', 'timeline-scrollarea'); this.dispatch('topic-notifications-button:keyboard-trigger', 'topic-notifications-button'); } diff --git a/app/assets/javascripts/discourse/controllers/topic.js.es6 b/app/assets/javascripts/discourse/controllers/topic.js.es6 index 067f6510814..cf634b98325 100644 --- a/app/assets/javascripts/discourse/controllers/topic.js.es6 +++ b/app/assets/javascripts/discourse/controllers/topic.js.es6 @@ -670,6 +670,8 @@ export default Ember.Controller.extend(SelectedPostsCount, BufferedContent, { return; } + this.appEvents.trigger('topic:jump-to-post', postId); + const topic = this.get('model'); const postStream = topic.get('postStream'); const post = postStream.findLoadedPost(postId); diff --git a/app/assets/javascripts/discourse/lib/keyboard-shortcuts.js.es6 b/app/assets/javascripts/discourse/lib/keyboard-shortcuts.js.es6 index 49e543a52ee..477b914ce58 100644 --- a/app/assets/javascripts/discourse/lib/keyboard-shortcuts.js.es6 +++ b/app/assets/javascripts/discourse/lib/keyboard-shortcuts.js.es6 @@ -4,7 +4,7 @@ import { scrollTopFor } from 'discourse/lib/offset-calculator'; const bindings = { '!': {postAction: 'showFlags'}, - '#': {handler: 'toggleProgress', anonymous: true}, + '#': {handler: 'goToPost', anonymous: true}, '/': {handler: 'toggleSearch', anonymous: true}, '=': {handler: 'toggleHamburgerMenu', anonymous: true}, '?': {handler: 'showHelpModal', anonymous: true}, @@ -170,8 +170,8 @@ export default { this.container.lookup('controller:topic').togglePinnedState(); }, - toggleProgress() { - this.appEvents.trigger('topic-progress:keyboard-trigger', { type: 'jump' }); + goToPost() { + this.appEvents.trigger('topic:keyboard-trigger', { type: 'jump' }); }, toggleSearch(event) { diff --git a/app/assets/javascripts/discourse/templates/components/topic-progress.hbs b/app/assets/javascripts/discourse/templates/components/topic-progress.hbs index a840c135645..8c91ce73d7d 100644 --- a/app/assets/javascripts/discourse/templates/components/topic-progress.hbs +++ b/app/assets/javascripts/discourse/templates/components/topic-progress.hbs @@ -1,33 +1,8 @@ -{{#unless hidden}} - {{#if expanded}} - - {{/if}} - -{{/unless}} + diff --git a/app/assets/javascripts/discourse/templates/topic.hbs b/app/assets/javascripts/discourse/templates/topic.hbs index 638eceb6b0a..f6b97c0fc82 100644 --- a/app/assets/javascripts/discourse/templates/topic.hbs +++ b/app/assets/javascripts/discourse/templates/topic.hbs @@ -66,17 +66,26 @@