feat: Add on/off/blurred options to the background image (#442)

Co-authored-by: PartyDonut <PartyDonut@users.noreply.github.com>
This commit is contained in:
PartyDonut 2025-08-09 09:23:47 +02:00 committed by GitHub
parent ef6780b412
commit 715e707bb6
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
8 changed files with 109 additions and 63 deletions

View file

@ -3,6 +3,7 @@ import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:fladder/l10n/generated/app_localizations.dart';
import 'package:fladder/models/settings/client_settings_model.dart';
import 'package:fladder/providers/settings/client_settings_provider.dart';
import 'package:fladder/screens/settings/settings_list_tile.dart';
import 'package:fladder/screens/settings/widgets/settings_label_divider.dart';
@ -90,13 +91,18 @@ List<Widget> buildClientSettingsVisual(
SettingsListTile(
label: Text(context.localized.enableBackgroundPostersTitle),
subLabel: Text(context.localized.enableBackgroundPostersDesc),
onTap: () => ref
.read(clientSettingsProvider.notifier)
.update((cb) => cb.copyWith(backgroundPosters: !clientSettings.backgroundPosters)),
trailing: Switch(
value: clientSettings.backgroundPosters,
onChanged: (value) =>
ref.read(clientSettingsProvider.notifier).update((cb) => cb.copyWith(backgroundPosters: value)),
trailing: EnumBox(
current: clientSettings.backgroundImage.label(context),
itemBuilder: (context) => BackgroundType.values
.map(
(e) => PopupMenuItem(
value: e,
child: Text(e.label(context)),
onTap: () =>
ref.read(clientSettingsProvider.notifier).update((cb) => cb.copyWith(backgroundImage: e)),
),
)
.toList(),
),
),
SettingsListTile(

View file

@ -96,34 +96,37 @@ class _DetailScaffoldState extends ConsumerState<DetailScaffold> {
if (backgroundImage != null)
Align(
alignment: Alignment.topCenter,
child: ShaderMask(
shaderCallback: (bounds) => LinearGradient(
begin: Alignment.topCenter,
end: Alignment.bottomCenter,
colors: [
Colors.white,
Colors.white,
Colors.white,
Colors.white,
Colors.white,
Colors.white.withValues(alpha: 0),
],
).createShader(bounds),
child: ConstrainedBox(
constraints: BoxConstraints(
minWidth: double.infinity,
minHeight: minHeight - 20,
maxHeight: maxHeight.clamp(minHeight, 2500) - 20,
),
child: FadeInImage(
placeholder: backgroundImage!.imageProvider,
placeholderColor: Colors.transparent,
fit: BoxFit.cover,
alignment: Alignment.topCenter,
placeholderFit: BoxFit.cover,
excludeFromSemantics: true,
placeholderFilterQuality: FilterQuality.low,
image: backgroundImage!.imageProvider,
child: Padding(
padding: EdgeInsets.only(left: sideBarPadding),
child: ShaderMask(
shaderCallback: (bounds) => LinearGradient(
begin: Alignment.topCenter,
end: Alignment.bottomCenter,
colors: [
Colors.white,
Colors.white,
Colors.white,
Colors.white,
Colors.white,
Colors.white.withValues(alpha: 0),
],
).createShader(bounds),
child: ConstrainedBox(
constraints: BoxConstraints(
minWidth: double.infinity,
minHeight: minHeight - 20,
maxHeight: maxHeight.clamp(minHeight, 2500) - 20,
),
child: FadeInImage(
placeholder: backgroundImage!.imageProvider,
placeholderColor: Colors.transparent,
fit: BoxFit.cover,
alignment: Alignment.topCenter,
placeholderFit: BoxFit.cover,
excludeFromSemantics: true,
placeholderFilterQuality: FilterQuality.low,
image: backgroundImage!.imageProvider,
),
),
),
),

View file

@ -2,6 +2,8 @@ import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:fladder/providers/settings/client_settings_provider.dart';
class NestedScaffold extends ConsumerWidget {
final Widget body;
final Widget? background;
@ -13,6 +15,7 @@ class NestedScaffold extends ConsumerWidget {
@override
Widget build(BuildContext context, WidgetRef ref) {
final backgroundOpacity = ref.watch(clientSettingsProvider.select((value) => value.backgroundImage.opacityValues));
return Stack(
alignment: Alignment.bottomCenter,
children: [
@ -23,8 +26,8 @@ class NestedScaffold extends ConsumerWidget {
begin: Alignment.topCenter,
end: Alignment.bottomCenter,
colors: [
Theme.of(context).colorScheme.surface.withValues(alpha: 0.85),
Theme.of(context).colorScheme.surface.withValues(alpha: 0.7),
Theme.of(context).colorScheme.surface.withValues(alpha: backgroundOpacity),
Theme.of(context).colorScheme.surface.withValues(alpha: backgroundOpacity - 0.15),
],
),
),