Use StyleKit alerts and confirms
This commit is contained in:
@@ -86,6 +86,7 @@ module.exports = function(grunt) {
|
||||
src: [
|
||||
'node_modules/standard-file-js/dist/regenerator.js',
|
||||
'node_modules/standard-file-js/dist/sfjs.js',
|
||||
'node_modules/sn-stylekit/dist/stylekit.js',
|
||||
'node_modules/angular/angular.js',
|
||||
'vendor/assets/javascripts/angular-sanitize.js',
|
||||
'vendor/assets/javascripts/lodash/lodash.custom.min.js'
|
||||
|
||||
@@ -24,7 +24,7 @@ angular.module('app')
|
||||
})
|
||||
.controller('EditorCtrl', function ($sce, $timeout, authManager, $rootScope, actionsManager,
|
||||
syncManager, modelManager, themeManager, componentManager, storageManager, sessionHistory,
|
||||
privilegesManager, keyboardManager, desktopManager) {
|
||||
privilegesManager, keyboardManager, desktopManager, alertManager) {
|
||||
|
||||
this.spellcheck = true;
|
||||
this.componentManager = componentManager;
|
||||
@@ -278,12 +278,12 @@ angular.module('app')
|
||||
note.dummy = false;
|
||||
|
||||
if(note.deleted) {
|
||||
alert("The note you are attempting to edit has been deleted, and is awaiting sync. Changes you make will be disregarded.");
|
||||
alertManager.alert({text: "The note you are attempting to edit has been deleted, and is awaiting sync. Changes you make will be disregarded."});
|
||||
return;
|
||||
}
|
||||
|
||||
if(!modelManager.findItem(note.uuid)) {
|
||||
alert("The note you are attempting to save can not be found or has been deleted. Changes you make will not be synced. Please copy this note's text and start a new note.");
|
||||
alertManager.alert({text: "The note you are attempting to save can not be found or has been deleted. Changes you make will not be synced. Please copy this note's text and start a new note."});
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -315,7 +315,7 @@ angular.module('app')
|
||||
syncManager.sync().then((response) => {
|
||||
if(response && response.error && !this.didShowErrorAlert) {
|
||||
this.didShowErrorAlert = true;
|
||||
alert("There was an error saving your note. Please try again.");
|
||||
alertManager.alert({text: "There was an error saving your note. Please try again."});
|
||||
}
|
||||
})
|
||||
}, syncDebouceMs)
|
||||
@@ -399,21 +399,22 @@ angular.module('app')
|
||||
|
||||
this.deleteNote = async function(permanently) {
|
||||
if(this.note.dummy) {
|
||||
alert("This note is a placeholder and cannot be deleted. To remove from your list, simply navigate to a different note.");
|
||||
alertManager.alert({text: "This note is a placeholder and cannot be deleted. To remove from your list, simply navigate to a different note."});
|
||||
return;
|
||||
}
|
||||
|
||||
let run = () => {
|
||||
$timeout(() => {
|
||||
if(this.note.locked) {
|
||||
alert("This note is locked. If you'd like to delete it, unlock it, and try again.");
|
||||
alertManager.alert("This note is locked. If you'd like to delete it, unlock it, and try again.");
|
||||
return;
|
||||
}
|
||||
|
||||
let title = this.note.safeTitle().length ? `'${this.note.title}'` : "this note";
|
||||
let message = permanently ? `Are you sure you want to permanently delete ${title}?`
|
||||
let text = permanently ? `Are you sure you want to permanently delete ${title}?`
|
||||
: `Are you sure you want to move ${title} to the trash?`
|
||||
if(confirm(message)) {
|
||||
|
||||
alertManager.confirm({text, destructive: true, onConfirm: () => {
|
||||
if(permanently) {
|
||||
this.remove()(this.note);
|
||||
} else {
|
||||
@@ -421,7 +422,7 @@ angular.module('app')
|
||||
this.saveNote({bypassDebouncer: true, dontUpdatePreviews: true});
|
||||
}
|
||||
this.showMenu = false;
|
||||
}
|
||||
}})
|
||||
});
|
||||
}
|
||||
|
||||
@@ -449,10 +450,10 @@ angular.module('app')
|
||||
|
||||
this.emptyTrash = function() {
|
||||
let count = this.getTrashCount();
|
||||
if(confirm(`Are you sure you want to permanently delete ${count} note(s)?`)) {
|
||||
alertManager.confirm({text: `Are you sure you want to permanently delete ${count} note(s)?`, destructive: true, onConfirm: () => {
|
||||
modelManager.emptyTrash();
|
||||
syncManager.sync();
|
||||
}
|
||||
}})
|
||||
}
|
||||
|
||||
this.togglePin = function() {
|
||||
|
||||
@@ -24,7 +24,7 @@ angular.module('app')
|
||||
})
|
||||
.controller('FooterCtrl', function ($rootScope, authManager, modelManager, $timeout, dbManager,
|
||||
syncManager, storageManager, passcodeManager, componentManager, singletonManager, nativeExtManager,
|
||||
privilegesManager, statusManager) {
|
||||
privilegesManager, statusManager, alertManager) {
|
||||
|
||||
authManager.checkForSecurityUpdate().then((available) => {
|
||||
this.securityUpdateAvailable = available;
|
||||
@@ -152,7 +152,7 @@ angular.module('app')
|
||||
this.isRefreshing = false;
|
||||
}.bind(this), 200)
|
||||
if(response && response.error) {
|
||||
alert("There was an error syncing. Please try again. If all else fails, try signing out and signing back in.");
|
||||
alertManager.alert({text: "There was an error syncing. Please try again. If all else fails, try signing out and signing back in."});
|
||||
} else {
|
||||
this.syncUpdated();
|
||||
}
|
||||
@@ -175,7 +175,7 @@ angular.module('app')
|
||||
|
||||
this.clickedNewUpdateAnnouncement = function() {
|
||||
this.newUpdateAvailable = false;
|
||||
alert("A new update is ready to install. Please use the top-level 'Updates' menu to manage installation.")
|
||||
alertManager.alert({text: "A new update is ready to install. Please use the top-level 'Updates' menu to manage installation."})
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
angular.module('app')
|
||||
.controller('HomeCtrl', function ($scope, $location, $rootScope, $timeout, modelManager,
|
||||
dbManager, syncManager, authManager, themeManager, passcodeManager, storageManager, migrationManager,
|
||||
privilegesManager, statusManager) {
|
||||
privilegesManager, statusManager, alertManager) {
|
||||
|
||||
storageManager.initialize(passcodeManager.hasPasscode(), authManager.isEphemeralSession());
|
||||
|
||||
@@ -77,11 +77,11 @@ angular.module('app')
|
||||
lastSessionInvalidAlert = new Date();
|
||||
setTimeout(function () {
|
||||
// If this alert is displayed on launch, it may sometimes dismiss automatically really quicky for some reason. So we wrap in timeout
|
||||
alert("Your session has expired. New changes will not be pulled in. Please sign out and sign back in to refresh your session.");
|
||||
alertManager.alert({text: "Your session has expired. New changes will not be pulled in. Please sign out and sign back in to refresh your session."});
|
||||
}, 500);
|
||||
}
|
||||
} else if(syncEvent == "sync-exception") {
|
||||
alert(`There was an error while trying to save your items. Please contact support and share this message: ${data}`);
|
||||
alertManager.alert({text: `There was an error while trying to save your items. Please contact support and share this message: ${data}`});
|
||||
}
|
||||
});
|
||||
|
||||
@@ -223,13 +223,13 @@ angular.module('app')
|
||||
*/
|
||||
|
||||
$scope.removeTag = function(tag) {
|
||||
if(confirm("Are you sure you want to delete this tag? Note: deleting a tag will not delete its notes.")) {
|
||||
alertManager.confirm({text: "Are you sure you want to delete this tag? Note: deleting a tag will not delete its notes.", destructive: true, onConfirm: () => {
|
||||
modelManager.setItemToBeDeleted(tag);
|
||||
syncManager.sync().then(() => {
|
||||
// force scope tags to update on sub directives
|
||||
$rootScope.safeApply();
|
||||
});
|
||||
}
|
||||
}})
|
||||
}
|
||||
|
||||
$scope.notesSelectionMade = function(note) {
|
||||
@@ -303,7 +303,7 @@ angular.module('app')
|
||||
|
||||
window.addEventListener('drop', (event) => {
|
||||
event.preventDefault();
|
||||
alert("Please use FileSafe or the Bold Editor to attach images and files. Learn more at standardnotes.org/filesafe.")
|
||||
alertManager.alert({text: "Please use FileSafe or the Bold Editor to attach images and files. Learn more at standardnotes.org/filesafe."})
|
||||
}, false)
|
||||
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@ class LockScreen {
|
||||
};
|
||||
}
|
||||
|
||||
controller($scope, passcodeManager, authManager, syncManager, storageManager) {
|
||||
controller($scope, passcodeManager, authManager, syncManager, storageManager, alertManager) {
|
||||
'ngInject';
|
||||
|
||||
$scope.formData = {};
|
||||
@@ -32,7 +32,7 @@ class LockScreen {
|
||||
}
|
||||
passcodeManager.unlock($scope.formData.passcode, (success) => {
|
||||
if(!success) {
|
||||
alert("Invalid passcode. Please try again.");
|
||||
alertManager.alert({text: "Invalid passcode. Please try again."});
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -45,13 +45,11 @@ class LockScreen {
|
||||
}
|
||||
|
||||
$scope.beginDeleteData = function() {
|
||||
if(!confirm("Are you sure you want to clear all local data?")) {
|
||||
return;
|
||||
}
|
||||
|
||||
authManager.signout(true).then(() => {
|
||||
window.location.reload();
|
||||
})
|
||||
alertManager.confirm({text: "Are you sure you want to clear all local data?", destructive: true, onConfirm: () => {
|
||||
authManager.signout(true).then(() => {
|
||||
window.location.reload();
|
||||
})
|
||||
}})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,27 +1,28 @@
|
||||
angular
|
||||
.module('app')
|
||||
.directive('clickOutside', ['$document', function($document) {
|
||||
return {
|
||||
restrict: 'A',
|
||||
replace: false,
|
||||
link : function($scope, $element, attrs) {
|
||||
angular.module('app').directive('clickOutside', ['$document', function($document) {
|
||||
return {
|
||||
restrict: 'A',
|
||||
replace: false,
|
||||
link: function($scope, $element, attrs) {
|
||||
|
||||
var didApplyClickOutside = false;
|
||||
let didApplyClickOutside = false;
|
||||
|
||||
$element.bind('click', function(e) {
|
||||
didApplyClickOutside = false;
|
||||
if (attrs.isOpen) {
|
||||
e.stopPropagation();
|
||||
}
|
||||
});
|
||||
$element.bind('click', function(e) {
|
||||
didApplyClickOutside = false;
|
||||
if(attrs.isOpen) {
|
||||
e.stopPropagation();
|
||||
}
|
||||
});
|
||||
|
||||
$document.bind('click', function() {
|
||||
if(!didApplyClickOutside) {
|
||||
$scope.$apply(attrs.clickOutside);
|
||||
didApplyClickOutside = true;
|
||||
}
|
||||
})
|
||||
|
||||
}
|
||||
$document.bind('click', function(event) {
|
||||
// Ignore click if on SKAlert
|
||||
if(event.target.closest(".sk-modal")) {
|
||||
return;
|
||||
}
|
||||
if(!didApplyClickOutside) {
|
||||
$scope.$apply(attrs.clickOutside);
|
||||
didApplyClickOutside = true;
|
||||
}
|
||||
})
|
||||
}
|
||||
}]);
|
||||
}
|
||||
}]);
|
||||
|
||||
@@ -10,7 +10,7 @@ class AccountMenu {
|
||||
}
|
||||
|
||||
controller($scope, $rootScope, authManager, modelManager, syncManager, storageManager, dbManager, passcodeManager,
|
||||
$timeout, $compile, archiveManager, privilegesManager, appVersion) {
|
||||
$timeout, $compile, archiveManager, privilegesManager, appVersion, alertManager) {
|
||||
'ngInject';
|
||||
|
||||
$scope.appVersion = "v" + (window.electronAppVersion || appVersion);
|
||||
@@ -88,7 +88,9 @@ class AccountMenu {
|
||||
else {
|
||||
$scope.formData.showLogin = true;
|
||||
$scope.formData.mfa = null;
|
||||
if(error.message) { alert(error.message); }
|
||||
if(error.message) {
|
||||
alertManager.alert({text: error.message});
|
||||
}
|
||||
}
|
||||
|
||||
$scope.formData.authenticating = false;
|
||||
@@ -108,7 +110,7 @@ class AccountMenu {
|
||||
$scope.register = function() {
|
||||
let confirmation = $scope.formData.password_conf;
|
||||
if(confirmation !== $scope.formData.user_password) {
|
||||
alert("The two passwords you entered do not match. Please try again.");
|
||||
alertManager.alert({text: "The two passwords you entered do not match. Please try again."});
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -123,7 +125,7 @@ class AccountMenu {
|
||||
$scope.formData.status = null;
|
||||
var error = response ? response.error : {message: "An unknown error occured."}
|
||||
$scope.formData.authenticating = false;
|
||||
alert(error.message);
|
||||
alertManager.alert({text: error.message});
|
||||
} else {
|
||||
$scope.onAuthSuccess(() => {
|
||||
syncManager.sync();
|
||||
@@ -136,9 +138,9 @@ class AccountMenu {
|
||||
|
||||
$scope.mergeLocalChanged = function() {
|
||||
if(!$scope.formData.mergeLocal) {
|
||||
if(!confirm("Unchecking this option means any of the notes you have written while you were signed out will be deleted. Are you sure you want to discard these notes?")) {
|
||||
alertManager.confirm({text: "Unchecking this option means any of the notes you have written while you were signed out will be deleted. Are you sure you want to discard these notes?", destructive: true, onCancel: () => {
|
||||
$scope.formData.mergeLocal = true;
|
||||
}
|
||||
}})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -201,13 +203,11 @@ class AccountMenu {
|
||||
}
|
||||
|
||||
$scope.destroyLocalData = function() {
|
||||
if(!confirm("Are you sure you want to end your session? This will delete all local items and extensions.")) {
|
||||
return;
|
||||
}
|
||||
|
||||
authManager.signout(true).then(() => {
|
||||
window.location.reload();
|
||||
})
|
||||
alertManager.confirm({text: "Are you sure you want to end your session? This will delete all local items and extensions.", destructive: true, onConfirm: () => {
|
||||
authManager.signout(true).then(() => {
|
||||
window.location.reload();
|
||||
})
|
||||
}})
|
||||
}
|
||||
|
||||
/* Import/Export */
|
||||
@@ -232,13 +232,13 @@ class AccountMenu {
|
||||
setTimeout(function () {
|
||||
// Response can be null if syncing offline
|
||||
if(response && response.error) {
|
||||
alert("There was an error importing your data. Please try again.");
|
||||
alertManager.alert({text: "There was an error importing your data. Please try again."});
|
||||
} else {
|
||||
if(errorCount > 0) {
|
||||
var message = `Import complete. ${errorCount} items were not imported because there was an error decrypting them. Make sure the password is correct and try again.`;
|
||||
alert(message);
|
||||
alertManager.alert({text: message});
|
||||
} else {
|
||||
alert("Your data has been successfully imported.")
|
||||
alertManager.alert({text: "Your data has been successfully imported."})
|
||||
}
|
||||
}
|
||||
}, 10);
|
||||
@@ -275,7 +275,7 @@ class AccountMenu {
|
||||
}
|
||||
})
|
||||
} catch (e) {
|
||||
alert("Unable to open file. Ensure it is a proper JSON file and try again.");
|
||||
alertManager.alert({text: "Unable to open file. Ensure it is a proper JSON file and try again."});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -333,7 +333,7 @@ class AccountMenu {
|
||||
}
|
||||
catch (e) {
|
||||
console.log("Error decrypting", e);
|
||||
alert("There was an error decrypting your items. Make sure the password you entered is correct and try again.");
|
||||
alertManager.alert({text: "There was an error decrypting your items. Make sure the password you entered is correct and try again."});
|
||||
callback(null);
|
||||
return;
|
||||
}
|
||||
@@ -433,7 +433,7 @@ class AccountMenu {
|
||||
$scope.submitPasscodeForm = function() {
|
||||
var passcode = $scope.formData.passcode;
|
||||
if(passcode !== $scope.formData.confirmPasscode) {
|
||||
alert("The two passcodes you entered do not match. Please try again.");
|
||||
alertManager.alert({text: "The two passcodes you entered do not match. Please try again."});
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -480,7 +480,8 @@ class AccountMenu {
|
||||
if(!signedIn) {
|
||||
message += " This will remove encryption from your local data.";
|
||||
}
|
||||
if(confirm(message)) {
|
||||
|
||||
alertManager.confirm({text: message, destructive: true, onConfirm: () => {
|
||||
passcodeManager.clearPasscode();
|
||||
|
||||
if(authManager.offline()) {
|
||||
@@ -489,7 +490,7 @@ class AccountMenu {
|
||||
// we don't want to write unencrypted data to disk.
|
||||
// $rootScope.$broadcast("major-data-change");
|
||||
}
|
||||
}
|
||||
}})
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
@@ -22,7 +22,7 @@ class ConflictResolutionModal {
|
||||
}
|
||||
}
|
||||
|
||||
controller($scope, modelManager, syncManager, archiveManager) {
|
||||
controller($scope, modelManager, syncManager, archiveManager, alertManager) {
|
||||
'ngInject';
|
||||
|
||||
$scope.createContentString = function(item) {
|
||||
@@ -37,27 +37,25 @@ class ConflictResolutionModal {
|
||||
$scope.item2Content = $scope.createContentString($scope.item2);
|
||||
|
||||
$scope.keepItem1 = function() {
|
||||
if(!confirm("Are you sure you want to delete the item on the right?")) {
|
||||
return;
|
||||
}
|
||||
modelManager.setItemToBeDeleted($scope.item2);
|
||||
syncManager.sync().then(() => {
|
||||
$scope.applyCallback();
|
||||
})
|
||||
alertManager.confirm({text: `Are you sure you want to delete the item on the right?`, destructive: true, onConfirm: () => {
|
||||
modelManager.setItemToBeDeleted($scope.item2);
|
||||
syncManager.sync().then(() => {
|
||||
$scope.applyCallback();
|
||||
})
|
||||
|
||||
$scope.dismiss();
|
||||
$scope.dismiss();
|
||||
}});
|
||||
}
|
||||
|
||||
$scope.keepItem2 = function() {
|
||||
if(!confirm("Are you sure you want to delete the item on the left?")) {
|
||||
return;
|
||||
}
|
||||
modelManager.setItemToBeDeleted($scope.item1);
|
||||
syncManager.sync().then(() => {
|
||||
$scope.applyCallback();
|
||||
})
|
||||
alertManager.confirm({text: `Are you sure you want to delete the item on the left?`, destructive: true, onConfirm: () => {
|
||||
modelManager.setItemToBeDeleted($scope.item1);
|
||||
syncManager.sync().then(() => {
|
||||
$scope.applyCallback();
|
||||
})
|
||||
|
||||
$scope.dismiss();
|
||||
$scope.dismiss();
|
||||
}});
|
||||
}
|
||||
|
||||
$scope.keepBoth = function() {
|
||||
|
||||
@@ -12,7 +12,7 @@ class PasswordWizard {
|
||||
$scope.el = el;
|
||||
}
|
||||
|
||||
controller($scope, modelManager, archiveManager, authManager, syncManager, $timeout) {
|
||||
controller($scope, modelManager, archiveManager, authManager, syncManager, $timeout, alertManager) {
|
||||
'ngInject';
|
||||
|
||||
window.onbeforeunload = (e) => {
|
||||
@@ -26,7 +26,7 @@ class PasswordWizard {
|
||||
|
||||
$scope.dismiss = function() {
|
||||
if($scope.lockContinue) {
|
||||
alert("Cannot close window until pending tasks are complete.");
|
||||
alertManager.alert({text: "Cannot close window until pending tasks are complete."});
|
||||
return;
|
||||
}
|
||||
$scope.el.remove();
|
||||
@@ -181,20 +181,20 @@ class PasswordWizard {
|
||||
let newPass = $scope.securityUpdate ? currentPassword : $scope.formData.newPassword;
|
||||
|
||||
if(!currentPassword || currentPassword.length == 0) {
|
||||
alert("Please enter your current password.");
|
||||
alertManager.alert({text: "Please enter your current password."});
|
||||
callback(false);
|
||||
return;
|
||||
}
|
||||
|
||||
if($scope.changePassword) {
|
||||
if(!newPass || newPass.length == 0) {
|
||||
alert("Please enter a new password.");
|
||||
alertManager.alert({text: "Please enter a new password."});
|
||||
callback(false);
|
||||
return;
|
||||
}
|
||||
|
||||
if(newPass != $scope.formData.newPasswordConfirmation) {
|
||||
alert("Your new password does not match its confirmation.");
|
||||
alertManager.alert({text: "Your new password does not match its confirmation."});
|
||||
$scope.formData.status = null;
|
||||
callback(false);
|
||||
return;
|
||||
@@ -202,7 +202,7 @@ class PasswordWizard {
|
||||
}
|
||||
|
||||
if(!authManager.user.email) {
|
||||
alert("We don't have your email stored. Please log out then log back in to fix this issue.");
|
||||
alertManager.alert({text: "We don't have your email stored. Please log out then log back in to fix this issue."});
|
||||
$scope.formData.status = null;
|
||||
callback(false);
|
||||
return;
|
||||
@@ -216,7 +216,7 @@ class PasswordWizard {
|
||||
if(success) {
|
||||
this.currentServerPw = keys.pw;
|
||||
} else {
|
||||
alert("The current password you entered is not correct. Please try again.");
|
||||
alertManager.alert({text: "The current password you entered is not correct. Please try again."});
|
||||
}
|
||||
$timeout(() => callback(success));
|
||||
});
|
||||
@@ -226,7 +226,7 @@ class PasswordWizard {
|
||||
modelManager.setAllItemsDirty();
|
||||
syncManager.sync().then((response) => {
|
||||
if(!response || response.error) {
|
||||
alert(FailedSyncMessage)
|
||||
alertManager.alert({text: FailedSyncMessage})
|
||||
$timeout(() => callback(false));
|
||||
} else {
|
||||
$timeout(() => callback(true));
|
||||
@@ -247,7 +247,7 @@ class PasswordWizard {
|
||||
let syncResponse = await syncManager.sync();
|
||||
authManager.changePassword(await syncManager.getServerURL(), authManager.user.email, currentServerPw, newKeys, newAuthParams).then((response) => {
|
||||
if(response.error) {
|
||||
alert(response.error.message ? response.error.message : "There was an error changing your password. Please try again.");
|
||||
alertManager.alert({text: response.error.message ? response.error.message : "There was an error changing your password. Please try again."});
|
||||
$timeout(() => callback(false));
|
||||
} else {
|
||||
$timeout(() => callback(true));
|
||||
|
||||
@@ -13,7 +13,7 @@ class RevisionPreviewModal {
|
||||
$scope.el = el;
|
||||
}
|
||||
|
||||
controller($scope, modelManager, syncManager, componentManager, $timeout) {
|
||||
controller($scope, modelManager, syncManager, componentManager, $timeout, alertManager) {
|
||||
'ngInject';
|
||||
|
||||
$scope.dismiss = function() {
|
||||
@@ -59,30 +59,34 @@ class RevisionPreviewModal {
|
||||
$scope.editor = editorCopy;
|
||||
}
|
||||
|
||||
|
||||
$scope.restore = function(asCopy) {
|
||||
if(!asCopy && !confirm("Are you sure you want to replace the current note's contents with what you see in this preview?")) {
|
||||
return;
|
||||
const run = () => {
|
||||
let item;
|
||||
if(asCopy) {
|
||||
let contentCopy = Object.assign({}, $scope.content);
|
||||
if(contentCopy.title) { contentCopy.title += " (copy)"; }
|
||||
item = modelManager.createItem({content_type: "Note", content: contentCopy});
|
||||
modelManager.addItem(item);
|
||||
} else {
|
||||
let uuid = $scope.uuid;
|
||||
item = modelManager.findItem(uuid);
|
||||
item.content = Object.assign({}, $scope.content);
|
||||
// mapResponseItemsToLocalModels is async, but we don't need to wait here.
|
||||
modelManager.mapResponseItemsToLocalModels([item], SFModelManager.MappingSourceRemoteActionRetrieved);
|
||||
}
|
||||
|
||||
modelManager.setItemDirty(item, true);
|
||||
syncManager.sync();
|
||||
$scope.dismiss();
|
||||
}
|
||||
|
||||
var item;
|
||||
if(asCopy) {
|
||||
var contentCopy = Object.assign({}, $scope.content);
|
||||
if(contentCopy.title) { contentCopy.title += " (copy)"; }
|
||||
item = modelManager.createItem({content_type: "Note", content: contentCopy});
|
||||
modelManager.addItem(item);
|
||||
if(!asCopy) {
|
||||
alertManager.confirm({text: "Are you sure you want to replace the current note's contents with what you see in this preview?", destructive: true, onConfirm: () => {
|
||||
run();
|
||||
}})
|
||||
} else {
|
||||
var uuid = $scope.uuid;
|
||||
item = modelManager.findItem(uuid);
|
||||
item.content = Object.assign({}, $scope.content);
|
||||
// mapResponseItemsToLocalModels is async, but we don't need to wait here.
|
||||
modelManager.mapResponseItemsToLocalModels([item], SFModelManager.MappingSourceRemoteActionRetrieved);
|
||||
run();
|
||||
}
|
||||
|
||||
modelManager.setItemDirty(item, true);
|
||||
syncManager.sync();
|
||||
|
||||
$scope.dismiss();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,7 +8,7 @@ class SessionHistoryMenu {
|
||||
};
|
||||
}
|
||||
|
||||
controller($scope, modelManager, sessionHistory, actionsManager, $timeout) {
|
||||
controller($scope, modelManager, sessionHistory, actionsManager, $timeout, alertManager) {
|
||||
'ngInject';
|
||||
|
||||
$scope.diskEnabled = sessionHistory.diskEnabled;
|
||||
@@ -41,40 +41,41 @@ class SessionHistoryMenu {
|
||||
}
|
||||
|
||||
$scope.clearItemHistory = function() {
|
||||
if(!confirm("Are you sure you want to delete the local session history for this note?")) {
|
||||
return;
|
||||
}
|
||||
|
||||
sessionHistory.clearItemHistory($scope.item).then(() => {
|
||||
$timeout(() => {
|
||||
$scope.reloadHistory();
|
||||
})
|
||||
});
|
||||
alertManager.confirm({text: "Are you sure you want to delete the local session history for this note?", destructive: true, onConfirm: () => {
|
||||
sessionHistory.clearHistoryForItem($scope.item).then(() => {
|
||||
$timeout(() => {
|
||||
$scope.reloadHistory();
|
||||
})
|
||||
});
|
||||
}})
|
||||
}
|
||||
|
||||
$scope.clearAllHistory = function() {
|
||||
if(!confirm("Are you sure you want to delete the local session history for all notes?")) {
|
||||
return;
|
||||
}
|
||||
|
||||
sessionHistory.clearAllHistory().then(() => {
|
||||
$timeout(() => {
|
||||
$scope.reloadHistory();
|
||||
})
|
||||
});
|
||||
alertManager.confirm({text: "Are you sure you want to delete the local session history for all notes?", destructive: true, onConfirm: () => {
|
||||
sessionHistory.clearAllHistory().then(() => {
|
||||
$timeout(() => {
|
||||
$scope.reloadHistory();
|
||||
})
|
||||
});
|
||||
}})
|
||||
}
|
||||
|
||||
$scope.toggleDiskSaving = function() {
|
||||
if(!sessionHistory.diskEnabled) {
|
||||
if(!confirm("Are you sure you want to save history to disk? This will decrease general performance, especially as you type. You are advised to disable this feature if you experience any lagging.")){
|
||||
return;
|
||||
}
|
||||
const run = () => {
|
||||
sessionHistory.toggleDiskSaving().then(() => {
|
||||
$timeout(() => {
|
||||
$scope.diskEnabled = sessionHistory.diskEnabled;
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
if(!sessionHistory.diskEnabled) {
|
||||
alertManager.confirm({text: "Are you sure you want to save history to disk? This will decrease general performance, especially as you type. You are advised to disable this feature if you experience any lagging.", destructive: true, onConfirm: () => {
|
||||
run();
|
||||
}})
|
||||
} else {
|
||||
run();
|
||||
}
|
||||
sessionHistory.toggleDiskSaving().then(() => {
|
||||
$timeout(() => {
|
||||
$scope.diskEnabled = sessionHistory.diskEnabled;
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
$scope.toggleAutoOptimize = function() {
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
class ActionsManager {
|
||||
|
||||
constructor(httpManager, modelManager, authManager, syncManager, $rootScope, $compile, $timeout) {
|
||||
constructor(httpManager, modelManager, authManager, syncManager, $rootScope, $compile, $timeout, alertManager) {
|
||||
this.httpManager = httpManager;
|
||||
this.modelManager = modelManager;
|
||||
this.authManager = authManager;
|
||||
this.syncManager = syncManager;
|
||||
this.alertManager = alertManager;
|
||||
this.$rootScope = $rootScope;
|
||||
this.$compile = $compile;
|
||||
this.$timeout = $timeout;
|
||||
@@ -89,7 +90,7 @@ class ActionsManager {
|
||||
// Error decrypting
|
||||
if(!response.auth_params) {
|
||||
// In some cases revisions were missing auth params. Instruct the user to email us to get this remedied.
|
||||
alert("We were unable to decrypt this revision using your current keys, and this revision is missing metadata that would allow us to try different keys to decrypt it. This can likely be fixed with some manual intervention. Please email hello@standardnotes.org for assistance.");
|
||||
this.alertManager.alert({text: "We were unable to decrypt this revision using your current keys, and this revision is missing metadata that would allow us to try different keys to decrypt it. This can likely be fixed with some manual intervention. Please email hello@standardnotes.org for assistance."});
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -122,17 +123,17 @@ class ActionsManager {
|
||||
|
||||
switch (action.verb) {
|
||||
case "get": {
|
||||
if(confirm("Are you sure you want to replace the current note contents with this action's results?")) {
|
||||
this.alertManager.confirm({text: "Are you sure you want to replace the current note contents with this action's results?", onConfirm: () => {
|
||||
this.httpManager.getAbsolute(action.url, {}, async (response) => {
|
||||
action.error = false;
|
||||
handleResponseDecryption(response, await this.authManager.keys(), true);
|
||||
}, (response) => {
|
||||
let error = (response && response.error) || {message: "An issue occurred while processing this action. Please try again."}
|
||||
alert(error.message);
|
||||
this.alertManager.alert({text: error.message});
|
||||
action.error = true;
|
||||
customCallback(null, error);
|
||||
})
|
||||
}
|
||||
}})
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -142,7 +143,7 @@ class ActionsManager {
|
||||
handleResponseDecryption(response, await this.authManager.keys(), false);
|
||||
}, (response) => {
|
||||
let error = (response && response.error) || {message: "An issue occurred while processing this action. Please try again."}
|
||||
alert(error.message);
|
||||
this.alertManager.alert({text: error.message});
|
||||
action.error = true;
|
||||
customCallback(null, error);
|
||||
})
|
||||
@@ -167,7 +168,7 @@ class ActionsManager {
|
||||
|
||||
this.performPost(action, extension, params, (response) => {
|
||||
if(response && response.error) {
|
||||
alert("An issue occurred while processing this action. Please try again.");
|
||||
this.alertManager.alert({text: "An issue occurred while processing this action. Please try again."});
|
||||
}
|
||||
customCallback(response);
|
||||
});
|
||||
|
||||
47
app/assets/javascripts/app/services/alertManager.js
Normal file
47
app/assets/javascripts/app/services/alertManager.js
Normal file
@@ -0,0 +1,47 @@
|
||||
class AlertManager extends SFAlertManager {
|
||||
|
||||
constructor($timeout) {
|
||||
super();
|
||||
this.$timeout = $timeout;
|
||||
}
|
||||
|
||||
async alert({title, text, closeButtonText = "OK", onClose} = {}) {
|
||||
return new Promise((resolve, reject) => {
|
||||
let buttons = [
|
||||
{text: closeButtonText, style: "neutral", action: async () => {
|
||||
if(onClose) {
|
||||
this.$timeout(onClose);
|
||||
}
|
||||
resolve(true);
|
||||
}}
|
||||
]
|
||||
let alert = new Stylekit.SKAlert({title, text, buttons});
|
||||
alert.present();
|
||||
})
|
||||
}
|
||||
|
||||
async confirm({title, text, confirmButtonText = "Confirm", cancelButtonText = "Cancel", onConfirm, onCancel, destructive = false} = {}) {
|
||||
return new Promise((resolve, reject) => {
|
||||
let buttons = [
|
||||
{text: cancelButtonText, style: "neutral", action: async () => {
|
||||
if(onCancel) {
|
||||
this.$timeout(onCancel);
|
||||
}
|
||||
reject(false);
|
||||
}},
|
||||
{text: confirmButtonText, style: destructive ? "danger" : "info", action: async () => {
|
||||
if(onConfirm) {
|
||||
this.$timeout(onConfirm);
|
||||
}
|
||||
resolve(true);
|
||||
}},
|
||||
];
|
||||
|
||||
let alert = new Stylekit.SKAlert({title, text, buttons});
|
||||
alert.present();
|
||||
})
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
angular.module('app').service('alertManager', AlertManager);
|
||||
@@ -1,14 +1,15 @@
|
||||
class DBManager {
|
||||
|
||||
constructor() {
|
||||
constructor(alertManager) {
|
||||
this.locked = true;
|
||||
this.alertManager;
|
||||
}
|
||||
|
||||
displayOfflineAlert() {
|
||||
var message = "There was an issue loading your offline database. This could happen for two reasons:";
|
||||
message += "\n\n1. You're in a private window in your browser. We can't save your data without access to the local database. Please use a non-private window.";
|
||||
message += "\n\n2. You have two windows of the app open at the same time. Please close any other app instances and reload the page.";
|
||||
alert(message);
|
||||
this.alertManager.alert({text: message});
|
||||
}
|
||||
|
||||
setLocked(locked) {
|
||||
@@ -24,7 +25,7 @@ class DBManager {
|
||||
|
||||
request.onerror = function(event) {
|
||||
if(event.target.errorCode) {
|
||||
alert("Offline database issue: " + event.target.errorCode);
|
||||
this.alertManager.alert({text: "Offline database issue: " + event.target.errorCode});
|
||||
} else {
|
||||
this.displayOfflineAlert();
|
||||
}
|
||||
@@ -121,9 +122,9 @@ class DBManager {
|
||||
console.log("Offline saving aborted:", event);
|
||||
var error = event.target.error;
|
||||
if(error.name == "QuotaExceededError") {
|
||||
alert("Unable to save changes locally because your device is out of space. Please free up some disk space and try again, otherwise, your data may end up in an inconsistent state.");
|
||||
this.alertManager.alert({text: "Unable to save changes locally because your device is out of space. Please free up some disk space and try again, otherwise, your data may end up in an inconsistent state."});
|
||||
} else {
|
||||
alert(`Unable to save changes locally due to an unknown system issue. Issue Code: ${error.code} Issue Name: ${error.name}.`);
|
||||
this.alertManager.alert({text: `Unable to save changes locally due to an unknown system issue. Issue Code: ${error.code} Issue Name: ${error.name}.`});
|
||||
}
|
||||
onerror && onerror(error);
|
||||
};
|
||||
@@ -174,7 +175,7 @@ class DBManager {
|
||||
|
||||
deleteRequest.onblocked = function(event) {
|
||||
console.error("Delete request blocked");
|
||||
alert("Your browser is blocking Standard Notes from deleting the local database. Make sure there are no other open windows of this app and try again. If the issue persists, please manually delete app data to sign out.")
|
||||
this.alertManager.alert({text: "Your browser is blocking Standard Notes from deleting the local database. Make sure there are no other open windows of this app and try again. If the issue persists, please manually delete app data to sign out."})
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -38,9 +38,10 @@ class MemoryStorage {
|
||||
|
||||
class StorageManager extends SFStorageManager {
|
||||
|
||||
constructor(dbManager) {
|
||||
constructor(dbManager, alertManager) {
|
||||
super();
|
||||
this.dbManager = dbManager;
|
||||
this.alertManager = alertManager;
|
||||
}
|
||||
|
||||
initialize(hasPasscode, ephemeral) {
|
||||
@@ -111,7 +112,7 @@ class StorageManager extends SFStorageManager {
|
||||
storage.setItem(key, value);
|
||||
} catch (e) {
|
||||
console.error("Exception while trying to setItem in StorageManager:", e);
|
||||
alert("The application's local storage is out of space. If you have Session History save-to-disk enabled, please disable it, and try again.");
|
||||
this.alertManager.alert({text: "The application's local storage is out of space. If you have Session History save-to-disk enabled, please disable it, and try again."});
|
||||
}
|
||||
|
||||
if(vaultKey === StorageManager.FixedEncrypted || (!vaultKey && this.itemsStorageMode === StorageManager.FixedEncrypted)) {
|
||||
|
||||
2444
dist/javascripts/compiled.js
vendored
2444
dist/javascripts/compiled.js
vendored
File diff suppressed because it is too large
Load Diff
2
dist/javascripts/compiled.min.js
vendored
2
dist/javascripts/compiled.min.js
vendored
File diff suppressed because one or more lines are too long
6
package-lock.json
generated
6
package-lock.json
generated
@@ -6241,9 +6241,9 @@
|
||||
"dev": true
|
||||
},
|
||||
"sn-stylekit": {
|
||||
"version": "2.0.16",
|
||||
"resolved": "https://registry.npmjs.org/sn-stylekit/-/sn-stylekit-2.0.16.tgz",
|
||||
"integrity": "sha512-KZcTqsSej1qneuszOg311NY7jNi10x30yQKSpYkkSWXA8+K4CSarqEzmEX/2tAdsAiiX4DFNk0SVmVuIsY6thQ==",
|
||||
"version": "2.0.17",
|
||||
"resolved": "https://registry.npmjs.org/sn-stylekit/-/sn-stylekit-2.0.17.tgz",
|
||||
"integrity": "sha512-TmLIgpI9TeQZhnxIEZ3ANKTPWwCBfmMiva9TNECB73jEJ2WNeAIkT7SyegPBauyCSP62Td8vxxo4UStUtj1PbQ==",
|
||||
"dev": true
|
||||
},
|
||||
"snapdragon": {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "standard-notes-web",
|
||||
"version": "3.0.19",
|
||||
"version": "3.0.21",
|
||||
"license": "AGPL-3.0-or-later",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
@@ -38,7 +38,7 @@
|
||||
"grunt-shell": "^3.0.1",
|
||||
"mocha": "^6.2.2",
|
||||
"serve-static": "^1.14.1",
|
||||
"sn-stylekit": "2.0.16",
|
||||
"sn-stylekit": "2.0.17",
|
||||
"snjs": "0.2.8",
|
||||
"standard-file-js": "0.3.71"
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user