Commit de033244 authored by Austin Tankiang's avatar Austin Tankiang Committed by Commit Bot

Add banner to inform of offline availability feature

This banner will be shown the first three times the user runs Files App
and navigates to Drive (as opposed to the first three times the user
sees the banner).

Bug: 1129778
Change-Id: I0073d7dd6b6f1cdf9494e621f0edfccbcc380238
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2417741Reviewed-by: default avatarLuciano Pacheco <lucmult@chromium.org>
Reviewed-by: default avatarNoel Gordon <noel@chromium.org>
Commit-Queue: Austin Tankiang <austinct@chromium.org>
Cr-Commit-Position: refs/heads/master@{#821160}
parent adc269ee
......@@ -652,7 +652,8 @@ WRAPPED_INSTANTIATE_TEST_SUITE_P(
TestCase("driveLinkToDirectory"),
TestCase("driveLinkOpenFileThroughLinkedDirectory"),
TestCase("driveLinkOpenFileThroughTransitiveLink"),
TestCase("driveWelcomeBanner")));
TestCase("driveWelcomeBanner"),
TestCase("driveOfflineInfoBanner")));
WRAPPED_INSTANTIATE_TEST_SUITE_P(
Transfer, /* transfer.js */
......
......@@ -736,6 +736,7 @@ std::unique_ptr<base::DictionaryValue> GetFileManagerStrings() {
SET_STRING("OFFLINE_HEADER", IDS_FILE_BROWSER_OFFLINE_HEADER);
SET_STRING("OFFLINE_MESSAGE", IDS_FILE_BROWSER_OFFLINE_MESSAGE);
SET_STRING("OFFLINE_MESSAGE_PLURAL", IDS_FILE_BROWSER_OFFLINE_MESSAGE_PLURAL);
SET_STRING("OFFLINE_BANNER_MESSAGE", IDS_FILE_BROWSER_OFFLINE_BANNER_MESSAGE);
SET_STRING("OK_LABEL", IDS_FILE_BROWSER_OK_LABEL);
SET_STRING("ONE_DIRECTORY_SELECTED", IDS_FILE_BROWSER_ONE_DIRECTORY_SELECTED);
SET_STRING("ONE_FILE_SELECTED", IDS_FILE_BROWSER_ONE_FILE_SELECTED);
......
......@@ -1185,6 +1185,9 @@
<message name="IDS_FILE_BROWSER_OFFLINE_MESSAGE_PLURAL" desc="Message informing the user how to make multiple selected files available offline.">
To save these files for offline use, get back online, right-click the files, and select the <ph name="OFFLINE_CHECKBOX_NAME">'$1'<ex>'Available offline'</ex></ph> option.
</message>
<message name="IDS_FILE_BROWSER_OFFLINE_BANNER_MESSAGE" desc="Message informing the user that they can make files available offline.">
You can make files available offline for access when you don't have internet connection.
</message>
<message name="IDS_FILE_BROWSER_QUICK_VIEW_NO_PLAYBACK_AVAILABLE" desc="Massage for user to notify no playback is available.">
No playback available
</message>
......
1088d06b10489a0585e87d0ee5a38661b1330cd4
\ No newline at end of file
......@@ -1988,6 +1988,17 @@ body.files-ng .volume-warning .banner-button {
padding-inline-start: 16px;
}
body.files-ng .volume-warning .info-icon {
-webkit-mask-image: url(../images/files/ui/info.svg);
background-color: var(--cros-text-color-secondary);
background-size: 20px 20px;
flex: none;
height: 20px;
margin-inline-end: 16px;
margin-inline-start: 8px;
width: 20px;
}
body:not(.files-ng) .banner-close {
background: -webkit-image-set(
url(../images/files/ui/close_button_white.png) 1x,
......
......@@ -20,6 +20,12 @@ const DRIVE_WARNING_DISMISSED_KEY = 'driveSpaceWarningDismissed';
*/
const DOWNLOADS_WARNING_DISMISSED_KEY = 'downloadsSpaceWarningDismissed';
/**
* Key in localStorage to store the number of sessions the Offline Info banner
* message has shown in.
*/
const OFFLINE_INFO_BANNER_COUNTER_KEY = 'driveOfflineInfoBannerCounter';
/**
* Maximum times Drive Welcome banner could have shown.
*/
......@@ -45,6 +51,11 @@ const DOWNLOADS_SPACE_WARNING_THRESHOLD_SIZE = 1 * 1024 * 1024 * 1024;
*/
const DOWNLOADS_SPACE_WARNING_DISMISS_DURATION = 36 * 60 * 60 * 1000;
/**
* Maximum sessions the Offline Info banner should be shown.
*/
const OFFLINE_INFO_BANNER_COUNTER_LIMIT = 3;
/**
* Responsible for showing following banners in the file list.
* - WelcomeBanner
......@@ -71,7 +82,7 @@ class Banners extends cr.EventTarget {
this.privateOnDirectoryChangedBound_ =
this.privateOnDirectoryChanged_.bind(this);
const handler = this.checkSpaceAndMaybeShowWelcomeBanner_.bind(this);
const handler = this.maybeShowDriveBanners_.bind(this);
this.directoryModel_.addEventListener('scan-completed', handler);
this.directoryModel_.addEventListener('rescan-completed', handler);
this.directoryModel_.addEventListener(
......@@ -88,11 +99,25 @@ class Banners extends cr.EventTarget {
this.warningDismissedCounter_ = 0;
this.downloadsWarningDismissedTime_ = 0;
/**
* Number of sessions the offline info banner has been shown in already.
* @private {!number}
*/
this.offlineInfoBannerCounter_ = 0;
/**
* Whether or not the offline info banner has been shown this session.
* @private {!boolean}
*/
this.hasShownOfflineInfoBanner_ = false;
this.ready_ = new Promise((resolve, reject) => {
chrome.storage.local.get(
[
WELCOME_HEADER_COUNTER_KEY, DRIVE_WARNING_DISMISSED_KEY,
DOWNLOADS_WARNING_DISMISSED_KEY
WELCOME_HEADER_COUNTER_KEY,
DRIVE_WARNING_DISMISSED_KEY,
DOWNLOADS_WARNING_DISMISSED_KEY,
OFFLINE_INFO_BANNER_COUNTER_KEY,
],
values => {
if (chrome.runtime.lastError) {
......@@ -107,12 +132,15 @@ class Banners extends cr.EventTarget {
parseInt(values[DRIVE_WARNING_DISMISSED_KEY], 10) || 0;
this.downloadsWarningDismissedTime_ =
parseInt(values[DOWNLOADS_WARNING_DISMISSED_KEY], 10) || 0;
this.offlineInfoBannerCounter_ =
parseInt(values[OFFLINE_INFO_BANNER_COUNTER_KEY], 10) || 0;
// If it's in test, override the counter to show the header by
// force.
if (chrome.test) {
this.welcomeHeaderCounter_ = 0;
this.warningDismissedCounter_ = 0;
this.offlineInfoBannerCounter_ = 0;
}
resolve();
});
......@@ -128,6 +156,15 @@ class Banners extends cr.EventTarget {
e.preventDefault();
});
this.maybeShowAuthFailBanner_();
/**
* Banner informing user they can make elements available offline.
* @private {!HTMLElement}
* @const
*/
this.offlineInfoBanner_ = queryRequiredElement('#offline-info-banner');
util.setClampLine(
queryRequiredElement('.body2-primary', this.offlineInfoBanner_), '2');
}
/**
......@@ -151,6 +188,17 @@ class Banners extends cr.EventTarget {
chrome.storage.local.set(values);
}
/**
* @param {number} value How many sessions the Offline Info banner has shown
* in.
* @private
*/
setOfflineInfoBannerCounter_(value) {
const values = {};
values[OFFLINE_INFO_BANNER_COUNTER_KEY] = value;
chrome.storage.local.set(values);
}
/**
* chrome.storage.onChanged event handler.
* @param {Object<Object>} changes Changes values.
......@@ -169,6 +217,10 @@ class Banners extends cr.EventTarget {
this.downloadsWarningDismissedTime_ =
changes[DOWNLOADS_WARNING_DISMISSED_KEY].newValue;
}
if (areaName == 'local' && OFFLINE_INFO_BANNER_COUNTER_KEY in changes) {
this.offlineInfoBannerCounter_ =
changes[OFFLINE_INFO_BANNER_COUNTER_KEY].newValue;
}
}
/**
......@@ -400,32 +452,43 @@ class Banners extends cr.EventTarget {
* Shows or hides the welcome banner for drive.
* @private
*/
checkSpaceAndMaybeShowWelcomeBanner_() {
maybeShowDriveBanners_() {
this.ready_.then(() => {
if (!this.isOnCurrentProfileDrive()) {
// We are not on the drive file system. Do not show (close) the welcome
// banner.
// We are not on the drive file system. Do not show (close) the drive
// banners.
this.cleanupWelcomeBanner_();
this.previousDirWasOnDrive_ = false;
this.offlineInfoBanner_.hidden = true;
return;
}
const driveVolume = this.volumeManager_.getCurrentProfileVolumeInfo(
VolumeManagerCommon.VolumeType.DRIVE);
if (this.welcomeHeaderCounter_ >= WELCOME_HEADER_COUNTER_LIMIT ||
!driveVolume || driveVolume.error) {
// The banner is already shown enough times or the drive FS is not
// mounted. So, do nothing here.
if (!driveVolume || driveVolume.error) {
// Drive is not mounted, so do nothing.
return;
}
this.maybeShowWelcomeBanner_();
if (this.welcomeHeaderCounter_ < WELCOME_HEADER_COUNTER_LIMIT) {
this.maybeShowWelcomeBanner_();
}
if (util.isFilesNg() &&
(this.offlineInfoBannerCounter_ < OFFLINE_INFO_BANNER_COUNTER_LIMIT ||
this.hasShownOfflineInfoBanner_)) {
this.offlineInfoBanner_.hidden = false;
if (!this.hasShownOfflineInfoBanner_) {
this.hasShownOfflineInfoBanner_ = true;
this.setOfflineInfoBannerCounter_(this.offlineInfoBannerCounter_ + 1);
}
}
});
}
/**
* Decides which banner should be shown, and show it. This method is designed
* to be called only from checkSpaceAndMaybeShowWelcomeBanner_.
* to be called only from maybeShowDriveBanners_.
* @private
*/
maybeShowWelcomeBanner_() {
......
......@@ -541,6 +541,10 @@
<div class="drive-icon"></div>
<div class="drive-text" id="drive-auth-failed-warning-text"></div>
</div>
<div class="volume-warning" id="offline-info-banner" hidden>
<div class="info-icon"></div>
<div class="body2-primary">$i18n{OFFLINE_BANNER_MESSAGE}</div>
</div>
<div class="downloads-warning" hidden></div>
<files-message id='files-message' hidden></files-message>
<div id="file-type-filter-container" hidden></div>
......
......@@ -748,3 +748,11 @@ testcase.driveWelcomeBanner = async () => {
}
});
};
testcase.driveOfflineInfoBanner = async () => {
// Open Files app on Drive.
const appId = await setupAndWaitUntilReady(RootPath.DRIVE, []);
// Check: the Drive Offline info banner should appear.
await remoteCall.waitForElement(appId, '#offline-info-banner:not([hidden])');
};
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment