Skip to content

Commit 7056dc0

Browse files
committed
Expose user avatar URL field in the UI
To be able to change a avatar the URL field needs to be exposed but changing the URL alone is difficult. This patch adds a image upload field to the edit view of a user. If there is a file detected it uploads it to the servers media repository and sets that new URL as the avatar URL one. This way a admin can change any users avatar which is especially nice for bridged users like in the IRC bridge and bots.
1 parent 1f56bac commit 7056dc0

2 files changed

Lines changed: 38 additions & 6 deletions

File tree

src/components/users.js

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,8 @@ import {
3636
ExportButton,
3737
TopToolbar,
3838
sanitizeListRestProps,
39+
ImageInput,
40+
ImageField,
3941
} from "react-admin";
4042
import { ServerNoticeButton, ServerNoticeBulkButton } from "./ServerNotices";
4143
import { DeviceRemoveButton } from "./devices";
@@ -221,6 +223,9 @@ export const UserEdit = props => {
221223
<TextInput source="id" disabled />
222224
<TextInput source="displayname" />
223225
<PasswordInput source="password" autoComplete="new-password" />
226+
<ImageInput source="avatar_file" label="Avatar" accept="image/*">
227+
<ImageField source="avatar_src" title="Avatar" />
228+
</ImageInput>
224229
<BooleanInput source="admin" />
225230
<BooleanInput
226231
source="deactivated"

src/synapse/dataProvider.js

Lines changed: 33 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ const resourceMap = {
3232
...u,
3333
id: u.name,
3434
avatar_src: mxcUrlToHttp(u.avatar_url),
35+
avatar_url: u.avatar_url,
3536
is_guest: !!u.is_guest,
3637
admin: !!u.admin,
3738
deactivated: !!u.deactivated,
@@ -202,12 +203,38 @@ const dataProvider = {
202203
const res = resourceMap[resource];
203204

204205
const endpoint_url = homeserver + res.path;
205-
return jsonClient(`${endpoint_url}/${params.data.id}`, {
206-
method: "PUT",
207-
body: JSON.stringify(params.data, filterNullValues),
208-
}).then(({ json }) => ({
209-
data: res.map(json),
210-
}));
206+
207+
// In case there is a avatar_file object, save it in the media repository
208+
// and update the avatar_url.
209+
const f = params?.data?.avatar_file?.rawFile;
210+
if (f instanceof File) {
211+
const file_endpoint =
212+
homeserver + "/_matrix/media/r0/upload?filename=" + f.name;
213+
const headers = new Headers();
214+
headers.append("Content-Type", f.type);
215+
const options = {
216+
method: "POST",
217+
body: f,
218+
headers: headers,
219+
};
220+
return jsonClient(file_endpoint, options).then(r => {
221+
params.data.avatar_url = r.json.content_uri;
222+
223+
return jsonClient(`${endpoint_url}/${params.data.id}`, {
224+
method: "PUT",
225+
body: JSON.stringify(params.data, filterNullValues),
226+
}).then(({ json }) => ({
227+
data: res.map(json),
228+
}));
229+
});
230+
} else {
231+
return jsonClient(`${endpoint_url}/${params.data.id}`, {
232+
method: "PUT",
233+
body: JSON.stringify(params.data, filterNullValues),
234+
}).then(({ json }) => ({
235+
data: res.map(json),
236+
}));
237+
}
211238
},
212239

213240
updateMany: (resource, params) => {

0 commit comments

Comments
 (0)