Chore: Evaluate ThreadMessagesView - TypeScript (#4084)
This commit is contained in:
parent
55d66c85db
commit
abbb97cd84
|
@ -1,8 +1,7 @@
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { StyleSheet, Text, View } from 'react-native';
|
import { StyleSheet, Text, View } from 'react-native';
|
||||||
|
|
||||||
import { themes } from '../../../lib/constants';
|
import { useTheme } from '../../../theme';
|
||||||
import { TSupportedThemes, withTheme } from '../../../theme';
|
|
||||||
import Touch from '../../../utils/touch';
|
import Touch from '../../../utils/touch';
|
||||||
import { CustomIcon, TIconsName } from '../../../containers/CustomIcon';
|
import { CustomIcon, TIconsName } from '../../../containers/CustomIcon';
|
||||||
import sharedStyles from '../../Styles';
|
import sharedStyles from '../../Styles';
|
||||||
|
@ -25,17 +24,19 @@ const styles = StyleSheet.create({
|
||||||
interface IDropdownItem {
|
interface IDropdownItem {
|
||||||
text: string;
|
text: string;
|
||||||
iconName: TIconsName | null;
|
iconName: TIconsName | null;
|
||||||
theme?: TSupportedThemes;
|
|
||||||
onPress: () => void;
|
onPress: () => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
const DropdownItem = React.memo(({ theme, onPress, iconName, text }: IDropdownItem) => (
|
const DropdownItem = React.memo(({ onPress, iconName, text }: IDropdownItem) => {
|
||||||
<Touch theme={theme!} onPress={onPress} style={{ backgroundColor: themes[theme!].backgroundColor }}>
|
const { colors, theme } = useTheme();
|
||||||
<View style={styles.container}>
|
return (
|
||||||
<Text style={[styles.text, { color: themes[theme!].auxiliaryText }]}>{text}</Text>
|
<Touch theme={theme} onPress={onPress} style={{ backgroundColor: colors.backgroundColor }}>
|
||||||
{iconName ? <CustomIcon name={iconName} size={22} color={themes[theme!].auxiliaryText} /> : null}
|
<View style={styles.container}>
|
||||||
</View>
|
<Text style={[styles.text, { color: colors.auxiliaryText }]}>{text}</Text>
|
||||||
</Touch>
|
{iconName ? <CustomIcon name={iconName} size={22} color={colors.auxiliaryText} /> : null}
|
||||||
));
|
</View>
|
||||||
|
</Touch>
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
export default withTheme(DropdownItem);
|
export default DropdownItem;
|
||||||
|
|
|
@ -15,7 +15,7 @@ const ANIMATION_DURATION = 200;
|
||||||
|
|
||||||
interface IDropdownProps {
|
interface IDropdownProps {
|
||||||
isMasterDetail?: boolean;
|
isMasterDetail?: boolean;
|
||||||
theme?: TSupportedThemes;
|
theme: TSupportedThemes;
|
||||||
insets?: EdgeInsets;
|
insets?: EdgeInsets;
|
||||||
currentFilter: Filter;
|
currentFilter: Filter;
|
||||||
onClose: () => void;
|
onClose: () => void;
|
||||||
|
@ -59,7 +59,7 @@ class Dropdown extends React.Component<IDropdownProps> {
|
||||||
});
|
});
|
||||||
const backdropOpacity = this.animatedValue.interpolate({
|
const backdropOpacity = this.animatedValue.interpolate({
|
||||||
inputRange: [0, 1],
|
inputRange: [0, 1],
|
||||||
outputRange: [0, themes[theme!].backdropOpacity]
|
outputRange: [0, themes[theme].backdropOpacity]
|
||||||
});
|
});
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
|
@ -68,7 +68,7 @@ class Dropdown extends React.Component<IDropdownProps> {
|
||||||
style={[
|
style={[
|
||||||
styles.backdrop,
|
styles.backdrop,
|
||||||
{
|
{
|
||||||
backgroundColor: themes[theme!].backdropColor,
|
backgroundColor: themes[theme].backdropColor,
|
||||||
opacity: backdropOpacity,
|
opacity: backdropOpacity,
|
||||||
top: heightDestination
|
top: heightDestination
|
||||||
}
|
}
|
||||||
|
@ -80,8 +80,8 @@ class Dropdown extends React.Component<IDropdownProps> {
|
||||||
styles.dropdownContainer,
|
styles.dropdownContainer,
|
||||||
{
|
{
|
||||||
transform: [{ translateY }],
|
transform: [{ translateY }],
|
||||||
backgroundColor: themes[theme!].backgroundColor,
|
backgroundColor: themes[theme].backgroundColor,
|
||||||
borderColor: themes[theme!].separatorColor
|
borderColor: themes[theme].separatorColor
|
||||||
}
|
}
|
||||||
]}>
|
]}>
|
||||||
<DropdownItemHeader currentFilter={currentFilter} onPress={this.close} />
|
<DropdownItemHeader currentFilter={currentFilter} onPress={this.close} />
|
||||||
|
|
|
@ -9,7 +9,7 @@ import { themes } from '../../lib/constants';
|
||||||
import { MarkdownPreview } from '../../containers/markdown';
|
import { MarkdownPreview } from '../../containers/markdown';
|
||||||
import { formatDateThreads, makeThreadName } from '../../utils/room';
|
import { formatDateThreads, makeThreadName } from '../../utils/room';
|
||||||
import ThreadDetails from '../../containers/ThreadDetails';
|
import ThreadDetails from '../../containers/ThreadDetails';
|
||||||
import { TThreadModel } from '../../definitions/IThread';
|
import { TThreadModel } from '../../definitions';
|
||||||
|
|
||||||
const styles = StyleSheet.create({
|
const styles = StyleSheet.create({
|
||||||
container: {
|
container: {
|
||||||
|
@ -59,7 +59,7 @@ const styles = StyleSheet.create({
|
||||||
interface IItem {
|
interface IItem {
|
||||||
item: TThreadModel;
|
item: TThreadModel;
|
||||||
useRealName: boolean;
|
useRealName: boolean;
|
||||||
user: any;
|
user: { id: string };
|
||||||
badgeColor?: string;
|
badgeColor?: string;
|
||||||
onPress: (item: TThreadModel) => void;
|
onPress: (item: TThreadModel) => void;
|
||||||
toggleFollowThread: (isFollowing: boolean, id: string) => void;
|
toggleFollowThread: (isFollowing: boolean, id: string) => void;
|
||||||
|
|
|
@ -4,8 +4,7 @@ import { connect } from 'react-redux';
|
||||||
import { Q } from '@nozbe/watermelondb';
|
import { Q } from '@nozbe/watermelondb';
|
||||||
import { sanitizedRaw } from '@nozbe/watermelondb/RawRecord';
|
import { sanitizedRaw } from '@nozbe/watermelondb/RawRecord';
|
||||||
import { EdgeInsets, withSafeAreaInsets } from 'react-native-safe-area-context';
|
import { EdgeInsets, withSafeAreaInsets } from 'react-native-safe-area-context';
|
||||||
import { HeaderBackButton, StackNavigationOptions, StackNavigationProp } from '@react-navigation/stack';
|
import { HeaderBackButton, StackNavigationOptions } from '@react-navigation/stack';
|
||||||
import { RouteProp } from '@react-navigation/native';
|
|
||||||
import { Observable, Subscription } from 'rxjs';
|
import { Observable, Subscription } from 'rxjs';
|
||||||
|
|
||||||
import ActivityIndicator from '../../containers/ActivityIndicator';
|
import ActivityIndicator from '../../containers/ActivityIndicator';
|
||||||
|
@ -36,20 +35,12 @@ import DropdownItemHeader from './Dropdown/DropdownItemHeader';
|
||||||
import Dropdown from './Dropdown';
|
import Dropdown from './Dropdown';
|
||||||
import Item from './Item';
|
import Item from './Item';
|
||||||
import styles from './styles';
|
import styles from './styles';
|
||||||
import { IMessage, SubscriptionType, TSubscriptionModel, TThreadModel } from '../../definitions';
|
import { IApplicationState, IBaseScreen, IMessage, SubscriptionType, TSubscriptionModel, TThreadModel } from '../../definitions';
|
||||||
import { getUidDirectMessage } from '../../lib/methods';
|
import { getUidDirectMessage } from '../../lib/methods';
|
||||||
import { Services } from '../../lib/services';
|
import { Services } from '../../lib/services';
|
||||||
|
|
||||||
const API_FETCH_COUNT = 50;
|
const API_FETCH_COUNT = 50;
|
||||||
|
|
||||||
// interface IResultFetch {
|
|
||||||
// threads: IThreadResult[];
|
|
||||||
// count: number;
|
|
||||||
// offset: number;
|
|
||||||
// total: number;
|
|
||||||
// success: boolean;
|
|
||||||
// }
|
|
||||||
|
|
||||||
interface IThreadMessagesViewState {
|
interface IThreadMessagesViewState {
|
||||||
loading: boolean;
|
loading: boolean;
|
||||||
end: boolean;
|
end: boolean;
|
||||||
|
@ -62,10 +53,8 @@ interface IThreadMessagesViewState {
|
||||||
searchText: string;
|
searchText: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface IThreadMessagesViewProps {
|
interface IThreadMessagesViewProps extends IBaseScreen<ChatsStackParamList, 'ThreadMessagesView'> {
|
||||||
navigation: StackNavigationProp<ChatsStackParamList, 'ThreadMessagesView'>;
|
user: { id: string };
|
||||||
route: RouteProp<ChatsStackParamList, 'ThreadMessagesView'>;
|
|
||||||
user: any;
|
|
||||||
baseUrl: string;
|
baseUrl: string;
|
||||||
useRealName: boolean;
|
useRealName: boolean;
|
||||||
theme: TSupportedThemes;
|
theme: TSupportedThemes;
|
||||||
|
@ -80,7 +69,7 @@ class ThreadMessagesView extends React.Component<IThreadMessagesViewProps, IThre
|
||||||
|
|
||||||
private t: string;
|
private t: string;
|
||||||
|
|
||||||
private subSubscription: any;
|
private subSubscription?: Subscription;
|
||||||
|
|
||||||
private messagesSubscription?: Subscription;
|
private messagesSubscription?: Subscription;
|
||||||
|
|
||||||
|
@ -274,9 +263,9 @@ class ThreadMessagesView extends React.Component<IThreadMessagesViewProps, IThre
|
||||||
const db = database.active;
|
const db = database.active;
|
||||||
const threadsCollection = db.get('threads');
|
const threadsCollection = db.get('threads');
|
||||||
const allThreadsRecords = await subscription.threads.fetch();
|
const allThreadsRecords = await subscription.threads.fetch();
|
||||||
let threadsToCreate: any[] = [];
|
let threadsToCreate: TThreadModel[] = [];
|
||||||
let threadsToUpdate: any[] = [];
|
let threadsToUpdate: (TThreadModel | null | undefined)[] = [];
|
||||||
let threadsToDelete: any[] = [];
|
let threadsToDelete: TThreadModel[] = [];
|
||||||
|
|
||||||
if (remove && remove.length) {
|
if (remove && remove.length) {
|
||||||
threadsToDelete = allThreadsRecords.filter((i1: { id: string }) => remove.find(i2 => i1.id === i2._id));
|
threadsToDelete = allThreadsRecords.filter((i1: { id: string }) => remove.find(i2 => i1.id === i2._id));
|
||||||
|
@ -286,7 +275,9 @@ class ThreadMessagesView extends React.Component<IThreadMessagesViewProps, IThre
|
||||||
if (update && update.length) {
|
if (update && update.length) {
|
||||||
update = update.map(m => buildMessage(m)) as IMessage[];
|
update = update.map(m => buildMessage(m)) as IMessage[];
|
||||||
// filter threads
|
// filter threads
|
||||||
threadsToCreate = update.filter(i1 => !allThreadsRecords.find((i2: { id: string }) => i1._id === i2.id));
|
threadsToCreate = update.filter(
|
||||||
|
i1 => !allThreadsRecords.find((i2: { id: string }) => i1._id === i2.id)
|
||||||
|
) as TThreadModel[];
|
||||||
threadsToUpdate = allThreadsRecords.filter((i1: { id: string }) => update.find(i2 => i1.id === i2._id));
|
threadsToUpdate = allThreadsRecords.filter((i1: { id: string }) => update.find(i2 => i1.id === i2._id));
|
||||||
threadsToCreate = threadsToCreate.map(thread =>
|
threadsToCreate = threadsToCreate.map(thread =>
|
||||||
threadsCollection.prepareCreate(
|
threadsCollection.prepareCreate(
|
||||||
|
@ -298,10 +289,10 @@ class ThreadMessagesView extends React.Component<IThreadMessagesViewProps, IThre
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
threadsToUpdate = threadsToUpdate.map(thread => {
|
threadsToUpdate = threadsToUpdate.map(thread => {
|
||||||
const newThread = update.find(t => t._id === thread.id);
|
const newThread = update.find(t => t._id === thread?.id);
|
||||||
try {
|
try {
|
||||||
return thread.prepareUpdate(
|
return thread?.prepareUpdate(
|
||||||
protectedFunction((t: any) => {
|
protectedFunction((t: TThreadModel) => {
|
||||||
Object.assign(t, newThread);
|
Object.assign(t, newThread);
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
|
@ -316,7 +307,7 @@ class ThreadMessagesView extends React.Component<IThreadMessagesViewProps, IThre
|
||||||
...threadsToCreate,
|
...threadsToCreate,
|
||||||
...threadsToUpdate,
|
...threadsToUpdate,
|
||||||
...threadsToDelete,
|
...threadsToDelete,
|
||||||
subscription.prepareUpdate((s: any) => {
|
subscription.prepareUpdate(s => {
|
||||||
s.lastThreadSync = lastThreadSync;
|
s.lastThreadSync = lastThreadSync;
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
|
@ -421,7 +412,6 @@ class ThreadMessagesView extends React.Component<IThreadMessagesViewProps, IThre
|
||||||
|
|
||||||
// helper to query threads
|
// helper to query threads
|
||||||
getFilteredThreads = (messages: TThreadModel[], subscription?: TSubscriptionModel, currentFilter?: Filter): TThreadModel[] => {
|
getFilteredThreads = (messages: TThreadModel[], subscription?: TSubscriptionModel, currentFilter?: Filter): TThreadModel[] => {
|
||||||
// const { currentFilter } = this.state;
|
|
||||||
const { user } = this.props;
|
const { user } = this.props;
|
||||||
if (currentFilter === Filter.Following) {
|
if (currentFilter === Filter.Following) {
|
||||||
return messages?.filter(item => item?.replies?.find(u => u === user.id));
|
return messages?.filter(item => item?.replies?.find(u => u === user.id));
|
||||||
|
@ -534,23 +524,29 @@ class ThreadMessagesView extends React.Component<IThreadMessagesViewProps, IThre
|
||||||
render() {
|
render() {
|
||||||
console.count(`${this.constructor.name}.render calls`);
|
console.count(`${this.constructor.name}.render calls`);
|
||||||
const { showFilterDropdown, currentFilter } = this.state;
|
const { showFilterDropdown, currentFilter } = this.state;
|
||||||
|
const { theme } = this.props;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<SafeAreaView testID='thread-messages-view'>
|
<SafeAreaView testID='thread-messages-view'>
|
||||||
<StatusBar />
|
<StatusBar />
|
||||||
{this.renderContent()}
|
{this.renderContent()}
|
||||||
{showFilterDropdown ? (
|
{showFilterDropdown ? (
|
||||||
<Dropdown currentFilter={currentFilter} onFilterSelected={this.onFilterSelected} onClose={this.closeFilterDropdown} />
|
<Dropdown
|
||||||
|
currentFilter={currentFilter}
|
||||||
|
onFilterSelected={this.onFilterSelected}
|
||||||
|
onClose={this.closeFilterDropdown}
|
||||||
|
theme={theme}
|
||||||
|
/>
|
||||||
) : null}
|
) : null}
|
||||||
</SafeAreaView>
|
</SafeAreaView>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const mapStateToProps = (state: any) => ({
|
const mapStateToProps = (state: IApplicationState) => ({
|
||||||
baseUrl: state.server.server,
|
baseUrl: state.server.server,
|
||||||
user: getUserSelector(state),
|
user: getUserSelector(state),
|
||||||
useRealName: state.settings.UI_Use_Real_Name,
|
useRealName: state.settings.UI_Use_Real_Name as boolean,
|
||||||
isMasterDetail: state.app.isMasterDetail
|
isMasterDetail: state.app.isMasterDetail
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue