Skip to content
This repository has been archived by the owner on Nov 3, 2021. It is now read-only.

Commit

Permalink
Merge pull request #27872 from weilonge/TV_1120357
Browse files Browse the repository at this point in the history
Bug 1120357 - Show app install/uninstall dialog with Smart Buttons. r=johnhu
  • Loading branch information
weilonge committed Feb 6, 2015
2 parents a1c3317 + c7aef55 commit 5af094a
Show file tree
Hide file tree
Showing 7 changed files with 249 additions and 89 deletions.
42 changes: 21 additions & 21 deletions tv_apps/smart-system/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@
<script defer src="shared/js/font_size_utils.js"></script>
<!-- XXX can be removed while gecko support navigator.mozHour12 API -->
<script defer src="shared/js/date_time_helper.js"></script>
<script defer src="tv_shared/js/simple_key_navigation.js"></script>
<script defer src="tv_shared/js/key_navigation_adapter.js"></script>

<script defer src="js/service.js"></script>
<script defer src="js/base_ui.js"></script>
Expand Down Expand Up @@ -206,7 +208,6 @@

<!-- Notifications -->
<link rel="stylesheet" type="text/css" href="style/notifications/notifications.css">
<script defer src="tv_shared/js/simple_key_navigation.js"></script>
<script defer src="js/notifications.js"></script>
<script defer src="js/interactive_notifications.js"></script>

Expand Down Expand Up @@ -318,7 +319,6 @@

<!-- Navigation -->
<script defer src="tv_shared/js/spatial_navigator.js"></script>
<script defer src="tv_shared/js/key_navigation_adapter.js"></script>
<script defer src="tv_shared/js/init_gesture.js"></script>

<!-- API Services -->
Expand Down Expand Up @@ -576,18 +576,9 @@ <h2 id="permission-message"></h2>
data-z-index-level="app-install-dialog">
<section>
<h1 id="app-install-message"></h1>
<dl>
<dt data-l10n-id="size">Size</dt>
<dd id="app-install-size"></dd>
<dt data-l10n-id="author">Author</dt>
<dd>
<span id="app-install-author-name"></span><br />
<span id="app-install-author-url"></span>
</dd>
</dl>
<menu data-items="2">
<button id="app-install-cancel-button" data-l10n-id="cancel">Cancel</button>
<button id="app-install-install-button" class="recommend" data-l10n-id="install">Install</button>
<smart-button id="app-install-cancel-button" data-l10n-id="cancel" type="circle-text">Cancel</smart-button>
<smart-button id="app-install-install-button" class="recommend primary" data-l10n-id="install" type="circle-text">Install</smart-button>
</menu>
</section>
</form>
Expand All @@ -596,15 +587,24 @@ <h1 id="app-install-message"></h1>
data-type="confirm" role="dialog"
data-z-index-level="app-install-dialog">
<section>
<h1 data-l10n-id="cancel-install">Cancel Install</h1>
<p>
<small data-l10n-id="cancelling-will-not-refund">Cancelling will not refund a purchase. Refunds for paid content are provided by the original seller.</small>
<small data-l10n-id="apps-can-be-installed-later">Apps can be installed later from the original installation source.</small>
</p>
<p data-l10n-id="are-you-sure-you-want-to-cancel">Are you sure you want to cancel this install?</p>
<h1 data-l10n-id="cancelling-will-not-refund">Cancelling will not refund a purchase. Refunds for paid content are provided by the original seller.</h1>
<h1 data-l10n-id="apps-can-be-installed-later">Apps can be installed later from the original installation source.</h1>
<h1 data-l10n-id="are-you-sure-you-want-to-cancel">Are you sure you want to cancel this install?</h1>
<menu data-items="2">
<smart-button id="app-install-confirm-cancel-button" type="circle-text" data-l10n-id="cancel-install-button">Cancel Install</smart-button>
<smart-button id="app-install-resume-button" type="circle-text" data-l10n-id="resume">Resume</smart-button>
</menu>
</section>
</form>

<form id="app-uninstall-dialog" class='app-uninstall-dialog generic-dialog'
data-type="confirm" role="dialog"
data-z-index-level="app-install-dialog">
<section>
<h1 id="app-uninstall-message"></h1>
<menu data-items="2">
<button id="app-install-confirm-cancel-button" type="reset" data-l10n-id="cancel-install-button">Cancel Install</button>
<button id="app-install-resume-button" type="submit" data-l10n-id="resume">Resume</button>
<smart-button id="app-uninstall-cancel-button" data-l10n-id="cancel" type="circle-text">Cancel</smart-button>
<smart-button id="app-uninstall-confirm-button" class="danger" data-l10n-id="delete" type="circle-text">delete</smart-button>
</menu>
</section>
</form>
Expand Down
193 changes: 132 additions & 61 deletions tv_apps/smart-system/js/app_install_manager.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
/* jshint moz:true */
/* global ConfirmDialogHelper */
/* global FtuLauncher */
/* global KeyboardHelper */
/* global KeyboardManager */
Expand All @@ -20,6 +19,9 @@
/* global Template */
/* global KeyboardHelper */
/* global applications */
/* global KeyNavigationAdapter */
/* global SimpleKeyNavigation */
/* global AppWindowManager */

var AppInstallManager = {
mapDownloadErrorsToMessage: {
Expand Down Expand Up @@ -63,8 +65,17 @@ var AppInstallManager = {
this.setupAppName = document.getElementById('setup-app-name');
this.setupAppDescription = document.getElementById('setup-app-description');

this.appUninstallDialog = document.getElementById('app-uninstall-dialog');
this.appUninstallMessage = document.getElementById('app-uninstall-message');
this.appUninstallCancelButton =
document.getElementById('app-uninstall-cancel-button');
this.appUninstallConfirmButton =
document.getElementById('app-uninstall-confirm-button');

this.resumeButton = document.getElementById('app-install-resume-button');

this.simpleKeyNavigation = new SimpleKeyNavigation();

this.appInfos = {};
this.setupQueue = [];
this.isSetupInProgress = false;
Expand All @@ -89,6 +100,11 @@ var AppInstallManager = {
this.confirmCancelButton.onclick = this.handleInstallCancel.bind(this);
this.resumeButton.onclick = this.hideInstallCancelDialog.bind(this);

this.appUninstallCancelButton.onclick =
this.hideUninstallCancelDialog.bind(this);
this.appUninstallConfirmButton.onclick =
this.handleUninstallDialog.bind(this);

this.downloadCancelDialog.querySelector('.confirm').onclick =
this.handleConfirmDownloadCancel.bind(this);
this.downloadCancelDialog.querySelector('.cancel').onclick =
Expand All @@ -115,12 +131,28 @@ var AppInstallManager = {
window.addEventListener('applicationready',
this.handleApplicationReady);

window.addEventListener('home', this.handleHomeButtonPressed.bind(this));
window.addEventListener('home', this.hideAllDialogs.bind(this));

this.keyNavigationAdapter = new KeyNavigationAdapter();
this.keyNavigationAdapter.on('esc-keyup', this.escKeyUpHandler.bind(this));
},

handleHomeButtonPressed: function ai_handleHomeButtonPressed(e) {
this.dialog.classList.remove('visible');
this.handleInstallCancel();
escKeyUpHandler: function ai_escKeyUpHandler() {
this.keyNavigationAdapter.uninit();
this.hideAllDialogs();
},

hideAllDialogs: function ai_hideAllDialogs(e) {
if (this.dialog.classList.contains('visible')) {
this.dialog.classList.remove('visible');
this.handleInstallCancel();
} else if (this.installCancelDialog.classList.contains('visible')) {
this.installCancelDialog.classList.remove('visible');
this.handleInstallCancel();
} else if (this.appUninstallDialog.classList.contains('visible')) {
this.appUninstallDialog.classList.remove('visible');
this.hideUninstallCancelDialog();
}
},

handleApplicationReady: function ai_handleApplicationReady(e) {
Expand Down Expand Up @@ -162,54 +194,40 @@ var AppInstallManager = {
return;
}

this.hookSimpleNavigator(
[this.cancelButton, this.installButton], this.installButton);

this.dialog.classList.add('visible');

var id = detail.id;

if (manifest.size) {
this.size.textContent = this.humanizeSize(manifest.size);
} else {
this.size.setAttribute('data-l10n-id', 'size-unknown');
}

// Wrap manifest to get localized properties
manifest = new ManifestHelper(manifest);
navigator.mozL10n.setAttributes(this.msg,
'install-app', {'name': manifest.name}
);

if (manifest.developer) {
if (manifest.developer.name) {
this.authorName.removeAttribute('data-l10n-id');
this.authorName.textContent = manifest.developer.name;
} else {
this.authorName.setAttribute('data-l10n-id', 'author-unknown');
}
this.authorUrl.textContent = manifest.developer.url || '';
} else {
this.authorName.setAttribute('data-l10n-id', 'author-unknown');
this.authorUrl.textContent = '';
}
this.keyNavigationAdapter.init();

this.installCallback = (function ai_installCallback() {
this.unhookSimpleNavigator();
this.dispatchResponse(id, 'webapps-install-granted');
}).bind(this);

this.installCancelCallback = (function ai_cancelCallback() {
this.unhookSimpleNavigator();
this.dispatchResponse(id, 'webapps-install-denied');
}).bind(this);

},

handleInstall: function ai_handleInstall(evt) {
if (evt) {
evt.preventDefault();
}
if (this.installCallback) {
this.installCallback();
}
this.installCallback = null;
this.dialog.classList.remove('visible');
AppWindowManager.getActiveApp().focus();
},

handleAppUninstallPrompt: function ai_handleUninstallPrompt(detail) {
Expand All @@ -229,38 +247,67 @@ var AppInstallManager = {
!app.downloadAvailable &&
!app.readyToApplyDownload;

var dialogConfig;

if (unrecoverable) {
dialogConfig = {
type: 'unrecoverable',
title: 'unrecoverable-error-title',
body: 'unrecoverable-error-body',
confirm: {
title: 'unrecoverable-error-action',
cb: () => { this.dispatchResponse(id, 'webapps-uninstall-granted'); }
}
};
this.hookSimpleNavigator(
[this.appUninstallConfirmButton],
this.appUninstallConfirmButton);

this.appUninstallDialog.classList.add('visible');

// Hide Cancel button and adjust its position.
this.appUninstallCancelButton.style.display = 'none';
this.appUninstallConfirmButton.style.marginLeft = '0';
this.appUninstallConfirmButton.parentNode.setAttribute('data-items', 1);

navigator.mozL10n.setAttributes(this.appUninstallMessage,
'unrecoverable-error-body'
);
} else {
var nameObj = { name: manifest.name };
dialogConfig = {
type: 'remove',
title: {id: 'delete-title', args: nameObj},
body: {id: 'delete-body', args: nameObj},
cancel: {
title: 'cancel',
cb: () => { this.dispatchResponse(id, 'webapps-uninstall-denied'); }
},
confirm: {
title: 'delete',
type: 'danger',
cb: () => { this.dispatchResponse(id, 'webapps-uninstall-granted'); }
}
};
this.hookSimpleNavigator(
[this.appUninstallCancelButton, this.appUninstallConfirmButton],
this.appUninstallCancelButton);

this.appUninstallDialog.classList.add('visible');

// Show Cancel button.
this.appUninstallCancelButton.style.display = '';
this.appUninstallConfirmButton.style.marginLeft = '';
this.appUninstallConfirmButton.parentNode.setAttribute('data-items', 2);

navigator.mozL10n.setAttributes(this.appUninstallMessage,
'delete-body', {'name': manifest.name}
);
}

var dialog = new ConfirmDialogHelper(dialogConfig);
dialog.show(document.body);
this.keyNavigationAdapter.init();

this.uninstallCallback = (function ai_uninstallCallback() {
this.unhookSimpleNavigator();
this.dispatchResponse(id, 'webapps-uninstall-granted');
}).bind(this);

this.uninstallCancelCallback = (function ai_cancelCallback() {
this.unhookSimpleNavigator();
this.dispatchResponse(id, 'webapps-uninstall-denied');
}).bind(this);
},

handleUninstallDialog: function ai_handleUninstallDialog(evt) {
if (this.uninstallCallback) {
this.uninstallCallback();
}
this.uninstallCallback = null;
this.appUninstallDialog.classList.remove('visible');
AppWindowManager.getActiveApp().focus();
},

hideUninstallCancelDialog: function ai_hideUninstallCancelDialog(evt) {
if (this.uninstallCancelCallback) {
this.uninstallCancelCallback();
}
this.uninstallCancelCallback = null;
this.appUninstallDialog.classList.remove('visible');
AppWindowManager.getActiveApp().focus();
},

prepareForDownload: function ai_prepareForDownload(app) {
Expand Down Expand Up @@ -466,7 +513,7 @@ var AppInstallManager = {
onDownloadStop: function ai_onDownloadStop(app) {
var manifestURL = app.manifestURL,
appInfo = this.appInfos[manifestURL];
if (appInfo.isDownloading) {
if (appInfo && appInfo.isDownloading) {
this.releaseWifiLock(app);
appInfo.isDownloading = false;
}
Expand Down Expand Up @@ -546,17 +593,17 @@ var AppInstallManager = {
},

showInstallCancelDialog: function ai_showInstallCancelDialog(evt) {
if (evt) {
evt.preventDefault();
}
this.hookSimpleNavigator(
[this.confirmCancelButton, this.resumeButton], this.confirmCancelButton);

this.installCancelDialog.classList.add('visible');
this.dialog.classList.remove('visible');
},

hideInstallCancelDialog: function ai_hideInstallCancelDialog(evt) {
if (evt) {
evt.preventDefault();
}
this.unhookSimpleNavigator();
this.hookSimpleNavigator(
[this.cancelButton, this.installButton], this.installButton);
this.dialog.classList.add('visible');
this.installCancelDialog.classList.remove('visible');
},
Expand All @@ -565,8 +612,10 @@ var AppInstallManager = {
if (this.installCancelCallback) {
this.installCancelCallback();
}
this.unhookSimpleNavigator();
this.installCancelCallback = null;
this.installCancelDialog.classList.remove('visible');
AppWindowManager.getActiveApp().focus();
},

handleConfirmDownloadCancel: function ai_handleConfirmDownloadCancel(e) {
Expand All @@ -590,6 +639,28 @@ var AppInstallManager = {
var dialog = this.downloadCancelDialog;
dialog.classList.remove('visible');
delete dialog.dataset.manifest;
},

hookSimpleNavigator: function(navigableButtons, defaultFocusButton) {
var that = this;
this.simpleKeyNavigation.start(navigableButtons,
SimpleKeyNavigation.DIRECTION.HORIZONTAL);
window.setTimeout(function() {
if (document.activeElement) {
document.activeElement.blur();
}
if (defaultFocusButton) {
that.simpleKeyNavigation.focusOn(defaultFocusButton);
}
});
this.simpleKeyNavigation.on('focusChanged', function(focusedButton) {
focusedButton.focus();
});
},

unhookSimpleNavigator: function() {
this.simpleKeyNavigation.off('focusChanged');
this.simpleKeyNavigation.stop();
}
};

Expand Down
Loading

0 comments on commit 5af094a

Please sign in to comment.