feat: Switch to VRouter

This commit is contained in:
Christian Pauly 2021-05-23 13:11:55 +02:00
commit c2fce64494
57 changed files with 678 additions and 617 deletions

View file

@ -28,7 +28,7 @@ class ArchiveController extends State<Archive> {
okLabel: L10n.of(context).yes,
cancelLabel: L10n.of(context).cancel,
message: L10n.of(context).clearArchive,
useRootNavigator: false,
) !=
OkCancelResult.ok) {
return;

View file

@ -25,13 +25,11 @@ class BootstrapDialog extends StatefulWidget {
? showCupertinoDialog(
context: context,
builder: (context) => this,
useRootNavigator: false,
barrierDismissible: true,
)
: showDialog(
context: context,
builder: (context) => this,
useRootNavigator: false,
barrierDismissible: true,
);
@ -196,7 +194,6 @@ class _BootstrapDialogState extends State<BootstrapDialog> {
if (OkCancelResult.ok ==
await showOkCancelAlertDialog(
context: context,
useRootNavigator: false,
title: L10n.of(context).securityKeyLost,
message: L10n.of(context).wipeChatBackup,
okLabel: L10n.of(context).ok,

View file

@ -2,7 +2,7 @@ import 'dart:async';
import 'dart:io';
import 'package:adaptive_dialog/adaptive_dialog.dart';
import 'package:adaptive_page_layout/adaptive_page_layout.dart';
import 'package:famedlysdk/famedlysdk.dart';
import 'package:file_picker_cross/file_picker_cross.dart';
import 'package:fluffychat/config/app_config.dart';
@ -23,17 +23,16 @@ import 'package:image_picker/image_picker.dart';
import 'package:permission_handler/permission_handler.dart';
import 'package:scroll_to_index/scroll_to_index.dart';
import 'package:url_launcher/url_launcher.dart';
import 'package:vrouter/vrouter.dart';
import 'send_file_dialog.dart';
import '../utils/matrix_sdk_extensions.dart/filtered_timeline_extension.dart';
import '../utils/matrix_sdk_extensions.dart/matrix_file_extension.dart';
class Chat extends StatefulWidget {
final String id;
final String scrollToEventId;
final Widget sideView;
Chat(this.id, {Key key, this.scrollToEventId})
: super(key: key ?? Key('chatroom-$id'));
Chat({Key key, this.sideView}) : super(key: key);
@override
ChatController createState() => ChatController();
@ -46,6 +45,8 @@ class ChatController extends State<Chat> {
MatrixState matrix;
String get roomId => context.vRouter.pathParameters['roomid'];
final AutoScrollController scrollController = AutoScrollController();
FocusNode inputFocus = FocusNode();
@ -97,7 +98,7 @@ class ChatController extends State<Chat> {
try {
await timeline.requestHistory(historyCount: _loadHistoryCount);
} catch (err) {
AdaptivePageLayout.of(context).showSnackBar(
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(content: Text(err.toLocalizedString(context))));
}
}
@ -167,8 +168,9 @@ class ChatController extends State<Chat> {
// "load more" button is visible on the screen
SchedulerBinding.instance.addPostFrameCallback((_) async {
if (mounted) {
if (widget.scrollToEventId != null) {
scrollToEventId(widget.scrollToEventId);
final event = VRouter.of(context).queryParameters['event'];
if (event != null) {
scrollToEventId(event);
}
_updateScrollController();
}
@ -231,7 +233,6 @@ class ChatController extends State<Chat> {
if (result == null) return;
await showDialog(
context: context,
useRootNavigator: false,
builder: (c) => SendFileDialog(
file: MatrixFile(
bytes: result.toUint8List(),
@ -248,7 +249,6 @@ class ChatController extends State<Chat> {
if (result == null) return;
await showDialog(
context: context,
useRootNavigator: false,
builder: (c) => SendFileDialog(
file: MatrixImageFile(
bytes: result.toUint8List(),
@ -265,7 +265,6 @@ class ChatController extends State<Chat> {
final bytes = await file.readAsBytes();
await showDialog(
context: context,
useRootNavigator: false,
builder: (c) => SendFileDialog(
file: MatrixImageFile(
bytes: bytes,
@ -284,7 +283,6 @@ class ChatController extends State<Chat> {
final result = await showDialog<String>(
context: context,
builder: (c) => RecordingDialog(),
useRootNavigator: false,
);
if (result == null) return;
final audioFile = File(result);
@ -325,7 +323,6 @@ class ChatController extends State<Chat> {
final score = await showConfirmationDialog<int>(
context: context,
title: L10n.of(context).howOffensiveIsThisContent,
useRootNavigator: false,
actions: [
AlertDialogAction(
key: -100,
@ -346,7 +343,6 @@ class ChatController extends State<Chat> {
title: L10n.of(context).whyDoYouWantToReportThis,
okLabel: L10n.of(context).ok,
cancelLabel: L10n.of(context).cancel,
useRootNavigator: false,
textFields: [DialogTextField(hintText: L10n.of(context).reason)]);
if (reason == null || reason.single.isEmpty) return;
final result = await showFutureLoadingDialog(
@ -360,7 +356,7 @@ class ChatController extends State<Chat> {
);
if (result.error != null) return;
setState(() => selectedEvents.clear());
AdaptivePageLayout.of(context).showSnackBar(
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(content: Text(L10n.of(context).contentHasBeenReported)));
}
@ -370,7 +366,6 @@ class ChatController extends State<Chat> {
title: L10n.of(context).messageWillBeRemovedWarning,
okLabel: L10n.of(context).remove,
cancelLabel: L10n.of(context).cancel,
useRootNavigator: false,
) ==
OkCancelResult.ok;
if (!confirmed) return;
@ -400,7 +395,7 @@ class ChatController extends State<Chat> {
};
}
setState(() => selectedEvents.clear());
AdaptivePageLayout.of(context).popUntilIsFirst();
VRouter.of(context).push('/rooms');
}
void sendAgainAction() {
@ -566,8 +561,7 @@ class ChatController extends State<Chat> {
future: room.leave,
);
if (result.error == null) {
await AdaptivePageLayout.of(context)
.pushNamedAndRemoveUntilIsFirst('/rooms/${result.result}');
VRouter.of(context).push('/rooms/${result.result}');
}
}
@ -653,5 +647,29 @@ class ChatController extends State<Chat> {
});
@override
Widget build(BuildContext context) => ChatView(this);
Widget build(BuildContext context) {
var currentUrl = Uri.decodeFull(VRouter.of(context).url);
if (!currentUrl.endsWith('/')) currentUrl += '/';
final hideSideView = currentUrl == '/rooms/$roomId/';
return widget.sideView == null
? ChatView(this)
: Row(
children: [
Expanded(
child: ClipRRect(child: ChatView(this)),
),
Container(
width: 1.0,
color: Theme.of(context).dividerColor,
),
AnimatedContainer(
duration: Duration(milliseconds: 300),
clipBehavior: Clip.antiAlias,
decoration: BoxDecoration(),
width: hideSideView ? 0 : 360.0,
child: hideSideView ? null : widget.sideView,
),
],
);
}
}

View file

@ -1,5 +1,4 @@
import 'package:adaptive_dialog/adaptive_dialog.dart';
import 'package:adaptive_page_layout/adaptive_page_layout.dart';
import 'package:famedlysdk/famedlysdk.dart';
@ -13,13 +12,12 @@ import 'package:fluffychat/utils/platform_infos.dart';
import 'package:flutter/material.dart';
import 'package:flutter_gen/gen_l10n/l10n.dart';
import 'package:image_picker/image_picker.dart';
import 'package:vrouter/vrouter.dart';
enum AliasActions { copy, delete, setCanonical }
class ChatDetails extends StatefulWidget {
final String roomId;
const ChatDetails(this.roomId);
const ChatDetails();
@override
ChatDetailsController createState() => ChatDetailsController();
@ -28,21 +26,16 @@ class ChatDetails extends StatefulWidget {
class ChatDetailsController extends State<ChatDetails> {
List<User> members;
@override
void initState() {
super.initState();
members ??=
Matrix.of(context).client.getRoomById(widget.roomId).getParticipants();
}
String get roomId => VRouter.of(context).pathParameters['roomid'];
void setDisplaynameAction() async {
final room = Matrix.of(context).client.getRoomById(widget.roomId);
final room = Matrix.of(context).client.getRoomById(roomId);
final input = await showTextInputDialog(
context: context,
title: L10n.of(context).changeTheNameOfTheGroup,
okLabel: L10n.of(context).ok,
cancelLabel: L10n.of(context).cancel,
useRootNavigator: false,
textFields: [
DialogTextField(
initialText: room.getLocalizedDisplayname(
@ -59,13 +52,13 @@ class ChatDetailsController extends State<ChatDetails> {
future: () => room.setName(input.single),
);
if (success.error == null) {
AdaptivePageLayout.of(context).showSnackBar(
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(content: Text(L10n.of(context).displaynameHasBeenChanged)));
}
}
void editAliases() async {
final room = Matrix.of(context).client.getRoomById(widget.roomId);
final room = Matrix.of(context).client.getRoomById(roomId);
// The current endpoint doesnt seem to be implemented in Synapse. This may
// change in the future and then we just need to switch to this api call:
@ -136,7 +129,7 @@ class ChatDetailsController extends State<ChatDetails> {
switch (option) {
case AliasActions.copy:
await Clipboard.setData(ClipboardData(text: select));
AdaptivePageLayout.of(context).showSnackBar(
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(content: Text(L10n.of(context).copiedToClipboard)),
);
break;
@ -159,7 +152,7 @@ class ChatDetailsController extends State<ChatDetails> {
}
void setAliasAction() async {
final room = Matrix.of(context).client.getRoomById(widget.roomId);
final room = Matrix.of(context).client.getRoomById(roomId);
final domain = room.client.userID.domain;
final input = await showTextInputDialog(
@ -167,7 +160,7 @@ class ChatDetailsController extends State<ChatDetails> {
title: L10n.of(context).setInvitationLink,
okLabel: L10n.of(context).ok,
cancelLabel: L10n.of(context).cancel,
useRootNavigator: false,
textFields: [
DialogTextField(
prefixText: '#',
@ -186,13 +179,13 @@ class ChatDetailsController extends State<ChatDetails> {
}
void setTopicAction() async {
final room = Matrix.of(context).client.getRoomById(widget.roomId);
final room = Matrix.of(context).client.getRoomById(roomId);
final input = await showTextInputDialog(
context: context,
title: L10n.of(context).setGroupDescription,
okLabel: L10n.of(context).ok,
cancelLabel: L10n.of(context).cancel,
useRootNavigator: false,
textFields: [
DialogTextField(
hintText: L10n.of(context).setGroupDescription,
@ -208,7 +201,7 @@ class ChatDetailsController extends State<ChatDetails> {
future: () => room.setDescription(input.single),
);
if (success.error == null) {
AdaptivePageLayout.of(context).showSnackBar(SnackBar(
ScaffoldMessenger.of(context).showSnackBar(SnackBar(
content: Text(L10n.of(context).groupDescriptionHasBeenChanged)));
}
}
@ -217,7 +210,7 @@ class ChatDetailsController extends State<ChatDetails> {
context: context,
future: () => Matrix.of(context)
.client
.getRoomById(widget.roomId)
.getRoomById(roomId)
.setGuestAccess(guestAccess),
);
@ -226,7 +219,7 @@ class ChatDetailsController extends State<ChatDetails> {
context: context,
future: () => Matrix.of(context)
.client
.getRoomById(widget.roomId)
.getRoomById(roomId)
.setHistoryVisibility(historyVisibility),
);
@ -234,23 +227,21 @@ class ChatDetailsController extends State<ChatDetails> {
context: context,
future: () => Matrix.of(context)
.client
.getRoomById(widget.roomId)
.getRoomById(roomId)
.setJoinRules(joinRule),
);
void goToEmoteSettings() async {
final room = Matrix.of(context).client.getRoomById(widget.roomId);
final room = Matrix.of(context).client.getRoomById(roomId);
// okay, we need to test if there are any emote state events other than the default one
// if so, we need to be directed to a selection screen for which pack we want to look at
// otherwise, we just open the normal one.
if ((room.states['im.ponies.room_emotes'] ?? <String, Event>{})
.keys
.any((String s) => s.isNotEmpty)) {
await AdaptivePageLayout.of(context)
.pushNamed('/rooms/${room.id}/emotes');
VRouter.of(context).pushNamed('/rooms/${room.id}/emotes');
} else {
await AdaptivePageLayout.of(context)
.pushNamed('/settings/emotes', arguments: {'room': room});
VRouter.of(context).pushNamed('/settings/emotes');
}
}
@ -277,20 +268,20 @@ class ChatDetailsController extends State<ChatDetails> {
name: result.fileName,
);
}
final room = Matrix.of(context).client.getRoomById(widget.roomId);
final room = Matrix.of(context).client.getRoomById(roomId);
final success = await showFutureLoadingDialog(
context: context,
future: () => room.setAvatar(file),
);
if (success.error == null) {
AdaptivePageLayout.of(context).showSnackBar(
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(content: Text(L10n.of(context).avatarHasBeenChanged)));
}
}
void requestMoreMembersAction() async {
final room = Matrix.of(context).client.getRoomById(widget.roomId);
final room = Matrix.of(context).client.getRoomById(roomId);
final participants = await showFutureLoadingDialog(
context: context, future: () => room.requestParticipants());
if (participants.error == null) {
@ -299,5 +290,11 @@ class ChatDetailsController extends State<ChatDetails> {
}
@override
Widget build(BuildContext context) => ChatDetailsView(this);
Widget build(BuildContext context) {
members ??= Matrix.of(context).client.getRoomById(roomId).getParticipants();
return Container(
width: 360.0,
child: ChatDetailsView(this),
);
}
}

View file

@ -3,12 +3,11 @@ import 'package:famedlysdk/famedlysdk.dart';
import 'package:fluffychat/pages/views/chat_encryption_settings_view.dart';
import 'package:fluffychat/widgets/matrix.dart';
import 'package:flutter/material.dart';
import 'package:vrouter/vrouter.dart';
import 'key_verification_dialog.dart';
class ChatEncryptionSettings extends StatefulWidget {
final String id;
const ChatEncryptionSettings(this.id, {Key key}) : super(key: key);
const ChatEncryptionSettings({Key key}) : super(key: key);
@override
ChatEncryptionSettingsController createState() =>
@ -16,9 +15,10 @@ class ChatEncryptionSettings extends StatefulWidget {
}
class ChatEncryptionSettingsController extends State<ChatEncryptionSettings> {
String get roomId => VRouter.of(context).pathParameters['roomid'];
Future<void> onSelected(
BuildContext context, String action, DeviceKeys key) async {
final room = Matrix.of(context).client.getRoomById(widget.id);
final room = Matrix.of(context).client.getRoomById(roomId);
final unblock = () async {
if (key.blocked) {
await key.setBlocked(false);

View file

@ -2,7 +2,7 @@ import 'dart:async';
import 'dart:io';
import 'package:adaptive_dialog/adaptive_dialog.dart';
import 'package:adaptive_page_layout/adaptive_page_layout.dart';
import 'package:famedlysdk/famedlysdk.dart';
import 'package:fluffychat/utils/fluffy_share.dart';
import 'package:fluffychat/pages/views/chat_list_view.dart';
@ -14,6 +14,7 @@ import 'package:flutter/material.dart';
import 'package:future_loading_dialog/future_loading_dialog.dart';
import 'package:receive_sharing_intent/receive_sharing_intent.dart';
import 'package:uni_links/uni_links.dart';
import 'package:vrouter/vrouter.dart';
import '../main.dart';
import '../widgets/matrix.dart';
import '../utils/matrix_sdk_extensions.dart/matrix_file_extension.dart';
@ -43,7 +44,7 @@ class ChatListController extends State<ChatList> {
void _processIncomingSharedFiles(List<SharedMediaFile> files) {
if (files?.isEmpty ?? true) return;
AdaptivePageLayout.of(context).popUntilIsFirst();
VRouter.of(context).push('/rooms');
final file = File(files.first.path);
Matrix.of(context).shareContent = {
@ -57,7 +58,7 @@ class ChatListController extends State<ChatList> {
void _processIncomingSharedText(String text) {
if (text == null) return;
AdaptivePageLayout.of(context).popUntilIsFirst();
VRouter.of(context).push('/rooms');
if (text.toLowerCase().startsWith(AppConfig.inviteLinkPrefix) ||
(text.toLowerCase().startsWith(AppConfig.schemePrefix) &&
!RegExp(r'\s').hasMatch(text))) {
@ -74,7 +75,7 @@ class ChatListController extends State<ChatList> {
if (text.toLowerCase().startsWith(AppConfig.inviteLinkPrefix) ||
(text.toLowerCase().startsWith(AppConfig.schemePrefix) &&
!RegExp(r'\s').hasMatch(text))) {
AdaptivePageLayout.of(context).popUntilIsFirst();
VRouter.of(context).push('/rooms');
UrlLauncher(context, text).openMatrixToUrl();
return;
}
@ -158,7 +159,6 @@ class ChatListController extends State<ChatList> {
title: L10n.of(context).areYouSure,
okLabel: L10n.of(context).yes,
cancelLabel: L10n.of(context).cancel,
useRootNavigator: false,
) ==
OkCancelResult.ok;
if (!confirmed) return;
@ -175,7 +175,6 @@ class ChatListController extends State<ChatList> {
title: L10n.of(context).setStatus,
okLabel: L10n.of(context).ok,
cancelLabel: L10n.of(context).cancel,
useRootNavigator: false,
textFields: [
DialogTextField(
hintText: L10n.of(context).statusExampleMessage,
@ -198,7 +197,7 @@ class ChatListController extends State<ChatList> {
setStatus();
break;
case PopupMenuAction.settings:
AdaptivePageLayout.of(context).pushNamed('/settings');
VRouter.of(context).push('/settings');
break;
case PopupMenuAction.invite:
FluffyShare.share(
@ -207,10 +206,10 @@ class ChatListController extends State<ChatList> {
context);
break;
case PopupMenuAction.newGroup:
AdaptivePageLayout.of(context).pushNamed('/newgroup');
VRouter.of(context).push('/newgroup');
break;
case PopupMenuAction.archive:
AdaptivePageLayout.of(context).pushNamed('/archive');
VRouter.of(context).push('/archive');
break;
}
}

View file

@ -1,7 +1,7 @@
import 'dart:developer';
import 'package:adaptive_dialog/adaptive_dialog.dart';
import 'package:adaptive_page_layout/adaptive_page_layout.dart';
import 'package:fluffychat/pages/views/chat_permissions_settings_view.dart';
import 'package:fluffychat/pages/permission_slider_dialog.dart';
import 'package:future_loading_dialog/future_loading_dialog.dart';
@ -10,11 +10,10 @@ import 'package:fluffychat/widgets/matrix.dart';
import 'package:flutter/material.dart';
import 'package:flutter_gen/gen_l10n/l10n.dart';
import 'package:famedlysdk/famedlysdk.dart';
import 'package:vrouter/vrouter.dart';
class ChatPermissionsSettings extends StatefulWidget {
final String roomId;
const ChatPermissionsSettings(this.roomId, {Key key}) : super(key: key);
const ChatPermissionsSettings({Key key}) : super(key: key);
@override
ChatPermissionsSettingsController createState() =>
@ -22,11 +21,12 @@ class ChatPermissionsSettings extends StatefulWidget {
}
class ChatPermissionsSettingsController extends State<ChatPermissionsSettings> {
String get roomId => VRouter.of(context).pathParameters['roomid'];
void editPowerLevel(BuildContext context, String key, int currentLevel,
{String category}) async {
final room = Matrix.of(context).client.getRoomById(widget.roomId);
final room = Matrix.of(context).client.getRoomById(roomId);
if (!room.canSendEvent(EventTypes.RoomPowerLevels)) {
AdaptivePageLayout.of(context)
ScaffoldMessenger.of(context)
.showSnackBar(SnackBar(content: Text(L10n.of(context).noPermission)));
return;
}
@ -54,14 +54,14 @@ class ChatPermissionsSettingsController extends State<ChatPermissionsSettings> {
Stream get onChanged => Matrix.of(context).client.onSync.stream.where(
(e) =>
(e?.rooms?.join?.containsKey(widget.roomId) ?? false) &&
(e.rooms.join[widget.roomId]?.timeline?.events
(e?.rooms?.join?.containsKey(roomId) ?? false) &&
(e.rooms.join[roomId]?.timeline?.events
?.any((s) => s.type == EventTypes.RoomPowerLevels) ??
false),
);
void updateRoomAction(ServerCapabilities capabilities) async {
final room = Matrix.of(context).client.getRoomById(widget.roomId);
final room = Matrix.of(context).client.getRoomById(roomId);
final String roomVersion =
room.getState(EventTypes.RoomCreate).content['room_version'] ?? '1';
final newVersion = await showConfirmationDialog<String>(
@ -87,8 +87,8 @@ class ChatPermissionsSettingsController extends State<ChatPermissionsSettings> {
}
await showFutureLoadingDialog(
context: context,
future: () => room.client.upgradeRoom(widget.roomId, newVersion),
).then((_) => AdaptivePageLayout.of(context).pop());
future: () => room.client.upgradeRoom(roomId, newVersion),
).then((_) => VRouter.of(context).pop());
}
@override

View file

@ -33,7 +33,6 @@ class DevicesSettingsController extends State<DevicesSettings> {
title: L10n.of(context).areYouSure,
okLabel: L10n.of(context).yes,
cancelLabel: L10n.of(context).cancel,
useRootNavigator: false,
) ==
OkCancelResult.cancel) return;
final matrix = Matrix.of(context);
@ -68,7 +67,6 @@ class DevicesSettingsController extends State<DevicesSettings> {
title: L10n.of(context).changeDeviceName,
okLabel: L10n.of(context).ok,
cancelLabel: L10n.of(context).cancel,
useRootNavigator: false,
textFields: [
DialogTextField(
hintText: device.displayName,

View file

@ -1,4 +1,3 @@
import 'package:adaptive_page_layout/adaptive_page_layout.dart';
import 'package:famedlysdk/famedlysdk.dart';
import 'package:fluffychat/pages/views/homeserver_picker_view.dart';
import 'package:fluffychat/widgets/matrix.dart';
@ -7,6 +6,7 @@ import 'package:fluffychat/config/setting_keys.dart';
import 'package:flutter_gen/gen_l10n/l10n.dart';
import 'package:flutter/material.dart';
import '../utils/localized_exception_extension.dart';
import 'package:vrouter/vrouter.dart';
class HomeserverPicker extends StatefulWidget {
@override
@ -51,10 +51,11 @@ class HomeserverPickerController extends State<HomeserverPicker> {
AppConfig.jitsiInstance = jitsi;
}
await AdaptivePageLayout.of(context)
.pushNamed(AppConfig.enableRegistration ? '/signup' : '/login');
VRouter.of(context).push(
AppConfig.enableRegistration ? '/signup' : '/login',
historyState: {'/home': '/signup'});
} catch (e) {
AdaptivePageLayout.of(context).showSnackBar(
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(content: Text((e as Object).toLocalizedString(context))));
} finally {
if (mounted) {

View file

@ -1,9 +1,9 @@
import 'package:adaptive_page_layout/adaptive_page_layout.dart';
import 'package:famedlysdk/famedlysdk.dart';
import 'package:fluffychat/utils/platform_infos.dart';
import 'package:fluffychat/pages/views/image_viewer_view.dart';
import 'package:fluffychat/widgets/matrix.dart';
import 'package:flutter/material.dart';
import 'package:vrouter/vrouter.dart';
import '../utils/matrix_sdk_extensions.dart/event_extension.dart';
@ -21,7 +21,7 @@ class ImageViewerController extends State<ImageViewer> {
/// Forward this image to another room.
void forwardAction() {
Matrix.of(context).shareContent = widget.event.content;
AdaptivePageLayout.of(context).popUntilIsFirst();
VRouter.of(context).push('/rooms');
}
/// Open this file with a system call.

View file

@ -1,19 +1,17 @@
import 'dart:async';
import 'package:adaptive_page_layout/adaptive_page_layout.dart';
import 'package:famedlysdk/famedlysdk.dart';
import 'package:fluffychat/pages/views/invitation_selection_view.dart';
import 'package:future_loading_dialog/future_loading_dialog.dart';
import 'package:fluffychat/widgets/matrix.dart';
import 'package:flutter/material.dart';
import 'package:flutter_gen/gen_l10n/l10n.dart';
import 'package:vrouter/vrouter.dart';
import '../utils/localized_exception_extension.dart';
class InvitationSelection extends StatefulWidget {
final String roomId;
const InvitationSelection(this.roomId, {Key key}) : super(key: key);
const InvitationSelection({Key key}) : super(key: key);
@override
InvitationSelectionController createState() =>
@ -27,9 +25,11 @@ class InvitationSelectionController extends State<InvitationSelection> {
List<Profile> foundProfiles = [];
Timer coolDown;
String get roomId => VRouter.of(context).pathParameters['roomid'];
Future<List<User>> getContacts(BuildContext context) async {
final client = Matrix.of(context).client;
final room = client.getRoomById(widget.roomId);
final room = client.getRoomById(roomId);
final participants = await room.requestParticipants();
participants.removeWhere(
(u) => ![Membership.join, Membership.invite].contains(u.membership),
@ -56,13 +56,13 @@ class InvitationSelectionController extends State<InvitationSelection> {
}
void inviteAction(BuildContext context, String id) async {
final room = Matrix.of(context).client.getRoomById(widget.roomId);
final room = Matrix.of(context).client.getRoomById(roomId);
final success = await showFutureLoadingDialog(
context: context,
future: () => room.invite(id),
);
if (success.error == null) {
AdaptivePageLayout.of(context).showSnackBar(SnackBar(
ScaffoldMessenger.of(context).showSnackBar(SnackBar(
content: Text(L10n.of(context).contactHasBeenInvitedToTheGroup)));
}
}
@ -89,7 +89,7 @@ class InvitationSelectionController extends State<InvitationSelection> {
try {
response = await matrix.client.searchUserDirectory(text, limit: 10);
} catch (e) {
AdaptivePageLayout.of(context).showSnackBar(
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(content: Text((e as Object).toLocalizedString(context))));
return;
} finally {
@ -105,7 +105,7 @@ class InvitationSelectionController extends State<InvitationSelection> {
}
final participants = Matrix.of(context)
.client
.getRoomById(widget.roomId)
.getRoomById(roomId)
.getParticipants()
.where((user) =>
[Membership.join, Membership.invite].contains(user.membership))

View file

@ -16,13 +16,11 @@ class KeyVerificationDialog extends StatefulWidget {
context: context,
barrierDismissible: true,
builder: (context) => this,
useRootNavigator: false,
)
: showDialog(
context: context,
barrierDismissible: true,
builder: (context) => this,
useRootNavigator: false,
);
final KeyVerification request;
@ -100,7 +98,6 @@ class _KeyVerificationPageState extends State<KeyVerificationDialog> {
await showOkAlertDialog(
context: context,
message: L10n.of(context).incorrectPassphraseOrKey,
useRootNavigator: false,
);
}
};
@ -187,7 +184,6 @@ class _KeyVerificationPageState extends State<KeyVerificationDialog> {
onPressed: () async {
final result = await showOkCancelAlertDialog(
context: context,
useRootNavigator: false,
title: L10n.of(context).verifyManual,
message: key.ed25519Key.beautified,
);

View file

@ -1,7 +1,7 @@
import 'dart:async';
import 'package:adaptive_dialog/adaptive_dialog.dart';
import 'package:adaptive_page_layout/adaptive_page_layout.dart';
import 'package:famedlysdk/famedlysdk.dart';
import 'package:future_loading_dialog/future_loading_dialog.dart';
import 'package:fluffychat/widgets/matrix.dart';
@ -119,7 +119,6 @@ class LoginController extends State<Login> {
title: L10n.of(context).enterAnEmailAddress,
okLabel: L10n.of(context).ok,
cancelLabel: L10n.of(context).cancel,
useRootNavigator: false,
textFields: [
DialogTextField(
hintText: L10n.of(context).enterAnEmailAddress,
@ -143,7 +142,6 @@ class LoginController extends State<Login> {
title: L10n.of(context).weSentYouAnEmail,
message: L10n.of(context).pleaseClickOnLink,
okLabel: L10n.of(context).iHaveClickedOnLink,
useRootNavigator: false,
);
if (ok == null) return;
final password = await showTextInputDialog(
@ -151,7 +149,6 @@ class LoginController extends State<Login> {
title: L10n.of(context).chooseAStrongPassword,
okLabel: L10n.of(context).ok,
cancelLabel: L10n.of(context).cancel,
useRootNavigator: false,
textFields: [
DialogTextField(
hintText: '******',
@ -178,7 +175,7 @@ class LoginController extends State<Login> {
),
);
if (success.error == null) {
AdaptivePageLayout.of(context).showSnackBar(
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(content: Text(L10n.of(context).passwordHasBeenChanged)));
}
}

View file

@ -1,9 +1,9 @@
import 'package:adaptive_page_layout/adaptive_page_layout.dart';
import 'package:famedlysdk/famedlysdk.dart' as sdk;
import 'package:fluffychat/pages/views/new_group_view.dart';
import 'package:future_loading_dialog/future_loading_dialog.dart';
import 'package:fluffychat/widgets/matrix.dart';
import 'package:flutter/material.dart';
import 'package:vrouter/vrouter.dart';
class NewGroup extends StatefulWidget {
@override
@ -31,11 +31,8 @@ class NewGroupController extends State<NewGroup> {
name: controller.text.isNotEmpty ? controller.text : null,
),
);
AdaptivePageLayout.of(context).popUntilIsFirst();
if (roomID != null) {
await AdaptivePageLayout.of(context).pushNamed('/rooms/${roomID.result}');
await AdaptivePageLayout.of(context)
.pushNamed('/rooms/${roomID.result}/invite');
if (roomID.error == null) {
VRouter.of(context).push('/rooms/${roomID.result}/invite');
}
}

View file

@ -1,6 +1,5 @@
import 'dart:async';
import 'package:adaptive_page_layout/adaptive_page_layout.dart';
import 'package:famedlysdk/famedlysdk.dart';
import 'package:fluffychat/utils/fluffy_share.dart';
import 'package:fluffychat/pages/views/new_private_chat_view.dart';
@ -8,6 +7,7 @@ import 'package:future_loading_dialog/future_loading_dialog.dart';
import 'package:fluffychat/widgets/matrix.dart';
import 'package:flutter/material.dart';
import 'package:flutter_gen/gen_l10n/l10n.dart';
import 'package:vrouter/vrouter.dart';
class NewPrivateChat extends StatefulWidget {
@override
@ -47,8 +47,7 @@ class NewPrivateChatController extends State<NewPrivateChat> {
);
if (roomID.error == null) {
await AdaptivePageLayout.of(context)
.popAndPushNamed('/rooms/${roomID.result}');
VRouter.of(context).push('/rooms/${roomID.result}');
}
}

View file

@ -14,12 +14,10 @@ class PermissionSliderDialog extends StatefulWidget {
? showCupertinoDialog<int>(
context: context,
builder: (context) => this,
useRootNavigator: false,
)
: showDialog<int>(
context: context,
builder: (context) => this,
useRootNavigator: false,
);
final int initialPermission;

View file

@ -1,18 +1,17 @@
import 'dart:async';
import 'package:adaptive_dialog/adaptive_dialog.dart';
import 'package:adaptive_page_layout/adaptive_page_layout.dart';
import 'package:famedlysdk/famedlysdk.dart';
import 'package:fluffychat/widgets/matrix.dart';
import 'package:flutter/material.dart';
import 'package:flutter_gen/gen_l10n/l10n.dart';
import 'package:future_loading_dialog/future_loading_dialog.dart';
import 'package:vrouter/vrouter.dart';
import 'views/search_view.dart';
class Search extends StatefulWidget {
final String alias;
const Search({Key key, this.alias}) : super(key: key);
const Search({Key key}) : super(key: key);
@override
SearchController createState() => SearchController();
@ -24,6 +23,7 @@ class SearchController extends State<Search> {
String lastServer;
Timer _coolDown;
String genericSearchTerm;
String alias;
void search(String query) async {
setState(() => null);
@ -64,7 +64,6 @@ class SearchController extends State<Search> {
title: '${room.name} (${room.numJoinedMembers ?? 0})',
message: room.topic ?? L10n.of(context).noDescription,
cancelLabel: L10n.of(context).cancel,
useRootNavigator: false,
) ==
OkCancelResult.cancel) {
return;
@ -78,8 +77,7 @@ class SearchController extends State<Search> {
),
);
if (success.error == null) {
await AdaptivePageLayout.of(context)
.pushNamedAndRemoveUntilIsFirst('/rooms/${success.result}');
VRouter.of(context).push('/rooms/${success.result}');
}
}
@ -91,7 +89,6 @@ class SearchController extends State<Search> {
context: context,
okLabel: L10n.of(context).ok,
cancelLabel: L10n.of(context).cancel,
useRootNavigator: false,
textFields: [
DialogTextField(
prefixText: 'https://',
@ -133,11 +130,9 @@ class SearchController extends State<Search> {
}
@override
void initState() {
genericSearchTerm = widget.alias;
super.initState();
Widget build(BuildContext context) {
alias = VRouter.of(context).queryParameters['query'];
genericSearchTerm = alias;
return SearchView(this);
}
@override
Widget build(BuildContext context) => SearchView(this);
}

View file

@ -1,7 +1,7 @@
import 'dart:async';
import 'package:adaptive_dialog/adaptive_dialog.dart';
import 'package:adaptive_page_layout/adaptive_page_layout.dart';
import 'package:famedlysdk/famedlysdk.dart';
import 'package:file_picker_cross/file_picker_cross.dart';
@ -13,6 +13,7 @@ import 'package:flutter_app_lock/flutter_app_lock.dart';
import 'package:flutter_gen/gen_l10n/l10n.dart';
import 'package:flutter_secure_storage/flutter_secure_storage.dart';
import 'package:image_picker/image_picker.dart';
import 'package:vrouter/vrouter.dart';
import 'views/settings_view.dart';
import 'package:future_loading_dialog/future_loading_dialog.dart';
@ -40,7 +41,6 @@ class SettingsController extends State<Settings> {
title: L10n.of(context).areYouSureYouWantToLogout,
okLabel: L10n.of(context).yes,
cancelLabel: L10n.of(context).cancel,
useRootNavigator: false,
) ==
OkCancelResult.cancel) {
return;
@ -58,7 +58,6 @@ class SettingsController extends State<Settings> {
title: L10n.of(context).changePassword,
okLabel: L10n.of(context).ok,
cancelLabel: L10n.of(context).cancel,
useRootNavigator: false,
textFields: [
DialogTextField(
hintText: L10n.of(context).pleaseEnterYourPassword,
@ -82,7 +81,7 @@ class SettingsController extends State<Settings> {
.changePassword(input.last, oldPassword: input.first),
);
if (success.error == null) {
AdaptivePageLayout.of(context).showSnackBar(
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(content: Text(L10n.of(context).passwordHasBeenChanged)));
}
}
@ -94,7 +93,6 @@ class SettingsController extends State<Settings> {
message: L10n.of(context).deactivateAccountWarning,
okLabel: L10n.of(context).ok,
cancelLabel: L10n.of(context).cancel,
useRootNavigator: false,
) ==
OkCancelResult.cancel) {
return;
@ -104,7 +102,6 @@ class SettingsController extends State<Settings> {
title: L10n.of(context).areYouSure,
okLabel: L10n.of(context).yes,
cancelLabel: L10n.of(context).cancel,
useRootNavigator: false,
) ==
OkCancelResult.cancel) {
return;
@ -114,7 +111,6 @@ class SettingsController extends State<Settings> {
title: L10n.of(context).pleaseEnterYourPassword,
okLabel: L10n.of(context).ok,
cancelLabel: L10n.of(context).cancel,
useRootNavigator: false,
textFields: [
DialogTextField(
obscureText: true,
@ -145,7 +141,6 @@ class SettingsController extends State<Settings> {
title: L10n.of(context).editJitsiInstance,
okLabel: L10n.of(context).ok,
cancelLabel: L10n.of(context).cancel,
useRootNavigator: false,
textFields: [
DialogTextField(
initialText: AppConfig.jitsiInstance.replaceFirst(prefix, ''),
@ -169,7 +164,6 @@ class SettingsController extends State<Settings> {
title: L10n.of(context).editDisplayname,
okLabel: L10n.of(context).ok,
cancelLabel: L10n.of(context).cancel,
useRootNavigator: false,
textFields: [
DialogTextField(
initialText: profile?.displayname ??
@ -234,7 +228,6 @@ class SettingsController extends State<Settings> {
title: L10n.of(context).askSSSSCache,
okLabel: L10n.of(context).ok,
cancelLabel: L10n.of(context).cancel,
useRootNavigator: false,
textFields: [
DialogTextField(
hintText: L10n.of(context).passphraseOrKey,
@ -266,7 +259,6 @@ class SettingsController extends State<Settings> {
context: context,
message: L10n.of(context).cachedKeys,
okLabel: L10n.of(context).ok,
useRootNavigator: false,
);
setState(() {
crossSigningCachedFuture = null;
@ -279,7 +271,6 @@ class SettingsController extends State<Settings> {
context: context,
message: L10n.of(context).incorrectPassphraseOrKey,
okLabel: L10n.of(context).ok,
useRootNavigator: false,
);
}
}
@ -296,7 +287,6 @@ class SettingsController extends State<Settings> {
title: L10n.of(context).pleaseChooseAPasscode,
message: L10n.of(context).pleaseEnter4Digits,
cancelLabel: L10n.of(context).cancel,
useRootNavigator: false,
textFields: [
DialogTextField(
validator: (text) {
@ -333,7 +323,6 @@ class SettingsController extends State<Settings> {
isDestructiveAction: true,
okLabel: L10n.of(context).ok,
cancelLabel: L10n.of(context).cancel,
useRootNavigator: false,
)) {
await BootstrapDialog(
client: Matrix.of(context).client,
@ -351,7 +340,7 @@ class SettingsController extends State<Settings> {
await BootstrapDialog(
client: Matrix.of(context).client,
).show(context);
AdaptivePageLayout.of(context).popUntilIsFirst();
VRouter.of(context).push('/rooms');
}
@override

View file

@ -21,7 +21,6 @@ class Settings3PidController extends State<Settings3Pid> {
title: L10n.of(context).enterAnEmailAddress,
okLabel: L10n.of(context).ok,
cancelLabel: L10n.of(context).cancel,
useRootNavigator: false,
textFields: [
DialogTextField(
hintText: L10n.of(context).enterAnEmailAddress,
@ -45,7 +44,6 @@ class Settings3PidController extends State<Settings3Pid> {
title: L10n.of(context).weSentYouAnEmail,
message: L10n.of(context).pleaseClickOnLink,
okLabel: L10n.of(context).iHaveClickedOnLink,
useRootNavigator: false,
);
if (ok == null) return;
final success = await showFutureLoadingDialog(
@ -70,7 +68,6 @@ class Settings3PidController extends State<Settings3Pid> {
title: L10n.of(context).areYouSure,
okLabel: L10n.of(context).yes,
cancelLabel: L10n.of(context).cancel,
useRootNavigator: false,
) !=
OkCancelResult.ok) {
return;

View file

@ -1,5 +1,5 @@
import 'package:adaptive_dialog/adaptive_dialog.dart';
import 'package:adaptive_page_layout/adaptive_page_layout.dart';
import 'package:famedlysdk/famedlysdk.dart';
import 'package:file_picker_cross/file_picker_cross.dart';
import 'package:fluffychat/utils/platform_infos.dart';
@ -138,7 +138,6 @@ class EmotesSettingsController extends State<EmotesSettings> {
context: context,
message: L10n.of(context).emoteExists,
okLabel: L10n.of(context).ok,
useRootNavigator: false,
);
return;
}
@ -148,7 +147,6 @@ class EmotesSettingsController extends State<EmotesSettings> {
context: context,
message: L10n.of(context).emoteInvalid,
okLabel: L10n.of(context).ok,
useRootNavigator: false,
);
return;
}
@ -187,7 +185,6 @@ class EmotesSettingsController extends State<EmotesSettings> {
context: context,
message: L10n.of(context).emoteWarnNeedToPick,
okLabel: L10n.of(context).ok,
useRootNavigator: false,
);
return;
}
@ -198,7 +195,6 @@ class EmotesSettingsController extends State<EmotesSettings> {
context: context,
message: L10n.of(context).emoteExists,
okLabel: L10n.of(context).ok,
useRootNavigator: false,
);
return;
}
@ -207,7 +203,6 @@ class EmotesSettingsController extends State<EmotesSettings> {
context: context,
message: L10n.of(context).emoteInvalid,
okLabel: L10n.of(context).ok,
useRootNavigator: false,
);
return;
}
@ -222,7 +217,7 @@ class EmotesSettingsController extends State<EmotesSettings> {
void emoteImagePickerAction(TextEditingController controller) async {
if (kIsWeb) {
AdaptivePageLayout.of(context).showSnackBar(
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(content: Text(L10n.of(context).notSupportedInWeb)));
return;
}

View file

@ -1,11 +1,10 @@
import 'package:flutter/material.dart';
import 'package:vrouter/vrouter.dart';
import 'views/settings_multiple_emotes_view.dart';
class MultipleEmotesSettings extends StatefulWidget {
final String roomId;
MultipleEmotesSettings(this.roomId, {Key key}) : super(key: key);
MultipleEmotesSettings({Key key}) : super(key: key);
@override
MultipleEmotesSettingsController createState() =>
@ -13,6 +12,7 @@ class MultipleEmotesSettings extends StatefulWidget {
}
class MultipleEmotesSettingsController extends State<MultipleEmotesSettings> {
String get roomId => VRouter.of(context).pathParameters['roomid'];
@override
Widget build(BuildContext context) => MultipleEmotesSettingsView(this);
}

View file

@ -1,7 +1,6 @@
import 'dart:async';
import 'dart:io';
import 'package:adaptive_page_layout/adaptive_page_layout.dart';
import 'package:famedlysdk/famedlysdk.dart';
import 'package:file_picker_cross/file_picker_cross.dart';
import 'package:fluffychat/config/app_config.dart';
@ -17,6 +16,7 @@ import 'package:future_loading_dialog/future_loading_dialog.dart';
import 'package:uni_links/uni_links.dart';
import 'package:url_launcher/url_launcher.dart';
import 'package:universal_html/html.dart' as html;
import 'package:vrouter/vrouter.dart';
import '../main.dart';
@ -29,7 +29,7 @@ class SignUpController extends State<SignUp> {
final TextEditingController usernameController = TextEditingController();
String usernameError;
bool loading = false;
MatrixFile avatar;
static MatrixFile avatar;
LoginTypes _loginTypes;
StreamSubscription _intentDataStreamSubscription;
@ -48,7 +48,7 @@ class SignUpController extends State<SignUp> {
void _processIncomingUris(String text) async {
if (text == null || !text.startsWith(AppConfig.appOpenUrlScheme)) return;
AdaptivePageLayout.of(context).popUntilIsFirst();
VRouter.of(context).push('/home');
final token = Uri.parse(text).queryParameters['loginToken'];
if (token != null) _loginWithToken(token);
}
@ -151,9 +151,10 @@ class SignUpController extends State<SignUp> {
return setState(() => loading = false);
}
setState(() => loading = false);
await AdaptivePageLayout.of(context).pushNamed(
VRouter.of(context).push(
'/signup/password/${Uri.encodeComponent(preferredUsername)}/${Uri.encodeComponent(usernameController.text)}',
arguments: avatar,
queryParameters: {'displayname': usernameController.text},
);
}

View file

@ -1,21 +1,20 @@
import 'package:adaptive_dialog/adaptive_dialog.dart';
import 'package:adaptive_page_layout/adaptive_page_layout.dart';
import 'package:email_validator/email_validator.dart';
import 'package:famedlysdk/famedlysdk.dart';
import 'package:fluffychat/pages/sign_up.dart';
import 'package:fluffychat/utils/get_client_secret.dart';
import 'package:fluffychat/pages/views/sign_up_password_view.dart';
import 'package:fluffychat/widgets/matrix.dart';
import 'package:flutter/material.dart';
import 'package:flutter_gen/gen_l10n/l10n.dart';
import 'package:vrouter/vrouter.dart';
import '../utils/platform_infos.dart';
class SignUpPassword extends StatefulWidget {
final MatrixFile avatar;
final String username;
final String displayname;
const SignUpPassword(this.username, {this.avatar, this.displayname});
const SignUpPassword();
@override
SignUpPasswordController createState() => SignUpPasswordController();
}
@ -70,8 +69,10 @@ class SignUpPasswordController extends State<SignUpPassword> {
}
}
final waitForLogin = matrix.client.onLoginStateChanged.stream.first;
final username = VRouter.of(context).pathParameters['username'];
await matrix.client.uiaRequestBackground((auth) => matrix.client.register(
username: widget.username,
username: username,
password: passwordController.text,
initialDeviceDisplayName: PlatformInfos.clientName,
auth: auth,
@ -91,19 +92,20 @@ class SignUpPasswordController extends State<SignUpPassword> {
}
await matrix.client.onLoginStateChanged.stream
.firstWhere((l) => l == LoginState.logged);
// tchncs.de
try {
await matrix.client
.setDisplayName(matrix.client.userID, widget.displayname);
} catch (exception) {
AdaptivePageLayout.of(context).showSnackBar(
SnackBar(content: Text(L10n.of(context).couldNotSetDisplayname)));
}
if (widget.avatar != null) {
final displayname = VRouter.of(context).queryParameters['displayname'];
if (displayname != null) {
try {
await matrix.client.setAvatar(widget.avatar);
await matrix.client.setDisplayName(matrix.client.userID, displayname);
} catch (exception) {
AdaptivePageLayout.of(context).showSnackBar(
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(content: Text(L10n.of(context).couldNotSetDisplayname)));
}
}
if (SignUpController.avatar != null) {
try {
await matrix.client.setAvatar(SignUpController.avatar);
} catch (exception) {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(content: Text(L10n.of(context).couldNotSetAvatar)));
}
}

View file

@ -1,11 +1,12 @@
import 'package:adaptive_dialog/adaptive_dialog.dart';
import 'package:adaptive_page_layout/adaptive_page_layout.dart';
import 'package:famedlysdk/famedlysdk.dart';
import 'package:fluffychat/pages/permission_slider_dialog.dart';
import 'package:flutter/material.dart';
import 'package:flutter_gen/gen_l10n/l10n.dart';
import 'package:future_loading_dialog/future_loading_dialog.dart';
import 'package:vrouter/vrouter.dart';
import 'views/user_bottom_sheet_view.dart';
@ -30,7 +31,6 @@ class UserBottomSheetController extends State<UserBottomSheet> {
final Function _askConfirmation =
() async => (await showOkCancelAlertDialog(
context: context,
useRootNavigator: false,
title: L10n.of(context).areYouSure,
okLabel: L10n.of(context).yes,
cancelLabel: L10n.of(context).no,
@ -83,8 +83,7 @@ class UserBottomSheetController extends State<UserBottomSheet> {
break;
case 'message':
final roomId = await widget.user.startDirectChat();
await AdaptivePageLayout.of(widget.outerContext)
.pushNamedAndRemoveUntilIsFirst('/rooms/$roomId');
VRouter.of(widget.outerContext).push('/rooms/$roomId');
Navigator.of(context, rootNavigator: false).pop();
break;
}

View file

@ -1,4 +1,3 @@
import 'package:adaptive_page_layout/adaptive_page_layout.dart';
import 'package:fluffychat/config/app_config.dart';
import 'package:fluffychat/pages/chat_details.dart';
import 'package:fluffychat/widgets/avatar.dart';
@ -15,6 +14,7 @@ import 'package:fluffychat/utils/matrix_sdk_extensions.dart/matrix_locals.dart';
import 'package:flutter/material.dart';
import 'package:flutter_gen/gen_l10n/l10n.dart';
import 'package:matrix_link_text/link_text.dart';
import 'package:vrouter/vrouter.dart';
import '../../utils/url_launcher.dart';
@ -25,12 +25,10 @@ class ChatDetailsView extends StatelessWidget {
@override
Widget build(BuildContext context) {
final room =
Matrix.of(context).client.getRoomById(controller.widget.roomId);
final room = Matrix.of(context).client.getRoomById(controller.roomId);
if (room == null) {
return Scaffold(
appBar: AppBar(
leading: BackButton(),
title: Text(L10n.of(context).oopsSomethingWentWrong),
),
body: Center(
@ -52,8 +50,12 @@ class ChatDetailsView extends StatelessWidget {
headerSliverBuilder:
(BuildContext context, bool innerBoxIsScrolled) => <Widget>[
SliverAppBar(
leading: IconButton(
icon: Icon(Icons.close_outlined),
onPressed: () =>
VRouter.of(context).push('/rooms/${controller.roomId}'),
),
elevation: Theme.of(context).appBarTheme.elevation,
leading: BackButton(),
expandedHeight: 300.0,
floating: true,
pinned: true,
@ -308,8 +310,8 @@ class ChatDetailsView extends StatelessWidget {
foregroundColor: Colors.grey,
child: Icon(Icons.edit_attributes_outlined),
),
onTap: () => AdaptivePageLayout.of(context)
.pushNamed('/rooms/${room.id}/permissions'),
onTap: () => VRouter.of(context).push(
'/rooms/${room.id}/details/permissions'),
),
Divider(thickness: 1),
ListTile(
@ -334,8 +336,8 @@ class ChatDetailsView extends StatelessWidget {
radius: Avatar.defaultSize / 2,
child: Icon(Icons.add_outlined),
),
onTap: () => AdaptivePageLayout.of(context)
.pushNamed('/rooms/${room.id}/invite'),
onTap: () => VRouter.of(context)
.push('/rooms/${room.id}/invite'),
)
: Container(),
],

View file

@ -5,6 +5,7 @@ import 'package:fluffychat/widgets/matrix.dart';
import 'package:fluffychat/widgets/layouts/max_width_body.dart';
import 'package:flutter/material.dart';
import 'package:flutter_gen/gen_l10n/l10n.dart';
import 'package:vrouter/vrouter.dart';
import '../../utils/matrix_sdk_extensions.dart/device_extension.dart';
class ChatEncryptionSettingsView extends StatelessWidget {
@ -15,11 +16,15 @@ class ChatEncryptionSettingsView extends StatelessWidget {
@override
Widget build(BuildContext context) {
final room = Matrix.of(context).client.getRoomById(controller.widget.id);
final room = Matrix.of(context).client.getRoomById(controller.roomId);
return Scaffold(
appBar: AppBar(
leading: BackButton(),
leading: IconButton(
icon: Icon(Icons.close_outlined),
onPressed: () =>
VRouter.of(context).push('/rooms/${controller.roomId}'),
),
title: Text(L10n.of(context).tapOnDeviceToVerify),
bottom: PreferredSize(
preferredSize: Size.fromHeight(56),

View file

@ -1,4 +1,3 @@
import 'package:adaptive_page_layout/adaptive_page_layout.dart';
import 'package:famedlysdk/famedlysdk.dart';
import 'package:fluffychat/pages/chat_list.dart';
import 'package:fluffychat/widgets/connection_status_header.dart';
@ -7,6 +6,7 @@ import 'package:flutter/cupertino.dart';
import 'package:fluffychat/config/app_config.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:vrouter/vrouter.dart';
import '../../widgets/matrix.dart';
import 'package:flutter_gen/gen_l10n/l10n.dart';
@ -28,7 +28,9 @@ class ChatListView extends StatelessWidget {
return Scaffold(
appBar: AppBar(
elevation:
AdaptivePageLayout.of(context).columnMode(context) ? 1 : null,
MediaQuery.of(context).size.width > AppConfig.columnWidth * 2
? 1
: null,
leading: selectMode == SelectMode.normal
? null
: IconButton(
@ -82,8 +84,8 @@ class ChatListView extends StatelessWidget {
IconButton(
icon: Icon(Icons.search_outlined),
tooltip: L10n.of(context).search,
onPressed: () => AdaptivePageLayout.of(context)
.pushNamed('/search'),
onPressed: () =>
VRouter.of(context).push('/search'),
),
PopupMenuButton<PopupMenuAction>(
onSelected: controller.onPopupMenuSelect,
@ -223,8 +225,8 @@ class ChatListView extends StatelessWidget {
]),
floatingActionButton: selectMode == SelectMode.normal
? FloatingActionButton(
onPressed: () => AdaptivePageLayout.of(context)
.pushNamedAndRemoveUntilIsFirst('/newprivatechat'),
onPressed: () =>
VRouter.of(context).push('/newprivatechat'),
child: Icon(CupertinoIcons.chat_bubble),
)
: null,

View file

@ -26,7 +26,7 @@ class ChatPermissionsSettingsView extends StatelessWidget {
stream: controller.onChanged,
builder: (context, _) {
final room =
Matrix.of(context).client.getRoomById(controller.widget.roomId);
Matrix.of(context).client.getRoomById(controller.roomId);
final powerLevelsContent = Map<String, dynamic>.from(
room.getState(EventTypes.RoomPowerLevels).content);
final powerLevels = Map<String, dynamic>.from(powerLevelsContent)

View file

@ -1,7 +1,6 @@
import 'dart:math';
import 'dart:ui';
import 'package:adaptive_page_layout/adaptive_page_layout.dart';
import 'package:emoji_picker_flutter/emoji_picker_flutter.dart';
import 'package:famedlysdk/famedlysdk.dart';
import 'package:fluffychat/pages/chat.dart';
@ -28,6 +27,7 @@ import 'package:flutter/services.dart';
import 'package:flutter_gen/gen_l10n/l10n.dart';
import 'package:scroll_to_index/scroll_to_index.dart';
import 'package:swipe_to_action/swipe_to_action.dart';
import 'package:vrouter/vrouter.dart';
class ChatView extends StatelessWidget {
final ChatController controller;
@ -38,7 +38,7 @@ class ChatView extends StatelessWidget {
Widget build(BuildContext context) {
controller.matrix = Matrix.of(context);
final client = controller.matrix.client;
controller.room ??= client.getRoomById(controller.widget.id);
controller.room ??= client.getRoomById(controller.roomId);
if (controller.room == null) {
return Scaffold(
appBar: AppBar(
@ -49,7 +49,7 @@ class ChatView extends StatelessWidget {
),
);
}
controller.matrix.client.activeRoomId = controller.widget.id;
controller.matrix.client.activeRoomId = controller.roomId;
if (controller.room.membership == Membership.invite) {
showFutureLoadingDialog(
@ -64,11 +64,7 @@ class ChatView extends StatelessWidget {
onPressed: controller.clearSelectedEvents,
tooltip: L10n.of(context).close,
)
: AdaptivePageLayout.of(context).columnMode(context)
? null
: UnreadBadgeBackButton(roomId: controller.widget.id),
titleSpacing:
AdaptivePageLayout.of(context).columnMode(context) ? null : 0,
: UnreadBadgeBackButton(roomId: controller.roomId),
title: controller.selectedEvents.isEmpty
? StreamBuilder(
stream: controller.room.onUpdate.stream,
@ -88,15 +84,8 @@ class ChatView extends StatelessWidget {
'${controller.room.directChatMatrixID} ',
),
)
: () => (!AdaptivePageLayout.of(context)
.columnMode(context) ||
AdaptivePageLayout.of(context)
.viewDataStack
.length <
3)
? AdaptivePageLayout.of(context).pushNamed(
'/rooms/${controller.room.id}/details')
: null,
: () => VRouter.of(context)
.push('/rooms/${controller.room.id}/details'),
title: Text(
controller.room.getLocalizedDisplayname(
MatrixLocals(L10n.of(context))),
@ -259,13 +248,7 @@ class ChatView extends StatelessWidget {
final horizontalPadding = max(
0,
(MediaQuery.of(context).size.width -
FluffyThemes.columnWidth *
(AdaptivePageLayout.of(context)
.currentViewData
?.rightView !=
null
? 4.5
: 3.5)) /
FluffyThemes.columnWidth * (3.5)) /
2)
.toDouble();

View file

@ -1,6 +1,7 @@
import 'package:flutter/material.dart';
class EmptyPage extends StatelessWidget {
const EmptyPage({Key key}) : super(key: key);
@override
Widget build(BuildContext context) {
return Scaffold(

View file

@ -15,8 +15,7 @@ class InvitationSelectionView extends StatelessWidget {
@override
Widget build(BuildContext context) {
final room =
Matrix.of(context).client.getRoomById(controller.widget.roomId);
final room = Matrix.of(context).client.getRoomById(controller.roomId);
final groupName =
room.name?.isEmpty ?? false ? L10n.of(context).group : room.name;
return Scaffold(

View file

@ -1,4 +1,3 @@
import 'package:adaptive_page_layout/adaptive_page_layout.dart';
import 'package:fluffychat/pages/new_private_chat.dart';
import 'package:fluffychat/widgets/avatar.dart';
import 'package:fluffychat/widgets/contacts_list.dart';
@ -7,6 +6,7 @@ import 'package:fluffychat/widgets/matrix.dart';
import 'package:flutter/material.dart';
import 'package:flutter_gen/gen_l10n/l10n.dart';
import 'package:famedlysdk/famedlysdk.dart';
import 'package:vrouter/vrouter.dart';
class NewPrivateChatView extends StatelessWidget {
final NewPrivateChatController controller;
@ -22,8 +22,7 @@ class NewPrivateChatView extends StatelessWidget {
elevation: 0,
actions: [
TextButton(
onPressed: () => AdaptivePageLayout.of(context)
.pushNamedAndRemoveUntilIsFirst('/newgroup'),
onPressed: () => VRouter.of(context).push('/newgroup'),
child: Text(
L10n.of(context).createNewGroup,
style: TextStyle(color: Theme.of(context).accentColor),

View file

@ -1,4 +1,3 @@
import 'package:adaptive_page_layout/adaptive_page_layout.dart';
import 'package:famedlysdk/famedlysdk.dart';
import 'package:fluffychat/widgets/avatar.dart';
import 'package:fluffychat/widgets/contacts_list.dart';
@ -8,6 +7,7 @@ import 'package:fluffychat/widgets/matrix.dart';
import 'package:flutter/material.dart';
import 'package:flutter_gen/gen_l10n/l10n.dart';
import 'package:future_loading_dialog/future_loading_dialog.dart';
import 'package:vrouter/vrouter.dart';
import '../../utils/localized_exception_extension.dart';
import '../search.dart';
@ -32,21 +32,21 @@ class SearchView extends StatelessWidget {
genericSearchTerm: controller.genericSearchTerm,
)
.catchError((error) {
if (controller.widget.alias == null) {
if (controller.alias == null) {
throw error;
}
return PublicRoomsResponse.fromJson({
'chunk': [],
});
}).then((PublicRoomsResponse res) {
if (controller.widget.alias != null &&
if (controller.alias != null &&
!res.chunk.any((room) =>
(room.aliases?.contains(controller.widget.alias) ?? false) ||
room.canonicalAlias == controller.widget.alias)) {
(room.aliases?.contains(controller.alias) ?? false) ||
room.canonicalAlias == controller.alias)) {
// we have to tack on the original alias
res.chunk.add(PublicRoom.fromJson(<String, dynamic>{
'aliases': [controller.widget.alias],
'name': controller.widget.alias,
'aliases': [controller.alias],
'name': controller.alias,
}));
}
return res;
@ -238,8 +238,7 @@ class SearchView extends StatelessWidget {
.startDirectChat(foundProfile.userId),
);
if (roomID.error == null) {
await AdaptivePageLayout.of(context)
.popAndPushNamed('/rooms/${roomID.result}');
VRouter.of(context).push('/rooms/${roomID.result}');
}
},
leading: Avatar(

View file

@ -1,9 +1,9 @@
import 'package:adaptive_page_layout/adaptive_page_layout.dart';
import 'package:fluffychat/pages/settings_multiple_emotes.dart';
import 'package:fluffychat/widgets/matrix.dart';
import 'package:flutter/material.dart';
import 'package:famedlysdk/famedlysdk.dart';
import 'package:flutter_gen/gen_l10n/l10n.dart';
import 'package:vrouter/vrouter.dart';
class MultipleEmotesSettingsView extends StatelessWidget {
final MultipleEmotesSettingsController controller;
@ -12,8 +12,7 @@ class MultipleEmotesSettingsView extends StatelessWidget {
@override
Widget build(BuildContext context) {
final room =
Matrix.of(context).client.getRoomById(controller.widget.roomId);
final room = Matrix.of(context).client.getRoomById(controller.roomId);
return Scaffold(
appBar: AppBar(
leading: BackButton(),
@ -45,13 +44,7 @@ class MultipleEmotesSettingsView extends StatelessWidget {
return ListTile(
title: Text(packName),
onTap: () async {
await AdaptivePageLayout.of(context).pushNamed(
'/settings/emotes',
arguments: {
'room': room,
'stateKey': keys[i],
},
);
VRouter.of(context).push('/settings/emotes');
},
);
});

View file

@ -1,5 +1,5 @@
import 'package:adaptive_dialog/adaptive_dialog.dart';
import 'package:adaptive_page_layout/adaptive_page_layout.dart';
import 'package:fluffychat/widgets/sentry_switch_list_tile.dart';
import 'package:fluffychat/widgets/settings_switch_list_tile.dart';
@ -11,6 +11,7 @@ import 'package:fluffychat/utils/platform_infos.dart';
import 'package:flutter/material.dart';
import 'package:flutter_gen/gen_l10n/l10n.dart';
import 'package:url_launcher/url_launcher.dart';
import 'package:vrouter/vrouter.dart';
import '../../widgets/content_banner.dart';
import '../../widgets/matrix.dart';
@ -31,10 +32,6 @@ class SettingsView extends StatelessWidget {
headerSliverBuilder: (BuildContext context, bool innerBoxIsScrolled) =>
<Widget>[
SliverAppBar(
leading: IconButton(
icon: Icon(Icons.close_outlined),
onPressed: () => AdaptivePageLayout.of(context).popUntilIsFirst(),
),
expandedHeight: 300.0,
floating: true,
pinned: true,
@ -85,8 +82,7 @@ class SettingsView extends StatelessWidget {
ListTile(
trailing: Icon(Icons.notifications_outlined),
title: Text(L10n.of(context).notifications),
onTap: () => AdaptivePageLayout.of(context)
.pushNamed('/settings/notifications'),
onTap: () => VRouter.of(context).push('/settings/notifications'),
),
Divider(thickness: 1),
ListTile(
@ -100,8 +96,7 @@ class SettingsView extends StatelessWidget {
),
ListTile(
title: Text(L10n.of(context).changeTheme),
onTap: () =>
AdaptivePageLayout.of(context).pushNamed('/settings/style'),
onTap: () => VRouter.of(context).push('/settings/style'),
trailing: Icon(Icons.style_outlined),
),
SettingsSwitchListTile(
@ -124,8 +119,7 @@ class SettingsView extends StatelessWidget {
),
ListTile(
title: Text(L10n.of(context).emoteSettings),
onTap: () =>
AdaptivePageLayout.of(context).pushNamed('/settings/emotes'),
onTap: () => VRouter.of(context).push('/settings/emotes'),
trailing: Icon(Icons.insert_emoticon_outlined),
),
Divider(thickness: 1),
@ -154,14 +148,12 @@ class SettingsView extends StatelessWidget {
ListTile(
trailing: Icon(Icons.devices_other_outlined),
title: Text(L10n.of(context).devices),
onTap: () =>
AdaptivePageLayout.of(context).pushNamed('/settings/devices'),
onTap: () => VRouter.of(context).push('/settings/devices'),
),
ListTile(
trailing: Icon(Icons.block_outlined),
title: Text(L10n.of(context).ignoredUsers),
onTap: () =>
AdaptivePageLayout.of(context).pushNamed('/settings/ignore'),
onTap: () => VRouter.of(context).push('/settings/ignorelist'),
),
SentrySwitchListTile(),
Divider(thickness: 1),
@ -175,8 +167,7 @@ class SettingsView extends StatelessWidget {
ListTile(
trailing: Icon(Icons.email_outlined),
title: Text(L10n.of(context).passwordRecovery),
onTap: () =>
AdaptivePageLayout.of(context).pushNamed('/settings/3pid'),
onTap: () => VRouter.of(context).push('/settings/3pid'),
),
ListTile(
trailing: Icon(Icons.exit_to_app_outlined),
@ -215,7 +206,6 @@ class SettingsView extends StatelessWidget {
title: L10n.of(context).yourPublicKey,
message: client.fingerprintKey.beautified,
okLabel: L10n.of(context).ok,
useRootNavigator: false,
),
trailing: Icon(Icons.vpn_key_outlined),
),
@ -236,7 +226,7 @@ class SettingsView extends StatelessWidget {
fontWeight: FontWeight.bold,
),
),
onTap: () => AdaptivePageLayout.of(context).pushNamed('/logs'),
onTap: () => VRouter.of(context).push('/logs'),
),
ListTile(
trailing: Icon(Icons.help_outlined),

View file

@ -1,4 +1,4 @@
import 'package:adaptive_page_layout/adaptive_page_layout.dart';
import 'package:vrouter/vrouter.dart';
import 'package:fluffychat/pages/sign_up.dart';
import 'package:fluffychat/widgets/fluffy_banner.dart';
@ -71,29 +71,29 @@ class SignUpView extends StatelessWidget {
SizedBox(height: 8),
ListTile(
leading: CircleAvatar(
backgroundImage: controller.avatar == null
backgroundImage: SignUpController.avatar == null
? null
: MemoryImage(controller.avatar.bytes),
backgroundColor: controller.avatar == null
: MemoryImage(SignUpController.avatar.bytes),
backgroundColor: SignUpController.avatar == null
? Theme.of(context).brightness == Brightness.dark
? Color(0xff121212)
: Colors.white
: Theme.of(context).secondaryHeaderColor,
child: controller.avatar == null
child: SignUpController.avatar == null
? Icon(Icons.camera_alt_outlined,
color: Theme.of(context).primaryColor)
: null,
),
trailing: controller.avatar == null
trailing: SignUpController.avatar == null
? null
: Icon(
Icons.close,
color: Colors.red,
),
title: Text(controller.avatar == null
title: Text(SignUpController.avatar == null
? L10n.of(context).setAProfilePicture
: L10n.of(context).discardPicture),
onTap: controller.avatar == null
onTap: SignUpController.avatar == null
? controller.setAvatarAction
: controller.resetAvatarAction,
),
@ -146,8 +146,7 @@ class SignUpView extends StatelessWidget {
Theme.of(context).textTheme.bodyText1.color,
elevation: 2,
),
onPressed: () => AdaptivePageLayout.of(context)
.pushNamed('/login'),
onPressed: () => context.vRouter.push('/login'),
child: Text(L10n.of(context).login),
),
),