Skip to content

Commit

Permalink
Merge pull request #4251 from tloncorp/po/desktop-navigation-fixes
Browse files Browse the repository at this point in the history
desktop: navigation fixes
  • Loading branch information
patosullivan authored Dec 5, 2024
2 parents 26cb735 + f95d1eb commit 0605823
Show file tree
Hide file tree
Showing 15 changed files with 158 additions and 72 deletions.
10 changes: 9 additions & 1 deletion packages/app/features/top/ChannelScreen.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -71,14 +71,22 @@ export default function ChannelScreen(props: Props) {
store.syncChannelThreadUnreads(channel.id, {
priority: store.SyncPriority.High,
});
if (group) {
// Update the last visited channel in the group so we can return to it
// when we come back to the group
db.updateGroup({
id: group.id,
lastVisitedChannelId: channel.id,
});
}
}
// Mark the channel as visited when we unfocus/leave this screen
() => {
if (channel) {
store.markChannelVisited(channel);
}
};
}, [channel])
}, [channel, group])
);

const [channelNavOpen, setChannelNavOpen] = React.useState(false);
Expand Down
101 changes: 53 additions & 48 deletions packages/app/features/top/ChatListScreen.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import {
GroupPreviewSheet,
InviteUsersSheet,
NavBarView,
NavigationProvider,
RequestsProvider,
ScreenHeader,
View,
Expand Down Expand Up @@ -45,8 +46,10 @@ export default function ChatListScreen(props: Props) {

export function ChatListScreenView({
previewGroupId,
focusedChannelId,
}: {
previewGroupId?: string;
focusedChannelId?: string;
}) {
const navigation = useNavigation<NavigationProp<RootStackParamList>>();
const [addGroupOpen, setAddGroupOpen] = useState(false);
Expand Down Expand Up @@ -267,55 +270,57 @@ export function ChatListScreenView({
setInviteSheetGroup(group);
}}
>
<View flex={1}>
<ScreenHeader
title={notReadyMessage ?? screenTitle}
rightControls={
<>
<ScreenHeader.IconButton
type="Search"
onPress={handleSearchInputToggled}
/>
<ScreenHeader.IconButton
type="Add"
onPress={() => setAddGroupOpen(true)}
/>
</>
}
/>
{chats && chats.unpinned.length ? (
<ChatList
activeTab={activeTab}
setActiveTab={setActiveTab}
pinned={resolvedChats.pinned}
unpinned={resolvedChats.unpinned}
pending={resolvedChats.pending}
onPressItem={onPressChat}
onSectionChange={handleSectionChange}
showSearchInput={showSearchInput}
onSearchToggle={handleSearchInputToggled}
searchQuery={searchQuery}
onSearchQueryChange={setSearchQuery}
<NavigationProvider focusedChannelId={focusedChannelId}>
<View flex={1}>
<ScreenHeader
title={notReadyMessage ?? screenTitle}
rightControls={
<>
<ScreenHeader.IconButton
type="Search"
onPress={handleSearchInputToggled}
/>
<ScreenHeader.IconButton
type="Add"
onPress={() => setAddGroupOpen(true)}
/>
</>
}
/>
) : null}

<WelcomeSheet
open={splashVisible}
onOpenChange={handleWelcomeOpenChange}
/>
<GroupPreviewSheet
open={!!selectedGroup}
onOpenChange={handleGroupPreviewSheetOpenChange}
group={selectedGroup ?? undefined}
onActionComplete={handleGroupAction}
/>
<InviteUsersSheet
open={inviteSheetGroup !== null}
onOpenChange={handleInviteSheetOpenChange}
onInviteComplete={() => setInviteSheetGroup(null)}
group={inviteSheetGroup ?? undefined}
/>
</View>
{chats && chats.unpinned.length ? (
<ChatList
activeTab={activeTab}
setActiveTab={setActiveTab}
pinned={resolvedChats.pinned}
unpinned={resolvedChats.unpinned}
pending={resolvedChats.pending}
onPressItem={onPressChat}
onSectionChange={handleSectionChange}
showSearchInput={showSearchInput}
onSearchToggle={handleSearchInputToggled}
searchQuery={searchQuery}
onSearchQueryChange={setSearchQuery}
/>
) : null}

<WelcomeSheet
open={splashVisible}
onOpenChange={handleWelcomeOpenChange}
/>
<GroupPreviewSheet
open={!!selectedGroup}
onOpenChange={handleGroupPreviewSheetOpenChange}
group={selectedGroup ?? undefined}
onActionComplete={handleGroupAction}
/>
<InviteUsersSheet
open={inviteSheetGroup !== null}
onOpenChange={handleInviteSheetOpenChange}
onInviteComplete={() => setInviteSheetGroup(null)}
group={inviteSheetGroup ?? undefined}
/>
</View>
</NavigationProvider>
<NavBarView
navigateToContacts={() => {
navigation.navigate('Contacts');
Expand Down
21 changes: 13 additions & 8 deletions packages/app/features/top/GroupChannelsScreen.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import {
ChatOptionsProvider,
GroupChannelsScreenView,
InviteUsersSheet,
NavigationProvider,
} from '@tloncorp/ui';
import { useCallback, useState } from 'react';

Expand All @@ -26,8 +27,10 @@ export function GroupChannelsScreen({ route }: Props) {

export function GroupChannelsScreenContent({
groupId: id,
focusedChannelId,
}: {
groupId: string;
focusedChannelId?: string;
}) {
const navigation = useNavigation<NavigationProp<RootStackParamList>>();
const isFocused = useIsFocused();
Expand Down Expand Up @@ -76,14 +79,16 @@ export function GroupChannelsScreenContent({
}}
{...useChatSettingsNavigation()}
>
<GroupChannelsScreenView
onChannelPressed={handleChannelSelected}
onBackPressed={handleGoBackPressed}
onJoinChannel={handleJoinChannel}
group={group}
unjoinedChannels={unjoinedChannels}
enableCustomChannels={enableCustomChannels}
/>
<NavigationProvider focusedChannelId={focusedChannelId}>
<GroupChannelsScreenView
onChannelPressed={handleChannelSelected}
onBackPressed={handleGoBackPressed}
onJoinChannel={handleJoinChannel}
group={group}
unjoinedChannels={unjoinedChannels}
enableCustomChannels={enableCustomChannels}
/>
</NavigationProvider>
<InviteUsersSheet
open={inviteSheetGroup !== null}
onOpenChange={(open) => {
Expand Down
12 changes: 12 additions & 0 deletions packages/app/navigation/desktop/HomeNavigator.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,19 @@ function DrawerContent(props: DrawerContentComponentProps) {
'groupId' in focusedRoute.params &&
focusedRoute.params.groupId
) {
if ('channelId' in focusedRoute.params) {
return (
<GroupChannelsScreenContent
groupId={focusedRoute.params.groupId}
focusedChannelId={focusedRoute.params.channelId}
/>
);
}
return <GroupChannelsScreenContent groupId={focusedRoute.params.groupId} />;
} else if (focusedRoute.params && 'channelId' in focusedRoute.params) {
return (
<ChatListScreenView focusedChannelId={focusedRoute.params.channelId} />
);
} else {
return <ChatListScreenView />;
}
Expand Down
12 changes: 9 additions & 3 deletions packages/app/navigation/desktop/TopLevelDrawer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -34,19 +34,25 @@ const DrawerContent = (props: DrawerContentComponentProps) => {
// hasUnreads={(unreadCount?.channels ?? 0) > 0}
// intentionally leave undotted for now
hasUnreads={false}
onPress={() => props.navigation.navigate('Home')}
onPress={() =>
props.navigation.reset({ index: 0, routes: [{ name: 'Home' }] })
}
/>
<NavIcon
type="Notifications"
activeType="NotificationsFilled"
hasUnreads={haveUnreadUnseenActivity}
isActive={isRouteActive('Activity')}
onPress={() => props.navigation.navigate('Activity')}
onPress={() =>
props.navigation.reset({ index: 0, routes: [{ name: 'Activity' }] })
}
/>
<AvatarNavIcon
id={userId}
focused={isRouteActive('Profile')}
onPress={() => props.navigation.navigate('Profile')}
onPress={() =>
props.navigation.reset({ index: 0, routes: [{ name: 'Profile' }] })
}
/>
{webAppNeedsUpdate && (
<NavIcon
Expand Down
22 changes: 18 additions & 4 deletions packages/app/navigation/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import {
import * as db from '@tloncorp/shared/db';
import * as logic from '@tloncorp/shared/logic';
import * as store from '@tloncorp/shared/store';
import { useIsWindowNarrow } from '@tloncorp/ui';
import { useCallback } from 'react';

import { useFeatureFlagStore } from '../lib/featureFlags';
Expand Down Expand Up @@ -92,25 +93,38 @@ export function useResetToGroup() {
}

export function useNavigateToGroup() {
const isWindowNarrow = useIsWindowNarrow();
const navigation = useNavigation<RootStackNavigationProp>();
const navigationRef = logic.useMutableRef(navigation);
return useCallback(
async (groupId: string) => {
navigationRef.current.navigate(await getMainGroupRoute(groupId));
navigationRef.current.navigate(
await getMainGroupRoute(groupId, isWindowNarrow)
);
},
[navigationRef]
[navigationRef, isWindowNarrow]
);
}

export async function getMainGroupRoute(groupId: string) {
export async function getMainGroupRoute(
groupId: string,
isWindowNarrow?: boolean
) {
const group = await db.getGroup({ id: groupId });
const channelSwitcherEnabled =
useFeatureFlagStore.getState().flags.channelSwitcher;
if (
group &&
group.channels &&
(group.channels.length === 1 || channelSwitcherEnabled)
(group.channels.length === 1 || channelSwitcherEnabled || !isWindowNarrow)
) {
if (!isWindowNarrow && group.lastVisitedChannelId) {
return {
name: 'Channel',
params: { channelId: group.lastVisitedChannelId, groupId },
} as const;
}

return {
name: 'Channel',
params: { channelId: group.channels[0].id, groupId },
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -226,7 +226,8 @@ CREATE TABLE `groups` (
`is_new` integer,
`join_status` text,
`last_post_id` text,
`last_post_at` integer
`last_post_at` integer,
`last_visited_channel_id` text
);
--> statement-breakpoint
CREATE TABLE `pins` (
Expand Down
9 changes: 8 additions & 1 deletion packages/shared/src/db/migrations/meta/0000_snapshot.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"version": "6",
"dialect": "sqlite",
"id": "2ec6d840-6e53-4d97-bf4c-b4d00a248728",
"id": "74260723-19aa-401e-92d0-c790bcc15a53",
"prevId": "00000000-0000-0000-0000-000000000000",
"tables": {
"activity_event_contact_group_pins": {
Expand Down Expand Up @@ -1520,6 +1520,13 @@
"primaryKey": false,
"notNull": false,
"autoincrement": false
},
"last_visited_channel_id": {
"name": "last_visited_channel_id",
"type": "text",
"primaryKey": false,
"notNull": false,
"autoincrement": false
}
},
"indexes": {},
Expand Down
4 changes: 2 additions & 2 deletions packages/shared/src/db/migrations/meta/_journal.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@
{
"idx": 0,
"version": "6",
"when": 1732574199336,
"tag": "0000_lowly_tinkerer",
"when": 1733348853492,
"tag": "0000_loving_namora",
"breakpoints": true
}
]
Expand Down
2 changes: 1 addition & 1 deletion packages/shared/src/db/migrations/migrations.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// This file is required for Expo/React Native SQLite migrations - https://orm.drizzle.team/quick-sqlite/expo

import journal from './meta/_journal.json';
import m0000 from './0000_lowly_tinkerer.sql';
import m0000 from './0000_loving_namora.sql';

export default {
journal,
Expand Down
1 change: 1 addition & 0 deletions packages/shared/src/db/schema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -311,6 +311,7 @@ export const groups = sqliteTable('groups', {
joinStatus: text('join_status').$type<GroupJoinStatus>(),
lastPostId: text('last_post_id'),
lastPostAt: timestamp('last_post_at'),
lastVisitedChannelId: text('last_visited_channel_id'),
});

export const groupsRelations = relations(groups, ({ one, many }) => ({
Expand Down
4 changes: 4 additions & 0 deletions packages/ui/src/components/ListItem/ChannelListItem.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import * as logic from '@tloncorp/shared/logic';
import { useMemo } from 'react';
import { View, isWeb } from 'tamagui';

import { useNavigation } from '../../contexts';
import * as utils from '../../utils';
import { capitalize } from '../../utils';
import { Badge } from '../Badge';
Expand Down Expand Up @@ -57,12 +58,15 @@ export function ChannelListItem({
}
}, [model, firstMemberId, memberCount]);

const isFocused = useNavigation().focusedChannelId === model.id;

return (
<View>
<Pressable
borderRadius="$xl"
onPress={handlePress}
onLongPress={handleLongPress}
backgroundColor={isFocused ? '$secondaryBackground' : undefined}
>
<ListItem {...props}>
<ListItem.ChannelIcon
Expand Down
Loading

0 comments on commit 0605823

Please sign in to comment.