Merge branch 'theme-add-dark-theme' into 'master'

Add dark Theme!

Closes #9

See merge request ChristianPauly/fluffychat-flutter!24
This commit is contained in:
Christian Pauly 2020-02-16 14:57:50 +00:00
commit 38ef2b7807
16 changed files with 577 additions and 111 deletions

View file

@ -0,0 +1,285 @@
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import '../utils/famedlysdk_store.dart';
import 'matrix.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,
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(
title: TextStyle(
color: Colors.black,
fontSize: 20,
),
),
iconTheme: IconThemeData(color: Colors.black),
),
);
final ThemeData darkTheme = ThemeData.dark().copyWith(
primaryColorDark: Color(0xff121212),
primaryColorLight: Colors.white,
primaryColor: Color(0xFF5625BA),
backgroundColor: Color(0xff121212),
scaffoldBackgroundColor: Color(0xff121212),
accentColor: Color(0xFFF5B4D2),
secondaryHeaderColor: Color(0xff1D1D1D),
appBarTheme: AppBarTheme(
brightness: Brightness.dark,
color: Color(0xff1D1D1D),
textTheme: TextTheme(
title: 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(0xFF5625BA),
backgroundColor: Colors.black,
scaffoldBackgroundColor: Colors.black,
accentColor: Color(0xFFF5B4D2),
secondaryHeaderColor: Color(0xff1D1D1D),
appBarTheme: AppBarTheme(
brightness: Brightness.dark,
color: Color(0xff1D1D1D),
textTheme: TextTheme(
title: TextStyle(
color: Colors.white,
fontSize: 20,
),
),
iconTheme: IconThemeData(color: Colors.white),
),
);
Color chatListItemColor(BuildContext context, bool activeChat) =>
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, 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) {
ThemeSwitcherWidgetState newState =
(context.dependOnInheritedWidgetOfExactType<ThemeSwitcher>()).data;
newState.context = context;
return newState;
}
}
class ThemeSwitcherWidgetState extends State<ThemeSwitcherWidget> {
ThemeData themeData;
Themes selectedTheme;
bool amoledEnabled;
BuildContext context;
Future loadSelection(MatrixState matrix) async {
if (kIsWeb) {
Store store = matrix.client.storeAPI;
String item = await store.getItem("theme") ?? "light";
selectedTheme =
Themes.values.firstWhere((e) => e.toString() == 'Themes.' + item);
amoledEnabled =
(await store.getItem("amoled_enabled") ?? "false").toLowerCase() ==
'true';
} else {
ExtendedStore store = matrix.client.storeAPI;
String item = await store.getItem("theme") ?? "light";
selectedTheme =
Themes.values.firstWhere((e) => e.toString() == 'Themes.' + item);
amoledEnabled =
(await store.getItem("amoled_enabled") ?? "false").toLowerCase() ==
'true';
}
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
Brightness 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 {
if (kIsWeb) {
Store store = matrix.client.storeAPI;
await store.setItem("theme", value.toString().split('.').last);
} else {
ExtendedStore store = matrix.client.storeAPI;
await store.setItem("theme", value.toString().split('.').last);
}
}
Future saveAmoledEnabledValue(MatrixState matrix, bool value) async {
if (kIsWeb) {
Store store = matrix.client.storeAPI;
await store.setItem("amoled_enabled", value.toString());
} else {
ExtendedStore store = matrix.client.storeAPI;
await store.setItem("amoled_enabled", value.toString());
}
}
void setup() async {
final MatrixState matrix = Matrix.of(context);
await loadSelection(matrix);
if (selectedTheme == null) {
switchTheme(matrix, Themes.light, false);
} else {
switch (selectedTheme) {
case Themes.light:
switchTheme(matrix, Themes.light, false);
break;
case Themes.dark:
if (amoledEnabled) {
switchTheme(matrix, Themes.dark, true);
} else {
switchTheme(matrix, Themes.dark, false);
}
break;
case Themes.system:
switchTheme(matrix, Themes.system, false);
break;
}
}
}
@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
Brightness 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,
);
}
}
}

View file

@ -1,18 +1,19 @@
import 'package:famedlysdk/famedlysdk.dart';
import 'package:fluffychat/components/dialogs/simple_dialogs.dart';
import 'package:fluffychat/i18n/i18n.dart';
import 'package:fluffychat/utils/event_extension.dart';
import 'package:fluffychat/utils/date_time_extension.dart';
import 'package:fluffychat/utils/app_route.dart';
import 'package:fluffychat/utils/room_extension.dart';
import 'package:fluffychat/views/chat.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter_slidable/flutter_slidable.dart';
import 'package:toast/toast.dart';
import 'package:pedantic/pedantic.dart';
import 'package:toast/toast.dart';
import '../../i18n/i18n.dart';
import '../../utils/app_route.dart';
import '../../utils/date_time_extension.dart';
import '../../utils/event_extension.dart';
import '../../utils/room_extension.dart';
import '../../views/chat.dart';
import '../ThemeSwitcher.dart';
import '../avatar.dart';
import '../dialogs/simple_dialogs.dart';
import '../matrix.dart';
class ChatListItem extends StatelessWidget {
@ -133,7 +134,7 @@ class ChatListItem extends StatelessWidget {
onWillDismiss: (actionType) => archiveAction(context),
),
child: Material(
color: activeChat ? Color(0xFFE8E8E8) : Colors.white,
color: chatListItemColor(context, activeChat),
child: ListTile(
leading: Avatar(room.avatar, room.displayname),
title: Row(

View file

@ -44,7 +44,11 @@ class Message extends StatelessWidget {
BubbleNip nip = sameSender
? BubbleNip.no
: ownMessage ? BubbleNip.rightBottom : BubbleNip.leftBottom;
final Color textColor = ownMessage ? Colors.white : Colors.black;
final Color textColor = ownMessage
? Colors.white
: Theme.of(context).brightness == Brightness.dark
? Colors.white
: Colors.black;
MainAxisAlignment rowMainAxisAlignment =
ownMessage ? MainAxisAlignment.end : MainAxisAlignment.start;

View file

@ -1,14 +1,9 @@
import 'dart:async';
import 'dart:convert';
import 'dart:io';
import 'package:firebase_messaging/firebase_messaging.dart';
import 'package:famedlysdk/famedlysdk.dart';
import 'package:fluffychat/i18n/i18n.dart';
import 'package:fluffychat/utils/app_route.dart';
import 'package:fluffychat/utils/event_extension.dart';
import 'package:fluffychat/utils/famedlysdk_store.dart';
import 'package:fluffychat/utils/room_extension.dart';
import 'package:fluffychat/views/chat.dart';
import 'package:firebase_messaging/firebase_messaging.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter_local_notifications/flutter_local_notifications.dart';
@ -16,6 +11,13 @@ import 'package:localstorage/localstorage.dart';
import 'package:path_provider/path_provider.dart';
import 'package:toast/toast.dart';
import '../i18n/i18n.dart';
import '../utils/app_route.dart';
import '../utils/event_extension.dart';
import '../utils/famedlysdk_store.dart';
import '../utils/room_extension.dart';
import '../views/chat.dart';
class Matrix extends StatefulWidget {
final Widget child;
@ -295,7 +297,7 @@ class MatrixState extends State<Matrix> {
client.storeAPI = kIsWeb ? Store(client) : ExtendedStore(client);
debugPrint(
"[Store] Store is extended: ${client.storeAPI.extended.toString()}");
if (await initLoginState == LoginState.logged) {
if (await initLoginState == LoginState.logged && !kIsWeb) {
await setupFirebase();
}
}

View file

@ -569,6 +569,16 @@ class I18n {
String get signUp => Intl.message("Sign up");
String get changeTheme => Intl.message("Change your style");
String get systemTheme => Intl.message("System");
String get lightTheme => Intl.message("Light");
String get darkTheme => Intl.message("Dark");
String get useAmoledTheme => Intl.message("Use Amoled compatible colors?");
String get sourceCode => Intl.message("Source code");
String get startYourFirstChat => Intl.message("Start your first chat :-)");

View file

@ -892,6 +892,31 @@
"type": "text",
"placeholders": {}
},
"Change your style": "Change your style",
"@Change your style": {
"type": "text",
"placeholders": {}
},
"System": "System",
"@System": {
"type": "text",
"placeholders": {}
},
"Light": "Hell",
"@Light": {
"type": "text",
"placeholders": {}
},
"Dark": "Dunkel",
"@Dark": {
"type": "text",
"placeholders": {}
},
"Use Amoled compatible colors?": "Amoled optimierte Farben verwenden?",
"@Use Amoled compatible colors?": {
"type": "text",
"placeholders": {}
},
"Source code": "Quellcode",
"@Source code": {
"type": "text",

View file

@ -892,6 +892,31 @@
"type": "text",
"placeholders": {}
},
"Change your style": "Change your style",
"@Change your style": {
"type": "text",
"placeholders": {}
},
"System": "System",
"@System": {
"type": "text",
"placeholders": {}
},
"Light": "Light",
"@Light": {
"type": "text",
"placeholders": {}
},
"Dark": "Dark",
"@Dark": {
"type": "text",
"placeholders": {}
},
"Use Amoled compatible colors?": "Use Amoled compatible colors?",
"@Use Amoled compatible colors?": {
"type": "text",
"placeholders": {}
},
"Source code": "Source code",
"@Source code": {
"type": "text",

View file

@ -150,6 +150,7 @@ class MessageLookup extends MessageLookupByLibrary {
"Ban from chat" : MessageLookupByLibrary.simpleMessage("Aus dem Chat verbannen"),
"Banned" : MessageLookupByLibrary.simpleMessage("Banned"),
"Change the name of the group" : MessageLookupByLibrary.simpleMessage("Gruppenname ändern"),
"Change your style" : MessageLookupByLibrary.simpleMessage("Change your style"),
"Changelog" : MessageLookupByLibrary.simpleMessage("Changelog"),
"Chat details" : MessageLookupByLibrary.simpleMessage("Gruppeninfo"),
"Choose a username" : MessageLookupByLibrary.simpleMessage("Wähle einen Benutzernamen"),
@ -166,6 +167,7 @@ class MessageLookup extends MessageLookupByLibrary {
"Create" : MessageLookupByLibrary.simpleMessage("Create"),
"Create account now" : MessageLookupByLibrary.simpleMessage("Account jetzt erstellen"),
"Create new group" : MessageLookupByLibrary.simpleMessage("Neue Gruppe"),
"Dark" : MessageLookupByLibrary.simpleMessage("Dunkel"),
"Delete" : MessageLookupByLibrary.simpleMessage("Löschen"),
"Delete message" : MessageLookupByLibrary.simpleMessage("Nachricht löschen"),
"Discard picture" : MessageLookupByLibrary.simpleMessage("Bild verwerfen"),
@ -199,6 +201,7 @@ class MessageLookup extends MessageLookupByLibrary {
"Leave" : MessageLookupByLibrary.simpleMessage("Verlassen"),
"Left the chat" : MessageLookupByLibrary.simpleMessage("Hat den Chat verlassen"),
"License" : MessageLookupByLibrary.simpleMessage("Lizenz"),
"Light" : MessageLookupByLibrary.simpleMessage("Hell"),
"Loading... Please wait" : MessageLookupByLibrary.simpleMessage("Lade ... Bitte warten"),
"Login" : MessageLookupByLibrary.simpleMessage("Login"),
"Logout" : MessageLookupByLibrary.simpleMessage("Logout"),
@ -244,12 +247,14 @@ class MessageLookup extends MessageLookupByLibrary {
"Source code" : MessageLookupByLibrary.simpleMessage("Quellcode"),
"Start your first chat :-)" : MessageLookupByLibrary.simpleMessage("Starte deinen ersten Chat :-)"),
"Sunday" : MessageLookupByLibrary.simpleMessage("Sonntag"),
"System" : MessageLookupByLibrary.simpleMessage("System"),
"Tap to show menu" : MessageLookupByLibrary.simpleMessage("Tippen, um das Menü anzuzeigen"),
"This room has been archived." : MessageLookupByLibrary.simpleMessage("Dieser Raum wurde archiviert."),
"Thursday" : MessageLookupByLibrary.simpleMessage("Donnerstag"),
"Try to send again" : MessageLookupByLibrary.simpleMessage("Nochmal versuchen zu senden"),
"Tuesday" : MessageLookupByLibrary.simpleMessage("Tuesday"),
"Unmute chat" : MessageLookupByLibrary.simpleMessage("Stumm aus"),
"Use Amoled compatible colors?" : MessageLookupByLibrary.simpleMessage("Amoled optimierte Farben verwenden?"),
"Username" : MessageLookupByLibrary.simpleMessage("Benutzername"),
"Visibility of the chat history" : MessageLookupByLibrary.simpleMessage("Sichtbarkeit des Chat-Verlaufs"),
"Visible for all participants" : MessageLookupByLibrary.simpleMessage("Sichtbar für alle Teilnehmer"),

View file

@ -150,6 +150,7 @@ class MessageLookup extends MessageLookupByLibrary {
"Ban from chat" : MessageLookupByLibrary.simpleMessage("Ban from chat"),
"Banned" : MessageLookupByLibrary.simpleMessage("Banned"),
"Change the name of the group" : MessageLookupByLibrary.simpleMessage("Change the name of the group"),
"Change your style" : MessageLookupByLibrary.simpleMessage("Change your style"),
"Changelog" : MessageLookupByLibrary.simpleMessage("Changelog"),
"Chat details" : MessageLookupByLibrary.simpleMessage("Chat details"),
"Choose a username" : MessageLookupByLibrary.simpleMessage("Choose a username"),
@ -166,6 +167,7 @@ class MessageLookup extends MessageLookupByLibrary {
"Create" : MessageLookupByLibrary.simpleMessage("Create"),
"Create account now" : MessageLookupByLibrary.simpleMessage("Create account now"),
"Create new group" : MessageLookupByLibrary.simpleMessage("Create new group"),
"Dark" : MessageLookupByLibrary.simpleMessage("Dark"),
"Delete" : MessageLookupByLibrary.simpleMessage("Delete"),
"Delete message" : MessageLookupByLibrary.simpleMessage("Delete message"),
"Discard picture" : MessageLookupByLibrary.simpleMessage("Discard picture"),
@ -199,6 +201,7 @@ class MessageLookup extends MessageLookupByLibrary {
"Leave" : MessageLookupByLibrary.simpleMessage("Leave"),
"Left the chat" : MessageLookupByLibrary.simpleMessage("Left the chat"),
"License" : MessageLookupByLibrary.simpleMessage("License"),
"Light" : MessageLookupByLibrary.simpleMessage("Light"),
"Loading... Please wait" : MessageLookupByLibrary.simpleMessage("Loading... Please wait"),
"Login" : MessageLookupByLibrary.simpleMessage("Login"),
"Logout" : MessageLookupByLibrary.simpleMessage("Logout"),
@ -244,12 +247,14 @@ class MessageLookup extends MessageLookupByLibrary {
"Source code" : MessageLookupByLibrary.simpleMessage("Source code"),
"Start your first chat :-)" : MessageLookupByLibrary.simpleMessage("Start your first chat :-)"),
"Sunday" : MessageLookupByLibrary.simpleMessage("Sunday"),
"System" : MessageLookupByLibrary.simpleMessage("System"),
"Tap to show menu" : MessageLookupByLibrary.simpleMessage("Tap to show menu"),
"This room has been archived." : MessageLookupByLibrary.simpleMessage("This room has been archived."),
"Thursday" : MessageLookupByLibrary.simpleMessage("Thursday"),
"Try to send again" : MessageLookupByLibrary.simpleMessage("Try to send again"),
"Tuesday" : MessageLookupByLibrary.simpleMessage("Tuesday"),
"Unmute chat" : MessageLookupByLibrary.simpleMessage("Unmute chat"),
"Use Amoled compatible colors?" : MessageLookupByLibrary.simpleMessage("Use Amoled compatible colors?"),
"Username" : MessageLookupByLibrary.simpleMessage("Username"),
"Visibility of the chat history" : MessageLookupByLibrary.simpleMessage("Visibility of the chat history"),
"Visible for all participants" : MessageLookupByLibrary.simpleMessage("Visible for all participants"),

View file

@ -1,19 +1,17 @@
import 'package:famedlysdk/famedlysdk.dart';
import 'package:fluffychat/i18n/i18n.dart';
import 'package:fluffychat/views/sign_up.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_localizations/flutter_localizations.dart';
import 'package:universal_html/prefer_universal/html.dart' as html;
import 'i18n/i18n.dart';
import 'views/sign_up.dart';
import 'components/ThemeSwitcher.dart';
import 'components/matrix.dart';
import 'views/chat_list.dart';
void main() {
SystemChrome.setSystemUIOverlayStyle(
SystemUiOverlayStyle(statusBarColor: Colors.white),
);
SystemUiOverlayStyle(statusBarColor: Colors.transparent));
runApp(App());
}
@ -23,63 +21,39 @@ class App extends StatelessWidget {
return Matrix(
clientName: "FluffyChat",
child: Builder(
builder: (BuildContext context) => MaterialApp(
title: 'FluffyChat',
theme: ThemeData(
brightness: Brightness.light,
primaryColor: Color(0xFF5625BA),
backgroundColor: Colors.white,
secondaryHeaderColor: Color(0xFFECECF2),
scaffoldBackgroundColor: Colors.white,
dialogTheme: DialogTheme(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(8.0),
builder: (BuildContext context) => ThemeSwitcherWidget(
child: Builder(
builder: (BuildContext context) => MaterialApp(
title: 'FluffyChat',
theme: ThemeSwitcherWidget.of(context).themeData,
localizationsDelegates: [
AppLocalizationsDelegate(),
GlobalMaterialLocalizations.delegate,
GlobalWidgetsLocalizations.delegate,
GlobalCupertinoLocalizations.delegate,
],
supportedLocales: [
const Locale('en'), // English
const Locale('de'), // German
],
home: FutureBuilder<LoginState>(
future:
Matrix.of(context).client.onLoginStateChanged.stream.first,
builder: (context, snapshot) {
if (!snapshot.hasData) {
return Scaffold(
body: Center(
child: CircularProgressIndicator(),
),
);
}
if (Matrix.of(context).client.isLogged()) {
return ChatListView();
}
return SignUp();
},
),
),
popupMenuTheme: PopupMenuThemeData(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(8.0),
),
),
appBarTheme: AppBarTheme(
brightness: Brightness.light,
color: Colors.white,
//elevation: 1,
textTheme: TextTheme(
title: TextStyle(
color: Colors.black,
fontSize: 20,
),
),
iconTheme: IconThemeData(color: Colors.black),
),
),
localizationsDelegates: [
AppLocalizationsDelegate(),
GlobalMaterialLocalizations.delegate,
GlobalWidgetsLocalizations.delegate,
GlobalCupertinoLocalizations.delegate,
],
supportedLocales: [
const Locale('en'), // English
const Locale('de'), // German
],
locale: kIsWeb
? Locale(html.window.navigator.language.split("-").first)
: null,
home: FutureBuilder<LoginState>(
future: Matrix.of(context).client.onLoginStateChanged.stream.first,
builder: (context, snapshot) {
if (!snapshot.hasData) {
return Scaffold(
body: Center(
child: CircularProgressIndicator(),
),
);
}
if (Matrix.of(context).client.isLogged()) return ChatListView();
return SignUp();
},
),
),
),

View file

@ -237,7 +237,7 @@ class _ChatDetailsState extends State<ChatDetails> {
linkStyle: TextStyle(color: Colors.blueAccent),
textStyle: TextStyle(
fontSize: 14,
color: Colors.black,
color: Theme.of(context).accentColor,
),
),
onTap: widget.room.canSendEvent("m.room.topic")

View file

@ -1,16 +1,6 @@
import 'dart:async';
import 'package:famedlysdk/famedlysdk.dart';
import 'package:fluffychat/components/adaptive_page_layout.dart';
import 'package:fluffychat/components/list_items/chat_list_item.dart';
import 'package:fluffychat/components/matrix.dart';
import 'package:fluffychat/i18n/i18n.dart';
import 'package:fluffychat/utils/app_route.dart';
import 'package:fluffychat/utils/url_launcher.dart';
import 'package:fluffychat/views/archive.dart';
import 'package:fluffychat/views/new_group.dart';
import 'package:fluffychat/views/new_private_chat.dart';
import 'package:fluffychat/views/settings.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
@ -18,6 +8,18 @@ import 'package:flutter_speed_dial/flutter_speed_dial.dart';
import 'package:toast/toast.dart';
import 'package:uni_links/uni_links.dart';
import '../components/ThemeSwitcher.dart';
import '../components/adaptive_page_layout.dart';
import '../components/list_items/chat_list_item.dart';
import '../components/matrix.dart';
import '../i18n/i18n.dart';
import '../utils/app_route.dart';
import '../utils/url_launcher.dart';
import 'archive.dart';
import 'new_group.dart';
import 'new_private_chat.dart';
import 'settings.dart';
enum SelectMode { normal, share }
class ChatListView extends StatelessWidget {
@ -39,6 +41,7 @@ class ChatList extends StatefulWidget {
final String activeChat;
const ChatList({this.activeChat, Key key}) : super(key: key);
@override
_ChatListState createState() => _ChatListState();
}
@ -189,13 +192,15 @@ class _ChatListState extends State<ChatList> {
),
floatingActionButton: SpeedDial(
child: Icon(Icons.add),
overlayColor: blackWhiteColor(context),
backgroundColor: Theme.of(context).primaryColor,
children: [
SpeedDialChild(
child: Icon(Icons.people_outline),
backgroundColor: Colors.blue,
label: I18n.of(context).createNewGroup,
labelStyle: TextStyle(fontSize: 18.0),
labelStyle:
TextStyle(fontSize: 18.0, color: blackWhiteColor(context)),
onTap: () => Navigator.of(context).pushAndRemoveUntil(
AppRoute.defaultRoute(context, NewGroupView()),
(r) => r.isFirst),
@ -204,7 +209,11 @@ class _ChatListState extends State<ChatList> {
child: Icon(Icons.person_add),
backgroundColor: Colors.green,
label: I18n.of(context).newPrivateChat,
labelStyle: TextStyle(fontSize: 18.0),
labelStyle: TextStyle(
fontSize: 18.0,
color: Theme.of(context).brightness == Brightness.light
? Colors.white
: Colors.black),
onTap: () => Navigator.of(context).pushAndRemoveUntil(
AppRoute.defaultRoute(context, NewPrivateChatView()),
(r) => r.isFirst),

View file

@ -120,7 +120,6 @@ class _LoginState extends State<Login> {
),
ListTile(
leading: CircleAvatar(
backgroundColor: Colors.white,
child: Icon(Icons.account_box,
color: Theme.of(context).primaryColor),
),
@ -137,7 +136,9 @@ class _LoginState extends State<Login> {
),
ListTile(
leading: CircleAvatar(
backgroundColor: Colors.white,
backgroundColor: Theme.of(context).brightness == Brightness.dark
? Color(0xff121212)
: Colors.white,
child: Icon(Icons.lock, color: Theme.of(context).primaryColor),
),
title: TextField(

View file

@ -1,20 +1,22 @@
import 'dart:io';
import 'package:famedlysdk/famedlysdk.dart';
import 'package:fluffychat/components/adaptive_page_layout.dart';
import 'package:fluffychat/components/content_banner.dart';
import 'package:fluffychat/components/dialogs/simple_dialogs.dart';
import 'package:fluffychat/components/matrix.dart';
import 'package:fluffychat/i18n/i18n.dart';
import 'package:fluffychat/utils/app_route.dart';
import 'package:fluffychat/views/app_info.dart';
import 'package:fluffychat/views/chat_list.dart';
import 'package:fluffychat/views/sign_up.dart';
import 'package:flutter/material.dart';
import 'package:image_picker/image_picker.dart';
import 'package:toast/toast.dart';
import 'package:url_launcher/url_launcher.dart';
import 'app_info.dart';
import 'chat_list.dart';
import 'settings_themes.dart';
import 'sign_up.dart';
import '../components/dialogs/simple_dialogs.dart';
import '../components/adaptive_page_layout.dart';
import '../components/content_banner.dart';
import '../components/matrix.dart';
import '../i18n/i18n.dart';
import '../utils/app_route.dart';
class SettingsView extends StatelessWidget {
@override
Widget build(BuildContext context) {
@ -34,6 +36,7 @@ class Settings extends StatefulWidget {
class _SettingsState extends State<Settings> {
Future<dynamic> profileFuture;
dynamic profile;
void logoutAction(BuildContext context) async {
if (await SimpleDialogs(context).askConfirmation() == false) {
return;
@ -140,6 +143,17 @@ class _SettingsState extends State<Settings> {
subtitle: Text(profile?.displayname ?? client.userID.localpart),
onTap: () => setDisplaynameAction(context),
),
ListTile(
trailing: Icon(Icons.color_lens),
title: Text(I18n.of(context).changeTheme),
onTap: () async => await Navigator.of(context).push(
AppRoute.defaultRoute(
context,
ThemesSettingsView(),
),
),
),
Divider(thickness: 1),
ListTile(
trailing: Icon(Icons.exit_to_app),
title: Text(I18n.of(context).logout),

View file

@ -0,0 +1,105 @@
import 'package:flutter/material.dart';
import '../components/ThemeSwitcher.dart';
import '../components/adaptive_page_layout.dart';
import '../components/matrix.dart';
import '../i18n/i18n.dart';
import 'chat_list.dart';
class ThemesSettingsView extends StatelessWidget {
@override
Widget build(BuildContext context) {
return AdaptivePageLayout(
primaryPage: FocusPage.SECOND,
firstScaffold: ChatList(),
secondScaffold: ThemesSettings(),
);
}
}
class ThemesSettings extends StatefulWidget {
@override
ThemesSettingsState createState() => ThemesSettingsState();
}
class ThemesSettingsState extends State<ThemesSettings> {
Themes _selectedTheme;
bool _amoledEnabled;
@override
Widget build(BuildContext context) {
final MatrixState matrix = Matrix.of(context);
final ThemeSwitcherWidgetState themeEngine =
ThemeSwitcherWidget.of(context);
_selectedTheme = themeEngine.selectedTheme;
_amoledEnabled = themeEngine.amoledEnabled;
return Scaffold(
appBar: AppBar(
title: Text(I18n.of(context).changeTheme),
),
body: Column(
children: <Widget>[
RadioListTile<Themes>(
title: Text(
I18n.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(
I18n.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(
I18n.of(context).darkTheme,
),
value: Themes.dark,
groupValue: _selectedTheme,
activeColor: Theme.of(context).primaryColor,
onChanged: (Themes value) {
setState(() {
_selectedTheme = value;
themeEngine.switchTheme(matrix, value, _amoledEnabled);
});
},
),
Divider(thickness: 8),
ListTile(
title: Text(
I18n.of(context).useAmoledTheme,
),
trailing: Switch(
value: _amoledEnabled,
activeColor: Theme.of(context).primaryColor,
onChanged: (bool value) {
setState(() {
_amoledEnabled = value;
themeEngine.switchTheme(matrix, _selectedTheme, value);
});
},
),
),
],
),
);
}
}

View file

@ -97,12 +97,13 @@ class _SignUpState extends State<SignUp> {
autocorrect: false,
controller: serverController,
decoration: InputDecoration(
icon: Icon(Icons.domain),
hintText: "matrix-client.matrix.org",
errorText: serverError,
errorMaxLines: 1,
prefixText: "https://",
labelText: serverError == null ? "Homeserver" : serverError),
icon: Icon(Icons.domain),
hintText: "matrix-client.matrix.org",
errorText: serverError,
errorMaxLines: 1,
prefixText: "https://",
labelText: serverError == null ? "Homeserver" : serverError,
),
),
),
body: ListView(
@ -115,7 +116,7 @@ class _SignUpState extends State<SignUp> {
leading: CircleAvatar(
backgroundImage: avatar == null ? null : FileImage(avatar),
backgroundColor: avatar == null
? Colors.white
? Theme.of(context).brightness == Brightness.dark ? Color(0xff121212) : Colors.white
: Theme.of(context).secondaryHeaderColor,
child: avatar == null
? Icon(Icons.camera_alt,
@ -137,7 +138,7 @@ class _SignUpState extends State<SignUp> {
),
ListTile(
leading: CircleAvatar(
backgroundColor: Colors.white,
backgroundColor: Theme.of(context).brightness == Brightness.dark ? Color(0xff121212) : Colors.white,
child: Icon(
Icons.account_circle,
color: Theme.of(context).primaryColor,