mirror of
https://gitlab.com/comunic/comunicmobile
synced 2025-06-20 16:55:17 +00:00
Start to fix null safety migration errors
This commit is contained in:
@ -14,10 +14,10 @@ class AppBarCustomDropDownWidget extends StatefulWidget {
|
||||
final Widget Function(BuildContext) onBuildOverlay;
|
||||
|
||||
const AppBarCustomDropDownWidget({
|
||||
Key key,
|
||||
@required this.icon,
|
||||
@required this.notificationsBadge,
|
||||
@required this.onBuildOverlay,
|
||||
Key? key,
|
||||
required this.icon,
|
||||
required this.notificationsBadge,
|
||||
required this.onBuildOverlay,
|
||||
}) : assert(icon != null),
|
||||
assert(notificationsBadge != null),
|
||||
assert(onBuildOverlay != null),
|
||||
@ -46,7 +46,7 @@ class AppBarCustomDropDownWidgetState
|
||||
setState(() => _visible = !_visible);
|
||||
|
||||
if (_visible) {
|
||||
RenderBox renderBox = context.findRenderObject();
|
||||
RenderBox renderBox = context.findRenderObject() as RenderBox;
|
||||
final size = renderBox.size;
|
||||
final offset = renderBox.localToGlobal(Offset(size.width, size.height));
|
||||
|
||||
@ -68,10 +68,10 @@ class _AppBarCustomPopupRoute extends PopupRoute {
|
||||
final void Function() onDispose;
|
||||
|
||||
_AppBarCustomPopupRoute({
|
||||
@required this.showContext,
|
||||
@required this.onBuild,
|
||||
@required this.offset,
|
||||
@required this.onDispose,
|
||||
required this.showContext,
|
||||
required this.onBuild,
|
||||
required this.offset,
|
||||
required this.onDispose,
|
||||
});
|
||||
|
||||
@override
|
||||
@ -82,7 +82,7 @@ class _AppBarCustomPopupRoute extends PopupRoute {
|
||||
}
|
||||
|
||||
@override
|
||||
Color get barrierColor => null;
|
||||
Color? get barrierColor => null;
|
||||
|
||||
@override
|
||||
bool get barrierDismissible => true;
|
||||
@ -116,10 +116,10 @@ class _AppBarCustomPopupRoute extends PopupRoute {
|
||||
}
|
||||
|
||||
class _PopupContentBody extends StatelessWidget {
|
||||
final Widget Function(BuildContext) onBuild;
|
||||
final Offset offset;
|
||||
final Widget Function(BuildContext)? onBuild;
|
||||
final Offset? offset;
|
||||
|
||||
const _PopupContentBody({Key key, this.onBuild, this.offset})
|
||||
const _PopupContentBody({Key? key, this.onBuild, this.offset})
|
||||
: super(key: key);
|
||||
|
||||
@override
|
||||
@ -132,12 +132,12 @@ class _PopupContentBody extends StatelessWidget {
|
||||
child: Container(color: Color(0x55000000)),
|
||||
),
|
||||
Positioned(
|
||||
left: offset.dx - _overlay_w + 4,
|
||||
top: offset.dy - 4,
|
||||
left: offset!.dx - _overlay_w + 4,
|
||||
top: offset!.dy - 4,
|
||||
width: _overlay_w,
|
||||
height: _overlay_h,
|
||||
child: Scaffold(
|
||||
body: Card(child: onBuild(context)),
|
||||
body: Card(child: onBuild!(context)),
|
||||
backgroundColor: Colors.transparent,
|
||||
),
|
||||
)
|
||||
|
@ -15,9 +15,9 @@ class CallWindowWidget extends StatefulWidget {
|
||||
final void Function() onClose;
|
||||
|
||||
const CallWindowWidget({
|
||||
Key key,
|
||||
@required this.convID,
|
||||
@required this.onClose,
|
||||
Key? key,
|
||||
required this.convID,
|
||||
required this.onClose,
|
||||
}) : assert(convID != null),
|
||||
assert(onClose != null),
|
||||
super(key: key);
|
||||
@ -27,7 +27,7 @@ class CallWindowWidget extends StatefulWidget {
|
||||
}
|
||||
|
||||
class _CallWindowWidgetState extends State<CallWindowWidget> {
|
||||
double _left, _top;
|
||||
double? _left, _top;
|
||||
|
||||
var _fullScreen = false;
|
||||
|
||||
@ -71,7 +71,7 @@ class _CallWindowWidgetState extends State<CallWindowWidget> {
|
||||
height: 30,
|
||||
appBar: AppBar(
|
||||
backgroundColor: Colors.black,
|
||||
title: Text(convName == null ? tr("Loading...") : convName),
|
||||
title: Text(convName == null ? tr("Loading...")! : convName),
|
||||
actions: <Widget>[
|
||||
// Go full screen
|
||||
IconButton(
|
||||
@ -98,9 +98,9 @@ class _CallWindowWidgetState extends State<CallWindowWidget> {
|
||||
void _moveEnd(DraggableDetails details) {
|
||||
// Determine the limits of containing stack
|
||||
RenderBox renderBox = context
|
||||
.findAncestorStateOfType<CallsAreaState>()
|
||||
.findAncestorStateOfType<CallsAreaState>()!
|
||||
.context
|
||||
.findRenderObject();
|
||||
.findRenderObject() as RenderBox;
|
||||
final size = renderBox.size;
|
||||
final offset = renderBox.localToGlobal(Offset.zero);
|
||||
|
||||
@ -109,13 +109,13 @@ class _CallWindowWidgetState extends State<CallWindowWidget> {
|
||||
_left = details.offset.dx - offset.dx;
|
||||
|
||||
// Force the window to appear completely on the screen
|
||||
if (_top + _WindowSize.height >= size.height)
|
||||
if (_top! + _WindowSize.height >= size.height)
|
||||
_top = size.height - _WindowSize.height;
|
||||
if (_left + _WindowSize.width >= size.width)
|
||||
if (_left! + _WindowSize.width >= size.width)
|
||||
_left = size.width - _WindowSize.width;
|
||||
|
||||
if (_top < 0) _top = 0;
|
||||
if (_left < 0) _left = 0;
|
||||
if (_top! < 0) _top = 0;
|
||||
if (_left! < 0) _left = 0;
|
||||
|
||||
setState(() {});
|
||||
}
|
||||
|
@ -6,7 +6,7 @@ import 'package:flutter/material.dart';
|
||||
/// @author Pierre Hubert
|
||||
|
||||
class CallsArea extends StatefulWidget {
|
||||
const CallsArea({Key key}) : super(key: key);
|
||||
const CallsArea({Key? key}) : super(key: key);
|
||||
|
||||
@override
|
||||
CallsAreaState createState() => CallsAreaState();
|
||||
|
@ -24,9 +24,9 @@ class ConversationWindow extends StatefulWidget {
|
||||
final Function() onClose;
|
||||
|
||||
const ConversationWindow({
|
||||
Key key,
|
||||
@required this.convID,
|
||||
@required this.onClose,
|
||||
Key? key,
|
||||
required this.convID,
|
||||
required this.onClose,
|
||||
}) : assert(convID != null),
|
||||
assert(onClose != null),
|
||||
super(key: key);
|
||||
@ -36,8 +36,8 @@ class ConversationWindow extends StatefulWidget {
|
||||
}
|
||||
|
||||
class _ConversationWindowState extends SafeState<ConversationWindow> {
|
||||
Conversation _conversation;
|
||||
String _convTitle;
|
||||
Conversation? _conversation;
|
||||
late String _convTitle;
|
||||
bool _error = false;
|
||||
bool _collapsed = false;
|
||||
bool _hasNewMessages = false;
|
||||
@ -71,7 +71,7 @@ class _ConversationWindowState extends SafeState<ConversationWindow> {
|
||||
} catch (e, s) {
|
||||
_setError(true);
|
||||
print("Could not refresh the list of conversations! $e\n$s");
|
||||
showSimpleSnack(context, tr("Could not load conversation information!"));
|
||||
showSimpleSnack(context, tr("Could not load conversation information!")!);
|
||||
}
|
||||
}
|
||||
|
||||
@ -92,7 +92,7 @@ class _ConversationWindowState extends SafeState<ConversationWindow> {
|
||||
if (_error)
|
||||
return ConversationWindowContainer(
|
||||
icon: Icon(Icons.error),
|
||||
title: Text(tr("Error")),
|
||||
title: Text(tr("Error")!),
|
||||
onClose: widget.onClose,
|
||||
onToggleCollapse: _toggleVisibility,
|
||||
isCollapsed: _collapsed,
|
||||
@ -100,7 +100,7 @@ class _ConversationWindowState extends SafeState<ConversationWindow> {
|
||||
actions: [
|
||||
ElevatedButton(
|
||||
onPressed: _refresh,
|
||||
child: Text(tr("Try again").toUpperCase()),
|
||||
child: Text(tr("Try again")!.toUpperCase()),
|
||||
)
|
||||
]),
|
||||
);
|
||||
@ -109,7 +109,7 @@ class _ConversationWindowState extends SafeState<ConversationWindow> {
|
||||
if (_conversation == null)
|
||||
return ConversationWindowContainer(
|
||||
icon: Icon(Icons.message),
|
||||
title: Text(tr("Loading...")),
|
||||
title: Text(tr("Loading...")!),
|
||||
onClose: widget.onClose,
|
||||
onToggleCollapse: _toggleVisibility,
|
||||
isCollapsed: _collapsed,
|
||||
@ -123,7 +123,7 @@ class _ConversationWindowState extends SafeState<ConversationWindow> {
|
||||
onClose: widget.onClose,
|
||||
onToggleCollapse: _toggleVisibility,
|
||||
isCollapsed: _collapsed,
|
||||
action: (_conversation.callCapabilities != CallCapabilities.NONE
|
||||
action: (_conversation!.callCapabilities != CallCapabilities.NONE
|
||||
? [IconButton(icon: Icon(Icons.call), onPressed: _startCall)]
|
||||
: [])
|
||||
..addAll(<Widget>[
|
||||
@ -131,19 +131,19 @@ class _ConversationWindowState extends SafeState<ConversationWindow> {
|
||||
itemBuilder: (c) => [
|
||||
// Show in full screen
|
||||
PopupMenuItem(
|
||||
child: Text(tr("Open in full screen")),
|
||||
child: Text(tr("Open in full screen")!),
|
||||
value: _Actions.OPEN_FULL_SCREEN,
|
||||
),
|
||||
|
||||
// Show the list of members
|
||||
PopupMenuItem(
|
||||
child: Text(tr("Members")),
|
||||
child: Text(tr("Members")!),
|
||||
value: _Actions.OPEN_MEMBERS,
|
||||
),
|
||||
|
||||
// Show conversation settings
|
||||
PopupMenuItem(
|
||||
child: Text(tr("Settings")),
|
||||
child: Text(tr("Settings")!),
|
||||
value: _Actions.OPEN_SETTINGS,
|
||||
)
|
||||
],
|
||||
@ -174,8 +174,8 @@ class _ConversationWindowState extends SafeState<ConversationWindow> {
|
||||
}
|
||||
|
||||
void _openFullScreen() {
|
||||
MainController.of(context)
|
||||
.openConversation(_conversation, fullScreen: true);
|
||||
MainController.of(context)!
|
||||
.openConversation(_conversation!, fullScreen: true);
|
||||
widget.onClose();
|
||||
}
|
||||
|
||||
@ -189,5 +189,5 @@ class _ConversationWindowState extends SafeState<ConversationWindow> {
|
||||
_refresh();
|
||||
}
|
||||
|
||||
void _startCall() => MainController.of(context).startCall(_convID);
|
||||
void _startCall() => MainController.of(context)!.startCall(_convID);
|
||||
}
|
||||
|
@ -8,24 +8,24 @@ import 'package:flutter/material.dart';
|
||||
/// @author Pierre Hubert
|
||||
|
||||
class ConversationWindowContainer extends StatelessWidget {
|
||||
final Color appBarBgColor;
|
||||
final Widget icon;
|
||||
final Color? appBarBgColor;
|
||||
final Widget? icon;
|
||||
final Widget title;
|
||||
final void Function() onClose;
|
||||
final void Function() onToggleCollapse;
|
||||
final bool isCollapsed;
|
||||
final Widget body;
|
||||
final List<Widget> action;
|
||||
final List<Widget>? action;
|
||||
|
||||
const ConversationWindowContainer({
|
||||
Key key,
|
||||
Key? key,
|
||||
this.appBarBgColor,
|
||||
this.icon,
|
||||
@required this.title,
|
||||
@required this.onClose,
|
||||
@required this.body,
|
||||
@required this.onToggleCollapse,
|
||||
@required this.isCollapsed,
|
||||
required this.title,
|
||||
required this.onClose,
|
||||
required this.body,
|
||||
required this.onToggleCollapse,
|
||||
required this.isCollapsed,
|
||||
this.action,
|
||||
}) : assert(title != null),
|
||||
assert(onClose != null),
|
||||
@ -47,7 +47,7 @@ class ConversationWindowContainer extends StatelessWidget {
|
||||
backgroundColor: appBarBgColor,
|
||||
leading: icon,
|
||||
title: GestureDetector(child: title, onTap: onToggleCollapse),
|
||||
actions: (action == null ? [] : action)
|
||||
actions: action ?? []
|
||||
..add(
|
||||
IconButton(icon: Icon(Icons.close), onPressed: onClose),
|
||||
),
|
||||
|
@ -9,14 +9,14 @@ import 'package:flutter/material.dart';
|
||||
/// @author Pierre
|
||||
|
||||
class ConversationsAreaWidget extends StatefulWidget {
|
||||
const ConversationsAreaWidget({Key key}) : super(key: key);
|
||||
const ConversationsAreaWidget({Key? key}) : super(key: key);
|
||||
|
||||
@override
|
||||
ConversationsAreaWidgetState createState() => ConversationsAreaWidgetState();
|
||||
}
|
||||
|
||||
class ConversationsAreaWidgetState extends State<ConversationsAreaWidget> {
|
||||
final _openConversations = Map<int, UniqueKey>();
|
||||
final _openConversations = Map<int?, UniqueKey>();
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
@ -31,17 +31,17 @@ class ConversationsAreaWidgetState extends State<ConversationsAreaWidget> {
|
||||
Widget _buildOpenButton() => OpenConversationButton();
|
||||
|
||||
/// Open a new conversation
|
||||
void openConversations(int convID) {
|
||||
void openConversations(int? convID) {
|
||||
if (!_openConversations.containsKey(convID))
|
||||
setState(() => _openConversations[convID] = UniqueKey());
|
||||
}
|
||||
|
||||
MapEntry<int, Widget> _conversationWindow(int convID, UniqueKey key) =>
|
||||
MapEntry<int?, Widget> _conversationWindow(int? convID, UniqueKey key) =>
|
||||
MapEntry(
|
||||
convID,
|
||||
ConversationWindow(
|
||||
key: key,
|
||||
convID: convID,
|
||||
convID: convID!,
|
||||
onClose: () => setState(() => _openConversations.remove(convID)),
|
||||
),
|
||||
);
|
||||
|
@ -17,7 +17,7 @@ class CurrentUserPanel extends StatefulWidget {
|
||||
}
|
||||
|
||||
class _CurrentUserPanelState extends SafeState<CurrentUserPanel> {
|
||||
User _user;
|
||||
User? _user;
|
||||
|
||||
Future<void> _refresh() async {
|
||||
try {
|
||||
@ -49,12 +49,12 @@ class _CurrentUserPanelState extends SafeState<CurrentUserPanel> {
|
||||
if (_user == null) return buildCenteredProgressBar();
|
||||
|
||||
return ListTile(
|
||||
onTap: () => MainController.of(context).openCurrentUserPage(),
|
||||
onTap: () => MainController.of(context)!.openCurrentUserPage(),
|
||||
leading: AccountImageWidget(
|
||||
user: _user,
|
||||
user: _user!,
|
||||
width: 50,
|
||||
),
|
||||
title: Text(_user.displayName),
|
||||
title: Text(_user!.displayName),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -36,9 +36,9 @@ class _GlobalSearchFieldState extends State<GlobalSearchField> {
|
||||
|
||||
final _controller = TextEditingController();
|
||||
|
||||
_SearchResults _searchResultsList;
|
||||
_SearchResults? _searchResultsList;
|
||||
|
||||
OverlayEntry _overlayEntry;
|
||||
OverlayEntry? _overlayEntry;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
@ -96,29 +96,29 @@ class _GlobalSearchFieldState extends State<GlobalSearchField> {
|
||||
|
||||
_searchResultsList = _SearchResults(results, users, groups);
|
||||
|
||||
if (_overlayEntry != null) _overlayEntry.markNeedsBuild();
|
||||
if (_overlayEntry != null) _overlayEntry!.markNeedsBuild();
|
||||
} catch (e, s) {
|
||||
print("Could not perform search! $e\n$s");
|
||||
showSimpleSnack(context, tr("Could not perform search!"));
|
||||
showSimpleSnack(context, tr("Could not perform search!")!);
|
||||
}
|
||||
}
|
||||
|
||||
void _showOverlay() {
|
||||
if (_overlayEntry == null) {
|
||||
_overlayEntry = _createOverlayEntry();
|
||||
Overlay.of(context).insert(_overlayEntry);
|
||||
Overlay.of(context)!.insert(_overlayEntry!);
|
||||
}
|
||||
}
|
||||
|
||||
void _removeOverlay() {
|
||||
if (_overlayEntry != null) {
|
||||
_overlayEntry.remove();
|
||||
_overlayEntry!.remove();
|
||||
_overlayEntry = null;
|
||||
}
|
||||
}
|
||||
|
||||
OverlayEntry _createOverlayEntry() {
|
||||
RenderBox renderBox = context.findRenderObject();
|
||||
RenderBox renderBox = context.findRenderObject() as RenderBox;
|
||||
var size = renderBox.size;
|
||||
var offset = renderBox.localToGlobal(Offset.zero);
|
||||
|
||||
@ -140,13 +140,13 @@ class _GlobalSearchFieldState extends State<GlobalSearchField> {
|
||||
}
|
||||
|
||||
class _SearchResultsWidget extends StatelessWidget {
|
||||
final _SearchResults results;
|
||||
final _SearchResults? results;
|
||||
final Function() onTap;
|
||||
|
||||
const _SearchResultsWidget({
|
||||
Key key,
|
||||
@required this.results,
|
||||
@required this.onTap,
|
||||
Key? key,
|
||||
required this.results,
|
||||
required this.onTap,
|
||||
}) : assert(onTap != null),
|
||||
super(key: key);
|
||||
|
||||
@ -155,32 +155,32 @@ class _SearchResultsWidget extends StatelessWidget {
|
||||
if (results == null) return Container();
|
||||
return ListView.builder(
|
||||
itemBuilder: _builder,
|
||||
itemCount: results.list.length,
|
||||
itemCount: results!.list.length,
|
||||
);
|
||||
}
|
||||
|
||||
Widget _builder(BuildContext context, int index) {
|
||||
final res = results.list[index];
|
||||
final SearchResult res = results!.list[index];
|
||||
|
||||
switch (res.kind) {
|
||||
case SearchResultKind.USER:
|
||||
final user = results.users.getUser(res.id);
|
||||
final user = results!.users.getUser(res.id);
|
||||
return ListTile(
|
||||
leading: AccountImageWidget(user: user),
|
||||
title: Text(user.displayName),
|
||||
onTap: () {
|
||||
MainController.of(context).openUserPage(user.id);
|
||||
MainController.of(context)!.openUserPage(user.id!);
|
||||
onTap();
|
||||
},
|
||||
);
|
||||
|
||||
case SearchResultKind.GROUP:
|
||||
final group = results.groups.getGroup(res.id);
|
||||
final group = results!.groups.getGroup(res.id)!;
|
||||
return ListTile(
|
||||
leading: GroupIcon(group: group),
|
||||
title: Text(group.displayName),
|
||||
onTap: () {
|
||||
MainController.of(context).openGroup(group.id);
|
||||
MainController.of(context)!.openGroup(group.id);
|
||||
onTap();
|
||||
},
|
||||
);
|
||||
|
@ -29,8 +29,8 @@ class MembershipsPanel extends StatefulWidget {
|
||||
final PageInfo currentPage;
|
||||
|
||||
const MembershipsPanel({
|
||||
Key key,
|
||||
@required this.currentPage,
|
||||
Key? key,
|
||||
required this.currentPage,
|
||||
}) : assert(currentPage != null),
|
||||
super(key: key);
|
||||
|
||||
@ -42,9 +42,9 @@ const _MembershipIconsWidth = 30.0;
|
||||
|
||||
class _MembershipsPanelState extends SafeState<MembershipsPanel> {
|
||||
final _refreshKey = GlobalKey<RefreshIndicatorState>();
|
||||
MembershipList _membershipList;
|
||||
UsersList _usersList;
|
||||
GroupsList _groupsList;
|
||||
MembershipList? _membershipList;
|
||||
UsersList? _usersList;
|
||||
late GroupsList _groupsList;
|
||||
|
||||
Future<void> _refresh() async {
|
||||
try {
|
||||
@ -87,13 +87,13 @@ class _MembershipsPanelState extends SafeState<MembershipsPanel> {
|
||||
iconColor: IconTheme.of(context).color,
|
||||
child: ListView.builder(
|
||||
itemBuilder: _buildMembershipTile,
|
||||
itemCount: _membershipList.length,
|
||||
itemCount: _membershipList!.length,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buildMembershipTile(BuildContext context, int index) {
|
||||
final membership = _membershipList[index];
|
||||
final Membership membership = _membershipList![index]!;
|
||||
|
||||
switch (membership.type) {
|
||||
case MembershipType.FRIEND:
|
||||
@ -111,17 +111,19 @@ class _MembershipsPanelState extends SafeState<MembershipsPanel> {
|
||||
|
||||
// TODO : add private messages icon support
|
||||
Widget _buildFriendMembership(Membership membership) {
|
||||
final user = _usersList.getUser(membership.friend.id);
|
||||
final connected = membership.friend.isConnected;
|
||||
final user = _usersList!.getUser(membership.friend!.id);
|
||||
final connected = membership.friend!.isConnected;
|
||||
|
||||
Widget subtitle;
|
||||
|
||||
if (!membership.friend.accepted) {
|
||||
final friend = membership.friend!;
|
||||
|
||||
if (!friend.accepted) {
|
||||
subtitle = RichText(
|
||||
text: TextSpan(children: [
|
||||
WidgetSpan(
|
||||
child: _RespondFriendshipRequestButton(
|
||||
friend: membership.friend,
|
||||
friend: friend,
|
||||
accept: true,
|
||||
text: tr("Accept"),
|
||||
color: Colors.green,
|
||||
@ -130,7 +132,7 @@ class _MembershipsPanelState extends SafeState<MembershipsPanel> {
|
||||
TextSpan(text: " "),
|
||||
WidgetSpan(
|
||||
child: _RespondFriendshipRequestButton(
|
||||
friend: membership.friend,
|
||||
friend: friend,
|
||||
accept: false,
|
||||
text: tr("Reject"),
|
||||
color: Colors.red,
|
||||
@ -139,7 +141,9 @@ class _MembershipsPanelState extends SafeState<MembershipsPanel> {
|
||||
]));
|
||||
} else
|
||||
subtitle = Text(
|
||||
connected ? tr("Online") : diffTimeFromNowToStr(membership.lastActive),
|
||||
connected
|
||||
? tr("Online")!
|
||||
: diffTimeFromNowToStr(membership.lastActive!)!,
|
||||
style: TextStyle(color: connected ? Colors.green : null),
|
||||
);
|
||||
|
||||
@ -152,13 +156,13 @@ class _MembershipsPanelState extends SafeState<MembershipsPanel> {
|
||||
leading: AccountImageWidget(user: user, width: _MembershipIconsWidth),
|
||||
title: Text(user.displayName),
|
||||
subtitle: subtitle,
|
||||
onTap: () => MainController.of(context).openUserPage(user.id),
|
||||
onTap: () => MainController.of(context)!.openUserPage(user.id!),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buildGroupMembership(Membership membership) {
|
||||
final group = _groupsList.getGroup(membership.groupID);
|
||||
final group = _groupsList.getGroup(membership.groupID)!;
|
||||
|
||||
return Container(
|
||||
color: widget.currentPage.type == PageType.GROUP_PAGE &&
|
||||
@ -167,11 +171,11 @@ class _MembershipsPanelState extends SafeState<MembershipsPanel> {
|
||||
: null,
|
||||
child: Column(
|
||||
children: [_buildMainGroupInformationTile(membership, group)]
|
||||
..addAll(_membershipList
|
||||
..addAll(_membershipList!
|
||||
.getGroupConversations(group.id)
|
||||
.map((e) => Padding(
|
||||
padding: const EdgeInsets.only(left: 30.0),
|
||||
child: _buildConversationMembership(e, true),
|
||||
child: _buildConversationMembership(e!, true),
|
||||
))
|
||||
.toList()),
|
||||
),
|
||||
@ -183,11 +187,11 @@ class _MembershipsPanelState extends SafeState<MembershipsPanel> {
|
||||
if (!group.isAtLeastMember) {
|
||||
subtitle = GroupMembershipWidget(
|
||||
group: group,
|
||||
onUpdated: () => _refreshKey.currentState.show(),
|
||||
onUpdated: () => _refreshKey.currentState!.show(),
|
||||
onError: _onGroupMembershipUpdateError,
|
||||
);
|
||||
} else {
|
||||
subtitle = Text(diffTimeFromNowToStr(membership.lastActive));
|
||||
subtitle = Text(diffTimeFromNowToStr(membership.lastActive!)!);
|
||||
} // Main group information
|
||||
|
||||
return ListTile(
|
||||
@ -197,17 +201,17 @@ class _MembershipsPanelState extends SafeState<MembershipsPanel> {
|
||||
),
|
||||
title: Text(group.displayName),
|
||||
subtitle: subtitle,
|
||||
onTap: () => MainController.of(context).openGroup(group.id),
|
||||
onTap: () => MainController.of(context)!.openGroup(group.id),
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buildConversationMembership(Membership membership,
|
||||
[bool allowGroup = false]) {
|
||||
final conversation = membership.conversation;
|
||||
final conversation = membership.conversation!;
|
||||
|
||||
if (conversation.isGroupConversation && !allowGroup) return Container();
|
||||
|
||||
Color color;
|
||||
Color? color;
|
||||
if (conversation.isHavingCall)
|
||||
color = Color(0xFF815d1d);
|
||||
else if (widget.currentPage.type == PageType.CONVERSATION_PAGE &&
|
||||
@ -221,7 +225,7 @@ class _MembershipsPanelState extends SafeState<MembershipsPanel> {
|
||||
dense: true,
|
||||
leading: ConversationImageWidget(
|
||||
conversation: conversation,
|
||||
users: _usersList,
|
||||
users: _usersList!,
|
||||
noUserImage: conversation.isGroupConversation,
|
||||
),
|
||||
title: Row(
|
||||
@ -233,20 +237,20 @@ class _MembershipsPanelState extends SafeState<MembershipsPanel> {
|
||||
SizedBox(width: 5),
|
||||
Expanded(
|
||||
child: Text(ConversationsHelper.getConversationName(
|
||||
conversation, _usersList)),
|
||||
conversation, _usersList)!),
|
||||
),
|
||||
],
|
||||
),
|
||||
subtitle: Text(diffTimeFromNowToStr(membership.lastActive) +
|
||||
(conversation.isHavingCall ? "\n" + tr("Ongoing call") : "")),
|
||||
onTap: () => MainController.of(context)
|
||||
subtitle: Text(diffTimeFromNowToStr(membership.lastActive!)! +
|
||||
(conversation.isHavingCall ? "\n" + tr("Ongoing call")! : "")),
|
||||
onTap: () => MainController.of(context)!
|
||||
.openConversation(conversation, fullScreen: true),
|
||||
trailing: conversation.isHavingCall
|
||||
? FloatingActionButton(
|
||||
heroTag: null,
|
||||
child: Icon(Icons.call),
|
||||
onPressed: () =>
|
||||
MainController.of(context).startCall(conversation.id),
|
||||
MainController.of(context)!.startCall(conversation.id!),
|
||||
)
|
||||
: null,
|
||||
),
|
||||
@ -269,43 +273,43 @@ class _MembershipsPanelState extends SafeState<MembershipsPanel> {
|
||||
if (accept)
|
||||
f.accepted = true;
|
||||
else
|
||||
_membershipList.removeFriend(f.id);
|
||||
_membershipList!.removeFriend(f.id);
|
||||
});
|
||||
_refreshKey.currentState.show();
|
||||
_refreshKey.currentState!.show();
|
||||
} catch (e, s) {
|
||||
print("Could not respond to friendship request! $e\n$s");
|
||||
showSimpleSnack(context, tr("Could not respond to friendship request!"));
|
||||
showSimpleSnack(context, tr("Could not respond to friendship request!")!);
|
||||
}
|
||||
}
|
||||
|
||||
/// Handles the case of failure in group membership update
|
||||
void _onGroupMembershipUpdateError() {
|
||||
showSimpleSnack(context, tr("Could not update group membership!"));
|
||||
_refreshKey.currentState.show();
|
||||
showSimpleSnack(context, tr("Could not update group membership!")!);
|
||||
_refreshKey.currentState!.show();
|
||||
}
|
||||
}
|
||||
|
||||
class _RespondFriendshipRequestButton extends StatelessWidget {
|
||||
final Friend friend;
|
||||
final bool accept;
|
||||
final String text;
|
||||
final String? text;
|
||||
final Color color;
|
||||
final void Function(Friend, bool) onTap;
|
||||
|
||||
const _RespondFriendshipRequestButton({
|
||||
Key key,
|
||||
@required this.friend,
|
||||
@required this.accept,
|
||||
@required this.text,
|
||||
@required this.color,
|
||||
@required this.onTap,
|
||||
Key? key,
|
||||
required this.friend,
|
||||
required this.accept,
|
||||
required this.text,
|
||||
required this.color,
|
||||
required this.onTap,
|
||||
}) : super(key: key);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return InkWell(
|
||||
onTap: () => onTap(friend, accept),
|
||||
child: Text(text, style: TextStyle(color: color)),
|
||||
child: Text(text!, style: TextStyle(color: color)),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -63,12 +63,12 @@ class _ComunicTabletAppBarWidgetState
|
||||
return AppBar(
|
||||
title: GestureDetector(
|
||||
child: Text("Comunic"),
|
||||
onTap: () => MainController.of(context).openLatestPostsPage()),
|
||||
onTap: () => MainController.of(context)!.openLatestPostsPage()),
|
||||
actions: <Widget>[
|
||||
AppBarCustomDropDownWidget(
|
||||
key: notificationsDropdownKey,
|
||||
icon: Icon(Icons.notifications),
|
||||
notificationsBadge: _unreadNotifications.notifications,
|
||||
notificationsBadge: _unreadNotifications.notifications!,
|
||||
onBuildOverlay: (c) => Padding(
|
||||
padding: const EdgeInsets.all(8.0),
|
||||
child: NotificationsScreen(useSmallDeleteButton: true),
|
||||
@ -77,7 +77,7 @@ class _ComunicTabletAppBarWidgetState
|
||||
AppBarCustomDropDownWidget(
|
||||
key: conversationsDropdownKey,
|
||||
icon: Icon(Icons.message),
|
||||
notificationsBadge: _unreadNotifications.conversations,
|
||||
notificationsBadge: _unreadNotifications.conversations!,
|
||||
onBuildOverlay: (c) => Padding(
|
||||
padding: const EdgeInsets.all(8.0),
|
||||
child: UnreadConversationsScreen(),
|
||||
@ -88,29 +88,29 @@ class _ComunicTabletAppBarWidgetState
|
||||
itemBuilder: (c) => [
|
||||
// Get groups
|
||||
_MainMenuItem(
|
||||
label: tr("Groups"),
|
||||
label: tr("Groups")!,
|
||||
icon: Icons.group,
|
||||
onTap: () => MainController.of(context).openGroupsListPage()),
|
||||
onTap: () => MainController.of(context)!.openGroupsListPage()),
|
||||
|
||||
// Toggle dark theme
|
||||
_MainMenuItem(
|
||||
label: tr("Night mode"),
|
||||
icon: preferences().preferences.enableDarkMode
|
||||
label: tr("Night mode")!,
|
||||
icon: preferences()!.preferences.enableDarkMode
|
||||
? Icons.brightness_2
|
||||
: Icons.wb_sunny,
|
||||
onTap: _toggleDarkMode),
|
||||
|
||||
// Open settings
|
||||
_MainMenuItem(
|
||||
label: tr("Settings"),
|
||||
label: tr("Settings")!,
|
||||
icon: Icons.settings,
|
||||
onTap: () => MainController.of(context).openSettings()),
|
||||
onTap: () => MainController.of(context)!.openSettings()),
|
||||
|
||||
// Sign out
|
||||
_MainMenuItem(
|
||||
label: tr("Sign out"),
|
||||
label: tr("Sign out")!,
|
||||
icon: Icons.power_settings_new,
|
||||
onTap: () => MainController.of(context).requestLogout()),
|
||||
onTap: () => MainController.of(context)!.requestLogout()),
|
||||
],
|
||||
onSelected: (v) => v(),
|
||||
),
|
||||
@ -120,9 +120,9 @@ class _ComunicTabletAppBarWidgetState
|
||||
|
||||
/// Toggle dark mode
|
||||
void _toggleDarkMode() async {
|
||||
final prefs = preferences().preferences;
|
||||
final prefs = preferences()!.preferences;
|
||||
prefs.enableDarkMode = !prefs.enableDarkMode;
|
||||
await preferences().setPreferences(prefs);
|
||||
await preferences()!.setPreferences(prefs);
|
||||
|
||||
applyNewThemeSettings(context);
|
||||
}
|
||||
@ -136,9 +136,9 @@ class _MainMenuItem extends PopupMenuEntry<_MenuItemCallback> {
|
||||
final _MenuItemCallback onTap;
|
||||
|
||||
const _MainMenuItem({
|
||||
@required this.label,
|
||||
@required this.icon,
|
||||
@required this.onTap,
|
||||
required this.label,
|
||||
required this.icon,
|
||||
required this.onTap,
|
||||
}) : assert(label != null),
|
||||
assert(icon != null),
|
||||
assert(onTap != null);
|
||||
@ -150,7 +150,7 @@ class _MainMenuItem extends PopupMenuEntry<_MenuItemCallback> {
|
||||
double get height => kMinInteractiveDimension;
|
||||
|
||||
@override
|
||||
bool represents(_MenuItemCallback value) => onTap == value;
|
||||
bool represents(_MenuItemCallback? value) => onTap == value;
|
||||
}
|
||||
|
||||
class __MainMenuItemState extends State<_MainMenuItem> {
|
||||
|
@ -23,14 +23,14 @@ import 'package:flutter/material.dart';
|
||||
|
||||
class UserPageTablet extends StatefulWidget {
|
||||
final AdvancedUserInfo userInfo;
|
||||
final FriendStatus friendshipStatus;
|
||||
final FriendStatus? friendshipStatus;
|
||||
final void Function() onNeedRefresh;
|
||||
|
||||
const UserPageTablet({
|
||||
Key key,
|
||||
@required this.userInfo,
|
||||
@required this.friendshipStatus,
|
||||
@required this.onNeedRefresh,
|
||||
Key? key,
|
||||
required this.userInfo,
|
||||
required this.friendshipStatus,
|
||||
required this.onNeedRefresh,
|
||||
}) : assert(userInfo != null),
|
||||
assert(onNeedRefresh != null),
|
||||
super(key: key);
|
||||
@ -106,7 +106,7 @@ class _UserPageTabletState extends State<UserPageTablet> {
|
||||
_isCurrentUser
|
||||
? Container()
|
||||
: FriendshipStatusWidget(
|
||||
status: widget.friendshipStatus,
|
||||
status: widget.friendshipStatus!,
|
||||
onFriendshipUpdated: widget.onNeedRefresh,
|
||||
)
|
||||
],
|
||||
@ -124,7 +124,7 @@ class _UserPageTabletState extends State<UserPageTablet> {
|
||||
_userInfo.isFriendsListPublic
|
||||
? Expanded(
|
||||
child: OutlinedButton.icon(
|
||||
onPressed: () => MainController.of(context)
|
||||
onPressed: () => MainController.of(context)!
|
||||
.openUserFriendsList(_userInfo.id),
|
||||
icon: Icon(Icons.group),
|
||||
label: Text("${_userInfo.numberFriends}"),
|
||||
@ -153,7 +153,7 @@ class _UserPageTabletState extends State<UserPageTablet> {
|
||||
// User membership
|
||||
_AboutUserEntry(
|
||||
icon: Icons.access_time,
|
||||
title: tr("Membership"),
|
||||
title: tr("Membership")!,
|
||||
value: tr("Member for %t%", args: {
|
||||
"t": diffTimeFromNowToStr(_userInfo.accountCreationTime)
|
||||
})),
|
||||
@ -161,7 +161,7 @@ class _UserPageTabletState extends State<UserPageTablet> {
|
||||
// User public note
|
||||
_AboutUserEntry(
|
||||
icon: Icons.note,
|
||||
title: tr("Note"),
|
||||
title: tr("Note")!,
|
||||
value: _userInfo.publicNote,
|
||||
visible: _userInfo.hasPublicNote,
|
||||
parsed: true,
|
||||
@ -170,7 +170,7 @@ class _UserPageTabletState extends State<UserPageTablet> {
|
||||
// User email address
|
||||
_AboutUserEntry(
|
||||
icon: Icons.mail_outline,
|
||||
title: tr("Email address"),
|
||||
title: tr("Email address")!,
|
||||
value: _userInfo.emailAddress,
|
||||
visible: _userInfo.emailAddress != null,
|
||||
),
|
||||
@ -178,7 +178,7 @@ class _UserPageTabletState extends State<UserPageTablet> {
|
||||
// Location
|
||||
_AboutUserEntry(
|
||||
icon: Icons.location_on,
|
||||
title: tr("Location"),
|
||||
title: tr("Location")!,
|
||||
value: _userInfo.location,
|
||||
visible: _userInfo.location != null,
|
||||
),
|
||||
@ -186,7 +186,7 @@ class _UserPageTabletState extends State<UserPageTablet> {
|
||||
// User website
|
||||
_AboutUserEntry(
|
||||
icon: Icons.link,
|
||||
title: tr("Website"),
|
||||
title: tr("Website")!,
|
||||
value: _userInfo.personalWebsite,
|
||||
visible: _userInfo.hasPersonalWebsite,
|
||||
parsed: true,
|
||||
@ -197,9 +197,9 @@ class _UserPageTabletState extends State<UserPageTablet> {
|
||||
}
|
||||
|
||||
class _LeftPaneContainer extends StatelessWidget {
|
||||
final Widget child;
|
||||
final Widget? child;
|
||||
|
||||
const _LeftPaneContainer({Key key, this.child}) : super(key: key);
|
||||
const _LeftPaneContainer({Key? key, this.child}) : super(key: key);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
@ -218,7 +218,7 @@ class _LeftPaneContainer extends StatelessWidget {
|
||||
class _MainCardSpacer extends StatelessWidget {
|
||||
final bool visible;
|
||||
|
||||
const _MainCardSpacer({this.visible = true, Key key})
|
||||
const _MainCardSpacer({this.visible = true, Key? key})
|
||||
: assert(visible != null),
|
||||
super(key: key);
|
||||
|
||||
@ -230,15 +230,15 @@ class _MainCardSpacer extends StatelessWidget {
|
||||
class _AboutUserEntry extends StatelessWidget {
|
||||
final IconData icon;
|
||||
final String title;
|
||||
final String value;
|
||||
final String? value;
|
||||
final bool visible;
|
||||
final bool parsed;
|
||||
|
||||
const _AboutUserEntry({
|
||||
Key key,
|
||||
@required this.icon,
|
||||
@required this.title,
|
||||
@required this.value,
|
||||
Key? key,
|
||||
required this.icon,
|
||||
required this.title,
|
||||
required this.value,
|
||||
this.visible = true,
|
||||
this.parsed = false,
|
||||
}) : assert(icon != null),
|
||||
@ -268,7 +268,7 @@ class _AboutUserEntry extends StatelessWidget {
|
||||
content: DisplayedString(value),
|
||||
style: TextStyle(),
|
||||
)
|
||||
: Text(value),
|
||||
: Text(value!),
|
||||
dense: true,
|
||||
);
|
||||
}
|
||||
|
Reference in New Issue
Block a user