summaryrefslogtreecommitdiff
path: root/repo/dino
diff options
context:
space:
mode:
Diffstat (limited to 'repo/dino')
-rw-r--r--repo/dino/dino.xibuild32
-rw-r--r--repo/dino/mobile-ui.patch967
2 files changed, 999 insertions, 0 deletions
diff --git a/repo/dino/dino.xibuild b/repo/dino/dino.xibuild
new file mode 100644
index 0000000..8f40781
--- /dev/null
+++ b/repo/dino/dino.xibuild
@@ -0,0 +1,32 @@
+#!/bin/sh
+
+NAME="dino"
+DESC="Modern Jabber/XMPP client"
+
+MAKEDEPS=" cmake glib glib-networking gpgme gspell gst-libav gst-plugins-base gtk3 libgcrypt libgee libhandy1 libnice libqrencode libsignal-protocol-c libsoup libsrtp ninja sqlite vala webrtc-audio-processing"
+
+PKG_VER=0.3.0
+SOURCE="https://github.com/dino/dino/releases/download/v$PKG_VER/dino-$PKG_VER.tar.gz"
+
+ADDITIONAL="
+mobile-ui.patch
+"
+
+build() {
+ ./configure \
+ --prefix=/usr \
+ --sysconfdir=/etc \
+ --mandir=/usr/share/man \
+ --localstatedir=/var \
+ --with-tests
+ make
+}
+
+check() {
+ build/xmpp-vala-test
+ build/signal-protocol-vala-test
+}
+
+package() {
+ make DESTDIR="$PKG_DEST" install
+}
diff --git a/repo/dino/mobile-ui.patch b/repo/dino/mobile-ui.patch
new file mode 100644
index 0000000..f274acf
--- /dev/null
+++ b/repo/dino/mobile-ui.patch
@@ -0,0 +1,967 @@
+diff --git a/cmake/FindHandy.cmake b/cmake/FindHandy.cmake
+new file mode 100644
+index 00000000..49148f0f
+--- /dev/null
++++ b/cmake/FindHandy.cmake
+@@ -0,0 +1,11 @@
++include(PkgConfigWithFallback)
++find_pkg_config_with_fallback(Handy
++ PKG_CONFIG_NAME libhandy-1
++ LIB_NAMES libhandy-1
++ INCLUDE_NAMES handy.h
++)
++
++include(FindPackageHandleStandardArgs)
++find_package_handle_standard_args(Handy
++ REQUIRED_VARS Handy_LIBRARY
++ VERSION_VAR Handy_VERSION)
+diff --git a/main/CMakeLists.txt b/main/CMakeLists.txt
+index e052785a..f6c3edc7 100644
+--- a/main/CMakeLists.txt
++++ b/main/CMakeLists.txt
+@@ -11,6 +11,7 @@ find_packages(MAIN_PACKAGES REQUIRED
+ GTK3
+ ICU
+ Gspell
++ Handy
+ )
+
+ set(RESOURCE_LIST
+diff --git a/main/data/add_conversation/select_jid_fragment.ui b/main/data/add_conversation/select_jid_fragment.ui
+index 50bc0e36..be56e710 100644
+--- a/main/data/add_conversation/select_jid_fragment.ui
++++ b/main/data/add_conversation/select_jid_fragment.ui
+@@ -1,82 +1,88 @@
+ <?xml version="1.0" encoding="UTF-8"?>
+ <interface>
+ <template class="DinoUiSelectJidFragment">
+- <property name="height_request">500</property>
+- <property name="width_request">460</property>
++ <property name="height_request">480</property>
+ <property name="visible">True</property>
+ <child>
+- <object class="GtkGrid">
+- <property name="expand">True</property>
+- <property name="margin-top">20</property>
+- <property name="margin-right">80</property>
+- <property name="margin-bottom">20</property>
+- <property name="margin-left">80</property>
+- <property name="orientation">vertical</property>
+- <property name="row-spacing">10</property>
++ <object class="HdyClamp">
++ <property name="margin-right">18</property>
++ <property name="margin-left">18</property>
++ <property name="maximum-size">300</property>
+ <property name="visible">True</property>
++ <property name="can_focus">False</property>
+ <child>
+- <object class="GtkEntry" id="entry">
+- <property name="activates_default">True</property>
+- <property name="hexpand">True</property>
+- <property name="visible">True</property>
+- </object>
+- </child>
+- <child>
+- <object class="GtkBox">
++ <object class="GtkGrid">
+ <property name="expand">True</property>
++ <property name="margin-top">20</property>
++ <property name="margin-bottom">20</property>
+ <property name="orientation">vertical</property>
++ <property name="row-spacing">10</property>
+ <property name="visible">True</property>
+ <child>
+- <object class="GtkFrame">
++ <object class="GtkEntry" id="entry">
++ <property name="activates_default">True</property>
++ <property name="hexpand">True</property>
++ <property name="visible">True</property>
++ </object>
++ </child>
++ <child>
++ <object class="GtkBox">
++ <property name="expand">True</property>
++ <property name="orientation">vertical</property>
+ <property name="visible">True</property>
+ <child>
+- <object class="GtkScrolledWindow" id="scrolled_window">
+- <property name="hscrollbar_policy">never</property>
+- <property name="expand">True</property>
++ <object class="GtkFrame">
+ <property name="visible">True</property>
+ <child>
+- <object class="GtkBox" id="box">
+- <property name="orientation">vertical</property>
++ <object class="GtkScrolledWindow" id="scrolled_window">
++ <property name="hscrollbar_policy">never</property>
++ <property name="expand">True</property>
+ <property name="visible">True</property>
++ <child>
++ <object class="GtkBox" id="box">
++ <property name="orientation">vertical</property>
++ <property name="visible">True</property>
++ </object>
++ </child>
+ </object>
+ </child>
+ </object>
+ </child>
+- </object>
+- </child>
+- <child>
+- <object class="GtkToolbar">
+- <property name="visible">True</property>
+- <style>
+- <class name="inline-toolbar"/>
+- </style>
+ <child>
+- <object class="GtkToolItem">
++ <object class="GtkToolbar">
+ <property name="visible">True</property>
++ <style>
++ <class name="inline-toolbar"/>
++ </style>
+ <child>
+- <object class="GtkBox">
++ <object class="GtkToolItem">
+ <property name="visible">True</property>
+ <child>
+- <object class="GtkButton" id="add_button">
++ <object class="GtkBox">
+ <property name="visible">True</property>
+ <child>
+- <object class="GtkImage">
+- <property name="icon-name">list-add-symbolic</property>
+- <property name="icon-size">1</property>
++ <object class="GtkButton" id="add_button">
+ <property name="visible">True</property>
++ <child>
++ <object class="GtkImage">
++ <property name="icon-name">list-add-symbolic</property>
++ <property name="icon-size">1</property>
++ <property name="visible">True</property>
++ </object>
++ </child>
+ </object>
+ </child>
+- </object>
+- </child>
+- <child>
+- <object class="GtkButton" id="remove_button">
+- <property name="sensitive">False</property>
+- <property name="visible">True</property>
+ <child>
+- <object class="GtkImage">
+- <property name="icon-name">list-remove-symbolic</property>
+- <property name="icon-size">1</property>
++ <object class="GtkButton" id="remove_button">
++ <property name="sensitive">False</property>
+ <property name="visible">True</property>
++ <child>
++ <object class="GtkImage">
++ <property name="icon-name">list-remove-symbolic</property>
++ <property name="icon-size">1</property>
++ <property name="visible">True</property>
++ </object>
++ </child>
+ </object>
+ </child>
+ </object>
+diff --git a/main/data/contact_details_dialog.ui b/main/data/contact_details_dialog.ui
+index 4058bc77..3ba17746 100644
+--- a/main/data/contact_details_dialog.ui
++++ b/main/data/contact_details_dialog.ui
+@@ -1,6 +1,7 @@
+ <?xml version="1.0" encoding="UTF-8"?>
+ <interface>
+ <template class="DinoUiContactDetailsDialog">
++ <property name="default_width">800</property>
+ <property name="modal">True</property>
+ <child type="titlebar">
+ <object class="GtkHeaderBar">
+@@ -21,98 +22,103 @@
+ <property name="expand">True</property>
+ <property name="visible">True</property>
+ <child>
+- <object class="GtkBox">
+- <property name="orientation">vertical</property>
++ <object class="HdyClamp">
++ <property name="margin-right">18</property>
++ <property name="margin-left">18</property>
+ <property name="visible">True</property>
++ <property name="can_focus">False</property>
+ <child>
+- <object class="GtkGrid">
+- <property name="margin-top">20</property>
+- <property name="margin-bottom">12</property>
+- <property name="margin-right">100</property>
+- <property name="margin-left">100</property>
+- <property name="column-spacing">10</property>
++ <object class="GtkBox">
++ <property name="orientation">vertical</property>
+ <property name="visible">True</property>
+ <child>
+- <object class="DinoUiAvatarImage" id="avatar">
+- <property name="height">50</property>
+- <property name="width">50</property>
+- <property name="visible">True</property>
+- <property name="allow_gray">False</property>
+- </object>
+- <packing>
+- <property name="left_attach">0</property>
+- <property name="top_attach">0</property>
+- <property name="width">1</property>
+- <property name="height">2</property>
+- </packing>
+- </child>
+- <child>
+- <object class="DinoUiUtilEntryLabelHybrid" id="name_hybrid">
+- <property name="xalign">0</property>
+- <property name="expand">True</property>
+- <property name="visible">True</property>
+- </object>
+- <packing>
+- <property name="left_attach">1</property>
+- <property name="top_attach">0</property>
+- <property name="width">1</property>
+- <property name="height">1</property>
+- </packing>
+- </child>
+- <child>
+- <object class="GtkLabel" id="name_label">
+- <property name="xalign">0</property>
+- <property name="expand">True</property>
++ <object class="GtkGrid">
++ <property name="margin-top">20</property>
++ <property name="margin-bottom">12</property>
++ <property name="column-spacing">10</property>
++ <property name="expand">False</property>
+ <property name="visible">True</property>
+- <attributes>
+- <attribute name="weight" value="PANGO_WEIGHT_BOLD"/>
+- </attributes>
++ <child>
++ <object class="DinoUiAvatarImage" id="avatar">
++ <property name="height">50</property>
++ <property name="width">50</property>
++ <property name="visible">True</property>
++ <property name="allow_gray">False</property>
++ </object>
++ <packing>
++ <property name="left_attach">0</property>
++ <property name="top_attach">0</property>
++ <property name="width">1</property>
++ <property name="height">2</property>
++ </packing>
++ </child>
++ <child>
++ <object class="DinoUiUtilEntryLabelHybrid" id="name_hybrid">
++ <property name="xalign">0</property>
++ <property name="expand">True</property>
++ <property name="visible">True</property>
++ </object>
++ <packing>
++ <property name="left_attach">1</property>
++ <property name="top_attach">0</property>
++ <property name="width">1</property>
++ <property name="height">1</property>
++ </packing>
++ </child>
++ <child>
++ <object class="GtkLabel" id="name_label">
++ <property name="xalign">0</property>
++ <property name="expand">True</property>
++ <property name="visible">True</property>
++ <attributes>
++ <attribute name="weight" value="PANGO_WEIGHT_BOLD"/>
++ </attributes>
++ </object>
++ <packing>
++ <property name="left_attach">1</property>
++ <property name="top_attach">0</property>
++ <property name="width">1</property>
++ <property name="height">1</property>
++ </packing>
++ </child>
++ <child>
++ <object class="GtkLabel" id="jid_label">
++ <property name="xalign">0</property>
++ <property name="yalign">0</property>
++ <property name="selectable">True</property>
++ <property name="expand">True</property>
++ <property name="visible">True</property>
++ </object>
++ <packing>
++ <property name="left_attach">1</property>
++ <property name="top_attach">1</property>
++ <property name="width">1</property>
++ <property name="height">1</property>
++ </packing>
++ </child>
++ <child>
++ <object class="GtkLabel" id="account_label">
++ <property name="xalign">1</property>
++ <property name="yalign">1</property>
++ <property name="margin">5</property>
++ <property name="expand">True</property>
++ <property name="visible">True</property>
++ </object>
++ <packing>
++ <property name="left_attach">1</property>
++ <property name="top_attach">2</property>
++ <property name="width">1</property>
++ <property name="height">1</property>
++ </packing>
++ </child>
+ </object>
+- <packing>
+- <property name="left_attach">1</property>
+- <property name="top_attach">0</property>
+- <property name="width">1</property>
+- <property name="height">1</property>
+- </packing>
+ </child>
+ <child>
+- <object class="GtkLabel" id="jid_label">
+- <property name="xalign">0</property>
+- <property name="yalign">0</property>
+- <property name="selectable">True</property>
+- <property name="expand">True</property>
++ <object class="GtkBox" id="main_box">
++ <property name="orientation">vertical</property>
+ <property name="visible">True</property>
+ </object>
+- <packing>
+- <property name="left_attach">1</property>
+- <property name="top_attach">1</property>
+- <property name="width">1</property>
+- <property name="height">1</property>
+- </packing>
+ </child>
+- <child>
+- <object class="GtkLabel" id="account_label">
+- <property name="xalign">1</property>
+- <property name="yalign">1</property>
+- <property name="margin">5</property>
+- <property name="expand">True</property>
+- <property name="visible">True</property>
+- </object>
+- <packing>
+- <property name="left_attach">2</property>
+- <property name="top_attach">1</property>
+- <property name="width">1</property>
+- <property name="height">1</property>
+- </packing>
+- </child>
+- </object>
+- </child>
+- <child>
+- <object class="GtkBox" id="main_box">
+- <property name="orientation">vertical</property>
+- <property name="margin-right">100</property>
+- <property name="margin-left">100</property>
+- <property name="visible">True</property>
+ </object>
+ </child>
+ </object>
+diff --git a/main/data/conversation_content_view/view.ui b/main/data/conversation_content_view/view.ui
+index 17f753f5..47302e2f 100644
+--- a/main/data/conversation_content_view/view.ui
++++ b/main/data/conversation_content_view/view.ui
+@@ -4,6 +4,7 @@
+ <property name="expand">True</property>
+ <property name="homogeneous">False</property>
+ <property name="spacing">0</property>
++ <property name="width_request">350</property>
+ <property name="visible">True</property>
+ <child>
+ <object class="GtkStack" id="stack">
+diff --git a/main/data/emojichooser.ui b/main/data/emojichooser.ui
+index d47a2c22..473820a6 100644
+--- a/main/data/emojichooser.ui
++++ b/main/data/emojichooser.ui
+@@ -187,7 +187,7 @@
+ </object>
+ </child>
+ <child>
+- <object class="GtkBox">
++ <object class="GtkGrid">
+ <property name="visible">1</property>
+ <!-- Remember to keep tooltips here in sync with section headings above -->
+ <child>
+@@ -204,6 +204,10 @@
+ </object>
+ </child>
+ </object>
++ <packing>
++ <property name="left_attach">0</property>
++ <property name="top_attach">0</property>
++ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="people.button">
+@@ -219,6 +223,10 @@
+ </object>
+ </child>
+ </object>
++ <packing>
++ <property name="left_attach">1</property>
++ <property name="top_attach">0</property>
++ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="body.button">
+@@ -234,6 +242,10 @@
+ </object>
+ </child>
+ </object>
++ <packing>
++ <property name="left_attach">2</property>
++ <property name="top_attach">0</property>
++ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="nature.button">
+@@ -249,6 +261,10 @@
+ </object>
+ </child>
+ </object>
++ <packing>
++ <property name="left_attach">3</property>
++ <property name="top_attach">0</property>
++ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="food.button">
+@@ -264,6 +280,10 @@
+ </object>
+ </child>
+ </object>
++ <packing>
++ <property name="left_attach">4</property>
++ <property name="top_attach">0</property>
++ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="travel.button">
+@@ -279,6 +299,10 @@
+ </object>
+ </child>
+ </object>
++ <packing>
++ <property name="left_attach">0</property>
++ <property name="top_attach">1</property>
++ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="activities.button">
+@@ -294,6 +318,10 @@
+ </object>
+ </child>
+ </object>
++ <packing>
++ <property name="left_attach">1</property>
++ <property name="top_attach">1</property>
++ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="objects.button">
+@@ -309,6 +337,10 @@
+ </object>
+ </child>
+ </object>
++ <packing>
++ <property name="left_attach">2</property>
++ <property name="top_attach">1</property>
++ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="symbols.button">
+@@ -324,6 +356,10 @@
+ </object>
+ </child>
+ </object>
++ <packing>
++ <property name="left_attach">3</property>
++ <property name="top_attach">1</property>
++ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="flags.button">
+@@ -339,6 +375,10 @@
+ </object>
+ </child>
+ </object>
++ <packing>
++ <property name="left_attach">4</property>
++ <property name="top_attach">1</property>
++ </packing>
+ </child>
+ </object>
+ </child>
+diff --git a/main/data/im.dino.Dino.appdata.xml.in b/main/data/im.dino.Dino.appdata.xml.in
+index c95ef12e..180b7873 100644
+--- a/main/data/im.dino.Dino.appdata.xml.in
++++ b/main/data/im.dino.Dino.appdata.xml.in
+@@ -45,5 +45,11 @@
+ </description>
+ </release>
+ </releases>
+- -->
+-</component>
++ -->
++
++ <custom>
++ <value key="Purism::form_factor">workstation</value>
++ <value key="Purism::form_factor">mobile</value>
++ </custom>
++
++ </component>
+diff --git a/main/data/im.dino.Dino.desktop b/main/data/im.dino.Dino.desktop
+index 90f3e38f..66faaa82 100644
+--- a/main/data/im.dino.Dino.desktop
++++ b/main/data/im.dino.Dino.desktop
+@@ -11,3 +11,4 @@ Type=Application
+ Categories=GTK;Network;Chat;InstantMessaging;
+ X-GNOME-UsesNotifications=true
+ MimeType=x-scheme-handler/xmpp;
++X-Purism-FormFactor=Workstation;Mobile;
+diff --git a/main/data/theme.css b/main/data/theme.css
+index 3e076248..897e4cc9 100644
+--- a/main/data/theme.css
++++ b/main/data/theme.css
+@@ -74,6 +74,11 @@ window.dino-main .dino-sidebar > frame {
+ border-bottom: 1px solid @borders;
+ }
+
++window.dino-main list.sidebar {
++ border-left: 0px;
++ border-right: 0px;
++}
++
+ .message-box {
+ transition: background .05s ease;
+ }
+diff --git a/main/data/unified_main_content.ui b/main/data/unified_main_content.ui
+index 03c206c1..e16bc4a8 100644
+--- a/main/data/unified_main_content.ui
++++ b/main/data/unified_main_content.ui
+@@ -1,12 +1,14 @@
+ <?xml version="1.0" encoding="UTF-8"?>
+ <interface>
+- <object class="GtkPaned" id="paned">
+- <property name="position">300</property>
++ <object class="HdyLeaflet" id="paned">
+ <property name="orientation">horizontal</property>
+ <property name="visible">True</property>
++ <property name="can_focus">False</property>
++ <property name="transition-type">slide</property>
+ <child>
+ <object class="GtkStack" id="left_stack">
+ <property name="visible">True</property>
++ <property name="hexpand">False</property>
+ <child>
+ <object class="GtkScrolledWindow" id="scrolled">
+ <property name="expand">True</property>
+@@ -29,6 +31,7 @@
+ <property name="valign">start</property>
+ <property name="halign">start</property>
+ <property name="visible">True</property>
++ <property name="width_request">260</property>
+ <child>
+ <object class="GtkImage" id="conversation_list_placeholder_image">
+ <property name="visible">True</property>
+@@ -44,7 +47,9 @@
+ <property name="margin-top">70</property>
+ <property name="margin-right">50</property>
+ <property name="visible">True</property>
++ <property name="xalign">0</property>
+ <property name="valign">end</property>
++ <property name="max-width-chars">0</property>
+ <property name="label" translatable="yes">Click here to start a conversation or join a channel.</property>
+ <style>
+ <class name="dim-label"/>
+@@ -58,10 +63,18 @@
+ </child>
+ </object>
+ <packing>
+- <property name="resize">False</property>
+- <property name="shrink">False</property>
++ <property name="name">list-pane</property>
+ </packing>
+ </child>
++ <child>
++ <object class="GtkSeparator" id="paned_separator">
++ <property name="orientation">vertical</property>
++ <property name="visible">True</property>
++ <style>
++ <class name="sidebar"/>
++ </style>
++ </object>
++ </child>
+ <child>
+ <object class="GtkOverlay">
+ <property name="visible">True</property>
+@@ -139,8 +152,7 @@
+ </child>
+ </object>
+ <packing>
+- <property name="resize">True</property>
+- <property name="shrink">False</property>
++ <property name="name">view-pane</property>
+ </packing>
+ </child>
+ </object>
+diff --git a/main/src/ui/add_conversation/add_conference_dialog.vala b/main/src/ui/add_conversation/add_conference_dialog.vala
+index a03f3db6..dfe877ec 100644
+--- a/main/src/ui/add_conversation/add_conference_dialog.vala
++++ b/main/src/ui/add_conversation/add_conference_dialog.vala
+@@ -35,6 +35,8 @@ public class AddConferenceDialog : Gtk.Dialog {
+ setup_jid_add_view();
+ setup_conference_details_view();
+ show_jid_add_view();
++
++ set_default_size(400, 520);
+ }
+
+ private void show_jid_add_view() {
+diff --git a/main/src/ui/add_conversation/select_contact_dialog.vala b/main/src/ui/add_conversation/select_contact_dialog.vala
+index d78a17c1..6be7cf3b 100644
+--- a/main/src/ui/add_conversation/select_contact_dialog.vala
++++ b/main/src/ui/add_conversation/select_contact_dialog.vala
+@@ -27,6 +27,8 @@ public class SelectContactDialog : Gtk.Dialog {
+
+ setup_view();
+ setup_headerbar();
++
++ set_default_size(400, 520);
+ }
+
+ public void set_filter(string str) {
+diff --git a/main/src/ui/contact_details/dialog.vala b/main/src/ui/contact_details/dialog.vala
+index f29d068e..fe21cbba 100644
+--- a/main/src/ui/contact_details/dialog.vala
++++ b/main/src/ui/contact_details/dialog.vala
+@@ -85,11 +85,11 @@ public class Dialog : Gtk.Dialog {
+ ListBoxRow list_row = new ListBoxRow() { activatable=false, visible=true };
+ Box row = new Box(Orientation.HORIZONTAL, 20) { margin_start=15, margin_end=15, margin_top=3, margin_bottom=3, visible=true };
+ list_row.add(row);
+- Label label_label = new Label(label) { xalign=0, yalign=0.5f, hexpand=true, visible=true };
++ Label label_label = new Label(label) { xalign=0, yalign=0.5f, hexpand=true, wrap=true, visible=true };
+ if (description != null && description != "") {
+ Box box = new Box(Orientation.VERTICAL, 0) { visible=true };
+ box.add(label_label);
+- Label desc_label = new Label("") { xalign=0, yalign=0.5f, hexpand=true, visible=true };
++ Label desc_label = new Label("") { xalign=0, yalign=0.5f, hexpand=true, wrap=true, visible=true };
+ desc_label.set_markup("<span size='small'>%s</span>".printf(Markup.escape_text(description)));
+ desc_label.get_style_context().add_class("dim-label");
+ box.add(desc_label);
+@@ -117,7 +117,7 @@ public class Dialog : Gtk.Dialog {
+
+ int pref_height, pref_width;
+ get_content_area().get_preferred_height(null, out pref_height);
+- get_preferred_width(out pref_width, null);
++ get_default_size(out pref_width, null);
+ resize(pref_width, int.min(500, pref_height));
+ }
+
+diff --git a/main/src/ui/conversation_titlebar/conversation_titlebar.vala b/main/src/ui/conversation_titlebar/conversation_titlebar.vala
+index 60d8286b..e7455cab 100644
+--- a/main/src/ui/conversation_titlebar/conversation_titlebar.vala
++++ b/main/src/ui/conversation_titlebar/conversation_titlebar.vala
+@@ -10,6 +10,10 @@ public interface ConversationTitlebar : Widget {
+ public abstract string? subtitle { get; set; }
+ public abstract string? title { get; set; }
+
++ public abstract bool back_button { get; set; }
++
++ public signal void back_pressed();
++
+ public abstract void insert_entry(Plugins.ConversationTitlebarEntry entry);
+ }
+
+@@ -28,6 +32,12 @@ public class ConversationTitlebarNoCsd : ConversationTitlebar, Gtk.Box {
+ }
+ }
+
++ private Revealer back_revealer;
++ public bool back_button {
++ get { return back_revealer.reveal_child; }
++ set { back_revealer.reveal_child = value; }
++ }
++
+ private Box widgets_box = new Box(Orientation.HORIZONTAL, 0) { margin_start=15, valign=Align.END, visible=true };
+ private Label title_label = new Label("") { ellipsize=EllipsizeMode.END, visible=true };
+ private Label subtitle_label = new Label("") { use_markup=true, ellipsize=EllipsizeMode.END, visible=false };
+@@ -36,8 +46,17 @@ public class ConversationTitlebarNoCsd : ConversationTitlebar, Gtk.Box {
+ Box content_box = new Box(Orientation.HORIZONTAL, 0) { margin=5, margin_start=15, margin_end=10, hexpand=true, visible=true };
+ this.add(content_box);
+
++ back_revealer = new Revealer() { visible = true, transition_type = RevealerTransitionType.SLIDE_RIGHT, transition_duration = 200, can_focus = false, reveal_child = false };
++ Button back_button = new Button.from_icon_name("go-previous-symbolic") { visible = true, valign = Align.CENTER, use_underline = true, relief = ReliefStyle.NONE };
++ back_button.get_style_context().add_class("image-button");
++ back_button.clicked.connect(() => back_pressed());
++ back_revealer.add(back_button);
++ content_box.add(back_revealer);
++
+ Box titles_box = new Box(Orientation.VERTICAL, 0) { valign=Align.CENTER, hexpand=true, visible=true };
+- content_box.add(titles_box);
++ ScrolledWindow titles_scroll = new ScrolledWindow(null, null) { vscrollbar_policy=NEVER, hscrollbar_policy=NEVER, visible=true };
++ titles_scroll.add(titles_box);
++ content_box.add(titles_scroll);
+
+ titles_box.add(title_label);
+ subtitle_label.attributes = new AttrList();
+@@ -65,11 +84,22 @@ public class ConversationTitlebarCsd : ConversationTitlebar, Gtk.HeaderBar {
+
+ public new string? title { get { return this.get_title(); } set { base.set_title(value); } }
+ public new string? subtitle { get { return this.get_subtitle(); } set { base.set_subtitle(value); } }
++ private Revealer back_revealer;
++ public bool back_button {
++ get { return back_revealer.reveal_child; }
++ set { back_revealer.reveal_child = value; }
++ }
+
+ public ConversationTitlebarCsd() {
+ this.get_style_context().add_class("dino-right");
+ show_close_button = true;
+ hexpand = true;
++ back_revealer = new Revealer() { visible = true, transition_type = RevealerTransitionType.SLIDE_RIGHT, transition_duration = 200, can_focus = false, reveal_child = false };
++ Button back_button = new Button.from_icon_name("go-previous-symbolic") { visible = true, valign = Align.CENTER, use_underline = true };
++ back_button.get_style_context().add_class("image-button");
++ back_button.clicked.connect(() => back_pressed());
++ back_revealer.add(back_button);
++ this.pack_start(back_revealer);
+ }
+
+ public void insert_entry(Plugins.ConversationTitlebarEntry entry) {
+@@ -77,6 +107,16 @@ public class ConversationTitlebarCsd : ConversationTitlebar, Gtk.HeaderBar {
+ Button gtk_widget = (Gtk.Button)widget;
+ this.pack_end(gtk_widget);
+ }
++
++ /*
++ * HdyLeaflet collapses based on natural_width, but labels set natural_width to the width required to have the full
++ * text in a single line, thus if the label gets longer, HdyLeaflet would collapse. Work around is to just use the
++ * minimum_width as natural_width.
++ */
++ public override void get_preferred_width(out int minimum_width, out int natural_width) {
++ base.get_preferred_width(out minimum_width, out natural_width);
++ natural_width = minimum_width;
++ }
+ }
+
+ }
+diff --git a/main/src/ui/main_window.vala b/main/src/ui/main_window.vala
+index 04c01b26..14563c28 100644
+--- a/main/src/ui/main_window.vala
++++ b/main/src/ui/main_window.vala
+@@ -22,8 +22,10 @@ public class MainWindow : Gtk.Window {
+ public ConversationListTitlebarCsd conversation_list_titlebar_csd;
+ public HeaderBar placeholder_headerbar = new HeaderBar() { title="Dino", show_close_button=true, visible=true };
+ public Box box = new Box(Orientation.VERTICAL, 0) { orientation=Orientation.VERTICAL, visible=true };
+- public Paned headerbar_paned = new Paned(Orientation.HORIZONTAL) { visible=true };
+- public Paned paned;
++ public Hdy.Leaflet headerbar_paned = new Hdy.Leaflet() { visible=true };
++ public Hdy.TitleBar titlebar = new Hdy.TitleBar() { visible=true };
++ public Hdy.HeaderGroup headergroup = new Hdy.HeaderGroup();
++ public Hdy.Leaflet paned;
+ public Revealer search_revealer;
+ public SearchEntry search_entry;
+ public GlobalSearch search_box;
+@@ -44,23 +46,33 @@ public class MainWindow : Gtk.Window {
+ restore_window_size();
+
+ this.get_style_context().add_class("dino-main");
+- setup_headerbar();
+- Gtk.Settings.get_default().notify["gtk-decoration-layout"].connect(set_window_buttons);
+- this.realize.connect(set_window_buttons);
+ setup_unified();
++ setup_headerbar();
+ setup_stack();
+
+- paned.bind_property("position", headerbar_paned, "position", BindingFlags.SYNC_CREATE | BindingFlags.BIDIRECTIONAL);
++ if (!Util.use_csd()) {
++ box.add(headerbar_paned);
++ box.add(new Separator(Orientation.VERTICAL) { visible = true });
++ }
++ box.add(paned);
++
++ paned.bind_property("transition-type", headerbar_paned, "transition-type", BindingFlags.SYNC_CREATE | BindingFlags.BIDIRECTIONAL);
++ paned.bind_property("mode-transition-duration", headerbar_paned, "mode-transition-duration", BindingFlags.SYNC_CREATE | BindingFlags.BIDIRECTIONAL);
++ paned.bind_property("child-transition-duration", headerbar_paned, "child-transition-duration", BindingFlags.SYNC_CREATE | BindingFlags.BIDIRECTIONAL);
++ paned.bind_property("visible-child-name", headerbar_paned, "visible-child-name", BindingFlags.SYNC_CREATE | BindingFlags.BIDIRECTIONAL);
++
++ headerbar_paned.bind_property("folded", headergroup, "decorate-all", BindingFlags.SYNC_CREATE);
+ }
+
+ private void setup_unified() {
+ Builder builder = new Builder.from_resource("/im/dino/Dino/unified_main_content.ui");
+- paned = (Paned) builder.get_object("paned");
+- box.add(paned);
++ paned = (Hdy.Leaflet) builder.get_object("paned");
++ paned.notify["folded"].connect_after(() => update_headerbar());
+ left_stack = (Stack) builder.get_object("left_stack");
+ right_stack = (Stack) builder.get_object("right_stack");
+ conversation_view = (ConversationView) builder.get_object("conversation_view");
+ conversation_selector = ((ConversationSelector) builder.get_object("conversation_list")).init(stream_interactor);
++ conversation_selector.conversation_selected.connect_after(() => show_view_pane());
+ search_box = ((GlobalSearch) builder.get_object("search_box")).init(stream_interactor);
+ search_revealer = (Revealer) builder.get_object("search_revealer");
+ search_entry = (SearchEntry) builder.get_object("search_entry");
+@@ -68,35 +80,60 @@ public class MainWindow : Gtk.Window {
+ conversation_list_placeholder_image.set_from_pixbuf(new Pixbuf.from_resource("/im/dino/Dino/icons/dino-conversation-list-placeholder-arrow.svg"));
+ }
+
++ private void update_headerbar() {
++ conversation_titlebar.back_button = paned.folded;
++ }
++
++ private void show_list_pane() {
++ paned.visible_child_name = "list-pane";
++ if (paned.folded) {
++ conversation_selector.unselect_row(conversation_selector.get_selected_row());
++ }
++ }
++
++ private void show_view_pane() {
++ paned.visible_child_name = "view-pane";
++ }
++
+ private void setup_headerbar() {
++ SizeGroup conversation_list_group = new SizeGroup(SizeGroupMode.HORIZONTAL);
++ conversation_list_group.add_widget(left_stack);
++ SizeGroup conversation_view_group = new SizeGroup(SizeGroupMode.HORIZONTAL);
++ conversation_view_group.add_widget(right_stack);
+ if (Util.use_csd()) {
+ conversation_list_titlebar_csd = new ConversationListTitlebarCsd() { visible=true };
+- headerbar_paned.pack1(conversation_list_titlebar_csd, false, false);
++ headerbar_paned.add_with_properties(conversation_list_titlebar_csd, "name", "list-pane");
++ headergroup.add_gtk_header_bar(conversation_list_titlebar_csd);
++ conversation_list_group.add_widget(conversation_list_titlebar_csd);
++
++ Separator sep = new Separator(Orientation.HORIZONTAL) { visible = true };
++ sep.get_style_context().add_class("sidebar");
++ headerbar_paned.add(sep);
+
+ conversation_titlebar_csd = new ConversationTitlebarCsd() { visible=true };
++ conversation_titlebar_csd.back_pressed.connect(() => show_list_pane());
+ conversation_titlebar = conversation_titlebar_csd;
+- headerbar_paned.pack2(conversation_titlebar_csd, true, false);
++ headerbar_paned.add_with_properties(conversation_titlebar_csd, "name", "view-pane");
++ headergroup.add_gtk_header_bar(conversation_titlebar_csd);
++ conversation_view_group.add_widget(conversation_titlebar);
++
++ titlebar.add(headerbar_paned);
+ } else {
+ ConversationListTitlebar conversation_list_titlebar = new ConversationListTitlebar() { visible=true };
+- headerbar_paned.pack1(conversation_list_titlebar, false, false);
++ headerbar_paned.add_with_properties(conversation_list_titlebar, "name", "list-pane");
++ conversation_list_group.add_widget(conversation_list_titlebar);
+
+- conversation_titlebar = new ConversationTitlebarNoCsd() { visible=true };
+- headerbar_paned.pack2(conversation_titlebar, true, false);
++ Separator sep = new Separator(Orientation.HORIZONTAL) { visible = true };
++ sep.get_style_context().add_class("sidebar");
++ headerbar_paned.add(sep);
+
+- box.add(headerbar_paned);
++ conversation_titlebar = new ConversationTitlebarNoCsd() { visible=true };
++ conversation_titlebar.back_pressed.connect(() => show_list_pane());
++ headerbar_paned.add_with_properties(conversation_titlebar, "name", "view-pane");
++ conversation_view_group.add_widget(conversation_titlebar);
+ }
+ }
+
+- private void set_window_buttons() {
+- if (!Util.use_csd()) return;
+- Gtk.Settings? gtk_settings = Gtk.Settings.get_default();
+- if (gtk_settings == null) return;
+-
+- string[] buttons = gtk_settings.gtk_decoration_layout.split(":");
+- this.conversation_list_titlebar_csd.decoration_layout = buttons[0] + ":";
+- this.conversation_titlebar_csd.decoration_layout = ((buttons.length == 2) ? ":" + buttons[1] : "");
+- }
+-
+ private void setup_stack() {
+ stack.add_named(box, "main");
+ stack.add_named(welcome_placeholder, "welcome_placeholder");
+@@ -118,7 +155,7 @@ public class MainWindow : Gtk.Window {
+
+ stack.set_visible_child_name("main");
+ if (Util.use_csd()) {
+- set_titlebar(headerbar_paned);
++ set_titlebar(titlebar);
+ }
+ } else if (stack_state == StackState.CLEAN_START || stack_state == StackState.NO_ACTIVE_ACCOUNTS) {
+ if (stack_state == StackState.CLEAN_START) {
+@@ -134,7 +171,7 @@ public class MainWindow : Gtk.Window {
+ left_stack.set_visible_child_name("placeholder");
+ right_stack.set_visible_child_name("placeholder");
+ if (Util.use_csd()) {
+- set_titlebar(headerbar_paned);
++ set_titlebar(titlebar);
+ }
+ }
+ }
+diff --git a/plugins/omemo/data/contact_details_dialog.ui b/plugins/omemo/data/contact_details_dialog.ui
+index 188bf06e..d9a35e97 100644
+--- a/plugins/omemo/data/contact_details_dialog.ui
++++ b/plugins/omemo/data/contact_details_dialog.ui
+@@ -2,7 +2,6 @@
+ <interface>
+ <template class="DinoPluginsOmemoContactDetailsDialog">
+ <property name="modal">True</property>
+- <property name="resizable">False</property>
+ <child internal-child="vbox">
+ <object class="GtkBox">
+ <property name="visible">True</property>
+@@ -37,6 +36,8 @@
+ <object class="GtkLabel" id="automatically_accept_new_label">
+ <property name="visible">True</property>
+ <property name="halign">start</property>
++ <property name="xalign">0</property>
++ <property name="wrap">True</property>
+ <attributes>
+ <attribute name="scale" value="1.1"/>
+ </attributes>
+@@ -114,8 +115,10 @@
+ <object class="GtkLabel" id="own_fingerprint_label">
+ <property name="visible">True</property>
+ <property name="halign">start</property>
+- <property name="justify">right</property>
+ <property name="hexpand">True</property>
++ <property name="max_width_chars">35</property>
++ <property name="xalign">0</property>
++ <property name="wrap">True</property>
+ </object>
+ </child>
+ <child>
+diff --git a/plugins/omemo/src/ui/contact_details_dialog.vala b/plugins/omemo/src/ui/contact_details_dialog.vala
+index b268cc13..a714b717 100644
+--- a/plugins/omemo/src/ui/contact_details_dialog.vala
++++ b/plugins/omemo/src/ui/contact_details_dialog.vala
+@@ -288,7 +288,7 @@ public class ContactDetailsDialog : Gtk.Dialog {
+ public class FingerprintRow : ListBoxRow {
+
+ private Image trust_image = new Image() { visible = true, halign = Align.END, icon_size = IconSize.BUTTON };
+- private Label fingerprint_label = new Label("") { use_markup=true, justify=Justification.RIGHT, visible=true, halign = Align.START, valign = Align.CENTER, hexpand = false };
++ private Label fingerprint_label = new Label("") { use_markup=true, max_width_chars=35, wrap=true, visible=true, halign = Align.START, valign = Align.CENTER, hexpand = false, xalign = 0 };
+ private Label trust_label = new Label(null) { visible = true, hexpand = true, xalign = 0 };
+
+ public Row row;
+diff --git a/plugins/omemo/src/ui/util.vala b/plugins/omemo/src/ui/util.vala
+index cf61ed82..0b0c4a9f 100644
+--- a/plugins/omemo/src/ui/util.vala
++++ b/plugins/omemo/src/ui/util.vala
+@@ -51,9 +51,8 @@ public static string fingerprint_markup(string s) {
+ b = (uint8) (b * factor);
+ }
+
+- if (i % 32 == 0 && i != 0) markup += "\n";
+ markup += @"<span foreground=\"$("#%02x%02x%02x".printf(r, g, b))\">$four_chars</span>";
+- if (i % 8 == 4 && i % 32 != 28) markup += " ";
++ if (i % 8 == 4) markup += " ";
+ }
+
+ return "<span font_family='monospace' font='8'>" + markup + "</span>";