Skip to content
This repository has been archived by the owner on Dec 1, 2017. It is now read-only.

Commit

Permalink
Bug 1245608 - Implement slideshow frame for Hello, r=Standard8
Browse files Browse the repository at this point in the history
  • Loading branch information
Dan Mosedale authored and Standard8 committed Feb 15, 2016
1 parent e71a2f9 commit 285e100
Show file tree
Hide file tree
Showing 12 changed files with 238 additions and 46 deletions.
28 changes: 28 additions & 0 deletions add-on/chrome/bootstrap.js
Expand Up @@ -24,6 +24,18 @@ XPCOMUtils.defineLazyModuleGetter(this, "CustomizableUI",
XPCOMUtils.defineLazyModuleGetter(this, "Task",
"resource://gre/modules/Task.jsm");

// See LOG_LEVELS in Console.jsm. Common examples: "All", "Info", "Warn", & "Error".
const PREF_LOG_LEVEL = "loop.debug.loglevel";

XPCOMUtils.defineLazyGetter(this, "log", () => {
let ConsoleAPI = Cu.import("resource://gre/modules/Console.jsm", {}).ConsoleAPI;
let consoleOptions = {
maxLogLevelPref: PREF_LOG_LEVEL,
prefix: "Loop"
};
return new ConsoleAPI(consoleOptions);
});

/**
* This window listener gets loaded into each browser.xul window and is used
* to provide the required loop functions for the window.
Expand All @@ -43,6 +55,7 @@ var WindowListener = {
let xhrClass = Cc["@mozilla.org/xmlextras/xmlhttprequest;1"];
let FileReader = window.FileReader;
let menuItem = null;
let isSlideshowOpen = false;

// the "exported" symbols
var LoopUI = {
Expand Down Expand Up @@ -77,6 +90,15 @@ var WindowListener = {
return browser;
},

get isSlideshowOpen() {
return isSlideshowOpen;
},

set isSlideshowOpen(aOpen) {
log.info("in isSlideshowOpen setter, aOpen = ", aOpen);
isSlideshowOpen = aOpen;
this.updateToolbarState();
},
/**
* @return {Object} Getter for the Loop constants
*/
Expand Down Expand Up @@ -133,6 +155,10 @@ var WindowListener = {
});
}

if (this.isSlideshowOpen) {
return Promise.resolve();
}

return this.openPanel(event).then(mm => {
if (mm) {
mm.sendAsyncMessage("Social:EnsureFocusElement");
Expand Down Expand Up @@ -349,6 +375,8 @@ var WindowListener = {
if (this.MozLoopService.errors.size) {
state = "error";
mozL10nId += "-error";
} else if (this.isSlideshowOpen) {
state = "slideshow";
} else if (this.MozLoopService.screenShareActive) {
state = "action";
mozL10nId += "-screensharing";
Expand Down
13 changes: 7 additions & 6 deletions add-on/chrome/modules/MozLoopAPI.jsm
Expand Up @@ -811,16 +811,13 @@ const kMessageHandlers = {
*
* @param {Object} message Message meant for the handler function, containing
* the following parameters in its `data` property:
* [
* {String} src Origin that starts or resumes the tour
* ]
* []
* @param {Function} reply Callback function, invoked with the result of this
* message handler. The result will be sent back to
* the senders' channel.
*/
OpenGettingStartedTour: function(message, reply) {
var src = message.data[0];
MozLoopService.openGettingStartedTour(src);
MozLoopService.openGettingStartedTour();
reply();
},

Expand Down Expand Up @@ -1075,7 +1072,11 @@ const LoopAPIInternal = {

Cu.import("resource://gre/modules/RemotePageManager.jsm");

gPageListeners = [new RemotePages("about:looppanel"), new RemotePages("about:loopconversation")];
gPageListeners = [new RemotePages("about:looppanel"),
new RemotePages("about:loopconversation"),
// Slideshow added here to expose the loop api to make L10n work.
// XXX Can remove once slideshow is made remote.
new RemotePages("chrome://loop/content/panels/slideshow.html")];
for (let page of gPageListeners) {
page.addMessageListener(kMessageName, this.handleMessage.bind(this));
}
Expand Down
82 changes: 70 additions & 12 deletions add-on/chrome/modules/MozLoopService.jsm
Expand Up @@ -1655,6 +1655,19 @@ this.MozLoopService = {
}
},

/*
* Returns current FTU version
*
* @return {Number}
*
* XXX must match number in panel.jsx; expose this via MozLoopAPI
* and kill that constant.
*/
get FTU_VERSION()
{
return 2;
},

/**
* Set any preference under "loop.".
*
Expand Down Expand Up @@ -1918,20 +1931,65 @@ this.MozLoopService = {

/**
* Opens the Getting Started tour in the browser.
*
* @param {String} [aSrc] A string representing the entry point to begin the tour, optional.
*/
openGettingStartedTour: Task.async(function(aSrc = null) {
try {
let url = this.getTourURL(aSrc);
let win = Services.wm.getMostRecentWindow("navigator:browser");
win.switchToTabHavingURI(url, true, {
ignoreFragment: true,
replaceQueryString: true
});
} catch (ex) {
log.error("Error opening Getting Started tour", ex);
openGettingStartedTour: Task.async(function() {
const kNSXUL = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";

// User will have _just_ clicked the tour menu item or the FTU
// button in the panel, (or else it wouldn't be visible), so...
let xulWin = Services.wm.getMostRecentWindow("navigator:browser");
let xulDoc = xulWin.document;

let box = xulDoc.createElementNS(kNSXUL, "box");
box.setAttribute("id", "loop-slideshow-container");

let appContent = xulDoc.getElementById("appcontent");
let tabBrowser = xulDoc.getElementById("content");
appContent.insertBefore(box, tabBrowser);

var xulBrowser = xulDoc.createElementNS(kNSXUL, "browser");
xulBrowser.setAttribute("id", "loop-slideshow-browser");
xulBrowser.setAttribute("flex", "1");
xulBrowser.setAttribute("type", "content");
box.appendChild(xulBrowser);

// Notify the UI, which has the side effect of disabling panel opening
// and updating the toolbar icon to visually indicate difference.
xulWin.LoopUI.isSlideshowOpen = true;

var removeSlideshow = function() {
try {
appContent.removeChild(box);
} catch (ex) {
log.error(ex);
}

this.setLoopPref("gettingStarted.latestFTUVersion", this.FTU_VERSION);

// Notify the UI, which has the side effect of re-enabling panel opening
// and updating the toolbar.
xulWin.LoopUI.isSlideshowOpen = false;

xulWin.removeEventListener("CloseSlideshow", removeSlideshow);

log.info("slideshow removed");
}.bind(this);

function xulLoadListener() {
xulBrowser.contentWindow.addEventListener("CloseSlideshow",
removeSlideshow);
log.info("CloseSlideshow handler added");

xulBrowser.removeEventListener("load", xulLoadListener, true);
}

xulBrowser.addEventListener("load", xulLoadListener, true);

// XXX we are loading the slideshow page with chrome privs.
// To make this remote, we'll need to think through a better
// security model.
xulBrowser.setAttribute("src",
"chrome://loop/content/panels/slideshow.html");
}),

/**
Expand Down
30 changes: 30 additions & 0 deletions add-on/chrome/skin/shared/loop.css
Expand Up @@ -50,6 +50,15 @@
-moz-image-region: rect(1px, 125px, 17px, 109px);
}

/* The slideshow state disables the button for that window and makes it look
the same as the hover state to visually indicate that it's in-use.
*/
#loop-button[state="slideshow"] {
background: var(--toolbarbutton-hover-background);
border-color: var(--toolbarbutton-hover-bordercolor);
box-shadow: var(--toolbarbutton-hover-boxshadow);
}

@media (min-resolution: 1.1dppx) {
#loop-button {
list-style-image: url("chrome://loop/skin/toolbar@2x.png");
Expand Down Expand Up @@ -289,4 +298,25 @@
pointer-events: none;
position: absolute;
}

#loop-slideshow-container {
/* cover the entire viewport, mouse interaction with non-slideshow
content is now impossible. */
position: fixed;
z-index: 1;
width: 100%;
height: 100%;

/* darken the background content */
background: rgba(0, 0, 0, .8);
}

#loop-slideshow-browser {
width: 480px;
height: 360px;
margin-top: 40px;

/* XXX derived from width, so should be 50% - 480px / 2? */
-moz-margin-start: calc(50% - 240px);
}
}
2 changes: 1 addition & 1 deletion add-on/chrome/test/mochitest/browser_fxa_login.js
Expand Up @@ -41,7 +41,7 @@ function* checkFxA401() {
}

add_task(function* setup() {
Services.prefs.setIntPref("loop.gettingStarted.latestFTUVersion", 1);
Services.prefs.setIntPref("loop.gettingStarted.latestFTUVersion", 2);
MozLoopServiceInternal.mocks.pushHandler = mockPushHandler;
// Normally the same pushUrl would be registered but we change it in the test
// to be able to check for success on the second registration.
Expand Down
2 changes: 1 addition & 1 deletion add-on/chrome/test/mochitest/browser_toolbarbutton.js
Expand Up @@ -8,7 +8,7 @@
"use strict";

Components.utils.import("resource://gre/modules/Promise.jsm", this);
Services.prefs.setIntPref("loop.gettingStarted.latestFTUVersion", 1);
Services.prefs.setIntPref("loop.gettingStarted.latestFTUVersion", 2);

const fxASampleToken = {
token_type: "bearer",
Expand Down
45 changes: 23 additions & 22 deletions add-on/panels/js/panel.jsx
Expand Up @@ -12,19 +12,15 @@ loop.panel = (function(_, mozL10n) {
var sharedActions = loop.shared.actions;
var Button = sharedViews.Button;

var FTU_VERSION = 1;
// XXX This must be kept in sync with the number in MozLoopService.jsm.
// We should expose that one through MozLoopAPI and kill this constant.
var FTU_VERSION = 2;

var GettingStartedView = React.createClass({
mixins: [sharedMixins.WindowCloseMixin],

handleButtonClick: function() {
loop.requestMulti(
["OpenGettingStartedTour", "getting-started"],
["SetLoopPref", "gettingStarted.latestFTUVersion", FTU_VERSION]
).then(function() {
var event = new CustomEvent("GettingStartedSeen");
window.dispatchEvent(event);
}.bind(this));
loop.request("OpenGettingStartedTour");
this.closeWindow();
},

Expand Down Expand Up @@ -265,7 +261,7 @@ loop.panel = (function(_, mozL10n) {
},

openGettingStartedTour: function() {
loop.request("OpenGettingStartedTour", "settings-menu");
loop.request("OpenGettingStartedTour");
this.closeWindow();
},

Expand Down Expand Up @@ -967,27 +963,34 @@ loop.panel = (function(_, mozL10n) {
_onStatusChanged: function() {
loop.requestMulti(
["GetUserProfile"],
["GetHasEncryptionKey"]
["GetHasEncryptionKey"],
["GetLoopPref", "gettingStarted.latestFTUVersion"]
).then(function(results) {
var profile = results[0];
var hasEncryptionKey = results[1];
var prefFTUVersion = results[2];

var stateToUpdate = {};

// It's possible that this state change was slideshow related
// so update that if the pref has changed.
var prefGettingStartedSeen = (prefFTUVersion >= FTU_VERSION);
if (prefGettingStartedSeen !== this.state.gettingStartedSeen) {
stateToUpdate.gettingStartedSeen = prefGettingStartedSeen;
}

var currUid = this.state.userProfile ? this.state.userProfile.uid : null;
var newUid = profile ? profile.uid : null;
if (currUid === newUid) {
// Update the state of hasEncryptionKey as this might have changed now.
this.setState({ hasEncryptionKey: hasEncryptionKey });
stateToUpdate.hasEncryptionKey = hasEncryptionKey;
} else {
this.setState({ userProfile: profile });
stateToUpdate.userProfile = profile;
}
this.updateServiceErrors();
}.bind(this));
},

_gettingStartedSeen: function() {
loop.request("GetLoopPref", "gettingStarted.latestFTUVersion").then(function(result) {
this.setState({
gettingStartedSeen: result >= FTU_VERSION
});
this.setState(stateToUpdate);

this.updateServiceErrors();
}.bind(this));
},

Expand All @@ -997,12 +1000,10 @@ loop.panel = (function(_, mozL10n) {

componentDidMount: function() {
loop.subscribe("LoopStatusChanged", this._onStatusChanged);
window.addEventListener("GettingStartedSeen", this._gettingStartedSeen);
},

componentWillUnmount: function() {
loop.unsubscribe("LoopStatusChanged", this._onStatusChanged);
window.removeEventListener("GettingStartedSeen", this._gettingStartedSeen);
},

handleContextMenu: function(e) {
Expand Down

0 comments on commit 285e100

Please sign in to comment.