Skip to content

Commit

Permalink
feat:reactive post updates (#251)
Browse files Browse the repository at this point in the history
* feat: reactive status edits

* fix(MarkupView): unparent before destroying

* feat(Thread)[performance]: append => splice

* feat: reactive thread replies
  • Loading branch information
GeopJr committed May 14, 2023
1 parent f2d804c commit a6102ec
Show file tree
Hide file tree
Showing 4 changed files with 61 additions and 7 deletions.
12 changes: 10 additions & 2 deletions src/Dialogs/Composer/Dialog.vala
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@ public class Tuba.Dialogs.Compose : Adw.Window {

public API.Status status { get; construct set; }

public delegate void SuccessCallback (API.Status cb_status);
protected SuccessCallback? cb;

public string button_label {
set { commit_button.label = value; }
}
Expand Down Expand Up @@ -98,7 +101,7 @@ public class Tuba.Dialogs.Compose : Adw.Window {
);
}

public Compose.edit (API.Status t_status, API.StatusSource? source = null) {
public Compose.edit (API.Status t_status, API.StatusSource? source = null, owned SuccessCallback? t_cb = null) {
var template = new API.Status.empty () {
id = t_status.id,
poll = t_status.poll,
Expand All @@ -121,9 +124,11 @@ public class Tuba.Dialogs.Compose : Adw.Window {
button_class: "suggested-action",
editing: true
);

this.cb = (owned) t_cb;
}

public Compose.reply (API.Status to) {
public Compose.reply (API.Status to, owned SuccessCallback? t_cb = null) {
var template = new API.Status.empty () {
in_reply_to_id = to.id.to_string (),
in_reply_to_account_id = to.account.id.to_string (),
Expand All @@ -138,6 +143,8 @@ public class Tuba.Dialogs.Compose : Adw.Window {
button_label: _("_Reply"),
button_class: "suggested-action"
);

this.cb = (owned) t_cb;
}

protected T? get_page<T> () {
Expand Down Expand Up @@ -205,6 +212,7 @@ public class Tuba.Dialogs.Compose : Adw.Window {
var node = network.parse_node (parser);
var status = API.Status.from (node);
message (@"Published post with id $(status.id)");
if (cb != null) cb (status);

on_close ();
}
Expand Down
34 changes: 32 additions & 2 deletions src/Views/Thread.vala
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,23 @@ public class Tuba.Views.Thread : Views.ContentBase, AccountHolder {
root_widget.thread_line_bottom.hide ();
}

private void on_replied (API.Status t_status) {
var found = false;
if (t_status.in_reply_to_id != null) {
for (uint i = 0; i < model.get_n_items(); i++) {
var status_obj = (API.Status)model.get_item(i);
if (status_obj.id == t_status.in_reply_to_id) {
model.insert (i+1, t_status);
found = true;
break;
}
}
}

if (!found) model.append (t_status);
connect_threads ();
}

public void request () {
new Request.GET (@"/api/v1/statuses/$(root_status.id)/context")
.with_account (account)
Expand All @@ -63,23 +80,27 @@ public class Tuba.Views.Thread : Views.ContentBase, AccountHolder {
var parser = Network.get_parser_from_inputstream(in_stream);
var root = network.parse (parser);

Object[] to_add_ancestors = {};
var ancestors = root.get_array_member ("ancestors");
ancestors.foreach_element ((array, i, node) => {
var e = entity_cache.lookup_or_insert (node, typeof (API.Status));
model.append (e);
to_add_ancestors += e;
});
model.splice (model.n_items, 0, to_add_ancestors);

model.append (root_status);
uint root_index;
model.find (root_status, out root_index);
root_widget = content.get_row_at_index ((int)root_index) as Widgets.Status;
root_widget.expand_root ();

Object[] to_add_descendants = {};
var descendants = root.get_array_member ("descendants");
descendants.foreach_element ((array, i, node) => {
var e = entity_cache.lookup_or_insert (node, typeof (API.Status));
model.append (e);
to_add_descendants += e;
});
model.splice (model.n_items, 0, to_add_descendants);

connect_threads ();
on_content_changed ();
Expand Down Expand Up @@ -112,4 +133,13 @@ public class Tuba.Views.Thread : Views.ContentBase, AccountHolder {
.exec ();
}

public override Gtk.Widget on_create_model_widget(Object obj) {
var widget = base.on_create_model_widget(obj);
var widget_status = widget as Widgets.Status;

widget_status.reply_cb = on_replied;

return widget_status;
}

}
1 change: 1 addition & 0 deletions src/Widgets/MarkupView.vala
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ public class Tuba.Widgets.MarkupView : Box {
current_chunk = null;

for (var w = get_first_child (); w != null; w = w.get_next_sibling ()) {
w.unparent ();
w.destroy ();
}

Expand Down
21 changes: 18 additions & 3 deletions src/Widgets/Status.vala
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,8 @@ public class Tuba.Widgets.Status : ListBoxRow {
}
}

public Dialogs.Compose.SuccessCallback? reply_cb;

[GtkChild] protected unowned Box status_box;
[GtkChild] protected unowned Box avatar_side;
[GtkChild] protected unowned Box title_box;
Expand Down Expand Up @@ -277,6 +279,11 @@ public class Tuba.Widgets.Status : ListBoxRow {
app.main_window.open_view (new Views.StatusStats (status.formal.id));
}

private void on_edit (API.Status x) {
this.status.patch(x);
bind ();
}

private void edit_status () {
new Request.GET (@"/api/v1/statuses/$(status.formal.id)/source")
.with_account (accounts.active)
Expand All @@ -285,10 +292,10 @@ public class Tuba.Widgets.Status : ListBoxRow {
var node = network.parse_node (parser);
var source = API.StatusSource.from (node);

new Dialogs.Compose.edit (status.formal, source);
new Dialogs.Compose.edit (status.formal, source, on_edit);
})
.on_error (() => {
new Dialogs.Compose.edit (status.formal);
new Dialogs.Compose.edit (status.formal, null, on_edit);
})
.exec ();
}
Expand Down Expand Up @@ -713,10 +720,18 @@ public class Tuba.Widgets.Status : ListBoxRow {
privacy_dialog.present ();
}

private void on_reply (API.Status x) {
reply_cb (x);
}

private void on_reply_button_clicked () {
new Dialogs.Compose.reply (status.formal, on_reply);
}

protected virtual void append_actions () {
reply_button = new Button ();
reply_button_content = new Adw.ButtonContent ();
reply_button.clicked.connect (() => new Dialogs.Compose.reply (status.formal));
reply_button.clicked.connect (on_reply_button_clicked);
actions.append (reply_button);

reblog_button = new StatusActionButton () {
Expand Down

0 comments on commit a6102ec

Please sign in to comment.