Skip to content

Commit

Permalink
chore: created useThreadFilter and useThreadSearch
Browse files Browse the repository at this point in the history
  • Loading branch information
OtavioStasiak committed Oct 21, 2024
1 parent 6ef34b5 commit 1de16de
Show file tree
Hide file tree
Showing 6 changed files with 269 additions and 171 deletions.
Original file line number Diff line number Diff line change
@@ -1,26 +1,16 @@
import React from "react";

import { Filter } from "./filters";
import { IBaseScreen, TSubscriptionModel, TThreadModel } from "../../definitions";
import { ChatsStackParamList } from "../../stacks/types";
import { TSupportedThemes } from "../../theme";


export type TSearchThreadMessages = {
export interface ISearchThreadMessages {
isSearching: boolean;
searchText: string;
};

export type TUseThreadMessagesProps = {
rid: string;
getFilteredThreads: (messages: TThreadModel[], subscription?: TSubscriptionModel, currentFilter?: Filter) => TThreadModel[];
search: TSearchThreadMessages;
currentFilter: Filter;
initFilter: () => void;
viewName: string;
};

export type TUSeThreadMessages = {
export interface IUSeThreadMessages {
subscription: TSubscriptionModel;
messages: TThreadModel[];
displayingThreads: TThreadModel[];
Expand All @@ -36,7 +26,7 @@ export type TUSeThreadMessages = {
}) => void;
};

export type IThreadMessagesViewProps = IBaseScreen<ChatsStackParamList, 'ThreadMessagesView'> & {
export interface IThreadMessagesViewProps extends IBaseScreen<ChatsStackParamList, 'ThreadMessagesView'> {
user: { id: string };
baseUrl: string;
useRealName: boolean;
Expand All @@ -45,4 +35,3 @@ export type IThreadMessagesViewProps = IBaseScreen<ChatsStackParamList, 'ThreadM
};



76 changes: 76 additions & 0 deletions app/views/ThreadMessagesView/hooks/useThreadFilter.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
import { useCallback } from 'react';
import I18n from 'i18n-js';

import { Filter } from '../filters';
import UserPreferences from '../../../lib/methods/userPreferences';
import { showActionSheetRef } from '../../../containers/ActionSheet';
import { CustomIcon } from '../../../containers/CustomIcon';
import { IUser, TSubscriptionModel, TThreadModel } from '../../../definitions';
import getFilteredThreads from '../utils/helper';

const THREADS_FILTER = 'threadsFilter';

interface IUseThreadFilter {
user: IUser;
messages: TThreadModel[];
subscription: TSubscriptionModel;
currentFilter: Filter;
setCurrentFilter: (filter: Filter) => void;
setDisplayingThreads: (threads: TThreadModel[]) => void;
}

const useThreadFilter = ({
user,
messages,
subscription,
currentFilter,
setCurrentFilter,
setDisplayingThreads
}: IUseThreadFilter) => {
const initFilter = () => {
const savedFilter = UserPreferences.getString(THREADS_FILTER);
if (savedFilter) {
setCurrentFilter(savedFilter as Filter);
}
};

const onFilterSelected = useCallback(
(filter: Filter) => {
const displayingThreads = getFilteredThreads(user, messages, subscription, filter);
setCurrentFilter(filter);
setDisplayingThreads(displayingThreads);
UserPreferences.setString(THREADS_FILTER, filter);
},
[messages, subscription]
);

const showFilters = () => {
showActionSheetRef({
options: [
{
title: I18n.t(Filter.All),
right: currentFilter === Filter.All ? () => <CustomIcon name='check' size={24} /> : undefined,
onPress: () => onFilterSelected(Filter.All)
},
{
title: I18n.t(Filter.Following),
right: currentFilter === Filter.Following ? () => <CustomIcon name='check' size={24} /> : undefined,
onPress: () => onFilterSelected(Filter.Following)
},
{
title: I18n.t(Filter.Unread),
right: currentFilter === Filter.Unread ? () => <CustomIcon name='check' size={24} /> : undefined,
onPress: () => onFilterSelected(Filter.Unread)
}
]
});
};

return {
currentFilter,
initFilter,
showFilters
};
};

export default useThreadFilter;
50 changes: 27 additions & 23 deletions app/views/ThreadMessagesView/hooks/useThreadMessages.tsx
Original file line number Diff line number Diff line change
@@ -1,25 +1,33 @@
import { useLayoutEffect, useState } from 'react';
import { useState } from 'react';
import { Q } from '@nozbe/watermelondb';
import { Observable, Subscription } from 'rxjs';
import { sanitizedRaw } from '@nozbe/watermelondb/RawRecord';

import { TUseThreadMessagesProps } from '../types';
import { IMessage, TSubscriptionModel, TThreadModel } from '../../../definitions';
import { ISearchThreadMessages } from '../definitions';
import { IMessage, IUser, TSubscriptionModel, TThreadModel } from '../../../definitions';
import { debounce } from '../../../lib/methods/helpers';
import { Services } from '../../../lib/services';
import { sanitizeLikeString } from '../../../lib/database/utils';
import log from '../../../lib/methods/helpers/log';
import protectedFunction from '../../../lib/methods/helpers/protectedFunction';
import buildMessage from '../../../lib/methods/helpers/buildMessage';
import database from '../../../lib/database';
import getFilteredThreads from '../utils/helper';
import { Filter } from '../filters';

const API_FETCH_COUNT = 50;

const useThreadMessages = ({ rid, getFilteredThreads, search, currentFilter, initFilter, viewName }: TUseThreadMessagesProps) => {
interface IUseThreadMessagesProps {
user: IUser;
rid: string;
messagesObservable: Observable<TThreadModel[]>;
currentFilter: Filter;
search: ISearchThreadMessages;
}

const useThreadMessages = ({ user, rid, search, currentFilter, messagesObservable }: IUseThreadMessagesProps) => {
let subSubscription: Subscription;
let messagesSubscription: Subscription;
let messagesObservable: Observable<TThreadModel[]>;

const [loading, setLoading] = useState(false);
const [end, setEnd] = useState(false);
const [messages, setMessages] = useState<TThreadModel[]>([]);
Expand All @@ -28,7 +36,6 @@ const useThreadMessages = ({ rid, getFilteredThreads, search, currentFilter, ini
const [offset, setOffset] = useState(0);

const init = () => {
initFilter();
if (!subscription) {
return load();
}
Expand Down Expand Up @@ -81,7 +88,7 @@ const useThreadMessages = ({ rid, getFilteredThreads, search, currentFilter, ini
.observeWithColumns(['_updated_at']);

messagesSubscription = messagesObservable.subscribe(messages => {
const displayingThreads = getFilteredThreads(messages, subscription, currentFilter);
const displayingThreads = getFilteredThreads(user, messages, subscription, currentFilter);
setMessages(messages);
setDisplayingThreads(displayingThreads);
});
Expand Down Expand Up @@ -206,29 +213,26 @@ const useThreadMessages = ({ rid, getFilteredThreads, search, currentFilter, ini
}
};

useLayoutEffect(() => {
initSubscription();
subscribeMessages({});
init();
return () => {
console.countReset(`${viewName}.render calls`);
if (subSubscription) {
subSubscription.unsubscribe();
}
if (messagesSubscription) {
messagesSubscription.unsubscribe();
}
};
}, [currentFilter]);
const unsubscribeMessages = () => {
if (subSubscription) {
subSubscription.unsubscribe();
}
if (messagesSubscription) {
messagesSubscription.unsubscribe();
}
};

return {
subscription,
messages,
init,
initSubscription,
displayingThreads,
loadMore: load,
loading,
setDisplayingThreads,
subscribeMessages
subscribeMessages,
unsubscribeMessages
};
};

Expand Down
86 changes: 86 additions & 0 deletions app/views/ThreadMessagesView/hooks/useeThreadSearch.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
import { debounce } from 'lodash';
import I18n from 'i18n-js';
import { NativeStackNavigationOptions, NativeStackNavigationProp } from '@react-navigation/native-stack';

import * as HeaderButton from '../../../containers/HeaderButton';
import SearchHeader from '../../../containers/SearchHeader';
import { ChatsStackParamList } from '../../../stacks/types';
import { TNavigation } from '../../../stacks/stackType';
import { TSubscriptionModel } from '../../../definitions';
import { ISearchThreadMessages } from '../definitions';

interface IUseThreadSearch {
isMasterDetail: boolean;
navigation: NativeStackNavigationProp<ChatsStackParamList & TNavigation, 'ThreadMessagesView'>;
search: ISearchThreadMessages;
setSearch: (search: ISearchThreadMessages) => void;
subscribeMessages: ({ subscription, searchText }: { subscription?: TSubscriptionModel; searchText?: string }) => void;
showFilters: () => void;
}

const useThreadSearch = ({ isMasterDetail, navigation, search, setSearch, subscribeMessages, showFilters }: IUseThreadSearch) => {
const getHeader = (triggerSearch?: boolean): NativeStackNavigationOptions => {
if (search.isSearching || triggerSearch) {
return {
headerLeft: () => (
<HeaderButton.Container left>
<HeaderButton.Item iconName='close' onPress={onCancelSearchPress} />
</HeaderButton.Container>
),
headerTitle: () => <SearchHeader onSearchChangeText={onSearchChangeText} testID='thread-messages-view-search-header' />,
headerRight: () => null
};
}

const options: NativeStackNavigationOptions = {
headerLeft: () => null,
headerTitle: I18n.t('Threads'),
headerRight: () => (
<HeaderButton.Container>
<HeaderButton.Item iconName='filter' onPress={showFilters} />
<HeaderButton.Item iconName='search' onPress={onSearchPress} testID='thread-messages-view-search-icon' />
</HeaderButton.Container>
)
};

if (isMasterDetail) {
options.headerLeft = () => <HeaderButton.CloseModal navigation={navigation} />;
}

return options;
};

const setHeader = () => {
const options = getHeader();
navigation.setOptions(options);
};

const onSearchPress = () => {
setSearch({ ...search, isSearching: true });
const options = getHeader(true);
navigation.setOptions(options);
};

const onSearchChangeText = debounce((searchText: string) => {
setSearch({ isSearching: true, searchText });
subscribeMessages({ searchText });
}, 300);

const onCancelSearchPress = () => {
setSearch({
isSearching: false,
searchText: ''
});
setHeader();
subscribeMessages({});
};

return {
setHeader,
onSearchPress,
onSearchChangeText,
onCancelSearchPress
};
};

export default useThreadSearch;
Loading

0 comments on commit 1de16de

Please sign in to comment.