Projects (GanjooRazor -> DivanRazor, GanjoorService.sln -> DivanService.sln), files, folders, classes, namespaces, settings, API routes (/api/divan) and DB tables (Divan*). External addresses (ganjoor.net, github.com/ganjoor) unchanged. Migrations renamed consistently (no pending model changes); requires a fresh database. Upstream RUNNING_LOCALLY/SEMANTIC_SEARCH docs archived unmodified under docs/. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
283 lines
15 KiB
Plaintext
283 lines
15 KiB
Plaintext
@page
|
|
@model DivanRazor.Areas.User.Pages.SuggestQuotedModel
|
|
@using DNTPersianUtils.Core
|
|
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
|
|
@{
|
|
Layout = "_UserPanelLayout";
|
|
ViewData["Title"] = "پیشنهاد مشق شعر";
|
|
await DivanRazor.Utils.DivanSessionChecker.ApplyPermissionsToViewData(Request, Response, ViewData);
|
|
}
|
|
|
|
<div class="up-page-header">
|
|
<h1>@ViewData["Title"]</h1>
|
|
</div>
|
|
|
|
@if (!string.IsNullOrEmpty(Model.LastMessage))
|
|
{
|
|
<div class="up-alert up-alert--danger">@Html.Raw(Model.LastMessage)</div>
|
|
}
|
|
|
|
@if (Model.DivanQuotedPoem != null && Model.Couplets != null)
|
|
{
|
|
<script>
|
|
|
|
function selectDivanPage() {
|
|
document.getElementById('display-frame').style.display = 'none';
|
|
document.getElementById('select-poem').style.display = 'block';
|
|
document.getElementById('finalize-select').style.display = 'block';
|
|
document.getElementById('finalize-select2').style.display = 'block';
|
|
}
|
|
|
|
function getCouplets(verses) {
|
|
let coupetIndex = -1;
|
|
let coupletText = "";
|
|
let coupletIndices = [];
|
|
let coupletTexts = [];
|
|
let verseIndex = 0;
|
|
let incompleteCouplet = false;
|
|
|
|
while (verseIndex < verses.length) {
|
|
switch (verses[verseIndex].versePosition) {
|
|
case 5: // Comment
|
|
incompleteCouplet = false;
|
|
break;
|
|
case -1: // Paragraph
|
|
case 4: // Single
|
|
incompleteCouplet = false;
|
|
if (coupletText) {
|
|
coupletIndices.push(coupetIndex);
|
|
coupletTexts.push(coupletText);
|
|
coupletText = "";
|
|
}
|
|
coupetIndex++;
|
|
coupletIndices.push(coupetIndex);
|
|
coupletTexts.push(verses[verseIndex].text);
|
|
break;
|
|
case 0: // Right
|
|
case 2: // CenteredVerse1
|
|
incompleteCouplet = false;
|
|
if (coupletText) {
|
|
coupletIndices.push(coupetIndex);
|
|
coupletTexts.push(coupletText);
|
|
}
|
|
coupetIndex++;
|
|
coupletText = verses[verseIndex].text;
|
|
break;
|
|
case 1: // Left
|
|
case 3: // CenteredVerse2
|
|
incompleteCouplet = true;
|
|
coupletText += ` - ${verses[verseIndex].text}`;
|
|
break;
|
|
}
|
|
verseIndex++;
|
|
}
|
|
|
|
if (incompleteCouplet && coupletText) {
|
|
coupletIndices.push(coupetIndex);
|
|
coupletTexts.push(coupletText);
|
|
}
|
|
|
|
return { coupletIndices, coupletTexts };
|
|
}
|
|
|
|
|
|
|
|
function finalizeSelectPage() {
|
|
document.getElementById('loading-selection').style.display = 'block';
|
|
document.getElementById('finalize-select2').style.display = 'none';
|
|
document.getElementById('display-frame').style.display = 'block';
|
|
document.getElementById('select-poem').style.display = 'none';
|
|
document.getElementById('finalize-select').style.display = 'none';
|
|
|
|
|
|
const currentUrl = document.getElementById('select-poem').contentWindow.location.href;
|
|
|
|
var url = currentUrl.substring(currentUrl.indexOf('/', currentUrl.indexOf('//') + 2));
|
|
|
|
fetch('@(DivanRazor.APIRoot.InternetUrl)/api/divan/page?url=' + url)
|
|
.then((response) => response.json())
|
|
.then((json) => {
|
|
|
|
if (json.poem == null) {
|
|
document.getElementById('loading-selection').style.display = 'none';
|
|
upToast('صفحهای که انتخاب کردهاید حاوی یک شعر نیست.', 'error');
|
|
selectDivanPage();
|
|
return;
|
|
}
|
|
|
|
document.getElementById('DivanQuotedPoem_RelatedPoemId').value = json.poem.id;
|
|
document.getElementById('DivanQuotedPoem_RelatedPoetId').value = json.poem.category.poet.id;
|
|
document.getElementById('DivanQuotedPoem_CachedRelatedPoemPoetName').value = json.poem.category.poet.nickname;
|
|
document.getElementById('DivanQuotedPoem_CachedRelatedPoemPoetDeathYearInLHijri').value = json.poem.category.poet.deathYearInLHijri.toString();
|
|
document.getElementById('DivanQuotedPoem_CachedRelatedPoemPoetUrl').value = json.poem.category.poet.fullUrl;
|
|
document.getElementById('DivanQuotedPoem_CachedRelatedPoemPoetImage').value = json.poem.category.poet.imageUrl;
|
|
document.getElementById('DivanQuotedPoem_CachedRelatedPoemFullTitle').value = json.poem.fullTitle;
|
|
document.getElementById('DivanQuotedPoem_CachedRelatedPoemFullUrl').value = json.poem.fullUrl;
|
|
|
|
const result = getCouplets(json.poem.verses);
|
|
var coupletIndices = result.coupletIndices;
|
|
var coupletTexts = result.coupletTexts;
|
|
|
|
var x = document.getElementById("DivanQuotedPoem_RelatedCoupletIndex");
|
|
x.length = 0;
|
|
for (var i = 0; i < coupletIndices.length; i++) {
|
|
var option = document.createElement("option");
|
|
option.text = bshfarsinum((i + 1).toString()) + ' - ' + coupletTexts[i];
|
|
option.value = coupletIndices[i];
|
|
x.add(option);
|
|
}
|
|
|
|
x.value = coupletIndices[0];
|
|
document.getElementById('loading-selection').style.display = 'none';
|
|
|
|
}).catch((error) => {
|
|
document.getElementById('loading-selection').style.display = 'none';
|
|
upToast('در انتخاب صفحه خطایی رخ داد. جزئیات بیشتر: ' + error, 'error');
|
|
selectDivanPage();
|
|
});
|
|
|
|
}
|
|
|
|
</script>
|
|
<div class="up-alert up-alert--info">
|
|
<p class="up-mt-0">از این طریق میتوانید نقل قول یک شاعر از یک شاعر دیگر را در دیوان ثبت کنید. توجه داشته باشید که اقتفا (یکسانی قافیه) دلیل کافی بر نقل قول نیست. باید در شعرها حداقل یک مصرع بعینه (با تخفیف تفاوت جزئی واژگان) نقل قول شده باشد.</p>
|
|
</div>
|
|
<div class="up-card">
|
|
<form method="post" class="up-form">
|
|
@Html.AntiForgeryToken()
|
|
<div class="up-alert up-alert--info">
|
|
<p class="up-mt-0">از فهرست زیر بیتی را که نقل قول در آن رخ داده مشخص کنید.</p>
|
|
</div>
|
|
|
|
<p>
|
|
بیت مرجع از <a href="/?p=@Model.DivanQuotedPoem.PoemId">شعر</a>:
|
|
<input type="hidden" asp-for="DivanQuotedPoem.Id" />
|
|
<input type="hidden" asp-for="DivanQuotedPoem.PoemId" />
|
|
<input type="hidden" asp-for="DivanQuotedPoem.PoetId" />
|
|
</p>
|
|
|
|
<div class="up-field">
|
|
<label for="DivanQuotedPoem_CoupletIndex">بیت</label>
|
|
<select asp-for="DivanQuotedPoem.CoupletIndex">
|
|
@foreach (var item in Model.Couplets)
|
|
{
|
|
<option value="@item.Item1">@($"{(item.Item1 + 1).ToPersianNumbers()} - {item.Item2}")</option>
|
|
}
|
|
</select>
|
|
</div>
|
|
|
|
<div class="up-check-row">
|
|
<input asp-for="DivanQuotedPoem.CoupletVerse1ShouldBeEmphasized" />
|
|
<label for="DivanQuotedPoem_CoupletVerse1ShouldBeEmphasized">نقل قول در مصرع اول</label>
|
|
</div>
|
|
<div class="up-check-row">
|
|
<input asp-for="DivanQuotedPoem.CoupletVerse2ShouldBeEmphasized" />
|
|
<label for="DivanQuotedPoem_CoupletVerse2ShouldBeEmphasized">نقل قول در مصرع دوم</label>
|
|
</div>
|
|
|
|
<div class="up-alert up-alert--info">
|
|
<p class="up-mt-0">اگر شعر مرتبط در دیوان وجود دارد آن را با «گزینش شعر مرتبط» و پیدا کردن آن در صفحهای که باز میشود مشخص کنید.</p>
|
|
</div>
|
|
|
|
<a onclick="finalizeSelectPage()" class="up-btn up-btn--ghost" role="button" id="finalize-select2" style="display:none">انتخاب کردم</a>
|
|
<iframe id="select-poem" src="/" height="600" style="display:none;width:100%;margin:auto"></iframe>
|
|
|
|
<div class="up-btn-group">
|
|
<a onclick="selectDivanPage()" class="up-btn up-btn--ghost" role="button" id="display-frame">🔎 گزینش شعر مرتبط</a>
|
|
<input asp-for="DivanQuotedPoem.RelatedPoemId" type="hidden" />
|
|
<a onclick="finalizeSelectPage()" class="up-btn up-btn--ghost" role="button" id="finalize-select" style="display:none">انتخاب کردم</a>
|
|
<div id="loading-selection" style="display:none"><img src="/image/loading.gif" /></div>
|
|
</div>
|
|
|
|
@if (Model.DivanQuotedPoem.RelatedPoemId != null)
|
|
{
|
|
<p><a href="/?p=@Model.DivanQuotedPoem.RelatedPoemId">🔗 مشاهدهٔ شعر مرتبط</a></p>
|
|
}
|
|
|
|
<div class="up-field">
|
|
<label for="DivanQuotedPoem_RelatedCoupletIndex">بیت مرتبط</label>
|
|
<select asp-for="DivanQuotedPoem.RelatedCoupletIndex">
|
|
@foreach (var item in Model.RelatedCouplets)
|
|
{
|
|
<option value="@item.Item1">@($"{(item.Item1 + 1).ToPersianNumbers()} - {item.Item2}")</option>
|
|
}
|
|
</select>
|
|
</div>
|
|
|
|
<div class="up-alert up-alert--info">
|
|
<p class="up-mt-0">اگر شعر مرتبط در دیوان وجود ندارد مصرع اول و دوم مرتبط آن را در کادرهای بعد تایپ کنید.</p>
|
|
</div>
|
|
|
|
<div class="up-field">
|
|
<label for="DivanQuotedPoem_RelatedCoupletVerse1">مصرع اول مرتبط (خارج از دیوان)</label>
|
|
<p class="up-hint">اگر شعر را از طریق دکمهٔ «گزینش شعر مرتبط» انتخاب کردهاید کادر زیر را خالی بگذارید.</p>
|
|
<input asp-for="DivanQuotedPoem.RelatedCoupletVerse1" size="65" />
|
|
</div>
|
|
<div class="up-check-row">
|
|
<input asp-for="DivanQuotedPoem.RelatedCoupletVerse1ShouldBeEmphasized" />
|
|
<label for="DivanQuotedPoem_RelatedCoupletVerse1ShouldBeEmphasized">نقل قول در مصرع اول شعر مرتبط</label>
|
|
</div>
|
|
|
|
<div class="up-field">
|
|
<label for="DivanQuotedPoem_RelatedCoupletVerse2">مصرع دوم مرتبط (خارج از دیوان)</label>
|
|
<p class="up-hint">اگر شعر را از طریق دکمهٔ «گزینش شعر مرتبط» انتخاب کردهاید کادر زیر را خالی بگذارید.</p>
|
|
<input asp-for="DivanQuotedPoem.RelatedCoupletVerse2" size="65" />
|
|
</div>
|
|
<div class="up-check-row">
|
|
<input asp-for="DivanQuotedPoem.RelatedCoupletVerse2ShouldBeEmphasized" />
|
|
<label for="DivanQuotedPoem_RelatedCoupletVerse2ShouldBeEmphasized">نقل قول در مصرع دوم شعر مرتبط</label>
|
|
<input asp-for="DivanQuotedPoem.SortOrder" hidden />
|
|
</div>
|
|
|
|
<div class="up-check-row">
|
|
<input asp-for="DivanQuotedPoem.IsPriorToRelated" />
|
|
<label for="DivanQuotedPoem_IsPriorToRelated">این شعر قدیمیتر از شعر مرتبط است</label>
|
|
<input asp-for="DivanQuotedPoem.ChosenForMainList" type="hidden" />
|
|
<input asp-for="DivanQuotedPoem.IndirectQuotation" type="hidden" />
|
|
</div>
|
|
|
|
<div class="up-check-row">
|
|
<input asp-for="DivanQuotedPoem.ClaimedByBothPoets" />
|
|
<label for="DivanQuotedPoem_ClaimedByBothPoets">منتسب به هر دو شاعر</label>
|
|
</div>
|
|
|
|
<div class="up-field">
|
|
<label for="DivanQuotedPoem_CachedRelatedPoemPoetName">شاعر</label>
|
|
<input asp-for="DivanQuotedPoem.RelatedPoetId" hidden />
|
|
<input asp-for="DivanQuotedPoem.CachedRelatedPoemPoetName" />
|
|
</div>
|
|
<div class="up-field">
|
|
<label for="DivanQuotedPoem_CachedRelatedPoemPoetDeathYearInLHijri">سالمرگ شاعر</label>
|
|
<input asp-for="DivanQuotedPoem.CachedRelatedPoemPoetDeathYearInLHijri" />
|
|
</div>
|
|
<div class="up-field up-field--ltr">
|
|
<label for="DivanQuotedPoem_CachedRelatedPoemPoetUrl">نشانی صفحهٔ شاعر</label>
|
|
<input asp-for="DivanQuotedPoem.CachedRelatedPoemPoetUrl" size="65" />
|
|
<input asp-for="DivanQuotedPoem.CachedRelatedPoemPoetImage" type="hidden" />
|
|
</div>
|
|
<div class="up-field">
|
|
<label for="DivanQuotedPoem_CachedRelatedPoemFullTitle">عنوان شعر</label>
|
|
<input asp-for="DivanQuotedPoem.CachedRelatedPoemFullTitle" size="65" />
|
|
</div>
|
|
<div class="up-field up-field--ltr">
|
|
<label for="DivanQuotedPoem_CachedRelatedPoemFullUrl">نشانی شعر</label>
|
|
<input asp-for="DivanQuotedPoem.CachedRelatedPoemFullUrl" size="65" />
|
|
<input asp-for="DivanQuotedPoem.Published" hidden />
|
|
<input asp-for="DivanQuotedPoem.SamePoemsQuotedCount" hidden />
|
|
</div>
|
|
|
|
<div class="up-field">
|
|
<label for="DivanQuotedPoem_Note"><span class="up-field-icon" aria-hidden="true">🗒️</span> یادداشت</label>
|
|
<textarea asp-for="DivanQuotedPoem.Note" rows="4" cols="80" class="editor"></textarea>
|
|
</div>
|
|
|
|
<div class="up-hint">نیازی به پیشنهاد معکوس این نقل قول نیست. در صورت تأیید، معکوس آن هم به طور خودکار ایجاد میشود.</div>
|
|
|
|
<div class="up-form-actions">
|
|
<input type="submit" value="پیشنهاد" class="up-btn up-btn--success up-btn--block" />
|
|
</div>
|
|
</form>
|
|
</div>
|
|
|
|
}
|