mirror of
https://gitlab.com/famedly/fluffychat.git
synced 2024-12-28 17:12:33 +01:00
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:
commit
38ef2b7807
285
lib/components/ThemeSwitcher.dart
Normal file
285
lib/components/ThemeSwitcher.dart
Normal 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,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
@ -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(
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
@ -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 :-)");
|
||||
|
@ -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",
|
||||
|
@ -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",
|
||||
|
@ -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"),
|
||||
|
@ -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"),
|
||||
|
@ -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();
|
||||
},
|
||||
),
|
||||
),
|
||||
),
|
||||
|
@ -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")
|
||||
|
@ -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),
|
||||
|
@ -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(
|
||||
|
@ -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),
|
||||
|
105
lib/views/settings_themes.dart
Normal file
105
lib/views/settings_themes.dart
Normal 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);
|
||||
});
|
||||
},
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
@ -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,
|
||||
|
Loading…
Reference in New Issue
Block a user