Support deletion of pics/statuses
This commit is contained in:
parent
518f181c4f
commit
295ea4834e
7 changed files with 142 additions and 13 deletions
|
@ -13,7 +13,18 @@
|
|||
<label>Description</label>
|
||||
</div>
|
||||
</div>
|
||||
<nav class="right-align no-space">
|
||||
<nav class="no-space">
|
||||
@if (confirmDelete) {
|
||||
<button @onclick="ConfirmDeletePic" disabled="@loading" class="red-7-bg white-fg">
|
||||
<i class="fa-solid fa-exclamation-triangle"></i> <span>Are you sure?</span>
|
||||
</button>
|
||||
}
|
||||
else {
|
||||
<button @onclick="DeletePic" disabled="@loading" class="red-7-bg white-fg">
|
||||
<i class="fa-solid fa-trash"></i> <span>Delete</span>
|
||||
</button>
|
||||
}
|
||||
<div class="max"></div>
|
||||
<button class="transparent link" data-ui="#@id" disabled="@loading">Cancel</button>
|
||||
<button @onclick="PostPic" disabled="@loading">
|
||||
@if (loading) {
|
||||
|
@ -42,11 +53,38 @@
|
|||
private bool loading = false;
|
||||
[Parameter]
|
||||
public string id { get; set; }
|
||||
private bool confirmDelete { get; set; }
|
||||
|
||||
protected override async Task OnInitializedAsync() {
|
||||
Description = Pic?.Description;
|
||||
}
|
||||
|
||||
public async Task DeletePic() {
|
||||
if (!confirmDelete) confirmDelete = true;
|
||||
await InvokeAsync(StateHasChanged);
|
||||
}
|
||||
|
||||
public async Task ConfirmDeletePic() {
|
||||
if (confirmDelete) {
|
||||
loading = true;
|
||||
await InvokeAsync(StateHasChanged);
|
||||
|
||||
if (!string.IsNullOrEmpty(Pic?.Id)) {
|
||||
await api.DeletePic(State.SelectedAddressName, Pic.Id);
|
||||
await State.RefreshPics();
|
||||
await InvokeAsync(StateHasChanged);
|
||||
}
|
||||
|
||||
await JS.InvokeVoidAsync("ui", "#" + id);
|
||||
// clear input
|
||||
Description = string.Empty;
|
||||
Pic = null;
|
||||
loading = false;
|
||||
confirmDelete = false;
|
||||
await InvokeAsync(StateHasChanged);
|
||||
}
|
||||
}
|
||||
|
||||
public async Task PostPic() {
|
||||
loading = true;
|
||||
await InvokeAsync(StateHasChanged);
|
||||
|
@ -62,6 +100,7 @@
|
|||
Description = string.Empty;
|
||||
Pic = null;
|
||||
loading = false;
|
||||
confirmDelete = false;
|
||||
await InvokeAsync(StateHasChanged);
|
||||
|
||||
}
|
||||
|
|
|
@ -29,7 +29,18 @@
|
|||
<label>Status</label>
|
||||
</div>
|
||||
</div>
|
||||
<nav class="right-align no-space">
|
||||
<nav class="no-space">
|
||||
@if (confirmDelete) {
|
||||
<button @onclick="ConfirmDeleteStatus" disabled="@loading" class="red-7-bg white-fg">
|
||||
<i class="fa-solid fa-exclamation-triangle"></i> <span>Are you sure?</span>
|
||||
</button>
|
||||
}
|
||||
else {
|
||||
<button @onclick="DeleteStatus" disabled="@loading" class="red-7-bg white-fg">
|
||||
<i class="fa-solid fa-trash"></i> <span>Delete</span>
|
||||
</button>
|
||||
}
|
||||
<div class="max"></div>
|
||||
<InputText id="status-emoji-input" class="invisible" @bind-Value="Emoji"></InputText>
|
||||
<button class="transparent link" data-ui="#@id" disabled="@loading">Cancel</button>
|
||||
<button @onclick="PatchStatus" disabled="@loading">
|
||||
|
@ -60,12 +71,40 @@
|
|||
private bool loading = false;
|
||||
[Parameter]
|
||||
public string id { get; set; }
|
||||
private bool confirmDelete { get; set; }
|
||||
|
||||
protected override async Task OnInitializedAsync() {
|
||||
Content = Status?.Content;
|
||||
Emoji = Status?.Emoji;
|
||||
}
|
||||
|
||||
public async Task DeleteStatus() {
|
||||
if (!confirmDelete) confirmDelete = true;
|
||||
await InvokeAsync(StateHasChanged);
|
||||
}
|
||||
|
||||
public async Task ConfirmDeleteStatus() {
|
||||
if(confirmDelete) {
|
||||
loading = true;
|
||||
await InvokeAsync(StateHasChanged);
|
||||
|
||||
if (!string.IsNullOrEmpty(Status?.Id)) {
|
||||
await api.DeleteStatus(State.SelectedAddressName, Status.Id);
|
||||
await State.RefreshStatuses();
|
||||
await InvokeAsync(StateHasChanged);
|
||||
}
|
||||
|
||||
await JS.InvokeVoidAsync("ui", "#" + id);
|
||||
// clear input
|
||||
Content = string.Empty;
|
||||
Emoji = string.Empty;
|
||||
Status = null;
|
||||
loading = false;
|
||||
confirmDelete = false;
|
||||
await InvokeAsync(StateHasChanged);
|
||||
}
|
||||
}
|
||||
|
||||
public async Task PatchStatus() {
|
||||
loading = true;
|
||||
await InvokeAsync(StateHasChanged);
|
||||
|
@ -82,6 +121,7 @@
|
|||
Emoji = string.Empty;
|
||||
Status = null;
|
||||
loading = false;
|
||||
confirmDelete = false;
|
||||
await InvokeAsync(StateHasChanged);
|
||||
|
||||
}
|
||||
|
|
|
@ -9,15 +9,15 @@
|
|||
<div class="row">
|
||||
<div class="min square extra">
|
||||
<button class="transparent square extra no-margin">
|
||||
<object id="status-emoji" class="large emoji @(Emoji == null ? "animated" : string.Empty)" data-emoji="@(Emoji ?? "🫥")">@(Emoji ?? "🫥")</object>
|
||||
<object id="new-status-emoji" class="large emoji @(Emoji == null ? "animated" : string.Empty)" data-emoji="@(Emoji ?? "🫥")">@(Emoji ?? "🫥")</object>
|
||||
<menu class="no-wrap">
|
||||
<script type="module" src="https://cdn.jsdelivr.net/npm/emoji-picker-element@@^1/index.js"></script>
|
||||
<emoji-picker emoji-version="15.1"></emoji-picker>
|
||||
<script>
|
||||
document.querySelector('emoji-picker')
|
||||
.addEventListener('emoji-click', event => {
|
||||
document.getElementById('status-emoji').setAttribute('data-emoji', event.detail.unicode)
|
||||
const input = document.getElementById('status-emoji-input')
|
||||
document.getElementById('new-status-emoji').setAttribute('data-emoji', event.detail.unicode)
|
||||
const input = document.getElementById('new-status-emoji-input')
|
||||
input.value = event.detail.unicode
|
||||
var event = new Event('change');
|
||||
input.dispatchEvent(event);
|
||||
|
@ -37,7 +37,7 @@
|
|||
<span>Post this to Mastodon</span>
|
||||
</label>
|
||||
}
|
||||
<InputText id="status-emoji-input" class="invisible" @bind-Value="Emoji"></InputText>
|
||||
<InputText id="new-status-emoji-input" class="invisible" @bind-Value="Emoji"></InputText>
|
||||
<button class="transparent link" data-ui="#@id" disabled="@loading">Cancel</button>
|
||||
<button @onclick="PostStatus" disabled="@loading">
|
||||
@if (loading) {
|
||||
|
|
11
Models/DeleteResponseData.cs
Normal file
11
Models/DeleteResponseData.cs
Normal file
|
@ -0,0 +1,11 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Neighbourhood.omg.lol.Models {
|
||||
public class DeleteResponseData : IOmgLolResponseData {
|
||||
public string Message { get; set; }
|
||||
}
|
||||
}
|
|
@ -193,8 +193,16 @@ namespace Neighbourhood.omg.lol.Models {
|
|||
return CachedAddressPics;
|
||||
}
|
||||
|
||||
public async Task RefreshStatuses() => await GetStatuses(forceRefresh: true);
|
||||
public async Task RefreshPics() => await GetPics(forceRefresh: true);
|
||||
public async Task RefreshStatuses() {
|
||||
await GetStatuses(forceRefresh: true);
|
||||
if(SelectedAddressName != null)
|
||||
await GetStatuses(SelectedAddressName, forceRefresh: true);
|
||||
}
|
||||
public async Task RefreshPics() {
|
||||
await GetPics(forceRefresh: true);
|
||||
if (SelectedAddressName != null)
|
||||
await GetPics(SelectedAddressName, forceRefresh: true );
|
||||
}
|
||||
public async Task RefreshNow() => await GetNowGarden(forceRefresh: true);
|
||||
|
||||
}
|
||||
|
|
|
@ -117,6 +117,31 @@ namespace Neighbourhood.omg.lol {
|
|||
return responseData;
|
||||
}
|
||||
|
||||
private async Task<T?> Delete<T>(string uri, CancellationToken cancellationToken = default) where T : IOmgLolResponseData {
|
||||
T? responseData = default(T);
|
||||
try {
|
||||
HttpResponseMessage response = await _client.DeleteAsync(uri, cancellationToken: cancellationToken);
|
||||
if (response.IsSuccessStatusCode) {
|
||||
string str = await response.Content.ReadAsStringAsync();
|
||||
try {
|
||||
OmgLolResponse<T>? responseObj = await response.Content.ReadFromJsonAsync<OmgLolResponse<T>>(_serializerOptions, cancellationToken: cancellationToken);
|
||||
if (responseObj != null && responseObj.Request.Success) {
|
||||
responseData = responseObj.Response;
|
||||
}
|
||||
}
|
||||
catch (JsonException ex) {
|
||||
Debug.WriteLine(@"\tERROR {0}", ex.Message);
|
||||
Debug.WriteLine(str);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception ex) {
|
||||
Debug.WriteLine(@"\tERROR {0}", ex.Message);
|
||||
}
|
||||
|
||||
return responseData;
|
||||
}
|
||||
|
||||
public async Task<List<Status>> StatuslogLatest() =>
|
||||
(await Get<StatusResponseData>("/statuslog/latest"))?.Statuses ?? new List<Status>();
|
||||
|
||||
|
@ -170,10 +195,16 @@ namespace Neighbourhood.omg.lol {
|
|||
|
||||
public async Task<PutPicResponseData?> PostPicDescription(string address, string id, string description) =>
|
||||
(await Post<PutPicResponseData, PostPic>($"/address/{address}/pics/{id}", new PostPic { Description = description }));
|
||||
public async Task<DeleteResponseData?> DeletePic(string address, string id) =>
|
||||
(await Delete<DeleteResponseData>($"/address/{address}/pics/{id}"));
|
||||
|
||||
|
||||
public async Task<PatchStatusResponseData?> PatchStatus(string address, string id, string content, string? emoji) =>
|
||||
(await Patch<PatchStatusResponseData, PatchStatus>($"/address/{address}/statuses/", new PatchStatus { Id = id, Content = content, Emoji = emoji }));
|
||||
|
||||
public async Task<DeleteResponseData?> DeleteStatus(string address, string id) =>
|
||||
(await Delete<DeleteResponseData>($"/address/{address}/statuses/{id}"));
|
||||
|
||||
public async Task<List<NowData>?> NowGarden() =>
|
||||
(await Get<NowResponseData>($"/now/garden"))?.Garden ?? new List<NowData>();
|
||||
|
||||
|
|
|
@ -91,7 +91,7 @@ img {
|
|||
text-indent: -10px;
|
||||
}
|
||||
|
||||
.status .emoji, #status-emoji {
|
||||
.status .emoji, #status-emoji, #new-status-emoji {
|
||||
margin-bottom: auto;
|
||||
inline-size: 3.5rem;
|
||||
block-size: 3.5rem;
|
||||
|
|
Loading…
Reference in a new issue