mirror of
https://gitlab.com/famedly/fluffychat.git
synced 2024-11-27 23:09:35 +01:00
Merge branch 'krille/adaptivetheme' into 'main'
refactor: Use adaptive_theme See merge request famedly/fluffychat!336
This commit is contained in:
commit
df5134623f
@ -1,6 +1,7 @@
|
||||
import 'package:adaptive_dialog/adaptive_dialog.dart';
|
||||
import 'package:circular_check_box/circular_check_box.dart';
|
||||
import 'package:famedlysdk/famedlysdk.dart';
|
||||
import 'package:fluffychat/config/themes.dart';
|
||||
import 'package:fluffychat/utils/event_extension.dart';
|
||||
import 'package:fluffychat/utils/matrix_locals.dart';
|
||||
import 'package:fluffychat/utils/room_status_extension.dart';
|
||||
@ -18,7 +19,6 @@ import '../dialogs/send_file_dialog.dart';
|
||||
import 'package:future_loading_dialog/future_loading_dialog.dart';
|
||||
import '../matrix.dart';
|
||||
import '../mouse_over_builder.dart';
|
||||
import '../theme_switcher.dart';
|
||||
|
||||
enum ArchivedRoomAction { delete, rejoin }
|
||||
|
||||
@ -142,7 +142,7 @@ class ChatListItem extends StatelessWidget {
|
||||
room.lastEvent?.senderId == Matrix.of(context).client.userID;
|
||||
return Center(
|
||||
child: Material(
|
||||
color: chatListItemColor(context, activeChat, selected),
|
||||
color: FluffyThemes.chatListItemColor(context, activeChat, selected),
|
||||
child: ListTile(
|
||||
onLongPress: onLongPress,
|
||||
leading: MouseOverBuilder(
|
||||
|
@ -1,83 +0,0 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_gen/gen_l10n/l10n.dart';
|
||||
|
||||
import '../components/matrix.dart';
|
||||
import '../components/theme_switcher.dart';
|
||||
|
||||
class ThemesSettings extends StatefulWidget {
|
||||
@override
|
||||
ThemesSettingsState createState() => ThemesSettingsState();
|
||||
}
|
||||
|
||||
class ThemesSettingsState extends State<ThemesSettings> {
|
||||
Themes _selectedTheme;
|
||||
bool _amoledEnabled;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final matrix = Matrix.of(context);
|
||||
final themeEngine = ThemeSwitcherWidget.of(context);
|
||||
_selectedTheme = themeEngine.selectedTheme;
|
||||
_amoledEnabled = themeEngine.amoledEnabled;
|
||||
|
||||
return Column(
|
||||
children: <Widget>[
|
||||
RadioListTile<Themes>(
|
||||
title: Text(
|
||||
L10n.of(context).systemTheme,
|
||||
),
|
||||
value: Themes.system,
|
||||
groupValue: _selectedTheme,
|
||||
activeColor: Theme.of(context).primaryColor,
|
||||
onChanged: (Themes value) {
|
||||
setState(() {
|
||||
_selectedTheme = value;
|
||||
themeEngine.switchTheme(matrix, value, _amoledEnabled);
|
||||
});
|
||||
},
|
||||
),
|
||||
RadioListTile<Themes>(
|
||||
title: Text(
|
||||
L10n.of(context).lightTheme,
|
||||
),
|
||||
value: Themes.light,
|
||||
groupValue: _selectedTheme,
|
||||
activeColor: Theme.of(context).primaryColor,
|
||||
onChanged: (Themes value) {
|
||||
setState(() {
|
||||
_selectedTheme = value;
|
||||
themeEngine.switchTheme(matrix, value, _amoledEnabled);
|
||||
});
|
||||
},
|
||||
),
|
||||
RadioListTile<Themes>(
|
||||
title: Text(
|
||||
L10n.of(context).darkTheme,
|
||||
),
|
||||
value: Themes.dark,
|
||||
groupValue: _selectedTheme,
|
||||
activeColor: Theme.of(context).primaryColor,
|
||||
onChanged: (Themes value) {
|
||||
setState(() {
|
||||
_selectedTheme = value;
|
||||
themeEngine.switchTheme(matrix, value, _amoledEnabled);
|
||||
});
|
||||
},
|
||||
),
|
||||
SwitchListTile(
|
||||
title: Text(
|
||||
L10n.of(context).useAmoledTheme,
|
||||
),
|
||||
value: _amoledEnabled,
|
||||
activeColor: Theme.of(context).primaryColor,
|
||||
onChanged: (bool value) {
|
||||
setState(() {
|
||||
_amoledEnabled = value;
|
||||
themeEngine.switchTheme(matrix, _selectedTheme, value);
|
||||
});
|
||||
},
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
}
|
@ -1,276 +0,0 @@
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'matrix.dart';
|
||||
import '../config/setting_keys.dart';
|
||||
|
||||
enum Themes {
|
||||
light,
|
||||
dark,
|
||||
system,
|
||||
}
|
||||
|
||||
final ThemeData lightTheme = ThemeData(
|
||||
primaryColorDark: Colors.white,
|
||||
primaryColorLight: Color(0xff121212),
|
||||
brightness: Brightness.light,
|
||||
primaryColor: Color(0xFF5625BA),
|
||||
backgroundColor: Colors.white,
|
||||
secondaryHeaderColor: Color(0xFFECECF2),
|
||||
scaffoldBackgroundColor: Colors.white,
|
||||
snackBarTheme: SnackBarThemeData(
|
||||
behavior: kIsWeb ? SnackBarBehavior.floating : SnackBarBehavior.fixed,
|
||||
),
|
||||
dialogTheme: DialogTheme(
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(8.0),
|
||||
),
|
||||
),
|
||||
popupMenuTheme: PopupMenuThemeData(
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(8.0),
|
||||
),
|
||||
),
|
||||
appBarTheme: AppBarTheme(
|
||||
brightness: Brightness.light,
|
||||
color: Colors.white,
|
||||
textTheme: TextTheme(
|
||||
headline6: TextStyle(
|
||||
color: Colors.black,
|
||||
fontSize: 20,
|
||||
),
|
||||
),
|
||||
iconTheme: IconThemeData(color: Colors.black),
|
||||
),
|
||||
);
|
||||
|
||||
final ThemeData darkTheme = ThemeData.dark().copyWith(
|
||||
primaryColorDark: Color(0xff1B1B1B),
|
||||
primaryColorLight: Colors.white,
|
||||
primaryColor: Color(0xFF8966CF),
|
||||
errorColor: Color(0xFFCF6679),
|
||||
backgroundColor: Color(0xff121212),
|
||||
scaffoldBackgroundColor: Color(0xff1B1B1B),
|
||||
accentColor: Color(0xFFF5B4D2),
|
||||
secondaryHeaderColor: Color(0xff202020),
|
||||
snackBarTheme: SnackBarThemeData(
|
||||
behavior: kIsWeb ? SnackBarBehavior.floating : SnackBarBehavior.fixed,
|
||||
),
|
||||
dialogTheme: DialogTheme(
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(8.0),
|
||||
),
|
||||
),
|
||||
popupMenuTheme: PopupMenuThemeData(
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(8.0),
|
||||
),
|
||||
),
|
||||
appBarTheme: AppBarTheme(
|
||||
brightness: Brightness.dark,
|
||||
color: Color(0xff1D1D1D),
|
||||
textTheme: TextTheme(
|
||||
headline6: TextStyle(
|
||||
color: Colors.white,
|
||||
fontSize: 20,
|
||||
),
|
||||
),
|
||||
iconTheme: IconThemeData(color: Colors.white),
|
||||
),
|
||||
);
|
||||
|
||||
final ThemeData amoledTheme = ThemeData.dark().copyWith(
|
||||
primaryColorDark: Color(0xff121212),
|
||||
primaryColorLight: Colors.white,
|
||||
primaryColor: Color(0xFF8966CF),
|
||||
errorColor: Color(0xFFCF6679),
|
||||
backgroundColor: Colors.black,
|
||||
scaffoldBackgroundColor: Colors.black,
|
||||
accentColor: Color(0xFFF5B4D2),
|
||||
secondaryHeaderColor: Color(0xff1D1D1D),
|
||||
snackBarTheme: SnackBarThemeData(
|
||||
behavior: kIsWeb ? SnackBarBehavior.floating : SnackBarBehavior.fixed,
|
||||
),
|
||||
dialogTheme: DialogTheme(
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(8.0),
|
||||
),
|
||||
),
|
||||
popupMenuTheme: PopupMenuThemeData(
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(8.0),
|
||||
),
|
||||
),
|
||||
appBarTheme: AppBarTheme(
|
||||
brightness: Brightness.dark,
|
||||
color: Color(0xff1D1D1D),
|
||||
textTheme: TextTheme(
|
||||
headline6: TextStyle(
|
||||
color: Colors.white,
|
||||
fontSize: 20,
|
||||
),
|
||||
),
|
||||
iconTheme: IconThemeData(color: Colors.white),
|
||||
),
|
||||
);
|
||||
|
||||
Color chatListItemColor(BuildContext context, bool activeChat, bool selected) =>
|
||||
selected
|
||||
? Theme.of(context).primaryColor.withAlpha(100)
|
||||
: Theme.of(context).brightness == Brightness.light
|
||||
? activeChat
|
||||
? Color(0xFFE8E8E8)
|
||||
: Colors.white
|
||||
: activeChat
|
||||
? ThemeSwitcherWidget.of(context).amoledEnabled
|
||||
? Color(0xff121212)
|
||||
: Colors.black
|
||||
: ThemeSwitcherWidget.of(context).amoledEnabled
|
||||
? Colors.black
|
||||
: Color(0xff121212);
|
||||
|
||||
Color blackWhiteColor(BuildContext context) =>
|
||||
Theme.of(context).brightness == Brightness.light
|
||||
? Colors.white
|
||||
: Colors.black;
|
||||
|
||||
class ThemeSwitcher extends InheritedWidget {
|
||||
final ThemeSwitcherWidgetState data;
|
||||
|
||||
const ThemeSwitcher({
|
||||
Key key,
|
||||
@required this.data,
|
||||
@required Widget child,
|
||||
}) : assert(child != null),
|
||||
super(key: key, child: child);
|
||||
|
||||
@override
|
||||
bool updateShouldNotify(ThemeSwitcher old) {
|
||||
return this != old;
|
||||
}
|
||||
}
|
||||
|
||||
class ThemeSwitcherWidget extends StatefulWidget {
|
||||
final Widget child;
|
||||
|
||||
ThemeSwitcherWidget({Key key, @required this.child})
|
||||
: assert(child != null),
|
||||
super(key: key);
|
||||
|
||||
@override
|
||||
ThemeSwitcherWidgetState createState() => ThemeSwitcherWidgetState();
|
||||
|
||||
/// Returns the (nearest) Client instance of your application.
|
||||
static ThemeSwitcherWidgetState of(BuildContext context) {
|
||||
var newState =
|
||||
(context.dependOnInheritedWidgetOfExactType<ThemeSwitcher>()).data;
|
||||
newState.context = context;
|
||||
return newState;
|
||||
}
|
||||
}
|
||||
|
||||
class ThemeSwitcherWidgetState extends State<ThemeSwitcherWidget> {
|
||||
ThemeData themeData;
|
||||
Themes selectedTheme;
|
||||
bool amoledEnabled;
|
||||
@override
|
||||
BuildContext context;
|
||||
|
||||
Future loadSelection(MatrixState matrix) async {
|
||||
var item = await matrix.store.getItem(SettingKeys.theme) ?? 'system';
|
||||
selectedTheme = Themes.values.firstWhere(
|
||||
(e) => e.toString() == 'Themes.' + item,
|
||||
orElse: () => Themes.system);
|
||||
|
||||
amoledEnabled = await matrix.store.getItemBool(SettingKeys.amoledEnabled);
|
||||
|
||||
switchTheme(matrix, selectedTheme, amoledEnabled);
|
||||
return;
|
||||
}
|
||||
|
||||
void switchTheme(
|
||||
MatrixState matrix, Themes newTheme, bool amoled_enabled) async {
|
||||
ThemeData theme;
|
||||
switch (newTheme) {
|
||||
case Themes.light:
|
||||
theme = lightTheme;
|
||||
break;
|
||||
case Themes.dark:
|
||||
if (amoled_enabled) {
|
||||
theme = amoledTheme;
|
||||
} else {
|
||||
theme = darkTheme;
|
||||
}
|
||||
break;
|
||||
case Themes.system:
|
||||
// This needs to be a low level call as we don't have a MaterialApp yet
|
||||
var brightness =
|
||||
MediaQueryData.fromWindow(WidgetsBinding.instance.window)
|
||||
.platformBrightness;
|
||||
if (brightness == Brightness.dark) {
|
||||
if (amoled_enabled) {
|
||||
theme = amoledTheme;
|
||||
} else {
|
||||
theme = darkTheme;
|
||||
}
|
||||
} else {
|
||||
theme = lightTheme;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
await saveThemeValue(matrix, newTheme);
|
||||
await saveAmoledEnabledValue(matrix, amoled_enabled);
|
||||
setState(() {
|
||||
amoledEnabled = amoled_enabled;
|
||||
selectedTheme = newTheme;
|
||||
themeData = theme;
|
||||
});
|
||||
}
|
||||
|
||||
Future saveThemeValue(MatrixState matrix, Themes value) async {
|
||||
await matrix.store
|
||||
.setItem(SettingKeys.theme, value.toString().split('.').last);
|
||||
}
|
||||
|
||||
Future saveAmoledEnabledValue(MatrixState matrix, bool value) async {
|
||||
await matrix.store.setItem(SettingKeys.amoledEnabled, value.toString());
|
||||
}
|
||||
|
||||
void setup() async {
|
||||
final matrix = Matrix.of(context);
|
||||
await loadSelection(matrix);
|
||||
}
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
WidgetsBinding.instance.addPostFrameCallback((_) {
|
||||
if (amoledEnabled == null || selectedTheme == null) {
|
||||
setup();
|
||||
}
|
||||
});
|
||||
super.initState();
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
if (themeData == null) {
|
||||
// This needs to be a low level call as we don't have a MaterialApp yet
|
||||
var brightness = MediaQueryData.fromWindow(WidgetsBinding.instance.window)
|
||||
.platformBrightness;
|
||||
if (brightness == Brightness.dark) {
|
||||
themeData = darkTheme;
|
||||
} else {
|
||||
themeData = lightTheme;
|
||||
}
|
||||
return ThemeSwitcher(
|
||||
data: this,
|
||||
child: widget.child,
|
||||
);
|
||||
} else {
|
||||
return ThemeSwitcher(
|
||||
data: this,
|
||||
child: widget.child,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
90
lib/config/themes.dart
Normal file
90
lib/config/themes.dart
Normal file
@ -0,0 +1,90 @@
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
abstract class FluffyThemes {
|
||||
static ThemeData light = ThemeData(
|
||||
primaryColorDark: Colors.white,
|
||||
primaryColorLight: Color(0xff121212),
|
||||
brightness: Brightness.light,
|
||||
primaryColor: Color(0xFF5625BA),
|
||||
backgroundColor: Colors.white,
|
||||
secondaryHeaderColor: Color(0xFFECECF2),
|
||||
scaffoldBackgroundColor: Colors.white,
|
||||
snackBarTheme: SnackBarThemeData(
|
||||
behavior: kIsWeb ? SnackBarBehavior.floating : SnackBarBehavior.fixed,
|
||||
),
|
||||
dialogTheme: DialogTheme(
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(8.0),
|
||||
),
|
||||
),
|
||||
popupMenuTheme: PopupMenuThemeData(
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(8.0),
|
||||
),
|
||||
),
|
||||
appBarTheme: AppBarTheme(
|
||||
brightness: Brightness.light,
|
||||
color: Colors.white,
|
||||
textTheme: TextTheme(
|
||||
headline6: TextStyle(
|
||||
color: Colors.black,
|
||||
fontSize: 20,
|
||||
),
|
||||
),
|
||||
iconTheme: IconThemeData(color: Colors.black),
|
||||
),
|
||||
);
|
||||
|
||||
static ThemeData dark = ThemeData.dark().copyWith(
|
||||
primaryColorDark: Color(0xff121212),
|
||||
primaryColorLight: Colors.white,
|
||||
primaryColor: Color(0xFF8966CF),
|
||||
errorColor: Color(0xFFCF6679),
|
||||
backgroundColor: Colors.black,
|
||||
scaffoldBackgroundColor: Colors.black,
|
||||
accentColor: Color(0xFFF5B4D2),
|
||||
secondaryHeaderColor: Color(0xff1D1D1D),
|
||||
snackBarTheme: SnackBarThemeData(
|
||||
behavior: kIsWeb ? SnackBarBehavior.floating : SnackBarBehavior.fixed,
|
||||
),
|
||||
dialogTheme: DialogTheme(
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(8.0),
|
||||
),
|
||||
),
|
||||
popupMenuTheme: PopupMenuThemeData(
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(8.0),
|
||||
),
|
||||
),
|
||||
appBarTheme: AppBarTheme(
|
||||
brightness: Brightness.dark,
|
||||
color: Color(0xff1D1D1D),
|
||||
textTheme: TextTheme(
|
||||
headline6: TextStyle(
|
||||
color: Colors.white,
|
||||
fontSize: 20,
|
||||
),
|
||||
),
|
||||
iconTheme: IconThemeData(color: Colors.white),
|
||||
),
|
||||
);
|
||||
|
||||
static Color chatListItemColor(
|
||||
BuildContext context, bool activeChat, bool selected) =>
|
||||
selected
|
||||
? Theme.of(context).primaryColor.withAlpha(100)
|
||||
: Theme.of(context).brightness == Brightness.light
|
||||
? activeChat
|
||||
? Color(0xFFE8E8E8)
|
||||
: Colors.white
|
||||
: activeChat
|
||||
? Color(0xff121212)
|
||||
: Colors.black;
|
||||
|
||||
static Color blackWhiteColor(BuildContext context) =>
|
||||
Theme.of(context).brightness == Brightness.light
|
||||
? Colors.white
|
||||
: Colors.black;
|
||||
}
|
@ -1,6 +1,7 @@
|
||||
// @dart=2.9
|
||||
import 'dart:async';
|
||||
|
||||
import 'package:adaptive_theme/adaptive_theme.dart';
|
||||
import 'package:famedlysdk/famedlysdk.dart';
|
||||
import 'package:fluffychat/utils/sentry_controller.dart';
|
||||
import 'package:fluffychat/views/homeserver_picker.dart';
|
||||
@ -13,7 +14,7 @@ import 'package:future_loading_dialog/future_loading_dialog.dart';
|
||||
import 'package:universal_html/prefer_universal/html.dart' as html;
|
||||
|
||||
import 'components/matrix.dart';
|
||||
import 'components/theme_switcher.dart';
|
||||
import 'config/themes.dart';
|
||||
import 'utils/localized_exception_extension.dart';
|
||||
import 'app_config.dart';
|
||||
import 'views/chat_list.dart';
|
||||
@ -34,32 +35,30 @@ class App extends StatelessWidget {
|
||||
Widget build(BuildContext context) {
|
||||
return Matrix(
|
||||
child: Builder(
|
||||
builder: (BuildContext context) => ThemeSwitcherWidget(
|
||||
child: Builder(
|
||||
builder: (context) => MaterialApp(
|
||||
builder: (BuildContext context) => AdaptiveTheme(
|
||||
light: FluffyThemes.light,
|
||||
dark: FluffyThemes.dark,
|
||||
initial: AdaptiveThemeMode.system,
|
||||
builder: (theme, darkTheme) => MaterialApp(
|
||||
title: '${AppConfig.applicationName}',
|
||||
theme: ThemeSwitcherWidget.of(context).themeData,
|
||||
theme: theme,
|
||||
darkTheme: darkTheme,
|
||||
localizationsDelegates: L10n.localizationsDelegates,
|
||||
supportedLocales: L10n.supportedLocales,
|
||||
locale: kIsWeb
|
||||
? Locale(
|
||||
html.window.navigator.language.split('-').first)
|
||||
? Locale(html.window.navigator.language.split('-').first)
|
||||
: null,
|
||||
home: FutureBuilder<LoginState>(
|
||||
future: Matrix.of(context)
|
||||
.client
|
||||
.onLoginStateChanged
|
||||
.stream
|
||||
.first,
|
||||
future:
|
||||
Matrix.of(context).client.onLoginStateChanged.stream.first,
|
||||
builder: (context, snapshot) {
|
||||
LoadingDialog.defaultTitle =
|
||||
L10n.of(context).loadingPleaseWait;
|
||||
LoadingDialog.defaultTitle = L10n.of(context).loadingPleaseWait;
|
||||
LoadingDialog.defaultBackLabel = L10n.of(context).close;
|
||||
LoadingDialog.defaultOnError =
|
||||
(Object e) => e.toLocalizedString(context);
|
||||
if (snapshot.hasError) {
|
||||
WidgetsBinding.instance.addPostFrameCallback((_) =>
|
||||
FlushbarHelper.createError(
|
||||
WidgetsBinding.instance
|
||||
.addPostFrameCallback((_) => FlushbarHelper.createError(
|
||||
title: L10n.of(context).oopsSomethingWentWrong,
|
||||
message: snapshot.error.toString(),
|
||||
).show(context));
|
||||
@ -78,7 +77,7 @@ class App extends StatelessWidget {
|
||||
return HomeserverPicker();
|
||||
},
|
||||
),
|
||||
)),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
|
@ -1,7 +1,7 @@
|
||||
import 'dart:io';
|
||||
|
||||
import 'package:adaptive_theme/adaptive_theme.dart';
|
||||
import 'package:fluffychat/components/adaptive_page_layout.dart';
|
||||
import 'package:fluffychat/components/settings_themes.dart';
|
||||
import 'package:fluffychat/config/setting_keys.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_gen/gen_l10n/l10n.dart';
|
||||
@ -43,6 +43,23 @@ class _SettingsStyleState extends State<SettingsStyle> {
|
||||
setState(() => null);
|
||||
}
|
||||
|
||||
AdaptiveThemeMode _currentTheme;
|
||||
|
||||
void _switchTheme(AdaptiveThemeMode newTheme, BuildContext context) {
|
||||
switch (newTheme) {
|
||||
case AdaptiveThemeMode.light:
|
||||
AdaptiveTheme.of(context).setLight();
|
||||
break;
|
||||
case AdaptiveThemeMode.dark:
|
||||
AdaptiveTheme.of(context).setDark();
|
||||
break;
|
||||
case AdaptiveThemeMode.system:
|
||||
AdaptiveTheme.of(context).setSystem();
|
||||
break;
|
||||
}
|
||||
setState(() => _currentTheme = newTheme);
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
@ -51,7 +68,24 @@ class _SettingsStyleState extends State<SettingsStyle> {
|
||||
),
|
||||
body: ListView(
|
||||
children: [
|
||||
ThemesSettings(),
|
||||
RadioListTile<AdaptiveThemeMode>(
|
||||
groupValue: _currentTheme,
|
||||
value: AdaptiveThemeMode.system,
|
||||
title: Text(L10n.of(context).systemTheme),
|
||||
onChanged: (t) => _switchTheme(t, context),
|
||||
),
|
||||
RadioListTile<AdaptiveThemeMode>(
|
||||
groupValue: _currentTheme,
|
||||
value: AdaptiveThemeMode.light,
|
||||
title: Text(L10n.of(context).lightTheme),
|
||||
onChanged: (t) => _switchTheme(t, context),
|
||||
),
|
||||
RadioListTile<AdaptiveThemeMode>(
|
||||
groupValue: _currentTheme,
|
||||
value: AdaptiveThemeMode.dark,
|
||||
title: Text(L10n.of(context).darkTheme),
|
||||
onChanged: (t) => _switchTheme(t, context),
|
||||
),
|
||||
Divider(thickness: 1),
|
||||
ListTile(
|
||||
title: Text(
|
||||
|
18
pubspec.lock
18
pubspec.lock
@ -15,6 +15,20 @@ packages:
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.9.3"
|
||||
adaptive_page_layout:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: adaptive_page_layout
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.1.6"
|
||||
adaptive_theme:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: adaptive_theme
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.1.0"
|
||||
analyzer:
|
||||
dependency: transitive
|
||||
description:
|
||||
@ -831,12 +845,12 @@ packages:
|
||||
source: hosted
|
||||
version: "3.0.13"
|
||||
provider:
|
||||
dependency: transitive
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: provider
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "4.3.2+2"
|
||||
version: "4.3.2+4"
|
||||
pub_semver:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -22,6 +22,9 @@ dependencies:
|
||||
cached_network_image: ^2.5.0
|
||||
firebase_messaging: ^7.0.3
|
||||
flutter_local_notifications: ^3.0.3
|
||||
adaptive_page_layout: ^0.1.6
|
||||
provider: ^4.3.2+4
|
||||
adaptive_theme: ^1.1.0
|
||||
# desktop_notifications: ^0.0.0-dev.4 // Currently blocked by: https://github.com/canonical/desktop_notifications.dart/issues/5
|
||||
matrix_link_text: ^0.3.2
|
||||
path_provider: ^1.6.27
|
||||
|
Loading…
Reference in New Issue
Block a user