mirror of
https://github.com/discourse/discourse.git
synced 2025-02-08 20:34:52 +00:00
Better error messages when topics can't load
This commit is contained in:
parent
d9d3419a51
commit
397c6ca761
@ -142,18 +142,15 @@ Discourse.Topic = Discourse.Model.extend({
|
|||||||
},
|
},
|
||||||
|
|
||||||
toggleStar: function() {
|
toggleStar: function() {
|
||||||
var _this = this;
|
var topic = this;
|
||||||
this.toggleProperty('starred');
|
topic.toggleProperty('starred');
|
||||||
return jQuery.ajax({
|
return jQuery.ajax({
|
||||||
url: "" + (this.get('url')) + "/star",
|
url: "" + (this.get('url')) + "/star",
|
||||||
type: 'PUT',
|
type: 'PUT',
|
||||||
data: {
|
data: { starred: topic.get('starred') ? true : false },
|
||||||
starred: this.get('starred') ? true : false
|
|
||||||
},
|
|
||||||
error: function(error) {
|
error: function(error) {
|
||||||
var errors;
|
topic.toggleProperty('starred');
|
||||||
_this.toggleProperty('starred');
|
var errors = jQuery.parseJSON(error.responseText).errors;
|
||||||
errors = jQuery.parseJSON(error.responseText).errors;
|
|
||||||
return bootbox.alert(errors[0]);
|
return bootbox.alert(errors[0]);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -203,31 +200,22 @@ Discourse.Topic = Discourse.Model.extend({
|
|||||||
|
|
||||||
// Load the posts for this topic
|
// Load the posts for this topic
|
||||||
loadPosts: function(opts) {
|
loadPosts: function(opts) {
|
||||||
var _this = this;
|
var topic = this;
|
||||||
if (!opts) {
|
|
||||||
opts = {};
|
if (!opts) opts = {};
|
||||||
}
|
|
||||||
|
|
||||||
// Load the first post by default
|
// Load the first post by default
|
||||||
if (!opts.bestOf) {
|
if ((!opts.bestOf) && (!opts.nearPost)) opts.nearPost = 1;
|
||||||
if (!opts.nearPost) opts.nearPost = 1
|
|
||||||
}
|
|
||||||
|
|
||||||
// If we already have that post in the DOM, jump to it
|
// If we already have that post in the DOM, jump to it
|
||||||
if (Discourse.TopicView.scrollTo(this.get('id'), opts.nearPost)) return;
|
if (Discourse.TopicView.scrollTo(this.get('id'), opts.nearPost)) return;
|
||||||
|
|
||||||
return Discourse.Topic.find(this.get('id'), {
|
// If loading the topic succeeded...
|
||||||
nearPost: opts.nearPost,
|
var afterTopicLoaded = function(result) {
|
||||||
bestOf: opts.bestOf,
|
|
||||||
trackVisit: opts.trackVisit
|
|
||||||
}).then(function(result) {
|
|
||||||
|
|
||||||
// If loading the topic succeeded...
|
|
||||||
// Update the slug if different
|
|
||||||
var closestPostNumber, lastPost, postDiff;
|
var closestPostNumber, lastPost, postDiff;
|
||||||
if (result.slug) {
|
|
||||||
_this.set('slug', result.slug);
|
// Update the slug if different
|
||||||
}
|
if (result.slug) topic.set('slug', result.slug);
|
||||||
|
|
||||||
// If we want to scroll to a post that doesn't exist, just pop them to the closest
|
// If we want to scroll to a post that doesn't exist, just pop them to the closest
|
||||||
// one instead. This is likely happening due to a deleted post.
|
// one instead. This is likely happening due to a deleted post.
|
||||||
@ -235,34 +223,29 @@ Discourse.Topic = Discourse.Model.extend({
|
|||||||
closestPostNumber = 0;
|
closestPostNumber = 0;
|
||||||
postDiff = Number.MAX_VALUE;
|
postDiff = Number.MAX_VALUE;
|
||||||
result.posts.each(function(p) {
|
result.posts.each(function(p) {
|
||||||
var diff;
|
var diff = Math.abs(p.post_number - opts.nearPost);
|
||||||
diff = Math.abs(p.post_number - opts.nearPost);
|
|
||||||
if (diff < postDiff) {
|
if (diff < postDiff) {
|
||||||
postDiff = diff;
|
postDiff = diff;
|
||||||
closestPostNumber = p.post_number;
|
closestPostNumber = p.post_number;
|
||||||
if (diff === 0) {
|
if (diff === 0) return false;
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
opts.nearPost = closestPostNumber;
|
opts.nearPost = closestPostNumber;
|
||||||
if (_this.get('participants')) {
|
if (topic.get('participants')) {
|
||||||
_this.get('participants').clear();
|
topic.get('participants').clear();
|
||||||
}
|
}
|
||||||
if (result.suggested_topics) {
|
if (result.suggested_topics) {
|
||||||
_this.set('suggested_topics', Em.A());
|
topic.set('suggested_topics', Em.A());
|
||||||
}
|
}
|
||||||
_this.mergeAttributes(result, {
|
topic.mergeAttributes(result, { suggested_topics: Discourse.Topic });
|
||||||
suggested_topics: Discourse.Topic
|
topic.set('posts', Em.A());
|
||||||
});
|
|
||||||
_this.set('posts', Em.A());
|
|
||||||
if (opts.trackVisit && result.draft && result.draft.length > 0) {
|
if (opts.trackVisit && result.draft && result.draft.length > 0) {
|
||||||
Discourse.openComposer({
|
Discourse.openComposer({
|
||||||
draft: Discourse.Draft.getLocal(result.draft_key, result.draft),
|
draft: Discourse.Draft.getLocal(result.draft_key, result.draft),
|
||||||
draftKey: result.draft_key,
|
draftKey: result.draft_key,
|
||||||
draftSequence: result.draft_sequence,
|
draftSequence: result.draft_sequence,
|
||||||
topic: _this,
|
topic: topic,
|
||||||
ignoreIfChanged: true
|
ignoreIfChanged: true
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -273,15 +256,41 @@ Discourse.Topic = Discourse.Model.extend({
|
|||||||
var post;
|
var post;
|
||||||
p.scrollToAfterInsert = opts.nearPost;
|
p.scrollToAfterInsert = opts.nearPost;
|
||||||
post = Discourse.Post.create(p);
|
post = Discourse.Post.create(p);
|
||||||
post.set('topic', _this);
|
post.set('topic', topic);
|
||||||
_this.get('posts').pushObject(post);
|
topic.get('posts').pushObject(post);
|
||||||
lastPost = post;
|
lastPost = post;
|
||||||
});
|
});
|
||||||
return _this.set('loaded', true);
|
topic.set('loaded', true);
|
||||||
}, function(result) {
|
}
|
||||||
_this.set('missing', true);
|
|
||||||
return _this.set('message', Em.String.i18n('topic.not_found.description'));
|
var errorLoadingTopic = function(result) {
|
||||||
});
|
topic.set('errorLoading', true);
|
||||||
|
|
||||||
|
// If the result was 404 the post is not found
|
||||||
|
if (result.status == 404) {
|
||||||
|
topic.set('errorTitle', Em.String.i18n('topic.not_found.title'))
|
||||||
|
topic.set('message', Em.String.i18n('topic.not_found.description'));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// If the result is 403 it means invalid access
|
||||||
|
if (result.status == 403) {
|
||||||
|
topic.set('errorTitle', Em.String.i18n('topic.invalid_access.title'))
|
||||||
|
topic.set('message', Em.String.i18n('topic.invalid_access.description'));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Otherwise supply a generic error message
|
||||||
|
topic.set('errorTitle', Em.String.i18n('topic.server_error.title'))
|
||||||
|
topic.set('message', Em.String.i18n('topic.server_error.description'));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Finally, call our find method
|
||||||
|
Discourse.Topic.find(this.get('id'), {
|
||||||
|
nearPost: opts.nearPost,
|
||||||
|
bestOf: opts.bestOf,
|
||||||
|
trackVisit: opts.trackVisit
|
||||||
|
}).then(afterTopicLoaded, errorLoadingTopic);
|
||||||
},
|
},
|
||||||
|
|
||||||
notificationReasonText: (function() {
|
notificationReasonText: (function() {
|
||||||
@ -324,10 +333,10 @@ Discourse.Topic = Discourse.Model.extend({
|
|||||||
isReplyDirectlyBelow: function(post) {
|
isReplyDirectlyBelow: function(post) {
|
||||||
var postBelow, posts;
|
var postBelow, posts;
|
||||||
posts = this.get('posts');
|
posts = this.get('posts');
|
||||||
if (!posts) {
|
if (!posts) return;
|
||||||
return;
|
|
||||||
}
|
|
||||||
postBelow = posts[posts.indexOf(post) + 1];
|
postBelow = posts[posts.indexOf(post) + 1];
|
||||||
|
|
||||||
// If the post directly below's reply_to_post_number is our post number, it's
|
// If the post directly below's reply_to_post_number is our post number, it's
|
||||||
// considered directly below.
|
// considered directly below.
|
||||||
return (postBelow ? postBelow.get('reply_to_post_number') : void 0) === post.get('post_number');
|
return (postBelow ? postBelow.get('reply_to_post_number') : void 0) === post.get('post_number');
|
||||||
@ -346,12 +355,13 @@ window.Discourse.Topic.reopenClass({
|
|||||||
// options:
|
// options:
|
||||||
// onLoad - the callback after the topic is loaded
|
// onLoad - the callback after the topic is loaded
|
||||||
find: function(topicId, opts) {
|
find: function(topicId, opts) {
|
||||||
var data, promise, url,
|
var data, promise, url;
|
||||||
_this = this;
|
|
||||||
url = "/t/" + topicId;
|
url = "/t/" + topicId;
|
||||||
|
|
||||||
if (opts.nearPost) {
|
if (opts.nearPost) {
|
||||||
url += "/" + opts.nearPost;
|
url += "/" + opts.nearPost;
|
||||||
}
|
}
|
||||||
|
|
||||||
data = {};
|
data = {};
|
||||||
if (opts.postsAfter) {
|
if (opts.postsAfter) {
|
||||||
data.posts_after = opts.postsAfter;
|
data.posts_after = opts.postsAfter;
|
||||||
@ -397,15 +407,11 @@ window.Discourse.Topic.reopenClass({
|
|||||||
movePosts: function(topicId, title, postIds) {
|
movePosts: function(topicId, title, postIds) {
|
||||||
return jQuery.ajax("/t/" + topicId + "/move-posts", {
|
return jQuery.ajax("/t/" + topicId + "/move-posts", {
|
||||||
type: 'POST',
|
type: 'POST',
|
||||||
data: {
|
data: { title: title, post_ids: postIds }
|
||||||
title: title,
|
|
||||||
post_ids: postIds
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
create: function(obj, topicView) {
|
create: function(obj, topicView) {
|
||||||
var _this = this;
|
|
||||||
return Object.tap(this._super(obj), function(result) {
|
return Object.tap(this._super(obj), function(result) {
|
||||||
if (result.participants) {
|
if (result.participants) {
|
||||||
result.participants = result.participants.map(function(u) {
|
result.participants = result.participants.map(function(u) {
|
||||||
@ -413,9 +419,7 @@ window.Discourse.Topic.reopenClass({
|
|||||||
});
|
});
|
||||||
result.fewParticipants = Em.A();
|
result.fewParticipants = Em.A();
|
||||||
return result.participants.each(function(p) {
|
return result.participants.each(function(p) {
|
||||||
if (result.fewParticipants.length >= 8) {
|
if (result.fewParticipants.length >= 8) return false;
|
||||||
return false;
|
|
||||||
}
|
|
||||||
result.fewParticipants.pushObject(p);
|
result.fewParticipants.pushObject(p);
|
||||||
return true;
|
return true;
|
||||||
});
|
});
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
{{#if view.showFavoriteButton}}
|
{{#if view.showFavoriteButton}}
|
||||||
<a {{bindAttr class=":star view.topic.starred:starred"}} {{action toggleStar target="controller"}} href='#' title="{{i18n favorite.help}}"></a>
|
<a {{bindAttr class=":star view.topic.starred:starred"}} {{action toggleStar target="controller"}} href='#' title="{{i18n favorite.help}}"></a>
|
||||||
{{/if}}
|
{{/if}}
|
||||||
{{#if view.editingTopic}}
|
{{#if view.editingTopic}}
|
||||||
<input id='edit-title' type='text' {{bindAttr value="view.topic.title"}}>
|
<input id='edit-title' type='text' {{bindAttr value="view.topic.title"}}>
|
||||||
{{view Discourse.ComboboxViewCategory valueAttribute="name" contentBinding="view.categories" valueBinding="view.topic.categoryName"}}
|
{{view Discourse.ComboboxViewCategory valueAttribute="name" contentBinding="view.categories" valueBinding="view.topic.categoryName"}}
|
||||||
<button class='btn btn-primary btn-small' {{action finishedEdit target="view"}}><i class='icon-ok'></i></button>
|
<button class='btn btn-primary btn-small' {{action finishedEdit target="view"}}><i class='icon-ok'></i></button>
|
||||||
@ -19,8 +19,8 @@
|
|||||||
{{view Discourse.TopicStatusView topicBinding="view.topic"}}
|
{{view Discourse.TopicStatusView topicBinding="view.topic"}}
|
||||||
<a href='{{unbound view.topic.url}}'>{{{unbound view.topic.fancy_title}}}</a>
|
<a href='{{unbound view.topic.url}}'>{{{unbound view.topic.fancy_title}}}</a>
|
||||||
{{else}}
|
{{else}}
|
||||||
{{#if view.topic.missing}}
|
{{#if view.topic.errorLoading}}
|
||||||
{{i18n topic.not_found.title}}
|
{{view.topic.errorTitle}}
|
||||||
{{else}}
|
{{else}}
|
||||||
{{i18n topic.loading}}
|
{{i18n topic.loading}}
|
||||||
{{/if}}
|
{{/if}}
|
||||||
@ -33,7 +33,7 @@
|
|||||||
</h1>
|
</h1>
|
||||||
{{/if}}
|
{{/if}}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{{/if}}
|
{{/if}}
|
||||||
|
|
||||||
@ -102,7 +102,7 @@
|
|||||||
{{/if}}
|
{{/if}}
|
||||||
|
|
||||||
|
|
||||||
</section>
|
</section>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
@ -7,8 +7,8 @@
|
|||||||
{{view Discourse.TopicStatusView topicBinding="view.topic"}}
|
{{view Discourse.TopicStatusView topicBinding="view.topic"}}
|
||||||
<a class='topic-link' href='{{unbound view.topic.url}}'>{{{view.topic.fancy_title}}}</a>
|
<a class='topic-link' href='{{unbound view.topic.url}}'>{{{view.topic.fancy_title}}}</a>
|
||||||
{{else}}
|
{{else}}
|
||||||
{{#if view.topic.missing}}
|
{{#if view.topic.errorLoading}}
|
||||||
{{i18n topic.not_found.title}}
|
{{topic.errorTitle}}
|
||||||
{{else}}
|
{{else}}
|
||||||
{{i18n topic.loading}}
|
{{i18n topic.loading}}
|
||||||
{{/if}}
|
{{/if}}
|
||||||
|
@ -129,12 +129,12 @@ class TopicsController < ApplicationController
|
|||||||
end
|
end
|
||||||
|
|
||||||
def timings
|
def timings
|
||||||
|
|
||||||
PostTiming.process_timings(
|
PostTiming.process_timings(
|
||||||
current_user,
|
current_user,
|
||||||
params[:topic_id].to_i,
|
params[:topic_id].to_i,
|
||||||
params[:highest_seen].to_i,
|
params[:highest_seen].to_i,
|
||||||
params[:topic_time].to_i,
|
params[:topic_time].to_i,
|
||||||
(params[:timings] || []).map{|post_number, t| [post_number.to_i, t.to_i]}
|
(params[:timings] || []).map{|post_number, t| [post_number.to_i, t.to_i]}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -170,7 +170,7 @@ en:
|
|||||||
|
|
||||||
filters:
|
filters:
|
||||||
all: "All"
|
all: "All"
|
||||||
|
|
||||||
stream:
|
stream:
|
||||||
posted_by: "Posted by"
|
posted_by: "Posted by"
|
||||||
sent_by: "Sent by"
|
sent_by: "Sent by"
|
||||||
@ -341,10 +341,15 @@ en:
|
|||||||
title: 'Topic'
|
title: 'Topic'
|
||||||
loading_more: "Loading more Topics..."
|
loading_more: "Loading more Topics..."
|
||||||
loading: 'Loading topic...'
|
loading: 'Loading topic...'
|
||||||
missing: "Topic Not Found"
|
invalid_access:
|
||||||
|
title: "You can't do that!"
|
||||||
|
description: "You don't have access to view that topic."
|
||||||
|
server_error:
|
||||||
|
title: "Error loading topic!"
|
||||||
|
description: "Sorry, we couldn't load that topic, possibly due to a connection problem. Please try again."
|
||||||
not_found:
|
not_found:
|
||||||
title: "Topic Not Found"
|
title: "Topic not found!"
|
||||||
description: "Sorry, we couldn't load that topic, possibly due to a connection problem. Please try again. If the problem persists, perhaps the topic was deleted."
|
description: "That topic could not be found. It's likely it was deleted by a moderator."
|
||||||
unread_posts: "you have {{unread}} unread old posts in this topic"
|
unread_posts: "you have {{unread}} unread old posts in this topic"
|
||||||
new_posts: "there are {{new_posts}} new posts in this topic since you last read it"
|
new_posts: "there are {{new_posts}} new posts in this topic since you last read it"
|
||||||
likes: "there are {{likes}} likes in this topic"
|
likes: "there are {{likes}} likes in this topic"
|
||||||
|
Loading…
x
Reference in New Issue
Block a user