diff --git a/data/resources/resources.gresource.xml b/data/resources/resources.gresource.xml
index 813d0a75..2ac70f3f 100644
--- a/data/resources/resources.gresource.xml
+++ b/data/resources/resources.gresource.xml
@@ -20,6 +20,7 @@
ui/components-audio-player.ui
ui/components-auth-dialog.ui
ui/components-avatar.ui
+ ui/components-editable-avatar.ui
ui/components-loading-listbox-row.ui
ui/components-reaction-chooser.ui
ui/components-video-player.ui
diff --git a/data/resources/ui/components-editable-avatar.ui b/data/resources/ui/components-editable-avatar.ui
new file mode 100644
index 00000000..9c8e48ae
--- /dev/null
+++ b/data/resources/ui/components-editable-avatar.ui
@@ -0,0 +1,81 @@
+
+
+
+
+
+
+
+
diff --git a/po/POTFILES.in b/po/POTFILES.in
index fcb9078a..81faf3cb 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -37,6 +37,7 @@ data/resources/ui/qr-code-scanner.ui
# Rust files
src/application.rs
+src/components/editable_avatar.rs
src/login.rs
src/secret.rs
src/session/account_settings/devices_page/device_list.rs
diff --git a/src/components/editable_avatar.rs b/src/components/editable_avatar.rs
new file mode 100644
index 00000000..76ca6848
--- /dev/null
+++ b/src/components/editable_avatar.rs
@@ -0,0 +1,417 @@
+use adw::subclass::prelude::*;
+use gettextrs::gettext;
+use gtk::{
+ gdk, gio, glib,
+ glib::{clone, closure_local},
+ prelude::*,
+ subclass::prelude::*,
+ CompositeTemplate,
+};
+use log::error;
+
+use super::{ActionButton, ActionState};
+use crate::{session::Avatar, spawn};
+
+mod imp {
+ use std::cell::{Cell, RefCell};
+
+ use glib::subclass::{InitializingObject, Signal};
+ use once_cell::sync::Lazy;
+
+ use super::*;
+
+ #[derive(Debug, Default, CompositeTemplate)]
+ #[template(resource = "/org/gnome/FractalNext/components-editable-avatar.ui")]
+ pub struct EditableAvatar {
+ /// The avatar to display.
+ pub avatar: RefCell