Open Podcast in external browser (WIP)

This commit is contained in:
Paul Schneider 2026-11-01 18:53:38 +00:00
commit 89d9137884
Signed by: notazof
GPG key ID: AD4B9B545FBD7D12
3 changed files with 23 additions and 13 deletions

View file

@ -82,6 +82,15 @@ public class BlogReaderTests
Assert.Equal(StatusSeverity.Warning, vm.ActionStatus.Severity);
}
[Theory]
[InlineData("https://org.example.test/files/paul/clip.mp4", true)]
[InlineData("https://localhost/files/paul/clip.mp4", false)]
public void Video_links_only_open_externally_when_the_source_is_a_real_external_resource(string source, bool expected)
{
var vm = new VideoPageViewModel(new Uri(source), "video/mp4");
Assert.Equal(expected, vm.CanOpenExternal);
}
[AvaloniaFact]
public async Task Reader_hides_editor_and_wires_hyperlinks_to_the_application()
{

View file

@ -1,17 +1,27 @@
using System;
using CommunityToolkit.Mvvm.ComponentModel;
using Yavsc.Abstract.Streaming;
using Yavsc.Api.Client;
namespace PostIt.ViewModels;
public sealed class VideoPageViewModel(Uri source, string mimeType) : ViewModelBase
public partial class VideoPageViewModel(Uri source, string mimeType) : ViewModelBase
{
public Uri Source { get; } = source;
public string MimeType { get; } = mimeType;
public PodcastApiClient? PodcastClient { get; init; }
public PodcastResponse? Podcast { get; init; }
public bool CanOpenExternal => Podcast is null;
public PodcastResponse? Podcast { get; set; }
public bool CanOpenExternal => CanLaunchExternally(Source);
public string Title => Podcast?.Title ?? Uri.UnescapeDataString(System.IO.Path.GetFileName(Source.AbsolutePath));
public override bool CanNavigateNext { get => false; protected set { } }
public override bool CanNavigatePrevious { get => true; protected set { } }
private static bool CanLaunchExternally(Uri source)
=> source is { IsAbsoluteUri: true }
&& (string.Equals(source.Scheme, "http", StringComparison.OrdinalIgnoreCase)
|| string.Equals(source.Scheme, "https", StringComparison.OrdinalIgnoreCase))
&& !string.Equals(source.Host, "localhost", StringComparison.OrdinalIgnoreCase)
&& !string.Equals(source.AbsolutePath, "/", StringComparison.OrdinalIgnoreCase)
&& !string.Equals(source.Scheme, "about", StringComparison.OrdinalIgnoreCase);
}

View file

@ -172,15 +172,6 @@ public partial class VideoPage : ContentPage
private void PodcastFailed(string message) => Dispatcher.UIThread.Post(() => PlaybackStatus.Text = message);
private static bool CanLaunchExternally(Uri source)
=> source is { IsAbsoluteUri: true }
&& (string.Equals(source.Scheme, "http", StringComparison.OrdinalIgnoreCase)
|| string.Equals(source.Scheme, "https", StringComparison.OrdinalIgnoreCase))
&& !string.Equals(source.Host, "localhost", StringComparison.OrdinalIgnoreCase)
&& !string.Equals(source.AbsolutePath, "/", StringComparison.OrdinalIgnoreCase)
&& !source.AbsolutePath.Contains("/api/", StringComparison.OrdinalIgnoreCase)
&& !string.Equals(source.Scheme, "about", StringComparison.OrdinalIgnoreCase);
private void Player_EncounteredError(object? sender, EventArgs e)
=> Dispatcher.UIThread.Post(() =>
{
@ -208,7 +199,7 @@ public partial class VideoPage : ContentPage
return;
try
{
if (!CanLaunchExternally(vm.Source))
if (!vm.CanOpenExternal)
{
PlaybackStatus.Text = "Ce flux interne ne peut pas être ouvert dans le navigateur.";
return;