Skip to content

Commit 1278400

Browse files
committed
新增:添加 NSFW 图片模糊显示功能
1 parent b38943b commit 1278400

File tree

4 files changed

+54
-9
lines changed

4 files changed

+54
-9
lines changed

frontend/src/App.vue

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,9 @@
44
<AppNavbar
55
:nsfw="nsfw"
66
:dark-mode="darkMode"
7+
:blur-nsfw="blurNsfw"
78
@toggle-nsfw="toggleNsfw"
9+
@toggle-blur-nsfw="toggleBlurNsfw"
810
@toggle-dark-mode="toggleDarkMode"
911
@open-settings="openSettings"
1012
@open-filter-sidebar="openFilterSidebar"
@@ -23,6 +25,7 @@
2325
<ModelDetailModal
2426
ref="modelDetailModalRef"
2527
:model="selectedModel"
28+
:blur-nsfw="blurNsfw"
2629
@close="closeModelDetail"
2730
/>
2831

@@ -38,6 +41,7 @@
3841
:progress-message="progressMessage"
3942
:error="error"
4043
:nsfw="nsfw"
44+
:blur-nsfw="blurNsfw"
4145
@model-click="openModelDetails"
4246
@open-settings="openSettings"
4347
/>
@@ -84,6 +88,7 @@ const modelPath = ref('');
8488
const models = ref<Model[]>([]);
8589
const nsfw = ref(false);
8690
const darkMode = ref(false);
91+
const blurNsfw = ref(true);
8792
const loading = ref(false);
8893
const progress = ref(0);
8994
const progressMessage = ref('');
@@ -176,6 +181,12 @@ function toggleNsfw() {
176181
localStorage.setItem('nsfw', String(nsfw.value));
177182
}
178183
184+
function toggleBlurNsfw() {
185+
blurNsfw.value = !blurNsfw.value;
186+
// 保存设置到 localStorage
187+
localStorage.setItem('blurNsfw', String(blurNsfw.value));
188+
}
189+
179190
function toggleDarkMode() {
180191
darkMode.value = !darkMode.value;
181192
const theme = darkMode.value ? 'dark' : 'light';
@@ -311,6 +322,12 @@ onMounted(async () => {
311322
nsfw.value = savedNsfw === 'true';
312323
}
313324
325+
// 从 localStorage 加载模糊设置
326+
const savedBlurNsfw = localStorage.getItem('blurNsfw');
327+
if (savedBlurNsfw !== null) {
328+
blurNsfw.value = savedBlurNsfw === 'true';
329+
}
330+
314331
// 加载暗色模式设置
315332
const savedTheme = localStorage.getItem('theme');
316333
if (savedTheme) {

frontend/src/components/AppNavbar.vue

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,19 @@
1818
<span>NSFW {{ nsfw ? '已开启' : '已关闭' }}</span>
1919
</button>
2020

21+
<button
22+
type="button"
23+
:class="blurNsfw ? 'btn btn-outline btn-neutral' : 'btn btn-outline btn-error'"
24+
title="NSFW图片模糊控制"
25+
@click="toggleBlurNsfw"
26+
>
27+
<span class="icon-[tabler--blur] size-5 me-1.5" v-if="blurNsfw"></span>
28+
<span class="icon-[tabler--blur-off] size-5 me-1.5" v-else></span>
29+
<span>模糊{{ blurNsfw ? '开' : '关' }}</span>
30+
</button>
31+
32+
<div class="w-3"></div>
33+
2134
<button
2235
type="button"
2336
class="btn btn-icon btn-outline btn-neutral"
@@ -54,10 +67,12 @@
5467
defineProps<{
5568
nsfw: boolean;
5669
darkMode: boolean;
70+
blurNsfw: boolean;
5771
}>();
5872
5973
const emit = defineEmits<{
6074
'toggle-nsfw': [];
75+
'toggle-blur-nsfw': [];
6176
'toggle-dark-mode': [];
6277
'open-settings': [];
6378
'open-filter-sidebar': [];
@@ -67,6 +82,10 @@ function toggleNsfw() {
6782
emit('toggle-nsfw');
6883
}
6984
85+
function toggleBlurNsfw() {
86+
emit('toggle-blur-nsfw');
87+
}
88+
7089
function toggleDarkMode() {
7190
emit('toggle-dark-mode');
7291
}

frontend/src/components/ModelDetailModal.vue

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -33,11 +33,15 @@
3333
<div class="modal-body p-6">
3434
<div class="grid grid-cols-1 md:grid-cols-3 gap-6">
3535
<div class="md:col-span-2">
36-
<img
37-
v-if="model?.preview"
38-
:src="model.preview"
39-
class="w-full rounded-lg"
40-
:alt="model?.name">
36+
<div v-if="model?.preview" class="overflow-hidden rounded-lg">
37+
<img
38+
:src="model.preview"
39+
:class="[
40+
'w-full transition-all duration-300',
41+
{ 'blur-2xl': model.nsfw && blurNsfw }
42+
]"
43+
:alt="model?.name">
44+
</div>
4145
<div
4246
v-else
4347
class="flex flex-col items-center justify-center p-12 rounded-lg bg-base-200">
@@ -78,6 +82,7 @@ import type { Model } from '../api/models';
7882
7983
defineProps<{
8084
model: Model | null;
85+
blurNsfw: boolean;
8186
}>();
8287
8388
const emit = defineEmits<{

frontend/src/components/ModelList.vue

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -26,22 +26,25 @@
2626
class="rounded-lg shadow-sm hover:shadow-md transition-all duration-200 transform hover:-translate-y-1 cursor-pointer h-full flex flex-col bg-base-100 border border-base-200"
2727
>
2828
<div
29-
class="relative pt-[125%] cursor-pointer"
29+
class="relative pt-[125%] cursor-pointer overflow-hidden rounded-t-lg"
3030
@click="onModelClick(model)"
3131
>
3232
<img
3333
v-if="model.preview && (nsfw || !model.nsfw)"
3434
:src="model.preview"
35-
class="absolute inset-0 w-full h-full object-cover rounded-t-lg"
35+
:class="[
36+
'absolute inset-0 w-full h-full object-cover transition-all duration-300',
37+
{ 'blur-2xl': model.nsfw && blurNsfw }
38+
]"
3639
:alt="model.name">
3740
<div
3841
v-else
39-
class="absolute inset-0 flex items-center justify-center rounded-t-lg bg-base-200">
42+
class="absolute inset-0 flex items-center justify-center bg-base-200">
4043
<span class="icon-[tabler--photo] size-10 text-base-content opacity-50"></span>
4144
</div>
4245
<div
4346
v-if="model.nsfw"
44-
class="badge badge-error absolute top-2 right-2"
47+
class="badge badge-error absolute top-2 right-2 z-10"
4548
>NSFW</div>
4649
</div>
4750
<div
@@ -109,6 +112,7 @@ defineProps<{
109112
progressMessage: string;
110113
error: string;
111114
nsfw: boolean;
115+
blurNsfw: boolean;
112116
}>();
113117
114118
const emit = defineEmits<{

0 commit comments

Comments
 (0)