Generalize detail modal action buttons beyond the blacklisted-only case
Build and Deploy / build-and-deploy (push) Successful in 2m11s

The previous "orphaned" condition (blacklisted && not in library) was
too narrow - a title reached by drilling into another release's
recommends list, or via manual search, is very often not blacklisted
at all, just not something you've acted on yet, and still had no way
to act on it without leaving the modal. Now mirrors MediaCard's own
logic generally, by status/watched combination:
 - IN_LIBRARY: badge only, same as everywhere else.
 - not in library, already watched: "Добавить в Radarr/Sonarr" +
   blacklist toggle, but no "Уже смотрел" (already true).
 - not in library, not watched: all three actions.

The blacklist toggle is now two-way ("Не предлагать" / "Добавить в
рекомендации" depending on current state), matching normal cards
instead of only ever offering the un-hide direction.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
Kayashov.SM
2026-09-18 00:30:52 +04:00
co-authored by Claude Sonnet 5
parent 2188458646
commit e7463c71b2
+25 -14
View File
@@ -55,15 +55,21 @@ export default function MediaDetailModal({ media, onClose, onChanged }) {
}
}
// Being blacklisted is the only way a title is invisible on BOTH
// Рекомендации (excluded there) and Просмотрено (excluded from its normal
// view too, see ScoringService.getWatched) - un-hiding it is what actually
// makes it show up in Рекомендации again, hence the button's wording.
async function addToRecommendations() {
// Two-way toggle, mirroring MediaCard's single "Не предлагать" - here it
// also needs the reverse direction, since a title reached by drilling into
// another release's recommends list is very often one you already
// blacklisted (that's the only way it's invisible on both Рекомендации and
// Просмотрено at once) and this may be the only place you can act on it.
async function toggleBlacklist() {
setBusy(true);
try {
await api.unblacklist(current.id);
setCurrent((c) => ({ ...c, blacklisted: false }));
if (current.blacklisted) {
await api.unblacklist(current.id);
setCurrent((c) => ({ ...c, blacklisted: false }));
} else {
await api.blacklist(current.id);
setCurrent((c) => ({ ...c, blacklisted: true }));
}
onChanged?.();
} finally {
setBusy(false);
@@ -77,10 +83,6 @@ export default function MediaDetailModal({ media, onClose, onChanged }) {
const posterUrl = posterUrlOf(current.posterPath, 'w300');
// Duplicated action buttons only make sense for a title that's otherwise
// invisible everywhere else in the app right now - see addToRecommendations above.
const isOrphaned = current.blacklisted && current.status !== 'IN_LIBRARY';
return (
<div className="modal-backdrop" onClick={onClose}>
<div className="modal" onClick={(e) => e.stopPropagation()}>
@@ -91,13 +93,22 @@ export default function MediaDetailModal({ media, onClose, onChanged }) {
<p style={{ color: 'var(--text-dim)', fontSize: 13, lineHeight: 1.5 }}>
{current.overview || 'Описание недоступно.'}
</p>
{isOrphaned && (
{current.status === 'IN_LIBRARY' ? (
<div className="badge" style={{ marginBottom: 12 }}>В библиотеке</div>
) : (
<div className="actions" style={{ marginBottom: 12 }}>
<button className="primary" disabled={busy} onClick={() => setShowAddModal(true)}>
Добавить в {(current.type === 'SERIES' || current.type === 'CARTOON_SERIES') ? 'Sonarr' : 'Radarr'}
</button>
<button disabled={busy} onClick={addToRecommendations}>Добавить в рекомендации</button>
<button disabled={busy} onClick={markWatched}>Уже смотрел</button>
{/* Already watched (elsewhere, without ever owning it) - marking
it watched again would be redundant, but you may still want
to own it now, or hide/unhide it from Рекомендации. */}
{!current.watched && (
<button disabled={busy} onClick={markWatched}>Уже смотрел</button>
)}
<button disabled={busy} onClick={toggleBlacklist}>
{current.blacklisted ? 'Добавить в рекомендации' : 'Не предлагать'}
</button>
</div>
)}
<div style={{ marginTop: 16 }}>