tajik home page
This commit is contained in:
parent
133b65606c
commit
c8782e73e2
@ -59,48 +59,25 @@
|
|||||||
{
|
{
|
||||||
var popularGroup = Model.PoetGroups.SingleOrDefault(g => g.Id == 0);
|
var popularGroup = Model.PoetGroups.SingleOrDefault(g => g.Id == 0);
|
||||||
var centuryGroups = Model.PoetGroups.Where(g => g.Id != 0).ToList();
|
var centuryGroups = Model.PoetGroups.Where(g => g.Id != 0).ToList();
|
||||||
@if (popularGroup != null)
|
|
||||||
{
|
|
||||||
<div class="tg-century-heading">Шоирони маъмул</div>
|
|
||||||
<div class="tg-poet-grid">
|
|
||||||
@foreach (var poet in popularGroup.Poets)
|
|
||||||
{
|
|
||||||
<a class="tg-poet-card" href="@poet.FullUrl" title="@poet.Name" data-value="@poet.Nickname">
|
|
||||||
<span class="tg-poet-portrait">
|
|
||||||
<img src="/images/poets/@(poet.Id).png" alt="@poet.Nickname" loading="lazy"
|
|
||||||
onerror="this.onerror=null;this.src='/images/poets/999.png';" />
|
|
||||||
</span>
|
|
||||||
<span class="tg-poet-name">@poet.Nickname</span>
|
|
||||||
</a>
|
|
||||||
}
|
|
||||||
</div>
|
|
||||||
}
|
|
||||||
|
|
||||||
<div class="tg-poet-search">
|
<div class="tg-poet-search">
|
||||||
<input type="text" id="tg-findpoet" placeholder="Ҷустуҷӯи шоир" oninput="tgInlineSearch(this.value)" />
|
<input type="text" id="tg-findpoet" placeholder="Ҷустуҷӯи шоир" oninput="tgInlineSearch(this.value)" />
|
||||||
<div class="tg-poet-grid" id="tg-found-poets"></div>
|
<div class="tg-poet-grid" id="tg-found-poets"></div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@if (centuryGroups.Count > 0)
|
<div class="tg-view-switch">
|
||||||
{
|
<button type="button" class="tg-view-switch-btn active" data-view="century" onclick="tgSwitchView('century')">Аз рӯи аср</button>
|
||||||
<div class="tg-century-heading">Гурӯҳбандӣ бар асоси аср</div>
|
<button type="button" class="tg-view-switch-btn" data-view="alpha" onclick="tgSwitchView('alpha')">Аз рӯи алифбо</button>
|
||||||
<div class="tg-century-nav">
|
</div>
|
||||||
@foreach (var g in centuryGroups)
|
|
||||||
{
|
|
||||||
<a href="#tg-pg-@g.Id" class="circled-number">@(g.HalfCenturyOrder + 2)</a>
|
|
||||||
}
|
|
||||||
</div>
|
|
||||||
|
|
||||||
@foreach (var century in centuryGroups)
|
<div id="tg-view-century">
|
||||||
|
@if (popularGroup != null)
|
||||||
{
|
{
|
||||||
@if (century.ShowInTimeLine)
|
<div class="tg-century-heading">Шоирони маъмул</div>
|
||||||
{
|
|
||||||
<div class="tg-century-heading" id="tg-pg-@century.Id">@century.Name</div>
|
|
||||||
}
|
|
||||||
<div class="tg-poet-grid">
|
<div class="tg-poet-grid">
|
||||||
@foreach (var poet in century.Poets)
|
@foreach (var poet in popularGroup.Poets)
|
||||||
{
|
{
|
||||||
<a class="tg-poet-card" href="@poet.FullUrl" title="@poet.Name" data-value="@poet.Nickname">
|
<a class="tg-poet-card" href="@poet.FullUrl" title="@poet.Name" data-poet-id="@poet.Id" data-value="@poet.Nickname">
|
||||||
<span class="tg-poet-portrait">
|
<span class="tg-poet-portrait">
|
||||||
<img src="/images/poets/@(poet.Id).png" alt="@poet.Nickname" loading="lazy"
|
<img src="/images/poets/@(poet.Id).png" alt="@poet.Nickname" loading="lazy"
|
||||||
onerror="this.onerror=null;this.src='/images/poets/999.png';" />
|
onerror="this.onerror=null;this.src='/images/poets/999.png';" />
|
||||||
@ -110,7 +87,54 @@
|
|||||||
}
|
}
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
@if (centuryGroups.Count > 0)
|
||||||
|
{
|
||||||
|
<div class="tg-century-heading">Гурӯҳбандӣ бар асоси аср</div>
|
||||||
|
<div class="tg-century-nav">
|
||||||
|
@foreach (var g in centuryGroups)
|
||||||
|
{
|
||||||
|
<a href="#tg-pg-@g.Id" class="circled-number">@(g.HalfCenturyOrder + 2)</a>
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
@foreach (var century in centuryGroups)
|
||||||
|
{
|
||||||
|
@if (century.ShowInTimeLine)
|
||||||
|
{
|
||||||
|
<div class="tg-century-heading" id="tg-pg-@century.Id">@century.Name</div>
|
||||||
|
}
|
||||||
|
<div class="tg-poet-grid">
|
||||||
|
@foreach (var poet in century.Poets)
|
||||||
|
{
|
||||||
|
<a class="tg-poet-card" href="@poet.FullUrl" title="@poet.Name" data-poet-id="@poet.Id" data-value="@poet.Nickname">
|
||||||
|
<span class="tg-poet-portrait">
|
||||||
|
<img src="/images/poets/@(poet.Id).png" alt="@poet.Nickname" loading="lazy"
|
||||||
|
onerror="this.onerror=null;this.src='/images/poets/999.png';" />
|
||||||
|
</span>
|
||||||
|
<span class="tg-poet-name">@poet.Nickname</span>
|
||||||
|
</a>
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div id="tg-view-alpha" style="display:none">
|
||||||
|
<div class="tg-century-heading">Аз рӯи алифбо</div>
|
||||||
|
<div class="tg-poet-grid">
|
||||||
|
@foreach (var poet in Model.AlphabeticalPoets)
|
||||||
|
{
|
||||||
|
<a class="tg-poet-card" href="@poet.FullUrl" title="@poet.Name" data-poet-id="@poet.Id" data-value="@poet.Nickname">
|
||||||
|
<span class="tg-poet-portrait">
|
||||||
|
<img src="/images/poets/@(poet.Id).png" alt="@poet.Nickname" loading="lazy"
|
||||||
|
onerror="this.onerror=null;this.src='/images/poets/999.png';" />
|
||||||
|
</span>
|
||||||
|
<span class="tg-poet-name">@poet.Nickname</span>
|
||||||
|
</a>
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|||||||
@ -38,6 +38,13 @@ namespace TajikGanjoor.Pages
|
|||||||
/// poets grouped by century, shown on the home page - mirrors GanjooRazor's Index.cshtml.cs
|
/// poets grouped by century, shown on the home page - mirrors GanjooRazor's Index.cshtml.cs
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public List<GanjoorCenturyViewModel> PoetGroups { get; set; }
|
public List<GanjoorCenturyViewModel> PoetGroups { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// all translated poets, sorted alphabetically by Tajik nickname - alternate flat view,
|
||||||
|
/// switched to on the home page instead of the century grouping
|
||||||
|
/// </summary>
|
||||||
|
public List<GanjoorPoetViewModel> AlphabeticalPoets { get; set; }
|
||||||
|
|
||||||
public async Task<IActionResult> OnGetAsync()
|
public async Task<IActionResult> OnGetAsync()
|
||||||
{
|
{
|
||||||
if (bool.Parse(Configuration["MaintenanceMode"] ?? false.ToString()))
|
if (bool.Parse(Configuration["MaintenanceMode"] ?? false.ToString()))
|
||||||
@ -58,6 +65,21 @@ namespace TajikGanjoor.Pages
|
|||||||
{
|
{
|
||||||
return Page();
|
return Page();
|
||||||
}
|
}
|
||||||
|
// plain ordinal sort gets this wrong: the six Tajik-specific letters
|
||||||
|
// (ғ ӣ қ ӯ ҳ ҷ) sit outside the main Cyrillic code point block, so they'd
|
||||||
|
// sort out of alphabetical order (e.g. after "я") under Ordinal - a
|
||||||
|
// culture-aware comparer places them correctly relative to their base
|
||||||
|
// letter (ғ after г, etc). Falls back to Ordinal if "tg-TJ" collation
|
||||||
|
// data isn't available on the server, rather than failing the page.
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var tajikCulture = System.Globalization.CultureInfo.GetCultureInfo("tg-TJ");
|
||||||
|
AlphabeticalPoets = Poets.OrderBy(p => p.Nickname, StringComparer.Create(tajikCulture, false)).ToList();
|
||||||
|
}
|
||||||
|
catch (System.Globalization.CultureNotFoundException)
|
||||||
|
{
|
||||||
|
AlphabeticalPoets = Poets.OrderBy(p => p.Nickname, StringComparer.Ordinal).ToList();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
int pageNumber = 1;
|
int pageNumber = 1;
|
||||||
if (IsSearchPage)
|
if (IsSearchPage)
|
||||||
|
|||||||
@ -693,6 +693,38 @@ html, body {
|
|||||||
margin-top: 14px;
|
margin-top: 14px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* century-grouped vs. alphabetical homepage view switch */
|
||||||
|
.tg-view-switch {
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
gap: 8px;
|
||||||
|
max-width: 480px;
|
||||||
|
margin: 18px auto 0 auto;
|
||||||
|
padding: 0 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tg-view-switch-btn {
|
||||||
|
font-family: 'PT Sans', sans-serif;
|
||||||
|
font-size: 0.9rem;
|
||||||
|
padding: 7px 16px;
|
||||||
|
border: 1px solid var(--tg-rule);
|
||||||
|
border-radius: 20px;
|
||||||
|
background: var(--tg-surface);
|
||||||
|
color: var(--tg-ink-soft);
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tg-view-switch-btn:hover {
|
||||||
|
border-color: var(--tg-accent);
|
||||||
|
color: var(--tg-accent-deep);
|
||||||
|
}
|
||||||
|
|
||||||
|
.tg-view-switch-btn.active {
|
||||||
|
background: var(--tg-accent-deep);
|
||||||
|
border-color: var(--tg-accent-deep);
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
|
|
||||||
/* ---------- error page ---------- */
|
/* ---------- error page ---------- */
|
||||||
|
|
||||||
.text-danger {
|
.text-danger {
|
||||||
|
|||||||
@ -6,6 +6,10 @@
|
|||||||
// clones the matches into the results container. No numeral conversion needed here (unlike the
|
// clones the matches into the results container. No numeral conversion needed here (unlike the
|
||||||
// Persian site, which converts typed digits to Persian-Indic numerals first) since Tajik Cyrillic
|
// Persian site, which converts typed digits to Persian-Indic numerals first) since Tajik Cyrillic
|
||||||
// uses plain Western digits.
|
// uses plain Western digits.
|
||||||
|
//
|
||||||
|
// A "popular" poet's card appears more than once in the page (once in the popular-poets section,
|
||||||
|
// again in their real century group, and again in the alphabetical listing) - deduped here by
|
||||||
|
// data-poet-id so a matching search doesn't show the same poet two or three times.
|
||||||
function tgInlineSearch(value) {
|
function tgInlineSearch(value) {
|
||||||
var resultsNode = document.getElementById('tg-found-poets');
|
var resultsNode = document.getElementById('tg-found-poets');
|
||||||
if (!resultsNode) return;
|
if (!resultsNode) return;
|
||||||
@ -14,10 +18,30 @@ function tgInlineSearch(value) {
|
|||||||
|
|
||||||
var needle = value.toLowerCase();
|
var needle = value.toLowerCase();
|
||||||
var cards = document.querySelectorAll('.tg-poet-card[data-value]');
|
var cards = document.querySelectorAll('.tg-poet-card[data-value]');
|
||||||
|
var seenIds = {};
|
||||||
for (var i = 0; i < cards.length; i++) {
|
for (var i = 0; i < cards.length; i++) {
|
||||||
|
var poetId = cards[i].getAttribute('data-poet-id');
|
||||||
|
if (poetId && seenIds[poetId]) continue;
|
||||||
|
|
||||||
var haystack = cards[i].getAttribute('data-value').toLowerCase();
|
var haystack = cards[i].getAttribute('data-value').toLowerCase();
|
||||||
if (haystack.indexOf(needle) !== -1) {
|
if (haystack.indexOf(needle) !== -1) {
|
||||||
resultsNode.appendChild(cards[i].cloneNode(true));
|
resultsNode.appendChild(cards[i].cloneNode(true));
|
||||||
|
if (poetId) seenIds[poetId] = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Toggles the homepage between the century-grouped view and the flat alphabetical listing.
|
||||||
|
function tgSwitchView(view) {
|
||||||
|
var centuryView = document.getElementById('tg-view-century');
|
||||||
|
var alphaView = document.getElementById('tg-view-alpha');
|
||||||
|
if (!centuryView || !alphaView) return;
|
||||||
|
|
||||||
|
centuryView.style.display = view === 'century' ? '' : 'none';
|
||||||
|
alphaView.style.display = view === 'alpha' ? '' : 'none';
|
||||||
|
|
||||||
|
var buttons = document.querySelectorAll('.tg-view-switch-btn');
|
||||||
|
for (var i = 0; i < buttons.length; i++) {
|
||||||
|
buttons[i].classList.toggle('active', buttons[i].getAttribute('data-view') === view);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user