✨ Post web view
This commit is contained in:
@ -26,6 +26,7 @@
|
|||||||
<PackageReference Include="HtmlAgilityPack" Version="1.12.1" />
|
<PackageReference Include="HtmlAgilityPack" Version="1.12.1" />
|
||||||
<PackageReference Include="Livekit.Server.Sdk.Dotnet" Version="1.0.8" />
|
<PackageReference Include="Livekit.Server.Sdk.Dotnet" Version="1.0.8" />
|
||||||
<PackageReference Include="MailKit" Version="4.11.0" />
|
<PackageReference Include="MailKit" Version="4.11.0" />
|
||||||
|
<PackageReference Include="Markdig" Version="0.41.3" />
|
||||||
<PackageReference Include="MaxMind.GeoIP2" Version="5.3.0" />
|
<PackageReference Include="MaxMind.GeoIP2" Version="5.3.0" />
|
||||||
<PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="9.0.4" />
|
<PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="9.0.4" />
|
||||||
<PackageReference Include="Microsoft.AspNetCore.OpenApi" Version="9.0.2" />
|
<PackageReference Include="Microsoft.AspNetCore.OpenApi" Version="9.0.2" />
|
||||||
|
@ -1,17 +1,62 @@
|
|||||||
@page "/posts/{PostId:guid}"
|
@page "/posts/{PostId:guid}"
|
||||||
@model DysonNetwork.Sphere.Pages.Posts.PostDetailModel
|
@model DysonNetwork.Sphere.Pages.Posts.PostDetailModel
|
||||||
|
@using Markdig
|
||||||
@{
|
@{
|
||||||
ViewData["Title"] = Model.Post?.Title + " | Solar Network";
|
ViewData["Title"] = Model.Post?.Title + " | Solar Network";
|
||||||
|
var imageUrl = Model.Post?.Attachments?.FirstOrDefault(a => a.MimeType.StartsWith("image/"))?.Id;
|
||||||
|
}
|
||||||
|
|
||||||
|
@section Head {
|
||||||
|
<meta property="og:title" content="@Model.Post?.Title" />
|
||||||
|
<meta property="og:type" content="article" />
|
||||||
|
@if (imageUrl != null)
|
||||||
|
{
|
||||||
|
<meta property="og:image" content="/api/files/@imageUrl" />
|
||||||
|
}
|
||||||
|
<meta property="og:url" content="@Request.Scheme://@Request.Host@Request.Path" />
|
||||||
|
<meta property="og:description" content="@Model.Post?.Description" />
|
||||||
}
|
}
|
||||||
|
|
||||||
<div class="container mx-auto p-4">
|
<div class="container mx-auto p-4">
|
||||||
@if (Model.Post != null)
|
@if (Model.Post != null)
|
||||||
{
|
{
|
||||||
<h1 class="text-3xl font-bold mb-4">@Model.Post.Title</h1>
|
<h1 class="text-3xl font-bold mb-4">@Model.Post.Title</h1>
|
||||||
<p class="text-gray-600 mb-2">Created at: @Model.Post.CreatedAt</p>
|
<p class="text-gray-600 mb-2">
|
||||||
<div class="prose lg:prose-xl">
|
Created at: @Model.Post.CreatedAt
|
||||||
<p>@Model.Post.Content</p>
|
@if (Model.Post.Publisher?.Account != null)
|
||||||
|
{
|
||||||
|
<span>by <a href="#" class="text-blue-500">@@@Model.Post.Publisher.Name</a></span>
|
||||||
|
}
|
||||||
|
</p>
|
||||||
|
<div class="prose lg:prose-xl mb-4">
|
||||||
|
@Html.Raw(Markdown.ToHtml(Model.Post.Content ?? string.Empty))
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
@if (Model.Post.Attachments != null && Model.Post.Attachments.Any())
|
||||||
|
{
|
||||||
|
<h2 class="text-2xl font-bold mb-2">Attachments</h2>
|
||||||
|
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4">
|
||||||
|
@foreach (var attachment in Model.Post.Attachments)
|
||||||
|
{
|
||||||
|
<div class="border p-2 rounded-md">
|
||||||
|
@if (attachment.MimeType != null && attachment.MimeType.StartsWith("image/"))
|
||||||
|
{
|
||||||
|
<img src="/api/files/@attachment.Id" alt="@attachment.Name" class="w-full h-auto object-cover mb-2" />
|
||||||
|
}
|
||||||
|
else if (attachment.MimeType != null && attachment.MimeType.StartsWith("video/"))
|
||||||
|
{
|
||||||
|
<video controls class="w-full h-auto object-cover mb-2">
|
||||||
|
<source src="/api/files/@attachment.Id" type="@attachment.MimeType">
|
||||||
|
Your browser does not support the video tag.
|
||||||
|
</video>
|
||||||
|
}
|
||||||
|
<a href="/api/files/@attachment.Id" target="_blank" class="text-blue-500 hover:underline">
|
||||||
|
@attachment.Name
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -31,6 +31,7 @@ public class PostDetailModel(
|
|||||||
Post = await db.Posts
|
Post = await db.Posts
|
||||||
.Where(e => e.Id == PostId)
|
.Where(e => e.Id == PostId)
|
||||||
.Include(e => e.Publisher)
|
.Include(e => e.Publisher)
|
||||||
|
.ThenInclude(p => p.Account)
|
||||||
.Include(e => e.Tags)
|
.Include(e => e.Tags)
|
||||||
.Include(e => e.Categories)
|
.Include(e => e.Categories)
|
||||||
.FilterWithVisibility(currentUser, userFriends, userPublishers)
|
.FilterWithVisibility(currentUser, userFriends, userPublishers)
|
||||||
|
@ -15,6 +15,8 @@
|
|||||||
href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:opsz,wght,FILL,GRAD@20..48,100..700,0..1,-50..200"
|
href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:opsz,wght,FILL,GRAD@20..48,100..700,0..1,-50..200"
|
||||||
rel="stylesheet"
|
rel="stylesheet"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
|
@await RenderSectionAsync("Head", required: false)
|
||||||
</head>
|
</head>
|
||||||
<body class="h-full bg-base-200">
|
<body class="h-full bg-base-200">
|
||||||
<header class="navbar bg-base-100/35 backdrop-blur-md shadow-xl fixed left-0 right-0 top-0 z-50 px-5">
|
<header class="navbar bg-base-100/35 backdrop-blur-md shadow-xl fixed left-0 right-0 top-0 z-50 px-5">
|
||||||
|
@ -6,6 +6,7 @@
|
|||||||
--font-sans: "Nunito", sans-serif;
|
--font-sans: "Nunito", sans-serif;
|
||||||
--font-mono: "Noto Sans Mono", monospace;
|
--font-mono: "Noto Sans Mono", monospace;
|
||||||
--color-blue-400: oklch(70.7% 0.165 254.624);
|
--color-blue-400: oklch(70.7% 0.165 254.624);
|
||||||
|
--color-blue-500: oklch(62.3% 0.214 259.815);
|
||||||
--color-blue-600: oklch(54.6% 0.245 262.881);
|
--color-blue-600: oklch(54.6% 0.245 262.881);
|
||||||
--color-gray-600: oklch(44.6% 0.03 256.802);
|
--color-gray-600: oklch(44.6% 0.03 256.802);
|
||||||
--color-black: #000;
|
--color-black: #000;
|
||||||
@ -1957,6 +1958,9 @@
|
|||||||
.h-12 {
|
.h-12 {
|
||||||
height: calc(var(--spacing) * 12);
|
height: calc(var(--spacing) * 12);
|
||||||
}
|
}
|
||||||
|
.h-auto {
|
||||||
|
height: auto;
|
||||||
|
}
|
||||||
.h-full {
|
.h-full {
|
||||||
height: 100%;
|
height: 100%;
|
||||||
}
|
}
|
||||||
@ -2179,6 +2183,12 @@
|
|||||||
.stroke-current {
|
.stroke-current {
|
||||||
stroke: currentcolor;
|
stroke: currentcolor;
|
||||||
}
|
}
|
||||||
|
.object-cover {
|
||||||
|
object-fit: cover;
|
||||||
|
}
|
||||||
|
.p-2 {
|
||||||
|
padding: calc(var(--spacing) * 2);
|
||||||
|
}
|
||||||
.p-4 {
|
.p-4 {
|
||||||
padding: calc(var(--spacing) * 4);
|
padding: calc(var(--spacing) * 4);
|
||||||
}
|
}
|
||||||
@ -2293,6 +2303,9 @@
|
|||||||
color: color-mix(in oklab, var(--color-base-content) 70%, transparent);
|
color: color-mix(in oklab, var(--color-base-content) 70%, transparent);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
.text-blue-500 {
|
||||||
|
color: var(--color-blue-500);
|
||||||
|
}
|
||||||
.text-blue-600 {
|
.text-blue-600 {
|
||||||
color: var(--color-blue-600);
|
color: var(--color-blue-600);
|
||||||
}
|
}
|
||||||
@ -2398,6 +2411,13 @@
|
|||||||
--btn-color: var(--color-primary);
|
--btn-color: var(--color-primary);
|
||||||
--btn-fg: var(--color-primary-content);
|
--btn-fg: var(--color-primary-content);
|
||||||
}
|
}
|
||||||
|
.hover\:underline {
|
||||||
|
&:hover {
|
||||||
|
@media (hover: hover) {
|
||||||
|
text-decoration-line: underline;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
.sm\:p-8 {
|
.sm\:p-8 {
|
||||||
@media (width >= 40rem) {
|
@media (width >= 40rem) {
|
||||||
padding: calc(var(--spacing) * 8);
|
padding: calc(var(--spacing) * 8);
|
||||||
@ -2428,6 +2448,11 @@
|
|||||||
width: calc(1/4 * 100%);
|
width: calc(1/4 * 100%);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
.lg\:grid-cols-3 {
|
||||||
|
@media (width >= 64rem) {
|
||||||
|
grid-template-columns: repeat(3, minmax(0, 1fr));
|
||||||
|
}
|
||||||
|
}
|
||||||
.lg\:px-8 {
|
.lg\:px-8 {
|
||||||
@media (width >= 64rem) {
|
@media (width >= 64rem) {
|
||||||
padding-inline: calc(var(--spacing) * 8);
|
padding-inline: calc(var(--spacing) * 8);
|
||||||
|
Reference in New Issue
Block a user