Share target updates (including pics!)

Still need to work out the "multiple windows" type issue.
This commit is contained in:
Gordon Pedersen 2024-06-18 16:23:03 +10:00
parent 63d844e7a3
commit f2025df922
6 changed files with 126 additions and 33 deletions

View file

@ -20,12 +20,10 @@
private void IntentRecieved(object? sender = null, EventArgs? e = null) { private void IntentRecieved(object? sender = null, EventArgs? e = null) {
if (!string.IsNullOrEmpty(State.ShareString)) { if (!string.IsNullOrEmpty(State.ShareString)) {
NavigationManager.NavigateTo($"/sharetext/{State.ShareString}"); NavigationManager.NavigateTo($"/sharetext");
State.ShareString = null;
} }
else if (!string.IsNullOrEmpty(State.SharePhoto)) { else if (!string.IsNullOrEmpty(State.SharePhoto)) {
NavigationManager.NavigateTo($"/sharepic/{State.SharePhoto}"); NavigationManager.NavigateTo($"/sharepic");
State.SharePhoto = null;
} }
} }

View file

@ -1,9 +1,10 @@
@inject IJSRuntime JS @inject IJSRuntime JS
@inject State State @inject State State
@inject RestService api @inject RestService api
@inject NavigationManager navigationManager
<div class="overlay" data-ui="#@id"></div> <div class="overlay @(Active ? "active" : string.Empty)" data-ui="#@id"></div>
<dialog id="@id"> <dialog id="@id" class="@(Active ? "active" : string.Empty)" open="@Active">
<h5>Share a picture</h5> <h5>Share a picture</h5>
<div class="row"> <div class="row">
<button @onclick="PicFromMedia"><i class="fa-solid fa-image"></i> Select a picture</button> <button @onclick="PicFromMedia"><i class="fa-solid fa-image"></i> Select a picture</button>
@ -14,10 +15,12 @@
<input type="text"> <input type="text">
<label>Select a picture</label> <label>Select a picture</label>
</div> *@ </div> *@
@if(File != null && Base64File != null && FileSize != null){ </div>
<div class="row">
@if(Base64File != null && FileSize != null){
<img class="extra" src="@Base64Url"> <img class="extra" src="@Base64Url">
<small> <small>
@File.ContentType (@formatSizeUnits(FileSize)) @FileContentType (@formatSizeUnits(FileSize))
</small> </small>
} }
@ -43,26 +46,35 @@
@code { @code {
// private IBrowserFile? File { get; set; } // private IBrowserFile? File { get; set; }
private FileResult? File { get; set; } [Parameter]
private string? Base64File { get; set; } public string? Base64File { get; set; }
private long? FileSize { get; set; } [Parameter]
private string? Base64Url { public long? FileSize { get; set; }
get { [Parameter]
if(File == null || Base64File == null) return null; public string? FileContentType { get; set; }
[Parameter]
return $"data:{File.ContentType};base64,{Base64File}"; public string? Description { get; set; }
}
}
private string Description { get; set; }
private bool loading = false;
[Parameter] [Parameter]
public string id { get; set; } public string id { get; set; }
[Parameter]
public bool Active { get; set; }
private bool loading = false;
private FileResult? File { get; set; }
private string? Base64Url {
get {
if (FileContentType == null || Base64File == null) return null;
return $"data:{FileContentType};base64,{Base64File}";
}
}
public async Task PostPic() { public async Task PostPic() {
loading = true; loading = true;
await InvokeAsync(StateHasChanged); await InvokeAsync(StateHasChanged);
PutPicResponseData? response = await api.PutPic(State.SelectedAddressName, File); PutPicResponseData? response = await api.PutPic(State.SelectedAddressName, Base64File);
if(!string.IsNullOrEmpty(Description) && response != null && !string.IsNullOrEmpty(response.Id)) { if(!string.IsNullOrEmpty(Description) && response != null && !string.IsNullOrEmpty(response.Id)) {
await api.PostPicDescription(State.SelectedAddressName, response.Id, Description); await api.PostPicDescription(State.SelectedAddressName, response.Id, Description);
await State.RefreshPics(); await State.RefreshPics();
@ -78,6 +90,13 @@
} }
protected override async Task OnAfterRenderAsync(bool firstRender) {
await base.OnAfterRenderAsync(firstRender);
if (firstRender) {
string tmp = "tmp";
}
}
// private async Task ChangeFile(InputFileChangeEventArgs e){ // private async Task ChangeFile(InputFileChangeEventArgs e){
// File = e.File; // File = e.File;
// } // }
@ -94,7 +113,7 @@
return formatted; return formatted;
} }
private async Task PicFromMedia(EventArgs e) { private async Task PicFromMedia(EventArgs e) {
File = await MediaPicker.Default.PickPhotoAsync(); File = await MediaPicker.Default.PickPhotoAsync();
@ -107,6 +126,7 @@
} }
private async Task PopulateFileDetails() { private async Task PopulateFileDetails() {
FileContentType = File.ContentType;
FileSize = await Utilities.FileSize(File); FileSize = await Utilities.FileSize(File);
Base64File = await Utilities.Base64FromFile(File); Base64File = await Utilities.Base64FromFile(File);
} }

View file

@ -0,0 +1,51 @@
@page "/sharepic"
@inject NavigationManager navigationManager
@inject AuthenticationStateProvider AuthStateProvider
@inject State State
<PageHeading title="Some.pics" icon="fa-solid fa-images">
<Description>Upload an image to <a href="https://some.pics/">some.pics</a></Description>
</PageHeading>
<AuthorizeView>
<Authorized>
<button class="fab circle extra large-elevate" data-ui="#post-modal">
<i class="fa-solid fa-camera-retro"></i>
</button>
<NewPicDialog id="post-modal" Active="true" Base64File="@SharePhoto" FileSize="@SharePhotoSize" FileContentType="@SharePhotoContentType" Description="@SharePhotoText"></NewPicDialog>
</Authorized>
</AuthorizeView>
@code {
public string SharePhoto { get; set; }
public long? SharePhotoSize { get; set; }
public string? SharePhotoContentType { get; set; }
public string? SharePhotoText { get; set; }
protected override async Task OnInitializedAsync() {
await checkLogin();
SharePhoto = State.SharePhoto;
SharePhotoContentType = State.SharePhotoContentType;
SharePhotoSize = State.SharePhotoSize;
SharePhotoText = State.SharePhotoText;
State.SharePhoto = null;
State.SharePhotoContentType = null;
State.SharePhotoSize = null;
State.SharePhotoText = null;
}
private async Task<bool> checkLogin() {
var authState = await AuthStateProvider.GetAuthenticationStateAsync();
var user = authState.User;
if (user.Identity is not null && user.Identity.IsAuthenticated) {
return true;
}
else {
navigationManager.NavigateTo("/login");
return false;
}
}
}

View file

@ -1,6 +1,7 @@
@page "/sharetext/{Text}" @page "/sharetext"
@inject NavigationManager navigationManager @inject NavigationManager navigationManager
@inject AuthenticationStateProvider AuthStateProvider @inject AuthenticationStateProvider AuthStateProvider
@inject State State
<PageHeading title="Status.lol" icon="fa-solid fa-message-smile"> <PageHeading title="Status.lol" icon="fa-solid fa-message-smile">
<Description>Share a post to <a href="https://status.lol">status.lol</a></Description> <Description>Share a post to <a href="https://status.lol">status.lol</a></Description>
@ -16,19 +17,20 @@
</AuthorizeView> </AuthorizeView>
@code { @code {
[Parameter] public string? Text { get; set; }
public string Text { get; set; }
protected override async Task OnInitializedAsync() { protected override async Task OnInitializedAsync() {
await checkLogin(); await checkLogin();
}
// protected override async Task OnAfterRenderAsync(bool firstRender) { Text = State.ShareString;
// await base.OnAfterRenderAsync(firstRender);
// if (firstRender && await checkLogin()) { if (!string.IsNullOrWhiteSpace(State.ShareStringSubject)) {
// await JS.InvokeVoidAsync("focusText"); Text = $"{State.ShareStringSubject}\n\n{State.ShareString}";
// } }
// }
State.ShareStringSubject = null;
State.ShareString = null;
}
private async Task<bool> checkLogin() { private async Task<bool> checkLogin() {
var authState = await AuthStateProvider.GetAuthenticationStateAsync(); var authState = await AuthStateProvider.GetAuthenticationStateAsync();

View file

@ -49,6 +49,8 @@ namespace Neighbourhood.omg.lol.Models {
IntentReceived?.Invoke(this, EventArgs.Empty); IntentReceived?.Invoke(this, EventArgs.Empty);
} }
} }
public string? ShareStringSubject { get; set; }
private string? _sharePhoto; private string? _sharePhoto;
public string? SharePhoto { public string? SharePhoto {
get => _sharePhoto; get => _sharePhoto;
@ -57,6 +59,9 @@ namespace Neighbourhood.omg.lol.Models {
IntentReceived?.Invoke(this, EventArgs.Empty); IntentReceived?.Invoke(this, EventArgs.Empty);
} }
} }
public long? SharePhotoSize { get; set; }
public string? SharePhotoContentType { get; set; }
public string? SharePhotoText { get; set; }
// refreshing // refreshing
public event PropertyChangedEventHandler? PropertyChanged; public event PropertyChangedEventHandler? PropertyChanged;

View file

@ -2,6 +2,7 @@
using Android.App; using Android.App;
using Android.Content; using Android.Content;
using Android.Content.PM; using Android.Content.PM;
using Android.Net;
using Android.OS; using Android.OS;
using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection;
using Neighbourhood.omg.lol.Models; using Neighbourhood.omg.lol.Models;
@ -25,15 +26,31 @@ namespace Neighbourhood.omg.lol {
if (intent != null && intent.Type != null) { if (intent != null && intent.Type != null) {
if (intent.Type.StartsWith("text/")) //string if (intent.Type.StartsWith("text/")) //string
{ {
string? subject = intent.GetStringExtra(Intent.ExtraSubject);
string? shareString = intent.GetStringExtra(Intent.ExtraText); string? shareString = intent.GetStringExtra(Intent.ExtraText);
if (!string.IsNullOrWhiteSpace(shareString)) { if (!string.IsNullOrWhiteSpace(shareString)) {
State state = IPlatformApplication.Current!.Services.GetService<State>()!; State state = IPlatformApplication.Current!.Services.GetService<State>()!;
state.ShareStringSubject = subject;
state.ShareString = shareString; state.ShareString = shareString;
} }
} }
else if (intent.Type.StartsWith("image/")) //image else if (intent.Type.StartsWith("image/")) //image
{ {
var uri = intent.GetParcelableExtra(Intent.ExtraStream); string? shareString = intent.GetStringExtra(Intent.ExtraText);
var extra = intent.GetParcelableExtra(Intent.ExtraStream);
if (extra is Android.Net.Uri) {
Stream? stream = ContentResolver?.OpenInputStream(extra as Android.Net.Uri);
byte[] bytes = new byte[stream?.Length ?? 0];
stream?.Read(bytes, 0, bytes.Length);
string base64String = Convert.ToBase64String(bytes);
if (!string.IsNullOrWhiteSpace(base64String)) {
State state = IPlatformApplication.Current!.Services.GetService<State>()!;
state.SharePhotoContentType = intent.Type;
state.SharePhotoSize = bytes.Length;
state.SharePhotoText = shareString;
state.SharePhoto = base64String;
}
}
} }
else if (intent.Type.Equals(Intent.ActionSendMultiple)) //Multiple file else if (intent.Type.Equals(Intent.ActionSendMultiple)) //Multiple file
{ {