Files
f0ckm/views/snippets/visibility-modal.html
T
2026-09-28 23:24:50 +02:00

145 lines
8.7 KiB
HTML

{{-- Item visibility modal (shared by item-partial-modern / item-partial-legacy). JS hooks: #visibility-modal, #visibility-item-id, input[name=visibility], #visibility-modal-cancel/-save --}}
<div id="visibility-modal" class="modal-overlay" style="display: none;">
<div class="modal-content vis-modal-content">
<div class="vis-header">
<button type="button" class="modal-x" aria-label="Close" title="Close" onclick="document.getElementById('visibility-modal-cancel').click()">&times;</button>
<h3><i class="fa-solid fa-eye"></i> Change visibility</h3>
<p>Choose who can see this post.</p>
</div>
<div class="vis-body">
<form id="visibility-form" onsubmit="return false;">
<input type="hidden" id="visibility-item-id" value="{{ item.id }}" />
<div class="visibility-options">
<label class="visibility-option">
<input type="radio" name="visibility" value="0" />
<span class="vis-radio"></span>
<span class="vis-text">
<strong><i class="fa-solid fa-globe"></i> Public</strong>
<span>Visible to everyone in main feeds, search, and rankings.</span>
</span>
</label>
<label class="visibility-option">
<input type="radio" name="visibility" value="1" />
<span class="vis-radio"></span>
<span class="vis-text">
<strong><i class="fa-solid fa-link"></i> Unlisted</strong>
<span>Hidden from main feeds; accessible only via direct link or slug.</span>
</span>
</label>
<label class="visibility-option">
<input type="radio" name="visibility" value="2" />
<span class="vis-radio"></span>
<span class="vis-text">
<strong><i class="fa-solid fa-lock"></i> Private</strong>
<span>Only visible to you and site moderators.</span>
</span>
</label>
@if(is_mod_or_admin)
<label class="visibility-option vis-danger">
<input type="radio" name="visibility" value="3" />
<span class="vis-radio"></span>
<span class="vis-text">
<strong><i class="fa-solid fa-ban"></i> Unavailable (451)</strong>
<span>Only visible to administrators. Serves HTTP 451 on direct media for all other users.</span>
</span>
</label>
@endif
</div>
</form>
</div>
<div class="modal-actions vis-footer">
<button type="button" class="btn-secondary" id="visibility-modal-cancel">Cancel</button>
<button type="button" class="btn-primary" id="visibility-modal-save">Save visibility</button>
</div>
</div>
</div>
<style>
/* Visibility modal — same rules as the report/info modals: square, flat, fixed header/footer, full screen on phones */
#visibility-modal .vis-modal-content {
--vm-accent: var(--accent, #0096ff);
--vm-text: var(--text-color, #fff);
--vm-muted: var(--text-muted, #8a8f98);
--vm-surface: rgba(255, 255, 255, 0.04);
--vm-border: rgba(255, 255, 255, 0.1);
--vm-danger: #ff5c5c;
width: min(440px, 92vw);
max-height: min(90vh, 90dvh);
display: flex; flex-direction: column; overflow: hidden;
padding: 0; text-align: left;
border-radius: 0 !important;
border: 1px solid var(--accent) !important;
background: var(--bg) !important;
box-shadow: 0 0 20px rgba(0, 0, 0, 0.5) !important;
color: var(--vm-text);
}
#visibility-modal .vis-modal-content * { border-radius: 0 !important; }
#visibility-modal .vis-header { position: relative; flex-shrink: 0; padding: 20px 64px 14px 24px; border-bottom: 1px solid var(--vm-border); }
#visibility-modal .vis-header h3 { display: flex; align-items: center; gap: 10px; margin: 0; font-size: 1.2em; font-weight: 700; color: var(--vm-text); }
#visibility-modal .vis-header h3 i { color: var(--vm-accent); font-size: 0.9em; }
#visibility-modal .vis-header p { margin: 6px 0 0; font-size: 0.85em; color: var(--vm-muted); }
#visibility-modal .vis-body { flex: 1 1 auto; min-height: 0; overflow-y: auto; overscroll-behavior: contain; padding: 16px 24px; }
#visibility-modal .visibility-options { display: flex; flex-direction: column; gap: 6px; }
#visibility-modal .visibility-option {
display: flex; align-items: flex-start; gap: 12px; margin: 0; padding: 12px 14px;
background: var(--vm-surface); border: 1px solid var(--vm-border);
cursor: pointer; user-select: none; transition: border-color 0.15s, background 0.15s;
}
#visibility-modal .visibility-option:hover { border-color: rgba(255, 255, 255, 0.22); }
#visibility-modal .visibility-option:has(input:checked) { border-color: var(--vm-accent); background: color-mix(in srgb, var(--vm-accent) 8%, transparent); }
#visibility-modal .visibility-option input { position: absolute; opacity: 0; width: 0; height: 0; margin: 0; }
#visibility-modal .vis-radio {
position: relative; width: 18px; height: 18px; flex-shrink: 0; margin-top: 1px;
border: 1px solid rgba(255, 255, 255, 0.28); background: var(--vm-surface); transition: border-color 0.15s;
}
#visibility-modal .vis-radio::after {
content: ''; position: absolute; inset: 4px; background: var(--vm-accent); transform: scale(0); transition: transform 0.15s;
}
#visibility-modal .visibility-option input:checked + .vis-radio { border-color: var(--vm-accent); }
#visibility-modal .visibility-option input:checked + .vis-radio::after { transform: scale(1); }
#visibility-modal .visibility-option input:focus-visible + .vis-radio { outline: 2px solid var(--vm-accent); outline-offset: 2px; }
#visibility-modal .vis-text { display: flex; flex-direction: column; gap: 3px; font-size: 0.88em; line-height: 1.4; }
#visibility-modal .vis-text strong { display: flex; align-items: center; gap: 7px; color: var(--vm-text); font-weight: 700; }
#visibility-modal .vis-text strong i { width: 14px; text-align: center; color: var(--vm-muted); }
#visibility-modal .visibility-option:has(input:checked) .vis-text strong i { color: var(--vm-accent); }
#visibility-modal .vis-text > span { color: var(--vm-muted); }
#visibility-modal .vis-danger .vis-text strong,
#visibility-modal .vis-danger .vis-text strong i { color: var(--vm-danger); }
#visibility-modal .vis-danger:has(input:checked) { border-color: var(--vm-danger); background: rgba(255, 92, 92, 0.08); }
#visibility-modal .vis-danger input:checked + .vis-radio { border-color: var(--vm-danger); }
#visibility-modal .vis-danger .vis-radio::after { background: var(--vm-danger); }
#visibility-modal .vis-footer {
flex-shrink: 0; display: flex; justify-content: flex-end; gap: 8px; margin: 0;
padding: 14px 24px; border-top: 1px solid var(--vm-border); background: rgba(0, 0, 0, 0.2);
}
#visibility-modal .vis-footer button {
height: 40px; margin: 0; padding: 0 18px; font: inherit; font-size: 0.85em; cursor: pointer;
display: inline-flex; align-items: center; justify-content: center;
transition: background 0.18s, color 0.18s, border-color 0.18s;
}
#visibility-modal #visibility-modal-cancel { background: transparent; border: 1px solid var(--vm-border); color: var(--vm-muted); font-weight: 600; }
#visibility-modal #visibility-modal-cancel:hover { color: var(--vm-text); border-color: rgba(255, 255, 255, 0.25); background: var(--vm-surface); }
#visibility-modal #visibility-modal-save {
background: var(--vm-accent); border: 1px solid var(--vm-accent); color: #000;
font-weight: 800; text-transform: uppercase; letter-spacing: 0.08em;
}
#visibility-modal #visibility-modal-save:hover:not(:disabled) { background: transparent; color: var(--vm-accent); }
#visibility-modal #visibility-modal-save:disabled { opacity: 0.6; cursor: progress; }
#visibility-modal .vis-footer button:focus-visible { outline: 2px solid var(--vm-accent); outline-offset: 2px; }
@media (max-width: 600px) {
#visibility-modal { padding: 0 !important; align-items: stretch !important; }
#visibility-modal .vis-modal-content {
width: 100vw; max-width: none;
height: 100vh; height: 100dvh; max-height: none;
border: 0 !important; box-shadow: none !important;
}
#visibility-modal .vis-footer { padding-bottom: calc(14px + env(safe-area-inset-bottom, 0px)); }
#visibility-modal .vis-footer button { flex: 1; }
}
</style>