diff --git a/src/state/models/profile-view.ts b/src/state/models/profile-view.ts index 787e69e3..9b32c874 100644 --- a/src/state/models/profile-view.ts +++ b/src/state/models/profile-view.ts @@ -39,15 +39,13 @@ export class ProfileViewModel { displayName?: string description?: string avatar?: string + banner?: string followersCount: number = 0 followsCount: number = 0 membersCount: number = 0 postsCount: number = 0 myState = new ProfileViewMyStateModel() - // TODO TEMP data to be implemented in the protocol - userBanner: string | null = null - // added data descriptionEntities?: Entity[] @@ -123,11 +121,8 @@ export class ProfileViewModel { async updateProfile( updates: Profile.Record, newUserAvatar: PickedImage | undefined, - userBanner: string | null, // TODO TEMP + newUserBanner: PickedImage | undefined, ) { - // TODO TEMP add userBanner to the protocol when suported - this.userBanner = userBanner - if (newUserAvatar) { const res = await this.rootStore.api.com.atproto.blob.upload( newUserAvatar.path, // this will be special-cased by the fetch monkeypatch in /src/state/lib/api.ts @@ -140,6 +135,18 @@ export class ProfileViewModel { mimeType: newUserAvatar.mime, } } + if (newUserBanner) { + const res = await this.rootStore.api.com.atproto.blob.upload( + newUserBanner.path, // this will be special-cased by the fetch monkeypatch in /src/state/lib/api.ts + { + encoding: newUserBanner.mime, + }, + ) + updates.banner = { + cid: res.data.cid, + mimeType: newUserBanner.mime, + } + } await this.rootStore.api.app.bsky.actor.updateProfile(updates) await this.rootStore.me.load() await this.refresh() @@ -187,6 +194,7 @@ export class ProfileViewModel { this.displayName = res.data.displayName this.description = res.data.description this.avatar = res.data.avatar + this.banner = res.data.banner this.followersCount = res.data.followersCount this.followsCount = res.data.followsCount this.membersCount = res.data.membersCount diff --git a/src/view/com/modals/EditProfile.tsx b/src/view/com/modals/EditProfile.tsx index cf89f182..dcb0ba83 100644 --- a/src/view/com/modals/EditProfile.tsx +++ b/src/view/com/modals/EditProfile.tsx @@ -41,12 +41,13 @@ export function Component({ const [description, setDescription] = useState( profileView.description || '', ) - const [userBanner, setUserBanner] = useState( - profileView.userBanner, + const [userBanner, setUserBanner] = useState( + profileView.banner, ) const [userAvatar, setUserAvatar] = useState( profileView.avatar, ) + const [newUserBanner, setNewUserBanner] = useState() const [newUserAvatar, setNewUserAvatar] = useState() const onPressCancel = () => { store.shell.closeModal() @@ -55,6 +56,10 @@ export function Component({ setNewUserAvatar(img) setUserAvatar(img.path) } + const onSelectNewBanner = (img: PickedImage) => { + setNewUserBanner(img) + setUserBanner(img.path) + } const onPressSave = async () => { setProcessing(true) if (error) { @@ -67,7 +72,7 @@ export function Component({ description, }, newUserAvatar, - userBanner, // TEMP + newUserBanner, ) Toast.show('Profile updated') onUpdate?.() @@ -90,8 +95,8 @@ export function Component({ Edit my profile diff --git a/src/view/com/profile/ProfileHeader.tsx b/src/view/com/profile/ProfileHeader.tsx index fb31c184..eb0a7477 100644 --- a/src/view/com/profile/ProfileHeader.tsx +++ b/src/view/com/profile/ProfileHeader.tsx @@ -152,7 +152,7 @@ export const ProfileHeader = observer(function ProfileHeader({ } return ( - + > + banner?: string | null + onSelectNewBanner?: (img: PickedImage) => void }) { const gradient = getGradient(handle) @@ -30,13 +30,14 @@ export function UserBanner({ openCamera({ mediaType: 'photo', cropping: true, + compressImageMaxWidth: 1500, width: 1500, + compressImageMaxHeight: 500, height: 500, - }).then(item => { - if (setUserBanner != null) { - setUserBanner(item.path) - } - }) + forceJpg: true, // ios only + compressImageQuality: 0.4, + includeExif: true, + }).then(onSelectNewBanner) }, }, { @@ -48,18 +49,19 @@ export function UserBanner({ await openCropper({ mediaType: 'photo', path: item.path, + compressImageMaxWidth: 1500, width: 1500, + compressImageMaxHeight: 500, height: 500, - }).then(croppedItem => { - if (setUserBanner != null) { - setUserBanner(croppedItem.path) - } - }) + forceJpg: true, // ios only + compressImageQuality: 0.4, + includeExif: true, + }).then(onSelectNewBanner) }) }, }, ]) - }, [setUserBanner]) + }, [onSelectNewBanner]) const renderSvg = () => ( @@ -79,10 +81,10 @@ export function UserBanner({ ) // setUserBanner is only passed as prop on the EditProfile component - return setUserBanner != null && IMAGES_ENABLED ? ( + return onSelectNewBanner ? ( - {userBanner ? ( - + {banner ? ( + ) : ( renderSvg() )} @@ -94,11 +96,11 @@ export function UserBanner({ /> - ) : userBanner ? ( + ) : banner ? ( ) : ( renderSvg()