2026-06-20 17:16:07 +01:00
|
|
|
using Android.App;
|
2026-05-29 01:29:36 +01:00
|
|
|
using Android.Content.PM;
|
2026-06-20 17:16:07 +01:00
|
|
|
using Android.Content;
|
2026-05-29 01:29:36 +01:00
|
|
|
using Avalonia.Android;
|
2026-08-22 06:42:12 +01:00
|
|
|
using AndroidX.Emoji2.Text;
|
2026-05-29 01:29:36 +01:00
|
|
|
|
|
|
|
|
namespace PostIt.Android;
|
|
|
|
|
|
|
|
|
|
[Activity(
|
2026-06-20 17:16:07 +01:00
|
|
|
Name = "PostIt.Android.PostItMainActivity",
|
2026-05-29 01:29:36 +01:00
|
|
|
Label = "PostIt.Android",
|
|
|
|
|
Theme = "@style/MyTheme.NoActionBar",
|
|
|
|
|
Icon = "@drawable/icon",
|
|
|
|
|
MainLauncher = true,
|
2026-06-20 17:16:07 +01:00
|
|
|
LaunchMode = LaunchMode.SingleTask,
|
2026-05-29 01:29:36 +01:00
|
|
|
ConfigurationChanges = ConfigChanges.Orientation | ConfigChanges.ScreenSize | ConfigChanges.UiMode)]
|
2026-08-22 16:09:35 +01:00
|
|
|
public class MainActivity : AvaloniaMainActivity
|
2026-05-29 01:29:36 +01:00
|
|
|
{
|
2026-06-20 17:26:13 +01:00
|
|
|
/// <summary>
|
|
|
|
|
/// Strongly-typed handle to the current MainActivity instance, set in
|
|
|
|
|
/// <see cref="OnCreate"/> and consumed by platform services such as
|
|
|
|
|
/// <see cref="Services.AndroidSystemBrowser"/> which need to launch
|
|
|
|
|
/// Chrome Custom Tabs.
|
|
|
|
|
/// </summary>
|
|
|
|
|
public static MainActivity? Current { get; private set; }
|
|
|
|
|
|
|
|
|
|
protected override void OnCreate(global::Android.OS.Bundle? savedInstanceState)
|
|
|
|
|
{
|
2026-08-22 06:42:12 +01:00
|
|
|
EmojiCompat.Init(this);
|
2026-06-20 17:26:13 +01:00
|
|
|
base.OnCreate(savedInstanceState);
|
|
|
|
|
PlatformBootstrap.EnsureInitialized();
|
|
|
|
|
Current = this;
|
|
|
|
|
}
|
|
|
|
|
|
2026-06-20 17:16:07 +01:00
|
|
|
/// <summary>
|
|
|
|
|
/// Receives the deep-link Intent fired by the system browser after the
|
|
|
|
|
/// user completes the OIDC login on https://yavsc.pschneider.fr. The
|
|
|
|
|
/// Intent URI has the shape <c>android://postit-signin?code=...&state=...</c>.
|
|
|
|
|
///
|
|
|
|
|
/// IdentityModel.OidcClient.Browser.SystemBrowser is set up to await this
|
|
|
|
|
/// callback via a TaskCompletionSource; expose the received Intent here
|
|
|
|
|
/// through a static sink so the browser can resolve the pending login.
|
|
|
|
|
/// </summary>
|
|
|
|
|
protected override void OnNewIntent(Intent? intent)
|
|
|
|
|
{
|
|
|
|
|
base.OnNewIntent(intent);
|
|
|
|
|
if (intent is not null) AndroidOidcCallbackSink.Handle(intent);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
internal static class AndroidOidcCallbackSink
|
|
|
|
|
{
|
|
|
|
|
private static System.Threading.Tasks.TaskCompletionSource<string>? _pending;
|
|
|
|
|
|
|
|
|
|
public static System.Threading.Tasks.Task<string> AwaitNextCallbackAsync()
|
|
|
|
|
{
|
|
|
|
|
_pending = new System.Threading.Tasks.TaskCompletionSource<string>(
|
|
|
|
|
System.Threading.Tasks.TaskCreationOptions.RunContinuationsAsynchronously);
|
|
|
|
|
return _pending.Task;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public static void Handle(Intent intent)
|
|
|
|
|
{
|
|
|
|
|
var tcs = System.Threading.Interlocked.Exchange(ref _pending, null);
|
|
|
|
|
tcs?.TrySetResult(intent?.Data?.ToString() ?? string.Empty);
|
|
|
|
|
}
|
|
|
|
|
}
|
2026-08-22 03:34:48 +01:00
|
|
|
}
|