mirror of
https://github.com/jkingsman/Remote-Terminal-for-MeshCore.git
synced 2026-03-28 17:43:05 +01:00
Fix sidebar and test typing
This commit is contained in:
@@ -258,61 +258,60 @@ export function Sidebar({
|
||||
setContactsCollapsed(prev.contacts);
|
||||
setRepeatersCollapsed(prev.repeaters);
|
||||
}
|
||||
}, [
|
||||
isSearching,
|
||||
favoritesCollapsed,
|
||||
channelsCollapsed,
|
||||
contactsCollapsed,
|
||||
repeatersCollapsed,
|
||||
]);
|
||||
}, [isSearching, favoritesCollapsed, channelsCollapsed, contactsCollapsed, repeatersCollapsed]);
|
||||
|
||||
// Separate favorites from regular items, and build combined favorites list
|
||||
const { favoriteItems, nonFavoriteChannels, nonFavoriteContacts, nonFavoriteRepeaters } = useMemo(() => {
|
||||
const favChannels = filteredChannels.filter((c) => isFavorite(favorites, 'channel', c.key));
|
||||
const favContacts = [...filteredNonRepeaterContacts, ...filteredRepeaters].filter((c) =>
|
||||
isFavorite(favorites, 'contact', c.public_key)
|
||||
);
|
||||
const nonFavChannels = filteredChannels.filter((c) => !isFavorite(favorites, 'channel', c.key));
|
||||
const nonFavContacts = filteredNonRepeaterContacts.filter(
|
||||
(c) => !isFavorite(favorites, 'contact', c.public_key)
|
||||
);
|
||||
const nonFavRepeaters = filteredRepeaters.filter(
|
||||
(c) => !isFavorite(favorites, 'contact', c.public_key)
|
||||
);
|
||||
const { favoriteItems, nonFavoriteChannels, nonFavoriteContacts, nonFavoriteRepeaters } =
|
||||
useMemo(() => {
|
||||
const favChannels = filteredChannels.filter((c) => isFavorite(favorites, 'channel', c.key));
|
||||
const favContacts = [...filteredNonRepeaterContacts, ...filteredRepeaters].filter((c) =>
|
||||
isFavorite(favorites, 'contact', c.public_key)
|
||||
);
|
||||
const nonFavChannels = filteredChannels.filter(
|
||||
(c) => !isFavorite(favorites, 'channel', c.key)
|
||||
);
|
||||
const nonFavContacts = filteredNonRepeaterContacts.filter(
|
||||
(c) => !isFavorite(favorites, 'contact', c.public_key)
|
||||
);
|
||||
const nonFavRepeaters = filteredRepeaters.filter(
|
||||
(c) => !isFavorite(favorites, 'contact', c.public_key)
|
||||
);
|
||||
|
||||
const items: FavoriteItem[] = [
|
||||
...favChannels.map((channel) => ({ type: 'channel' as const, channel })),
|
||||
...favContacts.map((contact) => ({ type: 'contact' as const, contact })),
|
||||
].sort((a, b) => {
|
||||
const timeA =
|
||||
a.type === 'channel'
|
||||
? getLastMessageTime('channel', a.channel.key)
|
||||
: getLastMessageTime('contact', a.contact.public_key);
|
||||
const timeB =
|
||||
b.type === 'channel'
|
||||
? getLastMessageTime('channel', b.channel.key)
|
||||
: getLastMessageTime('contact', b.contact.public_key);
|
||||
if (timeA && timeB) return timeB - timeA;
|
||||
if (timeA && !timeB) return -1;
|
||||
if (!timeA && timeB) return 1;
|
||||
const nameA = a.type === 'channel' ? a.channel.name : a.contact.name || a.contact.public_key;
|
||||
const nameB = b.type === 'channel' ? b.channel.name : b.contact.name || b.contact.public_key;
|
||||
return nameA.localeCompare(nameB);
|
||||
});
|
||||
const items: FavoriteItem[] = [
|
||||
...favChannels.map((channel) => ({ type: 'channel' as const, channel })),
|
||||
...favContacts.map((contact) => ({ type: 'contact' as const, contact })),
|
||||
].sort((a, b) => {
|
||||
const timeA =
|
||||
a.type === 'channel'
|
||||
? getLastMessageTime('channel', a.channel.key)
|
||||
: getLastMessageTime('contact', a.contact.public_key);
|
||||
const timeB =
|
||||
b.type === 'channel'
|
||||
? getLastMessageTime('channel', b.channel.key)
|
||||
: getLastMessageTime('contact', b.contact.public_key);
|
||||
if (timeA && timeB) return timeB - timeA;
|
||||
if (timeA && !timeB) return -1;
|
||||
if (!timeA && timeB) return 1;
|
||||
const nameA =
|
||||
a.type === 'channel' ? a.channel.name : a.contact.name || a.contact.public_key;
|
||||
const nameB =
|
||||
b.type === 'channel' ? b.channel.name : b.contact.name || b.contact.public_key;
|
||||
return nameA.localeCompare(nameB);
|
||||
});
|
||||
|
||||
return {
|
||||
favoriteItems: items,
|
||||
nonFavoriteChannels: nonFavChannels,
|
||||
nonFavoriteContacts: nonFavContacts,
|
||||
nonFavoriteRepeaters: nonFavRepeaters,
|
||||
};
|
||||
}, [
|
||||
filteredChannels,
|
||||
filteredNonRepeaterContacts,
|
||||
filteredRepeaters,
|
||||
favorites,
|
||||
getLastMessageTime,
|
||||
]);
|
||||
return {
|
||||
favoriteItems: items,
|
||||
nonFavoriteChannels: nonFavChannels,
|
||||
nonFavoriteContacts: nonFavContacts,
|
||||
nonFavoriteRepeaters: nonFavRepeaters,
|
||||
};
|
||||
}, [
|
||||
filteredChannels,
|
||||
filteredNonRepeaterContacts,
|
||||
filteredRepeaters,
|
||||
favorites,
|
||||
getLastMessageTime,
|
||||
]);
|
||||
|
||||
const buildChannelRow = (channel: Channel, keyPrefix: string): ConversationRow => ({
|
||||
key: `${keyPrefix}-${channel.key}`,
|
||||
|
||||
@@ -38,10 +38,11 @@ function renderSidebar(overrides?: {
|
||||
favorites?: Favorite[];
|
||||
lastMessageTimes?: ConversationTimes;
|
||||
}) {
|
||||
const aliceName = 'Alice';
|
||||
const publicChannel = makeChannel('AA'.repeat(16), 'Public');
|
||||
const flightChannel = makeChannel('BB'.repeat(16), '#flight');
|
||||
const opsChannel = makeChannel('CC'.repeat(16), '#ops');
|
||||
const alice = makeContact('11'.repeat(32), 'Alice');
|
||||
const alice = makeContact('11'.repeat(32), aliceName);
|
||||
const relay = makeContact('22'.repeat(32), 'Relay', CONTACT_TYPE_REPEATER);
|
||||
|
||||
const unreadCounts = overrides?.unreadCounts ?? {
|
||||
@@ -73,7 +74,7 @@ function renderSidebar(overrides?: {
|
||||
/>
|
||||
);
|
||||
|
||||
return { flightChannel, opsChannel, alice };
|
||||
return { flightChannel, opsChannel, aliceName };
|
||||
}
|
||||
|
||||
function getSectionHeaderContainer(title: string): HTMLElement {
|
||||
@@ -94,27 +95,26 @@ describe('Sidebar section summaries', () => {
|
||||
});
|
||||
|
||||
it('expands collapsed sections during search and restores collapse state after clearing search', async () => {
|
||||
const { opsChannel, alice } = renderSidebar();
|
||||
const { opsChannel, aliceName } = renderSidebar();
|
||||
|
||||
fireEvent.click(screen.getByRole('button', { name: /Channels/i }));
|
||||
fireEvent.click(screen.getByRole('button', { name: /Contacts/i }));
|
||||
|
||||
expect(screen.queryByText(opsChannel.name)).not.toBeInTheDocument();
|
||||
expect(screen.queryByText(alice.name)).not.toBeInTheDocument();
|
||||
expect(screen.queryByText(aliceName)).not.toBeInTheDocument();
|
||||
|
||||
const search = screen.getByPlaceholderText('Search...');
|
||||
fireEvent.change(search, { target: { value: 'alice' } });
|
||||
|
||||
await waitFor(() => {
|
||||
expect(screen.getByText(alice.name)).toBeInTheDocument();
|
||||
expect(screen.getByText(aliceName)).toBeInTheDocument();
|
||||
});
|
||||
|
||||
fireEvent.change(search, { target: { value: '' } });
|
||||
|
||||
await waitFor(() => {
|
||||
expect(screen.queryByText(opsChannel.name)).not.toBeInTheDocument();
|
||||
expect(screen.queryByText(alice.name)).not.toBeInTheDocument();
|
||||
expect(screen.queryByText(aliceName)).not.toBeInTheDocument();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
Reference in New Issue
Block a user