Reimplement Conversations
This commit is contained in:
parent
ddde3edd67
commit
c9d0717e6a
|
@ -24,7 +24,7 @@
|
||||||
</object>
|
</object>
|
||||||
<template class="TootleWidgetsStatus" parent="GtkListBoxRow">
|
<template class="TootleWidgetsStatus" parent="GtkListBoxRow">
|
||||||
<property name="visible">True</property>
|
<property name="visible">True</property>
|
||||||
<property name="activatable">True</property>
|
<property name="can_focus">False</property>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkGrid" id="grid">
|
<object class="GtkGrid" id="grid">
|
||||||
<property name="visible">True</property>
|
<property name="visible">True</property>
|
||||||
|
@ -212,7 +212,6 @@
|
||||||
<packing>
|
<packing>
|
||||||
<property name="left_attach">0</property>
|
<property name="left_attach">0</property>
|
||||||
<property name="top_attach">1</property>
|
<property name="top_attach">1</property>
|
||||||
<property name="height">1</property>
|
|
||||||
</packing>
|
</packing>
|
||||||
</child>
|
</child>
|
||||||
<child>
|
<child>
|
||||||
|
@ -252,7 +251,6 @@
|
||||||
<property name="visible">True</property>
|
<property name="visible">True</property>
|
||||||
<property name="can_focus">False</property>
|
<property name="can_focus">False</property>
|
||||||
<property name="vexpand">True</property>
|
<property name="vexpand">True</property>
|
||||||
<property name="valign">fill</property>
|
|
||||||
<property name="row_homogeneous">True</property>
|
<property name="row_homogeneous">True</property>
|
||||||
<child>
|
<child>
|
||||||
<object class="TootleWidgetsRichLabel" id="name_label">
|
<object class="TootleWidgetsRichLabel" id="name_label">
|
||||||
|
@ -265,7 +263,7 @@
|
||||||
<packing>
|
<packing>
|
||||||
<property name="left_attach">0</property>
|
<property name="left_attach">0</property>
|
||||||
<property name="top_attach">0</property>
|
<property name="top_attach">0</property>
|
||||||
<property name="width">2</property>
|
<property name="width">3</property>
|
||||||
</packing>
|
</packing>
|
||||||
</child>
|
</child>
|
||||||
<child>
|
<child>
|
||||||
|
@ -283,33 +281,57 @@
|
||||||
</packing>
|
</packing>
|
||||||
</child>
|
</child>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkImage" id="pin_indicator">
|
<object class="GtkBox" id="indicators">
|
||||||
<property name="visible">True</property>
|
<property name="visible">True</property>
|
||||||
<property name="can_focus">False</property>
|
<property name="can_focus">False</property>
|
||||||
<property name="margin_left">8</property>
|
<property name="halign">end</property>
|
||||||
|
<property name="valign">start</property>
|
||||||
<property name="margin_start">8</property>
|
<property name="margin_start">8</property>
|
||||||
<property name="icon_name">view-pin-symbolic</property>
|
<property name="spacing">8</property>
|
||||||
<property name="icon_size">1</property>
|
<child>
|
||||||
|
<object class="GtkImage" id="pin_indicator">
|
||||||
|
<property name="can_focus">False</property>
|
||||||
|
<property name="icon_name">view-pin-symbolic</property>
|
||||||
|
<property name="icon_size">1</property>
|
||||||
|
<property name="opacity">0.5</property>
|
||||||
|
</object>
|
||||||
|
<packing>
|
||||||
|
<property name="expand">False</property>
|
||||||
|
<property name="fill">True</property>
|
||||||
|
<property name="position">0</property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="GtkImage" id="indicator">
|
||||||
|
<property name="can_focus">False</property>
|
||||||
|
<property name="icon_name">unknown</property>
|
||||||
|
<property name="icon_size">1</property>
|
||||||
|
<property name="opacity">0.5</property>
|
||||||
|
</object>
|
||||||
|
<packing>
|
||||||
|
<property name="expand">False</property>
|
||||||
|
<property name="fill">True</property>
|
||||||
|
<property name="position">1</property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="TootleWidgetsRichLabel" id="date_label">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can_focus">False</property>
|
||||||
|
<property name="label" translatable="no">Yesterday</property>
|
||||||
|
<property name="opacity">0.5</property>
|
||||||
|
</object>
|
||||||
|
<packing>
|
||||||
|
<property name="expand">False</property>
|
||||||
|
<property name="fill">True</property>
|
||||||
|
<property name="position">2</property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
</object>
|
</object>
|
||||||
<packing>
|
<packing>
|
||||||
<property name="left_attach">2</property>
|
<property name="left_attach">2</property>
|
||||||
<property name="top_attach">0</property>
|
<property name="top_attach">0</property>
|
||||||
</packing>
|
<property name="width">2</property>
|
||||||
</child>
|
|
||||||
<child>
|
|
||||||
<object class="TootleWidgetsRichLabel" id="date_label">
|
|
||||||
<property name="visible">True</property>
|
|
||||||
<property name="can_focus">False</property>
|
|
||||||
<property name="opacity">0.5</property>
|
|
||||||
<property name="margin_left">8</property>
|
|
||||||
<property name="margin_start">8</property>
|
|
||||||
<property name="label" translatable="no">Yesterday</property>
|
|
||||||
<property name="halign">end</property>
|
|
||||||
<property name="valign">start</property>
|
|
||||||
</object>
|
|
||||||
<packing>
|
|
||||||
<property name="left_attach">3</property>
|
|
||||||
<property name="top_attach">0</property>
|
|
||||||
</packing>
|
</packing>
|
||||||
</child>
|
</child>
|
||||||
</object>
|
</object>
|
||||||
|
|
|
@ -79,6 +79,7 @@ executable(
|
||||||
'src/Widgets/RichLabel.vala',
|
'src/Widgets/RichLabel.vala',
|
||||||
'src/Widgets/Status.vala',
|
'src/Widgets/Status.vala',
|
||||||
'src/Widgets/Notification.vala',
|
'src/Widgets/Notification.vala',
|
||||||
|
'src/Widgets/Conversation.vala',
|
||||||
'src/Widgets/VisibilityPopover.vala',
|
'src/Widgets/VisibilityPopover.vala',
|
||||||
'src/Widgets/Attachment/Box.vala',
|
'src/Widgets/Attachment/Box.vala',
|
||||||
'src/Widgets/Attachment/Slot.vala',
|
'src/Widgets/Attachment/Slot.vala',
|
||||||
|
|
|
@ -1,6 +1,30 @@
|
||||||
public class Tootle.API.Conversation : Entity, Widgetizable {
|
public class Tootle.API.Conversation : Entity, Widgetizable {
|
||||||
|
|
||||||
public string id { get; construct set; }
|
public string id { get; set; }
|
||||||
|
public Gee.ArrayList<API.Account> accounts { get; set; }
|
||||||
public bool unread { get; set; default = false; }
|
public bool unread { get; set; default = false; }
|
||||||
|
public API.Status? last_status { get; set; default = null; }
|
||||||
|
|
||||||
|
public override Gtk.Widget to_widget () {
|
||||||
|
return new Widgets.Conversation (this);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void open () {
|
||||||
|
var view = new Views.ExpandedStatus (last_status.formal);
|
||||||
|
window.open_view (view);
|
||||||
|
|
||||||
|
if (unread)
|
||||||
|
mark_read ();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void mark_read () {
|
||||||
|
new Request.POST (@"/api/v1/conversations/$id/read")
|
||||||
|
.with_account (Tootle.accounts.active)
|
||||||
|
.then (() => {
|
||||||
|
unread = false;
|
||||||
|
})
|
||||||
|
.on_error (() => {})
|
||||||
|
.exec ();
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,13 +4,14 @@ public class Tootle.Views.Conversations : Views.Timeline {
|
||||||
Object (
|
Object (
|
||||||
url: "/api/v1/conversations",
|
url: "/api/v1/conversations",
|
||||||
label: _("Conversations"),
|
label: _("Conversations"),
|
||||||
icon: API.Visibility.DIRECT.get_icon (),
|
icon: API.Visibility.DIRECT.get_icon ()
|
||||||
accepts: typeof (API.Conversation)
|
|
||||||
);
|
);
|
||||||
|
accepts = typeof (API.Conversation);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override string? get_stream_url () {
|
// TODO: Reload when an update is received
|
||||||
return @"/api/v1/streaming/?stream=direct&access_token=$(account.access_token)";
|
// public override string? get_stream_url () {
|
||||||
}
|
// return @"/api/v1/streaming/?stream=direct&access_token=$(account.access_token)";
|
||||||
|
// }
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,37 +17,6 @@ public class Tootle.Widgets.Attachment.Box : FlowBox {
|
||||||
Object (editing: editing);
|
Object (editing: editing);
|
||||||
}
|
}
|
||||||
|
|
||||||
//TODO: Upload attachments in Compose dialog
|
|
||||||
public void select () {
|
|
||||||
var filter = new Gtk.FileFilter ();
|
|
||||||
filter.add_mime_type ("image/jpeg");
|
|
||||||
filter.add_mime_type ("image/png");
|
|
||||||
filter.add_mime_type ("image/gif");
|
|
||||||
filter.add_mime_type ("video/webm");
|
|
||||||
filter.add_mime_type ("video/mp4");
|
|
||||||
|
|
||||||
var chooser = new Gtk.FileChooserDialog (
|
|
||||||
_("Select media files to add"),
|
|
||||||
null,
|
|
||||||
Gtk.FileChooserAction.OPEN,
|
|
||||||
_("_Cancel"),
|
|
||||||
Gtk.ResponseType.CANCEL,
|
|
||||||
_("_Open"),
|
|
||||||
Gtk.ResponseType.ACCEPT);
|
|
||||||
|
|
||||||
chooser.select_multiple = true;
|
|
||||||
chooser.set_filter (filter);
|
|
||||||
|
|
||||||
if (chooser.run () == ResponseType.ACCEPT) {
|
|
||||||
show ();
|
|
||||||
foreach (unowned string uri in chooser.get_uris ()) {
|
|
||||||
//var widget = new ImageAttachment.upload (uri);
|
|
||||||
//append_widget (widget);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
chooser.close ();
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool populate (ArrayList<API.Attachment>? list) {
|
public bool populate (ArrayList<API.Attachment>? list) {
|
||||||
if (list == null)
|
if (list == null)
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -0,0 +1,53 @@
|
||||||
|
using Gtk;
|
||||||
|
|
||||||
|
public class Tootle.Widgets.Conversation : Widgets.Status {
|
||||||
|
|
||||||
|
public API.Conversation conversation { get; construct set; }
|
||||||
|
|
||||||
|
public Conversation (API.Conversation entity) {
|
||||||
|
Object (conversation: entity, status: entity.last_status);
|
||||||
|
conversation.bind_property ("unread", this.indicator, "visible", BindingFlags.SYNC_CREATE);
|
||||||
|
this.indicators.child_set_property (this.indicator, "position", 2);
|
||||||
|
this.indicator.opacity = 1;
|
||||||
|
this.indicator.icon_name = Desktop.fallback_icon (
|
||||||
|
"software-update-urgent-symbolic",
|
||||||
|
"dialog-warning-symbolic");
|
||||||
|
this.actions.destroy ();
|
||||||
|
}
|
||||||
|
|
||||||
|
public new string title_text {
|
||||||
|
owned get {
|
||||||
|
var label = "";
|
||||||
|
foreach (API.Account account in conversation.accounts) {
|
||||||
|
label += "<b>" + Html.simplify (account.display_name) + "</b>";
|
||||||
|
if (conversation.accounts.last () != account)
|
||||||
|
label += ", ";
|
||||||
|
}
|
||||||
|
return @"$label";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public new string subtitle_text {
|
||||||
|
owned get {
|
||||||
|
var label = "";
|
||||||
|
foreach (API.Account account in conversation.accounts) {
|
||||||
|
label += account.handle + " ";
|
||||||
|
}
|
||||||
|
return @"<small>$label</small>";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public new string? avatar_url {
|
||||||
|
owned get {
|
||||||
|
if (conversation.accounts.size > 1)
|
||||||
|
return null;
|
||||||
|
else
|
||||||
|
return conversation.accounts.get (0).avatar;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void on_open () {
|
||||||
|
conversation.open ();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -22,10 +22,14 @@ public class Tootle.Widgets.Status : ListBoxRow {
|
||||||
[GtkChild]
|
[GtkChild]
|
||||||
protected Widgets.RichLabel handle_label;
|
protected Widgets.RichLabel handle_label;
|
||||||
[GtkChild]
|
[GtkChild]
|
||||||
|
protected Box indicators;
|
||||||
|
[GtkChild]
|
||||||
protected Widgets.RichLabel date_label;
|
protected Widgets.RichLabel date_label;
|
||||||
[GtkChild]
|
[GtkChild]
|
||||||
protected Image pin_indicator;
|
protected Image pin_indicator;
|
||||||
[GtkChild]
|
[GtkChild]
|
||||||
|
protected Image indicator;
|
||||||
|
[GtkChild]
|
||||||
public Revealer revealer;
|
public Revealer revealer;
|
||||||
[GtkChild]
|
[GtkChild]
|
||||||
protected Widgets.RichLabel content;
|
protected Widgets.RichLabel content;
|
||||||
|
@ -68,13 +72,6 @@ public class Tootle.Widgets.Status : ListBoxRow {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected string display_name {
|
|
||||||
owned get {
|
|
||||||
var name = Html.simplify (status.formal.account.display_name);
|
|
||||||
return @"<b>$name</b>";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
protected string date {
|
protected string date {
|
||||||
owned get {
|
owned get {
|
||||||
var date = new GLib.DateTime.from_iso8601 (status.formal.created_at, null);
|
var date = new GLib.DateTime.from_iso8601 (status.formal.created_at, null);
|
||||||
|
@ -83,13 +80,28 @@ public class Tootle.Widgets.Status : ListBoxRow {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected string handle {
|
public string title_text {
|
||||||
|
owned get {
|
||||||
|
var name = Html.simplify (status.formal.account.display_name);
|
||||||
|
return @"<b>$name</b>";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public string subtitle_text {
|
||||||
owned get {
|
owned get {
|
||||||
return @"<small>$(status.formal.account.handle)</small>";
|
return @"<small>$(status.formal.account.handle)</small>";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public virtual signal void open () {
|
public string? avatar_url {
|
||||||
|
owned get {
|
||||||
|
return status.formal.account.avatar;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public signal void open ();
|
||||||
|
|
||||||
|
public virtual void on_open () {
|
||||||
if (status.id == "")
|
if (status.id == "")
|
||||||
on_avatar_clicked ();
|
on_avatar_clicked ();
|
||||||
else
|
else
|
||||||
|
@ -99,6 +111,7 @@ public class Tootle.Widgets.Status : ListBoxRow {
|
||||||
construct {
|
construct {
|
||||||
content.activate_link.connect (on_toggle_spoiler);
|
content.activate_link.connect (on_toggle_spoiler);
|
||||||
notify["kind"].connect (on_kind_changed);
|
notify["kind"].connect (on_kind_changed);
|
||||||
|
open.connect (on_open);
|
||||||
|
|
||||||
if (kind == null) {
|
if (kind == null) {
|
||||||
if (status.reblog != null)
|
if (status.reblog != null)
|
||||||
|
@ -124,11 +137,11 @@ public class Tootle.Widgets.Status : ListBoxRow {
|
||||||
|
|
||||||
bind_property ("escaped-spoiler", content, "text", BindingFlags.SYNC_CREATE);
|
bind_property ("escaped-spoiler", content, "text", BindingFlags.SYNC_CREATE);
|
||||||
bind_property ("escaped-content", revealer_content, "text", BindingFlags.SYNC_CREATE);
|
bind_property ("escaped-content", revealer_content, "text", BindingFlags.SYNC_CREATE);
|
||||||
status.formal.account.bind_property ("avatar", avatar, "url", BindingFlags.SYNC_CREATE);
|
bind_property ("title_text", name_label, "text", BindingFlags.SYNC_CREATE);
|
||||||
bind_property ("handle", handle_label, "label", BindingFlags.SYNC_CREATE);
|
bind_property ("subtitle_text", handle_label, "text", BindingFlags.SYNC_CREATE);
|
||||||
bind_property ("display_name", name_label, "text", BindingFlags.SYNC_CREATE);
|
|
||||||
bind_property ("date", date_label, "label", BindingFlags.SYNC_CREATE);
|
bind_property ("date", date_label, "label", BindingFlags.SYNC_CREATE);
|
||||||
status.formal.bind_property ("pinned", pin_indicator, "visible", BindingFlags.SYNC_CREATE);
|
status.formal.bind_property ("pinned", pin_indicator, "visible", BindingFlags.SYNC_CREATE);
|
||||||
|
bind_property ("avatar_url", avatar, "url", BindingFlags.SYNC_CREATE);
|
||||||
|
|
||||||
status.formal.bind_property ("has_spoiler", revealer_content, "visible", BindingFlags.SYNC_CREATE);
|
status.formal.bind_property ("has_spoiler", revealer_content, "visible", BindingFlags.SYNC_CREATE);
|
||||||
revealer.reveal_child = !status.formal.has_spoiler;
|
revealer.reveal_child = !status.formal.has_spoiler;
|
||||||
|
|
Loading…
Reference in New Issue