Merge branch 'krille/logs' into 'main'

feat: Implement logger

See merge request ChristianPauly/fluffychat-flutter!312
This commit is contained in:
Christian Pauly 2020-12-19 12:41:37 +00:00
commit 0265f516ba
13 changed files with 80 additions and 131 deletions

View File

@ -15,6 +15,7 @@ import 'package:flushbar/flushbar.dart';
import 'package:flutter/foundation.dart'; import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_gen/gen_l10n/l10n.dart'; import 'package:flutter_gen/gen_l10n/l10n.dart';
import 'package:logger_flutter/logger_flutter.dart';
import 'package:universal_html/prefer_universal/html.dart' as html; import 'package:universal_html/prefer_universal/html.dart' as html;
import 'package:url_launcher/url_launcher.dart'; import 'package:url_launcher/url_launcher.dart';
import 'package:path_provider/path_provider.dart'; import 'package:path_provider/path_provider.dart';
@ -166,7 +167,7 @@ class MatrixState extends State<Matrix> {
), ),
); );
default: default:
debugPrint('Warning! Cannot handle the stage "$stage"'); Logs().w('Warning! Cannot handle the stage "$stage"');
return; return;
} }
} }
@ -301,13 +302,13 @@ class MatrixState extends State<Matrix> {
} }
final configJson = json.decode(configJsonString); final configJson = json.decode(configJsonString);
AppConfig.loadFromJson(configJson); AppConfig.loadFromJson(configJson);
} catch (error) { } catch (e, s) {
debugPrint( Logs().w('[ConfigLoader] Failed to load config.json', e, s);
'[ConfigLoader] Failed to load config.json: ' + error.toString());
} }
} }
void initMatrix() { void initMatrix() {
LogConsole.init();
clientName = clientName =
'${AppConfig.applicationName} ${kIsWeb ? 'Web' : Platform.operatingSystem}'; '${AppConfig.applicationName} ${kIsWeb ? 'Web' : Platform.operatingSystem}';
final Set verificationMethods = <KeyVerificationMethod>{ final Set verificationMethods = <KeyVerificationMethod>{

View File

@ -1757,6 +1757,11 @@
"unreadChats": {} "unreadChats": {}
} }
}, },
"yourPublicKey": "Your public key",
"@yourPublicKey": {
"type": "text",
"placeholders": {}
},
"numUsersTyping": "{count} users are typing…", "numUsersTyping": "{count} users are typing…",
"@numUsersTyping": { "@numUsersTyping": {
"type": "text", "type": "text",

View File

@ -1,3 +1,4 @@
// @dart=2.9
import 'dart:async'; import 'dart:async';
import 'package:famedlysdk/famedlysdk.dart'; import 'package:famedlysdk/famedlysdk.dart';

View File

@ -5,7 +5,6 @@ import 'package:famedlysdk/famedlysdk.dart';
import 'package:path_provider/path_provider.dart'; import 'package:path_provider/path_provider.dart';
import 'package:sqflite/sqflite.dart' show getDatabasesPath; import 'package:sqflite/sqflite.dart' show getDatabasesPath;
import 'package:path/path.dart' as p; import 'package:path/path.dart' as p;
import 'package:flutter/material.dart';
import 'package:moor/moor.dart'; import 'package:moor/moor.dart';
import 'package:moor/isolate.dart'; import 'package:moor/isolate.dart';
import '../platform_infos.dart'; import '../platform_infos.dart';
@ -53,7 +52,7 @@ Future<Database> constructDb(
String filename = 'database.sqlite', String filename = 'database.sqlite',
String password = ''}) async { String password = ''}) async {
if (PlatformInfos.isMobile || Platform.isMacOS) { if (PlatformInfos.isMobile || Platform.isMacOS) {
debugPrint('[Moor] using encrypted moor'); Logs().v('[Moor] using encrypted moor');
final dbFolder = await getDatabasesPath(); final dbFolder = await getDatabasesPath();
final targetPath = p.join(dbFolder, filename); final targetPath = p.join(dbFolder, filename);
final receivePort = ReceivePort(); final receivePort = ReceivePort();
@ -65,11 +64,11 @@ Future<Database> constructDb(
final isolate = (await receivePort.first as MoorIsolate); final isolate = (await receivePort.first as MoorIsolate);
return Database.connect(await isolate.connect()); return Database.connect(await isolate.connect());
} else if (Platform.isLinux) { } else if (Platform.isLinux) {
debugPrint('[Moor] using Linux desktop moor'); Logs().v('[Moor] using Linux desktop moor');
final appDocDir = await getApplicationSupportDirectory(); final appDocDir = await getApplicationSupportDirectory();
return Database(moor.VmDatabase(File('${appDocDir.path}/$filename'))); return Database(moor.VmDatabase(File('${appDocDir.path}/$filename')));
} else if (Platform.isWindows) { } else if (Platform.isWindows) {
debugPrint('[Moor] using Windows desktop moor'); Logs().v('[Moor] using Windows desktop moor');
open.overrideFor(OperatingSystem.windows, _openOnWindows); open.overrideFor(OperatingSystem.windows, _openOnWindows);
return Database(moor.VmDatabase.memory()); return Database(moor.VmDatabase.memory());
} }

View File

@ -1,13 +1,12 @@
import 'package:famedlysdk/famedlysdk.dart'; import 'package:famedlysdk/famedlysdk.dart';
import 'package:moor/moor_web.dart'; import 'package:moor/moor_web.dart';
import 'package:flutter/material.dart';
import 'dart:html'; import 'dart:html';
Future<Database> constructDb( Future<Database> constructDb(
{bool logStatements = false, {bool logStatements = false,
String filename = 'database.sqlite', String filename = 'database.sqlite',
String password = ''}) async { String password = ''}) async {
debugPrint('[Moor] Using moor web'); Logs().v('[Moor] Using moor web');
return Database(WebDatabase.withStorage( return Database(WebDatabase.withStorage(
MoorWebStorage.indexedDbIfSupported(filename), MoorWebStorage.indexedDbIfSupported(filename),
logStatements: logStatements)); logStatements: logStatements));

View File

@ -54,7 +54,7 @@ abstract class FirebaseController {
return; return;
} }
final pushers = await client.requestPushers().catchError((e) { final pushers = await client.requestPushers().catchError((e) {
debugPrint('[Push] Unable to request pushers: ${e.toString()}'); Logs().w('[Push] Unable to request pushers', e);
return <Pusher>[]; return <Pusher>[];
}); });
final currentPushers = pushers.where((pusher) => pusher.pushkey == token); final currentPushers = pushers.where((pusher) => pusher.pushkey == token);
@ -68,7 +68,7 @@ abstract class FirebaseController {
AppConfig.pushNotificationsGatewayUrl && AppConfig.pushNotificationsGatewayUrl &&
currentPushers.first.data.format == currentPushers.first.data.format ==
AppConfig.pushNotificationsPusherFormat) { AppConfig.pushNotificationsPusherFormat) {
debugPrint('[Push] Pusher already set'); Logs().i('[Push] Pusher already set');
} else { } else {
if (currentPushers.isNotEmpty) { if (currentPushers.isNotEmpty) {
for (final currentPusher in currentPushers) { for (final currentPusher in currentPushers) {
@ -78,7 +78,7 @@ abstract class FirebaseController {
currentPusher, currentPusher,
append: true, append: true,
); );
debugPrint('[Push] Remove legacy pusher for this device'); Logs().i('[Push] Remove legacy pusher for this device');
} }
} }
await client await client
@ -97,8 +97,8 @@ abstract class FirebaseController {
), ),
append: false, append: false,
) )
.catchError((e) { .catchError((e, s) {
debugPrint('[Push] Unable to set pushers: ${e.toString()}'); Logs().e('[Push] Unable to set pushers', e, s);
return []; return [];
}); });
} }
@ -121,7 +121,7 @@ abstract class FirebaseController {
} catch (_) { } catch (_) {
await FlushbarHelper.createError(message: 'Failed to open chat...') await FlushbarHelper.createError(message: 'Failed to open chat...')
.show(context); .show(context);
debugPrint(_); rethrow;
} }
}; };
@ -145,7 +145,7 @@ abstract class FirebaseController {
onResume: goToRoom, onResume: goToRoom,
onLaunch: goToRoom, onLaunch: goToRoom,
); );
debugPrint('[Push] Firebase initialized'); Logs().i('[Push] Firebase initialized');
return; return;
} }
@ -162,10 +162,10 @@ abstract class FirebaseController {
return null; return null;
} }
if (context != null && Matrix.of(context).activeRoomId == roomId) { if (context != null && Matrix.of(context).activeRoomId == roomId) {
debugPrint('[Push] New clearing push'); Logs().i('[Push] New clearing push');
return null; return null;
} }
debugPrint('[Push] New message received'); Logs().i('[Push] New message received');
// FIXME unable to init without context currently https://github.com/flutter/flutter/issues/67092 // FIXME unable to init without context currently https://github.com/flutter/flutter/issues/67092
// Locked on EN until issue resolved // Locked on EN until issue resolved
final i18n = context == null ? L10nEn() : L10n.of(context); final i18n = context == null ? L10nEn() : L10n.of(context);
@ -183,7 +183,7 @@ abstract class FirebaseController {
final platform = kIsWeb ? 'Web' : Platform.operatingSystem; final platform = kIsWeb ? 'Web' : Platform.operatingSystem;
final clientName = 'FluffyChat $platform'; final clientName = 'FluffyChat $platform';
client = Client(clientName, databaseBuilder: getDatabase)..init(); client = Client(clientName, databaseBuilder: getDatabase)..init();
debugPrint('[Push] Use a temp client'); Logs().i('[Push] Use a temp client');
await client.onLoginStateChanged.stream await client.onLoginStateChanged.stream
.firstWhere((l) => l == LoginState.logged) .firstWhere((l) => l == LoginState.logged)
.timeout( .timeout(
@ -194,12 +194,12 @@ abstract class FirebaseController {
// Get the room // Get the room
var room = client.getRoomById(roomId); var room = client.getRoomById(roomId);
if (room == null) { if (room == null) {
debugPrint('[Push] Wait for the room'); Logs().i('[Push] Wait for the room');
await client.onRoomUpdate.stream await client.onRoomUpdate.stream
.where((u) => u.id == roomId) .where((u) => u.id == roomId)
.first .first
.timeout(Duration(seconds: 5)); .timeout(Duration(seconds: 5));
debugPrint('[Push] Room found'); Logs().i('[Push] Room found');
room = client.getRoomById(roomId); room = client.getRoomById(roomId);
if (room == null) return null; if (room == null) return null;
} }
@ -207,12 +207,12 @@ abstract class FirebaseController {
// Get the event // Get the event
var event = await client.database.getEventById(client.id, eventId, room); var event = await client.database.getEventById(client.id, eventId, room);
if (event == null) { if (event == null) {
debugPrint('[Push] Wait for the event'); Logs().i('[Push] Wait for the event');
final eventUpdate = await client.onEvent.stream final eventUpdate = await client.onEvent.stream
.where((u) => u.content['event_id'] == eventId) .where((u) => u.content['event_id'] == eventId)
.first .first
.timeout(Duration(seconds: 5)); .timeout(Duration(seconds: 5));
debugPrint('[Push] Event found'); Logs().i('[Push] Event found');
event = Event.fromJson(eventUpdate.content, room); event = Event.fromJson(eventUpdate.content, room);
if (room == null) return null; if (room == null) return null;
} }
@ -284,11 +284,10 @@ abstract class FirebaseController {
if (tempClient) { if (tempClient) {
await client.dispose(); await client.dispose();
client = null; client = null;
debugPrint('[Push] Temp client disposed'); Logs().i('[Push] Temp client disposed');
} }
} catch (exception) { } catch (e, s) {
debugPrint('[Push] Error while processing notification: ' + Logs().e('[Push] Error while processing notification', e, s);
exception.toString());
await _showDefaultNotification(message); await _showDefaultNotification(message);
} }
return null; return null;
@ -341,9 +340,8 @@ abstract class FirebaseController {
await flutterLocalNotificationsPlugin.show( await flutterLocalNotificationsPlugin.show(
1, title, l10n.openAppToReadMessages, platformChannelSpecifics, 1, title, l10n.openAppToReadMessages, platformChannelSpecifics,
payload: roomID); payload: roomID);
} catch (exception) { } catch (e, s) {
debugPrint('[Push] Error while processing background notification: ' + Logs().e('[Push] Error while processing background notification', e, s);
exception.toString());
} }
return Future<void>.value(); return Future<void>.value();
} }
@ -374,7 +372,7 @@ abstract class FirebaseController {
IosNotificationSettings(sound: true, badge: true, alert: true)); IosNotificationSettings(sound: true, badge: true, alert: true));
_firebaseMessaging.onIosSettingsRegistered _firebaseMessaging.onIosSettingsRegistered
.listen((IosNotificationSettings settings) { .listen((IosNotificationSettings settings) {
debugPrint('Settings registered: $settings'); Logs().i('Settings registered: $settings');
}); });
} }
} }

View File

@ -1,4 +1,5 @@
import 'package:adaptive_dialog/adaptive_dialog.dart'; import 'package:adaptive_dialog/adaptive_dialog.dart';
import 'package:famedlysdk/famedlysdk.dart';
import 'package:flushbar/flushbar_helper.dart'; import 'package:flushbar/flushbar_helper.dart';
import 'package:fluffychat/app_config.dart'; import 'package:fluffychat/app_config.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
@ -37,8 +38,7 @@ abstract class SentryController {
static final sentry = SentryClient(dsn: AppConfig.sentryDns); static final sentry = SentryClient(dsn: AppConfig.sentryDns);
static void captureException(error, stackTrace) async { static void captureException(error, stackTrace) async {
debugPrint(error.toString()); Logs().e('Capture exception', error, stackTrace);
debugPrint(stackTrace.toString());
if (!kDebugMode && await getSentryStatus()) { if (!kDebugMode && await getSentryStatus()) {
await sentry.captureException( await sentry.captureException(
exception: error, exception: error,

View File

@ -1,73 +0,0 @@
import 'package:fluffychat/components/adaptive_page_layout.dart';
import 'package:fluffychat/components/matrix.dart';
import 'package:fluffychat/utils/beautify_string_extension.dart';
import 'package:fluffychat/views/chat_list.dart';
import 'package:flutter/material.dart';
import 'package:flutter_gen/gen_l10n/l10n.dart';
import 'package:olm/olm.dart' as olm;
class AppInfoView extends StatelessWidget {
@override
Widget build(BuildContext context) {
return AdaptivePageLayout(
primaryPage: FocusPage.SECOND,
firstScaffold: ChatList(),
secondScaffold: AppInfo(),
);
}
}
class AppInfo extends StatelessWidget {
@override
Widget build(BuildContext context) {
var client = Matrix.of(context).client;
return Scaffold(
appBar: AppBar(
title: Text(L10n.of(context).accountInformation),
),
body: ListView(
children: <Widget>[
ListTile(
title: Text(L10n.of(context).yourOwnUsername + ':'),
subtitle: Text(client.userID),
),
ListTile(
title: Text('Homeserver:'),
subtitle: Text(client.homeserver.toString()),
),
ListTile(
title: Text('Device name:'),
subtitle: Text(client.userDeviceKeys[client.userID]
?.deviceKeys[client.deviceID]?.deviceDisplayName ??
L10n.of(context).unknownDevice),
),
ListTile(
title: Text('Device ID:'),
subtitle: Text(client.deviceID),
),
ListTile(
title: Text('Encryption enabled:'),
subtitle: Text(client.encryptionEnabled.toString()),
),
if (client.encryptionEnabled)
Column(
children: <Widget>[
ListTile(
title: Text('Your public fingerprint key:'),
subtitle: Text(client.fingerprintKey.beautified),
),
ListTile(
title: Text('Your public identity key:'),
subtitle: Text(client.identityKey.beautified),
),
ListTile(
title: Text('LibOlm version:'),
subtitle: Text(olm.get_library_version().join('.')),
),
],
),
],
),
);
}
}

View File

@ -6,6 +6,7 @@ import 'package:fluffychat/views/settings_style.dart';
import 'package:flushbar/flushbar_helper.dart'; import 'package:flushbar/flushbar_helper.dart';
import 'package:famedlysdk/famedlysdk.dart'; import 'package:famedlysdk/famedlysdk.dart';
import 'package:file_picker_cross/file_picker_cross.dart'; import 'package:file_picker_cross/file_picker_cross.dart';
import 'package:fluffychat/utils/beautify_string_extension.dart';
import 'package:fluffychat/app_config.dart'; import 'package:fluffychat/app_config.dart';
import 'package:fluffychat/utils/platform_infos.dart'; import 'package:fluffychat/utils/platform_infos.dart';
@ -16,6 +17,7 @@ import 'package:flutter/material.dart';
import 'package:flutter_gen/gen_l10n/l10n.dart'; import 'package:flutter_gen/gen_l10n/l10n.dart';
import 'package:image_picker/image_picker.dart'; import 'package:image_picker/image_picker.dart';
import 'package:url_launcher/url_launcher.dart'; import 'package:url_launcher/url_launcher.dart';
import 'package:logger_flutter/logger_flutter.dart';
import '../components/adaptive_page_layout.dart'; import '../components/adaptive_page_layout.dart';
import '../components/content_banner.dart'; import '../components/content_banner.dart';
@ -24,7 +26,6 @@ import '../components/matrix.dart';
import '../utils/app_route.dart'; import '../utils/app_route.dart';
import '../app_config.dart'; import '../app_config.dart';
import '../config/setting_keys.dart'; import '../config/setting_keys.dart';
import 'app_info.dart';
import 'chat_list.dart'; import 'chat_list.dart';
import 'settings_emotes.dart'; import 'settings_emotes.dart';
@ -433,16 +434,6 @@ class _SettingsState extends State<Settings> {
), ),
), ),
), ),
ListTile(
trailing: Icon(Icons.account_circle_outlined),
title: Text(L10n.of(context).accountInformation),
onTap: () => Navigator.of(context).push(
AppRoute.defaultRoute(
context,
AppInfoView(),
),
),
),
ListTile( ListTile(
trailing: Icon(Icons.bug_report_outlined), trailing: Icon(Icons.bug_report_outlined),
title: Text(L10n.of(context).sendBugReports), title: Text(L10n.of(context).sendBugReports),
@ -450,7 +441,7 @@ class _SettingsState extends State<Settings> {
), ),
Divider(thickness: 1), Divider(thickness: 1),
ListTile( ListTile(
trailing: Icon(Icons.vpn_key_outlined), trailing: Icon(Icons.security_outlined),
title: Text( title: Text(
L10n.of(context).changePassword, L10n.of(context).changePassword,
), ),
@ -589,6 +580,15 @@ class _SettingsState extends State<Settings> {
} }
}, },
), ),
ListTile(
title: Text(L10n.of(context).yourPublicKey),
onTap: () => showOkAlertDialog(
context: context,
title: L10n.of(context).yourPublicKey,
message: client.fingerprintKey.beautified,
),
trailing: Icon(Icons.vpn_key_outlined),
),
Divider(thickness: 1), Divider(thickness: 1),
ListTile( ListTile(
title: Text( title: Text(
@ -598,6 +598,14 @@ class _SettingsState extends State<Settings> {
fontWeight: FontWeight.bold, fontWeight: FontWeight.bold,
), ),
), ),
onTap: () => Navigator.of(context).push(
AppRoute.defaultRoute(
context,
LogConsole(
showCloseButton: true,
),
),
),
), ),
ListTile( ListTile(
trailing: Icon(Icons.help_outlined), trailing: Icon(Icons.help_outlined),

View File

@ -59,7 +59,6 @@ class _EmotesSettingsState extends State<EmotesSettings> {
if (readonly) { if (readonly) {
return; return;
} }
debugPrint('Saving....');
final client = Matrix.of(context).client; final client = Matrix.of(context).client;
// be sure to preserve any data not in "short" // be sure to preserve any data not in "short"
Map<String, dynamic> content; Map<String, dynamic> content;
@ -72,7 +71,6 @@ class _EmotesSettingsState extends State<EmotesSettings> {
content = client.accountData['im.ponies.user_emotes']?.content ?? content = client.accountData['im.ponies.user_emotes']?.content ??
<String, dynamic>{}; <String, dynamic>{};
} }
debugPrint(content.toString());
if (!(content['emoticons'] is Map)) { if (!(content['emoticons'] is Map)) {
content['emoticons'] = <String, dynamic>{}; content['emoticons'] = <String, dynamic>{};
} }
@ -95,7 +93,6 @@ class _EmotesSettingsState extends State<EmotesSettings> {
} }
// remove the old "short" key // remove the old "short" key
content.remove('short'); content.remove('short');
debugPrint(content.toString());
if (widget.room != null) { if (widget.room != null) {
await SimpleDialogs(context).tryRequestWithLoadingDialog( await SimpleDialogs(context).tryRequestWithLoadingDialog(
client.sendState(widget.room.id, 'im.ponies.room_emotes', content, client.sendState(widget.room.id, 'im.ponies.room_emotes', content,

View File

@ -89,7 +89,6 @@ class _SignUpPasswordState extends State<SignUpPassword> {
return setState(() => loading = false); return setState(() => loading = false);
} }
} catch (exception) { } catch (exception) {
debugPrint(exception);
setState(() => passwordError = exception.toString()); setState(() => passwordError = exception.toString());
return setState(() => loading = false); return setState(() => loading = false);
} }

View File

@ -36,13 +36,6 @@ packages:
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "1.1.2" version: "1.1.2"
ansicolor:
dependency: transitive
description:
name: ansicolor
url: "https://pub.dartlang.org"
source: hosted
version: "1.1.1"
args: args:
dependency: transitive dependency: transitive
description: description:
@ -202,7 +195,7 @@ packages:
description: description:
path: "." path: "."
ref: main ref: main
resolved-ref: "59d5849acc2d165fef6b96bac21ec5073c939778" resolved-ref: efadef4f3ea2b11d1d2b78c4bcaad50250a643e4
url: "https://gitlab.com/famedly/famedlysdk.git" url: "https://gitlab.com/famedly/famedlysdk.git"
source: git source: git
version: "0.0.1" version: "0.0.1"
@ -527,6 +520,20 @@ packages:
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "3.0.3+6" version: "3.0.3+6"
logger:
dependency: transitive
description:
name: logger
url: "https://pub.dartlang.org"
source: hosted
version: "0.7.0"
logger_flutter:
dependency: "direct main"
description:
name: logger_flutter
url: "https://pub.dartlang.org"
source: hosted
version: "0.7.1"
logging: logging:
dependency: transitive dependency: transitive
description: description:
@ -851,6 +858,13 @@ packages:
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "1.0.6" version: "1.0.6"
sensors:
dependency: transitive
description:
name: sensors
url: "https://pub.dartlang.org"
source: hosted
version: "0.4.2+6"
sentry: sentry:
dependency: "direct main" dependency: "direct main"
description: description:

View File

@ -64,6 +64,7 @@ dependencies:
flutter_cache_manager: ^2.0.0 flutter_cache_manager: ^2.0.0
open_noti_settings: ^0.0.4 open_noti_settings: ^0.0.4
emoji_picker: ^0.1.0 emoji_picker: ^0.1.0
logger_flutter: ^0.7.1
dev_dependencies: dev_dependencies:
flutter_test: flutter_test: