mirror of
https://github.com/mozilla/gecko-dev.git
synced 2025-02-04 13:07:52 +00:00
Bug 1000131 (Part 2): Loop expired call url view styling, r=dmose.
This commit is contained in:
parent
8081742abe
commit
c30531cbde
@ -15,19 +15,27 @@
|
||||
body {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
font-family: "Helvetica Neue", Helvetica, Arial, sans;
|
||||
font-size: 14px;
|
||||
font-family: "Lucida Grande", sans-serif;
|
||||
font-size: 12px;
|
||||
background: #fbfbfb;
|
||||
}
|
||||
|
||||
button {
|
||||
font-size: .9em; /* for some reason, text is larger within <button> */
|
||||
/* Resetting default <button> font properties; eg. strangely enough, FF mac
|
||||
wants to use Helvetica/12px whatever we define for parent elements */
|
||||
font-family: "Lucida Grande", sans-serif;
|
||||
font-size: 1em;
|
||||
}
|
||||
|
||||
img {
|
||||
border: none;
|
||||
}
|
||||
|
||||
h1, h2, h3 {
|
||||
font-family: "Open Sans", sans-serif;
|
||||
color: #666;
|
||||
}
|
||||
|
||||
/* Helpers */
|
||||
|
||||
/**
|
||||
@ -73,14 +81,24 @@ img {
|
||||
border: none;
|
||||
color: #fff;
|
||||
text-decoration: none;
|
||||
height: 26px;
|
||||
padding: 0 0.5em;
|
||||
padding: .3em .6em;
|
||||
border: 1px solid transparent;
|
||||
border-radius: 2px;
|
||||
cursor: pointer;
|
||||
font-size: .9em;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
button.btn {
|
||||
/* for some reason, buttons respond differently to setting padding than
|
||||
regular links */
|
||||
padding: .3em .3em .3em .5em;
|
||||
}
|
||||
|
||||
.btn-large {
|
||||
padding: .4em 1.6em;
|
||||
}
|
||||
|
||||
.btn-info {
|
||||
background-color: #0096dd;
|
||||
border: 1px solid #0095dd;
|
||||
@ -310,3 +328,39 @@ img {
|
||||
.linux h1 {
|
||||
font-family: 'Ubuntu Bold';
|
||||
}
|
||||
|
||||
/* Web panel */
|
||||
|
||||
.info-panel {
|
||||
border-radius: 4px;
|
||||
background: #fff;
|
||||
padding: 20px 0;
|
||||
border: 1px solid #e7e7e7;
|
||||
box-shadow: 0 2px 0 rgba(0, 0, 0, .03);
|
||||
margin-bottom: 25px;
|
||||
}
|
||||
|
||||
.info-panel h1 {
|
||||
font-size: 1.2em;
|
||||
font-weight: 700;
|
||||
padding: 20px 0;
|
||||
text-align: center;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.info-panel h4 {
|
||||
color: #aaa;
|
||||
text-align: center;
|
||||
font-weight: 300;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
/* Logos */
|
||||
|
||||
.firefox-logo {
|
||||
background: transparent url(../img/firefox-logo.png) no-repeat center center;
|
||||
background-size: contain;
|
||||
width: 100px;
|
||||
height: 100px;
|
||||
margin: 0px auto; /* horizontal block centering */
|
||||
}
|
||||
|
@ -194,6 +194,24 @@
|
||||
font-weight: normal;
|
||||
}
|
||||
|
||||
/* 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;
|
||||
}
|
||||
|
||||
/* Block incoming call */
|
||||
|
||||
.native-dropdown-menu {
|
||||
|
@ -3,10 +3,6 @@
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
/* Panel styles */
|
||||
body {
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.panel {
|
||||
/* XXX the Social API panel behaves weirdly on inner element size changes,
|
||||
adding unwanted scrollbars; quickfix is to hide these for now. */
|
||||
|
@ -17,7 +17,10 @@
|
||||
width: 600px;
|
||||
margin: 1em auto;
|
||||
background: #fff;
|
||||
font-family: Helvetica, Arial, sans;
|
||||
font-size: 12px;
|
||||
}
|
||||
h2 {
|
||||
margin-top: 3em;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
@ -102,8 +105,8 @@
|
||||
<div class="conversation">
|
||||
<ul class="controls">
|
||||
<li><button class="btn btn-hangup" title="Hangup"></button></li>
|
||||
<li><button class="btn media-control btn-mute-video streaming" title="Mute video"></button></li>
|
||||
<li><button class="btn media-control btn-mute-audio" title="Mute audio"></button></li>
|
||||
<li><button class="btn media-control local-media btn-mute-video" title="Mute video"></button></li>
|
||||
<li><button class="btn media-control local-media btn-mute-audio" title="Mute audio"></button></li>
|
||||
</ul>
|
||||
<div class="media nested">
|
||||
<div class="remote_wrapper">
|
||||
@ -119,8 +122,8 @@
|
||||
<div class="conversation">
|
||||
<ul class="controls">
|
||||
<li><button class="btn btn-hangup" title="Hangup"></button></li>
|
||||
<li><button class="btn media-control btn-mute-video streaming" title="Mute video"></button></li>
|
||||
<li><button class="btn media-control btn-mute-audio" title="Mute audio"></button></li>
|
||||
<li><button class="btn media-control local-media btn-mute-video" title="Mute video"></button></li>
|
||||
<li><button class="btn media-control local-media btn-mute-audio" title="Mute audio"></button></li>
|
||||
</ul>
|
||||
<div class="media nested">
|
||||
<div class="remote_wrapper">
|
||||
@ -150,8 +153,8 @@
|
||||
<div class="conversation">
|
||||
<ul class="controls">
|
||||
<li><button class="btn btn-hangup" title="Hangup"></button></li>
|
||||
<li><button class="btn media-control btn-mute-video" title="Mute video"></button></li>
|
||||
<li><button class="btn media-control btn-mute-audio" title="Mute audio"></button></li>
|
||||
<li><button class="btn media-control local-media btn-mute-video" title="Mute video"></button></li>
|
||||
<li><button class="btn media-control local-media btn-mute-audio" title="Mute audio"></button></li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
@ -162,8 +165,8 @@
|
||||
<div class="conversation">
|
||||
<ul class="controls">
|
||||
<li><button class="btn btn-hangup" title="Hangup"></button></li>
|
||||
<li><button class="btn media-control btn-mute-video" title="Mute video"></button></li>
|
||||
<li><button class="btn media-control btn-mute-audio muted" title="Mute audio"></button></li>
|
||||
<li><button class="btn media-control local-media btn-mute-video" title="Mute video"></button></li>
|
||||
<li><button class="btn media-control local-media btn-mute-audio muted" title="Mute audio"></button></li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
@ -174,33 +177,25 @@
|
||||
<div class="conversation">
|
||||
<ul class="controls">
|
||||
<li><button class="btn btn-hangup" title="Hangup"></button></li>
|
||||
<li><button class="btn media-control btn-mute-video muted" title="Mute video"></button></li>
|
||||
<li><button class="btn media-control btn-mute-audio" title="Mute audio"></button></li>
|
||||
<li><button class="btn media-control local-media btn-mute-video muted" title="Mute video"></button></li>
|
||||
<li><button class="btn media-control local-media btn-mute-audio" title="Mute audio"></button></li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<h3>Local audio streaming</h3>
|
||||
<h2>Expired call url view</h2>
|
||||
|
||||
<div style="width: 204px; min-height: 26px">
|
||||
<div class="conversation">
|
||||
<ul class="controls">
|
||||
<li><button class="btn btn-hangup" title="Hangup"></button></li>
|
||||
<li><button class="btn media-control btn-mute-video" title="Mute video"></button></li>
|
||||
<li><button class="btn media-control btn-mute-audio streaming" title="Mute audio"></button></li>
|
||||
</ul>
|
||||
<div class="expired-url-info">
|
||||
<div class="info-panel">
|
||||
<div class="firefox-logo"></div>
|
||||
<h1 >Oops!</h1>
|
||||
<h4 >This URL is unavailable.</h4>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<h3>Local video streaming</h3>
|
||||
|
||||
<div style="width: 204px; min-height: 26px">
|
||||
<div class="conversation">
|
||||
<ul class="controls">
|
||||
<li><button class="btn btn-hangup" title="Hangup"></button></li>
|
||||
<li><button class="btn media-control btn-mute-video streaming" title="Mute video"></button></li>
|
||||
<li><button class="btn media-control btn-mute-audio" title="Mute audio"></button></li>
|
||||
</ul>
|
||||
<div class="promote-firefox">
|
||||
<h3>Download Firefox to make free audio and video calls!</h3>
|
||||
<p>
|
||||
<a class="btn btn-large btn-success" href="https://www.mozilla.org/firefox/" data-reactid=".0.1.1.0">Get Firefox</a>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@ -230,6 +225,16 @@
|
||||
<button class="btn btn-error">error</button>
|
||||
</p>
|
||||
|
||||
<h3>Large buttons</h3>
|
||||
|
||||
<p>
|
||||
<a class="btn btn-large">default</a>
|
||||
<a class="btn btn-large btn-info">info</a>
|
||||
<a class="btn btn-large btn-success">success</a>
|
||||
<a class="btn btn-large btn-warning">warning</a>
|
||||
<a class="btn btn-large btn-error">error</a>
|
||||
</p>
|
||||
|
||||
<h2>Alerts</h2>
|
||||
|
||||
<div class="alert alert-error">
|
||||
@ -242,6 +247,12 @@
|
||||
<p class="message">Oops! This is a warning.</p>
|
||||
</div>
|
||||
|
||||
<h2>Logos</h2>
|
||||
|
||||
<h3>Centered Firefox logo</h3>
|
||||
|
||||
<div class="firefox-logo"></div>
|
||||
|
||||
<h2>Incoming call</h2>
|
||||
|
||||
<div class="incoming-call">
|
||||
|
@ -32,15 +32,51 @@ loop.webapp = (function($, _, OT, webL10n) {
|
||||
template: _.template('<p data-l10n-id="welcome"></p>')
|
||||
});
|
||||
|
||||
/**
|
||||
* Firefox promotion interstitial. Will display only to non-Firefox users.
|
||||
*/
|
||||
var PromoteFirefoxView = React.createClass({displayName: 'PromoteFirefoxView',
|
||||
propTypes: {
|
||||
helper: React.PropTypes.object.isRequired
|
||||
},
|
||||
|
||||
render: function() {
|
||||
if (this.props.helper.isFirefox(navigator.userAgent)) {
|
||||
return React.DOM.div(null );
|
||||
}
|
||||
return (
|
||||
React.DOM.div( {className:"promote-firefox"},
|
||||
React.DOM.h3(null, __("promote_firefox_hello_heading")),
|
||||
React.DOM.p(null,
|
||||
React.DOM.a( {className:"btn btn-large btn-success",
|
||||
href:"https://www.mozilla.org/firefox/"},
|
||||
__("get_firefox_button")
|
||||
)
|
||||
)
|
||||
)
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* Expired call URL view.
|
||||
*/
|
||||
var CallUrlExpiredView = React.createClass({displayName: 'CallUrlExpiredView',
|
||||
propTypes: {
|
||||
helper: React.PropTypes.object.isRequired
|
||||
},
|
||||
|
||||
render: function() {
|
||||
/* jshint ignore:start */
|
||||
return (
|
||||
// XXX proper UX/design should be implemented here (see bug 1000131)
|
||||
React.DOM.div(null, __("call_url_unavailable_notification"))
|
||||
React.DOM.div( {className:"expired-url-info"},
|
||||
React.DOM.div( {className:"info-panel"},
|
||||
React.DOM.div( {className:"firefox-logo"} ),
|
||||
React.DOM.h1(null, __("call_url_unavailable_notification_heading")),
|
||||
React.DOM.h4(null, __("call_url_unavailable_notification_message"))
|
||||
),
|
||||
PromoteFirefoxView( {helper:this.props.helper} )
|
||||
)
|
||||
);
|
||||
/* jshint ignore:end */
|
||||
}
|
||||
@ -135,7 +171,12 @@ loop.webapp = (function($, _, OT, webL10n) {
|
||||
"call/:token": "initiate"
|
||||
},
|
||||
|
||||
initialize: function() {
|
||||
initialize: function(options) {
|
||||
this.helper = options.helper;
|
||||
if (!this.helper) {
|
||||
throw new Error("WebappRouter requires an helper object");
|
||||
}
|
||||
|
||||
// Load default view
|
||||
this.loadView(new HomeView());
|
||||
|
||||
@ -193,7 +234,7 @@ loop.webapp = (function($, _, OT, webL10n) {
|
||||
},
|
||||
|
||||
expired: function() {
|
||||
this.loadReactComponent(CallUrlExpiredView());
|
||||
this.loadReactComponent(CallUrlExpiredView({helper: this.helper}));
|
||||
},
|
||||
|
||||
/**
|
||||
@ -238,8 +279,14 @@ loop.webapp = (function($, _, OT, webL10n) {
|
||||
this._iOSRegex = /^(iPad|iPhone|iPod)/;
|
||||
}
|
||||
|
||||
WebappHelper.prototype.isIOS = function isIOS(platform) {
|
||||
return this._iOSRegex.test(platform);
|
||||
WebappHelper.prototype = {
|
||||
isFirefox: function(platform) {
|
||||
return platform.indexOf("Firefox") !== -1;
|
||||
},
|
||||
|
||||
isIOS: function(platform) {
|
||||
return this._iOSRegex.test(platform);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
@ -248,6 +295,7 @@ loop.webapp = (function($, _, OT, webL10n) {
|
||||
function init() {
|
||||
var helper = new WebappHelper();
|
||||
router = new WebappRouter({
|
||||
helper: helper,
|
||||
notifier: new sharedViews.NotificationListView({el: "#messages"}),
|
||||
conversation: new sharedModels.ConversationModel({}, {
|
||||
sdk: OT,
|
||||
@ -267,8 +315,9 @@ loop.webapp = (function($, _, OT, webL10n) {
|
||||
CallUrlExpiredView: CallUrlExpiredView,
|
||||
ConversationFormView: ConversationFormView,
|
||||
HomeView: HomeView,
|
||||
WebappHelper: WebappHelper,
|
||||
init: init,
|
||||
PromoteFirefoxView: PromoteFirefoxView,
|
||||
WebappHelper: WebappHelper,
|
||||
WebappRouter: WebappRouter
|
||||
};
|
||||
})(jQuery, _, window.OT, document.webL10n);
|
||||
|
@ -32,15 +32,51 @@ loop.webapp = (function($, _, OT, webL10n) {
|
||||
template: _.template('<p data-l10n-id="welcome"></p>')
|
||||
});
|
||||
|
||||
/**
|
||||
* Firefox promotion interstitial. Will display only to non-Firefox users.
|
||||
*/
|
||||
var PromoteFirefoxView = React.createClass({
|
||||
propTypes: {
|
||||
helper: React.PropTypes.object.isRequired
|
||||
},
|
||||
|
||||
render: function() {
|
||||
if (this.props.helper.isFirefox(navigator.userAgent)) {
|
||||
return <div />;
|
||||
}
|
||||
return (
|
||||
<div className="promote-firefox">
|
||||
<h3>{__("promote_firefox_hello_heading")}</h3>
|
||||
<p>
|
||||
<a className="btn btn-large btn-success"
|
||||
href="https://www.mozilla.org/firefox/">
|
||||
{__("get_firefox_button")}
|
||||
</a>
|
||||
</p>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* Expired call URL view.
|
||||
*/
|
||||
var CallUrlExpiredView = React.createClass({
|
||||
propTypes: {
|
||||
helper: React.PropTypes.object.isRequired
|
||||
},
|
||||
|
||||
render: function() {
|
||||
/* jshint ignore:start */
|
||||
return (
|
||||
// XXX proper UX/design should be implemented here (see bug 1000131)
|
||||
<div>{__("call_url_unavailable_notification")}</div>
|
||||
<div className="expired-url-info">
|
||||
<div className="info-panel">
|
||||
<div className="firefox-logo" />
|
||||
<h1>{__("call_url_unavailable_notification_heading")}</h1>
|
||||
<h4>{__("call_url_unavailable_notification_message")}</h4>
|
||||
</div>
|
||||
<PromoteFirefoxView helper={this.props.helper} />
|
||||
</div>
|
||||
);
|
||||
/* jshint ignore:end */
|
||||
}
|
||||
@ -135,7 +171,12 @@ loop.webapp = (function($, _, OT, webL10n) {
|
||||
"call/:token": "initiate"
|
||||
},
|
||||
|
||||
initialize: function() {
|
||||
initialize: function(options) {
|
||||
this.helper = options.helper;
|
||||
if (!this.helper) {
|
||||
throw new Error("WebappRouter requires an helper object");
|
||||
}
|
||||
|
||||
// Load default view
|
||||
this.loadView(new HomeView());
|
||||
|
||||
@ -193,7 +234,7 @@ loop.webapp = (function($, _, OT, webL10n) {
|
||||
},
|
||||
|
||||
expired: function() {
|
||||
this.loadReactComponent(CallUrlExpiredView());
|
||||
this.loadReactComponent(CallUrlExpiredView({helper: this.helper}));
|
||||
},
|
||||
|
||||
/**
|
||||
@ -238,8 +279,14 @@ loop.webapp = (function($, _, OT, webL10n) {
|
||||
this._iOSRegex = /^(iPad|iPhone|iPod)/;
|
||||
}
|
||||
|
||||
WebappHelper.prototype.isIOS = function isIOS(platform) {
|
||||
return this._iOSRegex.test(platform);
|
||||
WebappHelper.prototype = {
|
||||
isFirefox: function(platform) {
|
||||
return platform.indexOf("Firefox") !== -1;
|
||||
},
|
||||
|
||||
isIOS: function(platform) {
|
||||
return this._iOSRegex.test(platform);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
@ -248,6 +295,7 @@ loop.webapp = (function($, _, OT, webL10n) {
|
||||
function init() {
|
||||
var helper = new WebappHelper();
|
||||
router = new WebappRouter({
|
||||
helper: helper,
|
||||
notifier: new sharedViews.NotificationListView({el: "#messages"}),
|
||||
conversation: new sharedModels.ConversationModel({}, {
|
||||
sdk: OT,
|
||||
@ -267,8 +315,9 @@ loop.webapp = (function($, _, OT, webL10n) {
|
||||
CallUrlExpiredView: CallUrlExpiredView,
|
||||
ConversationFormView: ConversationFormView,
|
||||
HomeView: HomeView,
|
||||
WebappHelper: WebappHelper,
|
||||
init: init,
|
||||
PromoteFirefoxView: PromoteFirefoxView,
|
||||
WebappHelper: WebappHelper,
|
||||
WebappRouter: WebappRouter
|
||||
};
|
||||
})(jQuery, _, window.OT, document.webL10n);
|
||||
|
@ -19,7 +19,10 @@ incompatible_device=Incompatible device
|
||||
sorry_device_unsupported=Sorry, Loop does not currently support your device.
|
||||
use_firefox_windows_mac_linux=Please open this page using the latest Firefox on Windows, Android, Mac or Linux.
|
||||
connection_error_see_console_notification=Call failed; see console for details.
|
||||
call_url_unavailable_notification=This URL is unavailable.
|
||||
call_url_unavailable_notification_heading=Oops!
|
||||
call_url_unavailable_notification_message=This URL is unavailable.
|
||||
promote_firefox_hello_heading=Download Firefox to make free audio and video calls!
|
||||
get_firefox_button=Get Firefox
|
||||
|
||||
[fr]
|
||||
call_has_ended=L'appel est terminé.
|
||||
@ -41,4 +44,7 @@ use_latest_firefox.innerHTML=Veuillez essayer ce lien dans un navigateur accepta
|
||||
incompatible_device=Plateforme non supportée
|
||||
sorry_device_unsupported=Désolé, Loop ne fonctionne actuellement pas sur votre appareil.
|
||||
use_firefox_windows_mac_linux=Merci d'ouvrir cette page avec une version récente de Firefox pour Windows, Android, Mac ou Linux.
|
||||
call_url_unavailable_notification=Cette URL n'est pas disponible.
|
||||
call_url_unavailable_notification_heading=Oups !
|
||||
call_url_unavailable_notification_message=Cette URL n'est pas disponible.
|
||||
promote_firefox_hello_heading=Téléchargez Firefox pour passer des appels audio et vidéo gratuitement !
|
||||
get_firefox_button=Téléchargez Firefox
|
||||
|
@ -5,6 +5,7 @@
|
||||
/* global loop, sinon */
|
||||
|
||||
var expect = chai.expect;
|
||||
var TestUtils = React.addons.TestUtils;
|
||||
|
||||
describe("loop.webapp", function() {
|
||||
"use strict";
|
||||
@ -76,6 +77,7 @@ describe("loop.webapp", function() {
|
||||
pendingCallTimeout: 1000
|
||||
});
|
||||
router = new loop.webapp.WebappRouter({
|
||||
helper: {},
|
||||
conversation: conversation,
|
||||
notifier: notifier
|
||||
});
|
||||
@ -359,6 +361,26 @@ describe("loop.webapp", function() {
|
||||
});
|
||||
});
|
||||
|
||||
describe("PromoteFirefoxView", function() {
|
||||
describe("#render", function() {
|
||||
it("should not render when using Firefox", function() {
|
||||
var comp = TestUtils.renderIntoDocument(loop.webapp.PromoteFirefoxView({
|
||||
helper: {isFirefox: function() { return true; }}
|
||||
}));
|
||||
|
||||
expect(comp.getDOMNode().querySelectorAll("h3").length).eql(0);
|
||||
});
|
||||
|
||||
it("should render when not using Firefox", function() {
|
||||
var comp = TestUtils.renderIntoDocument(loop.webapp.PromoteFirefoxView({
|
||||
helper: {isFirefox: function() { return false; }}
|
||||
}));
|
||||
|
||||
expect(comp.getDOMNode().querySelectorAll("h3").length).eql(1);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe("WebappHelper", function() {
|
||||
var helper;
|
||||
|
||||
@ -378,5 +400,18 @@ describe("loop.webapp", function() {
|
||||
expect(helper.isIOS("MacIntel")).eql(false);
|
||||
});
|
||||
});
|
||||
|
||||
describe("#isFirefox", function() {
|
||||
it("should detect Firefox", function() {
|
||||
expect(helper.isFirefox("Firefox")).eql(true);
|
||||
expect(helper.isFirefox("Gecko/Firefox")).eql(true);
|
||||
expect(helper.isFirefox("Firefox/Gecko")).eql(true);
|
||||
expect(helper.isFirefox("Gecko/Firefox/Chuck Norris")).eql(true);
|
||||
});
|
||||
|
||||
it("shouldn't detect Firefox with other platforms", function() {
|
||||
expect(helper.isFirefox("Opera")).eql(false);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
Loading…
x
Reference in New Issue
Block a user