Merge pull request #18 from richardnixondev/chore/remove-nsfw-blur-and-discreet
chore: remove NSFW blur gate and Discreet mode (UI only)
This commit is contained in:
commit
dd293ec117
5 changed files with 8 additions and 137 deletions
|
|
@ -7,7 +7,7 @@ packages = ["src"]
|
|||
|
||||
[project]
|
||||
name = "reddit-media-collector"
|
||||
version = "1.5.3"
|
||||
version = "1.5.4"
|
||||
description = "Self-hosted media collector for Reddit with Immich integration"
|
||||
readme = "README.md"
|
||||
requires-python = ">=3.11"
|
||||
|
|
|
|||
|
|
@ -1101,38 +1101,6 @@ button:hover {
|
|||
font-size: 12px;
|
||||
}
|
||||
|
||||
/* NSFW + discreet */
|
||||
.nsfw-thumb {
|
||||
filter: blur(22px);
|
||||
transition: filter 0.2s;
|
||||
}
|
||||
.show-nsfw .nsfw-thumb {
|
||||
filter: none;
|
||||
}
|
||||
.gallery-item:hover .nsfw-thumb {
|
||||
filter: blur(12px);
|
||||
}
|
||||
.show-nsfw .gallery-item:hover .nsfw-thumb {
|
||||
filter: none;
|
||||
}
|
||||
|
||||
.nsfw-badge {
|
||||
position: absolute;
|
||||
top: 5px;
|
||||
left: 5px;
|
||||
background: rgba(234, 0, 39, 0.95);
|
||||
color: #fff;
|
||||
padding: 2px 6px;
|
||||
border-radius: 3px;
|
||||
font-size: 10px;
|
||||
font-weight: bold;
|
||||
z-index: 6;
|
||||
letter-spacing: 0.5px;
|
||||
}
|
||||
.select-mode .gallery-item .nsfw-badge {
|
||||
left: 38px;
|
||||
}
|
||||
|
||||
.flair-badge {
|
||||
display: inline-block;
|
||||
margin-top: 4px;
|
||||
|
|
@ -1147,41 +1115,6 @@ button:hover {
|
|||
white-space: nowrap;
|
||||
}
|
||||
|
||||
/* Discreet mode: compact grids, no large modals */
|
||||
.discreet .gallery-grid,
|
||||
.discreet .authors-grid {
|
||||
grid-template-columns: repeat(auto-fill, minmax(110px, 1fr)) !important;
|
||||
}
|
||||
.discreet .recent-grid {
|
||||
grid-template-columns: repeat(auto-fill, minmax(140px, 1fr));
|
||||
}
|
||||
.discreet .recent-thumb {
|
||||
width: 36px;
|
||||
height: 36px;
|
||||
}
|
||||
.discreet .gallery-info,
|
||||
.discreet .author-info {
|
||||
padding: 6px;
|
||||
}
|
||||
.discreet .gallery-title,
|
||||
.discreet .author-name {
|
||||
font-size: 11px;
|
||||
}
|
||||
.discreet .flair-badge {
|
||||
display: none;
|
||||
}
|
||||
.discreet-banner {
|
||||
background: #343536;
|
||||
color: #818384;
|
||||
text-align: center;
|
||||
padding: 4px 10px;
|
||||
font-size: 11px;
|
||||
border-bottom: 1px solid #1a1a1b;
|
||||
}
|
||||
body:not(.discreet) .discreet-banner {
|
||||
display: none;
|
||||
}
|
||||
|
||||
/* Tag chips on gallery item (Fase 2 preview) */
|
||||
.tag-chips {
|
||||
display: flex;
|
||||
|
|
|
|||
|
|
@ -400,9 +400,8 @@ async function loadGallery(append = false) {
|
|||
const mediaType = document.getElementById('filter-type').value;
|
||||
const favoritesFilter = document.getElementById('filter-favorites').value;
|
||||
const sortOrder = document.getElementById('filter-sort').value;
|
||||
const nsfwFilter = document.getElementById('filter-nsfw')?.value || 'all';
|
||||
try {
|
||||
let url = `/api/media?limit=${pageSize}&offset=${galleryOffset}&sort=${sortOrder}&nsfw=${nsfwFilter}`;
|
||||
let url = `/api/media?limit=${pageSize}&offset=${galleryOffset}&sort=${sortOrder}`;
|
||||
if (subreddit) url += `&subreddit=${encodeURIComponent(subreddit)}`;
|
||||
if (author) url += `&author=${encodeURIComponent(author)}`;
|
||||
if (mediaType) url += `&media_type=${encodeURIComponent(mediaType)}`;
|
||||
|
|
@ -507,12 +506,9 @@ function appendToGallery(files) {
|
|||
const thumbSrc = isVideo
|
||||
? `/api/media/thumb/${filename}`
|
||||
: `/api/media/file/${filename}`;
|
||||
const isNsfw = !!item.nsfw;
|
||||
const thumbClass = isNsfw ? 'gallery-thumb nsfw-thumb' : 'gallery-thumb';
|
||||
const sourceIcon = item.source_type === 'user' ? '👤' : '📂';
|
||||
const flair = item.flair ? `<div class="flair-badge" title="Flair">${escapeHtml(item.flair)}</div>` : '';
|
||||
const chips = renderTagChips(item.tags);
|
||||
const nsfwBadge = isNsfw ? '<div class="nsfw-badge" title="NSFW">NSFW</div>' : '';
|
||||
const age = relativeTime(item.created_utc);
|
||||
return `
|
||||
<div class="gallery-item" data-id="${item.id}" data-author="${escapeHtml(item.author || '')}" onclick="handleGalleryClick(event, this)">
|
||||
|
|
@ -523,11 +519,10 @@ function appendToGallery(files) {
|
|||
<div class="score-badge ${scoreClass}" title="Score: ${score}">
|
||||
<span>▲</span>${formatScore(score)}
|
||||
</div>
|
||||
${nsfwBadge}
|
||||
${item.is_author_favorite ? '<div class="author-fav-badge" title="Autor favoritado">★ FAV</div>' : ''}
|
||||
<img class="${thumbClass}" src="${thumbSrc}" loading="lazy"
|
||||
<img class="gallery-thumb" src="${thumbSrc}" loading="lazy"
|
||||
onerror="this.style.display='none'; this.nextElementSibling.style.display='flex';">
|
||||
<div class="${thumbClass}" style="display:none;align-items:center;justify-content:center;font-size:48px;">
|
||||
<div class="gallery-thumb" style="display:none;align-items:center;justify-content:center;font-size:48px;">
|
||||
${isVideo ? '🎬' : '🖼️'}
|
||||
</div>
|
||||
${isVideo ? '<div style="position:absolute;bottom:5px;left:5px;background:rgba(0,0,0,0.7);padding:2px 6px;border-radius:3px;font-size:11px;">VIDEO</div>' : ''}
|
||||
|
|
@ -1731,50 +1726,9 @@ window.removeTagRelation = removeTagRelation;
|
|||
// regardless of how many close paths we added. `/api/search` stays in the
|
||||
// backend in case anything wants the universal typeahead by URL.)
|
||||
|
||||
// Alpine.store('prefs') — NSFW gate + discreet mode (Fase 1).
|
||||
document.addEventListener('alpine:init', () => {
|
||||
const stored = JSON.parse(localStorage.getItem('rmc:prefs') || '{}');
|
||||
Alpine.store('prefs', {
|
||||
showNsfw: stored.showNsfw ?? false,
|
||||
discreet: stored.discreet ?? false,
|
||||
toggleNsfw() {
|
||||
this.showNsfw = !this.showNsfw;
|
||||
this.persist();
|
||||
},
|
||||
toggleDiscreet() {
|
||||
this.discreet = !this.discreet;
|
||||
this.persist();
|
||||
},
|
||||
persist() {
|
||||
localStorage.setItem('rmc:prefs', JSON.stringify({
|
||||
showNsfw: this.showNsfw,
|
||||
discreet: this.discreet,
|
||||
}));
|
||||
document.body.classList.toggle('show-nsfw', this.showNsfw);
|
||||
document.body.classList.toggle('discreet', this.discreet);
|
||||
},
|
||||
init() { this.persist(); },
|
||||
});
|
||||
});
|
||||
|
||||
// Auto-discreet after 60s idle (mouse/keyboard stopped).
|
||||
// Hands-off privacy: walk away, screen quietly downsizes thumbs.
|
||||
(function autoDiscreet() {
|
||||
const IDLE_MS = 60 * 1000;
|
||||
let timer = null;
|
||||
function arm() {
|
||||
clearTimeout(timer);
|
||||
timer = setTimeout(() => {
|
||||
if (window.Alpine && Alpine.store('prefs') && !Alpine.store('prefs').discreet) {
|
||||
Alpine.store('prefs').toggleDiscreet();
|
||||
}
|
||||
}, IDLE_MS);
|
||||
}
|
||||
['mousemove', 'keydown', 'click', 'scroll'].forEach(ev =>
|
||||
document.addEventListener(ev, arm, { passive: true })
|
||||
);
|
||||
arm();
|
||||
})();
|
||||
// (NSFW blur gate + Discreet mode + auto-discreet were removed — the blur
|
||||
// did not make sense for the solo home-NAS deploy. Backend keeps the
|
||||
// `posts.nsfw` column and `/api/media?nsfw=` query param for filtering.)
|
||||
|
||||
// Keyboard shortcuts on gallery: j/k navigate, f favorite, b blacklist author,
|
||||
// Esc closes modal or clears selection. Inactive while typing in inputs.
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@
|
|||
<script src="/static/js/api.js?v={{ app_version }}"></script>
|
||||
<script src="/static/js/app.js?v={{ app_version }}" defer></script>
|
||||
</head>
|
||||
<body x-data x-init="$store.prefs.init()">
|
||||
<body>
|
||||
<div class="header">
|
||||
<h1>Reddit Media Collector</h1>
|
||||
<div class="tabs">
|
||||
|
|
@ -21,16 +21,6 @@
|
|||
<button class="tab-btn" onclick="switchTab('sources')">Fontes</button>
|
||||
<button class="tab-btn" onclick="switchTab('tags')">Tags</button>
|
||||
<button class="tab-btn" onclick="switchTab('settings')">Configuracoes</button>
|
||||
<button class="tab-btn"
|
||||
:title="$store.prefs.showNsfw ? 'NSFW visivel — clique para ocultar' : 'NSFW oculto — clique para mostrar'"
|
||||
:style="$store.prefs.showNsfw ? 'color:#ff4500' : ''"
|
||||
@click="$store.prefs.toggleNsfw()"
|
||||
x-text="$store.prefs.showNsfw ? 'NSFW 👁' : 'NSFW 🙈'"></button>
|
||||
<button class="tab-btn"
|
||||
:title="$store.prefs.discreet ? 'Modo discreto ativo' : 'Modo discreto desativado'"
|
||||
:style="$store.prefs.discreet ? 'color:#ff4500' : ''"
|
||||
@click="$store.prefs.toggleDiscreet()"
|
||||
x-text="$store.prefs.discreet ? 'Discreto 🤫' : 'Discreto 👁'"></button>
|
||||
{% if pin_enabled %}
|
||||
<button class="tab-btn" title="Trancar sessao agora"
|
||||
onclick="fetch('/lock',{method:'POST'}).then(()=>location.href='/unlock')">
|
||||
|
|
@ -39,7 +29,6 @@
|
|||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
<div class="discreet-banner">Modo discreto ativo — clique em "Discreto 🤫" para desligar</div>
|
||||
|
||||
<div id="alert" class="alert"></div>
|
||||
|
||||
|
|
|
|||
|
|
@ -24,11 +24,6 @@
|
|||
<option value="score_high">Maior Score</option>
|
||||
<option value="score_low">Menor Score</option>
|
||||
</select>
|
||||
<select id="filter-nsfw" onchange="debouncedLoadGallery()">
|
||||
<option value="all">NSFW: tudo</option>
|
||||
<option value="hide">NSFW: ocultar</option>
|
||||
<option value="only">NSFW: apenas</option>
|
||||
</select>
|
||||
<button class="btn-select-mode" id="btn-select-mode" onclick="toggleSelectMode()">
|
||||
Selecionar
|
||||
</button>
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue