@@ -20,6 +20,7 @@ import { type OperationParams, type ResultFor } from '../../definitions/rest/hel
2020import { type SubscriptionsEndpoints } from '../../definitions/rest/v1/subscriptions' ;
2121import { Encryption } from '../encryption' ;
2222import { type RoomTypes , roomTypeToApiType } from '../methods/roomTypeToApiType' ;
23+ import { uploadUserAvatarMultipart } from '../methods/uploadAvatar/uploadAvatar' ;
2324import { unsubscribeRooms } from '../methods/subscribeRooms' ;
2425import { compareServerVersion , getBundleId , isIOS } from '../methods/helpers' ;
2526import { getDeviceToken } from '../notifications' ;
@@ -721,17 +722,49 @@ export const resetAvatar = (userId: string) =>
721722 // RC 0.55.0
722723 sdk . post ( 'users.resetAvatar' , { userId } ) ;
723724
724- export const setAvatarFromService = ( {
725+ const isHttpAvatarUrl = ( value : string | undefined ) : value is string =>
726+ typeof value === 'string' && ( value . startsWith ( 'http://' ) || value . startsWith ( 'https://' ) ) ;
727+
728+ export const setAvatarFromService = async ( {
725729 data,
726730 contentType = '' ,
727- service = null
731+ service = null ,
732+ url
728733} : {
729734 data : any ;
730735 contentType ?: string ;
731736 service ?: string | null ;
732- } ) : Promise < void > =>
733- // RC 0.51.0
734- sdk . methodCallWrapper ( 'setAvatarFromService' , data , contentType , service ) ;
737+ url ?: string ;
738+ } ) : Promise < void > => {
739+ const serverVersion = reduxStore . getState ( ) . server . version ;
740+ const isHttpUrl = isHttpAvatarUrl ( url ) ;
741+ // In ChangeAvatarView, `url` can be:
742+ // - a remote http(s) URL from "Fetch image from URL"
743+ // - a local filesystem URI/path from camera/gallery upload (`response.path`)
744+ // Only remote URLs should be sent as `avatarUrl`; local paths must go through multipart upload.
745+ // RC 0.51.0 — keep DDP + payload shape unchanged below 8.0.0
746+ if ( compareServerVersion ( serverVersion , 'lowerThan' , '8.0.0' ) ) {
747+ return sdk . methodCallWrapper ( 'setAvatarFromService' , data , contentType , service ) ;
748+ }
749+
750+ // RC 8.0.0 — REST users.setAvatar (multipart image or JSON avatarUrl)
751+ if ( service === 'url' && typeof data === 'string' ) {
752+ await sdk . post ( 'users.setAvatar' , { avatarUrl : data } ) ;
753+ return ;
754+ }
755+
756+ if ( service === 'upload' && url && ! isHttpUrl ) {
757+ await uploadUserAvatarMultipart ( url , contentType || 'image/jpeg' , 'avatar.jpg' ) ;
758+ return ;
759+ }
760+
761+ if ( isHttpUrl ) {
762+ await sdk . post ( 'users.setAvatar' , { avatarUrl : url } ) ;
763+ return ;
764+ }
765+
766+ throw new Error ( 'Invalid avatar payload' ) ;
767+ } ;
735768
736769export const getUsernameSuggestion = ( ) =>
737770 // RC 0.65.0
0 commit comments