diff --git a/Moonlight/Moonlight.csproj b/Moonlight/Moonlight.csproj index 6d9ccd1..b0120d8 100644 --- a/Moonlight/Moonlight.csproj +++ b/Moonlight/Moonlight.csproj @@ -24,6 +24,7 @@ + all runtime; build; native; contentfiles; analyzers; buildtransitive diff --git a/Moonlight/Shared/Components/News/NewsEditor.razor b/Moonlight/Shared/Components/News/NewsEditor.razor new file mode 100644 index 0000000..a58d1b1 --- /dev/null +++ b/Moonlight/Shared/Components/News/NewsEditor.razor @@ -0,0 +1,98 @@ +@using Moonlight.App.Services +@using Moonlight.App.Database.Entities +@using BlazorMonaco + +@inject SmartTranslateService SmartTranslateService +@inject IJSRuntime JsRuntime + +
+
+

+ +

+
+ @{ + string dateInt(int i) => i.ToString().Length < 2 ? "0" + i : i.ToString(); + var date = Model.Date == default ? DateTime.Now : Model.Date; + } + @dateInt(date.Day).@dateInt(date.Month).@date.Year +
+
+
+ +
+ +
+ +@code { + // Monaco Editor + private MonacoEditor Editor; + private StandaloneEditorConstructionOptions EditorOptions; + + [Parameter] + public NewsEntry Model { get; set; } + + [Parameter] + public Func Save { get; set; } + + protected override void OnInitialized() + { + EditorOptions = new() + { + AutomaticLayout = true, + Language = "plaintext", + Value = "Loading content", + Theme = "moonlight-theme", + Contextmenu = false, + Minimap = new() + { + Enabled = false + }, + AutoIndent = true + }; + } + + protected override async Task OnAfterRenderAsync(bool firstRender) + { + if (firstRender) + { + await JsRuntime.InvokeVoidAsync("initMonacoTheme"); + + Editor.OnDidInit = new EventCallback(this, async () => + { + EditorOptions.Language = "markdown"; + + var model = await Editor.GetModel(); + await MonacoEditorBase.SetModelLanguage(model, EditorOptions.Language); + await Editor.SetPosition(new Position() + { + Column = 0, + LineNumber = 1 + }); + + await Editor.SetValue(string.IsNullOrWhiteSpace(Model.Markdown) ? "*enter your markdown here*" : Model.Markdown); + + await Editor.Layout(new Dimension() + { + Height = 500, + Width = 1000 + }); + }); + } + } + + private async Task DoSave() + { + Model.Date = Model.Date == default ? DateTime.Now : Model.Date; + Model.Markdown = await Editor.GetValue(); + + Save?.Invoke(Model); + } + + public async Task UpdateMonacoText() + { + await Editor.SetValue(Model.Markdown); + } +} \ No newline at end of file diff --git a/Moonlight/Shared/Components/Partials/SidebarMenu.razor b/Moonlight/Shared/Components/Partials/SidebarMenu.razor index c7e6c69..777667c 100644 --- a/Moonlight/Shared/Components/Partials/SidebarMenu.razor +++ b/Moonlight/Shared/Components/Partials/SidebarMenu.razor @@ -68,6 +68,14 @@ else Changelog + if (User.Admin) { diff --git a/Moonlight/Shared/News/Edit.razor b/Moonlight/Shared/News/Edit.razor new file mode 100644 index 0000000..aed04bf --- /dev/null +++ b/Moonlight/Shared/News/Edit.razor @@ -0,0 +1,32 @@ +@page "/news/edit/{Id:int}" + +@using Moonlight.App.Database.Entities +@using Moonlight.App.Repositories +@using Moonlight.Shared.Components.News + +@inject NewsEntryRepository NewsEntryRepository +@inject NavigationManager NavigationManager + + + + + + + +@code { + [Parameter] + public int Id { get; set; } + + private NewsEntry Entry; + + private async Task Load(LazyLoader loader) + { + Entry = NewsEntryRepository.Get().First(x => x.Id == Id); + } + + private async Task DoSave(NewsEntry entry) + { + NewsEntryRepository.Update(entry); + NavigationManager.NavigateTo("/news"); + } +} \ No newline at end of file diff --git a/Moonlight/Shared/Views/News.razor b/Moonlight/Shared/Views/News.razor new file mode 100644 index 0000000..d11f077 --- /dev/null +++ b/Moonlight/Shared/Views/News.razor @@ -0,0 +1,89 @@ +@page "/news" +@using Moonlight.App.Repositories +@using Moonlight.App.Database.Entities +@using Markdig +@using Moonlight.App.Services +@using Moonlight.App.Services.Interop +@using Moonlight.Shared.Components.News + +@inject NewsEntryRepository NewsEntryRepository +@inject SmartTranslateService SmartTranslateService +@inject NavigationManager NavigationManager +@inject AlertService AlertService + + + + + + + @foreach (var entry in Entries) + { +
+
+

@entry.Title

+
+ + + + + + + + + @{ + string dateInt(int i) => i.ToString().Length < 2 ? "0" + i : i.ToString(); + } + @dateInt(entry.Date.Day).@dateInt(entry.Date.Month).@entry.Date.Year +
+
+
+ @{ + var html = (MarkupString)Markdown.ToHtml(entry.Markdown); + } + + @html +
+
+ + } +
+ +@code { + private NewsEntry NewPost = new(); + private NewsEditor NewPostEditor; + + private NewsEntry[] Entries; + + private async Task Load(LazyLoader loader) + { + Entries = NewsEntryRepository.Get().OrderByDescending(x => x.Date).ToArray(); + } + + private async Task DoSaveNewPost(NewsEntry post) + { + NewsEntryRepository.Add(post); + + NavigationManager.NavigateTo(NavigationManager.Uri, true); + } + + private async Task Delete(NewsEntry entry) + { + var confirm = await AlertService.YesNo( + SmartTranslateService.Translate("Delete post"), + SmartTranslateService.Translate("Do you really want to delete the post \"") + entry.Title + "\"?", + SmartTranslateService.Translate("Yes"), + SmartTranslateService.Translate("No") + ); + + if(!confirm) return; + + NewsEntryRepository.Delete(entry); + + NavigationManager.NavigateTo(NavigationManager.Uri, true); + } +} \ No newline at end of file diff --git a/Moonlight/resources/lang/de_de.lang b/Moonlight/resources/lang/de_de.lang index 6b7ea7a..3fe0ffb 100644 --- a/Moonlight/resources/lang/de_de.lang +++ b/Moonlight/resources/lang/de_de.lang @@ -549,4 +549,11 @@ No node found to deploy to;No node found to deploy to Website details;Website details Configure your website;Configure your website The name cannot be longer that 32 characters;The name cannot be longer that 32 characters -The name should only consist of lower case characters;The name should only consist of lower case characters \ No newline at end of file +The name should only consist of lower case characters;The name should only consist of lower case characters +News;News +Title...;Title... +Enter text...;Enter text... +Saving...;Saving... +Deleting...;Deleting... +Delete post;Delete post +Do you really want to delete the post ";Do you really want to delete the post "