forked from Ivasoft/mattermost-mobile
Merge branch 'gekidou' into CommandAutocomplete
This commit is contained in:
@@ -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 {};
|
||||
|
||||
@@ -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 (
|
||||
<ChannelListItem
|
||||
@@ -29,7 +37,7 @@ const CategoryBody = ({currentChannelId, sortedIds, category}: Props) => {
|
||||
|
||||
return (
|
||||
<FlatList
|
||||
data={sortedIds}
|
||||
data={ids}
|
||||
renderItem={ChannelItem}
|
||||
keyExtractor={extractKey}
|
||||
removeClippedSubviews={true}
|
||||
|
||||
@@ -8,7 +8,7 @@ import {combineLatest, of as of$} from 'rxjs';
|
||||
import {switchMap} from 'rxjs/operators';
|
||||
|
||||
import {MM_TABLES} from '@app/constants/database';
|
||||
import {General} from '@constants';
|
||||
import {General, Preferences} from '@constants';
|
||||
import {WithDatabaseArgs} from '@typings/database/database';
|
||||
|
||||
import CategoryBody from './category_body';
|
||||
@@ -16,12 +16,13 @@ import CategoryBody from './category_body';
|
||||
import type CategoryModel from '@typings/database/models/servers/category';
|
||||
import type ChannelModel from '@typings/database/models/servers/channel';
|
||||
import type MyChannelSettingsModel from '@typings/database/models/servers/my_channel_settings';
|
||||
import type PreferenceModel from '@typings/database/models/servers/preference';
|
||||
|
||||
type ChannelData = Pick<ChannelModel, 'id' | 'displayName'> & {
|
||||
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<PreferenceModel>(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,
|
||||
};
|
||||
|
||||
@@ -134,6 +134,7 @@ class Markdown extends PureComponent<MarkdownProps> {
|
||||
channelLink: this.renderChannelLink,
|
||||
emoji: this.renderEmoji,
|
||||
hashtag: this.renderHashtag,
|
||||
latexinline: this.renderParagraph,
|
||||
|
||||
paragraph: this.renderParagraph,
|
||||
heading: this.renderHeading,
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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<KeyboardTrackingViewRef>;
|
||||
}
|
||||
|
||||
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 (
|
||||
<>
|
||||
<KeyboardTrackingView
|
||||
accessoriesContainerID={accessoriesContainerID}
|
||||
ref={keyboardTracker}
|
||||
scrollViewNativeID={scrollViewNativeID}
|
||||
viewInitialOffsetY={viewInitialOffsetY}
|
||||
viewInitialOffsetY={isTablet && !rootId ? KEYBOARD_TRACKING_OFFSET : 0}
|
||||
>
|
||||
{draftHandler}
|
||||
</KeyboardTrackingView>
|
||||
|
||||
@@ -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,
|
||||
};
|
||||
|
||||
|
||||
@@ -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<KeyboardTrackingViewRef>(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 (
|
||||
<>
|
||||
<SafeAreaView
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
import React, {useMemo} from 'react';
|
||||
import {StyleProp, StyleSheet, ViewStyle} from 'react-native';
|
||||
import {StyleSheet} from 'react-native';
|
||||
import {Edge, SafeAreaView} from 'react-native-safe-area-context';
|
||||
|
||||
import PostList from '@components/post_list';
|
||||
@@ -13,7 +13,6 @@ import type PostModel from '@typings/database/models/servers/post';
|
||||
|
||||
type Props = {
|
||||
channelId: string;
|
||||
contentContainerStyle?: StyleProp<ViewStyle>;
|
||||
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 = (
|
||||
<PostList
|
||||
channelId={channelId}
|
||||
contentContainerStyle={contentContainerStyle}
|
||||
contentContainerStyle={styles.container}
|
||||
currentTimezone={currentTimezone}
|
||||
currentUsername={currentUsername}
|
||||
isTimezoneEnabled={isTimezoneEnabled}
|
||||
|
||||
39
patches/react-native-animated-numbers+0.4.1.patch
Normal file
39
patches/react-native-animated-numbers+0.4.1.patch
Normal file
@@ -0,0 +1,39 @@
|
||||
diff --git a/node_modules/react-native-animated-numbers/index.js b/node_modules/react-native-animated-numbers/index.js
|
||||
index f624b91..af39f58 100644
|
||||
--- a/node_modules/react-native-animated-numbers/index.js
|
||||
+++ b/node_modules/react-native-animated-numbers/index.js
|
||||
@@ -1,4 +1,4 @@
|
||||
-import React from 'react';
|
||||
+import React, { useCallback } from 'react';
|
||||
import { Text, View } from 'react-native';
|
||||
import Animated, { EasingNode } from 'react-native-reanimated';
|
||||
|
||||
@@ -71,9 +71,9 @@ const AnimatedNumber = ({
|
||||
return new Animated.Value(animationHeight);
|
||||
});
|
||||
|
||||
- const setButtonLayout = (e) => {
|
||||
+ const setButtonLayout = useCallback((e) => {
|
||||
setNumberHeight(e.nativeEvent.layout.height);
|
||||
- };
|
||||
+ }, []);
|
||||
|
||||
React.useEffect(() => {
|
||||
animations.map((animation, index) => {
|
||||
@@ -139,12 +139,14 @@ const AnimatedNumber = ({
|
||||
})}
|
||||
</View>
|
||||
)}
|
||||
+ {numberHeight === 0 &&
|
||||
<Text
|
||||
- style={[fontStyle, { position: 'absolute', top: -999999 }]}
|
||||
+ style={[fontStyle]}
|
||||
onLayout={setButtonLayout}
|
||||
>
|
||||
- {0}
|
||||
+ {animateToNumberString}
|
||||
</Text>
|
||||
+ }
|
||||
</>
|
||||
);
|
||||
};
|
||||
@@ -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/**/*",
|
||||
],
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user