Skip to content

Commit

Permalink
logic fixes
Browse files Browse the repository at this point in the history
  • Loading branch information
latter-bolden committed Nov 20, 2024
1 parent 4709fa6 commit 7737184
Show file tree
Hide file tree
Showing 12 changed files with 255 additions and 64 deletions.
8 changes: 7 additions & 1 deletion packages/app/features/top/ChatListScreen.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import {
ScreenHeader,
View,
WelcomeSheet,
triggerHaptic,
} from '@tloncorp/ui';
import { useCallback, useEffect, useMemo, useRef, useState } from 'react';

Expand Down Expand Up @@ -283,6 +284,11 @@ export function ChatListScreenView({
setShowSearchInput(!showSearchInput);
}, [showSearchInput]);

const goToContacts = useCallback(() => {
triggerHaptic('baseButtonClick');
navigation.navigate('Contacts');
}, [navigation]);

return (
<RequestsProvider
usePostReference={store.usePostReference}
Expand All @@ -306,7 +312,7 @@ export function ChatListScreenView({
leftControls={
<ScreenHeader.IconButton
type="ChannelMultiDM"
onPress={() => navigation.navigate('Contacts')}
onPress={goToContacts}
/>
}
rightControls={
Expand Down
14 changes: 14 additions & 0 deletions packages/app/features/top/UserProfileScreen.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import * as store from '@tloncorp/shared/store';
import {
AppDataContextProvider,
AttachmentProvider,
GroupPreviewAction,
GroupPreviewSheet,
NavigationProvider,
UserProfileScreenView,
Expand All @@ -12,6 +13,7 @@ import { useState } from 'react';
import { useCallback } from 'react';

import { useCurrentUserId } from '../../hooks/useCurrentUser';
import { useGroupActions } from '../../hooks/useGroupActions';
import { RootStackParamList } from '../../navigation/types';
import { useResetToDm } from '../../navigation/utils';
import { useConnectionStatus } from './useConnectionStatus';
Expand All @@ -20,10 +22,21 @@ type Props = NativeStackScreenProps<RootStackParamList, 'UserProfile'>;

export function UserProfileScreen({ route: { params }, navigation }: Props) {
const userId = params.userId;
const { performGroupAction } = useGroupActions();
const currentUserId = useCurrentUserId();
const { data: contacts } = store.useContacts();
const connectionStatus = useConnectionStatus(userId);
const [selectedGroup, setSelectedGroup] = useState<db.Group | null>(null);

const handleGroupAction = useCallback(
(action: GroupPreviewAction, group: db.Group) => {
setSelectedGroup(null);
setTimeout(() => {
performGroupAction(action, group);
}, 100);
},
[performGroupAction]
);
const resetToDm = useResetToDm();

const handleGoToDm = useCallback(
Expand Down Expand Up @@ -67,6 +80,7 @@ export function UserProfileScreen({ route: { params }, navigation }: Props) {
open={selectedGroup !== null}
onOpenChange={handleGroupPreviewSheetOpenChange}
group={selectedGroup ?? undefined}
onActionComplete={handleGroupAction}
/>
</AttachmentProvider>
</NavigationProvider>
Expand Down
27 changes: 22 additions & 5 deletions packages/shared/src/api/contactsApi.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import * as db from '../db';
import { createDevLogger } from '../debug';
import { AnalyticsEvent, normalizeUrbitColor } from '../logic';
import * as ub from '../urbit';
import { poke, scry, subscribe } from './urbit';
import { getCurrentUserId, poke, scry, subscribe } from './urbit';

const logger = createDevLogger('contactsApi', true);

Expand Down Expand Up @@ -105,16 +105,16 @@ export const removeContact = async (contactId: string) => {
};

export interface ProfileUpdate {
nickname?: string;
nickname?: string | null;
status?: string;
bio?: string;
avatarImage?: string;
avatarImage?: string | null;
coverImage?: string;
}
export const updateCurrentUserProfile = async (update: ProfileUpdate) => {
const editedFields: ub.ContactEditField[] = [];
if (update.nickname !== undefined) {
editedFields.push({ nickname: update.nickname });
editedFields.push({ nickname: update.nickname ?? '' });
}

if (update.status !== undefined) {
Expand All @@ -126,7 +126,7 @@ export const updateCurrentUserProfile = async (update: ProfileUpdate) => {
}

if (update.avatarImage !== undefined) {
editedFields.push({ avatar: update.avatarImage });
editedFields.push({ avatar: update.avatarImage ?? '' });
}

if (update.coverImage !== undefined) {
Expand Down Expand Up @@ -162,6 +162,23 @@ export const removePinnedGroup = async (groupId: string) => {
});
};

export const setPinnedGroups = async (groupIds: string[]) => {
console.log(`api set pinned`, groupIds);
const contactUpdate: ub.ContactBookProfileEdit = {};
contactUpdate.groups = {
type: 'set',
value: groupIds.map((groupId) => ({ type: 'flag', value: groupId })),
};

console.log(`contact-action-1`, { self: { contact: contactUpdate } });

return poke({
app: 'contacts',
mark: 'contact-action-1',
json: { self: contactUpdate },
});
};

export type ContactsUpdate =
| { type: 'upsertContact'; contact: db.Contact }
| { type: 'removeContact'; contactId: string };
Expand Down
20 changes: 20 additions & 0 deletions packages/shared/src/db/queries.ts
Original file line number Diff line number Diff line change
Expand Up @@ -359,6 +359,7 @@ export const getChats = createReadQuery(
'groups',
'channels',
'posts',
'contacts',
'channelUnreads',
'groupUnreads',
'threadUnreads',
Expand Down Expand Up @@ -2791,6 +2792,25 @@ export const removePinnedGroup = createWriteQuery(
['contactGroups', 'contacts']
);

export const setPinnedGroups = createWriteQuery(
'setPinnedGroups',
async ({ groupIds }: { groupIds: string[] }, ctx: QueryCtx) => {
const currentUserId = getCurrentUserId();
await ctx.db
.delete($contactGroups)
.where(eq($contactGroups.contactId, currentUserId));

if (groupIds.length !== 0) {
const newGroups = groupIds.map((groupId) => ({
contactId: currentUserId,
groupId,
}));
await ctx.db.insert($contactGroups).values(newGroups);
}
},
['contactGroups', 'contacts']
);

export const insertContact = createWriteQuery(
'insertContact',
async (contact: Contact, ctx: QueryCtx) => {
Expand Down
65 changes: 17 additions & 48 deletions packages/shared/src/store/contactActions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,8 +50,8 @@ export async function removeContactSuggestion(contactId: string) {
export async function updateContactMetadata(
contactId: string,
metadata: {
nickname?: string;
avatarImage?: string;
nickname?: string | null;
avatarImage?: string | null;
}
) {
const { nickname, avatarImage } = metadata;
Expand All @@ -61,28 +61,16 @@ export async function updateContactMetadata(
// optimistic update
await db.updateContact({
id: contactId,
customNickname: nickname
? nickname
: existingContact?.customNickname
? ''
: undefined,
customAvatarImage: avatarImage
? avatarImage
: existingContact?.customAvatarImage
? ''
: undefined,
customNickname: nickname,
customAvatarImage: avatarImage,
});

try {
await api.updateContactMetadata(contactId, {
nickname: nickname
? nickname
: existingContact?.customNickname
? ''
: undefined,
nickname: nickname ? nickname : nickname === null ? '' : undefined,
avatarImage: avatarImage
? avatarImage
: existingContact?.customAvatarImage
: avatarImage === null
? ''
: undefined,
});
Expand Down Expand Up @@ -154,37 +142,18 @@ export async function removePinnedGroupFromProfile(groupId: string) {

export async function updateProfilePinnedGroups(newPinned: db.Group[]) {
const currentUserId = api.getCurrentUserId();
const currentUserContact = await db.getContact({ id: currentUserId });
const startingPinnedIds =
currentUserContact?.pinnedGroups.map((pg) => pg.groupId) ?? [];
const existingContact = await db.getContact({ id: currentUserId });
const existingPinnedIds =
existingContact?.pinnedGroups.map((pg) => pg.groupId) ?? [];
const newPinnedIds = newPinned.map((g) => g.id);

const additions = [];
const deletions = [];
// Optimistic update TODO
await db.setPinnedGroups({ groupIds: newPinnedIds });

for (const group of newPinned) {
if (!startingPinnedIds.includes(group.id)) {
additions.push(group.id);
}
}

for (const groupId of startingPinnedIds) {
if (!newPinned.find((g) => g.id === groupId)) {
deletions.push(groupId);
}
try {
await api.setPinnedGroups(newPinnedIds);
} catch (e) {
// Rollback the update
await db.setPinnedGroups({ groupIds: existingPinnedIds });
}

logger.log(
'Updating pinned groups [additions, deletions]',
additions,
deletions
);

const additionPromises = additions.map((groupId) =>
addPinnedGroupToProfile(groupId)
);
const deletionPromises = deletions.map((groupId) =>
removePinnedGroupFromProfile(groupId)
);

return Promise.all([...additionPromises, ...deletionPromises]);
}
1 change: 1 addition & 0 deletions packages/shared/src/store/sync.ts
Original file line number Diff line number Diff line change
Expand Up @@ -954,6 +954,7 @@ export async function syncGroupPreviews(groupIds: string[]) {
}

const groupPreview = await api.getGroupPreview(groupId);
console.log(`got preview for ${groupId}`, groupPreview);
await db.insertUnjoinedGroups([groupPreview]);
return groupPreview;
});
Expand Down
4 changes: 1 addition & 3 deletions packages/ui/src/components/ActionSheet.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -180,9 +180,7 @@ const ActionSheetHeader = ActionSheetHeaderFrame.styleable(
({ children, ...props }, ref) => {
return (
<ActionSheetHeaderFrame {...props} ref={ref}>
<ListItem paddingHorizontal="$2xl">
{children}
</ListItem>
<ListItem paddingHorizontal="$2xl">{children}</ListItem>
</ActionSheetHeaderFrame>
);
}
Expand Down
40 changes: 36 additions & 4 deletions packages/ui/src/components/EditProfileScreenView.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ export function EditProfileScreenView(props: Props) {
const nicknamePlaceholder = useMemo(() => {
return props.userId === currentUserId
? userContact?.id
: userContact?.nickname ?? userContact?.id;
: userContact?.peerNickname ?? userContact?.id;
}, [props.userId, currentUserId, userContact]);

const currentAvatarImage = useMemo(() => {
Expand All @@ -60,7 +60,7 @@ export function EditProfileScreenView(props: Props) {
const avatarPlaceholder = useMemo(() => {
return props.userId === currentUserId
? undefined
: userContact?.avatarImage ?? undefined;
: userContact?.peerAvatarImage ?? undefined;
}, [props.userId, currentUserId, userContact]);

const {
Expand All @@ -80,12 +80,44 @@ export function EditProfileScreenView(props: Props) {
const handlePressDone = useCallback(() => {
if (isDirty) {
handleSubmit((formData) => {
props.onSaveProfile(formData);
const nicknameStartVal =
props.userId === currentUserId
? userContact?.nickname
: userContact?.customNickname;
const avatarStartVal =
props.userId === currentUserId
? userContact?.avatarImage
: userContact?.customAvatarImage;

const update = {
status: formData.status,
bio: formData.bio,
nickname: formData.nickname
? formData.nickname
: nicknameStartVal
? null // clear existing
: undefined,
avatarImage: formData.avatarImage
? formData.avatarImage
: avatarStartVal
? null // clear existing
: undefined,
};
props.onSaveProfile(update);
})();
} else {
props.onGoBack();
}
}, [handleSubmit, isDirty, props]);
}, [
currentUserId,
handleSubmit,
isDirty,
props,
userContact?.avatarImage,
userContact?.customAvatarImage,
userContact?.customNickname,
userContact?.nickname,
]);

const handlePressCancel = () => {
if (isDirty) {
Expand Down
3 changes: 3 additions & 0 deletions packages/ui/src/components/NavBar/NavIcon.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,18 @@ export function AvatarNavIcon({
id,
focused,
onPress,
onLongPress,
}: {
id: string;
focused: boolean;
onPress?: () => void;
onLongPress?: () => void;
}) {
return (
<Pressable
flex={1}
onPress={onPress}
onLongPress={onLongPress}
alignItems="center"
paddingTop={'$s'}
pressStyle={{ backgroundColor: 'unset' }}
Expand Down
Loading

0 comments on commit 7737184

Please sign in to comment.