refactor: Migrate to null safety

This commit is contained in:
Krille Fear 2022-01-29 12:35:03 +01:00 committed by Christian Pauly
commit 55f0300f9f
163 changed files with 1759 additions and 1903 deletions

View file

@ -34,25 +34,28 @@ enum PopupMenuAction {
}
class ChatList extends StatefulWidget {
const ChatList({Key key}) : super(key: key);
const ChatList({Key? key}) : super(key: key);
@override
ChatListController createState() => ChatListController();
}
class ChatListController extends State<ChatList> {
StreamSubscription _intentDataStreamSubscription;
StreamSubscription? _intentDataStreamSubscription;
StreamSubscription _intentFileStreamSubscription;
StreamSubscription? _intentFileStreamSubscription;
StreamSubscription _intentUriStreamSubscription;
StreamSubscription? _intentUriStreamSubscription;
String _activeSpaceId;
String? _activeSpaceId;
String? get activeSpaceId {
final id = _activeSpaceId;
return id != null && Matrix.of(context).client.getRoomById(id) == null
? null
: _activeSpaceId;
}
String get activeSpaceId =>
Matrix.of(context).client.getRoomById(_activeSpaceId) == null
? null
: _activeSpaceId;
final ScrollController scrollController = ScrollController();
bool scrolledToTop = true;
@ -69,12 +72,12 @@ class ChatListController extends State<ChatList> {
}
}
void setActiveSpaceId(BuildContext context, String spaceId) {
void setActiveSpaceId(BuildContext context, String? spaceId) {
setState(() => _activeSpaceId = spaceId);
}
void editSpace(BuildContext context, String spaceId) async {
await Matrix.of(context).client.getRoomById(spaceId).postLoad();
await Matrix.of(context).client.getRoomById(spaceId)!.postLoad();
VRouter.of(context).toSegments(['spaces', spaceId]);
}
@ -82,7 +85,7 @@ class ChatListController extends State<ChatList> {
Matrix.of(context).client.rooms.where((r) => r.isSpace).toList();
final selectedRoomIds = <String>{};
bool crossSigningCached;
bool? crossSigningCached;
bool showChatBackupBanner = false;
void firstRunBootstrapAction() async {
@ -96,7 +99,7 @@ class ChatListController extends State<ChatList> {
VRouter.of(context).to('/rooms');
}
String get activeChat => VRouter.of(context).pathParameters['roomid'];
String? get activeChat => VRouter.of(context).pathParameters['roomid'];
SelectMode get selectMode => Matrix.of(context).shareContent != null
? SelectMode.share
@ -105,7 +108,7 @@ class ChatListController extends State<ChatList> {
: SelectMode.select;
void _processIncomingSharedFiles(List<SharedMediaFile> files) {
if (files?.isEmpty ?? true) return;
if (files.isEmpty) return;
VRouter.of(context).to('/rooms');
final file = File(files.first.path);
@ -118,7 +121,7 @@ class ChatListController extends State<ChatList> {
};
}
void _processIncomingSharedText(String text) {
void _processIncomingSharedText(String? text) {
if (text == null) return;
VRouter.of(context).to('/rooms');
if (text.toLowerCase().startsWith(AppConfig.deepLinkPrefix) ||
@ -133,10 +136,10 @@ class ChatListController extends State<ChatList> {
};
}
void _processIncomingUris(String text) async {
void _processIncomingUris(String? text) async {
if (text == null) return;
VRouter.of(context).to('/rooms');
WidgetsBinding.instance.addPostFrameCallback((_) {
WidgetsBinding.instance!.addPostFrameCallback((_) {
UrlLauncher(context, text).openMatrixToUrl();
});
}
@ -180,10 +183,10 @@ class ChatListController extends State<ChatList> {
await Matrix.of(context).client.accountDataLoading;
await Matrix.of(context).client.userDeviceKeysLoading;
final crossSigning =
await Matrix.of(context).client.encryption?.crossSigning?.isCached() ??
await Matrix.of(context).client.encryption?.crossSigning.isCached() ??
false;
final needsBootstrap =
Matrix.of(context).client.encryption?.crossSigning?.enabled == false ||
Matrix.of(context).client.encryption?.crossSigning.enabled == false ||
crossSigning == false;
final isUnknownSession = Matrix.of(context).client.isUnknownSession;
if (needsBootstrap || isUnknownSession) {
@ -206,23 +209,21 @@ class ChatListController extends State<ChatList> {
if (room.isSpace && room.membership == Membership.join && !room.isUnread) {
return false;
}
if (room.getState(EventTypes.RoomCreate)?.content?.tryGet<String>('type') ==
if (room.getState(EventTypes.RoomCreate)?.content.tryGet<String>('type') ==
ClientStoriesExtension.storiesRoomType) {
return false;
}
if (activeSpaceId != null) {
final space = Matrix.of(context).client.getRoomById(activeSpaceId);
if (space.spaceChildren?.any((child) => child.roomId == room.id) ??
false) {
final space = Matrix.of(context).client.getRoomById(activeSpaceId!)!;
if (space.spaceChildren.any((child) => child.roomId == room.id)) {
return true;
}
if (room.spaceParents?.any((parent) => parent.roomId == activeSpaceId) ??
false) {
if (room.spaceParents.any((parent) => parent.roomId == activeSpaceId)) {
return true;
}
if (room.isDirectChat &&
room.summary?.mHeroes != null &&
room.summary.mHeroes.any((userId) {
room.summary.mHeroes != null &&
room.summary.mHeroes!.any((userId) {
final user = space.getState(EventTypes.RoomMember, userId)?.asUser;
return user != null && user.membership == Membership.join;
})) {
@ -246,9 +247,9 @@ class ChatListController extends State<ChatList> {
final markUnread = anySelectedRoomNotMarkedUnread;
final client = Matrix.of(context).client;
for (final roomId in selectedRoomIds) {
final room = client.getRoomById(roomId);
final room = client.getRoomById(roomId)!;
if (room.markedUnread == markUnread) continue;
await client.getRoomById(roomId).markUnread(markUnread);
await client.getRoomById(roomId)!.markUnread(markUnread);
}
},
);
@ -262,9 +263,9 @@ class ChatListController extends State<ChatList> {
final makeFavorite = anySelectedRoomNotFavorite;
final client = Matrix.of(context).client;
for (final roomId in selectedRoomIds) {
final room = client.getRoomById(roomId);
final room = client.getRoomById(roomId)!;
if (room.isFavourite == makeFavorite) continue;
await client.getRoomById(roomId).setFavourite(makeFavorite);
await client.getRoomById(roomId)!.setFavourite(makeFavorite);
}
},
);
@ -280,9 +281,9 @@ class ChatListController extends State<ChatList> {
: PushRuleState.notify;
final client = Matrix.of(context).client;
for (final roomId in selectedRoomIds) {
final room = client.getRoomById(roomId);
final room = client.getRoomById(roomId)!;
if (room.pushRuleState == newState) continue;
await client.getRoomById(roomId).setPushRuleState(newState);
await client.getRoomById(roomId)!.setPushRuleState(newState);
}
},
);
@ -293,9 +294,9 @@ class ChatListController extends State<ChatList> {
final confirmed = await showOkCancelAlertDialog(
useRootNavigator: false,
context: context,
title: L10n.of(context).areYouSure,
okLabel: L10n.of(context).yes,
cancelLabel: L10n.of(context).cancel,
title: L10n.of(context)!.areYouSure,
okLabel: L10n.of(context)!.yes,
cancelLabel: L10n.of(context)!.cancel,
) ==
OkCancelResult.ok;
if (!confirmed) return;
@ -303,26 +304,26 @@ class ChatListController extends State<ChatList> {
context: context,
future: () => _archiveSelectedRooms(),
);
setState(() => null);
setState(() {});
}
void setStatus() async {
final input = await showTextInputDialog(
useRootNavigator: false,
context: context,
title: L10n.of(context).setStatus,
okLabel: L10n.of(context).ok,
cancelLabel: L10n.of(context).cancel,
title: L10n.of(context)!.setStatus,
okLabel: L10n.of(context)!.ok,
cancelLabel: L10n.of(context)!.cancel,
textFields: [
DialogTextField(
hintText: L10n.of(context).statusExampleMessage,
hintText: L10n.of(context)!.statusExampleMessage,
),
]);
if (input == null) return;
await showFutureLoadingDialog(
context: context,
future: () => Matrix.of(context).client.setPresence(
Matrix.of(context).client.userID,
Matrix.of(context).client.userID!,
PresenceType.online,
statusMsg: input.single,
),
@ -339,7 +340,7 @@ class ChatListController extends State<ChatList> {
break;
case PopupMenuAction.invite:
FluffyShare.share(
L10n.of(context).inviteText(Matrix.of(context).client.userID,
L10n.of(context)!.inviteText(Matrix.of(context).client.userID!,
'https://matrix.to/#/${Matrix.of(context).client.userID}?client=im.fluffychat'),
context);
break;
@ -360,7 +361,7 @@ class ChatListController extends State<ChatList> {
while (selectedRoomIds.isNotEmpty) {
final roomId = selectedRoomIds.first;
try {
await client.getRoomById(roomId).leave();
await client.getRoomById(roomId)!.leave();
} finally {
toggleSelection(roomId);
}
@ -371,36 +372,36 @@ class ChatListController extends State<ChatList> {
if (activeSpaceId != null) {
final consent = await showOkCancelAlertDialog(
context: context,
title: L10n.of(context).removeFromSpace,
message: L10n.of(context).removeFromSpaceDescription,
okLabel: L10n.of(context).remove,
cancelLabel: L10n.of(context).cancel,
title: L10n.of(context)!.removeFromSpace,
message: L10n.of(context)!.removeFromSpaceDescription,
okLabel: L10n.of(context)!.remove,
cancelLabel: L10n.of(context)!.cancel,
isDestructiveAction: true,
fullyCapitalizedForMaterial: false,
);
if (consent != OkCancelResult.ok) return;
final space = Matrix.of(context).client.getRoomById(activeSpaceId);
final space = Matrix.of(context).client.getRoomById(activeSpaceId!);
final result = await showFutureLoadingDialog(
context: context,
future: () async {
for (final roomId in selectedRoomIds) {
await space.removeSpaceChild(roomId);
await space!.removeSpaceChild(roomId);
}
},
);
if (result.error == null) {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Text(L10n.of(context).chatHasBeenRemovedFromThisSpace),
content: Text(L10n.of(context)!.chatHasBeenRemovedFromThisSpace),
),
);
}
} else {
final selectedSpace = await showConfirmationDialog<String>(
context: context,
title: L10n.of(context).addToSpace,
message: L10n.of(context).addToSpaceDescription,
title: L10n.of(context)!.addToSpace,
message: L10n.of(context)!.addToSpaceDescription,
fullyCapitalizedForMaterial: false,
actions: Matrix.of(context)
.client
@ -417,7 +418,7 @@ class ChatListController extends State<ChatList> {
final result = await showFutureLoadingDialog(
context: context,
future: () async {
final space = Matrix.of(context).client.getRoomById(selectedSpace);
final space = Matrix.of(context).client.getRoomById(selectedSpace)!;
if (space.canSendDefaultStates) {
for (final roomId in selectedRoomIds) {
await space.setSpaceChild(roomId);
@ -428,7 +429,7 @@ class ChatListController extends State<ChatList> {
if (result.error == null) {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Text(L10n.of(context).chatHasBeenAddedToThisSpace),
content: Text(L10n.of(context)!.chatHasBeenAddedToThisSpace),
),
);
}
@ -437,13 +438,13 @@ class ChatListController extends State<ChatList> {
}
bool get anySelectedRoomNotMarkedUnread => selectedRoomIds.any(
(roomId) => !Matrix.of(context).client.getRoomById(roomId).markedUnread);
(roomId) => !Matrix.of(context).client.getRoomById(roomId)!.markedUnread);
bool get anySelectedRoomNotFavorite => selectedRoomIds.any(
(roomId) => !Matrix.of(context).client.getRoomById(roomId).isFavourite);
(roomId) => !Matrix.of(context).client.getRoomById(roomId)!.isFavourite);
bool get anySelectedRoomNotMuted => selectedRoomIds.any((roomId) =>
Matrix.of(context).client.getRoomById(roomId).pushRuleState ==
Matrix.of(context).client.getRoomById(roomId)!.pushRuleState ==
PushRuleState.notify);
bool waitForFirstSync = false;
@ -457,10 +458,10 @@ class ChatListController extends State<ChatList> {
}
// Load space members to display DM rooms
if (activeSpaceId != null) {
final space = client.getRoomById(activeSpaceId);
final space = client.getRoomById(activeSpaceId!)!;
final localMembers = space.getParticipants().length;
final actualMembersCount = (space.summary?.mInvitedMemberCount ?? 0) +
(space.summary?.mJoinedMemberCount ?? 0);
final actualMembersCount = (space.summary.mInvitedMemberCount ?? 0) +
(space.summary.mJoinedMemberCount ?? 0);
if (localMembers < actualMembersCount) {
await space.requestParticipants();
}
@ -468,7 +469,7 @@ class ChatListController extends State<ChatList> {
setState(() {
waitForFirstSync = true;
});
WidgetsBinding.instance.addPostFrameCallback((_) => checkBootstrap());
WidgetsBinding.instance!.addPostFrameCallback((_) => checkBootstrap());
return;
}
@ -481,7 +482,6 @@ class ChatListController extends State<ChatList> {
}
void setActiveClient(Client client) {
if (client == null) return;
VRouter.of(context).to('/rooms');
setState(() {
_activeSpaceId = null;
@ -498,30 +498,30 @@ class ChatListController extends State<ChatList> {
selectedRoomIds.clear();
Matrix.of(context).activeBundle = bundle;
if (!Matrix.of(context)
.currentBundle
.currentBundle!
.any((client) => client == Matrix.of(context).client)) {
Matrix.of(context)
.setActiveClient(Matrix.of(context).currentBundle.first);
.setActiveClient(Matrix.of(context).currentBundle!.first);
}
});
}
void editBundlesForAccount(String userId, String activeBundle) async {
void editBundlesForAccount(String? userId, String? activeBundle) async {
final client = Matrix.of(context)
.widget
.clients[Matrix.of(context).getClientIndexByMatrixId(userId)];
.clients[Matrix.of(context).getClientIndexByMatrixId(userId!)];
final action = await showConfirmationDialog<EditBundleAction>(
context: context,
title: L10n.of(context).editBundlesForAccount,
title: L10n.of(context)!.editBundlesForAccount,
actions: [
AlertDialogAction(
key: EditBundleAction.addToBundle,
label: L10n.of(context).addToBundle,
label: L10n.of(context)!.addToBundle,
),
if (activeBundle != client.userID)
AlertDialogAction(
key: EditBundleAction.removeFromBundle,
label: L10n.of(context).removeFromBundle,
label: L10n.of(context)!.removeFromBundle,
),
],
);
@ -530,9 +530,9 @@ class ChatListController extends State<ChatList> {
case EditBundleAction.addToBundle:
final bundle = await showTextInputDialog(
context: context,
title: L10n.of(context).bundleName,
title: L10n.of(context)!.bundleName,
textFields: [
DialogTextField(hintText: L10n.of(context).bundleName)
DialogTextField(hintText: L10n.of(context)!.bundleName)
]);
if (bundle == null || bundle.isEmpty || bundle.single.isEmpty) return;
await showFutureLoadingDialog(
@ -543,7 +543,7 @@ class ChatListController extends State<ChatList> {
case EditBundleAction.removeFromBundle:
await showFutureLoadingDialog(
context: context,
future: () => client.removeFromAccountBundle(activeBundle),
future: () => client.removeFromAccountBundle(activeBundle!),
);
}
}
@ -552,7 +552,7 @@ class ChatListController extends State<ChatList> {
Matrix.of(context).hasComplexBundles &&
Matrix.of(context).accountBundles.keys.length > 1;
String get secureActiveBundle {
String? get secureActiveBundle {
if (Matrix.of(context).activeBundle == null ||
!Matrix.of(context)
.accountBundles
@ -564,7 +564,7 @@ class ChatListController extends State<ChatList> {
}
void resetActiveBundle() {
WidgetsBinding.instance.addPostFrameCallback((timeStamp) {
WidgetsBinding.instance!.addPostFrameCallback((timeStamp) {
setState(() {
Matrix.of(context).activeBundle = null;
});

View file

@ -21,9 +21,9 @@ class ChatListItem extends StatelessWidget {
final Room room;
final bool activeChat;
final bool selected;
final Function onForget;
final Function onTap;
final Function onLongPress;
final Function? onForget;
final Function? onTap;
final Function? onLongPress;
const ChatListItem(
this.room, {
@ -32,11 +32,11 @@ class ChatListItem extends StatelessWidget {
this.onTap,
this.onLongPress,
this.onForget,
Key key,
Key? key,
}) : super(key: key);
dynamic clickAction(BuildContext context) async {
if (onTap != null) return onTap();
if (onTap != null) return onTap!();
if (!activeChat) {
if (room.membership == Membership.invite &&
(await showFutureLoadingDialog(
@ -57,7 +57,7 @@ class ChatListItem extends StatelessWidget {
if (room.membership == Membership.ban) {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Text(L10n.of(context).youHaveBeenBannedFromThisChat),
content: Text(L10n.of(context)!.youHaveBeenBannedFromThisChat),
),
);
return;
@ -66,15 +66,15 @@ class ChatListItem extends StatelessWidget {
if (room.membership == Membership.leave) {
final action = await showModalActionSheet<ArchivedRoomAction>(
context: context,
title: L10n.of(context).archivedRoom,
message: L10n.of(context).thisRoomHasBeenArchived,
title: L10n.of(context)!.archivedRoom,
message: L10n.of(context)!.thisRoomHasBeenArchived,
actions: [
SheetAction(
label: L10n.of(context).rejoin,
label: L10n.of(context)!.rejoin,
key: ArchivedRoomAction.rejoin,
),
SheetAction(
label: L10n.of(context).delete,
label: L10n.of(context)!.delete,
key: ArchivedRoomAction.delete,
isDestructiveAction: true,
),
@ -97,18 +97,18 @@ class ChatListItem extends StatelessWidget {
if (room.membership == Membership.join) {
if (Matrix.of(context).shareContent != null) {
if (Matrix.of(context).shareContent['msgtype'] ==
if (Matrix.of(context).shareContent!['msgtype'] ==
'chat.fluffy.shared_file') {
await showDialog(
context: context,
useRootNavigator: false,
builder: (c) => SendFileDialog(
file: Matrix.of(context).shareContent['file'],
file: Matrix.of(context).shareContent!['file'],
room: room,
),
);
} else {
unawaited(room.sendEvent(Matrix.of(context).shareContent));
unawaited(room.sendEvent(Matrix.of(context).shareContent!));
}
Matrix.of(context).shareContent = null;
}
@ -125,16 +125,16 @@ class ChatListItem extends StatelessWidget {
future: () => room.forget(),
);
if (success.error == null) {
if (onForget != null) onForget();
if (onForget != null) onForget!();
}
return success;
return;
}
final confirmed = await showOkCancelAlertDialog(
useRootNavigator: false,
context: context,
title: L10n.of(context).areYouSure,
okLabel: L10n.of(context).yes,
cancelLabel: L10n.of(context).no,
title: L10n.of(context)!.areYouSure,
okLabel: L10n.of(context)!.yes,
cancelLabel: L10n.of(context)!.no,
);
if (confirmed == OkCancelResult.cancel) return;
await showFutureLoadingDialog(
@ -160,7 +160,7 @@ class ChatListItem extends StatelessWidget {
selectedTileColor: selected
? Theme.of(context).primaryColor.withAlpha(100)
: Theme.of(context).secondaryHeaderColor,
onLongPress: onLongPress,
onLongPress: onLongPress as void Function()?,
leading: selected
? SizedBox(
width: Avatar.defaultSize,
@ -174,13 +174,13 @@ class ChatListItem extends StatelessWidget {
: Avatar(
mxContent: room.avatar,
name: room.displayname,
onTap: onLongPress,
onTap: onLongPress as void Function()?,
),
title: Row(
children: <Widget>[
Expanded(
child: Text(
room.getLocalizedDisplayname(MatrixLocals(L10n.of(context))),
room.getLocalizedDisplayname(MatrixLocals(L10n.of(context)!)),
maxLines: 1,
overflow: TextOverflow.ellipsis,
softWrap: false,
@ -188,7 +188,7 @@ class ChatListItem extends StatelessWidget {
fontWeight: FontWeight.bold,
color: unread
? Theme.of(context).colorScheme.secondary
: Theme.of(context).textTheme.bodyText1.color,
: Theme.of(context).textTheme.bodyText1!.color,
),
),
),
@ -218,7 +218,7 @@ class ChatListItem extends StatelessWidget {
fontSize: 13,
color: unread
? Theme.of(context).colorScheme.secondary
: Theme.of(context).textTheme.bodyText2.color,
: Theme.of(context).textTheme.bodyText2!.color,
),
),
),
@ -229,7 +229,7 @@ class ChatListItem extends StatelessWidget {
children: <Widget>[
if (typingText.isEmpty &&
ownMessage &&
room.lastEvent.status.isSending) ...[
room.lastEvent!.status.isSending) ...[
const SizedBox(
width: 16,
height: 16,
@ -261,9 +261,9 @@ class ChatListItem extends StatelessWidget {
)
: Text(
room.membership == Membership.invite
? L10n.of(context).youAreInvitedToThisChat
? L10n.of(context)!.youAreInvitedToThisChat
: room.lastEvent?.getLocalizedBody(
MatrixLocals(L10n.of(context)),
MatrixLocals(L10n.of(context)!),
hideReply: true,
hideEdit: true,
plaintextBody: true,
@ -271,14 +271,14 @@ class ChatListItem extends StatelessWidget {
room.directChatMatrixID !=
room.lastEvent?.senderId,
) ??
L10n.of(context).emptyChat,
L10n.of(context)!.emptyChat,
softWrap: false,
maxLines: 1,
overflow: TextOverflow.ellipsis,
style: TextStyle(
color: unread
? Theme.of(context).colorScheme.secondary
: Theme.of(context).textTheme.bodyText2.color,
: Theme.of(context).textTheme.bodyText2!.color,
decoration: room.lastEvent?.redacted == true
? TextDecoration.lineThrough
: null,

View file

@ -21,11 +21,11 @@ import '../../widgets/matrix.dart';
class ChatListView extends StatelessWidget {
final ChatListController controller;
const ChatListView(this.controller, {Key key}) : super(key: key);
const ChatListView(this.controller, {Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return StreamBuilder<Object>(
return StreamBuilder<Object?>(
stream: Matrix.of(context).onShareContentChanged.stream,
builder: (_, __) {
final selectMode = controller.selectMode;
@ -48,7 +48,7 @@ class ChatListView extends StatelessWidget {
? ClientChooserButton(controller)
: null
: IconButton(
tooltip: L10n.of(context).cancel,
tooltip: L10n.of(context)!.cancel,
icon: const Icon(Icons.close_outlined),
onPressed: controller.cancelAction,
color: Theme.of(context).colorScheme.primary,
@ -60,12 +60,12 @@ class ChatListView extends StatelessWidget {
? [
if (controller.spaces.isNotEmpty)
IconButton(
tooltip: L10n.of(context).addToSpace,
tooltip: L10n.of(context)!.addToSpace,
icon: const Icon(Icons.group_work_outlined),
onPressed: controller.addOrRemoveToSpace,
),
IconButton(
tooltip: L10n.of(context).toggleUnread,
tooltip: L10n.of(context)!.toggleUnread,
icon: Icon(
controller.anySelectedRoomNotMarkedUnread
? Icons.mark_chat_read_outlined
@ -73,7 +73,7 @@ class ChatListView extends StatelessWidget {
onPressed: controller.toggleUnread,
),
IconButton(
tooltip: L10n.of(context).toggleFavorite,
tooltip: L10n.of(context)!.toggleFavorite,
icon: Icon(controller.anySelectedRoomNotFavorite
? Icons.push_pin_outlined
: Icons.push_pin),
@ -83,19 +83,19 @@ class ChatListView extends StatelessWidget {
icon: Icon(controller.anySelectedRoomNotMuted
? Icons.notifications_off_outlined
: Icons.notifications_outlined),
tooltip: L10n.of(context).toggleMuted,
tooltip: L10n.of(context)!.toggleMuted,
onPressed: controller.toggleMuted,
),
IconButton(
icon: const Icon(Icons.delete_outlined),
tooltip: L10n.of(context).archive,
tooltip: L10n.of(context)!.archive,
onPressed: controller.archiveAction,
),
]
: [
IconButton(
icon: const Icon(Icons.search_outlined),
tooltip: L10n.of(context).search,
tooltip: L10n.of(context)!.search,
onPressed: () =>
VRouter.of(context).to('/search'),
),
@ -109,7 +109,7 @@ class ChatListView extends StatelessWidget {
children: [
const Icon(Icons.edit_outlined),
const SizedBox(width: 12),
Text(L10n.of(context).setStatus),
Text(L10n.of(context)!.setStatus),
],
),
),
@ -120,7 +120,7 @@ class ChatListView extends StatelessWidget {
children: [
const Icon(Icons.group_add_outlined),
const SizedBox(width: 12),
Text(L10n.of(context).createNewGroup),
Text(L10n.of(context)!.createNewGroup),
],
),
),
@ -131,7 +131,7 @@ class ChatListView extends StatelessWidget {
children: [
const Icon(Icons.group_work_outlined),
const SizedBox(width: 12),
Text(L10n.of(context).createNewSpace),
Text(L10n.of(context)!.createNewSpace),
],
),
),
@ -142,7 +142,7 @@ class ChatListView extends StatelessWidget {
children: [
const Icon(Icons.share_outlined),
const SizedBox(width: 12),
Text(L10n.of(context).inviteContact),
Text(L10n.of(context)!.inviteContact),
],
),
),
@ -153,7 +153,7 @@ class ChatListView extends StatelessWidget {
children: [
const Icon(Icons.archive_outlined),
const SizedBox(width: 12),
Text(L10n.of(context).archive),
Text(L10n.of(context)!.archive),
],
),
),
@ -164,7 +164,7 @@ class ChatListView extends StatelessWidget {
children: [
const Icon(Icons.settings_outlined),
const SizedBox(width: 12),
Text(L10n.of(context).settings),
Text(L10n.of(context)!.settings),
],
),
),
@ -172,14 +172,14 @@ class ChatListView extends StatelessWidget {
),
],
title: Text(selectMode == SelectMode.share
? L10n.of(context).share
? L10n.of(context)!.share
: selectMode == SelectMode.select
? controller.selectedRoomIds.length.toString()
: controller.activeSpaceId == null
? AppConfig.applicationName
: Matrix.of(context)
.client
.getRoomById(controller.activeSpaceId)
.getRoomById(controller.activeSpaceId!)!
.displayname),
),
body: Column(children: [
@ -197,7 +197,7 @@ class ChatListView extends StatelessWidget {
fit: BoxFit.contain,
width: 44,
),
title: Text(L10n.of(context).setupChatBackupNow),
title: Text(L10n.of(context)!.setupChatBackupNow),
trailing: const Icon(Icons.chevron_right_outlined),
onTap: controller.firstRunBootstrapAction,
),
@ -211,7 +211,7 @@ class ChatListView extends StatelessWidget {
onPressed: () =>
VRouter.of(context).to('/newprivatechat'),
icon: const Icon(CupertinoIcons.chat_bubble),
label: Text(L10n.of(context).newChat),
label: Text(L10n.of(context)!.newChat),
)
: null,
bottomNavigationBar: Column(
@ -232,7 +232,7 @@ class ChatListView extends StatelessWidget {
class _ChatListViewBody extends StatefulWidget {
final ChatListController controller;
const _ChatListViewBody(this.controller, {Key key}) : super(key: key);
const _ChatListViewBody(this.controller, {Key? key}) : super(key: key);
@override
State<_ChatListViewBody> createState() => _ChatListViewBodyState();
@ -240,12 +240,12 @@ class _ChatListViewBody extends StatefulWidget {
class _ChatListViewBodyState extends State<_ChatListViewBody> {
// the matrix sync stream
StreamSubscription _subscription;
StreamSubscription _clientSubscription;
late StreamSubscription _subscription;
late StreamSubscription _clientSubscription;
// used to check the animation direction
String _lastUserId;
String _lastSpaceId;
String? _lastUserId;
String? _lastSpaceId;
@override
void initState() {
@ -285,7 +285,7 @@ class _ChatListViewBodyState extends State<_ChatListViewBody> {
),
Center(
child: Text(
L10n.of(context).startYourFirstChat,
L10n.of(context)!.startYourFirstChat,
textAlign: TextAlign.start,
style: const TextStyle(
color: Colors.grey,
@ -324,9 +324,9 @@ class _ChatListViewBodyState extends State<_ChatListViewBody> {
} else {
const dummyChatCount = 8;
final titleColor =
Theme.of(context).textTheme.bodyText1.color.withAlpha(100);
Theme.of(context).textTheme.bodyText1!.color!.withAlpha(100);
final subtitleColor =
Theme.of(context).textTheme.bodyText1.color.withAlpha(50);
Theme.of(context).textTheme.bodyText1!.color!.withAlpha(50);
child = ListView.builder(
itemCount: dummyChatCount,
itemBuilder: (context, i) => Opacity(
@ -336,7 +336,7 @@ class _ChatListViewBodyState extends State<_ChatListViewBody> {
backgroundColor: titleColor,
child: CircularProgressIndicator(
strokeWidth: 1,
color: Theme.of(context).textTheme.bodyText1.color,
color: Theme.of(context).textTheme.bodyText1!.color,
),
),
title: Row(
@ -417,11 +417,11 @@ class _ChatListViewBodyState extends State<_ChatListViewBody> {
final newClient = Matrix.of(context).client;
if (_lastUserId != newClient.userID) {
reversed = Matrix.of(context)
.currentBundle
.indexWhere((element) => element.userID == _lastUserId) <
.currentBundle!
.indexWhere((element) => element!.userID == _lastUserId) <
Matrix.of(context)
.currentBundle
.indexWhere((element) => element.userID == newClient.userID);
.currentBundle!
.indexWhere((element) => element!.userID == newClient.userID);
}
// otherwise, the space changed...
else {

View file

@ -8,20 +8,20 @@ import 'chat_list.dart';
class ClientChooserButton extends StatelessWidget {
final ChatListController controller;
const ClientChooserButton(this.controller, {Key key}) : super(key: key);
const ClientChooserButton(this.controller, {Key? key}) : super(key: key);
List<PopupMenuEntry<Object>> _bundleMenuItems(BuildContext context) {
final matrix = Matrix.of(context);
final bundles = matrix.accountBundles.keys.toList()
..sort((a, b) => a.isValidMatrixId == b.isValidMatrixId
..sort((a, b) => a!.isValidMatrixId == b!.isValidMatrixId
? 0
: a.isValidMatrixId && !b.isValidMatrixId
? -1
: 1);
return <PopupMenuEntry<Object>>[
for (final bundle in bundles) ...[
if (matrix.accountBundles[bundle].length != 1 ||
matrix.accountBundles[bundle].single.userID != bundle)
if (matrix.accountBundles[bundle]!.length != 1 ||
matrix.accountBundles[bundle]!.single!.userID != bundle)
PopupMenuItem(
value: null,
child: Column(
@ -29,9 +29,9 @@ class ClientChooserButton extends StatelessWidget {
mainAxisSize: MainAxisSize.min,
children: [
Text(
bundle,
bundle!,
style: TextStyle(
color: Theme.of(context).textTheme.subtitle1.color,
color: Theme.of(context).textTheme.subtitle1!.color,
fontSize: 14,
),
),
@ -39,25 +39,26 @@ class ClientChooserButton extends StatelessWidget {
],
),
),
...matrix.accountBundles[bundle]
...matrix.accountBundles[bundle]!
.map(
(client) => PopupMenuItem(
value: client,
child: FutureBuilder<Profile>(
future: client.ownProfile,
future: client!.ownProfile,
builder: (context, snapshot) => Row(
children: [
Avatar(
mxContent: snapshot.data?.avatarUrl,
name: snapshot.data?.displayName ??
client.userID.localpart,
client.userID!.localpart,
size: 28,
fontSize: 12,
),
const SizedBox(width: 12),
Expanded(
child: Text(
snapshot.data?.displayName ?? client.userID.localpart,
snapshot.data?.displayName ??
client.userID!.localpart!,
overflow: TextOverflow.ellipsis,
),
),
@ -86,7 +87,7 @@ class ClientChooserButton extends StatelessWidget {
builder: (context, snapshot) => PopupMenuButton<Object>(
child: Avatar(
mxContent: snapshot.data?.avatarUrl,
name: snapshot.data?.displayName ?? matrix.client.userID.localpart,
name: snapshot.data?.displayName ?? matrix.client.userID!.localpart,
size: 28,
fontSize: 12,
),

View file

@ -10,7 +10,7 @@ import 'package:fluffychat/widgets/matrix.dart';
class SpacesBottomBar extends StatelessWidget {
final ChatListController controller;
const SpacesBottomBar(this.controller, {Key key}) : super(key: key);
const SpacesBottomBar(this.controller, {Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
@ -25,8 +25,9 @@ class SpacesBottomBar extends StatelessWidget {
child: SafeArea(
child: StreamBuilder<Object>(
stream: Matrix.of(context).client.onSync.stream.where((sync) =>
(sync.rooms?.join?.values?.any((r) =>
r.state?.any((s) => s.type.startsWith('m.space'))) ??
(sync.rooms?.join?.values.any((r) =>
r.state?.any((s) => s.type.startsWith('m.space')) ??
false) ??
false) ||
(sync.rooms?.leave?.isNotEmpty ?? false)),
builder: (context, snapshot) {
@ -48,7 +49,7 @@ class SpacesBottomBar extends StatelessWidget {
icon: const Icon(CupertinoIcons.chat_bubble_2),
activeIcon:
const Icon(CupertinoIcons.chat_bubble_2_fill),
title: Text(L10n.of(context).allChats),
title: Text(L10n.of(context)!.allChats),
),
...controller.spaces
.map((space) => SalomonBottomBarItem(

View file

@ -1,5 +1,3 @@
//@dart=2.12
import 'package:flutter/material.dart';
import 'package:adaptive_dialog/adaptive_dialog.dart';