Bug 1212074 - Remove the tabs from Loop's panel. r=Standard8

This commit is contained in:
David Critchley 2015-10-08 11:30:06 +01:00
parent d6efa38e22
commit 4e0f9302bd
7 changed files with 35 additions and 549 deletions

View File

@ -76,147 +76,6 @@ body {
border-radius: 3px;
}
/* Tabs and tab selection buttons */
.tab-view-container {
width: 100%;
background-image: url("../shared/img/beta-ribbon.svg#beta-ribbon");
background-color: #fbfbfb;
background-size: 36px 36px;
background-repeat: no-repeat;
flex: 1;
display: flex;
flex-flow: column nowrap;
overflow: hidden;
}
.tab-view {
position: relative;
width: 100%;
height: 4rem;
line-height: 3.7rem;
color: #4A4A4A;
list-style: none;
border-bottom: 2px solid #ccc;
}
.tab-view > li {
display: inline-block;
text-align: center;
padding: 0;
cursor: pointer;
}
.tab-view > .slide-bar {
position: absolute;
bottom: -2px;
left: 0;
height: .2em;
width: 50%;
background: #00A9DC;
border: none;
transition: margin .3s ease-in-out;
}
.tab-view li:nth-child(1).selected ~ .slide-bar {
margin-left: 0;
}
.tab-view li:nth-child(2).selected ~ .slide-bar {
margin-left: 50%;
}
html[dir="rtl"] .tab-view li:nth-child(1).selected ~ .slide-bar {
margin-left: 50%;
}
html[dir="rtl"] .tab-view li:nth-child(2).selected ~ .slide-bar {
margin-left: 0;
}
.tab-view > li > div {
font-size: 1.2rem;
pointer-events: none;
display: inline;
}
.tab-view > li:before {
content: "";
pointer-events: none;
display: inline-block;
-moz-margin-end: .5rem;
vertical-align: middle;
height: 1.4rem;
width: 1.4rem;
transition-property: background-image;
}
.tab-view > li.selected {
transition-delay: .3s;
}
.tab-view > li[data-tab-name="rooms"]:before {
background-image: url("../shared/img/icons-14x14.svg#hello");
}
.tab-view > li[data-tab-name="rooms"]:hover:before {
background-image: url("../shared/img/icons-14x14.svg#hello-hover");
}
.tab-view > li[data-tab-name="rooms"].selected:before {
background-image: url("../shared/img/icons-14x14.svg#hello-active");
}
.tab-view > li[data-tab-name="contacts"]:before {
background-image: url("../shared/img/icons-14x14.svg#contacts");
}
.tab-view > li[data-tab-name="contacts"]:hover:before {
background-image: url("../shared/img/icons-14x14.svg#contacts-hover");
}
.tab-view > li[data-tab-name="contacts"].selected:before {
background-image: url("../shared/img/icons-14x14.svg#contacts-active");
}
/* Styling for one tab */
.tab-view li:first-child:nth-last-child(2) {
width: 100%;
}
.tab-view li:first-child:nth-last-child(2) > span {
display: none;
}
.tab-view li:first-child:nth-last-child(2) > span {
display: none;
}
.tab-view li:first-child:nth-last-child(2):before {
background-image: url("../shared/img/icons-14x14.svg#hello-hover");
}
.tab-view li:first-child:nth-last-child(2) ~ li {
/* hide the tab-slider when there is only one tab shown */
display: none;
}
.tab-view li:first-child:nth-last-child(3),
.tab-view li:first-child:nth-last-child(3) ~ li {
width: 50%;
}
.tab {
display: none;
flex: 1;
overflow: auto;
}
.tab.selected {
display: flex;
flex-flow: column nowrap;
}
/* Content area and input fields */
.content-area {
@ -232,8 +91,7 @@ html[dir="rtl"] .tab-view li:nth-child(2).selected ~ .slide-bar {
-moz-padding-start: 20px;
}
.fte-get-started-container + .generate-url > #share-link-header,
.tab-view + .tab .content-area > .generate-url > #share-link-header {
.fte-get-started-container + .generate-url > #share-link-header {
/* The header shouldn't be indented if the tabs are present. */
-moz-padding-start: 0;
}
@ -331,6 +189,7 @@ html[dir="rtl"] .tab-view li:nth-child(2).selected ~ .slide-bar {
flex: 1;
display: flex;
flex-flow: column nowrap;
width: 100%;
}
.rooms > h1 {
@ -414,6 +273,7 @@ html[dir="rtl"] .tab-view li:nth-child(2).selected ~ .slide-bar {
overflow-x: hidden;
display: flex;
flex-flow: column nowrap;
width: 100%;
}
.room-list-empty {

View File

@ -10,109 +10,8 @@ loop.panel = (function(_, mozL10n) {
var sharedModels = loop.shared.models;
var sharedMixins = loop.shared.mixins;
var sharedActions = loop.shared.actions;
var sharedUtils = loop.shared.utils;
var Button = sharedViews.Button;
var ButtonGroup = sharedViews.ButtonGroup;
var Checkbox = sharedViews.Checkbox;
var ContactsControllerView = loop.contacts.ContactsControllerView;
var TabView = React.createClass({displayName: "TabView",
propTypes: {
buttonsHidden: React.PropTypes.array,
children: React.PropTypes.arrayOf(React.PropTypes.element),
mozLoop: React.PropTypes.object,
// The selectedTab prop is used by the UI showcase.
selectedTab: React.PropTypes.string
},
getDefaultProps: function() {
return {
buttonsHidden: []
};
},
shouldComponentUpdate: function(nextProps, nextState) {
var tabChange = this.state.selectedTab !== nextState.selectedTab;
if (tabChange) {
this.props.mozLoop.notifyUITour("Loop:PanelTabChanged", nextState.selectedTab);
}
if (!tabChange && nextProps.buttonsHidden) {
if (nextProps.buttonsHidden.length !== this.props.buttonsHidden.length) {
tabChange = true;
} else {
for (var i = 0, l = nextProps.buttonsHidden.length; i < l && !tabChange; ++i) {
if (this.props.buttonsHidden.indexOf(nextProps.buttonsHidden[i]) === -1) {
tabChange = true;
}
}
}
}
return tabChange;
},
getInitialState: function() {
// XXX Work around props.selectedTab being undefined initially.
// When we don't need to rely on the pref, this can move back to
// getDefaultProps (bug 1100258).
return {
selectedTab: this.props.selectedTab || "rooms"
};
},
handleSelectTab: function(event) {
var tabName = event.target.dataset.tabName;
this.setState({selectedTab: tabName});
},
render: function() {
var cx = React.addons.classSet;
var tabButtons = [];
var tabs = [];
React.Children.forEach(this.props.children, function(tab, i) {
// Filter out null tabs (eg. rooms when the feature is disabled)
if (!tab) {
return;
}
var tabName = tab.props.name;
if (this.props.buttonsHidden.indexOf(tabName) > -1) {
return;
}
var isSelected = (this.state.selectedTab === tabName);
if (!tab.props.hidden) {
var label = mozL10n.get(tabName + "_tab_button");
tabButtons.push(
React.createElement("li", {className: cx({selected: isSelected}),
"data-tab-name": tabName,
key: i,
onClick: this.handleSelectTab},
React.createElement("div", null, label)
)
);
}
tabs.push(
React.createElement("div", {className: cx({tab: true, selected: isSelected}), key: i},
tab.props.children
)
);
}, this);
return (
React.createElement("div", {className: "tab-view-container"},
React.createElement("ul", {className: "tab-view"},
tabButtons,
React.createElement("li", {className: "slide-bar"})
),
tabs
)
);
}
});
var Tab = React.createClass({displayName: "Tab",
render: function() {
return null;
}
});
/**
* Availability drop down menu subview.
@ -1001,14 +900,10 @@ loop.panel = (function(_, mozL10n) {
var PanelView = React.createClass({displayName: "PanelView",
propTypes: {
dispatcher: React.PropTypes.instanceOf(loop.Dispatcher).isRequired,
initialSelectedTabComponent: React.PropTypes.string,
mozLoop: React.PropTypes.object.isRequired,
notifications: React.PropTypes.object.isRequired,
roomStore:
React.PropTypes.instanceOf(loop.store.RoomStore).isRequired,
selectedTab: React.PropTypes.string,
// Used only for unit tests.
showTabButtons: React.PropTypes.bool
React.PropTypes.instanceOf(loop.store.RoomStore).isRequired
},
getInitialState: function() {
@ -1056,8 +951,6 @@ loop.panel = (function(_, mozL10n) {
// Update the state of hasEncryptionKey as this might have changed now.
this.setState({hasEncryptionKey: this.props.mozLoop.hasEncryptionKey});
} else {
// On profile change (login, logout), switch back to the default tab.
this.selectTab("rooms");
this.setState({userProfile: profile});
}
this.updateServiceErrors();
@ -1069,25 +962,6 @@ loop.panel = (function(_, mozL10n) {
});
},
_UIActionHandler: function(e) {
switch (e.detail.action) {
case "selectTab":
this.selectTab(e.detail.tab);
break;
default:
console.error("Invalid action", e.detail.action);
break;
}
},
selectTab: function(name) {
// The tab view might not be created yet (e.g. getting started or fxa
// re-sign in.
if (this.refs.tabView) {
this.refs.tabView.setState({ selectedTab: name });
}
},
componentWillMount: function() {
this.updateServiceErrors();
},
@ -1095,13 +969,11 @@ loop.panel = (function(_, mozL10n) {
componentDidMount: function() {
window.addEventListener("LoopStatusChanged", this._onStatusChanged);
window.addEventListener("GettingStartedSeen", this._gettingStartedSeen);
window.addEventListener("UIAction", this._UIActionHandler);
},
componentWillUnmount: function() {
window.removeEventListener("LoopStatusChanged", this._onStatusChanged);
window.removeEventListener("GettingStartedSeen", this._gettingStartedSeen);
window.removeEventListener("UIAction", this._UIActionHandler);
},
render: function() {
@ -1123,35 +995,15 @@ loop.panel = (function(_, mozL10n) {
return React.createElement(SignInRequestView, {mozLoop: this.props.mozLoop});
}
// Determine which buttons to NOT show.
var hideButtons = [];
if (!this.state.userProfile && !this.props.showTabButtons) {
hideButtons.push("contacts");
}
return (
React.createElement("div", {className: "panel-content"},
React.createElement(NotificationListView, {
clearOnDocumentHidden: true,
notifications: this.props.notifications}),
React.createElement(TabView, {
buttonsHidden: hideButtons,
mozLoop: this.props.mozLoop,
ref: "tabView",
selectedTab: this.props.selectedTab},
React.createElement(Tab, {name: "rooms"},
React.createElement(RoomList, {dispatcher: this.props.dispatcher,
mozLoop: this.props.mozLoop,
store: this.props.roomStore,
userProfile: this.state.userProfile})
),
React.createElement(Tab, {name: "contacts"},
React.createElement(ContactsControllerView, {initialSelectedTabComponent: this.props.initialSelectedTabComponent,
mozLoop: this.props.mozLoop,
notifications: this.props.notifications,
ref: "contactControllerView"})
)
),
React.createElement(RoomList, {dispatcher: this.props.dispatcher,
mozLoop: this.props.mozLoop,
store: this.props.roomStore,
userProfile: this.state.userProfile}),
React.createElement("div", {className: "footer"},
React.createElement("div", {className: "user-details"},
React.createElement(AvailabilityDropdown, null)

View File

@ -10,109 +10,8 @@ loop.panel = (function(_, mozL10n) {
var sharedModels = loop.shared.models;
var sharedMixins = loop.shared.mixins;
var sharedActions = loop.shared.actions;
var sharedUtils = loop.shared.utils;
var Button = sharedViews.Button;
var ButtonGroup = sharedViews.ButtonGroup;
var Checkbox = sharedViews.Checkbox;
var ContactsControllerView = loop.contacts.ContactsControllerView;
var TabView = React.createClass({
propTypes: {
buttonsHidden: React.PropTypes.array,
children: React.PropTypes.arrayOf(React.PropTypes.element),
mozLoop: React.PropTypes.object,
// The selectedTab prop is used by the UI showcase.
selectedTab: React.PropTypes.string
},
getDefaultProps: function() {
return {
buttonsHidden: []
};
},
shouldComponentUpdate: function(nextProps, nextState) {
var tabChange = this.state.selectedTab !== nextState.selectedTab;
if (tabChange) {
this.props.mozLoop.notifyUITour("Loop:PanelTabChanged", nextState.selectedTab);
}
if (!tabChange && nextProps.buttonsHidden) {
if (nextProps.buttonsHidden.length !== this.props.buttonsHidden.length) {
tabChange = true;
} else {
for (var i = 0, l = nextProps.buttonsHidden.length; i < l && !tabChange; ++i) {
if (this.props.buttonsHidden.indexOf(nextProps.buttonsHidden[i]) === -1) {
tabChange = true;
}
}
}
}
return tabChange;
},
getInitialState: function() {
// XXX Work around props.selectedTab being undefined initially.
// When we don't need to rely on the pref, this can move back to
// getDefaultProps (bug 1100258).
return {
selectedTab: this.props.selectedTab || "rooms"
};
},
handleSelectTab: function(event) {
var tabName = event.target.dataset.tabName;
this.setState({selectedTab: tabName});
},
render: function() {
var cx = React.addons.classSet;
var tabButtons = [];
var tabs = [];
React.Children.forEach(this.props.children, function(tab, i) {
// Filter out null tabs (eg. rooms when the feature is disabled)
if (!tab) {
return;
}
var tabName = tab.props.name;
if (this.props.buttonsHidden.indexOf(tabName) > -1) {
return;
}
var isSelected = (this.state.selectedTab === tabName);
if (!tab.props.hidden) {
var label = mozL10n.get(tabName + "_tab_button");
tabButtons.push(
<li className={cx({selected: isSelected})}
data-tab-name={tabName}
key={i}
onClick={this.handleSelectTab}>
<div>{label}</div>
</li>
);
}
tabs.push(
<div className={cx({tab: true, selected: isSelected})} key={i}>
{tab.props.children}
</div>
);
}, this);
return (
<div className="tab-view-container">
<ul className="tab-view">
{tabButtons}
<li className="slide-bar" />
</ul>
{tabs}
</div>
);
}
});
var Tab = React.createClass({
render: function() {
return null;
}
});
/**
* Availability drop down menu subview.
@ -1001,14 +900,10 @@ loop.panel = (function(_, mozL10n) {
var PanelView = React.createClass({
propTypes: {
dispatcher: React.PropTypes.instanceOf(loop.Dispatcher).isRequired,
initialSelectedTabComponent: React.PropTypes.string,
mozLoop: React.PropTypes.object.isRequired,
notifications: React.PropTypes.object.isRequired,
roomStore:
React.PropTypes.instanceOf(loop.store.RoomStore).isRequired,
selectedTab: React.PropTypes.string,
// Used only for unit tests.
showTabButtons: React.PropTypes.bool
React.PropTypes.instanceOf(loop.store.RoomStore).isRequired
},
getInitialState: function() {
@ -1056,8 +951,6 @@ loop.panel = (function(_, mozL10n) {
// Update the state of hasEncryptionKey as this might have changed now.
this.setState({hasEncryptionKey: this.props.mozLoop.hasEncryptionKey});
} else {
// On profile change (login, logout), switch back to the default tab.
this.selectTab("rooms");
this.setState({userProfile: profile});
}
this.updateServiceErrors();
@ -1069,25 +962,6 @@ loop.panel = (function(_, mozL10n) {
});
},
_UIActionHandler: function(e) {
switch (e.detail.action) {
case "selectTab":
this.selectTab(e.detail.tab);
break;
default:
console.error("Invalid action", e.detail.action);
break;
}
},
selectTab: function(name) {
// The tab view might not be created yet (e.g. getting started or fxa
// re-sign in.
if (this.refs.tabView) {
this.refs.tabView.setState({ selectedTab: name });
}
},
componentWillMount: function() {
this.updateServiceErrors();
},
@ -1095,13 +969,11 @@ loop.panel = (function(_, mozL10n) {
componentDidMount: function() {
window.addEventListener("LoopStatusChanged", this._onStatusChanged);
window.addEventListener("GettingStartedSeen", this._gettingStartedSeen);
window.addEventListener("UIAction", this._UIActionHandler);
},
componentWillUnmount: function() {
window.removeEventListener("LoopStatusChanged", this._onStatusChanged);
window.removeEventListener("GettingStartedSeen", this._gettingStartedSeen);
window.removeEventListener("UIAction", this._UIActionHandler);
},
render: function() {
@ -1123,35 +995,15 @@ loop.panel = (function(_, mozL10n) {
return <SignInRequestView mozLoop={this.props.mozLoop} />;
}
// Determine which buttons to NOT show.
var hideButtons = [];
if (!this.state.userProfile && !this.props.showTabButtons) {
hideButtons.push("contacts");
}
return (
<div className="panel-content">
<NotificationListView
clearOnDocumentHidden={true}
notifications={this.props.notifications} />
<TabView
buttonsHidden={hideButtons}
mozLoop={this.props.mozLoop}
ref="tabView"
selectedTab={this.props.selectedTab}>
<Tab name="rooms">
<RoomList dispatcher={this.props.dispatcher}
mozLoop={this.props.mozLoop}
store={this.props.roomStore}
userProfile={this.state.userProfile} />
</Tab>
<Tab name="contacts">
<ContactsControllerView initialSelectedTabComponent={this.props.initialSelectedTabComponent}
mozLoop={this.props.mozLoop}
notifications={this.props.notifications}
ref="contactControllerView" />
</Tab>
</TabView>
<RoomList dispatcher={this.props.dispatcher}
mozLoop={this.props.mozLoop}
store={this.props.roomStore}
userProfile={this.state.userProfile} />
<div className="footer">
<div className="user-details">
<AvailabilityDropdown />

View File

@ -210,69 +210,6 @@ describe("loop.panel", function() {
.to.have.length.of(0);
});
describe("TabView", function() {
var view, callTab, roomsTab, contactsTab;
beforeEach(function() {
navigator.mozLoop.getLoopPref = function(pref) {
if (pref === "gettingStarted.seen") {
return true;
}
};
view = createTestPanelView();
[roomsTab, contactsTab] =
TestUtils.scryRenderedDOMComponentsWithClass(view, "tab");
});
it("should select contacts tab when clicking tab button", function() {
TestUtils.Simulate.click(
view.getDOMNode().querySelector("li[data-tab-name=\"contacts\"]"));
expect(contactsTab.getDOMNode().classList.contains("selected"))
.to.be.true;
});
it("should select rooms tab when clicking tab button", function() {
TestUtils.Simulate.click(
view.getDOMNode().querySelector("li[data-tab-name=\"rooms\"]"));
expect(roomsTab.getDOMNode().classList.contains("selected"))
.to.be.true;
});
});
describe("Contacts", function() {
var view, roomsTab, contactsTab;
beforeEach(function() {
view = TestUtils.renderIntoDocument(
React.createElement(loop.panel.PanelView, {
dispatcher: dispatcher,
initialSelectedTabComponent: "contactList",
mozLoop: navigator.mozLoop,
notifications: notifications,
roomStore: roomStore,
selectedTab: "contacts",
showTabButtons: true
}));
[roomsTab, contactsTab] =
TestUtils.scryRenderedDOMComponentsWithClass(view, "tab");
});
it("should expect Contacts tab to be selected when Contacts List displayed", function() {
expect(contactsTab.getDOMNode().classList.contains("selected"))
.to.be.true;
});
it("should expect Rooms tab to be not selected when Contacts List displayed", function() {
expect(roomsTab.getDOMNode().classList.contains("selected"))
.to.be.false;
});
});
describe("AccountLink", function() {
beforeEach(function() {
navigator.mozLoop.calls = { clearCallInProgress: function() {} };

View File

@ -766,8 +766,7 @@
dispatcher: dispatcher,
mozLoop: firstTimeUseMozLoop,
notifications: notifications,
roomStore: roomStore,
selectedTab: "rooms"})
roomStore: roomStore})
)
),
@ -784,75 +783,70 @@
React.createElement(FramedExample, {cssClass: "fx-embedded-panel",
dashed: true,
height: 410,
summary: "Room list tab",
summary: "Room list",
width: 330},
React.createElement("div", {className: "panel"},
React.createElement(PanelView, {client: mockClient,
dispatcher: dispatcher,
mozLoop: mockMozLoopLoggedIn,
notifications: notifications,
roomStore: roomStore,
selectedTab: "rooms"})
roomStore: roomStore})
)
),
React.createElement(FramedExample, {cssClass: "fx-embedded-panel",
dashed: true,
height: 410,
summary: "Room list tab (No Context)",
summary: "Room list (No Context)",
width: 330},
React.createElement("div", {className: "panel"},
React.createElement(PanelView, {client: mockClient,
dispatcher: dispatcher,
mozLoop: mockMozLoopLoggedInNoContext,
notifications: notifications,
roomStore: roomStore,
selectedTab: "rooms"})
roomStore: roomStore})
)
),
React.createElement(FramedExample, {cssClass: "fx-embedded-panel",
dashed: true,
height: 410,
summary: "Room list tab (no rooms)",
summary: "Room list (no rooms)",
width: 330},
React.createElement("div", {className: "panel"},
React.createElement(PanelView, {client: mockClient,
dispatcher: dispatcher,
mozLoop: mockMozLoopNoRooms,
notifications: notifications,
roomStore: roomStoreNoRooms,
selectedTab: "rooms"})
roomStore: roomStoreNoRooms})
)
),
React.createElement(FramedExample, {cssClass: "fx-embedded-panel",
dashed: true,
height: 410,
summary: "Room list tab (no rooms and no context)",
summary: "Room list (no rooms and no context)",
width: 330},
React.createElement("div", {className: "panel"},
React.createElement(PanelView, {client: mockClient,
dispatcher: dispatcher,
mozLoop: mockMozLoopNoRoomsNoContext,
notifications: notifications,
roomStore: roomStoreNoRooms,
selectedTab: "rooms"})
roomStore: roomStoreNoRooms})
)
),
React.createElement(FramedExample, {cssClass: "fx-embedded-panel",
dashed: true,
height: 410,
summary: "Room list tab (loading view)",
summary: "Room list (loading view)",
width: 330},
React.createElement("div", {className: "panel"},
React.createElement(PanelView, {client: mockClient,
dispatcher: dispatcher,
mozLoop: mockMozLoopNoRoomsNoContext,
notifications: notifications,
roomStore: roomStoreNoRoomsPending,
selectedTab: "rooms"})
roomStore: roomStoreNoRoomsPending})
)
),

View File

@ -766,8 +766,7 @@
dispatcher={dispatcher}
mozLoop={firstTimeUseMozLoop}
notifications={notifications}
roomStore={roomStore}
selectedTab="rooms" />
roomStore={roomStore} />
</div>
</FramedExample>
@ -784,75 +783,70 @@
<FramedExample cssClass="fx-embedded-panel"
dashed={true}
height={410}
summary="Room list tab"
summary="Room list"
width={330}>
<div className="panel">
<PanelView client={mockClient}
dispatcher={dispatcher}
mozLoop={mockMozLoopLoggedIn}
notifications={notifications}
roomStore={roomStore}
selectedTab="rooms" />
roomStore={roomStore} />
</div>
</FramedExample>
<FramedExample cssClass="fx-embedded-panel"
dashed={true}
height={410}
summary="Room list tab (No Context)"
summary="Room list (No Context)"
width={330}>
<div className="panel">
<PanelView client={mockClient}
dispatcher={dispatcher}
mozLoop={mockMozLoopLoggedInNoContext}
notifications={notifications}
roomStore={roomStore}
selectedTab="rooms" />
roomStore={roomStore} />
</div>
</FramedExample>
<FramedExample cssClass="fx-embedded-panel"
dashed={true}
height={410}
summary="Room list tab (no rooms)"
summary="Room list (no rooms)"
width={330}>
<div className="panel">
<PanelView client={mockClient}
dispatcher={dispatcher}
mozLoop={mockMozLoopNoRooms}
notifications={notifications}
roomStore={roomStoreNoRooms}
selectedTab="rooms" />
roomStore={roomStoreNoRooms} />
</div>
</FramedExample>
<FramedExample cssClass="fx-embedded-panel"
dashed={true}
height={410}
summary="Room list tab (no rooms and no context)"
summary="Room list (no rooms and no context)"
width={330}>
<div className="panel">
<PanelView client={mockClient}
dispatcher={dispatcher}
mozLoop={mockMozLoopNoRoomsNoContext}
notifications={notifications}
roomStore={roomStoreNoRooms}
selectedTab="rooms" />
roomStore={roomStoreNoRooms} />
</div>
</FramedExample>
<FramedExample cssClass="fx-embedded-panel"
dashed={true}
height={410}
summary="Room list tab (loading view)"
summary="Room list (loading view)"
width={330}>
<div className="panel">
<PanelView client={mockClient}
dispatcher={dispatcher}
mozLoop={mockMozLoopNoRoomsNoContext}
notifications={notifications}
roomStore={roomStoreNoRoomsPending}
selectedTab="rooms" />
roomStore={roomStoreNoRoomsPending} />
</div>
</FramedExample>

View File

@ -9,9 +9,6 @@
clientShortname2=Firefox Hello
clientSuperShortname=Hello
rooms_tab_button=Conversations
contacts_tab_button=Contacts
## LOCALIZATION_NOTE(sign_in_again_title_line_one, sign_in_again_title_line_two2):
## These are displayed together at the top of the panel when a user is needed to
## sign-in again. The emphesis is on the first line to get the user to sign-in again,