diff --git a/data/resources/stylesheet/_common.scss b/data/resources/stylesheet/_common.scss index 7fe4b257..ce1a195a 100644 --- a/data/resources/stylesheet/_common.scss +++ b/data/resources/stylesheet/_common.scss @@ -32,9 +32,14 @@ headerbar .suggested-action, .standalone-button { } .form-page { - scrolledwindow > viewport > clamp > box { - margin: 42px 12px; - border-spacing: 24px; + scrolledwindow > viewport > clamp { + > * { + margin: 42px 12px; + } + + > box { + border-spacing: 24px; + } } levelbar.discrete block { @@ -77,7 +82,7 @@ button.overlaid { } .avatar-row-list { - row { + row { &:first-child { margin-top: 0px; } diff --git a/po/POTFILES.in b/po/POTFILES.in index 1a056fdb..99bfab30 100644 --- a/po/POTFILES.in +++ b/po/POTFILES.in @@ -131,6 +131,8 @@ src/session/view/content/room_details/history_viewer/file_row.rs src/session/view/content/room_details/history_viewer/file_row.blp src/session/view/content/room_details/history_viewer/file.blp src/session/view/content/room_details/history_viewer/visual_media.blp +src/session/view/content/room_details/history_visibility_subpage.blp +src/session/view/content/room_details/history_visibility_subpage.rs src/session/view/content/room_details/invite_subpage/list.rs src/session/view/content/room_details/invite_subpage/mod.rs src/session/view/content/room_details/invite_subpage/mod.blp diff --git a/src/components/rows/combo_loading_row.blp b/src/components/rows/combo_loading_row.blp deleted file mode 100644 index eaa5e224..00000000 --- a/src/components/rows/combo_loading_row.blp +++ /dev/null @@ -1,47 +0,0 @@ -using Gtk 4.0; -using Adw 1; - -template $ComboLoadingRow: Adw.ActionRow { - selectable: false; - activatable: bind template.read-only inverted; - - styles [ - "combo", - "property", - ] - - Gtk.Box arrow_box { - valign: center; - - $LoadingBin loading_bin { - child: Gtk.Image { - visible: bind template.read-only inverted; - icon-name: "pan-down-symbolic"; - accessible-role: presentation; - - styles [ - "dropdown-arrow", - ] - }; - } - - Gtk.Popover popover { - notify::visible => $popover_visible() swapped; - - styles [ - "menu", - ] - - child: Gtk.ScrolledWindow { - hscrollbar-policy: never; - max-content-height: 400; - propagate-natural-width: true; - propagate-natural-height: true; - - child: Gtk.ListBox list { - row-activated => $row_activated() swapped; - }; - }; - } - } -} diff --git a/src/components/rows/combo_loading_row.rs b/src/components/rows/combo_loading_row.rs deleted file mode 100644 index 79d31698..00000000 --- a/src/components/rows/combo_loading_row.rs +++ /dev/null @@ -1,278 +0,0 @@ -use adw::{prelude::*, subclass::prelude::*}; -use gtk::{CompositeTemplate, glib, glib::clone, pango}; - -use crate::{components::LoadingBin, utils::BoundObject}; - -mod imp { - use std::{ - cell::{Cell, RefCell}, - marker::PhantomData, - }; - - use glib::subclass::InitializingObject; - - use super::*; - - #[derive(Debug, Default, CompositeTemplate, glib::Properties)] - #[template(resource = "/org/gnome/Fractal/ui/components/rows/combo_loading_row.ui")] - #[properties(wrapper_type = super::ComboLoadingRow)] - pub struct ComboLoadingRow { - #[template_child] - loading_bin: TemplateChild, - #[template_child] - popover: TemplateChild, - #[template_child] - list: TemplateChild, - /// The string model to build the list. - #[property(get, set = Self::set_string_model, explicit_notify, nullable)] - string_model: BoundObject, - /// The position of the selected string. - #[property(get, default = gtk::INVALID_LIST_POSITION)] - selected: Cell, - /// The selected string. - #[property(get, set = Self::set_selected_string, explicit_notify, nullable)] - selected_string: RefCell>, - /// Whether the row is loading. - #[property(get = Self::is_loading, set = Self::set_is_loading)] - is_loading: PhantomData, - /// Whether the row is read-only. - #[property(get, set = Self::set_read_only, explicit_notify)] - read_only: Cell, - selected_handlers: RefCell>, - } - - #[glib::object_subclass] - impl ObjectSubclass for ComboLoadingRow { - const NAME: &'static str = "ComboLoadingRow"; - type Type = super::ComboLoadingRow; - type ParentType = adw::ActionRow; - - fn class_init(klass: &mut Self::Class) { - Self::bind_template(klass); - Self::bind_template_callbacks(klass); - - klass.set_accessible_role(gtk::AccessibleRole::ComboBox); - } - - fn instance_init(obj: &InitializingObject) { - obj.init_template(); - } - } - - #[glib::derived_properties] - impl ObjectImpl for ComboLoadingRow {} - - impl WidgetImpl for ComboLoadingRow {} - impl ListBoxRowImpl for ComboLoadingRow {} - impl PreferencesRowImpl for ComboLoadingRow {} - - impl ActionRowImpl for ComboLoadingRow { - fn activate(&self) { - if !self.is_loading() { - self.popover.popup(); - } - } - } - - #[gtk::template_callbacks] - impl ComboLoadingRow { - /// Set the string model to build the list. - fn set_string_model(&self, model: Option) { - if self.string_model.obj() == model { - return; - } - let obj = self.obj(); - - for handler in self.selected_handlers.take() { - obj.disconnect(handler); - } - self.string_model.disconnect_signals(); - - self.list.bind_model( - model.as_ref(), - clone!( - #[weak] - obj, - #[upgrade_or_else] - || { gtk::ListBoxRow::new().upcast() }, - move |item| { - let Some(item) = item.downcast_ref::() else { - return gtk::ListBoxRow::new().upcast(); - }; - - let string = item.string(); - let child = gtk::Box::new(gtk::Orientation::Horizontal, 6); - - let label = gtk::Label::builder() - .xalign(0.0) - .ellipsize(pango::EllipsizeMode::End) - .max_width_chars(40) - .valign(gtk::Align::Center) - .label(string) - .build(); - child.append(&label); - - let icon = gtk::Image::builder() - .accessible_role(gtk::AccessibleRole::Presentation) - .icon_name("object-select-symbolic") - .build(); - - let selected_handler = obj.connect_selected_string_notify(clone!( - #[weak] - label, - #[weak] - icon, - move |obj| { - let is_selected = - obj.selected_string().is_some_and(|s| s == label.label()); - let opacity = if is_selected { 1.0 } else { 0.0 }; - icon.set_opacity(opacity); - } - )); - obj.imp() - .selected_handlers - .borrow_mut() - .push(selected_handler); - - let is_selected = obj.selected_string().is_some_and(|s| s == label.label()); - let opacity = if is_selected { 1.0 } else { 0.0 }; - icon.set_opacity(opacity); - child.append(&icon); - - gtk::ListBoxRow::builder().child(&child).build().upcast() - } - ), - ); - - if let Some(model) = model { - let items_changed_handler = model.connect_items_changed(clone!( - #[weak(rename_to = imp)] - self, - move |_, _, _, _| { - imp.update_selected(); - } - )); - - self.string_model.set(model, vec![items_changed_handler]); - } - - self.update_selected(); - obj.notify_string_model(); - } - - /// Set whether the row is loading. - fn set_selected_string(&self, string: Option) { - if *self.selected_string.borrow() == string { - return; - } - let obj = self.obj(); - - obj.set_subtitle(string.as_deref().unwrap_or_default()); - self.selected_string.replace(string); - - self.update_selected(); - obj.notify_selected_string(); - } - - /// Update the position of the selected string. - fn update_selected(&self) { - let mut selected = gtk::INVALID_LIST_POSITION; - - if let Some((string_model, selected_string)) = self - .string_model - .obj() - .zip(self.selected_string.borrow().clone()) - { - for (pos, item) in string_model.iter::().enumerate() { - let Some(item) = item.ok().and_downcast::() else { - // The iterator is broken. - break; - }; - - if item.string() == selected_string { - selected = pos as u32; - break; - } - } - } - - if self.selected.get() == selected { - return; - } - - self.selected.set(selected); - self.obj().notify_selected(); - } - - /// Whether the row is loading. - fn is_loading(&self) -> bool { - self.loading_bin.is_loading() - } - - /// Set whether the row is loading. - fn set_is_loading(&self, loading: bool) { - if self.is_loading() == loading { - return; - } - - self.loading_bin.set_is_loading(loading); - self.obj().notify_is_loading(); - } - - /// Set whether the row is read-only. - fn set_read_only(&self, read_only: bool) { - if self.read_only.get() == read_only { - return; - } - let obj = self.obj(); - - self.read_only.set(read_only); - - obj.update_property(&[gtk::accessible::Property::ReadOnly(read_only)]); - obj.notify_read_only(); - } - - /// A row was activated. - #[template_callback] - fn row_activated(&self, row: >k::ListBoxRow) { - let Some(string) = row - .child() - .and_downcast::() - .and_then(|b| b.first_child()) - .and_downcast::() - .map(|l| l.label()) - else { - return; - }; - - self.popover.popdown(); - self.set_selected_string(Some(string.into())); - } - - /// The popover's visibility changed. - #[template_callback] - fn popover_visible(&self) { - let obj = self.obj(); - let is_visible = self.popover.is_visible(); - - if is_visible { - obj.add_css_class("has-open-popup"); - } else { - obj.remove_css_class("has-open-popup"); - } - } - } -} - -glib::wrapper! { - /// An `AdwActionRow` behaving like a combo box, with a loading state. - pub struct ComboLoadingRow(ObjectSubclass) - @extends gtk::Widget, gtk::ListBoxRow, adw::PreferencesRow, adw::ActionRow, - @implements gtk::Actionable, gtk::Accessible; -} - -impl ComboLoadingRow { - pub fn new() -> Self { - glib::Object::new() - } -} diff --git a/src/components/rows/mod.rs b/src/components/rows/mod.rs index 77f6afa9..a08c889d 100644 --- a/src/components/rows/mod.rs +++ b/src/components/rows/mod.rs @@ -2,7 +2,6 @@ mod button_count_row; mod check_loading_row; -mod combo_loading_row; mod copyable_row; mod entry_add_row; mod loading_button_row; @@ -13,7 +12,7 @@ mod switch_loading_row; pub use self::{ button_count_row::ButtonCountRow, check_loading_row::CheckLoadingRow, - combo_loading_row::ComboLoadingRow, copyable_row::CopyableRow, entry_add_row::EntryAddRow, - loading_button_row::LoadingButtonRow, loading_row::LoadingRow, removable_row::RemovableRow, - substring_entry_row::SubstringEntryRow, switch_loading_row::SwitchLoadingRow, + copyable_row::CopyableRow, entry_add_row::EntryAddRow, loading_button_row::LoadingButtonRow, + loading_row::LoadingRow, removable_row::RemovableRow, substring_entry_row::SubstringEntryRow, + switch_loading_row::SwitchLoadingRow, }; diff --git a/src/session/view/content/room_details/general_page.blp b/src/session/view/content/room_details/general_page.blp index b6661b42..1c1484c0 100644 --- a/src/session/view/content/room_details/general_page.blp +++ b/src/session/view/content/room_details/general_page.blp @@ -214,18 +214,14 @@ template $RoomDetailsGeneralPage: Adw.PreferencesPage { notify::is-active => $toggle_publish() swapped; } - $ComboLoadingRow history_visibility { + $ButtonCountRow history_visibility { title: _("Who Can Read History"); - notify::selected-string => $set_history_visibility() swapped; - - string-model: Gtk.StringList { - strings [ - _("Anyone, even if they are not in the room"), - _("Members only, since this option was selected"), - _("Members only, since they joined the room"), - _("Members only, since they were invited"), - ] - }; + action-name: "details.show-subpage"; + action-target: "'history-visibility'"; + + styles [ + "property", + ] } } diff --git a/src/session/view/content/room_details/general_page.rs b/src/session/view/content/room_details/general_page.rs index 917ebaf2..cc894a3b 100644 --- a/src/session/view/content/room_details/general_page.rs +++ b/src/session/view/content/room_details/general_page.rs @@ -15,7 +15,6 @@ use ruma::{ StateEventType, room::{ guest_access::{GuestAccess, RoomGuestAccessEventContent}, - history_visibility::RoomHistoryVisibilityEventContent, power_levels::PowerLevelAction, }, }, @@ -26,8 +25,7 @@ use super::{MemberRow, RoomDetails, UpgradeDialog, UpgradeInfo}; use crate::{ Window, components::{ - Avatar, ButtonCountRow, CheckLoadingRow, ComboLoadingRow, CopyableRow, LoadingButton, - SwitchLoadingRow, + Avatar, ButtonCountRow, CheckLoadingRow, CopyableRow, LoadingButton, SwitchLoadingRow, }, gettext_f, prelude::*, @@ -96,7 +94,7 @@ mod imp { #[template_child] publish: TemplateChild, #[template_child] - history_visibility: TemplateChild, + history_visibility: TemplateChild, #[template_child] encryption: TemplateChild, #[template_child] @@ -917,18 +915,15 @@ mod imp { self.update_publish().await; } - /// Update the history visibility edit button. + /// Update the history visibility row. fn update_history_visibility(&self) { let Some(room) = self.room.obj() else { return; }; - let row = &self.history_visibility; - row.set_is_loading(false); - - let visibility = room.history_visibility(); + let history_visibility = room.history_visibility(); - let text = match visibility { + let text = match history_visibility { HistoryVisibilityValue::WorldReadable => { gettext("Anyone, even if they are not in the room") } @@ -941,55 +936,16 @@ mod imp { } HistoryVisibilityValue::Unsupported => gettext("Unsupported rule"), }; - row.set_selected_string(Some(text)); - - let is_supported = visibility != HistoryVisibilityValue::Unsupported; - let can_change = room - .permissions() - .is_allowed_to(PowerLevelAction::SendState( - StateEventType::RoomHistoryVisibility, - )); - - row.set_read_only(!is_supported || !can_change); - } - - /// Set the history visibility of the room. - #[template_callback] - async fn set_history_visibility(&self) { - let Some(room) = self.room.obj() else { - return; - }; - let row = &self.history_visibility; - - let visibility = match row.selected() { - 0 => HistoryVisibilityValue::WorldReadable, - 1 => HistoryVisibilityValue::Shared, - 2 => HistoryVisibilityValue::Joined, - 3 => HistoryVisibilityValue::Invited, - _ => { - return; - } - }; + self.history_visibility.set_subtitle(&text); - if room.history_visibility() == visibility { - // Nothing to do. - return; - } - - row.set_is_loading(true); - row.set_read_only(true); - - let content = RoomHistoryVisibilityEventContent::new(visibility.into()); - - let matrix_room = room.matrix_room().clone(); - let handle = spawn_tokio!(async move { matrix_room.send_state_event(content).await }); - - if let Err(error) = handle.await.unwrap() { - error!("Could not change room history visibility: {error}"); - toast!(self.obj(), gettext("Could not change who can read history")); + let can_change = history_visibility != HistoryVisibilityValue::Unsupported + && room + .permissions() + .is_allowed_to(PowerLevelAction::SendState( + StateEventType::RoomHistoryVisibility, + )); - self.update_history_visibility(); - } + self.history_visibility.set_activatable(can_change); } /// Update the encryption row. diff --git a/src/session/view/content/room_details/history_visibility_subpage.blp b/src/session/view/content/room_details/history_visibility_subpage.blp new file mode 100644 index 00000000..a86cca45 --- /dev/null +++ b/src/session/view/content/room_details/history_visibility_subpage.blp @@ -0,0 +1,79 @@ +using Gtk 4.0; +using Adw 1; + +template $RoomDetailsHistoryVisibilitySubpage: Adw.NavigationPage { + title: _("Who Can Read History"); + + styles [ + "form-page", + ] + + child: Adw.ToolbarView { + [top] + Adw.HeaderBar { + show-back-button: false; + + [start] + Gtk.Button { + icon-name: "go-previous-symbolic"; + tooltip-text: _("Back"); + clicked => $go_back() swapped; + + styles [ + "back", + ] + } + + [end] + $LoadingButton save_button { + sensitive: bind template.changed; + content-label: _("_Save"); + use-underline: true; + clicked => $save() swapped; + + styles [ + "suggested-action", + ] + } + } + + content: Gtk.ScrolledWindow scrolled_window { + hscrollbar-policy: never; + propagate-natural-height: true; + + child: Adw.Clamp { + child: Gtk.ListBox { + valign: start; + + styles [ + "boxed-list", + ] + + $CheckLoadingRow { + title: _("Anyone, even if they are not in the room"); + action-name: "history-visibility.set-value"; + action-target: "'world-readable'"; + } + + $CheckLoadingRow { + title: _("Members only, since this option was selected"); + action-name: "history-visibility.set-value"; + action-target: "'shared'"; + } + + $CheckLoadingRow { + title: _("Members only, since they were invited"); + action-name: "history-visibility.set-value"; + action-target: "'invited'"; + } + + $CheckLoadingRow { + title: _("Members only, since they joined the room"); + action-name: "history-visibility.set-value"; + action-target: "'joined'"; + } + }; + }; + }; + }; +} diff --git a/src/session/view/content/room_details/history_visibility_subpage.rs b/src/session/view/content/room_details/history_visibility_subpage.rs new file mode 100644 index 00000000..8b439caf --- /dev/null +++ b/src/session/view/content/room_details/history_visibility_subpage.rs @@ -0,0 +1,241 @@ +use adw::{prelude::*, subclass::prelude::*}; +use gettextrs::gettext; +use gtk::{glib, glib::clone}; +use ruma::events::{ + StateEventType, + room::{history_visibility::RoomHistoryVisibilityEventContent, power_levels::PowerLevelAction}, +}; +use tracing::error; + +use crate::{ + components::{CheckLoadingRow, LoadingButton, UnsavedChangesResponse, unsaved_changes_dialog}, + session::model::{HistoryVisibilityValue, Room}, + spawn_tokio, toast, + utils::BoundObjectWeakRef, +}; + +mod imp { + use std::cell::{Cell, RefCell}; + + use glib::subclass::InitializingObject; + + use super::*; + + #[derive(Debug, Default, gtk::CompositeTemplate, glib::Properties)] + #[template( + resource = "/org/gnome/Fractal/ui/session/view/content/room_details/history_visibility_subpage.ui" + )] + #[properties(wrapper_type = super::HistoryVisibilitySubpage)] + pub struct HistoryVisibilitySubpage { + #[template_child] + save_button: TemplateChild, + /// The presented room. + #[property(get, set = Self::set_room, explicit_notify, nullable)] + room: BoundObjectWeakRef, + /// The local value of the history visibility. + #[property(get, set = Self::set_local_value, explicit_notify, builder(HistoryVisibilityValue::default()))] + local_value: Cell, + /// Whether the history visibility was changed by the user. + #[property(get)] + changed: Cell, + permissions_handler: RefCell>, + } + + #[glib::object_subclass] + impl ObjectSubclass for HistoryVisibilitySubpage { + const NAME: &'static str = "RoomDetailsHistoryVisibilitySubpage"; + type Type = super::HistoryVisibilitySubpage; + type ParentType = adw::NavigationPage; + + fn class_init(klass: &mut Self::Class) { + CheckLoadingRow::ensure_type(); + + Self::bind_template(klass); + Self::bind_template_callbacks(klass); + + klass.install_property_action("history-visibility.set-value", "local-value"); + } + + fn instance_init(obj: &InitializingObject) { + obj.init_template(); + } + } + + #[glib::derived_properties] + impl ObjectImpl for HistoryVisibilitySubpage { + fn dispose(&self) { + self.disconnect_signals(); + } + } + + impl WidgetImpl for HistoryVisibilitySubpage {} + impl NavigationPageImpl for HistoryVisibilitySubpage {} + + #[gtk::template_callbacks] + impl HistoryVisibilitySubpage { + /// Set the presented room. + fn set_room(&self, room: Option<&Room>) { + let Some(room) = room else { + // Just ignore when room is missing. + return; + }; + + self.disconnect_signals(); + + let permissions_handler = room.permissions().connect_changed(clone!( + #[weak(rename_to = imp)] + self, + move |_| { + imp.update(); + } + )); + self.permissions_handler.replace(Some(permissions_handler)); + + let history_visibility_handler = room.connect_history_visibility_notify(clone!( + #[weak(rename_to = imp)] + self, + move |_| { + imp.update(); + } + )); + + self.room.set(room, vec![history_visibility_handler]); + + self.update(); + self.obj().notify_room(); + } + + /// Update the subpage. + fn update(&self) { + let Some(room) = self.room.obj() else { + return; + }; + + self.set_local_value(room.history_visibility()); + + self.save_button.set_is_loading(false); + self.update_changed(); + } + + /// Set the local value of the history visibility. + fn set_local_value(&self, value: HistoryVisibilityValue) { + if self.local_value.get() == value { + return; + } + + self.local_value.set(value); + + self.update_changed(); + self.obj().notify_local_value(); + } + + /// Whether we can change the history visibility. + fn can_change(&self) -> bool { + let Some(room) = self.room.obj() else { + return false; + }; + + if room.history_visibility() == HistoryVisibilityValue::Unsupported { + return false; + } + + room.permissions() + .is_allowed_to(PowerLevelAction::SendState( + StateEventType::RoomHistoryVisibility, + )) + } + + /// Update whether the join rule was changed by the user. + #[template_callback] + fn update_changed(&self) { + let Some(room) = self.room.obj() else { + return; + }; + + let changed = if self.can_change() { + let current_join_rule = room.history_visibility(); + let new_join_rule = self.local_value.get(); + + current_join_rule != new_join_rule + } else { + false + }; + + self.changed.set(changed); + self.obj().notify_changed(); + } + + /// Save the changes of this page. + #[template_callback] + async fn save(&self) { + if !self.changed.get() { + // Nothing to do. + return; + } + + let Some(room) = self.room.obj() else { + return; + }; + + self.save_button.set_is_loading(true); + + let content = RoomHistoryVisibilityEventContent::new(self.local_value.get().into()); + + let matrix_room = room.matrix_room().clone(); + let handle = spawn_tokio!(async move { matrix_room.send_state_event(content).await }); + + if let Err(error) = handle.await.unwrap() { + error!("Could not change room history visibility: {error}"); + toast!(self.obj(), gettext("Could not change who can read history")); + self.save_button.set_is_loading(false); + } + } + + /// Go back to the previous page in the room details. + /// + /// If there are changes in the page, ask the user to confirm. + #[template_callback] + async fn go_back(&self) { + let obj = self.obj(); + let mut reset_after = false; + + if self.changed.get() { + match unsaved_changes_dialog(&*obj).await { + UnsavedChangesResponse::Save => self.save().await, + UnsavedChangesResponse::Discard => reset_after = true, + UnsavedChangesResponse::Cancel => return, + } + } + + let _ = obj.activate_action("navigation.pop", None); + + if reset_after { + self.update(); + } + } + + /// Disconnect all the signal handlers. + fn disconnect_signals(&self) { + if let Some(room) = self.room.obj() { + if let Some(handler) = self.permissions_handler.take() { + room.permissions().disconnect(handler); + } + } + + self.room.disconnect_signals(); + } + } +} + +glib::wrapper! { + /// Subpage to select the history visibility of a room. + pub struct HistoryVisibilitySubpage(ObjectSubclass) + @extends gtk::Widget, adw::NavigationPage, @implements gtk::Accessible; +} + +impl HistoryVisibilitySubpage { + /// Construct a new `HistoryVisibilitySubpage` for the given room. + pub fn new(room: &Room) -> Self { + glib::Object::builder().property("room", room).build() + } +} diff --git a/src/session/view/content/room_details/mod.rs b/src/session/view/content/room_details/mod.rs index 6d359281..647ba1c5 100644 --- a/src/session/view/content/room_details/mod.rs +++ b/src/session/view/content/room_details/mod.rs @@ -11,6 +11,7 @@ mod addresses_subpage; mod edit_details_subpage; mod general_page; mod history_viewer; +mod history_visibility_subpage; mod invite_subpage; mod join_rule_subpage; mod member_row; @@ -26,6 +27,7 @@ use self::{ history_viewer::{ AudioHistoryViewer, FileHistoryViewer, HistoryViewerTimeline, VisualMediaHistoryViewer, }, + history_visibility_subpage::HistoryVisibilitySubpage, invite_subpage::InviteSubpage, join_rule_subpage::JoinRuleSubpage, member_row::MemberRow, @@ -61,6 +63,8 @@ pub(super) enum SubpageName { Permissions, /// The page to edit the join rule of the room. JoinRule, + /// The page to edit the history visibility of the room. + HistoryVisibility, } /// The view to present when opening the room details. @@ -241,6 +245,7 @@ mod imp { PermissionsSubpage::new(&room.permissions()).upcast() } SubpageName::JoinRule => JoinRuleSubpage::new(room).upcast(), + SubpageName::HistoryVisibility => HistoryVisibilitySubpage::new(room).upcast(), }) .clone() } diff --git a/src/ui-blueprint-resources.in b/src/ui-blueprint-resources.in index 428a91ee..55d569ba 100644 --- a/src/ui-blueprint-resources.in +++ b/src/ui-blueprint-resources.in @@ -32,7 +32,6 @@ components/power_level_selection/popover.blp components/power_level_selection/row.blp components/rows/button_count_row.blp components/rows/check_loading_row.blp -components/rows/combo_loading_row.blp components/rows/copyable_row.blp components/rows/entry_add_row.blp components/rows/loading_button_row.blp @@ -93,6 +92,7 @@ session/view/content/room_details/history_viewer/file.blp session/view/content/room_details/history_viewer/file_row.blp session/view/content/room_details/history_viewer/visual_media.blp session/view/content/room_details/history_viewer/visual_media_item.blp +session/view/content/room_details/history_visibility_subpage.blp session/view/content/room_details/invite_subpage/mod.blp session/view/content/room_details/invite_subpage/row.blp session/view/content/room_details/join_rule_subpage.blp