import from other repo
This commit is contained in:
commit
d8a81fdfc0
53 changed files with 2243 additions and 0 deletions
44
ImageBoardServerApp/Shared/Components/Board.razor
Normal file
44
ImageBoardServerApp/Shared/Components/Board.razor
Normal file
|
@ -0,0 +1,44 @@
|
|||
@using System.ComponentModel.DataAnnotations
|
||||
@using ImageBoardServerApp.Data
|
||||
@using ImageBoardServerApp.Data.Repository
|
||||
|
||||
<h3>@board.Topic Board</h3>
|
||||
|
||||
<PageTitle>/@board.Tag/ - @board.Topic - BulletBoard</PageTitle>
|
||||
|
||||
<PostForm board="@board"/>
|
||||
|
||||
<br/>
|
||||
<br/>
|
||||
|
||||
|
||||
<h3>Threads</h3>
|
||||
<br/>
|
||||
|
||||
@if (posts.Any())
|
||||
{
|
||||
@foreach(var post in posts)
|
||||
{
|
||||
<Post post="@post"></Post>
|
||||
<hr/>
|
||||
}
|
||||
}
|
||||
<PageFooter/>
|
||||
|
||||
<!--Admin -->
|
||||
<!--Moderator -->
|
||||
<!--Janitor -->
|
||||
|
||||
@code {
|
||||
|
||||
private List<PostData> posts;
|
||||
|
||||
protected override async Task OnInitializedAsync()
|
||||
{
|
||||
posts = await PostsRepository.getPostsByBoardAsync(board.Tag);
|
||||
}
|
||||
|
||||
[Parameter]
|
||||
[Required]
|
||||
public BoardData board { get; set; }
|
||||
}
|
6
ImageBoardServerApp/Shared/Components/PageFooter.razor
Normal file
6
ImageBoardServerApp/Shared/Components/PageFooter.razor
Normal file
|
@ -0,0 +1,6 @@
|
|||
<br/>
|
||||
<br/>
|
||||
<span class="footerwarning">All trademarks and copyrights on this page are owned by their respective parties. Images uploaded are the responsibility of the Poster. Comments are owned by the Poster.</span>
|
||||
@code {
|
||||
|
||||
}
|
|
@ -0,0 +1,6 @@
|
|||
.footerwarning{
|
||||
display: block;
|
||||
text-align: center;
|
||||
font-size: 10px;
|
||||
color: #c6cfd0;
|
||||
}
|
71
ImageBoardServerApp/Shared/Components/Post.razor
Normal file
71
ImageBoardServerApp/Shared/Components/Post.razor
Normal file
|
@ -0,0 +1,71 @@
|
|||
@using System.ComponentModel.DataAnnotations
|
||||
@using ImageBoardServerApp.Data
|
||||
|
||||
<div class="threadHeader">
|
||||
<span>[</span>
|
||||
<a class="toggleOpened" onclick="@ToggleOpened">@toggleText</a>
|
||||
<span>]</span>
|
||||
<span class="title">@post.Title</span>
|
||||
<span class="name">@post.Username</span>
|
||||
<span class="date">@getTimeFromUnix(post.CreatedAt)</span>
|
||||
<span class="post-id">No.@post.PostID</span>
|
||||
</div>
|
||||
@if (opened)
|
||||
{
|
||||
<div class="threadContent">
|
||||
<div class="threadImage">
|
||||
<!-- TODO: Make Images Required. -->
|
||||
@if (@post.Image != null)
|
||||
{
|
||||
<img src="@($"data:image/jpeg;base64,{Convert.ToBase64String(@post.Image.Image)}")" alt="No Image found" />
|
||||
}
|
||||
else
|
||||
{
|
||||
<span>[No Image]</span>
|
||||
}
|
||||
</div>
|
||||
<div class="threadTextContainer">
|
||||
@foreach (string s in @post.Content.Split("\n"))
|
||||
{
|
||||
<span class='threadText'>@s</span>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
<div class="threadFooter">
|
||||
<!--<RadzenButton class="bump" Text="bump"></RadzenButton> -->
|
||||
<span>[</span>
|
||||
<a class="report" href="/report/@post.Board/@post.PostID" target="_blank">Report</a>
|
||||
<span>]</span>
|
||||
<span>[</span>
|
||||
<a class="openThread" href="/@post.Board/@post.PostID" target="_blank">(@post.Interactions) Open Thread</a>
|
||||
<span>]</span>
|
||||
</div>
|
||||
}
|
||||
|
||||
|
||||
|
||||
@code {
|
||||
|
||||
|
||||
|
||||
private static DateTime getTimeFromUnix(double javaTimeStamp)
|
||||
{
|
||||
var dateTime = new DateTime(1970, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc);
|
||||
dateTime = dateTime.AddMilliseconds( javaTimeStamp ).ToLocalTime();
|
||||
return dateTime;
|
||||
}
|
||||
|
||||
private bool opened = true;
|
||||
|
||||
private string toggleText = "-";
|
||||
|
||||
private void ToggleOpened()
|
||||
{
|
||||
opened = !opened;
|
||||
toggleText = opened ? "-" : "+";
|
||||
}
|
||||
|
||||
[Parameter]
|
||||
[Required]
|
||||
public PostData post { get; set; }
|
||||
}
|
57
ImageBoardServerApp/Shared/Components/Post.razor.css
Normal file
57
ImageBoardServerApp/Shared/Components/Post.razor.css
Normal file
|
@ -0,0 +1,57 @@
|
|||
.toggleOpened{
|
||||
color: #0a58ca;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.toggleOpened:hover{
|
||||
color: #0a58ca; !important;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.title{
|
||||
color: #1e5aaf;
|
||||
}
|
||||
|
||||
.name{
|
||||
color: #339305;
|
||||
}
|
||||
|
||||
.threadHeader{
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.threadFooter{
|
||||
text-align: right; !important;
|
||||
align-self: end; !important;
|
||||
}
|
||||
|
||||
.threadContent{
|
||||
text-align: left;
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.threadImage{
|
||||
margin: 6px;
|
||||
max-width: 500px;
|
||||
max-height: 500px;
|
||||
padding: 5px;
|
||||
}
|
||||
|
||||
.threadImage img{
|
||||
max-width:150px;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.threadImage img:hover{
|
||||
transform: scale(3);
|
||||
/*max-width:500px;
|
||||
width: 100%; */
|
||||
}
|
||||
|
||||
.threadText{
|
||||
display: grid;
|
||||
}
|
||||
|
||||
.threadTextContainer{
|
||||
margin: 0;
|
||||
}
|
139
ImageBoardServerApp/Shared/Components/PostForm.razor
Normal file
139
ImageBoardServerApp/Shared/Components/PostForm.razor
Normal file
|
@ -0,0 +1,139 @@
|
|||
@using Radzen
|
||||
@using System.ComponentModel.DataAnnotations
|
||||
@using System.IO.Pipelines
|
||||
@using System.Net.Mime
|
||||
@using System.Reflection
|
||||
@using System.Runtime.CompilerServices
|
||||
@using ImageBoardServerApp.Data
|
||||
@using ImageBoardServerApp.Data.Repository
|
||||
|
||||
@inject NavigationManager NavigationManager
|
||||
|
||||
<div>
|
||||
<span>[</span>
|
||||
<a class="toggleOpened" onclick="@ToggleOpened">@toggleText</a>
|
||||
<span>]</span>
|
||||
</div>
|
||||
@if (opened)
|
||||
{
|
||||
<div class="pd centered">
|
||||
<span>Post to /@board.Tag/ - @board.Topic</span>
|
||||
|
||||
<div class="pd centered marg">
|
||||
<RadzenTextBox Placeholder="Username (Anonymous)" MaxLength="15" Change=@(args => OnChange(args, "username")) Class="w-100"/>
|
||||
</div>
|
||||
|
||||
<div class="pd centered marg">
|
||||
<RadzenTextBox Placeholder="Title" MaxLength="20" Change=@(args => OnChange(args, "title")) Class="w-100"/>
|
||||
</div>
|
||||
|
||||
<div class="pd centered marg">
|
||||
<RadzenTextArea Placeholder="Content..." @bind-Value="@postContent" Cols="30" Rows="6" Change=@(args => OnChange(args, "Content")) Class="w-100"/>
|
||||
</div>
|
||||
|
||||
<div class="pd centered marg">
|
||||
<InputFile OnChange="@SingleUpload" type="file" accept="image/*"/>
|
||||
<RadzenButton class="pd" Click="@onPostClick" Text="Post!"></RadzenButton>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
}
|
||||
|
||||
|
||||
@code {
|
||||
|
||||
private bool opened = false;
|
||||
|
||||
private string toggleText = "Open Post Formula";
|
||||
|
||||
private void ToggleOpened()
|
||||
{
|
||||
opened = !opened;
|
||||
toggleText = opened ? "Close Post Formula" : "Open Post Formula";
|
||||
}
|
||||
|
||||
[Parameter]
|
||||
[Required]
|
||||
public BoardData board { get; set; } = new BoardData();
|
||||
|
||||
string postUsername = "Anonymous";
|
||||
string postTitle = "";
|
||||
string postContent = "";
|
||||
|
||||
void OnChange(string value, string name)
|
||||
{
|
||||
switch (name)
|
||||
{
|
||||
case "title":
|
||||
postTitle = value;
|
||||
break;
|
||||
case "username":
|
||||
postUsername = value;
|
||||
break;
|
||||
case "content":
|
||||
postContent = value;
|
||||
break;
|
||||
default:
|
||||
Console.WriteLine("not found.");
|
||||
break;
|
||||
}
|
||||
Console.WriteLine($"Smth changed!: {value}");
|
||||
}
|
||||
|
||||
private async Task SingleUpload(InputFileChangeEventArgs e)
|
||||
{
|
||||
MemoryStream ms = new MemoryStream();
|
||||
await e.File.OpenReadStream().CopyToAsync(ms);
|
||||
var bytes = ms.ToArray();
|
||||
image = bytes;
|
||||
Console.WriteLine("File has been selected!");
|
||||
ms.Close();
|
||||
}
|
||||
|
||||
private Byte[] image;
|
||||
|
||||
private async Task onPostClick()
|
||||
{
|
||||
var userToCreate = new UserData
|
||||
{
|
||||
Ipv4Address = "192.168.178.101",
|
||||
Banned = false,
|
||||
lastActionTimeStamp = DateTime.Now.Millisecond
|
||||
};
|
||||
int userID = await UsersRepository.createUserAsync(userToCreate);
|
||||
|
||||
//TODO Add check if data is image
|
||||
|
||||
|
||||
var imageToUpload = new ImageData
|
||||
{
|
||||
Board = board.Tag,
|
||||
Image = image
|
||||
};
|
||||
int imageID = await ImagesRepository.createImageAsync(imageToUpload);
|
||||
var postToPost = new PostData
|
||||
{
|
||||
UserID = userID,
|
||||
ImageID = imageID,
|
||||
Username = postUsername,
|
||||
Title = postTitle,
|
||||
Content = postContent,
|
||||
Interactions = "",
|
||||
CreatedAt = DateTimeOffset.Now.ToUnixTimeMilliseconds(),
|
||||
Board = board.Tag
|
||||
};
|
||||
int postId = await PostsRepository.createPostAsync(postToPost);
|
||||
if (postId != -1)
|
||||
{
|
||||
//Open post successfull
|
||||
NavigationManager.NavigateTo("/SuccessfulPost");
|
||||
Console.WriteLine("Post created");
|
||||
}
|
||||
else
|
||||
{
|
||||
//Open post unsucessfull
|
||||
NavigationManager.NavigateTo("/UnSuccessfulPost");
|
||||
Console.WriteLine("Shit sucks and did not work.");
|
||||
}
|
||||
}
|
||||
}
|
23
ImageBoardServerApp/Shared/Components/PostForm.razor.css
Normal file
23
ImageBoardServerApp/Shared/Components/PostForm.razor.css
Normal file
|
@ -0,0 +1,23 @@
|
|||
.toggleOpened{
|
||||
color: #0a58ca;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.toggleOpened:hover{
|
||||
color: #0a58ca; !important;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.centered {
|
||||
text-align: center;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.pd {
|
||||
padding: 5px;
|
||||
}
|
||||
|
||||
.marg{
|
||||
margin: 2px
|
||||
}
|
20
ImageBoardServerApp/Shared/MainLayout.razor
Normal file
20
ImageBoardServerApp/Shared/MainLayout.razor
Normal file
|
@ -0,0 +1,20 @@
|
|||
@inherits LayoutComponentBase
|
||||
|
||||
<PageTitle>BulletBoard</PageTitle>
|
||||
|
||||
<div class="page">
|
||||
<div class="sidebar">
|
||||
<NavMenu/>
|
||||
</div>
|
||||
|
||||
<main>
|
||||
<div class="top-row px-4">
|
||||
<a href="/faq">[FAQ]</a>
|
||||
<a href="/rules">[Rules]</a>
|
||||
</div>
|
||||
|
||||
<article class="content px-4">
|
||||
@Body
|
||||
</article>
|
||||
</main>
|
||||
</div>
|
93
ImageBoardServerApp/Shared/MainLayout.razor.css
Normal file
93
ImageBoardServerApp/Shared/MainLayout.razor.css
Normal file
|
@ -0,0 +1,93 @@
|
|||
.page {
|
||||
position: relative;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
main {
|
||||
flex: 1;
|
||||
background-color: #1b1d1e;
|
||||
color: #dcdcdc;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.sidebar {
|
||||
background-image: linear-gradient(180deg, rgb(5, 39, 103) 0%, #3a0647 70%);
|
||||
}
|
||||
|
||||
.top-row {
|
||||
|
||||
border-bottom: 1px solid #d6d5d5;
|
||||
justify-content: flex-end;
|
||||
height: 3.5rem;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
background-color: #1f2223;
|
||||
color: #dcdcdc;
|
||||
}
|
||||
|
||||
.top-row a {
|
||||
text-decoration: none;
|
||||
color: white;
|
||||
padding: 3px;
|
||||
}
|
||||
|
||||
.top-row ::deep a, .top-row ::deep .btn-link {
|
||||
white-space: nowrap;
|
||||
margin-left: 1.5rem;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.top-row ::deep a:hover, .top-row ::deep .btn-link:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
.top-row ::deep a:first-child {
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
@media (max-width: 640.98px) {
|
||||
.top-row:not(.auth) {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.top-row.auth {
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.top-row ::deep a, .top-row ::deep .btn-link {
|
||||
margin-left: 0;
|
||||
}
|
||||
}
|
||||
|
||||
@media (min-width: 641px) {
|
||||
.page {
|
||||
flex-direction: row;
|
||||
}
|
||||
|
||||
.sidebar {
|
||||
width: 250px;
|
||||
height: 100vh;
|
||||
position: sticky;
|
||||
top: 0;
|
||||
}
|
||||
|
||||
.top-row {
|
||||
position: sticky;
|
||||
top: 0;
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
.top-row.auth ::deep a:first-child {
|
||||
flex: 1;
|
||||
text-align: right;
|
||||
width: 0;
|
||||
}
|
||||
|
||||
.top-row, article {
|
||||
padding-left: 2rem !important;
|
||||
padding-right: 1.5rem !important;
|
||||
}
|
||||
}
|
35
ImageBoardServerApp/Shared/NavMenu.razor
Normal file
35
ImageBoardServerApp/Shared/NavMenu.razor
Normal file
|
@ -0,0 +1,35 @@
|
|||
<div class="top-row ps-3 navbar navbar-dark">
|
||||
<div class="container-fluid">
|
||||
<a class="navbar-brand" href="">ImageBoard</a>
|
||||
<button title="Navigation menu" class="navbar-toggler" @onclick="ToggleNavMenu">
|
||||
<span class="navbar-toggler-icon"></span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="@NavMenuCssClass" @onclick="ToggleNavMenu">
|
||||
<nav class="flex-column">
|
||||
<div class="nav-item px-3">
|
||||
<NavLink class="nav-link" href="" Match="NavLinkMatch.All">
|
||||
<span class="oi oi-home" aria-hidden="true"></span> Home
|
||||
</NavLink>
|
||||
</div>
|
||||
<div class="nav-item px-3">
|
||||
<NavLink class="nav-link" href="b">
|
||||
<span class="oi oi-list-rich" aria-hidden="true"></span> /b/ - Random
|
||||
</NavLink>
|
||||
</div>
|
||||
</nav>
|
||||
</div>
|
||||
|
||||
@code {
|
||||
private bool collapseNavMenu = true;
|
||||
|
||||
private string? NavMenuCssClass => collapseNavMenu ? "collapse" : null;
|
||||
|
||||
private void ToggleNavMenu()
|
||||
{
|
||||
collapseNavMenu = !collapseNavMenu;
|
||||
}
|
||||
|
||||
}
|
62
ImageBoardServerApp/Shared/NavMenu.razor.css
Normal file
62
ImageBoardServerApp/Shared/NavMenu.razor.css
Normal file
|
@ -0,0 +1,62 @@
|
|||
.navbar-toggler {
|
||||
background-color: rgba(255, 255, 255, 0.1);
|
||||
}
|
||||
|
||||
.top-row {
|
||||
height: 3.5rem;
|
||||
background-color: rgba(0, 0, 0, 0.4);
|
||||
}
|
||||
|
||||
.navbar-brand {
|
||||
font-size: 1.1rem;
|
||||
}
|
||||
|
||||
.oi {
|
||||
width: 2rem;
|
||||
font-size: 1.1rem;
|
||||
vertical-align: text-top;
|
||||
top: -2px;
|
||||
}
|
||||
|
||||
.nav-item {
|
||||
font-size: 0.9rem;
|
||||
padding-bottom: 0.5rem;
|
||||
}
|
||||
|
||||
.nav-item:first-of-type {
|
||||
padding-top: 1rem;
|
||||
}
|
||||
|
||||
.nav-item:last-of-type {
|
||||
padding-bottom: 1rem;
|
||||
}
|
||||
|
||||
.nav-item ::deep a {
|
||||
color: #d7d7d7;
|
||||
border-radius: 4px;
|
||||
height: 3rem;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
line-height: 3rem;
|
||||
}
|
||||
|
||||
.nav-item ::deep a.active {
|
||||
background-color: rgba(255, 255, 255, 0.25);
|
||||
color: white;
|
||||
}
|
||||
|
||||
.nav-item ::deep a:hover {
|
||||
background-color: rgba(255, 255, 255, 0.1);
|
||||
color: white;
|
||||
}
|
||||
|
||||
@media (min-width: 500px) {
|
||||
.navbar-toggler {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.collapse {
|
||||
/* Never collapse the sidebar for wide screens */
|
||||
display: block;
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue