mirror of
https://github.com/HabitRPG/habitica.git
synced 2025-12-17 22:57:21 +01:00
Remove localstorage and add notifications (#7588)
* move remaining files frm /common/script/public to website/public * remove localstorage * add back noscript template and put all javascript in the footer * fixes client side tests * remove double quotes where possible * simplify jade code and add tests for buildManifest * loading page with logo and spinner * better loading screen in landscape mode * icon on top of text logo * wip: user.notifications * notifications: simpler and working code * finish implementing notifications * correct loading screen css and re-inline images * add tests for user notifications * split User model in multiple files * remove old comment about missing .catch() * correctly setup hooks and methods for User model. Cleanup localstorage * include UserNotificationsService in static page js and split loading-screen css in its own file * add cron notification and misc fixes * remove console.log * fix tests * fix multiple notifications
This commit is contained in:
@@ -2,4 +2,5 @@ export const MAX_HEALTH = 50;
|
||||
export const MAX_LEVEL = 100;
|
||||
export const MAX_STAT_POINTS = MAX_LEVEL;
|
||||
export const ATTRIBUTES = ['str', 'int', 'per', 'con'];
|
||||
export const TAVERN_ID = '00000000-0000-4000-A000-000000000000';
|
||||
|
||||
export const TAVERN_ID = '00000000-0000-4000-A000-000000000000';
|
||||
@@ -12,6 +12,10 @@ module.exports = function ultimateGear (user) {
|
||||
});
|
||||
return soFarGood && (!found || owned[found.key] === true);
|
||||
}, true);
|
||||
|
||||
if (user.achievements.ultimateGearSets[klass] === true) {
|
||||
user.addNotification('ULTIMATE_GEAR_ACHIEVEMENT');
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
@@ -59,6 +59,8 @@ module.exports = function updateStats (user, stats, req = {}, analytics) {
|
||||
}
|
||||
if (!user.flags.dropsEnabled && user.stats.lvl >= 3) {
|
||||
user.flags.dropsEnabled = true;
|
||||
user.addNotification('DROPS_ENABLED');
|
||||
|
||||
if (user.items.eggs.Wolf > 0) {
|
||||
user.items.eggs.Wolf++;
|
||||
} else {
|
||||
@@ -92,6 +94,7 @@ module.exports = function updateStats (user, stats, req = {}, analytics) {
|
||||
}
|
||||
});
|
||||
if (!user.flags.rebirthEnabled && (user.stats.lvl >= 50 || user.achievements.beastMaster)) {
|
||||
user.addNotification('REBIRTH_ENABLED');
|
||||
user.flags.rebirthEnabled = true;
|
||||
}
|
||||
};
|
||||
|
||||
@@ -242,6 +242,11 @@ api.wrap = function wrapUser (user, main = true) {
|
||||
user.markModified = function noopMarkModified () {};
|
||||
}
|
||||
|
||||
// same for addNotification
|
||||
if (!user.addNotification) {
|
||||
user.addNotification = function noopAddNotification () {};
|
||||
}
|
||||
|
||||
if (main) {
|
||||
user.ops = {
|
||||
update: _.partial(importedOps.update, user),
|
||||
|
||||
@@ -48,7 +48,6 @@ import openMysteryItem from './openMysteryItem';
|
||||
import scoreTask from './scoreTask';
|
||||
import markPmsRead from './markPMSRead';
|
||||
|
||||
|
||||
module.exports = {
|
||||
update,
|
||||
sleep,
|
||||
|
||||
@@ -93,6 +93,8 @@ module.exports = function rebirth (user, tasks = [], req = {}, analytics) {
|
||||
user.achievements.rebirthLevel = lvl;
|
||||
}
|
||||
|
||||
user.addNotification('REBIRTH_ACHIEVEMENT');
|
||||
|
||||
user.stats.buffs = {};
|
||||
|
||||
if (req.v2 === true) {
|
||||
|
||||
@@ -214,7 +214,10 @@ module.exports = function scoreTask (options = {}, req = {}) {
|
||||
if (direction === 'up') {
|
||||
task.streak += 1;
|
||||
// Give a streak achievement when the streak is a multiple of 21
|
||||
if (task.streak % 21 === 0) user.achievements.streak = user.achievements.streak ? user.achievements.streak + 1 : 1;
|
||||
if (task.streak % 21 === 0) {
|
||||
user.achievements.streak = user.achievements.streak ? user.achievements.streak + 1 : 1;
|
||||
user.addNotification('STREAK_ACHIEVEMENT');
|
||||
}
|
||||
task.completed = true;
|
||||
} else if (direction === 'down') {
|
||||
// Remove a streak achievement if streak was a multiple of 21 and the daily was undone
|
||||
|
||||
@@ -1,108 +0,0 @@
|
||||
'use strict';
|
||||
|
||||
angular.module('habitrpg')
|
||||
.config(['$httpProvider', function($httpProvider){
|
||||
$httpProvider.interceptors.push(['$q', '$rootScope', function($q, $rootScope){
|
||||
var resyncNumber = 0;
|
||||
var lastResync = 0;
|
||||
|
||||
// Verify that the user was not updated from another browser/app/client
|
||||
// If it was, sync
|
||||
function verifyUserUpdated (response) {
|
||||
var isApiCall = response.config.url.indexOf('api/v3') !== -1;
|
||||
var isUserAvailable = $rootScope.User && $rootScope.User.user && $rootScope.User.user._wrapped === true;
|
||||
var hasUserV = response.data && response.data.userV;
|
||||
var isNotSync = response.config.url.indexOf('/api/v3/user') !== 0;
|
||||
|
||||
if (isApiCall && isUserAvailable && hasUserV) {
|
||||
var oldUserV = $rootScope.User.user._v;
|
||||
$rootScope.User.user._v = response.data.userV;
|
||||
|
||||
// Something has changed on the user object that was not tracked here, sync the user
|
||||
if (isNotSync && ($rootScope.User.user._v - oldUserV) > 1) {
|
||||
$rootScope.User.sync();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
request: function (config) {
|
||||
var url = config.url;
|
||||
|
||||
if (url.indexOf('api/v3') !== -1) {
|
||||
if ($rootScope.User && $rootScope.User.user) {
|
||||
if (url.indexOf('?') !== -1) {
|
||||
config.url += '&userV=' + $rootScope.User.user._v;
|
||||
} else {
|
||||
config.url += '?userV=' + $rootScope.User.user._v;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return config;
|
||||
},
|
||||
response: function(response) {
|
||||
verifyUserUpdated(response);
|
||||
return response;
|
||||
},
|
||||
responseError: function(response) {
|
||||
var mobileApp = !!window.env.appVersion;
|
||||
|
||||
// Offline
|
||||
if (response.status == 0 ||
|
||||
// don't know why we're getting 404 here, should be 0
|
||||
(response.status == 404 && _.isEmpty(response.data))) {
|
||||
|
||||
if (!mobileApp) // skip mobile, queue actions
|
||||
$rootScope.$broadcast('responseText', window.env.t('serverUnreach'));
|
||||
|
||||
// Needs refresh
|
||||
} else if (response.needRefresh) {
|
||||
if (!mobileApp) // skip mobile for now
|
||||
$rootScope.$broadcast('responseError', "The site has been updated and the page needs to refresh. The last action has not been recorded, please refresh and try again.");
|
||||
|
||||
} else if (response.data && response.data.code && response.data.code === 'ACCOUNT_SUSPENDED') {
|
||||
confirm(response.data.err);
|
||||
localStorage.clear();
|
||||
window.location.href = mobileApp ? '/app/login' : '/logout'; //location.reload()
|
||||
|
||||
// 400 range
|
||||
} else if (response.status < 400) {
|
||||
// never triggered because we're in responseError
|
||||
$rootScope.$broadcast('responseText', response.data && response.data.message);
|
||||
} else if (response.status < 500) {
|
||||
if (response.status === 400 && response.data && response.data.errors && _.isArray(response.data.errors)) { // bad requests with more info
|
||||
response.data.errors.forEach(function (err) {
|
||||
$rootScope.$broadcast('responseError', err.message);
|
||||
});
|
||||
} else {
|
||||
$rootScope.$broadcast('responseError', response.data && response.data.message);
|
||||
}
|
||||
|
||||
if ($rootScope.User && $rootScope.User.sync) {
|
||||
if (resyncNumber < 100 && (Date.now() - lastResync) > 500) { // avoid thousands of requests when user is not found
|
||||
$rootScope.User.sync();
|
||||
resyncNumber++;
|
||||
lastResync = Date.now();
|
||||
}
|
||||
}
|
||||
|
||||
// Need to reject the prompse so the error is handled correctly
|
||||
if (response.status === 401) {
|
||||
return $q.reject(response);
|
||||
}
|
||||
// Error
|
||||
} else {
|
||||
var error = window.env.t('requestError') + '<br><br>"' +
|
||||
window.env.t('error') + ' ' + (response.data.message || response.data.error || response.data || 'something went wrong') +
|
||||
'" <br><br>' + window.env.t('seeConsole');
|
||||
if (mobileApp) error = 'Error contacting the server. Please try again in a few minutes.';
|
||||
$rootScope.$broadcast('responseError500', error);
|
||||
console.error(response);
|
||||
}
|
||||
|
||||
return $q.reject(response);
|
||||
}
|
||||
};
|
||||
}]);
|
||||
}]);
|
||||
@@ -1,78 +0,0 @@
|
||||
'use strict';
|
||||
|
||||
/**
|
||||
* Markdown
|
||||
*/
|
||||
(function(){
|
||||
var md = function () {
|
||||
var mdown = window.habiticaMarkdown;
|
||||
|
||||
var toHtml = function (markdown) {
|
||||
if (markdown == undefined)
|
||||
return '';
|
||||
|
||||
markdown = mdown.render(markdown);
|
||||
|
||||
return markdown;
|
||||
};
|
||||
|
||||
return {
|
||||
toHtml:toHtml
|
||||
};
|
||||
}();
|
||||
|
||||
habitrpg.directive('markdown', ['$timeout', function($timeout) {
|
||||
return {
|
||||
restrict: 'E',
|
||||
link: function(scope, element, attrs) {
|
||||
var removeWatch = !!scope.$eval(attrs.removeWatch);
|
||||
var useTimeout = !!scope.$eval(attrs.useTimeout);
|
||||
var timeoutTime = scope.$eval(attrs.timeoutTime) || 0;
|
||||
|
||||
var doRemoveWatch = scope.$watch(attrs.text, function(value, oldValue) {
|
||||
var replaceMarkdown = function(){
|
||||
|
||||
var markdown = value;
|
||||
var linktarget = attrs.target || '_self';
|
||||
var userName = scope.User.user.profile.name;
|
||||
var userHighlight = "@"+userName;
|
||||
var html = md.toHtml(markdown);
|
||||
|
||||
html = html.replace(userHighlight, "<u>@"+userName+"</u>");
|
||||
|
||||
element.html(html);
|
||||
|
||||
if (removeWatch) {
|
||||
doRemoveWatch();
|
||||
}
|
||||
};
|
||||
|
||||
if(useTimeout) {
|
||||
$timeout(replaceMarkdown, timeoutTime);
|
||||
} else {
|
||||
replaceMarkdown();
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
}]);
|
||||
|
||||
habitrpg.filter('markdown', function() {
|
||||
return function(input){
|
||||
var html = md.toHtml(input);
|
||||
|
||||
return html;
|
||||
};
|
||||
});
|
||||
})()
|
||||
|
||||
habitrpg.directive('questRewards', ['$rootScope', function($rootScope){
|
||||
return {
|
||||
restrict: 'AE',
|
||||
templateUrl: 'partials/options.social.party.quest-rewards.html',
|
||||
link: function(scope, element, attrs){
|
||||
scope.header = attrs.header || 'Rewards';
|
||||
scope.quest = $rootScope.Content.quests[attrs.key];
|
||||
}
|
||||
}
|
||||
}]);
|
||||
Reference in New Issue
Block a user