RN-137 Team sidebar (#577)
* Team sidebar * Update NOTICES.txt * feedback review
This commit is contained in:
parent
f6266c10c5
commit
5b1a68db74
42 changed files with 7097 additions and 191 deletions
4
Makefile
4
Makefile
|
|
@ -12,9 +12,9 @@ android_target := $(filter-out build-android,$(MAKECMDGOALS))
|
|||
exit 1; \
|
||||
fi
|
||||
|
||||
@echo Getting dependencies using npm
|
||||
@echo Getting dependencies using yarn
|
||||
|
||||
yarn install
|
||||
yarn install --pure-lockfile
|
||||
|
||||
touch $@
|
||||
|
||||
|
|
|
|||
52
NOTICE.txt
52
NOTICE.txt
|
|
@ -8,6 +8,39 @@ This document includes a list of open source components used in Mattermost Mobil
|
|||
|
||||
--------
|
||||
|
||||
## react-native-swiper
|
||||
|
||||
This product contains 'react-native-swiper', A Swiper component for React Native.
|
||||
|
||||
* HOMEPAGE:
|
||||
* https://github.com/leecade/react-native-swiper
|
||||
|
||||
* LICENSE:
|
||||
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2015 斯人
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
|
||||
---
|
||||
|
||||
## react-native-search-bar
|
||||
|
||||
This product contains a modified portion of 'react-native-search-bar', a high-quality iOS native search bar for react native by Zhao Han.
|
||||
|
|
@ -875,22 +908,3 @@ IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
|||
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
---
|
||||
|
||||
## react-native-sentry
|
||||
|
||||
Official Sentry client for react-native
|
||||
|
||||
* HOMEPAGE
|
||||
* https://github.com/getsentry/react-native-sentry
|
||||
|
||||
* LICENSE
|
||||
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2017 Sentry
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
|
|
|||
Binary file not shown.
BIN
android/app/src/main/assets/fonts/OpenSans-Bold.ttf
Executable file
BIN
android/app/src/main/assets/fonts/OpenSans-Bold.ttf
Executable file
Binary file not shown.
BIN
android/app/src/main/assets/fonts/OpenSans-BoldItalic.ttf
Executable file
BIN
android/app/src/main/assets/fonts/OpenSans-BoldItalic.ttf
Executable file
Binary file not shown.
BIN
android/app/src/main/assets/fonts/OpenSans-ExtraBold.ttf
Executable file
BIN
android/app/src/main/assets/fonts/OpenSans-ExtraBold.ttf
Executable file
Binary file not shown.
BIN
android/app/src/main/assets/fonts/OpenSans-ExtraBoldItalic.ttf
Executable file
BIN
android/app/src/main/assets/fonts/OpenSans-ExtraBoldItalic.ttf
Executable file
Binary file not shown.
BIN
android/app/src/main/assets/fonts/OpenSans-Italic.ttf
Executable file
BIN
android/app/src/main/assets/fonts/OpenSans-Italic.ttf
Executable file
Binary file not shown.
BIN
android/app/src/main/assets/fonts/OpenSans-Light.ttf
Executable file
BIN
android/app/src/main/assets/fonts/OpenSans-Light.ttf
Executable file
Binary file not shown.
BIN
android/app/src/main/assets/fonts/OpenSans-LightItalic.ttf
Executable file
BIN
android/app/src/main/assets/fonts/OpenSans-LightItalic.ttf
Executable file
Binary file not shown.
BIN
android/app/src/main/assets/fonts/OpenSans-Regular.ttf
Executable file
BIN
android/app/src/main/assets/fonts/OpenSans-Regular.ttf
Executable file
Binary file not shown.
BIN
android/app/src/main/assets/fonts/OpenSans-Semibold.ttf
Executable file
BIN
android/app/src/main/assets/fonts/OpenSans-Semibold.ttf
Executable file
Binary file not shown.
BIN
android/app/src/main/assets/fonts/OpenSans-SemiboldItalic.ttf
Executable file
BIN
android/app/src/main/assets/fonts/OpenSans-SemiboldItalic.ttf
Executable file
Binary file not shown.
|
|
@ -3,13 +3,22 @@
|
|||
|
||||
import React, {PureComponent} from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import {BackHandler, InteractionManager, Keyboard} from 'react-native';
|
||||
import {
|
||||
BackHandler,
|
||||
InteractionManager,
|
||||
Keyboard,
|
||||
View
|
||||
} from 'react-native';
|
||||
|
||||
import Drawer from 'app/components/drawer';
|
||||
import ChannelDrawerList from 'app/components/channel_drawer_list';
|
||||
import ChannelDrawerSwiper from 'app/components/channel_drawer_swiper';
|
||||
import ChannelDrawerTeams from 'app/components/channel_drawer_teams';
|
||||
|
||||
import EventEmitter from 'mattermost-redux/utils/event_emitter';
|
||||
|
||||
const DRAWER_INITIAL_OFFSET = 40;
|
||||
|
||||
export default class ChannelDrawer extends PureComponent {
|
||||
static propTypes = {
|
||||
actions: PropTypes.shape({
|
||||
|
|
@ -25,6 +34,7 @@ export default class ChannelDrawer extends PureComponent {
|
|||
currentChannel: PropTypes.object,
|
||||
channels: PropTypes.object,
|
||||
channelMembers: PropTypes.object,
|
||||
myTeamMembers: PropTypes.object.isRequired,
|
||||
theme: PropTypes.object.isRequired
|
||||
};
|
||||
|
||||
|
|
@ -34,9 +44,12 @@ export default class ChannelDrawer extends PureComponent {
|
|||
};
|
||||
|
||||
state = {
|
||||
openDrawer: false
|
||||
openDrawer: false,
|
||||
openDrawerOffset: DRAWER_INITIAL_OFFSET
|
||||
};
|
||||
|
||||
swiperIndex = 1;
|
||||
|
||||
componentDidMount() {
|
||||
EventEmitter.on('open_channel_drawer', this.openChannelDrawer);
|
||||
EventEmitter.on('close_channel_drawer', this.closeChannelDrawer);
|
||||
|
|
@ -63,6 +76,7 @@ export default class ChannelDrawer extends PureComponent {
|
|||
};
|
||||
|
||||
handleDrawerClose = () => {
|
||||
this.resetDrawer();
|
||||
setTimeout(() => {
|
||||
InteractionManager.clearInteractionHandle(this.closeLeftHandle);
|
||||
});
|
||||
|
|
@ -128,20 +142,85 @@ export default class ChannelDrawer extends PureComponent {
|
|||
});
|
||||
};
|
||||
|
||||
render() {
|
||||
onPageSelected = (index) => {
|
||||
this.swiperIndex = index;
|
||||
};
|
||||
|
||||
showTeams = () => {
|
||||
const teamsCount = Object.keys(this.props.myTeamMembers).length;
|
||||
if (this.swiperIndex === 1 && teamsCount > 1) {
|
||||
this.refs.swiper.showTeamsPage();
|
||||
}
|
||||
};
|
||||
|
||||
resetDrawer = () => {
|
||||
const teamsCount = Object.keys(this.props.myTeamMembers).length;
|
||||
if (this.swiperIndex === 0 && teamsCount > 1) {
|
||||
this.refs.swiper.resetPage();
|
||||
}
|
||||
};
|
||||
|
||||
renderContent = () => {
|
||||
const {
|
||||
children,
|
||||
currentChannel,
|
||||
currentTeam,
|
||||
channels,
|
||||
channelMembers,
|
||||
navigator,
|
||||
myTeamMembers,
|
||||
theme
|
||||
} = this.props;
|
||||
const showTeams = Object.keys(myTeamMembers).length > 1;
|
||||
|
||||
let teams;
|
||||
if (showTeams) {
|
||||
teams = (
|
||||
<View style={{flex: 1, marginBottom: 10}}>
|
||||
<ChannelDrawerTeams
|
||||
closeChannelDrawer={this.closeChannelDrawer}
|
||||
myTeamMembers={myTeamMembers}
|
||||
/>
|
||||
</View>
|
||||
);
|
||||
}
|
||||
|
||||
const channelsList = (
|
||||
<View style={{flex: 1, marginBottom: 10}}>
|
||||
<ChannelDrawerList
|
||||
currentTeam={currentTeam}
|
||||
currentChannel={currentChannel}
|
||||
channels={channels}
|
||||
channelMembers={channelMembers}
|
||||
myTeamMembers={myTeamMembers}
|
||||
theme={theme}
|
||||
onSelectChannel={this.selectChannel}
|
||||
navigator={navigator}
|
||||
onShowTeams={this.showTeams}
|
||||
/>
|
||||
</View>
|
||||
);
|
||||
|
||||
return (
|
||||
<ChannelDrawerSwiper
|
||||
ref='swiper'
|
||||
onPageSelected={this.onPageSelected}
|
||||
openDrawerOffset={this.state.openDrawerOffset}
|
||||
showTeams={showTeams}
|
||||
theme={theme}
|
||||
>
|
||||
{teams}
|
||||
{channelsList}
|
||||
</ChannelDrawerSwiper>
|
||||
);
|
||||
};
|
||||
|
||||
render() {
|
||||
const {children} = this.props;
|
||||
const {openDrawer, openDrawerOffset} = this.state;
|
||||
|
||||
return (
|
||||
<Drawer
|
||||
open={this.state.openDrawer}
|
||||
open={openDrawer}
|
||||
onOpenStart={this.handleDrawerOpenStart}
|
||||
onOpen={this.handleDrawerOpen}
|
||||
onCloseStart={this.handleDrawerCloseStart}
|
||||
|
|
@ -150,22 +229,12 @@ export default class ChannelDrawer extends PureComponent {
|
|||
type='static'
|
||||
acceptTap={true}
|
||||
disabled={false}
|
||||
content={
|
||||
<ChannelDrawerList
|
||||
currentTeam={currentTeam}
|
||||
currentChannel={currentChannel}
|
||||
channels={channels}
|
||||
channelMembers={channelMembers}
|
||||
theme={theme}
|
||||
onSelectChannel={this.selectChannel}
|
||||
navigator={navigator}
|
||||
/>
|
||||
}
|
||||
content={this.renderContent()}
|
||||
tapToClose={true}
|
||||
openDrawerOffset={40}
|
||||
openDrawerOffset={openDrawerOffset}
|
||||
onRequestClose={this.closeChannelDrawer}
|
||||
panOpenMask={0.2}
|
||||
panCloseMask={40}
|
||||
panCloseMask={openDrawerOffset}
|
||||
panThreshold={0.25}
|
||||
acceptPan={true}
|
||||
negotiatePan={true}
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ import {handleSelectChannel, setChannelLoading} from 'app/actions/views/channel'
|
|||
|
||||
import {getChannelsWithUnreadSection, getCurrentChannel} from 'mattermost-redux/selectors/entities/channels';
|
||||
import {getTheme} from 'app/selectors/preferences';
|
||||
import {getCurrentTeam} from 'mattermost-redux/selectors/entities/teams';
|
||||
import {getCurrentTeam, getTeamMemberships} from 'mattermost-redux/selectors/entities/teams';
|
||||
|
||||
import {viewChannel, markChannelAsRead} from 'mattermost-redux/actions/channels';
|
||||
|
||||
|
|
@ -21,6 +21,7 @@ function mapStateToProps(state, ownProps) {
|
|||
currentChannel: getCurrentChannel(state),
|
||||
channels: getChannelsWithUnreadSection(state),
|
||||
channelMembers: state.entities.channels.myMembers,
|
||||
myTeamMembers: getTeamMemberships(state),
|
||||
theme: getTheme(state)
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@ import {injectIntl, intlShape} from 'react-intl';
|
|||
import AwesomeIcon from 'react-native-vector-icons/FontAwesome';
|
||||
import MaterialIcon from 'react-native-vector-icons/MaterialIcons';
|
||||
|
||||
import Badge from 'app/components/badge';
|
||||
import FormattedText from 'app/components/formatted_text';
|
||||
import {preventDoubleTap} from 'app/utils/tap';
|
||||
import {changeOpacity, makeStyleSheetFromTheme} from 'app/utils/theme';
|
||||
|
|
@ -33,8 +34,10 @@ class ChannelDrawerList extends Component {
|
|||
currentTeam: PropTypes.object.isRequired,
|
||||
currentChannel: PropTypes.object,
|
||||
intl: intlShape.isRequired,
|
||||
myTeamMembers: PropTypes.object.isRequired,
|
||||
navigator: PropTypes.object,
|
||||
onSelectChannel: PropTypes.func.isRequired,
|
||||
onShowTeams: PropTypes.func.isRequired,
|
||||
theme: PropTypes.object.isRequired
|
||||
};
|
||||
|
||||
|
|
@ -210,20 +213,20 @@ class ChannelDrawerList extends Component {
|
|||
|
||||
if (unreadChannels.length) {
|
||||
data.push(
|
||||
this.renderTitle(styles, 'mobile.channel_list.unreads', 'UNREADS', null, unreadChannels.length > 0),
|
||||
this.renderTitle(styles, 'mobile.channel_list.unreads', 'UNREADS', null, false, unreadChannels.length > 0),
|
||||
...unreadChannels
|
||||
);
|
||||
}
|
||||
|
||||
if (favoriteChannels.length) {
|
||||
data.push(
|
||||
this.renderTitle(styles, 'sidebar.favorite', 'FAVORITES', null, favoriteChannels.length > 0),
|
||||
this.renderTitle(styles, 'sidebar.favorite', 'FAVORITES', null, unreadChannels.length > 0, favoriteChannels.length > 0),
|
||||
...favoriteChannels
|
||||
);
|
||||
}
|
||||
|
||||
data.push(
|
||||
this.renderTitle(styles, 'sidebar.channels', 'CHANNELS', this.showMoreChannelsModal, publicChannels.length > 0),
|
||||
this.renderTitle(styles, 'sidebar.channels', 'CHANNELS', this.showMoreChannelsModal, favoriteChannels.length > 0, publicChannels.length > 0),
|
||||
...publicChannels
|
||||
);
|
||||
|
||||
|
|
@ -232,12 +235,12 @@ class ChannelDrawerList extends Component {
|
|||
createPrivateChannel = this.createPrivateChannel;
|
||||
}
|
||||
data.push(
|
||||
this.renderTitle(styles, 'sidebar.pg', 'PRIVATE CHANNELS', createPrivateChannel, privateChannels.length > 0),
|
||||
this.renderTitle(styles, 'sidebar.pg', 'PRIVATE CHANNELS', createPrivateChannel, true, privateChannels.length > 0),
|
||||
...privateChannels
|
||||
);
|
||||
|
||||
data.push(
|
||||
this.renderTitle(styles, 'sidebar.direct', 'DIRECT MESSAGES', this.showDirectMessagesModal, directAndGroupChannels.length > 0),
|
||||
this.renderTitle(styles, 'sidebar.direct', 'DIRECT MESSAGES', this.showDirectMessagesModal, true, directAndGroupChannels.length > 0),
|
||||
...directAndGroupChannels
|
||||
);
|
||||
|
||||
|
|
@ -349,14 +352,15 @@ class ChannelDrawerList extends Component {
|
|||
return item.title;
|
||||
};
|
||||
|
||||
renderTitle = (styles, id, defaultMessage, action, bottomDivider) => {
|
||||
renderTitle = (styles, id, defaultMessage, action, topDivider, bottomDivider) => {
|
||||
const {formatMessage} = this.props.intl;
|
||||
|
||||
return {
|
||||
id,
|
||||
isTitle: true,
|
||||
title: (
|
||||
<View>
|
||||
{this.renderDivider(styles, 0)}
|
||||
{topDivider && this.renderDivider(styles, 0)}
|
||||
<View style={styles.titleContainer}>
|
||||
<Text style={styles.title}>
|
||||
{formatMessage({id, defaultMessage}).toUpperCase()}
|
||||
|
|
@ -370,11 +374,20 @@ class ChannelDrawerList extends Component {
|
|||
};
|
||||
|
||||
render() {
|
||||
if (!this.props.currentChannel) {
|
||||
const {
|
||||
currentChannel,
|
||||
currentTeam,
|
||||
myTeamMembers,
|
||||
onShowTeams,
|
||||
theme
|
||||
} = this.props;
|
||||
|
||||
const {dataSource, showAbove, showBelow} = this.state;
|
||||
const teamMembers = Object.values(myTeamMembers);
|
||||
|
||||
if (!currentChannel) {
|
||||
return <Text>{'Loading'}</Text>;
|
||||
}
|
||||
|
||||
const {theme} = this.props;
|
||||
const styles = getStyleSheet(theme);
|
||||
|
||||
const settings = (
|
||||
|
|
@ -391,8 +404,7 @@ class ChannelDrawerList extends Component {
|
|||
);
|
||||
|
||||
let above;
|
||||
let below;
|
||||
if (this.state.showAbove) {
|
||||
if (showAbove) {
|
||||
above = (
|
||||
<UnreadIndicator
|
||||
style={[styles.above, {width: (this.width - 40)}]}
|
||||
|
|
@ -407,7 +419,8 @@ class ChannelDrawerList extends Component {
|
|||
);
|
||||
}
|
||||
|
||||
if (this.state.showBelow) {
|
||||
let below;
|
||||
if (showBelow) {
|
||||
below = (
|
||||
<UnreadIndicator
|
||||
style={[styles.below, {width: (this.width - 40)}]}
|
||||
|
|
@ -422,6 +435,66 @@ class ChannelDrawerList extends Component {
|
|||
);
|
||||
}
|
||||
|
||||
const title = (
|
||||
<Text
|
||||
ellipsizeMode='tail'
|
||||
numberOfLines={1}
|
||||
style={styles.header}
|
||||
onPress={onShowTeams}
|
||||
>
|
||||
{currentTeam.display_name}
|
||||
</Text>
|
||||
);
|
||||
|
||||
let badge;
|
||||
let switcher;
|
||||
if (teamMembers.length > 1) {
|
||||
let mentionCount = 0;
|
||||
let messageCount = 0;
|
||||
teamMembers.forEach((m) => {
|
||||
if (m.team_id !== currentTeam.id) {
|
||||
mentionCount = mentionCount + m.mention_count;
|
||||
messageCount = messageCount + m.msg_count;
|
||||
}
|
||||
});
|
||||
|
||||
let badgeCount = mentionCount;
|
||||
if (!badgeCount && messageCount) {
|
||||
badgeCount = -1;
|
||||
}
|
||||
|
||||
if (badgeCount !== 0) {
|
||||
badge = (
|
||||
<Badge
|
||||
style={styles.badge}
|
||||
countStyle={styles.mention}
|
||||
count={badgeCount}
|
||||
minHeight={5}
|
||||
minWidth={5}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
switcher = (
|
||||
<TouchableHighlight
|
||||
onPress={() => preventDoubleTap(onShowTeams)}
|
||||
underlayColor={changeOpacity(theme.sidebarHeaderBg, 0.5)}
|
||||
>
|
||||
<View style={styles.switcherContainer}>
|
||||
<AwesomeIcon
|
||||
name='chevron-left'
|
||||
size={12}
|
||||
color={theme.sidebarHeaderBg}
|
||||
/>
|
||||
<View style={styles.switcherDivider}/>
|
||||
<Text style={styles.switcherTeam}>
|
||||
{currentTeam.display_name.substr(0, 2).toUpperCase()}
|
||||
</Text>
|
||||
</View>
|
||||
</TouchableHighlight>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<View
|
||||
style={styles.container}
|
||||
|
|
@ -429,19 +502,15 @@ class ChannelDrawerList extends Component {
|
|||
>
|
||||
<View style={styles.statusBar}>
|
||||
<View style={styles.headerContainer}>
|
||||
<Text
|
||||
ellipsizeMode='tail'
|
||||
numberOfLines={1}
|
||||
style={styles.header}
|
||||
>
|
||||
{this.props.currentTeam.display_name}
|
||||
</Text>
|
||||
{switcher}
|
||||
{title}
|
||||
{settings}
|
||||
{badge}
|
||||
</View>
|
||||
</View>
|
||||
<FlatList
|
||||
ref='list'
|
||||
data={this.state.dataSource}
|
||||
data={dataSource}
|
||||
renderItem={this.renderItem}
|
||||
keyExtractor={(item) => item.id}
|
||||
onViewableItemsChanged={this.updateUnreadIndicators}
|
||||
|
|
@ -472,22 +541,27 @@ const getStyleSheet = makeStyleSheetFromTheme((theme) => {
|
|||
}
|
||||
})
|
||||
},
|
||||
scrollContainer: {
|
||||
flex: 1
|
||||
},
|
||||
headerContainer: {
|
||||
alignItems: 'center',
|
||||
backgroundColor: theme.sidebarHeaderBg,
|
||||
flexDirection: 'row',
|
||||
height: 44,
|
||||
paddingLeft: 16
|
||||
borderBottomWidth: 1,
|
||||
borderBottomColor: changeOpacity(theme.sidebarHeaderTextColor, 0.10),
|
||||
...Platform.select({
|
||||
android: {
|
||||
height: 46
|
||||
},
|
||||
ios: {
|
||||
height: 44
|
||||
}
|
||||
})
|
||||
},
|
||||
header: {
|
||||
color: theme.sidebarHeaderTextColor,
|
||||
flex: 1,
|
||||
fontSize: 14,
|
||||
fontSize: 17,
|
||||
fontWeight: 'normal',
|
||||
lineHeight: 16
|
||||
paddingLeft: 16
|
||||
},
|
||||
settingsContainer: {
|
||||
alignItems: 'center',
|
||||
|
|
@ -516,6 +590,44 @@ const getStyleSheet = makeStyleSheetFromTheme((theme) => {
|
|||
letterSpacing: 0.8,
|
||||
lineHeight: 18
|
||||
},
|
||||
switcherContainer: {
|
||||
alignItems: 'center',
|
||||
backgroundColor: theme.sidebarHeaderTextColor,
|
||||
borderRadius: 2,
|
||||
flexDirection: 'row',
|
||||
height: 32,
|
||||
justifyContent: 'center',
|
||||
marginLeft: 16,
|
||||
paddingHorizontal: 6
|
||||
},
|
||||
switcherDivider: {
|
||||
backgroundColor: theme.sidebarHeaderBg,
|
||||
height: 15,
|
||||
marginHorizontal: 6,
|
||||
width: 1
|
||||
},
|
||||
switcherTeam: {
|
||||
color: theme.sidebarHeaderBg,
|
||||
fontFamily: 'OpenSans',
|
||||
fontSize: 14
|
||||
},
|
||||
badge: {
|
||||
backgroundColor: theme.mentionBj,
|
||||
borderColor: theme.sidebarHeaderBg,
|
||||
borderRadius: 10,
|
||||
borderWidth: 1,
|
||||
flexDirection: 'row',
|
||||
height: 20,
|
||||
padding: 3,
|
||||
position: 'absolute',
|
||||
left: 5,
|
||||
top: 0,
|
||||
width: 20
|
||||
},
|
||||
mention: {
|
||||
color: theme.mentionColor,
|
||||
fontSize: 10
|
||||
},
|
||||
divider: {
|
||||
backgroundColor: changeOpacity(theme.sidebarText, 0.1),
|
||||
height: 1
|
||||
|
|
|
|||
|
|
@ -0,0 +1,51 @@
|
|||
// Copyright (c) 2017-present Mattermost, Inc. All Rights Reserved.
|
||||
// See License.txt for license information.
|
||||
|
||||
import React, {PureComponent} from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import {ViewPagerAndroid} from 'react-native';
|
||||
|
||||
export default class ChannelDrawerSwiper extends PureComponent {
|
||||
static propTypes = {
|
||||
children: PropTypes.node.isRequired,
|
||||
onPageSelected: PropTypes.func,
|
||||
showTeams: PropTypes.bool.isRequired,
|
||||
theme: PropTypes.object.isRequired
|
||||
};
|
||||
|
||||
static defaultProps = {
|
||||
onPageSelected: () => true
|
||||
};
|
||||
|
||||
swiperPageSelected = (event) => {
|
||||
this.props.onPageSelected(event.nativeEvent.position);
|
||||
};
|
||||
|
||||
showTeamsPage = () => {
|
||||
this.refs.swiper.setPage(0);
|
||||
};
|
||||
|
||||
resetPage = () => {
|
||||
this.refs.swiper.setPageWithoutAnimation(1);
|
||||
};
|
||||
|
||||
render() {
|
||||
const {
|
||||
children,
|
||||
showTeams,
|
||||
theme
|
||||
} = this.props;
|
||||
|
||||
return (
|
||||
<ViewPagerAndroid
|
||||
ref='swiper'
|
||||
style={{flex: 1, backgroundColor: theme.sidebarBg}}
|
||||
initialPage={1}
|
||||
scrollEnabled={showTeams}
|
||||
onPageSelected={this.swiperPageSelected}
|
||||
>
|
||||
{children}
|
||||
</ViewPagerAndroid>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,69 @@
|
|||
// Copyright (c) 2017-present Mattermost, Inc. All Rights Reserved.
|
||||
// See License.txt for license information.
|
||||
|
||||
import React, {PureComponent} from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import {Dimensions} from 'react-native';
|
||||
import Swiper from 'react-native-swiper';
|
||||
|
||||
import {changeOpacity} from 'app/utils/theme';
|
||||
|
||||
const {height: deviceHeight, width: deviceWidth} = Dimensions.get('window');
|
||||
|
||||
export default class ChannelDrawerSwiper extends PureComponent {
|
||||
static propTypes = {
|
||||
children: PropTypes.node.isRequired,
|
||||
onPageSelected: PropTypes.func,
|
||||
openDrawerOffset: PropTypes.number,
|
||||
showTeams: PropTypes.bool.isRequired,
|
||||
theme: PropTypes.object.isRequired
|
||||
};
|
||||
|
||||
static defaultProps = {
|
||||
onPageSelected: () => true,
|
||||
openDrawerOffset: 0
|
||||
};
|
||||
|
||||
swiperPageSelected = (e, state, context) => {
|
||||
this.props.onPageSelected(context.state.index);
|
||||
};
|
||||
|
||||
showTeamsPage = () => {
|
||||
this.refs.swiper.scrollBy(-1, true);
|
||||
};
|
||||
|
||||
resetPage = () => {
|
||||
this.refs.swiper.scrollBy(1, false);
|
||||
};
|
||||
|
||||
render() {
|
||||
const {
|
||||
children,
|
||||
openDrawerOffset,
|
||||
showTeams,
|
||||
theme
|
||||
} = this.props;
|
||||
|
||||
return (
|
||||
<Swiper
|
||||
ref='swiper'
|
||||
horizontal={true}
|
||||
loop={false}
|
||||
index={1}
|
||||
onMomentumScrollEnd={this.swiperPageSelected}
|
||||
paginationStyle={{position: 'relative', bottom: 10}}
|
||||
width={deviceWidth - openDrawerOffset}
|
||||
height={deviceHeight}
|
||||
style={{backgroundColor: theme.sidebarBg}}
|
||||
activeDotColor={theme.sidebarText}
|
||||
dotColor={changeOpacity(theme.sidebarText, 0.5)}
|
||||
removeClippedSubviews={true}
|
||||
automaticallyAdjustContentInsets={true}
|
||||
scrollEnabled={showTeams}
|
||||
showsPagination={showTeams}
|
||||
>
|
||||
{children}
|
||||
</Swiper>
|
||||
);
|
||||
}
|
||||
}
|
||||
6
app/components/channel_drawer_swiper/index.js
Normal file
6
app/components/channel_drawer_swiper/index.js
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
// Copyright (c) 2017-present Mattermost, Inc. All Rights Reserved.
|
||||
// See License.txt for license information.
|
||||
|
||||
// Used to leverage the platform specific components
|
||||
import ChannelDrawerSwiper from './channel_drawer_swiper';
|
||||
export default ChannelDrawerSwiper;
|
||||
249
app/components/channel_drawer_teams/channel_drawer_teams.js
Normal file
249
app/components/channel_drawer_teams/channel_drawer_teams.js
Normal file
|
|
@ -0,0 +1,249 @@
|
|||
// Copyright (c) 2017-present Mattermost, Inc. All Rights Reserved.
|
||||
// See License.txt for license information.
|
||||
|
||||
import React, {PureComponent} from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import {
|
||||
InteractionManager,
|
||||
FlatList,
|
||||
Platform,
|
||||
StyleSheet,
|
||||
Text,
|
||||
TouchableHighlight,
|
||||
View
|
||||
} from 'react-native';
|
||||
import IonIcon from 'react-native-vector-icons/Ionicons';
|
||||
|
||||
import Badge from 'app/components/badge';
|
||||
import FormattedText from 'app/components/formatted_text';
|
||||
import {preventDoubleTap} from 'app/utils/tap';
|
||||
import {changeOpacity, makeStyleSheetFromTheme} from 'app/utils/theme';
|
||||
|
||||
export default class ChannelDrawerTeams extends PureComponent {
|
||||
static propTypes = {
|
||||
actions: PropTypes.shape({
|
||||
handleTeamChange: PropTypes.func.isRequired
|
||||
}).isRequired,
|
||||
canCreateTeams: PropTypes.bool.isRequired,
|
||||
canJoinTeams: PropTypes.bool.isRequired,
|
||||
closeChannelDrawer: PropTypes.func.isRequired,
|
||||
currentTeamId: PropTypes.string.isRequired,
|
||||
currentUrl: PropTypes.string.isRequired,
|
||||
myTeamMembers: PropTypes.object.isRequired,
|
||||
teams: PropTypes.array.isRequired,
|
||||
theme: PropTypes.object.isRequired
|
||||
};
|
||||
|
||||
selectTeam = (team) => {
|
||||
const {actions, closeChannelDrawer, currentTeamId} = this.props;
|
||||
if (team.id === currentTeamId) {
|
||||
closeChannelDrawer();
|
||||
} else {
|
||||
closeChannelDrawer();
|
||||
InteractionManager.runAfterInteractions(() => {
|
||||
actions.handleTeamChange(team);
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
renderItem = ({item}) => {
|
||||
const {currentTeamId, currentUrl, myTeamMembers, theme} = this.props;
|
||||
const styles = getStyleSheet(theme);
|
||||
|
||||
let current;
|
||||
let badge;
|
||||
if (item.id === currentTeamId) {
|
||||
current = (
|
||||
<View style={styles.checkmarkContainer}>
|
||||
<IonIcon
|
||||
name='md-checkmark'
|
||||
style={styles.checkmark}
|
||||
/>
|
||||
</View>
|
||||
);
|
||||
} else {
|
||||
const member = myTeamMembers[item.id];
|
||||
let badgeCount = member.mention_count;
|
||||
if (!badgeCount && member.msg_count) {
|
||||
badgeCount = -1;
|
||||
}
|
||||
|
||||
if (badgeCount !== 0) {
|
||||
badge = (
|
||||
<Badge
|
||||
style={styles.badge}
|
||||
countStyle={styles.mention}
|
||||
count={badgeCount}
|
||||
minHeight={5}
|
||||
minWidth={5}
|
||||
/>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
<View style={styles.teamWrapper}>
|
||||
<TouchableHighlight
|
||||
underlayColor={changeOpacity(theme.sidebarTextHoverBg, 0.5)}
|
||||
onPress={() => preventDoubleTap(this.selectTeam, this, item)}
|
||||
>
|
||||
<View style={styles.teamContainer}>
|
||||
<View style={styles.teamIconContainer}>
|
||||
<Text style={styles.teamIcon}>
|
||||
{item.display_name.substr(0, 2).toUpperCase()}
|
||||
</Text>
|
||||
</View>
|
||||
<View style={styles.teamNameContainer}>
|
||||
<Text
|
||||
numberOfLines={1}
|
||||
ellipsizeMode='tail'
|
||||
style={styles.teamName}
|
||||
>
|
||||
{item.display_name}
|
||||
</Text>
|
||||
<Text
|
||||
numberOfLines={1}
|
||||
ellipsizeMode='tail'
|
||||
style={styles.teamUrl}
|
||||
>
|
||||
{`${currentUrl}/${item.name}`}
|
||||
</Text>
|
||||
</View>
|
||||
{current}
|
||||
</View>
|
||||
</TouchableHighlight>
|
||||
{badge}
|
||||
</View>
|
||||
);
|
||||
};
|
||||
|
||||
render() {
|
||||
const {teams, theme} = this.props;
|
||||
const styles = getStyleSheet(theme);
|
||||
|
||||
let moreAction;
|
||||
|
||||
return (
|
||||
<View style={styles.container}>
|
||||
<View style={styles.statusBar}>
|
||||
<View style={styles.headerContainer}>
|
||||
<FormattedText
|
||||
id='mobile.drawer.teamsTitle'
|
||||
defaultMessage='Teams'
|
||||
style={styles.header}
|
||||
/>
|
||||
{moreAction}
|
||||
</View>
|
||||
</View>
|
||||
<FlatList
|
||||
data={teams}
|
||||
renderItem={this.renderItem}
|
||||
keyExtractor={(item) => item.id}
|
||||
viewabilityConfig={{
|
||||
viewAreaCoveragePercentThreshold: 3,
|
||||
waitForInteraction: false
|
||||
}}
|
||||
/>
|
||||
</View>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
const getStyleSheet = makeStyleSheetFromTheme((theme) => {
|
||||
return StyleSheet.create({
|
||||
container: {
|
||||
backgroundColor: theme.sidebarBg,
|
||||
flex: 1
|
||||
},
|
||||
statusBar: {
|
||||
backgroundColor: theme.sidebarHeaderBg,
|
||||
...Platform.select({
|
||||
ios: {
|
||||
paddingTop: 20
|
||||
}
|
||||
})
|
||||
},
|
||||
headerContainer: {
|
||||
alignItems: 'center',
|
||||
backgroundColor: theme.sidebarHeaderBg,
|
||||
flexDirection: 'row',
|
||||
paddingLeft: 16,
|
||||
borderBottomWidth: 1,
|
||||
borderBottomColor: changeOpacity(theme.sidebarHeaderTextColor, 0.10),
|
||||
...Platform.select({
|
||||
android: {
|
||||
height: 46
|
||||
},
|
||||
ios: {
|
||||
height: 44
|
||||
}
|
||||
})
|
||||
},
|
||||
header: {
|
||||
color: theme.sidebarHeaderTextColor,
|
||||
flex: 1,
|
||||
fontSize: 17,
|
||||
fontWeight: 'normal'
|
||||
},
|
||||
teamWrapper: {
|
||||
marginTop: 20
|
||||
},
|
||||
teamContainer: {
|
||||
alignItems: 'center',
|
||||
flex: 1,
|
||||
flexDirection: 'row',
|
||||
marginHorizontal: 16
|
||||
},
|
||||
teamIconContainer: {
|
||||
alignItems: 'center',
|
||||
backgroundColor: theme.sidebarText,
|
||||
borderRadius: 2,
|
||||
height: 40,
|
||||
justifyContent: 'center',
|
||||
width: 40
|
||||
},
|
||||
teamIcon: {
|
||||
color: theme.sidebarBg,
|
||||
fontFamily: 'OpenSans',
|
||||
fontSize: 18,
|
||||
fontWeight: '600'
|
||||
},
|
||||
teamNameContainer: {
|
||||
flex: 1,
|
||||
flexDirection: 'column',
|
||||
marginLeft: 10
|
||||
},
|
||||
teamName: {
|
||||
color: theme.sidebarText,
|
||||
fontSize: 18
|
||||
},
|
||||
teamUrl: {
|
||||
color: changeOpacity(theme.sidebarText, 0.5),
|
||||
fontSize: 12
|
||||
},
|
||||
checkmarkContainer: {
|
||||
alignItems: 'flex-end'
|
||||
},
|
||||
checkmark: {
|
||||
color: theme.sidebarText,
|
||||
fontSize: 20
|
||||
},
|
||||
badge: {
|
||||
backgroundColor: theme.mentionBj,
|
||||
borderColor: theme.sidebarHeaderBg,
|
||||
borderRadius: 10,
|
||||
borderWidth: 1,
|
||||
flexDirection: 'row',
|
||||
height: 20,
|
||||
padding: 3,
|
||||
position: 'absolute',
|
||||
left: 45,
|
||||
top: -7.5,
|
||||
width: 20
|
||||
},
|
||||
mention: {
|
||||
color: theme.mentionColor,
|
||||
fontSize: 10
|
||||
}
|
||||
});
|
||||
});
|
||||
47
app/components/channel_drawer_teams/index.js
Normal file
47
app/components/channel_drawer_teams/index.js
Normal file
|
|
@ -0,0 +1,47 @@
|
|||
// Copyright (c) 2017-present Mattermost, Inc. All Rights Reserved.
|
||||
// See License.txt for license information.
|
||||
|
||||
import {bindActionCreators} from 'redux';
|
||||
import {connect} from 'react-redux';
|
||||
|
||||
import {getCurrentUrl} from 'mattermost-redux/selectors/entities/general';
|
||||
import {getCurrentTeamId, getMyTeams} from 'mattermost-redux/selectors/entities/teams';
|
||||
import {getCurrentUser} from 'mattermost-redux/selectors/entities/users';
|
||||
|
||||
import {handleTeamChange} from 'app/actions/views/select_team';
|
||||
import {getTheme} from 'app/selectors/preferences';
|
||||
import {removeProtocol} from 'app/utils/url';
|
||||
|
||||
import ChannelDrawerTeams from './channel_drawer_teams';
|
||||
|
||||
function mapStateToProps(state, ownProps) {
|
||||
const user = getCurrentUser(state);
|
||||
|
||||
function sortTeams(locale, a, b) {
|
||||
if (a.display_name !== b.display_name) {
|
||||
return a.display_name.toLowerCase().localeCompare(b.display_name.toLowerCase(), locale, {numeric: true});
|
||||
}
|
||||
|
||||
return a.name.toLowerCase().localeCompare(b.name.toLowerCase(), locale, {numeric: true});
|
||||
}
|
||||
|
||||
return {
|
||||
canCreateTeams: false,
|
||||
canJoinTeams: false,
|
||||
currentTeamId: getCurrentTeamId(state),
|
||||
currentUrl: removeProtocol(getCurrentUrl(state)),
|
||||
teams: getMyTeams(state).sort(sortTeams.bind(null, (user.locale))),
|
||||
theme: getTheme(state),
|
||||
...ownProps
|
||||
};
|
||||
}
|
||||
|
||||
function mapDispatchToProps(dispatch) {
|
||||
return {
|
||||
actions: bindActionCreators({
|
||||
handleTeamChange
|
||||
}, dispatch)
|
||||
};
|
||||
}
|
||||
|
||||
export default connect(mapStateToProps, mapDispatchToProps)(ChannelDrawerTeams);
|
||||
|
|
@ -81,12 +81,9 @@ export default class Mattermost {
|
|||
handleVersionUpgrade = async () => {
|
||||
const {dispatch, getState} = store;
|
||||
|
||||
// const {closeDrawers, logout, unrenderDrawer} = this.props.actions;
|
||||
|
||||
Client4.serverVersion = '';
|
||||
PushNotification.setApplicationIconBadgeNumber(0);
|
||||
|
||||
// closeDrawers();
|
||||
// unrenderDrawer();
|
||||
if (getState().entities.general.credentials.token) {
|
||||
InteractionManager.runAfterInteractions(() => {
|
||||
logout()(dispatch, getState);
|
||||
|
|
|
|||
|
|
@ -19,11 +19,14 @@ import {getTheme} from 'app/selectors/preferences';
|
|||
import {preventDoubleTap} from 'app/utils/tap';
|
||||
|
||||
import {getUnreadsInCurrentTeam} from 'mattermost-redux/selectors/entities/channels';
|
||||
import {getCurrentTeamId, getTeamMemberships} from 'mattermost-redux/selectors/entities/teams';
|
||||
import EventEmitter from 'mattermost-redux/utils/event_emitter';
|
||||
|
||||
class ChannelDrawerButton extends PureComponent {
|
||||
static propTypes = {
|
||||
applicationInitializing: PropTypes.bool.isRequired,
|
||||
currentTeamId: PropTypes.string.isRequired,
|
||||
myTeamMembers: PropTypes.object,
|
||||
theme: PropTypes.object,
|
||||
messageCount: PropTypes.number,
|
||||
mentionCount: PropTypes.number
|
||||
|
|
@ -75,14 +78,32 @@ class ChannelDrawerButton extends PureComponent {
|
|||
};
|
||||
|
||||
render() {
|
||||
if (this.props.applicationInitializing) {
|
||||
const {
|
||||
applicationInitializing,
|
||||
currentTeamId,
|
||||
mentionCount,
|
||||
messageCount,
|
||||
myTeamMembers,
|
||||
theme
|
||||
} = this.props;
|
||||
|
||||
if (applicationInitializing) {
|
||||
return null;
|
||||
}
|
||||
|
||||
let badge;
|
||||
let badgeCount = this.props.mentionCount;
|
||||
let mentions = mentionCount;
|
||||
let messages = messageCount;
|
||||
|
||||
if (!badgeCount && this.props.messageCount) {
|
||||
const members = Object.values(myTeamMembers).filter((m) => m.team_id !== currentTeamId);
|
||||
members.forEach((m) => {
|
||||
mentions = mentions + m.mention_count;
|
||||
messages = messages + m.msg_count;
|
||||
});
|
||||
|
||||
let badge;
|
||||
let badgeCount = mentions;
|
||||
|
||||
if (!badgeCount && messages) {
|
||||
badgeCount = -1;
|
||||
}
|
||||
|
||||
|
|
@ -109,7 +130,7 @@ class ChannelDrawerButton extends PureComponent {
|
|||
<Icon
|
||||
name='md-menu'
|
||||
size={25}
|
||||
color={this.props.theme.sidebarHeaderTextColor}
|
||||
color={theme.sidebarHeaderTextColor}
|
||||
/>
|
||||
{badge}
|
||||
</View>
|
||||
|
|
@ -158,6 +179,8 @@ const style = StyleSheet.create({
|
|||
function mapStateToProps(state) {
|
||||
return {
|
||||
applicationInitializing: state.views.root.appInitializing,
|
||||
currentTeamId: getCurrentTeamId(state),
|
||||
myTeamMembers: getTeamMemberships(state),
|
||||
theme: getTheme(state),
|
||||
...getUnreadsInCurrentTeam(state)
|
||||
};
|
||||
|
|
|
|||
|
|
@ -12,7 +12,6 @@ import {getTheme} from 'app/selectors/preferences';
|
|||
import Settings from './settings';
|
||||
|
||||
function mapStateToProps(state, ownProps) {
|
||||
const showTeamSelection = Object.keys(state.entities.teams.teams).length > 1;
|
||||
const {config} = state.entities.general;
|
||||
|
||||
return {
|
||||
|
|
@ -21,8 +20,7 @@ function mapStateToProps(state, ownProps) {
|
|||
theme: getTheme(state),
|
||||
errors: state.errors,
|
||||
currentUserId: state.entities.users.currentUserId,
|
||||
currentTeamId: state.entities.teams.currentTeamId,
|
||||
showTeamSelection
|
||||
currentTeamId: state.entities.teams.currentTeamId
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -30,7 +30,6 @@ class Settings extends PureComponent {
|
|||
errors: PropTypes.array.isRequired,
|
||||
intl: intlShape.isRequired,
|
||||
navigator: PropTypes.object,
|
||||
showTeamSelection: PropTypes.bool.isRequired,
|
||||
theme: PropTypes.object
|
||||
};
|
||||
|
||||
|
|
@ -89,21 +88,6 @@ class Settings extends PureComponent {
|
|||
});
|
||||
};
|
||||
|
||||
goToSelectTeam = () => {
|
||||
const {intl, navigator, theme} = this.props;
|
||||
navigator.push({
|
||||
screen: 'SelectTeam',
|
||||
title: intl.formatMessage({id: 'mobile.routes.selectTeam', defaultMessage: 'Select Team'}),
|
||||
animated: true,
|
||||
backButtonTitle: '',
|
||||
navigatorStyle: {
|
||||
navBarTextColor: theme.sidebarHeaderTextColor,
|
||||
navBarBackgroundColor: theme.sidebarHeaderBg,
|
||||
navBarButtonColor: theme.sidebarHeaderTextColor
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
handlePress = (action) => {
|
||||
preventDoubleTap(action, this);
|
||||
};
|
||||
|
|
@ -138,7 +122,7 @@ class Settings extends PureComponent {
|
|||
};
|
||||
|
||||
render() {
|
||||
const {config, showTeamSelection, theme} = this.props;
|
||||
const {config, theme} = this.props;
|
||||
const style = getStyleSheet(theme);
|
||||
|
||||
return (
|
||||
|
|
@ -153,17 +137,6 @@ class Settings extends PureComponent {
|
|||
separator={true}
|
||||
theme={theme}
|
||||
/>
|
||||
{showTeamSelection &&
|
||||
<SettingsItem
|
||||
defaultMessage='Team Selection'
|
||||
i18nId='mobile.settings.team_selection'
|
||||
iconName='ios-people'
|
||||
iconType='ion'
|
||||
onPress={() => this.handlePress(this.goToSelectTeam)}
|
||||
separator={true}
|
||||
theme={theme}
|
||||
/>
|
||||
}
|
||||
{config.HelpLink &&
|
||||
<SettingsItem
|
||||
defaultMessage='Help'
|
||||
|
|
|
|||
|
|
@ -9,3 +9,7 @@ export function isValidUrl(url) {
|
|||
export function stripTrailingSlashes(url) {
|
||||
return url.replace(/\/+$/, '').trim();
|
||||
}
|
||||
|
||||
export function removeProtocol(url) {
|
||||
return url.replace(/(^\w+:|^)\/\//, '');
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1756,7 +1756,6 @@
|
|||
"mobile.server_ping_failed": "Cannot connect to the server. Please check your server URL and internet connection.",
|
||||
"mobile.server_url.invalid_format": "URL must start with http:// or https://",
|
||||
"mobile.session_expired": "Session Expired: Please log in to continue receiving notifications.",
|
||||
"mobile.settings.team_selection": "Team Selection",
|
||||
"more_channels.close": "Close",
|
||||
"more_channels.create": "Create New Channel",
|
||||
"more_channels.createClick": "Click 'Create New Channel' to make a new one",
|
||||
|
|
|
|||
6234
assets/base/i18n/tr.json
Normal file
6234
assets/base/i18n/tr.json
Normal file
File diff suppressed because it is too large
Load diff
BIN
assets/fonts/OpenSans-Bold.ttf
Executable file
BIN
assets/fonts/OpenSans-Bold.ttf
Executable file
Binary file not shown.
BIN
assets/fonts/OpenSans-BoldItalic.ttf
Executable file
BIN
assets/fonts/OpenSans-BoldItalic.ttf
Executable file
Binary file not shown.
BIN
assets/fonts/OpenSans-ExtraBold.ttf
Executable file
BIN
assets/fonts/OpenSans-ExtraBold.ttf
Executable file
Binary file not shown.
BIN
assets/fonts/OpenSans-ExtraBoldItalic.ttf
Executable file
BIN
assets/fonts/OpenSans-ExtraBoldItalic.ttf
Executable file
Binary file not shown.
BIN
assets/fonts/OpenSans-Italic.ttf
Executable file
BIN
assets/fonts/OpenSans-Italic.ttf
Executable file
Binary file not shown.
BIN
assets/fonts/OpenSans-Light.ttf
Executable file
BIN
assets/fonts/OpenSans-Light.ttf
Executable file
Binary file not shown.
BIN
assets/fonts/OpenSans-LightItalic.ttf
Executable file
BIN
assets/fonts/OpenSans-LightItalic.ttf
Executable file
Binary file not shown.
BIN
assets/fonts/OpenSans-Regular.ttf
Executable file
BIN
assets/fonts/OpenSans-Regular.ttf
Executable file
Binary file not shown.
BIN
assets/fonts/OpenSans-Semibold.ttf
Executable file
BIN
assets/fonts/OpenSans-Semibold.ttf
Executable file
Binary file not shown.
BIN
assets/fonts/OpenSans-SemiboldItalic.ttf
Executable file
BIN
assets/fonts/OpenSans-SemiboldItalic.ttf
Executable file
Binary file not shown.
|
|
@ -46,6 +46,16 @@
|
|||
C035DB50ED2045F09923FFAE /* MaterialCommunityIcons.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 04AA5E8EF3B54735A11E3B95 /* MaterialCommunityIcons.ttf */; };
|
||||
C337E8708D2845C6A8DBB47E /* Ionicons.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 2DCFD31D3F4A4154822AB532 /* Ionicons.ttf */; };
|
||||
F006936FC2884C24A1321FC0 /* MaterialIcons.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 356C9186FA374641A00EB2EA /* MaterialIcons.ttf */; };
|
||||
9358B95F95184EE0A4DCE629 /* OpenSans-Bold.ttf in Resources */ = {isa = PBXBuildFile; fileRef = D4B1B363C2414DA19C1AC521 /* OpenSans-Bold.ttf */; };
|
||||
55C6561DDBBA45929D88B6D1 /* OpenSans-BoldItalic.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 32AC3D4EA79E44738A6E9766 /* OpenSans-BoldItalic.ttf */; };
|
||||
D719A67137964F08BE47A5FC /* OpenSans-ExtraBold.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 3647DF63D6764CF093375861 /* OpenSans-ExtraBold.ttf */; };
|
||||
0111A42B7F264BCF8CBDE3ED /* OpenSans-ExtraBoldItalic.ttf in Resources */ = {isa = PBXBuildFile; fileRef = FBBEC29EE2D3418D9AC33BD5 /* OpenSans-ExtraBoldItalic.ttf */; };
|
||||
0C0D24F53F254F75869E5951 /* OpenSans-Italic.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 41F3AFE83AAF4B74878AB78A /* OpenSans-Italic.ttf */; };
|
||||
2D5296A8926B4D7FBAF2D6E2 /* OpenSans-Light.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 6561AEAC21CC40B8A72ABB93 /* OpenSans-Light.ttf */; };
|
||||
F083DB472349411A8E6E7AAD /* OpenSans-LightItalic.ttf in Resources */ = {isa = PBXBuildFile; fileRef = BE17F630DB5D41FD93F32D22 /* OpenSans-LightItalic.ttf */; };
|
||||
A08D512E7ADC40CCAD055A9E /* OpenSans-Regular.ttf in Resources */ = {isa = PBXBuildFile; fileRef = BC977883E2624E05975CA65B /* OpenSans-Regular.ttf */; };
|
||||
62A8448264674B4D95A5A7C2 /* OpenSans-Semibold.ttf in Resources */ = {isa = PBXBuildFile; fileRef = C78A387124874496AD2C1466 /* OpenSans-Semibold.ttf */; };
|
||||
69AC753E496743BABB7A7124 /* OpenSans-SemiboldItalic.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 0E617BF0F36D4E738F51D169 /* OpenSans-SemiboldItalic.ttf */; };
|
||||
/* End PBXBuildFile section */
|
||||
|
||||
/* Begin PBXContainerItemProxy section */
|
||||
|
|
@ -387,6 +397,16 @@
|
|||
EE671DF7637347CD8C069819 /* libRNDeviceInfo.a */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = archive.ar; path = libRNDeviceInfo.a; sourceTree = "<group>"; };
|
||||
F1F071EE85494E269A50AE88 /* SimpleLineIcons.ttf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = unknown; name = SimpleLineIcons.ttf; path = "../node_modules/react-native-vector-icons/Fonts/SimpleLineIcons.ttf"; sourceTree = "<group>"; };
|
||||
F81F6DC42D394831B4549928 /* libRNSearchBar.a */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = archive.ar; path = libRNSearchBar.a; sourceTree = "<group>"; };
|
||||
D4B1B363C2414DA19C1AC521 /* OpenSans-Bold.ttf */ = {isa = PBXFileReference; name = "OpenSans-Bold.ttf"; path = "../assets/fonts/OpenSans-Bold.ttf"; sourceTree = "<group>"; fileEncoding = undefined; lastKnownFileType = unknown; explicitFileType = undefined; includeInIndex = 0; };
|
||||
32AC3D4EA79E44738A6E9766 /* OpenSans-BoldItalic.ttf */ = {isa = PBXFileReference; name = "OpenSans-BoldItalic.ttf"; path = "../assets/fonts/OpenSans-BoldItalic.ttf"; sourceTree = "<group>"; fileEncoding = undefined; lastKnownFileType = unknown; explicitFileType = undefined; includeInIndex = 0; };
|
||||
3647DF63D6764CF093375861 /* OpenSans-ExtraBold.ttf */ = {isa = PBXFileReference; name = "OpenSans-ExtraBold.ttf"; path = "../assets/fonts/OpenSans-ExtraBold.ttf"; sourceTree = "<group>"; fileEncoding = undefined; lastKnownFileType = unknown; explicitFileType = undefined; includeInIndex = 0; };
|
||||
FBBEC29EE2D3418D9AC33BD5 /* OpenSans-ExtraBoldItalic.ttf */ = {isa = PBXFileReference; name = "OpenSans-ExtraBoldItalic.ttf"; path = "../assets/fonts/OpenSans-ExtraBoldItalic.ttf"; sourceTree = "<group>"; fileEncoding = undefined; lastKnownFileType = unknown; explicitFileType = undefined; includeInIndex = 0; };
|
||||
41F3AFE83AAF4B74878AB78A /* OpenSans-Italic.ttf */ = {isa = PBXFileReference; name = "OpenSans-Italic.ttf"; path = "../assets/fonts/OpenSans-Italic.ttf"; sourceTree = "<group>"; fileEncoding = undefined; lastKnownFileType = unknown; explicitFileType = undefined; includeInIndex = 0; };
|
||||
6561AEAC21CC40B8A72ABB93 /* OpenSans-Light.ttf */ = {isa = PBXFileReference; name = "OpenSans-Light.ttf"; path = "../assets/fonts/OpenSans-Light.ttf"; sourceTree = "<group>"; fileEncoding = undefined; lastKnownFileType = unknown; explicitFileType = undefined; includeInIndex = 0; };
|
||||
BE17F630DB5D41FD93F32D22 /* OpenSans-LightItalic.ttf */ = {isa = PBXFileReference; name = "OpenSans-LightItalic.ttf"; path = "../assets/fonts/OpenSans-LightItalic.ttf"; sourceTree = "<group>"; fileEncoding = undefined; lastKnownFileType = unknown; explicitFileType = undefined; includeInIndex = 0; };
|
||||
BC977883E2624E05975CA65B /* OpenSans-Regular.ttf */ = {isa = PBXFileReference; name = "OpenSans-Regular.ttf"; path = "../assets/fonts/OpenSans-Regular.ttf"; sourceTree = "<group>"; fileEncoding = undefined; lastKnownFileType = unknown; explicitFileType = undefined; includeInIndex = 0; };
|
||||
C78A387124874496AD2C1466 /* OpenSans-Semibold.ttf */ = {isa = PBXFileReference; name = "OpenSans-Semibold.ttf"; path = "../assets/fonts/OpenSans-Semibold.ttf"; sourceTree = "<group>"; fileEncoding = undefined; lastKnownFileType = unknown; explicitFileType = undefined; includeInIndex = 0; };
|
||||
0E617BF0F36D4E738F51D169 /* OpenSans-SemiboldItalic.ttf */ = {isa = PBXFileReference; name = "OpenSans-SemiboldItalic.ttf"; path = "../assets/fonts/OpenSans-SemiboldItalic.ttf"; sourceTree = "<group>"; fileEncoding = undefined; lastKnownFileType = unknown; explicitFileType = undefined; includeInIndex = 0; };
|
||||
/* End PBXFileReference section */
|
||||
|
||||
/* Begin PBXFrameworksBuildPhase section */
|
||||
|
|
@ -502,6 +522,16 @@
|
|||
EDC04CBCF81642219D199CBB /* Octicons.ttf */,
|
||||
F1F071EE85494E269A50AE88 /* SimpleLineIcons.ttf */,
|
||||
0A091BF1A3D04650AD306A0D /* Zocial.ttf */,
|
||||
D4B1B363C2414DA19C1AC521 /* OpenSans-Bold.ttf */,
|
||||
32AC3D4EA79E44738A6E9766 /* OpenSans-BoldItalic.ttf */,
|
||||
3647DF63D6764CF093375861 /* OpenSans-ExtraBold.ttf */,
|
||||
FBBEC29EE2D3418D9AC33BD5 /* OpenSans-ExtraBoldItalic.ttf */,
|
||||
41F3AFE83AAF4B74878AB78A /* OpenSans-Italic.ttf */,
|
||||
6561AEAC21CC40B8A72ABB93 /* OpenSans-Light.ttf */,
|
||||
BE17F630DB5D41FD93F32D22 /* OpenSans-LightItalic.ttf */,
|
||||
BC977883E2624E05975CA65B /* OpenSans-Regular.ttf */,
|
||||
C78A387124874496AD2C1466 /* OpenSans-Semibold.ttf */,
|
||||
0E617BF0F36D4E738F51D169 /* OpenSans-SemiboldItalic.ttf */,
|
||||
);
|
||||
name = Resources;
|
||||
sourceTree = "<group>";
|
||||
|
|
@ -1191,6 +1221,16 @@
|
|||
7F292A711E8AB73400A450A3 /* SplashScreenResource in Resources */,
|
||||
2B4C9B708010475DA575B81D /* SimpleLineIcons.ttf in Resources */,
|
||||
1BCA51319AC6442991C6A208 /* Zocial.ttf in Resources */,
|
||||
9358B95F95184EE0A4DCE629 /* OpenSans-Bold.ttf in Resources */,
|
||||
55C6561DDBBA45929D88B6D1 /* OpenSans-BoldItalic.ttf in Resources */,
|
||||
D719A67137964F08BE47A5FC /* OpenSans-ExtraBold.ttf in Resources */,
|
||||
0111A42B7F264BCF8CBDE3ED /* OpenSans-ExtraBoldItalic.ttf in Resources */,
|
||||
0C0D24F53F254F75869E5951 /* OpenSans-Italic.ttf in Resources */,
|
||||
2D5296A8926B4D7FBAF2D6E2 /* OpenSans-Light.ttf in Resources */,
|
||||
F083DB472349411A8E6E7AAD /* OpenSans-LightItalic.ttf in Resources */,
|
||||
A08D512E7ADC40CCAD055A9E /* OpenSans-Regular.ttf in Resources */,
|
||||
62A8448264674B4D95A5A7C2 /* OpenSans-Semibold.ttf in Resources */,
|
||||
69AC753E496743BABB7A7124 /* OpenSans-SemiboldItalic.ttf in Resources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1,84 +1,94 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>CFBundleDevelopmentRegion</key>
|
||||
<string>en</string>
|
||||
<key>CFBundleExecutable</key>
|
||||
<string>$(EXECUTABLE_NAME)</string>
|
||||
<key>CFBundleIdentifier</key>
|
||||
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
|
||||
<key>CFBundleInfoDictionaryVersion</key>
|
||||
<string>6.0</string>
|
||||
<key>CFBundleName</key>
|
||||
<string>$(PRODUCT_NAME)</string>
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>APPL</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>1.0</string>
|
||||
<key>CFBundleSignature</key>
|
||||
<string>????</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>30</string>
|
||||
<key>ITSAppUsesNonExemptEncryption</key>
|
||||
<false/>
|
||||
<key>LSRequiresIPhoneOS</key>
|
||||
<true/>
|
||||
<key>NSAllowsArbitraryLoads</key>
|
||||
<true/>
|
||||
<key>NSAppTransportSecurity</key>
|
||||
<dict>
|
||||
<key>NSAllowsArbitraryLoads</key>
|
||||
<true/>
|
||||
<key>NSExceptionDomains</key>
|
||||
<dict>
|
||||
<key>localhost</key>
|
||||
<dict>
|
||||
<key>NSExceptionAllowsInsecureHTTPLoads</key>
|
||||
<true/>
|
||||
</dict>
|
||||
</dict>
|
||||
</dict>
|
||||
<key>NSCameraUsageDescription</key>
|
||||
<string>Take a Photo or Video and upload it to your mattermost instance</string>
|
||||
<key>NSLocationWhenInUseUsageDescription</key>
|
||||
<string></string>
|
||||
<key>NSPhotoLibraryUsageDescription</key>
|
||||
<string>Upload Photos and Videos to your Mattermost instance</string>
|
||||
<key>UIAppFonts</key>
|
||||
<array>
|
||||
<string>Entypo.ttf</string>
|
||||
<string>EvilIcons.ttf</string>
|
||||
<string>FontAwesome.ttf</string>
|
||||
<string>Foundation.ttf</string>
|
||||
<string>Ionicons.ttf</string>
|
||||
<string>MaterialIcons.ttf</string>
|
||||
<string>Octicons.ttf</string>
|
||||
<string>Zocial.ttf</string>
|
||||
<string>Entypo.ttf</string>
|
||||
<string>EvilIcons.ttf</string>
|
||||
<string>FontAwesome.ttf</string>
|
||||
<string>Foundation.ttf</string>
|
||||
<string>Ionicons.ttf</string>
|
||||
<string>MaterialCommunityIcons.ttf</string>
|
||||
<string>MaterialIcons.ttf</string>
|
||||
<string>Octicons.ttf</string>
|
||||
<string>SimpleLineIcons.ttf</string>
|
||||
<string>Zocial.ttf</string>
|
||||
</array>
|
||||
<key>UILaunchStoryboardName</key>
|
||||
<string>LaunchScreen</string>
|
||||
<key>UIRequiredDeviceCapabilities</key>
|
||||
<array>
|
||||
<string>armv7</string>
|
||||
</array>
|
||||
<key>UISupportedInterfaceOrientations</key>
|
||||
<array>
|
||||
<string>UIInterfaceOrientationPortrait</string>
|
||||
<string>UIInterfaceOrientationLandscapeLeft</string>
|
||||
<string>UIInterfaceOrientationLandscapeRight</string>
|
||||
</array>
|
||||
<key>UIViewControllerBasedStatusBarAppearance</key>
|
||||
<false/>
|
||||
</dict>
|
||||
</plist>
|
||||
<dict>
|
||||
<key>CFBundleDevelopmentRegion</key>
|
||||
<string>en</string>
|
||||
<key>CFBundleExecutable</key>
|
||||
<string>$(EXECUTABLE_NAME)</string>
|
||||
<key>CFBundleIdentifier</key>
|
||||
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
|
||||
<key>CFBundleInfoDictionaryVersion</key>
|
||||
<string>6.0</string>
|
||||
<key>CFBundleName</key>
|
||||
<string>$(PRODUCT_NAME)</string>
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>APPL</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>1.0</string>
|
||||
<key>CFBundleSignature</key>
|
||||
<string>????</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>30</string>
|
||||
<key>ITSAppUsesNonExemptEncryption</key>
|
||||
<false/>
|
||||
<key>LSRequiresIPhoneOS</key>
|
||||
<true/>
|
||||
<key>NSAllowsArbitraryLoads</key>
|
||||
<true/>
|
||||
<key>NSAppTransportSecurity</key>
|
||||
<dict>
|
||||
<key>NSAllowsArbitraryLoads</key>
|
||||
<true/>
|
||||
<key>NSExceptionDomains</key>
|
||||
<dict>
|
||||
<key>localhost</key>
|
||||
<dict>
|
||||
<key>NSExceptionAllowsInsecureHTTPLoads</key>
|
||||
<true/>
|
||||
</dict>
|
||||
</dict>
|
||||
</dict>
|
||||
<key>NSCameraUsageDescription</key>
|
||||
<string>Take a Photo or Video and upload it to your mattermost instance</string>
|
||||
<key>NSLocationWhenInUseUsageDescription</key>
|
||||
<string/>
|
||||
<key>NSPhotoLibraryUsageDescription</key>
|
||||
<string>Upload Photos and Videos to your Mattermost instance</string>
|
||||
<key>UIAppFonts</key>
|
||||
<array>
|
||||
<string>Entypo.ttf</string>
|
||||
<string>EvilIcons.ttf</string>
|
||||
<string>FontAwesome.ttf</string>
|
||||
<string>Foundation.ttf</string>
|
||||
<string>Ionicons.ttf</string>
|
||||
<string>MaterialIcons.ttf</string>
|
||||
<string>Octicons.ttf</string>
|
||||
<string>Zocial.ttf</string>
|
||||
<string>Entypo.ttf</string>
|
||||
<string>EvilIcons.ttf</string>
|
||||
<string>FontAwesome.ttf</string>
|
||||
<string>Foundation.ttf</string>
|
||||
<string>Ionicons.ttf</string>
|
||||
<string>MaterialCommunityIcons.ttf</string>
|
||||
<string>MaterialIcons.ttf</string>
|
||||
<string>Octicons.ttf</string>
|
||||
<string>SimpleLineIcons.ttf</string>
|
||||
<string>Zocial.ttf</string>
|
||||
<string>OpenSans-Bold.ttf</string>
|
||||
<string>OpenSans-BoldItalic.ttf</string>
|
||||
<string>OpenSans-ExtraBold.ttf</string>
|
||||
<string>OpenSans-ExtraBoldItalic.ttf</string>
|
||||
<string>OpenSans-Italic.ttf</string>
|
||||
<string>OpenSans-Light.ttf</string>
|
||||
<string>OpenSans-LightItalic.ttf</string>
|
||||
<string>OpenSans-Regular.ttf</string>
|
||||
<string>OpenSans-Semibold.ttf</string>
|
||||
<string>OpenSans-SemiboldItalic.ttf</string>
|
||||
</array>
|
||||
<key>UILaunchStoryboardName</key>
|
||||
<string>LaunchScreen</string>
|
||||
<key>UIRequiredDeviceCapabilities</key>
|
||||
<array>
|
||||
<string>armv7</string>
|
||||
</array>
|
||||
<key>UISupportedInterfaceOrientations</key>
|
||||
<array>
|
||||
<string>UIInterfaceOrientationPortrait</string>
|
||||
<string>UIInterfaceOrientationLandscapeLeft</string>
|
||||
<string>UIInterfaceOrientationLandscapeRight</string>
|
||||
</array>
|
||||
<key>UIViewControllerBasedStatusBarAppearance</key>
|
||||
<false/>
|
||||
</dict>
|
||||
</plist>
|
||||
|
|
@ -31,6 +31,7 @@
|
|||
"react-native-push-notification": "3.0.0",
|
||||
"react-native-search-bar": "enahum/react-native-search-bar.git",
|
||||
"react-native-svg": "5.1.8",
|
||||
"react-native-swiper": "1.5.4",
|
||||
"react-native-tooltip": "5.0.0",
|
||||
"react-native-vector-icons": "4.1.1",
|
||||
"react-redux": "5.0.4",
|
||||
|
|
@ -81,5 +82,10 @@
|
|||
"start": "node node_modules/react-native/local-cli/cli.js start -- --reset-cache",
|
||||
"test": "NODE_ENV=test mocha --opts test/mocha.opts",
|
||||
"postinstall": "make post-install"
|
||||
},
|
||||
"rnpm": {
|
||||
"assets": [
|
||||
"./assets/fonts"
|
||||
]
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3526,7 +3526,7 @@ makeerror@1.0.x:
|
|||
|
||||
mattermost-redux@mattermost/mattermost-redux#master:
|
||||
version "0.0.1"
|
||||
resolved "https://codeload.github.com/mattermost/mattermost-redux/tar.gz/dd0d59b2b29aea9c9e6407b72c8eb6e6e0ba091f"
|
||||
resolved "https://codeload.github.com/mattermost/mattermost-redux/tar.gz/1755fccae9f6e11899e128f29023b0f7e1475bef"
|
||||
dependencies:
|
||||
deep-equal "1.0.1"
|
||||
harmony-reflect "1.5.1"
|
||||
|
|
@ -4391,6 +4391,10 @@ react-native-svg@5.1.8:
|
|||
color "^0.11.1"
|
||||
lodash "^4.16.6"
|
||||
|
||||
react-native-swiper@1.5.4:
|
||||
version "1.5.4"
|
||||
resolved "https://registry.yarnpkg.com/react-native-swiper/-/react-native-swiper-1.5.4.tgz#a85535b5374ef8d605a7a720e447ac46816ac448"
|
||||
|
||||
react-native-tooltip@5.0.0:
|
||||
version "5.0.0"
|
||||
resolved "https://registry.yarnpkg.com/react-native-tooltip/-/react-native-tooltip-5.0.0.tgz#90477f257081ce168d2a27d2ac29e74759b7a7d6"
|
||||
|
|
|
|||
Loading…
Reference in a new issue