Added a way to edit the profile page
Including custom css and head content, but not custom themes or metadata (yet)
This commit is contained in:
parent
b42bf2023d
commit
25f362bfc5
7 changed files with 145 additions and 0 deletions
|
@ -223,6 +223,15 @@ namespace Neighbourhood.omg.lol
|
||||||
public async Task<BasicResponseData?> PostEphemeral(string content) =>
|
public async Task<BasicResponseData?> PostEphemeral(string content) =>
|
||||||
await Post<BasicResponseData, EphemeralData>("/ephemeral", new EphemeralData { Content = content });
|
await Post<BasicResponseData, EphemeralData>("/ephemeral", new EphemeralData { Content = content });
|
||||||
|
|
||||||
|
public async Task<ProfileResponseData?> GetProfile(string address) =>
|
||||||
|
await Get<ProfileResponseData>($"/address/{address}/web");
|
||||||
|
|
||||||
|
public async Task<BasicResponseData?> PostProfile(string address, string content, bool publish = true) =>
|
||||||
|
await Post<BasicResponseData, PostProfile>($"/address/{address}/web", new PostProfile { Content = content, Publish = publish });
|
||||||
|
|
||||||
|
public async Task<BasicResponseData?> PostProfile(string address, PostProfile data) =>
|
||||||
|
await Post<BasicResponseData, PostProfile>($"/address/{address}/web", data);
|
||||||
|
|
||||||
public async Task<List<MarkupString>> EphemeralScrape() {
|
public async Task<List<MarkupString>> EphemeralScrape() {
|
||||||
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/");
|
||||||
|
|
83
Components/Pages/EditProfile.razor
Normal file
83
Components/Pages/EditProfile.razor
Normal file
|
@ -0,0 +1,83 @@
|
||||||
|
@page "/editProfile"
|
||||||
|
@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>
|
||||||
|
|
||||||
|
<details id="advanced">
|
||||||
|
<summary> Advanced </summary>
|
||||||
|
<small>Style you include here will be places in a <style> element in your page’s <head>.</small>
|
||||||
|
<div class="field textarea label border max">
|
||||||
|
<InputTextArea @bind-Value="css"></InputTextArea>
|
||||||
|
<label>Custom CSS</label>
|
||||||
|
</div>
|
||||||
|
<small>Anything you put here will be included in your page’s <head> element.</small>
|
||||||
|
<div class="field textarea label border max">
|
||||||
|
<InputTextArea @bind-Value="head"></InputTextArea>
|
||||||
|
<label>Additional <head> Content</label>
|
||||||
|
</div>
|
||||||
|
</details>
|
||||||
|
|
||||||
|
<nav>
|
||||||
|
<div class="max"></div>
|
||||||
|
<button class="transparent link" onclick="history.back();" disabled="@loading">Cancel</button>
|
||||||
|
<button @onclick="Save" disabled="@loading">
|
||||||
|
@if (loading) {
|
||||||
|
<span>Saving...</span>
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
<i class="fa-solid fa-floppy-disk"></i> <span>Save & Publish</span>
|
||||||
|
}
|
||||||
|
</button>
|
||||||
|
</nav>
|
||||||
|
|
||||||
|
@code {
|
||||||
|
private MarkdownEditor? Editor;
|
||||||
|
private string? markdownValue;
|
||||||
|
private string? css;
|
||||||
|
private string? head;
|
||||||
|
|
||||||
|
private bool loading = false;
|
||||||
|
|
||||||
|
protected override async Task OnInitializedAsync() {
|
||||||
|
await base.OnInitializedAsync();
|
||||||
|
ProfileResponseData? data = await api.GetProfile(State.SelectedAddressName!);
|
||||||
|
if (data != null) {
|
||||||
|
markdownValue = data.Content;
|
||||||
|
css = data.Css;
|
||||||
|
head = data.Head;
|
||||||
|
|
||||||
|
await Editor!.SetValueAsync(markdownValue);
|
||||||
|
}
|
||||||
|
await InvokeAsync(StateHasChanged);
|
||||||
|
}
|
||||||
|
|
||||||
|
Task OnMarkdownValueChanged(string value) {
|
||||||
|
return Task.CompletedTask;
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task Save() {
|
||||||
|
loading = true;
|
||||||
|
await InvokeAsync(StateHasChanged);
|
||||||
|
var result = await api.PostProfile(State.SelectedAddressName!,
|
||||||
|
new PostProfile() {
|
||||||
|
Content = markdownValue ?? string.Empty,
|
||||||
|
Css = string.IsNullOrEmpty(css) ? null : css,
|
||||||
|
Head = string.IsNullOrEmpty(head) ? null : head
|
||||||
|
});
|
||||||
|
if (result != null) {
|
||||||
|
await State.RefreshNow();
|
||||||
|
await InvokeAsync(StateHasChanged);
|
||||||
|
Nav.NavigateTo($"/person/{State.SelectedAddressName}#profile");
|
||||||
|
}
|
||||||
|
|
||||||
|
loading = false;
|
||||||
|
}
|
||||||
|
}
|
|
@ -52,6 +52,12 @@
|
||||||
<div id="profile" class="page no-padding">
|
<div id="profile" class="page no-padding">
|
||||||
<a href="@ProfileUrl" 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="@ProfileUrl" 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="profile_page" @ref="ProfilePage" Url="@ProfileUrl"></ExternalPageComponent>
|
<ExternalPageComponent id="profile_page" @ref="ProfilePage" Url="@ProfileUrl"></ExternalPageComponent>
|
||||||
|
@if (IsMe) {
|
||||||
|
<a href="/editProfile" 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 id="statuses" class="page padding active">
|
<div id="statuses" class="page padding active">
|
||||||
|
|
14
Models/API/PostProfile.cs
Normal file
14
Models/API/PostProfile.cs
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace Neighbourhood.omg.lol.Models {
|
||||||
|
public class PostProfile {
|
||||||
|
public string Content { get; set; } = string.Empty;
|
||||||
|
public bool Publish { get; set; } = true;
|
||||||
|
public string? Css { get; set; }
|
||||||
|
public string? Head { get; set; }
|
||||||
|
}
|
||||||
|
}
|
21
Models/API/ProfileResponseData.cs
Normal file
21
Models/API/ProfileResponseData.cs
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace Neighbourhood.omg.lol.Models {
|
||||||
|
public class ProfileResponseData: IOmgLolResponseData {
|
||||||
|
public string Message { get; set; } = string.Empty;
|
||||||
|
public string Content { get; set; } = string.Empty;
|
||||||
|
public string Type { get; set; } = string.Empty;
|
||||||
|
public string Theme { get; set; } = string.Empty;
|
||||||
|
public string Css { get; set; } = string.Empty;
|
||||||
|
public string Head { get; set; } = string.Empty;
|
||||||
|
public string Verified { get; set; } = string.Empty;
|
||||||
|
public string Pfp { get; set; } = string.Empty;
|
||||||
|
public string Metadata { get; set; } = string.Empty;
|
||||||
|
public string Branding { get; set; } = string.Empty;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
|
@ -496,3 +496,9 @@ article.now {
|
||||||
margin: 0;
|
margin: 0;
|
||||||
width:auto;
|
width:auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#advanced textarea, #advanced .field.textarea {
|
||||||
|
background-color: #212121;
|
||||||
|
color: #EEFFFF;
|
||||||
|
font-family: monospace;
|
||||||
|
}
|
|
@ -23,3 +23,9 @@ function scrollToId(id) {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function toggleDetails(id) {
|
||||||
|
const element = document.getElementById(id)
|
||||||
|
if (element instanceof HTMLDetailsElement)
|
||||||
|
element.open = !element.open
|
||||||
|
}
|
Loading…
Reference in a new issue