diff --git a/src/API/Attachment.vala b/src/API/Attachment.vala index dbc775df7..8c7a7d452 100644 --- a/src/API/Attachment.vala +++ b/src/API/Attachment.vala @@ -83,7 +83,7 @@ public class Tuba.API.Attachment : Entity, Widgetizable { if (error != null || in_stream == null) throw new Oopsie.INSTANCE (error); else { - var parser = Network.get_parser_from_inputstream (in_stream); + var parser = yield Network.get_parser_from_inputstream_async (in_stream); var node = network.parse_node (parser); var entity = accounts.active.create_entity (node); debug (@"OK! ID $(entity.id)"); diff --git a/src/API/Mention.vala b/src/API/Mention.vala index 0f6afe676..dd0616c35 100644 --- a/src/API/Mention.vala +++ b/src/API/Mention.vala @@ -24,9 +24,15 @@ public class Tuba.API.Mention : Entity, Widgetizable { new Request.GET (@"/api/v1/accounts/$id") .with_account (accounts.active) .then ((in_stream) => { - var parser = Network.get_parser_from_inputstream (in_stream); - var node = network.parse_node (parser); - API.Account.from (node).open (); + Network.get_parser_from_inputstream_async.begin (in_stream, (obj, res) => { + try { + var parser = Network.get_parser_from_inputstream_async.end (res); + var node = network.parse_node (parser); + API.Account.from (node).open (); + } catch (Error e) { + critical (@"Couldn't parse json: $(e.code) $(e.message)"); + } + }); }) .exec (); } diff --git a/src/API/Notification.vala b/src/API/Notification.vala index 2cd0a72f2..b45a05348 100644 --- a/src/API/Notification.vala +++ b/src/API/Notification.vala @@ -91,9 +91,15 @@ public class Tuba.API.Notification : Entity, Widgetizable { new Request.GET (@"/api/v1/annual_reports/$year") .with_account (accounts.active) .then ((in_stream) => { - var parser = Network.get_parser_from_inputstream (in_stream); - var node = network.parse_node (parser); - API.AnnualReports.from (node).open (year); + Network.get_parser_from_inputstream_async.begin (in_stream, (obj, res) => { + try { + var parser = Network.get_parser_from_inputstream_async.end (res); + var node = network.parse_node (parser); + API.AnnualReports.from (node).open (year); + } catch (Error e) { + critical (@"Couldn't parse json: $(e.code) $(e.message)"); + } + }); }) .exec (); break; diff --git a/src/API/Relationship.vala b/src/API/Relationship.vala index e95d24954..63919692e 100644 --- a/src/API/Relationship.vala +++ b/src/API/Relationship.vala @@ -48,9 +48,15 @@ public class Tuba.API.Relationship : Entity { .with_account (accounts.active) .with_param ("id", id) .then ((in_stream) => { - var parser = Network.get_parser_from_inputstream (in_stream); - Network.parse_array (parser, node => { - invalidate (node); + Network.get_parser_from_inputstream_async.begin (in_stream, (obj, res) => { + try { + var parser = Network.get_parser_from_inputstream_async.end (res); + Network.parse_array (parser, node => { + invalidate (node); + }); + } catch (Error e) { + critical (@"Couldn't parse json: $(e.code) $(e.message)"); + } }); }) .exec (); @@ -64,7 +70,7 @@ public class Tuba.API.Relationship : Entity { .with_account (accounts.active); yield req.await (); - var parser = Network.get_parser_from_inputstream (req.response_body); + var parser = yield Network.get_parser_from_inputstream_async (req.response_body); Network.parse_array (parser, node => { API.Relationship entity = Entity.from_json (typeof (API.Relationship), node) as API.Relationship; entity.tuba_has_loaded = true; @@ -92,13 +98,19 @@ public class Tuba.API.Relationship : Entity { var req = new Request.POST (@"/api/v1/accounts/$id/$operation") .with_account (accounts.active) .then ((in_stream) => { - var parser = Network.get_parser_from_inputstream (in_stream); - var node = network.parse_node (parser); - invalidate (node); - debug (@"Performed \"$operation\" on Relationship $id"); - - if (operation in REQUIRES_USER_REMOVAL) app.remove_user_id (id); - else if (operation in REQUIRES_FEATURED_REFRESH) app.refresh_featured (); + Network.get_parser_from_inputstream_async.begin (in_stream, (obj, res) => { + try { + var parser = Network.get_parser_from_inputstream_async.end (res); + var node = network.parse_node (parser); + invalidate (node); + debug (@"Performed \"$operation\" on Relationship $id"); + + if (operation in REQUIRES_USER_REMOVAL) app.remove_user_id (id); + else if (operation in REQUIRES_FEATURED_REFRESH) app.refresh_featured (); + } catch (Error e) { + critical (@"Couldn't parse json: $(e.code) $(e.message)"); + } + }); }); if (modify_params != null) { @@ -123,10 +135,16 @@ public class Tuba.API.Relationship : Entity { .with_account (accounts.active) .body_json (builder) .then ((in_stream) => { - var parser = Network.get_parser_from_inputstream (in_stream); - var node = network.parse_node (parser); - invalidate (node); - debug (@"Performed \"note\" on Relationship $id"); + Network.get_parser_from_inputstream_async.begin (in_stream, (obj, res) => { + try { + var parser = Network.get_parser_from_inputstream_async.end (res); + var node = network.parse_node (parser); + invalidate (node); + debug (@"Performed \"note\" on Relationship $id"); + } catch (Error e) { + critical (@"Couldn't parse json: $(e.code) $(e.message)"); + } + }); }) .exec (); } diff --git a/src/API/SearchResults.vala b/src/API/SearchResults.vala index 07c67cdd9..4a06f6e85 100644 --- a/src/API/SearchResults.vala +++ b/src/API/SearchResults.vala @@ -39,7 +39,7 @@ public class Tuba.API.SearchResults : Entity { .with_param ("q", q); yield req.await (); - var parser = Network.get_parser_from_inputstream (req.response_body); + var parser = yield Network.get_parser_from_inputstream_async (req.response_body); return from (network.parse_node (parser)); } } diff --git a/src/API/Status/PreviewCard.vala b/src/API/Status/PreviewCard.vala index 0f97dcf08..f4fb28320 100644 --- a/src/API/Status/PreviewCard.vala +++ b/src/API/Status/PreviewCard.vala @@ -212,29 +212,36 @@ public class Tuba.API.PreviewCard : Entity, Widgetizable { new Request.GET (api_url) .then ((in_stream) => { - var parser = Network.get_parser_from_inputstream (in_stream); - var node = network.parse_node (parser); + Network.get_parser_from_inputstream_async.begin (in_stream, (obj, res) => { + try { + var parser = Network.get_parser_from_inputstream_async.end (res); + var node = network.parse_node (parser); - switch (this.special_card) { - case API.PreviewCard.CardSpecialType.FUNKWHALE: - var funkwhale_obj = API.Funkwhale.from (node); - string res_url; + switch (this.special_card) { + case API.PreviewCard.CardSpecialType.FUNKWHALE: + var funkwhale_obj = API.Funkwhale.from (node); + string res_url; - if (funkwhale_obj.get_track (host, out res_url)) { - app.main_window.show_media_viewer (res_url, Tuba.Attachment.MediaType.AUDIO, null, null, false, null, this.url, null, true); - } - break; - case API.PreviewCard.CardSpecialType.BOOKWYRM: - API.BookWyrm bookwyrm_obj = API.BookWyrm.from (node); + if (funkwhale_obj.get_track (host, out res_url)) { + app.main_window.show_media_viewer (res_url, Tuba.Attachment.MediaType.AUDIO, null, null, false, null, this.url, null, true); + } + break; + case API.PreviewCard.CardSpecialType.BOOKWYRM: + API.BookWyrm bookwyrm_obj = API.BookWyrm.from (node); - if (bookwyrm_obj.title != null && bookwyrm_obj.title != "") { - app.main_window.show_book (bookwyrm_obj); + if (bookwyrm_obj.title != null && bookwyrm_obj.title != "") { + app.main_window.show_book (bookwyrm_obj); + } + break; + default: + open_url (this.url); + break; } - break; - default: + } catch (Error e) { open_url (this.url); - break; - } + critical (@"Couldn't parse json: $(e.code) $(e.message)"); + } + }); }) .on_error (() => { open_url (this.url); diff --git a/src/Application.vala b/src/Application.vala index b6514c593..263f9a9ce 100644 --- a/src/Application.vala +++ b/src/Application.vala @@ -803,7 +803,7 @@ namespace Tuba { try { yield msg.await (); - var parser = Network.get_parser_from_inputstream (msg.response_body); + var parser = yield Network.get_parser_from_inputstream_async (msg.response_body); string[] new_contributors = {}; Network.parse_array (parser, node => { diff --git a/src/Dialogs/Composer/Attachment.vala b/src/Dialogs/Composer/Attachment.vala index 18ab25862..d0040a284 100644 --- a/src/Dialogs/Composer/Attachment.vala +++ b/src/Dialogs/Composer/Attachment.vala @@ -455,7 +455,7 @@ public class Tuba.Dialogs.Composer.Components.Attachment : Adw.Bin { this.progress = 1; this.file = file; try { - var parser = Network.get_parser_from_inputstream (in_stream); + var parser = yield Network.get_parser_from_inputstream_async (in_stream); var node = network.parse_node (parser); var entity = accounts.active.create_entity (node); diff --git a/src/Dialogs/Composer/Completion/HandleProvider.vala b/src/Dialogs/Composer/Completion/HandleProvider.vala index d6eac1a93..053d77c19 100644 --- a/src/Dialogs/Composer/Completion/HandleProvider.vala +++ b/src/Dialogs/Composer/Completion/HandleProvider.vala @@ -21,7 +21,7 @@ public class Tuba.HandleProvider: Tuba.CompletionProvider { yield req.await (); var results = new GLib.ListStore (typeof (Object)); - var parser = Network.get_parser_from_inputstream (req.response_body); + var parser = yield Network.get_parser_from_inputstream_async (req.response_body); Network.parse_array (parser, node => { var entity = Tuba.Helper.Entity.from_json (node, typeof (API.Account)); if (entity is API.Account) { diff --git a/src/Dialogs/Composer/Completion/HashtagProvider.vala b/src/Dialogs/Composer/Completion/HashtagProvider.vala index 1dd0b0ddc..97d8d76dc 100644 --- a/src/Dialogs/Composer/Completion/HashtagProvider.vala +++ b/src/Dialogs/Composer/Completion/HashtagProvider.vala @@ -21,7 +21,7 @@ public class Tuba.HashtagProvider: Tuba.CompletionProvider { yield req.await (); var suggestions = new GLib.ListStore (typeof (Object)); - var parser = Network.get_parser_from_inputstream (req.response_body); + var parser = yield Network.get_parser_from_inputstream_async (req.response_body); var results = API.SearchResults.from (network.parse_node (parser)); if (results != null) { results.hashtags.foreach (tag => { diff --git a/src/Dialogs/Composer/Dialog.vala b/src/Dialogs/Composer/Dialog.vala index 458116735..9b11888d1 100644 --- a/src/Dialogs/Composer/Dialog.vala +++ b/src/Dialogs/Composer/Dialog.vala @@ -1080,7 +1080,7 @@ public class Tuba.Dialogs.Composer.Dialog : Adw.Dialog { publish_req.body_json (populate_json_body ()); yield publish_req.await (); - var parser = Network.get_parser_from_inputstream (publish_req.response_body); + var parser = yield Network.get_parser_from_inputstream_async (publish_req.response_body); var node = network.parse_node (parser); var status = API.Status.from (node); debug (@"Published post with id $(status.id)"); diff --git a/src/Dialogs/FilterEdit.vala b/src/Dialogs/FilterEdit.vala index b9aeeba40..bfb5fb367 100644 --- a/src/Dialogs/FilterEdit.vala +++ b/src/Dialogs/FilterEdit.vala @@ -315,9 +315,16 @@ public class Tuba.Dialogs.FilterEdit : Adw.NavigationPage { .body_json (builder) .with_account (accounts.active) .then ((in_stream) => { - var parser = Network.get_parser_from_inputstream (in_stream); - var node = network.parse_node (parser); - saved (API.Filters.Filter.from (node)); + Network.get_parser_from_inputstream_async.begin (in_stream, (obj, res) => { + try { + var parser = Network.get_parser_from_inputstream_async.end (res); + var node = network.parse_node (parser); + saved (API.Filters.Filter.from (node)); + } catch (Error e) { + this.sensitive = true; + critical (@"Couldn't parse json: $(e.code) $(e.message)"); + } + }); on_close (); }) .on_error ((code, message) => { diff --git a/src/Dialogs/ListEdit.vala b/src/Dialogs/ListEdit.vala index 6211473d4..273242797 100644 --- a/src/Dialogs/ListEdit.vala +++ b/src/Dialogs/ListEdit.vala @@ -120,34 +120,40 @@ public class Tuba.Dialogs.ListEdit : Adw.PreferencesDialog { new Request.GET (@"/api/v1/lists/$(list.id)/accounts") .with_account (accounts.active) .then ((in_stream) => { - var parser = Network.get_parser_from_inputstream (in_stream); - if (Network.get_array_size (parser) > 0) { - this.add (members_page); - - Network.parse_array (parser, node => { - var member = API.Account.from (node); - var avi = new Widgets.Avatar () { - account = member, - size = 32 - }; - - var remove_button = new MemberCheckButton (member.id) { - active = false, - valign = Gtk.Align.CENTER, - halign = Gtk.Align.CENTER, - }; - remove_button.changed.connect (on_member_remove_changed); - - var member_row = new Adw.ActionRow () { - title = member.full_handle - }; - - member_row.add_prefix (avi); - member_row.add_suffix (remove_button); - - members_group.add (member_row); - }); - } + Network.get_parser_from_inputstream_async.begin (in_stream, (obj, res) => { + try { + var parser = Network.get_parser_from_inputstream_async.end (res); + if (Network.get_array_size (parser) > 0) { + this.add (members_page); + + Network.parse_array (parser, node => { + var member = API.Account.from (node); + var avi = new Widgets.Avatar () { + account = member, + size = 32 + }; + + var remove_button = new MemberCheckButton (member.id) { + active = false, + valign = Gtk.Align.CENTER, + halign = Gtk.Align.CENTER, + }; + remove_button.changed.connect (on_member_remove_changed); + + var member_row = new Adw.ActionRow () { + title = member.full_handle + }; + + member_row.add_prefix (avi); + member_row.add_suffix (remove_button); + + members_group.add (member_row); + }); + } + } catch (Error e) { + critical (@"Couldn't parse json: $(e.code) $(e.message)"); + } + }); }) .exec (); } diff --git a/src/Dialogs/NewAccount.vala b/src/Dialogs/NewAccount.vala index 09190635e..a845f50eb 100644 --- a/src/Dialogs/NewAccount.vala +++ b/src/Dialogs/NewAccount.vala @@ -186,7 +186,7 @@ public class Tuba.Dialogs.NewAccount: Adw.Window { .with_form_data ("website", Build.WEBSITE); yield msg.await (); - var parser = Network.get_parser_from_inputstream (msg.response_body); + var parser = yield Network.get_parser_from_inputstream_async (msg.response_body); var root = network.parse (parser); if (root.get_string_member ("name") != Build.NAME) @@ -226,7 +226,7 @@ public class Tuba.Dialogs.NewAccount: Adw.Window { .with_form_data ("code", code_entry.text); yield token_req.await (); - var parser = Network.get_parser_from_inputstream (token_req.response_body); + var parser = yield Network.get_parser_from_inputstream_async (token_req.response_body); var root = network.parse (parser); account.access_token = root.get_string_member ("access_token"); diff --git a/src/Dialogs/NotificationSettings.vala b/src/Dialogs/NotificationSettings.vala index c237548b3..612da651d 100644 --- a/src/Dialogs/NotificationSettings.vala +++ b/src/Dialogs/NotificationSettings.vala @@ -165,23 +165,30 @@ public class Tuba.Dialogs.NotificationSettings : Adw.Dialog { new Request.GET ("/api/v1/notifications/policy") .with_account (accounts.active) .then ((in_stream) => { - var parser = Network.get_parser_from_inputstream (in_stream); - var node = network.parse_node (parser); - if (node == null) return; + Network.get_parser_from_inputstream_async.begin (in_stream, (obj, res) => { + try { + var parser = Network.get_parser_from_inputstream_async.end (res); + var node = network.parse_node (parser); + if (node == null) return; - filtered_notifications_group.visible = true; - var policies = API.NotificationFilter.Policy.from (node); + filtered_notifications_group.visible = true; + var policies = API.NotificationFilter.Policy.from (node); - notification_filter_policy_status = new Gee.HashMap (); - notification_filter_policy_status.set (filter_notifications_following_switch, policies.filter_not_following); - notification_filter_policy_status.set (filter_notifications_follower_switch, policies.filter_not_followers); - notification_filter_policy_status.set (filter_notifications_new_account_switch, policies.filter_new_accounts); - notification_filter_policy_status.set (filter_notifications_dm_switch, policies.filter_private_mentions); + notification_filter_policy_status = new Gee.HashMap (); + notification_filter_policy_status.set (filter_notifications_following_switch, policies.filter_not_following); + notification_filter_policy_status.set (filter_notifications_follower_switch, policies.filter_not_followers); + notification_filter_policy_status.set (filter_notifications_new_account_switch, policies.filter_new_accounts); + notification_filter_policy_status.set (filter_notifications_dm_switch, policies.filter_private_mentions); - notification_filter_policy_status.@foreach (entry => { - ((Adw.SwitchRow) entry.key).active = (bool) entry.value; + notification_filter_policy_status.@foreach (entry => { + ((Adw.SwitchRow) entry.key).active = (bool) entry.value; - return true; + return true; + }); + + } catch (Error e) { + critical (@"Couldn't parse json: $(e.code) $(e.message)"); + } }); }) .on_error ((code, message) => { diff --git a/src/Dialogs/Preferences.vala b/src/Dialogs/Preferences.vala index dd12c3b90..9f79cb251 100644 --- a/src/Dialogs/Preferences.vala +++ b/src/Dialogs/Preferences.vala @@ -214,11 +214,17 @@ public class Tuba.Dialogs.Preferences : Adw.PreferencesDialog { new Request.GET ("/api/v2/filters") .with_account (accounts.active) .then ((in_stream) => { - var parser = Network.get_parser_from_inputstream (in_stream); - Network.parse_array (parser, node => { - var row = new FilterRow (API.Filters.Filter.from (node), this); - row.filter_deleted.connect (on_filter_delete); - keywords_group.add (row); + Network.get_parser_from_inputstream_async.begin (in_stream, (obj, res) => { + try { + var parser = Network.get_parser_from_inputstream_async.end (res); + Network.parse_array (parser, node => { + var row = new FilterRow (API.Filters.Filter.from (node), this); + row.filter_deleted.connect (on_filter_delete); + keywords_group.add (row); + }); + } catch (Error e) { + critical (@"Couldn't parse json: $(e.code) $(e.message)"); + } }); }) .exec (); @@ -356,11 +362,17 @@ public class Tuba.Dialogs.Preferences : Adw.PreferencesDialog { .with_account (accounts.active) .with_form_data ("source[language]", new_lang) .then ((in_stream) => { - var parser = Network.get_parser_from_inputstream (in_stream); - var node = network.parse_node (parser); - var updated = API.Account.from (node); - - settings.default_language = updated.source.language; + Network.get_parser_from_inputstream_async.begin (in_stream, (obj, res) => { + try { + var parser = Network.get_parser_from_inputstream_async.end (res); + var node = network.parse_node (parser); + var updated = API.Account.from (node); + + settings.default_language = updated.source.language; + } catch (Error e) { + critical (@"Couldn't parse json: $(e.code) $(e.message)"); + } + }); }) .exec (); } diff --git a/src/Dialogs/ProfileEdit.vala b/src/Dialogs/ProfileEdit.vala index 1288a4667..99d4387a5 100644 --- a/src/Dialogs/ProfileEdit.vala +++ b/src/Dialogs/ProfileEdit.vala @@ -317,8 +317,7 @@ public class Tuba.Dialogs.ProfileEdit : Adw.Dialog { } yield req.await (); - - accounts.active.update_object (req.response_body); + yield accounts.active.update_object (req.response_body); saved (); } diff --git a/src/Dialogs/Report.vala b/src/Dialogs/Report.vala index f26416143..83a8c2a28 100644 --- a/src/Dialogs/Report.vala +++ b/src/Dialogs/Report.vala @@ -485,40 +485,49 @@ public class Tuba.Dialogs.Report : Adw.Dialog { css_classes = {"boxed-list"} }; listbox.row_activated.connect (on_row_activated); - var parser = Network.get_parser_from_inputstream (in_stream); - - Network.parse_array (parser, node => { - var status = API.Status.from (node); - if (status_id != null && status.id == status_id) return; - status.spoiler_text = null; - status.tuba_spoiler_revealed = true; - status.sensitive = false; - status.card = null; - - var widget_status = status.to_widget () as Widgets.Status; - if (widget_status == null) return; - - var checkbutton = new Gtk.CheckButton () { - css_classes = {"selection-mode"}, - valign = Gtk.Align.CENTER - }; - status_buttons.set (status.id, checkbutton); - - widget_status.hexpand = true; - widget_status.indicators.visible = false; - widget_status.can_focus = false; - widget_status.can_target = false; - widget_status.focusable = false; - widget_status.actions.visible = false; - #if USE_LISTVIEW - widget_status.can_be_opened = false; - #else - widget_status.activatable = false; - #endif - listbox.append (new StatusRow (checkbutton, widget_status)); + + bool parsing_failed = false; + Network.get_parser_from_inputstream_async.begin (in_stream, (obj, res) => { + try { + var parser = Network.get_parser_from_inputstream_async.end (res); + + Network.parse_array (parser, node => { + var status = API.Status.from (node); + if (status_id != null && status.id == status_id) return; + status.spoiler_text = null; + status.tuba_spoiler_revealed = true; + status.sensitive = false; + status.card = null; + + var widget_status = status.to_widget () as Widgets.Status; + if (widget_status == null) return; + + var checkbutton = new Gtk.CheckButton () { + css_classes = {"selection-mode"}, + valign = Gtk.Align.CENTER + }; + status_buttons.set (status.id, checkbutton); + + widget_status.hexpand = true; + widget_status.indicators.visible = false; + widget_status.can_focus = false; + widget_status.can_target = false; + widget_status.focusable = false; + widget_status.actions.visible = false; + #if USE_LISTVIEW + widget_status.can_be_opened = false; + #else + widget_status.activatable = false; + #endif + listbox.append (new StatusRow (checkbutton, widget_status)); + }); + } catch (Error e) { + parsing_failed = true; + critical (@"Couldn't parse json: $(e.code) $(e.message)"); + } }); - if (status_buttons.size == 0) { + if (status_buttons.size == 0 || parsing_failed) { page_3.visible = false; page_3_error.description = _("%s. You can continue with the report however.").printf (_("No posts found")); page_3_stack.visible_child_name = "error"; diff --git a/src/Services/Accounts/AccountStore.vala b/src/Services/Accounts/AccountStore.vala index 3acef102b..4e1f701f5 100644 --- a/src/Services/Accounts/AccountStore.vala +++ b/src/Services/Accounts/AccountStore.vala @@ -163,7 +163,7 @@ public abstract class Tuba.AccountStore : GLib.Object { .with_account (account); yield req.await (); - var parser = Network.get_parser_from_inputstream (req.response_body); + var parser = yield Network.get_parser_from_inputstream_async (req.response_body); var root = network.parse (parser); string? backend = null; diff --git a/src/Services/Accounts/InstanceAccount.vala b/src/Services/Accounts/InstanceAccount.vala index d28e2f8c2..4b1394c87 100644 --- a/src/Services/Accounts/InstanceAccount.vala +++ b/src/Services/Accounts/InstanceAccount.vala @@ -157,25 +157,30 @@ public class Tuba.InstanceAccount : API.Account, Streamable { private void on_network_change () { if (is_active && app.is_online) { if (needs_update) { - needs_update = false; - new Request.GET (@"/api/v1/accounts/$(this.id)") - .with_account (this) - .then ((in_stream) => { - var parser = Network.get_parser_from_inputstream (in_stream); - var node = network.parse_node (parser); - if (node == null) { - needs_update = true; - return; - } - - var acc = API.Account.from (node); - - if (this.display_name != acc.display_name || this.avatar != acc.avatar) { - this.display_name = acc.display_name; - this.avatar = acc.avatar; - } - }) - .exec (); + needs_update = false; + new Request.GET (@"/api/v1/accounts/$(this.id)") + .with_account (this) + .then ((in_stream) => { + Network.get_parser_from_inputstream_async.begin (in_stream, (obj, res) => { + try { + var parser = Network.get_parser_from_inputstream_async.end (res); + var node = network.parse_node (parser); + if (node == null) { + needs_update = true; + return; + } + + var acc = API.Account.from (node); + if (this.display_name != acc.display_name || this.avatar != acc.avatar) { + this.display_name = acc.display_name; + this.avatar = acc.avatar; + } + } catch (Error e) { + critical (@"Couldn't parse json: $(e.code) $(e.message)"); + } + }); + }) + .exec (); } reconnect (); @@ -240,12 +245,11 @@ public class Tuba.InstanceAccount : API.Account, Streamable { public async void verify_credentials () throws Error { var req = new Request.GET ("/api/v1/accounts/verify_credentials").with_account (this); yield req.await (); - - update_object (req.response_body); + yield update_object (req.response_body); } - public void update_object (InputStream in_stream) throws Error { - var parser = Network.get_parser_from_inputstream (in_stream); + public async void update_object (InputStream in_stream) throws Error { + var parser = yield Network.get_parser_from_inputstream_async (in_stream); var node = network.parse_node (parser); var updated = API.Account.from (node); patch (updated); @@ -530,46 +534,52 @@ public class Tuba.InstanceAccount : API.Account, Streamable { new Request.GET ("/api/v1/instance") .with_account (this) .then ((in_stream) => { - var parser = Network.get_parser_from_inputstream (in_stream); - var node = network.parse_node (parser); - if (node == null) return; - - instance_info = API.Instance.from (node); - - var content_types = instance_info.compat_supported_mime_types; - if (content_types != null) { - supported_mime_types.remove_all (); - foreach (string content_type in content_types) { - supported_mime_types.append (new StatusContentType (content_type)); - } - } + Network.get_parser_from_inputstream_async.begin (in_stream, (obj, res) => { + try { + var parser = Network.get_parser_from_inputstream_async.end (res); + var node = network.parse_node (parser); + if (node == null) return; + + instance_info = API.Instance.from (node); + + var content_types = instance_info.compat_supported_mime_types; + if (content_types != null) { + supported_mime_types.remove_all (); + foreach (string content_type in content_types) { + supported_mime_types.append (new StatusContentType (content_type)); + } + } - var new_flags = this.tuba_instance_features; + var new_flags = this.tuba_instance_features; - if (instance_info.pleroma == null) { - gather_v2_instance_info (); - } else if (instance_info.pleroma.metadata != null && instance_info.pleroma.metadata.features != null) { - instance_info.tuba_can_translate = "akkoma:machine_translation" in instance_info.pleroma.metadata.features; + if (instance_info.pleroma == null) { + gather_v2_instance_info (); + } else if (instance_info.pleroma.metadata != null && instance_info.pleroma.metadata.features != null) { + instance_info.tuba_can_translate = "akkoma:machine_translation" in instance_info.pleroma.metadata.features; - new_flags = instance_info.supports_quote_posting ? new_flags | InstanceFeatures.QUOTE : new_flags & ~InstanceFeatures.QUOTE; - new_flags = instance_info.tuba_can_translate ? new_flags | InstanceFeatures.TRANSLATION : new_flags & ~InstanceFeatures.TRANSLATION; - new_flags = instance_info.supports_bubble ? new_flags | InstanceFeatures.BUBBLE : new_flags & ~InstanceFeatures.BUBBLE; - } + new_flags = instance_info.supports_quote_posting ? new_flags | InstanceFeatures.QUOTE : new_flags & ~InstanceFeatures.QUOTE; + new_flags = instance_info.tuba_can_translate ? new_flags | InstanceFeatures.TRANSLATION : new_flags & ~InstanceFeatures.TRANSLATION; + new_flags = instance_info.supports_bubble ? new_flags | InstanceFeatures.BUBBLE : new_flags & ~InstanceFeatures.BUBBLE; + } - if (instance_info.version != null) { - if ("Pleroma " in instance_info.version) { - new_flags |= InstanceFeatures.EMOJI_REACTIONS | InstanceFeatures.FEATURE_TAGS | InstanceFeatures.ENDORSE_USERS | InstanceFeatures.MUTUALS | InstanceFeatures.LOCAL_ONLY; - } else if ("Iceshrimp.NET/" in instance_info.version) { - new_flags |= InstanceFeatures.ICESHRIMP | InstanceFeatures.EMOJI_REACTIONS; - } else if ("+glitch" in instance_info.version) { - new_flags |= InstanceFeatures.GLITCH | InstanceFeatures.LOCAL_ONLY | InstanceFeatures.FEATURE_TAGS | InstanceFeatures.ENDORSE_USERS; - } else if ("+hometown" in instance_info.version) { - new_flags |= InstanceFeatures.LOCAL_ONLY | InstanceFeatures.FEATURE_TAGS | InstanceFeatures.ENDORSE_USERS; - } else if ("Akkoma " in instance_info.version) { - new_flags |= InstanceFeatures.EMOJI_REACTIONS | InstanceFeatures.LOCAL_ONLY; + if (instance_info.version != null) { + if ("Pleroma " in instance_info.version) { + new_flags |= InstanceFeatures.EMOJI_REACTIONS | InstanceFeatures.FEATURE_TAGS | InstanceFeatures.ENDORSE_USERS | InstanceFeatures.MUTUALS | InstanceFeatures.LOCAL_ONLY; + } else if ("Iceshrimp.NET/" in instance_info.version) { + new_flags |= InstanceFeatures.ICESHRIMP | InstanceFeatures.EMOJI_REACTIONS; + } else if ("+glitch" in instance_info.version) { + new_flags |= InstanceFeatures.GLITCH | InstanceFeatures.LOCAL_ONLY | InstanceFeatures.FEATURE_TAGS | InstanceFeatures.ENDORSE_USERS; + } else if ("+hometown" in instance_info.version) { + new_flags |= InstanceFeatures.LOCAL_ONLY | InstanceFeatures.FEATURE_TAGS | InstanceFeatures.ENDORSE_USERS; + } else if ("Akkoma " in instance_info.version) { + new_flags |= InstanceFeatures.EMOJI_REACTIONS | InstanceFeatures.LOCAL_ONLY; + } + } + tuba_instance_features_update_and_save (new_flags); + } catch (Error e) { + critical (@"Couldn't parse json: $(e.code) $(e.message)"); } - } - tuba_instance_features_update_and_save (new_flags); + }); app.handle_share (); bump_sidebar_items (); @@ -583,44 +593,50 @@ public class Tuba.InstanceAccount : API.Account, Streamable { new Request.GET ("/api/v2/instance") .with_account (this) .then ((in_stream) => { - var parser = Network.get_parser_from_inputstream (in_stream); - var node = network.parse_node (parser); - if (node == null) return; - - InstanceFeatures? new_flags = null; - var instance_v2 = API.InstanceV2.from (node); - if (instance_v2 != null) { - new_flags = this.tuba_instance_features; - - if (instance_v2.configuration != null) { - if (instance_v2.configuration.translation != null) this.instance_info.tuba_can_translate = instance_v2.configuration.translation.enabled; - if (instance_v2.configuration.media_attachments != null) this.instance_info.tuba_max_alt_chars = instance_v2.configuration.media_attachments.description_limit; + Network.get_parser_from_inputstream_async.begin (in_stream, (obj, res) => { + try { + var parser = Network.get_parser_from_inputstream_async.end (res); + var node = network.parse_node (parser); + if (node == null) return; + + InstanceFeatures? new_flags = null; + var instance_v2 = API.InstanceV2.from (node); + if (instance_v2 != null) { + new_flags = this.tuba_instance_features; + + if (instance_v2.configuration != null) { + if (instance_v2.configuration.translation != null) this.instance_info.tuba_can_translate = instance_v2.configuration.translation.enabled; + if (instance_v2.configuration.media_attachments != null) this.instance_info.tuba_max_alt_chars = instance_v2.configuration.media_attachments.description_limit; + + new_flags = instance_info.tuba_can_translate ? new_flags | InstanceFeatures.TRANSLATION : new_flags & ~InstanceFeatures.TRANSLATION; + } - new_flags = instance_info.tuba_can_translate ? new_flags | InstanceFeatures.TRANSLATION : new_flags & ~InstanceFeatures.TRANSLATION; - } + if (instance_v2.api_versions != null && instance_v2.api_versions.mastodon > 0) { + if (!this.tuba_api_versions.tuba_same (instance_v2.api_versions)) { + this.tuba_api_versions = instance_v2.api_versions; + accounts.update_account (this); + } + this.tuba_probably_has_notification_filters = true; - if (instance_v2.api_versions != null && instance_v2.api_versions.mastodon > 0) { - if (!this.tuba_api_versions.tuba_same (instance_v2.api_versions)) { - this.tuba_api_versions = instance_v2.api_versions; - accounts.update_account (this); - } - this.tuba_probably_has_notification_filters = true; + if (this.tuba_api_versions.mastodon > 1) { + gather_annual_report (); + new_flags |= InstanceFeatures.GROUP_NOTIFCATIONS; + } - if (this.tuba_api_versions.mastodon > 1) { - gather_annual_report (); - new_flags |= InstanceFeatures.GROUP_NOTIFCATIONS; - } + if (this.tuba_api_versions.chuckya > 0) { + new_flags |= InstanceFeatures.EMOJI_REACTIONS; + } - if (this.tuba_api_versions.chuckya > 0) { - new_flags |= InstanceFeatures.EMOJI_REACTIONS; + new_flags |= InstanceFeatures.FEATURE_TAGS | InstanceFeatures.ENDORSE_USERS | InstanceFeatures.MUTUALS; + new_flags = instance_info.supports_bubble ? new_flags | InstanceFeatures.BUBBLE : new_flags & ~InstanceFeatures.BUBBLE; + } } - new_flags |= InstanceFeatures.FEATURE_TAGS | InstanceFeatures.ENDORSE_USERS | InstanceFeatures.MUTUALS; - new_flags = instance_info.supports_bubble ? new_flags | InstanceFeatures.BUBBLE : new_flags & ~InstanceFeatures.BUBBLE; + if (new_flags != null) tuba_instance_features_update_and_save (new_flags); + } catch (Error e) { + critical (@"Couldn't parse json: $(e.code) $(e.message)"); } - } - - if (new_flags != null) tuba_instance_features_update_and_save (new_flags); + }); bump_sidebar_items (); }) .exec (); @@ -646,10 +662,16 @@ public class Tuba.InstanceAccount : API.Account, Streamable { new Request.GET (@"/api/v1/annual_reports/$(year)") .with_account (this) .then ((in_stream) => { - var parser = Network.get_parser_from_inputstream (in_stream); - var node = network.parse_node (parser); - annual_report = API.AnnualReports.from (node); - if (annual_report.annual_reports.size > 0) tuba_last_fediwrapped_year = year; + Network.get_parser_from_inputstream_async.begin (in_stream, (obj, res) => { + try { + var parser = Network.get_parser_from_inputstream_async.end (res); + var node = network.parse_node (parser); + annual_report = API.AnnualReports.from (node); + if (annual_report.annual_reports.size > 0) tuba_last_fediwrapped_year = year; + } catch (Error e) { + critical (@"Couldn't parse json: $(e.code) $(e.message)"); + } + }); }) .exec (); } @@ -667,13 +689,20 @@ public class Tuba.InstanceAccount : API.Account, Streamable { new Request.GET ("/api/v1/custom_emojis") .with_account (this) .then ((in_stream) => { - var parser = Network.get_parser_from_inputstream (in_stream); - var node = network.parse_node (parser); - if (node == null) return; - - Value res_emojis; - Entity.des_list (out res_emojis, node, typeof (API.Emoji)); - instance_emojis = (Gee.ArrayList) res_emojis; + Network.get_parser_from_inputstream_async.begin (in_stream, (obj, res) => { + try { + var parser = Network.get_parser_from_inputstream_async.end (res); + var node = network.parse_node (parser); + if (node == null) return; + + Value res_emojis; + Entity.des_list (out res_emojis, node, typeof (API.Emoji)); + instance_emojis = (Gee.ArrayList) res_emojis; + + } catch (Error e) { + critical (@"Couldn't parse json: $(e.code) $(e.message)"); + } + }); }) .exec (); } @@ -713,32 +742,38 @@ public class Tuba.InstanceAccount : API.Account, Streamable { new Request.GET ("/api/v1/lists") .with_account (this) .then ((in_stream) => { - var parser = Network.get_parser_from_inputstream (in_stream); - Place[] fav_lists = {}; - string[] all_ids = {}; - Network.parse_array (parser, node => { - var list = API.List.from (node); - if (list.id in settings.favorite_lists_ids) { - fav_lists += new Place () { - icon = "tuba-list-compact-symbolic", - title = list.title, - extra_data = list, - open_func = (win, list) => { - win.open_view (set_as_sidebar_item (new Views.List ((API.List) list))); - + Network.get_parser_from_inputstream_async.begin (in_stream, (obj, res) => { + try { + var parser = Network.get_parser_from_inputstream_async.end (res); + Place[] fav_lists = {}; + string[] all_ids = {}; + Network.parse_array (parser, node => { + var list = API.List.from (node); + if (list.id in settings.favorite_lists_ids) { + fav_lists += new Place () { + icon = "tuba-list-compact-symbolic", + title = list.title, + extra_data = list, + open_func = (win, list) => { + win.open_view (set_as_sidebar_item (new Views.List ((API.List) list))); + + } + }; } - }; - } - all_ids += list.id; - }); - this.register_extra (this.list_places, fav_lists); + all_ids += list.id; + }); + this.register_extra (this.list_places, fav_lists); - string[] new_favs = {}; - foreach (string fav_id in settings.favorite_lists_ids) { - if (fav_id in all_ids) new_favs += fav_id; - } - settings.favorite_lists_ids = new_favs; + string[] new_favs = {}; + foreach (string fav_id in settings.favorite_lists_ids) { + if (fav_id in all_ids) new_favs += fav_id; + } + settings.favorite_lists_ids = new_favs; + } catch (Error e) { + critical (@"Couldn't parse json: $(e.code) $(e.message)"); + } + }); }) .exec (); @@ -756,14 +791,20 @@ public class Tuba.InstanceAccount : API.Account, Streamable { .with_account (this) .with_param ("min_id", last_read_id.to_string ()) .then ((in_stream) => { - var parser = Network.get_parser_from_inputstream (in_stream); - var array = Network.get_array_mstd (parser); - if (array != null) { - unread_count = (int)array.get_length (); - if (unread_count > 0) { - last_received_id = int.parse (array.get_object_element (0).get_string_member_with_default ("id", "-1")); + Network.get_parser_from_inputstream_async.begin (in_stream, (obj, res) => { + try { + var parser = Network.get_parser_from_inputstream_async.end (res); + var array = Network.get_array_mstd (parser); + if (array != null) { + unread_count = (int)array.get_length (); + if (unread_count > 0) { + last_received_id = int.parse (array.get_object_element (0).get_string_member_with_default ("id", "-1")); + } + } + } catch (Error e) { + critical (@"Couldn't parse json: $(e.code) $(e.message)"); } - } + }); }) .exec (); } @@ -772,12 +813,19 @@ public class Tuba.InstanceAccount : API.Account, Streamable { new Request.GET ("/api/v1/markers?timeline[]=notifications") .with_account (this) .then ((in_stream) => { - var parser = Network.get_parser_from_inputstream (in_stream); - var root = network.parse (parser); - if (!root.has_member ("notifications")) return; - var notifications = root.get_object_member ("notifications"); - last_read_id = int.parse (notifications.get_string_member_with_default ("last_read_id", "-1")); - init_notifications (); + Network.get_parser_from_inputstream_async.begin (in_stream, (obj, res) => { + try { + var parser = Network.get_parser_from_inputstream_async.end (res); + var root = network.parse (parser); + if (!root.has_member ("notifications")) return; + var notifications = root.get_object_member ("notifications"); + last_read_id = int.parse (notifications.get_string_member_with_default ("last_read_id", "-1")); + } catch (Error e) { + critical (@"Couldn't parse json: $(e.code) $(e.message)"); + } + + init_notifications (); + }); }) .exec (); } @@ -786,15 +834,21 @@ public class Tuba.InstanceAccount : API.Account, Streamable { new Request.GET ("/api/v1/announcements") .with_account (this) .then ((in_stream) => { - var parser = Network.get_parser_from_inputstream (in_stream); - var array = Network.get_array_mstd (parser); - if (array != null) { - int t_unread_announcements = 0; - array.foreach_element ((array, i, node) => { - if (node.get_object ().get_boolean_member_with_default ("read", true) == false) t_unread_announcements += 1; - }); - unread_announcements = t_unread_announcements; - } + Network.get_parser_from_inputstream_async.begin (in_stream, (obj, res) => { + try { + var parser = Network.get_parser_from_inputstream_async.end (res); + var array = Network.get_array_mstd (parser); + if (array != null) { + int t_unread_announcements = 0; + array.foreach_element ((array, i, node) => { + if (node.get_object ().get_boolean_member_with_default ("read", true) == false) t_unread_announcements += 1; + }); + unread_announcements = t_unread_announcements; + } + } catch (Error e) { + critical (@"Couldn't parse json: $(e.code) $(e.message)"); + } + }); }) .exec (); } diff --git a/src/Services/Accounts/SecretAccountStore.vala b/src/Services/Accounts/SecretAccountStore.vala index ebfc1e8aa..ad430a471 100644 --- a/src/Services/Accounts/SecretAccountStore.vala +++ b/src/Services/Accounts/SecretAccountStore.vala @@ -73,16 +73,22 @@ public class Tuba.SecretAccountStore : AccountStore { new Request.GET (@"/api/v1/accounts/$(account.id)") .with_account (account) .then ((in_stream) => { - var parser = Network.get_parser_from_inputstream (in_stream); - var node = network.parse_node (parser); - var acc = API.Account.from (node); - - if (account.display_name != acc.display_name || account.avatar != acc.avatar) { - account.display_name = acc.display_name; - account.avatar = acc.avatar; - - account_to_secret (account); - } + Network.get_parser_from_inputstream_async.begin (in_stream, (obj, res) => { + try { + var parser = Network.get_parser_from_inputstream_async.end (res); + var node = network.parse_node (parser); + var acc = API.Account.from (node); + + if (account.display_name != acc.display_name || account.avatar != acc.avatar) { + account.display_name = acc.display_name; + account.avatar = acc.avatar; + + account_to_secret (account); + } + } catch (Error e) { + critical (@"Couldn't parse json: $(e.code) $(e.message)"); + } + }); }) .exec (); saved.add (account); diff --git a/src/Services/Network/Network.vala b/src/Services/Network/Network.vala index 201593c6e..edf0e3b3c 100644 --- a/src/Services/Network/Network.vala +++ b/src/Services/Network/Network.vala @@ -82,16 +82,21 @@ public class Tuba.Network : GLib.Object { if (ecb == null) { critical (@"Request \"$(msg.uri.to_string ())\" failed: $status $(msg.reason_phrase)"); } else { - string error_msg = msg.reason_phrase; + Network.get_parser_from_inputstream_async.begin (in_stream, (obj, res) => { + string error_msg = msg.reason_phrase; - try { - var parser = Network.get_parser_from_inputstream (in_stream); - var root = network.parse (parser); - if (root != null) - error_msg = root.get_string_member_with_default ("error", msg.reason_phrase); - } catch {} + try { + var parser = Network.get_parser_from_inputstream_async.end (res); + var root = network.parse (parser); + if (root != null) + error_msg = root.get_string_member_with_default ("error", msg.reason_phrase); + } catch (Error e) { + critical (@"Couldn't parse json: $(e.code) $(e.message)"); + } + + ecb ((int32) status, error_msg); + }); - ecb ((int32) status, error_msg); } } } catch (GLib.Error e) { @@ -125,6 +130,12 @@ public class Tuba.Network : GLib.Object { return parser; } + public static async Json.Parser get_parser_from_inputstream_async (InputStream in_stream) throws Error { + var parser = new Json.Parser (); + yield parser.load_from_stream_async (in_stream); + return parser; + } + public static Json.Array? get_array_mstd (Json.Parser parser) { return parser.get_root ().get_array (); } diff --git a/src/Services/Network/Request.vala b/src/Services/Network/Request.vala index 4257656a4..900a117f1 100644 --- a/src/Services/Network/Request.vala +++ b/src/Services/Network/Request.vala @@ -88,8 +88,14 @@ public class Tuba.Request : GLib.Object { public Request then_parse_array (owned Network.NodeCallback _cb) { this.cb = (in_stream) => { - var parser = Network.get_parser_from_inputstream (in_stream); - Network.parse_array (parser, (owned) _cb); + Network.get_parser_from_inputstream_async.begin (in_stream, (obj, res) => { + try { + var parser = Network.get_parser_from_inputstream_async.end (res); + Network.parse_array (parser, (owned) _cb); + } catch (Error e) { + critical (@"Couldn't parse json: $(e.code) $(e.message)"); + } + }); }; return this; } diff --git a/src/Views/Admin/Pages/Dashboard.vala b/src/Views/Admin/Pages/Dashboard.vala index 536f72c21..c376b154f 100644 --- a/src/Views/Admin/Pages/Dashboard.vala +++ b/src/Views/Admin/Pages/Dashboard.vala @@ -63,27 +63,32 @@ public class Tuba.Views.Admin.Page.Dashboard : Views.Admin.Page.Base { .with_account (accounts.active) .body_json (get_dimensions_body (key)) .then ((in_stream) => { - var parser = Network.get_parser_from_inputstream (in_stream); - Network.parse_array (parser, node => { - if (node != null) { - var dimension = API.Admin.Dimension.from (node); - if (dimension.key == key && dimension.total != null) { - add_stat ( - new Adw.ActionRow () { - title = title, - subtitle = dimension.total, - use_markup = false, - subtitle_selectable = true + Network.get_parser_from_inputstream_async.begin (in_stream, (obj, res) => { + try { + var parser = Network.get_parser_from_inputstream_async.end (res); + Network.parse_array (parser, node => { + if (node != null) { + var dimension = API.Admin.Dimension.from (node); + if (dimension.key == key && dimension.total != null) { + add_stat ( + new Adw.ActionRow () { + title = title, + subtitle = dimension.total, + use_markup = false, + subtitle_selectable = true + } + ); + + if (next_i > -1) { + populate_stats (next_i); + } } - ); - - if (next_i > -1) { - populate_stats (next_i); } - } + }); + } catch (Error e) { + critical (@"Couldn't parse json: $(e.code) $(e.message)"); } }); - update_requests (-1); }) .on_error ((code, message) => { @@ -100,23 +105,29 @@ public class Tuba.Views.Admin.Page.Dashboard : Views.Admin.Page.Base { .with_account (accounts.active) .body_json (get_dimensions_body (key, limit)) .then ((in_stream) => { - var parser = Network.get_parser_from_inputstream (in_stream); - Network.parse_array (parser, node => { - if (node != null) { - var dimension = API.Admin.Dimension.from (node); - if (dimension.key == key && dimension.data != null && dimension.data.size > 0) { - foreach (var entry in dimension.data) { - group.add ( - new Adw.ActionRow () { - title = entry.human_key, - subtitle = entry.human_value != null ? entry.human_value : entry.value, - use_markup = false, - subtitle_selectable = true + Network.get_parser_from_inputstream_async.begin (in_stream, (obj, res) => { + try { + var parser = Network.get_parser_from_inputstream_async.end (res); + Network.parse_array (parser, node => { + if (node != null) { + var dimension = API.Admin.Dimension.from (node); + if (dimension.key == key && dimension.data != null && dimension.data.size > 0) { + foreach (var entry in dimension.data) { + group.add ( + new Adw.ActionRow () { + title = entry.human_key, + subtitle = entry.human_value != null ? entry.human_value : entry.value, + use_markup = false, + subtitle_selectable = true + } + ); + group.visible = true; } - ); - group.visible = true; + } } - } + }); + } catch (Error e) { + critical (@"Couldn't parse json: $(e.code) $(e.message)"); } }); update_requests (-1); diff --git a/src/Views/Admin/Timelines/PaginationTimeline.vala b/src/Views/Admin/Timelines/PaginationTimeline.vala index 61bd13baf..0d8ef5421 100644 --- a/src/Views/Admin/Timelines/PaginationTimeline.vala +++ b/src/Views/Admin/Timelines/PaginationTimeline.vala @@ -133,15 +133,22 @@ public class Tuba.Views.Admin.Timeline.PaginationTimeline : Gtk.Box { .with_extra_data (Tuba.Network.ExtraData.RESPONSE_HEADERS) .then ((in_stream, headers) => { content.remove_all (); - var parser = Network.get_parser_from_inputstream (in_stream); - - Network.parse_array (parser, node => { - content.append (on_create_model_widget (Tuba.Helper.Entity.from_json (node, accepts))); + Network.get_parser_from_inputstream_async.begin (in_stream, (obj, res) => { + try { + var parser = Network.get_parser_from_inputstream_async.end (res); + + Network.parse_array (parser, node => { + content.append (on_create_model_widget (Tuba.Helper.Entity.from_json (node, accepts))); + }); + + if (headers != null) + get_pages (headers.get_one ("Link")); + } catch (Error e) { + on_error (e.code, e.message); + critical (@"Couldn't parse json: $(e.code) $(e.message)"); + } + this.working = false; }); - - this.working = false; - if (headers != null) - get_pages (headers.get_one ("Link")); }) .on_error ((code, message) => { on_error (code, message); diff --git a/src/Views/FollowRequests.vala b/src/Views/FollowRequests.vala index 4bd8f67f4..0c5cbef33 100644 --- a/src/Views/FollowRequests.vala +++ b/src/Views/FollowRequests.vala @@ -24,17 +24,23 @@ public class Tuba.Views.FollowRequests : Views.Timeline { fr_row.sensitive = false; req .then ((in_stream) => { - var parser = Network.get_parser_from_inputstream (in_stream); - var node = network.parse_node (parser); - var relationship = Entity.from_json (typeof (API.Relationship), node) as API.Relationship; - if (relationship.followed_by == true) { - uint indx; - var found = model.find (widget, out indx); - if (found) - model.remove (indx); - } else { + Network.get_parser_from_inputstream_async.begin (in_stream, (obj, res) => { + try { + var parser = Network.get_parser_from_inputstream_async.end (res); + var node = network.parse_node (parser); + var relationship = Entity.from_json (typeof (API.Relationship), node) as API.Relationship; + if (relationship.followed_by == true) { + uint indx; + var found = model.find (widget, out indx); + if (found) + model.remove (indx); + } + } catch (Error e) { + critical (@"Couldn't parse json: $(e.code) $(e.message)"); + } + fr_row.sensitive = true; - } + }); }) .exec (); } diff --git a/src/Views/Hashtag.vala b/src/Views/Hashtag.vala index 379f3a536..aa71a6d62 100644 --- a/src/Views/Hashtag.vala +++ b/src/Views/Hashtag.vala @@ -58,13 +58,21 @@ public class Tuba.Views.Hashtag : Views.Timeline { new Request.POST (@"/api/v1/tags/$tag/$(!this.featured ? "unfeature" : "feature")") // we reversed it above .with_account (accounts.active) .then ((in_stream) => { - var parser = Network.get_parser_from_inputstream (in_stream); + Network.get_parser_from_inputstream_async.begin (in_stream, (obj, res) => { + try { + var parser = Network.get_parser_from_inputstream_async.end (res); - var node = network.parse_node (parser); - var tag_info = API.Tag.from (node); + var node = network.parse_node (parser); + var tag_info = API.Tag.from (node); - if (this.following != tag_info.following) this.following = tag_info.following; - if (this.featured != tag_info.featuring) this.featured = tag_info.featuring; + if (this.following != tag_info.following) this.following = tag_info.following; + if (this.featured != tag_info.featuring) this.featured = tag_info.featuring; + + } catch (Error e) { + this.featured = !this.featured; + critical (@"Couldn't parse json: $(e.code) $(e.message)"); + } + }); app.refresh_featured (); feature_tag_btn.unblock_clicked (); @@ -108,11 +116,18 @@ public class Tuba.Views.Hashtag : Views.Timeline { new Request.POST (@"/api/v1/tags/$tag/$action") .with_account (accounts.active) .then ((in_stream) => { - var parser = Network.get_parser_from_inputstream (in_stream); - var root = network.parse (parser); - if (!root.has_member ("following")) { - this.following = !this.following; - }; + Network.get_parser_from_inputstream_async.begin (in_stream, (obj, res) => { + try { + var parser = Network.get_parser_from_inputstream_async.end (res); + var root = network.parse (parser); + if (!root.has_member ("following")) { + this.following = !this.following; + }; + } catch (Error e) { + this.following = !this.following; + critical (@"Couldn't parse json: $(e.code) $(e.message)"); + } + }); }) .exec (); } @@ -121,12 +136,18 @@ public class Tuba.Views.Hashtag : Views.Timeline { new Request.GET (@"/api/v1/tags/$tag") .with_account (accounts.active) .then ((in_stream) => { - var parser = Network.get_parser_from_inputstream (in_stream); - var node = network.parse_node (parser); - var tag_info = API.Tag.from (node); - this.following = tag_info.following; - this.featured = tag_info.featuring; - create_featuring_button (); + Network.get_parser_from_inputstream_async.begin (in_stream, (obj, res) => { + try { + var parser = Network.get_parser_from_inputstream_async.end (res); + var node = network.parse_node (parser); + var tag_info = API.Tag.from (node); + this.following = tag_info.following; + this.featured = tag_info.featuring; + create_featuring_button (); + } catch (Error e) { + critical (@"Couldn't parse json: $(e.code) $(e.message)"); + } + }); }) .exec (); } diff --git a/src/Views/Lists.vala b/src/Views/Lists.vala index d9d974750..83d7d87c1 100644 --- a/src/Views/Lists.vala +++ b/src/Views/Lists.vala @@ -188,10 +188,16 @@ public class Tuba.Views.Lists : Views.Timeline { .with_account (accounts.active) .body_json (builder) .then ((in_stream) => { - var parser = Network.get_parser_from_inputstream (in_stream); - var node = network.parse_node (parser); - var list = API.List.from (node); - model.insert (0, list); + Network.get_parser_from_inputstream_async.begin (in_stream, (obj, res) => { + try { + var parser = Network.get_parser_from_inputstream_async.end (res); + var node = network.parse_node (parser); + var list = API.List.from (node); + model.insert (0, list); + } catch (Error e) { + critical (@"Couldn't parse json: $(e.code) $(e.message)"); + } + }); }) .exec (); } diff --git a/src/Views/Notifications.vala b/src/Views/Notifications.vala index 1d383c872..b8c431c1e 100644 --- a/src/Views/Notifications.vala +++ b/src/Views/Notifications.vala @@ -189,45 +189,51 @@ public class Tuba.Views.Notifications : Views.Timeline, AccountHolder, Streamabl .with_ctx (this) .with_extra_data (Tuba.Network.ExtraData.RESPONSE_HEADERS) .then ((in_stream, headers) => { - var parser = Network.get_parser_from_inputstream (in_stream); - var node = network.parse_node (parser); - if (node == null) return; - - Object[] to_add = {}; - var group_notifications = API.GroupedNotificationsResults.from (node); - foreach (var group in group_notifications.notification_groups) { - Gee.ArrayList group_accounts = new Gee.ArrayList (); - foreach (var account in group_notifications.accounts) { - if (account.id in group.sample_account_ids) - group_accounts.add (account); - } - group.tuba_accounts = group_accounts; + Network.get_parser_from_inputstream_async.begin (in_stream, (obj, res) => { + try { + var parser = Network.get_parser_from_inputstream_async.end (res); + var node = network.parse_node (parser); + if (node == null) return; + + Object[] to_add = {}; + var group_notifications = API.GroupedNotificationsResults.from (node); + foreach (var group in group_notifications.notification_groups) { + Gee.ArrayList group_accounts = new Gee.ArrayList (); + foreach (var account in group_notifications.accounts) { + if (account.id in group.sample_account_ids) + group_accounts.add (account); + } + group.tuba_accounts = group_accounts; - if (group.tuba_accounts.size == 1) { - group.account = group.tuba_accounts.get (0); - } + if (group.tuba_accounts.size == 1) { + group.account = group.tuba_accounts.get (0); + } - if (group.status_id != null) { - foreach (var status in group_notifications.statuses) { - if (status.id == group.status_id) { - group.status = status; - break; + if (group.status_id != null) { + foreach (var status in group_notifications.statuses) { + if (status.id == group.status_id) { + group.status = status; + break; + } + } } - } - } - // filtering is based on the status - // so it can only happen after the above - if (!(should_hide (group))) to_add += group; - } - model.splice (model.get_n_items (), 0, to_add); + // filtering is based on the status + // so it can only happen after the above + if (!(should_hide (group))) to_add += group; + } + model.splice (model.get_n_items (), 0, to_add); - if (headers != null) - get_pages (headers.get_one ("Link")); + if (headers != null) + get_pages (headers.get_one ("Link")); - if (to_add.length == 0) - on_content_changed (); - on_request_finish (); + if (to_add.length == 0) + on_content_changed (); + on_request_finish (); + } catch (Error e) { + on_error (e.code, e.message); + } + }); }) .on_error (on_error) .exec (); @@ -239,17 +245,24 @@ public class Tuba.Views.Notifications : Views.Timeline, AccountHolder, Streamabl new Request.GET ("/api/v1/notifications/policy") .with_account (accounts.active) .then ((in_stream) => { - var parser = Network.get_parser_from_inputstream (in_stream); - var node = network.parse_node (parser); - if (node == null) { - accounts.active.filtered_notifications_count = 0; - return; - }; - - var policies = API.NotificationFilter.Policy.from (node); - if (policies.summary != null) { - accounts.active.filtered_notifications_count = policies.summary.pending_notifications_count; - } + Network.get_parser_from_inputstream_async.begin (in_stream, (obj, res) => { + try { + var parser = Network.get_parser_from_inputstream_async.end (res); + var node = network.parse_node (parser); + if (node == null) { + accounts.active.filtered_notifications_count = 0; + return; + }; + + var policies = API.NotificationFilter.Policy.from (node); + if (policies.summary != null) { + accounts.active.filtered_notifications_count = policies.summary.pending_notifications_count; + } + } catch (Error e) { + accounts.active.filtered_notifications_count = 0; + critical (@"Couldn't parse json: $(e.code) $(e.message)"); + } + }); }) .on_error ((code, message) => { accounts.active.filtered_notifications_count = 0; diff --git a/src/Views/Profile.vala b/src/Views/Profile.vala index 86e3f09bb..8daf7895f 100644 --- a/src/Views/Profile.vala +++ b/src/Views/Profile.vala @@ -14,7 +14,7 @@ public class Tuba.Views.Profile : Views.Accounts { try { yield req.await (); - var parser = Network.get_parser_from_inputstream (req.response_body); + var parser = yield Network.get_parser_from_inputstream_async (req.response_body); var node = network.parse_node (parser); var updated = API.Account.from (node); @@ -147,17 +147,23 @@ public class Tuba.Views.Profile : Views.Accounts { .with_param ("pinned", "true") .with_ctx (this) .then ((in_stream) => { - var parser = Network.get_parser_from_inputstream (in_stream); + Network.get_parser_from_inputstream_async.begin (in_stream, (obj, res) => { + try { + var parser = Network.get_parser_from_inputstream_async.end (res); - Object[] to_add = {}; - Network.parse_array (parser, node => { - var e = Tuba.Helper.Entity.from_json (node, typeof (API.Status)); - var e_status = e as API.Status; - if (e_status != null) e_status.pinned = true; + Object[] to_add = {}; + Network.parse_array (parser, node => { + var e = Tuba.Helper.Entity.from_json (node, typeof (API.Status)); + var e_status = e as API.Status; + if (e_status != null) e_status.pinned = true; - to_add += e_status; + to_add += e_status; + }); + model.splice (TOTAL_STATIC_ITEMS, 0, to_add); + } catch (Error e) { + critical (@"Couldn't parse json: $(e.code) $(e.message)"); + } }); - model.splice (TOTAL_STATIC_ITEMS, 0, to_add); }) .exec (); } @@ -322,7 +328,7 @@ public class Tuba.Views.Profile : Views.Accounts { .with_ctx (this); yield req.await (); - var parser = Network.get_parser_from_inputstream (req.response_body); + var parser = yield Network.get_parser_from_inputstream_async (req.response_body); Network.parse_array (parser, node => { to_add += Tuba.Helper.Entity.from_json (node, typeof (API.FeaturedTag)); }); @@ -621,68 +627,80 @@ public class Tuba.Views.Profile : Views.Accounts { title = _("You don't have any lists") }; + // TODO: async yield these new Request.GET ("/api/v1/lists/") .with_account (accounts.active) .with_ctx (this) .on_error (on_error) .then ((in_stream) => { - var parser = Network.get_parser_from_inputstream (in_stream); - if (Network.get_array_size (parser) > 0) { - new Request.GET (@"/api/v1/accounts/$(profile.account.id)/lists") - .with_account (accounts.active) - .with_ctx (this) - .on_error (on_error) - .then ((in_stream2) => { - var added = false; - var in_list = new Gee.ArrayList (); - - var parser2 = Network.get_parser_from_inputstream (in_stream2); - Network.parse_array (parser2, node => { - var list = API.List.from (node); - in_list.add (list.id); - }); - Network.parse_array (parser, node => { - var list = API.List.from (node); - var is_already = in_list.contains (list.id); - - var add_button = new RowButton () { - icon_name = is_already ? "tuba-minus-large-symbolic" : "tuba-plus-large-symbolic", - tooltip_text = is_already - ? _("Remove \"%s\" from \"%s\"").printf (profile.account.handle, list.title) - : _("Add \"%s\" to \"%s\"").printf (profile.account.handle, list.title), - halign = Gtk.Align.CENTER, - valign = Gtk.Align.CENTER, - css_classes = { "flat", "circular" } - }; - add_button.remove = is_already; - - var row = new Adw.ActionRow () { - use_markup = false, - title = list.title - }; - row.add_suffix (add_button); - - add_button.clicked.connect (() => { - handle_list_edit (list, row, toast_overlay, add_button); - }); - - preferences_group.add (row); - added = true; - }); - - if (added) { - preferences_page.add (preferences_group); - - toast_overlay.child = preferences_page; - toast_overlay.valign = Gtk.Align.FILL; + Network.get_parser_from_inputstream_async.begin (in_stream, (obj, res) => { + try { + var parser = Network.get_parser_from_inputstream_async.end (res); + if (Network.get_array_size (parser) > 0) { + new Request.GET (@"/api/v1/accounts/$(profile.account.id)/lists") + .with_account (accounts.active) + .with_ctx (this) + .on_error (on_error) + .then ((in_stream2) => { + Network.get_parser_from_inputstream_async.begin (in_stream2, (obj, res) => { + try { + var added = false; + var in_list = new Gee.ArrayList (); + var parser2 = Network.get_parser_from_inputstream_async.end (res); + Network.parse_array (parser2, node => { + var list = API.List.from (node); + in_list.add (list.id); + }); + Network.parse_array (parser, node => { + var list = API.List.from (node); + var is_already = in_list.contains (list.id); + + var add_button = new RowButton () { + icon_name = is_already ? "tuba-minus-large-symbolic" : "tuba-plus-large-symbolic", + tooltip_text = is_already + ? _("Remove \"%s\" from \"%s\"").printf (profile.account.handle, list.title) + : _("Add \"%s\" to \"%s\"").printf (profile.account.handle, list.title), + halign = Gtk.Align.CENTER, + valign = Gtk.Align.CENTER, + css_classes = { "flat", "circular" } + }; + add_button.remove = is_already; + + var row = new Adw.ActionRow () { + use_markup = false, + title = list.title + }; + row.add_suffix (add_button); + + add_button.clicked.connect (() => { + handle_list_edit (list, row, toast_overlay, add_button); + }); + + preferences_group.add (row); + added = true; + }); + + if (added) { + preferences_page.add (preferences_group); + + toast_overlay.child = preferences_page; + toast_overlay.valign = Gtk.Align.FILL; + } else { + toast_overlay.child = no_lists_page; + } + } catch (Error e) { + critical (@"Couldn't parse json: $(e.code) $(e.message)"); + } + }); + }) + .exec (); } else { toast_overlay.child = no_lists_page; } - }) - .exec (); - } else { - toast_overlay.child = no_lists_page; - } + } catch (Error e) { + critical (@"Couldn't parse json: $(e.code) $(e.message)"); + } + }); }) .exec (); diff --git a/src/Views/Search.vala b/src/Views/Search.vala index a0bd0ba9b..10249063e 100644 --- a/src/Views/Search.vala +++ b/src/Views/Search.vala @@ -485,12 +485,18 @@ public class Tuba.Views.Search : Views.TabbedBase { .with_param ("exclude_unreviewed", "true") .with_param ("limit", "1") .then ((in_stream) => { - var parser = Network.get_parser_from_inputstream (in_stream); - var search_results = API.SearchResults.from (network.parse_node (parser)); + Network.get_parser_from_inputstream_async.begin (in_stream, (obj, res) => { + try { + var parser = Network.get_parser_from_inputstream_async.end (res); + var search_results = API.SearchResults.from (network.parse_node (parser)); - if (search_results.accounts.size > 0) { - user_row.text = search_results.accounts.get (0).full_handle; - } + if (search_results.accounts.size > 0) { + user_row.text = search_results.accounts.get (0).full_handle; + } + } catch (Error e) { + critical (@"Couldn't parse json: $(e.code) $(e.message)"); + } + }); auto_fill_users_button.sensitive = true; }) diff --git a/src/Views/Thread.vala b/src/Views/Thread.vala index e73723a34..110a8b924 100644 --- a/src/Views/Thread.vala +++ b/src/Views/Thread.vala @@ -47,15 +47,21 @@ public class Tuba.Views.Thread : Views.ContentBase, AccountHolder { .with_account (account) .with_ctx (this) .then ((in_stream) => { - var parser = Network.get_parser_from_inputstream (in_stream); - var node = network.parse_node (parser); - var api_status = API.Status.from (node); - if (api_status != null) { - if (root_status != null) root_status.patch (api_status); - if (root_status_widget != null) { - root_status_widget.on_edit (api_status); + Network.get_parser_from_inputstream_async.begin (in_stream, (obj, res) => { + try { + var parser = Network.get_parser_from_inputstream_async.end (res); + var node = network.parse_node (parser); + var api_status = API.Status.from (node); + if (api_status != null) { + if (root_status != null) root_status.patch (api_status); + if (root_status_widget != null) { + root_status_widget.on_edit (api_status); + } + } + } catch (Error e) { + critical (@"Couldn't parse json: $(e.code) $(e.message)"); } - } + }); }) .exec (); } @@ -165,42 +171,48 @@ public class Tuba.Views.Thread : Views.ContentBase, AccountHolder { .with_account (account) .with_ctx (this) .then ((in_stream) => { - 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 = (API.Status) Tuba.Helper.Entity.from_json (node, typeof (API.Status)); - if (!e.formal.tuba_filter_hidden) - to_add_ancestors += e; - }); - to_add_ancestors += root_status; - model.splice (model.get_n_items (), 0, to_add_ancestors); - - Object[] to_add_descendants = {}; - var descendants = root.get_array_member ("descendants"); - descendants.foreach_element ((array, i, node) => { - var e = (API.Status) Tuba.Helper.Entity.from_json (node, typeof (API.Status)); - if (!e.formal.tuba_filter_hidden) - to_add_descendants += e; - }); - model.splice (model.get_n_items (), 0, to_add_descendants); - - connect_threads (); - on_content_changed (); - - #if USE_LISTVIEW - if (to_add_ancestors.length > 0) { - uint timeout = 0; - timeout = Timeout.add (1000, () => { - content.scroll_to (to_add_ancestors.length, Gtk.ListScrollFlags.FOCUS, null); - - GLib.Source.remove (timeout); - return true; - }, Priority.LOW); + Network.get_parser_from_inputstream_async.begin (in_stream, (obj, res) => { + try { + var parser = Network.get_parser_from_inputstream_async.end (res); + var root = network.parse (parser); + + Object[] to_add_ancestors = {}; + var ancestors = root.get_array_member ("ancestors"); + ancestors.foreach_element ((array, i, node) => { + var e = (API.Status) Tuba.Helper.Entity.from_json (node, typeof (API.Status)); + if (!e.formal.tuba_filter_hidden) + to_add_ancestors += e; + }); + to_add_ancestors += root_status; + model.splice (model.get_n_items (), 0, to_add_ancestors); + + Object[] to_add_descendants = {}; + var descendants = root.get_array_member ("descendants"); + descendants.foreach_element ((array, i, node) => { + var e = (API.Status) Tuba.Helper.Entity.from_json (node, typeof (API.Status)); + if (!e.formal.tuba_filter_hidden) + to_add_descendants += e; + }); + model.splice (model.get_n_items (), 0, to_add_descendants); + + connect_threads (); + on_content_changed (); + + #if USE_LISTVIEW + if (to_add_ancestors.length > 0) { + uint timeout = 0; + timeout = Timeout.add (1000, () => { + content.scroll_to (to_add_ancestors.length, Gtk.ListScrollFlags.FOCUS, null); + + GLib.Source.remove (timeout); + return true; + }, Priority.LOW); + } + #endif + } catch (Error e) { + critical (@"Couldn't parse json: $(e.code) $(e.message)"); } - #endif + }); }) .exec (); @@ -213,16 +225,22 @@ public class Tuba.Views.Thread : Views.ContentBase, AccountHolder { .with_param ("q", q) .with_param ("resolve", "true") .then ((in_stream) => { - var parser = Network.get_parser_from_inputstream (in_stream); - var root = network.parse (parser); - var statuses = root.get_array_member ("statuses"); - var node = statuses.get_element (0); - if (node != null) { - var status = API.Status.from (node); - app.main_window.open_view (new Views.Thread (status)); - } - else - Utils.Host.open_url.begin (q); + Network.get_parser_from_inputstream_async.begin (in_stream, (obj, res) => { + try { + var parser = Network.get_parser_from_inputstream_async.end (res); + var root = network.parse (parser); + var statuses = root.get_array_member ("statuses"); + var node = statuses.get_element (0); + if (node != null) { + var status = API.Status.from (node); + app.main_window.open_view (new Views.Thread (status)); + } + else + Utils.Host.open_url.begin (q); + } catch (Error e) { + critical (@"Couldn't parse json: $(e.code) $(e.message)"); + } + }); }) .exec (); } diff --git a/src/Views/Timeline.vala b/src/Views/Timeline.vala index bf980eb1f..46bc3b4f0 100644 --- a/src/Views/Timeline.vala +++ b/src/Views/Timeline.vala @@ -204,21 +204,26 @@ public class Tuba.Views.Timeline : AccountHolder, Streamable, Views.ContentBase .with_ctx (this) .with_extra_data (Tuba.Network.ExtraData.RESPONSE_HEADERS) .then ((in_stream, headers) => { - var parser = Network.get_parser_from_inputstream (in_stream); - - Object[] to_add = {}; - Network.parse_array (parser, node => { - var e = Tuba.Helper.Entity.from_json (node, accepts); - if (!(should_hide (e))) to_add += e; + Network.get_parser_from_inputstream_async.begin (in_stream, (obj, res) => { + try { + var parser = Network.get_parser_from_inputstream_async.end (res); + Object[] to_add = {}; + Network.parse_array (parser, node => { + var e = Tuba.Helper.Entity.from_json (node, accepts); + if (!(should_hide (e))) to_add += e; + }); + model.splice (model.get_n_items (), 0, to_add); + + if (headers != null) + get_pages (headers.get_one ("Link")); + + if (to_add.length == 0) + on_content_changed (); + on_request_finish (); + } catch (Error e) { + on_error (e.code, e.message); + } }); - model.splice (model.get_n_items (), 0, to_add); - - if (headers != null) - get_pages (headers.get_one ("Link")); - - if (to_add.length == 0) - on_content_changed (); - on_request_finish (); }) .on_error (on_error) .exec (); diff --git a/src/Widgets/AccountSuggestions.vala b/src/Widgets/AccountSuggestions.vala index ded231793..d43d5774a 100644 --- a/src/Widgets/AccountSuggestions.vala +++ b/src/Widgets/AccountSuggestions.vala @@ -155,30 +155,36 @@ public class Tuba.Widgets.AccountSuggestions : Gtk.ListBoxRow { .with_account (accounts.active) .with_param ("limit", "10") .then ((in_stream) => { - var parser = Network.get_parser_from_inputstream (in_stream); - - Gee.HashMap widgets = new Gee.HashMap (); - Gtk.Widget? last_sep = null; - Network.parse_array (parser, node => { - var entity = Tuba.Helper.Entity.from_json (node, typeof (API.Suggestion)) as API.Suggestion; - if (entity != null) { - var widget = new AccountSuggestion (((API.Suggestion) entity).account); - widgets.set (((API.Suggestion) entity).account.id, widget); - account_box.append (widget); - - last_sep = new Gtk.Separator (Gtk.Orientation.VERTICAL); - account_box.append (last_sep); + Network.get_parser_from_inputstream_async.begin (in_stream, (obj, res) => { + try { + var parser = Network.get_parser_from_inputstream_async.end (res); + Gee.HashMap widgets = new Gee.HashMap (); + Gtk.Widget? last_sep = null; + Network.parse_array (parser, node => { + var entity = Tuba.Helper.Entity.from_json (node, typeof (API.Suggestion)) as API.Suggestion; + if (entity != null) { + var widget = new AccountSuggestion (((API.Suggestion) entity).account); + widgets.set (((API.Suggestion) entity).account.id, widget); + account_box.append (widget); + + last_sep = new Gtk.Separator (Gtk.Orientation.VERTICAL); + account_box.append (last_sep); + } + }); + + if (last_sep != null) account_box.remove (last_sep); + if (widgets.size > 0) { + this.visible = true; + populate_account_suggestions_relationships (widgets); + } else { + this.visible = false; + } + on_page_changed (); + } catch (Error e) { + this.visible = false; + critical (@"Couldn't parse json: $(e.code) $(e.message)"); } }); - - if (last_sep != null) account_box.remove (last_sep); - if (widgets.size > 0) { - this.visible = true; - populate_account_suggestions_relationships (widgets); - } else { - this.visible = false; - } - on_page_changed (); }) .on_error (() => { this.visible = false; diff --git a/src/Widgets/Admin/AssignedRow.vala b/src/Widgets/Admin/AssignedRow.vala index ecb7c1de2..f121c11c9 100644 --- a/src/Widgets/Admin/AssignedRow.vala +++ b/src/Widgets/Admin/AssignedRow.vala @@ -64,10 +64,17 @@ public class Tuba.Widgets.Admin.AssignedToRow : Adw.ActionRow { new Request.POST (@"/api/v1/admin/reports/$report_id/$endpoint") .with_account (accounts.active) .then ((in_stream) => { - var parser = Network.get_parser_from_inputstream (in_stream); - var node = network.parse_node (parser); - update_account (API.Admin.Report.from (node).assigned_account); - assign_button.sensitive = true; + Network.get_parser_from_inputstream_async.begin (in_stream, (obj, res) => { + try { + var parser = Network.get_parser_from_inputstream_async.end (res); + var node = network.parse_node (parser); + update_account (API.Admin.Report.from (node).assigned_account); + } catch (Error e) { + critical (@"Couldn't parse json: $(e.code) $(e.message)"); + } + + assign_button.sensitive = true; + }); }) .on_error ((code, message) => { warning (@"Error trying to re-assign $report_id: $message $code"); diff --git a/src/Widgets/BookWyrmPage.vala b/src/Widgets/BookWyrmPage.vala index 75062a2e3..be395a4f0 100644 --- a/src/Widgets/BookWyrmPage.vala +++ b/src/Widgets/BookWyrmPage.vala @@ -44,12 +44,19 @@ public class Tuba.Widgets.BookWyrmPage : Gtk.Box { foreach (var author in t_obj.authors) { new Request.GET (@"$author.json") .then ((in_stream) => { - var parser = Network.get_parser_from_inputstream (in_stream); - var node = network.parse_node (parser); - var author_obj = API.BookWyrmAuthor.from (node); - if (author_obj.id == author) { - authors.label = generate_authors_label (author_obj.name, author_obj.id); - } + Network.get_parser_from_inputstream_async.begin (in_stream, (obj, res) => { + try { + var parser = Network.get_parser_from_inputstream_async.end (res); + var node = network.parse_node (parser); + var author_obj = API.BookWyrmAuthor.from (node); + if (author_obj.id == author) { + authors.label = generate_authors_label (author_obj.name, author_obj.id); + } + } catch (Error e) { + authors.visible = false; + critical (@"Couldn't parse json: $(e.code) $(e.message)"); + } + }); }) .on_error (() => authors.visible = false) .exec (); diff --git a/src/Widgets/ProfileCover.vala b/src/Widgets/ProfileCover.vala index 29d9c4be5..1d91c4e4f 100644 --- a/src/Widgets/ProfileCover.vala +++ b/src/Widgets/ProfileCover.vala @@ -382,39 +382,45 @@ protected class Tuba.Widgets.Cover : Gtk.Box { .with_account (accounts.active) .with_param ("id", profile_id) .then ((in_stream) => { - var parser = Network.get_parser_from_inputstream (in_stream); - var node = network.parse_node (parser); - if (node == null) return; - - Value res_accounts; - Entity.des_list (out res_accounts, node, typeof (API.FamiliarFollowers)); - var res_mutual_accounts = (Gee.ArrayList) res_accounts; - if (res_mutual_accounts.size == 0) return; - - mutual_accounts = res_mutual_accounts.get (0).accounts; - if (mutual_accounts.size > 0) { - mutuals_button.visible = true; - - mutuals_button.child = new MutualsButtonContent (mutual_accounts); - mutuals_listbox = new Gtk.ListBox () { - selection_mode = Gtk.SelectionMode.NONE, - css_classes = {"boxed-list"} - }; - - mutuals_button.popover = new Gtk.Popover () { - child = new Gtk.ScrolledWindow () { - child = mutuals_listbox, - hexpand = true, - vexpand = true, - hscrollbar_policy = Gtk.PolicyType.NEVER, - max_content_height = 500, - width_request = 360, - propagate_natural_height = true + Network.get_parser_from_inputstream_async.begin (in_stream, (obj, res) => { + try { + var parser = Network.get_parser_from_inputstream_async.end (res); + var node = network.parse_node (parser); + if (node == null) return; + + Value res_accounts; + Entity.des_list (out res_accounts, node, typeof (API.FamiliarFollowers)); + var res_mutual_accounts = (Gee.ArrayList) res_accounts; + if (res_mutual_accounts.size == 0) return; + + mutual_accounts = res_mutual_accounts.get (0).accounts; + if (mutual_accounts.size > 0) { + mutuals_button.visible = true; + + mutuals_button.child = new MutualsButtonContent (mutual_accounts); + mutuals_listbox = new Gtk.ListBox () { + selection_mode = Gtk.SelectionMode.NONE, + css_classes = {"boxed-list"} + }; + + mutuals_button.popover = new Gtk.Popover () { + child = new Gtk.ScrolledWindow () { + child = mutuals_listbox, + hexpand = true, + vexpand = true, + hscrollbar_policy = Gtk.PolicyType.NEVER, + max_content_height = 500, + width_request = 360, + propagate_natural_height = true + } + }; + + mutuals_button.notify["active"].connect (on_mutuals_popover); } - }; - - mutuals_button.notify["active"].connect (on_mutuals_popover); - } + } catch (Error e) { + critical (@"Couldn't parse json: $(e.code) $(e.message)"); + } + }); }) .exec (); diff --git a/src/Widgets/ScheduledStatus.vala b/src/Widgets/ScheduledStatus.vala index 1ba60a6a8..914ea1f43 100644 --- a/src/Widgets/ScheduledStatus.vala +++ b/src/Widgets/ScheduledStatus.vala @@ -175,10 +175,16 @@ public class Tuba.Widgets.ScheduledStatus : Gtk.ListBoxRow { .with_account (accounts.active) .with_form_data ("scheduled_at", iso8601) .then ((in_stream) => { - var parser = Network.get_parser_from_inputstream (in_stream); - var node = network.parse_node (parser); - var e = Tuba.Helper.Entity.from_json (node, typeof (API.ScheduledStatus), true); - if (e is API.ScheduledStatus) bind ((API.ScheduledStatus) e); + Network.get_parser_from_inputstream_async.begin (in_stream, (obj, res) => { + try { + var parser = Network.get_parser_from_inputstream_async.end (res); + var node = network.parse_node (parser); + var e = Tuba.Helper.Entity.from_json (node, typeof (API.ScheduledStatus), true); + if (e is API.ScheduledStatus) bind ((API.ScheduledStatus) e); + } catch (Error e) { + critical (@"Couldn't parse json: $(e.code) $(e.message)"); + } + }); }) .on_error ((code, message) => { warning (@"Error while rescheduling: $code $message"); diff --git a/src/Widgets/Status.vala b/src/Widgets/Status.vala index 2cbda3a3d..a3c8ae2ff 100644 --- a/src/Widgets/Status.vala +++ b/src/Widgets/Status.vala @@ -487,15 +487,21 @@ req .with_account (accounts.active) .then ((in_stream) => { - var parser = Network.get_parser_from_inputstream (in_stream); - var node = network.parse_node (parser); - var source = API.StatusSource.from (node); - - if (redraft) { - new Dialogs.Composer.Dialog.edit (status.formal, source, null, true); - } else { - new Dialogs.Composer.Dialog.edit (status.formal, source, on_edit); - } + Network.get_parser_from_inputstream_async.begin (in_stream, (obj, res) => { + try { + var parser = Network.get_parser_from_inputstream_async.end (res); + var node = network.parse_node (parser); + var source = API.StatusSource.from (node); + + if (redraft) { + new Dialogs.Composer.Dialog.edit (status.formal, source, null, true); + } else { + new Dialogs.Composer.Dialog.edit (status.formal, source, on_edit); + } + } catch (Error e) { + critical (@"Couldn't parse json: $(e.code) $(e.message)"); + } + }); }) .on_error ((code, message) => { if (redraft) { @@ -611,17 +617,23 @@ new Request.GET (@"/api/v1/statuses/$(status.formal.id)/translations/$(Tuba.default_locale)") .with_account (accounts.active) .then ((in_stream) => { - var parser = Network.get_parser_from_inputstream (in_stream); - var node = network.parse_node (parser); - var akkotrans = API.AkkomaTranslation.from (node); - translation = new API.Translation () { - content = akkotrans.text, - detected_source_language = akkotrans.detected_language - }; - bind (); - - translate_simple_action.set_enabled (false); - show_original_simple_action.set_enabled (true); + Network.get_parser_from_inputstream_async.begin (in_stream, (obj, res) => { + try { + var parser = Network.get_parser_from_inputstream_async.end (res); + var node = network.parse_node (parser); + var akkotrans = API.AkkomaTranslation.from (node); + translation = new API.Translation () { + content = akkotrans.text, + detected_source_language = akkotrans.detected_language + }; + bind (); + + translate_simple_action.set_enabled (false); + show_original_simple_action.set_enabled (true); + } catch (Error e) { + critical (@"Couldn't parse json: $(e.code) $(e.message)"); + } + }); }) .on_error ((code, message) => { warning (@"Couldn't translate $(status.formal.id): $code $message"); @@ -636,13 +648,19 @@ .with_form_data ("lang", Tuba.default_locale) .with_account (accounts.active) .then ((in_stream) => { - var parser = Network.get_parser_from_inputstream (in_stream); - var node = network.parse_node (parser); - translation = API.Translation.from (node); - bind (); - - translate_simple_action.set_enabled (false); - show_original_simple_action.set_enabled (true); + Network.get_parser_from_inputstream_async.begin (in_stream, (obj, res) => { + try { + var parser = Network.get_parser_from_inputstream_async.end (res); + var node = network.parse_node (parser); + translation = API.Translation.from (node); + bind (); + + translate_simple_action.set_enabled (false); + show_original_simple_action.set_enabled (true); + } catch (Error e) { + critical (@"Couldn't parse json: $(e.code) $(e.message)"); + } + }); }) .on_error ((code, message) => { warning (@"Couldn't translate $(status.formal.id): $code $message"); diff --git a/src/Widgets/Status/ReactionsRow.vala b/src/Widgets/Status/ReactionsRow.vala index a6f332b5a..61ffd55ab 100644 --- a/src/Widgets/Status/ReactionsRow.vala +++ b/src/Widgets/Status/ReactionsRow.vala @@ -163,12 +163,18 @@ public class Tuba.Widgets.ReactionsRow : Adw.Bin { .with_account (accounts.active) .then ((in_stream) => { if (!this.is_announcement) { - var parser = Network.get_parser_from_inputstream (in_stream); - var node = network.parse_node (parser); - var status = API.Status.from (node); - if (status.formal.compat_status_reactions != null) { - update_reactions_diff (status.formal.compat_status_reactions); - } + Network.get_parser_from_inputstream_async.begin (in_stream, (obj, res) => { + try { + var parser = Network.get_parser_from_inputstream_async.end (res); + var node = network.parse_node (parser); + var status = API.Status.from (node); + if (status.formal.compat_status_reactions != null) { + update_reactions_diff (status.formal.compat_status_reactions); + } + } catch (Error e) { + critical (@"Couldn't parse json: $(e.code) $(e.message)"); + } + }); } }) .on_error ((code, message) => { diff --git a/src/Widgets/VoteBox.vala b/src/Widgets/VoteBox.vala index 46eda9258..686638aa1 100644 --- a/src/Widgets/VoteBox.vala +++ b/src/Widgets/VoteBox.vala @@ -51,14 +51,20 @@ public class Tuba.Widgets.VoteBox : Gtk.Box { API.Poll.vote (accounts.active, poll.options, selected_index, poll.id) .then ((in_stream) => { - var parser = Network.get_parser_from_inputstream (in_stream); - - freeze_notify (); - poll = API.Poll.from (network.parse_node (parser)); - thaw_notify (); - update_rows (); + Network.get_parser_from_inputstream_async.begin (in_stream, (obj, res) => { + try { + var parser = Network.get_parser_from_inputstream_async.end (res); + + freeze_notify (); + poll = API.Poll.from (network.parse_node (parser)); + thaw_notify (); + update_rows (); + } catch (Error e) { + critical (@"Couldn't parse json: $(e.code) $(e.message)"); + } - button.sensitive = true; + button.sensitive = true; + }); }) .on_error ((code, reason) => { app.toast ("%s: %s".printf (_("Error"), reason)); @@ -191,14 +197,20 @@ public class Tuba.Widgets.VoteBox : Gtk.Box { .then ((in_stream) => { button_refresh.sensitive = true; - var parser = Network.get_parser_from_inputstream (in_stream); - var node = network.parse_node (parser); - var parsed_poll = API.Poll.from (node); + Network.get_parser_from_inputstream_async.begin (in_stream, (obj, res) => { + try { + var parser = Network.get_parser_from_inputstream_async.end (res); + var node = network.parse_node (parser); + var parsed_poll = API.Poll.from (node); - if (parsed_poll != null) { - poll = parsed_poll; - update_rows (); - } + if (parsed_poll != null) { + poll = parsed_poll; + update_rows (); + } + } catch (Error e) { + critical (@"Couldn't parse json: $(e.code) $(e.message)"); + } + }); }) .on_error ((code, message) => { warning (@"Couldn't refresh poll $(poll.id): $code $message");