Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

native: android fixes, logout, & view build number #3558

Merged
merged 3 commits into from
Jun 14, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
86 changes: 50 additions & 36 deletions apps/tlon-mobile/src/components/AddGroupSheet.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,12 @@ import {
NativeStackScreenProps,
createNativeStackNavigator,
} from '@react-navigation/native-stack';
import { QueryClientProvider, queryClient } from '@tloncorp/shared/dist/api';
import * as db from '@tloncorp/shared/dist/db';
import {
Button,
ContactBook,
ContactsProvider,
CreateGroupWidget,
GroupPreviewPane,
Icon,
Expand All @@ -20,6 +22,7 @@ import {
XStack,
YStack,
triggerHaptic,
useContacts,
useTheme,
} from '@tloncorp/ui/src';
import {
Expand All @@ -44,6 +47,7 @@ interface AddGroupActions {
}) => void;
onScrollChange: (scrolling: boolean) => void;
screenKey?: number;
contacts?: db.Contact[] | null;
}
const ActionContext = createContext<AddGroupActions>({} as AddGroupActions);

Expand Down Expand Up @@ -79,6 +83,7 @@ export default function AddGroupSheet({
const theme = useTheme();
const navigationRef = useRef<NavigationContainerRef<StackParamList>>(null);
const [screenKey, setScreenKey] = useState<number>(0);
const contacts = useContacts();

const dismiss = useCallback(() => {
if (navigationRef.current && navigationRef.current.canGoBack()) {
Expand Down Expand Up @@ -107,41 +112,46 @@ export default function AddGroupSheet({
>
<Sheet.Overlay />
<Sheet.LazyFrame>
<Sheet.Handle marginBottom="$l" />
<KeyboardAvoidingView style={{ flex: 1 }}>
<NavigationContainer independent={true} ref={navigationRef}>
<ActionContext.Provider
value={{
dismiss,
onCreatedGroup,
onScrollChange: setScreenScrolling,
screenKey,
}}
>
<Stack.Navigator
initialRouteName="Root"
screenOptions={{
headerShown: false,
contentStyle: { backgroundColor: theme.background.val },
}}
>
<Stack.Screen name="Root" component={RootScreen} />
<Stack.Screen
name="CreateGroup"
component={CreateGroupScreen}
/>
<Stack.Screen
name="ViewContactGroups"
component={ViewContactGroupsScreen}
/>
<Stack.Screen
name="ViewGroupPreview"
component={ViewGroupPreviewScreen}
/>
</Stack.Navigator>
</ActionContext.Provider>
</NavigationContainer>
</KeyboardAvoidingView>
<QueryClientProvider client={queryClient}>
<ContactsProvider contacts={contacts ?? null}>
<Sheet.Handle marginBottom="$l" />
<KeyboardAvoidingView style={{ flex: 1 }}>
<NavigationContainer independent={true} ref={navigationRef}>
<ActionContext.Provider
value={{
dismiss,
onCreatedGroup,
onScrollChange: setScreenScrolling,
screenKey,
contacts,
}}
>
<Stack.Navigator
initialRouteName="Root"
screenOptions={{
headerShown: false,
contentStyle: { backgroundColor: theme.background.val },
}}
>
<Stack.Screen name="Root" component={RootScreen} />
<Stack.Screen
name="CreateGroup"
component={CreateGroupScreen}
/>
<Stack.Screen
name="ViewContactGroups"
component={ViewContactGroupsScreen}
/>
<Stack.Screen
name="ViewGroupPreview"
component={ViewGroupPreviewScreen}
/>
</Stack.Navigator>
</ActionContext.Provider>
</NavigationContainer>
</KeyboardAvoidingView>
</ContactsProvider>
</QueryClientProvider>
</Sheet.LazyFrame>
</Sheet>
);
Expand All @@ -167,7 +177,7 @@ function ScreenWrapper({
}

function RootScreen(props: NativeStackScreenProps<StackParamList, 'Root'>) {
const { onScrollChange, screenKey } = useContext(ActionContext);
const { onScrollChange, screenKey, contacts } = useContext(ActionContext);
const insets = useSafeAreaInsets();
const onSelect = useCallback(
(contactId: string) => {
Expand All @@ -180,6 +190,9 @@ function RootScreen(props: NativeStackScreenProps<StackParamList, 'Root'>) {

return (
<ScreenWrapper withoutSafe>
{/* Unclear why we have to render another contacts provider here, but the screen context shows up empty */}
{/* on Android? */}
{/* <ContactsProvider contacts={contacts ?? null}> */}
<YStack flex={1} gap="$xl">
<ContactBook
searchable
Expand All @@ -194,6 +207,7 @@ function RootScreen(props: NativeStackScreenProps<StackParamList, 'Root'>) {
</Button>
</View>
</YStack>
{/* </ContactsProvider> */}
</ScreenWrapper>
);
}
Expand Down
1 change: 1 addition & 0 deletions apps/tlon-mobile/src/lib/nativeDb.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ export async function purgeDb() {
client = null;
logger.log('purged sqlite database, recreating');
setupDb();
runMigrations();
}

export function getDbPath() {
Expand Down
17 changes: 17 additions & 0 deletions apps/tlon-mobile/src/screens/ProfileScreen.tsx
Original file line number Diff line number Diff line change
@@ -1,23 +1,40 @@
import { NativeStackScreenProps } from '@react-navigation/native-stack';
import * as api from '@tloncorp/shared/dist/api';
import * as store from '@tloncorp/shared/dist/store';
import { ProfileScreenView, View } from '@tloncorp/ui';
import { useCallback } from 'react';

import { clearShipInfo, useShip } from '../contexts/ship';
import { useCurrentUserId } from '../hooks/useCurrentUser';
import { purgeDb } from '../lib/nativeDb';
import NavBar from '../navigation/NavBarView';
import { SettingsStackParamList } from '../types';
import { removeHostingToken, removeHostingUserId } from '../utils/hosting';

type Props = NativeStackScreenProps<SettingsStackParamList, 'Profile'>;

export default function ProfileScreen(props: Props) {
const { clearShip } = useShip();
const currentUserId = useCurrentUserId();
const { data: contacts } = store.useContacts();

const handleLogout = useCallback(async () => {
await purgeDb();
api.queryClient.clear();
api.removeUrbitClient();
clearShip();
clearShipInfo();
removeHostingToken();
removeHostingUserId();
}, [clearShip]);

return (
<View backgroundColor="$background" flex={1}>
<ProfileScreenView
contacts={contacts ?? []}
currentUserId={currentUserId}
onAppSettingsPressed={() => props.navigation.navigate('FeatureFlags')}
handleLogout={handleLogout}
/>
<NavBar navigation={props.navigation} />
</View>
Expand Down
55 changes: 31 additions & 24 deletions packages/ui/src/components/AddChats/AddDmSheet.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
import { QueryClientProvider, queryClient } from '@tloncorp/shared/dist/api';
import * as store from '@tloncorp/shared/dist/store';
import { useCallback, useEffect, useState } from 'react';
import { useSafeAreaInsets } from 'react-native-safe-area-context';

import { ContactsProvider, useContacts } from '../../contexts';
import { XStack, YStack, ZStack } from '../../core';
import { triggerHaptic } from '../../utils';
import { Button } from '../Button';
Expand All @@ -18,6 +20,7 @@ export function StartDmSheet({
onOpenChange: (open: boolean) => void;
goToDm: (participants: string[]) => void;
}) {
const contacts = useContacts();
const insets = useSafeAreaInsets();
const [contentScrolling, setContentScrolling] = useState(false);
const [dmParticipants, setDmParticipants] = useState<string[]>([]);
Expand Down Expand Up @@ -60,31 +63,35 @@ export function StartDmSheet({
>
<Sheet.Overlay />
<Sheet.LazyFrame paddingTop="$s" paddingHorizontal="$2xl">
<Sheet.Handle marginBottom="$l" />
<ZStack flex={1}>
<YStack flex={1} gap="$2xl">
<ContactBook
key={contactBookKey}
multiSelect
onSelectedChange={setDmParticipants}
searchable
searchPlaceholder="Start a DM with..."
onScrollChange={setContentScrolling}
/>
{dmParticipants.length > 0 && (
<XStack
position="absolute"
bottom={insets.bottom + 12}
justifyContent="center"
>
<StartDMButton
participants={dmParticipants}
onPress={handleGoToDm}
<QueryClientProvider client={queryClient}>
<ContactsProvider contacts={contacts ?? null}>
<Sheet.Handle marginBottom="$l" />
<ZStack flex={1}>
<YStack flex={1} gap="$2xl">
<ContactBook
key={contactBookKey}
multiSelect
onSelectedChange={setDmParticipants}
searchable
searchPlaceholder="Start a DM with..."
onScrollChange={setContentScrolling}
/>
</XStack>
)}
</YStack>
</ZStack>
{dmParticipants.length > 0 && (
<XStack
position="absolute"
bottom={insets.bottom + 12}
justifyContent="center"
>
<StartDMButton
participants={dmParticipants}
onPress={handleGoToDm}
/>
</XStack>
)}
</YStack>
</ZStack>
</ContactsProvider>
</QueryClientProvider>
</Sheet.LazyFrame>
</Sheet>
);
Expand Down
14 changes: 13 additions & 1 deletion packages/ui/src/components/Channel/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import { UploadInfo } from '@tloncorp/shared/dist/api';
import * as db from '@tloncorp/shared/dist/db';
import { JSONContent, Story } from '@tloncorp/shared/dist/urbit';
import { useCallback, useMemo, useState } from 'react';
import { Platform } from 'react-native';
import { useSafeAreaInsets } from 'react-native-safe-area-context';
import { AnimatePresence } from 'tamagui';

Expand Down Expand Up @@ -125,7 +126,18 @@ export function Channel({
? NotebookPost
: GalleryPost;
const renderEmptyComponent = useCallback(() => {
return <EmptyChannelNotice channel={channel} userId={currentUserId} />;
return (
<View
// hack to fix inverted Flatlist empty component being erroneously rotated on Android
style={
Platform.OS === 'android'
? { transform: [{ rotateY: '180deg' }] }
: {}
}
>
<EmptyChannelNotice channel={channel} userId={currentUserId} />
</View>
);
}, [currentUserId, channel]);

const onPressGroupRef = useCallback((group: db.Group) => {
Expand Down
26 changes: 24 additions & 2 deletions packages/ui/src/components/ProfileScreenView.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import * as db from '@tloncorp/shared/dist/db';
import { PropsWithChildren } from 'react';
import { Dimensions, ImageBackground } from 'react-native';
import { Alert, Dimensions, ImageBackground } from 'react-native';
import { useSafeAreaInsets } from 'react-native-safe-area-context';
import { ScrollView, XStack, getTokens } from 'tamagui';

Expand All @@ -14,6 +14,7 @@ import { ListItem } from './ListItem';
interface Props {
currentUserId: string;
onAppSettingsPressed?: () => void;
handleLogout: () => void;
}

export function ProfileScreenView({
Expand All @@ -31,6 +32,19 @@ export function Wrapped(props: Props) {
const { top } = useSafeAreaInsets();
const contact = useContact(props.currentUserId);

const onLogoutPress = () => {
Alert.alert('Log out', 'Are you sure you want to log out?', [
{
text: 'Cancel',
style: 'cancel',
},
{
text: 'Log out',
onPress: props.handleLogout,
},
]);
};

return (
<ScrollView>
<YStack flex={1} paddingHorizontal="$xl" paddingTop={top}>
Expand All @@ -52,6 +66,12 @@ export function Wrapped(props: Props) {
icon="Settings"
onPress={props.onAppSettingsPressed}
/>
<ProfileAction
title="Log Out"
icon="LogOut"
hideCaret
onPress={onLogoutPress}
/>
</View>
</YStack>
</ScrollView>
Expand Down Expand Up @@ -138,10 +158,12 @@ function ProfileRow({
function ProfileAction({
icon,
title,
hideCaret,
onPress,
}: {
icon: IconType;
title: string;
hideCaret?: boolean;
onPress?: () => void;
}) {
return (
Expand All @@ -154,7 +176,7 @@ function ProfileAction({
<ListItem.MainContent>
<ListItem.Title>{title}</ListItem.Title>
</ListItem.MainContent>
<ListItem.Icon icon="ChevronRight" />
{!hideCaret && <ListItem.Icon icon="ChevronRight" />}
</ListItem>
);
}