Public home page, Naskh default font, no poet photos

- home page is public: no redirect to login/admin import; flat poet list until century
  groups exist (upstream needed a pinned 'popular poets' group, which Divan never has, so
  the home page always redirected); public 'being prepared' notice when there are no poets
- Naskh is the default font, Nastaliq the option (site and static reader)
- poet/writer photos hidden everywhere (CSS on /poet/image/), poet page photos tab removed

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Anas Rashid 2026-10-08 19:59:20 +02:00
parent b186ed3336
commit 5f2b779e89
7 changed files with 68 additions and 70 deletions

View File

@ -65,7 +65,7 @@ else
<select name="author" id="author">
<option value="0" selected>تمام شعرا کے کلام میں</option>
@{
foreach (RMuseum.Models.Divan.ViewModels.DivanPoetViewModel poet in Model.Poets)
foreach (RMuseum.Models.Divan.ViewModels.DivanPoetViewModel poet in Model.Poets ?? new())
{
<option value="@poet.Id">@poet.Nickname</option>
}
@ -83,6 +83,8 @@ else
<div id="main">
<div id="guides">
@if (Model.PoetGroups != null && Model.PoetGroups.Any(g => g.Id == 0))
{
<div id="home-popular-poets-row">
<div class="century">
مقبول شعرا
@ -112,8 +114,35 @@ else
</div>
}
</div>
}
@{
@if (Model.NoContentYet)
{
<div class="notice">
<p>دیوان کا مواد تیار کیا جا رہا ہے۔ براہِ کرم کچھ دیر بعد دوبارہ تشریف لائیں۔</p>
@if (Model.LoggedIn)
{
<p><a href="/Admin/PublicDataImport">مواد درآمد کریں</a></p>
}
</div>
}
else if (!Model.PoetGroups.Any(g => g.Id != 0))
{
@* century groups are rebuilt when an import finishes; until then list all poets *@
<div class="century">شعرا</div>
<div class="spacer">
@foreach (var poet in Model.Poets)
{
<div class="poet" data-value="@poet.Nickname">
<div class="caption">
<a href="@poet.FullUrl">@poet.Nickname</a>
</div>
</div>
}
</div>
}
else
{
<div class="century" id="cl">
صدیوں کے لحاظ سے
</div>

View File

@ -165,11 +165,9 @@ namespace DivanRazor.Pages
// empty database instead of rendering something useful. Steer the visitor toward
// fixing that instead of letting them hit an unhandled exception: log in first if
// needed, then straight to the admin page that can seed real content.
if (IsDatabaseEffectivelyEmpty())
{
const string targetUrl = "/Admin/PublicDataImport";
return LoggedIn ? Redirect(targetUrl) : Redirect($"/login?redirect={targetUrl}");
}
// divan: the home page is public. No poets yet -> public "being prepared" notice (admins get an
// import link in the view); poets but no century groups yet (e.g. mid-import) -> one flat group.
NoContentYet = IsDatabaseEffectivelyEmpty();
ViewData["Title"] = "دیوان";
@ -177,15 +175,18 @@ namespace DivanRazor.Pages
}
/// <summary>
/// true if there's nothing meaningful to show on the home page yet — no poets at all, or
/// no century grouping (the "popular poets" group with Id == 0 that the view relies on).
/// true if there are no poets to show yet
/// </summary>
private bool IsDatabaseEffectivelyEmpty()
{
return Poets == null || Poets.Count == 0
|| PoetGroups == null || !PoetGroups.Any(g => g.Id == 0);
return Poets == null || Poets.Count == 0 || PoetGroups == null;
}
/// <summary>
/// true when there is nothing to list yet (fresh install or import not started)
/// </summary>
public bool NoContentYet { get; set; }
public async Task<IActionResult> OnGetPoetInformationAsync(int id)
{
if (id == 0)

View File

@ -52,7 +52,6 @@
<div class="poemtablinks"><a href="#quoteds">مشقِ سخن</a></div>
<div class="poemtablinks"><a href="#words" onclick="javascript:loadWordCounts(@Model.DivanPage.PoetOrCat.Cat.Id, @Model.DivanPage.PoetOrCat.Poet.Id, false)">الفاظ</a></div>
<div class="poemtablinks"><a href="#recitations" onclick="javascript:loadCatRecitations(@Model.DivanPage.PoetOrCat.Cat.Id)">قرأتیں</a></div>
<div class="poemtablinks"><a href="#photos">تصاویر</a></div>
<div class="poemtablinks"><a href="#papersources">مطبوعہ مآخذ</a></div>
<div class="poemtablinks"><a href="#persongraph" onclick="javascript:loadPersonGraph(@Model.DivanPage.PoetOrCat.Cat.Id)">شخصیات</a></div>
</div>
@ -69,7 +68,6 @@
<div class="poemtablinks active"><a href="#quoteds">مشقِ سخن</a></div>
<div class="poemtablinks"><a href="#words" onclick="javascript:loadWordCounts(@Model.DivanPage.PoetOrCat.Cat.Id, @Model.DivanPage.PoetOrCat.Poet.Id, false)">الفاظ</a></div>
<div class="poemtablinks"><a href="#recitations" onclick="javascript:loadCatRecitations(@Model.DivanPage.PoetOrCat.Cat.Id)">قرأتیں</a></div>
<div class="poemtablinks"><a href="#photos">تصاویر</a></div>
<div class="poemtablinks"><a href="#papersources">مطبوعہ مآخذ</a></div>
<div class="poemtablinks"><a href="#persongraph" onclick="javascript:loadPersonGraph(@Model.DivanPage.PoetOrCat.Cat.Id)">شخصیات</a></div>
</div>
@ -84,7 +82,6 @@
<div class="poemtablinks"><a href="#quoteds">مشقِ سخن</a></div>
<div class="poemtablinks active"><a href="#words" onclick="javascript:loadWordCounts(@Model.DivanPage.PoetOrCat.Cat.Id, @Model.DivanPage.PoetOrCat.Poet.Id, false)">الفاظ</a></div>
<div class="poemtablinks"><a href="#recitations" onclick="javascript:loadCatRecitations(@Model.DivanPage.PoetOrCat.Cat.Id)">قرأتیں</a></div>
<div class="poemtablinks"><a href="#photos">تصاویر</a></div>
<div class="poemtablinks"><a href="#papersources">مطبوعہ مآخذ</a></div>
<div class="poemtablinks"><a href="#persongraph" onclick="javascript:loadPersonGraph(@Model.DivanPage.PoetOrCat.Cat.Id)">شخصیات</a></div>
</div>
@ -107,7 +104,6 @@
<div class="poemtablinks"><a href="#quoteds">مشقِ سخن</a></div>
<div class="poemtablinks"><a href="#words" onclick="javascript:loadWordCounts(@Model.DivanPage.PoetOrCat.Cat.Id, @Model.DivanPage.PoetOrCat.Poet.Id, false)">الفاظ</a></div>
<div class="poemtablinks active"><a href="#recitations" onclick="javascript:loadCatRecitations(@Model.DivanPage.PoetOrCat.Cat.Id)">قرأتیں</a></div>
<div class="poemtablinks"><a href="#photos">تصاویر</a></div>
<div class="poemtablinks"><a href="#papersources">مطبوعہ مآخذ</a></div>
<div class="poemtablinks"><a href="#persongraph" onclick="javascript:loadPersonGraph(@Model.DivanPage.PoetOrCat.Cat.Id)">شخصیات</a></div>
</div>
@ -125,39 +121,6 @@
}
</div>
@* Photos Section *@
<div class="poempretab" id="photos"></div>
<div class="poemtab">
<div class="poemtablinks"><a href="#pretab">اعداد و شمار</a></div>
<div class="poemtablinks"><a href="#quoteds">مشقِ سخن</a></div>
<div class="poemtablinks"><a href="#words" onclick="javascript:loadWordCounts(@Model.DivanPage.PoetOrCat.Cat.Id, @Model.DivanPage.PoetOrCat.Poet.Id, false)">الفاظ</a></div>
<div class="poemtablinks"><a href="#recitations" onclick="javascript:loadCatRecitations(@Model.DivanPage.PoetOrCat.Cat.Id)">قرأتیں</a></div>
<div class="poemtablinks active"><a href="#photos">تصاویر</a></div>
<div class="poemtablinks"><a href="#papersources">مطبوعہ مآخذ</a></div>
<div class="poemtablinks"><a href="#persongraph" onclick="javascript:loadPersonGraph(@Model.DivanPage.PoetOrCat.Cat.Id)">شخصیات</a></div>
</div>
<div class="poemtabcontent">
<div class="related-images-frame">
@if (Model.Photo != null)
{
<div class="century">
@Model.Photo.Title
@if (Model.Photo.ChosenOne)
{
<i class="notranslate noindent-info-button done-icon"></i>
}
</div>
<div class="clear-both">
<img src="@Html.Raw(Model.Photo.ExternalNormalSizeImageUrl.Replace("/norm/", "/orig/"))" alt="@Model.Photo.Title" class="max-width-100per">
</div>
<div class="comments-like-div">
@Html.Raw(Model.Photo.Description)
</div>
}
<a href="/photos?p=@Model.DivanPage.PoetOrCat.Cat.UrlSlug" role="button" class="pagebutton comments-link">تصاویر دیکھیں اور تجویز کریں: @Model.DivanPage.PoetOrCat.Poet.Nickname</a>
</div>
</div>
@* Paper Sources Section *@
@if (Model.DivanPage.SecondPoet == null)
{
@ -167,7 +130,6 @@
<div class="poemtablinks"><a href="#quoteds">مشقِ سخن</a></div>
<div class="poemtablinks"><a href="#words" onclick="javascript:loadWordCounts(@Model.DivanPage.PoetOrCat.Cat.Id, @Model.DivanPage.PoetOrCat.Poet.Id, false)">الفاظ</a></div>
<div class="poemtablinks"><a href="#recitations" onclick="javascript:loadCatRecitations(@Model.DivanPage.PoetOrCat.Cat.Id)">قرأتیں</a></div>
<div class="poemtablinks"><a href="#photos">تصاویر</a></div>
<div class="poemtablinks active"><a href="#papersources">مطبوعہ مآخذ</a></div>
<div class="poemtablinks"><a href="#persongraph" onclick="javascript:loadPersonGraph(@Model.DivanPage.PoetOrCat.Cat.Id)">شخصیات</a></div>
</div>
@ -208,7 +170,6 @@
<div class="poemtablinks"><a href="#quoteds">مشقِ سخن</a></div>
<div class="poemtablinks"><a href="#words" onclick="javascript:loadWordCounts(@Model.DivanPage.PoetOrCat.Cat.Id, @Model.DivanPage.PoetOrCat.Poet.Id, false)">الفاظ</a></div>
<div class="poemtablinks"><a href="#recitations" onclick="javascript:loadCatRecitations(@Model.DivanPage.PoetOrCat.Cat.Id)">قرأتیں</a></div>
<div class="poemtablinks"><a href="#photos">تصاویر</a></div>
<div class="poemtablinks"><a href="#papersources">مطبوعہ مآخذ</a></div>
<div class="poemtablinks active"><a href="#persongraph" onclick="javascript:loadPersonGraph(@Model.DivanPage.PoetOrCat.Cat.Id)">شخصیات</a></div>
</div>

View File

@ -1,15 +1,15 @@
@* divan: Urdu fonts (Nastaliq default / Naskh option) + overrides, included in every page <head> after p8.css *@
@* divan: Urdu fonts (Naskh default / Nastaliq option) + overrides, included in every page <head> after p8.css *@
<link rel="preconnect" href="https://fonts.googleapis.com" />
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
<link href="https://fonts.googleapis.com/css2?family=Noto+Nastaliq+Urdu:wght@400..700&family=Noto+Naskh+Arabic:wght@400..700&display=swap" rel="stylesheet" />
<link href="~/css/divan.css" asp-append-version="true" rel="stylesheet" type="text/css" />
<script>
// divan: Nastaliq (default) / Naskh font choice, applied before render to avoid a flash
try { if (localStorage.getItem("divan-font") === "naskh") document.documentElement.classList.add("font-naskh"); } catch (e) { }
// divan: Naskh (default) / Nastaliq font choice, applied before render to avoid a flash
try { if (localStorage.getItem("divan-font") === "nastaliq") document.documentElement.classList.add("font-nastaliq"); } catch (e) { }
function toggleDivanFont() {
var naskh = document.documentElement.classList.toggle("font-naskh");
try { localStorage.setItem("divan-font", naskh ? "naskh" : "nastaliq"); } catch (e) { }
var nastaliq = document.documentElement.classList.toggle("font-nastaliq");
try { localStorage.setItem("divan-font", nastaliq ? "nastaliq" : "naskh"); } catch (e) { }
var t = document.getElementById("font-toggle");
if (t) t.textContent = naskh ? "نسخ" : "نستعلیق";
if (t) t.textContent = nastaliq ? "نستعلیق" : "نسخ";
}
</script>

View File

@ -129,9 +129,9 @@
}
</script>
<a href="javascript:toggleDivanFont();" id="font-toggle" title="خط بدلیں: نستعلیق / نسخ">نستعلیق</a>
<a href="javascript:toggleDivanFont();" id="font-toggle" title="خط بدلیں: نسخ / نستعلیق">نسخ</a>
<script>
if (document.documentElement.classList.contains("font-naskh")) document.getElementById("font-toggle").textContent = "نسخ";
if (document.documentElement.classList.contains("font-nastaliq")) document.getElementById("font-toggle").textContent = "نستعلیق";
</script>
<a href="javascript:toggleColorScheme();" id="theme-toggle" title="رنگ بدلیں">

View File

@ -1,12 +1,19 @@
/* Divan overrides on top of Divan's p8.css: Urdu fonts (Nastaliq default, Naskh option) + wordmark. */
/* Divan overrides on top of upstream's p8.css: Urdu fonts (Naskh default, Nastaliq option), wordmark,
no poet/writer photos for now. */
:root {
--divan-font: 'Noto Naskh Arabic', 'Noto Nastaliq Urdu', serif;
--divan-line-height: 2;
}
html.font-nastaliq {
--divan-font: 'Noto Nastaliq Urdu', 'Noto Naskh Arabic', serif;
--divan-line-height: 2.6;
}
html.font-naskh {
--divan-font: 'Noto Naskh Arabic', 'Noto Nastaliq Urdu', serif;
--divan-line-height: 2;
/* poet/writer photos are not shown for now (every portrait is served from the API's /poet/image/ endpoint) */
img[src*="/poet/image/"],
a:has(> img[src*="/poet/image/"]) { /* also the oval portrait frame around it on poet tiles */
display: none !important;
}
/* poem lines, prose paragraphs, titles */

View File

@ -12,12 +12,12 @@
/* Divan static reader: no server, reads the divan-data static API (ganjoor-data layout). */
:root {
--bg: #faf7f0; --card: #ffffff; --ink: #2b2620; --muted: #7a6f60; --line: #e6dfd2; --accent: #8a5a19;
--font: 'Noto Nastaliq Urdu', 'Noto Naskh Arabic', serif; --lh: 2.5;
--font: 'Noto Naskh Arabic', 'Noto Nastaliq Urdu', serif; --lh: 2;
}
@media (prefers-color-scheme: dark) {
:root { --bg: #17140f; --card: #211d17; --ink: #ece4d6; --muted: #a89c88; --line: #3a3328; --accent: #d9a55a; }
}
html.naskh { --font: 'Noto Naskh Arabic', 'Noto Nastaliq Urdu', serif; --lh: 2; }
html.nastaliq { --font: 'Noto Nastaliq Urdu', 'Noto Naskh Arabic', serif; --lh: 2.5; }
* { box-sizing: border-box; }
body { margin: 0; background: var(--bg); color: var(--ink); font-family: var(--font); line-height: var(--lh); }
a { color: var(--accent); text-decoration: none; }
@ -45,13 +45,13 @@
@media (max-width: 600px) { .b { grid-template-columns: 1fr; } .b p:last-child { text-align: right; padding-right: 32px; } }
.msg { color: var(--muted); text-align: center; padding: 32px; }
</style>
<script>try { if (localStorage.getItem('divan-font') === 'naskh') document.documentElement.classList.add('naskh'); } catch (e) {}</script>
<script>try { if (localStorage.getItem('divan-font') === 'nastaliq') document.documentElement.classList.add('nastaliq'); } catch (e) {}</script>
</head>
<body>
<header>
<h1><a href="#/">دیوان</a></h1>
<span class="grow"></span>
<button id="font" type="button" title="خط بدلیں">نستعلیق</button>
<button id="font" type="button" title="خط بدلیں">نسخ</button>
</header>
<main id="app"><p class="msg">لوڈ ہو رہا ہے…</p></main>
<script>
@ -140,11 +140,11 @@ window.addEventListener('hashchange', route);
route();
var fontBtn = document.getElementById('font');
fontBtn.textContent = document.documentElement.classList.contains('naskh') ? 'نسخ' : 'نستعلیق';
fontBtn.textContent = document.documentElement.classList.contains('nastaliq') ? 'نستعلیق' : 'نسخ';
fontBtn.onclick = function () {
var naskh = document.documentElement.classList.toggle('naskh');
try { localStorage.setItem('divan-font', naskh ? 'naskh' : 'nastaliq'); } catch (e) {}
fontBtn.textContent = naskh ? 'نسخ' : 'نستعلیق';
var nastaliq = document.documentElement.classList.toggle('nastaliq');
try { localStorage.setItem('divan-font', nastaliq ? 'nastaliq' : 'naskh'); } catch (e) {}
fontBtn.textContent = nastaliq ? 'نستعلیق' : 'نسخ';
};
</script>
</body>