diff --git a/app/actions/local/thread.ts b/app/actions/local/thread.ts index 435203253..641db6ae4 100644 --- a/app/actions/local/thread.ts +++ b/app/actions/local/thread.ts @@ -1,14 +1,13 @@ // Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved. // See LICENSE.txt for license information. -import CompassIcon from '@components/compass_icon'; import {General, Screens} from '@constants'; import DatabaseManager from '@database/manager'; import {getTranslations, t} from '@i18n'; import {queryChannelById} from '@queries/servers/channel'; import {queryPostById} from '@queries/servers/post'; import {queryCurrentUser} from '@queries/servers/user'; -import {showModal} from '@screens/navigation'; +import {goToScreen} from '@screens/navigation'; import EphemeralStore from '@store/ephemeral_store'; import {changeOpacity} from '@utils/theme'; @@ -54,9 +53,7 @@ export const switchToThread = async (serverUrl: string, rootId: string) => { subtitle = subtitle.replace('{channelName}', channel.displayName); } - const closeButtonId = 'close-threads'; - - showModal(Screens.THREAD, '', {closeButtonId, rootId}, { + goToScreen(Screens.THREAD, '', {rootId}, { topBar: { title: { text: title, @@ -65,11 +62,6 @@ export const switchToThread = async (serverUrl: string, rootId: string) => { color: changeOpacity(theme.sidebarHeaderTextColor, 0.72), text: subtitle, }, - leftButtons: [{ - id: closeButtonId, - icon: CompassIcon.getImageSourceSync('close', 24, theme.centerChannelColor), - testID: closeButtonId, - }], }, }); return {}; diff --git a/app/components/channel_list/categories/body/category_body.tsx b/app/components/channel_list/categories/body/category_body.tsx index 605e16e09..38f3787a9 100644 --- a/app/components/channel_list/categories/body/category_body.tsx +++ b/app/components/channel_list/categories/body/category_body.tsx @@ -1,7 +1,7 @@ // Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved. // See LICENSE.txt for license information. -import React, {useCallback} from 'react'; +import React, {useCallback, useMemo} from 'react'; import {FlatList} from 'react-native'; import ChannelListItem from './channel'; @@ -12,11 +12,19 @@ type Props = { currentChannelId: string; sortedIds: string[]; category: CategoryModel; + limit: number; }; const extractKey = (item: string) => item; -const CategoryBody = ({currentChannelId, sortedIds, category}: Props) => { +const CategoryBody = ({currentChannelId, sortedIds, category, limit}: Props) => { + const ids = useMemo(() => { + if (category.type === 'direct_messages' && limit > 0) { + return sortedIds.slice(0, limit - 1); + } + return sortedIds; + }, [category.type, limit]); + const ChannelItem = useCallback(({item}: {item: string}) => { return ( { return ( & { isMuted: boolean; }; -const {SERVER: {MY_CHANNEL_SETTINGS}} = MM_TABLES; +const {SERVER: {MY_CHANNEL_SETTINGS, PREFERENCE}} = MM_TABLES; const sortAlpha = (locale: string, a: ChannelData, b: ChannelData) => { if (a.isMuted && !b.isMuted) { @@ -87,7 +88,27 @@ const enhance = withObservables(['category'], ({category, locale, database}: {ca switchMap((c) => getSortedIds(database, c, locale)), ); + let limit = of$(0); + if (category.type === 'direct_messages') { + limit = database.get(PREFERENCE). + query( + Q.where('category', Preferences.CATEGORY_SIDEBAR_SETTINGS), + Q.where('name', 'limit_visible_dms_gms'), + ).observe().pipe( + switchMap( + (val) => { + if (val[0]) { + return of$(parseInt(val[0].value, 10)); + } + + return of$(0); + }, + ), + ); + } + return { + limit, sortedIds, category: observedCategory, }; diff --git a/app/components/markdown/index.tsx b/app/components/markdown/index.tsx index 4487a8dce..0f7534124 100644 --- a/app/components/markdown/index.tsx +++ b/app/components/markdown/index.tsx @@ -134,6 +134,7 @@ class Markdown extends PureComponent { channelLink: this.renderChannelLink, emoji: this.renderEmoji, hashtag: this.renderHashtag, + latexinline: this.renderParagraph, paragraph: this.renderParagraph, heading: this.renderHeading, diff --git a/app/components/post_draft/draft_input/index.tsx b/app/components/post_draft/draft_input/index.tsx index 3a522829e..6e3625371 100644 --- a/app/components/post_draft/draft_input/index.tsx +++ b/app/components/post_draft/draft_input/index.tsx @@ -70,6 +70,7 @@ const getStyleSheet = makeStyleSheetFromTheme((theme) => { paddingBottom: 2, backgroundColor: theme.centerChannelBg, borderWidth: 1, + borderBottomWidth: 0, borderColor: changeOpacity(theme.centerChannelColor, 0.20), borderTopLeftRadius: 12, borderTopRightRadius: 12, diff --git a/app/components/post_draft/post_draft.tsx b/app/components/post_draft/post_draft.tsx index 6576e567b..7fec124b4 100644 --- a/app/components/post_draft/post_draft.tsx +++ b/app/components/post_draft/post_draft.tsx @@ -2,7 +2,7 @@ // See LICENSE.txt for license information. import React, {RefObject, useState} from 'react'; -import {Platform, useWindowDimensions, View} from 'react-native'; +import {Platform, View} from 'react-native'; import {KeyboardTrackingView, KeyboardTrackingViewRef} from 'react-native-keyboard-tracking-view'; import Autocomplete from '@components/autocomplete'; @@ -29,11 +29,7 @@ type Props = { keyboardTracker: RefObject; } -const { - KEYBOARD_TRACKING_OFFSET, - KEYBOARD_TRACKING_OFFSET_MODAL_LANDSCAPE, - KEYBOARD_TRACKING_OFFSET_MODAL_PORTRAIT, -} = ViewConstants; +const {KEYBOARD_TRACKING_OFFSET} = ViewConstants; function PostDraft({ testID, @@ -54,8 +50,6 @@ function PostDraft({ const [cursorPosition, setCursorPosition] = useState(message.length); const [postInputTop, setPostInputTop] = useState(0); const isTablet = useIsTablet(); - const dimensions = useWindowDimensions(); - const isLandscape = dimensions.width > dimensions.height; if (channelIsArchived || deactivatedChannel) { const archivedTestID = `${testID}.archived`; @@ -114,18 +108,13 @@ function PostDraft({ ); } - let viewInitialOffsetY = isTablet ? KEYBOARD_TRACKING_OFFSET : 0; - if (isTablet && rootId) { - viewInitialOffsetY = isLandscape ? KEYBOARD_TRACKING_OFFSET_MODAL_LANDSCAPE : KEYBOARD_TRACKING_OFFSET_MODAL_PORTRAIT; - } - return ( <> {draftHandler} diff --git a/app/constants/view.ts b/app/constants/view.ts index af96cef84..ff63c1912 100644 --- a/app/constants/view.ts +++ b/app/constants/view.ts @@ -22,8 +22,6 @@ export const IOS_HEADER_SEARCH_INSET = 20; export const TABLET_HEADER_SEARCH_INSET = 28; export const ANDROID_HEADER_SEARCH_INSET = 11; export const KEYBOARD_TRACKING_OFFSET = 72; -export const KEYBOARD_TRACKING_OFFSET_MODAL_LANDSCAPE = 44; -export const KEYBOARD_TRACKING_OFFSET_MODAL_PORTRAIT = 154; export const INDICATOR_BAR_HEIGHT = 38; @@ -48,7 +46,5 @@ export default { ANDROID_HEADER_SEARCH_INSET, INDICATOR_BAR_HEIGHT, KEYBOARD_TRACKING_OFFSET, - KEYBOARD_TRACKING_OFFSET_MODAL_LANDSCAPE, - KEYBOARD_TRACKING_OFFSET_MODAL_PORTRAIT, }; diff --git a/app/screens/thread/thread.tsx b/app/screens/thread/thread.tsx index 21b4aba79..9cf6e5d0e 100644 --- a/app/screens/thread/thread.tsx +++ b/app/screens/thread/thread.tsx @@ -1,24 +1,20 @@ // Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved. // See LICENSE.txt for license information. -import React, {useCallback, useEffect, useRef} from 'react'; -import {BackHandler, StyleSheet, View} from 'react-native'; +import React, {useRef} from 'react'; +import {StyleSheet, View} from 'react-native'; import {KeyboardTrackingViewRef} from 'react-native-keyboard-tracking-view'; -import {Navigation} from 'react-native-navigation'; import {Edge, SafeAreaView} from 'react-native-safe-area-context'; import PostDraft from '@components/post_draft'; import {THREAD_ACCESSORIES_CONTAINER_NATIVE_ID} from '@constants/post_draft'; import {useAppState} from '@hooks/device'; -import {dismissModal} from '@screens/navigation'; import ThreadPostList from './thread_post_list'; import type PostModel from '@typings/database/models/servers/post'; type ThreadProps = { - closeButtonId: string; - componentId: string; rootPost?: PostModel; }; @@ -30,39 +26,11 @@ const getStyleSheet = StyleSheet.create(() => ({ }, })); -const Thread = ({closeButtonId, componentId, rootPost}: ThreadProps) => { +const Thread = ({rootPost}: ThreadProps) => { const appState = useAppState(); const styles = getStyleSheet(); const postDraftRef = useRef(null); - const close = useCallback(() => { - dismissModal({componentId}); - return true; - }, []); - - useEffect(() => { - const unsubscribe = Navigation.events().registerComponentListener({ - navigationButtonPressed: ({buttonId}: { buttonId: string }) => { - switch (buttonId) { - case closeButtonId: - close(); - break; - } - }, - }, componentId); - - return () => { - unsubscribe.remove(); - }; - }, []); - - useEffect(() => { - const backHandler = BackHandler.addEventListener('hardwareBackPress', close); - return () => { - backHandler.remove(); - }; - }, []); - return ( <> ; currentTimezone: string | null; currentUsername: string; isTimezoneEnabled: boolean; @@ -26,11 +25,12 @@ type Props = { const edges: Edge[] = ['bottom']; const styles = StyleSheet.create({ + container: {marginTop: 20}, flex: {flex: 1}, }); const ThreadPostList = ({ - channelId, contentContainerStyle, currentTimezone, currentUsername, + channelId, currentTimezone, currentUsername, isTimezoneEnabled, lastViewedAt, nativeID, posts, rootPost, }: Props) => { const isTablet = useIsTablet(); @@ -42,7 +42,7 @@ const ThreadPostList = ({ const postList = ( { ++ const setButtonLayout = useCallback((e) => { + setNumberHeight(e.nativeEvent.layout.height); +- }; ++ }, []); + + React.useEffect(() => { + animations.map((animation, index) => { +@@ -139,12 +139,14 @@ const AnimatedNumber = ({ + })} + + )} ++ {numberHeight === 0 && + +- {0} ++ {animateToNumberString} + ++ } + + ); + }; diff --git a/tsconfig.json b/tsconfig.json index a58d0f314..352a3f125 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -53,7 +53,6 @@ "@share/*": ["share_extension/*"], "@store": ["app/store/index"], "@store/*": ["app/store/*"], - "@support/*": ["detox/e2e/support/*"], "@telemetry/*": ["/app/telemetry/*"], "@typings/*": ["types/*"], "@test/*": ["test/*"], @@ -65,12 +64,13 @@ ] } }, - "include": ["app/**/*", "share_extensionn/**/*", "test/**/*", "detox/**/*", "types/**/*"], + "include": ["app/**/*", "share_extensionn/**/*", "test/**/*", "types/**/*"], "exclude": [ "node_modules", "build", "babel.config.js", "metro.config.js", "jest.config.js", + "detox/**/*", ], }