implemented a customizable chat background system with support for patterns, solid colors, and gallery images; added a dedicated settings page with live preview and adjustable blur/dim effects, updated the image cropper to support flexible aspect ratios for wallpapers, and integrated file cleanup logic during account logout.

This commit is contained in:
2026-05-31 19:20:18 +02:00
parent 5ebf5bccdb
commit 6e12da08c0
14 changed files with 771 additions and 14 deletions
+46
View File
@@ -0,0 +1,46 @@
import 'package:json_annotation/json_annotation.dart';
part 'chat_background_settings.g.dart';
/// Source of the chat background.
/// * [pattern] — the bundled tiled asset (legacy default, dark-mode inverted)
/// * [image] — a user-picked image stored at [AppPaths.chatBackgroundImage]
/// * [color] — a single solid colour ([ChatBackgroundSettings.colorValue])
/// * [none] — plain theme surface colour
enum ChatBackgroundType { pattern, image, color, none }
/// How [ChatBackgroundType.pattern]/[ChatBackgroundType.image] fill the area.
enum ChatBackgroundFit { cover, tile, center }
@JsonSerializable()
class ChatBackgroundSettings {
ChatBackgroundType type;
ChatBackgroundFit fit;
/// ARGB colour for [ChatBackgroundType.color]; null until the user picks one.
int? colorValue;
/// Monotonically increasing cache-buster. The image lives under a constant
/// filename, so Flutter's [ImageCache] can't tell a replacement apart — this
/// counter drives a [ValueKey] that forces a fresh subtree after a swap.
int imageVersion;
/// Strength of the black dim overlay drawn above the background (0..1).
double dim;
/// Gaussian blur sigma applied to the pattern/image layer (0..~25).
double blur;
ChatBackgroundSettings({
required this.type,
required this.fit,
required this.colorValue,
required this.imageVersion,
required this.dim,
required this.blur,
});
factory ChatBackgroundSettings.fromJson(Map<String, dynamic> json) =>
_$ChatBackgroundSettingsFromJson(json);
Map<String, dynamic> toJson() => _$ChatBackgroundSettingsToJson(this);
}
@@ -0,0 +1,42 @@
// GENERATED CODE - DO NOT MODIFY BY HAND
part of 'chat_background_settings.dart';
// **************************************************************************
// JsonSerializableGenerator
// **************************************************************************
ChatBackgroundSettings _$ChatBackgroundSettingsFromJson(
Map<String, dynamic> json,
) => ChatBackgroundSettings(
type: $enumDecode(_$ChatBackgroundTypeEnumMap, json['type']),
fit: $enumDecode(_$ChatBackgroundFitEnumMap, json['fit']),
colorValue: (json['colorValue'] as num?)?.toInt(),
imageVersion: (json['imageVersion'] as num).toInt(),
dim: (json['dim'] as num).toDouble(),
blur: (json['blur'] as num).toDouble(),
);
Map<String, dynamic> _$ChatBackgroundSettingsToJson(
ChatBackgroundSettings instance,
) => <String, dynamic>{
'type': _$ChatBackgroundTypeEnumMap[instance.type]!,
'fit': _$ChatBackgroundFitEnumMap[instance.fit]!,
'colorValue': instance.colorValue,
'imageVersion': instance.imageVersion,
'dim': instance.dim,
'blur': instance.blur,
};
const _$ChatBackgroundTypeEnumMap = {
ChatBackgroundType.pattern: 'pattern',
ChatBackgroundType.image: 'image',
ChatBackgroundType.color: 'color',
ChatBackgroundType.none: 'none',
};
const _$ChatBackgroundFitEnumMap = {
ChatBackgroundFit.cover: 'cover',
ChatBackgroundFit.tile: 'tile',
ChatBackgroundFit.center: 'center',
};
+3
View File
@@ -1,6 +1,7 @@
import 'package:flutter/material.dart';
import 'package:json_annotation/json_annotation.dart';
import 'chat_background_settings.dart';
import 'dev_tools_settings.dart';
import 'file_settings.dart';
import 'file_view_settings.dart';
@@ -22,6 +23,7 @@ class Settings {
ModulesSettings modulesSettings;
TimetableSettings timetableSettings;
TalkSettings talkSettings;
ChatBackgroundSettings chatBackgroundSettings;
FileSettings fileSettings;
HolidaysSettings holidaysSettings;
FileViewSettings fileViewSettings;
@@ -35,6 +37,7 @@ class Settings {
required this.modulesSettings,
required this.timetableSettings,
required this.talkSettings,
required this.chatBackgroundSettings,
required this.fileSettings,
required this.holidaysSettings,
required this.fileViewSettings,
+4
View File
@@ -18,6 +18,9 @@ Settings _$SettingsFromJson(Map<String, dynamic> json) => Settings(
talkSettings: TalkSettings.fromJson(
json['talkSettings'] as Map<String, dynamic>,
),
chatBackgroundSettings: ChatBackgroundSettings.fromJson(
json['chatBackgroundSettings'] as Map<String, dynamic>,
),
fileSettings: FileSettings.fromJson(
json['fileSettings'] as Map<String, dynamic>,
),
@@ -44,6 +47,7 @@ Map<String, dynamic> _$SettingsToJson(Settings instance) => <String, dynamic>{
'modulesSettings': instance.modulesSettings.toJson(),
'timetableSettings': instance.timetableSettings.toJson(),
'talkSettings': instance.talkSettings.toJson(),
'chatBackgroundSettings': instance.chatBackgroundSettings.toJson(),
'fileSettings': instance.fileSettings.toJson(),
'holidaysSettings': instance.holidaysSettings.toJson(),
'fileViewSettings': instance.fileViewSettings.toJson(),