Skip to content

Commit ad082ce

Browse files
committed
Big commit:
- Support for a popup that shows similar topics - Cleaned up a lot of Javascript - Cleaned up use of Promises
1 parent 7714e20 commit ad082ce

39 files changed

Lines changed: 580 additions & 556 deletions

Gemfile.lock

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -456,7 +456,7 @@ GEM
456456
turbo-sprockets-rails3 (0.3.6)
457457
railties (> 3.2.8, < 4.0.0)
458458
sprockets (>= 2.0.0)
459-
tzinfo (0.3.35)
459+
tzinfo (0.3.37)
460460
uglifier (1.3.0)
461461
execjs (>= 0.3.0)
462462
multi_json (~> 1.0, >= 1.0.2)

app/assets/javascripts/admin/models/admin_user.js

Lines changed: 3 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -156,15 +156,9 @@ Discourse.AdminUser.reopenClass({
156156
},
157157

158158
find: function(username) {
159-
var promise;
160-
promise = new RSVP.Promise();
161-
$.ajax({
162-
url: "/admin/users/" + username,
163-
success: function(result) {
164-
return promise.resolve(Discourse.AdminUser.create(result));
165-
}
166-
});
167-
return promise;
159+
return $.ajax({url: "/admin/users/" + username}).then(function (result) {
160+
return Discourse.AdminUser.create(result);
161+
})
168162
},
169163

170164
findAll: function(query, filter) {

app/assets/javascripts/admin/models/flagged_post.js

Lines changed: 3 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -46,47 +46,15 @@ Discourse.FlaggedPost = Discourse.Post.extend({
4646
}).property('topic_hidden'),
4747

4848
deletePost: function() {
49-
var promise;
50-
promise = new RSVP.Promise();
5149
if (this.get('post_number') === "1") {
52-
return $.ajax("/t/" + this.topic_id, {
53-
type: 'DELETE',
54-
cache: false,
55-
success: function() {
56-
promise.resolve();
57-
},
58-
error: function(e) {
59-
promise.reject();
60-
}
61-
});
50+
return $.ajax("/t/" + this.topic_id, { type: 'DELETE', cache: false });
6251
} else {
63-
return $.ajax("/posts/" + this.id, {
64-
type: 'DELETE',
65-
cache: false,
66-
success: function() {
67-
promise.resolve();
68-
},
69-
error: function(e) {
70-
promise.reject();
71-
}
72-
});
52+
return $.ajax("/posts/" + this.id, { type: 'DELETE', cache: false });
7353
}
7454
},
7555

7656
clearFlags: function() {
77-
var promise;
78-
promise = new RSVP.Promise();
79-
$.ajax("/admin/flags/clear/" + this.id, {
80-
type: 'POST',
81-
cache: false,
82-
success: function() {
83-
promise.resolve();
84-
},
85-
error: function(e) {
86-
promise.reject();
87-
}
88-
});
89-
return promise;
57+
return $.ajax("/admin/flags/clear/" + this.id, { type: 'POST', cache: false });
9058
},
9159

9260
hiddenClass: (function() {

app/assets/javascripts/admin/models/version_check.js

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -26,14 +26,8 @@ Discourse.VersionCheck = Discourse.Model.extend({
2626

2727
Discourse.VersionCheck.reopenClass({
2828
find: function() {
29-
var promise = new RSVP.Promise();
30-
$.ajax({
31-
url: '/admin/version_check',
32-
dataType: 'json',
33-
success: function(json) {
34-
promise.resolve(Discourse.VersionCheck.create(json));
35-
}
29+
return $.ajax({ url: '/admin/version_check', dataType: 'json' }).then(function(json) {
30+
return Discourse.VersionCheck.create(json);
3631
});
37-
return promise;
3832
}
3933
});

app/assets/javascripts/discourse/controllers/composer_controller.js

Lines changed: 88 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -8,22 +8,20 @@
88
**/
99
Discourse.ComposerController = Discourse.Controller.extend({
1010
needs: ['modal', 'topic'],
11-
hasReply: false,
1211

1312
togglePreview: function() {
14-
return this.get('content').togglePreview();
13+
this.get('content').togglePreview();
1514
},
1615

1716
// Import a quote from the post
1817
importQuote: function() {
19-
return this.get('content').importQuote();
18+
this.get('content').importQuote();
2019
},
2120

2221
appendText: function(text) {
23-
var c;
24-
c = this.get('content');
22+
var c = this.get('content');
2523
if (c) {
26-
return c.appendText(text);
24+
c.appendText(text);
2725
}
2826
},
2927

@@ -72,11 +70,10 @@ Discourse.ComposerController = Discourse.Controller.extend({
7270
}
7371

7472
bootbox.dialog(message, buttons);
75-
7673
return;
7774
}
7875
}
79-
76+
8077
return composer.save({
8178
imageSizes: this.get('view').imageSizes()
8279
}).then(function(opts) {
@@ -94,17 +91,80 @@ Discourse.ComposerController = Discourse.Controller.extend({
9491
});
9592
},
9693

97-
checkReplyLength: function() {
98-
if (this.present('content.reply')) {
99-
this.set('hasReply', true);
100-
} else {
101-
this.set('hasReply', false);
94+
closeEducation: function() {
95+
this.set('educationClosed', true);
96+
},
97+
98+
closeSimilar: function() {
99+
this.set('similarClosed', true);
100+
},
101+
102+
similarVisible: function() {
103+
if (this.get('similarClosed')) return false;
104+
if (this.get('content.composeState') !== Discourse.Composer.OPEN) return false;
105+
return (this.get('similarTopics.length') || 0) > 0;
106+
}.property('similarTopics.length', 'similarClosed', 'content.composeState'),
107+
108+
newUserEducationVisible: function() {
109+
if (!this.get('educationContents')) return false;
110+
if (this.get('content.composeState') !== Discourse.Composer.OPEN) return false;
111+
if (!this.present('content.reply')) return false;
112+
if (this.get('educationClosed')) return false;
113+
return true;
114+
}.property('content.composeState', 'content.reply', 'educationClosed', 'educationContents'),
115+
116+
fetchNewUserEducation: function() {
117+
// If creating a topic, use topic_count, otherwise post_count
118+
var count = this.get('content.creatingTopic') ? Discourse.get('currentUser.topic_count') : Discourse.get('currentUser.reply_count');
119+
if (count >= Discourse.SiteSettings.educate_until_posts) {
120+
this.set('educationClosed', true);
121+
this.set('educationContents', '');
122+
return;
102123
}
124+
125+
// The user must have typed a reply
126+
if (!this.get('typedReply')) return;
127+
128+
this.set('educationClosed', false);
129+
130+
// If visible update the text
131+
var educationKey = this.get('content.creatingTopic') ? 'new-topic' : 'new-reply';
132+
var composerController = this;
133+
$.get("/education/" + educationKey).then(function(result) {
134+
composerController.set('educationContents', result);
135+
});
136+
}.observes('typedReply', 'content.creatingTopic', 'Discourse.currentUser.reply_count'),
137+
138+
checkReplyLength: function() {
139+
this.set('typedReply', this.present('content.reply'));
140+
},
141+
142+
/**
143+
Fired after a user stops typing. Considers whether to check for similar
144+
topics based on the current composer state.
145+
146+
@method findSimilarTopics
147+
**/
148+
findSimilarTopics: function() {
149+
150+
// We don't care about similar topics unless creating a topic
151+
if (!this.get('content.creatingTopic')) return;
152+
153+
var body = this.get('content.reply');
154+
var title = this.get('content.title');
155+
156+
// Ensure the fields are of the minimum length
157+
if (body.length < Discourse.SiteSettings.min_body_similar_length) return;
158+
if (title.length < Discourse.SiteSettings.min_title_similar_length) return;
159+
160+
var composerController = this;
161+
Discourse.Topic.findSimilarTo(title, body).then(function (topics) {
162+
composerController.set('similarTopics', topics);
163+
});
103164
},
104165

105166
saveDraft: function() {
106-
var model;
107-
model = this.get('content');
167+
var model = this.get('content');
108168
if (model) model.saveDraft();
109169
},
110170

@@ -123,8 +183,11 @@ Discourse.ComposerController = Discourse.Controller.extend({
123183
_this = this;
124184
if (!opts) opts = {};
125185

126-
opts.promise = promise = opts.promise || new RSVP.Promise();
127-
this.set('hasReply', false);
186+
opts.promise = promise = opts.promise || Ember.Deferred.create();
187+
this.set('typedReply', false);
188+
this.set('similarTopics', null);
189+
this.set('similarClosed', false);
190+
128191
if (!opts.draftKey) {
129192
alert("composer was opened without a draft key");
130193
throw "composer opened without a proper draft key";
@@ -133,9 +196,7 @@ Discourse.ComposerController = Discourse.Controller.extend({
133196
// ensure we have a view now, without it transitions are going to be messed
134197
view = this.get('view');
135198
if (!view) {
136-
view = Discourse.ComposerView.create({
137-
controller: this
138-
});
199+
view = Discourse.ComposerView.create({ controller: this });
139200
view.appendTo($('#main'));
140201
this.set('view', view);
141202
// the next runloop is too soon, need to get the control rendered and then
@@ -197,8 +258,7 @@ Discourse.ComposerController = Discourse.Controller.extend({
197258
},
198259

199260
wouldLoseChanges: function() {
200-
var composer;
201-
composer = this.get('content');
261+
var composer = this.get('content');
202262
return composer && composer.wouldLoseChanges();
203263
},
204264

@@ -210,10 +270,9 @@ Discourse.ComposerController = Discourse.Controller.extend({
210270
},
211271

212272
destroyDraft: function() {
213-
var key;
214-
key = this.get('content.draftKey');
273+
var key = this.get('content.draftKey');
215274
if (key) {
216-
return Discourse.Draft.clear(key, this.get('content.draftSequence'));
275+
Discourse.Draft.clear(key, this.get('content.draftSequence'));
217276
}
218277
},
219278

@@ -243,17 +302,17 @@ Discourse.ComposerController = Discourse.Controller.extend({
243302
}
244303
},
245304

246-
click: function() {
305+
openIfDraft: function() {
247306
if (this.get('content.composeState') === Discourse.Composer.DRAFT) {
248-
return this.set('content.composeState', Discourse.Composer.OPEN);
307+
this.set('content.composeState', Discourse.Composer.OPEN);
249308
}
250309
},
251310

252311
shrink: function() {
253312
if (this.get('content.reply') === this.get('content.originalText')) {
254-
return this.close();
313+
this.close();
255314
} else {
256-
return this.collapse();
315+
this.collapse();
257316
}
258317
},
259318

app/assets/javascripts/discourse/controllers/list_controller.js

Lines changed: 10 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -42,27 +42,23 @@ Discourse.ListController = Discourse.Controller.extend({
4242
this.set('loading', true);
4343

4444
if (filterMode === 'categories') {
45-
return Ember.Deferred.promise(function(deferred) {
46-
Discourse.CategoryList.list(filterMode).then(function(items) {
47-
listController.set('loading', false);
48-
listController.set('filterMode', filterMode);
49-
listController.set('categoryMode', true);
50-
return deferred.resolve(items);
51-
});
45+
return Discourse.CategoryList.list(filterMode).then(function(items) {
46+
listController.set('loading', false);
47+
listController.set('filterMode', filterMode);
48+
listController.set('categoryMode', true);
49+
return items;
5250
});
5351
}
5452

5553
var current = (this.get('availableNavItems').filter(function(f) { return f.name === filterMode; }))[0];
5654
if (!current) {
5755
current = Discourse.NavItem.create({ name: filterMode });
5856
}
59-
return Ember.Deferred.promise(function(deferred) {
60-
Discourse.TopicList.list(current).then(function(items) {
61-
listController.set('filterSummary', items.filter_summary);
62-
listController.set('filterMode', filterMode);
63-
listController.set('loading', false);
64-
return deferred.resolve(items);
65-
});
57+
return Discourse.TopicList.list(current).then(function(items) {
58+
listController.set('filterSummary', items.filter_summary);
59+
listController.set('filterMode', filterMode);
60+
listController.set('loading', false);
61+
return items;
6662
});
6763
},
6864

app/assets/javascripts/discourse/controllers/topic_controller.js

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -117,19 +117,18 @@ Discourse.TopicController = Discourse.ObjectController.extend({
117117
},
118118

119119
replyAsNewTopic: function(post) {
120-
var composerController, postLink, postUrl, promise;
121-
composerController = this.get('controllers.composer');
122-
123120
// TODO shut down topic draft cleanly if it exists ...
124-
promise = composerController.open({
121+
var composerController = this.get('controllers.composer');
122+
var promise = composerController.open({
125123
action: Discourse.Composer.CREATE_TOPIC,
126124
draftKey: Discourse.Composer.REPLY_AS_NEW_TOPIC_KEY
127125
});
128-
postUrl = "" + location.protocol + "//" + location.host + (post.get('url'));
129-
postLink = "[" + (this.get('title')) + "](" + postUrl + ")";
130-
return promise.then(function() {
131-
return Discourse.Post.loadQuote(post.get('id')).then(function(q) {
132-
return composerController.appendText("" + (Em.String.i18n("post.continue_discussion", {
126+
var postUrl = "" + location.protocol + "//" + location.host + (post.get('url'));
127+
var postLink = "[" + (this.get('title')) + "](" + postUrl + ")";
128+
129+
promise.then(function() {
130+
Discourse.Post.loadQuote(post.get('id')).then(function(q) {
131+
composerController.appendText("" + (Em.String.i18n("post.continue_discussion", {
133132
postLink: postLink
134133
})) + "\n\n" + q);
135134
});

0 commit comments

Comments
 (0)