Skip to content

Commit c5ceceb

Browse files
Merge pull request #6458 from nguyentrannhan/fix-typo
updated fetch threads
2 parents 4e9b5e4 + 086e578 commit c5ceceb

File tree

6 files changed

+58
-38
lines changed

6 files changed

+58
-38
lines changed

apps/mobile/src/app/navigation/Authentication/index.tsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,11 @@ import moment from 'moment';
1111
import { Dimensions, NativeModules, Platform } from 'react-native';
1212
import BottomSheetRootListener from '../../components/BottomSheetRootListener';
1313
import CallingModalWrapper from '../../components/CallingModalWrapper';
14+
import ModalRootListener from '../../components/ModalRootListener';
1415
import useTabletLandscape from '../../hooks/useTabletLandscape';
1516
import HomeScreenTablet from '../../screens/home/HomeScreenTablet';
17+
import ChannelMessageListener from '../../screens/home/homedrawer/ChannelMessageListener';
18+
import ChannelMessageReactionListener from '../../screens/home/homedrawer/ChannelMessageReactionListener';
1619
import HomeDefaultWrapper from '../../screens/home/homedrawer/HomeDefaultWrapper';
1720
import ChannelVoicePopup from '../../screens/home/homedrawer/components/ChannelVoicePopup';
1821
import { RenderVideoDetail } from '../../screens/home/homedrawer/components/RenderVideoDetail';
@@ -28,9 +31,6 @@ import { MessagesStacks } from './stacks/MessagesStacks';
2831
import { NotificationStacks } from './stacks/NotificationStacks';
2932
import { ServersStacks } from './stacks/ServersStacks';
3033
import { SettingStacks } from './stacks/SettingStacks';
31-
import ChannelMessageListener from "../../screens/home/homedrawer/ChannelMessageListener";
32-
import ChannelMessageReactionListener from "../../screens/home/homedrawer/ChannelMessageReactionListener";
33-
import ModalRootListener from "../../components/ModalRootListener";
3434
const RootStack = createStackNavigator();
3535
const { SharedPreferences } = NativeModules;
3636

apps/mobile/src/app/screens/home/homedrawer/BackNativeListener.tsx

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,8 @@
1-
import { ActionEmitEvent } from '@mezon/mobile-components';
21
import { selectDmGroupCurrentId, selectHiddenBottomTabMobile } from '@mezon/store';
32
import { useDrawerStatus } from '@react-navigation/drawer';
43
import { DrawerActions, useNavigation, useNavigationState } from '@react-navigation/native';
5-
import React, { useEffect, useMemo, useState } from 'react';
6-
import { Alert, BackHandler, DeviceEventEmitter, View } from 'react-native';
4+
import React, { useEffect, useMemo } from 'react';
5+
import { Alert, BackHandler, View } from 'react-native';
76
import { useSelector } from 'react-redux';
87
import { APP_SCREEN } from '../../../navigation/ScreenTypes';
98

apps/mobile/src/app/screens/home/homedrawer/components/ClanMenu/ClanMenu/index.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { useBottomSheetModal } from '@gorhom/bottom-sheet';
22
import { useMarkAsRead, usePermissionChecker } from '@mezon/core';
33
import { ActionEmitEvent, Icons } from '@mezon/mobile-components';
4-
import { baseColor, useTheme } from '@mezon/mobile-ui';
4+
import { useTheme } from '@mezon/mobile-ui';
55
import { appActions, categoriesActions, selectCurrentClan, selectIsShowEmptyCategory, useAppDispatch } from '@mezon/store-mobile';
66
import { EPermission } from '@mezon/utils';
77
import { useNavigation } from '@react-navigation/native';
@@ -10,7 +10,7 @@ import { useTranslation } from 'react-i18next';
1010
import { DeviceEventEmitter, Text, View } from 'react-native';
1111
import { ScrollView } from 'react-native-gesture-handler';
1212
import { useSelector } from 'react-redux';
13-
import { IMezonMenuItemProps, IMezonMenuSectionProps, MezonClanAvatar, MezonMenu, MezonSwitch, reserve } from '../../../../../../componentUI';
13+
import { IMezonMenuItemProps, IMezonMenuSectionProps, MezonClanAvatar, MezonMenu, MezonSwitch } from '../../../../../../componentUI';
1414
import MezonButtonIcon from '../../../../../../componentUI/MezonButtonIcon';
1515
import DeleteClanModal from '../../../../../../components/DeleteClanModal';
1616
import { APP_SCREEN, AppStackScreenProps } from '../../../../../../navigation/ScreenTypes';

libs/components/src/lib/components/ChannelTopbar/TopBarComponents/Threads/ThreadModal/ThreadList.tsx

Lines changed: 32 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,36 +1,57 @@
11
import { useOnScreen } from '@mezon/core';
22
import { ThreadsEntity } from '@mezon/store';
3-
import { MutableRefObject, useEffect } from 'react';
3+
import { useEffect, useRef } from 'react';
44
import GroupThreads from './GroupThreads';
55
import { getActiveThreads, getJoinedThreadsWithinLast30Days, getThreadsOlderThan30Days } from './hepler';
66

77
type ThreadListProps = {
8-
hasMore: boolean;
98
isLoading: boolean;
109
loadMore: () => void | undefined | null;
1110
threads: ThreadsEntity[];
12-
preventClosePannel: MutableRefObject<boolean>;
11+
preventClosePannel: React.MutableRefObject<boolean>;
1312
};
1413

15-
export default function ThreadList({ hasMore, isLoading, loadMore, threads, preventClosePannel }: ThreadListProps) {
14+
export default function ThreadList({ isLoading, threads, loadMore, preventClosePannel }: ThreadListProps) {
15+
const ulRef = useRef<HTMLUListElement | null>(null);
1616
const activeThreads = getActiveThreads(threads);
1717
const joinedThreads = getJoinedThreadsWithinLast30Days(threads);
1818
const oldThreads = getThreadsOlderThan30Days(threads);
1919

20-
const { measureRef, isIntersecting, observer } = useOnScreen();
20+
const { measureRef, isIntersecting, observer } = useOnScreen({ root: ulRef.current });
21+
22+
const lastThread = threads[threads.length - 1];
23+
24+
const isLastInActive = activeThreads.includes(lastThread);
25+
const isLastInJoined = joinedThreads.includes(lastThread);
26+
const isLastInOld = oldThreads.includes(lastThread);
2127

2228
useEffect(() => {
23-
if (isIntersecting && hasMore) {
29+
if (isIntersecting) {
2430
loadMore();
2531
observer?.disconnect();
2632
}
27-
}, [isIntersecting, hasMore, loadMore]);
33+
}, [isIntersecting, loadMore]);
2834

2935
return (
30-
<ul className="pb-4 pr-4 pl-4">
31-
<GroupThreads preventClosePannel={preventClosePannel} title="Active Threads" threads={activeThreads} />
32-
<GroupThreads preventClosePannel={preventClosePannel} title="Joined Threads (Last 30 Days)" threads={joinedThreads} />
33-
<GroupThreads preventClosePannel={preventClosePannel} title="Older Threads" threads={oldThreads} measureRef={measureRef} />
36+
<ul ref={ulRef} className="pb-4 pr-4 pl-4 overflow-y-auto h-[500px]">
37+
<GroupThreads
38+
preventClosePannel={preventClosePannel}
39+
title="Active Threads"
40+
threads={activeThreads}
41+
measureRef={isLastInActive ? measureRef : undefined}
42+
/>
43+
<GroupThreads
44+
preventClosePannel={preventClosePannel}
45+
title="Joined Threads (Last 30 Days)"
46+
threads={joinedThreads}
47+
measureRef={isLastInJoined ? measureRef : undefined}
48+
/>
49+
<GroupThreads
50+
preventClosePannel={preventClosePannel}
51+
title="Older Threads"
52+
threads={oldThreads}
53+
measureRef={isLastInOld ? measureRef : undefined}
54+
/>
3455
{isLoading && <li>Loading...</li>}
3556
</ul>
3657
);

libs/components/src/lib/components/ChannelTopbar/TopBarComponents/Threads/ThreadModal/index.tsx

Lines changed: 18 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -84,34 +84,40 @@ const ThreadModal = ({ onClose, rootRef }: ThreadsProps) => {
8484
const [page, setPage] = useState(1);
8585
const [hasMore, setHasMore] = useState(false);
8686
const [isLoading, setIsLoading] = useState(false);
87-
88-
const fetchThreads = async () => {
87+
const fetchThreads = async (pageNumber: number) => {
8988
setIsLoading(true);
9089
try {
9190
const body = {
9291
channelId: currentChannelId,
9392
clanId: currentClanId ?? '',
94-
page: page,
93+
page: pageNumber,
9594
noCache: true
9695
};
9796

9897
const res = await dispatch(threadsActions.fetchThreads(body));
9998
const newThreads = Array.isArray(res?.payload) ? res.payload : [];
100-
const endResult = newThreads.length < LIMIT;
101-
setHasMore(!endResult);
99+
const isLastPage = newThreads.length < LIMIT;
100+
setHasMore(!isLastPage);
102101
} catch (error) {
103102
console.error('Error fetching threads:', error);
104103
}
105104
setIsLoading(false);
106105
};
106+
107107
useEffect(() => {
108-
fetchThreads();
109-
}, [page, currentChannelId]);
108+
fetchThreads(1);
109+
}, []);
110110

111111
const loadMore = useCallback(() => {
112-
setPage((page) => page + 1);
113-
setIsLoading(true);
114-
}, []);
112+
if (hasMore) {
113+
setPage((prevPage) => {
114+
const nextPage = prevPage + 1;
115+
fetchThreads(nextPage);
116+
return nextPage;
117+
});
118+
}
119+
}, [hasMore]);
120+
115121
return (
116122
<div
117123
ref={modalRef}
@@ -146,14 +152,8 @@ const ThreadModal = ({ onClose, rootRef }: ThreadsProps) => {
146152
</ul>
147153
)}
148154
{showThreadList && (
149-
<div className="h-[500px] overflow-y-auto">
150-
<ThreadList
151-
preventClosePannel={preventClosePannel}
152-
hasMore={hasMore}
153-
isLoading={isLoading}
154-
loadMore={loadMore}
155-
threads={threadFetched}
156-
/>
155+
<div className="h-[500px] ">
156+
<ThreadList preventClosePannel={preventClosePannel} isLoading={isLoading} loadMore={loadMore} threads={threadFetched} />
157157
</div>
158158
)}
159159
{showEmpty && <EmptyThread onClick={handleCreateThread} />}

libs/core/src/lib/chat/hooks/useOnScreen.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { useCallback, useState } from 'react';
22

3-
export const useOnScreen = ({ root = null, rootMargin = '0px', threshold = 0 } = {}) => {
3+
export const useOnScreen = ({ root = null as HTMLElement | null, rootMargin = '0px', threshold = 0 } = {}) => {
44
const [observer, setObserver] = useState<IntersectionObserver | null>(null);
55
const [isIntersecting, setIntersecting] = useState(false);
66

0 commit comments

Comments
 (0)