Skip to content

Commit

Permalink
Fixes and adjustments
Browse files Browse the repository at this point in the history
  • Loading branch information
arnautov-anton committed Dec 4, 2024
1 parent 267d7d0 commit 66c8cf4
Show file tree
Hide file tree
Showing 3 changed files with 46 additions and 35 deletions.
9 changes: 2 additions & 7 deletions src/components/ChannelList/ChannelList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,7 @@ import { ChannelListMessenger, ChannelListMessengerProps } from './ChannelListMe
import { useConnectionRecoveredListener } from './hooks/useConnectionRecoveredListener';
import { useMobileNavigation } from './hooks/useMobileNavigation';
import { CustomQueryChannelsFn, usePaginatedChannels } from './hooks/usePaginatedChannels';
import {
MAX_QUERY_CHANNELS_LIMIT,
moveChannelUpwards,
shouldConsiderPinnedChannels,
} from './utils';
import { MAX_QUERY_CHANNELS_LIMIT, moveChannelUpwards } from './utils';

import { Avatar as DefaultAvatar } from '../Avatar';
import { ChannelPreview, ChannelPreviewUIComponentProps } from '../ChannelPreview/ChannelPreview';
Expand Down Expand Up @@ -237,8 +233,7 @@ const UnMemoizedChannelList = <SCG extends DefaultStreamChatGenerics = DefaultSt
const newChannels = moveChannelUpwards({
channels,
channelToMove: customActiveChannelObject,
// TODO: adjust acordingly (based on sort)
considerPinnedChannels: shouldConsiderPinnedChannels(sort),
sort,
});

setChannels(newChannels);
Expand Down
38 changes: 26 additions & 12 deletions src/components/ChannelList/hooks/useChannelListShape.ts
Original file line number Diff line number Diff line change
Expand Up @@ -146,7 +146,7 @@ export const useChannelListShapeDefaults = <SCG extends ExtendableGenerics>() =>
channels,
channelToMove,
channelToMoveIndexWithinChannels: targetChannelIndex,
considerPinnedChannels,
sort,
});
}

Expand All @@ -169,29 +169,31 @@ export const useChannelListShapeDefaults = <SCG extends ExtendableGenerics>() =>
return customHandler(setChannels, event);
}

const considerArchivedChannels = shouldConsiderArchivedChannels(filters);
const considerPinnedChannels = shouldConsiderPinnedChannels(sort);

if (!event.channel?.type) return;
if (!event.channel) {
return;
}

const channel = await getChannel({
client,
id: event.channel.id,
type: event.channel.type,
});

const considerArchivedChannels = shouldConsiderArchivedChannels(filters);
if (isChannelArchived(channel) && considerArchivedChannels) {
return;
}

if (!allowNewMessagesFromUnfilteredChannels) return;
if (!allowNewMessagesFromUnfilteredChannels) {
return;
}

setChannels((channels) =>
moveChannelUpwards({
channels,
channelToMove: channel,
channelToMoveIndexWithinChannels: -1,
considerPinnedChannels,
sort,
}),
);
},
Expand Down Expand Up @@ -249,32 +251,44 @@ export const useChannelListShapeDefaults = <SCG extends ExtendableGenerics>() =>
return;
}

const member = event.member;
const channelType = event.channel_type;
const channelId = event.channel_id;

const considerPinnedChannels = shouldConsiderPinnedChannels(sort);

// TODO: extract this and consider single property sort object too
const pinnedAtSort = Array.isArray(sort) ? (sort[0]?.pinned_at ?? null) : null;

setChannels((currentChannels) => {
const targetChannel = client.channel(channelType, channelId);
// assumes that channel instances are not changing
const targetChannelIndex = currentChannels.indexOf(targetChannel);
const targetChannelExistsWithinList = targetChannelIndex >= 0;

// handle pinning
if (!considerPinnedChannels || lockChannelOrder) return currentChannels;

const newChannels = [...currentChannels];

if (targetChannelExistsWithinList) {
newChannels.splice(targetChannelIndex, 1);
}

// handle archiving
if (typeof event.member?.archived_at === 'string') {
// handle archiving (remove channel)
if (typeof member.archived_at === 'string') {
return newChannels;
}

// handle pinning
if (!considerPinnedChannels || lockChannelOrder) return currentChannels;
let lastPinnedChannelIndex: number | null = null;

// calculate last pinned channel index only if `pinned_at` sort is set to
// ascending order or if it's in descending order while the pin is being removed, otherwise
// we move to the top (index 0)
if (pinnedAtSort === 1 || (pinnedAtSort === -1 && !member.pinned_at)) {
lastPinnedChannelIndex = findLastPinnedChannelIndex({ channels: newChannels });
}

const lastPinnedChannelIndex = findLastPinnedChannelIndex({ channels: newChannels });
const newTargetChannelIndex =
typeof lastPinnedChannelIndex === 'number' ? lastPinnedChannelIndex + 1 : 0;

Expand Down
34 changes: 18 additions & 16 deletions src/components/ChannelList/utils.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import uniqBy from 'lodash.uniqby';
import type { Channel, ExtendableGenerics } from 'stream-chat';
import type { Channel, ChannelSort, ExtendableGenerics } from 'stream-chat';

import type { DefaultStreamChatGenerics } from '../../types/types';
import type { ChannelListProps } from './ChannelList';
Expand Down Expand Up @@ -59,27 +59,24 @@ export function findLastPinnedChannelIndex<SCG extends ExtendableGenerics>({
type MoveChannelUpwardsParams<SCG extends DefaultStreamChatGenerics = DefaultStreamChatGenerics> = {
channels: Array<Channel<SCG>>;
channelToMove: Channel<SCG>;
sort: ChannelSort<SCG>;
/**
* If the index of the channel within `channels` list which is being moved upwards
* (`channelToMove`) is known, you can supply it to skip extra calculation.
*/
channelToMoveIndexWithinChannels?: number;
/**
* Pinned channels should not move within the list based on recent activity, channels which
* receive messages and are not pinned should move upwards but only under the last pinned channel
* in the list. Property defaults to `false` and should be calculated based on existence of
* the `pinned_at` sort option.
*/
considerPinnedChannels?: boolean;
};

/**
* This function should not be used to move pinned already channels.
*/
export const moveChannelUpwards = <
SCG extends DefaultStreamChatGenerics = DefaultStreamChatGenerics,
>({
channels,
channelToMove,
channelToMoveIndexWithinChannels,
considerPinnedChannels = false,
sort,
}: MoveChannelUpwardsParams<SCG>) => {
// get index of channel to move up
const targetChannelIndex =
Expand All @@ -89,14 +86,12 @@ export const moveChannelUpwards = <
const targetChannelExistsWithinList = targetChannelIndex >= 0;
const targetChannelAlreadyAtTheTop = targetChannelIndex === 0;

if (targetChannelAlreadyAtTheTop) return channels;
// pinned channels should not move within the list based on recent activity, channels which
// receive messages and are not pinned should move upwards but only under the last pinned channel
// in the list
const considerPinnedChannels = shouldConsiderPinnedChannels(sort);

// as position of pinned channels has to stay unchanged, we need to
// find last pinned channel in the list to move the target channel after
let lastPinnedChannelIndex: number | null = null;
if (considerPinnedChannels) {
lastPinnedChannelIndex = findLastPinnedChannelIndex({ channels });
}
if (targetChannelAlreadyAtTheTop) return channels;

const newChannels = [...channels];

Expand All @@ -105,6 +100,13 @@ export const moveChannelUpwards = <
newChannels.splice(targetChannelIndex, 1);
}

// as position of pinned channels has to stay unchanged, we need to
// find last pinned channel in the list to move the target channel after
let lastPinnedChannelIndex: number | null = null;
if (considerPinnedChannels) {
lastPinnedChannelIndex = findLastPinnedChannelIndex({ channels: newChannels });
}

// re-insert it at the new place (to specific index if pinned channels are considered)
newChannels.splice(
typeof lastPinnedChannelIndex === 'number' ? lastPinnedChannelIndex + 1 : 0,
Expand Down

0 comments on commit 66c8cf4

Please sign in to comment.