diff --git a/README-RU.md b/README-RU.md
index 2265e2d..35e113d 100644
--- a/README-RU.md
+++ b/README-RU.md
@@ -78,7 +78,7 @@ AppLauncher поддерживает:
- NV-102 (+)
- - NV-300
+ - NV-300 (+)
- Mag STB (Aura STB)
diff --git a/README.md b/README.md
index 7b365bb..cd3a232 100644
--- a/README.md
+++ b/README.md
@@ -8,7 +8,7 @@ AppLauncher
AppLauncher allows running Smart TV and STB application avoiding standard
installation process.
-AppLauncher lets to create list of applications’ URLs to run. URLs are sorted
+AppLauncher lets to create list of applications URLs to run. URLs are sorted
according to last activities: adding or launching.
Install AppLauncher once and easily run dozens of your applications at Smart TV
@@ -18,11 +18,11 @@ or STB.
Important details:
-1. You have to run web-server to provide application's URL to run. AppLauncher
+1. You have to run web-server to provide application URL to run. AppLauncher
works only with URLs, not ipk or zip files!
-2. AppLauncher could not check applications’ URLs before running them due to
- platforms' limitations. Be careful while entering URL. Improper URL can
+2. AppLauncher could not check applications URLs before running them due to
+ platforms limitations. Be careful while entering URL. Improper URL can
cause Smart TV/STB hang-up. Reboot your Smart TV/STB in this situation.
3. You can use remote control digital buttons to enter digits into URL instead
@@ -36,7 +36,7 @@ Platforms
AppLauncer was tested on devices marked (+). It must also work on other devices
listed below, but there can be problems of various types. If you run AppLauncher
on devices without (+) mark, please write mail to
-[applauncher@interfaced.ru](mailto:applauncher@interfaced.ru) and inform us about both success and problems
+[applauncher@interfaced.tv](mailto:applauncher@interfaced.tv) and inform us about both success and problems
you have.
@@ -77,7 +77,7 @@ AppLauncher supports:
- NV-102 (+)
- - NV-300
+ - NV-300 (+)
- Mag STB (Aura STB)
diff --git a/app/launcher/app-config.js b/app/launcher/app-config.js
index 17ffe2e..41e9cce 100644
--- a/app/launcher/app-config.js
+++ b/app/launcher/app-config.js
@@ -6,5 +6,6 @@ goog.provide('launcher.appConfig');
* @struct
*/
launcher.appConfig = {
+ googleAnalyticsId: 'UA-29756002-6',
noticeTime: 5000
};
diff --git a/app/launcher/application.js b/app/launcher/application.js
index 80cb396..d7ad26f 100644
--- a/app/launcher/application.js
+++ b/app/launcher/application.js
@@ -2,6 +2,7 @@ goog.provide('launcher.Application');
goog.require('launcher.BaseApplication');
goog.require('launcher.services.AppList');
goog.require('launcher.services.HelpBarItemFactory');
+goog.require('zb.ui.GoogleAnalytics');
@@ -12,6 +13,7 @@ goog.require('launcher.services.HelpBarItemFactory');
launcher.Application = function() {
zb.console.setLevel(zb.console.Level.LOG | zb.console.Level.ERROR);
this.services = {
+ ga: null,
appList: null,
helpBarItemFactory: null
};
@@ -33,6 +35,21 @@ launcher.Application.prototype.canBack = function() {
* @inheritDoc
*/
launcher.Application.prototype.onReady = function() {
+ var gaId = '';
+ if (COMPILED) {
+ gaId = launcher.appConfig.googleAnalyticsId;
+
+ this._layerManager.on(this._layerManager.EVENT_TRANSITION_SUCCESS, function(eventName, transitionData) {
+ transitionData = /** @type {zb.LayerManager.TransitionData} */(transitionData);
+ var layer = transitionData.layer;
+ var pageName = '/' + /s-([a-z0-9\-]+)$/i.exec(layer.getCSSClassName())[1];
+ this.services.ga.sendPageview(pageName);
+ }.bind(this));
+ }
+
+ this.services.ga = new zb.ui.GoogleAnalytics(gaId, this.device, {
+ analyticsJS: 'analytics.js'
+ });
this.services.appList = new launcher.services.AppList(this.device.storage);
this.services.helpBarItemFactory = new launcher.services.HelpBarItemFactory;
this.setHomeScene('app-list');
@@ -45,8 +62,10 @@ launcher.Application.prototype.onReady = function() {
launcher.Application.prototype.onStart = function() {
var apps = this.services.appList.getApps();
if (apps.length) {
+ this.services.ga.sendEvent('app', 'start');
this.home();
} else {
+ this.services.ga.sendEvent('app', 'first-start');
this.show('app-add', {});
}
};
@@ -70,6 +89,7 @@ launcher.Application.prototype._appendScreenSizeClass = function() {
/**
* @type {{
+ * ga: zb.ui.GoogleAnalytics,
* appList: launcher.services.AppList,
* helpBarItemFactory: launcher.services.HelpBarItemFactory
* }}
diff --git a/app/launcher/scenes/about/about.js b/app/launcher/scenes/about/about.js
index 78f448b..42acecd 100644
--- a/app/launcher/scenes/about/about.js
+++ b/app/launcher/scenes/about/about.js
@@ -1,6 +1,6 @@
goog.provide('launcher.scenes.About');
-goog.require('launcher.scenes.AbstractBase');
goog.require('launcher.scenes.templates.about.about');
+goog.require('launcher.scenes.AbstractBase');
@@ -11,12 +11,14 @@ goog.require('launcher.scenes.templates.about.about');
launcher.scenes.About = function() {
goog.base(this);
this._addContainerClass('s-about');
+
+ this._createHelpBar();
};
goog.inherits(launcher.scenes.About, launcher.scenes.AbstractBase);
/**
- * @inheritDoc
+ * @protected
*/
launcher.scenes.About.prototype._createHelpBar = function() {
goog.base(this, '_createHelpBar');
@@ -30,16 +32,14 @@ launcher.scenes.About.prototype._createHelpBar = function() {
};
-/**
- * @inheritDoc
- */
+/** @inheritDoc */
launcher.scenes.About.prototype._renderTemplate = function() {
return launcher.scenes.templates.about.about(this._getTemplateData(), this._getTemplateOptions());
};
/**
-* @type {launcher.scenes.templates.about.AboutOut}
-* @protected
-*/
+ * @type {launcher.scenes.templates.about.AboutOut}
+ * @protected
+ */
launcher.scenes.About.prototype._exported;
diff --git a/app/launcher/scenes/about/about.jst b/app/launcher/scenes/about/about.jst
index 99442f9..01233d5 100644
--- a/app/launcher/scenes/about/about.jst
+++ b/app/launcher/scenes/about/about.jst
@@ -3,17 +3,17 @@
AppLauncher allows to run Smart TV and STB application avoiding standard application installation process.
- AppLauncher lets to create list of applications’ URLs to run.
+ AppLauncher lets to create list of applications URLs to run.
URLs are sorted according to last activities: adding or launching.
Attention:
- AppLauncher couldn’t check applications’ URLs before running them due to platform limitations.
+ AppLauncher couldn’t check applications URLs before running them due to platform limitations.
Be careful while entering URL. Improper URL can cause Smart TV/STB hang-up.
Reboot your Smart TV/STB in this situation.
Developed by Interfaced
-
site: interfaced.ru, e-mail: info@ifaced.ru
+
site: interfaced.tv, e-mail: info@interfaced.tv
diff --git a/app/launcher/scenes/abstract-base/abstract-base.css b/app/launcher/scenes/abstract-base/abstract-base.css
index d8723bf..d3758ce 100644
--- a/app/launcher/scenes/abstract-base/abstract-base.css
+++ b/app/launcher/scenes/abstract-base/abstract-base.css
@@ -12,7 +12,7 @@
font-size: 47px;
font-weight: bold;
}
- .s-abstract-base-head__made {
+ .s-abstract-base-head__version {
font-size: 23px;
margin-left: 5px;
}
@@ -33,6 +33,9 @@
.s-abstract-base-head__notice._remove {
background: #e78787;
}
+ .s-abstract-base-head__notice._change {
+ background: #f8d56e;
+ }
.s-abstract-base {}
.s-abstract-base .s-abstract-base-head {
diff --git a/app/launcher/scenes/abstract-base/abstract-base.js b/app/launcher/scenes/abstract-base/abstract-base.js
index 92c59f6..1730703 100644
--- a/app/launcher/scenes/abstract-base/abstract-base.js
+++ b/app/launcher/scenes/abstract-base/abstract-base.js
@@ -45,6 +45,16 @@ launcher.scenes.AbstractBase.prototype.processKey = function(zbKey, e) {
*/
launcher.scenes.AbstractBase.prototype._createHelpBar = function() {
this._helpBar = new zb.ui.HelpBar;
+ this._helpBar.setOrder([
+ zb.device.input.Keys.ENTER,
+ zb.device.input.Keys.PAGE_UP,
+ zb.device.input.Keys.PAGE_DOWN,
+ zb.device.input.Keys.RED,
+ zb.device.input.Keys.GREEN,
+ zb.device.input.Keys.YELLOW,
+ zb.device.input.Keys.BLUE,
+ zb.device.input.Keys.BACK
+ ]);
this._container.appendChild(this._helpBar.getContainer());
this.appendWidget(this._helpBar);
};
diff --git a/app/launcher/scenes/abstract-base/abstract-base.jst b/app/launcher/scenes/abstract-base/abstract-base.jst
index c9d18e2..8805794 100644
--- a/app/launcher/scenes/abstract-base/abstract-base.jst
+++ b/app/launcher/scenes/abstract-base/abstract-base.jst
@@ -3,7 +3,7 @@
AppLauncher
- by Interfaced
+ v.{{- zb.packageInfo.version }}
URL added
diff --git a/app/launcher/scenes/app-add/app-add-input-active.png b/app/launcher/scenes/app-add/app-add-input-active.png
new file mode 100644
index 0000000..4a19151
Binary files /dev/null and b/app/launcher/scenes/app-add/app-add-input-active.png differ
diff --git a/app/launcher/scenes/app-add/app-add-input.png b/app/launcher/scenes/app-add/app-add-input.png
new file mode 100644
index 0000000..58c7d1b
Binary files /dev/null and b/app/launcher/scenes/app-add/app-add-input.png differ
diff --git a/app/launcher/scenes/app-add/app-add.css b/app/launcher/scenes/app-add/app-add.css
index 7d15e28..8a77764 100644
--- a/app/launcher/scenes/app-add/app-add.css
+++ b/app/launcher/scenes/app-add/app-add.css
@@ -1,17 +1,30 @@
/* AppAdd scene
*******************************/
+.s-app-add-input-button {
+ background: url(app-add-input.png) 50% 50% no-repeat;
+ border: 2px solid #00809c;
+ border-radius: 12px;
+}
+
+.s-app-add-input-button._active {
+ background-color: #00809c;
+ background-image: url(app-add-input-active.png);
+}
+
.s-app-add-input {}
.s-app-add-input__title {
- text-align: center;
font-size: 23px;
font-weight: bold;
+ text-align: center;
}
.s-app-add-input__address {
position: relative;
margin-top: 8px;
}
- .s-app-add-input .w-button {
+ .s-app-add-input .s-app-add-input-button {
+ width: 60px;
+ height: 40px;
position: absolute;
top: 0;
left: 100%;
@@ -19,30 +32,29 @@
}
.s-app-add-input__input {
width: 100%;
- font-size: 23px;
+ font-size: 24px;
+ padding: 7px 0;
box-sizing: border-box;
- padding: 7px;
- padding-right: 0;
- border: 1px solid #022a33;
+ outline: 1px solid #022a33;
}
.s-app-add-input__input._active {
- box-shadow: 0 0 5px #00809c;
- }
- .s-app-add-input__input:focus {
- outline: none;
+ box-shadow: 0 0 8px 2px #00809c;
}
.s-app-add-input__warning {
font-size: 18px;
color: #00809c;
margin-top: 17px;
}
+ .s-app-add-input .w-zbui-div-input .w-zbui-div-input__wrapper {
+ margin-left: 7px;
+ }
.s-app-add {}
.s-app-add .s-app-add-input {
position: absolute;
top: 50px;
- left: 200px;
right: 200px;
+ left: 200px;
}
.s-app-add .w-keyboard {
position: absolute;
diff --git a/app/launcher/scenes/app-add/app-add.js b/app/launcher/scenes/app-add/app-add.js
index 4d182df..6ae913a 100644
--- a/app/launcher/scenes/app-add/app-add.js
+++ b/app/launcher/scenes/app-add/app-add.js
@@ -1,6 +1,7 @@
goog.provide('launcher.scenes.AppAdd');
goog.require('launcher.scenes.AbstractBase');
goog.require('launcher.scenes.templates.appAdd.appAdd');
+goog.require('zb.html');
@@ -9,6 +10,8 @@ goog.require('launcher.scenes.templates.appAdd.appAdd');
* @extends {launcher.scenes.AbstractBase}
*/
launcher.scenes.AppAdd = function() {
+ this._url = null;
+
goog.base(this);
this._addContainerClass('s-app-add');
this.setDefaultWidget(this._exported.input);
@@ -18,21 +21,49 @@ launcher.scenes.AppAdd = function() {
}.bind(this));
this._exported.input.on(this._exported.input.EVENT_FINISH, this._onInputFinish.bind(this));
+ this._exported.input.setTheme(this._exported.input.THEME_NONE);
this._exported.keyboard.setInput(this._exported.input);
- this.setNavigationRule(this._exported.keyboard, zb.Direction.RIGHT, null);
- this.setNavigationRule(this._exported.keyboard, zb.Direction.LEFT, null);
+ this.setNavigationRule(this._exported.keyboard, zb.std.plain.Direction.Value.RIGHT, null);
+ this.setNavigationRule(this._exported.keyboard, zb.std.plain.Direction.Value.LEFT, null);
};
goog.inherits(launcher.scenes.AppAdd, launcher.scenes.AbstractBase);
/**
+ * @param {launcher.scenes.AppAdd.Data} data
* @inheritDoc
*/
launcher.scenes.AppAdd.prototype.beforeDOMShow = function(state, data) {
goog.base(this, 'beforeDOMShow', state, data);
- this._exported.input.setValue('http://');
+
+ if (state) {
+ return;
+ }
+
+ var url = 'http://';
+ var title = 'New application URL';
+ var savedUrl = null;
+
+ if (data.url !== undefined) {
+ url = data.url;
+ savedUrl = data.url;
+ title = 'Edit application URL';
+ }
+
+ this._url = savedUrl;
+ this._exported.input.setValue(url);
+ zb.html.text(this._exported.title, title);
+};
+
+
+/**
+ * @inheritDoc
+ */
+launcher.scenes.AppAdd.prototype.afterDOMShow = function(state, data) {
+ goog.base(this, 'afterDOMShow', state, data);
+ this._exported.input.showCaret(true);
};
@@ -60,6 +91,17 @@ launcher.scenes.AppAdd.prototype._renderTemplate = function() {
};
+/**
+ * @inheritDoc
+ */
+launcher.scenes.AppAdd.prototype._processKey = function(zbKey, e) {
+ if (!this._exported.keyboard.processShortcutKey(zbKey)) {
+ return goog.base(this, '_processKey', zbKey, e);
+ }
+ return true;
+};
+
+
/**
* @param {string} eventName
* @param {string} url
@@ -68,7 +110,13 @@ launcher.scenes.AppAdd.prototype._renderTemplate = function() {
launcher.scenes.AppAdd.prototype._onInputFinish = function(eventName, url) {
if (url) {
this._exported.input.setValue('', true);
- app.services.appList.addApp(url);
+
+ if (this._url !== null) {
+ app.services.appList.changeApp(this._url, url);
+ } else {
+ app.services.appList.addApp(url);
+ }
+
if (app.canBack()) {
app.back();
} else {
@@ -95,3 +143,24 @@ launcher.scenes.AppAdd.prototype._pressBack = function() {
* @protected
*/
launcher.scenes.AppAdd.prototype._exported;
+
+
+/**
+* @type {?string}
+* @protected
+*/
+launcher.scenes.AppAdd.prototype._url;
+
+
+/**
+ * @typedef {{
+ * url: (string|undefined)
+ * }}
+ */
+launcher.scenes.AppAdd.Input;
+
+
+/**
+ * @typedef {launcher.scenes.AppAdd.Input}
+ */
+launcher.scenes.AppAdd.Data;
diff --git a/app/launcher/scenes/app-add/app-add.jst b/app/launcher/scenes/app-add/app-add.jst
index ec01e33..db55984 100644
--- a/app/launcher/scenes/app-add/app-add.jst
+++ b/app/launcher/scenes/app-add/app-add.jst
@@ -1,10 +1,10 @@
{{$ launcher.scenes.templates.appAdd.appAdd }}
diff --git a/app/launcher/scenes/app-list/app-list.css b/app/launcher/scenes/app-list/app-list.css
index 48b621a..3e99a3e 100644
--- a/app/launcher/scenes/app-list/app-list.css
+++ b/app/launcher/scenes/app-list/app-list.css
@@ -9,3 +9,20 @@
right: 0;
left: 0;
}
+
+ .s-app-list__throbber-container {
+ width: 100%;
+ height: 100%;
+ background: rgba(0, 0, 0, 0.5);
+ display: none;
+ position: absolute;
+ top: 0;
+ left: 0;
+ }
+ .s-app-list__throbber-container .w-zbui-throbber {
+ position: absolute;
+ top: 50%;
+ left: 50%;
+ margin-top: -44px;
+ margin-left: -44px;
+ }
diff --git a/app/launcher/scenes/app-list/app-list.js b/app/launcher/scenes/app-list/app-list.js
index 143a582..9ff21d6 100644
--- a/app/launcher/scenes/app-list/app-list.js
+++ b/app/launcher/scenes/app-list/app-list.js
@@ -16,26 +16,24 @@ launcher.scenes.AppList = function() {
this._addContainerClass('s-app-list');
this._appList = new zb.ui.DataList;
- this._exported.appList.setDataList(this._appList, {
- padding: this.COUNT_APPS_ON_PAGE - 1
+ this._exported.appList.setSource(this._appList, {
+ padding: this.COUNT_APPS_ON_PAGE
});
this._exported.appList.on(this._exported.appList.EVENT_CLICK, this._onAppClick.bind(this));
- app.services.appList.on(app.services.appList.EVENT_APP_LIST_CHANGED, this._setApps.bind(this));
- app.services.appList.on(app.services.appList.EVENT_APP_REMOVED, this._notice.showRemoved.bind(this._notice));
- app.services.appList.on(app.services.appList.EVENT_APP_ADDED, this._notice.showAdded.bind(this._notice));
-};
-goog.inherits(launcher.scenes.AppList, launcher.scenes.AbstractBase);
+ app.services.appList.on(app.services.appList.EVENT_APP_REMOVED, this._onAppRemoved.bind(this));
+ app.services.appList.on(app.services.appList.EVENT_APP_ADDED, this._onAppAdded.bind(this));
+ app.services.appList.on(app.services.appList.EVENT_APP_CHANGED, this._onAppChanged.bind(this));
+ this._appList.setItems(app.services.appList.getApps());
-/**
- * @inheritDoc
- */
-launcher.scenes.AppList.prototype.afterDOMShow = function(state, data) {
- goog.base(this, 'afterDOMShow', state, data);
+ // Prevent save/load state for app list.
+ delete this._namedWidgets['appList'];
- this._appList.setItems(app.services.appList.getApps());
+ this._configureThrobber();
+ this._updateHelpBar();
};
+goog.inherits(launcher.scenes.AppList, launcher.scenes.AbstractBase);
/**
@@ -59,9 +57,10 @@ launcher.scenes.AppList.prototype._createHelpBar = function() {
this._paginationHelpBarItem.hide();
helpBar.setItems([
- factory.createOk(this._executeApp.bind(this)),
+ factory.createOk(this._executeCurrentApp.bind(this)),
factory.createBack(),
factory.createRemoveApp(this._removeApp.bind(this)),
+ factory.createEditApp(this._editApp.bind(this)),
factory.createAddApp(this._addApp.bind(this)),
factory.createAbout(),
this._paginationHelpBarItem
@@ -85,16 +84,25 @@ launcher.scenes.AppList.prototype._updateHelpBar = function() {
* @private
*/
launcher.scenes.AppList.prototype._onAppClick = function(eventName, appView) {
- app.services.appList.executeApp(appView.url);
+ this._executeApp(appView.url);
+};
+
+
+/**
+ * @private
+ */
+launcher.scenes.AppList.prototype._executeCurrentApp = function() {
+ this._executeApp(this._getCurrentAppUrl());
};
/**
+ * @param {string} url
* @private
*/
-launcher.scenes.AppList.prototype._executeApp = function() {
- var application = this._exported.appList.getCurrentData();
- app.services.appList.executeApp(application.url);
+launcher.scenes.AppList.prototype._executeApp = function(url) {
+ var promise = app.services.appList.executeApp(url);
+ this._exported.throbber.wait(promise);
};
@@ -102,17 +110,17 @@ launcher.scenes.AppList.prototype._executeApp = function() {
* @private
*/
launcher.scenes.AppList.prototype._removeApp = function() {
- var currentApp = this._appList.current();
- if (!currentApp) {
+ var url = this._getCurrentAppUrl();
+ if (!url) {
return;
}
launcher.popups.Confirm
.asPromise({
- url: currentApp.url
+ url: url
})
.then(function() {
- app.services.appList.removeApp(currentApp.url);
+ app.services.appList.removeApp(url);
var appList = app.services.appList.getApps();
if (!appList.length) {
app.show('app-add', {});
@@ -129,13 +137,70 @@ launcher.scenes.AppList.prototype._addApp = function() {
};
+/**
+ * @private
+ */
+launcher.scenes.AppList.prototype._editApp = function() {
+ var url = this._getCurrentAppUrl();
+ if (!url) {
+ return;
+ }
+
+ app.show('app-add', {url: url});
+};
+
+
+/**
+ * @return {string}
+ * @protected
+ */
+launcher.scenes.AppList.prototype._getCurrentAppUrl = function() {
+ var currentApp = this._appList.current();
+ if (!currentApp) {
+ return '';
+ }
+
+ return currentApp.url;
+};
+
+
+/**
+ * @param {string} eventName
+ * @param {number} index
+ * @param {string} url
+ * @private
+ */
+launcher.scenes.AppList.prototype._onAppRemoved = function(eventName, index, url) {
+ this._notice.showRemoved();
+ this._appList.removeAt(index);
+ this._updateHelpBar();
+};
+
+
/**
* @param {string} eventName
- * @param {Array.} apps
+ * @param {number} index
+ * @param {string} url
* @private
*/
-launcher.scenes.AppList.prototype._setApps = function(eventName, apps) {
- this._appList.setItems(apps);
+launcher.scenes.AppList.prototype._onAppAdded = function(eventName, index, url) {
+ var appItem = /** @type {!launcher.services.AppList.AppView} */(app.services.appList.getAppByIndex(index));
+ this._notice.showAdded();
+ this._appList.addAt(appItem, index);
+ this._appList.selectAt(index);
+ this._updateHelpBar();
+};
+
+
+/**
+ * @param {string} eventName
+ * @param {number} index
+ * @param {string} newUrl
+ * @param {string} oldUrl
+ * @private
+ */
+launcher.scenes.AppList.prototype._onAppChanged = function(eventName, index, newUrl, oldUrl) {
+ this._notice.showChanged();
this._updateHelpBar();
};
@@ -175,6 +240,21 @@ launcher.scenes.AppList.prototype._showHidePaginationHelpBarItem = function(show
};
+/**
+ * @protected
+ */
+launcher.scenes.AppList.prototype._configureThrobber = function() {
+ var throbber = this._exported.throbber;
+ throbber.on(throbber.EVENT_START, function() {
+ this._exported.throbberContainer.style.display = 'block';
+ }.bind(this));
+ throbber.on(throbber.EVENT_STOP, function() {
+ this._exported.throbberContainer.style.display = 'none';
+ }.bind(this));
+ this._container.appendChild(this._exported.throbberContainer);
+};
+
+
/**
* @type {launcher.scenes.templates.appList.AppListOut}
* @protected
@@ -199,4 +279,4 @@ launcher.scenes.AppList.prototype._paginationHelpBarItem;
/**
* @const {number}
*/
-launcher.scenes.AppList.prototype.COUNT_APPS_ON_PAGE = 10;
+launcher.scenes.AppList.prototype.COUNT_APPS_ON_PAGE = 9;
diff --git a/app/launcher/scenes/app-list/app-list.jst b/app/launcher/scenes/app-list/app-list.jst
index d021478..5b44791 100644
--- a/app/launcher/scenes/app-list/app-list.jst
+++ b/app/launcher/scenes/app-list/app-list.jst
@@ -1,3 +1,7 @@
{{$ launcher.scenes.templates.appList.appList }}
{{% launcher.widgets.AppList, {}, appList }}
+
+
+ {{% zb.ui.Throbber, {}, throbber }}
+
diff --git a/app/launcher/services/app-list.js b/app/launcher/services/app-list.js
index 7e522ef..de14c08 100644
--- a/app/launcher/services/app-list.js
+++ b/app/launcher/services/app-list.js
@@ -16,25 +16,53 @@ launcher.services.AppList = function(storage) {
goog.inherits(launcher.services.AppList, zb.events.EventPublisher);
+/**
+ * @param {string} oldUrl
+ * @param {string} newUrl
+ * @return {boolean}
+ */
+launcher.services.AppList.prototype.changeApp = function(oldUrl, newUrl) {
+ this._logEvent('app-change');
+ var index = this._findAppByUrl(oldUrl);
+ if (-1 !== index) {
+ this._apps[index].url = newUrl;
+
+ // move to first position
+ var app = this._apps[index];
+ this._apps.splice(index, 1);
+ this._fireEvent(this.EVENT_APP_REMOVED, index, newUrl);
+ this._apps.splice(index, 0, app);
+ this._fireEvent(this.EVENT_APP_ADDED, index, newUrl);
+
+ this._fireEvent(this.EVENT_APP_CHANGED, newUrl, oldUrl);
+
+ this._saveApps();
+ return true;
+ }
+ return false;
+};
+
+
/**
* @param {string} url
*/
launcher.services.AppList.prototype.addApp = function(url) {
+ this._logEvent('app-add');
var index = this._findAppByUrl(url);
if (-1 !== index) {
- // prevent url duplication
- return;
+ this.removeApp(url);
}
/** @type {launcher.services.AppList.AppView} */
var app = {
url: url,
- launchTime: Date.now(),
+ launchTime: NaN,
launchCount: 0
};
+ this._touchApp(app);
this._apps.unshift(app);
+ this._fireEvent(this.EVENT_APP_ADDED, 0, url);
this._saveApps();
- this._fireEvent(this.EVENT_APP_ADDED, url);
};
@@ -42,28 +70,52 @@ launcher.services.AppList.prototype.addApp = function(url) {
* @param {string} url
*/
launcher.services.AppList.prototype.removeApp = function(url) {
+ this._logEvent('app-remove');
var index = this._findAppByUrl(url);
if (-1 !== index) {
this._apps.splice(index, 1);
+ this._fireEvent(this.EVENT_APP_REMOVED, index, url);
this._saveApps();
- this._fireEvent(this.EVENT_APP_REMOVED, url);
}
};
/**
* @param {string} url
+ * @return {IThenable}
*/
launcher.services.AppList.prototype.executeApp = function(url) {
+ this._logEvent('app-execute');
var app = this._apps[this._findAppByUrl(url)];
if (app) {
app.launchCount++;
- app.launchTime = Date.now();
+ this._touchApp(app);
this._saveApps();
}
- this._replaceUrl(url);
+ return new Promise(function(resolve, reject) {
+ // never resolve promise while new page is not loaded
+ this._replaceUrl(url);
+ }.bind(this));
+};
+
+
+/**
+ * @param {number} index
+ * @return {?launcher.services.AppList.AppView}
+ */
+launcher.services.AppList.prototype.getAppByIndex = function(index) {
+ return this._apps[index] || null;
+};
+
+
+/**
+ * @param {string} url
+ * @return {?launcher.services.AppList.AppView}
+ */
+launcher.services.AppList.prototype.getAppByUrl = function(url) {
+ return this._apps[this._findAppByUrl(url)] || null;
};
@@ -78,6 +130,23 @@ launcher.services.AppList.prototype.getApps = function() {
};
+/**
+ * @param {string} eventName
+ * @private
+ */
+launcher.services.AppList.prototype._logEvent = function(eventName) {
+ app.services.ga.sendEvent('app', eventName);
+};
+
+
+/**
+ * @param {launcher.services.AppList.AppView} app
+ */
+launcher.services.AppList.prototype._touchApp = function(app) {
+ app.launchTime = Date.now();
+};
+
+
/**
* @param {string} url
* @return {number}
@@ -179,14 +248,21 @@ launcher.services.AppList.prototype.STORAGE_KEY = 'app-launcher-list';
/**
- * Fired with: {string} url
+ * Fired with: {number} index, {string} url
* @const {string}
*/
launcher.services.AppList.prototype.EVENT_APP_ADDED = 'app-added';
/**
- * Fired with: {string} url
+ * Fired with: {number} index, {string} newUrl, {string} oldUrl
+ * @const {string}
+ */
+launcher.services.AppList.prototype.EVENT_APP_CHANGED = 'app-changed';
+
+
+/**
+ * Fired with: {number} index, {string} url
* @const {string}
*/
launcher.services.AppList.prototype.EVENT_APP_REMOVED = 'app-removed';
diff --git a/app/launcher/services/help-bar-item-factory.js b/app/launcher/services/help-bar-item-factory.js
index aee34a2..ea3cb4c 100644
--- a/app/launcher/services/help-bar-item-factory.js
+++ b/app/launcher/services/help-bar-item-factory.js
@@ -51,13 +51,26 @@ launcher.services.HelpBarItemFactory.prototype.createRemoveApp = function(opt_ha
};
+/**
+ * @param {Function=} opt_handler
+ * @return {zb.ui.HelpBarItem}
+ */
+launcher.services.HelpBarItemFactory.prototype.createEditApp = function(opt_handler) {
+ return this._createHelpBarItem({
+ label: 'edit selected',
+ keys: [zb.device.input.Keys.YELLOW],
+ cssClass: '_yellow'
+ }, opt_handler);
+};
+
+
/**
* @param {Function=} opt_handler
* @return {zb.ui.HelpBarItem}
*/
launcher.services.HelpBarItemFactory.prototype.createAddApp = function(opt_handler) {
return this._createHelpBarItem({
- label: 'add application',
+ label: 'add URL',
keys: [zb.device.input.Keys.GREEN],
cssClass: '_green'
}, opt_handler);
@@ -84,7 +97,7 @@ launcher.services.HelpBarItemFactory.prototype.createAbout = function(opt_handle
*/
launcher.services.HelpBarItemFactory.prototype.createPagination = function(opt_handler) {
return this._createHelpBarItem({
- label: 'page up/page down',
+ label: 'page up/down',
keys: [zb.device.input.Keys.PAGE_UP, zb.device.input.Keys.PAGE_DOWN],
cssClass: '_pagination'
}, opt_handler);
diff --git a/app/launcher/widgets/app-list/app-list.css b/app/launcher/widgets/app-list/app-list.css
index 01ec5d8..6cbcf17 100644
--- a/app/launcher/widgets/app-list/app-list.css
+++ b/app/launcher/widgets/app-list/app-list.css
@@ -35,7 +35,7 @@
}
.w-app-list._active .w-app-list-item._active .w-app-list-item__shad {
border-color: #c3e1e8;
- box-shadow: 0 0 8px #00809c;
+ box-shadow: 0 0 8px 1px #00809c;
}
.w-app-list {
diff --git a/app/launcher/widgets/button/button.js b/app/launcher/widgets/button/button.js
index f7c068f..f5b1bea 100644
--- a/app/launcher/widgets/button/button.js
+++ b/app/launcher/widgets/button/button.js
@@ -4,6 +4,7 @@ goog.require('zb.ui.Button');
/**
+ * @deprecated as redundant
* @inheritDoc
* @extends {zb.ui.Button}
* @constructor
diff --git a/app/launcher/widgets/help-bar/help-bar-item-pagination.png b/app/launcher/widgets/help-bar/help-bar-item-pagination.png
index bade7c8..403a22e 100644
Binary files a/app/launcher/widgets/help-bar/help-bar-item-pagination.png and b/app/launcher/widgets/help-bar/help-bar-item-pagination.png differ
diff --git a/app/launcher/widgets/help-bar/help-bar-item-yellow.png b/app/launcher/widgets/help-bar/help-bar-item-yellow.png
new file mode 100644
index 0000000..cd66ee5
Binary files /dev/null and b/app/launcher/widgets/help-bar/help-bar-item-yellow.png differ
diff --git a/app/launcher/widgets/help-bar/help-bar.css b/app/launcher/widgets/help-bar/help-bar.css
index 8e49424..2dc945d 100644
--- a/app/launcher/widgets/help-bar/help-bar.css
+++ b/app/launcher/widgets/help-bar/help-bar.css
@@ -3,35 +3,58 @@
.w-help-bar-item {
background-repeat: no-repeat;
- background-position: 0 50%;
- line-height: 43px;
+ background-position: 4px 50%;
+ line-height: 30px;
+ border-radius: 5px;
}
+
.w-help-bar-item._back {
background-image: url(help-bar-item-back.png);
- padding-left: 22px;
+ padding-left: 26px;
+ padding-right: 7px;
+}
+
+.w-help-bar-item._pagination,
+.w-help-bar-item._ok {
+ padding-left: 40px;
+ padding-right: 7px;
}
+
.w-help-bar-item._pagination {
background-image: url(help-bar-item-pagination.png);
- padding-left: 24px;
}
+
.w-help-bar-item._ok {
background-image: url(help-bar-item-ok.png);
- padding-left: 36px;
}
+
+.w-help-bar-item._red,
+.w-help-bar-item._green,
+.w-help-bar-item._yellow,
+.w-help-bar-item._blue {
+ padding-left: 43px;
+ padding-right: 7px;
+}
+
.w-help-bar-item._red {
background-image: url(help-bar-item-red.png);
- padding-left: 39px;
}
+
.w-help-bar-item._green {
background-image: url(help-bar-item-green.png);
- padding-left: 39px;
}
+
+.w-help-bar-item._yellow {
+ background-image: url(help-bar-item-yellow.png);
+}
+
.w-help-bar-item._blue {
background-image: url(help-bar-item-blue.png);
- padding-left: 39px;
}
+
.w-help-bar-item._active {
- color: #00809c;
+ background-color: #00809c;
+ color: #fff;
}
.w-help-bar {
diff --git a/app/launcher/widgets/keyboard/keyboard.css b/app/launcher/widgets/keyboard/keyboard.css
index c280436..4310c82 100644
--- a/app/launcher/widgets/keyboard/keyboard.css
+++ b/app/launcher/widgets/keyboard/keyboard.css
@@ -11,6 +11,26 @@
border: 2px solid #00809c;
border-radius: 12px;
}
+
+.w-keyboard-item._yellow,
+.w-keyboard-item._red,
+.w-keyboard-item._green {
+ color: #fff;
+ border-color: transparent;
+}
+
+.w-keyboard-item._yellow {
+ background-color: #e5d202;
+}
+
+.w-keyboard-item._red {
+ background-color: #d10b0b;
+}
+
+.w-keyboard-item._green {
+ background-color: #0f8200;
+}
+
.w-keyboard-item._service {
width: 64px;
height: 44px;
@@ -28,18 +48,25 @@
border: 1px solid #00809c;
border-radius: 10px;
}
+
.w-keyboard-item._backspace,
.w-keyboard-item._type {
width: 70px;
}
+
.w-keyboard-item._caps {
background: url(keyboard-item-caps.png) 50% 50% no-repeat;
}
+
.w-keyboard-item._active {
background-color: #00809c;
color: #fff;
}
+.w-keyboard-item._switch-keyboard {
+ font-size: 24px;
+}
+
.w-keyboard {}
.w-keyboard__line {
text-align: center;
diff --git a/app/launcher/widgets/keyboard/keyboard.js b/app/launcher/widgets/keyboard/keyboard.js
index 4cc8d70..e8415b2 100644
--- a/app/launcher/widgets/keyboard/keyboard.js
+++ b/app/launcher/widgets/keyboard/keyboard.js
@@ -27,6 +27,34 @@ launcher.widgets.Keyboard.prototype._renderTemplate = function() {
};
+/**
+ * @param {zb.device.input.Keys} zbKey
+ * @return {boolean}
+ */
+launcher.widgets.Keyboard.prototype.processShortcutKey = function(zbKey) {
+ var zbKeys = zb.device.input.Keys;
+ var zbCharKey = app.device.input.keyToPrintableChar(zbKey);
+
+ switch (zbKey) {
+ case zbKeys.RED:
+ this._setSymbol('.');
+ return true;
+ case zbKeys.GREEN:
+ this._setSymbol(':');
+ return true;
+ case zbKeys.YELLOW:
+ this._setSymbol('/');
+ return true;
+ default:
+ if (zbCharKey !== null) {
+ this._setSymbol(zbCharKey);
+ return true;
+ }
+ return false;
+ }
+};
+
+
/**
* @inheritDoc
*/
diff --git a/app/launcher/widgets/keyboard/keyboard.jst b/app/launcher/widgets/keyboard/keyboard.jst
index f9f43fc..ff8cc53 100644
--- a/app/launcher/widgets/keyboard/keyboard.jst
+++ b/app/launcher/widgets/keyboard/keyboard.jst
@@ -4,16 +4,19 @@
- {{ "1 2 3 4 5 6 7 8 9 0 : .".split(" ").forEach(function(sym) { }}
+ {{ "1 2 3 4 5 6 7 8 9 0".split(" ").forEach(function(sym) { }}
{{=sym}}
{{ }); }}
+
.
+
:
- {{ "? q w e r t y u i o p /".split(" ").forEach(function(sym) { }}
+ {{ "? q w e r t y u i o p".split(" ").forEach(function(sym) { }}
{{=sym}}
{{ }); }}
+
/
@@ -22,7 +25,9 @@
{{ "a s d f g h j k l".split(" ").forEach(function(sym) { }}
{{=sym}}
{{ }); }}
-
123
+
+ #%&
+
@@ -47,7 +52,7 @@
{{ "- _ = + ~ , ; !".split(" ").forEach(function(sym) { }}
{{=sym}}
{{ }); }}
-
ABC
+
ABC
<
diff --git a/app/launcher/widgets/notice/notice.js b/app/launcher/widgets/notice/notice.js
index 132f000..e7d3f71 100644
--- a/app/launcher/widgets/notice/notice.js
+++ b/app/launcher/widgets/notice/notice.js
@@ -34,25 +34,40 @@ launcher.widgets.Notice.prototype.isFocusable = function() {
/**
*/
launcher.widgets.Notice.prototype.showAdded = function() {
- this.open(true);
+ this.open(launcher.widgets.Notice.State.ADDED);
zb.html.text(this._container, 'URL added');
};
+/**
+ */
+launcher.widgets.Notice.prototype.showChanged = function() {
+ this.open(launcher.widgets.Notice.State.CHANGED);
+ zb.html.text(this._container, 'URL edited');
+};
+
+
/**
*/
launcher.widgets.Notice.prototype.showRemoved = function() {
- this.open(false);
+ this.open(launcher.widgets.Notice.State.REMOVED);
zb.html.text(this._container, 'URL removed');
};
/**
- * @param {boolean} isAdded
+ * @param {launcher.widgets.Notice.State} state
*/
-launcher.widgets.Notice.prototype.open = function(isAdded) {
- zb.html.updateClassName(this._container, launcher.widgets.Notice.State.ADDED, isAdded);
- zb.html.updateClassName(this._container, launcher.widgets.Notice.State.REMOVED, !isAdded);
+launcher.widgets.Notice.prototype.open = function(state) {
+ var allClasses = Object.keys(launcher.widgets.Notice.State)
+ .map(function(key) {
+ return launcher.widgets.Notice.State[key];
+ });
+
+ allClasses.forEach(function(cssClass) {
+ zb.html.updateClassName(this._container, cssClass, cssClass === state);
+ }, this);
+
zb.html.show(this._container);
this._timeout.restart();
};
@@ -77,5 +92,6 @@ launcher.widgets.Notice.prototype._timeout;
*/
launcher.widgets.Notice.State = {
ADDED: '_add',
- REMOVED: '_remove'
+ REMOVED: '_remove',
+ CHANGED: '_change'
};
diff --git a/custom-platforms/dune/template/root/logo.png b/custom-platforms/dune/template/root/logo.png
index 149d3e5..1b83b9d 100644
Binary files a/custom-platforms/dune/template/root/logo.png and b/custom-platforms/dune/template/root/logo.png differ
diff --git a/custom-platforms/eltex/template/root/logo.png b/custom-platforms/eltex/template/root/logo.png
index 2afa1ac..d72bb42 100755
Binary files a/custom-platforms/eltex/template/root/logo.png and b/custom-platforms/eltex/template/root/logo.png differ
diff --git a/custom-platforms/eltex/template/root/logo_small.png b/custom-platforms/eltex/template/root/logo_small.png
index e417394..59ee1d0 100755
Binary files a/custom-platforms/eltex/template/root/logo_small.png and b/custom-platforms/eltex/template/root/logo_small.png differ
diff --git a/custom-platforms/samsung/icons/106x87.png b/custom-platforms/samsung/icons/106x87.png
index 8dbe353..50e8d57 100644
Binary files a/custom-platforms/samsung/icons/106x87.png and b/custom-platforms/samsung/icons/106x87.png differ
diff --git a/custom-platforms/samsung/icons/115x95.png b/custom-platforms/samsung/icons/115x95.png
index 34a5f48..f793a42 100644
Binary files a/custom-platforms/samsung/icons/115x95.png and b/custom-platforms/samsung/icons/115x95.png differ
diff --git a/custom-platforms/samsung/icons/85x70.png b/custom-platforms/samsung/icons/85x70.png
index 9e09d9f..73792ce 100644
Binary files a/custom-platforms/samsung/icons/85x70.png and b/custom-platforms/samsung/icons/85x70.png differ
diff --git a/custom-platforms/samsung/icons/95x78.png b/custom-platforms/samsung/icons/95x78.png
index a573cc4..8a7763e 100644
Binary files a/custom-platforms/samsung/icons/95x78.png and b/custom-platforms/samsung/icons/95x78.png differ
diff --git a/docs/eltex-eng.md b/docs/eltex-eng.md
index 1f0e239..fa77dc8 100644
--- a/docs/eltex-eng.md
+++ b/docs/eltex-eng.md
@@ -1,9 +1,11 @@
Installation guide for Eltex STB
--------------------------------
+### Eltex STB NV-10x
+
1. Copy folder with application to USB flash drive.
-2. Download libstbbrowser.so from http://download.eltex-media.ru/nv/nv300/plugins/libstbbrowser.so and copy it to folder with application.
+2. Download libstbbrowser.so from http://download.eltex-media.ru/nv/nv102/plugins/libstbbrowser.so and copy it to folder with application.
3. Plug USB flash drive into STB.
@@ -15,15 +17,47 @@ Installation guide for Eltex STB
5. Enter commands:
- `mount -o remount,rw /sdk`
+ ```
+ mount -o remount,rw /sdk
+ cd /sdk/qt-install-4.7.0/STBGUI_PLUGIN/
+ cp -r /mnt/stb/local/$flash_drive/$path_to_appLauncher appLauncher
+ sync
+ reboot
+ ```
+
+ where
- `cd /sdk/qt-install-4.7.0/STBGUI_PLUGIN/`
+ `$flash_drive` - flash drive's name in the system,
- `cp -r /mnt/stb/local/$flash_drive/$path_to_appLauncher appLauncher`
+ `$path_to_appLauncher` - path to the distrib folder.
- `sync`
+6. Application will be available in the main menu.
+
+### Eltex STB NV-300
- `reboot`
+1. Copy folder with application to USB flash drive.
+
+2. Download libstbbrowser.so from http://download.eltex-media.ru/nv/nv300/plugins/libstbbrowser.so and copy it to folder with application.
+
+3. Plug USB flash drive into STB.
+
+4. Connect to STB via SSH:
+
+ **login:** root,
+
+ **password:** is generated from STB serial number:
+ - Generator for Windows http://download.eltex-media.ru/nv/psswdgen/PSSWDGen_win.zip
+ - Generator for Linux http://download.eltex-media.ru/nv/psswdgen/PSSWDGen-linux-x86_64
+
+5. Enter commands:
+
+ ```
+ mount -o remount,rw /sdk
+ cd /usr/local/bin/stbgui/
+ cp -r /mnt/stb/local/$flash_drive/$path_to_appLauncher appLauncher
+ sync
+ reboot
+ ```
where
@@ -31,4 +65,4 @@ Installation guide for Eltex STB
`$path_to_appLauncher` - path to the distrib folder.
-6. Application will be available in the main menu.
+6. Application will be available in the main menu.
\ No newline at end of file
diff --git a/docs/eltex-rus.md b/docs/eltex-rus.md
index 9c42a83..a175743 100644
--- a/docs/eltex-rus.md
+++ b/docs/eltex-rus.md
@@ -1,9 +1,11 @@
Руководство по установке приложений на Eltex STB
--------------------------------
+### Eltex STB NV-10x
+
1. Скопировать папку с приложением на USB флэш диск.
-2. Скачать libstbbrowser.so с http://download.eltex-media.ru/nv/nv300/plugins/libstbbrowser.so и скопировать его в папку с приложением.
+2. Скачать libstbbrowser.so с http://download.eltex-media.ru/nv/nv102/plugins/libstbbrowser.so и скопировать его в папку с приложением.
3. Вставить USB флэш диск в приставку.
@@ -15,15 +17,47 @@
5. Ввести команды:
- `mount -o remount,rw /sdk`
+ ```
+ mount -o remount,rw /sdk
+ cd /sdk/qt-install-4.7.0/STBGUI_PLUGIN/
+ cp -r /mnt/stb/local/$flash_drive/$path_to_appLauncher appLauncher
+ sync
+ reboot
+ ```
+
+ где
+
+ `$flash_drive` - наименование флэш диска в системе,
+
+ `$path_to_appLauncher` - путь до папки с приложением.
+
+6. Приложение станет доступным в главном меню.
+
+### Eltex STB NV-300
+
+1. Скопировать папку с приложением на USB флэш диск.
+
+2. Скачать libstbbrowser.so с http://download.eltex-media.ru/nv/nv300/plugins/libstbbrowser.so и скопировать его в папку с приложением.
+
+3. Вставить USB флэш диск в приставку.
- `cd /sdk/qt-install-4.7.0/STBGUI_PLUGIN/`
+4. Присоединиться к приставке через SSH:
- `cp -r /mnt/stb/local/$flash_drive/$path_to_appLauncher appLauncher`
+ **login:** root,
- `sync`
+ **password:** генерируется на основе серийного номера приставки:
+ - генератор паролей под Windows http://download.eltex-media.ru/nv/psswdgen/PSSWDGen_win.zip
+ - генератор паролей под Linux http://download.eltex-media.ru/nv/psswdgen/PSSWDGen-linux-x86_64
+
+5. Ввести команды:
- `reboot`
+ ```
+ mount -o remount,rw /sdk
+ cd /usr/local/bin/stbgui/
+ cp -r /mnt/stb/local/$flash_drive/$path_to_appLauncher appLauncher
+ sync
+ reboot
+ ```
где
diff --git a/docs/lg-netcast-eng.md b/docs/lg-netcast-eng.md
index 1f616cd..7a31382 100644
--- a/docs/lg-netcast-eng.md
+++ b/docs/lg-netcast-eng.md
@@ -5,16 +5,43 @@ Installation guide for LG NetCast Smart TV
### 2012
-1. Plug Ethernet cable to connect your TV to Internet.
+- Login
-2. Unzip your application zip archive to folder `lgapps\installed` of USB flash drive.
+ 1. Plug Ethernet cable to connect your TV to Internet.
+
+ 2. Press **HOME** home remote button.
+
+ 3. Select icon with man silhouette in the right top corner.
-3. Plug flash drive into TV.
+ 4. (if you don't have account) Press **red** remote button.
-4. Press **MY APPS** remote button, press **OK** remote button.
+ 5. (if you don't have account) Select two times **Agree**.
-5. OR press **HOME** remote button, select **My Apps**, press **OK** remote button.
+ 6. (if you don't have account) Enter **E-mail**, **Password**.
-6. Select USB icon in the top-right corner near free space counter.
+ 7. (if you don't have account) Select **Check validity**.
-7. Select your application.
+ 8. (if you don't have account) Select **OK**.
+
+ 9. (if you don't have account) Check e-mail which you entered as ID and
+ confirm registration.
+
+
+ 10. Enter **ID or e-mail** and **Password** and select **Sign In**.
+
+- Launch on TV
+
+ 1. Unzip your application zip archive to folder `lgapps\installed` of NTFS formatted USB flash drive.
+
+ 2. Plug flash drive into TV into USB connector marked **USB Apps**.
+
+ 3. Press **MY APPS** remote button, press **OK** remote button.
+
+ 4. OR press **HOME** remote button, select **My Apps**, press **OK** remote button.
+
+ 5. Select USB icon in the top-right corner near free space counter.
+
+ 6. Select your application.
+
+
+**Note:** USB flash drive must be formatted into NTFS.
\ No newline at end of file
diff --git a/docs/lg-netcast-rus.md b/docs/lg-netcast-rus.md
index a6b2eb9..24b356d 100644
--- a/docs/lg-netcast-rus.md
+++ b/docs/lg-netcast-rus.md
@@ -5,16 +5,43 @@
### 2012
-1. Вставить сетевой кабель в телевизор, чтобы подключить его к Интернет.
+- Вход в систему
-2. Распаковать zip архив с приложением в папку `lgapps\installed` USB флэш диска.
+ 1. Вставить сетевой кабель в телевизор, чтобы подключить его к Интернет.
+
+ 2. Нажать на пульте кнопку **HOME**.
+
+ 3. Выбрать иконку с человечком в правом верхнем углу экрана.
-3. Вставить USB флэш диск в телевизор.
+ 4. (если у вас нет аккаунта) Нажать на пульте **Красную кнопку**.
-4. Нажать на пульте кнопку **MY APPS**, нажать на пульте кнопку **OK**.
+ 5. (если у вас нет аккаунта) Выбрать **Согласен** два раза.
-5. ИЛИ нажать на пульте кнопку **HOME**, выбрать **Мои приложения**, нажать на пульте кнопку **OK**.
+ 6. (если у вас нет аккаунта) Ввести **E-mail**, **Пароль**.
-6. Выбрать иконку USB в правой верхней части экрана рядом с указателем свободного места.
+ 7. (если у вас нет аккаунта) Выбрать **Проверка подлинности**.
-7. Выбрать установленное приложение.
+ 8. (если у вас нет аккаунта) Выбрать **OK**.
+
+ 9. (если у вас нет аккаунта) Проверить электронную почту, которую вы ввели
+ в качестве идентфикатора, и подтвердить регистрацию.
+
+ 10. Ввести **ID или e-mail** и **Пароль** и выбрать **Войти**.
+
+
+- Запуск на телевизоре
+
+ 2. Распаковать zip архив с приложением в папку `lgapps\installed` USB флэш диска, отформатированного под NTFS.
+
+ 3. Вставить USB флэш диск в телевизор в разъем, подписанный **USB Apps**.
+
+ 4. Нажать на пульте кнопку **MY APPS**, нажать на пульте кнопку **OK**.
+
+ 5. ИЛИ нажать на пульте кнопку **HOME**, выбрать **Мои приложения**, нажать на пульте кнопку **OK**.
+
+ 6. Выбрать иконку USB в правой верхней части экрана рядом с указателем свободного места.
+
+ 7. Выбрать установленное приложение.
+
+
+**Примечание:** USB флэш диск должен быть отформатирован под NTFS.
diff --git a/docs/lg-webos-eng.md b/docs/lg-webos-eng.md
index 785ada2..257693a 100644
--- a/docs/lg-webos-eng.md
+++ b/docs/lg-webos-eng.md
@@ -31,7 +31,7 @@ Installation guide for LG webOS SmartTV
- Launch on TV
1. Unzip your application zip archive to folder
- `developer\apps\usr\palm\applications\` of USB flash drive
+ `developer\apps\usr\palm\applications\` of NTFS formatted USB flash drive.
2. Plug flash drive into TV.
diff --git a/docs/lg-webos-rus.md b/docs/lg-webos-rus.md
index b6bf622..2ede28e 100644
--- a/docs/lg-webos-rus.md
+++ b/docs/lg-webos-rus.md
@@ -23,7 +23,7 @@
7. (если у вас нет аккаунта) Выбрать **OK**.
8. (если у вас нет аккаунта) Проверить электронную почту, которую вы ввели
- в качестве идентфикатора, и подтвердить регистрацию.
+ в качестве идентификатора, и подтвердить регистрацию.
9. (если у вас нет аккаунта) Выбрать **ВОЙТИ**.
@@ -34,7 +34,7 @@
- Запуск на телевизоре
1. Распаковать zip архив с приложением в папку
- `developer\apps\usr\palm\applications\` USB флэш диска
+ `developer\apps\usr\palm\applications\` USB флэш диска, отформатированного под NTFS.
2. Вставить USB флэш диск в телевизор.
diff --git a/package.json b/package.json
index cfe42ed..984d59a 100644
--- a/package.json
+++ b/package.json
@@ -1,52 +1,57 @@
{
"name": "appLauncher",
- "version": "0.1.0",
+ "version": "0.2.0",
"description": "AppLauncher allows running Smart TV and STB application avoiding standard installation process.",
"homepage": "https://github.com/ifaced/app-launcher",
- "repository" : {
- "type" : "git",
- "url" : "https://github.com/ifaced/app-launcher.git"
+ "repository": {
+ "type": "git",
+ "url": "https://github.com/ifaced/app-launcher.git"
},
"contributors": [
{
- "name" : "Andrew Motoshin",
- "email" : "andrew@htmlhero.ru",
- "url" : "http://htmlhero.ru/"
+ "name": "Andrew Motoshin",
+ "email": "andrew@htmlhero.ru",
+ "url": "http://htmlhero.ru/"
},
{
- "name" : "Oleg Akinin",
- "email" : "o.akinin@ifaced.ru"
+ "name": "Oleg Akinin",
+ "email": "o.akinin@ifaced.ru"
},
{
- "name" : "Vyatcheslav Zaytcev",
- "email" : "slava@ifaced.ru"
+ "name": "Vyatcheslav Zaytcev",
+ "email": "slava@ifaced.ru"
},
{
- "name" : "Anuar Turenov",
- "email" : "turenov@ifaced.ru"
+ "name": "Anuar Turenov",
+ "email": "turenov@ifaced.ru"
},
{
- "name" : "Maxim Dymchenko",
- "email" : "maximatorrus@ifaced.ru"
+ "name": "Maxim Dymchenko",
+ "email": "maximatorrus@ifaced.ru"
},
{
- "name" : "Kirill Dronkin",
- "email" : "kirilldronkin@ifaced.ru"
+ "name": "Kirill Dronkin",
+ "email": "kirilldronkin@ifaced.ru"
},
{
- "name" : "Alex Babenko",
- "email" : "babenkoalex@ifaced.ru"
+ "name": "Dmitry Zubarev",
+ "email": "zubrolet@interfaced.ru"
+ },
+ {
+ "name": "Alex Babenko",
+ "email": "babenkoalex@ifaced.ru"
}
],
"license": "Apache-2.0",
"dependencies": {
- "zombiebox": "0.0.176",
- "zombiebox-platform-dune": "0.0.41",
- "zombiebox-platform-eltex": "0.0.22",
- "zombiebox-platform-lg": "0.0.11",
- "zombiebox-platform-mag250": "0.0.26",
- "zombiebox-platform-samsung": "0.0.26",
- "zombiebox-platform-tvip": "0.0.10",
- "zombiebox-platform-webos": "0.0.10"
+ "zombiebox": "0.0.193",
+ "zombiebox-extension-ui": "^0.1.2",
+ "zombiebox-platform-dune": "0.0.44",
+ "zombiebox-platform-eltex": "0.0.26",
+ "zombiebox-platform-lg": "0.0.14",
+ "zombiebox-platform-mag250": "0.0.35",
+ "zombiebox-platform-samsung": "0.0.40",
+ "zombiebox-platform-tvip": "0.0.12",
+ "zombiebox-platform-webos": "0.0.11"
}
}
diff --git a/web/analytics.js b/web/analytics.js
new file mode 100644
index 0000000..818acbc
--- /dev/null
+++ b/web/analytics.js
@@ -0,0 +1,38 @@
+(function(){var aa=encodeURIComponent,f=window,ba=setTimeout,n=Math,ea=RegExp;function fa(a,b){return a.name=b}function Pc(a,b){return a.href=b}
+var p="push",h="hash",ha="slice",Qc="replace",q="data",r="cookie",t="indexOf",m="match",ia="defaultValue",ja="port",u="createElement",id="setAttribute",v="name",da="getTime",x="host",y="length",z="prototype",la="clientWidth",A="split",B="location",ma="hostname",ga="search",jd="target",C="call",E="protocol",na="clientHeight",Ab="href",F="substring",kd="action",G="apply",oa="navigator",Ub="parentNode",H="join",I="toLowerCase";var pa=new function(){var a=[];this.set=function(b){a[b]=!0};this.M=function(){for(var b=[],c=0;c=a[y])wc(a,b);else if(8192>=a[y]){var c=b;if(0<=O[oa].userAgent[t]("Firefox")&&![].reduce)throw new Ea(a[y]);xc(a,c)||Fa(a,c)}else throw new Da(a[y]);},wc=function(a,b){var c=Ca(oc()+"/collect?"+a);c.onload=c.onerror=function(){c.onload=null;c.onerror=null;b()}},
+xc=function(a,b){var c,d=O.XDomainRequest;if(d)c=new d,c.open("POST",oc()+"/collect");else if(d=O.XMLHttpRequest)d=new d,"withCredentials"in d&&(c=d,c.open("POST",oc()+"/collect",!0),c.setRequestHeader("Content-Type","text/plain"));if(c)return c.onreadystatechange=function(){4==c.readyState&&(b(),c=null)},c.send(a),!0},Fa=function(a,b){if(M.body){a=aa(a);try{var c=M[u]('')}catch(d){c=M[u]("iframe"),fa(c,a)}c.height="0";c.width="0";c.style.display="none";c.style.visibility=
+"hidden";var e=M[B],e=oc()+"/analytics_iframe.html#"+aa(e[E]+"//"+e[x]+"/favicon.ico"),g=function(){c.src="";c[Ub]&&c[Ub].removeChild(c)};ta(O,"beforeunload",g);var ca=!1,l=0,k=function(){if(!ca){try{if(9=100*R(a,Ka))throw"abort";}function Ma(a){if(xa(P(a,Na)))throw"abort";}function Oa(){var a=M[B][E];}
+function Pa(a){a.set(Ac,R(a,Ac)+1);var b=[];Qa.map(function(c,d){if(d.p){var e=a.get(c);void 0!=e&&e!=d[ia]&&("boolean"==typeof e&&(e*=1),b[p](d.p+"="+sa(""+e)))}});b[p]("z="+ra());a.set(Ra,b[H]("&"),!0)}function Sa(a){Ga(P(a,Ra),a.get(Ia));a.set(Ia,L,!0)}function Hc(a){var b=O.gaData;b&&(b.expId&&a.set(Nc,b.expId),b.expVar&&a.set(Oc,b.expVar))}function cd(){if(O[oa]&&"preview"==O[oa].loadPurpose)throw"abort";};function Ta(a){var b=R(a,Ua);500<=b&&J(15);var c=P(a,Va);if("transaction"!=c&&"item"!=c){var c=R(a,Wa),d=(new Date)[da](),e=R(a,Xa);0==e&&a.set(Xa,d);e=n.round(2*(d-e)/1E3);0=c)throw"abort";a.set(Wa,--c)}a.set(Ua,++b)};var Ya=function(){this.data=new N},Qa=new N,Za=[];Ya[z].get=function(a){var b=$a(a),c=this[q].get(a);b&&void 0==c&&(c=K(b[ia])?b[ia]():b[ia]);return b&&b.n?b.n(this,a,c):c};var P=function(a,b){var c=a.get(b);return void 0==c?"":""+c},R=function(a,b){var c=a.get(b);return void 0==c||""===c?0:1*c};Ya[z].set=function(a,b,c){if(a)if("object"==typeof a)for(var d in a)a.hasOwnProperty(d)&&ab(this,d,a[d],c);else ab(this,a,b,c)};
+var ab=function(a,b,c,d){var e=$a(b);e&&e.o?e.o(a,b,c,d):a[q].set(b,c,d)},bb=function(a,b,c,d,e){fa(this,a);this.p=b;this.n=d;this.o=e;this.defaultValue=c},$a=function(a){var b=Qa.get(a);if(!b)for(var c=0;c=c)&&(c={},Ec(c)||Fc(c))){var d=c[Eb];void 0==d||Infinity==d||isNaN(d)||(0c)a[b]=void 0};var hc=!1,mc=function(a){if("cookie"==P(a,ac)){var b=P(a,U),c=nd(a),d=kc(P(a,Yb)),e=lc(P(a,W)),g=1E3*R(a,Zb),ca=P(a,Na);if("auto"!=e)zc(b,c,d,e,ca,g)&&(hc=!0);else{J(32);var l;t:{c=[];e=eb()[A](".");if(4==e[y]&&(l=e[e[y]-1],parseInt(l,10)==l)){l=["none"];break t}for(l=e[y]-2;0<=l;l--)c[p](e[ha](l)[H]("."));c[p]("none");l=c}for(var k=0;k=a&&d[p]({hash:ca[0],R:e[g],O:ca})}return 0==d[y]?void 0:1==d[y]?d[0]:Zc(b,d)||Zc(c,d)||Zc(null,d)||d[0]}function Zc(a,b){var c,d;null==a?c=d=1:(c=La(a),d=La(0==a[t](".")?a[F](1):"."+a));for(var e=0;ed[y])){c=[];for(var e=0;e=ca[0]||0>=ca[1]?"":ca[H]("x");a.set(rb,c);a.set(tb,fc());a.set(ob,M.characterSet||M.charset);a.set(sb,b&&"function"===typeof b.javaEnabled&&b.javaEnabled()||!1);a.set(nb,(b&&(b.language||b.browserLanguage)||"")[I]());if(d&&a.get(cc)&&(b=M[B][h])){b=b[F](1);b=b[A]("&");d=[];for(c=0;carguments[y])){var b,c;"string"===typeof arguments[0]?(b=arguments[0],c=[][ha][C](arguments,1)):(b=arguments[0]&&arguments[0][Va],c=arguments);b&&(c=wa(qc[b]||[],c),c[Va]=b,this.b.set(c,void 0,!0),this.filters.D(this.b),"pageview"==b&&Lc(this),this.b[q].m={})}};var Lc=function(a){a.I||(a.I=!0,gc(a.b,function(b){a.send("timing",b)}))};var rc=function(a){if("prerender"==M.webkitVisibilityState)return!1;a();return!0},Mc=function(a){if(!rc(a)){J(16);var b=!1,c=function(){!b&&rc(a)&&(b=!0,ua(M,"webkitvisibilitychange",c))};ta(M,"webkitvisibilitychange",c)}};var td=/^(?:(\w+)\.)?(?:(\w+):)?(\w+)$/,sc=function(a){if(K(a[0]))this.u=a[0];else{var b=td.exec(a[0]);null!=b&&4==b[y]&&(this.c=b[1]||"t0",this.e=b[2]||"",this.d=b[3],this.a=[][ha][C](a,1),this.e||(this.A="create"==this.d,this.i="require"==this.d,this.g="provide"==this.d));b=a[1];a=a[2];if(!this.d)throw"abort";if(this.i&&(!qa(b)||""==b))throw"abort";if(this.g&&(!qa(b)||""==b||!K(a)))throw"abort";if(ud(this.c)||ud(this.e))throw"abort";if(this.g&&"t0"!=this.c)throw"abort";}};
+function ud(a){return 0<=a[t](".")||0<=a[t](":")};var Z={F:"/plugins/ua/"};Z.k=new N;Z.f=[];Z.B=function(a,b,c){var d=Z.k.get(a);if(!K(d))return!1;b.plugins_=b.plugins_||new N;b.plugins_.set(a,new d(b,c||{}));return!0};Z.C=function(a,b){Z.k.set(a,b)};Z.D=function(a){var b=Z.J[G](Z,arguments),b=Z.f.concat(b);for(Z.f=[];0a[A]("/")[0][t](":")&&(a=ca+e[2][F](0,e[2].lastIndexOf("/"))+"/"+a):a=ca+e[2]+(a||g);Pc(c,a);d=b(c);return{protocol:(c[E]||"")[I](),host:d[0],port:d[1],
+path:d[2],G:c[ga]||"",url:a||""}};var $=function(a){J(1);Z.D[G](Z,[arguments])};$.h={};$.P=[];$.L=0;$.answer=42;var uc=[Na,W,V];$.create=function(a){var b=wa(uc,[][ha][C](arguments));b[V]||(b[V]="t0");var c=""+b[V];if($.h[c])return $.h[c];b=new pc(b);$.h[c]=b;$.P[p](b);return b};$.j=function(a){return $.h[a]};$.K=function(){return $.P[ha](0)};$.N=function(){var a=O[gb];if(!a||42!=a.answer){$.L=a&&a.l;$.loaded=!0;O[gb]=$;Cc();var b=a&&a.q;"[object Array]"==Object[z].toString[C](Object(b))&&Mc(function(){Z.D[G]($,b)})}};$.N();function La(a){var b=1,c=0,d;if(a)for(b=0,d=a[y]-1;0<=d;d--)c=a.charCodeAt(d),b=(b<<6&268435455)+c+(c<<14),c=b&266338304,b=0!=c?b^c>>21:b;return b};})(window);
\ No newline at end of file