Now Page Markdown Editor

This commit is contained in:
Gordon Pedersen 2024-06-21 16:26:11 +10:00
parent 295ea4834e
commit 57885b4c5e
12 changed files with 284 additions and 9 deletions

View file

@ -0,0 +1,52 @@
@page "/editNow"
@inject NavigationManager Nav
@inject RestService api
@inject State State
<div class="max markdown-editor">
<MarkdownEditor @ref="Editor"
@bind-Value="@markdownValue"
Theme="material-darker"
MaxHeight="100%"
/>
</div>
<nav>
<label class="checkbox">
<InputCheckbox @bind-Value="listed"></InputCheckbox>
<span>Include my page in the Now Garden</span>
</label>
<div class="max"></div>
<button class="transparent link" onclick="history.back();">Cancel</button>
<button @onclick="Save">
<i class="fa-solid fa-floppy-disk"></i> <span>Save</span>
</button>
</nav>
@code {
MarkdownEditor Editor;
bool listed;
string markdownValue;
string markdownHtml;
protected override async Task OnInitializedAsync() {
await base.OnInitializedAsync();
NowContentData? data = await api.GetNowPage(State.SelectedAddressName);
if (data != null)
{
listed = data.Listed == 1;
markdownValue = data.Content;
await Editor.SetValueAsync(markdownValue);
}
InvokeAsync(StateHasChanged);
}
Task OnMarkdownValueChanged(string value) {
return Task.CompletedTask;
}
public async Task Save() {
await api.PostNowPage(State.SelectedAddressName, markdownValue, listed);
}
}

View file

@ -27,7 +27,7 @@
<i class="fa-solid fa-images"></i> <i class="fa-solid fa-images"></i>
<span>Some.pics</span> <span>Some.pics</span>
</a> </a>
@if(now != null){ @if(now != null || IsMe){
<a data-ui="#now" @onclick="ReloadNow"> <a data-ui="#now" @onclick="ReloadNow">
<i class="fa-duotone fa-seedling"></i> <i class="fa-duotone fa-seedling"></i>
<span>/Now</span> <span>/Now</span>
@ -73,10 +73,16 @@
<NewPicDialog id="post-modal"></NewPicDialog> <NewPicDialog id="post-modal"></NewPicDialog>
} }
</div> </div>
@if(now != null){ @if(now != null || IsMe){
<div id="now" class="page no-padding"> <div id="now" class="page no-padding">
<a href="@now.Url" target="_blank" class="hover absolute top right chip fill large-elevate">Open in browser <i class="fa-solid fa-arrow-up-right-from-square tiny"></i></a> <a href="@NowPageUrl" target="_blank" class="hover absolute top right chip fill large-elevate">Open in browser <i class="fa-solid fa-arrow-up-right-from-square tiny"></i></a>
<ExternalPageComponent id="now_page" @ref="NowPage" Url="@now.Url"></ExternalPageComponent> <ExternalPageComponent id="now_page" @ref="NowPage" Url="@NowPageUrl"></ExternalPageComponent>
@if (IsMe) {
<a href="/editNow" class="button fab circle extra large-elevate center-align middle-align">
<i class="square fa-solid fa-file-pen" style="line-height:56px;"></i>
<span>Edit</span>
</a>
}
</div> </div>
} }
</div> </div>
@ -96,6 +102,10 @@
get => $"https://{Address}.omg.lol/"; get => $"https://{Address}.omg.lol/";
} }
public string NowPageUrl {
get => now?.Url ?? $"https://{Address}.omg.lol/now";
}
public ExternalPageComponent? NowPage { get; set; } public ExternalPageComponent? NowPage { get; set; }
public ExternalPageComponent? ProfilePage { get; set; } public ExternalPageComponent? ProfilePage { get; set; }

View file

@ -12,3 +12,5 @@
@using Neighbourhood.omg.lol.Components @using Neighbourhood.omg.lol.Components
@using Neighbourhood.omg.lol.Models @using Neighbourhood.omg.lol.Models
@using Markdig @using Markdig
@using PSC.Blazor.Components.MarkdownEditor
@using PSC.Blazor.Components.MarkdownEditor.EventsArgs

View file

@ -5,7 +5,7 @@ using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
namespace Neighbourhood.omg.lol.Models { namespace Neighbourhood.omg.lol.Models {
public class DeleteResponseData : IOmgLolResponseData { public class BasicResponseData : IOmgLolResponseData {
public string Message { get; set; } public string Message { get; set; }
} }
} }

15
Models/NowContentData.cs Normal file
View file

@ -0,0 +1,15 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Neighbourhood.omg.lol.Models {
public class NowContentData {
public string? Content { get; set; }
public long? Updated { get; set; }
public int? Listed { get; set; }
public int? Nudge { get; set; }
public string? Metadata { get; set; }
}
}

View file

@ -0,0 +1,12 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Neighbourhood.omg.lol.Models {
public class NowPageResponseData : IOmgLolResponseData {
public string Message { get; set; }
public NowContentData Now { get; set; }
}
}

View file

@ -207,6 +207,7 @@
<PackageReference Include="Microsoft.AspNetCore.Components.WebView.Maui" Version="$(MauiVersion)" /> <PackageReference Include="Microsoft.AspNetCore.Components.WebView.Maui" Version="$(MauiVersion)" />
<PackageReference Include="Microsoft.Extensions.Logging.Debug" Version="8.0.0" /> <PackageReference Include="Microsoft.Extensions.Logging.Debug" Version="8.0.0" />
<PackageReference Include="Microsoft.Maui.Essentials" Version="8.0.40" /> <PackageReference Include="Microsoft.Maui.Essentials" Version="8.0.40" />
<PackageReference Include="PSC.Blazor.Components.MarkdownEditor" Version="8.0.0" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>

View file

@ -195,15 +195,15 @@ namespace Neighbourhood.omg.lol {
public async Task<PutPicResponseData?> PostPicDescription(string address, string id, string description) => public async Task<PutPicResponseData?> PostPicDescription(string address, string id, string description) =>
(await Post<PutPicResponseData, PostPic>($"/address/{address}/pics/{id}", new PostPic { Description = description })); (await Post<PutPicResponseData, PostPic>($"/address/{address}/pics/{id}", new PostPic { Description = description }));
public async Task<DeleteResponseData?> DeletePic(string address, string id) => public async Task<BasicResponseData?> DeletePic(string address, string id) =>
(await Delete<DeleteResponseData>($"/address/{address}/pics/{id}")); (await Delete<BasicResponseData>($"/address/{address}/pics/{id}"));
public async Task<PatchStatusResponseData?> PatchStatus(string address, string id, string content, string? emoji) => 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 })); (await Patch<PatchStatusResponseData, PatchStatus>($"/address/{address}/statuses/", new PatchStatus { Id = id, Content = content, Emoji = emoji }));
public async Task<DeleteResponseData?> DeleteStatus(string address, string id) => public async Task<BasicResponseData?> DeleteStatus(string address, string id) =>
(await Delete<DeleteResponseData>($"/address/{address}/statuses/{id}")); (await Delete<BasicResponseData>($"/address/{address}/statuses/{id}"));
public async Task<List<NowData>?> NowGarden() => public async Task<List<NowData>?> NowGarden() =>
(await Get<NowResponseData>($"/now/garden"))?.Garden ?? new List<NowData>(); (await Get<NowResponseData>($"/now/garden"))?.Garden ?? new List<NowData>();
@ -211,6 +211,12 @@ namespace Neighbourhood.omg.lol {
public async Task<List<string>?> Directory() => public async Task<List<string>?> Directory() =>
(await Get<DirectoryResponseData>($"/directory"))?.Directory ?? new List<string>(); (await Get<DirectoryResponseData>($"/directory"))?.Directory ?? new List<string>();
public async Task<NowContentData?> GetNowPage(string address) =>
(await Get<NowPageResponseData>($"/address/{address}/now"))?.Now;
public async Task<BasicResponseData?> PostNowPage(string address, string content, bool listed) =>
await Post<BasicResponseData, NowContentData>($"/address/{address}/now", new NowContentData { Content = content, Listed = listed ? 1 : 0 });
public async Task<List<MarkupString>> Ephemeral() { public async Task<List<MarkupString>> Ephemeral() {
List<string> notes = new List<string>(); List<string> notes = new List<string>();
Uri Uri = new Uri($"https://eph.emer.al/"); Uri Uri = new Uri($"https://eph.emer.al/");

View file

@ -416,4 +416,39 @@ article#directory ul{
#directoryIndex a { #directoryIndex a {
font-size: 1.5rem; font-size: 1.5rem;
}
.editor-toolbar .easymde-dropdown, .editor-toolbar button {
color: inherit;
}
.editor-toolbar i.separator {
---size: unset;
opacity: 0.25;
border-radius: 0
}
.markdown-editor .editor-preview {
background: var(--surface);
}
.markdown-editor {
flex: auto;
display: flex;
flex-direction:column;
}
.markdown-editor + nav {
flex: none;
}
.markdown-editor > .EasyMDEContainer {
flex: 1;
display: flex;
flex-direction: column;
}
.markdown-editor > .EasyMDEContainer > .editor-toolbar{
flex: none;
}
.markdown-editor > .EasyMDEContainer > .CodeMirror {
flex: auto;
} }

View file

@ -10,9 +10,14 @@
<link rel="stylesheet" href="css/app.css" /> <link rel="stylesheet" href="css/app.css" />
<link rel="stylesheet" href="css/style.css" /> <link rel="stylesheet" href="css/style.css" />
<link rel="stylesheet" href="Neighbourhood.omg.lol.styles.css" /> <link rel="stylesheet" href="Neighbourhood.omg.lol.styles.css" />
<script src="vendor/jquery-3.7.1.min.js"></script>
<script type="module" src="vendor/beer.min.js"></script> <script type="module" src="vendor/beer.min.js"></script>
<script type="module" src="vendor/material-dynamic-colors.min.js"></script> <script type="module" src="vendor/material-dynamic-colors.min.js"></script>
<script src="vendor/iframe-resizer/parent.js"></script> <script src="vendor/iframe-resizer/parent.js"></script>
<link href="/_content/PSC.Blazor.Components.MarkdownEditor/css/easymde.min.css" rel="stylesheet" />
<link href="/vendor/cm-material.css" rel="stylesheet" />
<script src="/_content/PSC.Blazor.Components.MarkdownEditor/js/easymde.min.js"></script>
<script src="/_content/PSC.Blazor.Components.MarkdownEditor/js/markdownEditor.js"></script>
<script src="/js/csharp.js"></script> <script src="/js/csharp.js"></script>
<link rel="icon" type="image/png" href="favicon.png" /> <link rel="icon" type="image/png" href="favicon.png" />
</head> </head>

135
wwwroot/vendor/cm-material.css vendored Normal file
View file

@ -0,0 +1,135 @@
/*
Name: material
Author: Mattia Astorino (http://github.com/equinusocio)
Website: https://material-theme.site/
*/
.cm-s-material-darker.CodeMirror {
background-color: #212121;
color: #EEFFFF;
}
.cm-s-material-darker .CodeMirror-gutters {
background: #212121;
color: #545454;
border: none;
}
.cm-s-material-darker .CodeMirror-guttermarker,
.cm-s-material-darker .CodeMirror-guttermarker-subtle,
.cm-s-material-darker .CodeMirror-linenumber {
color: #545454;
}
.cm-s-material-darker .CodeMirror-cursor {
border-left: 1px solid #FFCC00;
}
.cm-s-material-darker div.CodeMirror-selected {
background: rgba(97, 97, 97, 0.2);
}
.cm-s-material-darker.CodeMirror-focused div.CodeMirror-selected {
background: rgba(97, 97, 97, 0.2);
}
.cm-s-material-darker .CodeMirror-line::selection,
.cm-s-material-darker .CodeMirror-line > span::selection,
.cm-s-material-darker .CodeMirror-line > span > span::selection {
background: rgba(128, 203, 196, 0.2);
}
.cm-s-material-darker .CodeMirror-line::-moz-selection,
.cm-s-material-darker .CodeMirror-line > span::-moz-selection,
.cm-s-material-darker .CodeMirror-line > span > span::-moz-selection {
background: rgba(128, 203, 196, 0.2);
}
.cm-s-material-darker .CodeMirror-activeline-background {
background: rgba(0, 0, 0, 0.5);
}
.cm-s-material-darker .cm-keyword {
color: #C792EA;
}
.cm-s-material-darker .cm-operator {
color: #89DDFF;
}
.cm-s-material-darker .cm-variable-2 {
color: #EEFFFF;
}
.cm-s-material-darker .cm-variable-3,
.cm-s-material-darker .cm-type {
color: #f07178;
}
.cm-s-material-darker .cm-builtin {
color: #FFCB6B;
}
.cm-s-material-darker .cm-atom {
color: #F78C6C;
}
.cm-s-material-darker .cm-number {
color: #FF5370;
}
.cm-s-material-darker .cm-def {
color: #82AAFF;
}
.cm-s-material-darker .cm-string {
color: #C3E88D;
}
.cm-s-material-darker .cm-string-2 {
color: #f07178;
}
.cm-s-material-darker .cm-comment {
color: #545454;
}
.cm-s-material-darker .cm-variable {
color: #f07178;
}
.cm-s-material-darker .cm-tag {
color: #FF5370;
}
.cm-s-material-darker .cm-meta {
color: #FFCB6B;
}
.cm-s-material-darker .cm-attribute {
color: #C792EA;
}
.cm-s-material-darker .cm-property {
color: #C792EA;
}
.cm-s-material-darker .cm-qualifier {
color: #DECB6B;
}
.cm-s-material-darker .cm-variable-3,
.cm-s-material-darker .cm-type {
color: #DECB6B;
}
.cm-s-material-darker .cm-error {
color: rgba(255, 255, 255, 1.0);
background-color: #FF5370;
}
.cm-s-material-darker .CodeMirror-matchingbracket {
text-decoration: underline;
color: white !important;
}

2
wwwroot/vendor/jquery-3.7.1.min.js vendored Normal file

File diff suppressed because one or more lines are too long