From ef02265ccde07b8907cc15da2a2d748d77390170 Mon Sep 17 00:00:00 2001 From: LittleSheep Date: Sat, 22 Nov 2025 14:16:40 +0800 Subject: [PATCH] :lipstick: Optimize hosted page index --- DysonNetwork.Zone/Pages/About.cshtml | 56 +------- DysonNetwork.Zone/Pages/Index.cshtml | 136 ++++++++++++++++-- DysonNetwork.Zone/Pages/Index.cshtml.cs | 103 ++++++++++++- DysonNetwork.Zone/Pages/Posts.cshtml | 117 +-------------- .../Pages/Shared/_PostItem.cshtml | 89 ++++++++++++ .../Pages/Shared/_PublisherInfo.cshtml | 36 +++++ .../Pages/Shared/_SiteInfo.cshtml | 58 ++++++++ .../Pages/Shared/_UserInfo.cshtml | 70 +++++++++ 8 files changed, 484 insertions(+), 181 deletions(-) create mode 100644 DysonNetwork.Zone/Pages/Shared/_PostItem.cshtml create mode 100644 DysonNetwork.Zone/Pages/Shared/_PublisherInfo.cshtml create mode 100644 DysonNetwork.Zone/Pages/Shared/_SiteInfo.cshtml create mode 100644 DysonNetwork.Zone/Pages/Shared/_UserInfo.cshtml diff --git a/DysonNetwork.Zone/Pages/About.cshtml b/DysonNetwork.Zone/Pages/About.cshtml index fa4705b..08ff425 100644 --- a/DysonNetwork.Zone/Pages/About.cshtml +++ b/DysonNetwork.Zone/Pages/About.cshtml @@ -304,60 +304,6 @@ About the site -
-
-
-
-

Info

- -
-
- - - Name - - @Model.Site.Name -
-
-
-
- - - Slug - - @Model.Site.Slug -
-
-
-
-
- -
- @if (!string.IsNullOrEmpty(Model.Site.Description)) - { -
-
-
-

- Description -

-
- @Model.Site.Description -
-
-
-
- } - -
-
-

Proudly powered by the Solar Network Pages

-

Hosted on the Solar Network

-

Network powered by Cloudflare

-

Therefore, if the site is down, 99% is Cloudflare's fault

-
-
-
-
+ } diff --git a/DysonNetwork.Zone/Pages/Index.cshtml b/DysonNetwork.Zone/Pages/Index.cshtml index e2ad447..555ce9c 100644 --- a/DysonNetwork.Zone/Pages/Index.cshtml +++ b/DysonNetwork.Zone/Pages/Index.cshtml @@ -1,16 +1,134 @@ -@page +@page @model IndexModel @{ Layout = "_LayoutContained"; - ViewData["Title"] = "Solar Network Pages"; + + var pageTitle = "Home"; + var pageDescription = "Welcome to the Solar Network Pages."; + var ogType = "website"; + string? ogImageUrl = null; + var canonicalUrl = $"{Request.Scheme}://{Request.Host}{Request.Path}{Request.QueryString}"; + var siteName = Model.Site?.Name ?? "Solar Network"; + + if (Model.UserAccount != null) + { + pageTitle = $"{Model.UserAccount.Nick ?? Model.UserAccount.Name}'s Page"; + pageDescription = !string.IsNullOrWhiteSpace(Model.UserAccount.Profile?.Bio) ? Model.UserAccount.Profile.Bio : $"Profile of {Model.UserAccount.Nick ?? Model.UserAccount.Name} on {siteName}"; + ogType = "profile"; + ogImageUrl = Model.UserBackgroundUrl; + if (!string.IsNullOrEmpty(ogImageUrl) && !ogImageUrl.StartsWith("http")) + ogImageUrl = $"{Request.Scheme}://{Request.Host}{ogImageUrl}"; + } + else if (Model.Site != null) + { + pageTitle = Model.Site.Name; + if (!string.IsNullOrWhiteSpace(Model.Site.Description)) + { + pageDescription = Model.Site.Description; + } + ogType = "website"; + ogImageUrl = null; + } + + if (!string.IsNullOrWhiteSpace(pageDescription) && pageDescription.Length > 160) + { + pageDescription = pageDescription.Substring(0, 157) + "..."; + } + + ViewData["Title"] = $"{pageTitle} - {siteName}"; } -
-
- Logo -

Hello World 👋

-

Here are the Solar Network Pages

-

为什么这个首页长这样呢?因为羊不知道该放什么,所以如果你有想法欢迎跟羊讲!

+@section Head { + + + + + + + + @if (!string.IsNullOrEmpty(ogImageUrl)) + { + + } + + + + + + @if (!string.IsNullOrEmpty(ogImageUrl)) + { + + } +} + +
+ @if (Model.FeaturedPosts.Any()) + { +

+ Featured Posts +

+ + @if (Model.FeaturedPosts.Count > 1) + { +
+ @for (var idx = 0; idx < Model.FeaturedPosts.Count; idx++) + { + @(idx + 1) + } +
+ } + } + +
+ @if (Model.UserAccount != null) + { +
+

+ About me +

+ +
+ } + + @if (Model.Site != null) + { +
+

+ About the Site +

+ +
+ }
-
+
\ No newline at end of file diff --git a/DysonNetwork.Zone/Pages/Index.cshtml.cs b/DysonNetwork.Zone/Pages/Index.cshtml.cs index 7e9b36c..763126e 100644 --- a/DysonNetwork.Zone/Pages/Index.cshtml.cs +++ b/DysonNetwork.Zone/Pages/Index.cshtml.cs @@ -1,10 +1,109 @@ +using Markdig; +using DysonNetwork.Shared.Models; +using DysonNetwork.Shared.Proto; +using DysonNetwork.Shared.Registry; +using DysonNetwork.Zone.Publication; using Microsoft.AspNetCore.Mvc.RazorPages; +using NodaTime; namespace DysonNetwork.Zone.Pages; -public class IndexModel : PageModel +public class IndexModel(PostService.PostServiceClient postClient, RemotePublisherService rps, RemoteAccountService ras) : PageModel { - public void OnGet() + public SnPublicationSite? Site { get; set; } + public SnPublisher? Publisher { get; set; } + public Account? UserAccount { get; set; } + public List FeaturedPosts { get; set; } = []; + + public string? UserPictureUrl => UserAccount?.Profile?.Picture?.Id != null + ? $"/drive/files/{UserAccount.Profile.Picture.Id}" + : null; + + public string? UserBackgroundUrl => UserAccount?.Profile?.Background?.Id != null + ? $"/drive/files/{UserAccount.Profile.Background.Id}?original=true" + : null; + + + public async Task OnGetAsync() { + Site = HttpContext.Items[PublicationSiteMiddleware.SiteContextKey] as SnPublicationSite; + + if (Site != null) + { + // Fetch Publisher Information + Publisher = await rps.GetPublisher(id: Site!.PublisherId.ToString()); + + // Fetch User Account Information if available + UserAccount = await ras.GetAccount(Site.AccountId); + + // Fetch Featured Posts (e.g., top 5 by views) + var request = new ListPostsRequest + { + OrderBy = "views", // Assuming 'views' is a valid order-by option for popularity + OrderDesc = true, + PageSize = 5, + PublisherId = Site!.PublisherId.ToString() + }; + + var response = await postClient.ListPostsAsync(request); + + if (response?.Posts != null) + { + FeaturedPosts = response.Posts.Select(SnPost.FromProtoValue).ToList(); + + // Convert the markdown content to HTML + foreach (var post in FeaturedPosts.Where(post => !string.IsNullOrEmpty(post.Content))) + post.Content = Markdown.ToHtml(post.Content!); + } + } + } + + public int CalculateAge(Instant birthday) + { + var birthDate = birthday.ToDateTimeOffset(); + var today = DateTimeOffset.Now; + var age = today.Year - birthDate.Year; + if (birthDate > today.AddYears(-age)) age--; + return age; + } + + public string GetOffsetUtcString(string targetTimeZone) + { + try + { + var tz = TimeZoneInfo.FindSystemTimeZoneById(targetTimeZone); + var offset = tz.GetUtcOffset(DateTimeOffset.Now); + var sign = offset >= TimeSpan.Zero ? "+" : "-"; + return $"{Math.Abs(offset.Hours):D2}:{Math.Abs(offset.Minutes):D2}"; + } + catch + { + return "00:00"; + } + } + + public string GetCurrentTimeInTimeZone(string targetTimeZone) + { + try + { + var tz = TimeZoneInfo.FindSystemTimeZoneById(targetTimeZone); + var now = TimeZoneInfo.ConvertTime(DateTimeOffset.Now, tz); + return now.ToString("t", System.Globalization.CultureInfo.InvariantCulture); + } + catch + { + return DateTime.Now.ToString("t", System.Globalization.CultureInfo.InvariantCulture); + } + } + + public (string Name, string Color) GetPerkInfo(string identifier) + { + return identifier switch + { + "solian.stellar.primary" => ("Stellar", "#2196f3"), + "solian.stellar.nova" => ("Nova", "#39c5bb"), + "solian.stellar.supernova" => ("Supernova", "#ffc109"), + _ => ("Unknown", "#2196f3") + }; } } \ No newline at end of file diff --git a/DysonNetwork.Zone/Pages/Posts.cshtml b/DysonNetwork.Zone/Pages/Posts.cshtml index 8079ed2..6cec415 100644 --- a/DysonNetwork.Zone/Pages/Posts.cshtml +++ b/DysonNetwork.Zone/Pages/Posts.cshtml @@ -58,92 +58,7 @@
@foreach (var post in Model.Posts) { -
-
-
- @if (!string.IsNullOrWhiteSpace(post.Title) || !string.IsNullOrWhiteSpace(post.Description)) - { -
- @if (!string.IsNullOrWhiteSpace(post.Title)) - { -

- @post.Title -

- } - @if (!string.IsNullOrWhiteSpace(post.Description)) - { -

@post.Description

- } -
- } -

@Html.Raw(post.Content)

-
- - @if (post.Attachments.Any()) - { -
- @foreach (var attachment in post.Attachments) - { -
- @if (attachment.MimeType!.StartsWith("image")) - { -
- @attachment.Name -
- } - else if (attachment.MimeType!.StartsWith("video")) - { - - } - else if (attachment.MimeType!.StartsWith("audio")) - { - - } - else - { - @attachment.Name - } -
- } -
- } - - @if (post.Categories.Any() || post.Tags.Any()) - { -
- @foreach (var category in post.Categories) - { - - - @(!string.IsNullOrEmpty(category.Name) ? category.Name : category.Slug) - - } - @foreach (var tag in post.Tags) - { - - - @(!string.IsNullOrEmpty(tag.Name) ? tag.Name : tag.Slug) - - } -
- } - -
-
- Posted on @post.CreatedAt.ToDateTimeOffset().ToString("yyyy-MM-dd") -
- - - -
-
-
+ }
} @@ -175,35 +90,7 @@ @if (Model.Publisher != null) {
-
- @if (Model.Publisher!.Background != null) - { -
- Background -
- } -
-
-
-
- Avatar -
-
-

- @Model.Publisher.Nick - @@@Model.Publisher.Name -

-
- @if (!string.IsNullOrWhiteSpace(Model.Publisher.Bio)) - { -

@Model.Publisher.Bio

- } -
-
+
}
diff --git a/DysonNetwork.Zone/Pages/Shared/_PostItem.cshtml b/DysonNetwork.Zone/Pages/Shared/_PostItem.cshtml new file mode 100644 index 0000000..74eac09 --- /dev/null +++ b/DysonNetwork.Zone/Pages/Shared/_PostItem.cshtml @@ -0,0 +1,89 @@ +@using DysonNetwork.Shared.Models +@model DysonNetwork.Shared.Models.SnPost + +
+
+
+ @if (!string.IsNullOrWhiteSpace(Model.Title) || !string.IsNullOrWhiteSpace(Model.Description)) + { +
+ @if (!string.IsNullOrWhiteSpace(Model.Title)) + { +

+ @Model.Title +

+ } + @if (!string.IsNullOrWhiteSpace(Model.Description)) + { +

@Model.Description

+ } +
+ } +

@Html.Raw(Model.Content)

+
+ + @if (Model.Attachments.Any()) + { +
+ @foreach (var attachment in Model.Attachments) + { +
+ @if (attachment.MimeType!.StartsWith("image")) + { +
+ @attachment.Name +
+ } + else if (attachment.MimeType!.StartsWith("video")) + { + + } + else if (attachment.MimeType!.StartsWith("audio")) + { + + } + else + { + @attachment.Name + } +
+ } +
+ } + + @if (Model.Categories.Any() || Model.Tags.Any()) + { +
+ @foreach (var category in Model.Categories) + { + + + @(!string.IsNullOrEmpty(category.Name) ? category.Name : category.Slug) + + } + @foreach (var tag in Model.Tags) + { + + + @(!string.IsNullOrEmpty(tag.Name) ? tag.Name : tag.Slug) + + } +
+ } + +
+
+ Posted on @Model.CreatedAt.ToDateTimeOffset().ToString("yyyy-MM-dd") +
+ + + +
+
+
\ No newline at end of file diff --git a/DysonNetwork.Zone/Pages/Shared/_PublisherInfo.cshtml b/DysonNetwork.Zone/Pages/Shared/_PublisherInfo.cshtml new file mode 100644 index 0000000..28542ba --- /dev/null +++ b/DysonNetwork.Zone/Pages/Shared/_PublisherInfo.cshtml @@ -0,0 +1,36 @@ +@using DysonNetwork.Shared.Models +@model DysonNetwork.Shared.Models.SnPublisher + +@{ + const string defaultAvatar = "https://www.gravatar.com/avatar/00000000000000000000000000000000?d=mp"; +} + +
+ @if (Model.Background != null) + { +
+ Background +
+ } +
+
+
+
+ Avatar +
+
+

+ @Model.Nick + @@@Model.Name +

+
+ @if (!string.IsNullOrWhiteSpace(Model.Bio)) + { +

@Model.Bio

+ } +
+
\ No newline at end of file diff --git a/DysonNetwork.Zone/Pages/Shared/_SiteInfo.cshtml b/DysonNetwork.Zone/Pages/Shared/_SiteInfo.cshtml new file mode 100644 index 0000000..3a609a7 --- /dev/null +++ b/DysonNetwork.Zone/Pages/Shared/_SiteInfo.cshtml @@ -0,0 +1,58 @@ +@using DysonNetwork.Shared.Models +@model DysonNetwork.Shared.Models.SnPublicationSite + +
+
+
+
+

Info

+ +
+
+ + + Name + + @Model.Name +
+
+
+
+ + + Slug + + @Model.Slug +
+
+
+
+
+ +
+ @if (!string.IsNullOrEmpty(Model.Description)) + { +
+
+
+

+ Description +

+
+ @Model.Description +
+
+
+
+ } + +
+
+

Proudly powered by the Solar Network Pages

+

Hosted on the Solar Network

+

Network powered by Cloudflare

+

Therefore, if the site is down, 99% is Cloudflare's fault

+
+
+
+
\ No newline at end of file diff --git a/DysonNetwork.Zone/Pages/Shared/_UserInfo.cshtml b/DysonNetwork.Zone/Pages/Shared/_UserInfo.cshtml new file mode 100644 index 0000000..43107f5 --- /dev/null +++ b/DysonNetwork.Zone/Pages/Shared/_UserInfo.cshtml @@ -0,0 +1,70 @@ +@model DysonNetwork.Zone.Pages.IndexModel + +@if (Model.UserAccount != null) +{ +
+
+
+ @if (!string.IsNullOrEmpty(Model.UserPictureUrl)) + { + Avatar + } + else + { +
+ @(Model.UserAccount.Name != null ? Model.UserAccount.Name[0] : '?') +
+ } +
+
+ @(Model.UserAccount.Nick ?? Model.UserAccount.Name) +
+
@@@Model.UserAccount.Name
+
+
+
+ @if (!string.IsNullOrEmpty(Model.UserAccount.Profile?.TimeZone)) + { +
+ + + Time Zone + + + @Model.GetCurrentTimeInTimeZone(Model.UserAccount.Profile.TimeZone) + · + @Model.GetOffsetUtcString(Model.UserAccount.Profile.TimeZone) + · + @Model.UserAccount.Profile.TimeZone + +
+ } + @if (!string.IsNullOrEmpty(Model.UserAccount.Profile?.Location)) + { +
+ + Location + + @Model.UserAccount.Profile.Location +
+ } + @if (!string.IsNullOrEmpty(Model.UserAccount.Profile?.FirstName) || !string.IsNullOrEmpty(Model.UserAccount.Profile?.LastName)) + { +
+ + Name + + + @string.Join(" ", new[] + { + Model.UserAccount.Profile.FirstName, + Model.UserAccount.Profile.MiddleName, + Model.UserAccount.Profile.LastName + }.Where(s => !string.IsNullOrEmpty(s))) + +
+ } +
+
+
+}