@ -1,9 +1,14 @@
import ' dart:ui ' ;
import ' package:flutter/material.dart ' ;
import ' package:dynamic_color/dynamic_color.dart ' ;
import ' package:flutter_gen/gen_l10n/l10n.dart ' ;
import ' package:matrix/matrix.dart ' ;
import ' package:fluffychat/config/setting_keys.dart ' ;
import ' package:fluffychat/config/themes.dart ' ;
import ' package:fluffychat/pages/chat/events/state_message.dart ' ;
import ' package:fluffychat/utils/account_config.dart ' ;
import ' package:fluffychat/widgets/avatar.dart ' ;
import ' package:fluffychat/widgets/layouts/max_width_body.dart ' ;
@ -32,7 +37,36 @@ class SettingsStyleView extends StatelessWidget {
backgroundColor: theme . colorScheme . surface ,
body: MaxWidthBody (
child: Column (
crossAxisAlignment: CrossAxisAlignment . stretch ,
children: [
Padding (
padding: const EdgeInsets . all ( 12.0 ) ,
child: SegmentedButton < ThemeMode > (
selected: { controller . currentTheme } ,
onSelectionChanged: ( selected ) = >
controller . switchTheme ( selected . single ) ,
segments: [
ButtonSegment (
value: ThemeMode . light ,
label: Text ( L10n . of ( context ) . lightTheme ) ,
icon: const Icon ( Icons . light_mode_outlined ) ,
) ,
ButtonSegment (
value: ThemeMode . dark ,
label: Text ( L10n . of ( context ) . darkTheme ) ,
icon: const Icon ( Icons . dark_mode_outlined ) ,
) ,
ButtonSegment (
value: ThemeMode . system ,
label: Text ( L10n . of ( context ) . systemTheme ) ,
icon: const Icon ( Icons . auto_mode_outlined ) ,
) ,
] ,
) ,
) ,
Divider (
color: theme . dividerColor ,
) ,
ListTile (
title: Text (
L10n . of ( context ) . setColorTheme ,
@ -42,152 +76,61 @@ class SettingsStyleView extends StatelessWidget {
) ,
) ,
) ,
SizedBox (
height: colorPickerSize + 24 ,
child: ListView (
shrinkWrap: true ,
scrollDirection: Axis . horizontal ,
children: SettingsStyleController . customColors
. map (
( color ) = > Padding (
padding: const EdgeInsets . all ( 12.0 ) ,
DynamicColorBuilder (
builder: ( light , dark ) {
final systemColor =
Theme . of ( context ) . brightness = = Brightness . light
? light ? . primary
: dark ? . primary ;
final colors =
List < Color ? > . from ( SettingsStyleController . customColors ) ;
if ( systemColor = = null ) {
colors . remove ( null ) ;
}
return GridView . builder (
shrinkWrap: true ,
gridDelegate: const SliverGridDelegateWithMaxCrossAxisExtent (
maxCrossAxisExtent: 64 ,
) ,
itemCount: colors . length ,
itemBuilder: ( context , i ) {
final color = colors [ i ] ;
return Padding (
padding: const EdgeInsets . all ( 12.0 ) ,
child: Tooltip (
message: color = = null
? L10n . of ( context ) . systemTheme
: ' # ${ color . value . toRadixString ( 16 ) . toUpperCase ( ) } ' ,
child: InkWell (
borderRadius: BorderRadius . circular ( colorPickerSize ) ,
onTap: ( ) = > controller . setChatColor ( color ) ,
child: color = = null
? Material (
elevation: 6 ,
shadowColor: AppConfig . colorSchemeSeed ,
borderRadius:
BorderRadius . circular ( colorPickerSize ) ,
child: DecoratedBox (
decoration: BoxDecoration (
borderRadius: BorderRadius . circular (
colorPickerSize ,
) ,
gradient: FluffyThemes . backgroundGradient (
context ,
255 ,
child: Material (
color: color ? ? systemColor ,
elevation: 6 ,
borderRadius:
BorderRadius . circular ( colorPickerSize ) ,
child: SizedBox (
width: colorPickerSize ,
height: colorPickerSize ,
child: controller . currentColor = = color
? Center (
child: Icon (
Icons . check ,
size: 16 ,
color: Theme . of ( context )
. colorScheme
. onPrimary ,
) ,
) ,
child: SizedBox (
height: colorPickerSize ,
child: Padding (
padding: const EdgeInsets . symmetric (
horizontal: 8.0 ,
) ,
child: Center (
child: Row (
mainAxisSize: MainAxisSize . min ,
children: [
if ( controller . currentColor = =
null )
Padding (
padding:
const EdgeInsets . only (
right: 8.0 ,
) ,
child: Icon (
Icons . check ,
size: 16 ,
color: theme
. colorScheme . onSurface ,
) ,
) ,
Text (
L10n . of ( context ) . systemTheme ,
textAlign: TextAlign . center ,
style: TextStyle (
color: theme
. colorScheme . onSurface ,
) ,
) ,
] ,
) ,
) ,
) ,
) ,
) ,
)
: Material (
color: color ,
elevation: 6 ,
borderRadius:
BorderRadius . circular ( colorPickerSize ) ,
child: SizedBox (
width: colorPickerSize ,
height: colorPickerSize ,
child: controller . currentColor = = color
? const Center (
child: Icon (
Icons . check ,
size: 16 ,
color: Colors . white ,
) ,
)
: null ,
) ,
) ,
)
: null ,
) ,
) ,
) ,
) ,
)
. toList ( ) ,
) ,
) ,
const SizedBox ( height: 8 ) ,
Divider (
color: theme . dividerColor ,
) ,
ListTile (
title: Text (
L10n . of ( context ) . setTheme ,
style: TextStyle (
color: theme . colorScheme . secondary ,
fontWeight: FontWeight . bold ,
) ,
) ,
) ,
RadioListTile < ThemeMode > (
groupValue: controller . currentTheme ,
value: ThemeMode . system ,
title: Text ( L10n . of ( context ) . systemTheme ) ,
onChanged: controller . switchTheme ,
) ,
RadioListTile < ThemeMode > (
groupValue: controller . currentTheme ,
value: ThemeMode . light ,
title: Text ( L10n . of ( context ) . lightTheme ) ,
onChanged: controller . switchTheme ,
) ,
RadioListTile < ThemeMode > (
groupValue: controller . currentTheme ,
value: ThemeMode . dark ,
title: Text ( L10n . of ( context ) . darkTheme ) ,
onChanged: controller . switchTheme ,
) ,
Divider (
color: theme . dividerColor ,
) ,
ListTile (
title: Text (
L10n . of ( context ) . overview ,
style: TextStyle (
color: theme . colorScheme . secondary ,
fontWeight: FontWeight . bold ,
) ,
) ,
) ,
SettingsSwitchListTile . adaptive (
title: L10n . of ( context ) . presencesToggle ,
onChanged: ( b ) = > AppConfig . showPresences = b ,
storeKey: SettingKeys . showPresences ,
defaultValue: AppConfig . showPresences ,
) ,
SettingsSwitchListTile . adaptive (
title: L10n . of ( context ) . separateChatTypes ,
onChanged: ( b ) = > AppConfig . separateChatTypes = b ,
storeKey: SettingKeys . separateChatTypes ,
defaultValue: AppConfig . separateChatTypes ,
) ;
} ,
) ;
} ,
) ,
Divider (
color: theme . dividerColor ,
@ -213,8 +156,6 @@ class SettingsStyleView extends StatelessWidget {
) ,
builder: ( context , snapshot ) {
final accountConfig = client . applicationAccountConfig ;
final wallpaperOpacity = accountConfig . wallpaperOpacity ? ? 1 ;
final wallpaperOpacityIsDefault = wallpaperOpacity = = 1 ;
return Column (
mainAxisSize: MainAxisSize . min ,
@ -222,56 +163,119 @@ class SettingsStyleView extends StatelessWidget {
AnimatedContainer (
duration: FluffyThemes . animationDuration ,
curve: FluffyThemes . animationCurve ,
alignment: Alignment . centerLeft ,
decoration: const BoxDecoration ( ) ,
clipBehavior: Clip . hardEdge ,
child: Stack (
alignment: Alignment . center ,
children: [
if ( accountConfig . wallpaperUrl ! = null )
Opacity (
opacity: wallpaperOpacity ,
child: MxcImage (
uri: accountConfig . wallpaperUrl ,
fit: BoxFit . cover ,
isThumbnail: true ,
width: FluffyThemes . columnWidth * 2 ,
height: 156 ,
opacity: controller . wallpaperOpacity ,
child: ImageFiltered (
imageFilter: ImageFilter . blur (
sigmaX: controller . wallpaperBlur ,
sigmaY: controller . wallpaperBlur ,
) ,
child: MxcImage (
key: ValueKey ( accountConfig . wallpaperUrl ) ,
uri: accountConfig . wallpaperUrl ,
fit: BoxFit . cover ,
isThumbnail: true ,
width: FluffyThemes . columnWidth * 2 ,
height: 212 ,
) ,
) ,
) ,
Padding (
padding: EdgeInsets . only (
left: 12 + 12 + Avatar . defaultSize ,
right: 12 ,
top: accountConfig . wallpaperUrl = = null ? 0 : 12 ,
bottom: 12 ,
) ,
child: Material (
color: theme . colorScheme . primary ,
borderRadius: BorderRadius . circular (
AppConfig . borderRadius ,
Column (
mainAxisSize: MainAxisSize . min ,
children: [
const SizedBox ( height: 16 ) ,
StateMessage (
Event (
eventId: ' style_dummy ' ,
room:
Room ( id: ' !style_dummy ' , client: client ) ,
content: { ' membership ' : ' join ' } ,
type: EventTypes . RoomMember ,
senderId: client . userID ! ,
originServerTs: DateTime . now ( ) ,
stateKey: client . userID ! ,
) ,
) ,
child: Padding (
padding: const EdgeInsets . symmetric (
horizontal: 16 ,
vertical: 8 ,
Padding (
padding: EdgeInsets . only (
left: 12 + 12 + Avatar . defaultSize ,
right: 12 ,
top: accountConfig . wallpaperUrl = = null
? 0
: 12 ,
bottom: 12 ,
) ,
child: Text (
' Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor ' ,
style: TextStyle (
color: theme . colorScheme . onPrimary ,
fontSize: AppConfig . messageFontSize *
AppConfig . fontSizeFactor ,
child: Material (
color: theme . colorScheme . primary ,
borderRadius: BorderRadius . circular (
AppConfig . borderRadius ,
) ,
child: Padding (
padding: const EdgeInsets . symmetric (
horizontal: 16 ,
vertical: 8 ,
) ,
child: Text (
' Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor ' ,
style: TextStyle (
color: theme . colorScheme . onPrimary ,
fontSize: AppConfig . messageFontSize *
AppConfig . fontSizeFactor ,
) ,
) ,
) ,
) ,
) ,
) ,
Align (
alignment: Alignment . centerLeft ,
child: Padding (
padding: EdgeInsets . only (
right: 12 ,
left: 12 ,
top: accountConfig . wallpaperUrl = = null
? 0
: 12 ,
bottom: 12 ,
) ,
child: Material (
color: theme
. colorScheme . surfaceContainerHighest ,
borderRadius: BorderRadius . circular (
AppConfig . borderRadius ,
) ,
child: Padding (
padding: const EdgeInsets . symmetric (
horizontal: 16 ,
vertical: 8 ,
) ,
child: Text (
' Lorem ipsum dolor sit amet ' ,
style: TextStyle (
color: theme . colorScheme . onSurface ,
fontSize: AppConfig . messageFontSize *
AppConfig . fontSizeFactor ,
) ,
) ,
) ,
) ,
) ,
) ,
] ,
) ,
] ,
) ,
) ,
ListTile (
title: Text ( L10n . of ( context ) . wallpaper ) ,
leading: const Icon ( Icons . photo_outlined ) ,
title: OutlinedButton (
onPressed: controller . setWallpaper ,
child: Text ( L10n . of ( context ) . setWallpaper ) ,
) ,
trailing: accountConfig . wallpaperUrl = = null
? null
: IconButton (
@ -279,23 +283,29 @@ class SettingsStyleView extends StatelessWidget {
color: theme . colorScheme . error ,
onPressed: controller . deleteChatWallpaper ,
) ,
onTap: controller . setWallpaper ,
) ,
AnimatedSize (
duration: FluffyThemes . animationDuration ,
curve: FluffyThemes . animationCurve ,
child: accountConfig . wallpaperUrl ! = null
? SwitchListTile . adaptive (
title: Text ( L10n . of ( context ) . transparent ) ,
secondary: const Icon ( Icons . blur_linear_outlined ) ,
value: ! wallpaperOpacityIsDefault ,
onChanged: ( _ ) = >
controller . setChatWallpaperOpacity (
wallpaperOpacityIsDefault ? 0.4 : 1 ,
) ,
)
: null ,
) ,
if ( accountConfig . wallpaperUrl ! = null ) . . . [
ListTile ( title: Text ( L10n . of ( context ) . opacity ) ) ,
Slider . adaptive (
min: 0.1 ,
max: 1.0 ,
divisions: 9 ,
semanticFormatterCallback: ( d ) = > d . toString ( ) ,
value: controller . wallpaperOpacity ,
onChanged: controller . updateWallpaperOpacity ,
onChangeEnd: controller . saveWallpaperOpacity ,
) ,
ListTile ( title: Text ( L10n . of ( context ) . blur ) ) ,
Slider . adaptive (
min: 0.0 ,
max: 10.0 ,
divisions: 10 ,
semanticFormatterCallback: ( d ) = > d . toString ( ) ,
value: controller . wallpaperBlur ,
onChanged: controller . updateWallpaperBlur ,
onChangeEnd: controller . saveWallpaperBlur ,
) ,
] ,
] ,
) ;
} ,
@ -312,6 +322,30 @@ class SettingsStyleView extends StatelessWidget {
semanticFormatterCallback: ( d ) = > d . toString ( ) ,
onChanged: controller . changeFontSizeFactor ,
) ,
Divider (
color: theme . dividerColor ,
) ,
ListTile (
title: Text (
L10n . of ( context ) . overview ,
style: TextStyle (
color: theme . colorScheme . secondary ,
fontWeight: FontWeight . bold ,
) ,
) ,
) ,
SettingsSwitchListTile . adaptive (
title: L10n . of ( context ) . presencesToggle ,
onChanged: ( b ) = > AppConfig . showPresences = b ,
storeKey: SettingKeys . showPresences ,
defaultValue: AppConfig . showPresences ,
) ,
SettingsSwitchListTile . adaptive (
title: L10n . of ( context ) . separateChatTypes ,
onChanged: ( b ) = > AppConfig . separateChatTypes = b ,
storeKey: SettingKeys . separateChatTypes ,
defaultValue: AppConfig . separateChatTypes ,
) ,
] ,
) ,
) ,