feat: started working on stickys and locking, started working on replying in threads, added banners, added autism board, other small changes
This commit is contained in:
parent
d8fcc93394
commit
5fdebe3fc1
18 changed files with 132 additions and 35 deletions
|
@ -42,4 +42,8 @@ public class PostData
|
||||||
public List<CommentData> Comments { get; set; }
|
public List<CommentData> Comments { get; set; }
|
||||||
|
|
||||||
public ReportData? Report { get; set; }
|
public ReportData? Report { get; set; }
|
||||||
|
|
||||||
|
public bool IsSticky { get; set; }
|
||||||
|
|
||||||
|
public bool IsLocked { get; set; }
|
||||||
}
|
}
|
|
@ -38,6 +38,8 @@ public class TheManager
|
||||||
{
|
{
|
||||||
for (int i = board.maxThreads + 1; i >= sortedThreads.Count; ++i)
|
for (int i = board.maxThreads + 1; i >= sortedThreads.Count; ++i)
|
||||||
{
|
{
|
||||||
|
if (sortedThreads[i].IsSticky)
|
||||||
|
continue;
|
||||||
await deleteThread(sortedThreads[i]);
|
await deleteThread(sortedThreads[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,10 +22,13 @@
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Folder Include="Data\Migrations" />
|
<Folder Include="Data\Migrations" />
|
||||||
<Folder Include="wwwroot\img\dynamic\comment\art" />
|
<Folder Include="wwwroot\img\dynamic\comment\art" />
|
||||||
<Folder Include="wwwroot\img\dynamic\comment\m" />
|
<Folder Include="wwwroot\img\dynamic\comment\au" />
|
||||||
|
<Folder Include="wwwroot\img\dynamic\comment\e" />
|
||||||
<Folder Include="wwwroot\img\dynamic\comment\tec" />
|
<Folder Include="wwwroot\img\dynamic\comment\tec" />
|
||||||
<Folder Include="wwwroot\img\dynamic\comment\vg" />
|
<Folder Include="wwwroot\img\dynamic\comment\vg" />
|
||||||
<Folder Include="wwwroot\img\dynamic\op\art" />
|
<Folder Include="wwwroot\img\dynamic\op\art" />
|
||||||
|
<Folder Include="wwwroot\img\dynamic\op\au" />
|
||||||
|
<Folder Include="wwwroot\img\dynamic\op\e" />
|
||||||
<Folder Include="wwwroot\img\dynamic\op\tec" />
|
<Folder Include="wwwroot\img\dynamic\op\tec" />
|
||||||
<Folder Include="wwwroot\img\dynamic\op\vg" />
|
<Folder Include="wwwroot\img\dynamic\op\vg" />
|
||||||
<Folder Include="wwwroot\img\thumb" />
|
<Folder Include="wwwroot\img\thumb" />
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
<span>This is a simple Imageboard made in Razor.</span>
|
<span>This is a simple Imageboard made in Razor.</span>
|
||||||
<br/>
|
<br/>
|
||||||
<span>We're currently hosting @amountOfPosts Threads, @amountOfComments Comments and @amountOfUsers Users.</span>
|
<span>We're currently hosting @amountOfPosts Threads, @amountOfComments Comments and @amountOfUsers Users.</span>
|
||||||
<sr/>
|
<br/>
|
||||||
<span>@Details</span>
|
<span>@Details</span>
|
||||||
<AuthorizeView>
|
<AuthorizeView>
|
||||||
<Authorized>
|
<Authorized>
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
@page "/m/"
|
@page "/e/"
|
||||||
|
|
||||||
<Board board="@m"/>
|
<Board board="@m"/>
|
||||||
|
|
||||||
|
@ -8,7 +8,7 @@
|
||||||
{
|
{
|
||||||
BoardID = 0,
|
BoardID = 0,
|
||||||
maxThreads = 10,
|
maxThreads = 10,
|
||||||
Tag = "m",
|
Tag = "e",
|
||||||
Topic = "Main"
|
Topic = "Everything"
|
||||||
};
|
};
|
||||||
}
|
}
|
14
ImageBoardServerApp/Pages/Boards/E.razor
Normal file
14
ImageBoardServerApp/Pages/Boards/E.razor
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
@page "/au/"
|
||||||
|
|
||||||
|
<Board board="@m"/>
|
||||||
|
|
||||||
|
@code {
|
||||||
|
|
||||||
|
private BoardData m { get; set; } = new()
|
||||||
|
{
|
||||||
|
BoardID = 0,
|
||||||
|
maxThreads = 10,
|
||||||
|
Tag = "au",
|
||||||
|
Topic = "Autism"
|
||||||
|
};
|
||||||
|
}
|
|
@ -13,5 +13,5 @@
|
||||||
margin-right: auto;
|
margin-right: auto;
|
||||||
width: 500px;
|
width: 500px;
|
||||||
max-height: 500px;
|
max-height: 500px;
|
||||||
max-width: 90vw !important;
|
max-width: 80vw !important;
|
||||||
}
|
}
|
|
@ -1,4 +1,5 @@
|
||||||
@using System.ComponentModel.DataAnnotations
|
@using System.ComponentModel.DataAnnotations
|
||||||
|
@using System.Text.RegularExpressions
|
||||||
@using ImageBoardServerApp.Auth
|
@using ImageBoardServerApp.Auth
|
||||||
@using ImageBoardServerApp.Data
|
@using ImageBoardServerApp.Data
|
||||||
@using ImageBoardServerApp.Data.Repository
|
@using ImageBoardServerApp.Data.Repository
|
||||||
|
@ -28,14 +29,33 @@
|
||||||
<div class="threadTextContainer">
|
<div class="threadTextContainer">
|
||||||
@foreach (string s in @comment.Content.Split("\n"))
|
@foreach (string s in @comment.Content.Split("\n"))
|
||||||
{
|
{
|
||||||
@if (s.StartsWith(">"))
|
var className = "";
|
||||||
|
@if (s.StartsWith(">") && !Regex.IsMatch(s, "^>{2,}"))
|
||||||
{
|
{
|
||||||
<span class="threadText greenText">@s</span>
|
className = "greenText";
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
<span class='threadText'>@s</span>
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
<span class='threadText @className'>
|
||||||
|
@foreach (string line in s.Split(" "))
|
||||||
|
{
|
||||||
|
var className2 = "";
|
||||||
|
@if (@Regex.IsMatch(line, ">>\\d+"))
|
||||||
|
{
|
||||||
|
className2 = "redText";
|
||||||
|
<a href="/@comment.Board/@comment.PostID/@Regex.Match(s, ">>(\\d+)").Value.Substring(2)" class="threadMsg @className2">
|
||||||
|
@line
|
||||||
|
</a>
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
<span class="threadMsg">
|
||||||
|
@line
|
||||||
|
</span>
|
||||||
|
}
|
||||||
|
<span> </span>
|
||||||
|
|
||||||
|
}
|
||||||
|
</span>
|
||||||
}
|
}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -59,7 +79,7 @@
|
||||||
var user = await cauthStateProvder.GetAuthenticationStateAsync();
|
var user = await cauthStateProvder.GetAuthenticationStateAsync();
|
||||||
var usr = user.User;
|
var usr = user.User;
|
||||||
UserData foundusr = await UsersRepository.getUserByEmailAsync(usr.Identity.Name);
|
UserData foundusr = await UsersRepository.getUserByEmailAsync(usr.Identity.Name);
|
||||||
if (foundusr.PermissionInteger >= 50 || comment.UserID == foundusr.UserID)
|
if (foundusr.Role != "User" || comment.UserID == foundusr.UserID)
|
||||||
{
|
{
|
||||||
await TheManager.deleteComment(comment);
|
await TheManager.deleteComment(comment);
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,6 +16,11 @@
|
||||||
color: #339305;
|
color: #339305;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.redText {
|
||||||
|
color: #a91e1e;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
.threadHeader{
|
.threadHeader{
|
||||||
text-align: left;
|
text-align: left;
|
||||||
}
|
}
|
||||||
|
@ -53,7 +58,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
.threadText{
|
.threadText{
|
||||||
display: grid;
|
display: block;
|
||||||
}
|
}
|
||||||
|
|
||||||
.threadTextContainer{
|
.threadTextContainer{
|
||||||
|
|
|
@ -98,6 +98,14 @@
|
||||||
foundusr.lastActionTimeStamp = DateTimeOffset.Now.ToUnixTimeMilliseconds();
|
foundusr.lastActionTimeStamp = DateTimeOffset.Now.ToUnixTimeMilliseconds();
|
||||||
await UsersRepository.updateUserAsync(foundusr);
|
await UsersRepository.updateUserAsync(foundusr);
|
||||||
|
|
||||||
|
PostData updatedPost = await PostsRepository.getPostByIdAsync(post.PostID);
|
||||||
|
if (updatedPost.IsLocked)
|
||||||
|
{
|
||||||
|
hasErr = true;
|
||||||
|
postErr = "This Post is locked.";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
bool hasImage = selectedFile != null;
|
bool hasImage = selectedFile != null;
|
||||||
|
|
||||||
CommentData commentToCreate;
|
CommentData commentToCreate;
|
||||||
|
|
|
@ -146,7 +146,9 @@
|
||||||
Content = postContent,
|
Content = postContent,
|
||||||
Interactions = 0,
|
Interactions = 0,
|
||||||
CreatedAt = DateTimeOffset.Now.ToUnixTimeMilliseconds(),
|
CreatedAt = DateTimeOffset.Now.ToUnixTimeMilliseconds(),
|
||||||
Board = board.Tag
|
Board = board.Tag,
|
||||||
|
IsLocked = false,
|
||||||
|
IsSticky = false
|
||||||
};
|
};
|
||||||
int postId = await PostsRepository.createPostAsync(postToPost);
|
int postId = await PostsRepository.createPostAsync(postToPost);
|
||||||
if (postId != -1)
|
if (postId != -1)
|
||||||
|
|
|
@ -1,16 +1,19 @@
|
||||||
@using System.ComponentModel.DataAnnotations
|
@using System.ComponentModel.DataAnnotations
|
||||||
|
@using System.Text.RegularExpressions
|
||||||
@using ImageBoardServerApp.Auth
|
@using ImageBoardServerApp.Auth
|
||||||
@using ImageBoardServerApp.Data
|
@using ImageBoardServerApp.Data
|
||||||
@using ImageBoardServerApp.Data.Repository
|
@using ImageBoardServerApp.Data.Repository
|
||||||
|
@using Microsoft.AspNetCore.Html
|
||||||
@inject AuthenticationStateProvider authStateProvider
|
@inject AuthenticationStateProvider authStateProvider
|
||||||
@inject NavigationManager navigationManager;
|
@inject NavigationManager navigationManager;
|
||||||
|
|
||||||
|
|
||||||
<div class="threadHeader">
|
<div class="threadHeader">
|
||||||
@if (showOpenThread)
|
@if (showOpenThread)
|
||||||
{
|
{
|
||||||
<span>[</span>
|
<span>[</span>
|
||||||
<a class="toggleOpened" onclick="@ToggleOpened">@toggleText</a>
|
<a class="toggleOpened" onclick="@ToggleOpened">@toggleText</a>
|
||||||
<span>]</span>
|
<span>] </span>
|
||||||
}
|
}
|
||||||
<span class="title">@post.Title</span>
|
<span class="title">@post.Title</span>
|
||||||
<span class="name">@post.Username </span>
|
<span class="name">@post.Username </span>
|
||||||
|
@ -27,6 +30,14 @@
|
||||||
<span>(@value)</span>
|
<span>(@value)</span>
|
||||||
</Authorized>
|
</Authorized>
|
||||||
</AuthorizeView>
|
</AuthorizeView>
|
||||||
|
@if (post.IsSticky)
|
||||||
|
{
|
||||||
|
<img src="img/static/sys/sticky.png" alt="Stickied"/>
|
||||||
|
}
|
||||||
|
@if (post.IsLocked)
|
||||||
|
{
|
||||||
|
<img src="img/static/sys/locked.png" alt="Locked"/>
|
||||||
|
}
|
||||||
</div>
|
</div>
|
||||||
@if (opened)
|
@if (opened)
|
||||||
{
|
{
|
||||||
|
@ -44,18 +55,31 @@
|
||||||
<div class="threadTextContainer">
|
<div class="threadTextContainer">
|
||||||
@foreach (string s in @post.Content.Split("\n"))
|
@foreach (string s in @post.Content.Split("\n"))
|
||||||
{
|
{
|
||||||
@if (@s.StartsWith(">"))
|
var className = "";
|
||||||
|
@if (s.StartsWith(">") && !Regex.IsMatch(s, "^>{2,}"))
|
||||||
{
|
{
|
||||||
<span class="threadText greenText">@s</span>
|
className = "greenText";
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
<span class='threadText'>@s</span>
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
<span class='threadText @className'>@s </span>
|
||||||
}
|
}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="threadFooter">
|
<div class="threadFooter">
|
||||||
|
<div class="sticky">
|
||||||
|
|
||||||
|
</div>
|
||||||
|
<AuthorizeView Roles="Admin, Mod">
|
||||||
|
<Authorized>
|
||||||
|
<span>[</span>
|
||||||
|
<a onclick="@stickyMe()" href="javascript:void(0)">Sticky</a>
|
||||||
|
<span>]</span>
|
||||||
|
<span>[</span>
|
||||||
|
<a onclick="@lockMe()" href="javascript:void(0)">Lock</a>
|
||||||
|
<span>]</span>
|
||||||
|
</Authorized>
|
||||||
|
</AuthorizeView>
|
||||||
|
|
||||||
<span>[</span>
|
<span>[</span>
|
||||||
<a @onclick="@deletePost" href="javascript:void(0)">Delete</a>
|
<a @onclick="@deletePost" href="javascript:void(0)">Delete</a>
|
||||||
<span>]</span>
|
<span>]</span>
|
||||||
|
@ -80,6 +104,19 @@
|
||||||
|
|
||||||
|
|
||||||
@code {
|
@code {
|
||||||
|
|
||||||
|
private async Task lockMe()
|
||||||
|
{
|
||||||
|
post.IsLocked = !post.IsLocked;
|
||||||
|
await PostsRepository.updatePostAsync(post);
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task stickyMe()
|
||||||
|
{
|
||||||
|
post.IsSticky = !post.IsSticky;
|
||||||
|
await PostsRepository.updatePostAsync(post);
|
||||||
|
}
|
||||||
|
|
||||||
private static DateTime getTimeFromUnix(double javaTimeStamp)
|
private static DateTime getTimeFromUnix(double javaTimeStamp)
|
||||||
{
|
{
|
||||||
var dateTime = new DateTime(1970, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc);
|
var dateTime = new DateTime(1970, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc);
|
||||||
|
@ -94,13 +131,14 @@
|
||||||
var user = await cauthStateProvder.GetAuthenticationStateAsync();
|
var user = await cauthStateProvder.GetAuthenticationStateAsync();
|
||||||
var usr = user.User;
|
var usr = user.User;
|
||||||
UserData foundusr = await UsersRepository.getUserByEmailAsync(usr.Identity.Name);
|
UserData foundusr = await UsersRepository.getUserByEmailAsync(usr.Identity.Name);
|
||||||
if (foundusr.PermissionInteger >= 50 || post.UserID == foundusr.UserID)
|
if (foundusr.Role != "User" || post.UserID == foundusr.UserID)
|
||||||
{
|
{
|
||||||
await TheManager.deleteThread(post);
|
await TheManager.deleteThread(post);
|
||||||
navigationManager.NavigateTo($"/{boardTag}");
|
navigationManager.NavigateTo($"/{boardTag}");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private bool opened = true;
|
private bool opened = true;
|
||||||
|
|
||||||
private string toggleText = "-";
|
private string toggleText = "-";
|
||||||
|
|
|
@ -61,9 +61,13 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
.threadText{
|
.threadText{
|
||||||
display: grid;
|
display: block;
|
||||||
}
|
}
|
||||||
|
|
||||||
.threadTextContainer{
|
.threadTextContainer{
|
||||||
margin: 0;
|
margin: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.threadMsg {
|
||||||
|
display: inline-block;
|
||||||
|
}
|
|
@ -5,7 +5,6 @@
|
||||||
<span>@user.Comments.Count Comments | </span>
|
<span>@user.Comments.Count Comments | </span>
|
||||||
<span>@user.SubmittedReports.Count Reports submitted | </span>
|
<span>@user.SubmittedReports.Count Reports submitted | </span>
|
||||||
<span>@user.RecivedReports.Count Reports recived | </span>
|
<span>@user.RecivedReports.Count Reports recived | </span>
|
||||||
<a onclick="@editF()" href="javascript:void(0)">Edit</a>
|
|
||||||
<span> </span>
|
<span> </span>
|
||||||
<select name="role" id="role" @bind="@selectedRole">
|
<select name="role" id="role" @bind="@selectedRole">
|
||||||
<option value="User">User</option>
|
<option value="User">User</option>
|
||||||
|
@ -19,7 +18,6 @@
|
||||||
|
|
||||||
@code {
|
@code {
|
||||||
private string selectedRole;
|
private string selectedRole;
|
||||||
private bool edit = false;
|
|
||||||
|
|
||||||
[Parameter]
|
[Parameter]
|
||||||
[Required]
|
[Required]
|
||||||
|
@ -27,15 +25,9 @@
|
||||||
|
|
||||||
protected override async Task OnInitializedAsync()
|
protected override async Task OnInitializedAsync()
|
||||||
{
|
{
|
||||||
edit = false;
|
|
||||||
selectedRole = user.Role;
|
selectedRole = user.Role;
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task editF()
|
|
||||||
{
|
|
||||||
edit = !edit;
|
|
||||||
}
|
|
||||||
|
|
||||||
private async Task updateRole()
|
private async Task updateRole()
|
||||||
{
|
{
|
||||||
user.Role = selectedRole;
|
user.Role = selectedRole;
|
||||||
|
|
|
@ -27,8 +27,8 @@
|
||||||
</NavLink>
|
</NavLink>
|
||||||
</div>
|
</div>
|
||||||
<div class="nav-item px-3">
|
<div class="nav-item px-3">
|
||||||
<NavLink class="nav-link" href="m">
|
<NavLink class="nav-link" href="e">
|
||||||
<span class="oi oi-list-rich" aria-hidden="true"></span> /m/ - Main
|
<span class="oi oi-list-rich" aria-hidden="true"></span> /e/ - Everything
|
||||||
</NavLink>
|
</NavLink>
|
||||||
</div>
|
</div>
|
||||||
<div class="nav-item px-3">
|
<div class="nav-item px-3">
|
||||||
|
@ -46,6 +46,11 @@
|
||||||
<span class="oi oi-list-rich" aria-hidden="true"></span> /vg/ - Video Games
|
<span class="oi oi-list-rich" aria-hidden="true"></span> /vg/ - Video Games
|
||||||
</NavLink>
|
</NavLink>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="nav-item px-3">
|
||||||
|
<NavLink class="nav-link" href="au">
|
||||||
|
<span class="oi oi-list-rich" aria-hidden="true"></span> /au/ - Autism
|
||||||
|
</NavLink>
|
||||||
|
</div>
|
||||||
</nav>
|
</nav>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
Binary file not shown.
Before Width: | Height: | Size: 76 KiB After Width: | Height: | Size: 77 KiB |
Binary file not shown.
Before Width: | Height: | Size: 168 KiB |
Binary file not shown.
Before Width: | Height: | Size: 248 KiB After Width: | Height: | Size: 248 KiB |
Loading…
Reference in a new issue