Refactor PagedList components to be independent from the lists it renders
This commit is contained in:
parent
2ee8f1ef58
commit
68608478f6
Binary file not shown.
After Width: | Height: | Size: 612 B |
Binary file not shown.
After Width: | Height: | Size: 889 B |
|
@ -55,6 +55,7 @@
|
|||
"go": "GO",
|
||||
"join": "JOIN",
|
||||
"privacy": "Privacy",
|
||||
"recentList": "History",
|
||||
"roomname": "Enter room name",
|
||||
"roomnameHint": "Enter the name or URL of the room you want to join. You may make a name up, just let the people you are meeting know it so that they enter the same name.",
|
||||
"sendFeedback": "Send feedback",
|
||||
|
|
|
@ -3,18 +3,16 @@
|
|||
import React, { Component } from 'react';
|
||||
import { View } from 'react-native';
|
||||
|
||||
import { MeetingList } from '../../calendar-sync';
|
||||
import { RecentList } from '../../recent-list';
|
||||
|
||||
import styles from './styles';
|
||||
|
||||
/**
|
||||
* The page to be displayed on render.
|
||||
*/
|
||||
export const DEFAULT_PAGE = 0;
|
||||
|
||||
type Props = {
|
||||
|
||||
/**
|
||||
* The index (starting from 0) of the page that should be rendered
|
||||
* active as default.
|
||||
*/
|
||||
defaultPage: number,
|
||||
|
||||
/**
|
||||
* Indicates if the list is disabled or not.
|
||||
*/
|
||||
|
@ -26,9 +24,15 @@ type Props = {
|
|||
dispatch: Function,
|
||||
|
||||
/**
|
||||
* The i18n translate function
|
||||
* The pages of the PagedList component to be rendered.
|
||||
* Note: page.component may be undefined and then they don't need to be
|
||||
* rendered.
|
||||
*/
|
||||
t: Function
|
||||
pages: Array<{
|
||||
component: Object,
|
||||
icon: string | number,
|
||||
title: string
|
||||
}>
|
||||
};
|
||||
|
||||
type State = {
|
||||
|
@ -40,14 +44,9 @@ type State = {
|
|||
};
|
||||
|
||||
/**
|
||||
* Abstract class for the platform specific paged lists.
|
||||
* Abstract class containing the platform independent logic of the paged lists.
|
||||
*/
|
||||
export default class AbstractPagedList extends Component<Props, State> {
|
||||
/**
|
||||
* The list of pages displayed in the component, referenced by page index.
|
||||
*/
|
||||
_pages: Array<Object>;
|
||||
|
||||
/**
|
||||
* Constructor of the component.
|
||||
*
|
||||
|
@ -56,16 +55,13 @@ export default class AbstractPagedList extends Component<Props, State> {
|
|||
constructor(props: Props) {
|
||||
super(props);
|
||||
|
||||
this._pages = [];
|
||||
for (const component of [ RecentList, MeetingList ]) {
|
||||
// XXX Certain pages may be contributed by optional features. For
|
||||
// example, MeetingList is contributed by the calendar feature and
|
||||
// apps i.e. SDK consumers may not enable the calendar feature.
|
||||
component && this._pages.push(component);
|
||||
}
|
||||
// props.defaultPage may point to a non existing page if some of the
|
||||
// pages are disabled.
|
||||
const maxPageIndex
|
||||
= props.pages.filter(page => page.component).length - 1;
|
||||
|
||||
this.state = {
|
||||
pageIndex: DEFAULT_PAGE
|
||||
pageIndex: Math.max(0, Math.min(maxPageIndex, props.defaultPage))
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -75,7 +71,8 @@ export default class AbstractPagedList extends Component<Props, State> {
|
|||
* @inheritdoc
|
||||
*/
|
||||
render() {
|
||||
const { disabled } = this.props;
|
||||
const { disabled, pages } = this.props;
|
||||
const enabledPages = pages.filter(page => page.component);
|
||||
|
||||
return (
|
||||
<View
|
||||
|
@ -84,14 +81,15 @@ export default class AbstractPagedList extends Component<Props, State> {
|
|||
disabled ? styles.pagedListContainerDisabled : null
|
||||
] }>
|
||||
{
|
||||
this._pages.length > 1
|
||||
enabledPages.length > 1
|
||||
? this._renderPagedList(disabled)
|
||||
: React.createElement(
|
||||
/* type */ this._pages[0],
|
||||
/* props */ {
|
||||
disabled,
|
||||
style: styles.pagedList
|
||||
})
|
||||
: enabledPages.length === 1
|
||||
? React.createElement(
|
||||
/* type */ enabledPages[0].component,
|
||||
/* props */ {
|
||||
disabled,
|
||||
style: styles.pagedList
|
||||
}) : null
|
||||
}
|
||||
</View>
|
||||
);
|
||||
|
@ -115,10 +113,10 @@ export default class AbstractPagedList extends Component<Props, State> {
|
|||
|
||||
// The page's Component may have a refresh(dispatch) function which we
|
||||
// invoke when the page is selected.
|
||||
const selectedPageComponent = this._pages[pageIndex];
|
||||
const selectedPage = this.props.pages[pageIndex];
|
||||
|
||||
if (selectedPageComponent) {
|
||||
const { refresh } = selectedPageComponent;
|
||||
if (selectedPage && selectedPage.component) {
|
||||
const { refresh } = selectedPage.component;
|
||||
|
||||
typeof refresh === 'function' && refresh(this.props.dispatch);
|
||||
}
|
|
@ -0,0 +1,198 @@
|
|||
// @flow
|
||||
|
||||
import React from 'react';
|
||||
import { Text, TouchableOpacity, View, ViewPagerAndroid } from 'react-native';
|
||||
import { connect } from 'react-redux';
|
||||
|
||||
import { Icon } from '../../../font-icons';
|
||||
|
||||
import AbstractPagedList from './AbstractPagedList';
|
||||
import styles from './styles';
|
||||
|
||||
/**
|
||||
* An Android specific component to render a paged list.
|
||||
*
|
||||
* @extends PagedList
|
||||
*/
|
||||
class PagedList extends AbstractPagedList {
|
||||
/**
|
||||
* A reference to the viewpager.
|
||||
*/
|
||||
_viewPager: ViewPagerAndroid;
|
||||
|
||||
/**
|
||||
* Initializes a new {@code PagedList} instance.
|
||||
*
|
||||
* @inheritdoc
|
||||
*/
|
||||
constructor(props) {
|
||||
super(props);
|
||||
|
||||
// Bind event handlers so they are only bound once per instance.
|
||||
this._onIconPress = this._onIconPress.bind(this);
|
||||
this._getIndicatorStyle = this._getIndicatorStyle.bind(this);
|
||||
this._onPageSelected = this._onPageSelected.bind(this);
|
||||
this._setViewPager = this._setViewPager.bind(this);
|
||||
}
|
||||
|
||||
_onIconPress: number => Function;
|
||||
|
||||
/**
|
||||
* Constructs a function to be used as a callback for the icons in the tab
|
||||
* bar.
|
||||
*
|
||||
* @param {number} pageIndex - The index of the page to activate via the
|
||||
* callback.
|
||||
* @private
|
||||
* @returns {Function}
|
||||
*/
|
||||
_onIconPress(pageIndex) {
|
||||
return () => {
|
||||
this._viewPager.setPage(pageIndex);
|
||||
this._selectPage(pageIndex);
|
||||
};
|
||||
}
|
||||
|
||||
_getIndicatorStyle: number => Object;
|
||||
|
||||
/**
|
||||
* Constructs the style of an indicator.
|
||||
*
|
||||
* @param {number} indicatorIndex - The index of the indicator.
|
||||
* @private
|
||||
* @returns {Object}
|
||||
*/
|
||||
_getIndicatorStyle(indicatorIndex) {
|
||||
if (this.state.pageIndex === indicatorIndex) {
|
||||
return styles.pageIndicatorActive;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
_onPageSelected: Object => void;
|
||||
|
||||
/**
|
||||
* Updates the index of the currently selected page, based on the native
|
||||
* event received from the {@link ViewPagerAndroid} component.
|
||||
*
|
||||
* @param {Object} event - The native event of the callback.
|
||||
* @private
|
||||
* @returns {void}
|
||||
*/
|
||||
_onPageSelected({ nativeEvent: { position } }) {
|
||||
if (this.state.pageIndex !== position) {
|
||||
this._selectPage(position);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders a single page of the page list.
|
||||
*
|
||||
* @private
|
||||
* @param {Object} page - The page to render.
|
||||
* @param {number} index - The index of the rendered page.
|
||||
* @param {boolean} disabled - Renders the page disabled.
|
||||
* @returns {React$Node}
|
||||
*/
|
||||
_renderPage(page, index, disabled) {
|
||||
return page.component
|
||||
? <View key = { index }>
|
||||
{
|
||||
React.createElement(
|
||||
page.component,
|
||||
{
|
||||
disabled
|
||||
})
|
||||
}
|
||||
</View>
|
||||
: null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders a page indicator (icon) for the page.
|
||||
*
|
||||
* @private
|
||||
* @param {Object} page - The page the indicator is rendered for.
|
||||
* @param {number} index - The index of the page the indicator is rendered
|
||||
* for.
|
||||
* @param {boolean} disabled - Renders the indicator disabled.
|
||||
* @returns {React$Node}
|
||||
*/
|
||||
_renderPageIndicator(page, index, disabled) {
|
||||
return page.component
|
||||
? <TouchableOpacity
|
||||
disabled = { disabled }
|
||||
onPress = { this._onIconPress(index) }
|
||||
style = { styles.pageIndicator } >
|
||||
<View style = { styles.pageIndicator }>
|
||||
<Icon
|
||||
name = { page.icon }
|
||||
style = { [
|
||||
styles.pageIndicatorIcon,
|
||||
this._getIndicatorStyle(index)
|
||||
] } />
|
||||
<Text
|
||||
style = { [
|
||||
styles.pageIndicatorText,
|
||||
this._getIndicatorStyle(index)
|
||||
] }>
|
||||
{ page.title }
|
||||
</Text>
|
||||
</View>
|
||||
</TouchableOpacity>
|
||||
: null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders the paged list if multiple pages are to be rendered. This is the
|
||||
* platform dependent part of the component.
|
||||
*
|
||||
* @param {boolean} disabled - True if the rendered lists should be
|
||||
* disabled.
|
||||
* @returns {ReactElement}
|
||||
*/
|
||||
_renderPagedList(disabled) {
|
||||
const { defaultPage, pages } = this.props;
|
||||
|
||||
return (
|
||||
<View style = { styles.pagedListContainer }>
|
||||
<ViewPagerAndroid
|
||||
initialPage = { defaultPage }
|
||||
onPageSelected = { this._onPageSelected }
|
||||
peekEnabled = { true }
|
||||
ref = { this._setViewPager }
|
||||
style = { styles.pagedList }>
|
||||
{
|
||||
pages.map((page, index) => this._renderPage(
|
||||
page, index, disabled
|
||||
))
|
||||
}
|
||||
</ViewPagerAndroid>
|
||||
<View style = { styles.pageIndicatorContainer }>
|
||||
{
|
||||
pages.map((page, index) => this._renderPageIndicator(
|
||||
page, index, disabled
|
||||
))
|
||||
}
|
||||
</View>
|
||||
</View>
|
||||
);
|
||||
}
|
||||
|
||||
_setViewPager: Object => void;
|
||||
|
||||
/**
|
||||
* Sets the {@link ViewPagerAndroid} instance.
|
||||
*
|
||||
* @param {ViewPagerAndroid} viewPager - The {@code ViewPagerAndroid}
|
||||
* instance.
|
||||
* @private
|
||||
* @returns {void}
|
||||
*/
|
||||
_setViewPager(viewPager) {
|
||||
this._viewPager = viewPager;
|
||||
}
|
||||
}
|
||||
|
||||
export default connect()(PagedList);
|
|
@ -0,0 +1,100 @@
|
|||
// @flow
|
||||
|
||||
import React from 'react';
|
||||
import { TabBarIOS } from 'react-native';
|
||||
import { connect } from 'react-redux';
|
||||
|
||||
import AbstractPagedList from './AbstractPagedList';
|
||||
import styles from './styles';
|
||||
|
||||
/**
|
||||
* An iOS specific component to render a paged list.
|
||||
*
|
||||
* @extends PagedList
|
||||
*/
|
||||
class PagedList extends AbstractPagedList {
|
||||
|
||||
/**
|
||||
* Initializes a new {@code PagedList} instance.
|
||||
*
|
||||
* @inheritdoc
|
||||
*/
|
||||
constructor(props) {
|
||||
super(props);
|
||||
|
||||
// Bind event handlers so they are only bound once per instance.
|
||||
this._onTabSelected = this._onTabSelected.bind(this);
|
||||
}
|
||||
|
||||
_onTabSelected: number => Function;
|
||||
|
||||
/**
|
||||
* Constructs a callback to update the selected tab when the bottom bar icon
|
||||
* is pressed.
|
||||
*
|
||||
* @param {number} tabIndex - The selected tab.
|
||||
* @private
|
||||
* @returns {Function}
|
||||
*/
|
||||
_onTabSelected(tabIndex) {
|
||||
return () => super._selectPage(tabIndex);
|
||||
}
|
||||
|
||||
_renderPage: (Object, number, boolean) => React$Node
|
||||
|
||||
/**
|
||||
* Renders a single page of the page list.
|
||||
*
|
||||
* @private
|
||||
* @param {Object} page - The page to render.
|
||||
* @param {number} index - The index of the rendered page.
|
||||
* @param {boolean} disabled - Renders the page disabled.
|
||||
* @returns {React$Node}
|
||||
*/
|
||||
_renderPage(page, index, disabled) {
|
||||
const { pageIndex } = this.state;
|
||||
|
||||
return page.component
|
||||
? <TabBarIOS.Item
|
||||
icon = { page.icon }
|
||||
key = { index }
|
||||
onPress = { this._onTabSelected(index) }
|
||||
selected = { pageIndex === index }
|
||||
title = { page.title }>
|
||||
{
|
||||
React.createElement(
|
||||
page.component,
|
||||
{
|
||||
disabled
|
||||
})
|
||||
}
|
||||
</TabBarIOS.Item>
|
||||
: null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders the paged list if multiple pages are to be rendered. This is the
|
||||
* platform dependent part of the component.
|
||||
*
|
||||
* @param {boolean} disabled - True if the rendered lists should be
|
||||
* disabled.
|
||||
* @returns {ReactElement}
|
||||
*/
|
||||
_renderPagedList(disabled) {
|
||||
const { pages } = this.props;
|
||||
|
||||
return (
|
||||
<TabBarIOS
|
||||
itemPositioning = 'fill'
|
||||
style = { styles.pagedList }>
|
||||
{
|
||||
pages.map((page, index) => this._renderPage(
|
||||
page, index, disabled
|
||||
))
|
||||
}
|
||||
</TabBarIOS>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default connect()(PagedList);
|
|
@ -3,6 +3,7 @@ export { default as Header } from './Header';
|
|||
export { default as NavigateSectionList } from './NavigateSectionList';
|
||||
export { default as Link } from './Link';
|
||||
export { default as LoadingIndicator } from './LoadingIndicator';
|
||||
export { default as PagedList } from './PagedList';
|
||||
export { default as Pressable } from './Pressable';
|
||||
export { default as SideBar } from './SideBar';
|
||||
export { default as Text } from './Text';
|
||||
|
|
|
@ -71,6 +71,77 @@ const HEADER_STYLES = {
|
|||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Style classes of the PagedList-based components.
|
||||
*/
|
||||
const PAGED_LIST_STYLES = {
|
||||
|
||||
/**
|
||||
* Style of the page indicator (Android).
|
||||
*/
|
||||
pageIndicator: {
|
||||
alignItems: 'center',
|
||||
flex: 1,
|
||||
flexDirection: 'column',
|
||||
justifyContent: 'center'
|
||||
},
|
||||
|
||||
/**
|
||||
* Additional style for the active indicator icon (Android).
|
||||
*/
|
||||
pageIndicatorActive: {
|
||||
color: ColorPalette.white
|
||||
},
|
||||
|
||||
/**
|
||||
* Container for the page indicators (Android).
|
||||
*/
|
||||
pageIndicatorContainer: {
|
||||
alignItems: 'stretch',
|
||||
backgroundColor: ColorPalette.blue,
|
||||
flexDirection: 'row',
|
||||
height: 56,
|
||||
justifyContent: 'center'
|
||||
},
|
||||
|
||||
/**
|
||||
* Icon of the page indicator (Android).
|
||||
*/
|
||||
pageIndicatorIcon: {
|
||||
color: ColorPalette.blueHighlight,
|
||||
fontSize: 24
|
||||
},
|
||||
|
||||
/**
|
||||
* Label of the page indicator (Android).
|
||||
*/
|
||||
pageIndicatorText: {
|
||||
color: ColorPalette.blueHighlight
|
||||
},
|
||||
|
||||
/**
|
||||
* Top level style of the paged list.
|
||||
*/
|
||||
pagedList: {
|
||||
flex: 1
|
||||
},
|
||||
|
||||
/**
|
||||
* The paged list container View.
|
||||
*/
|
||||
pagedListContainer: {
|
||||
flex: 1,
|
||||
flexDirection: 'column'
|
||||
},
|
||||
|
||||
/**
|
||||
* Disabled style for the container.
|
||||
*/
|
||||
pagedListContainerDisabled: {
|
||||
opacity: 0.2
|
||||
}
|
||||
};
|
||||
|
||||
const SECTION_LIST_STYLES = {
|
||||
/**
|
||||
* The style of the actual avatar.
|
||||
|
@ -248,6 +319,7 @@ const SIDEBAR_STYLES = {
|
|||
*/
|
||||
export default createStyleSheet({
|
||||
...HEADER_STYLES,
|
||||
...PAGED_LIST_STYLES,
|
||||
...SECTION_LIST_STYLES,
|
||||
...SIDEBAR_STYLES
|
||||
});
|
||||
|
|
|
@ -1,173 +0,0 @@
|
|||
// @flow
|
||||
|
||||
import React from 'react';
|
||||
import { Text, TouchableOpacity, View, ViewPagerAndroid } from 'react-native';
|
||||
import { connect } from 'react-redux';
|
||||
|
||||
import { Icon } from '../../base/font-icons';
|
||||
import { MeetingList } from '../../calendar-sync';
|
||||
import { RecentList } from '../../recent-list';
|
||||
|
||||
import AbstractPagedList, { DEFAULT_PAGE } from './AbstractPagedList';
|
||||
import styles from './styles';
|
||||
|
||||
/**
|
||||
* A platform specific component to render a paged or tabbed list/view.
|
||||
*
|
||||
* @extends PagedList
|
||||
*/
|
||||
class PagedList extends AbstractPagedList {
|
||||
/**
|
||||
* A reference to the viewpager.
|
||||
*/
|
||||
_viewPager: Object;
|
||||
|
||||
/**
|
||||
* Initializes a new {@code PagedList} instance.
|
||||
*
|
||||
* @inheritdoc
|
||||
*/
|
||||
constructor(props) {
|
||||
super(props);
|
||||
|
||||
// Bind event handlers so they are only bound once per instance.
|
||||
this._getIndicatorStyle = this._getIndicatorStyle.bind(this);
|
||||
this._onPageSelected = this._onPageSelected.bind(this);
|
||||
this._onSelectPage = this._onSelectPage.bind(this);
|
||||
this._setViewPager = this._setViewPager.bind(this);
|
||||
}
|
||||
|
||||
_getIndicatorStyle: number => Object;
|
||||
|
||||
/**
|
||||
* Constructs the style of an indicator.
|
||||
*
|
||||
* @param {number} indicatorIndex - The index of the indicator.
|
||||
* @private
|
||||
* @returns {Object}
|
||||
*/
|
||||
_getIndicatorStyle(indicatorIndex) {
|
||||
if (this.state.pageIndex === indicatorIndex) {
|
||||
return styles.pageIndicatorTextActive;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
_onPageSelected: Object => void;
|
||||
|
||||
/**
|
||||
* Updates the index of the currently selected page.
|
||||
*
|
||||
* @param {Object} event - The native event of the callback.
|
||||
* @private
|
||||
* @returns {void}
|
||||
*/
|
||||
_onPageSelected({ nativeEvent: { position } }) {
|
||||
if (this.state.pageIndex !== position) {
|
||||
this._selectPage(position);
|
||||
}
|
||||
}
|
||||
|
||||
_onSelectPage: number => Function;
|
||||
|
||||
/**
|
||||
* Constructs a function to be used as a callback for the tab bar.
|
||||
*
|
||||
* @param {number} pageIndex - The index of the page to activate via the
|
||||
* callback.
|
||||
* @private
|
||||
* @returns {Function}
|
||||
*/
|
||||
_onSelectPage(pageIndex) {
|
||||
return () => {
|
||||
this._viewPager.setPage(pageIndex);
|
||||
this._selectPage(pageIndex);
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders the entire paged list if calendar is enabled.
|
||||
*
|
||||
* @param {boolean} disabled - True if the rendered lists should be
|
||||
* disabled.
|
||||
* @returns {ReactElement}
|
||||
*/
|
||||
_renderPagedList(disabled) {
|
||||
return (
|
||||
<View style = { styles.pagedListContainer }>
|
||||
<ViewPagerAndroid
|
||||
initialPage = { DEFAULT_PAGE }
|
||||
onPageSelected = { this._onPageSelected }
|
||||
peekEnabled = { true }
|
||||
ref = { this._setViewPager }
|
||||
style = { styles.pagedList }>
|
||||
<View key = { 0 }>
|
||||
<RecentList disabled = { disabled } />
|
||||
</View>
|
||||
<View key = { 1 }>
|
||||
<MeetingList disabled = { disabled } />
|
||||
</View>
|
||||
</ViewPagerAndroid>
|
||||
<View style = { styles.pageIndicatorContainer }>
|
||||
<TouchableOpacity
|
||||
disabled = { disabled }
|
||||
onPress = { this._onSelectPage(0) }
|
||||
style = { styles.pageIndicator } >
|
||||
<View style = { styles.pageIndicator }>
|
||||
<Icon
|
||||
name = 'restore'
|
||||
style = { [
|
||||
styles.pageIndicatorIcon,
|
||||
this._getIndicatorStyle(0)
|
||||
] } />
|
||||
<Text
|
||||
style = { [
|
||||
styles.pageIndicatorText,
|
||||
this._getIndicatorStyle(0)
|
||||
] }>
|
||||
History
|
||||
</Text>
|
||||
</View>
|
||||
</TouchableOpacity>
|
||||
<TouchableOpacity
|
||||
disabled = { disabled }
|
||||
onPress = { this._onSelectPage(1) }
|
||||
style = { styles.pageIndicator } >
|
||||
<View style = { styles.pageIndicator }>
|
||||
<Icon
|
||||
name = 'event_note'
|
||||
style = { [
|
||||
styles.pageIndicatorIcon,
|
||||
this._getIndicatorStyle(1)
|
||||
] } />
|
||||
<Text
|
||||
style = { [
|
||||
styles.pageIndicatorText,
|
||||
this._getIndicatorStyle(1)
|
||||
] }>
|
||||
Calendar
|
||||
</Text>
|
||||
</View>
|
||||
</TouchableOpacity>
|
||||
</View>
|
||||
</View>
|
||||
);
|
||||
}
|
||||
|
||||
_setViewPager: Object => void;
|
||||
|
||||
/**
|
||||
* Sets the {@link ViewPagerAndroid} instance.
|
||||
*
|
||||
* @param {ViewPagerAndroid} viewPager - The {@code ViewPagerAndroid}
|
||||
* instance.
|
||||
* @private
|
||||
* @returns {void}
|
||||
*/
|
||||
_setViewPager(viewPager) {
|
||||
this._viewPager = viewPager;
|
||||
}
|
||||
}
|
||||
|
||||
export default connect()(PagedList);
|
|
@ -1,81 +0,0 @@
|
|||
// @flow
|
||||
|
||||
import React from 'react';
|
||||
import { TabBarIOS } from 'react-native';
|
||||
import { connect } from 'react-redux';
|
||||
|
||||
import { translate } from '../../base/i18n';
|
||||
import { MeetingList } from '../../calendar-sync';
|
||||
import { RecentList } from '../../recent-list';
|
||||
|
||||
import AbstractPagedList from './AbstractPagedList';
|
||||
import styles from './styles';
|
||||
|
||||
const CALENDAR_ICON = require('../../../../images/calendar.png');
|
||||
|
||||
/**
|
||||
* A platform specific component to render a paged or tabbed list/view.
|
||||
*
|
||||
* @extends PagedList
|
||||
*/
|
||||
class PagedList extends AbstractPagedList {
|
||||
|
||||
/**
|
||||
* Initializes a new {@code PagedList} instance.
|
||||
*
|
||||
* @inheritdoc
|
||||
*/
|
||||
constructor(props) {
|
||||
super(props);
|
||||
|
||||
// Bind event handlers so they are only bound once per instance.
|
||||
this._onTabSelected = this._onTabSelected.bind(this);
|
||||
}
|
||||
|
||||
_onTabSelected: number => Function;
|
||||
|
||||
/**
|
||||
* Constructs a callback to update the selected tab.
|
||||
*
|
||||
* @param {number} tabIndex - The selected tab.
|
||||
* @private
|
||||
* @returns {Function}
|
||||
*/
|
||||
_onTabSelected(tabIndex) {
|
||||
return () => super._selectPage(tabIndex);
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders the entire paged list if calendar is enabled.
|
||||
*
|
||||
* @param {boolean} disabled - True if the rendered lists should be
|
||||
* disabled.
|
||||
* @returns {ReactElement}
|
||||
*/
|
||||
_renderPagedList(disabled) {
|
||||
const { pageIndex } = this.state;
|
||||
const { t } = this.props;
|
||||
|
||||
return (
|
||||
<TabBarIOS
|
||||
itemPositioning = 'fill'
|
||||
style = { styles.pagedList }>
|
||||
<TabBarIOS.Item
|
||||
onPress = { this._onTabSelected(0) }
|
||||
selected = { pageIndex === 0 }
|
||||
systemIcon = 'history'>
|
||||
<RecentList disabled = { disabled } />
|
||||
</TabBarIOS.Item>
|
||||
<TabBarIOS.Item
|
||||
icon = { CALENDAR_ICON }
|
||||
onPress = { this._onTabSelected(1) }
|
||||
selected = { pageIndex === 1 }
|
||||
title = { t('welcomepage.calendar') }>
|
||||
<MeetingList disabled = { disabled } />
|
||||
</TabBarIOS.Item>
|
||||
</TabBarIOS>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default translate(connect()(PagedList));
|
|
@ -26,12 +26,12 @@ import { SettingsView } from '../../settings';
|
|||
import { AbstractWelcomePage, _mapStateToProps } from './AbstractWelcomePage';
|
||||
import { setSideBarVisible } from '../actions';
|
||||
import LocalVideoTrackUnderlay from './LocalVideoTrackUnderlay';
|
||||
import PagedList from './PagedList';
|
||||
import styles, {
|
||||
PLACEHOLDER_TEXT_COLOR,
|
||||
SWITCH_THUMB_COLOR,
|
||||
SWITCH_UNDER_COLOR
|
||||
} from './styles';
|
||||
import WelcomePageLists from './WelcomePageLists';
|
||||
import WelcomePageSideBar from './WelcomePageSideBar';
|
||||
|
||||
/**
|
||||
|
@ -139,7 +139,7 @@ class WelcomePage extends AbstractWelcomePage {
|
|||
}
|
||||
</View>
|
||||
</SafeAreaView>
|
||||
<PagedList disabled = { this.state._fieldFocused } />
|
||||
<WelcomePageLists disabled = { this.state._fieldFocused } />
|
||||
<SettingsView />
|
||||
</View>
|
||||
<WelcomePageSideBar />
|
||||
|
|
|
@ -0,0 +1,88 @@
|
|||
// @flow
|
||||
|
||||
import React, { Component } from 'react';
|
||||
import { Platform } from 'react-native';
|
||||
|
||||
import { translate } from '../../base/i18n';
|
||||
import { PagedList } from '../../base/react';
|
||||
import { MeetingList } from '../../calendar-sync';
|
||||
import { RecentList } from '../../recent-list';
|
||||
|
||||
type Props = {
|
||||
|
||||
/**
|
||||
* Renders the lists disabled.
|
||||
*/
|
||||
disabled: boolean,
|
||||
|
||||
/**
|
||||
* The i18n translate function.
|
||||
*/
|
||||
t: Function
|
||||
};
|
||||
|
||||
/**
|
||||
* Icon to be used for the calendar page on iOS.
|
||||
*/
|
||||
const IOS_CALENDAR_ICON = require('../../../../images/calendar.png');
|
||||
|
||||
/**
|
||||
* Icon to be used for the recent list page on iOS.
|
||||
*/
|
||||
const IOS_RECENT_LIST_ICON = require('../../../../images/history.png');
|
||||
|
||||
/**
|
||||
* Implements the lists displayed on the mobile welcome screen.
|
||||
*/
|
||||
class WelcomePageLists extends Component<Props> {
|
||||
/**
|
||||
* The pages to be rendered.
|
||||
* Note: The component field may be undefined if a feature (such as
|
||||
* Calendar) is disabled, and that means that the page must not be rendered.
|
||||
*/
|
||||
pages: Array<{
|
||||
component: Object,
|
||||
icon: string | number,
|
||||
title: string
|
||||
}>
|
||||
|
||||
/**
|
||||
* Component contructor.
|
||||
*
|
||||
* @inheritdoc
|
||||
*/
|
||||
constructor(props) {
|
||||
super(props);
|
||||
|
||||
const { t } = props;
|
||||
const isAndroid = Platform.OS === 'android';
|
||||
|
||||
this.pages = [ {
|
||||
component: RecentList,
|
||||
icon: isAndroid ? 'restore' : IOS_RECENT_LIST_ICON,
|
||||
title: t('welcomepage.recentList')
|
||||
}, {
|
||||
component: MeetingList,
|
||||
icon: isAndroid ? 'event_note' : IOS_CALENDAR_ICON,
|
||||
title: t('welcomepage.calendar')
|
||||
} ];
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements React Component's render.
|
||||
*
|
||||
* @inheritdoc
|
||||
*/
|
||||
render() {
|
||||
const { disabled } = this.props;
|
||||
|
||||
return (
|
||||
<PagedList
|
||||
defaultPage = { 0 }
|
||||
disabled = { disabled }
|
||||
pages = { this.pages } />
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default translate(WelcomePageLists);
|
|
@ -161,53 +161,6 @@ export default createStyleSheet({
|
|||
flexDirection: 'column'
|
||||
},
|
||||
|
||||
pageIndicator: {
|
||||
alignItems: 'center',
|
||||
flex: 1,
|
||||
flexDirection: 'column',
|
||||
justifyContent: 'center'
|
||||
},
|
||||
|
||||
pageIndicatorContainer: {
|
||||
alignItems: 'stretch',
|
||||
backgroundColor: ColorPalette.blue,
|
||||
flexDirection: 'row',
|
||||
height: 56,
|
||||
justifyContent: 'center'
|
||||
},
|
||||
|
||||
pageIndicatorIcon: {
|
||||
color: ColorPalette.blueHighlight,
|
||||
fontSize: 24
|
||||
},
|
||||
|
||||
pageIndicatorText: {
|
||||
color: ColorPalette.blueHighlight
|
||||
},
|
||||
|
||||
pageIndicatorTextActive: {
|
||||
color: ColorPalette.white
|
||||
},
|
||||
|
||||
/**
|
||||
* Top level style of the paged list.
|
||||
*/
|
||||
pagedList: {
|
||||
flex: 1
|
||||
},
|
||||
|
||||
pagedListContainer: {
|
||||
flex: 1,
|
||||
flexDirection: 'column'
|
||||
},
|
||||
|
||||
/**
|
||||
* Disabled style for the container.
|
||||
*/
|
||||
pagedListContainerDisabled: {
|
||||
opacity: 0.2
|
||||
},
|
||||
|
||||
/**
|
||||
* Container for room name input box and 'join' button.
|
||||
*/
|
||||
|
|
Loading…
Reference in New Issue