|
|
|
|
@ -1,36 +1,35 @@ |
|
|
|
|
import React, { memo, useCallback, useMemo, useState } from 'react'; |
|
|
|
|
import { Box, Icon, TextInput, Margins, Select, Throbber, ButtonGroup, Button } from '@rocket.chat/fuselage'; |
|
|
|
|
import { Virtuoso } from 'react-virtuoso'; |
|
|
|
|
import { useMutableCallback, useLocalStorage, useAutoFocus } from '@rocket.chat/fuselage-hooks'; |
|
|
|
|
|
|
|
|
|
import { useTranslation } from '../../../contexts/TranslationContext'; |
|
|
|
|
import { useEndpoint } from '../../../contexts/ServerContext'; |
|
|
|
|
import { useSetModal } from '../../../contexts/ModalContext'; |
|
|
|
|
import { useScrollableRecordList } from '../../../hooks/lists/useScrollableRecordList'; |
|
|
|
|
import { useRecordList } from '../../../hooks/lists/useRecordList'; |
|
|
|
|
import { RecordList } from '../../../lib/lists/RecordList.ts'; |
|
|
|
|
import { TeamChannelItem } from './TeamChannelItem'; |
|
|
|
|
import { useTabBarClose } from '../../room/providers/ToolboxProvider'; |
|
|
|
|
import { roomTypes } from '../../../../app/utils'; |
|
|
|
|
import ScrollableContentWrapper from '../../../components/ScrollableContentWrapper'; |
|
|
|
|
import VerticalBar from '../../../components/VerticalBar'; |
|
|
|
|
import AddExistingModal from '../modals/AddExistingModal'; |
|
|
|
|
import CreateChannel from '../../../sidebar/header/CreateChannel'; |
|
|
|
|
import RoomInfo from '../../room/contextualBar/Info'; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const Row = memo(function Row({ room, onClickView }) { |
|
|
|
|
import { useMutableCallback, useLocalStorage, useAutoFocus, useDebouncedValue } from '@rocket.chat/fuselage-hooks'; |
|
|
|
|
|
|
|
|
|
import { useTranslation } from '../../../../contexts/TranslationContext'; |
|
|
|
|
import { useSetModal } from '../../../../contexts/ModalContext'; |
|
|
|
|
import { useRecordList } from '../../../../hooks/lists/useRecordList'; |
|
|
|
|
import { TeamsChannelItem } from './TeamsChannelItem'; |
|
|
|
|
import { useTabBarClose } from '../../../room/providers/ToolboxProvider'; |
|
|
|
|
import { roomTypes } from '../../../../../app/utils'; |
|
|
|
|
import ScrollableContentWrapper from '../../../../components/ScrollableContentWrapper'; |
|
|
|
|
import VerticalBar from '../../../../components/VerticalBar'; |
|
|
|
|
import AddExistingModal from './AddExistingModal'; |
|
|
|
|
import CreateChannel from '../../../../sidebar/header/CreateChannel'; |
|
|
|
|
import RoomInfo from '../../../room/contextualBar/Info'; |
|
|
|
|
import { useTeamsChannelList } from './hooks/useTeamsChannelList'; |
|
|
|
|
import { AsyncStatePhase } from '../../../../lib/asyncState'; |
|
|
|
|
|
|
|
|
|
const Row = memo(function Row({ room, onClickView, reload }) { |
|
|
|
|
if (!room) { |
|
|
|
|
return <BaseTeamChannels.Option.Skeleton />; |
|
|
|
|
return <BaseTeamsChannels.Option.Skeleton />; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
return <BaseTeamChannels.Option |
|
|
|
|
return <BaseTeamsChannels.Option |
|
|
|
|
room={room} |
|
|
|
|
onClickView={onClickView} |
|
|
|
|
reload={reload} |
|
|
|
|
/>; |
|
|
|
|
}); |
|
|
|
|
|
|
|
|
|
const BaseTeamChannels = ({ |
|
|
|
|
const BaseTeamsChannels = ({ |
|
|
|
|
loading, |
|
|
|
|
channels = [], |
|
|
|
|
text, |
|
|
|
|
@ -43,6 +42,7 @@ const BaseTeamChannels = ({ |
|
|
|
|
total, |
|
|
|
|
loadMoreItems, |
|
|
|
|
onClickView, |
|
|
|
|
reload, |
|
|
|
|
}) => { |
|
|
|
|
const t = useTranslation(); |
|
|
|
|
const inputRef = useAutoFocus(true); |
|
|
|
|
@ -52,13 +52,13 @@ const BaseTeamChannels = ({ |
|
|
|
|
['autoJoin', t('Auto-join')], |
|
|
|
|
], [t]); |
|
|
|
|
|
|
|
|
|
const lm = useMutableCallback((start) => loadMoreItems(start + 1, Math.min(50, start + 1 - channels.length))); |
|
|
|
|
const lm = useMutableCallback((start) => !loading && loadMoreItems(start)); |
|
|
|
|
|
|
|
|
|
return ( |
|
|
|
|
<> |
|
|
|
|
<VerticalBar.Header> |
|
|
|
|
<VerticalBar.Icon name='hash'/> |
|
|
|
|
<VerticalBar.Text>{t('Channels')}</VerticalBar.Text> |
|
|
|
|
<VerticalBar.Text>{t('Team_Channels')}</VerticalBar.Text> |
|
|
|
|
{ onClickClose && <VerticalBar.Close onClick={onClickClose} /> } |
|
|
|
|
</VerticalBar.Header> |
|
|
|
|
|
|
|
|
|
@ -78,25 +78,20 @@ const BaseTeamChannels = ({ |
|
|
|
|
</Box> |
|
|
|
|
|
|
|
|
|
{loading && <Box pi='x24' pb='x12'><Throbber size='x12' /></Box>} |
|
|
|
|
{!loading && channels.length <= 0 && <Box pi='x24' pb='x12'>{t('No_results_found')}</Box>} |
|
|
|
|
|
|
|
|
|
<Box w='full' h='full' overflow='hidden' flexShrink={1}> |
|
|
|
|
{!loading && channels && channels.length > 0 && <Virtuoso |
|
|
|
|
style={{ |
|
|
|
|
height: '100%', |
|
|
|
|
width: '100%', |
|
|
|
|
}} |
|
|
|
|
{!loading && channels.length === 0 && <Box pi='x24' pb='x12'>{t('No_results_found')}</Box>} |
|
|
|
|
{!loading && <Box w='full' h='full' overflow='hidden' flexShrink={1}> |
|
|
|
|
<Virtuoso |
|
|
|
|
totalCount={total} |
|
|
|
|
endReached={lm} |
|
|
|
|
overscan={50} |
|
|
|
|
data={channels} |
|
|
|
|
components={{ Scroller: ScrollableContentWrapper }} |
|
|
|
|
itemContent={(index, data) => <Row |
|
|
|
|
onClickView={onClickView} |
|
|
|
|
room={data} |
|
|
|
|
reload={reload} |
|
|
|
|
/>} |
|
|
|
|
/>} |
|
|
|
|
</Box> |
|
|
|
|
/> |
|
|
|
|
</Box>} |
|
|
|
|
</VerticalBar.Content> |
|
|
|
|
|
|
|
|
|
<VerticalBar.Footer> |
|
|
|
|
@ -109,8 +104,6 @@ const BaseTeamChannels = ({ |
|
|
|
|
); |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
BaseTeamChannels.Option = TeamChannelItem; |
|
|
|
|
|
|
|
|
|
export const useReactModal = (Component, props) => { |
|
|
|
|
const setModal = useSetModal(); |
|
|
|
|
|
|
|
|
|
@ -128,41 +121,25 @@ export const useReactModal = (Component, props) => { |
|
|
|
|
}); |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
const TeamChannels = ({ teamId }) => { |
|
|
|
|
const TeamsChannels = ({ teamId }) => { |
|
|
|
|
const [state, setState] = useState({}); |
|
|
|
|
const onClickClose = useTabBarClose(); |
|
|
|
|
|
|
|
|
|
const [type, setType] = useLocalStorage('channels-list-type', 'all'); |
|
|
|
|
const [text, setText] = useState(''); |
|
|
|
|
const [roomList] = useState(() => new RecordList()); |
|
|
|
|
|
|
|
|
|
const roomListEndpoint = useEndpoint('GET', 'teams.listRooms'); |
|
|
|
|
const debouncedText = useDebouncedValue(text, 800); |
|
|
|
|
|
|
|
|
|
const fetchData = useCallback(async () => { |
|
|
|
|
const { rooms, total } = await roomListEndpoint({ teamId }); |
|
|
|
|
const { teamsChannelList, loadMoreItems, reload } = useTeamsChannelList(useMemo(() => ({ teamId, text: debouncedText, type }), [teamId, debouncedText, type])); |
|
|
|
|
|
|
|
|
|
const roomsDated = rooms.map((rooms) => { |
|
|
|
|
rooms._updatedAt = new Date(rooms._updatedAt); |
|
|
|
|
return { ...rooms }; |
|
|
|
|
}); |
|
|
|
|
return { |
|
|
|
|
items: roomsDated, |
|
|
|
|
itemCount: total, |
|
|
|
|
}; |
|
|
|
|
}, [roomListEndpoint, teamId]); |
|
|
|
|
|
|
|
|
|
const { loadMoreItems } = useScrollableRecordList( |
|
|
|
|
roomList, |
|
|
|
|
fetchData, |
|
|
|
|
); |
|
|
|
|
const { phase, items, itemCount } = useRecordList(roomList); |
|
|
|
|
const { phase, items, itemCount: total } = useRecordList(teamsChannelList); |
|
|
|
|
|
|
|
|
|
const handleTextChange = useCallback((event) => { |
|
|
|
|
setText(event.currentTarget.value); |
|
|
|
|
}, []); |
|
|
|
|
|
|
|
|
|
const addExisting = useReactModal(AddExistingModal, { teamId }); |
|
|
|
|
const createNew = useReactModal(CreateChannel, { teamId }); |
|
|
|
|
const addExisting = useReactModal(AddExistingModal, { teamId, reload }); |
|
|
|
|
const createNew = useReactModal(CreateChannel, { teamId, reload }); |
|
|
|
|
|
|
|
|
|
const goToRoom = useCallback((room) => roomTypes.openRouteLink(room.t, room), []); |
|
|
|
|
const handleBack = useCallback(() => setState({}), [setState]); |
|
|
|
|
@ -180,21 +157,24 @@ const TeamChannels = ({ teamId }) => { |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
return ( |
|
|
|
|
<BaseTeamChannels |
|
|
|
|
loading={phase === 'loading'} |
|
|
|
|
<BaseTeamsChannels |
|
|
|
|
loading={phase === AsyncStatePhase.LOADING} |
|
|
|
|
type={type} |
|
|
|
|
text={text} |
|
|
|
|
setType={setType} |
|
|
|
|
setText={handleTextChange} |
|
|
|
|
channels={items} |
|
|
|
|
total={itemCount} |
|
|
|
|
total={total} |
|
|
|
|
onClickClose={onClickClose} |
|
|
|
|
onClickAddExisting={addExisting} |
|
|
|
|
onClickCreateNew={createNew} |
|
|
|
|
onClickView={viewRoom} |
|
|
|
|
loadMoreItems={loadMoreItems} |
|
|
|
|
reload={reload} |
|
|
|
|
/> |
|
|
|
|
); |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
export default TeamChannels; |
|
|
|
|
BaseTeamsChannels.Option = TeamsChannelItem; |
|
|
|
|
|
|
|
|
|
export default TeamsChannels; |