From 1c1d0e36aa4df36ae788217b3237e6678d3bfc52 Mon Sep 17 00:00:00 2001 From: Shaz Amjad Date: Fri, 5 Nov 2021 00:32:35 +1100 Subject: [PATCH] MM-38682: Gekidou Homepage (Static) (#5756) * Home page first pass * Adds missing static elements, introduces button component * Removes inlines styles * Various clean ups and button component added * Updates typography, and adds button util * Removes button component * Uses stylesheet.create for memoization * Snapshots updated * Podfile update / fix * Flatlist! * Tests updated * Moves out server icon, styling fixes * Sneaky buttons added, compass-icons list, and server_icon removed * Snapshots * Adds chevron to header * Removes unnecessary files * Tidies up header and error * Address feedback * Compass Icon const removed --- app/actions/websocket/index.ts | 2 +- .../__snapshots__/index.test.tsx.snap | 762 ++++++++++++++++++ .../__snapshots__/index.test.tsx.snap | 430 ++++++++++ .../body/__snapshots__/index.test.tsx.snap | 127 +++ .../channel/__snapshots__/index.test.tsx.snap | 43 + .../categories/body/channel/index.test.tsx | 19 + .../categories/body/channel/index.tsx | 75 ++ .../categories/body/index.test.tsx | 21 + .../channel_list/categories/body/index.tsx | 32 + .../header/__snapshots__/index.test.tsx.snap | 26 + .../categories/header/index.test.tsx | 16 + .../channel_list/categories/header/index.tsx | 39 + .../channel_list/categories/index.test.tsx | 26 + .../channel_list/categories/index.tsx | 40 + .../header/__snapshots__/index.test.tsx.snap | 137 ++++ .../channel_list/header/index.test.tsx | 16 + app/components/channel_list/header/index.tsx | 89 ++ app/components/channel_list/index.test.tsx | 16 + app/components/channel_list/index.tsx | 79 ++ .../loading/__snapshots__/index.test.tsx.snap | 58 ++ .../channel_list/loading/index.test.tsx | 16 + app/components/channel_list/loading/index.tsx | 31 + .../channel_list/loading/spinner.json | 1 + .../__snapshots__/index.test.tsx.snap | 151 ++++ .../channel_list/loading_error/index.test.tsx | 16 + .../channel_list/loading_error/index.tsx | 70 ++ .../search/__snapshots__/index.test.tsx.snap | 63 ++ .../channel_list/search/index.test.tsx | 16 + app/components/channel_list/search/index.tsx | 69 ++ app/components/channel_list/tempo-types.d.ts | 16 + .../threads/__snapshots__/index.test.tsx.snap | 70 ++ .../channel_list/threads/index.test.tsx | 16 + app/components/channel_list/threads/index.tsx | 56 ++ app/components/compass_icon/index.tsx | 5 +- .../team_sidebar/add_team/team_list.tsx | 2 +- app/components/team_sidebar/index.ts | 4 +- .../team_sidebar/server_icon/server_icon.tsx | 38 - app/components/team_sidebar/team_sidebar.tsx | 12 +- app/init/push_notifications.ts | 2 +- app/init/websocket_manager.ts | 8 +- app/screens/bottom_sheet/index.tsx | 2 +- app/screens/channel_list/index.tsx | 48 -- app/screens/emoji_picker/index.tsx | 2 +- .../options/user_presence/index.tsx | 2 +- app/screens/home/channel_list/index.tsx | 28 +- .../__snapshots__/server_icon.test.tsx.snap | 26 + .../server_icon/server_icon.test.tsx | 16 + .../channel_list/server_icon/server_icon.tsx | 39 + app/screens/server/form.tsx | 2 +- app/screens/server/header.tsx | 2 +- app/utils/buttonStyles.ts | 17 +- ios/Podfile.lock | 20 +- package-lock.json | 69 ++ package.json | 2 + 54 files changed, 2859 insertions(+), 131 deletions(-) create mode 100644 app/components/channel_list/__snapshots__/index.test.tsx.snap create mode 100644 app/components/channel_list/categories/__snapshots__/index.test.tsx.snap create mode 100644 app/components/channel_list/categories/body/__snapshots__/index.test.tsx.snap create mode 100644 app/components/channel_list/categories/body/channel/__snapshots__/index.test.tsx.snap create mode 100644 app/components/channel_list/categories/body/channel/index.test.tsx create mode 100644 app/components/channel_list/categories/body/channel/index.tsx create mode 100644 app/components/channel_list/categories/body/index.test.tsx create mode 100644 app/components/channel_list/categories/body/index.tsx create mode 100644 app/components/channel_list/categories/header/__snapshots__/index.test.tsx.snap create mode 100644 app/components/channel_list/categories/header/index.test.tsx create mode 100644 app/components/channel_list/categories/header/index.tsx create mode 100644 app/components/channel_list/categories/index.test.tsx create mode 100644 app/components/channel_list/categories/index.tsx create mode 100644 app/components/channel_list/header/__snapshots__/index.test.tsx.snap create mode 100644 app/components/channel_list/header/index.test.tsx create mode 100644 app/components/channel_list/header/index.tsx create mode 100644 app/components/channel_list/index.test.tsx create mode 100644 app/components/channel_list/index.tsx create mode 100644 app/components/channel_list/loading/__snapshots__/index.test.tsx.snap create mode 100644 app/components/channel_list/loading/index.test.tsx create mode 100644 app/components/channel_list/loading/index.tsx create mode 100644 app/components/channel_list/loading/spinner.json create mode 100644 app/components/channel_list/loading_error/__snapshots__/index.test.tsx.snap create mode 100644 app/components/channel_list/loading_error/index.test.tsx create mode 100644 app/components/channel_list/loading_error/index.tsx create mode 100644 app/components/channel_list/search/__snapshots__/index.test.tsx.snap create mode 100644 app/components/channel_list/search/index.test.tsx create mode 100644 app/components/channel_list/search/index.tsx create mode 100644 app/components/channel_list/tempo-types.d.ts create mode 100644 app/components/channel_list/threads/__snapshots__/index.test.tsx.snap create mode 100644 app/components/channel_list/threads/index.test.tsx create mode 100644 app/components/channel_list/threads/index.tsx delete mode 100644 app/components/team_sidebar/server_icon/server_icon.tsx delete mode 100644 app/screens/channel_list/index.tsx create mode 100644 app/screens/home/channel_list/server_icon/__snapshots__/server_icon.test.tsx.snap create mode 100644 app/screens/home/channel_list/server_icon/server_icon.test.tsx create mode 100644 app/screens/home/channel_list/server_icon/server_icon.tsx diff --git a/app/actions/websocket/index.ts b/app/actions/websocket/index.ts index a3405adb3..f27770baf 100644 --- a/app/actions/websocket/index.ts +++ b/app/actions/websocket/index.ts @@ -10,9 +10,9 @@ import {fetchRoles} from '@actions/remote/role'; import {fetchConfigAndLicense} from '@actions/remote/systems'; import {fetchAllTeams, fetchMyTeams} from '@actions/remote/team'; import {fetchMe, updateAllUsersSinceLastDisconnect} from '@actions/remote/user'; -import Events from '@app/constants/events'; import {General, WebsocketEvents} from '@constants'; import {SYSTEM_IDENTIFIERS} from '@constants/database'; +import Events from '@constants/events'; import DatabaseManager from '@database/manager'; import {getTeammateNameDisplaySetting} from '@helpers/api/preference'; import {prepareMyChannelsForTeam} from '@queries/servers/channel'; diff --git a/app/components/channel_list/__snapshots__/index.test.tsx.snap b/app/components/channel_list/__snapshots__/index.test.tsx.snap new file mode 100644 index 000000000..eaeb5b73d --- /dev/null +++ b/app/components/channel_list/__snapshots__/index.test.tsx.snap @@ -0,0 +1,762 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`Channels List should match snapshot 1`] = ` + + + + + + + + Contributors + + + + + + + + + + + + + + + Community TEST + + + + + + + + + + + + + + + + + Threads + + + + + + + + + MY FIRST CATEGORY + + + + + + + + Just a channel + + + + + + + + A Highlighted Channel!!! + + + + + + + + And a longer channel name. + + + + + + + + + ANOTHER CAT + + + + + + + + Just a channel + + + + + + + + A Highlighted Channel!!! + + + + + + + + And a longer channel name. + + + + + + + + +`; diff --git a/app/components/channel_list/categories/__snapshots__/index.test.tsx.snap b/app/components/channel_list/categories/__snapshots__/index.test.tsx.snap new file mode 100644 index 000000000..2d0e3b41a --- /dev/null +++ b/app/components/channel_list/categories/__snapshots__/index.test.tsx.snap @@ -0,0 +1,430 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`Category List Component should match snapshot 1`] = ` + + + + + + + + + Threads + + + + + + + + + MY FIRST CATEGORY + + + + + + + + Just a channel + + + + + + + + Highlighted!!! + + + + + + + + + ANOTHER CAT + + + + + + + + Just a channel + + + + + + + + Highlighted!!! + + + + + + + +`; diff --git a/app/components/channel_list/categories/body/__snapshots__/index.test.tsx.snap b/app/components/channel_list/categories/body/__snapshots__/index.test.tsx.snap new file mode 100644 index 000000000..2014360a3 --- /dev/null +++ b/app/components/channel_list/categories/body/__snapshots__/index.test.tsx.snap @@ -0,0 +1,127 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`Category Body Component should match snapshot 1`] = ` + + + + + + + Just a channel + + + + + + + + Highlighted!!! + + + + + +`; diff --git a/app/components/channel_list/categories/body/channel/__snapshots__/index.test.tsx.snap b/app/components/channel_list/categories/body/channel/__snapshots__/index.test.tsx.snap new file mode 100644 index 000000000..55ea35f10 --- /dev/null +++ b/app/components/channel_list/categories/body/channel/__snapshots__/index.test.tsx.snap @@ -0,0 +1,43 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`Category Channel List Item should match snapshot 1`] = ` + + + + Channel Name + + +`; diff --git a/app/components/channel_list/categories/body/channel/index.test.tsx b/app/components/channel_list/categories/body/channel/index.test.tsx new file mode 100644 index 000000000..ccb818945 --- /dev/null +++ b/app/components/channel_list/categories/body/channel/index.test.tsx @@ -0,0 +1,19 @@ +// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved. +// See LICENSE.txt for license information. + +import React from 'react'; + +import {renderWithIntlAndTheme} from '@test/intl-test-helper'; + +import ChannelItem from './index'; + +test('Category Channel List Item should match snapshot', () => { + const {toJSON} = renderWithIntlAndTheme( + , + ); + + expect(toJSON()).toMatchSnapshot(); +}); diff --git a/app/components/channel_list/categories/body/channel/index.tsx b/app/components/channel_list/categories/body/channel/index.tsx new file mode 100644 index 000000000..ae3b09e8d --- /dev/null +++ b/app/components/channel_list/categories/body/channel/index.tsx @@ -0,0 +1,75 @@ +// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved. +// See LICENSE.txt for license information. + +import React from 'react'; +import {StyleSheet, Text, View} from 'react-native'; + +import CompassIcon from '@components/compass_icon'; +import {useTheme} from '@context/theme'; +import {changeOpacity, makeStyleSheetFromTheme} from '@utils/theme'; +import {typography} from '@utils/typography'; + +const getStyleSheet = makeStyleSheetFromTheme((theme: Theme) => ({ + container: { + paddingVertical: 4, + flexDirection: 'row', + }, + icon: { + fontSize: 24, + lineHeight: 28, + color: changeOpacity(theme.sidebarText, 0.72), + }, + text: { + marginTop: 1, + color: changeOpacity(theme.sidebarText, 0.72), + paddingLeft: 12, + }, + highlight: { + color: theme.sidebarText, + }, +})); + +const textStyle = StyleSheet.create({ + bright: typography('Body', 200, 'SemiBold'), + regular: typography('Body', 200, 'Regular'), +}); + +type Props = { + unreadCount?: number; + highlight?: boolean; + name: string; + icon: string; +} + +const ChannelListItem = (props: Props) => { + const theme = useTheme(); + const styles = getStyleSheet(theme); + + const {unreadCount, highlight, name, icon} = props; + + // Make it brighter if it's highlighted, or has unreads + const bright = highlight || (unreadCount && unreadCount > 0); + + return ( + + {icon && ( + + )} + + {name} + + + + ); +}; + +export default ChannelListItem; diff --git a/app/components/channel_list/categories/body/index.test.tsx b/app/components/channel_list/categories/body/index.test.tsx new file mode 100644 index 000000000..612428cc1 --- /dev/null +++ b/app/components/channel_list/categories/body/index.test.tsx @@ -0,0 +1,21 @@ +// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved. +// See LICENSE.txt for license information. + +import React from 'react'; + +import {renderWithIntlAndTheme} from '@test/intl-test-helper'; + +import CategoryBody from './index'; + +const channels: TempoChannel[] = [ + {id: '1', name: 'Just a channel'}, + {id: '2', name: 'Highlighted!!!', highlight: true}, +]; + +test('Category Body Component should match snapshot', () => { + const {toJSON} = renderWithIntlAndTheme( + , + ); + + expect(toJSON()).toMatchSnapshot(); +}); diff --git a/app/components/channel_list/categories/body/index.tsx b/app/components/channel_list/categories/body/index.tsx new file mode 100644 index 000000000..3ac9d8b50 --- /dev/null +++ b/app/components/channel_list/categories/body/index.tsx @@ -0,0 +1,32 @@ +// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved. +// See LICENSE.txt for license information. + +import React from 'react'; +import {FlatList} from 'react-native'; + +import ChannelListItem from './channel'; + +const renderChannelItem = (data: { item: TempoChannel }) => { + return ( + + ); +}; + +type Props = { + channels: TempoChannel[]; +}; + +const CategoryBody = (props: Props) => { + return ( + + ); +}; + +export default CategoryBody; diff --git a/app/components/channel_list/categories/header/__snapshots__/index.test.tsx.snap b/app/components/channel_list/categories/header/__snapshots__/index.test.tsx.snap new file mode 100644 index 000000000..2baacfda8 --- /dev/null +++ b/app/components/channel_list/categories/header/__snapshots__/index.test.tsx.snap @@ -0,0 +1,26 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`Category Header Component should match snapshot 1`] = ` + + + CAT HEADING + + +`; diff --git a/app/components/channel_list/categories/header/index.test.tsx b/app/components/channel_list/categories/header/index.test.tsx new file mode 100644 index 000000000..231e446f9 --- /dev/null +++ b/app/components/channel_list/categories/header/index.test.tsx @@ -0,0 +1,16 @@ +// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved. +// See LICENSE.txt for license information. + +import React from 'react'; + +import {renderWithIntlAndTheme} from '@test/intl-test-helper'; + +import Header from './index'; + +test('Category Header Component should match snapshot', () => { + const {toJSON} = renderWithIntlAndTheme( +
, + ); + + expect(toJSON()).toMatchSnapshot(); +}); diff --git a/app/components/channel_list/categories/header/index.tsx b/app/components/channel_list/categories/header/index.tsx new file mode 100644 index 000000000..c2741dafa --- /dev/null +++ b/app/components/channel_list/categories/header/index.tsx @@ -0,0 +1,39 @@ +// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved. +// See LICENSE.txt for license information. + +import React from 'react'; +import {Text, View} from 'react-native'; + +import {useTheme} from '@context/theme'; +import {changeOpacity, makeStyleSheetFromTheme} from '@utils/theme'; +import {typography} from '@utils/typography'; + +const getStyleSheet = makeStyleSheetFromTheme((theme: Theme) => ({ + container: { + paddingVertical: 8, + marginTop: 12, + }, + heading: { + color: changeOpacity(theme.sidebarText, 0.64), + ...typography('Heading', 75), + }, +})); + +type Props = { + heading: string; +} + +const CategoryHeader = (props: Props) => { + const theme = useTheme(); + const styles = getStyleSheet(theme); + + return ( + + + {props.heading.toUpperCase()} + + + ); +}; + +export default CategoryHeader; diff --git a/app/components/channel_list/categories/index.test.tsx b/app/components/channel_list/categories/index.test.tsx new file mode 100644 index 000000000..848404b8f --- /dev/null +++ b/app/components/channel_list/categories/index.test.tsx @@ -0,0 +1,26 @@ +// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved. +// See LICENSE.txt for license information. + +import React from 'react'; + +import {renderWithIntlAndTheme} from '@test/intl-test-helper'; + +import Category from './index'; + +const channels: TempoChannel[] = [ + {id: '1', name: 'Just a channel'}, + {id: '2', name: 'Highlighted!!!', highlight: true}, +]; + +const categories: TempoCategory[] = [ + {id: '1', title: 'My first Category', channels}, + {id: '2', title: 'Another cat', channels}, +]; + +test('Category List Component should match snapshot', () => { + const {toJSON} = renderWithIntlAndTheme( + , + ); + + expect(toJSON()).toMatchSnapshot(); +}); diff --git a/app/components/channel_list/categories/index.tsx b/app/components/channel_list/categories/index.tsx new file mode 100644 index 000000000..82927dd21 --- /dev/null +++ b/app/components/channel_list/categories/index.tsx @@ -0,0 +1,40 @@ +// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved. +// See LICENSE.txt for license information. + +import React from 'react'; +import {FlatList, StyleSheet} from 'react-native'; + +import ThreadsButton from '../threads'; + +import CategoryBody from './body'; +import CategoryHeader from './header'; + +type Props = { + categories: TempoCategory[]; +} + +const styles = StyleSheet.create({ + flex: { + flex: 1, + }, +}); + +const renderCategory = (data: {item: TempoCategory}) => ( + <> + + + +); + +const Categories = (props: Props) => { + return ( + + ); +}; + +export default Categories; diff --git a/app/components/channel_list/header/__snapshots__/index.test.tsx.snap b/app/components/channel_list/header/__snapshots__/index.test.tsx.snap new file mode 100644 index 000000000..f3f8451e0 --- /dev/null +++ b/app/components/channel_list/header/__snapshots__/index.test.tsx.snap @@ -0,0 +1,137 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`Channel List Header Component should match snapshot 1`] = ` + + + + + Hello World! + + + + + + + + + + + + + + + +`; diff --git a/app/components/channel_list/header/index.test.tsx b/app/components/channel_list/header/index.test.tsx new file mode 100644 index 000000000..35247b2cb --- /dev/null +++ b/app/components/channel_list/header/index.test.tsx @@ -0,0 +1,16 @@ +// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved. +// See LICENSE.txt for license information. + +import React from 'react'; + +import {renderWithIntlAndTheme} from '@test/intl-test-helper'; + +import Header from './index'; + +test('Channel List Header Component should match snapshot', () => { + const {toJSON} = renderWithIntlAndTheme( +
, + ); + + expect(toJSON()).toMatchSnapshot(); +}); diff --git a/app/components/channel_list/header/index.tsx b/app/components/channel_list/header/index.tsx new file mode 100644 index 000000000..f263bfae1 --- /dev/null +++ b/app/components/channel_list/header/index.tsx @@ -0,0 +1,89 @@ +// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved. +// See LICENSE.txt for license information. + +import React from 'react'; +import {Text, View} from 'react-native'; + +import CompassIcon from '@components/compass_icon'; +import TouchableWithFeedback from '@components/touchable_with_feedback'; +import {useTheme} from '@context/theme'; +import {changeOpacity, makeStyleSheetFromTheme} from '@utils/theme'; +import {typography} from '@utils/typography'; + +type Props = { + heading: string; + subheading?: string; + iconPad?: boolean; +} + +const getStyles = makeStyleSheetFromTheme((theme: Theme) => ({ + headingStyles: { + color: theme.sidebarText, + ...typography('Heading', 700), + }, + subHeadingStyles: { + color: changeOpacity(theme.sidebarText, 0.64), + ...typography('Heading', 50), + }, + iconPad: { + marginLeft: 44, + }, + headerRow: { + flexDirection: 'row', + alignItems: 'center', + justifyContent: 'space-between', + }, + chevronButton: { + marginLeft: 4, + }, + chevronIcon: { + color: changeOpacity(theme.sidebarText, 0.8), + fontSize: 24, + }, + plusButton: { + backgroundColor: changeOpacity(theme.sidebarText, 0.08), + height: 28, + width: 28, + borderRadius: 14, + justifyContent: 'center', + alignItems: 'center', + }, + plusIcon: { + color: changeOpacity(theme.sidebarText, 0.8), + fontSize: 18, + }, +})); + +const ChannelListHeader = (props: Props) => { + const theme = useTheme(); + const styles = getStyles(theme); + + return ( + + + + + {props.heading} + + + + + + + + + + + {props.subheading} + + + ); +}; + +export default ChannelListHeader; diff --git a/app/components/channel_list/index.test.tsx b/app/components/channel_list/index.test.tsx new file mode 100644 index 000000000..fa96d5b9a --- /dev/null +++ b/app/components/channel_list/index.test.tsx @@ -0,0 +1,16 @@ +// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved. +// See LICENSE.txt for license information. + +import React from 'react'; + +import {renderWithIntlAndTheme} from '@test/intl-test-helper'; + +import ChannelsList from './index'; + +test('Channels List should match snapshot', () => { + const {toJSON} = renderWithIntlAndTheme( + , + ); + + expect(toJSON()).toMatchSnapshot(); +}); diff --git a/app/components/channel_list/index.tsx b/app/components/channel_list/index.tsx new file mode 100644 index 000000000..77fe21c15 --- /dev/null +++ b/app/components/channel_list/index.tsx @@ -0,0 +1,79 @@ +// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved. +// See LICENSE.txt for license information. + +import React, {useState} from 'react'; +import {View} from 'react-native'; +import {TouchableOpacity} from 'react-native-gesture-handler'; + +import TABLET from '@constants/view'; +import {useTheme} from '@context/theme'; +import {useIsTablet} from '@hooks/device'; +import {makeStyleSheetFromTheme} from '@utils/theme'; + +import Categories from './categories'; +import ChannelListHeader from './header'; +import LoadingError from './loading_error'; +import SearchField from './search'; + +// import Loading from './loading'; + +const channels: TempoChannel[] = [ + {id: '1', name: 'Just a channel'}, + {id: '2', name: 'A Highlighted Channel!!!', highlight: true}, + {id: '3', name: 'And a longer channel name.'}, +]; + +const categories: TempoCategory[] = [ + {id: '1', title: 'My first Category', channels}, + {id: '2', title: 'Another Cat', channels}, +]; + +const getStyleSheet = makeStyleSheetFromTheme((theme: Theme) => ({ + container: { + flex: 1, + backgroundColor: theme.sidebarBg, + paddingHorizontal: 20, + paddingVertical: 10, + }, + maxW: { + maxWidth: TABLET.TABLET_SIDEBAR_WIDTH, + }, + +})); + +type ChannelListProps = { + iconPad?: boolean; +} + +const ChannelList = ({iconPad}: ChannelListProps) => { + const theme = useTheme(); + const styles = getStyleSheet(theme); + + // @to-do; remove after testing + const [showCats, setShowCats] = useState(true); + + const isTablet = useIsTablet(); + + return ( + + setShowCats(!showCats)}> + + + + {showCats && ( + <> + + + + )} + {/* */} + {!showCats && ()} + + ); +}; + +export default ChannelList; diff --git a/app/components/channel_list/loading/__snapshots__/index.test.tsx.snap b/app/components/channel_list/loading/__snapshots__/index.test.tsx.snap new file mode 100644 index 000000000..f36ef5870 --- /dev/null +++ b/app/components/channel_list/loading/__snapshots__/index.test.tsx.snap @@ -0,0 +1,58 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`Loading should match snapshot 1`] = ` + + + + + +`; diff --git a/app/components/channel_list/loading/index.test.tsx b/app/components/channel_list/loading/index.test.tsx new file mode 100644 index 000000000..b783cde84 --- /dev/null +++ b/app/components/channel_list/loading/index.test.tsx @@ -0,0 +1,16 @@ +// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved. +// See LICENSE.txt for license information. + +import React from 'react'; + +import {renderWithIntlAndTheme} from '@test/intl-test-helper'; + +import Loading from './index'; + +test('Loading should match snapshot', () => { + const {toJSON} = renderWithIntlAndTheme( + , + ); + + expect(toJSON()).toMatchSnapshot(); +}); diff --git a/app/components/channel_list/loading/index.tsx b/app/components/channel_list/loading/index.tsx new file mode 100644 index 000000000..67f7a68ab --- /dev/null +++ b/app/components/channel_list/loading/index.tsx @@ -0,0 +1,31 @@ +// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved. +// See LICENSE.txt for license information. + +import LottieView from 'lottie-react-native'; +import React from 'react'; +import {StyleSheet, View} from 'react-native'; + +const Loading = () => ( + + + +); + +const styles = StyleSheet.create({ + container: { + flex: 1, + justifyContent: 'center', + padding: 20, + maxHeight: 40, + }, + lottie: { + height: 32, + width: 32, + }, +}); + +export default Loading; diff --git a/app/components/channel_list/loading/spinner.json b/app/components/channel_list/loading/spinner.json new file mode 100644 index 000000000..8fa3774f2 --- /dev/null +++ b/app/components/channel_list/loading/spinner.json @@ -0,0 +1 @@ +{"v":"5.5.7","meta":{"g":"LottieFiles AE 0.1.20","a":"","k":"","d":"","tc":""},"fr":60,"ip":0,"op":40,"w":32,"h":32,"nm":"Spinner - white","ddd":0,"assets":[],"layers":[{"ddd":0,"ind":1,"ty":4,"nm":"Shape Layer 2","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":0,"s":[0]},{"t":40,"s":[360]}],"ix":10},"p":{"a":0,"k":[16,16,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[27,27],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"gs","o":{"a":0,"k":100,"ix":9},"w":{"a":0,"k":3,"ix":10},"g":{"p":3,"k":{"a":0,"k":[0.001,1,1,1,0.5,1,1,1,1,1,1,1,0,1,0.5,0.5,1,0],"ix":8}},"s":{"a":0,"k":[2.423,11.896],"ix":4},"e":{"a":0,"k":[1.431,-12.387],"ix":5},"t":1,"lc":1,"lj":1,"ml":4,"ml2":{"a":0,"k":4,"ix":13},"bm":0,"nm":"Gradient Stroke 1","mn":"ADBE Vector Graphic - G-Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0.05,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":1800,"st":0,"bm":0},{"ddd":0,"ind":2,"ty":4,"nm":"Shape Layer 1","parent":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[0,0,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"hasMask":true,"masksProperties":[{"inv":false,"mode":"a","pt":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[-15.95,-15.938],[-15.963,16],[-0.025,16],[-0.013,-15.938]],"c":true},"ix":1},"o":{"a":0,"k":100,"ix":3},"x":{"a":0,"k":0,"ix":4},"nm":"Mask 1"}],"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[27,27],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"st","c":{"a":0,"k":[1,1,1,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":3,"ix":5},"lc":1,"lj":1,"ml":4,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0.05,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":1800,"st":0,"bm":0}],"markers":[]} \ No newline at end of file diff --git a/app/components/channel_list/loading_error/__snapshots__/index.test.tsx.snap b/app/components/channel_list/loading_error/__snapshots__/index.test.tsx.snap new file mode 100644 index 000000000..a4e54968e --- /dev/null +++ b/app/components/channel_list/loading_error/__snapshots__/index.test.tsx.snap @@ -0,0 +1,151 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`Loading Error should match snapshot 1`] = ` + + + + + + Couldn’t load Staff + + + There was a problem loading the content for this team. + + + + + Retry + + + + +`; diff --git a/app/components/channel_list/loading_error/index.test.tsx b/app/components/channel_list/loading_error/index.test.tsx new file mode 100644 index 000000000..90dd1723f --- /dev/null +++ b/app/components/channel_list/loading_error/index.test.tsx @@ -0,0 +1,16 @@ +// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved. +// See LICENSE.txt for license information. + +import React from 'react'; + +import {renderWithIntlAndTheme} from '@test/intl-test-helper'; + +import ErrorComponent from './index'; + +test('Loading Error should match snapshot', () => { + const {toJSON} = renderWithIntlAndTheme( + , + ); + + expect(toJSON()).toMatchSnapshot(); +}); diff --git a/app/components/channel_list/loading_error/index.tsx b/app/components/channel_list/loading_error/index.tsx new file mode 100644 index 000000000..d928d4b8f --- /dev/null +++ b/app/components/channel_list/loading_error/index.tsx @@ -0,0 +1,70 @@ +// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved. +// See LICENSE.txt for license information. +import React from 'react'; +import {Text, View} from 'react-native'; + +import CompassIcon from '@components/compass_icon'; +import TouchableWithFeedback from '@components/touchable_with_feedback'; +import {useTheme} from '@context/theme'; +import {buttonBackgroundStyle, buttonTextStyle} from '@utils/buttonStyles'; +import {changeOpacity, makeStyleSheetFromTheme} from '@utils/theme'; +import {typography} from '@utils/typography'; + +const getStyleSheet = makeStyleSheetFromTheme((theme: Theme) => ({ + container: { + flex: 1, + alignItems: 'center', + justifyContent: 'center', + padding: 20, + }, + iconWrapper: { + height: 120, + width: 120, + backgroundColor: changeOpacity(theme.sidebarText, 0.08), + borderRadius: 60, + justifyContent: 'center', + alignItems: 'center', + }, + icon: { + fontSize: 72, + lineHeight: 72, + color: changeOpacity(theme.sidebarText, 0.48), + }, + header: { + color: theme.sidebarHeaderTextColor, + marginTop: 20, + textAlign: 'center', + }, + body: { + color: theme.sidebarText, + textAlign: 'center', + marginTop: 4, + }, +})); + +const LoadingError = () => { + const theme = useTheme(); + const styles = getStyleSheet(theme); + + return ( + + + + + + {'Couldn’t load Staff'} + + + {'There was a problem loading the content for this team.'} + + + {'Retry'} + + + ); +}; + +export default LoadingError; diff --git a/app/components/channel_list/search/__snapshots__/index.test.tsx.snap b/app/components/channel_list/search/__snapshots__/index.test.tsx.snap new file mode 100644 index 000000000..640e69691 --- /dev/null +++ b/app/components/channel_list/search/__snapshots__/index.test.tsx.snap @@ -0,0 +1,63 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`Search Field should match snapshot 1`] = ` + + + + +`; diff --git a/app/components/channel_list/search/index.test.tsx b/app/components/channel_list/search/index.test.tsx new file mode 100644 index 000000000..04c35e38e --- /dev/null +++ b/app/components/channel_list/search/index.test.tsx @@ -0,0 +1,16 @@ +// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved. +// See LICENSE.txt for license information. + +import React from 'react'; + +import {renderWithIntlAndTheme} from '@test/intl-test-helper'; + +import Search from './index'; + +test('Search Field should match snapshot', () => { + const {toJSON} = renderWithIntlAndTheme( + , + ); + + expect(toJSON()).toMatchSnapshot(); +}); diff --git a/app/components/channel_list/search/index.tsx b/app/components/channel_list/search/index.tsx new file mode 100644 index 000000000..698ed8907 --- /dev/null +++ b/app/components/channel_list/search/index.tsx @@ -0,0 +1,69 @@ +// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved. +// See LICENSE.txt for license information. + +import React from 'react'; +import {StyleSheet, View} from 'react-native'; +import {TextInput} from 'react-native-gesture-handler'; + +import CompassIcon from '@components/compass_icon'; +import {useTheme} from '@context/theme'; +import {changeOpacity, makeStyleSheetFromTheme} from '@utils/theme'; +import {typography} from '@utils/typography'; + +const getStyleSheet = makeStyleSheetFromTheme((theme: Theme) => ({ + container: { + flex: 1, + flexDirection: 'row', + justifyContent: 'flex-start', + alignItems: 'center', + width: '100%', + backgroundColor: changeOpacity(theme.sidebarText, 0.12), + borderRadius: 8, + padding: 8, + marginVertical: 20, + height: 40, + maxHeight: 40, + }, + icon: { + width: 24, + fontSize: 24, + color: changeOpacity(theme.sidebarText, 0.72), + }, + input: { + flex: 1, + height: 40, + color: theme.sidebarText, + alignItems: 'center', + alignContent: 'center', + marginLeft: 5, + marginTop: -2, + }, +})); + +const textStyles = StyleSheet.create([ + typography('Body', 200), + {textAlignVertical: 'center'}, +]); + +const SearchField = () => { + const theme = useTheme(); + const styles = getStyleSheet(theme); + + return ( + + + + + ); +}; + +export default SearchField; diff --git a/app/components/channel_list/tempo-types.d.ts b/app/components/channel_list/tempo-types.d.ts new file mode 100644 index 000000000..e0993d6c0 --- /dev/null +++ b/app/components/channel_list/tempo-types.d.ts @@ -0,0 +1,16 @@ +// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved. +// See LICENSE.txt for license information. + +// THIS IS TEMPORARY POC/MVP - WILL BE REMOVEd +// @to-do - Wire up actual models +type TempoChannel = { + id: string; + name: string; + highlight?: boolean; +}; + +type TempoCategory = { + id: string; + title: string; + channels: TempoChannel[]; +} diff --git a/app/components/channel_list/threads/__snapshots__/index.test.tsx.snap b/app/components/channel_list/threads/__snapshots__/index.test.tsx.snap new file mode 100644 index 000000000..cd2f561d2 --- /dev/null +++ b/app/components/channel_list/threads/__snapshots__/index.test.tsx.snap @@ -0,0 +1,70 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`Threads Component should match snapshot 1`] = ` + + + + + + Threads + + + + +`; diff --git a/app/components/channel_list/threads/index.test.tsx b/app/components/channel_list/threads/index.test.tsx new file mode 100644 index 000000000..daa5cf9fb --- /dev/null +++ b/app/components/channel_list/threads/index.test.tsx @@ -0,0 +1,16 @@ +// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved. +// See LICENSE.txt for license information. + +import React from 'react'; + +import {renderWithIntlAndTheme} from '@test/intl-test-helper'; + +import Threads from './index'; + +test('Threads Component should match snapshot', () => { + const {toJSON} = renderWithIntlAndTheme( + , + ); + + expect(toJSON()).toMatchSnapshot(); +}); diff --git a/app/components/channel_list/threads/index.tsx b/app/components/channel_list/threads/index.tsx new file mode 100644 index 000000000..17fca262e --- /dev/null +++ b/app/components/channel_list/threads/index.tsx @@ -0,0 +1,56 @@ +// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved. +// See LICENSE.txt for license information. + +import React from 'react'; +import {StyleSheet, Text, View} from 'react-native'; + +import CompassIcon from '@components/compass_icon'; +import TouchableWithFeedback from '@components/touchable_with_feedback'; +import {Screens} from '@constants'; +import {useTheme} from '@context/theme'; +import {goToScreen} from '@screens/navigation'; +import {makeStyleSheetFromTheme} from '@utils/theme'; +import {typography} from '@utils/typography'; + +const getStyleSheet = makeStyleSheetFromTheme((theme: Theme) => ({ + container: { + display: 'flex', + flexDirection: 'row', + }, + icon: { + fontSize: 24, + lineHeight: 28, + color: theme.sidebarText, + }, + text: { + color: theme.sidebarText, + paddingLeft: 12, + }, +})); + +const textStyle = StyleSheet.create([typography('Body', 200, 'SemiBold')]); + +const ThreadsButton = () => { + const theme = useTheme(); + const styles = getStyleSheet(theme); + + /* + * @to-do: + * - Check if there are threads, else return null + * - Change to button, navigate to threads view + * - Add right-side number badge + */ + return ( + goToScreen(Screens.CHANNEL, 'Channel', {}, {topBar: {visible: false}})} > + + + {'Threads'} + + + ); +}; + +export default ThreadsButton; diff --git a/app/components/compass_icon/index.tsx b/app/components/compass_icon/index.tsx index fe63c6a66..22139a372 100644 --- a/app/components/compass_icon/index.tsx +++ b/app/components/compass_icon/index.tsx @@ -5,4 +5,7 @@ import {createIconSetFromFontello} from 'react-native-vector-icons'; import fontelloConfig from '@assets/compass-icons.json'; -export default createIconSetFromFontello(fontelloConfig, 'compass-icons', 'compass-icons.ttf'); +const CompassIcon = createIconSetFromFontello(fontelloConfig, 'compass-icons', + 'compass-icons.ttf'); + +export default CompassIcon; diff --git a/app/components/team_sidebar/add_team/team_list.tsx b/app/components/team_sidebar/add_team/team_list.tsx index 583338c24..2c337e46b 100644 --- a/app/components/team_sidebar/add_team/team_list.tsx +++ b/app/components/team_sidebar/add_team/team_list.tsx @@ -5,9 +5,9 @@ import React from 'react'; import {ListRenderItemInfo, View} from 'react-native'; import {FlatList} from 'react-native-gesture-handler'; -import {makeStyleSheetFromTheme} from '@app/utils/theme'; import FormattedText from '@components/formatted_text'; import {useTheme} from '@context/theme'; +import {makeStyleSheetFromTheme} from '@utils/theme'; import TeamListItem from './team_list_item'; diff --git a/app/components/team_sidebar/index.ts b/app/components/team_sidebar/index.ts index d29c2ec79..023487ba2 100644 --- a/app/components/team_sidebar/index.ts +++ b/app/components/team_sidebar/index.ts @@ -7,9 +7,9 @@ import withObservables from '@nozbe/with-observables'; import {of as of$} from 'rxjs'; import {switchMap} from 'rxjs/operators'; -import {Permissions} from '@app/constants'; -import {hasPermission} from '@app/utils/role'; +import {Permissions} from '@constants'; import {MM_TABLES, SYSTEM_IDENTIFIERS} from '@constants/database'; +import {hasPermission} from '@utils/role'; import TeamSidebar from './team_sidebar'; diff --git a/app/components/team_sidebar/server_icon/server_icon.tsx b/app/components/team_sidebar/server_icon/server_icon.tsx deleted file mode 100644 index 013dd7c8e..000000000 --- a/app/components/team_sidebar/server_icon/server_icon.tsx +++ /dev/null @@ -1,38 +0,0 @@ -// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved. -// See LICENSE.txt for license information. - -import React from 'react'; -import {View} from 'react-native'; - -import CompassIcon from '@components/compass_icon'; -import {useTheme} from '@context/theme'; -import {changeOpacity, makeStyleSheetFromTheme} from '@utils/theme'; - -// TODO PLACEHOLDER -export default function ServerIcon() { - const theme = useTheme(); - const styles = getStyleSheet(theme); - return ( - - - - ); -} - -const getStyleSheet = makeStyleSheetFromTheme(() => { - return { - container: { - flex: 0, - borderRadius: 10, - height: 60, - width: '100%', - overflow: 'hidden', - alignItems: 'center', - justifyContent: 'center', - }, - }; -}); diff --git a/app/components/team_sidebar/team_sidebar.tsx b/app/components/team_sidebar/team_sidebar.tsx index 8d801dbf4..440925acd 100644 --- a/app/components/team_sidebar/team_sidebar.tsx +++ b/app/components/team_sidebar/team_sidebar.tsx @@ -11,7 +11,6 @@ import {useTheme} from '@context/theme'; import {makeStyleSheetFromTheme} from '@utils/theme'; import AddTeam from './add_team/add_team'; -import ServerIcon from './server_icon/server_icon'; import TeamList from './team_list'; import type TeamModel from '@typings/database/models/servers/team'; @@ -19,9 +18,10 @@ import type TeamModel from '@typings/database/models/servers/team'; type Props = { canCreateTeams: boolean; otherTeams: TeamModel[]; + iconPad?: boolean; } -export default function TeamSidebar({canCreateTeams, otherTeams}: Props) { +export default function TeamSidebar({canCreateTeams, otherTeams, iconPad}: Props) { const theme = useTheme(); const styles = getStyleSheet(theme); const serverUrl = useServerUrl(); @@ -34,8 +34,7 @@ export default function TeamSidebar({canCreateTeams, otherTeams}: Props) { return ( - - + {showAddTeam && ( { height: '100%', backgroundColor: theme.sidebarBg, display: 'flex', + paddingTop: 10, }, listContainer: { backgroundColor: theme.sidebarTeamBarBg, borderTopRightRadius: 12, flex: 1, }, + iconMargin: { + marginTop: 44, + paddingTop: 0, + }, }; }); diff --git a/app/init/push_notifications.ts b/app/init/push_notifications.ts index 7fd796c7b..ab48e7413 100644 --- a/app/init/push_notifications.ts +++ b/app/init/push_notifications.ts @@ -16,7 +16,6 @@ import { import {markChannelAsViewed} from '@actions/local/channel'; import {backgroundNotification, openNotification} from '@actions/remote/notifications'; -import EphemeralStore from '@app/store/ephemeral_store'; import {Device, Events, Navigation, Screens} from '@constants'; import {GLOBAL_IDENTIFIERS} from '@constants/database'; import DatabaseManager from '@database/manager'; @@ -25,6 +24,7 @@ import NativeNotifications from '@notifications'; import {queryServerName} from '@queries/app/servers'; import {queryCurrentChannelId} from '@queries/servers/system'; import {showOverlay} from '@screens/navigation'; +import EphemeralStore from '@store/ephemeral_store'; import {isTablet} from '@utils/helpers'; import {convertToNotificationData} from '@utils/notification'; diff --git a/app/init/websocket_manager.ts b/app/init/websocket_manager.ts index 5e5f59240..ffdc01a45 100644 --- a/app/init/websocket_manager.ts +++ b/app/init/websocket_manager.ts @@ -7,11 +7,11 @@ import {AppState, AppStateStatus} from 'react-native'; import {setCurrentUserStatusOffline} from '@actions/local/user'; import {fetchStatusByIds} from '@actions/remote/user'; import {handleClose, handleEvent, handleFirstConnect, handleReconnect} from '@actions/websocket'; -import WebSocketClient from '@app/client/websocket'; -import {General} from '@app/constants'; -import {queryCurrentUserId, resetWebSocketLastDisconnected} from '@app/queries/servers/system'; -import {queryAllUsers} from '@app/queries/servers/user'; +import WebSocketClient from '@client/websocket'; +import {General} from '@constants'; import DatabaseManager from '@database/manager'; +import {queryCurrentUserId, resetWebSocketLastDisconnected} from '@queries/servers/system'; +import {queryAllUsers} from '@queries/servers/user'; import type {ServerCredential} from '@typings/credentials'; diff --git a/app/screens/bottom_sheet/index.tsx b/app/screens/bottom_sheet/index.tsx index d55e84a1a..7af97bcc0 100644 --- a/app/screens/bottom_sheet/index.tsx +++ b/app/screens/bottom_sheet/index.tsx @@ -8,12 +8,12 @@ import {Navigation as RNN} from 'react-native-navigation'; import Animated from 'react-native-reanimated'; import RNBottomSheet from 'reanimated-bottom-sheet'; -import {changeOpacity, makeStyleSheetFromTheme} from '@app/utils/theme'; import {Navigation} from '@constants'; import {useTheme} from '@context/theme'; import {useIsTablet} from '@hooks/device'; import {dismissModal} from '@screens/navigation'; import {hapticFeedback} from '@utils/general'; +import {changeOpacity, makeStyleSheetFromTheme} from '@utils/theme'; import Indicator from './indicator'; diff --git a/app/screens/channel_list/index.tsx b/app/screens/channel_list/index.tsx deleted file mode 100644 index c58b73168..000000000 --- a/app/screens/channel_list/index.tsx +++ /dev/null @@ -1,48 +0,0 @@ -// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved. -// See LICENSE.txt for license information. - -import React from 'react'; -import {Text, View} from 'react-native'; - -import {makeStyleSheetFromTheme} from '@utils/theme'; - -type ChannelProps = { - theme: Theme; -} - -const ChannelList = ({theme}: ChannelProps) => { - const styles = getStyleSheet(theme); - - return ( - - {' Channel Screen '} - - ); -}; - -const getStyleSheet = makeStyleSheetFromTheme(() => ({ - container: { - flex: 1, - justifyContent: 'center', - alignItems: 'center', - backgroundColor: '#ffffff', - }, - tabContainer: { - position: 'absolute', - bottom: 0, - backgroundColor: '#ffffff', - }, - textContainer: { - marginTop: 30, - alignItems: 'center', - }, - screenTitle: { - fontSize: 30, - alignSelf: 'center', - }, -})); - -export default ChannelList; diff --git a/app/screens/emoji_picker/index.tsx b/app/screens/emoji_picker/index.tsx index 046ee1feb..64fb90f10 100644 --- a/app/screens/emoji_picker/index.tsx +++ b/app/screens/emoji_picker/index.tsx @@ -5,7 +5,7 @@ import React, {useCallback, useEffect} from 'react'; import {Keyboard} from 'react-native'; import {Navigation} from 'react-native-navigation'; -import EmojiPicker from '@app/components/emoji_picker'; +import EmojiPicker from '@components/emoji_picker'; import {dismissModal, setButtons} from '@screens/navigation'; type Props = { diff --git a/app/screens/home/account/components/options/user_presence/index.tsx b/app/screens/home/account/components/options/user_presence/index.tsx index 591405a26..619a11e20 100644 --- a/app/screens/home/account/components/options/user_presence/index.tsx +++ b/app/screens/home/account/components/options/user_presence/index.tsx @@ -6,13 +6,13 @@ import {useIntl} from 'react-intl'; import {DeviceEventEmitter, TextStyle} from 'react-native'; import {setStatus} from '@actions/remote/user'; -import {useServerUrl} from '@app/context/server_url'; import DrawerItem from '@components/drawer_item'; import SlideUpPanelItem, {ITEM_HEIGHT} from '@components/slide_up_panel_item'; import StatusLabel from '@components/status_label'; import UserStatusIndicator from '@components/user_status'; import {Navigation} from '@constants'; import General from '@constants/general'; +import {useServerUrl} from '@context/server_url'; import {bottomSheet, dismissModal} from '@screens/navigation'; import {preventDoubleTap} from '@utils/tap'; import {changeOpacity} from '@utils/theme'; diff --git a/app/screens/home/channel_list/index.tsx b/app/screens/home/channel_list/index.tsx index e6fc38528..4346879de 100644 --- a/app/screens/home/channel_list/index.tsx +++ b/app/screens/home/channel_list/index.tsx @@ -3,16 +3,16 @@ import {useIsFocused, useRoute} from '@react-navigation/native'; import React from 'react'; -import {Text, View} from 'react-native'; +import {View} from 'react-native'; import Animated, {useAnimatedStyle, withTiming} from 'react-native-reanimated'; import {SafeAreaView, useSafeAreaInsets} from 'react-native-safe-area-context'; +import ChannelList from '@components/channel_list'; import TeamSidebar from '@components/team_sidebar'; -import {View as ViewConstants} from '@constants'; import {useTheme} from '@context/theme'; import {useIsTablet} from '@hooks/device'; import Channel from '@screens/channel'; -import {goToScreen} from '@screens/navigation'; +import ServerIcon from '@screens/home/channel_list/server_icon/server_icon'; import {makeStyleSheetFromTheme} from '@utils/theme'; import type {LaunchProps} from '@typings/launch'; @@ -43,18 +43,13 @@ const getStyleSheet = makeStyleSheetFromTheme((theme: Theme) => ({ const ChannelListScreen = (props: ChannelProps) => { const theme = useTheme(); const styles = getStyleSheet(theme); + const isTablet = useIsTablet(); const route = useRoute(); const isFocused = useIsFocused(); const insets = useSafeAreaInsets(); const params = route.params as {direction: string}; - let tabletSidebarStyle; - if (isTablet) { - const {TABLET_SIDEBAR_WIDTH, TEAM_SIDEBAR_WIDTH} = ViewConstants; - tabletSidebarStyle = {maxWidth: (TABLET_SIDEBAR_WIDTH - TEAM_SIDEBAR_WIDTH)}; - } - const animated = useAnimatedStyle(() => { if (!isFocused) { let initial = 0; @@ -79,18 +74,15 @@ const ChannelListScreen = (props: ChannelProps) => { style={styles.content} edges={['bottom', 'left', 'right']} > + - - - goToScreen('Channel', '', undefined, {topBar: {visible: false}})} - style={{fontSize: 20, color: theme.centerChannelColor}} - > - {'Channel List'} - - + {/* @to-do: Server Icon requires padding in the team and channel components: + * https://mattermost.atlassian.net/browse/MM-39702 + */} + + {isTablet && } diff --git a/app/screens/home/channel_list/server_icon/__snapshots__/server_icon.test.tsx.snap b/app/screens/home/channel_list/server_icon/__snapshots__/server_icon.test.tsx.snap new file mode 100644 index 000000000..c3ca88edb --- /dev/null +++ b/app/screens/home/channel_list/server_icon/__snapshots__/server_icon.test.tsx.snap @@ -0,0 +1,26 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`Server Icon Component should match snapshot 1`] = ` + + + +`; diff --git a/app/screens/home/channel_list/server_icon/server_icon.test.tsx b/app/screens/home/channel_list/server_icon/server_icon.test.tsx new file mode 100644 index 000000000..20ee4f5f5 --- /dev/null +++ b/app/screens/home/channel_list/server_icon/server_icon.test.tsx @@ -0,0 +1,16 @@ +// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved. +// See LICENSE.txt for license information. + +import React from 'react'; + +import {renderWithIntlAndTheme} from '@test/intl-test-helper'; + +import Icon from './server_icon'; + +test('Server Icon Component should match snapshot', () => { + const {toJSON} = renderWithIntlAndTheme( + , + ); + + expect(toJSON()).toMatchSnapshot(); +}); diff --git a/app/screens/home/channel_list/server_icon/server_icon.tsx b/app/screens/home/channel_list/server_icon/server_icon.tsx new file mode 100644 index 000000000..ef65f12c7 --- /dev/null +++ b/app/screens/home/channel_list/server_icon/server_icon.tsx @@ -0,0 +1,39 @@ +// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved. +// See LICENSE.txt for license information. + +import React from 'react'; +import {StyleSheet, View} from 'react-native'; + +import CompassIcon from '@components/compass_icon'; +import {useTheme} from '@context/theme'; +import {changeOpacity} from '@utils/theme'; + +const styles = StyleSheet.create({ + icon: { + flex: 0, + overflow: 'hidden', + alignItems: 'center', + justifyContent: 'center', + position: 'absolute', + zIndex: 10, + top: 10, + left: 16, + width: 40, + height: 40, + }, +}); + +export default function ServerIcon() { + const theme = useTheme(); + + return ( + + + + ); +} + diff --git a/app/screens/server/form.tsx b/app/screens/server/form.tsx index 4b34fd119..bbb1aa267 100644 --- a/app/screens/server/form.tsx +++ b/app/screens/server/form.tsx @@ -7,8 +7,8 @@ import {ActivityIndicator, Platform, useWindowDimensions, View} from 'react-nati import Button from 'react-native-button'; import {KeyboardAwareScrollView} from 'react-native-keyboard-aware-scroll-view'; -import FormattedText from '@app/components/formatted_text'; import FloatingTextInput, {FloatingTextInputRef} from '@components/floating_text_input_label'; +import FormattedText from '@components/formatted_text'; import {useIsTablet} from '@hooks/device'; import {t} from '@i18n'; import {buttonBackgroundStyle, buttonTextStyle} from '@utils/buttonStyles'; diff --git a/app/screens/server/header.tsx b/app/screens/server/header.tsx index f27a44b13..7add7fee0 100644 --- a/app/screens/server/header.tsx +++ b/app/screens/server/header.tsx @@ -4,7 +4,7 @@ import React from 'react'; import {View} from 'react-native'; -import FormattedText from '@app/components/formatted_text'; +import FormattedText from '@components/formatted_text'; import {useIsTablet} from '@hooks/device'; import {changeOpacity, makeStyleSheetFromTheme} from '@utils/theme'; import {typography} from '@utils/typography'; diff --git a/app/utils/buttonStyles.ts b/app/utils/buttonStyles.ts index 21987691b..dd760a683 100644 --- a/app/utils/buttonStyles.ts +++ b/app/utils/buttonStyles.ts @@ -44,6 +44,7 @@ export const buttonBackgroundStyle = ( flex: 0, alignItems: 'center', justifyContent: 'center', + textAlignVertical: 'center', borderRadius: 4, }, fullWidth: { @@ -106,13 +107,13 @@ export const buttonBackgroundStyle = ( backgroundColor: changeOpacity(theme.centerChannelColor, 0.08), }, hover: { - backgroundColor: changeOpacity(theme.centerChannelColor, 0), + backgroundColor: changeOpacity(theme.centerChannelColor, 0.08), }, active: { - backgroundColor: changeOpacity(theme.centerChannelColor, 0), + backgroundColor: changeOpacity(theme.centerChannelColor, 0.08), }, focus: { - backgroundColor: changeOpacity(theme.centerChannelColor, 0), + backgroundColor: changeOpacity(theme.centerChannelColor, 0.08), }, }, }, @@ -392,6 +393,10 @@ export const buttonTextStyle = ( main: { fontFamily: 'OpenSans-SemiBold', fontWeight: '600', + textAlignVertical: 'center', + alignItems: 'center', + justifyContent: 'center', + padding: 1, }, underline: { textDecorationLine: 'underline', @@ -403,18 +408,22 @@ export const buttonTextStyle = ( fontSize: 11, lineHeight: 10, letterSpacing: 0.02, + marginTop: 2, }, s: { fontSize: 12, - lineHeight: 11, + lineHeight: 12, + marginTop: 1, }, m: { fontSize: 14, lineHeight: 14, + marginTop: 3, }, lg: { fontSize: 16, lineHeight: 18, + marginTop: 2, }, }); diff --git a/ios/Podfile.lock b/ios/Podfile.lock index c488bc66a..724673b56 100644 --- a/ios/Podfile.lock +++ b/ios/Podfile.lock @@ -40,9 +40,13 @@ PODS: - libwebp/webp (= 1.2.0) - libwebp/demux (1.2.0): - libwebp/webp - - libwebp/mux (1.2.0): + - libwebp/mux (1.2.1): - libwebp/demux - - libwebp/webp (1.2.0) + - libwebp/webp (1.2.1) + - lottie-ios (3.2.3) + - lottie-react-native (4.1.3): + - lottie-ios (~> 3.2.3) + - React-Core - Permission-Camera (3.1.0): - RNPermissions - Permission-PhotoLibrary (3.1.0): @@ -479,7 +483,7 @@ PODS: - React-jsi - XCDYouTubeKit (2.8.2) - Yoga (1.14.0) - - YoutubePlayer-in-WKWebView (0.3.5) + - YoutubePlayer-in-WKWebView (0.3.8) DEPENDENCIES: - boost (from `../node_modules/react-native/third-party-podspecs/boost.podspec`) @@ -494,6 +498,8 @@ DEPENDENCIES: - hermes-engine (~> 0.9.0) - jail-monkey (from `../node_modules/jail-monkey`) - libevent (~> 2.1.12) + - lottie-ios (from `../node_modules/lottie-ios`) + - lottie-react-native (from `../node_modules/lottie-react-native`) - Permission-Camera (from `../node_modules/react-native-permissions/ios/Camera`) - Permission-PhotoLibrary (from `../node_modules/react-native-permissions/ios/PhotoLibrary`) - RCT-Folly (from `../node_modules/react-native/third-party-podspecs/RCT-Folly.podspec`) @@ -609,6 +615,10 @@ EXTERNAL SOURCES: :podspec: "../node_modules/react-native/third-party-podspecs/glog.podspec" jail-monkey: :path: "../node_modules/jail-monkey" + lottie-ios: + :path: "../node_modules/lottie-ios" + lottie-react-native: + :path: "../node_modules/lottie-react-native" Permission-Camera: :path: "../node_modules/react-native-permissions/ios/Camera" Permission-PhotoLibrary: @@ -777,6 +787,8 @@ SPEC CHECKSUMS: jail-monkey: 07b83767601a373db876e939b8dbf3f5eb15f073 libevent: 4049cae6c81cdb3654a443be001fb9bdceff7913 libwebp: e90b9c01d99205d03b6bb8f2c8c415e5a4ef66f0 + lottie-ios: c058aeafa76daa4cf64d773554bccc8385d0150e + lottie-react-native: b561920bba7ec727ec94a473b683cffba00faece Permission-Camera: 0db4fd6e1c556c1cf47f38b989a8084cea3ec3dd Permission-PhotoLibrary: 9dcf80d1353d81b9f1e210c34291591236aaf2b6 RCT-Folly: a21c126816d8025b547704b777a2ba552f3d9fa9 @@ -856,7 +868,7 @@ SPEC CHECKSUMS: WatermelonDB: e043b1a32ddc63864eb539b562e86ef80f8224cd XCDYouTubeKit: 79baadb0560673a67c771eba45f83e353fd12c1f Yoga: 2b4a01651f42a32f82e6cef3830a3ba48088237f - YoutubePlayer-in-WKWebView: cfbf46da51d7370662a695a8f351e5fa1d3e1008 + YoutubePlayer-in-WKWebView: 4fca3b4f6f09940077bfbae7bddb771f2b43aacd PODFILE CHECKSUM: 7d223db07581157903686d5b376c1b697a056354 diff --git a/package-lock.json b/package-lock.json index 68c5cae36..97850b717 100644 --- a/package-lock.json +++ b/package-lock.json @@ -5,6 +5,7 @@ "requires": true, "packages": { "": { + "name": "mattermost-mobile", "version": "2.0.0", "hasInstallScript": true, "license": "Apache 2.0", @@ -41,6 +42,8 @@ "emoji-regex": "10.0.0", "fuse.js": "6.4.6", "jail-monkey": "2.6.0", + "lottie-ios": "3.2.3", + "lottie-react-native": "4.1.3", "mime-db": "1.50.0", "moment-timezone": "0.5.33", "prop-types": "15.7.2", @@ -15875,6 +15878,42 @@ "loose-envify": "cli.js" } }, + "node_modules/lottie-ios": { + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/lottie-ios/-/lottie-ios-3.2.3.tgz", + "integrity": "sha512-mubYMN6+1HXa8z3EJKBvNBkl4UoVM4McjESeB2PgvRMSngmJtC5yUMRdhbbrIAn5Liu3hFGao/14s5hQIgtkRQ==" + }, + "node_modules/lottie-react-native": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/lottie-react-native/-/lottie-react-native-4.1.3.tgz", + "integrity": "sha512-RgQrn1VYRXMV3YTZE9DgZy/UqNsMmZvzXBU4eEUWDOTY9cemOoWmCg2BHrL7nNtDJqtsu1Mi/6e8hp0yN2mcBA==", + "dependencies": { + "invariant": "^2.2.2", + "prop-types": "^15.5.10", + "react-native-safe-modules": "^1.0.3" + }, + "peerDependencies": { + "lottie-ios": "^3.2.3", + "react": "*", + "react-native": ">=0.46" + } + }, + "node_modules/lottie-react-native/node_modules/dedent": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/dedent/-/dedent-0.6.0.tgz", + "integrity": "sha1-Dm2o8M5Sg471zsXI+TlrDBtko8s=" + }, + "node_modules/lottie-react-native/node_modules/react-native-safe-modules": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/react-native-safe-modules/-/react-native-safe-modules-1.0.3.tgz", + "integrity": "sha512-DUxti4Z+AgJ/ZsO5U7p3uSCUBko8JT8GvFlCeOXk9bMd+4qjpoDvMYpfbixXKgL88M+HwmU/KI1YFN6gsQZyBA==", + "dependencies": { + "dedent": "^0.6.0" + }, + "peerDependencies": { + "react-native": "*" + } + }, "node_modules/lru-cache": { "version": "4.1.5", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.5.tgz", @@ -37342,6 +37381,36 @@ "js-tokens": "^3.0.0 || ^4.0.0" } }, + "lottie-ios": { + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/lottie-ios/-/lottie-ios-3.2.3.tgz", + "integrity": "sha512-mubYMN6+1HXa8z3EJKBvNBkl4UoVM4McjESeB2PgvRMSngmJtC5yUMRdhbbrIAn5Liu3hFGao/14s5hQIgtkRQ==" + }, + "lottie-react-native": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/lottie-react-native/-/lottie-react-native-4.1.3.tgz", + "integrity": "sha512-RgQrn1VYRXMV3YTZE9DgZy/UqNsMmZvzXBU4eEUWDOTY9cemOoWmCg2BHrL7nNtDJqtsu1Mi/6e8hp0yN2mcBA==", + "requires": { + "invariant": "^2.2.2", + "prop-types": "^15.5.10", + "react-native-safe-modules": "^1.0.3" + }, + "dependencies": { + "dedent": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/dedent/-/dedent-0.6.0.tgz", + "integrity": "sha1-Dm2o8M5Sg471zsXI+TlrDBtko8s=" + }, + "react-native-safe-modules": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/react-native-safe-modules/-/react-native-safe-modules-1.0.3.tgz", + "integrity": "sha512-DUxti4Z+AgJ/ZsO5U7p3uSCUBko8JT8GvFlCeOXk9bMd+4qjpoDvMYpfbixXKgL88M+HwmU/KI1YFN6gsQZyBA==", + "requires": { + "dedent": "^0.6.0" + } + } + } + }, "lru-cache": { "version": "4.1.5", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.5.tgz", diff --git a/package.json b/package.json index b184d49ae..0991ae262 100644 --- a/package.json +++ b/package.json @@ -39,6 +39,8 @@ "emoji-regex": "10.0.0", "fuse.js": "6.4.6", "jail-monkey": "2.6.0", + "lottie-ios": "3.2.3", + "lottie-react-native": "4.1.3", "mime-db": "1.50.0", "moment-timezone": "0.5.33", "prop-types": "15.7.2",