UX: improve messaging so notifications list is far more stable PERF: improve performance of notifcation lookup queries - Add feature "SetTransientHeader" that allows shipping info to server in the next Ajax request - remove local storage hack used for notifications - amend lookupStale to return hydrated objects, move logic into store - stop magically clearing various notifications (likes, invitee accepted, group_summary, granted badge)
134 lines
3.7 KiB
JavaScript
134 lines
3.7 KiB
JavaScript
/**
|
|
This mixin provides an 'ajax' method that can be used to perform ajax requests that
|
|
respect Discourse paths and the run loop.
|
|
**/
|
|
var _trackView = false;
|
|
var _transientHeader = null;
|
|
|
|
Discourse.Ajax = Em.Mixin.create({
|
|
|
|
setTransientHeader: function(k, v) {
|
|
_transientHeader = {key: k, value: v};
|
|
},
|
|
|
|
viewTrackingRequired: function() {
|
|
_trackView = true;
|
|
},
|
|
|
|
/**
|
|
Our own $.ajax method. Makes sure the .then method executes in an Ember runloop
|
|
for performance reasons. Also automatically adjusts the URL to support installs
|
|
in subfolders.
|
|
|
|
@method ajax
|
|
**/
|
|
ajax: function() {
|
|
var url, args;
|
|
var ajax;
|
|
|
|
if (arguments.length === 1) {
|
|
if (typeof arguments[0] === "string") {
|
|
url = arguments[0];
|
|
args = {};
|
|
} else {
|
|
args = arguments[0];
|
|
url = args.url;
|
|
delete args.url;
|
|
}
|
|
} else if (arguments.length === 2) {
|
|
url = arguments[0];
|
|
args = arguments[1];
|
|
}
|
|
|
|
if (args.success || args.error) {
|
|
throw "Discourse.ajax should use promises";
|
|
}
|
|
|
|
var performAjax = function(resolve, reject) {
|
|
|
|
args.headers = args.headers || {};
|
|
|
|
if (_transientHeader) {
|
|
args.headers[_transientHeader.key] = _transientHeader.value;
|
|
_transientHeader = null;
|
|
}
|
|
|
|
if (_trackView && (!args.type || args.type === "GET")) {
|
|
_trackView = false;
|
|
// DON'T CHANGE: rack is prepending "HTTP_" in the header's name
|
|
args.headers['Discourse-Track-View'] = "true";
|
|
}
|
|
|
|
args.success = function(data, textStatus, xhr) {
|
|
if (xhr.getResponseHeader('Discourse-Readonly')) {
|
|
Ember.run(function() {
|
|
Discourse.Site.currentProp('isReadOnly', true);
|
|
});
|
|
}
|
|
|
|
Ember.run(null, resolve, data);
|
|
};
|
|
|
|
args.error = function(xhr, textStatus, errorThrown) {
|
|
// note: for bad CSRF we don't loop an extra request right away.
|
|
// this allows us to eliminate the possibility of having a loop.
|
|
if (xhr.status === 403 && xhr.responseText === "['BAD CSRF']") {
|
|
Discourse.Session.current().set('csrfToken', null);
|
|
}
|
|
|
|
// If it's a parsererror, don't reject
|
|
if (xhr.status === 200) return args.success(xhr);
|
|
|
|
// Fill in some extra info
|
|
xhr.jqTextStatus = textStatus;
|
|
xhr.requestedUrl = url;
|
|
|
|
Ember.run(null, reject, {
|
|
jqXHR: xhr,
|
|
textStatus: textStatus,
|
|
errorThrown: errorThrown
|
|
});
|
|
};
|
|
|
|
// We default to JSON on GET. If we don't, sometimes if the server doesn't return the proper header
|
|
// it will not be parsed as an object.
|
|
if (!args.type) args.type = 'GET';
|
|
if (!args.dataType && args.type.toUpperCase() === 'GET') args.dataType = 'json';
|
|
|
|
if (args.dataType === "script") {
|
|
args.headers['Discourse-Script'] = true;
|
|
}
|
|
|
|
if (args.type === 'GET' && args.cache !== true) {
|
|
args.cache = false;
|
|
}
|
|
|
|
ajax = $.ajax(Discourse.getURL(url), args);
|
|
};
|
|
|
|
var promise;
|
|
|
|
// For cached pages we strip out CSRF tokens, need to round trip to server prior to sending the
|
|
// request (bypass for GET, not needed)
|
|
if(args.type && args.type.toUpperCase() !== 'GET' && !Discourse.Session.currentProp('csrfToken')){
|
|
promise = new Ember.RSVP.Promise(function(resolve, reject){
|
|
ajax = $.ajax(Discourse.getURL('/session/csrf'), {cache: false})
|
|
.success(function(result){
|
|
Discourse.Session.currentProp('csrfToken', result.csrf);
|
|
performAjax(resolve, reject);
|
|
});
|
|
});
|
|
} else {
|
|
promise = new Ember.RSVP.Promise(performAjax);
|
|
}
|
|
|
|
promise.abort = function(){
|
|
if (ajax) {
|
|
ajax.abort();
|
|
}
|
|
};
|
|
|
|
return promise;
|
|
}
|
|
|
|
});
|