refactor: Make more widgets null safe

This commit is contained in:
Krille Fear 2021-11-19 20:38:16 +01:00
parent 3f10c0bae6
commit b73c6982a6
6 changed files with 54 additions and 38 deletions

View File

@ -1,3 +1,5 @@
//@dart=2.12
import 'package:flutter/cupertino.dart'; import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
@ -5,12 +7,12 @@ import 'package:fluffychat/utils/platform_infos.dart';
class AdaptiveFlatButton extends StatelessWidget { class AdaptiveFlatButton extends StatelessWidget {
final String label; final String label;
final Color textColor; final Color? textColor;
final Function onPressed; final void Function()? onPressed;
const AdaptiveFlatButton({ const AdaptiveFlatButton({
Key key, Key? key,
@required this.label, required this.label,
this.textColor, this.textColor,
this.onPressed, this.onPressed,
}) : super(key: key); }) : super(key: key);

View File

@ -1,3 +1,5 @@
//@dart=2.12
import 'package:flutter/foundation.dart'; import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
@ -8,12 +10,12 @@ import 'package:fluffychat/utils/string_color.dart';
import 'matrix.dart'; import 'matrix.dart';
class Avatar extends StatelessWidget { class Avatar extends StatelessWidget {
final Uri mxContent; final Uri? mxContent;
final String name; final String? name;
final double size; final double size;
final Function onTap; final void Function()? onTap;
static const double defaultSize = 44; static const double defaultSize = 44;
final Client client; final Client? client;
final double fontSize; final double fontSize;
const Avatar( const Avatar(
@ -23,7 +25,7 @@ class Avatar extends StatelessWidget {
this.onTap, this.onTap,
this.client, this.client,
this.fontSize = 18, this.fontSize = 18,
Key key, Key? key,
}) : super(key: key); }) : super(key: key);
@override @override
@ -34,11 +36,14 @@ class Avatar extends StatelessWidget {
height: size * MediaQuery.of(context).devicePixelRatio, height: size * MediaQuery.of(context).devicePixelRatio,
); );
var fallbackLetters = '@'; var fallbackLetters = '@';
if ((name?.runes?.length ?? 0) >= 2) { final name = this.name;
if (name != null) {
if (name.runes.length >= 2) {
fallbackLetters = String.fromCharCodes(name.runes, 0, 2); fallbackLetters = String.fromCharCodes(name.runes, 0, 2);
} else if ((name?.runes?.length ?? 0) == 1) { } else if (name.runes.length == 1) {
fallbackLetters = name; fallbackLetters = name;
} }
}
final noPic = mxContent == null || final noPic = mxContent == null ||
mxContent.toString().isEmpty || mxContent.toString().isEmpty ||
mxContent.toString() == 'null'; mxContent.toString() == 'null';

View File

@ -1,3 +1,5 @@
//@dart=2.12
import 'dart:async'; import 'dart:async';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
@ -13,7 +15,7 @@ import 'matrix.dart';
class ChatSettingsPopupMenu extends StatefulWidget { class ChatSettingsPopupMenu extends StatefulWidget {
final Room room; final Room room;
final bool displayChatDetails; final bool displayChatDetails;
const ChatSettingsPopupMenu(this.room, this.displayChatDetails, {Key key}) const ChatSettingsPopupMenu(this.room, this.displayChatDetails, {Key? key})
: super(key: key); : super(key: key);
@override @override
@ -21,7 +23,7 @@ class ChatSettingsPopupMenu extends StatefulWidget {
} }
class _ChatSettingsPopupMenuState extends State<ChatSettingsPopupMenu> { class _ChatSettingsPopupMenuState extends State<ChatSettingsPopupMenu> {
StreamSubscription notificationChangeSub; StreamSubscription? notificationChangeSub;
@override @override
void dispose() { void dispose() {
@ -37,7 +39,7 @@ class _ChatSettingsPopupMenuState extends State<ChatSettingsPopupMenu> {
.stream .stream
.where((u) => u.type == 'm.push_rules') .where((u) => u.type == 'm.push_rules')
.listen( .listen(
(u) => setState(() => null), (u) => setState(() {}),
); );
final items = <PopupMenuEntry<String>>[ final items = <PopupMenuEntry<String>>[
widget.room.pushRuleState == PushRuleState.notify widget.room.pushRuleState == PushRuleState.notify
@ -47,7 +49,7 @@ class _ChatSettingsPopupMenuState extends State<ChatSettingsPopupMenu> {
children: [ children: [
const Icon(Icons.notifications_off_outlined), const Icon(Icons.notifications_off_outlined),
const SizedBox(width: 12), const SizedBox(width: 12),
Text(L10n.of(context).muteChat), Text(L10n.of(context)!.muteChat),
], ],
), ),
) )
@ -57,7 +59,7 @@ class _ChatSettingsPopupMenuState extends State<ChatSettingsPopupMenu> {
children: [ children: [
const Icon(Icons.notifications_on_outlined), const Icon(Icons.notifications_on_outlined),
const SizedBox(width: 12), const SizedBox(width: 12),
Text(L10n.of(context).unmuteChat), Text(L10n.of(context)!.unmuteChat),
], ],
), ),
), ),
@ -67,7 +69,7 @@ class _ChatSettingsPopupMenuState extends State<ChatSettingsPopupMenu> {
children: [ children: [
const Icon(Icons.delete_outlined), const Icon(Icons.delete_outlined),
const SizedBox(width: 12), const SizedBox(width: 12),
Text(L10n.of(context).leave), Text(L10n.of(context)!.leave),
], ],
), ),
), ),
@ -81,7 +83,7 @@ class _ChatSettingsPopupMenuState extends State<ChatSettingsPopupMenu> {
children: [ children: [
const Icon(Icons.info_outline_rounded), const Icon(Icons.info_outline_rounded),
const SizedBox(width: 12), const SizedBox(width: 12),
Text(L10n.of(context).chatDetails), Text(L10n.of(context)!.chatDetails),
], ],
), ),
), ),
@ -94,9 +96,9 @@ class _ChatSettingsPopupMenuState extends State<ChatSettingsPopupMenu> {
final confirmed = await showOkCancelAlertDialog( final confirmed = await showOkCancelAlertDialog(
useRootNavigator: false, useRootNavigator: false,
context: context, context: context,
title: L10n.of(context).areYouSure, title: L10n.of(context)!.areYouSure,
okLabel: L10n.of(context).ok, okLabel: L10n.of(context)!.ok,
cancelLabel: L10n.of(context).cancel, cancelLabel: L10n.of(context)!.cancel,
); );
if (confirmed == OkCancelResult.ok) { if (confirmed == OkCancelResult.ok) {
final success = await showFutureLoadingDialog( final success = await showFutureLoadingDialog(

View File

@ -1,3 +1,5 @@
//@dart=2.12
import 'dart:async'; import 'dart:async';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
@ -9,15 +11,15 @@ import '../utils/localized_exception_extension.dart';
import 'matrix.dart'; import 'matrix.dart';
class ConnectionStatusHeader extends StatefulWidget { class ConnectionStatusHeader extends StatefulWidget {
const ConnectionStatusHeader({Key key}) : super(key: key); const ConnectionStatusHeader({Key? key}) : super(key: key);
@override @override
_ConnectionStatusHeaderState createState() => _ConnectionStatusHeaderState(); _ConnectionStatusHeaderState createState() => _ConnectionStatusHeaderState();
} }
class _ConnectionStatusHeaderState extends State<ConnectionStatusHeader> { class _ConnectionStatusHeaderState extends State<ConnectionStatusHeader> {
StreamSubscription _onSyncSub; StreamSubscription? _onSyncSub;
StreamSubscription _onSyncErrorSub; StreamSubscription? _onSyncErrorSub;
bool get _connected => bool get _connected =>
DateTime.now().millisecondsSinceEpoch - DateTime.now().millisecondsSinceEpoch -
_lastSyncReceived.millisecondsSinceEpoch < _lastSyncReceived.millisecondsSinceEpoch <
@ -82,14 +84,15 @@ extension on SyncStatusUpdate {
String toLocalizedString(BuildContext context) { String toLocalizedString(BuildContext context) {
switch (status) { switch (status) {
case SyncStatus.waitingForResponse: case SyncStatus.waitingForResponse:
return L10n.of(context).loadingPleaseWait; return L10n.of(context)!.loadingPleaseWait;
case SyncStatus.error: case SyncStatus.error:
return (error.exception as Object).toLocalizedString(context); return ((error?.exception ?? Object()) as Object)
.toLocalizedString(context);
case SyncStatus.processing: case SyncStatus.processing:
case SyncStatus.cleaningUp: case SyncStatus.cleaningUp:
case SyncStatus.finished: case SyncStatus.finished:
default: default:
return L10n.of(context).synchronizingPleaseWait; return L10n.of(context)!.synchronizingPleaseWait;
} }
} }
} }

View File

@ -1,3 +1,5 @@
//@dart=2.12
import 'dart:async'; import 'dart:async';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
@ -14,15 +16,15 @@ class ContactsList extends StatefulWidget {
final TextEditingController searchController; final TextEditingController searchController;
const ContactsList({ const ContactsList({
Key key, Key? key,
@required this.searchController, required this.searchController,
}) : super(key: key); }) : super(key: key);
@override @override
_ContactsState createState() => _ContactsState(); _ContactsState createState() => _ContactsState();
} }
class _ContactsState extends State<ContactsList> { class _ContactsState extends State<ContactsList> {
StreamSubscription _onSync; StreamSubscription? _onSync;
@override @override
void dispose() { void dispose() {
@ -31,11 +33,11 @@ class _ContactsState extends State<ContactsList> {
} }
DateTime _lastSetState = DateTime.now(); DateTime _lastSetState = DateTime.now();
Timer _coolDown; Timer? _coolDown;
void _updateView() { void _updateView() {
_lastSetState = DateTime.now(); _lastSetState = DateTime.now();
setState(() => null); setState(() {});
} }
@override @override
@ -68,15 +70,16 @@ class _ContactsState extends State<ContactsList> {
class _ContactListTile extends StatelessWidget { class _ContactListTile extends StatelessWidget {
final Presence contact; final Presence contact;
const _ContactListTile({Key key, @required this.contact}) : super(key: key); const _ContactListTile({Key? key, required this.contact}) : super(key: key);
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return FutureBuilder<Profile>( return FutureBuilder<Profile>(
future: future:
Matrix.of(context).client.getProfileFromUserId(contact.senderId), Matrix.of(context).client.getProfileFromUserId(contact.senderId),
builder: (context, snapshot) { builder: (context, snapshot) {
final displayname = final displayname = snapshot.data?.displayName ??
snapshot.data?.displayName ?? contact.senderId.localpart; contact.senderId.localpart ??
'No valid MXID';
final avatarUrl = snapshot.data?.avatarUrl; final avatarUrl = snapshot.data?.avatarUrl;
return ListTile( return ListTile(
leading: SizedBox( leading: SizedBox(
@ -108,7 +111,7 @@ class _ContactListTile extends StatelessWidget {
'rooms', 'rooms',
Matrix.of(context) Matrix.of(context)
.client .client
.getDirectChatFromUserId(contact.senderId) .getDirectChatFromUserId(contact.senderId)!
]), ]),
); );
}); });

View File

@ -1,4 +1,5 @@
//@dart=2.12 //@dart=2.12
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:fluffychat/config/themes.dart'; import 'package:fluffychat/config/themes.dart';