mirror of
https://gitlab.com/famedly/fluffychat.git
synced 2025-01-12 02:32:54 +01:00
Merge branch 'krille/null-safety' into 'main'
Null safety See merge request famedly/fluffychat!550
This commit is contained in:
commit
74e92f8474
@ -1,3 +1,5 @@
|
||||
//@dart=2.12
|
||||
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
@ -5,12 +7,12 @@ import 'package:fluffychat/utils/platform_infos.dart';
|
||||
|
||||
class AdaptiveFlatButton extends StatelessWidget {
|
||||
final String label;
|
||||
final Color textColor;
|
||||
final Function onPressed;
|
||||
final Color? textColor;
|
||||
final void Function()? onPressed;
|
||||
|
||||
const AdaptiveFlatButton({
|
||||
Key key,
|
||||
@required this.label,
|
||||
Key? key,
|
||||
required this.label,
|
||||
this.textColor,
|
||||
this.onPressed,
|
||||
}) : super(key: key);
|
||||
|
@ -1,3 +1,5 @@
|
||||
//@dart=2.12
|
||||
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
@ -8,12 +10,12 @@ import 'package:fluffychat/utils/string_color.dart';
|
||||
import 'matrix.dart';
|
||||
|
||||
class Avatar extends StatelessWidget {
|
||||
final Uri mxContent;
|
||||
final String name;
|
||||
final Uri? mxContent;
|
||||
final String? name;
|
||||
final double size;
|
||||
final Function onTap;
|
||||
final void Function()? onTap;
|
||||
static const double defaultSize = 44;
|
||||
final Client client;
|
||||
final Client? client;
|
||||
final double fontSize;
|
||||
|
||||
const Avatar(
|
||||
@ -23,7 +25,7 @@ class Avatar extends StatelessWidget {
|
||||
this.onTap,
|
||||
this.client,
|
||||
this.fontSize = 18,
|
||||
Key key,
|
||||
Key? key,
|
||||
}) : super(key: key);
|
||||
|
||||
@override
|
||||
@ -34,10 +36,13 @@ class Avatar extends StatelessWidget {
|
||||
height: size * MediaQuery.of(context).devicePixelRatio,
|
||||
);
|
||||
var fallbackLetters = '@';
|
||||
if ((name?.runes?.length ?? 0) >= 2) {
|
||||
fallbackLetters = String.fromCharCodes(name.runes, 0, 2);
|
||||
} else if ((name?.runes?.length ?? 0) == 1) {
|
||||
fallbackLetters = name;
|
||||
final name = this.name;
|
||||
if (name != null) {
|
||||
if (name.runes.length >= 2) {
|
||||
fallbackLetters = String.fromCharCodes(name.runes, 0, 2);
|
||||
} else if (name.runes.length == 1) {
|
||||
fallbackLetters = name;
|
||||
}
|
||||
}
|
||||
final noPic = mxContent == null ||
|
||||
mxContent.toString().isEmpty ||
|
||||
|
@ -1,3 +1,5 @@
|
||||
//@dart=2.12
|
||||
|
||||
import 'dart:async';
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
@ -13,7 +15,7 @@ import 'matrix.dart';
|
||||
class ChatSettingsPopupMenu extends StatefulWidget {
|
||||
final Room room;
|
||||
final bool displayChatDetails;
|
||||
const ChatSettingsPopupMenu(this.room, this.displayChatDetails, {Key key})
|
||||
const ChatSettingsPopupMenu(this.room, this.displayChatDetails, {Key? key})
|
||||
: super(key: key);
|
||||
|
||||
@override
|
||||
@ -21,7 +23,7 @@ class ChatSettingsPopupMenu extends StatefulWidget {
|
||||
}
|
||||
|
||||
class _ChatSettingsPopupMenuState extends State<ChatSettingsPopupMenu> {
|
||||
StreamSubscription notificationChangeSub;
|
||||
StreamSubscription? notificationChangeSub;
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
@ -37,7 +39,7 @@ class _ChatSettingsPopupMenuState extends State<ChatSettingsPopupMenu> {
|
||||
.stream
|
||||
.where((u) => u.type == 'm.push_rules')
|
||||
.listen(
|
||||
(u) => setState(() => null),
|
||||
(u) => setState(() {}),
|
||||
);
|
||||
final items = <PopupMenuEntry<String>>[
|
||||
widget.room.pushRuleState == PushRuleState.notify
|
||||
@ -47,7 +49,7 @@ class _ChatSettingsPopupMenuState extends State<ChatSettingsPopupMenu> {
|
||||
children: [
|
||||
const Icon(Icons.notifications_off_outlined),
|
||||
const SizedBox(width: 12),
|
||||
Text(L10n.of(context).muteChat),
|
||||
Text(L10n.of(context)!.muteChat),
|
||||
],
|
||||
),
|
||||
)
|
||||
@ -57,7 +59,7 @@ class _ChatSettingsPopupMenuState extends State<ChatSettingsPopupMenu> {
|
||||
children: [
|
||||
const Icon(Icons.notifications_on_outlined),
|
||||
const SizedBox(width: 12),
|
||||
Text(L10n.of(context).unmuteChat),
|
||||
Text(L10n.of(context)!.unmuteChat),
|
||||
],
|
||||
),
|
||||
),
|
||||
@ -67,7 +69,7 @@ class _ChatSettingsPopupMenuState extends State<ChatSettingsPopupMenu> {
|
||||
children: [
|
||||
const Icon(Icons.delete_outlined),
|
||||
const SizedBox(width: 12),
|
||||
Text(L10n.of(context).leave),
|
||||
Text(L10n.of(context)!.leave),
|
||||
],
|
||||
),
|
||||
),
|
||||
@ -81,7 +83,7 @@ class _ChatSettingsPopupMenuState extends State<ChatSettingsPopupMenu> {
|
||||
children: [
|
||||
const Icon(Icons.info_outline_rounded),
|
||||
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(
|
||||
useRootNavigator: false,
|
||||
context: context,
|
||||
title: L10n.of(context).areYouSure,
|
||||
okLabel: L10n.of(context).ok,
|
||||
cancelLabel: L10n.of(context).cancel,
|
||||
title: L10n.of(context)!.areYouSure,
|
||||
okLabel: L10n.of(context)!.ok,
|
||||
cancelLabel: L10n.of(context)!.cancel,
|
||||
);
|
||||
if (confirmed == OkCancelResult.ok) {
|
||||
final success = await showFutureLoadingDialog(
|
||||
|
@ -1,3 +1,5 @@
|
||||
//@dart=2.12
|
||||
|
||||
import 'dart:async';
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
@ -9,15 +11,15 @@ import '../utils/localized_exception_extension.dart';
|
||||
import 'matrix.dart';
|
||||
|
||||
class ConnectionStatusHeader extends StatefulWidget {
|
||||
const ConnectionStatusHeader({Key key}) : super(key: key);
|
||||
const ConnectionStatusHeader({Key? key}) : super(key: key);
|
||||
|
||||
@override
|
||||
_ConnectionStatusHeaderState createState() => _ConnectionStatusHeaderState();
|
||||
}
|
||||
|
||||
class _ConnectionStatusHeaderState extends State<ConnectionStatusHeader> {
|
||||
StreamSubscription _onSyncSub;
|
||||
StreamSubscription _onSyncErrorSub;
|
||||
StreamSubscription? _onSyncSub;
|
||||
StreamSubscription? _onSyncErrorSub;
|
||||
bool get _connected =>
|
||||
DateTime.now().millisecondsSinceEpoch -
|
||||
_lastSyncReceived.millisecondsSinceEpoch <
|
||||
@ -82,14 +84,15 @@ extension on SyncStatusUpdate {
|
||||
String toLocalizedString(BuildContext context) {
|
||||
switch (status) {
|
||||
case SyncStatus.waitingForResponse:
|
||||
return L10n.of(context).loadingPleaseWait;
|
||||
return L10n.of(context)!.loadingPleaseWait;
|
||||
case SyncStatus.error:
|
||||
return (error.exception as Object).toLocalizedString(context);
|
||||
return ((error?.exception ?? Object()) as Object)
|
||||
.toLocalizedString(context);
|
||||
case SyncStatus.processing:
|
||||
case SyncStatus.cleaningUp:
|
||||
case SyncStatus.finished:
|
||||
default:
|
||||
return L10n.of(context).synchronizingPleaseWait;
|
||||
return L10n.of(context)!.synchronizingPleaseWait;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,3 +1,5 @@
|
||||
//@dart=2.12
|
||||
|
||||
import 'dart:async';
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
@ -14,15 +16,15 @@ class ContactsList extends StatefulWidget {
|
||||
final TextEditingController searchController;
|
||||
|
||||
const ContactsList({
|
||||
Key key,
|
||||
@required this.searchController,
|
||||
Key? key,
|
||||
required this.searchController,
|
||||
}) : super(key: key);
|
||||
@override
|
||||
_ContactsState createState() => _ContactsState();
|
||||
}
|
||||
|
||||
class _ContactsState extends State<ContactsList> {
|
||||
StreamSubscription _onSync;
|
||||
StreamSubscription? _onSync;
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
@ -31,11 +33,11 @@ class _ContactsState extends State<ContactsList> {
|
||||
}
|
||||
|
||||
DateTime _lastSetState = DateTime.now();
|
||||
Timer _coolDown;
|
||||
Timer? _coolDown;
|
||||
|
||||
void _updateView() {
|
||||
_lastSetState = DateTime.now();
|
||||
setState(() => null);
|
||||
setState(() {});
|
||||
}
|
||||
|
||||
@override
|
||||
@ -68,15 +70,16 @@ class _ContactsState extends State<ContactsList> {
|
||||
class _ContactListTile extends StatelessWidget {
|
||||
final Presence contact;
|
||||
|
||||
const _ContactListTile({Key key, @required this.contact}) : super(key: key);
|
||||
const _ContactListTile({Key? key, required this.contact}) : super(key: key);
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return FutureBuilder<Profile>(
|
||||
future:
|
||||
Matrix.of(context).client.getProfileFromUserId(contact.senderId),
|
||||
builder: (context, snapshot) {
|
||||
final displayname =
|
||||
snapshot.data?.displayName ?? contact.senderId.localpart;
|
||||
final displayname = snapshot.data?.displayName ??
|
||||
contact.senderId.localpart ??
|
||||
'No valid MXID';
|
||||
final avatarUrl = snapshot.data?.avatarUrl;
|
||||
return ListTile(
|
||||
leading: SizedBox(
|
||||
@ -108,7 +111,7 @@ class _ContactListTile extends StatelessWidget {
|
||||
'rooms',
|
||||
Matrix.of(context)
|
||||
.client
|
||||
.getDirectChatFromUserId(contact.senderId)
|
||||
.getDirectChatFromUserId(contact.senderId)!
|
||||
]),
|
||||
);
|
||||
});
|
||||
|
@ -1,3 +1,5 @@
|
||||
//@dart=2.12
|
||||
|
||||
import 'dart:math';
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
@ -5,7 +7,7 @@ import 'package:flutter/material.dart';
|
||||
class EmptyPage extends StatelessWidget {
|
||||
final bool loading;
|
||||
static const double _width = 200;
|
||||
const EmptyPage({this.loading = false, Key key}) : super(key: key);
|
||||
const EmptyPage({this.loading = false, Key? key}) : super(key: key);
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final _width = min(MediaQuery.of(context).size.width, EmptyPage._width);
|
||||
|
@ -1,3 +1,5 @@
|
||||
//@dart=2.12
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
import 'package:matrix/matrix.dart';
|
||||
@ -7,26 +9,21 @@ import 'package:fluffychat/widgets/layouts/empty_page.dart';
|
||||
import 'package:fluffychat/widgets/matrix.dart';
|
||||
|
||||
class LoadingView extends StatelessWidget {
|
||||
const LoadingView({Key key}) : super(key: key);
|
||||
const LoadingView({Key? key}) : super(key: key);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
if (Matrix.of(context)
|
||||
.widget
|
||||
.clients
|
||||
.every((client) => client.loginState != null)) {
|
||||
WidgetsBinding.instance.addPostFrameCallback(
|
||||
(_) => VRouter.of(context).to(
|
||||
Matrix.of(context)
|
||||
.widget
|
||||
.clients
|
||||
.any((client) => client.loginState == LoginState.loggedIn)
|
||||
? '/rooms'
|
||||
: '/home',
|
||||
queryParameters: VRouter.of(context).queryParameters,
|
||||
),
|
||||
);
|
||||
}
|
||||
WidgetsBinding.instance?.addPostFrameCallback(
|
||||
(_) => VRouter.of(context).to(
|
||||
Matrix.of(context)
|
||||
.widget
|
||||
.clients
|
||||
.any((client) => client.loginState == LoginState.loggedIn)
|
||||
? '/rooms'
|
||||
: '/home',
|
||||
queryParameters: VRouter.of(context).queryParameters,
|
||||
),
|
||||
);
|
||||
return const EmptyPage(loading: true);
|
||||
}
|
||||
}
|
||||
|
@ -1,9 +1,11 @@
|
||||
//@dart=2.12
|
||||
|
||||
import 'dart:math';
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
class MaxWidthBody extends StatelessWidget {
|
||||
final Widget child;
|
||||
final Widget? child;
|
||||
final double maxWidth;
|
||||
final bool withScrolling;
|
||||
|
||||
@ -11,7 +13,7 @@ class MaxWidthBody extends StatelessWidget {
|
||||
this.child,
|
||||
this.maxWidth = 600,
|
||||
this.withScrolling = false,
|
||||
Key key,
|
||||
Key? key,
|
||||
}) : super(key: key);
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
|
@ -1,3 +1,5 @@
|
||||
//@dart=2.12
|
||||
|
||||
import 'dart:math';
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
@ -8,14 +10,14 @@ import 'package:fluffychat/widgets/matrix.dart';
|
||||
class OnePageCard extends StatelessWidget {
|
||||
final Widget child;
|
||||
|
||||
const OnePageCard({Key key, this.child}) : super(key: key);
|
||||
const OnePageCard({Key? key, required this.child}) : super(key: key);
|
||||
|
||||
static const int alpha = 12;
|
||||
static num breakpoint = FluffyThemes.columnWidth * 2;
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final horizontalPadding =
|
||||
max((MediaQuery.of(context).size.width - 600) / 2, 24);
|
||||
max<double>((MediaQuery.of(context).size.width - 600) / 2, 24);
|
||||
return MediaQuery.of(context).size.width <= breakpoint ||
|
||||
Matrix.of(context).client.isLogged()
|
||||
? child
|
||||
|
@ -1,3 +1,5 @@
|
||||
//@dart=2.12
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
import 'package:vrouter/vrouter.dart';
|
||||
@ -6,15 +8,16 @@ import 'package:fluffychat/config/themes.dart';
|
||||
|
||||
class SideViewLayout extends StatelessWidget {
|
||||
final Widget mainView;
|
||||
final Widget sideView;
|
||||
final Widget? sideView;
|
||||
|
||||
const SideViewLayout({Key key, @required this.mainView, this.sideView})
|
||||
const SideViewLayout({Key? key, required this.mainView, this.sideView})
|
||||
: super(key: key);
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
var currentUrl = Uri.decodeFull(VRouter.of(context).url);
|
||||
if (!currentUrl.endsWith('/')) currentUrl += '/';
|
||||
final hideSideView = currentUrl.split('/').length == 4;
|
||||
final sideView = this.sideView;
|
||||
return sideView == null
|
||||
? mainView
|
||||
: MediaQuery.of(context).size.width < FluffyThemes.columnWidth * 3.5 &&
|
||||
|
@ -1,3 +1,5 @@
|
||||
//@dart=2.12
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
import 'package:fluffychat/config/themes.dart';
|
||||
@ -6,9 +8,11 @@ class TwoColumnLayout extends StatelessWidget {
|
||||
final Widget mainView;
|
||||
final Widget sideView;
|
||||
|
||||
const TwoColumnLayout(
|
||||
{Key key, @required this.mainView, @required this.sideView})
|
||||
: super(key: key);
|
||||
const TwoColumnLayout({
|
||||
Key? key,
|
||||
required this.mainView,
|
||||
required this.sideView,
|
||||
}) : super(key: key);
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
if (MediaQuery.of(context).size.width <= FluffyThemes.columnWidth * 2) {
|
||||
|
Loading…
Reference in New Issue
Block a user