improved performance and battery usage on older devices

This commit is contained in:
2026-09-25 23:58:08 +02:00
parent ed8e52f475
commit 56a497985b
70 changed files with 1631 additions and 621 deletions
+20 -4
View File
@@ -8,6 +8,7 @@ import '../state/app/modules/settings/bloc/settings_cubit.dart';
import '../storage/chat_background_settings.dart';
import '../theming/app_theme.dart';
import '../utils/app_paths.dart';
import '../utils/screen_bound_image.dart';
/// Renders the configurable chat background behind [child].
///
@@ -24,7 +25,13 @@ class ChatBackground extends StatelessWidget {
@override
Widget build(BuildContext context) {
final s = context.watch<SettingsCubit>().val().chatBackgroundSettings;
// Value snapshot: the settings object is mutated in place, so only copied
// values can tell whether the background actually changed.
context.select((SettingsCubit c) {
final s = c.state.chatBackgroundSettings;
return (s.type, s.fit, s.colorValue, s.imageVersion, s.dim, s.blur);
});
final s = context.read<SettingsCubit>().val().chatBackgroundSettings;
final dark = AppTheme.isDarkMode(context);
final Widget background;
@@ -32,7 +39,9 @@ class ChatBackground extends StatelessWidget {
case ChatBackgroundType.none:
background = ColoredBox(color: Theme.of(context).colorScheme.surface);
case ChatBackgroundType.color:
background = ColoredBox(color: Color(s.colorValue ?? _fallbackColor.toARGB32()));
background = ColoredBox(
color: Color(s.colorValue ?? _fallbackColor.toARGB32()),
);
case ChatBackgroundType.pattern:
background = _imageLayer(
const AssetImage('assets/background/chat.png'),
@@ -41,12 +50,17 @@ class ChatBackground extends StatelessWidget {
isPattern: true,
);
case ChatBackgroundType.image:
final image = FileImage(File(AppPaths.chatBackgroundImage));
background = KeyedSubtree(
// imageVersion changes on every replacement, forcing a fresh subtree
// alongside the explicit ImageCache evict in the settings handler.
key: ValueKey(s.imageVersion),
// Only "cover" scales the photo to the screen; tile/center render
// it unscaled, so those keep the natural size.
child: _imageLayer(
FileImage(File(AppPaths.chatBackgroundImage)),
s.fit == ChatBackgroundFit.cover
? screenBoundImage(context, image)
: image,
s,
dark,
isPattern: false,
@@ -57,7 +71,9 @@ class ChatBackground extends StatelessWidget {
return Stack(
fit: StackFit.expand,
children: [
Positioned.fill(child: background),
// Own layer: without it every scroll frame of the message list above
// repaints the (possibly tiled or blurred) background as well.
Positioned.fill(child: RepaintBoundary(child: background)),
if (s.dim > 0)
Positioned.fill(
child: ColoredBox(color: Colors.black.withValues(alpha: s.dim)),