From f31d7fd997092724c83de846563588a04f621f2f Mon Sep 17 00:00:00 2001 From: Robert Mader Date: Thu, 25 Apr 2024 19:57:06 +0200 Subject: [PATCH 1/3] feat(Attachment.Box): stream attachments by default The bug preventing this before has long been fixed in Gst 1.22.1. --- src/Widgets/Attachment/Box.vala | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/Widgets/Attachment/Box.vala b/src/Widgets/Attachment/Box.vala index a7d99b710..ef1411a23 100644 --- a/src/Widgets/Attachment/Box.vala +++ b/src/Widgets/Attachment/Box.vala @@ -167,14 +167,12 @@ public class Tuba.Widgets.Attachment.Box : Adw.Bin { is_main = attachment_widgets[i].entity.url == url; var paintable = attachment_widgets[i].pic.paintable; - var stream = false; #if GSTREAMER if (attachment_widgets[i].media_kind == Tuba.Attachment.MediaType.AUDIO) { if (paintable == null) { paintable = this.audio_fallback_paintable; } - stream = true; } #endif @@ -187,7 +185,7 @@ public class Tuba.Widgets.Attachment.Box : Adw.Bin { attachment_widgets[i].pic.alternative_text, null, attachment_widgets[i].entity.blurhash, - stream, + true, is_main, is_main == null ); From 454bc29cc57459027f5631d07cb52653686693db Mon Sep 17 00:00:00 2001 From: Evan Paterakis Date: Thu, 25 Apr 2024 21:23:55 +0300 Subject: [PATCH 2/3] feat(helpers): use inputstreams for videos --- src/Services/Helpers/Video.vala | 41 ++++++++++++++++++++++++++++++++ src/Services/Helpers/meson.build | 1 + src/Views/MediaViewer.vala | 13 +++++++--- 3 files changed, 52 insertions(+), 3 deletions(-) create mode 100644 src/Services/Helpers/Video.vala diff --git a/src/Services/Helpers/Video.vala b/src/Services/Helpers/Video.vala new file mode 100644 index 000000000..307568156 --- /dev/null +++ b/src/Services/Helpers/Video.vala @@ -0,0 +1,41 @@ +public class Tuba.Helper.Video { + private static Soup.Session session; + private static Soup.Cache cache; + + public static void clear_cache () { + new Helper.Video (); + cache.clear (); + } + + public static void flush_cache () { + new Helper.Video (); + cache.flush (); + cache.dump (); + } + + static construct { + cache = new Soup.Cache ( + GLib.Path.build_path (GLib.Path.DIR_SEPARATOR_S, Tuba.cache_path, "soup", "videos"), + Soup.CacheType.SINGLE_USER + ); + cache.load (); + cache.set_max_size (1024 * 1024 * 100 * 2); + + session = new Soup.Session.with_options ("max-conns", 64, "max-conns-per-host", 64) { + user_agent = @"$(Build.NAME)/$(Build.VERSION) libsoup/$(Soup.get_major_version()).$(Soup.get_minor_version()).$(Soup.get_micro_version()) ($(Soup.MAJOR_VERSION).$(Soup.MINOR_VERSION).$(Soup.MICRO_VERSION))" // vala-lint=line-length + }; + session.add_feature (cache); + } + + public static async InputStream request (string? url) throws Oopsie { + if (url == null || url == "") throw new Tuba.Oopsie.INTERNAL ("No url provided"); + new Helper.Video (); + + var download_msg = new Soup.Message ("GET", url); + try { + return yield session.send_async (download_msg, 0, null); + } catch (Error e) { + throw new Tuba.Oopsie.INTERNAL (@"Failed to get video at \"$url\": $(e.message)"); + } + } +} diff --git a/src/Services/Helpers/meson.build b/src/Services/Helpers/meson.build index 7d9d8797d..12964c60c 100644 --- a/src/Services/Helpers/meson.build +++ b/src/Services/Helpers/meson.build @@ -2,4 +2,5 @@ sources += files( 'Blurhash.vala', 'Entity.vala', 'Image.vala', + 'Video.vala', ) diff --git a/src/Views/MediaViewer.vala b/src/Views/MediaViewer.vala index 98158b9ba..4c84c49ec 100644 --- a/src/Views/MediaViewer.vala +++ b/src/Views/MediaViewer.vala @@ -1051,9 +1051,16 @@ public class Tuba.Views.MediaViewer : Gtk.Widget, Gtk.Buildable, Adw.Swipeable { add_todo_item (item); #else if (stream) { - File file = File.new_for_uri (url); - video.set_file (file); - add_todo_item (item); + Helper.Video.request.begin (url, (obj, res) => { + try { + video.set_media_stream (Gtk.MediaFile.for_input_stream (Helper.Video.request.end (res))); + add_todo_item (item); + } catch (Oopsie e) { + warning (e.message); + var dlg = app.inform (_("Error"), e.message); + dlg.present (app.main_window); + } + }); } else if (!as_is) { download_video.begin (url, (obj, res) => { try { From c6e39a1388cda75e775407bc5a66813759b09a31 Mon Sep 17 00:00:00 2001 From: Robert Mader Date: Thu, 14 Aug 2025 00:51:37 +0200 Subject: [PATCH 3/3] Work around Adw.Breakpoint errors --- src/Dialogs/Composer/Dialog.vala | 2 +- src/Views/Admin/Pages/Accounts.vala | 2 +- src/Views/TabbedBase.vala | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Dialogs/Composer/Dialog.vala b/src/Dialogs/Composer/Dialog.vala index 192cf559a..26c60230e 100644 --- a/src/Dialogs/Composer/Dialog.vala +++ b/src/Dialogs/Composer/Dialog.vala @@ -341,7 +341,7 @@ public class Tuba.Dialogs.Composer.Dialog : Adw.Dialog { Adw.BreakpointConditionLengthType.MAX_WIDTH, 400, Adw.LengthUnit.SP ); - var breakpoint = new Adw.Breakpoint (condition); + var breakpoint = new Adw.Breakpoint (condition.copy()); breakpoint.add_setter (this, "is-narrow", true); add_breakpoint (breakpoint); diff --git a/src/Views/Admin/Pages/Accounts.vala b/src/Views/Admin/Pages/Accounts.vala index f97b33655..48e68a526 100644 --- a/src/Views/Admin/Pages/Accounts.vala +++ b/src/Views/Admin/Pages/Accounts.vala @@ -53,7 +53,7 @@ public class Tuba.Views.Admin.Page.Accounts : Views.Admin.Page.Base { Adw.BreakpointConditionLengthType.MAX_WIDTH, 450, Adw.LengthUnit.SP ); - var breakpoint = new Adw.Breakpoint (condition); + var breakpoint = new Adw.Breakpoint (condition.copy()); breakpoint.add_setter (revealer_box, "halign", Gtk.Align.FILL); breakpoint.add_setter (entry_box_1, "orientation", Gtk.Orientation.VERTICAL); breakpoint.add_setter (entry_box_2, "orientation", Gtk.Orientation.VERTICAL); diff --git a/src/Views/TabbedBase.vala b/src/Views/TabbedBase.vala index b4a65bd35..d9e4f3819 100644 --- a/src/Views/TabbedBase.vala +++ b/src/Views/TabbedBase.vala @@ -101,7 +101,7 @@ public class Tuba.Views.TabbedBase : Views.Base { if (this.current_breakpoint != null) remove_breakpoint (this.current_breakpoint); this.small = true; - var breakpoint = new Adw.Breakpoint (condition); + var breakpoint = new Adw.Breakpoint (condition.copy()); breakpoint.add_setter (this, "title-stack-page-visible", true); breakpoint.add_setter (switcher_bar, "reveal", true); add_breakpoint (breakpoint);