/*
* Copyright (c) 2015-2017, Michael A. Updike All rights reserved.
* Licensed under the BSD-3-Clause
* https://opensource.org/licenses/BSD-3-Clause
* https://github.com/opus1269/photo-screen-saver/blob/master/LICENSE.md
*/
(function() {
'use strict';
/**
* Extension's Options page
* @namespace Options
*/
new ExceptionHandler();
/**
* Manage an html page that is inserted on demand<br />
* May also be a url link to external site
* @typedef {{}} Options.Page
* @property {string} label - label for Nav menu
* @property {string} route - element name route to page
* @property {string} icon - icon for Nav Menu
* @property {?Object|Function} obj - something to be done when selected
* @property {boolean} ready - true if html is inserted
* @property {boolean} divider - true for divider before item
* @memberOf Options
*/
/**
* Path to the extension in the Web Store
* @type {string}
* @const
* @private
* @memberOf Options
*/
const EXT_URI =
'https://chrome.google.com/webstore/detail/photo-screen-saver/' +
chrome.runtime.id + '/';
/**
* Path to my Pushy Clipboard extension
* @type {string}
* @const
* @default
* @private
* @memberOf Options
*/
const PUSHY_URI =
'https://chrome.google.com/webstore/detail/pushy-clipboard/' +
'jemdfhaheennfkehopbpkephjlednffd';
/**
* auto-binding template
* @type {Object}
* @const
* @private
* @memberOf Options
*/
const t = document.querySelector('#t');
/**
* Array of pages
* @type {Options.Page[]}
* @memberOf Options
*/
t.pages = [
{
label: Chrome.Locale.localize('menu_settings'), route: 'page-settings',
icon: 'myicons:settings', obj: null, ready: true, divider: false,
},
{
label: Chrome.Locale.localize('menu_google'),
route: 'page-google-photos', icon: 'myicons:cloud',
obj: _showGooglePhotosPage, ready: false, divider: false,
},
{
label: Chrome.Locale.localize('menu_preview'), route: 'page-preview',
icon: 'myicons:pageview', obj: _showScreensaverPreview, ready: true,
divider: false,
},
{
label: Chrome.Locale.localize('menu_error'), route: 'page-error',
icon: 'myicons:error', obj: _showErrorPage,
ready: false, disabled: false, divider: false,
},
{
label: Chrome.Locale.localize('menu_help'), route: 'page-help',
icon: 'myicons:help', obj: _showHelpPage, ready: false,
divider: true,
},
{
label: Chrome.Locale.localize('help_faq'), route: 'page-faq',
icon: 'myicons:help',
obj: 'https://opus1269.github.io/photo-screen-saver/faq.html',
ready: true, divider: false,
},
{
label: Chrome.Locale.localize('menu_support'), route: 'page-support',
icon: 'myicons:help', obj: `${EXT_URI}support`, ready: true,
divider: false,
},
{
label: Chrome.Locale.localize('menu_rate'), route: 'page-rate',
icon: 'myicons:grade', obj: `${EXT_URI}reviews`, ready: true,
divider: false,
},
{
label: Chrome.Locale.localize('menu_pushy'), route: 'page-pushy',
icon: 'myicons:extension', obj: PUSHY_URI, ready: true,
divider: true,
},
];
// Error dialog
t.dialogTitle = '';
t.dialogText = '';
/**
* Current {@link Options.Page}
* @type {string}
* @memberOf Options
*/
t.route = 'page-settings';
/**
* Event Listener for template bound event to know when bindings
* have resolved and content has been stamped to the page
* @memberOf Options
*/
t.addEventListener('dom-change', function() {
Chrome.GA.page('/options.html');
// listen for chrome messages
Chrome.Msg.listen(_onMessage);
// initialize lastError enabled state
_setErrorMenuState();
// listen for changes to chrome.storage
chrome.storage.onChanged.addListener(function(changes) {
for (const key in changes) {
if (changes.hasOwnProperty(key)) {
if (key === 'lastError') {
_setErrorMenuState();
break;
}
}
}
});
});
/**
* Event: navigation menu selected
* Route to proper page
* @param {Event} event - ClickEvent
* @memberOf Options
*/
t._onNavMenuItemTapped = function(event) {
// Close drawer after menu item is selected if it is narrow
const drawerPanel = document.querySelector('#paperDrawerPanel');
if (drawerPanel && drawerPanel.narrow) {
drawerPanel.closeDrawer();
}
const idx = _getPageIdx(event.currentTarget.id);
Chrome.GA.event(Chrome.GA.EVENT.MENU, t.pages[idx].route);
const prevRoute = t.route;
if (!t.pages[idx].obj) {
// some pages are just pages
t.route = t.pages[idx].route;
_scrollPageToTop();
} else if (typeof t.pages[idx].obj === 'string') {
// some pages are url links
t.$.mainMenu.select(prevRoute);
chrome.tabs.create({url: t.pages[idx].obj});
} else {
// some pages have functions to view them
t.pages[idx].obj(idx, prevRoute);
}
};
/**
* Computed property: Page title
* @returns {string} i18n title
* @memberOf Options
*/
t._computeTitle = function() {
return Chrome.Locale.localize('chrome_extension_name');
};
/**
* Computed property: Menu label
* @returns {string} i18n label
* @memberOf Options
*/
t._computeMenu = function() {
return Chrome.Locale.localize('menu');
};
/**
* Get the index into the {@link Options.pages} array
* @param {string} name - {@link Options.page} route
* @returns {int} index into array
* @private
* @memberOf Options
*/
function _getPageIdx(name) {
return t.pages.map(function(e) {
return e.route;
}).indexOf(name);
}
/**
* Show the Google Photos page
* @param {int} index - index into [t.pages]{@link Options.t.pages}
* @memberOf Options
*/
function _showGooglePhotosPage(index) {
if (!t.pages[index].ready) {
// create the page the first time
t.pages[index].ready = true;
t.gPhotosPage =
new app.GooglePhotosPage('gPhotosPage');
Polymer.dom(t.$.googlePhotosInsertion).appendChild(t.gPhotosPage);
} else if (Chrome.Storage.getBool('isAlbumMode')) {
t.gPhotosPage.loadAlbumList();
}
t.route = t.pages[index].route;
_scrollPageToTop();
}
/**
* Show the error viewer page
* @param {int} index - index into {@link Options.pages}
* @private
* @memberOf Options
*/
function _showErrorPage(index) {
if (!t.pages[index].ready) {
// insert the page the first time
t.pages[index].ready = true;
const el = new app.ErrorPageFactory();
Polymer.dom(t.$.errorInsertion).appendChild(el);
}
t.route = t.pages[index].route;
_scrollPageToTop();
}
/**
* Show the help page
* @param {int} index - index into [t.pages]{@link Options.t.pages}
* @private
* @memberOf Options
*/
function _showHelpPage(index) {
if (!t.pages[index].ready) {
// insert the page the first time
t.pages[index].ready = true;
const el = new app.HelpPageFactory();
Polymer.dom(t.$.helpInsertion).appendChild(el);
}
t.route = t.pages[index].route;
_scrollPageToTop();
}
// noinspection JSUnusedLocalSymbols
/**
* Display a preview of the screen saver
* @param {int} index - index into [t.pages]{@link Options.t.pages}
* @param {string} prevRoute - last page selected
* @memberOf Options
*/
function _showScreensaverPreview(index, prevRoute) {
// reselect previous page - need to delay so tap event is done
t.async(function() {
t.$.mainMenu.select(prevRoute);
}, 500);
Chrome.Msg.send(app.Msg.SS_SHOW).catch(() => {});
}
/**
* Scroll page to top
* @memberOf Options
*/
function _scrollPageToTop() {
t.$.scrollPanel.scrollToTop(true);
}
/**
* Set enabled state of Error Viewer menu item
* @memberOf Options
*/
function _setErrorMenuState() {
// disable error-page if no lastError
Chrome.Storage.getLastError().then((lastError) => {
const idx = _getPageIdx('page-error');
const el = document.getElementById(t.pages[idx].route);
if (el && !Chrome.Utils.isWhiteSpace(lastError.message)) {
el.removeAttribute('disabled');
} else if (el) {
el.setAttribute('disabled', 'true');
}
return Promise.resolve();
}).catch((err) => {
Chrome.GA.error(err.message, 'Options._setErrorMenuState');
});
}
// noinspection JSUnusedLocalSymbols
/**
* Event: Fired when a message is sent from either an extension process<br>
* (by runtime.sendMessage) or a content script (by tabs.sendMessage).
* @see https://developer.chrome.com/extensions/runtime#event-onMessage
* @param {Chrome.Msg.Message} request - details for the message
* @param {Object} [sender] - MessageSender object
* @param {Function} [response] - function to call once after processing
* @returns {boolean} true if asynchronous
* @private
* @memberOf Options
*/
function _onMessage(request, sender, response) {
if (request.message === Chrome.Msg.HIGHLIGHT.message) {
// highlight ourselves and let the sender know we are here
const chromep = new ChromePromise();
chromep.tabs.getCurrent().then((t) => {
chrome.tabs.update(t.id, {'highlighted': true});
return null;
}).catch((err) => {
Chrome.Log.error(err.message, 'chromep.tabs.getCurrent');
});
response(JSON.stringify({message: 'OK'}));
} else if (request.message === Chrome.Msg.STORAGE_EXCEEDED.message) {
// Display Error Dialog if a save action exceeded the
// localStorage limit
t.dialogTitle = Chrome.Locale.localize('err_storage_title');
t.dialogText = Chrome.Locale.localize('err_storage_desc');
t.$.errorDialog.open();
} else if (request.message === app.Msg.PHOTO_SOURCE_FAILED.message) {
// failed to load
t.$.settingsPage.deselectPhotoSource(request.key);
t.dialogTitle = Chrome.Locale.localize('err_photo_source_title');
t.dialogText = request.error;
t.$.errorDialog.open();
}
return false;
}
})();