Skip to content

Commit

Permalink
Merge pull request #3742 from tloncorp/promote-dev-7-15
Browse files Browse the repository at this point in the history
ops: sync dev -> staging
  • Loading branch information
arthyn authored Jul 15, 2024
2 parents f399f1a + 625c72e commit 7cba1c2
Show file tree
Hide file tree
Showing 91 changed files with 2,498 additions and 921 deletions.
12 changes: 11 additions & 1 deletion apps/tlon-mobile/src/fixtures/GroupList.fixture.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,8 @@ export default {
basic: (
<FixtureWrapper fillWidth>
<ChatList
activeTab="all"
setActiveTab={() => {}}
pinned={[groupWithLongTitle, groupWithImage].map((g) =>
makeChannelSummary({ group: g })
)}
Expand All @@ -116,6 +118,8 @@ export default {
emptyPinned: (
<FixtureWrapper fillWidth>
<ChatList
activeTab="all"
setActiveTab={() => {}}
pinned={[dmSummary, groupDmSummary]}
unpinned={[
groupWithColorAndNoImage,
Expand All @@ -129,7 +133,13 @@ export default {
),
loading: (
<FixtureWrapper fillWidth>
<ChatList pinned={[]} unpinned={[]} pendingChats={[]} />
<ChatList
activeTab="all"
setActiveTab={() => {}}
pinned={[]}
unpinned={[]}
pendingChats={[]}
/>
</FixtureWrapper>
),
};
8 changes: 1 addition & 7 deletions apps/tlon-mobile/src/fixtures/ProfileWidget.fixture.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ export default {
>
<View paddingHorizontal="$xl">
<ProfileDisplayWidget
debugMessage=""
contact={brianContact}
contactId={brianContact.id}
/>
Expand All @@ -26,11 +25,7 @@ export default {
verticalAlign="center"
>
<View paddingHorizontal="$xl">
<ProfileDisplayWidget
contact={danContact}
contactId={danContact.id}
debugMessage=""
/>
<ProfileDisplayWidget contact={danContact} contactId={danContact.id} />
</View>
</FixtureWrapper>
),
Expand All @@ -44,7 +39,6 @@ export default {
<ProfileDisplayWidget
contact={markContact}
contactId={markContact.id}
debugMessage=""
/>
</View>
</FixtureWrapper>
Expand Down
23 changes: 23 additions & 0 deletions apps/tlon-mobile/src/hooks/useHandleLogout.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import * as api from '@tloncorp/shared/dist/api';
import { useCallback } from 'react';

import { clearShipInfo, useShip } from '../contexts/ship';
import { resetDb } from '../lib/nativeDb';
import { removeHostingToken, removeHostingUserId } from '../utils/hosting';

export function useHandleLogout() {
const { clearShip } = useShip();

const handleLogout = useCallback(async () => {
api.queryClient.clear();
api.removeUrbitClient();
clearShip();
clearShipInfo();
removeHostingToken();
removeHostingUserId();
// delay DB reset to next tick to avoid race conditions
setTimeout(() => resetDb());
}, [clearShip]);

return handleLogout;
}
17 changes: 0 additions & 17 deletions apps/tlon-mobile/src/hooks/useLogout.ts

This file was deleted.

82 changes: 43 additions & 39 deletions apps/tlon-mobile/src/hooks/useNotificationListener.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
import crashlytics from '@react-native-firebase/crashlytics';
import type { NavigationProp } from '@react-navigation/native';
import { CommonActions, useNavigation } from '@react-navigation/native';
import { syncDms, syncGroups } from '@tloncorp/shared';
import { markChatRead } from '@tloncorp/shared/dist/api';
import * as api from '@tloncorp/shared/dist/api';
import * as db from '@tloncorp/shared/dist/db';
import * as store from '@tloncorp/shared/dist/store';
import { whomIsDm, whomIsMultiDm } from '@tloncorp/shared/dist/urbit';
import { addNotificationResponseReceivedListener } from 'expo-notifications';
import { useEffect, useState } from 'react';
Expand All @@ -21,18 +23,20 @@ export default function useNotificationListener({
notificationChannelId,
}: Props) {
const navigation = useNavigation<NavigationProp<RootStackParamList>>();
const [{ postId, channelId, isDm }, setGotoData] = useState<{
const { data: isTlonEmployee } = store.useIsTlonEmployee();

const [{ postInfo, channelId, isDm }, setGotoData] = useState<{
path?: string;
isDm?: boolean;
postId?: string | null;
postInfo?: { id: string; authorId: string } | null;
channelId?: string;
}>({
path: notificationPath,
channelId: notificationChannelId,
});

const resetGotoData = () =>
setGotoData({ path: undefined, channelId: undefined });
setGotoData({ path: undefined, channelId: undefined, postInfo: undefined });

// Start notifications prompt
useEffect(() => {
Expand All @@ -53,7 +57,7 @@ export default function useNotificationListener({
},
},
} = response;
const postId = api.getPostIdFromWer(data.wer);
const postInfo = api.getPostInfoFromWer(data.wer);
const isDm = api.getIsDmFromWer(data.wer);
if (actionIdentifier === 'markAsRead' && data.channelId) {
markChatRead(data.channelId);
Expand All @@ -63,7 +67,7 @@ export default function useNotificationListener({
setGotoData({
path: data.wer,
isDm,
postId,
postInfo,
channelId: data.channelId,
});
}
Expand All @@ -86,42 +90,33 @@ export default function useNotificationListener({
}

// if we have a post id, try to navigate to the thread
if (postId) {
let postToNavigateTo: db.Post | null = null;
if (isDm) {
// for DMs, we get the backend ID (seal time) of the thread reply itself. So first we have to try to find that,
// then we grab the parent
const post = await db.getPostByBackendTime({ backendTime: postId });
if (post && post.parentId) {
const parentPost = await db.getPost({ postId: post.parentId });
if (parentPost) {
postToNavigateTo = parentPost;
}
}
} else {
// for group posts, we get the correct post ID and can just try to grab it
const post = await db.getPost({ postId });
if (post) {
postToNavigateTo = post;
}
}
if (postInfo) {
let postToNavigateTo: {
id: string;
authorId: string;
channelId: string;
} | null = null;

// if we found the post, navigate to it. Otherwise fallback to channel
if (postToNavigateTo) {
navigation.dispatch(
CommonActions.reset({
index: 1,
routes: [
{ name: 'ChatList' },
{ name: 'Channel', params: { channel } },
{ name: 'Post', params: { post: postToNavigateTo } },
],
})
);
const post = await db.getPost({ postId: postInfo.id });

resetGotoData();
return true;
if (post) {
postToNavigateTo = post;
} else {
postToNavigateTo = { ...postInfo, channelId };
}

navigation.dispatch(
CommonActions.reset({
index: 1,
routes: [
{ name: 'ChatList' },
{ name: 'Channel', params: { channel } },
{ name: 'Post', params: { post: postToNavigateTo } },
],
})
);
resetGotoData();
return true;
}

navigation.navigate('Channel', { channel });
Expand All @@ -145,10 +140,19 @@ export default function useNotificationListener({

// If still not found, clear out the requested channel ID
if (!didNavigate) {
if (isTlonEmployee) {
crashlytics().log(`failed channel ID: ${channelId}`);
crashlytics().log(`failed post ID: ${postInfo?.id}`);
}
crashlytics().recordError(
new Error(
`Notification listener: failed to navigate to ${isDm ? 'DM ' : ''}channel ${postInfo?.id ? ' thread' : ''}`
)
);
resetGotoData();
}
}
})();
}
}, [channelId, postId, navigation, isDm]);
}, [channelId, postInfo, navigation, isDm]);
}
5 changes: 5 additions & 0 deletions apps/tlon-mobile/src/lib/nativeDb.ts
Original file line number Diff line number Diff line change
Expand Up @@ -99,3 +99,8 @@ async function runMigrations() {
await migrate(client!, migrations);
logger.log("migrations succeeded after purge, shouldn't happen often");
}

export async function resetDb() {
await purgeDb();
await migrate(client!, migrations);
}
18 changes: 18 additions & 0 deletions apps/tlon-mobile/src/navigation/RootStack.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,19 @@ import { Platform, StatusBar } from 'react-native';

import { useIsDarkMode } from '../hooks/useIsDarkMode';
import { ActivityScreen } from '../screens/ActivityScreen';
import { AppInfoScreen } from '../screens/AppInfo';
import { AppSettingsScreen } from '../screens/AppSettingsScreen';
import { BlockedUsersScreen } from '../screens/BlockedUsersScreen';
import ChannelScreen from '../screens/ChannelScreen';
import ChannelSearch from '../screens/ChannelSearchScreen';
import ChatListScreen from '../screens/ChatListScreen';
import { EditProfileScreen } from '../screens/EditProfileScreen';
import { FeatureFlagScreen } from '../screens/FeatureFlagScreen';
import { GroupChannelsScreen } from '../screens/GroupChannelsScreen';
import ImageViewerScreen from '../screens/ImageViewerScreen';
import { ManageAccountScreen } from '../screens/ManageAccountScreen';
import PostScreen from '../screens/PostScreen';
import { PushNotificationSettingsScreen } from '../screens/PushNotificationSettingsScreen';
import type { RootStackParamList } from '../types';
import { GroupSettingsStack } from './GroupSettingsStack';
import { SettingsStack } from './SettingsStack';
Expand Down Expand Up @@ -66,6 +73,17 @@ export function RootStack() {
component={ImageViewerScreen}
options={{ animation: 'fade' }}
/>

<Root.Screen name="AppSettings" component={AppSettingsScreen} />
<Root.Screen name="ManageAccount" component={ManageAccountScreen} />
<Root.Screen name="BlockedUsers" component={BlockedUsersScreen} />
<Root.Screen name="AppInfo" component={AppInfoScreen} />
<Root.Screen name="FeatureFlags" component={FeatureFlagScreen} />
<Root.Screen
name="PushNotificationSettings"
component={PushNotificationSettingsScreen}
/>
<Root.Screen name="EditProfile" component={EditProfileScreen} />
</Root.Navigator>
);
}
91 changes: 91 additions & 0 deletions apps/tlon-mobile/src/screens/AppInfo.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
import { NativeStackScreenProps } from '@react-navigation/native-stack';
import * as store from '@tloncorp/shared/dist/store';
import {
AppSetting,
GenericHeader,
ListItem,
SizableText,
Stack,
View,
YStack,
} from '@tloncorp/ui';
import { preSig } from '@urbit/aura';
import * as Application from 'expo-application';
import { useCallback } from 'react';
import { Platform } from 'react-native';
import { ScrollView } from 'react-native-gesture-handler';

import { NOTIFY_PROVIDER, NOTIFY_SERVICE } from '../constants';
import { RootStackParamList } from '../types';

type Props = NativeStackScreenProps<RootStackParamList, 'AppInfo'>;

const BUILD_VERSION = `${Platform.OS === 'ios' ? 'iOS' : 'Android'} ${Application.nativeBuildVersion}`;

export function AppInfoScreen(props: Props) {
const { data: appInfo } = store.useAppInfo();

const onPressPreviewFeatures = useCallback(() => {
props.navigation.navigate('FeatureFlags');
}, [props.navigation]);

return (
<View flex={1}>
<GenericHeader
title="App Info"
goBack={() => props.navigation.goBack()}
/>
<ScrollView>
<YStack marginTop="$xl" marginHorizontal="$2xl" gap="$s">
<AppSetting title="Build version" value={BUILD_VERSION} copyable />
<AppSetting
title="Notify provider"
value={preSig(NOTIFY_PROVIDER)}
copyable
/>
<AppSetting title="Notify service" value={NOTIFY_SERVICE} copyable />
{appInfo ? (
<>
<AppSetting
title="Desk version"
value={appInfo.groupsVersion}
copyable
/>
<AppSetting
title="Desk source"
value={appInfo.groupsSyncNode}
copyable
/>
<AppSetting
title="Desk hash"
value={appInfo.groupsHash.split('.').pop() ?? 'n/a'}
copyable
/>
</>
) : (
<View>
<SizableText color="$negativeActionText">
Cannot load app info settings
</SizableText>
</View>
)}

<Stack marginTop="$xl">
<ListItem onPress={onPressPreviewFeatures}>
<ListItem.SystemIcon icon="Bang" rounded />
<ListItem.MainContent>
<ListItem.Title>Feature previews</ListItem.Title>
</ListItem.MainContent>
<ListItem.SystemIcon
icon="ChevronRight"
backgroundColor={'transparent'}
position="relative"
left="$m"
/>
</ListItem>
</Stack>
</YStack>
</ScrollView>
</View>
);
}
Loading

0 comments on commit 7cba1c2

Please sign in to comment.