From e592e59f4e339aff48589ba7a6f93209bf31d026 Mon Sep 17 00:00:00 2001 From: Ansh Date: Thu, 2 Mar 2023 16:53:18 -0800 Subject: [PATCH] 72-delete-avatar-and-cover (#255) * allow to delete profile pic * allow for removing banner --- src/state/models/profile-view.ts | 12 ++++++++---- src/view/com/modals/EditProfile.tsx | 27 +++++++++++++++++++++------ src/view/com/util/UserAvatar.tsx | 17 ++++++++--------- src/view/com/util/UserBanner.tsx | 17 ++++++++--------- 4 files changed, 45 insertions(+), 28 deletions(-) diff --git a/src/state/models/profile-view.ts b/src/state/models/profile-view.ts index 0988367b..a6854801 100644 --- a/src/state/models/profile-view.ts +++ b/src/state/models/profile-view.ts @@ -2,8 +2,8 @@ import {makeAutoObservable, runInAction} from 'mobx' import {PickedMedia} from 'lib/media/picker' import { AppBskyActorGetProfile as GetProfile, - AppBskyActorProfile as Profile, AppBskySystemDeclRef, + AppBskyActorUpdateProfile, } from '@atproto/api' type DeclRef = AppBskySystemDeclRef.Main import {extractEntities} from 'lib/strings/rich-text-detection' @@ -132,9 +132,9 @@ export class ProfileViewModel { } async updateProfile( - updates: Profile.Record, - newUserAvatar: PickedMedia | undefined, - newUserBanner: PickedMedia | undefined, + updates: AppBskyActorUpdateProfile.InputSchema, + newUserAvatar: PickedMedia | undefined | null, + newUserBanner: PickedMedia | undefined | null, ) { if (newUserAvatar) { const res = await apilib.uploadBlob( @@ -146,6 +146,8 @@ export class ProfileViewModel { cid: res.data.cid, mimeType: newUserAvatar.mime, } + } else { + updates.avatar = null } if (newUserBanner) { const res = await apilib.uploadBlob( @@ -157,6 +159,8 @@ export class ProfileViewModel { cid: res.data.cid, mimeType: newUserBanner.mime, } + } else { + updates.banner = null } await this.rootStore.api.app.bsky.actor.updateProfile(updates) await this.rootStore.me.load() diff --git a/src/view/com/modals/EditProfile.tsx b/src/view/com/modals/EditProfile.tsx index 052681fd..121831ad 100644 --- a/src/view/com/modals/EditProfile.tsx +++ b/src/view/com/modals/EditProfile.tsx @@ -44,20 +44,30 @@ export function Component({ const [description, setDescription] = useState( profileView.description || '', ) - const [userBanner, setUserBanner] = useState( + const [userBanner, setUserBanner] = useState( profileView.banner, ) - const [userAvatar, setUserAvatar] = useState( + const [userAvatar, setUserAvatar] = useState( profileView.avatar, ) - const [newUserBanner, setNewUserBanner] = useState() - const [newUserAvatar, setNewUserAvatar] = useState() + const [newUserBanner, setNewUserBanner] = useState< + PickedMedia | undefined | null + >() + const [newUserAvatar, setNewUserAvatar] = useState< + PickedMedia | undefined | null + >() const onPressCancel = () => { store.shell.closeModal() } - const onSelectNewAvatar = async (img: PickedMedia) => { + const onSelectNewAvatar = async (img: PickedMedia | null) => { track('EditProfile:AvatarSelected') try { + // if img is null, user selected "remove avatar" + if (!img) { + setNewUserAvatar(null) + setUserAvatar(null) + return + } const finalImg = await compressIfNeeded(img, 1000000) setNewUserAvatar({mediaType: 'photo', ...finalImg}) setUserAvatar(finalImg.path) @@ -65,7 +75,12 @@ export function Component({ setError(cleanError(e)) } } - const onSelectNewBanner = async (img: PickedMedia) => { + const onSelectNewBanner = async (img: PickedMedia | null) => { + if (!img) { + setNewUserBanner(null) + setUserBanner(null) + return + } track('EditProfile:BannerSelected') try { const finalImg = await compressIfNeeded(img, 1000000) diff --git a/src/view/com/util/UserAvatar.tsx b/src/view/com/util/UserAvatar.tsx index 5a7a4801..d0d2c273 100644 --- a/src/view/com/util/UserAvatar.tsx +++ b/src/view/com/util/UserAvatar.tsx @@ -31,7 +31,7 @@ export function UserAvatar({ handle: string displayName: string | undefined avatar?: string | null - onSelectNewAvatar?: (img: PickedMedia) => void + onSelectNewAvatar?: (img: PickedMedia | null) => void }) { const store = useStores() const pal = usePalette('default') @@ -97,14 +97,13 @@ export function UserAvatar({ ) }, }, - // TODO: Remove avatar https://github.com/bluesky-social/social-app/issues/122 - // { - // label: 'Remove', - // icon: ['far', 'trash-can'], - // onPress: () => { - // // Remove avatar API call - // }, - // }, + { + label: 'Remove', + icon: ['far', 'trash-can'] as IconProp, + onPress: async () => { + onSelectNewAvatar?.(null) + }, + }, ] // onSelectNewAvatar is only passed as prop on the EditProfile component return onSelectNewAvatar ? ( diff --git a/src/view/com/util/UserBanner.tsx b/src/view/com/util/UserBanner.tsx index 06a80d45..16e05311 100644 --- a/src/view/com/util/UserBanner.tsx +++ b/src/view/com/util/UserBanner.tsx @@ -25,7 +25,7 @@ export function UserBanner({ onSelectNewBanner, }: { banner?: string | null - onSelectNewBanner?: (img: PickedMedia) => void + onSelectNewBanner?: (img: PickedMedia | null) => void }) { const store = useStores() const pal = usePalette('default') @@ -70,14 +70,13 @@ export function UserBanner({ ) }, }, - // TODO: Remove banner https://github.com/bluesky-social/social-app/issues/122 - // { - // label: 'Remove', - // icon: ['far', 'trash-can'], - // onPress: () => { - // // Remove banner api call - // }, - // }, + { + label: 'Remove', + icon: ['far', 'trash-can'] as IconProp, + onPress: () => { + onSelectNewBanner?.(null) + }, + }, ] const renderSvg = () => (