Add Ntfy message box
This commit is contained in:
parent
ca997d10b1
commit
82dc4f227e
4 changed files with 160 additions and 4 deletions
|
@ -1,12 +1,15 @@
|
|||
@page "/"
|
||||
@using System.ComponentModel.DataAnnotations
|
||||
@using System.Text.Json
|
||||
@using PancakesWeb.Data
|
||||
@using PancakesWeb.Schema
|
||||
|
||||
<PageTitle>Home</PageTitle>
|
||||
|
||||
<main class="container">
|
||||
<h1 id="pancakes">pancakes</h1>
|
||||
<p>I'm a cat <abbr title="non-binary">enby</abbr> (<abbr
|
||||
title="they/them/their/theirs/themself or it/it/its/its/itself in English">they/it</abbr>) from Australia
|
||||
title="they/them/their/theirs/themself or it/it/its/its/itself in English">they/it</abbr>) from Australia
|
||||
that likes cats, Linux, and programming. You can find my links, projects, and other pages here.</p>
|
||||
|
||||
<h2 id="accounts">Accounts</h2>
|
||||
|
@ -121,4 +124,41 @@
|
|||
</li>
|
||||
}
|
||||
</ul>
|
||||
|
||||
<h2 id="notify">Notify</h2>
|
||||
<p>Send me a push notification. This will be a silent notification on my phone with no popup, vibration, or sound.</p>
|
||||
|
||||
<EditForm Model="Ntfy" OnValidSubmit="SubmitNtfy" FormName="Ntfy">
|
||||
<DataAnnotationsValidator/>
|
||||
<InputText @bind-Value="Ntfy.Message" maxlength="128" placeholder="Message"/>
|
||||
<button type="submit">Send</button>
|
||||
<ValidationSummary/>
|
||||
</EditForm>
|
||||
</main>
|
||||
|
||||
@code {
|
||||
[Inject] private HttpClient Http { get; set; } = null!;
|
||||
[Inject] private IConfiguration Config { get; set; } = null!;
|
||||
|
||||
[SupplyParameterFromForm] private NtfyModel Ntfy { get; set; } = new NtfyModel();
|
||||
|
||||
private async Task SubmitNtfy()
|
||||
{
|
||||
var ntfy = new NtfyRequest
|
||||
{
|
||||
Topic = Config["Ntfy:Topic"]!,
|
||||
Message = Ntfy.Message,
|
||||
Title = "pancakes.gay",
|
||||
Priority = 2,
|
||||
Tags = ["black_cat"]
|
||||
};
|
||||
|
||||
await Http.PostAsJsonAsync(Config["Ntfy:Url"], ntfy, JsonSerializerOptions.Web);
|
||||
}
|
||||
|
||||
public class NtfyModel
|
||||
{
|
||||
[StringLength(128)]
|
||||
public string Message { get; set; } = "";
|
||||
}
|
||||
}
|
|
@ -5,6 +5,14 @@ var builder = WebApplication.CreateBuilder(args);
|
|||
// Add services to the container.
|
||||
builder.Services.AddRazorComponents()
|
||||
.AddInteractiveServerComponents();
|
||||
builder.Services.AddHttpClient();
|
||||
|
||||
builder.Configuration.AddEnvironmentVariables();
|
||||
|
||||
if (builder.Configuration["Ntfy:Url"] == null)
|
||||
throw new Exception("Ntfy:Url is unset");
|
||||
if (builder.Configuration["Ntfy:Topic"] == null)
|
||||
throw new Exception("Ntfy:Topic is unset");
|
||||
|
||||
var app = builder.Build();
|
||||
|
||||
|
|
88
PancakesWeb/Schema/NtfyRequest.cs
Normal file
88
PancakesWeb/Schema/NtfyRequest.cs
Normal file
|
@ -0,0 +1,88 @@
|
|||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace PancakesWeb.Schema;
|
||||
|
||||
public class NtfyRequest
|
||||
{
|
||||
public required string Topic { get; set; }
|
||||
|
||||
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
|
||||
public string? Message { get; set; }
|
||||
|
||||
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
|
||||
public string? Title { get; set; }
|
||||
|
||||
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
|
||||
public List<string>? Tags { get; set; }
|
||||
|
||||
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
|
||||
public int? Priority { get; set; }
|
||||
|
||||
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
|
||||
public List<NtfyAction>? Actions { get; set; }
|
||||
|
||||
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
|
||||
public string? Click { get; set; }
|
||||
|
||||
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
|
||||
public string? Attach { get; set; }
|
||||
|
||||
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
|
||||
public bool? Markdown { get; set; }
|
||||
|
||||
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
|
||||
public string? Icon { get; set; }
|
||||
|
||||
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
|
||||
public string? Filename { get; set; }
|
||||
|
||||
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
|
||||
public string? Delay { get; set; }
|
||||
|
||||
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
|
||||
public string? Email { get; set; }
|
||||
|
||||
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
|
||||
public string? Call { get; set; }
|
||||
}
|
||||
|
||||
[JsonDerivedType(typeof(NtfyViewAction), "view")]
|
||||
[JsonDerivedType(typeof(NtfyBroadcastAction), "broadcast")]
|
||||
[JsonDerivedType(typeof(NtfyHttpAction), "http")]
|
||||
[JsonPolymorphic(TypeDiscriminatorPropertyName = "action",
|
||||
UnknownDerivedTypeHandling = JsonUnknownDerivedTypeHandling.FallBackToBaseType)]
|
||||
public abstract class NtfyAction
|
||||
{
|
||||
public required string Label { get; set; }
|
||||
|
||||
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
|
||||
public bool? Clear { get; set; }
|
||||
}
|
||||
|
||||
public class NtfyViewAction : NtfyAction
|
||||
{
|
||||
public required string Url { get; set; }
|
||||
}
|
||||
|
||||
public class NtfyBroadcastAction : NtfyAction
|
||||
{
|
||||
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
|
||||
public string? Intent { get; set; }
|
||||
|
||||
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
|
||||
public Dictionary<string, string>? Extras { get; set; }
|
||||
}
|
||||
|
||||
public class NtfyHttpAction : NtfyAction
|
||||
{
|
||||
public required string Url { get; set; }
|
||||
|
||||
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
|
||||
public string? Method { get; set; }
|
||||
|
||||
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
|
||||
public Dictionary<string, string>? Headers { get; set; }
|
||||
|
||||
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
|
||||
public string? Body { get; set; }
|
||||
}
|
|
@ -109,7 +109,7 @@ pre code {
|
|||
text-wrap: nowrap;
|
||||
}
|
||||
|
||||
button {
|
||||
button, input[type=submit] {
|
||||
display: inline-block;
|
||||
padding: 0.5em 1em;
|
||||
|
||||
|
@ -121,12 +121,28 @@ button {
|
|||
border: none;
|
||||
border-radius: var(--radius);
|
||||
cursor: pointer;
|
||||
transition: 0.2s background-color;
|
||||
}
|
||||
|
||||
button:hover, button:focus {
|
||||
button:hover, button:focus, input[type=submit]:hover, input[type=submit]:focus {
|
||||
background-color: color-mix(in srgb, var(--accent) 80%, var(--background));
|
||||
}
|
||||
|
||||
input, textarea {
|
||||
padding: 0.5rem;
|
||||
outline: none;
|
||||
|
||||
background-color: var(--foreground);
|
||||
color: var(--text);
|
||||
border: 1px solid var(--border-color);
|
||||
border-radius: var(--radius);
|
||||
transition: 0.2s border;
|
||||
}
|
||||
|
||||
input, textarea:focus {
|
||||
border-color: var(--accent);
|
||||
}
|
||||
|
||||
.copy-code-button {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
|
@ -166,6 +182,10 @@ pre code:hover + .copy-code-button, .copy-code-button:hover {
|
|||
text-decoration: none;
|
||||
}
|
||||
|
||||
.validation-errors {
|
||||
color: var(--error);
|
||||
}
|
||||
|
||||
@keyframes title-fade-in {
|
||||
0% {
|
||||
margin-top: 0;
|
||||
|
|
Loading…
Add table
Reference in a new issue