2024-07-28 22:59:28 +00:00
|
|
|
using System;
|
|
|
|
using System.IO;
|
|
|
|
using System.Linq;
|
|
|
|
using System.Threading.Tasks;
|
2024-08-10 18:32:16 +00:00
|
|
|
using Android.Media;
|
|
|
|
using Avalonia.Android;
|
|
|
|
using Avalonia.Controls;
|
|
|
|
using Avalonia.Platform;
|
2024-07-28 22:59:28 +00:00
|
|
|
using Avalonia.Platform.Storage;
|
2024-08-10 18:32:16 +00:00
|
|
|
using LibVLCSharp.Platforms.Android;
|
2024-07-28 22:59:28 +00:00
|
|
|
using Newtonsoft.Json;
|
|
|
|
using Tesses.VirtualFilesystem;
|
|
|
|
using Tesses.VirtualFilesystem.Extensions;
|
|
|
|
using Tesses.VirtualFilesystem.Filesystems;
|
|
|
|
namespace Tesses.CMS.Avalonia.Android;
|
2024-08-10 18:32:16 +00:00
|
|
|
public class NCH : NativeControlHost
|
|
|
|
{
|
|
|
|
LibVLCSharp.Shared.MediaPlayer? mediaPlayer;
|
|
|
|
VideoView? view;
|
|
|
|
protected override IPlatformHandle CreateNativeControlCore(IPlatformHandle parent)
|
|
|
|
{
|
|
|
|
/*return Implementation?.CreateControl(IsSecond, parent, () => base.CreateNativeControlCore(parent))
|
|
|
|
?? base.CreateNativeControlCore(parent);*/
|
|
|
|
|
|
|
|
var parentContext = (parent as AndroidViewControlHandle)?.View.Context
|
|
|
|
?? global::Android.App.Application.Context;
|
2024-07-28 22:59:28 +00:00
|
|
|
|
2024-08-10 18:32:16 +00:00
|
|
|
view = new VideoView(parentContext);
|
|
|
|
view.LayoutParameters = new global::Android.Views.ViewGroup.LayoutParams(global::Android.Views.ViewGroup.LayoutParams.MatchParent,global::Android.Views.ViewGroup.LayoutParams.MatchParent);
|
|
|
|
if(mediaPlayer != null)
|
|
|
|
{
|
|
|
|
view.MediaPlayer = mediaPlayer;
|
|
|
|
}
|
|
|
|
return new AndroidViewControlHandle(view);
|
|
|
|
}
|
|
|
|
|
|
|
|
protected override void DestroyNativeControlCore(IPlatformHandle control)
|
|
|
|
{
|
|
|
|
base.DestroyNativeControlCore(control);
|
|
|
|
}
|
|
|
|
|
|
|
|
public LibVLCSharp.Shared.MediaPlayer? MediaPlayer {
|
|
|
|
get {
|
|
|
|
if(view != null)
|
|
|
|
{
|
|
|
|
return view.MediaPlayer;
|
|
|
|
}
|
|
|
|
return mediaPlayer;
|
|
|
|
}
|
|
|
|
set {
|
|
|
|
if(view != null)
|
|
|
|
{
|
|
|
|
view.MediaPlayer = value;
|
|
|
|
|
|
|
|
}
|
|
|
|
mediaPlayer=value;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2024-07-28 22:59:28 +00:00
|
|
|
internal class MobilePlatform : IPlatform
|
|
|
|
{
|
|
|
|
string configpath;
|
|
|
|
MainActivity activity;
|
|
|
|
public const string MySAFKey = "MySafKey";
|
|
|
|
public MobilePlatform(MainActivity activity)
|
|
|
|
{
|
|
|
|
this.activity = activity;
|
|
|
|
configpath=activity.FilesDir?.AbsolutePath ?? "";
|
|
|
|
if(File.Exists(Path.Combine(configpath, "tesses_cms_app.json")))
|
|
|
|
{
|
|
|
|
var conf=JsonConvert.DeserializeObject<Configuration>(File.ReadAllText(Path.Combine(configpath, "tesses_cms_app.json")));
|
|
|
|
if(conf != null)
|
|
|
|
_conf = conf;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
var res= SAFFileSystem.GetSAFFromSharedStorage(activity,MySAFKey);
|
|
|
|
if(res != null)
|
|
|
|
virtualFilesystem = res;
|
|
|
|
}
|
|
|
|
|
|
|
|
Configuration _conf = new Configuration();
|
|
|
|
public Configuration Configuration => _conf;
|
|
|
|
|
|
|
|
public bool PlatformUsesNormalPathsForDownload => false;
|
|
|
|
|
|
|
|
internal IVirtualFilesystem? virtualFilesystem;
|
|
|
|
public IVirtualFilesystem? DownloadFilesystem => virtualFilesystem;
|
2024-08-10 18:32:16 +00:00
|
|
|
|
|
|
|
public bool CanTakeScreenShots => DownloadFilesystem != null && !string.IsNullOrWhiteSpace(ScreenshotPath);
|
|
|
|
|
|
|
|
public string ScreenshotPath => activity?.GetExternalCacheDirs()?[0].AbsolutePath ?? "";
|
|
|
|
|
|
|
|
public bool MustMoveScreenshot => true;
|
2024-07-28 22:59:28 +00:00
|
|
|
|
|
|
|
public async Task BrowseForDownloadDirectoryAsync()
|
|
|
|
{
|
|
|
|
/*var sp=App.Window?.StorageProvider;
|
|
|
|
if(sp != null)
|
|
|
|
{
|
|
|
|
var res=await sp.OpenFolderPickerAsync(new global::Avalonia.Platform.Storage.FolderPickerOpenOptions{Title="Browse for a downloads folder"});
|
|
|
|
|
|
|
|
if(res.Count > 0)
|
|
|
|
{
|
|
|
|
var first=res.First();
|
|
|
|
string? path=first.TryGetLocalPath();
|
|
|
|
if(!string.IsNullOrWhiteSpace(path))
|
|
|
|
{
|
|
|
|
_conf.DownloadPath = path;
|
|
|
|
await WriteConfigurationAsync();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}*/
|
|
|
|
try{
|
|
|
|
if(virtualFilesystem != null)
|
|
|
|
SAFFileSystem.Revoke(activity,MySAFKey);
|
|
|
|
}catch(Exception ex)
|
|
|
|
{
|
|
|
|
_=ex;
|
|
|
|
}
|
|
|
|
virtualFilesystem=null;
|
|
|
|
SAFFileSystem.RequestDirectory(activity,true,true);
|
|
|
|
await Task.CompletedTask;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
public async Task ReadConfigurationAsync()
|
|
|
|
{
|
|
|
|
if(File.Exists(Path.Combine(configpath, "tesses_cms_app.json")))
|
|
|
|
{
|
|
|
|
var conf=JsonConvert.DeserializeObject<Configuration>(await File.ReadAllTextAsync(Path.Combine(configpath, "tesses_cms_app.json")));
|
|
|
|
if(conf != null)
|
|
|
|
_conf = conf;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
public async Task WriteConfigurationAsync()
|
|
|
|
{
|
|
|
|
|
|
|
|
await File.WriteAllTextAsync(Path.Combine(configpath, "tesses_cms_app.json"),JsonConvert.SerializeObject(_conf));
|
|
|
|
|
|
|
|
|
|
|
|
}
|
2024-08-10 18:32:16 +00:00
|
|
|
|
|
|
|
public Control CreatePlayer()
|
|
|
|
{
|
|
|
|
return new NCH();
|
|
|
|
// return new global::Android.Widget.Button(this.activity);
|
|
|
|
}
|
|
|
|
|
|
|
|
public void SetMediaPlayer(Control control, global::LibVLCSharp.Shared.MediaPlayer? mediaPlayer)
|
|
|
|
{
|
|
|
|
var ctrl=control as NCH;
|
|
|
|
if(ctrl != null)
|
|
|
|
ctrl.MediaPlayer = mediaPlayer;
|
|
|
|
}
|
|
|
|
|
|
|
|
public global::LibVLCSharp.Shared.MediaPlayer? GetMediaPlayer(Control control)
|
|
|
|
{
|
|
|
|
var ctrl=control as NCH;
|
|
|
|
if(ctrl != null)
|
|
|
|
return ctrl.MediaPlayer;
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
public void LaunchUrl(string url)
|
|
|
|
{
|
|
|
|
//https://stackoverflow.com/a/3004542
|
|
|
|
//Intent intent = new Intent(Intent.ActionView);
|
|
|
|
|
|
|
|
}
|
2024-07-28 22:59:28 +00:00
|
|
|
}
|