diff --git a/css/styles.scss b/css/styles.scss index bf8828d86..787ba8c5b 100644 --- a/css/styles.scss +++ b/css/styles.scss @@ -144,13 +144,11 @@ body { .alert { width: 100%; - position: absolute; - z-index: 90; border: none; border-radius: 0; padding: 10px 10px 15px; - margin-bottom: 5px; - background-color: rgba(234,56,105,0.9); + margin-bottom: 0; + background-color: $colour-danger; border: none; color: $colour-text1; diff --git a/issue_template.md b/issue_template.md index 936b288b9..7ebe13279 100644 --- a/issue_template.md +++ b/issue_template.md @@ -3,7 +3,7 @@ Thanks for reporting a bug for xBrowserSync! This is the bug tracker for the xBrowserSync client apps. If you are running an xBrowserSync service and need to report a bug for it, please do so at https://github.com/xBrowserSync/API/issues/. -Alternatively, if you are a user and need to report an issue with a particular xBrowserSync service, please go to http://xbrowsersync.org/contact/. +Alternatively, if you are a user and need to report an issue with a particular xBrowserSync service, please go to https://www.xbrowsersync.org/contact/. Otherwise, to make it possible for us to help you please fill out the information below: --> diff --git a/js/app.js b/js/app.js index ca2cfb08c..c8900cca3 100644 --- a/js/app.js +++ b/js/app.js @@ -230,12 +230,12 @@ xBrowserSync.App.Controller = function($scope, $q, $timeout, complexify, platfor switch(view) { case vm.view.views.search: $timeout(function() { + platform.Interface.Refresh(); document.querySelector('input[name=txtSearch]').select(); }); break; case vm.view.views.bookmark: $timeout(function() { - // Focus on title field document.querySelector('input[name="bookmarkTitle"]').select(); }); break; @@ -650,6 +650,11 @@ xBrowserSync.App.Controller = function($scope, $q, $timeout, complexify, platfor else { errMessage = utility.GetErrorMessageFromException(response.error); vm.alert.display(errMessage.title, errMessage.message, 'danger'); + + // If data out of sync, refresh sync + if (!!response.error && !!response.error.code && response.error.code === global.ErrorCodes.DataOutOfSync) { + platform.Sync(vm.sync.asyncChannel, { type: global.SyncType.Pull }); + } } vm.working = false; @@ -691,38 +696,6 @@ xBrowserSync.App.Controller = function($scope, $q, $timeout, complexify, platfor break; } }; - - var syncBookmarksToolbar_Click = function() { - // If sync not enabled or user just clicked to disable toolbar sync, return - if (!global.SyncEnabled.Get() || !global.SyncBookmarksToolbar.Get()) { - return; - } - - // Otherwise, display sync confirmation - vm.settings.service.displaySyncBookmarksToolbarConfirmation = true; - $timeout(function() { - document.querySelector('#btnSyncBookmarksToolbar_Confirm').focus(); - }); - }; - - var syncBookmarksToolbar_Confirm = function() { - // If sync not enabled, return - if (!global.SyncEnabled.Get()) { - return; - } - - var syncData = {}; - syncData.type = (!global.Id.Get()) ? global.SyncType.Push : global.SyncType.Pull; - - // Hide sync confirmation - vm.settings.service.displaySyncBookmarksToolbarConfirmation = false; - - // Show loading animation - vm.working = true; - - // Start sync with no callback action - platform.Sync(vm.sync.asyncChannel, syncData, global.Commands.NoCallback); - }; var init = function() { // Display intro animation if required @@ -1130,6 +1103,38 @@ xBrowserSync.App.Controller = function($scope, $q, $timeout, complexify, platfor vm.working = true; queueSync(); }; + + var syncBookmarksToolbar_Click = function() { + // If sync not enabled or user just clicked to disable toolbar sync, return + if (!global.SyncEnabled.Get() || !global.SyncBookmarksToolbar.Get()) { + return; + } + + // Otherwise, display sync confirmation + vm.settings.service.displaySyncBookmarksToolbarConfirmation = true; + $timeout(function() { + document.querySelector('#btnSyncBookmarksToolbar_Confirm').focus(); + }); + }; + + var syncBookmarksToolbar_Confirm = function() { + // If sync not enabled, return + if (!global.SyncEnabled.Get()) { + return; + } + + var syncData = {}; + syncData.type = (!global.Id.Get()) ? global.SyncType.Push : global.SyncType.Pull; + + // Hide sync confirmation + vm.settings.service.displaySyncBookmarksToolbarConfirmation = false; + + // Show loading animation + vm.working = true; + + // Start sync with no callback action + platform.Sync(vm.sync.asyncChannel, syncData, global.Commands.NoCallback); + }; var syncForm_CancelSyncConfirmation_Click = function() { // TODO: Ensure any sync messaging or process is cancelled also diff --git a/js/bookmarks.js b/js/bookmarks.js index 6dbd281dd..08532f87c 100644 --- a/js/bookmarks.js +++ b/js/bookmarks.js @@ -405,7 +405,7 @@ xBrowserSync.App.Bookmarks = function($q, platform, global, api, utility) { if (!tagsOnly) { // Add all words from title - bookmarkWords = bookmarkWords.concat(_.compact(bookmark.title.replace("'", '').toLowerCase().split(/\s/))); + bookmarkWords = bookmarkWords.concat(_.compact(bookmark.title.replace("'", '').toLowerCase().split(/[\W_]/))); // Split tags into individual words if (!!bookmark.tags) { @@ -514,6 +514,12 @@ xBrowserSync.App.Bookmarks = function($q, platform, global, api, utility) { if (!data || !data.lastUpdated) { return $q.reject({ code: global.ErrorCodes.NoDataFound }); } + + // Check if data is out of sync + var lastUpdated = new Date(data.lastUpdated); + if (global.LastUpdated.Get().getTime() !== lastUpdated.getTime()) { + return $q.reject({ code: global.ErrorCodes.DataOutOfSync }); + } var bookmarksToUpdate; @@ -541,6 +547,12 @@ xBrowserSync.App.Bookmarks = function($q, platform, global, api, utility) { if (!data || !data.lastUpdated) { return $q.reject({ code: global.ErrorCodes.NoDataFound }); } + + // Check if data is out of sync + var lastUpdated = new Date(data.lastUpdated); + if (global.LastUpdated.Get().getTime() !== lastUpdated.getTime()) { + return $q.reject({ code: global.ErrorCodes.DataOutOfSync }); + } var bookmarksToUpdate; @@ -570,6 +582,12 @@ xBrowserSync.App.Bookmarks = function($q, platform, global, api, utility) { if (!data || !data.lastUpdated) { return $q.reject({ code: global.ErrorCodes.NoDataFound }); } + + // Check if data is out of sync + var lastUpdated = new Date(data.lastUpdated); + if (global.LastUpdated.Get().getTime() !== lastUpdated.getTime()) { + return $q.reject({ code: global.ErrorCodes.DataOutOfSync }); + } var bookmarksToUpdate; @@ -698,6 +716,12 @@ xBrowserSync.App.Bookmarks = function($q, platform, global, api, utility) { if (!data || !data.lastUpdated) { return $q.reject({ code: global.ErrorCodes.NoDataFound }); } + + // Check if data is out of sync + var lastUpdated = new Date(data.lastUpdated); + if (global.LastUpdated.Get().getTime() !== lastUpdated.getTime()) { + return $q.reject({ code: global.ErrorCodes.DataOutOfSync }); + } // Decrypt bookmarks try { diff --git a/js/global.js b/js/global.js index fa99f6b6b..0985a5031 100644 --- a/js/global.js +++ b/js/global.js @@ -179,7 +179,9 @@ xBrowserSync.App.Global = function(platform) { Error_InvalidData_Message: 'error_InvalidData_Message', Error_LastChangeNotSynced_Title: 'error_LastChangeNotSynced_Title', Error_LastChangeNotSynced_Message: 'error_LastChangeNotSynced_Message', - Error_OutOfSync_Title: 'error_OutOfSync_Title', + Error_BookmarkNotFound_Title: 'error_BookmarkNotFound_Title', + Error_BookmarkNotFound_Message: 'error_BookmarkNotFound_Message', + Error_OutOfSync_Title: 'error_OutOfSync_Title', Error_OutOfSync_Message: 'error_OutOfSync_Message', Error_ContainerChanged_Title: 'error_ContainerChanged_Title', Error_ContainerChanged_Message: 'error_ContainerChanged_Message', @@ -269,6 +271,7 @@ xBrowserSync.App.Global = function(platform) { UpdatedBookmarkNotFound: 10107, XBookmarkNotFound: 10108, ContainerChanged: 10109, + DataOutOfSync: 10110, NoStatus: 10200, FailedGetPageMetadata: 10300, NotImplemented: 10400 diff --git a/js/utility.js b/js/utility.js index 82ec03f5b..28bd5a3d7 100644 --- a/js/utility.js +++ b/js/utility.js @@ -169,13 +169,17 @@ xBrowserSync.App.Utility = function($q, platform, global) { errorMessage.message = platform.Constants.Get(global.Constants.Error_LastChangeNotSynced_Message); break; case global.ErrorCodes.XBookmarkNotFound: - errorMessage.title = platform.Constants.Get(global.Constants.Error_OutOfSync_Title); - errorMessage.message = platform.Constants.Get(global.Constants.Error_OutOfSync_Message); + errorMessage.title = platform.Constants.Get(global.Constants.Error_BookmarkNotFound_Title); + errorMessage.message = platform.Constants.Get(global.Constants.Wrror_BookmarkNotFound_Message); break; case global.ErrorCodes.ContainerChanged: errorMessage.title = platform.Constants.Get(global.Constants.Error_ContainerChanged_Title); errorMessage.message = platform.Constants.Get(global.Constants.Error_ContainerChanged_Message); break; + case global.ErrorCodes.DataOutOfSync: + errorMessage.title = platform.Constants.Get(global.Constants.Error_OutOfSync_Title); + errorMessage.message = platform.Constants.Get(global.Constants.Error_OutOfSync_Message); + break; case global.ErrorCodes.NotImplemented: errorMessage.title = platform.Constants.Get(global.Constants.Error_NotImplemented_Title); errorMessage.message = platform.Constants.Get(global.Constants.Error_NotImplemented_Message); diff --git a/package.json b/package.json index 551325807..9f9045a75 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "xbrowsersync-app", "description": "The xBrowserSync client app.", - "version": "1.1.0", + "version": "1.1.1", "author": "xBrowserSync", "license": "MIT", "repository": { @@ -19,7 +19,6 @@ "bootstrap": "3.3.x", "crypto-js": "3.1.x", "font-awesome": "4.6.x", - "minify": "2.0.11", "underscore": "1.8.x" }, "devDependencies": { diff --git a/platform/chrome/_locales/en/messages.json b/platform/chrome/_locales/en/messages.json index b2d19ba68..1ed1c69f8 100644 --- a/platform/chrome/_locales/en/messages.json +++ b/platform/chrome/_locales/en/messages.json @@ -27,7 +27,7 @@ "message": "Previous" }, "introPanel1_Message": { - "message": "

Welcome

Thanks for installing xBrowserSync!

Have a read through the following pages to help you get started. Should you require futher help, check out the FAQs.

" + "message": "

Welcome

Thanks for installing xBrowserSync!

Have a read through the following pages to help you get started. Should you require futher help, check out the FAQs.

" }, "introPanel2_Message": { "message": "

Your secret word

To begin, enter a secret word or phrase that will be used to encrypt and decrypt your browser data.

Make it strong to protect your data but also memorable, if you forget it we can't remind you and you won't be able to decrypt your data without it.

" @@ -135,7 +135,7 @@ "message": "Change Service" }, "updateServiceUrlForm_Message" : { - "message": "Enter the URL of an alternative xBrowserSync service. You can check the list of public xBrowserSync services here." + "message": "Enter the URL of an alternative xBrowserSync service. You can check the list of public xBrowserSync services here." }, "updateServiceUrlForm_Placeholder" : { "message": "xBrowserSync service URL" @@ -332,11 +332,17 @@ "error_LastChangeNotSynced_Message" : { "message": "The last change was not synced due to a bookmarks conflict. It would be a good idea to disable and re-enable sync before continuing." }, + "error_BookmarkNotFound_Title" : { + "message": "Bookmark not found" + }, + "error_BookmarkNotFound_Message" : { + "message": "It looks like your bookmarks are out of sync. It would be a good idea to disable and re-enable sync before continuing." + }, "error_OutOfSync_Title" : { - "message": "Bookmarks out of sync" + "message": "Data out of sync" }, "error_OutOfSync_Message" : { - "message": "The last change was not synced due to a bookmarks conflict. It would be a good idea to disable and re-enable sync before continuing." + "message": "Local data was out of sync but has now been refreshed. However, your last change was not synced so you will need to redo this change." }, "error_ContainerChanged_Title" : { "message": "xBrowserSync folder changed" diff --git a/platform/chrome/js/background.js b/platform/chrome/js/background.js index 415f40810..e28938d88 100644 --- a/platform/chrome/js/background.js +++ b/platform/chrome/js/background.js @@ -48,18 +48,13 @@ xBrowserSync.App.Background = function($q, platform, global, utility, bookmarks) } // Sync updates - bookmarks.Sync({ + syncBookmarks({ type: global.SyncType.Push, changeInfo: { type: global.UpdateType.Update, data: [id, changeInfo] } - }) - .catch(function(err) { - // Display alert - var errMessage = utility.GetErrorMessageFromException(err); - displayAlert(errMessage.title, errMessage.message); - }); + }); }; var createBookmark = function(id, bookmark) { @@ -69,18 +64,13 @@ xBrowserSync.App.Background = function($q, platform, global, utility, bookmarks) } // Sync updates - bookmarks.Sync({ + syncBookmarks({ type: global.SyncType.Push, changeInfo: { type: global.UpdateType.Create, data: [id, bookmark] } - }) - .catch(function(err) { - // Display alert - var errMessage = utility.GetErrorMessageFromException(err); - displayAlert(errMessage.title, errMessage.message); - }); + }); }; var displayAlert = function(title, message, callback) { @@ -172,18 +162,13 @@ xBrowserSync.App.Background = function($q, platform, global, utility, bookmarks) } // Sync updates - bookmarks.Sync({ + syncBookmarks({ type: global.SyncType.Push, changeInfo: { type: global.UpdateType.Move, data: [id, moveInfo] } - }) - .catch(function(err) { - // Display alert - var errMessage = utility.GetErrorMessageFromException(err); - displayAlert(errMessage.title, errMessage.message); - }); + }); }; var removeBookmark = function(id, removeInfo) { @@ -193,7 +178,7 @@ xBrowserSync.App.Background = function($q, platform, global, utility, bookmarks) } // Sync updates - bookmarks.Sync({ + syncBookmarks({ type: global.SyncType.Push, changeInfo: { type: global.UpdateType.Delete, @@ -204,24 +189,16 @@ xBrowserSync.App.Background = function($q, platform, global, utility, bookmarks) // Display alert var errMessage = utility.GetErrorMessageFromException(err); displayAlert(errMessage.title, errMessage.message); + + // If data out of sync, refresh sync + if (!!err && !!err.code && err.code === global.ErrorCodes.DataOutOfSync) { + syncBookmarks({ type: global.SyncType.Pull }); + } }); }; var restoreBookmarks = function(restoreData) { - // Start restore - bookmarks.Sync(restoreData) - .then(function() { - try { - asyncChannel.postMessage({ command: global.Commands.RestoreBookmarks, success: true }); - } - catch (ex) {} - }) - .catch(function(err) { - try { - asyncChannel.postMessage({ command: global.Commands.RestoreBookmarks, success: false, error: err }); - } - catch (ex) {} - }); + syncBookmarks(restoreData, global.Commands.RestoreBookmarks); }; var startup = function() { @@ -256,18 +233,25 @@ xBrowserSync.App.Background = function($q, platform, global, utility, bookmarks) var syncBookmarks = function(syncData, command) { // Start sync - bookmarks.Sync(syncData) + return bookmarks.Sync(syncData) .then(function() { - try { - asyncChannel.postMessage({ command: command, success: true }); + if (!!command) { + try { + asyncChannel.postMessage({ command: command, success: true }); + } + catch (ex) {} } - catch (ex) {} }) .catch(function(err) { - try { - asyncChannel.postMessage({ command: command, success: false, error: err }); + if (!!command) { + try { + asyncChannel.postMessage({ command: command, success: false, error: err }); + } + catch (ex) {} + } + else { + throw err; } - catch (ex) {} }); }; diff --git a/platform/chrome/js/platformImplementation.js b/platform/chrome/js/platformImplementation.js index 4252da8c2..5485c4aae 100644 --- a/platform/chrome/js/platformImplementation.js +++ b/platform/chrome/js/platformImplementation.js @@ -516,15 +516,6 @@ xBrowserSync.App.PlatformImplementation = function($q, $timeout, platform, globa return deferred.promise; }; - - var setInLocalStorage = function(itemName, itemValue) { - localStorage.setItem(itemName, itemValue); - }; - - var sync = function(asyncChannel, syncData, command) { - syncData.command = (!!command) ? command : global.Commands.SyncBookmarks; - asyncChannel.postMessage(syncData); - }; var openUrl = function(url) { // Get current tab @@ -623,10 +614,17 @@ xBrowserSync.App.PlatformImplementation = function($q, $timeout, platform, globa iconPath = 'img/browser-action-off.png'; } - $timeout(function() { - chrome.browserAction.setIcon({ path: iconPath }); - chrome.browserAction.setTitle({ title: tooltip }); - }, 100); + chrome.browserAction.setIcon({ path: iconPath }); + chrome.browserAction.setTitle({ title: tooltip }); + }; + + var setInLocalStorage = function(itemName, itemValue) { + localStorage.setItem(itemName, itemValue); + }; + + var sync = function(asyncChannel, syncData, command) { + syncData.command = (!!command) ? command : global.Commands.SyncBookmarks; + asyncChannel.postMessage(syncData); }; diff --git a/platform/chrome/manifest.json b/platform/chrome/manifest.json index 1f85470a2..11c3e2df6 100644 --- a/platform/chrome/manifest.json +++ b/platform/chrome/manifest.json @@ -1,7 +1,7 @@ { "manifest_version": 2, "name": "__MSG_title__", - "version": "1.1.0", + "version": "1.1.1", "description": "__MSG_description__", "icons": { "128": "img/ext-icon.png"