diff --git a/app/controller/sdl/Abstract/Controller.js b/app/controller/sdl/Abstract/Controller.js index d1aaef50b..396a8d79a 100644 --- a/app/controller/sdl/Abstract/Controller.js +++ b/app/controller/sdl/Abstract/Controller.js @@ -1759,6 +1759,53 @@ SDL.SDLController = Em.Object.extend( SDL.SDLModel.webApplicationFramesMap[policyAppID].hidden = false; }, + /** + * @function onUpdateFile + * @param {String} fileName + * @description Checks whether provided file was requested from SDL or not + * and sends notification if file was not requested yet + */ + onUpdateFile: function(fileName) { + if(SDL.SDLController.model && SDL.SDLController.model.appID) { + let model = SDL.SDLController.model; + if (!model.cachedIconFileNamesList.includes(fileName)) { + model.cachedIconFileNamesList.push(fileName); + FFW.UI.OnUpdateFile(model.appID, fileName); + } + } + }, + + /** + * @function onUpdateSubMenu + * @param {Integer} menuID + * @description Checks whether provided menuID update was requested from SDL + * or not and sends notification if submenu was not updated yet + */ + onUpdateSubMenu: function(menuID) { + if(SDL.SDLController.model && SDL.SDLController.model.appID) { + let model = SDL.SDLController.model; + if (!model.cachedSubmenuIdsList.includes(menuID)) { + model.cachedSubmenuIdsList.push(menuID); + FFW.UI.OnUpdateSubMenu(model.appID, menuID); + } + } + }, + + /** + * @function onDeleteSubMenu + * @param {Integer} menuID + * @description Removes menuID from application model cache if it was cached before + */ + onDeleteSubMenu: function(menuID) { + if (SDL.SDLController.model && SDL.SDLController.model.appID) { + let model = SDL.SDLController.model; + const index = model.cachedSubmenuIdsList.indexOf(menuID); + if (index >= 0) { + model.cachedSubmenuIdsList.splice(index, 1); + } + } + }, + /** * @description Callback for display image mode change. */ diff --git a/app/controlls/Button.js b/app/controlls/Button.js index 5f1e8207e..6364df159 100644 --- a/app/controlls/Button.js +++ b/app/controlls/Button.js @@ -175,10 +175,8 @@ SDL.Button = Em.View.extend(Ember.TargetActionSupport, // this.$('img') returns a jquery instance of // the img element inside of the SDL.Button this.$('img').on('error', function(event) { - if(SDL.SDLController.model && SDL.SDLController.model.appID) { - var regex = /\?(.*)/g; - FFW.UI.OnUpdateFile(SDL.SDLController.model.appID, $(this)[0].icon.replace(regex, "")) - } + var regex = /\?(.*)/g; + SDL.SDLController.onUpdateFile($(this)[0].icon.replace(regex, "")); }.bind(this)); } }, diff --git a/app/controlls/List.js b/app/controlls/List.js index 524b49036..62df68880 100644 --- a/app/controlls/List.js +++ b/app/controlls/List.js @@ -55,6 +55,11 @@ SDL.List = Em.ContainerView.extend({ /** Css style of list */ listScrollingAttributes: '', + /** + * Callback to react on page change events + */ + pageChangeListener: null, + /** Count of items in menu */ /* * listCount: function(){ if( this.items ) { return this.items.length; } @@ -108,8 +113,20 @@ SDL.List = Em.ContainerView.extend({ this.get('currentPage') * this.itemsOnPage * ( -50)) + 'px' ); + + if (this.pageChangeListener) { + this.pageChangeListener(this.currentPage); + } }.observes('currentPage'), + /** + * Specifies new page listener function + * @param {Function} callback + */ + addPageListener: function(callback) { + this.set('pageChangeListener', callback); + }, + /** Method for delete certain item from list */ deleteItem: function(id) { @@ -209,6 +226,10 @@ SDL.List = Em.ContainerView.extend({ // Push element to list this.get('childViews').pushObject(element); } + + // Page can be changed indirectly after items refresh so trigger + // page change event one more time + this._parentView.onCurrentPageChange(); } } ), diff --git a/app/model/sdl/Abstract/AppModel.js b/app/model/sdl/Abstract/AppModel.js index 88c3abedb..1eda6cc11 100644 --- a/app/model/sdl/Abstract/AppModel.js +++ b/app/model/sdl/Abstract/AppModel.js @@ -365,6 +365,18 @@ SDL.ABSAppModel = Em.Object.extend( */ unregisteringInProgress: false, + /** + * @type {Array} + * @description list of already requested icon file names from SDL + */ + cachedIconFileNamesList: [], + + /** + * @type {Array} + * @description list of already requested submenu ID updates from SDL + */ + cachedSubmenuIdsList: [], + /** * @param maskInputCharactersUserChoice * @type {Boolean} @@ -793,7 +805,9 @@ SDL.ABSAppModel = Em.Object.extend( } if (menuID in commandsList) { - delete(commandsList[menuID]) + delete(commandsList[menuID]); + SDL.SDLController.onDeleteSubMenu(menuID); + SDL.OptionsView.commands.refreshItems(); return SDL.SDLModel.data.resultCode.SUCCESS; } diff --git a/app/model/sdl/Abstract/Model.js b/app/model/sdl/Abstract/Model.js index d562f8a5a..baf316ecc 100644 --- a/app/model/sdl/Abstract/Model.js +++ b/app/model/sdl/Abstract/Model.js @@ -215,6 +215,11 @@ SDL.SDLModel = Em.Object.extend({ if (is_image_type && app_model) { result = app_model.onImageRemoved(params.fileName); + const cached_index = app_model.cachedIconFileNamesList.indexOf(fileName); + if (cached_index >= 0) { + app_model.cachedIconFileNamesList.splice(cached_index, 1); + } + if (app_model.appIcon.includes(params.fileName) && params.fileName.length == app_model.appIcon.length) { app_model.set('appIcon', SDL.SDLModel.data.defaultListOfIcons.app); diff --git a/app/model/sdl/MediaModel.js b/app/model/sdl/MediaModel.js index e3caa90e1..e3cfbfd6e 100644 --- a/app/model/sdl/MediaModel.js +++ b/app/model/sdl/MediaModel.js @@ -87,6 +87,8 @@ SDL.SDLMediaModel = SDL.ABSAppModel.extend({ this.set('commandsList', {'top': []}); this.set('softButtons', []); + this.set('cachedIconFileNamesList', []); + this.set('cachedSubmenuIdsList', []); this.set('inactiveWindows', []); this.set('backgroundWindows', []); diff --git a/app/model/sdl/NonMediaModel.js b/app/model/sdl/NonMediaModel.js index 563f68dcb..09f1df609 100644 --- a/app/model/sdl/NonMediaModel.js +++ b/app/model/sdl/NonMediaModel.js @@ -91,6 +91,8 @@ SDL.SDLNonMediaModel = SDL.ABSAppModel.extend({ this.set('commandsList', {'top': []}); this.set('softButtons', []); + this.set('cachedIconFileNamesList', []); + this.set('cachedSubmenuIdsList', []); this.resetGlobalProperties(); }, diff --git a/app/view/sdl/shared/optionsView.js b/app/view/sdl/shared/optionsView.js index 24e736711..6f02addde 100644 --- a/app/view/sdl/shared/optionsView.js +++ b/app/view/sdl/shared/optionsView.js @@ -45,6 +45,7 @@ SDL.OptionsView = SDL.SDLAbstractView.create( activate: function(text) { this._super(); SDL.SDLController.buttonsSort('top', SDL.SDLController.model.appID); + SDL.OptionsView.commands.addPageListener(this.onOptionsPageChanged); SDL.OptionsView.commands.refreshItems(); SDL.SDLController.onSystemContextChange(); SDL.SDLModel.data.registeredApps.forEach(app => { @@ -53,6 +54,26 @@ SDL.OptionsView = SDL.SDLAbstractView.create( }) }) }, + /** + * Listener for options page scroller + * @param {Integer} new_page + */ + onOptionsPageChanged: function(new_page) { + const items_per_page = SDL.OptionsView.commands.itemsOnPage; + const start_index = new_page * items_per_page; + const end_index = Math.min(start_index + items_per_page, + SDL.OptionsView.commands.items.length); + + let items = SDL.OptionsView.commands.items; + let menu_nested_items = SDL.SDLController.model.get('commandsList'); + for (let i = start_index; i < end_index; ++i) { + const menuID = items[i].params.menuID; + if (menuID && menuID >= 0 && menu_nested_items[menuID].length === 0) { + // Notify mobile to update submenu + SDL.SDLController.onUpdateSubMenu(menuID); + } + } + }, // Extend deactivate window deactivate: function() { if (SDL.SDLController.model) { @@ -116,10 +137,6 @@ SDL.OptionsView = SDL.SDLAbstractView.create( for (i = 0; i < len; i++) { var menuID = commands[i].menuID; if (menuID && menuID >= 0) { - if (allMenuItems[menuID].length === 0) { - // Notify mobile to update submenu - FFW.UI.OnUpdateSubMenu(SDL.SDLController.model.appID, menuID); - } template = 'arrowExtended'; } else { template = 'extended';