mirror of
https://github.com/discourse/discourse.git
synced 2025-02-25 18:55:32 -06:00
Add Discourse.Singleton
class mixin for creating singletons.
This commit is contained in:
parent
9564a6ce09
commit
8e1fae0459
@ -98,7 +98,7 @@ Discourse.ScreenTrack = Ember.Object.extend({
|
|||||||
highestSeen = Math.max(highestSeen, parseInt(postNumber, 10));
|
highestSeen = Math.max(highestSeen, parseInt(postNumber, 10));
|
||||||
});
|
});
|
||||||
|
|
||||||
var highestSeenByTopic = Discourse.Session.current('highestSeenByTopic');
|
var highestSeenByTopic = Discourse.Session.currentProp('highestSeenByTopic');
|
||||||
if ((highestSeenByTopic[topicId] || 0) < highestSeen) {
|
if ((highestSeenByTopic[topicId] || 0) < highestSeen) {
|
||||||
highestSeenByTopic[topicId] = highestSeen;
|
highestSeenByTopic[topicId] = highestSeen;
|
||||||
Discourse.TopicTrackingState.current().updateSeen(topicId, highestSeen);
|
Discourse.TopicTrackingState.current().updateSeen(topicId, highestSeen);
|
||||||
|
45
app/assets/javascripts/discourse/mixins/singleton.js
Normal file
45
app/assets/javascripts/discourse/mixins/singleton.js
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
/**
|
||||||
|
This mixin allows a class to return a singleton, as well as a method to quickly
|
||||||
|
read/write attributes on the singleton.
|
||||||
|
|
||||||
|
@class Discourse.Singleton
|
||||||
|
@extends Ember.Mixin
|
||||||
|
@namespace Discourse
|
||||||
|
@module Discourse
|
||||||
|
**/
|
||||||
|
Discourse.Singleton = Em.Mixin.create({
|
||||||
|
|
||||||
|
/**
|
||||||
|
Returns the current singleton instance of the class.
|
||||||
|
|
||||||
|
@method current
|
||||||
|
@returns {Ember.Object} the instance of the singleton
|
||||||
|
**/
|
||||||
|
current: function() {
|
||||||
|
if (!this._current) {
|
||||||
|
this._current = this.create({});
|
||||||
|
}
|
||||||
|
|
||||||
|
return this._current;
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
Returns or sets a property on the singleton instance.
|
||||||
|
|
||||||
|
@method currentProp
|
||||||
|
@param {String} property the property we want to get or set
|
||||||
|
@param {String} value the optional value to set the property to
|
||||||
|
@returns the value of the property
|
||||||
|
**/
|
||||||
|
currentProp: function(property, value) {
|
||||||
|
if (typeof(value) !== "undefined") {
|
||||||
|
this.current().set(property, value);
|
||||||
|
return value;
|
||||||
|
} else {
|
||||||
|
return this.current().get(property);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
|||||||
/**
|
/**
|
||||||
A data model representing current session data. You can put transient
|
A data model representing current session data. You can put transient
|
||||||
data here you might want later.
|
data here you might want later. It is not stored or serialized anywhere.
|
||||||
|
|
||||||
@class Session
|
@class Session
|
||||||
@extends Discourse.Model
|
@extends Discourse.Model
|
||||||
@ -13,28 +13,4 @@ Discourse.Session = Discourse.Model.extend({
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
Discourse.Session.reopenClass({
|
Discourse.Session.reopenClass(Discourse.Singleton);
|
||||||
|
|
||||||
/**
|
|
||||||
Returns the current session.
|
|
||||||
|
|
||||||
@method current
|
|
||||||
@returns {Discourse.Session} the current session singleton
|
|
||||||
**/
|
|
||||||
current: function(property, value) {
|
|
||||||
if (!this.currentSession) {
|
|
||||||
this.currentSession = Discourse.Session.create();
|
|
||||||
}
|
|
||||||
|
|
||||||
// If we found the current session
|
|
||||||
if (typeof property !== "undefined") {
|
|
||||||
if (typeof value !== "undefined") {
|
|
||||||
this.currentSession.set(property, value);
|
|
||||||
} else {
|
|
||||||
return this.currentSession.get(property);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return property ? this.currentSession.get(property) : this.currentSession;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
@ -87,7 +87,7 @@ Discourse.Topic = Discourse.Model.extend({
|
|||||||
// So take what the browser has seen into consideration.
|
// So take what the browser has seen into consideration.
|
||||||
displayNewPosts: function() {
|
displayNewPosts: function() {
|
||||||
var delta, highestSeen, result;
|
var delta, highestSeen, result;
|
||||||
if (highestSeen = Discourse.Session.current('highestSeenByTopic')[this.get('id')]) {
|
if (highestSeen = Discourse.Session.currentProp('highestSeenByTopic')[this.get('id')]) {
|
||||||
delta = highestSeen - this.get('last_read_post_number');
|
delta = highestSeen - this.get('last_read_post_number');
|
||||||
if (delta > 0) {
|
if (delta > 0) {
|
||||||
result = this.get('new_posts') - delta;
|
result = this.get('new_posts') - delta;
|
||||||
|
@ -45,7 +45,7 @@ Discourse.TopicList = Discourse.Model.extend({
|
|||||||
});
|
});
|
||||||
|
|
||||||
topicList.set('more_topics_url', result.topic_list.more_topics_url);
|
topicList.set('more_topics_url', result.topic_list.more_topics_url);
|
||||||
Discourse.Session.current('topicList', topicList);
|
Discourse.Session.currentProp('topicList', topicList);
|
||||||
topicList.set('loadingMore', false);
|
topicList.set('loadingMore', false);
|
||||||
|
|
||||||
return result.topic_list.more_topics_url;
|
return result.topic_list.more_topics_url;
|
||||||
@ -75,7 +75,7 @@ Discourse.TopicList = Discourse.Model.extend({
|
|||||||
t.set('highlight', true);
|
t.set('highlight', true);
|
||||||
topics.insertAt(0,t);
|
topics.insertAt(0,t);
|
||||||
});
|
});
|
||||||
Discourse.Session.current('topicList', topicList);
|
Discourse.Session.currentProp('topicList', topicList);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -41,7 +41,7 @@ Discourse.FilteredListRoute = Discourse.Route.extend({
|
|||||||
listController.set('canCreateTopic', topicList.get('can_create_topic'));
|
listController.set('canCreateTopic', topicList.get('can_create_topic'));
|
||||||
listTopicsController.set('model', topicList);
|
listTopicsController.set('model', topicList);
|
||||||
|
|
||||||
var scrollPos = Discourse.Session.current('topicListScrollPosition');
|
var scrollPos = Discourse.Session.currentProp('topicListScrollPosition');
|
||||||
if (scrollPos) {
|
if (scrollPos) {
|
||||||
Em.run.next(function() {
|
Em.run.next(function() {
|
||||||
$('html, body').scrollTop(scrollPos);
|
$('html, body').scrollTop(scrollPos);
|
||||||
|
@ -71,7 +71,7 @@ Discourse.TopicRoute = Discourse.Route.extend({
|
|||||||
this._super();
|
this._super();
|
||||||
|
|
||||||
var topic = this.modelFor('topic');
|
var topic = this.modelFor('topic');
|
||||||
Discourse.Session.current('lastTopicIdViewed', parseInt(topic.get('id'), 10));
|
Discourse.Session.currentProp('lastTopicIdViewed', parseInt(topic.get('id'), 10));
|
||||||
this.controllerFor('search').set('searchContext', topic.get('searchContext'));
|
this.controllerFor('search').set('searchContext', topic.get('searchContext'));
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -100,7 +100,6 @@ class UserNotifications < ActionMailer::Base
|
|||||||
end
|
end
|
||||||
|
|
||||||
def notification_email(user, opts)
|
def notification_email(user, opts)
|
||||||
|
|
||||||
return unless @notification = opts[:notification]
|
return unless @notification = opts[:notification]
|
||||||
return unless @post = opts[:post]
|
return unless @post = opts[:post]
|
||||||
|
|
||||||
|
37
test/javascripts/mixins/singleton_test.js
Normal file
37
test/javascripts/mixins/singleton_test.js
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
module("Discourse.Singleton");
|
||||||
|
|
||||||
|
test("current", function() {
|
||||||
|
var DummyModel = Ember.Object.extend({});
|
||||||
|
DummyModel.reopenClass(Discourse.Singleton);
|
||||||
|
|
||||||
|
var current = DummyModel.current();
|
||||||
|
present(current, 'current returns the current instance');
|
||||||
|
equal(current, DummyModel.current(), 'calling it again returns the same instance');
|
||||||
|
notEqual(current, DummyModel.create({}), 'we can create other instances that are not the same as current');
|
||||||
|
});
|
||||||
|
|
||||||
|
test("currentProp reading", function() {
|
||||||
|
var DummyModel = Ember.Object.extend({});
|
||||||
|
DummyModel.reopenClass(Discourse.Singleton);
|
||||||
|
var current = DummyModel.current();
|
||||||
|
|
||||||
|
blank(DummyModel.currentProp('evil'), 'by default attributes are blank');
|
||||||
|
current.set('evil', 'trout');
|
||||||
|
equal(DummyModel.currentProp('evil'), 'trout', 'after changing the instance, the value is set');
|
||||||
|
});
|
||||||
|
|
||||||
|
test("currentProp writing", function() {
|
||||||
|
var DummyModel = Ember.Object.extend({});
|
||||||
|
DummyModel.reopenClass(Discourse.Singleton);
|
||||||
|
|
||||||
|
blank(DummyModel.currentProp('adventure'), 'by default attributes are blank');
|
||||||
|
var result = DummyModel.currentProp('adventure', 'time');
|
||||||
|
equal(result, 'time', 'it returns the new value');
|
||||||
|
equal(DummyModel.currentProp('adventure'), 'time', 'after calling currentProp the value is set');
|
||||||
|
|
||||||
|
DummyModel.currentProp('count', 0);
|
||||||
|
equal(DummyModel.currentProp('count'), 0, 'we can set the value to 0');
|
||||||
|
|
||||||
|
DummyModel.currentProp('adventure', null);
|
||||||
|
equal(DummyModel.currentProp('adventure'), null, 'we can set the value to null');
|
||||||
|
});
|
@ -1,25 +1,6 @@
|
|||||||
module("Discourse.Session");
|
module("Discourse.Session");
|
||||||
|
|
||||||
test('current', function(){
|
|
||||||
var session = Discourse.Session.current();
|
|
||||||
|
|
||||||
present(session, "We have a current site session");
|
|
||||||
equal(session, Discourse.Session.current(), "Calling it a second time returns the same instance");
|
|
||||||
|
|
||||||
blank(Discourse.Session.current('orange'), "by default properties are nil");
|
|
||||||
session.set('orange', 'newBlack');
|
|
||||||
equal(Discourse.Session.current('orange'), "newBlack", "it remembers values");
|
|
||||||
|
|
||||||
Discourse.Session.current('orange', 'juice');
|
|
||||||
equal(session.get('orange'), "juice", "it can be updated");
|
|
||||||
|
|
||||||
Discourse.Session.current('zero', 0);
|
|
||||||
equal(session.get('zero'), 0);
|
|
||||||
});
|
|
||||||
|
|
||||||
test('highestSeenByTopic', function() {
|
test('highestSeenByTopic', function() {
|
||||||
|
|
||||||
var session = Discourse.Session.current();
|
var session = Discourse.Session.current();
|
||||||
deepEqual(session.get('highestSeenByTopic'), {}, "by default it returns an empty object");
|
deepEqual(session.get('highestSeenByTopic'), {}, "by default it returns an empty object");
|
||||||
|
|
||||||
});
|
});
|
Loading…
Reference in New Issue
Block a user