Bug 1045495 - Loop's link clicker UI needs new UX for notification of non supported platform. r=mikedeboer

This commit is contained in:
Mark Banner 2015-02-05 19:35:12 +00:00
Родитель 8a4d155f4d
Коммит b459d5b70b
14 изменённых файлов: 144 добавлений и 58 удалений

Просмотреть файл

@ -393,7 +393,8 @@ p {
.info-panel h4 {
color: #aaa;
text-align: center;
font-weight: 300;
font-weight: 500;
font-size: 1.2em;
margin: 0;
}

Просмотреть файл

@ -305,24 +305,6 @@
flex: 1;
}
/* Expired call url page */
.expired-url-info {
width: 400px;
margin: 0 auto;
}
.promote-firefox {
text-align: center;
font-size: 18px;
line-height: 24px;
margin: 2em 0;
}
.promote-firefox h3 {
font-weight: 300;
}
/*
* Dropdown menu hidden behind a chevron
*

Просмотреть файл

@ -84,8 +84,6 @@ loop.shared.utils = (function(mozL10n) {
return !!localStorage.getItem(prefName);
}
var IOS_REGEX = /^(iPad|iPhone|iPod)/;
function isFirefox(platform) {
return platform.indexOf("Firefox") !== -1;
}
@ -99,8 +97,26 @@ loop.shared.utils = (function(mozL10n) {
return !!window.MozActivity && /mobi/i.test(platform);
}
function isIOS(platform) {
return IOS_REGEX.test(platform);
/**
* Helper to get the platform if it is unsupported.
*
* @param {String} platform The platform this is running on.
* @return null for supported platforms, a string for unsupported platforms.
*/
function getUnsupportedPlatform(platform) {
if (/^(iPad|iPhone|iPod)/.test(platform)) {
return "ios";
}
if (/Windows Phone/i.test(platform)) {
return "windows_phone";
}
if (/BlackBerry/i.test(platform)) {
return "blackberry";
}
return null;
}
/**
@ -151,7 +167,7 @@ loop.shared.utils = (function(mozL10n) {
getBoolPreference: getBoolPreference,
isFirefox: isFirefox,
isFirefoxOS: isFirefoxOS,
isIOS: isIOS,
getUnsupportedPlatform: getUnsupportedPlatform,
locationData: locationData
};
})(document.mozL10n || navigator.mozL10n);

Просмотреть файл

@ -88,3 +88,4 @@ config:
@echo "loop.config.roomsSupportUrl = 'https://support.mozilla.org/kb/group-conversations-firefox-hello-webrtc';" >> content/config.js
@echo "loop.config.guestSupportUrl = 'https://support.mozilla.org/kb/respond-firefox-hello-invitation-guest-mode';" >> content/config.js
@echo "loop.config.generalSupportUrl = 'https://support.mozilla.org/kb/respond-firefox-hello-invitation-guest-mode';" >> content/config.js
@echo "loop.config.unsupportedPlatformUrl = 'https://support.mozilla.org/en-US/kb/which-browsers-will-work-firefox-hello-video-chat';" >> content/config.js

Просмотреть файл

@ -234,6 +234,31 @@ p.standalone-btn-label {
flex: 1;
}
/**
* Unsupported/expired views
*/
.highlight-issue-box {
width: 400px;
margin: 0 auto;
}
.promote-firefox {
text-align: center;
font-size: 18px;
line-height: 24px;
margin: 2em 0;
}
.promote-firefox h3 {
font-weight: 300;
}
.btn-unsupported-device {
width: 80%;
line-height: 24px;
}
/**
* Feedback form overlay (standalone only)
*/

Просмотреть файл

@ -109,7 +109,10 @@ loop.store.StandaloneAppStore = (function() {
var token;
// Check if we're on a supported device/platform.
if (sharedUtils.isIOS(navigator.platform)) {
var unsupportedPlatform =
sharedUtils.getUnsupportedPlatform(navigator.platform);
if (unsupportedPlatform) {
windowType = "unsupportedDevice";
} else if (!this._sdk.checkSystemRequirements()) {
windowType = "unsupportedBrowser";
@ -127,7 +130,8 @@ loop.store.StandaloneAppStore = (function() {
this.setStoreState({
windowType: windowType,
isFirefox: sharedUtils.isFirefox(navigator.userAgent)
isFirefox: sharedUtils.isFirefox(navigator.userAgent),
unsupportedPlatform: unsupportedPlatform
});
// If we've not got a window ID, don't dispatch the action, as we don't need

Просмотреть файл

@ -45,7 +45,7 @@ loop.webapp = (function($, _, OT, mozL10n) {
render: function() {
return (
React.createElement("div", {className: "expired-url-info"},
React.createElement("div", {className: "highlight-issue-box"},
React.createElement("div", {className: "info-panel"},
React.createElement("div", {className: "firefox-logo"}),
React.createElement("h1", null, mozL10n.get("incompatible_browser_heading")),
@ -61,12 +61,28 @@ loop.webapp = (function($, _, OT, mozL10n) {
* Unsupported Device view.
*/
var UnsupportedDeviceView = React.createClass({displayName: "UnsupportedDeviceView",
propTypes: {
platform: React.PropTypes.string.isRequired
},
render: function() {
var unsupportedDeviceParams = {
clientShortname: mozL10n.get("clientShortname2"),
platform: mozL10n.get("unsupported_platform_" + this.props.platform)
};
var unsupportedLearnMoreText = mozL10n.get("unsupported_platform_learn_more_link",
{clientShortname: mozL10n.get("clientShortname2")});
return (
React.createElement("div", null,
React.createElement("h2", null, mozL10n.get("incompatible_device")),
React.createElement("p", null, mozL10n.get("sorry_device_unsupported", {clientShortname: mozL10n.get("clientShortname2")})),
React.createElement("p", null, mozL10n.get("use_firefox_windows_mac_linux", {brandShortname: mozL10n.get("brandShortname")}))
React.createElement("div", {className: "highlight-issue-box"},
React.createElement("div", {className: "info-panel"},
React.createElement("div", {className: "firefox-logo"}),
React.createElement("h1", null, mozL10n.get("unsupported_platform_heading")),
React.createElement("h4", null, mozL10n.get("unsupported_platform_message", unsupportedDeviceParams))
),
React.createElement("p", null,
React.createElement("a", {className: "btn btn-large btn-accept btn-unsupported-device",
href: loop.config.unsupportedPlatformUrl}, unsupportedLearnMoreText))
)
);
}
@ -110,7 +126,7 @@ loop.webapp = (function($, _, OT, mozL10n) {
render: function() {
return (
React.createElement("div", {className: "expired-url-info"},
React.createElement("div", {className: "highlight-issue-box"},
React.createElement("div", {className: "info-panel"},
React.createElement("div", {className: "firefox-logo"}),
React.createElement("h1", null, mozL10n.get("call_url_unavailable_notification_heading")),
@ -965,7 +981,7 @@ loop.webapp = (function($, _, OT, mozL10n) {
render: function() {
switch (this.state.windowType) {
case "unsupportedDevice": {
return React.createElement(UnsupportedDeviceView, null);
return React.createElement(UnsupportedDeviceView, {platform: this.state.unsupportedPlatform});
}
case "unsupportedBrowser": {
return React.createElement(UnsupportedBrowserView, {isFirefox: this.state.isFirefox});

Просмотреть файл

@ -45,7 +45,7 @@ loop.webapp = (function($, _, OT, mozL10n) {
render: function() {
return (
<div className="expired-url-info">
<div className="highlight-issue-box">
<div className="info-panel">
<div className="firefox-logo" />
<h1>{mozL10n.get("incompatible_browser_heading")}</h1>
@ -61,12 +61,28 @@ loop.webapp = (function($, _, OT, mozL10n) {
* Unsupported Device view.
*/
var UnsupportedDeviceView = React.createClass({
propTypes: {
platform: React.PropTypes.string.isRequired
},
render: function() {
var unsupportedDeviceParams = {
clientShortname: mozL10n.get("clientShortname2"),
platform: mozL10n.get("unsupported_platform_" + this.props.platform)
};
var unsupportedLearnMoreText = mozL10n.get("unsupported_platform_learn_more_link",
{clientShortname: mozL10n.get("clientShortname2")});
return (
<div>
<h2>{mozL10n.get("incompatible_device")}</h2>
<p>{mozL10n.get("sorry_device_unsupported", {clientShortname: mozL10n.get("clientShortname2")})}</p>
<p>{mozL10n.get("use_firefox_windows_mac_linux", {brandShortname: mozL10n.get("brandShortname")})}</p>
<div className="highlight-issue-box">
<div className="info-panel">
<div className="firefox-logo" />
<h1>{mozL10n.get("unsupported_platform_heading")}</h1>
<h4>{mozL10n.get("unsupported_platform_message", unsupportedDeviceParams)}</h4>
</div>
<p>
<a className="btn btn-large btn-accept btn-unsupported-device"
href={loop.config.unsupportedPlatformUrl}>{unsupportedLearnMoreText}</a></p>
</div>
);
}
@ -110,7 +126,7 @@ loop.webapp = (function($, _, OT, mozL10n) {
render: function() {
return (
<div className="expired-url-info">
<div className="highlight-issue-box">
<div className="info-panel">
<div className="firefox-logo" />
<h1>{mozL10n.get("call_url_unavailable_notification_heading")}</h1>
@ -965,7 +981,7 @@ loop.webapp = (function($, _, OT, mozL10n) {
render: function() {
switch (this.state.windowType) {
case "unsupportedDevice": {
return <UnsupportedDeviceView />;
return <UnsupportedDeviceView platform={this.state.unsupportedPlatform}/>;
}
case "unsupportedBrowser": {
return <UnsupportedBrowserView isFirefox={this.state.isFirefox}/>;

Просмотреть файл

@ -27,9 +27,12 @@ incompatible_browser_heading=Oops!
incompatible_browser_message=Firefox Hello only works in browsers that support WebRTC
powered_by_webrtc=The audio and video components of {{clientShortname}} are powered by WebRTC.
use_latest_firefox=Please try this link in a WebRTC-enabled browser, such as {{firefoxBrandNameLink}}.
incompatible_device=Incompatible device
sorry_device_unsupported=Sorry, {{clientShortname}} does not currently support your device.
use_firefox_windows_mac_linux=Please open this page using the latest {{brandShortname}} on Windows, Android, Mac or Linux.
unsupported_platform_heading=Sorry!
unsupported_platform_message={{platform}} does not currently support {{clientShortname}}
unsupported_platform_ios=iOS
unsupported_platform_windows_phone=Windows Phone
unsupported_platform_blackberry=Blackberry
unsupported_platform_learn_more_link=Learn more about why your platform doesn't support {{clientShortname}}
connection_error_see_console_notification=Call failed; see console for details.
call_url_unavailable_notification_heading=Oops!
call_url_unavailable_notification_message2=Sorry, this URL is not available. It may be expired or entered incorrectly.

Просмотреть файл

@ -34,7 +34,8 @@ function getConfigFile(req, res) {
"loop.config.fxosApp.manifestUrl = 'http://fake-market.herokuapp.com/apps/packagedApp/manifest.webapp';",
"loop.config.roomsSupportUrl = 'https://support.mozilla.org/kb/group-conversations-firefox-hello-webrtc';",
"loop.config.guestSupportUrl = 'https://support.mozilla.org/kb/respond-firefox-hello-invitation-guest-mode';",
"loop.config.generalSupportUrl = 'https://support.mozilla.org/kb/respond-firefox-hello-invitation-guest-mode';"
"loop.config.generalSupportUrl = 'https://support.mozilla.org/kb/respond-firefox-hello-invitation-guest-mode';",
"loop.config.unsupportedPlatformUrl = 'https://support.mozilla.org/en-US/kb/which-browsers-will-work-firefox-hello-video-chat'"
].join("\n"));
}

Просмотреть файл

@ -22,15 +22,27 @@ describe("loop.shared.utils", function() {
sandbox.restore();
});
it("should detect iOS", function() {
expect(sharedUtils.isIOS("iPad")).eql(true);
expect(sharedUtils.isIOS("iPod")).eql(true);
expect(sharedUtils.isIOS("iPhone")).eql(true);
expect(sharedUtils.isIOS("iPhone Simulator")).eql(true);
});
describe("#getUnsupportedPlatform", function() {
it("should detect iOS", function() {
expect(sharedUtils.getUnsupportedPlatform("iPad")).eql('ios');
expect(sharedUtils.getUnsupportedPlatform("iPod")).eql('ios');
expect(sharedUtils.getUnsupportedPlatform("iPhone")).eql('ios');
expect(sharedUtils.getUnsupportedPlatform("iPhone Simulator")).eql('ios');
});
it("shouldn't detect iOS with other platforms", function() {
expect(sharedUtils.isIOS("MacIntel")).eql(false);
it("should detect Windows Phone", function() {
expect(sharedUtils.getUnsupportedPlatform("Windows Phone"))
.eql('windows_phone');
});
it("should detect BlackBerry", function() {
expect(sharedUtils.getUnsupportedPlatform("BlackBerry"))
.eql('blackberry');
});
it("shouldn't detect other platforms", function() {
expect(sharedUtils.getUnsupportedPlatform("MacIntel")).eql(null);
});
});
describe("#isFirefox", function() {

Просмотреть файл

@ -57,7 +57,7 @@ describe("loop.store.StandaloneAppStore", function () {
windowPath: ""
};
sandbox.stub(loop.shared.utils, "isIOS").returns(false);
sandbox.stub(loop.shared.utils, "getUnsupportedPlatform").returns();
sandbox.stub(loop.shared.utils, "isFirefox").returns(true);
fakeSdk = {
@ -94,9 +94,18 @@ describe("loop.store.StandaloneAppStore", function () {
expect(store.getStoreState().isFirefox).eql(false);
});
it("should set windowType to `unsupportedDevice` for IOS", function() {
// The stub should return true for this test.
loop.shared.utils.isIOS.returns(true);
it("should store the platform for unsupported platforms", function() {
loop.shared.utils.getUnsupportedPlatform.returns("fake");
store.extractTokenInfo(
new sharedActions.ExtractTokenInfo(fakeGetWindowData));
expect(store.getStoreState().unsupportedPlatform).eql("fake");
});
it("should set windowType to `unsupportedDevice` for ios", function() {
// The stub should return a platform for this test.
loop.shared.utils.getUnsupportedPlatform.returns("ios");
store.extractTokenInfo(
new sharedActions.ExtractTokenInfo(fakeGetWindowData));

Просмотреть файл

@ -555,7 +555,7 @@
React.createElement(Section, {name: "UnsupportedDeviceView"},
React.createElement(Example, {summary: "Standalone Unsupported Device"},
React.createElement("div", {className: "standalone"},
React.createElement(UnsupportedDeviceView, null)
React.createElement(UnsupportedDeviceView, {platform: "ios"})
)
)
),

Просмотреть файл

@ -555,7 +555,7 @@
<Section name="UnsupportedDeviceView">
<Example summary="Standalone Unsupported Device">
<div className="standalone">
<UnsupportedDeviceView />
<UnsupportedDeviceView platform="ios"/>
</div>
</Example>
</Section>