mirror of
https://github.com/discourse/discourse.git
synced 2025-09-06 10:50:21 +08:00
Refactor app events to more efficiently handle post highlighting
This commit is contained in:
parent
78d5d22776
commit
28f702a5b6
9 changed files with 61 additions and 57 deletions
|
@ -1,11 +1,12 @@
|
||||||
import Session from 'discourse/models/session';
|
import Session from 'discourse/models/session';
|
||||||
|
import AppEvents from 'discourse/lib/app-events';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: "inject-objects",
|
name: "inject-objects",
|
||||||
initialize: function(container, application) {
|
initialize: function(container, application) {
|
||||||
|
|
||||||
// Inject appEvents everywhere
|
// Inject appEvents everywhere
|
||||||
var appEvents = Ember.Object.createWithMixins(Ember.Evented);
|
var appEvents = AppEvents.create();
|
||||||
application.register('app-events:main', appEvents, { instantiate: false });
|
application.register('app-events:main', appEvents, { instantiate: false });
|
||||||
|
|
||||||
application.inject('controller', 'appEvents', 'app-events:main');
|
application.inject('controller', 'appEvents', 'app-events:main');
|
||||||
|
|
23
app/assets/javascripts/discourse/lib/app-events.js.es6
Normal file
23
app/assets/javascripts/discourse/lib/app-events.js.es6
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
export default Ember.Object.extend(Ember.Evented);
|
||||||
|
|
||||||
|
var id = 1;
|
||||||
|
function newKey() {
|
||||||
|
return "_view_app_event_" + (id++);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function createViewListener(eventName, cb) {
|
||||||
|
var extension = {};
|
||||||
|
extension[newKey()] = function() {
|
||||||
|
this.appEvents.on(eventName, this, cb);
|
||||||
|
}.on('didInsertElement');
|
||||||
|
|
||||||
|
extension[newKey()] = function() {
|
||||||
|
this.appEvents.off(eventName, this, cb);
|
||||||
|
}.on('willDestroyElement');
|
||||||
|
|
||||||
|
return extension;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function listenForViewEvent(viewClass, eventName, cb) {
|
||||||
|
viewClass.reopen(createViewListener(eventName, cb));
|
||||||
|
}
|
|
@ -2,7 +2,7 @@
|
||||||
var jumpScheduled = false,
|
var jumpScheduled = false,
|
||||||
rewrites = [];
|
rewrites = [];
|
||||||
|
|
||||||
Discourse.URL = Em.Object.createWithMixins({
|
Discourse.URL = Ember.Object.createWithMixins({
|
||||||
|
|
||||||
// Used for matching a topic
|
// Used for matching a topic
|
||||||
TOPIC_REGEXP: /\/t\/([^\/]+)\/(\d+)\/?(\d+)?/,
|
TOPIC_REGEXP: /\/t\/([^\/]+)\/(\d+)\/?(\d+)?/,
|
||||||
|
@ -210,10 +210,10 @@ Discourse.URL = Em.Object.createWithMixins({
|
||||||
if (path.match(/last$/)) { opts.nearPost = topicController.get('highest_post_number'); }
|
if (path.match(/last$/)) { opts.nearPost = topicController.get('highest_post_number'); }
|
||||||
var closest = opts.nearPost || 1;
|
var closest = opts.nearPost || 1;
|
||||||
|
|
||||||
|
var self = this;
|
||||||
postStream.refresh(opts).then(function() {
|
postStream.refresh(opts).then(function() {
|
||||||
topicController.setProperties({
|
topicController.setProperties({
|
||||||
currentPost: closest,
|
currentPost: closest,
|
||||||
highlightOnInsert: closest,
|
|
||||||
enteredAt: new Date().getTime().toString()
|
enteredAt: new Date().getTime().toString()
|
||||||
});
|
});
|
||||||
var closestPost = postStream.closestPostForPostNumber(closest),
|
var closestPost = postStream.closestPostForPostNumber(closest),
|
||||||
|
@ -221,7 +221,7 @@ Discourse.URL = Em.Object.createWithMixins({
|
||||||
progressController = container.lookup('controller:topic-progress');
|
progressController = container.lookup('controller:topic-progress');
|
||||||
|
|
||||||
progressController.set('progressPosition', progress);
|
progressController.set('progressPosition', progress);
|
||||||
Discourse.PostView.considerHighlighting(topicController, closest);
|
self.appEvents.trigger('post:highlight', closest);
|
||||||
}).then(function() {
|
}).then(function() {
|
||||||
Discourse.URL.jumpToPost(closest);
|
Discourse.URL.jumpToPost(closest);
|
||||||
});
|
});
|
||||||
|
|
|
@ -4,16 +4,9 @@
|
||||||
//
|
//
|
||||||
// This is useful if you want to get around Ember's default
|
// This is useful if you want to get around Ember's default
|
||||||
// behavior of not refreshing when navigating to the same place.
|
// behavior of not refreshing when navigating to the same place.
|
||||||
export default Em.Mixin.create({
|
|
||||||
_initURLRefresh: function() {
|
|
||||||
this.appEvents.on('url:refresh', this, '_urlRefresh');
|
|
||||||
}.on('didInsertElement'),
|
|
||||||
|
|
||||||
_tearDownURLRefresh: function() {
|
import { createViewListener } from 'discourse/lib/app-events';
|
||||||
this.appEvents.off('url:refresh', this, '_urlRefresh');
|
|
||||||
}.on('willDestroyElement'),
|
|
||||||
|
|
||||||
_urlRefresh: function() {
|
export default createViewListener('url:refresh', function() {
|
||||||
this.get('controller').send('refresh');
|
this.get('controller').send('refresh');
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
// This route is used for retrieving a topic based on params
|
// This route is used for retrieving a topic based on params
|
||||||
|
|
||||||
export default Discourse.Route.extend({
|
export default Discourse.Route.extend({
|
||||||
|
|
||||||
setupController: function(controller, params) {
|
setupController: function(controller, params) {
|
||||||
|
@ -15,6 +14,7 @@ export default Discourse.Route.extend({
|
||||||
// I sincerely hope no topic gets this many posts
|
// I sincerely hope no topic gets this many posts
|
||||||
if (params.nearPost === "last") { params.nearPost = 999999999; }
|
if (params.nearPost === "last") { params.nearPost = 999999999; }
|
||||||
|
|
||||||
|
var self = this;
|
||||||
postStream.refresh(params).then(function () {
|
postStream.refresh(params).then(function () {
|
||||||
|
|
||||||
// TODO we are seeing errors where closest post is null and this is exploding
|
// TODO we are seeing errors where closest post is null and this is exploding
|
||||||
|
@ -28,13 +28,13 @@ export default Discourse.Route.extend({
|
||||||
topicController.setProperties({
|
topicController.setProperties({
|
||||||
currentPost: closest,
|
currentPost: closest,
|
||||||
enteredAt: new Date().getTime().toString(),
|
enteredAt: new Date().getTime().toString(),
|
||||||
highlightOnInsert: closest
|
|
||||||
});
|
});
|
||||||
|
|
||||||
topicProgressController.setProperties({
|
topicProgressController.setProperties({
|
||||||
progressPosition: progress,
|
progressPosition: progress,
|
||||||
expanded: false
|
expanded: false
|
||||||
});
|
});
|
||||||
|
self.appEvents.trigger('post:highlight', closest);
|
||||||
Discourse.URL.jumpToPost(closest);
|
Discourse.URL.jumpToPost(closest);
|
||||||
|
|
||||||
if (topic.present('draft')) {
|
if (topic.present('draft')) {
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
var DAY = 60 * 50 * 1000;
|
var DAY = 60 * 50 * 1000;
|
||||||
|
|
||||||
Discourse.PostView = Discourse.GroupedView.extend(Ember.Evented, {
|
var PostView = Discourse.GroupedView.extend(Ember.Evented, {
|
||||||
classNames: ['topic-post', 'clearfix'],
|
classNames: ['topic-post', 'clearfix'],
|
||||||
templateName: 'post',
|
templateName: 'post',
|
||||||
classNameBindings: ['postTypeClass',
|
classNameBindings: ['postTypeClass',
|
||||||
|
@ -175,11 +175,7 @@ Discourse.PostView = Discourse.GroupedView.extend(Ember.Evented, {
|
||||||
},
|
},
|
||||||
|
|
||||||
actions: {
|
actions: {
|
||||||
/**
|
// Toggle the replies this post is a reply to
|
||||||
Toggle the replies this post is a reply to
|
|
||||||
|
|
||||||
@method showReplyHistory
|
|
||||||
**/
|
|
||||||
toggleReplyHistory: function(post) {
|
toggleReplyHistory: function(post) {
|
||||||
|
|
||||||
var replyHistory = post.get('replyHistory'),
|
var replyHistory = post.get('replyHistory'),
|
||||||
|
@ -203,7 +199,7 @@ Discourse.PostView = Discourse.GroupedView.extend(Ember.Evented, {
|
||||||
}
|
}
|
||||||
|
|
||||||
Em.run.next(function() {
|
Em.run.next(function() {
|
||||||
Discourse.PostView.highlight(replyPostNumber);
|
PostView.highlight(replyPostNumber);
|
||||||
$(window).scrollTop(self.$().position().top - offsetFromTop);
|
$(window).scrollTop(self.$().position().top - offsetFromTop);
|
||||||
});
|
});
|
||||||
return;
|
return;
|
||||||
|
@ -267,15 +263,7 @@ Discourse.PostView = Discourse.GroupedView.extend(Ember.Evented, {
|
||||||
|
|
||||||
this._showLinkCounts();
|
this._showLinkCounts();
|
||||||
|
|
||||||
// Track this post
|
|
||||||
Discourse.ScreenTrack.current().track(this.$().prop('id'), postNumber);
|
Discourse.ScreenTrack.current().track(this.$().prop('id'), postNumber);
|
||||||
|
|
||||||
// Highlight the post if required
|
|
||||||
if (postNumber > 1) {
|
|
||||||
Discourse.PostView.considerHighlighting(this.get('controller'), postNumber);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Add syntax highlighting
|
|
||||||
Discourse.SyntaxHighlighting.apply($post);
|
Discourse.SyntaxHighlighting.apply($post);
|
||||||
Discourse.Lightbox.apply($post);
|
Discourse.Lightbox.apply($post);
|
||||||
|
|
||||||
|
@ -307,27 +295,4 @@ Discourse.PostView = Discourse.GroupedView.extend(Ember.Evented, {
|
||||||
}.observes('controller.searchHighlight', 'cooked')
|
}.observes('controller.searchHighlight', 'cooked')
|
||||||
});
|
});
|
||||||
|
|
||||||
function highlight(postNumber) {
|
export default PostView;
|
||||||
var $contents = $('#post_' + postNumber +' .topic-body'),
|
|
||||||
origColor = $contents.data('orig-color') || $contents.css('backgroundColor');
|
|
||||||
|
|
||||||
$contents.data("orig-color", origColor)
|
|
||||||
.addClass('highlighted')
|
|
||||||
.stop()
|
|
||||||
.animate({ backgroundColor: origColor }, 2500, 'swing', function(){
|
|
||||||
$contents.removeClass('highlighted');
|
|
||||||
$contents.css({'background-color': ''});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
Discourse.PostView.reopenClass({
|
|
||||||
considerHighlighting: function(controller, postNumber) {
|
|
||||||
var highlightNumber = controller.get('highlightOnInsert');
|
|
||||||
|
|
||||||
// If we're meant to highlight a post
|
|
||||||
if (highlightNumber === postNumber) {
|
|
||||||
controller.set('highlightOnInsert', null);
|
|
||||||
Ember.run.scheduleOnce('afterRender', null, highlight, postNumber);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
|
@ -1,6 +1,7 @@
|
||||||
import AddCategoryClass from 'discourse/mixins/add-category-class';
|
import AddCategoryClass from 'discourse/mixins/add-category-class';
|
||||||
|
import { listenForViewEvent } from 'discourse/lib/app-events';
|
||||||
|
|
||||||
export default Discourse.View.extend(AddCategoryClass, Discourse.Scrolling, {
|
var TopicView = Discourse.View.extend(AddCategoryClass, Discourse.Scrolling, {
|
||||||
templateName: 'topic',
|
templateName: 'topic',
|
||||||
topicBinding: 'controller.model',
|
topicBinding: 'controller.model',
|
||||||
userFiltersBinding: 'controller.userFilters',
|
userFiltersBinding: 'controller.userFilters',
|
||||||
|
@ -157,3 +158,22 @@ export default Discourse.View.extend(AddCategoryClass, Discourse.Scrolling, {
|
||||||
}
|
}
|
||||||
}.property('topicTrackingState.messageCount')
|
}.property('topicTrackingState.messageCount')
|
||||||
});
|
});
|
||||||
|
|
||||||
|
function highlight(postNumber) {
|
||||||
|
var $contents = $('#post_' + postNumber +' .topic-body'),
|
||||||
|
origColor = $contents.data('orig-color') || $contents.css('backgroundColor');
|
||||||
|
|
||||||
|
$contents.data("orig-color", origColor)
|
||||||
|
.addClass('highlighted')
|
||||||
|
.stop()
|
||||||
|
.animate({ backgroundColor: origColor }, 2500, 'swing', function(){
|
||||||
|
$contents.removeClass('highlighted');
|
||||||
|
$contents.css({'background-color': ''});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
listenForViewEvent(TopicView, 'post:highlight', function(postNumber) {
|
||||||
|
Ember.run.scheduleOnce('afterRender', null, highlight, postNumber);
|
||||||
|
});
|
||||||
|
|
||||||
|
export default TopicView;
|
||||||
|
|
|
@ -10,6 +10,7 @@
|
||||||
//
|
//
|
||||||
|
|
||||||
// Stuff we need to load first
|
// Stuff we need to load first
|
||||||
|
//= require ./discourse/lib/app-events
|
||||||
//= require ./discourse/helpers/i18n
|
//= require ./discourse/helpers/i18n
|
||||||
//= require ./discourse/lib/ember_compat_handlebars
|
//= require ./discourse/lib/ember_compat_handlebars
|
||||||
//= require ./discourse/lib/computed
|
//= require ./discourse/lib/computed
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
import PollController from "discourse/plugins/poll/controllers/poll";
|
import PollController from "discourse/plugins/poll/controllers/poll";
|
||||||
|
import PostView from "discourse/views/post";
|
||||||
|
|
||||||
var Poll = Discourse.Model.extend({
|
var Poll = Discourse.Model.extend({
|
||||||
post: null,
|
post: null,
|
||||||
|
@ -71,7 +72,7 @@ export default {
|
||||||
name: 'poll',
|
name: 'poll',
|
||||||
|
|
||||||
initialize: function() {
|
initialize: function() {
|
||||||
Discourse.PostView.reopen({
|
PostView.reopen({
|
||||||
createPollUI: function($post) {
|
createPollUI: function($post) {
|
||||||
var post = this.get('post');
|
var post = this.get('post');
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue