Apply texas's pathc to reblur content

This commit is contained in:
2025-09-07 02:34:51 +08:00
parent 77b6ce9937
commit 3281d69eba

View File

@@ -802,97 +802,119 @@ class _CloudFileListEntry extends HookConsumerWidget {
this.onTap, this.onTap,
}); });
@override @override
Widget build(BuildContext context, WidgetRef ref) { Widget build(BuildContext context, WidgetRef ref) {
final dataSaving = ref.watch( final dataSaving = ref.watch(
appSettingsNotifierProvider.select((s) => s.dataSavingMode), appSettingsNotifierProvider.select((s) => s.dataSavingMode),
); );
final showMature = useState(false); final showMature = useState(false);
final showDataSaving = useState(!dataSaving); final showDataSaving = useState(!dataSaving);
final lockedByDS = dataSaving && !showDataSaving.value; final lockedByDS = dataSaving && !showDataSaving.value;
final lockedByMature = file.sensitiveMarks.isNotEmpty && !showMature.value; final lockedByMature = file.sensitiveMarks.isNotEmpty && !showMature.value;
final meta = file.fileMeta is Map ? file.fileMeta as Map : const {}; final meta = file.fileMeta is Map ? file.fileMeta as Map : const {};
final ratio = (meta['ratio'] is num && (meta['ratio'] as num) != 0) final ratio =
? (meta['ratio'] as num).toDouble() (meta['ratio'] is num && (meta['ratio'] as num) != 0)
: 1.0; ? (meta['ratio'] as num).toDouble()
: 1.0;
Widget bg = const SizedBox.shrink(); Widget bg = const SizedBox.shrink();
if (isImage) { if (isImage) {
if (meta['blur'] is String) { if (meta['blur'] is String) {
bg = BlurHash(hash: meta['blur'] as String); bg = BlurHash(hash: meta['blur'] as String);
} else if (!lockedByDS && !lockedByMature) { } else if (!lockedByDS && !lockedByMature) {
bg = ImageFiltered( bg = ImageFiltered(
imageFilter: ImageFilter.blur(sigmaX: 10, sigmaY: 10), imageFilter: ImageFilter.blur(sigmaX: 10, sigmaY: 10),
child: CloudFileWidget( child: CloudFileWidget(
item: file, item: file,
noBlurhash: true, noBlurhash: true,
useInternalGate: false, useInternalGate: false,
), ),
); );
} else { } else {
bg = const ColoredBox(color: Colors.black26); bg = const ColoredBox(color: Colors.black26);
} }
} }
final bool fullyUnlocked = !lockedByDS && !lockedByMature; final bool fullyUnlocked = !lockedByDS && !lockedByMature;
Widget fg = fullyUnlocked Widget fg =
? (isImage fullyUnlocked
? CloudFileWidget( ? (isImage
item: file, ? CloudFileWidget(
heroTag: heroTag, item: file,
noBlurhash: true, heroTag: heroTag,
fit: BoxFit.contain, noBlurhash: true,
useInternalGate: false, fit: BoxFit.contain,
) useInternalGate: false,
: CloudFileWidget( )
item: file, : CloudFileWidget(
heroTag: heroTag, item: file,
fit: BoxFit.contain, heroTag: heroTag,
useInternalGate: false, fit: BoxFit.contain,
) useInternalGate: false,
) ))
: AspectRatio(aspectRatio: ratio, child: const SizedBox.shrink()); : AspectRatio(aspectRatio: ratio, child: const SizedBox.shrink());
Widget overlays; Widget overlays;
if (lockedByDS) { if (lockedByDS) {
overlays = _DataSavingOverlay(); overlays = _DataSavingOverlay();
} else if (lockedByMature) { } else if (file.sensitiveMarks.isNotEmpty) {
overlays = _SensitiveOverlay(file: file); overlays = _SensitiveOverlay(
file: file,
isRevealed: showMature.value,
onHide: () => showMature.value = false,
);
} else { } else {
overlays = const SizedBox.shrink(); overlays = const SizedBox.shrink();
} }
final content = Stack( final content = Stack(
fit: StackFit.expand, fit: StackFit.expand,
children: [ children: [if (isImage) Positioned.fill(child: bg), fg, overlays],
if (isImage) Positioned.fill(child: bg),
fg,
overlays,
],
); );
return InkWell( return InkWell(
borderRadius: const BorderRadius.all(Radius.circular(16)), borderRadius: const BorderRadius.all(Radius.circular(16)),
onTap: () { onTap: () {
if (lockedByDS) { if (lockedByDS) {
showDataSaving.value = true; showDataSaving.value = true;
} else if (lockedByMature) { } else if (lockedByMature) {
showMature.value = true; showMature.value = true;
} else { } else {
onTap?.call(); onTap?.call();
} }
}, },
child: content, child: content,
); );
} }
} }
class _SensitiveOverlay extends StatelessWidget { class _SensitiveOverlay extends StatelessWidget {
final SnCloudFile file; final SnCloudFile file;
const _SensitiveOverlay({required this.file}); final VoidCallback? onHide;
final bool isRevealed;
const _SensitiveOverlay({
required this.file,
this.onHide,
this.isRevealed = false,
});
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
if (isRevealed) {
return Positioned(
top: 3,
left: 4,
child: IconButton(
iconSize: 16,
constraints: const BoxConstraints(),
icon: const Icon(Icons.visibility_off, color: Colors.white),
tooltip: 'Blur content',
onPressed: onHide,
),
);
}
return BackdropFilter( return BackdropFilter(
filter: ImageFilter.blur(sigmaX: 64, sigmaY: 64), filter: ImageFilter.blur(sigmaX: 64, sigmaY: 64),
child: Container( child: Container(
@@ -928,6 +950,7 @@ class _DataSavingOverlay extends StatelessWidget {
); );
} }
} }
class _OverlayCard extends StatelessWidget { class _OverlayCard extends StatelessWidget {
final IconData icon; final IconData icon;
final String title; final String title;
@@ -956,15 +979,20 @@ class _OverlayCard extends StatelessWidget {
children: [ children: [
Icon(icon, color: Colors.white, size: 24), Icon(icon, color: Colors.white, size: 24),
const Gap(4), const Gap(4),
Text(title, Text(
style: const TextStyle( title,
color: Colors.white, fontWeight: FontWeight.w600), style: const TextStyle(
textAlign: TextAlign.center), color: Colors.white,
Text(subtitle, fontWeight: FontWeight.w600,
style: const TextStyle(color: Colors.white, fontSize: 13)), ),
textAlign: TextAlign.center,
),
Text(
subtitle,
style: const TextStyle(color: Colors.white, fontSize: 13),
),
const Gap(4), const Gap(4),
Text(hint, Text(hint, style: const TextStyle(color: Colors.white, fontSize: 11)),
style: const TextStyle(color: Colors.white, fontSize: 11)),
], ],
), ),
); );