Skip to content

Commit 10cd720

Browse files
committed
(#424) wasm: update dto, create the markdown compoment
1 parent 7598d80 commit 10cd720

File tree

10 files changed

+235
-80
lines changed

10 files changed

+235
-80
lines changed

MiniSpace.Web/src/Astravent.Web.Wasm/Areas/Notifications/NotificationsService.cs

-1
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@
66
using Astravent.Web.Wasm.Data.Events;
77
using Astravent.Web.Wasm.DTO.Wrappers;
88
using Astravent.Web.Wasm.HttpClients;
9-
using Blazorise;
109
using Astravent.Web.Wasm.DTO.Notifications;
1110
using System.Collections.Concurrent;
1211

MiniSpace.Web/src/Astravent.Web.Wasm/Areas/Posts/IPostsService.cs

+1
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
using Astravent.Web.Wasm.Areas.Posts.CommandsDto;
55
using Astravent.Web.Wasm.Data.Posts;
66
using Astravent.Web.Wasm.DTO;
7+
using Astravent.Web.Wasm.DTO.Posts;
78
using Astravent.Web.Wasm.DTO.Wrappers;
89
using Astravent.Web.Wasm.HttpClients;
910

MiniSpace.Web/src/Astravent.Web.Wasm/Areas/Posts/PostsService.cs

+1
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
using Astravent.Web.Wasm.Data.Posts;
1010
using Astravent.Web.Wasm.DTO;
1111
using Astravent.Web.Wasm.DTO.Enums.Posts;
12+
using Astravent.Web.Wasm.DTO.Posts;
1213
using Astravent.Web.Wasm.DTO.Wrappers;
1314
using Astravent.Web.Wasm.HttpClients;
1415

MiniSpace.Web/src/Astravent.Web.Wasm/Astravent.Web.Wasm.csproj

+1
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313

1414
<ItemGroup>
1515
<PackageReference Include="Blazorise.Bootstrap5" Version="1.6.1" />
16+
<PackageReference Include="Blazorise.Markdown" Version="1.6.1" />
1617
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly" Version="8.0.6" />
1718
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly.DevServer" Version="8.0.6" PrivateAssets="all" />
1819
<PackageReference Include="Microsoft.AspNetCore.Components.Authorization" Version="8.0.6" />

MiniSpace.Web/src/Astravent.Web.Wasm/DTO/PostDto.cs MiniSpace.Web/src/Astravent.Web.Wasm/DTO/Posts/PostDto.cs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
using System;
22
using System.Collections.Generic;
33

4-
namespace Astravent.Web.Wasm.DTO
4+
namespace Astravent.Web.Wasm.DTO.Posts
55
{
66
public class PostDto
77
{
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
namespace Astravent.Web.Wasm.DTO.Posts
2+
{
3+
public enum PostType
4+
{
5+
BlogPost,
6+
SocialPost
7+
}
8+
}

MiniSpace.Web/src/Astravent.Web.Wasm/Pages/Posts/CreatePost.razor

+115-73
Original file line numberDiff line numberDiff line change
@@ -1,96 +1,138 @@
11
@page "/posts/create"
22
@inject IPostsService PostsService
3-
@inject IEventsService EventsService
43
@inject IIdentityService IdentityService
54
@inject IMediaFilesService MediaFilesService
65
@inject NavigationManager NavigationManager
76
@inject IJSRuntime JSRuntime
87
@using Astravent.Web.Wasm.Areas.Posts.CommandsDto
98
@using Astravent.Web.Wasm.DTO.Enums.Posts
109
@using MudBlazor
11-
@using System.IO
12-
@using Microsoft.AspNetCore.Components.Forms
13-
14-
<MudContainer MaxWidth="MaxWidth.Small" Class="pa-4">
15-
<MudCard>
16-
<MudCardHeader>
17-
<MudText Typo="Typo.h5">Create a New Post</MudText>
18-
</MudCardHeader>
19-
<MudCardContent>
20-
<MudForm @ref="form" @onsubmit="HandleSubmit">
21-
<MudTextField @bind-Value="textContent" Label="Description" Multiline="true" Lines="5" FullWidth Immediate="true" Required="true" />
22-
<MudMarkdown Value="@textContent" />
23-
24-
<MudButton Color="Color.Primary" Variant="Variant.Outlined" OnClick="UploadMediaFilesClick" StartIcon="@Icons.Material.Filled.Upload">
25-
Upload Media Files
26-
</MudButton>
27-
<InputFile id="fileInputMediaFiles" OnChange="@(async e => await UploadMediaFiles(e))" Multiple="true" style="display: none;" accept=".jpeg,.png,.jpg,.mp4,.pdf" />
28-
29-
@if (mediaFilesPreviews.Any())
10+
11+
<MudContainer MaxWidth="MaxWidth.Large" Class="pa-4">
12+
<MudGrid>
13+
<!-- Left Side: Post Preview (Public Information) -->
14+
<MudItem xs="12" md="6">
15+
<MudPaper Class="pa-4">
16+
<MudText Typo="Typo.h5">Post Preview</MudText>
17+
@if (postType == PostType.BlogPost)
3018
{
31-
<MudText Typo="Typo.h6" Class="mt-4">Uploaded Files Preview</MudText>
32-
<MudGrid>
33-
@foreach (var filePreview in mediaFilesPreviews)
34-
{
35-
<MudItem xs="12" sm="6">
36-
<MudCard>
37-
@if (filePreview.IsImage)
38-
{
39-
<MudCardMedia Image="@filePreview.Url" Title="Media Preview" AspectRatio="16:9" />
40-
}
41-
else if (filePreview.IsVideo)
42-
{
43-
<MudCardMedia AspectRatio="16:9">
44-
<video width="100%" controls>
45-
<source src="@filePreview.Url" type="@filePreview.ContentType">
46-
Your browser does not support the video tag.
47-
</video>
48-
</MudCardMedia>
49-
}
50-
else if (filePreview.IsPdf)
51-
{
52-
<MudCardContent>
53-
<MudButton Variant="Variant.Outlined" Color="Color.Secondary" StartIcon="@Icons.Material.Filled.PictureAsPdf" OnClick="@(async () => await JSRuntime.InvokeVoidAsync("window.open", filePreview.Url, "_blank"))">
54-
View PDF
55-
</MudButton>
56-
</MudCardContent>
57-
}
58-
</MudCard>
59-
</MudItem>
60-
}
61-
</MudGrid>
19+
<MudText Typo="Typo.h6" Class="mt-2">Title: @title</MudText>
20+
<MudMarkdown MarkupContent="@textContent" />
6221
}
63-
64-
<MudSelect T="string" @bind-Value="state" Label="State" Required="true" Class="mt-4">
65-
<MudSelectItem T="string" Value="@("InDraft")">Draft</MudSelectItem>
66-
<MudSelectItem T="string" Value="@("Published")">Published</MudSelectItem>
67-
</MudSelect>
68-
69-
<MudSelect T="string" @bind-Value="visibility" Label="Visibility" Required="true" Class="mt-4">
70-
<MudSelectItem T="string" Value="@("Visible")">Visible</MudSelectItem>
71-
<MudSelectItem T="string" Value="@("Invisible")">Invisible</MudSelectItem>
72-
</MudSelect>
73-
74-
<MudDatePicker @bind-Date="publishDate" Label="Publish Date" Class="mt-4" />
75-
76-
<MudStack Direction="Row" Spacing="2" Class="mt-4">
77-
<MudButton Color="Color.Primary" Variant="Variant.Filled" Type="Submit" StartIcon="@Icons.Material.Filled.Check">Create Post</MudButton>
78-
<MudButton Color="Color.Secondary" Variant="Variant.Outlined" OnClick="HandleCancel" StartIcon="@Icons.Material.Filled.Cancel">Cancel</MudButton>
79-
</MudStack>
80-
</MudForm>
81-
</MudCardContent>
82-
</MudCard>
22+
else if (postType == PostType.SocialPost)
23+
{
24+
<MudMarkdown MarkupContent="@textContent" />
25+
@if (mediaFilesPreviews.Any())
26+
{
27+
<MudText Typo="Typo.h6" Class="mt-4">Uploaded Files</MudText>
28+
<MudGrid>
29+
@foreach (var filePreview in mediaFilesPreviews)
30+
{
31+
<MudItem xs="12" sm="6">
32+
<MudCard>
33+
@if (filePreview.IsImage)
34+
{
35+
<MudCardMedia Image="@filePreview.Url" Title="Media Preview" AspectRatio="16:9" />
36+
}
37+
else if (filePreview.IsVideo)
38+
{
39+
<MudCardMedia AspectRatio="16:9">
40+
<video width="100%" controls>
41+
<source src="@filePreview.Url" type="@filePreview.ContentType">
42+
Your browser does not support the video tag.
43+
</video>
44+
</MudCardMedia>
45+
}
46+
else if (filePreview.IsPdf)
47+
{
48+
<MudCardContent>
49+
<MudButton Variant="Variant.Outlined" Color="Color.Secondary" StartIcon="@Icons.Material.Filled.PictureAsPdf" OnClick="@(async () => await JSRuntime.InvokeVoidAsync("window.open", filePreview.Url, "_blank"))">
50+
View PDF
51+
</MudButton>
52+
</MudCardContent>
53+
}
54+
</MudCard>
55+
</MudItem>
56+
}
57+
</MudGrid>
58+
}
59+
}
60+
</MudPaper>
61+
</MudItem>
62+
63+
<!-- Right Side: Post Configuration (Administration) -->
64+
<MudItem xs="12" md="6">
65+
<MudPaper Class="pa-4">
66+
<MudText Typo="Typo.h5">Post Configuration</MudText>
67+
<MudForm @ref="form" @onsubmit="HandleSubmit">
68+
<!-- Post Type Selection -->
69+
<MudSelect T="PostType" @bind-Value="postType" Label="Post Type" Required="true" FullWidth Class="mt-2">
70+
<MudSelectItem T="PostType" Value="PostType.BlogPost">Blog Post</MudSelectItem>
71+
<MudSelectItem T="PostType" Value="PostType.SocialPost">Social Post</MudSelectItem>
72+
</MudSelect>
73+
74+
<!-- Blog Post Specific Fields -->
75+
@if (postType == PostType.BlogPost)
76+
{
77+
<MudText Typo="Typo.subtitle1" Class="mt-4">Blog Post Details</MudText>
78+
<MudTextField @bind-Value="title" Label="Post Title" FullWidth Immediate="true" Required="true" />
79+
80+
<!-- Custom MarkdownEditor for Blog Post Content -->
81+
<MarkdownEditor @bind-MarkdownText="textContent" />
82+
83+
<MudSelect T="PostContext" @bind-Value="postContext" Label="Post Context" Required="true" FullWidth Class="mt-4">
84+
<MudSelectItem T="PostContext" Value="PostContext.UserPage">User Page</MudSelectItem>
85+
<MudSelectItem T="PostContext" Value="PostContext.OrganizationPage">Organization Page</MudSelectItem>
86+
<MudSelectItem T="PostContext" Value="PostContext.EventPage">Event Page</MudSelectItem>
87+
</MudSelect>
88+
}
89+
90+
<!-- Social Post Specific Fields -->
91+
@if (postType == PostType.SocialPost)
92+
{
93+
<MudText Typo="Typo.subtitle1" Class="mt-4">Social Post Details</MudText>
94+
<MudTextField @bind-Value="textContent" Label="Description" Multiline="true" Lines="5" FullWidth Immediate="true" Required="true" />
95+
<MudButton Color="Color.Primary" Variant="Variant.Outlined" OnClick="UploadMediaFilesClick" StartIcon="@Icons.Material.Filled.Upload" Class="mt-4">
96+
Upload Media Files
97+
</MudButton>
98+
<InputFile id="fileInputMediaFiles" OnChange="@(async e => await UploadMediaFiles(e))" Multiple="true" style="display: none;" accept=".jpeg,.png,.jpg,.mp4,.pdf" />
99+
}
100+
101+
<!-- Post State and Visibility -->
102+
<MudSelect T="string" @bind-Value="state" Label="State" Required="true" FullWidth Class="mt-4">
103+
<MudSelectItem T="string" Value="@("InDraft")">Draft</MudSelectItem>
104+
<MudSelectItem T="string" Value="@("Published")">Published</MudSelectItem>
105+
</MudSelect>
106+
107+
<MudSelect T="string" @bind-Value="visibility" Label="Visibility" Required="true" FullWidth Class="mt-4">
108+
<MudSelectItem T="string" Value="@("Visible")">Visible</MudSelectItem>
109+
<MudSelectItem T="string" Value="@("Invisible")">Invisible</MudSelectItem>
110+
</MudSelect>
111+
112+
<MudDatePicker @bind-Date="publishDate" Label="Publish Date" Class="mt-4" />
113+
114+
<MudStack Direction="Row" Spacing="2" Class="mt-4">
115+
<MudButton Color="Color.Primary" Variant="Variant.Filled" Type="Submit" StartIcon="@Icons.Material.Filled.Check">Create Post</MudButton>
116+
<MudButton Color="Color.Secondary" Variant="Variant.Outlined" OnClick="HandleCancel" StartIcon="@Icons.Material.Filled.Cancel">Cancel</MudButton>
117+
</MudStack>
118+
</MudForm>
119+
</MudPaper>
120+
</MudItem>
121+
</MudGrid>
83122
</MudContainer>
84123

85124
@code {
86125
private MudForm form;
87-
private string textContent;
126+
private string textContent = "## Markdown Content\n";
127+
private string title;
88128
private List<FilePreview> mediaFilesPreviews = new();
89129
private List<string> uploadedMediaUrls = new List<string>();
90130
private string state = "InDraft";
91131
private string visibility = "Visible";
92132
private DateTime? publishDate = DateTime.Now;
93133
private bool isUploading = false;
134+
private PostType postType = PostType.SocialPost; // Default to Social Post
135+
private PostContext postContext = PostContext.UserPage; // Default context
94136
95137
private async Task UploadMediaFilesClick()
96138
{
@@ -163,7 +205,7 @@
163205
State = state,
164206
Visibility = visibility,
165207
PublishDate = publishDate,
166-
Context = PostContext.UserPage
208+
Context = postContext // The context now reflects UserPage, OrganizationPage, or EventPage
167209
};
168210

169211
var response = await PostsService.CreatePostAsync(command);
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
@using MudBlazor
2+
3+
<MudPaper Class="pa-4" Style="background-color:#f9f9f9; border-radius: 12px;">
4+
<!-- Markdown TextField for Input -->
5+
<MudTextField @bind-Value="MarkdownText" Label="Markdown Text" Multiline="true" Lines="10" FullWidth Immediate="true" Class="mb-2" Required="true" id="markdown-editor" />
6+
7+
<!-- Toolbar with Buttons in a Row -->
8+
<MudGrid Class="mt-2" Gutter="2">
9+
<MudItem>
10+
<MudButton OnClick="@(async () => await ApplyMarkdown("bold"))" Color="Color.Primary" Variant="Variant.Text" StartIcon="@Icons.Material.Filled.FormatBold" Class="toolbar-btn">
11+
Bold
12+
</MudButton>
13+
</MudItem>
14+
<MudItem>
15+
<MudButton OnClick="@(async () => await ApplyMarkdown("italic"))" Color="Color.Primary" Variant="Variant.Text" StartIcon="@Icons.Material.Filled.FormatItalic" Class="toolbar-btn">
16+
Italic
17+
</MudButton>
18+
</MudItem>
19+
<MudItem>
20+
<MudButton OnClick="@(async () => await ApplyMarkdown("heading"))" Color="Color.Primary" Variant="Variant.Text" StartIcon="@Icons.Material.Filled.Title" Class="toolbar-btn">
21+
Heading
22+
</MudButton>
23+
</MudItem>
24+
<MudItem>
25+
<MudButton OnClick="@(async () => await ApplyMarkdown("link"))" Color="Color.Primary" Variant="Variant.Text" StartIcon="@Icons.Material.Filled.Link" Class="toolbar-btn">
26+
Link
27+
</MudButton>
28+
</MudItem>
29+
<MudItem>
30+
<MudButton OnClick="@(async () => await ApplyMarkdown("code"))" Color="Color.Primary" Variant="Variant.Text" StartIcon="@Icons.Material.Filled.Code" Class="toolbar-btn">
31+
Code
32+
</MudButton>
33+
</MudItem>
34+
</MudGrid>
35+
36+
<!-- Styles for a modern toolbar -->
37+
<style>
38+
.toolbar-btn {
39+
margin: 0 6px;
40+
min-width: 48px;
41+
height: 36px;
42+
}
43+
44+
#markdown-editor {
45+
font-size: 1rem;
46+
border-radius: 8px;
47+
}
48+
</style>
49+
</MudPaper>
50+
51+
@code {
52+
[Parameter]
53+
public string MarkdownText { get; set; } = string.Empty;
54+
55+
[Parameter]
56+
public EventCallback<string> MarkdownTextChanged { get; set; }
57+
58+
[Inject]
59+
IJSRuntime JSRuntime { get; set; }
60+
61+
// JavaScript interop to manipulate selected text
62+
private async Task ApplyMarkdown(string action)
63+
{
64+
var selectedText = await JSRuntime.InvokeAsync<string>("getSelectedText", "markdown-editor");
65+
66+
switch (action)
67+
{
68+
case "bold":
69+
InsertText("**", "**", selectedText);
70+
break;
71+
case "italic":
72+
InsertText("_", "_", selectedText);
73+
break;
74+
case "heading":
75+
InsertText("### ", "", selectedText);
76+
break;
77+
case "link":
78+
InsertText("[", "]()", selectedText);
79+
break;
80+
case "code":
81+
InsertText("`", "`", selectedText);
82+
break;
83+
}
84+
}
85+
86+
private void InsertText(string prefix, string suffix, string selectedText)
87+
{
88+
if (!string.IsNullOrEmpty(selectedText))
89+
{
90+
var newText = $"{prefix}{selectedText}{suffix}";
91+
MarkdownText = MarkdownText.Replace(selectedText, newText);
92+
}
93+
else
94+
{
95+
MarkdownText += $"{prefix}{suffix}";
96+
}
97+
98+
MarkdownTextChanged.InvokeAsync(MarkdownText);
99+
}
100+
}

MiniSpace.Web/src/Astravent.Web.Wasm/_Imports.razor

+2
Original file line numberDiff line numberDiff line change
@@ -54,3 +54,5 @@
5454

5555
@using Astravent.Web.Wasm.DTO.Users
5656
@using Astravent.Web.Wasm.Utilities
57+
@using Astravent.Web.Wasm.DTO.Posts
58+
@using Astravent.Web.Wasm.Shared.Components

0 commit comments

Comments
 (0)