mirror of
https://github.com/mozilla/gecko-dev.git
synced 2025-03-02 22:37:50 +00:00
Bug 1212074 - Remove the tabs from Loop's panel. r=Standard8
This commit is contained in:
parent
d6efa38e22
commit
4e0f9302bd
@ -76,147 +76,6 @@ body {
|
|||||||
border-radius: 3px;
|
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 and input fields */
|
||||||
|
|
||||||
.content-area {
|
.content-area {
|
||||||
@ -232,8 +91,7 @@ html[dir="rtl"] .tab-view li:nth-child(2).selected ~ .slide-bar {
|
|||||||
-moz-padding-start: 20px;
|
-moz-padding-start: 20px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.fte-get-started-container + .generate-url > #share-link-header,
|
.fte-get-started-container + .generate-url > #share-link-header {
|
||||||
.tab-view + .tab .content-area > .generate-url > #share-link-header {
|
|
||||||
/* The header shouldn't be indented if the tabs are present. */
|
/* The header shouldn't be indented if the tabs are present. */
|
||||||
-moz-padding-start: 0;
|
-moz-padding-start: 0;
|
||||||
}
|
}
|
||||||
@ -331,6 +189,7 @@ html[dir="rtl"] .tab-view li:nth-child(2).selected ~ .slide-bar {
|
|||||||
flex: 1;
|
flex: 1;
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-flow: column nowrap;
|
flex-flow: column nowrap;
|
||||||
|
width: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
.rooms > h1 {
|
.rooms > h1 {
|
||||||
@ -414,6 +273,7 @@ html[dir="rtl"] .tab-view li:nth-child(2).selected ~ .slide-bar {
|
|||||||
overflow-x: hidden;
|
overflow-x: hidden;
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-flow: column nowrap;
|
flex-flow: column nowrap;
|
||||||
|
width: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
.room-list-empty {
|
.room-list-empty {
|
||||||
|
@ -10,109 +10,8 @@ loop.panel = (function(_, mozL10n) {
|
|||||||
var sharedModels = loop.shared.models;
|
var sharedModels = loop.shared.models;
|
||||||
var sharedMixins = loop.shared.mixins;
|
var sharedMixins = loop.shared.mixins;
|
||||||
var sharedActions = loop.shared.actions;
|
var sharedActions = loop.shared.actions;
|
||||||
var sharedUtils = loop.shared.utils;
|
|
||||||
var Button = sharedViews.Button;
|
var Button = sharedViews.Button;
|
||||||
var ButtonGroup = sharedViews.ButtonGroup;
|
|
||||||
var Checkbox = sharedViews.Checkbox;
|
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.
|
* Availability drop down menu subview.
|
||||||
@ -1001,14 +900,10 @@ loop.panel = (function(_, mozL10n) {
|
|||||||
var PanelView = React.createClass({displayName: "PanelView",
|
var PanelView = React.createClass({displayName: "PanelView",
|
||||||
propTypes: {
|
propTypes: {
|
||||||
dispatcher: React.PropTypes.instanceOf(loop.Dispatcher).isRequired,
|
dispatcher: React.PropTypes.instanceOf(loop.Dispatcher).isRequired,
|
||||||
initialSelectedTabComponent: React.PropTypes.string,
|
|
||||||
mozLoop: React.PropTypes.object.isRequired,
|
mozLoop: React.PropTypes.object.isRequired,
|
||||||
notifications: React.PropTypes.object.isRequired,
|
notifications: React.PropTypes.object.isRequired,
|
||||||
roomStore:
|
roomStore:
|
||||||
React.PropTypes.instanceOf(loop.store.RoomStore).isRequired,
|
React.PropTypes.instanceOf(loop.store.RoomStore).isRequired
|
||||||
selectedTab: React.PropTypes.string,
|
|
||||||
// Used only for unit tests.
|
|
||||||
showTabButtons: React.PropTypes.bool
|
|
||||||
},
|
},
|
||||||
|
|
||||||
getInitialState: function() {
|
getInitialState: function() {
|
||||||
@ -1056,8 +951,6 @@ loop.panel = (function(_, mozL10n) {
|
|||||||
// Update the state of hasEncryptionKey as this might have changed now.
|
// Update the state of hasEncryptionKey as this might have changed now.
|
||||||
this.setState({hasEncryptionKey: this.props.mozLoop.hasEncryptionKey});
|
this.setState({hasEncryptionKey: this.props.mozLoop.hasEncryptionKey});
|
||||||
} else {
|
} else {
|
||||||
// On profile change (login, logout), switch back to the default tab.
|
|
||||||
this.selectTab("rooms");
|
|
||||||
this.setState({userProfile: profile});
|
this.setState({userProfile: profile});
|
||||||
}
|
}
|
||||||
this.updateServiceErrors();
|
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() {
|
componentWillMount: function() {
|
||||||
this.updateServiceErrors();
|
this.updateServiceErrors();
|
||||||
},
|
},
|
||||||
@ -1095,13 +969,11 @@ loop.panel = (function(_, mozL10n) {
|
|||||||
componentDidMount: function() {
|
componentDidMount: function() {
|
||||||
window.addEventListener("LoopStatusChanged", this._onStatusChanged);
|
window.addEventListener("LoopStatusChanged", this._onStatusChanged);
|
||||||
window.addEventListener("GettingStartedSeen", this._gettingStartedSeen);
|
window.addEventListener("GettingStartedSeen", this._gettingStartedSeen);
|
||||||
window.addEventListener("UIAction", this._UIActionHandler);
|
|
||||||
},
|
},
|
||||||
|
|
||||||
componentWillUnmount: function() {
|
componentWillUnmount: function() {
|
||||||
window.removeEventListener("LoopStatusChanged", this._onStatusChanged);
|
window.removeEventListener("LoopStatusChanged", this._onStatusChanged);
|
||||||
window.removeEventListener("GettingStartedSeen", this._gettingStartedSeen);
|
window.removeEventListener("GettingStartedSeen", this._gettingStartedSeen);
|
||||||
window.removeEventListener("UIAction", this._UIActionHandler);
|
|
||||||
},
|
},
|
||||||
|
|
||||||
render: function() {
|
render: function() {
|
||||||
@ -1123,35 +995,15 @@ loop.panel = (function(_, mozL10n) {
|
|||||||
return React.createElement(SignInRequestView, {mozLoop: this.props.mozLoop});
|
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 (
|
return (
|
||||||
React.createElement("div", {className: "panel-content"},
|
React.createElement("div", {className: "panel-content"},
|
||||||
React.createElement(NotificationListView, {
|
React.createElement(NotificationListView, {
|
||||||
clearOnDocumentHidden: true,
|
clearOnDocumentHidden: true,
|
||||||
notifications: this.props.notifications}),
|
notifications: this.props.notifications}),
|
||||||
React.createElement(TabView, {
|
React.createElement(RoomList, {dispatcher: this.props.dispatcher,
|
||||||
buttonsHidden: hideButtons,
|
mozLoop: this.props.mozLoop,
|
||||||
mozLoop: this.props.mozLoop,
|
store: this.props.roomStore,
|
||||||
ref: "tabView",
|
userProfile: this.state.userProfile}),
|
||||||
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("div", {className: "footer"},
|
React.createElement("div", {className: "footer"},
|
||||||
React.createElement("div", {className: "user-details"},
|
React.createElement("div", {className: "user-details"},
|
||||||
React.createElement(AvailabilityDropdown, null)
|
React.createElement(AvailabilityDropdown, null)
|
||||||
|
@ -10,109 +10,8 @@ loop.panel = (function(_, mozL10n) {
|
|||||||
var sharedModels = loop.shared.models;
|
var sharedModels = loop.shared.models;
|
||||||
var sharedMixins = loop.shared.mixins;
|
var sharedMixins = loop.shared.mixins;
|
||||||
var sharedActions = loop.shared.actions;
|
var sharedActions = loop.shared.actions;
|
||||||
var sharedUtils = loop.shared.utils;
|
|
||||||
var Button = sharedViews.Button;
|
var Button = sharedViews.Button;
|
||||||
var ButtonGroup = sharedViews.ButtonGroup;
|
|
||||||
var Checkbox = sharedViews.Checkbox;
|
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.
|
* Availability drop down menu subview.
|
||||||
@ -1001,14 +900,10 @@ loop.panel = (function(_, mozL10n) {
|
|||||||
var PanelView = React.createClass({
|
var PanelView = React.createClass({
|
||||||
propTypes: {
|
propTypes: {
|
||||||
dispatcher: React.PropTypes.instanceOf(loop.Dispatcher).isRequired,
|
dispatcher: React.PropTypes.instanceOf(loop.Dispatcher).isRequired,
|
||||||
initialSelectedTabComponent: React.PropTypes.string,
|
|
||||||
mozLoop: React.PropTypes.object.isRequired,
|
mozLoop: React.PropTypes.object.isRequired,
|
||||||
notifications: React.PropTypes.object.isRequired,
|
notifications: React.PropTypes.object.isRequired,
|
||||||
roomStore:
|
roomStore:
|
||||||
React.PropTypes.instanceOf(loop.store.RoomStore).isRequired,
|
React.PropTypes.instanceOf(loop.store.RoomStore).isRequired
|
||||||
selectedTab: React.PropTypes.string,
|
|
||||||
// Used only for unit tests.
|
|
||||||
showTabButtons: React.PropTypes.bool
|
|
||||||
},
|
},
|
||||||
|
|
||||||
getInitialState: function() {
|
getInitialState: function() {
|
||||||
@ -1056,8 +951,6 @@ loop.panel = (function(_, mozL10n) {
|
|||||||
// Update the state of hasEncryptionKey as this might have changed now.
|
// Update the state of hasEncryptionKey as this might have changed now.
|
||||||
this.setState({hasEncryptionKey: this.props.mozLoop.hasEncryptionKey});
|
this.setState({hasEncryptionKey: this.props.mozLoop.hasEncryptionKey});
|
||||||
} else {
|
} else {
|
||||||
// On profile change (login, logout), switch back to the default tab.
|
|
||||||
this.selectTab("rooms");
|
|
||||||
this.setState({userProfile: profile});
|
this.setState({userProfile: profile});
|
||||||
}
|
}
|
||||||
this.updateServiceErrors();
|
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() {
|
componentWillMount: function() {
|
||||||
this.updateServiceErrors();
|
this.updateServiceErrors();
|
||||||
},
|
},
|
||||||
@ -1095,13 +969,11 @@ loop.panel = (function(_, mozL10n) {
|
|||||||
componentDidMount: function() {
|
componentDidMount: function() {
|
||||||
window.addEventListener("LoopStatusChanged", this._onStatusChanged);
|
window.addEventListener("LoopStatusChanged", this._onStatusChanged);
|
||||||
window.addEventListener("GettingStartedSeen", this._gettingStartedSeen);
|
window.addEventListener("GettingStartedSeen", this._gettingStartedSeen);
|
||||||
window.addEventListener("UIAction", this._UIActionHandler);
|
|
||||||
},
|
},
|
||||||
|
|
||||||
componentWillUnmount: function() {
|
componentWillUnmount: function() {
|
||||||
window.removeEventListener("LoopStatusChanged", this._onStatusChanged);
|
window.removeEventListener("LoopStatusChanged", this._onStatusChanged);
|
||||||
window.removeEventListener("GettingStartedSeen", this._gettingStartedSeen);
|
window.removeEventListener("GettingStartedSeen", this._gettingStartedSeen);
|
||||||
window.removeEventListener("UIAction", this._UIActionHandler);
|
|
||||||
},
|
},
|
||||||
|
|
||||||
render: function() {
|
render: function() {
|
||||||
@ -1123,35 +995,15 @@ loop.panel = (function(_, mozL10n) {
|
|||||||
return <SignInRequestView mozLoop={this.props.mozLoop} />;
|
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 (
|
return (
|
||||||
<div className="panel-content">
|
<div className="panel-content">
|
||||||
<NotificationListView
|
<NotificationListView
|
||||||
clearOnDocumentHidden={true}
|
clearOnDocumentHidden={true}
|
||||||
notifications={this.props.notifications} />
|
notifications={this.props.notifications} />
|
||||||
<TabView
|
<RoomList dispatcher={this.props.dispatcher}
|
||||||
buttonsHidden={hideButtons}
|
mozLoop={this.props.mozLoop}
|
||||||
mozLoop={this.props.mozLoop}
|
store={this.props.roomStore}
|
||||||
ref="tabView"
|
userProfile={this.state.userProfile} />
|
||||||
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>
|
|
||||||
<div className="footer">
|
<div className="footer">
|
||||||
<div className="user-details">
|
<div className="user-details">
|
||||||
<AvailabilityDropdown />
|
<AvailabilityDropdown />
|
||||||
|
@ -210,69 +210,6 @@ describe("loop.panel", function() {
|
|||||||
.to.have.length.of(0);
|
.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() {
|
describe("AccountLink", function() {
|
||||||
beforeEach(function() {
|
beforeEach(function() {
|
||||||
navigator.mozLoop.calls = { clearCallInProgress: function() {} };
|
navigator.mozLoop.calls = { clearCallInProgress: function() {} };
|
||||||
|
@ -766,8 +766,7 @@
|
|||||||
dispatcher: dispatcher,
|
dispatcher: dispatcher,
|
||||||
mozLoop: firstTimeUseMozLoop,
|
mozLoop: firstTimeUseMozLoop,
|
||||||
notifications: notifications,
|
notifications: notifications,
|
||||||
roomStore: roomStore,
|
roomStore: roomStore})
|
||||||
selectedTab: "rooms"})
|
|
||||||
)
|
)
|
||||||
),
|
),
|
||||||
|
|
||||||
@ -784,75 +783,70 @@
|
|||||||
React.createElement(FramedExample, {cssClass: "fx-embedded-panel",
|
React.createElement(FramedExample, {cssClass: "fx-embedded-panel",
|
||||||
dashed: true,
|
dashed: true,
|
||||||
height: 410,
|
height: 410,
|
||||||
summary: "Room list tab",
|
summary: "Room list",
|
||||||
width: 330},
|
width: 330},
|
||||||
React.createElement("div", {className: "panel"},
|
React.createElement("div", {className: "panel"},
|
||||||
React.createElement(PanelView, {client: mockClient,
|
React.createElement(PanelView, {client: mockClient,
|
||||||
dispatcher: dispatcher,
|
dispatcher: dispatcher,
|
||||||
mozLoop: mockMozLoopLoggedIn,
|
mozLoop: mockMozLoopLoggedIn,
|
||||||
notifications: notifications,
|
notifications: notifications,
|
||||||
roomStore: roomStore,
|
roomStore: roomStore})
|
||||||
selectedTab: "rooms"})
|
|
||||||
)
|
)
|
||||||
),
|
),
|
||||||
|
|
||||||
React.createElement(FramedExample, {cssClass: "fx-embedded-panel",
|
React.createElement(FramedExample, {cssClass: "fx-embedded-panel",
|
||||||
dashed: true,
|
dashed: true,
|
||||||
height: 410,
|
height: 410,
|
||||||
summary: "Room list tab (No Context)",
|
summary: "Room list (No Context)",
|
||||||
width: 330},
|
width: 330},
|
||||||
React.createElement("div", {className: "panel"},
|
React.createElement("div", {className: "panel"},
|
||||||
React.createElement(PanelView, {client: mockClient,
|
React.createElement(PanelView, {client: mockClient,
|
||||||
dispatcher: dispatcher,
|
dispatcher: dispatcher,
|
||||||
mozLoop: mockMozLoopLoggedInNoContext,
|
mozLoop: mockMozLoopLoggedInNoContext,
|
||||||
notifications: notifications,
|
notifications: notifications,
|
||||||
roomStore: roomStore,
|
roomStore: roomStore})
|
||||||
selectedTab: "rooms"})
|
|
||||||
)
|
)
|
||||||
),
|
),
|
||||||
|
|
||||||
React.createElement(FramedExample, {cssClass: "fx-embedded-panel",
|
React.createElement(FramedExample, {cssClass: "fx-embedded-panel",
|
||||||
dashed: true,
|
dashed: true,
|
||||||
height: 410,
|
height: 410,
|
||||||
summary: "Room list tab (no rooms)",
|
summary: "Room list (no rooms)",
|
||||||
width: 330},
|
width: 330},
|
||||||
React.createElement("div", {className: "panel"},
|
React.createElement("div", {className: "panel"},
|
||||||
React.createElement(PanelView, {client: mockClient,
|
React.createElement(PanelView, {client: mockClient,
|
||||||
dispatcher: dispatcher,
|
dispatcher: dispatcher,
|
||||||
mozLoop: mockMozLoopNoRooms,
|
mozLoop: mockMozLoopNoRooms,
|
||||||
notifications: notifications,
|
notifications: notifications,
|
||||||
roomStore: roomStoreNoRooms,
|
roomStore: roomStoreNoRooms})
|
||||||
selectedTab: "rooms"})
|
|
||||||
)
|
)
|
||||||
),
|
),
|
||||||
|
|
||||||
React.createElement(FramedExample, {cssClass: "fx-embedded-panel",
|
React.createElement(FramedExample, {cssClass: "fx-embedded-panel",
|
||||||
dashed: true,
|
dashed: true,
|
||||||
height: 410,
|
height: 410,
|
||||||
summary: "Room list tab (no rooms and no context)",
|
summary: "Room list (no rooms and no context)",
|
||||||
width: 330},
|
width: 330},
|
||||||
React.createElement("div", {className: "panel"},
|
React.createElement("div", {className: "panel"},
|
||||||
React.createElement(PanelView, {client: mockClient,
|
React.createElement(PanelView, {client: mockClient,
|
||||||
dispatcher: dispatcher,
|
dispatcher: dispatcher,
|
||||||
mozLoop: mockMozLoopNoRoomsNoContext,
|
mozLoop: mockMozLoopNoRoomsNoContext,
|
||||||
notifications: notifications,
|
notifications: notifications,
|
||||||
roomStore: roomStoreNoRooms,
|
roomStore: roomStoreNoRooms})
|
||||||
selectedTab: "rooms"})
|
|
||||||
)
|
)
|
||||||
),
|
),
|
||||||
|
|
||||||
React.createElement(FramedExample, {cssClass: "fx-embedded-panel",
|
React.createElement(FramedExample, {cssClass: "fx-embedded-panel",
|
||||||
dashed: true,
|
dashed: true,
|
||||||
height: 410,
|
height: 410,
|
||||||
summary: "Room list tab (loading view)",
|
summary: "Room list (loading view)",
|
||||||
width: 330},
|
width: 330},
|
||||||
React.createElement("div", {className: "panel"},
|
React.createElement("div", {className: "panel"},
|
||||||
React.createElement(PanelView, {client: mockClient,
|
React.createElement(PanelView, {client: mockClient,
|
||||||
dispatcher: dispatcher,
|
dispatcher: dispatcher,
|
||||||
mozLoop: mockMozLoopNoRoomsNoContext,
|
mozLoop: mockMozLoopNoRoomsNoContext,
|
||||||
notifications: notifications,
|
notifications: notifications,
|
||||||
roomStore: roomStoreNoRoomsPending,
|
roomStore: roomStoreNoRoomsPending})
|
||||||
selectedTab: "rooms"})
|
|
||||||
)
|
)
|
||||||
),
|
),
|
||||||
|
|
||||||
|
@ -766,8 +766,7 @@
|
|||||||
dispatcher={dispatcher}
|
dispatcher={dispatcher}
|
||||||
mozLoop={firstTimeUseMozLoop}
|
mozLoop={firstTimeUseMozLoop}
|
||||||
notifications={notifications}
|
notifications={notifications}
|
||||||
roomStore={roomStore}
|
roomStore={roomStore} />
|
||||||
selectedTab="rooms" />
|
|
||||||
</div>
|
</div>
|
||||||
</FramedExample>
|
</FramedExample>
|
||||||
|
|
||||||
@ -784,75 +783,70 @@
|
|||||||
<FramedExample cssClass="fx-embedded-panel"
|
<FramedExample cssClass="fx-embedded-panel"
|
||||||
dashed={true}
|
dashed={true}
|
||||||
height={410}
|
height={410}
|
||||||
summary="Room list tab"
|
summary="Room list"
|
||||||
width={330}>
|
width={330}>
|
||||||
<div className="panel">
|
<div className="panel">
|
||||||
<PanelView client={mockClient}
|
<PanelView client={mockClient}
|
||||||
dispatcher={dispatcher}
|
dispatcher={dispatcher}
|
||||||
mozLoop={mockMozLoopLoggedIn}
|
mozLoop={mockMozLoopLoggedIn}
|
||||||
notifications={notifications}
|
notifications={notifications}
|
||||||
roomStore={roomStore}
|
roomStore={roomStore} />
|
||||||
selectedTab="rooms" />
|
|
||||||
</div>
|
</div>
|
||||||
</FramedExample>
|
</FramedExample>
|
||||||
|
|
||||||
<FramedExample cssClass="fx-embedded-panel"
|
<FramedExample cssClass="fx-embedded-panel"
|
||||||
dashed={true}
|
dashed={true}
|
||||||
height={410}
|
height={410}
|
||||||
summary="Room list tab (No Context)"
|
summary="Room list (No Context)"
|
||||||
width={330}>
|
width={330}>
|
||||||
<div className="panel">
|
<div className="panel">
|
||||||
<PanelView client={mockClient}
|
<PanelView client={mockClient}
|
||||||
dispatcher={dispatcher}
|
dispatcher={dispatcher}
|
||||||
mozLoop={mockMozLoopLoggedInNoContext}
|
mozLoop={mockMozLoopLoggedInNoContext}
|
||||||
notifications={notifications}
|
notifications={notifications}
|
||||||
roomStore={roomStore}
|
roomStore={roomStore} />
|
||||||
selectedTab="rooms" />
|
|
||||||
</div>
|
</div>
|
||||||
</FramedExample>
|
</FramedExample>
|
||||||
|
|
||||||
<FramedExample cssClass="fx-embedded-panel"
|
<FramedExample cssClass="fx-embedded-panel"
|
||||||
dashed={true}
|
dashed={true}
|
||||||
height={410}
|
height={410}
|
||||||
summary="Room list tab (no rooms)"
|
summary="Room list (no rooms)"
|
||||||
width={330}>
|
width={330}>
|
||||||
<div className="panel">
|
<div className="panel">
|
||||||
<PanelView client={mockClient}
|
<PanelView client={mockClient}
|
||||||
dispatcher={dispatcher}
|
dispatcher={dispatcher}
|
||||||
mozLoop={mockMozLoopNoRooms}
|
mozLoop={mockMozLoopNoRooms}
|
||||||
notifications={notifications}
|
notifications={notifications}
|
||||||
roomStore={roomStoreNoRooms}
|
roomStore={roomStoreNoRooms} />
|
||||||
selectedTab="rooms" />
|
|
||||||
</div>
|
</div>
|
||||||
</FramedExample>
|
</FramedExample>
|
||||||
|
|
||||||
<FramedExample cssClass="fx-embedded-panel"
|
<FramedExample cssClass="fx-embedded-panel"
|
||||||
dashed={true}
|
dashed={true}
|
||||||
height={410}
|
height={410}
|
||||||
summary="Room list tab (no rooms and no context)"
|
summary="Room list (no rooms and no context)"
|
||||||
width={330}>
|
width={330}>
|
||||||
<div className="panel">
|
<div className="panel">
|
||||||
<PanelView client={mockClient}
|
<PanelView client={mockClient}
|
||||||
dispatcher={dispatcher}
|
dispatcher={dispatcher}
|
||||||
mozLoop={mockMozLoopNoRoomsNoContext}
|
mozLoop={mockMozLoopNoRoomsNoContext}
|
||||||
notifications={notifications}
|
notifications={notifications}
|
||||||
roomStore={roomStoreNoRooms}
|
roomStore={roomStoreNoRooms} />
|
||||||
selectedTab="rooms" />
|
|
||||||
</div>
|
</div>
|
||||||
</FramedExample>
|
</FramedExample>
|
||||||
|
|
||||||
<FramedExample cssClass="fx-embedded-panel"
|
<FramedExample cssClass="fx-embedded-panel"
|
||||||
dashed={true}
|
dashed={true}
|
||||||
height={410}
|
height={410}
|
||||||
summary="Room list tab (loading view)"
|
summary="Room list (loading view)"
|
||||||
width={330}>
|
width={330}>
|
||||||
<div className="panel">
|
<div className="panel">
|
||||||
<PanelView client={mockClient}
|
<PanelView client={mockClient}
|
||||||
dispatcher={dispatcher}
|
dispatcher={dispatcher}
|
||||||
mozLoop={mockMozLoopNoRoomsNoContext}
|
mozLoop={mockMozLoopNoRoomsNoContext}
|
||||||
notifications={notifications}
|
notifications={notifications}
|
||||||
roomStore={roomStoreNoRoomsPending}
|
roomStore={roomStoreNoRoomsPending} />
|
||||||
selectedTab="rooms" />
|
|
||||||
</div>
|
</div>
|
||||||
</FramedExample>
|
</FramedExample>
|
||||||
|
|
||||||
|
@ -9,9 +9,6 @@
|
|||||||
clientShortname2=Firefox Hello
|
clientShortname2=Firefox Hello
|
||||||
clientSuperShortname=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):
|
## 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
|
## 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,
|
## sign-in again. The emphesis is on the first line to get the user to sign-in again,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user