diff --git a/po/POTFILES.in b/po/POTFILES.in index 96c51c91..c62cdd84 100644 --- a/po/POTFILES.in +++ b/po/POTFILES.in @@ -186,13 +186,13 @@ src/session/view/content/room_history/title.blp src/session/view/content/room_history/typing_row.rs src/session/view/content/room_history/verification_info_bar.rs src/session/view/create_direct_chat_dialog/mod.rs -src/session/view/create_direct_chat_dialog/mod.ui +src/session/view/create_direct_chat_dialog/mod.blp src/session/view/create_room_dialog.rs -src/session/view/create_room_dialog.ui +src/session/view/create_room_dialog.blp src/session/view/event_details_dialog.rs -src/session/view/event_details_dialog.ui +src/session/view/event_details_dialog.blp src/session/view/media_viewer.rs -src/session/view/media_viewer.ui +src/session/view/media_viewer.blp src/session/view/sidebar/mod.rs src/session/view/sidebar/mod.ui src/session/view/sidebar/room_row.rs diff --git a/src/blp-resources.in b/src/blp-resources.in index 3274e817..aa58e191 100644 --- a/src/blp-resources.in +++ b/src/blp-resources.in @@ -134,4 +134,9 @@ session/view/content/room_history/state/row.blp session/view/content/room_history/title.blp session/view/content/room_history/typing_row.blp session/view/content/room_history/verification_info_bar.blp +session/view/create_direct_chat_dialog/mod.blp +session/view/create_room_dialog.blp +session/view/event_details_dialog.blp +session/view/media_viewer.blp +session/view/session_view.blp window.blp diff --git a/src/session/view/create_direct_chat_dialog/mod.blp b/src/session/view/create_direct_chat_dialog/mod.blp new file mode 100644 index 00000000..b5f3e85e --- /dev/null +++ b/src/session/view/create_direct_chat_dialog/mod.blp @@ -0,0 +1,105 @@ +using Gtk 4.0; +using Adw 1; + +template $CreateDirectChatDialog: Adw.Dialog { + title: _("Direct Chat"); + content-width: 380; + content-height: 620; + + child: Adw.ToolbarView { + [top] + Adw.HeaderBar { + show-title: false; + } + + [top] + Adw.Clamp { + hexpand: true; + + Gtk.Box { + orientation: vertical; + spacing: 18; + margin-start: 12; + margin-end: 12; + + Gtk.Label heading { + wrap: true; + wrap-mode: word_char; + max-width-chars: 20; + justify: center; + xalign: 0.5; + label: _("New Direct Chat"); + + styles [ + "title-2", + ] + } + + Gtk.SearchEntry search_entry {} + } + } + + content: Gtk.Stack stack { + Gtk.StackPage { + name: "no-search-term"; + + child: Adw.StatusPage { + vexpand: true; + icon-name: "system-search-symbolic"; + // Translators: In this string, 'Search' is a verb. + title: _("Search"); + description: _("Search for people to start a new chat with"); + }; + } + + Gtk.StackPage { + name: "results"; + + child: Gtk.ScrolledWindow matching_page { + styles [ + "avatar-row-list", + ] + + child: Adw.Clamp { + child: Gtk.ListBox list_box { + activate-on-single-click: true; + margin-start: 6; + margin-end: 6; + row-activated => $create_direct_chat() swapped; + + styles [ + "navigation-sidebar", + ] + }; + }; + }; + } + + Gtk.StackPage { + name: "empty"; + + child: Adw.StatusPage { + icon-name: "system-search-symbolic"; + title: _("No Users Found"); + description: _("No users matching the search pattern were found"); + }; + } + + Gtk.StackPage { + name: "error"; + + child: Adw.StatusPage error_page { + icon-name: "error-symbolic"; + title: _("Error"); + description: _("An error occurred while searching for matches"); + }; + } + + Gtk.StackPage { + name: "loading"; + + child: Adw.Spinner {}; + } + }; + }; +} diff --git a/src/session/view/create_direct_chat_dialog/mod.ui b/src/session/view/create_direct_chat_dialog/mod.ui deleted file mode 100644 index c1aa9aa0..00000000 --- a/src/session/view/create_direct_chat_dialog/mod.ui +++ /dev/null @@ -1,123 +0,0 @@ - - - - diff --git a/src/session/view/create_room_dialog.blp b/src/session/view/create_room_dialog.blp new file mode 100644 index 00000000..ae605999 --- /dev/null +++ b/src/session/view/create_room_dialog.blp @@ -0,0 +1,173 @@ +using Gtk 4.0; +using Adw 1; + +template $CreateRoomDialog: $ToastableDialog { + default-widget: create_button; + content-width: 380; + + child-content: Adw.ToolbarView { + [top] + Adw.HeaderBar { + show-title: false; + } + + content: Gtk.ScrolledWindow scrolled_window { + hscrollbar-policy: never; + propagate-natural-height: true; + vexpand: true; + + child: Adw.Clamp { + maximum-size: 444; + + child: Gtk.Box { + orientation: vertical; + spacing: 24; + margin-bottom: 24; + margin-start: 24; + margin-end: 24; + + [top] + Gtk.Label heading { + wrap: true; + wrap-mode: word_char; + max-width-chars: 20; + justify: center; + xalign: 0.5; + label: _("New Room"); + + styles [ + "title-2", + ] + } + + Gtk.Box content { + orientation: vertical; + spacing: 18; + + Adw.PreferencesGroup { + title: _("Name"); + + Adw.EntryRow room_name { + title: _("Name"); + changed => $validate_form() swapped; + entry-activated => $create_room() swapped; + } + } + + Adw.PreferencesGroup topic_group { + title: _("Description (Optional)"); + + Gtk.ScrolledWindow { + height-request: 120; + + styles [ + "card", + ] + + Gtk.TextView topic_text_view { + hexpand: true; + wrap-mode: word_char; + + styles [ + "inline", + ] + + accessibility { + labelled-by: [ + topic_group, + ]; + } + } + } + } + + Adw.PreferencesGroup { + title: _("Room Visibility"); + + Adw.ActionRow { + title: _("Private"); + subtitle: _("Only invited people can join this room"); + activatable-widget: visibility_private; + + [prefix] + Gtk.CheckButton visibility_private { + valign: center; + active: true; + toggled => $validate_form() swapped; + } + } + + Adw.ActionRow { + title: _("Public"); + subtitle: _("Anyone can find and join this room"); + activatable-widget: visibility_public; + + [prefix] + Gtk.CheckButton visibility_public { + valign: center; + group: visibility_private; + } + } + } + + Adw.PreferencesGroup { + visible: bind visibility_private.active; + margin-top: 12; + + Adw.SwitchRow encryption { + title: _("End-to-End Encryption"); + subtitle: _("Cannot be disabled later"); + } + } + + Adw.PreferencesGroup { + visible: bind visibility_public.active; + margin-top: 12; + + $SubstringEntryRow room_address { + title: _("Main Address"); + // Translators: This is the placeholder for the first part of a room address, + // as in '@my-room:example.org'. + placeholder-text: _("my-room"); + accessible-description: _("First part of the address, for example “my-room”"); + prefix-text: "#"; + hide-add-button: true; + changed => $validate_form() swapped; + } + + Gtk.Revealer room_address_error_revealer { + child: Gtk.Label room_address_error { + wrap: true; + wrap-mode: word_char; + xalign: 0.0; + margin-top: 6; + + styles [ + "error", + "caption", + ] + }; + } + } + } + + $LoadingButton create_button { + content-label: _("_Create Room"); + use-underline: true; + sensitive: false; + halign: center; + valign: end; + vexpand: true; + clicked => $create_room() swapped; + + styles [ + "suggested-action", + "standalone-button", + "pill", + ] + } + }; + }; + }; + }; +} diff --git a/src/session/view/create_room_dialog.ui b/src/session/view/create_room_dialog.ui deleted file mode 100644 index 708713b6..00000000 --- a/src/session/view/create_room_dialog.ui +++ /dev/null @@ -1,186 +0,0 @@ - - - - diff --git a/src/session/view/event_details_dialog.blp b/src/session/view/event_details_dialog.blp new file mode 100644 index 00000000..a83e833a --- /dev/null +++ b/src/session/view/event_details_dialog.blp @@ -0,0 +1,202 @@ +using Gtk 4.0; +using Adw 1; +using GtkSource 5; + +template $EventDetailsDialog: $ToastableDialog { + title: _("Event Details"); + content-width: 500; + content-height: 400; + + styles [ + "event-details-dialog", + ] + + child-content: Adw.NavigationView navigation_view { + Adw.NavigationPage { + title: _("Event Details"); + tag: "details"; + + child: Adw.ToolbarView { + [top] + Adw.HeaderBar {} + + content: Gtk.ScrolledWindow { + hscrollbar-policy: never; + vexpand: true; + + child: Adw.Clamp { + vexpand: true; + margin-top: 12; + margin-bottom: 12; + margin-start: 12; + margin-end: 12; + + child: Gtk.Box { + orientation: vertical; + spacing: 24; + + Gtk.Box { + orientation: vertical; + spacing: 12; + + Label { + visible: bind template.event as <$RoomEvent>.is-edited; + label: _("Original Event"); + ellipsize: end; + xalign: 0; + + styles [ + "heading", + ] + } + + Gtk.ListBox { + styles [ + "boxed-list", + ] + + $CopyableRow original_event_id_row { + main-title: "subtitle"; + title: _("Event ID"); + subtitle: bind template.event as <$RoomEvent>.event-id-string; + copy-button-tooltip-text: _("Copy Event ID"); + toast-text: _("Event ID copied to clipboard"); + } + + $CopyableRow room_id_row { + main-title: "subtitle"; + title: _("Room ID"); + subtitle: bind template.event as <$RoomEvent>.timeline as <$Timeline>.room as <$Room>.room-id-string; + copy-button-tooltip-text: _("Copy Room ID"); + toast-text: _("Room ID copied to clipboard"); + } + + Adw.ActionRow sender_id_row { + title: _("Sender ID"); + subtitle: bind template.event as <$RoomEvent>.sender-id-string; + + styles [ + "property", + ] + + Gtk.Button { + valign: center; + icon-name: "user-info-symbolic"; + tooltip-text: _("Show Profile"); + clicked => $open_sender_profile() swapped; + + styles [ + "flat", + ] + } + } + + $CopyableRow original_timestamp_row { + main-title: "subtitle"; + title: _("Timestamp"); + subtitle: bind template.event as <$RoomEvent>.formatted-timestamp; + copy-button-tooltip-text: _("Copy Timestamp"); + toast-text: _("Timestamp copied to clipboard"); + } + + Adw.ButtonRow { + visible: bind template.event as <$RoomEvent>.has-source; + selectable: false; + title: _("View Source"); + end-icon-name: "go-next-symbolic"; + activated => $show_original_source() swapped; + } + } + } + + Gtk.Box { + visible: bind $string_not_empty(template.event as <$RoomEvent>.latest-edit-source) as ; + orientation: vertical; + spacing: 12; + + Gtk.Label { + label: _("Latest Edit"); + ellipsize: end; + xalign: 0; + + styles [ + "heading", + ] + } + + Gtk.ListBox { + styles [ + "boxed-list", + ] + + $CopyableRow edit_event_id_row { + main-title: "subtitle"; + title: _("Event ID"); + subtitle: bind template.event as <$RoomEvent>.latest-edit-event-id-string; + copy-button-tooltip-text: _("Copy Event ID"); + toast-text: _("Event ID copied to clipboard"); + } + + $CopyableRow edit_timestamp_row { + main-title: "subtitle"; + title: _("Timestamp"); + subtitle: bind template.event as <$RoomEvent>.latest-edit-formatted-timestamp; + copy-button-tooltip-text: _("Copy Timestamp"); + toast-text: _("Timestamp copied to clipboard"); + } + + Adw.ButtonRow { + selectable: false; + title: _("View Source"); + end-icon-name: "go-next-symbolic"; + activated => $show_edit_source() swapped; + } + } + } + }; + }; + }; + }; + } + + Adw.NavigationPage source_page { + tag: "source"; + + child: Adw.ToolbarView { + [top] + Adw.HeaderBar { + [end] + Gtk.Button { + icon-name: "copy-symbolic"; + focus-on-click: false; + tooltip-text: _("Copy Source"); + valign: center; + clicked => $copy_source() swapped; + + styles [ + "flat", + ] + } + } + + content: Gtk.ScrolledWindow { + child: GtkSource.View source_view { + can-focus: false; + editable: false; + hexpand: true; + vexpand: true; + wrap-mode: word_char; + left-margin: 12; + right-margin: 12; + top-margin: 12; + bottom-margin: 12; + + styles [ + "monospace", + ] + }; + }; + }; + } + }; +} diff --git a/src/session/view/event_details_dialog.ui b/src/session/view/event_details_dialog.ui deleted file mode 100644 index 6a638244..00000000 --- a/src/session/view/event_details_dialog.ui +++ /dev/null @@ -1,266 +0,0 @@ - - - - diff --git a/src/session/view/media_viewer.blp b/src/session/view/media_viewer.blp new file mode 100644 index 00000000..1b5ffb71 --- /dev/null +++ b/src/session/view/media_viewer.blp @@ -0,0 +1,141 @@ +using Gtk 4.0; +using Adw 1; + +menu media-secondary-menu-model { + section { + item { + label: _("_Copy Image"); + action: "media-viewer.copy-image"; + hidden-when: "action-disabled"; + } + + item { + label: _("S_ave Image"); + action: "media-viewer.save-image"; + hidden-when: "action-disabled"; + } + + item { + label: _("S_ave Video"); + action: "media-viewer.save-video"; + hidden-when: "action-disabled"; + } + + item { + label: _("Copy Message _Link"); + action: "media-viewer.permalink"; + hidden-when: "action-disabled"; + } + } +} + +menu media-context-menu-model { + section { + item { + label: _("_Copy Image"); + action: "media-viewer.copy-image"; + hidden-when: "action-disabled"; + } + + item { + label: _("S_ave Image"); + action: "media-viewer.save-image"; + hidden-when: "action-disabled"; + } + + item { + label: _("S_ave Video"); + action: "media-viewer.save-video"; + hidden-when: "action-disabled"; + } + } +} + +template $MediaViewer: Gtk.Widget { + Adw.ToolbarView toolbar_view { + extend-content-to-top-edge: bind template.fullscreened; + reveal-top-bars: bind template.fullscreened inverted; + overflow: visible; + + [top] + Gtk.HeaderBar header_bar { + title-widget: Gtk.Label { + label: bind template.filename; + single-line-mode: true; + ellipsize: end; + + styles [ + "title", + ] + }; + + [start] + Gtk.Button back { + icon-name: "go-previous-symbolic"; + action-name: "media-viewer.close"; + tooltip-text: _("Back"); + + accessibility { + label: _("Back"); + } + } + + [end] + Gtk.MenuButton menu { + icon-name: "menu-secondary-symbolic"; + menu-model: media-secondary-menu-model; + tooltip-text: _("Media Menu"); + primary: true; + + accessibility { + label: _("Media Menu"); + } + } + + [end] + Gtk.Button { + visible: bind template.fullscreened inverted; + icon-name: "fullscreen-symbolic"; + action-name: "win.toggle-fullscreen"; + tooltip-text: _("Fullscreen"); + + accessibility { + label: _("Fullscreen"); + } + } + + [end] + Gtk.Button { + visible: bind template.fullscreened; + icon-name: "restore-symbolic"; + action-name: "win.toggle-fullscreen"; + tooltip-text: _("Exit Fullscreen"); + + accessibility { + label: _("Exit Fullscreen"); + } + } + } + + content: $ScaleRevealer revealer { + child: $MediaContentViewer media { + autoplay: true; + has-context-menu: true; + + popover: Gtk.PopoverMenu { + has-arrow: false; + halign: start; + menu-model: media-context-menu-model; + }; + }; + }; + } + + Gtk.EventControllerMotion { + motion => $handle_motion() swapped; + } + + Gtk.GestureClick { + released => $handle_click() swapped; + } +} diff --git a/src/session/view/media_viewer.ui b/src/session/view/media_viewer.ui deleted file mode 100644 index 4eeb0165..00000000 --- a/src/session/view/media_viewer.ui +++ /dev/null @@ -1,141 +0,0 @@ - - - -
- - _Copy Image - media-viewer.copy-image - action-disabled - - - S_ave Image - media-viewer.save-image - action-disabled - - - S_ave Video - media-viewer.save-video - action-disabled - - - Copy Message _Link - media-viewer.permalink - action-disabled - -
-
- -
- - _Copy Image - media-viewer.copy-image - action-disabled - - - S_ave Image - media-viewer.save-image - action-disabled - - - S_ave Video - media-viewer.save-video - action-disabled - -
-
- -
diff --git a/src/session/view/session_view.blp b/src/session/view/session_view.blp new file mode 100644 index 00000000..b7f8b42a --- /dev/null +++ b/src/session/view/session_view.blp @@ -0,0 +1,54 @@ +using Gtk 4.0; +using Adw 1; + +template $SessionView: Adw.Bin { + child: Gtk.Stack stack { + visible-child: overlay; + transition-type: crossfade; + + Gtk.Overlay overlay { + [overlay] + $MediaViewer media_viewer { + visible: false; + } + + Adw.NavigationSplitView split_view { + collapsed: bind template.root as <$Window>.compact; + + sidebar: $Sidebar sidebar { + user: bind template.session as <$Session>.user; + list-model: bind template.session as <$Session>.sidebar-list-model; + }; + + content: $Content content { + session: bind template.session; + only-view: bind template.root as <$Window>.compact; + }; + } + } + }; + + Gtk.ShortcutController { + propagation-phase: capture; + + Gtk.Shortcut { + trigger: "Page_Up"; + action: "action(session.select-prev-room)"; + } + + Gtk.Shortcut { + trigger: "Page_Down"; + action: "action(session.select-next-room)"; + } + + Gtk.Shortcut { + trigger: "Page_Down"; + action: "action(session.select-next-unread-room)"; + } + + Gtk.Shortcut { + trigger: "Page_Up"; + action: "action(session.select-prev-unread-room)"; + } + } +} diff --git a/src/session/view/session_view.ui b/src/session/view/session_view.ui deleted file mode 100644 index edb7e9ba..00000000 --- a/src/session/view/session_view.ui +++ /dev/null @@ -1,82 +0,0 @@ - - - - diff --git a/src/ui-resources.gresource.xml b/src/ui-resources.gresource.xml index 719f095d..bb3d3514 100644 --- a/src/ui-resources.gresource.xml +++ b/src/ui-resources.gresource.xml @@ -2,11 +2,6 @@ session/view/account_settings/general_page/change_password_subpage.ui - session/view/create_direct_chat_dialog/mod.ui - session/view/create_room_dialog.ui - session/view/event_details_dialog.ui - session/view/media_viewer.ui - session/view/session_view.ui session/view/sidebar/icon_item_row.ui session/view/sidebar/mod.ui session/view/sidebar/room_row.ui