mirror of
https://gitlab.com/famedly/fluffychat.git
synced 2024-11-27 14:59:29 +01:00
feat: Switch to VRouter
This commit is contained in:
parent
8921389e15
commit
1ebae21ea2
@ -42,6 +42,7 @@ abstract class AppConfig {
|
|||||||
static const String emojiFontUrl =
|
static const String emojiFontUrl =
|
||||||
'https://github.com/googlefonts/noto-emoji/';
|
'https://github.com/googlefonts/noto-emoji/';
|
||||||
static const double borderRadius = 12.0;
|
static const double borderRadius = 12.0;
|
||||||
|
static const double columnWidth = 360.0;
|
||||||
|
|
||||||
static void loadFromJson(Map<String, dynamic> json) {
|
static void loadFromJson(Map<String, dynamic> json) {
|
||||||
if (json['application_name'] is String) {
|
if (json['application_name'] is String) {
|
||||||
|
@ -1,5 +1,3 @@
|
|||||||
import 'package:adaptive_page_layout/adaptive_page_layout.dart';
|
|
||||||
import 'package:famedlysdk/famedlysdk.dart';
|
|
||||||
import 'package:fluffychat/pages/archive.dart';
|
import 'package:fluffychat/pages/archive.dart';
|
||||||
import 'package:fluffychat/pages/homeserver_picker.dart';
|
import 'package:fluffychat/pages/homeserver_picker.dart';
|
||||||
import 'package:fluffychat/pages/invitation_selection.dart';
|
import 'package:fluffychat/pages/invitation_selection.dart';
|
||||||
@ -7,7 +5,7 @@ import 'package:fluffychat/pages/settings_emotes.dart';
|
|||||||
import 'package:fluffychat/pages/settings_multiple_emotes.dart';
|
import 'package:fluffychat/pages/settings_multiple_emotes.dart';
|
||||||
import 'package:fluffychat/pages/sign_up.dart';
|
import 'package:fluffychat/pages/sign_up.dart';
|
||||||
import 'package:fluffychat/pages/sign_up_password.dart';
|
import 'package:fluffychat/pages/sign_up_password.dart';
|
||||||
import 'package:fluffychat/widgets/matrix.dart';
|
import 'package:fluffychat/widgets/layouts/two_column_layout.dart';
|
||||||
import 'package:fluffychat/pages/chat.dart';
|
import 'package:fluffychat/pages/chat.dart';
|
||||||
import 'package:fluffychat/pages/chat_details.dart';
|
import 'package:fluffychat/pages/chat_details.dart';
|
||||||
import 'package:fluffychat/pages/chat_encryption_settings.dart';
|
import 'package:fluffychat/pages/chat_encryption_settings.dart';
|
||||||
@ -27,200 +25,261 @@ import 'package:fluffychat/pages/settings_ignore_list.dart';
|
|||||||
import 'package:fluffychat/pages/settings_notifications.dart';
|
import 'package:fluffychat/pages/settings_notifications.dart';
|
||||||
import 'package:fluffychat/pages/settings_style.dart';
|
import 'package:fluffychat/pages/settings_style.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:vrouter/vrouter.dart';
|
||||||
|
|
||||||
class FluffyRoutes {
|
class AppRoutes {
|
||||||
final BuildContext context;
|
final int columns;
|
||||||
|
|
||||||
const FluffyRoutes(this.context);
|
AppRoutes(this.columns);
|
||||||
|
|
||||||
ViewData onGenerateRoute(RouteSettings settings) {
|
List<VRouteElement> get routes => [
|
||||||
final parts = settings.name.split('/');
|
VWidget(path: '/', widget: LoadingView()),
|
||||||
|
VWidget(
|
||||||
// Routes if the app is loading
|
path: '/home',
|
||||||
if (Matrix.of(context).loginState == null) {
|
widget: HomeserverPicker(),
|
||||||
return ViewData(mainView: (_) => LoadingView());
|
buildTransition: _fadeTransition,
|
||||||
// Routes if user is NOT logged in
|
stackedRoutes: [
|
||||||
} else if (Matrix.of(context).loginState == LoginState.loggedOut) {
|
VWidget(
|
||||||
switch (parts[1]) {
|
path: '/signup',
|
||||||
case '':
|
widget: SignUp(),
|
||||||
return ViewData(mainView: (_) => HomeserverPicker());
|
buildTransition: _fadeTransition,
|
||||||
case 'login':
|
stackedRoutes: [
|
||||||
return ViewData(mainView: (_) => Login());
|
VWidget(
|
||||||
case 'signup':
|
path: 'password/:username',
|
||||||
if (parts.length == 5 && parts[2] == 'password') {
|
widget: SignUpPassword(),
|
||||||
return ViewData(
|
buildTransition: _fadeTransition,
|
||||||
mainView: (_) => SignUpPassword(
|
),
|
||||||
parts[3],
|
VWidget(
|
||||||
displayname: parts[4],
|
path: '/login',
|
||||||
avatar: settings.arguments,
|
widget: Login(),
|
||||||
|
buildTransition: _fadeTransition,
|
||||||
|
),
|
||||||
|
]),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
if (columns > 1) ...{
|
||||||
|
VNester(
|
||||||
|
path: '/rooms',
|
||||||
|
widgetBuilder: (child) => TwoColumnLayout(
|
||||||
|
mainView: ChatList(),
|
||||||
|
sideView: child,
|
||||||
|
),
|
||||||
|
buildTransition: _fadeTransition,
|
||||||
|
nestedRoutes: [
|
||||||
|
VWidget(
|
||||||
|
path: '',
|
||||||
|
widget: EmptyPage(),
|
||||||
|
buildTransition: _fadeTransition,
|
||||||
|
stackedRoutes: [
|
||||||
|
VWidget(
|
||||||
|
path: '/newprivatechat',
|
||||||
|
widget: NewPrivateChat(),
|
||||||
|
buildTransition: _fadeTransition,
|
||||||
|
),
|
||||||
|
VWidget(
|
||||||
|
path: '/newgroup',
|
||||||
|
widget: NewGroup(),
|
||||||
|
buildTransition: _fadeTransition,
|
||||||
|
),
|
||||||
|
if (columns == 2)
|
||||||
|
VWidget(
|
||||||
|
path: ':roomid',
|
||||||
|
widget: Chat(),
|
||||||
|
buildTransition: _fadeTransition,
|
||||||
|
stackedRoutes: [
|
||||||
|
VWidget(
|
||||||
|
path: 'encryption',
|
||||||
|
widget: ChatEncryptionSettings(),
|
||||||
|
buildTransition: _fadeTransition,
|
||||||
|
),
|
||||||
|
VWidget(
|
||||||
|
path: 'details',
|
||||||
|
widget: ChatDetails(),
|
||||||
|
buildTransition: _fadeTransition,
|
||||||
|
stackedRoutes: _chatDetailsRoutes,
|
||||||
|
),
|
||||||
|
VWidget(
|
||||||
|
path: 'invite',
|
||||||
|
widget: InvitationSelection(),
|
||||||
|
buildTransition: _fadeTransition,
|
||||||
|
),
|
||||||
|
]),
|
||||||
|
if (columns > 2)
|
||||||
|
VNester(
|
||||||
|
path: ':roomid',
|
||||||
|
widgetBuilder: (child) => Chat(sideView: child),
|
||||||
|
buildTransition: _fadeTransition,
|
||||||
|
nestedRoutes: [
|
||||||
|
VWidget(
|
||||||
|
path: '',
|
||||||
|
widget: EmptyPage(),
|
||||||
|
buildTransition: _fadeTransition,
|
||||||
|
),
|
||||||
|
VWidget(
|
||||||
|
path: 'encryption',
|
||||||
|
widget: ChatEncryptionSettings(),
|
||||||
|
buildTransition: _fadeTransition,
|
||||||
|
),
|
||||||
|
VWidget(
|
||||||
|
path: 'details',
|
||||||
|
widget: ChatDetails(),
|
||||||
|
buildTransition: _fadeTransition,
|
||||||
|
stackedRoutes: _chatDetailsRoutes,
|
||||||
|
),
|
||||||
|
VWidget(
|
||||||
|
path: 'invite',
|
||||||
|
widget: InvitationSelection(),
|
||||||
|
buildTransition: _fadeTransition,
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
],
|
||||||
),
|
),
|
||||||
);
|
],
|
||||||
}
|
|
||||||
return ViewData(mainView: (_) => SignUp());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// Routes IF user is logged in
|
|
||||||
else {
|
|
||||||
switch (parts[1]) {
|
|
||||||
case '':
|
|
||||||
return ViewData(
|
|
||||||
mainView: (_) => ChatList(), emptyView: (_) => EmptyPage());
|
|
||||||
case 'rooms':
|
|
||||||
final roomId = parts[2];
|
|
||||||
if (parts.length == 3) {
|
|
||||||
return ViewData(
|
|
||||||
leftView: (_) => ChatList(activeChat: roomId),
|
|
||||||
mainView: (_) => Chat(roomId),
|
|
||||||
);
|
|
||||||
} else if (parts.length == 4) {
|
|
||||||
final action = parts[3];
|
|
||||||
switch (action) {
|
|
||||||
case 'details':
|
|
||||||
return ViewData(
|
|
||||||
leftView: (_) => ChatList(activeChat: roomId),
|
|
||||||
mainView: (_) => Chat(roomId),
|
|
||||||
rightView: (_) => ChatDetails(roomId),
|
|
||||||
);
|
|
||||||
case 'encryption':
|
|
||||||
return ViewData(
|
|
||||||
leftView: (_) => ChatList(activeChat: roomId),
|
|
||||||
mainView: (_) => Chat(roomId),
|
|
||||||
rightView: (_) => ChatEncryptionSettings(roomId),
|
|
||||||
);
|
|
||||||
case 'permissions':
|
|
||||||
return ViewData(
|
|
||||||
leftView: (_) => ChatList(activeChat: roomId),
|
|
||||||
mainView: (_) => Chat(roomId),
|
|
||||||
rightView: (_) => ChatPermissionsSettings(roomId),
|
|
||||||
);
|
|
||||||
case 'invite':
|
|
||||||
return ViewData(
|
|
||||||
leftView: (_) => ChatList(activeChat: roomId),
|
|
||||||
mainView: (_) => Chat(roomId),
|
|
||||||
rightView: (_) => InvitationSelection(roomId),
|
|
||||||
);
|
|
||||||
case 'emotes':
|
|
||||||
return ViewData(
|
|
||||||
leftView: (_) => ChatList(activeChat: roomId),
|
|
||||||
mainView: (_) => Chat(roomId),
|
|
||||||
rightView: (_) => MultipleEmotesSettings(roomId),
|
|
||||||
);
|
|
||||||
default:
|
|
||||||
return ViewData(
|
|
||||||
leftView: (_) => ChatList(activeChat: roomId),
|
|
||||||
mainView: (_) => Chat(roomId,
|
|
||||||
scrollToEventId: action.sigil == '\$' ? action : null),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return ViewData(
|
|
||||||
mainView: (_) => ChatList(), emptyView: (_) => EmptyPage());
|
|
||||||
case 'archive':
|
|
||||||
return ViewData(
|
|
||||||
mainView: (_) => Archive(),
|
|
||||||
emptyView: (_) => EmptyPage(),
|
|
||||||
);
|
|
||||||
case 'logs':
|
|
||||||
return ViewData(
|
|
||||||
mainView: (_) => LogViewer(),
|
|
||||||
);
|
|
||||||
case 'newgroup':
|
|
||||||
return ViewData(
|
|
||||||
leftView: (_) => ChatList(),
|
|
||||||
mainView: (_) => NewGroup(),
|
|
||||||
);
|
|
||||||
case 'newprivatechat':
|
|
||||||
return ViewData(
|
|
||||||
leftView: (_) => ChatList(),
|
|
||||||
mainView: (_) => NewPrivateChat(),
|
|
||||||
);
|
|
||||||
case 'search':
|
|
||||||
if (parts.length == 3) {
|
|
||||||
return ViewData(
|
|
||||||
mainView: (_) => Search(alias: parts[2]),
|
|
||||||
emptyView: (_) => EmptyPage());
|
|
||||||
}
|
|
||||||
return ViewData(
|
|
||||||
mainView: (_) => Search(), emptyView: (_) => EmptyPage());
|
|
||||||
case 'settings':
|
|
||||||
if (parts.length == 3) {
|
|
||||||
final action = parts[2];
|
|
||||||
switch (action) {
|
|
||||||
case '3pid':
|
|
||||||
return ViewData(
|
|
||||||
leftView: (_) => Settings(),
|
|
||||||
mainView: (_) => Settings3Pid(),
|
|
||||||
);
|
|
||||||
case 'devices':
|
|
||||||
return ViewData(
|
|
||||||
leftView: (_) => Settings(),
|
|
||||||
mainView: (_) => DevicesSettings(),
|
|
||||||
);
|
|
||||||
case 'emotes':
|
|
||||||
return ViewData(
|
|
||||||
leftView: (_) => Settings(),
|
|
||||||
mainView: (_) => EmotesSettings(
|
|
||||||
room: ((settings.arguments ?? {}) as Map)['room'],
|
|
||||||
stateKey: ((settings.arguments ?? {}) as Map)['stateKey'],
|
|
||||||
),
|
|
||||||
);
|
|
||||||
case 'ignore':
|
|
||||||
return ViewData(
|
|
||||||
leftView: (_) => Settings(),
|
|
||||||
mainView: (_) => SettingsIgnoreList(
|
|
||||||
initialUserId: settings.arguments,
|
|
||||||
),
|
|
||||||
);
|
|
||||||
case 'notifications':
|
|
||||||
return ViewData(
|
|
||||||
leftView: (_) => Settings(),
|
|
||||||
mainView: (_) => SettingsNotifications(),
|
|
||||||
);
|
|
||||||
case 'style':
|
|
||||||
return ViewData(
|
|
||||||
leftView: (_) => Settings(),
|
|
||||||
mainView: (_) => SettingsStyle(),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
return ViewData(
|
|
||||||
mainView: (_) => Settings(), emptyView: (_) => EmptyPage());
|
|
||||||
}
|
|
||||||
return ViewData(
|
|
||||||
mainView: (_) => ChatList(), emptyView: (_) => EmptyPage());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// If route cant be found:
|
|
||||||
return ViewData(
|
|
||||||
mainView: (_) => Center(
|
|
||||||
child: Text('Route "${settings.name}" not found...'),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class SettingsDevices {}
|
|
||||||
|
|
||||||
class FadeRoute extends PageRouteBuilder {
|
|
||||||
final Widget page;
|
|
||||||
FadeRoute({this.page})
|
|
||||||
: super(
|
|
||||||
pageBuilder: (
|
|
||||||
BuildContext context,
|
|
||||||
Animation<double> animation,
|
|
||||||
Animation<double> secondaryAnimation,
|
|
||||||
) =>
|
|
||||||
page,
|
|
||||||
transitionsBuilder: (
|
|
||||||
BuildContext context,
|
|
||||||
Animation<double> animation,
|
|
||||||
Animation<double> secondaryAnimation,
|
|
||||||
Widget child,
|
|
||||||
) =>
|
|
||||||
FadeTransition(
|
|
||||||
opacity: animation,
|
|
||||||
child: child,
|
|
||||||
),
|
),
|
||||||
);
|
VWidget(
|
||||||
|
path: '/rooms',
|
||||||
|
widget: TwoColumnLayout(
|
||||||
|
mainView: ChatList(),
|
||||||
|
sideView: EmptyPage(),
|
||||||
|
),
|
||||||
|
buildTransition: _fadeTransition,
|
||||||
|
stackedRoutes: [
|
||||||
|
_settingsRoute,
|
||||||
|
VWidget(
|
||||||
|
path: '/search',
|
||||||
|
widget: TwoColumnLayout(
|
||||||
|
mainView: Search(),
|
||||||
|
sideView: EmptyPage(),
|
||||||
|
),
|
||||||
|
buildTransition: _fadeTransition,
|
||||||
|
),
|
||||||
|
VWidget(
|
||||||
|
path: '/archive',
|
||||||
|
widget: TwoColumnLayout(
|
||||||
|
mainView: Archive(),
|
||||||
|
sideView: EmptyPage(),
|
||||||
|
),
|
||||||
|
buildTransition: _fadeTransition,
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
},
|
||||||
|
if (columns == 1)
|
||||||
|
VWidget(
|
||||||
|
path: '/rooms',
|
||||||
|
widget: ChatList(),
|
||||||
|
stackedRoutes: [
|
||||||
|
VWidget(path: ':roomid', widget: Chat(), stackedRoutes: [
|
||||||
|
VWidget(
|
||||||
|
path: 'encryption',
|
||||||
|
widget: ChatEncryptionSettings(),
|
||||||
|
),
|
||||||
|
VWidget(
|
||||||
|
path: 'invite',
|
||||||
|
widget: InvitationSelection(),
|
||||||
|
),
|
||||||
|
VWidget(
|
||||||
|
path: 'details',
|
||||||
|
widget: ChatDetails(),
|
||||||
|
stackedRoutes: _chatDetailsRoutes,
|
||||||
|
),
|
||||||
|
]),
|
||||||
|
_settingsRoute,
|
||||||
|
VWidget(
|
||||||
|
path: '/search',
|
||||||
|
widget: Search(),
|
||||||
|
),
|
||||||
|
VWidget(
|
||||||
|
path: '/archive',
|
||||||
|
widget: Archive(),
|
||||||
|
),
|
||||||
|
VWidget(
|
||||||
|
path: '/newprivatechat',
|
||||||
|
widget: NewPrivateChat(),
|
||||||
|
),
|
||||||
|
VWidget(
|
||||||
|
path: '/newgroup',
|
||||||
|
widget: NewGroup(),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
];
|
||||||
|
|
||||||
|
List<VRouteElement> get _chatDetailsRoutes => [
|
||||||
|
VWidget(
|
||||||
|
path: 'permissions',
|
||||||
|
widget: ChatPermissionsSettings(),
|
||||||
|
buildTransition: _dynamicTransition,
|
||||||
|
),
|
||||||
|
VWidget(
|
||||||
|
path: 'invite',
|
||||||
|
widget: InvitationSelection(),
|
||||||
|
buildTransition: _dynamicTransition,
|
||||||
|
),
|
||||||
|
VWidget(
|
||||||
|
path: 'emotes',
|
||||||
|
widget: MultipleEmotesSettings(),
|
||||||
|
buildTransition: _dynamicTransition,
|
||||||
|
),
|
||||||
|
];
|
||||||
|
|
||||||
|
VNester get _settingsRoute => VNester(
|
||||||
|
path: '/settings',
|
||||||
|
widgetBuilder: (child) => TwoColumnLayout(
|
||||||
|
mainView: Settings(),
|
||||||
|
sideView: child,
|
||||||
|
),
|
||||||
|
buildTransition: _dynamicTransition,
|
||||||
|
nestedRoutes: [
|
||||||
|
VWidget(
|
||||||
|
path: '',
|
||||||
|
widget: EmptyPage(),
|
||||||
|
buildTransition: _dynamicTransition,
|
||||||
|
stackedRoutes: [
|
||||||
|
VWidget(
|
||||||
|
path: 'emotes',
|
||||||
|
widget: EmotesSettings(),
|
||||||
|
buildTransition: _dynamicTransition,
|
||||||
|
),
|
||||||
|
VWidget(
|
||||||
|
path: 'notifications',
|
||||||
|
widget: SettingsNotifications(),
|
||||||
|
buildTransition: _dynamicTransition,
|
||||||
|
),
|
||||||
|
VWidget(
|
||||||
|
path: 'ignorelist',
|
||||||
|
widget: SettingsIgnoreList(),
|
||||||
|
buildTransition: _dynamicTransition,
|
||||||
|
),
|
||||||
|
VWidget(
|
||||||
|
path: 'style',
|
||||||
|
widget: SettingsStyle(),
|
||||||
|
buildTransition: _dynamicTransition,
|
||||||
|
),
|
||||||
|
VWidget(
|
||||||
|
path: 'devices',
|
||||||
|
widget: DevicesSettings(),
|
||||||
|
buildTransition: _dynamicTransition,
|
||||||
|
),
|
||||||
|
VWidget(
|
||||||
|
path: '/logs',
|
||||||
|
widget: LogViewer(),
|
||||||
|
buildTransition: _dynamicTransition,
|
||||||
|
),
|
||||||
|
VWidget(
|
||||||
|
path: '3pid',
|
||||||
|
widget: Settings3Pid(),
|
||||||
|
buildTransition: _dynamicTransition,
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
|
||||||
|
final _fadeTransition = (animation1, _, child) =>
|
||||||
|
FadeTransition(opacity: animation1, child: child);
|
||||||
|
|
||||||
|
FadeTransition Function(dynamic, dynamic, dynamic) get _dynamicTransition =>
|
||||||
|
columns > 1 ? _fadeTransition : null;
|
||||||
}
|
}
|
||||||
|
104
lib/main.dart
104
lib/main.dart
@ -2,7 +2,6 @@
|
|||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
|
|
||||||
import 'package:adaptive_theme/adaptive_theme.dart';
|
import 'package:adaptive_theme/adaptive_theme.dart';
|
||||||
import 'package:adaptive_page_layout/adaptive_page_layout.dart';
|
|
||||||
import 'package:famedlysdk/famedlysdk.dart';
|
import 'package:famedlysdk/famedlysdk.dart';
|
||||||
import 'package:fluffychat/config/routes.dart';
|
import 'package:fluffychat/config/routes.dart';
|
||||||
import 'package:fluffychat/utils/platform_infos.dart';
|
import 'package:fluffychat/utils/platform_infos.dart';
|
||||||
@ -10,10 +9,12 @@ import 'package:fluffychat/utils/sentry_controller.dart';
|
|||||||
import 'package:flutter/cupertino.dart';
|
import 'package:flutter/cupertino.dart';
|
||||||
import 'package:flutter/foundation.dart';
|
import 'package:flutter/foundation.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter/services.dart';
|
import 'utils/localized_exception_extension.dart';
|
||||||
import 'package:flutter_app_lock/flutter_app_lock.dart';
|
import 'package:flutter_app_lock/flutter_app_lock.dart';
|
||||||
import 'package:flutter_gen/gen_l10n/l10n.dart';
|
import 'package:flutter_gen/gen_l10n/l10n.dart';
|
||||||
|
import 'package:future_loading_dialog/future_loading_dialog.dart';
|
||||||
import 'package:universal_html/html.dart' as html;
|
import 'package:universal_html/html.dart' as html;
|
||||||
|
import 'package:vrouter/vrouter.dart';
|
||||||
|
|
||||||
import 'widgets/lock_screen.dart';
|
import 'widgets/lock_screen.dart';
|
||||||
import 'widgets/matrix.dart';
|
import 'widgets/matrix.dart';
|
||||||
@ -47,11 +48,9 @@ void main() async {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
class FluffyChatApp extends StatelessWidget {
|
class FluffyChatApp extends StatefulWidget {
|
||||||
final Widget testWidget;
|
final Widget testWidget;
|
||||||
final Client testClient;
|
final Client testClient;
|
||||||
static final GlobalKey<AdaptivePageLayoutState> _apl =
|
|
||||||
GlobalKey<AdaptivePageLayoutState>();
|
|
||||||
|
|
||||||
const FluffyChatApp({Key key, this.testWidget, this.testClient})
|
const FluffyChatApp({Key key, this.testWidget, this.testClient})
|
||||||
: super(key: key);
|
: super(key: key);
|
||||||
@ -61,60 +60,59 @@ class FluffyChatApp extends StatelessWidget {
|
|||||||
/// in with qr code or magic link.
|
/// in with qr code or magic link.
|
||||||
static bool gotInitialLink = false;
|
static bool gotInitialLink = false;
|
||||||
|
|
||||||
|
@override
|
||||||
|
_FluffyChatAppState createState() => _FluffyChatAppState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _FluffyChatAppState extends State<FluffyChatApp> {
|
||||||
|
GlobalKey<VRouterState> _router;
|
||||||
|
int columns;
|
||||||
|
String _initialUrl = '/';
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return AdaptiveTheme(
|
return AdaptiveTheme(
|
||||||
light: FluffyThemes.light,
|
light: FluffyThemes.light,
|
||||||
dark: FluffyThemes.dark,
|
dark: FluffyThemes.dark,
|
||||||
initial: AdaptiveThemeMode.system,
|
initial: AdaptiveThemeMode.system,
|
||||||
builder: (theme, darkTheme) => MaterialApp(
|
builder: (theme, darkTheme) => Matrix(
|
||||||
title: '${AppConfig.applicationName}',
|
context: context,
|
||||||
theme: theme,
|
router: _router,
|
||||||
darkTheme: darkTheme,
|
testClient: widget.testClient,
|
||||||
localizationsDelegates: L10n.localizationsDelegates,
|
child: LayoutBuilder(
|
||||||
supportedLocales: L10n.supportedLocales,
|
builder: (context, constraints) {
|
||||||
locale: kIsWeb
|
var newColumns =
|
||||||
? Locale(html.window.navigator.language.split('-').first)
|
(constraints.maxWidth / AppConfig.columnWidth).floor();
|
||||||
: null,
|
if (newColumns > 3) newColumns = 3;
|
||||||
home: Builder(
|
columns ??= newColumns;
|
||||||
builder: (context) {
|
_router ??= GlobalKey<VRouterState>();
|
||||||
WidgetsBinding.instance.addPostFrameCallback((_) {
|
if (columns != newColumns) {
|
||||||
SystemChrome.setSystemUIOverlayStyle(
|
WidgetsBinding.instance.addPostFrameCallback((_) {
|
||||||
SystemUiOverlayStyle(
|
setState(() {
|
||||||
statusBarColor: Colors.transparent,
|
_initialUrl = _router.currentState.url;
|
||||||
systemNavigationBarColor: Theme.of(context).backgroundColor,
|
columns = newColumns;
|
||||||
systemNavigationBarIconBrightness:
|
_router = GlobalKey<VRouterState>();
|
||||||
Theme.of(context).brightness == Brightness.light
|
});
|
||||||
? Brightness.dark
|
});
|
||||||
: Brightness.light,
|
}
|
||||||
),
|
return VRouter(
|
||||||
);
|
key: _router,
|
||||||
});
|
title: '${AppConfig.applicationName}',
|
||||||
return Matrix(
|
theme: theme,
|
||||||
context: context,
|
darkTheme: darkTheme,
|
||||||
apl: _apl,
|
localizationsDelegates: L10n.localizationsDelegates,
|
||||||
testClient: testClient,
|
supportedLocales: L10n.supportedLocales,
|
||||||
child: Builder(
|
initialUrl: _initialUrl,
|
||||||
builder: (context) => AdaptivePageLayout(
|
locale: kIsWeb
|
||||||
key: _apl,
|
? Locale(html.window.navigator.language.split('-').first)
|
||||||
safeAreaOnColumnView: false,
|
: null,
|
||||||
onGenerateRoute: testWidget == null
|
routes: AppRoutes(columns).routes,
|
||||||
? FluffyRoutes(context).onGenerateRoute
|
builder: (context, child) {
|
||||||
: (_) => ViewData(mainView: (_) => testWidget),
|
LoadingDialog.defaultTitle = L10n.of(context).loadingPleaseWait;
|
||||||
dividerColor: Theme.of(context).dividerColor,
|
LoadingDialog.defaultBackLabel = L10n.of(context).close;
|
||||||
columnWidth: FluffyThemes.columnWidth,
|
LoadingDialog.defaultOnError =
|
||||||
dividerWidth: 1.0,
|
(Object e) => e.toLocalizedString(context);
|
||||||
routeBuilder: (builder, settings) =>
|
return child;
|
||||||
Matrix.of(context).loginState == LoginState.logged &&
|
},
|
||||||
!{
|
|
||||||
'/',
|
|
||||||
'/search',
|
|
||||||
'/contacts',
|
|
||||||
}.contains(settings.name)
|
|
||||||
? MaterialPageRoute(builder: builder)
|
|
||||||
: FadeRoute(page: builder(context)),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
|
@ -28,7 +28,7 @@ class ArchiveController extends State<Archive> {
|
|||||||
okLabel: L10n.of(context).yes,
|
okLabel: L10n.of(context).yes,
|
||||||
cancelLabel: L10n.of(context).cancel,
|
cancelLabel: L10n.of(context).cancel,
|
||||||
message: L10n.of(context).clearArchive,
|
message: L10n.of(context).clearArchive,
|
||||||
useRootNavigator: false,
|
|
||||||
) !=
|
) !=
|
||||||
OkCancelResult.ok) {
|
OkCancelResult.ok) {
|
||||||
return;
|
return;
|
||||||
|
@ -25,13 +25,11 @@ class BootstrapDialog extends StatefulWidget {
|
|||||||
? showCupertinoDialog(
|
? showCupertinoDialog(
|
||||||
context: context,
|
context: context,
|
||||||
builder: (context) => this,
|
builder: (context) => this,
|
||||||
useRootNavigator: false,
|
|
||||||
barrierDismissible: true,
|
barrierDismissible: true,
|
||||||
)
|
)
|
||||||
: showDialog(
|
: showDialog(
|
||||||
context: context,
|
context: context,
|
||||||
builder: (context) => this,
|
builder: (context) => this,
|
||||||
useRootNavigator: false,
|
|
||||||
barrierDismissible: true,
|
barrierDismissible: true,
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -196,7 +194,6 @@ class _BootstrapDialogState extends State<BootstrapDialog> {
|
|||||||
if (OkCancelResult.ok ==
|
if (OkCancelResult.ok ==
|
||||||
await showOkCancelAlertDialog(
|
await showOkCancelAlertDialog(
|
||||||
context: context,
|
context: context,
|
||||||
useRootNavigator: false,
|
|
||||||
title: L10n.of(context).securityKeyLost,
|
title: L10n.of(context).securityKeyLost,
|
||||||
message: L10n.of(context).wipeChatBackup,
|
message: L10n.of(context).wipeChatBackup,
|
||||||
okLabel: L10n.of(context).ok,
|
okLabel: L10n.of(context).ok,
|
||||||
|
@ -2,7 +2,7 @@ import 'dart:async';
|
|||||||
import 'dart:io';
|
import 'dart:io';
|
||||||
|
|
||||||
import 'package:adaptive_dialog/adaptive_dialog.dart';
|
import 'package:adaptive_dialog/adaptive_dialog.dart';
|
||||||
import 'package:adaptive_page_layout/adaptive_page_layout.dart';
|
|
||||||
import 'package:famedlysdk/famedlysdk.dart';
|
import 'package:famedlysdk/famedlysdk.dart';
|
||||||
import 'package:file_picker_cross/file_picker_cross.dart';
|
import 'package:file_picker_cross/file_picker_cross.dart';
|
||||||
import 'package:fluffychat/config/app_config.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:permission_handler/permission_handler.dart';
|
||||||
import 'package:scroll_to_index/scroll_to_index.dart';
|
import 'package:scroll_to_index/scroll_to_index.dart';
|
||||||
import 'package:url_launcher/url_launcher.dart';
|
import 'package:url_launcher/url_launcher.dart';
|
||||||
|
import 'package:vrouter/vrouter.dart';
|
||||||
|
|
||||||
import 'send_file_dialog.dart';
|
import 'send_file_dialog.dart';
|
||||||
import '../utils/matrix_sdk_extensions.dart/filtered_timeline_extension.dart';
|
import '../utils/matrix_sdk_extensions.dart/filtered_timeline_extension.dart';
|
||||||
import '../utils/matrix_sdk_extensions.dart/matrix_file_extension.dart';
|
import '../utils/matrix_sdk_extensions.dart/matrix_file_extension.dart';
|
||||||
|
|
||||||
class Chat extends StatefulWidget {
|
class Chat extends StatefulWidget {
|
||||||
final String id;
|
final Widget sideView;
|
||||||
final String scrollToEventId;
|
|
||||||
|
|
||||||
Chat(this.id, {Key key, this.scrollToEventId})
|
Chat({Key key, this.sideView}) : super(key: key);
|
||||||
: super(key: key ?? Key('chatroom-$id'));
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
ChatController createState() => ChatController();
|
ChatController createState() => ChatController();
|
||||||
@ -46,6 +45,8 @@ class ChatController extends State<Chat> {
|
|||||||
|
|
||||||
MatrixState matrix;
|
MatrixState matrix;
|
||||||
|
|
||||||
|
String get roomId => context.vRouter.pathParameters['roomid'];
|
||||||
|
|
||||||
final AutoScrollController scrollController = AutoScrollController();
|
final AutoScrollController scrollController = AutoScrollController();
|
||||||
|
|
||||||
FocusNode inputFocus = FocusNode();
|
FocusNode inputFocus = FocusNode();
|
||||||
@ -97,7 +98,7 @@ class ChatController extends State<Chat> {
|
|||||||
try {
|
try {
|
||||||
await timeline.requestHistory(historyCount: _loadHistoryCount);
|
await timeline.requestHistory(historyCount: _loadHistoryCount);
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
AdaptivePageLayout.of(context).showSnackBar(
|
ScaffoldMessenger.of(context).showSnackBar(
|
||||||
SnackBar(content: Text(err.toLocalizedString(context))));
|
SnackBar(content: Text(err.toLocalizedString(context))));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -167,8 +168,9 @@ class ChatController extends State<Chat> {
|
|||||||
// "load more" button is visible on the screen
|
// "load more" button is visible on the screen
|
||||||
SchedulerBinding.instance.addPostFrameCallback((_) async {
|
SchedulerBinding.instance.addPostFrameCallback((_) async {
|
||||||
if (mounted) {
|
if (mounted) {
|
||||||
if (widget.scrollToEventId != null) {
|
final event = VRouter.of(context).queryParameters['event'];
|
||||||
scrollToEventId(widget.scrollToEventId);
|
if (event != null) {
|
||||||
|
scrollToEventId(event);
|
||||||
}
|
}
|
||||||
_updateScrollController();
|
_updateScrollController();
|
||||||
}
|
}
|
||||||
@ -231,7 +233,6 @@ class ChatController extends State<Chat> {
|
|||||||
if (result == null) return;
|
if (result == null) return;
|
||||||
await showDialog(
|
await showDialog(
|
||||||
context: context,
|
context: context,
|
||||||
useRootNavigator: false,
|
|
||||||
builder: (c) => SendFileDialog(
|
builder: (c) => SendFileDialog(
|
||||||
file: MatrixFile(
|
file: MatrixFile(
|
||||||
bytes: result.toUint8List(),
|
bytes: result.toUint8List(),
|
||||||
@ -248,7 +249,6 @@ class ChatController extends State<Chat> {
|
|||||||
if (result == null) return;
|
if (result == null) return;
|
||||||
await showDialog(
|
await showDialog(
|
||||||
context: context,
|
context: context,
|
||||||
useRootNavigator: false,
|
|
||||||
builder: (c) => SendFileDialog(
|
builder: (c) => SendFileDialog(
|
||||||
file: MatrixImageFile(
|
file: MatrixImageFile(
|
||||||
bytes: result.toUint8List(),
|
bytes: result.toUint8List(),
|
||||||
@ -265,7 +265,6 @@ class ChatController extends State<Chat> {
|
|||||||
final bytes = await file.readAsBytes();
|
final bytes = await file.readAsBytes();
|
||||||
await showDialog(
|
await showDialog(
|
||||||
context: context,
|
context: context,
|
||||||
useRootNavigator: false,
|
|
||||||
builder: (c) => SendFileDialog(
|
builder: (c) => SendFileDialog(
|
||||||
file: MatrixImageFile(
|
file: MatrixImageFile(
|
||||||
bytes: bytes,
|
bytes: bytes,
|
||||||
@ -284,7 +283,6 @@ class ChatController extends State<Chat> {
|
|||||||
final result = await showDialog<String>(
|
final result = await showDialog<String>(
|
||||||
context: context,
|
context: context,
|
||||||
builder: (c) => RecordingDialog(),
|
builder: (c) => RecordingDialog(),
|
||||||
useRootNavigator: false,
|
|
||||||
);
|
);
|
||||||
if (result == null) return;
|
if (result == null) return;
|
||||||
final audioFile = File(result);
|
final audioFile = File(result);
|
||||||
@ -325,7 +323,6 @@ class ChatController extends State<Chat> {
|
|||||||
final score = await showConfirmationDialog<int>(
|
final score = await showConfirmationDialog<int>(
|
||||||
context: context,
|
context: context,
|
||||||
title: L10n.of(context).howOffensiveIsThisContent,
|
title: L10n.of(context).howOffensiveIsThisContent,
|
||||||
useRootNavigator: false,
|
|
||||||
actions: [
|
actions: [
|
||||||
AlertDialogAction(
|
AlertDialogAction(
|
||||||
key: -100,
|
key: -100,
|
||||||
@ -346,7 +343,6 @@ class ChatController extends State<Chat> {
|
|||||||
title: L10n.of(context).whyDoYouWantToReportThis,
|
title: L10n.of(context).whyDoYouWantToReportThis,
|
||||||
okLabel: L10n.of(context).ok,
|
okLabel: L10n.of(context).ok,
|
||||||
cancelLabel: L10n.of(context).cancel,
|
cancelLabel: L10n.of(context).cancel,
|
||||||
useRootNavigator: false,
|
|
||||||
textFields: [DialogTextField(hintText: L10n.of(context).reason)]);
|
textFields: [DialogTextField(hintText: L10n.of(context).reason)]);
|
||||||
if (reason == null || reason.single.isEmpty) return;
|
if (reason == null || reason.single.isEmpty) return;
|
||||||
final result = await showFutureLoadingDialog(
|
final result = await showFutureLoadingDialog(
|
||||||
@ -360,7 +356,7 @@ class ChatController extends State<Chat> {
|
|||||||
);
|
);
|
||||||
if (result.error != null) return;
|
if (result.error != null) return;
|
||||||
setState(() => selectedEvents.clear());
|
setState(() => selectedEvents.clear());
|
||||||
AdaptivePageLayout.of(context).showSnackBar(
|
ScaffoldMessenger.of(context).showSnackBar(
|
||||||
SnackBar(content: Text(L10n.of(context).contentHasBeenReported)));
|
SnackBar(content: Text(L10n.of(context).contentHasBeenReported)));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -370,7 +366,6 @@ class ChatController extends State<Chat> {
|
|||||||
title: L10n.of(context).messageWillBeRemovedWarning,
|
title: L10n.of(context).messageWillBeRemovedWarning,
|
||||||
okLabel: L10n.of(context).remove,
|
okLabel: L10n.of(context).remove,
|
||||||
cancelLabel: L10n.of(context).cancel,
|
cancelLabel: L10n.of(context).cancel,
|
||||||
useRootNavigator: false,
|
|
||||||
) ==
|
) ==
|
||||||
OkCancelResult.ok;
|
OkCancelResult.ok;
|
||||||
if (!confirmed) return;
|
if (!confirmed) return;
|
||||||
@ -400,7 +395,7 @@ class ChatController extends State<Chat> {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
setState(() => selectedEvents.clear());
|
setState(() => selectedEvents.clear());
|
||||||
AdaptivePageLayout.of(context).popUntilIsFirst();
|
VRouter.of(context).push('/rooms');
|
||||||
}
|
}
|
||||||
|
|
||||||
void sendAgainAction() {
|
void sendAgainAction() {
|
||||||
@ -566,8 +561,7 @@ class ChatController extends State<Chat> {
|
|||||||
future: room.leave,
|
future: room.leave,
|
||||||
);
|
);
|
||||||
if (result.error == null) {
|
if (result.error == null) {
|
||||||
await AdaptivePageLayout.of(context)
|
VRouter.of(context).push('/rooms/${result.result}');
|
||||||
.pushNamedAndRemoveUntilIsFirst('/rooms/${result.result}');
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -653,5 +647,29 @@ class ChatController extends State<Chat> {
|
|||||||
});
|
});
|
||||||
|
|
||||||
@override
|
@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,
|
||||||
|
),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,4 @@
|
|||||||
import 'package:adaptive_dialog/adaptive_dialog.dart';
|
import 'package:adaptive_dialog/adaptive_dialog.dart';
|
||||||
import 'package:adaptive_page_layout/adaptive_page_layout.dart';
|
|
||||||
|
|
||||||
import 'package:famedlysdk/famedlysdk.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/material.dart';
|
||||||
import 'package:flutter_gen/gen_l10n/l10n.dart';
|
import 'package:flutter_gen/gen_l10n/l10n.dart';
|
||||||
import 'package:image_picker/image_picker.dart';
|
import 'package:image_picker/image_picker.dart';
|
||||||
|
import 'package:vrouter/vrouter.dart';
|
||||||
|
|
||||||
enum AliasActions { copy, delete, setCanonical }
|
enum AliasActions { copy, delete, setCanonical }
|
||||||
|
|
||||||
class ChatDetails extends StatefulWidget {
|
class ChatDetails extends StatefulWidget {
|
||||||
final String roomId;
|
const ChatDetails();
|
||||||
|
|
||||||
const ChatDetails(this.roomId);
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
ChatDetailsController createState() => ChatDetailsController();
|
ChatDetailsController createState() => ChatDetailsController();
|
||||||
@ -28,21 +26,16 @@ class ChatDetails extends StatefulWidget {
|
|||||||
class ChatDetailsController extends State<ChatDetails> {
|
class ChatDetailsController extends State<ChatDetails> {
|
||||||
List<User> members;
|
List<User> members;
|
||||||
|
|
||||||
@override
|
String get roomId => VRouter.of(context).pathParameters['roomid'];
|
||||||
void initState() {
|
|
||||||
super.initState();
|
|
||||||
members ??=
|
|
||||||
Matrix.of(context).client.getRoomById(widget.roomId).getParticipants();
|
|
||||||
}
|
|
||||||
|
|
||||||
void setDisplaynameAction() async {
|
void setDisplaynameAction() async {
|
||||||
final room = Matrix.of(context).client.getRoomById(widget.roomId);
|
final room = Matrix.of(context).client.getRoomById(roomId);
|
||||||
final input = await showTextInputDialog(
|
final input = await showTextInputDialog(
|
||||||
context: context,
|
context: context,
|
||||||
title: L10n.of(context).changeTheNameOfTheGroup,
|
title: L10n.of(context).changeTheNameOfTheGroup,
|
||||||
okLabel: L10n.of(context).ok,
|
okLabel: L10n.of(context).ok,
|
||||||
cancelLabel: L10n.of(context).cancel,
|
cancelLabel: L10n.of(context).cancel,
|
||||||
useRootNavigator: false,
|
|
||||||
textFields: [
|
textFields: [
|
||||||
DialogTextField(
|
DialogTextField(
|
||||||
initialText: room.getLocalizedDisplayname(
|
initialText: room.getLocalizedDisplayname(
|
||||||
@ -59,13 +52,13 @@ class ChatDetailsController extends State<ChatDetails> {
|
|||||||
future: () => room.setName(input.single),
|
future: () => room.setName(input.single),
|
||||||
);
|
);
|
||||||
if (success.error == null) {
|
if (success.error == null) {
|
||||||
AdaptivePageLayout.of(context).showSnackBar(
|
ScaffoldMessenger.of(context).showSnackBar(
|
||||||
SnackBar(content: Text(L10n.of(context).displaynameHasBeenChanged)));
|
SnackBar(content: Text(L10n.of(context).displaynameHasBeenChanged)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void editAliases() async {
|
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
|
// 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:
|
// 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) {
|
switch (option) {
|
||||||
case AliasActions.copy:
|
case AliasActions.copy:
|
||||||
await Clipboard.setData(ClipboardData(text: select));
|
await Clipboard.setData(ClipboardData(text: select));
|
||||||
AdaptivePageLayout.of(context).showSnackBar(
|
ScaffoldMessenger.of(context).showSnackBar(
|
||||||
SnackBar(content: Text(L10n.of(context).copiedToClipboard)),
|
SnackBar(content: Text(L10n.of(context).copiedToClipboard)),
|
||||||
);
|
);
|
||||||
break;
|
break;
|
||||||
@ -159,7 +152,7 @@ class ChatDetailsController extends State<ChatDetails> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void setAliasAction() async {
|
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 domain = room.client.userID.domain;
|
||||||
|
|
||||||
final input = await showTextInputDialog(
|
final input = await showTextInputDialog(
|
||||||
@ -167,7 +160,7 @@ class ChatDetailsController extends State<ChatDetails> {
|
|||||||
title: L10n.of(context).setInvitationLink,
|
title: L10n.of(context).setInvitationLink,
|
||||||
okLabel: L10n.of(context).ok,
|
okLabel: L10n.of(context).ok,
|
||||||
cancelLabel: L10n.of(context).cancel,
|
cancelLabel: L10n.of(context).cancel,
|
||||||
useRootNavigator: false,
|
|
||||||
textFields: [
|
textFields: [
|
||||||
DialogTextField(
|
DialogTextField(
|
||||||
prefixText: '#',
|
prefixText: '#',
|
||||||
@ -186,13 +179,13 @@ class ChatDetailsController extends State<ChatDetails> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void setTopicAction() async {
|
void setTopicAction() async {
|
||||||
final room = Matrix.of(context).client.getRoomById(widget.roomId);
|
final room = Matrix.of(context).client.getRoomById(roomId);
|
||||||
final input = await showTextInputDialog(
|
final input = await showTextInputDialog(
|
||||||
context: context,
|
context: context,
|
||||||
title: L10n.of(context).setGroupDescription,
|
title: L10n.of(context).setGroupDescription,
|
||||||
okLabel: L10n.of(context).ok,
|
okLabel: L10n.of(context).ok,
|
||||||
cancelLabel: L10n.of(context).cancel,
|
cancelLabel: L10n.of(context).cancel,
|
||||||
useRootNavigator: false,
|
|
||||||
textFields: [
|
textFields: [
|
||||||
DialogTextField(
|
DialogTextField(
|
||||||
hintText: L10n.of(context).setGroupDescription,
|
hintText: L10n.of(context).setGroupDescription,
|
||||||
@ -208,7 +201,7 @@ class ChatDetailsController extends State<ChatDetails> {
|
|||||||
future: () => room.setDescription(input.single),
|
future: () => room.setDescription(input.single),
|
||||||
);
|
);
|
||||||
if (success.error == null) {
|
if (success.error == null) {
|
||||||
AdaptivePageLayout.of(context).showSnackBar(SnackBar(
|
ScaffoldMessenger.of(context).showSnackBar(SnackBar(
|
||||||
content: Text(L10n.of(context).groupDescriptionHasBeenChanged)));
|
content: Text(L10n.of(context).groupDescriptionHasBeenChanged)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -217,7 +210,7 @@ class ChatDetailsController extends State<ChatDetails> {
|
|||||||
context: context,
|
context: context,
|
||||||
future: () => Matrix.of(context)
|
future: () => Matrix.of(context)
|
||||||
.client
|
.client
|
||||||
.getRoomById(widget.roomId)
|
.getRoomById(roomId)
|
||||||
.setGuestAccess(guestAccess),
|
.setGuestAccess(guestAccess),
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -226,7 +219,7 @@ class ChatDetailsController extends State<ChatDetails> {
|
|||||||
context: context,
|
context: context,
|
||||||
future: () => Matrix.of(context)
|
future: () => Matrix.of(context)
|
||||||
.client
|
.client
|
||||||
.getRoomById(widget.roomId)
|
.getRoomById(roomId)
|
||||||
.setHistoryVisibility(historyVisibility),
|
.setHistoryVisibility(historyVisibility),
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -234,23 +227,21 @@ class ChatDetailsController extends State<ChatDetails> {
|
|||||||
context: context,
|
context: context,
|
||||||
future: () => Matrix.of(context)
|
future: () => Matrix.of(context)
|
||||||
.client
|
.client
|
||||||
.getRoomById(widget.roomId)
|
.getRoomById(roomId)
|
||||||
.setJoinRules(joinRule),
|
.setJoinRules(joinRule),
|
||||||
);
|
);
|
||||||
|
|
||||||
void goToEmoteSettings() async {
|
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
|
// 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
|
// 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.
|
// otherwise, we just open the normal one.
|
||||||
if ((room.states['im.ponies.room_emotes'] ?? <String, Event>{})
|
if ((room.states['im.ponies.room_emotes'] ?? <String, Event>{})
|
||||||
.keys
|
.keys
|
||||||
.any((String s) => s.isNotEmpty)) {
|
.any((String s) => s.isNotEmpty)) {
|
||||||
await AdaptivePageLayout.of(context)
|
VRouter.of(context).pushNamed('/rooms/${room.id}/emotes');
|
||||||
.pushNamed('/rooms/${room.id}/emotes');
|
|
||||||
} else {
|
} else {
|
||||||
await AdaptivePageLayout.of(context)
|
VRouter.of(context).pushNamed('/settings/emotes');
|
||||||
.pushNamed('/settings/emotes', arguments: {'room': room});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -277,20 +268,20 @@ class ChatDetailsController extends State<ChatDetails> {
|
|||||||
name: result.fileName,
|
name: result.fileName,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
final room = Matrix.of(context).client.getRoomById(widget.roomId);
|
final room = Matrix.of(context).client.getRoomById(roomId);
|
||||||
|
|
||||||
final success = await showFutureLoadingDialog(
|
final success = await showFutureLoadingDialog(
|
||||||
context: context,
|
context: context,
|
||||||
future: () => room.setAvatar(file),
|
future: () => room.setAvatar(file),
|
||||||
);
|
);
|
||||||
if (success.error == null) {
|
if (success.error == null) {
|
||||||
AdaptivePageLayout.of(context).showSnackBar(
|
ScaffoldMessenger.of(context).showSnackBar(
|
||||||
SnackBar(content: Text(L10n.of(context).avatarHasBeenChanged)));
|
SnackBar(content: Text(L10n.of(context).avatarHasBeenChanged)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void requestMoreMembersAction() async {
|
void requestMoreMembersAction() async {
|
||||||
final room = Matrix.of(context).client.getRoomById(widget.roomId);
|
final room = Matrix.of(context).client.getRoomById(roomId);
|
||||||
final participants = await showFutureLoadingDialog(
|
final participants = await showFutureLoadingDialog(
|
||||||
context: context, future: () => room.requestParticipants());
|
context: context, future: () => room.requestParticipants());
|
||||||
if (participants.error == null) {
|
if (participants.error == null) {
|
||||||
@ -299,5 +290,11 @@ class ChatDetailsController extends State<ChatDetails> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@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),
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -3,12 +3,11 @@ import 'package:famedlysdk/famedlysdk.dart';
|
|||||||
import 'package:fluffychat/pages/views/chat_encryption_settings_view.dart';
|
import 'package:fluffychat/pages/views/chat_encryption_settings_view.dart';
|
||||||
import 'package:fluffychat/widgets/matrix.dart';
|
import 'package:fluffychat/widgets/matrix.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:vrouter/vrouter.dart';
|
||||||
import 'key_verification_dialog.dart';
|
import 'key_verification_dialog.dart';
|
||||||
|
|
||||||
class ChatEncryptionSettings extends StatefulWidget {
|
class ChatEncryptionSettings extends StatefulWidget {
|
||||||
final String id;
|
const ChatEncryptionSettings({Key key}) : super(key: key);
|
||||||
|
|
||||||
const ChatEncryptionSettings(this.id, {Key key}) : super(key: key);
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
ChatEncryptionSettingsController createState() =>
|
ChatEncryptionSettingsController createState() =>
|
||||||
@ -16,9 +15,10 @@ class ChatEncryptionSettings extends StatefulWidget {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class ChatEncryptionSettingsController extends State<ChatEncryptionSettings> {
|
class ChatEncryptionSettingsController extends State<ChatEncryptionSettings> {
|
||||||
|
String get roomId => VRouter.of(context).pathParameters['roomid'];
|
||||||
Future<void> onSelected(
|
Future<void> onSelected(
|
||||||
BuildContext context, String action, DeviceKeys key) async {
|
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 {
|
final unblock = () async {
|
||||||
if (key.blocked) {
|
if (key.blocked) {
|
||||||
await key.setBlocked(false);
|
await key.setBlocked(false);
|
||||||
|
@ -2,7 +2,7 @@ import 'dart:async';
|
|||||||
import 'dart:io';
|
import 'dart:io';
|
||||||
|
|
||||||
import 'package:adaptive_dialog/adaptive_dialog.dart';
|
import 'package:adaptive_dialog/adaptive_dialog.dart';
|
||||||
import 'package:adaptive_page_layout/adaptive_page_layout.dart';
|
|
||||||
import 'package:famedlysdk/famedlysdk.dart';
|
import 'package:famedlysdk/famedlysdk.dart';
|
||||||
import 'package:fluffychat/utils/fluffy_share.dart';
|
import 'package:fluffychat/utils/fluffy_share.dart';
|
||||||
import 'package:fluffychat/pages/views/chat_list_view.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:future_loading_dialog/future_loading_dialog.dart';
|
||||||
import 'package:receive_sharing_intent/receive_sharing_intent.dart';
|
import 'package:receive_sharing_intent/receive_sharing_intent.dart';
|
||||||
import 'package:uni_links/uni_links.dart';
|
import 'package:uni_links/uni_links.dart';
|
||||||
|
import 'package:vrouter/vrouter.dart';
|
||||||
import '../main.dart';
|
import '../main.dart';
|
||||||
import '../widgets/matrix.dart';
|
import '../widgets/matrix.dart';
|
||||||
import '../utils/matrix_sdk_extensions.dart/matrix_file_extension.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) {
|
void _processIncomingSharedFiles(List<SharedMediaFile> files) {
|
||||||
if (files?.isEmpty ?? true) return;
|
if (files?.isEmpty ?? true) return;
|
||||||
AdaptivePageLayout.of(context).popUntilIsFirst();
|
VRouter.of(context).push('/rooms');
|
||||||
final file = File(files.first.path);
|
final file = File(files.first.path);
|
||||||
|
|
||||||
Matrix.of(context).shareContent = {
|
Matrix.of(context).shareContent = {
|
||||||
@ -57,7 +58,7 @@ class ChatListController extends State<ChatList> {
|
|||||||
|
|
||||||
void _processIncomingSharedText(String text) {
|
void _processIncomingSharedText(String text) {
|
||||||
if (text == null) return;
|
if (text == null) return;
|
||||||
AdaptivePageLayout.of(context).popUntilIsFirst();
|
VRouter.of(context).push('/rooms');
|
||||||
if (text.toLowerCase().startsWith(AppConfig.inviteLinkPrefix) ||
|
if (text.toLowerCase().startsWith(AppConfig.inviteLinkPrefix) ||
|
||||||
(text.toLowerCase().startsWith(AppConfig.schemePrefix) &&
|
(text.toLowerCase().startsWith(AppConfig.schemePrefix) &&
|
||||||
!RegExp(r'\s').hasMatch(text))) {
|
!RegExp(r'\s').hasMatch(text))) {
|
||||||
@ -74,7 +75,7 @@ class ChatListController extends State<ChatList> {
|
|||||||
if (text.toLowerCase().startsWith(AppConfig.inviteLinkPrefix) ||
|
if (text.toLowerCase().startsWith(AppConfig.inviteLinkPrefix) ||
|
||||||
(text.toLowerCase().startsWith(AppConfig.schemePrefix) &&
|
(text.toLowerCase().startsWith(AppConfig.schemePrefix) &&
|
||||||
!RegExp(r'\s').hasMatch(text))) {
|
!RegExp(r'\s').hasMatch(text))) {
|
||||||
AdaptivePageLayout.of(context).popUntilIsFirst();
|
VRouter.of(context).push('/rooms');
|
||||||
UrlLauncher(context, text).openMatrixToUrl();
|
UrlLauncher(context, text).openMatrixToUrl();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -158,7 +159,6 @@ class ChatListController extends State<ChatList> {
|
|||||||
title: L10n.of(context).areYouSure,
|
title: L10n.of(context).areYouSure,
|
||||||
okLabel: L10n.of(context).yes,
|
okLabel: L10n.of(context).yes,
|
||||||
cancelLabel: L10n.of(context).cancel,
|
cancelLabel: L10n.of(context).cancel,
|
||||||
useRootNavigator: false,
|
|
||||||
) ==
|
) ==
|
||||||
OkCancelResult.ok;
|
OkCancelResult.ok;
|
||||||
if (!confirmed) return;
|
if (!confirmed) return;
|
||||||
@ -175,7 +175,6 @@ class ChatListController extends State<ChatList> {
|
|||||||
title: L10n.of(context).setStatus,
|
title: L10n.of(context).setStatus,
|
||||||
okLabel: L10n.of(context).ok,
|
okLabel: L10n.of(context).ok,
|
||||||
cancelLabel: L10n.of(context).cancel,
|
cancelLabel: L10n.of(context).cancel,
|
||||||
useRootNavigator: false,
|
|
||||||
textFields: [
|
textFields: [
|
||||||
DialogTextField(
|
DialogTextField(
|
||||||
hintText: L10n.of(context).statusExampleMessage,
|
hintText: L10n.of(context).statusExampleMessage,
|
||||||
@ -198,7 +197,7 @@ class ChatListController extends State<ChatList> {
|
|||||||
setStatus();
|
setStatus();
|
||||||
break;
|
break;
|
||||||
case PopupMenuAction.settings:
|
case PopupMenuAction.settings:
|
||||||
AdaptivePageLayout.of(context).pushNamed('/settings');
|
VRouter.of(context).push('/settings');
|
||||||
break;
|
break;
|
||||||
case PopupMenuAction.invite:
|
case PopupMenuAction.invite:
|
||||||
FluffyShare.share(
|
FluffyShare.share(
|
||||||
@ -207,10 +206,10 @@ class ChatListController extends State<ChatList> {
|
|||||||
context);
|
context);
|
||||||
break;
|
break;
|
||||||
case PopupMenuAction.newGroup:
|
case PopupMenuAction.newGroup:
|
||||||
AdaptivePageLayout.of(context).pushNamed('/newgroup');
|
VRouter.of(context).push('/newgroup');
|
||||||
break;
|
break;
|
||||||
case PopupMenuAction.archive:
|
case PopupMenuAction.archive:
|
||||||
AdaptivePageLayout.of(context).pushNamed('/archive');
|
VRouter.of(context).push('/archive');
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import 'dart:developer';
|
import 'dart:developer';
|
||||||
|
|
||||||
import 'package:adaptive_dialog/adaptive_dialog.dart';
|
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/views/chat_permissions_settings_view.dart';
|
||||||
import 'package:fluffychat/pages/permission_slider_dialog.dart';
|
import 'package:fluffychat/pages/permission_slider_dialog.dart';
|
||||||
import 'package:future_loading_dialog/future_loading_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/material.dart';
|
||||||
import 'package:flutter_gen/gen_l10n/l10n.dart';
|
import 'package:flutter_gen/gen_l10n/l10n.dart';
|
||||||
import 'package:famedlysdk/famedlysdk.dart';
|
import 'package:famedlysdk/famedlysdk.dart';
|
||||||
|
import 'package:vrouter/vrouter.dart';
|
||||||
|
|
||||||
class ChatPermissionsSettings extends StatefulWidget {
|
class ChatPermissionsSettings extends StatefulWidget {
|
||||||
final String roomId;
|
const ChatPermissionsSettings({Key key}) : super(key: key);
|
||||||
|
|
||||||
const ChatPermissionsSettings(this.roomId, {Key key}) : super(key: key);
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
ChatPermissionsSettingsController createState() =>
|
ChatPermissionsSettingsController createState() =>
|
||||||
@ -22,11 +21,12 @@ class ChatPermissionsSettings extends StatefulWidget {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class ChatPermissionsSettingsController extends State<ChatPermissionsSettings> {
|
class ChatPermissionsSettingsController extends State<ChatPermissionsSettings> {
|
||||||
|
String get roomId => VRouter.of(context).pathParameters['roomid'];
|
||||||
void editPowerLevel(BuildContext context, String key, int currentLevel,
|
void editPowerLevel(BuildContext context, String key, int currentLevel,
|
||||||
{String category}) async {
|
{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)) {
|
if (!room.canSendEvent(EventTypes.RoomPowerLevels)) {
|
||||||
AdaptivePageLayout.of(context)
|
ScaffoldMessenger.of(context)
|
||||||
.showSnackBar(SnackBar(content: Text(L10n.of(context).noPermission)));
|
.showSnackBar(SnackBar(content: Text(L10n.of(context).noPermission)));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -54,14 +54,14 @@ class ChatPermissionsSettingsController extends State<ChatPermissionsSettings> {
|
|||||||
|
|
||||||
Stream get onChanged => Matrix.of(context).client.onSync.stream.where(
|
Stream get onChanged => Matrix.of(context).client.onSync.stream.where(
|
||||||
(e) =>
|
(e) =>
|
||||||
(e?.rooms?.join?.containsKey(widget.roomId) ?? false) &&
|
(e?.rooms?.join?.containsKey(roomId) ?? false) &&
|
||||||
(e.rooms.join[widget.roomId]?.timeline?.events
|
(e.rooms.join[roomId]?.timeline?.events
|
||||||
?.any((s) => s.type == EventTypes.RoomPowerLevels) ??
|
?.any((s) => s.type == EventTypes.RoomPowerLevels) ??
|
||||||
false),
|
false),
|
||||||
);
|
);
|
||||||
|
|
||||||
void updateRoomAction(ServerCapabilities capabilities) async {
|
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 =
|
final String roomVersion =
|
||||||
room.getState(EventTypes.RoomCreate).content['room_version'] ?? '1';
|
room.getState(EventTypes.RoomCreate).content['room_version'] ?? '1';
|
||||||
final newVersion = await showConfirmationDialog<String>(
|
final newVersion = await showConfirmationDialog<String>(
|
||||||
@ -87,8 +87,8 @@ class ChatPermissionsSettingsController extends State<ChatPermissionsSettings> {
|
|||||||
}
|
}
|
||||||
await showFutureLoadingDialog(
|
await showFutureLoadingDialog(
|
||||||
context: context,
|
context: context,
|
||||||
future: () => room.client.upgradeRoom(widget.roomId, newVersion),
|
future: () => room.client.upgradeRoom(roomId, newVersion),
|
||||||
).then((_) => AdaptivePageLayout.of(context).pop());
|
).then((_) => VRouter.of(context).pop());
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
|
@ -33,7 +33,6 @@ class DevicesSettingsController extends State<DevicesSettings> {
|
|||||||
title: L10n.of(context).areYouSure,
|
title: L10n.of(context).areYouSure,
|
||||||
okLabel: L10n.of(context).yes,
|
okLabel: L10n.of(context).yes,
|
||||||
cancelLabel: L10n.of(context).cancel,
|
cancelLabel: L10n.of(context).cancel,
|
||||||
useRootNavigator: false,
|
|
||||||
) ==
|
) ==
|
||||||
OkCancelResult.cancel) return;
|
OkCancelResult.cancel) return;
|
||||||
final matrix = Matrix.of(context);
|
final matrix = Matrix.of(context);
|
||||||
@ -68,7 +67,6 @@ class DevicesSettingsController extends State<DevicesSettings> {
|
|||||||
title: L10n.of(context).changeDeviceName,
|
title: L10n.of(context).changeDeviceName,
|
||||||
okLabel: L10n.of(context).ok,
|
okLabel: L10n.of(context).ok,
|
||||||
cancelLabel: L10n.of(context).cancel,
|
cancelLabel: L10n.of(context).cancel,
|
||||||
useRootNavigator: false,
|
|
||||||
textFields: [
|
textFields: [
|
||||||
DialogTextField(
|
DialogTextField(
|
||||||
hintText: device.displayName,
|
hintText: device.displayName,
|
||||||
|
@ -1,4 +1,3 @@
|
|||||||
import 'package:adaptive_page_layout/adaptive_page_layout.dart';
|
|
||||||
import 'package:famedlysdk/famedlysdk.dart';
|
import 'package:famedlysdk/famedlysdk.dart';
|
||||||
import 'package:fluffychat/pages/views/homeserver_picker_view.dart';
|
import 'package:fluffychat/pages/views/homeserver_picker_view.dart';
|
||||||
import 'package:fluffychat/widgets/matrix.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_gen/gen_l10n/l10n.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import '../utils/localized_exception_extension.dart';
|
import '../utils/localized_exception_extension.dart';
|
||||||
|
import 'package:vrouter/vrouter.dart';
|
||||||
|
|
||||||
class HomeserverPicker extends StatefulWidget {
|
class HomeserverPicker extends StatefulWidget {
|
||||||
@override
|
@override
|
||||||
@ -51,10 +51,11 @@ class HomeserverPickerController extends State<HomeserverPicker> {
|
|||||||
AppConfig.jitsiInstance = jitsi;
|
AppConfig.jitsiInstance = jitsi;
|
||||||
}
|
}
|
||||||
|
|
||||||
await AdaptivePageLayout.of(context)
|
VRouter.of(context).push(
|
||||||
.pushNamed(AppConfig.enableRegistration ? '/signup' : '/login');
|
AppConfig.enableRegistration ? '/signup' : '/login',
|
||||||
|
historyState: {'/home': '/signup'});
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
AdaptivePageLayout.of(context).showSnackBar(
|
ScaffoldMessenger.of(context).showSnackBar(
|
||||||
SnackBar(content: Text((e as Object).toLocalizedString(context))));
|
SnackBar(content: Text((e as Object).toLocalizedString(context))));
|
||||||
} finally {
|
} finally {
|
||||||
if (mounted) {
|
if (mounted) {
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
import 'package:adaptive_page_layout/adaptive_page_layout.dart';
|
|
||||||
import 'package:famedlysdk/famedlysdk.dart';
|
import 'package:famedlysdk/famedlysdk.dart';
|
||||||
import 'package:fluffychat/utils/platform_infos.dart';
|
import 'package:fluffychat/utils/platform_infos.dart';
|
||||||
import 'package:fluffychat/pages/views/image_viewer_view.dart';
|
import 'package:fluffychat/pages/views/image_viewer_view.dart';
|
||||||
import 'package:fluffychat/widgets/matrix.dart';
|
import 'package:fluffychat/widgets/matrix.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:vrouter/vrouter.dart';
|
||||||
|
|
||||||
import '../utils/matrix_sdk_extensions.dart/event_extension.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.
|
/// Forward this image to another room.
|
||||||
void forwardAction() {
|
void forwardAction() {
|
||||||
Matrix.of(context).shareContent = widget.event.content;
|
Matrix.of(context).shareContent = widget.event.content;
|
||||||
AdaptivePageLayout.of(context).popUntilIsFirst();
|
VRouter.of(context).push('/rooms');
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Open this file with a system call.
|
/// Open this file with a system call.
|
||||||
|
@ -1,19 +1,17 @@
|
|||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
|
|
||||||
import 'package:adaptive_page_layout/adaptive_page_layout.dart';
|
|
||||||
|
|
||||||
import 'package:famedlysdk/famedlysdk.dart';
|
import 'package:famedlysdk/famedlysdk.dart';
|
||||||
import 'package:fluffychat/pages/views/invitation_selection_view.dart';
|
import 'package:fluffychat/pages/views/invitation_selection_view.dart';
|
||||||
import 'package:future_loading_dialog/future_loading_dialog.dart';
|
import 'package:future_loading_dialog/future_loading_dialog.dart';
|
||||||
import 'package:fluffychat/widgets/matrix.dart';
|
import 'package:fluffychat/widgets/matrix.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_gen/gen_l10n/l10n.dart';
|
import 'package:flutter_gen/gen_l10n/l10n.dart';
|
||||||
|
import 'package:vrouter/vrouter.dart';
|
||||||
|
|
||||||
import '../utils/localized_exception_extension.dart';
|
import '../utils/localized_exception_extension.dart';
|
||||||
|
|
||||||
class InvitationSelection extends StatefulWidget {
|
class InvitationSelection extends StatefulWidget {
|
||||||
final String roomId;
|
const InvitationSelection({Key key}) : super(key: key);
|
||||||
const InvitationSelection(this.roomId, {Key key}) : super(key: key);
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
InvitationSelectionController createState() =>
|
InvitationSelectionController createState() =>
|
||||||
@ -27,9 +25,11 @@ class InvitationSelectionController extends State<InvitationSelection> {
|
|||||||
List<Profile> foundProfiles = [];
|
List<Profile> foundProfiles = [];
|
||||||
Timer coolDown;
|
Timer coolDown;
|
||||||
|
|
||||||
|
String get roomId => VRouter.of(context).pathParameters['roomid'];
|
||||||
|
|
||||||
Future<List<User>> getContacts(BuildContext context) async {
|
Future<List<User>> getContacts(BuildContext context) async {
|
||||||
final client = Matrix.of(context).client;
|
final client = Matrix.of(context).client;
|
||||||
final room = client.getRoomById(widget.roomId);
|
final room = client.getRoomById(roomId);
|
||||||
final participants = await room.requestParticipants();
|
final participants = await room.requestParticipants();
|
||||||
participants.removeWhere(
|
participants.removeWhere(
|
||||||
(u) => ![Membership.join, Membership.invite].contains(u.membership),
|
(u) => ![Membership.join, Membership.invite].contains(u.membership),
|
||||||
@ -56,13 +56,13 @@ class InvitationSelectionController extends State<InvitationSelection> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void inviteAction(BuildContext context, String id) async {
|
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(
|
final success = await showFutureLoadingDialog(
|
||||||
context: context,
|
context: context,
|
||||||
future: () => room.invite(id),
|
future: () => room.invite(id),
|
||||||
);
|
);
|
||||||
if (success.error == null) {
|
if (success.error == null) {
|
||||||
AdaptivePageLayout.of(context).showSnackBar(SnackBar(
|
ScaffoldMessenger.of(context).showSnackBar(SnackBar(
|
||||||
content: Text(L10n.of(context).contactHasBeenInvitedToTheGroup)));
|
content: Text(L10n.of(context).contactHasBeenInvitedToTheGroup)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -89,7 +89,7 @@ class InvitationSelectionController extends State<InvitationSelection> {
|
|||||||
try {
|
try {
|
||||||
response = await matrix.client.searchUserDirectory(text, limit: 10);
|
response = await matrix.client.searchUserDirectory(text, limit: 10);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
AdaptivePageLayout.of(context).showSnackBar(
|
ScaffoldMessenger.of(context).showSnackBar(
|
||||||
SnackBar(content: Text((e as Object).toLocalizedString(context))));
|
SnackBar(content: Text((e as Object).toLocalizedString(context))));
|
||||||
return;
|
return;
|
||||||
} finally {
|
} finally {
|
||||||
@ -105,7 +105,7 @@ class InvitationSelectionController extends State<InvitationSelection> {
|
|||||||
}
|
}
|
||||||
final participants = Matrix.of(context)
|
final participants = Matrix.of(context)
|
||||||
.client
|
.client
|
||||||
.getRoomById(widget.roomId)
|
.getRoomById(roomId)
|
||||||
.getParticipants()
|
.getParticipants()
|
||||||
.where((user) =>
|
.where((user) =>
|
||||||
[Membership.join, Membership.invite].contains(user.membership))
|
[Membership.join, Membership.invite].contains(user.membership))
|
||||||
|
@ -16,13 +16,11 @@ class KeyVerificationDialog extends StatefulWidget {
|
|||||||
context: context,
|
context: context,
|
||||||
barrierDismissible: true,
|
barrierDismissible: true,
|
||||||
builder: (context) => this,
|
builder: (context) => this,
|
||||||
useRootNavigator: false,
|
|
||||||
)
|
)
|
||||||
: showDialog(
|
: showDialog(
|
||||||
context: context,
|
context: context,
|
||||||
barrierDismissible: true,
|
barrierDismissible: true,
|
||||||
builder: (context) => this,
|
builder: (context) => this,
|
||||||
useRootNavigator: false,
|
|
||||||
);
|
);
|
||||||
|
|
||||||
final KeyVerification request;
|
final KeyVerification request;
|
||||||
@ -100,7 +98,6 @@ class _KeyVerificationPageState extends State<KeyVerificationDialog> {
|
|||||||
await showOkAlertDialog(
|
await showOkAlertDialog(
|
||||||
context: context,
|
context: context,
|
||||||
message: L10n.of(context).incorrectPassphraseOrKey,
|
message: L10n.of(context).incorrectPassphraseOrKey,
|
||||||
useRootNavigator: false,
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -187,7 +184,6 @@ class _KeyVerificationPageState extends State<KeyVerificationDialog> {
|
|||||||
onPressed: () async {
|
onPressed: () async {
|
||||||
final result = await showOkCancelAlertDialog(
|
final result = await showOkCancelAlertDialog(
|
||||||
context: context,
|
context: context,
|
||||||
useRootNavigator: false,
|
|
||||||
title: L10n.of(context).verifyManual,
|
title: L10n.of(context).verifyManual,
|
||||||
message: key.ed25519Key.beautified,
|
message: key.ed25519Key.beautified,
|
||||||
);
|
);
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
|
|
||||||
import 'package:adaptive_dialog/adaptive_dialog.dart';
|
import 'package:adaptive_dialog/adaptive_dialog.dart';
|
||||||
import 'package:adaptive_page_layout/adaptive_page_layout.dart';
|
|
||||||
import 'package:famedlysdk/famedlysdk.dart';
|
import 'package:famedlysdk/famedlysdk.dart';
|
||||||
import 'package:future_loading_dialog/future_loading_dialog.dart';
|
import 'package:future_loading_dialog/future_loading_dialog.dart';
|
||||||
import 'package:fluffychat/widgets/matrix.dart';
|
import 'package:fluffychat/widgets/matrix.dart';
|
||||||
@ -119,7 +119,6 @@ class LoginController extends State<Login> {
|
|||||||
title: L10n.of(context).enterAnEmailAddress,
|
title: L10n.of(context).enterAnEmailAddress,
|
||||||
okLabel: L10n.of(context).ok,
|
okLabel: L10n.of(context).ok,
|
||||||
cancelLabel: L10n.of(context).cancel,
|
cancelLabel: L10n.of(context).cancel,
|
||||||
useRootNavigator: false,
|
|
||||||
textFields: [
|
textFields: [
|
||||||
DialogTextField(
|
DialogTextField(
|
||||||
hintText: L10n.of(context).enterAnEmailAddress,
|
hintText: L10n.of(context).enterAnEmailAddress,
|
||||||
@ -143,7 +142,6 @@ class LoginController extends State<Login> {
|
|||||||
title: L10n.of(context).weSentYouAnEmail,
|
title: L10n.of(context).weSentYouAnEmail,
|
||||||
message: L10n.of(context).pleaseClickOnLink,
|
message: L10n.of(context).pleaseClickOnLink,
|
||||||
okLabel: L10n.of(context).iHaveClickedOnLink,
|
okLabel: L10n.of(context).iHaveClickedOnLink,
|
||||||
useRootNavigator: false,
|
|
||||||
);
|
);
|
||||||
if (ok == null) return;
|
if (ok == null) return;
|
||||||
final password = await showTextInputDialog(
|
final password = await showTextInputDialog(
|
||||||
@ -151,7 +149,6 @@ class LoginController extends State<Login> {
|
|||||||
title: L10n.of(context).chooseAStrongPassword,
|
title: L10n.of(context).chooseAStrongPassword,
|
||||||
okLabel: L10n.of(context).ok,
|
okLabel: L10n.of(context).ok,
|
||||||
cancelLabel: L10n.of(context).cancel,
|
cancelLabel: L10n.of(context).cancel,
|
||||||
useRootNavigator: false,
|
|
||||||
textFields: [
|
textFields: [
|
||||||
DialogTextField(
|
DialogTextField(
|
||||||
hintText: '******',
|
hintText: '******',
|
||||||
@ -178,7 +175,7 @@ class LoginController extends State<Login> {
|
|||||||
),
|
),
|
||||||
);
|
);
|
||||||
if (success.error == null) {
|
if (success.error == null) {
|
||||||
AdaptivePageLayout.of(context).showSnackBar(
|
ScaffoldMessenger.of(context).showSnackBar(
|
||||||
SnackBar(content: Text(L10n.of(context).passwordHasBeenChanged)));
|
SnackBar(content: Text(L10n.of(context).passwordHasBeenChanged)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
import 'package:adaptive_page_layout/adaptive_page_layout.dart';
|
|
||||||
import 'package:famedlysdk/famedlysdk.dart' as sdk;
|
import 'package:famedlysdk/famedlysdk.dart' as sdk;
|
||||||
import 'package:fluffychat/pages/views/new_group_view.dart';
|
import 'package:fluffychat/pages/views/new_group_view.dart';
|
||||||
import 'package:future_loading_dialog/future_loading_dialog.dart';
|
import 'package:future_loading_dialog/future_loading_dialog.dart';
|
||||||
import 'package:fluffychat/widgets/matrix.dart';
|
import 'package:fluffychat/widgets/matrix.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:vrouter/vrouter.dart';
|
||||||
|
|
||||||
class NewGroup extends StatefulWidget {
|
class NewGroup extends StatefulWidget {
|
||||||
@override
|
@override
|
||||||
@ -31,11 +31,8 @@ class NewGroupController extends State<NewGroup> {
|
|||||||
name: controller.text.isNotEmpty ? controller.text : null,
|
name: controller.text.isNotEmpty ? controller.text : null,
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
AdaptivePageLayout.of(context).popUntilIsFirst();
|
if (roomID.error == null) {
|
||||||
if (roomID != null) {
|
VRouter.of(context).push('/rooms/${roomID.result}/invite');
|
||||||
await AdaptivePageLayout.of(context).pushNamed('/rooms/${roomID.result}');
|
|
||||||
await AdaptivePageLayout.of(context)
|
|
||||||
.pushNamed('/rooms/${roomID.result}/invite');
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
|
|
||||||
import 'package:adaptive_page_layout/adaptive_page_layout.dart';
|
|
||||||
import 'package:famedlysdk/famedlysdk.dart';
|
import 'package:famedlysdk/famedlysdk.dart';
|
||||||
import 'package:fluffychat/utils/fluffy_share.dart';
|
import 'package:fluffychat/utils/fluffy_share.dart';
|
||||||
import 'package:fluffychat/pages/views/new_private_chat_view.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:fluffychat/widgets/matrix.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_gen/gen_l10n/l10n.dart';
|
import 'package:flutter_gen/gen_l10n/l10n.dart';
|
||||||
|
import 'package:vrouter/vrouter.dart';
|
||||||
|
|
||||||
class NewPrivateChat extends StatefulWidget {
|
class NewPrivateChat extends StatefulWidget {
|
||||||
@override
|
@override
|
||||||
@ -47,8 +47,7 @@ class NewPrivateChatController extends State<NewPrivateChat> {
|
|||||||
);
|
);
|
||||||
|
|
||||||
if (roomID.error == null) {
|
if (roomID.error == null) {
|
||||||
await AdaptivePageLayout.of(context)
|
VRouter.of(context).push('/rooms/${roomID.result}');
|
||||||
.popAndPushNamed('/rooms/${roomID.result}');
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -14,12 +14,10 @@ class PermissionSliderDialog extends StatefulWidget {
|
|||||||
? showCupertinoDialog<int>(
|
? showCupertinoDialog<int>(
|
||||||
context: context,
|
context: context,
|
||||||
builder: (context) => this,
|
builder: (context) => this,
|
||||||
useRootNavigator: false,
|
|
||||||
)
|
)
|
||||||
: showDialog<int>(
|
: showDialog<int>(
|
||||||
context: context,
|
context: context,
|
||||||
builder: (context) => this,
|
builder: (context) => this,
|
||||||
useRootNavigator: false,
|
|
||||||
);
|
);
|
||||||
|
|
||||||
final int initialPermission;
|
final int initialPermission;
|
||||||
|
@ -1,18 +1,17 @@
|
|||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
|
|
||||||
import 'package:adaptive_dialog/adaptive_dialog.dart';
|
import 'package:adaptive_dialog/adaptive_dialog.dart';
|
||||||
import 'package:adaptive_page_layout/adaptive_page_layout.dart';
|
|
||||||
import 'package:famedlysdk/famedlysdk.dart';
|
import 'package:famedlysdk/famedlysdk.dart';
|
||||||
import 'package:fluffychat/widgets/matrix.dart';
|
import 'package:fluffychat/widgets/matrix.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_gen/gen_l10n/l10n.dart';
|
import 'package:flutter_gen/gen_l10n/l10n.dart';
|
||||||
import 'package:future_loading_dialog/future_loading_dialog.dart';
|
import 'package:future_loading_dialog/future_loading_dialog.dart';
|
||||||
|
import 'package:vrouter/vrouter.dart';
|
||||||
import 'views/search_view.dart';
|
import 'views/search_view.dart';
|
||||||
|
|
||||||
class Search extends StatefulWidget {
|
class Search extends StatefulWidget {
|
||||||
final String alias;
|
const Search({Key key}) : super(key: key);
|
||||||
|
|
||||||
const Search({Key key, this.alias}) : super(key: key);
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
SearchController createState() => SearchController();
|
SearchController createState() => SearchController();
|
||||||
@ -24,6 +23,7 @@ class SearchController extends State<Search> {
|
|||||||
String lastServer;
|
String lastServer;
|
||||||
Timer _coolDown;
|
Timer _coolDown;
|
||||||
String genericSearchTerm;
|
String genericSearchTerm;
|
||||||
|
String alias;
|
||||||
|
|
||||||
void search(String query) async {
|
void search(String query) async {
|
||||||
setState(() => null);
|
setState(() => null);
|
||||||
@ -64,7 +64,6 @@ class SearchController extends State<Search> {
|
|||||||
title: '${room.name} (${room.numJoinedMembers ?? 0})',
|
title: '${room.name} (${room.numJoinedMembers ?? 0})',
|
||||||
message: room.topic ?? L10n.of(context).noDescription,
|
message: room.topic ?? L10n.of(context).noDescription,
|
||||||
cancelLabel: L10n.of(context).cancel,
|
cancelLabel: L10n.of(context).cancel,
|
||||||
useRootNavigator: false,
|
|
||||||
) ==
|
) ==
|
||||||
OkCancelResult.cancel) {
|
OkCancelResult.cancel) {
|
||||||
return;
|
return;
|
||||||
@ -78,8 +77,7 @@ class SearchController extends State<Search> {
|
|||||||
),
|
),
|
||||||
);
|
);
|
||||||
if (success.error == null) {
|
if (success.error == null) {
|
||||||
await AdaptivePageLayout.of(context)
|
VRouter.of(context).push('/rooms/${success.result}');
|
||||||
.pushNamedAndRemoveUntilIsFirst('/rooms/${success.result}');
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -91,7 +89,6 @@ class SearchController extends State<Search> {
|
|||||||
context: context,
|
context: context,
|
||||||
okLabel: L10n.of(context).ok,
|
okLabel: L10n.of(context).ok,
|
||||||
cancelLabel: L10n.of(context).cancel,
|
cancelLabel: L10n.of(context).cancel,
|
||||||
useRootNavigator: false,
|
|
||||||
textFields: [
|
textFields: [
|
||||||
DialogTextField(
|
DialogTextField(
|
||||||
prefixText: 'https://',
|
prefixText: 'https://',
|
||||||
@ -133,11 +130,9 @@ class SearchController extends State<Search> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void initState() {
|
Widget build(BuildContext context) {
|
||||||
genericSearchTerm = widget.alias;
|
alias = VRouter.of(context).queryParameters['query'];
|
||||||
super.initState();
|
genericSearchTerm = alias;
|
||||||
|
return SearchView(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
|
||||||
Widget build(BuildContext context) => SearchView(this);
|
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
|
|
||||||
import 'package:adaptive_dialog/adaptive_dialog.dart';
|
import 'package:adaptive_dialog/adaptive_dialog.dart';
|
||||||
import 'package:adaptive_page_layout/adaptive_page_layout.dart';
|
|
||||||
import 'package:famedlysdk/famedlysdk.dart';
|
import 'package:famedlysdk/famedlysdk.dart';
|
||||||
import 'package:file_picker_cross/file_picker_cross.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_gen/gen_l10n/l10n.dart';
|
||||||
import 'package:flutter_secure_storage/flutter_secure_storage.dart';
|
import 'package:flutter_secure_storage/flutter_secure_storage.dart';
|
||||||
import 'package:image_picker/image_picker.dart';
|
import 'package:image_picker/image_picker.dart';
|
||||||
|
import 'package:vrouter/vrouter.dart';
|
||||||
|
|
||||||
import 'views/settings_view.dart';
|
import 'views/settings_view.dart';
|
||||||
import 'package:future_loading_dialog/future_loading_dialog.dart';
|
import 'package:future_loading_dialog/future_loading_dialog.dart';
|
||||||
@ -40,7 +41,6 @@ class SettingsController extends State<Settings> {
|
|||||||
title: L10n.of(context).areYouSureYouWantToLogout,
|
title: L10n.of(context).areYouSureYouWantToLogout,
|
||||||
okLabel: L10n.of(context).yes,
|
okLabel: L10n.of(context).yes,
|
||||||
cancelLabel: L10n.of(context).cancel,
|
cancelLabel: L10n.of(context).cancel,
|
||||||
useRootNavigator: false,
|
|
||||||
) ==
|
) ==
|
||||||
OkCancelResult.cancel) {
|
OkCancelResult.cancel) {
|
||||||
return;
|
return;
|
||||||
@ -58,7 +58,6 @@ class SettingsController extends State<Settings> {
|
|||||||
title: L10n.of(context).changePassword,
|
title: L10n.of(context).changePassword,
|
||||||
okLabel: L10n.of(context).ok,
|
okLabel: L10n.of(context).ok,
|
||||||
cancelLabel: L10n.of(context).cancel,
|
cancelLabel: L10n.of(context).cancel,
|
||||||
useRootNavigator: false,
|
|
||||||
textFields: [
|
textFields: [
|
||||||
DialogTextField(
|
DialogTextField(
|
||||||
hintText: L10n.of(context).pleaseEnterYourPassword,
|
hintText: L10n.of(context).pleaseEnterYourPassword,
|
||||||
@ -82,7 +81,7 @@ class SettingsController extends State<Settings> {
|
|||||||
.changePassword(input.last, oldPassword: input.first),
|
.changePassword(input.last, oldPassword: input.first),
|
||||||
);
|
);
|
||||||
if (success.error == null) {
|
if (success.error == null) {
|
||||||
AdaptivePageLayout.of(context).showSnackBar(
|
ScaffoldMessenger.of(context).showSnackBar(
|
||||||
SnackBar(content: Text(L10n.of(context).passwordHasBeenChanged)));
|
SnackBar(content: Text(L10n.of(context).passwordHasBeenChanged)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -94,7 +93,6 @@ class SettingsController extends State<Settings> {
|
|||||||
message: L10n.of(context).deactivateAccountWarning,
|
message: L10n.of(context).deactivateAccountWarning,
|
||||||
okLabel: L10n.of(context).ok,
|
okLabel: L10n.of(context).ok,
|
||||||
cancelLabel: L10n.of(context).cancel,
|
cancelLabel: L10n.of(context).cancel,
|
||||||
useRootNavigator: false,
|
|
||||||
) ==
|
) ==
|
||||||
OkCancelResult.cancel) {
|
OkCancelResult.cancel) {
|
||||||
return;
|
return;
|
||||||
@ -104,7 +102,6 @@ class SettingsController extends State<Settings> {
|
|||||||
title: L10n.of(context).areYouSure,
|
title: L10n.of(context).areYouSure,
|
||||||
okLabel: L10n.of(context).yes,
|
okLabel: L10n.of(context).yes,
|
||||||
cancelLabel: L10n.of(context).cancel,
|
cancelLabel: L10n.of(context).cancel,
|
||||||
useRootNavigator: false,
|
|
||||||
) ==
|
) ==
|
||||||
OkCancelResult.cancel) {
|
OkCancelResult.cancel) {
|
||||||
return;
|
return;
|
||||||
@ -114,7 +111,6 @@ class SettingsController extends State<Settings> {
|
|||||||
title: L10n.of(context).pleaseEnterYourPassword,
|
title: L10n.of(context).pleaseEnterYourPassword,
|
||||||
okLabel: L10n.of(context).ok,
|
okLabel: L10n.of(context).ok,
|
||||||
cancelLabel: L10n.of(context).cancel,
|
cancelLabel: L10n.of(context).cancel,
|
||||||
useRootNavigator: false,
|
|
||||||
textFields: [
|
textFields: [
|
||||||
DialogTextField(
|
DialogTextField(
|
||||||
obscureText: true,
|
obscureText: true,
|
||||||
@ -145,7 +141,6 @@ class SettingsController extends State<Settings> {
|
|||||||
title: L10n.of(context).editJitsiInstance,
|
title: L10n.of(context).editJitsiInstance,
|
||||||
okLabel: L10n.of(context).ok,
|
okLabel: L10n.of(context).ok,
|
||||||
cancelLabel: L10n.of(context).cancel,
|
cancelLabel: L10n.of(context).cancel,
|
||||||
useRootNavigator: false,
|
|
||||||
textFields: [
|
textFields: [
|
||||||
DialogTextField(
|
DialogTextField(
|
||||||
initialText: AppConfig.jitsiInstance.replaceFirst(prefix, ''),
|
initialText: AppConfig.jitsiInstance.replaceFirst(prefix, ''),
|
||||||
@ -169,7 +164,6 @@ class SettingsController extends State<Settings> {
|
|||||||
title: L10n.of(context).editDisplayname,
|
title: L10n.of(context).editDisplayname,
|
||||||
okLabel: L10n.of(context).ok,
|
okLabel: L10n.of(context).ok,
|
||||||
cancelLabel: L10n.of(context).cancel,
|
cancelLabel: L10n.of(context).cancel,
|
||||||
useRootNavigator: false,
|
|
||||||
textFields: [
|
textFields: [
|
||||||
DialogTextField(
|
DialogTextField(
|
||||||
initialText: profile?.displayname ??
|
initialText: profile?.displayname ??
|
||||||
@ -234,7 +228,6 @@ class SettingsController extends State<Settings> {
|
|||||||
title: L10n.of(context).askSSSSCache,
|
title: L10n.of(context).askSSSSCache,
|
||||||
okLabel: L10n.of(context).ok,
|
okLabel: L10n.of(context).ok,
|
||||||
cancelLabel: L10n.of(context).cancel,
|
cancelLabel: L10n.of(context).cancel,
|
||||||
useRootNavigator: false,
|
|
||||||
textFields: [
|
textFields: [
|
||||||
DialogTextField(
|
DialogTextField(
|
||||||
hintText: L10n.of(context).passphraseOrKey,
|
hintText: L10n.of(context).passphraseOrKey,
|
||||||
@ -266,7 +259,6 @@ class SettingsController extends State<Settings> {
|
|||||||
context: context,
|
context: context,
|
||||||
message: L10n.of(context).cachedKeys,
|
message: L10n.of(context).cachedKeys,
|
||||||
okLabel: L10n.of(context).ok,
|
okLabel: L10n.of(context).ok,
|
||||||
useRootNavigator: false,
|
|
||||||
);
|
);
|
||||||
setState(() {
|
setState(() {
|
||||||
crossSigningCachedFuture = null;
|
crossSigningCachedFuture = null;
|
||||||
@ -279,7 +271,6 @@ class SettingsController extends State<Settings> {
|
|||||||
context: context,
|
context: context,
|
||||||
message: L10n.of(context).incorrectPassphraseOrKey,
|
message: L10n.of(context).incorrectPassphraseOrKey,
|
||||||
okLabel: L10n.of(context).ok,
|
okLabel: L10n.of(context).ok,
|
||||||
useRootNavigator: false,
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -296,7 +287,6 @@ class SettingsController extends State<Settings> {
|
|||||||
title: L10n.of(context).pleaseChooseAPasscode,
|
title: L10n.of(context).pleaseChooseAPasscode,
|
||||||
message: L10n.of(context).pleaseEnter4Digits,
|
message: L10n.of(context).pleaseEnter4Digits,
|
||||||
cancelLabel: L10n.of(context).cancel,
|
cancelLabel: L10n.of(context).cancel,
|
||||||
useRootNavigator: false,
|
|
||||||
textFields: [
|
textFields: [
|
||||||
DialogTextField(
|
DialogTextField(
|
||||||
validator: (text) {
|
validator: (text) {
|
||||||
@ -333,7 +323,6 @@ class SettingsController extends State<Settings> {
|
|||||||
isDestructiveAction: true,
|
isDestructiveAction: true,
|
||||||
okLabel: L10n.of(context).ok,
|
okLabel: L10n.of(context).ok,
|
||||||
cancelLabel: L10n.of(context).cancel,
|
cancelLabel: L10n.of(context).cancel,
|
||||||
useRootNavigator: false,
|
|
||||||
)) {
|
)) {
|
||||||
await BootstrapDialog(
|
await BootstrapDialog(
|
||||||
client: Matrix.of(context).client,
|
client: Matrix.of(context).client,
|
||||||
@ -351,7 +340,7 @@ class SettingsController extends State<Settings> {
|
|||||||
await BootstrapDialog(
|
await BootstrapDialog(
|
||||||
client: Matrix.of(context).client,
|
client: Matrix.of(context).client,
|
||||||
).show(context);
|
).show(context);
|
||||||
AdaptivePageLayout.of(context).popUntilIsFirst();
|
VRouter.of(context).push('/rooms');
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
|
@ -21,7 +21,6 @@ class Settings3PidController extends State<Settings3Pid> {
|
|||||||
title: L10n.of(context).enterAnEmailAddress,
|
title: L10n.of(context).enterAnEmailAddress,
|
||||||
okLabel: L10n.of(context).ok,
|
okLabel: L10n.of(context).ok,
|
||||||
cancelLabel: L10n.of(context).cancel,
|
cancelLabel: L10n.of(context).cancel,
|
||||||
useRootNavigator: false,
|
|
||||||
textFields: [
|
textFields: [
|
||||||
DialogTextField(
|
DialogTextField(
|
||||||
hintText: L10n.of(context).enterAnEmailAddress,
|
hintText: L10n.of(context).enterAnEmailAddress,
|
||||||
@ -45,7 +44,6 @@ class Settings3PidController extends State<Settings3Pid> {
|
|||||||
title: L10n.of(context).weSentYouAnEmail,
|
title: L10n.of(context).weSentYouAnEmail,
|
||||||
message: L10n.of(context).pleaseClickOnLink,
|
message: L10n.of(context).pleaseClickOnLink,
|
||||||
okLabel: L10n.of(context).iHaveClickedOnLink,
|
okLabel: L10n.of(context).iHaveClickedOnLink,
|
||||||
useRootNavigator: false,
|
|
||||||
);
|
);
|
||||||
if (ok == null) return;
|
if (ok == null) return;
|
||||||
final success = await showFutureLoadingDialog(
|
final success = await showFutureLoadingDialog(
|
||||||
@ -70,7 +68,6 @@ class Settings3PidController extends State<Settings3Pid> {
|
|||||||
title: L10n.of(context).areYouSure,
|
title: L10n.of(context).areYouSure,
|
||||||
okLabel: L10n.of(context).yes,
|
okLabel: L10n.of(context).yes,
|
||||||
cancelLabel: L10n.of(context).cancel,
|
cancelLabel: L10n.of(context).cancel,
|
||||||
useRootNavigator: false,
|
|
||||||
) !=
|
) !=
|
||||||
OkCancelResult.ok) {
|
OkCancelResult.ok) {
|
||||||
return;
|
return;
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import 'package:adaptive_dialog/adaptive_dialog.dart';
|
import 'package:adaptive_dialog/adaptive_dialog.dart';
|
||||||
import 'package:adaptive_page_layout/adaptive_page_layout.dart';
|
|
||||||
import 'package:famedlysdk/famedlysdk.dart';
|
import 'package:famedlysdk/famedlysdk.dart';
|
||||||
import 'package:file_picker_cross/file_picker_cross.dart';
|
import 'package:file_picker_cross/file_picker_cross.dart';
|
||||||
import 'package:fluffychat/utils/platform_infos.dart';
|
import 'package:fluffychat/utils/platform_infos.dart';
|
||||||
@ -138,7 +138,6 @@ class EmotesSettingsController extends State<EmotesSettings> {
|
|||||||
context: context,
|
context: context,
|
||||||
message: L10n.of(context).emoteExists,
|
message: L10n.of(context).emoteExists,
|
||||||
okLabel: L10n.of(context).ok,
|
okLabel: L10n.of(context).ok,
|
||||||
useRootNavigator: false,
|
|
||||||
);
|
);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -148,7 +147,6 @@ class EmotesSettingsController extends State<EmotesSettings> {
|
|||||||
context: context,
|
context: context,
|
||||||
message: L10n.of(context).emoteInvalid,
|
message: L10n.of(context).emoteInvalid,
|
||||||
okLabel: L10n.of(context).ok,
|
okLabel: L10n.of(context).ok,
|
||||||
useRootNavigator: false,
|
|
||||||
);
|
);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -187,7 +185,6 @@ class EmotesSettingsController extends State<EmotesSettings> {
|
|||||||
context: context,
|
context: context,
|
||||||
message: L10n.of(context).emoteWarnNeedToPick,
|
message: L10n.of(context).emoteWarnNeedToPick,
|
||||||
okLabel: L10n.of(context).ok,
|
okLabel: L10n.of(context).ok,
|
||||||
useRootNavigator: false,
|
|
||||||
);
|
);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -198,7 +195,6 @@ class EmotesSettingsController extends State<EmotesSettings> {
|
|||||||
context: context,
|
context: context,
|
||||||
message: L10n.of(context).emoteExists,
|
message: L10n.of(context).emoteExists,
|
||||||
okLabel: L10n.of(context).ok,
|
okLabel: L10n.of(context).ok,
|
||||||
useRootNavigator: false,
|
|
||||||
);
|
);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -207,7 +203,6 @@ class EmotesSettingsController extends State<EmotesSettings> {
|
|||||||
context: context,
|
context: context,
|
||||||
message: L10n.of(context).emoteInvalid,
|
message: L10n.of(context).emoteInvalid,
|
||||||
okLabel: L10n.of(context).ok,
|
okLabel: L10n.of(context).ok,
|
||||||
useRootNavigator: false,
|
|
||||||
);
|
);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -222,7 +217,7 @@ class EmotesSettingsController extends State<EmotesSettings> {
|
|||||||
|
|
||||||
void emoteImagePickerAction(TextEditingController controller) async {
|
void emoteImagePickerAction(TextEditingController controller) async {
|
||||||
if (kIsWeb) {
|
if (kIsWeb) {
|
||||||
AdaptivePageLayout.of(context).showSnackBar(
|
ScaffoldMessenger.of(context).showSnackBar(
|
||||||
SnackBar(content: Text(L10n.of(context).notSupportedInWeb)));
|
SnackBar(content: Text(L10n.of(context).notSupportedInWeb)));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -1,11 +1,10 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:vrouter/vrouter.dart';
|
||||||
|
|
||||||
import 'views/settings_multiple_emotes_view.dart';
|
import 'views/settings_multiple_emotes_view.dart';
|
||||||
|
|
||||||
class MultipleEmotesSettings extends StatefulWidget {
|
class MultipleEmotesSettings extends StatefulWidget {
|
||||||
final String roomId;
|
MultipleEmotesSettings({Key key}) : super(key: key);
|
||||||
|
|
||||||
MultipleEmotesSettings(this.roomId, {Key key}) : super(key: key);
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
MultipleEmotesSettingsController createState() =>
|
MultipleEmotesSettingsController createState() =>
|
||||||
@ -13,6 +12,7 @@ class MultipleEmotesSettings extends StatefulWidget {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class MultipleEmotesSettingsController extends State<MultipleEmotesSettings> {
|
class MultipleEmotesSettingsController extends State<MultipleEmotesSettings> {
|
||||||
|
String get roomId => VRouter.of(context).pathParameters['roomid'];
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) => MultipleEmotesSettingsView(this);
|
Widget build(BuildContext context) => MultipleEmotesSettingsView(this);
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
import 'dart:io';
|
import 'dart:io';
|
||||||
|
|
||||||
import 'package:adaptive_page_layout/adaptive_page_layout.dart';
|
|
||||||
import 'package:famedlysdk/famedlysdk.dart';
|
import 'package:famedlysdk/famedlysdk.dart';
|
||||||
import 'package:file_picker_cross/file_picker_cross.dart';
|
import 'package:file_picker_cross/file_picker_cross.dart';
|
||||||
import 'package:fluffychat/config/app_config.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:uni_links/uni_links.dart';
|
||||||
import 'package:url_launcher/url_launcher.dart';
|
import 'package:url_launcher/url_launcher.dart';
|
||||||
import 'package:universal_html/html.dart' as html;
|
import 'package:universal_html/html.dart' as html;
|
||||||
|
import 'package:vrouter/vrouter.dart';
|
||||||
|
|
||||||
import '../main.dart';
|
import '../main.dart';
|
||||||
|
|
||||||
@ -29,7 +29,7 @@ class SignUpController extends State<SignUp> {
|
|||||||
final TextEditingController usernameController = TextEditingController();
|
final TextEditingController usernameController = TextEditingController();
|
||||||
String usernameError;
|
String usernameError;
|
||||||
bool loading = false;
|
bool loading = false;
|
||||||
MatrixFile avatar;
|
static MatrixFile avatar;
|
||||||
|
|
||||||
LoginTypes _loginTypes;
|
LoginTypes _loginTypes;
|
||||||
StreamSubscription _intentDataStreamSubscription;
|
StreamSubscription _intentDataStreamSubscription;
|
||||||
@ -48,7 +48,7 @@ class SignUpController extends State<SignUp> {
|
|||||||
|
|
||||||
void _processIncomingUris(String text) async {
|
void _processIncomingUris(String text) async {
|
||||||
if (text == null || !text.startsWith(AppConfig.appOpenUrlScheme)) return;
|
if (text == null || !text.startsWith(AppConfig.appOpenUrlScheme)) return;
|
||||||
AdaptivePageLayout.of(context).popUntilIsFirst();
|
VRouter.of(context).push('/home');
|
||||||
final token = Uri.parse(text).queryParameters['loginToken'];
|
final token = Uri.parse(text).queryParameters['loginToken'];
|
||||||
if (token != null) _loginWithToken(token);
|
if (token != null) _loginWithToken(token);
|
||||||
}
|
}
|
||||||
@ -151,9 +151,10 @@ class SignUpController extends State<SignUp> {
|
|||||||
return setState(() => loading = false);
|
return setState(() => loading = false);
|
||||||
}
|
}
|
||||||
setState(() => loading = false);
|
setState(() => loading = false);
|
||||||
await AdaptivePageLayout.of(context).pushNamed(
|
|
||||||
|
VRouter.of(context).push(
|
||||||
'/signup/password/${Uri.encodeComponent(preferredUsername)}/${Uri.encodeComponent(usernameController.text)}',
|
'/signup/password/${Uri.encodeComponent(preferredUsername)}/${Uri.encodeComponent(usernameController.text)}',
|
||||||
arguments: avatar,
|
queryParameters: {'displayname': usernameController.text},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,21 +1,20 @@
|
|||||||
import 'package:adaptive_dialog/adaptive_dialog.dart';
|
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:email_validator/email_validator.dart';
|
||||||
|
|
||||||
import 'package:famedlysdk/famedlysdk.dart';
|
import 'package:famedlysdk/famedlysdk.dart';
|
||||||
|
import 'package:fluffychat/pages/sign_up.dart';
|
||||||
import 'package:fluffychat/utils/get_client_secret.dart';
|
import 'package:fluffychat/utils/get_client_secret.dart';
|
||||||
import 'package:fluffychat/pages/views/sign_up_password_view.dart';
|
import 'package:fluffychat/pages/views/sign_up_password_view.dart';
|
||||||
|
|
||||||
import 'package:fluffychat/widgets/matrix.dart';
|
import 'package:fluffychat/widgets/matrix.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_gen/gen_l10n/l10n.dart';
|
import 'package:flutter_gen/gen_l10n/l10n.dart';
|
||||||
|
import 'package:vrouter/vrouter.dart';
|
||||||
import '../utils/platform_infos.dart';
|
import '../utils/platform_infos.dart';
|
||||||
|
|
||||||
class SignUpPassword extends StatefulWidget {
|
class SignUpPassword extends StatefulWidget {
|
||||||
final MatrixFile avatar;
|
const SignUpPassword();
|
||||||
final String username;
|
|
||||||
final String displayname;
|
|
||||||
const SignUpPassword(this.username, {this.avatar, this.displayname});
|
|
||||||
@override
|
@override
|
||||||
SignUpPasswordController createState() => SignUpPasswordController();
|
SignUpPasswordController createState() => SignUpPasswordController();
|
||||||
}
|
}
|
||||||
@ -70,8 +69,10 @@ class SignUpPasswordController extends State<SignUpPassword> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
final waitForLogin = matrix.client.onLoginStateChanged.stream.first;
|
final waitForLogin = matrix.client.onLoginStateChanged.stream.first;
|
||||||
|
final username = VRouter.of(context).pathParameters['username'];
|
||||||
|
|
||||||
await matrix.client.uiaRequestBackground((auth) => matrix.client.register(
|
await matrix.client.uiaRequestBackground((auth) => matrix.client.register(
|
||||||
username: widget.username,
|
username: username,
|
||||||
password: passwordController.text,
|
password: passwordController.text,
|
||||||
initialDeviceDisplayName: PlatformInfos.clientName,
|
initialDeviceDisplayName: PlatformInfos.clientName,
|
||||||
auth: auth,
|
auth: auth,
|
||||||
@ -91,19 +92,20 @@ class SignUpPasswordController extends State<SignUpPassword> {
|
|||||||
}
|
}
|
||||||
await matrix.client.onLoginStateChanged.stream
|
await matrix.client.onLoginStateChanged.stream
|
||||||
.firstWhere((l) => l == LoginState.logged);
|
.firstWhere((l) => l == LoginState.logged);
|
||||||
// tchncs.de
|
final displayname = VRouter.of(context).queryParameters['displayname'];
|
||||||
try {
|
if (displayname != null) {
|
||||||
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) {
|
|
||||||
try {
|
try {
|
||||||
await matrix.client.setAvatar(widget.avatar);
|
await matrix.client.setDisplayName(matrix.client.userID, displayname);
|
||||||
} catch (exception) {
|
} 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)));
|
SnackBar(content: Text(L10n.of(context).couldNotSetAvatar)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,11 +1,12 @@
|
|||||||
import 'package:adaptive_dialog/adaptive_dialog.dart';
|
import 'package:adaptive_dialog/adaptive_dialog.dart';
|
||||||
import 'package:adaptive_page_layout/adaptive_page_layout.dart';
|
|
||||||
import 'package:famedlysdk/famedlysdk.dart';
|
import 'package:famedlysdk/famedlysdk.dart';
|
||||||
import 'package:fluffychat/pages/permission_slider_dialog.dart';
|
import 'package:fluffychat/pages/permission_slider_dialog.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_gen/gen_l10n/l10n.dart';
|
import 'package:flutter_gen/gen_l10n/l10n.dart';
|
||||||
|
|
||||||
import 'package:future_loading_dialog/future_loading_dialog.dart';
|
import 'package:future_loading_dialog/future_loading_dialog.dart';
|
||||||
|
import 'package:vrouter/vrouter.dart';
|
||||||
|
|
||||||
import 'views/user_bottom_sheet_view.dart';
|
import 'views/user_bottom_sheet_view.dart';
|
||||||
|
|
||||||
@ -30,7 +31,6 @@ class UserBottomSheetController extends State<UserBottomSheet> {
|
|||||||
final Function _askConfirmation =
|
final Function _askConfirmation =
|
||||||
() async => (await showOkCancelAlertDialog(
|
() async => (await showOkCancelAlertDialog(
|
||||||
context: context,
|
context: context,
|
||||||
useRootNavigator: false,
|
|
||||||
title: L10n.of(context).areYouSure,
|
title: L10n.of(context).areYouSure,
|
||||||
okLabel: L10n.of(context).yes,
|
okLabel: L10n.of(context).yes,
|
||||||
cancelLabel: L10n.of(context).no,
|
cancelLabel: L10n.of(context).no,
|
||||||
@ -83,8 +83,7 @@ class UserBottomSheetController extends State<UserBottomSheet> {
|
|||||||
break;
|
break;
|
||||||
case 'message':
|
case 'message':
|
||||||
final roomId = await widget.user.startDirectChat();
|
final roomId = await widget.user.startDirectChat();
|
||||||
await AdaptivePageLayout.of(widget.outerContext)
|
VRouter.of(widget.outerContext).push('/rooms/$roomId');
|
||||||
.pushNamedAndRemoveUntilIsFirst('/rooms/$roomId');
|
|
||||||
Navigator.of(context, rootNavigator: false).pop();
|
Navigator.of(context, rootNavigator: false).pop();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,3 @@
|
|||||||
import 'package:adaptive_page_layout/adaptive_page_layout.dart';
|
|
||||||
import 'package:fluffychat/config/app_config.dart';
|
import 'package:fluffychat/config/app_config.dart';
|
||||||
import 'package:fluffychat/pages/chat_details.dart';
|
import 'package:fluffychat/pages/chat_details.dart';
|
||||||
import 'package:fluffychat/widgets/avatar.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/material.dart';
|
||||||
import 'package:flutter_gen/gen_l10n/l10n.dart';
|
import 'package:flutter_gen/gen_l10n/l10n.dart';
|
||||||
import 'package:matrix_link_text/link_text.dart';
|
import 'package:matrix_link_text/link_text.dart';
|
||||||
|
import 'package:vrouter/vrouter.dart';
|
||||||
|
|
||||||
import '../../utils/url_launcher.dart';
|
import '../../utils/url_launcher.dart';
|
||||||
|
|
||||||
@ -25,12 +25,10 @@ class ChatDetailsView extends StatelessWidget {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
final room =
|
final room = Matrix.of(context).client.getRoomById(controller.roomId);
|
||||||
Matrix.of(context).client.getRoomById(controller.widget.roomId);
|
|
||||||
if (room == null) {
|
if (room == null) {
|
||||||
return Scaffold(
|
return Scaffold(
|
||||||
appBar: AppBar(
|
appBar: AppBar(
|
||||||
leading: BackButton(),
|
|
||||||
title: Text(L10n.of(context).oopsSomethingWentWrong),
|
title: Text(L10n.of(context).oopsSomethingWentWrong),
|
||||||
),
|
),
|
||||||
body: Center(
|
body: Center(
|
||||||
@ -52,8 +50,12 @@ class ChatDetailsView extends StatelessWidget {
|
|||||||
headerSliverBuilder:
|
headerSliverBuilder:
|
||||||
(BuildContext context, bool innerBoxIsScrolled) => <Widget>[
|
(BuildContext context, bool innerBoxIsScrolled) => <Widget>[
|
||||||
SliverAppBar(
|
SliverAppBar(
|
||||||
|
leading: IconButton(
|
||||||
|
icon: Icon(Icons.close_outlined),
|
||||||
|
onPressed: () =>
|
||||||
|
VRouter.of(context).push('/rooms/${controller.roomId}'),
|
||||||
|
),
|
||||||
elevation: Theme.of(context).appBarTheme.elevation,
|
elevation: Theme.of(context).appBarTheme.elevation,
|
||||||
leading: BackButton(),
|
|
||||||
expandedHeight: 300.0,
|
expandedHeight: 300.0,
|
||||||
floating: true,
|
floating: true,
|
||||||
pinned: true,
|
pinned: true,
|
||||||
@ -308,8 +310,8 @@ class ChatDetailsView extends StatelessWidget {
|
|||||||
foregroundColor: Colors.grey,
|
foregroundColor: Colors.grey,
|
||||||
child: Icon(Icons.edit_attributes_outlined),
|
child: Icon(Icons.edit_attributes_outlined),
|
||||||
),
|
),
|
||||||
onTap: () => AdaptivePageLayout.of(context)
|
onTap: () => VRouter.of(context).push(
|
||||||
.pushNamed('/rooms/${room.id}/permissions'),
|
'/rooms/${room.id}/details/permissions'),
|
||||||
),
|
),
|
||||||
Divider(thickness: 1),
|
Divider(thickness: 1),
|
||||||
ListTile(
|
ListTile(
|
||||||
@ -334,8 +336,8 @@ class ChatDetailsView extends StatelessWidget {
|
|||||||
radius: Avatar.defaultSize / 2,
|
radius: Avatar.defaultSize / 2,
|
||||||
child: Icon(Icons.add_outlined),
|
child: Icon(Icons.add_outlined),
|
||||||
),
|
),
|
||||||
onTap: () => AdaptivePageLayout.of(context)
|
onTap: () => VRouter.of(context)
|
||||||
.pushNamed('/rooms/${room.id}/invite'),
|
.push('/rooms/${room.id}/invite'),
|
||||||
)
|
)
|
||||||
: Container(),
|
: Container(),
|
||||||
],
|
],
|
||||||
|
@ -5,6 +5,7 @@ import 'package:fluffychat/widgets/matrix.dart';
|
|||||||
import 'package:fluffychat/widgets/layouts/max_width_body.dart';
|
import 'package:fluffychat/widgets/layouts/max_width_body.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_gen/gen_l10n/l10n.dart';
|
import 'package:flutter_gen/gen_l10n/l10n.dart';
|
||||||
|
import 'package:vrouter/vrouter.dart';
|
||||||
import '../../utils/matrix_sdk_extensions.dart/device_extension.dart';
|
import '../../utils/matrix_sdk_extensions.dart/device_extension.dart';
|
||||||
|
|
||||||
class ChatEncryptionSettingsView extends StatelessWidget {
|
class ChatEncryptionSettingsView extends StatelessWidget {
|
||||||
@ -15,11 +16,15 @@ class ChatEncryptionSettingsView extends StatelessWidget {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
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(
|
return Scaffold(
|
||||||
appBar: AppBar(
|
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),
|
title: Text(L10n.of(context).tapOnDeviceToVerify),
|
||||||
bottom: PreferredSize(
|
bottom: PreferredSize(
|
||||||
preferredSize: Size.fromHeight(56),
|
preferredSize: Size.fromHeight(56),
|
||||||
|
@ -1,4 +1,3 @@
|
|||||||
import 'package:adaptive_page_layout/adaptive_page_layout.dart';
|
|
||||||
import 'package:famedlysdk/famedlysdk.dart';
|
import 'package:famedlysdk/famedlysdk.dart';
|
||||||
import 'package:fluffychat/pages/chat_list.dart';
|
import 'package:fluffychat/pages/chat_list.dart';
|
||||||
import 'package:fluffychat/widgets/connection_status_header.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:fluffychat/config/app_config.dart';
|
||||||
import 'package:flutter/foundation.dart';
|
import 'package:flutter/foundation.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:vrouter/vrouter.dart';
|
||||||
import '../../widgets/matrix.dart';
|
import '../../widgets/matrix.dart';
|
||||||
import 'package:flutter_gen/gen_l10n/l10n.dart';
|
import 'package:flutter_gen/gen_l10n/l10n.dart';
|
||||||
|
|
||||||
@ -28,7 +28,9 @@ class ChatListView extends StatelessWidget {
|
|||||||
return Scaffold(
|
return Scaffold(
|
||||||
appBar: AppBar(
|
appBar: AppBar(
|
||||||
elevation:
|
elevation:
|
||||||
AdaptivePageLayout.of(context).columnMode(context) ? 1 : null,
|
MediaQuery.of(context).size.width > AppConfig.columnWidth * 2
|
||||||
|
? 1
|
||||||
|
: null,
|
||||||
leading: selectMode == SelectMode.normal
|
leading: selectMode == SelectMode.normal
|
||||||
? null
|
? null
|
||||||
: IconButton(
|
: IconButton(
|
||||||
@ -82,8 +84,8 @@ class ChatListView extends StatelessWidget {
|
|||||||
IconButton(
|
IconButton(
|
||||||
icon: Icon(Icons.search_outlined),
|
icon: Icon(Icons.search_outlined),
|
||||||
tooltip: L10n.of(context).search,
|
tooltip: L10n.of(context).search,
|
||||||
onPressed: () => AdaptivePageLayout.of(context)
|
onPressed: () =>
|
||||||
.pushNamed('/search'),
|
VRouter.of(context).push('/search'),
|
||||||
),
|
),
|
||||||
PopupMenuButton<PopupMenuAction>(
|
PopupMenuButton<PopupMenuAction>(
|
||||||
onSelected: controller.onPopupMenuSelect,
|
onSelected: controller.onPopupMenuSelect,
|
||||||
@ -223,8 +225,8 @@ class ChatListView extends StatelessWidget {
|
|||||||
]),
|
]),
|
||||||
floatingActionButton: selectMode == SelectMode.normal
|
floatingActionButton: selectMode == SelectMode.normal
|
||||||
? FloatingActionButton(
|
? FloatingActionButton(
|
||||||
onPressed: () => AdaptivePageLayout.of(context)
|
onPressed: () =>
|
||||||
.pushNamedAndRemoveUntilIsFirst('/newprivatechat'),
|
VRouter.of(context).push('/newprivatechat'),
|
||||||
child: Icon(CupertinoIcons.chat_bubble),
|
child: Icon(CupertinoIcons.chat_bubble),
|
||||||
)
|
)
|
||||||
: null,
|
: null,
|
||||||
|
@ -26,7 +26,7 @@ class ChatPermissionsSettingsView extends StatelessWidget {
|
|||||||
stream: controller.onChanged,
|
stream: controller.onChanged,
|
||||||
builder: (context, _) {
|
builder: (context, _) {
|
||||||
final room =
|
final room =
|
||||||
Matrix.of(context).client.getRoomById(controller.widget.roomId);
|
Matrix.of(context).client.getRoomById(controller.roomId);
|
||||||
final powerLevelsContent = Map<String, dynamic>.from(
|
final powerLevelsContent = Map<String, dynamic>.from(
|
||||||
room.getState(EventTypes.RoomPowerLevels).content);
|
room.getState(EventTypes.RoomPowerLevels).content);
|
||||||
final powerLevels = Map<String, dynamic>.from(powerLevelsContent)
|
final powerLevels = Map<String, dynamic>.from(powerLevelsContent)
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
import 'dart:math';
|
import 'dart:math';
|
||||||
import 'dart:ui';
|
import 'dart:ui';
|
||||||
|
|
||||||
import 'package:adaptive_page_layout/adaptive_page_layout.dart';
|
|
||||||
import 'package:emoji_picker_flutter/emoji_picker_flutter.dart';
|
import 'package:emoji_picker_flutter/emoji_picker_flutter.dart';
|
||||||
import 'package:famedlysdk/famedlysdk.dart';
|
import 'package:famedlysdk/famedlysdk.dart';
|
||||||
import 'package:fluffychat/pages/chat.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:flutter_gen/gen_l10n/l10n.dart';
|
||||||
import 'package:scroll_to_index/scroll_to_index.dart';
|
import 'package:scroll_to_index/scroll_to_index.dart';
|
||||||
import 'package:swipe_to_action/swipe_to_action.dart';
|
import 'package:swipe_to_action/swipe_to_action.dart';
|
||||||
|
import 'package:vrouter/vrouter.dart';
|
||||||
|
|
||||||
class ChatView extends StatelessWidget {
|
class ChatView extends StatelessWidget {
|
||||||
final ChatController controller;
|
final ChatController controller;
|
||||||
@ -38,7 +38,7 @@ class ChatView extends StatelessWidget {
|
|||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
controller.matrix = Matrix.of(context);
|
controller.matrix = Matrix.of(context);
|
||||||
final client = controller.matrix.client;
|
final client = controller.matrix.client;
|
||||||
controller.room ??= client.getRoomById(controller.widget.id);
|
controller.room ??= client.getRoomById(controller.roomId);
|
||||||
if (controller.room == null) {
|
if (controller.room == null) {
|
||||||
return Scaffold(
|
return Scaffold(
|
||||||
appBar: AppBar(
|
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) {
|
if (controller.room.membership == Membership.invite) {
|
||||||
showFutureLoadingDialog(
|
showFutureLoadingDialog(
|
||||||
@ -64,11 +64,7 @@ class ChatView extends StatelessWidget {
|
|||||||
onPressed: controller.clearSelectedEvents,
|
onPressed: controller.clearSelectedEvents,
|
||||||
tooltip: L10n.of(context).close,
|
tooltip: L10n.of(context).close,
|
||||||
)
|
)
|
||||||
: AdaptivePageLayout.of(context).columnMode(context)
|
: UnreadBadgeBackButton(roomId: controller.roomId),
|
||||||
? null
|
|
||||||
: UnreadBadgeBackButton(roomId: controller.widget.id),
|
|
||||||
titleSpacing:
|
|
||||||
AdaptivePageLayout.of(context).columnMode(context) ? null : 0,
|
|
||||||
title: controller.selectedEvents.isEmpty
|
title: controller.selectedEvents.isEmpty
|
||||||
? StreamBuilder(
|
? StreamBuilder(
|
||||||
stream: controller.room.onUpdate.stream,
|
stream: controller.room.onUpdate.stream,
|
||||||
@ -88,15 +84,8 @@ class ChatView extends StatelessWidget {
|
|||||||
'${controller.room.directChatMatrixID} ',
|
'${controller.room.directChatMatrixID} ',
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
: () => (!AdaptivePageLayout.of(context)
|
: () => VRouter.of(context)
|
||||||
.columnMode(context) ||
|
.push('/rooms/${controller.room.id}/details'),
|
||||||
AdaptivePageLayout.of(context)
|
|
||||||
.viewDataStack
|
|
||||||
.length <
|
|
||||||
3)
|
|
||||||
? AdaptivePageLayout.of(context).pushNamed(
|
|
||||||
'/rooms/${controller.room.id}/details')
|
|
||||||
: null,
|
|
||||||
title: Text(
|
title: Text(
|
||||||
controller.room.getLocalizedDisplayname(
|
controller.room.getLocalizedDisplayname(
|
||||||
MatrixLocals(L10n.of(context))),
|
MatrixLocals(L10n.of(context))),
|
||||||
@ -259,13 +248,7 @@ class ChatView extends StatelessWidget {
|
|||||||
final horizontalPadding = max(
|
final horizontalPadding = max(
|
||||||
0,
|
0,
|
||||||
(MediaQuery.of(context).size.width -
|
(MediaQuery.of(context).size.width -
|
||||||
FluffyThemes.columnWidth *
|
FluffyThemes.columnWidth * (3.5)) /
|
||||||
(AdaptivePageLayout.of(context)
|
|
||||||
.currentViewData
|
|
||||||
?.rightView !=
|
|
||||||
null
|
|
||||||
? 4.5
|
|
||||||
: 3.5)) /
|
|
||||||
2)
|
2)
|
||||||
.toDouble();
|
.toDouble();
|
||||||
|
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
class EmptyPage extends StatelessWidget {
|
class EmptyPage extends StatelessWidget {
|
||||||
|
const EmptyPage({Key key}) : super(key: key);
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return Scaffold(
|
return Scaffold(
|
||||||
|
@ -15,8 +15,7 @@ class InvitationSelectionView extends StatelessWidget {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
final room =
|
final room = Matrix.of(context).client.getRoomById(controller.roomId);
|
||||||
Matrix.of(context).client.getRoomById(controller.widget.roomId);
|
|
||||||
final groupName =
|
final groupName =
|
||||||
room.name?.isEmpty ?? false ? L10n.of(context).group : room.name;
|
room.name?.isEmpty ?? false ? L10n.of(context).group : room.name;
|
||||||
return Scaffold(
|
return Scaffold(
|
||||||
|
@ -1,4 +1,3 @@
|
|||||||
import 'package:adaptive_page_layout/adaptive_page_layout.dart';
|
|
||||||
import 'package:fluffychat/pages/new_private_chat.dart';
|
import 'package:fluffychat/pages/new_private_chat.dart';
|
||||||
import 'package:fluffychat/widgets/avatar.dart';
|
import 'package:fluffychat/widgets/avatar.dart';
|
||||||
import 'package:fluffychat/widgets/contacts_list.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/material.dart';
|
||||||
import 'package:flutter_gen/gen_l10n/l10n.dart';
|
import 'package:flutter_gen/gen_l10n/l10n.dart';
|
||||||
import 'package:famedlysdk/famedlysdk.dart';
|
import 'package:famedlysdk/famedlysdk.dart';
|
||||||
|
import 'package:vrouter/vrouter.dart';
|
||||||
|
|
||||||
class NewPrivateChatView extends StatelessWidget {
|
class NewPrivateChatView extends StatelessWidget {
|
||||||
final NewPrivateChatController controller;
|
final NewPrivateChatController controller;
|
||||||
@ -22,8 +22,7 @@ class NewPrivateChatView extends StatelessWidget {
|
|||||||
elevation: 0,
|
elevation: 0,
|
||||||
actions: [
|
actions: [
|
||||||
TextButton(
|
TextButton(
|
||||||
onPressed: () => AdaptivePageLayout.of(context)
|
onPressed: () => VRouter.of(context).push('/newgroup'),
|
||||||
.pushNamedAndRemoveUntilIsFirst('/newgroup'),
|
|
||||||
child: Text(
|
child: Text(
|
||||||
L10n.of(context).createNewGroup,
|
L10n.of(context).createNewGroup,
|
||||||
style: TextStyle(color: Theme.of(context).accentColor),
|
style: TextStyle(color: Theme.of(context).accentColor),
|
||||||
|
@ -1,4 +1,3 @@
|
|||||||
import 'package:adaptive_page_layout/adaptive_page_layout.dart';
|
|
||||||
import 'package:famedlysdk/famedlysdk.dart';
|
import 'package:famedlysdk/famedlysdk.dart';
|
||||||
import 'package:fluffychat/widgets/avatar.dart';
|
import 'package:fluffychat/widgets/avatar.dart';
|
||||||
import 'package:fluffychat/widgets/contacts_list.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/material.dart';
|
||||||
import 'package:flutter_gen/gen_l10n/l10n.dart';
|
import 'package:flutter_gen/gen_l10n/l10n.dart';
|
||||||
import 'package:future_loading_dialog/future_loading_dialog.dart';
|
import 'package:future_loading_dialog/future_loading_dialog.dart';
|
||||||
|
import 'package:vrouter/vrouter.dart';
|
||||||
import '../../utils/localized_exception_extension.dart';
|
import '../../utils/localized_exception_extension.dart';
|
||||||
import '../search.dart';
|
import '../search.dart';
|
||||||
|
|
||||||
@ -32,21 +32,21 @@ class SearchView extends StatelessWidget {
|
|||||||
genericSearchTerm: controller.genericSearchTerm,
|
genericSearchTerm: controller.genericSearchTerm,
|
||||||
)
|
)
|
||||||
.catchError((error) {
|
.catchError((error) {
|
||||||
if (controller.widget.alias == null) {
|
if (controller.alias == null) {
|
||||||
throw error;
|
throw error;
|
||||||
}
|
}
|
||||||
return PublicRoomsResponse.fromJson({
|
return PublicRoomsResponse.fromJson({
|
||||||
'chunk': [],
|
'chunk': [],
|
||||||
});
|
});
|
||||||
}).then((PublicRoomsResponse res) {
|
}).then((PublicRoomsResponse res) {
|
||||||
if (controller.widget.alias != null &&
|
if (controller.alias != null &&
|
||||||
!res.chunk.any((room) =>
|
!res.chunk.any((room) =>
|
||||||
(room.aliases?.contains(controller.widget.alias) ?? false) ||
|
(room.aliases?.contains(controller.alias) ?? false) ||
|
||||||
room.canonicalAlias == controller.widget.alias)) {
|
room.canonicalAlias == controller.alias)) {
|
||||||
// we have to tack on the original alias
|
// we have to tack on the original alias
|
||||||
res.chunk.add(PublicRoom.fromJson(<String, dynamic>{
|
res.chunk.add(PublicRoom.fromJson(<String, dynamic>{
|
||||||
'aliases': [controller.widget.alias],
|
'aliases': [controller.alias],
|
||||||
'name': controller.widget.alias,
|
'name': controller.alias,
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
return res;
|
return res;
|
||||||
@ -238,8 +238,7 @@ class SearchView extends StatelessWidget {
|
|||||||
.startDirectChat(foundProfile.userId),
|
.startDirectChat(foundProfile.userId),
|
||||||
);
|
);
|
||||||
if (roomID.error == null) {
|
if (roomID.error == null) {
|
||||||
await AdaptivePageLayout.of(context)
|
VRouter.of(context).push('/rooms/${roomID.result}');
|
||||||
.popAndPushNamed('/rooms/${roomID.result}');
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
leading: Avatar(
|
leading: Avatar(
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
import 'package:adaptive_page_layout/adaptive_page_layout.dart';
|
|
||||||
import 'package:fluffychat/pages/settings_multiple_emotes.dart';
|
import 'package:fluffychat/pages/settings_multiple_emotes.dart';
|
||||||
import 'package:fluffychat/widgets/matrix.dart';
|
import 'package:fluffychat/widgets/matrix.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:famedlysdk/famedlysdk.dart';
|
import 'package:famedlysdk/famedlysdk.dart';
|
||||||
import 'package:flutter_gen/gen_l10n/l10n.dart';
|
import 'package:flutter_gen/gen_l10n/l10n.dart';
|
||||||
|
import 'package:vrouter/vrouter.dart';
|
||||||
|
|
||||||
class MultipleEmotesSettingsView extends StatelessWidget {
|
class MultipleEmotesSettingsView extends StatelessWidget {
|
||||||
final MultipleEmotesSettingsController controller;
|
final MultipleEmotesSettingsController controller;
|
||||||
@ -12,8 +12,7 @@ class MultipleEmotesSettingsView extends StatelessWidget {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
final room =
|
final room = Matrix.of(context).client.getRoomById(controller.roomId);
|
||||||
Matrix.of(context).client.getRoomById(controller.widget.roomId);
|
|
||||||
return Scaffold(
|
return Scaffold(
|
||||||
appBar: AppBar(
|
appBar: AppBar(
|
||||||
leading: BackButton(),
|
leading: BackButton(),
|
||||||
@ -45,13 +44,7 @@ class MultipleEmotesSettingsView extends StatelessWidget {
|
|||||||
return ListTile(
|
return ListTile(
|
||||||
title: Text(packName),
|
title: Text(packName),
|
||||||
onTap: () async {
|
onTap: () async {
|
||||||
await AdaptivePageLayout.of(context).pushNamed(
|
VRouter.of(context).push('/settings/emotes');
|
||||||
'/settings/emotes',
|
|
||||||
arguments: {
|
|
||||||
'room': room,
|
|
||||||
'stateKey': keys[i],
|
|
||||||
},
|
|
||||||
);
|
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import 'package:adaptive_dialog/adaptive_dialog.dart';
|
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/sentry_switch_list_tile.dart';
|
||||||
import 'package:fluffychat/widgets/settings_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/material.dart';
|
||||||
import 'package:flutter_gen/gen_l10n/l10n.dart';
|
import 'package:flutter_gen/gen_l10n/l10n.dart';
|
||||||
import 'package:url_launcher/url_launcher.dart';
|
import 'package:url_launcher/url_launcher.dart';
|
||||||
|
import 'package:vrouter/vrouter.dart';
|
||||||
|
|
||||||
import '../../widgets/content_banner.dart';
|
import '../../widgets/content_banner.dart';
|
||||||
import '../../widgets/matrix.dart';
|
import '../../widgets/matrix.dart';
|
||||||
@ -31,10 +32,6 @@ class SettingsView extends StatelessWidget {
|
|||||||
headerSliverBuilder: (BuildContext context, bool innerBoxIsScrolled) =>
|
headerSliverBuilder: (BuildContext context, bool innerBoxIsScrolled) =>
|
||||||
<Widget>[
|
<Widget>[
|
||||||
SliverAppBar(
|
SliverAppBar(
|
||||||
leading: IconButton(
|
|
||||||
icon: Icon(Icons.close_outlined),
|
|
||||||
onPressed: () => AdaptivePageLayout.of(context).popUntilIsFirst(),
|
|
||||||
),
|
|
||||||
expandedHeight: 300.0,
|
expandedHeight: 300.0,
|
||||||
floating: true,
|
floating: true,
|
||||||
pinned: true,
|
pinned: true,
|
||||||
@ -85,8 +82,7 @@ class SettingsView extends StatelessWidget {
|
|||||||
ListTile(
|
ListTile(
|
||||||
trailing: Icon(Icons.notifications_outlined),
|
trailing: Icon(Icons.notifications_outlined),
|
||||||
title: Text(L10n.of(context).notifications),
|
title: Text(L10n.of(context).notifications),
|
||||||
onTap: () => AdaptivePageLayout.of(context)
|
onTap: () => VRouter.of(context).push('/settings/notifications'),
|
||||||
.pushNamed('/settings/notifications'),
|
|
||||||
),
|
),
|
||||||
Divider(thickness: 1),
|
Divider(thickness: 1),
|
||||||
ListTile(
|
ListTile(
|
||||||
@ -100,8 +96,7 @@ class SettingsView extends StatelessWidget {
|
|||||||
),
|
),
|
||||||
ListTile(
|
ListTile(
|
||||||
title: Text(L10n.of(context).changeTheme),
|
title: Text(L10n.of(context).changeTheme),
|
||||||
onTap: () =>
|
onTap: () => VRouter.of(context).push('/settings/style'),
|
||||||
AdaptivePageLayout.of(context).pushNamed('/settings/style'),
|
|
||||||
trailing: Icon(Icons.style_outlined),
|
trailing: Icon(Icons.style_outlined),
|
||||||
),
|
),
|
||||||
SettingsSwitchListTile(
|
SettingsSwitchListTile(
|
||||||
@ -124,8 +119,7 @@ class SettingsView extends StatelessWidget {
|
|||||||
),
|
),
|
||||||
ListTile(
|
ListTile(
|
||||||
title: Text(L10n.of(context).emoteSettings),
|
title: Text(L10n.of(context).emoteSettings),
|
||||||
onTap: () =>
|
onTap: () => VRouter.of(context).push('/settings/emotes'),
|
||||||
AdaptivePageLayout.of(context).pushNamed('/settings/emotes'),
|
|
||||||
trailing: Icon(Icons.insert_emoticon_outlined),
|
trailing: Icon(Icons.insert_emoticon_outlined),
|
||||||
),
|
),
|
||||||
Divider(thickness: 1),
|
Divider(thickness: 1),
|
||||||
@ -154,14 +148,12 @@ class SettingsView extends StatelessWidget {
|
|||||||
ListTile(
|
ListTile(
|
||||||
trailing: Icon(Icons.devices_other_outlined),
|
trailing: Icon(Icons.devices_other_outlined),
|
||||||
title: Text(L10n.of(context).devices),
|
title: Text(L10n.of(context).devices),
|
||||||
onTap: () =>
|
onTap: () => VRouter.of(context).push('/settings/devices'),
|
||||||
AdaptivePageLayout.of(context).pushNamed('/settings/devices'),
|
|
||||||
),
|
),
|
||||||
ListTile(
|
ListTile(
|
||||||
trailing: Icon(Icons.block_outlined),
|
trailing: Icon(Icons.block_outlined),
|
||||||
title: Text(L10n.of(context).ignoredUsers),
|
title: Text(L10n.of(context).ignoredUsers),
|
||||||
onTap: () =>
|
onTap: () => VRouter.of(context).push('/settings/ignorelist'),
|
||||||
AdaptivePageLayout.of(context).pushNamed('/settings/ignore'),
|
|
||||||
),
|
),
|
||||||
SentrySwitchListTile(),
|
SentrySwitchListTile(),
|
||||||
Divider(thickness: 1),
|
Divider(thickness: 1),
|
||||||
@ -175,8 +167,7 @@ class SettingsView extends StatelessWidget {
|
|||||||
ListTile(
|
ListTile(
|
||||||
trailing: Icon(Icons.email_outlined),
|
trailing: Icon(Icons.email_outlined),
|
||||||
title: Text(L10n.of(context).passwordRecovery),
|
title: Text(L10n.of(context).passwordRecovery),
|
||||||
onTap: () =>
|
onTap: () => VRouter.of(context).push('/settings/3pid'),
|
||||||
AdaptivePageLayout.of(context).pushNamed('/settings/3pid'),
|
|
||||||
),
|
),
|
||||||
ListTile(
|
ListTile(
|
||||||
trailing: Icon(Icons.exit_to_app_outlined),
|
trailing: Icon(Icons.exit_to_app_outlined),
|
||||||
@ -215,7 +206,6 @@ class SettingsView extends StatelessWidget {
|
|||||||
title: L10n.of(context).yourPublicKey,
|
title: L10n.of(context).yourPublicKey,
|
||||||
message: client.fingerprintKey.beautified,
|
message: client.fingerprintKey.beautified,
|
||||||
okLabel: L10n.of(context).ok,
|
okLabel: L10n.of(context).ok,
|
||||||
useRootNavigator: false,
|
|
||||||
),
|
),
|
||||||
trailing: Icon(Icons.vpn_key_outlined),
|
trailing: Icon(Icons.vpn_key_outlined),
|
||||||
),
|
),
|
||||||
@ -236,7 +226,7 @@ class SettingsView extends StatelessWidget {
|
|||||||
fontWeight: FontWeight.bold,
|
fontWeight: FontWeight.bold,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
onTap: () => AdaptivePageLayout.of(context).pushNamed('/logs'),
|
onTap: () => VRouter.of(context).push('/logs'),
|
||||||
),
|
),
|
||||||
ListTile(
|
ListTile(
|
||||||
trailing: Icon(Icons.help_outlined),
|
trailing: Icon(Icons.help_outlined),
|
||||||
|
@ -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/pages/sign_up.dart';
|
||||||
import 'package:fluffychat/widgets/fluffy_banner.dart';
|
import 'package:fluffychat/widgets/fluffy_banner.dart';
|
||||||
|
|
||||||
@ -71,29 +71,29 @@ class SignUpView extends StatelessWidget {
|
|||||||
SizedBox(height: 8),
|
SizedBox(height: 8),
|
||||||
ListTile(
|
ListTile(
|
||||||
leading: CircleAvatar(
|
leading: CircleAvatar(
|
||||||
backgroundImage: controller.avatar == null
|
backgroundImage: SignUpController.avatar == null
|
||||||
? null
|
? null
|
||||||
: MemoryImage(controller.avatar.bytes),
|
: MemoryImage(SignUpController.avatar.bytes),
|
||||||
backgroundColor: controller.avatar == null
|
backgroundColor: SignUpController.avatar == null
|
||||||
? Theme.of(context).brightness == Brightness.dark
|
? Theme.of(context).brightness == Brightness.dark
|
||||||
? Color(0xff121212)
|
? Color(0xff121212)
|
||||||
: Colors.white
|
: Colors.white
|
||||||
: Theme.of(context).secondaryHeaderColor,
|
: Theme.of(context).secondaryHeaderColor,
|
||||||
child: controller.avatar == null
|
child: SignUpController.avatar == null
|
||||||
? Icon(Icons.camera_alt_outlined,
|
? Icon(Icons.camera_alt_outlined,
|
||||||
color: Theme.of(context).primaryColor)
|
color: Theme.of(context).primaryColor)
|
||||||
: null,
|
: null,
|
||||||
),
|
),
|
||||||
trailing: controller.avatar == null
|
trailing: SignUpController.avatar == null
|
||||||
? null
|
? null
|
||||||
: Icon(
|
: Icon(
|
||||||
Icons.close,
|
Icons.close,
|
||||||
color: Colors.red,
|
color: Colors.red,
|
||||||
),
|
),
|
||||||
title: Text(controller.avatar == null
|
title: Text(SignUpController.avatar == null
|
||||||
? L10n.of(context).setAProfilePicture
|
? L10n.of(context).setAProfilePicture
|
||||||
: L10n.of(context).discardPicture),
|
: L10n.of(context).discardPicture),
|
||||||
onTap: controller.avatar == null
|
onTap: SignUpController.avatar == null
|
||||||
? controller.setAvatarAction
|
? controller.setAvatarAction
|
||||||
: controller.resetAvatarAction,
|
: controller.resetAvatarAction,
|
||||||
),
|
),
|
||||||
@ -146,8 +146,7 @@ class SignUpView extends StatelessWidget {
|
|||||||
Theme.of(context).textTheme.bodyText1.color,
|
Theme.of(context).textTheme.bodyText1.color,
|
||||||
elevation: 2,
|
elevation: 2,
|
||||||
),
|
),
|
||||||
onPressed: () => AdaptivePageLayout.of(context)
|
onPressed: () => context.vRouter.push('/login'),
|
||||||
.pushNamed('/login'),
|
|
||||||
child: Text(L10n.of(context).login),
|
child: Text(L10n.of(context).login),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
@ -22,7 +22,6 @@ import 'dart:convert';
|
|||||||
import 'dart:io';
|
import 'dart:io';
|
||||||
import 'dart:ui';
|
import 'dart:ui';
|
||||||
|
|
||||||
import 'package:adaptive_page_layout/adaptive_page_layout.dart';
|
|
||||||
import 'package:famedlysdk/famedlysdk.dart';
|
import 'package:famedlysdk/famedlysdk.dart';
|
||||||
import 'package:fcm_shared_isolate/fcm_shared_isolate.dart';
|
import 'package:fcm_shared_isolate/fcm_shared_isolate.dart';
|
||||||
|
|
||||||
@ -34,6 +33,7 @@ import 'package:flutter_gen/gen_l10n/l10n.dart';
|
|||||||
import 'package:flutter_gen/gen_l10n/l10n_en.dart';
|
import 'package:flutter_gen/gen_l10n/l10n_en.dart';
|
||||||
import 'package:flutter_local_notifications/flutter_local_notifications.dart';
|
import 'package:flutter_local_notifications/flutter_local_notifications.dart';
|
||||||
import 'package:path_provider/path_provider.dart';
|
import 'package:path_provider/path_provider.dart';
|
||||||
|
import 'package:vrouter/vrouter.dart';
|
||||||
import 'platform_infos.dart';
|
import 'platform_infos.dart';
|
||||||
import '../config/app_config.dart';
|
import '../config/app_config.dart';
|
||||||
import '../config/setting_keys.dart';
|
import '../config/setting_keys.dart';
|
||||||
@ -51,7 +51,7 @@ class BackgroundPush {
|
|||||||
FlutterLocalNotificationsPlugin();
|
FlutterLocalNotificationsPlugin();
|
||||||
FluffyClient client;
|
FluffyClient client;
|
||||||
BuildContext context;
|
BuildContext context;
|
||||||
GlobalKey<AdaptivePageLayoutState> apl;
|
GlobalKey<VRouterState> router;
|
||||||
String _fcmToken;
|
String _fcmToken;
|
||||||
LoginState _loginState;
|
LoginState _loginState;
|
||||||
L10n l10n;
|
L10n l10n;
|
||||||
@ -95,10 +95,10 @@ class BackgroundPush {
|
|||||||
}
|
}
|
||||||
|
|
||||||
factory BackgroundPush(FluffyClient _client, BuildContext _context,
|
factory BackgroundPush(FluffyClient _client, BuildContext _context,
|
||||||
GlobalKey<AdaptivePageLayoutState> _apl) {
|
GlobalKey<VRouterState> router) {
|
||||||
final instance = BackgroundPush.clientOnly(_client);
|
final instance = BackgroundPush.clientOnly(_client);
|
||||||
instance.context = _context;
|
instance.context = _context;
|
||||||
instance.apl = _apl;
|
instance.router = router;
|
||||||
instance.fullInit();
|
instance.fullInit();
|
||||||
return instance;
|
return instance;
|
||||||
}
|
}
|
||||||
@ -235,7 +235,7 @@ class BackgroundPush {
|
|||||||
if (details == null ||
|
if (details == null ||
|
||||||
!details.didNotificationLaunchApp ||
|
!details.didNotificationLaunchApp ||
|
||||||
_wentToRoomOnStartup ||
|
_wentToRoomOnStartup ||
|
||||||
apl == null) {
|
router == null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
_wentToRoomOnStartup = true;
|
_wentToRoomOnStartup = true;
|
||||||
@ -249,7 +249,7 @@ class BackgroundPush {
|
|||||||
}
|
}
|
||||||
if (await store.getItemBool(SettingKeys.showNoGoogle, true)) {
|
if (await store.getItemBool(SettingKeys.showNoGoogle, true)) {
|
||||||
await loadLocale();
|
await loadLocale();
|
||||||
apl.currentState.showSnackBar(SnackBar(
|
ScaffoldMessenger.of(context).showSnackBar(SnackBar(
|
||||||
content: Text(
|
content: Text(
|
||||||
PlatformInfos.isAndroid
|
PlatformInfos.isAndroid
|
||||||
? l10n.noGoogleServicesWarning
|
? l10n.noGoogleServicesWarning
|
||||||
@ -280,10 +280,10 @@ class BackgroundPush {
|
|||||||
Future<void> goToRoom(String roomId) async {
|
Future<void> goToRoom(String roomId) async {
|
||||||
try {
|
try {
|
||||||
Logs().v('[Push] Attempting to go to room $roomId...');
|
Logs().v('[Push] Attempting to go to room $roomId...');
|
||||||
if (apl == null) {
|
if (router == null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
await apl.currentState.pushNamedAndRemoveUntilIsFirst('/rooms/$roomId');
|
router.currentState.push('/rooms/$roomId');
|
||||||
} catch (e, s) {
|
} catch (e, s) {
|
||||||
Logs().e('[Push] Failed to open room', e, s);
|
Logs().e('[Push] Failed to open room', e, s);
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,3 @@
|
|||||||
import 'package:adaptive_page_layout/adaptive_page_layout.dart';
|
|
||||||
import 'package:fluffychat/utils/platform_infos.dart';
|
import 'package:fluffychat/utils/platform_infos.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter/services.dart';
|
import 'package:flutter/services.dart';
|
||||||
@ -13,7 +12,7 @@ abstract class FluffyShare {
|
|||||||
await Clipboard.setData(
|
await Clipboard.setData(
|
||||||
ClipboardData(text: text),
|
ClipboardData(text: text),
|
||||||
);
|
);
|
||||||
AdaptivePageLayout.of(context).showSnackBar(
|
ScaffoldMessenger.of(context).showSnackBar(
|
||||||
SnackBar(content: Text(L10n.of(context).copiedToClipboard)));
|
SnackBar(content: Text(L10n.of(context).copiedToClipboard)));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -43,7 +43,6 @@ abstract class PlatformInfos {
|
|||||||
final version = await PlatformInfos.getVersion();
|
final version = await PlatformInfos.getVersion();
|
||||||
showAboutDialog(
|
showAboutDialog(
|
||||||
context: context,
|
context: context,
|
||||||
useRootNavigator: false,
|
|
||||||
children: [
|
children: [
|
||||||
Text('Version: $version'),
|
Text('Version: $version'),
|
||||||
OutlinedButton(
|
OutlinedButton(
|
||||||
|
@ -1,11 +1,12 @@
|
|||||||
import 'package:adaptive_dialog/adaptive_dialog.dart';
|
import 'package:adaptive_dialog/adaptive_dialog.dart';
|
||||||
import 'package:adaptive_page_layout/adaptive_page_layout.dart';
|
|
||||||
import 'package:famedlysdk/famedlysdk.dart';
|
import 'package:famedlysdk/famedlysdk.dart';
|
||||||
import 'package:future_loading_dialog/future_loading_dialog.dart';
|
import 'package:future_loading_dialog/future_loading_dialog.dart';
|
||||||
import 'package:fluffychat/widgets/matrix.dart';
|
import 'package:fluffychat/widgets/matrix.dart';
|
||||||
import 'package:fluffychat/config/app_config.dart';
|
import 'package:fluffychat/config/app_config.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:url_launcher/url_launcher.dart';
|
import 'package:url_launcher/url_launcher.dart';
|
||||||
|
import 'package:vrouter/vrouter.dart';
|
||||||
|
|
||||||
class UrlLauncher {
|
class UrlLauncher {
|
||||||
final String url;
|
final String url;
|
||||||
@ -60,11 +61,10 @@ class UrlLauncher {
|
|||||||
if (room != null) {
|
if (room != null) {
|
||||||
// we have the room, so....just open it
|
// we have the room, so....just open it
|
||||||
if (event != null) {
|
if (event != null) {
|
||||||
await AdaptivePageLayout.of(context)
|
VRouter.of(context)
|
||||||
.pushNamedAndRemoveUntilIsFirst('/rooms/${room.id}/$event');
|
.push('/rooms/${room.id}', queryParameters: {'event': event});
|
||||||
} else {
|
} else {
|
||||||
await AdaptivePageLayout.of(context)
|
VRouter.of(context).push('/rooms/${room.id}');
|
||||||
.pushNamedAndRemoveUntilIsFirst('/rooms/${room.id}');
|
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -72,7 +72,6 @@ class UrlLauncher {
|
|||||||
if (await showOkCancelAlertDialog(
|
if (await showOkCancelAlertDialog(
|
||||||
context: context,
|
context: context,
|
||||||
title: 'Join room $roomIdOrAlias',
|
title: 'Join room $roomIdOrAlias',
|
||||||
useRootNavigator: false,
|
|
||||||
) ==
|
) ==
|
||||||
OkCancelResult.ok) {
|
OkCancelResult.ok) {
|
||||||
roomId = roomIdOrAlias;
|
roomId = roomIdOrAlias;
|
||||||
@ -89,16 +88,15 @@ class UrlLauncher {
|
|||||||
context: context,
|
context: context,
|
||||||
future: () => Future.delayed(const Duration(seconds: 2)));
|
future: () => Future.delayed(const Duration(seconds: 2)));
|
||||||
if (event != null) {
|
if (event != null) {
|
||||||
await AdaptivePageLayout.of(context).pushNamedAndRemoveUntilIsFirst(
|
VRouter.of(context).push('/rooms/${response.result}/$event');
|
||||||
'/rooms/${response.result}/$event');
|
|
||||||
} else {
|
} else {
|
||||||
await AdaptivePageLayout.of(context)
|
VRouter.of(context).push('/rooms/${response.result}');
|
||||||
.pushNamedAndRemoveUntilIsFirst('/rooms/${response.result}');
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
await AdaptivePageLayout.of(context)
|
VRouter.of(context).push('/search', queryParameters: {
|
||||||
.pushNamedAndRemoveUntilIsFirst('/search/$roomIdOrAlias');
|
if (roomIdOrAlias != null) 'query': roomIdOrAlias
|
||||||
|
});
|
||||||
}
|
}
|
||||||
} else if (identityParts.primaryIdentifier.sigil == '@') {
|
} else if (identityParts.primaryIdentifier.sigil == '@') {
|
||||||
final user = User(
|
final user = User(
|
||||||
@ -107,8 +105,7 @@ class UrlLauncher {
|
|||||||
);
|
);
|
||||||
var roomId = matrix.client.getDirectChatFromUserId(user.id);
|
var roomId = matrix.client.getDirectChatFromUserId(user.id);
|
||||||
if (roomId != null) {
|
if (roomId != null) {
|
||||||
await AdaptivePageLayout.of(context)
|
VRouter.of(context).push('/rooms/$roomId');
|
||||||
.pushNamedAndRemoveUntilIsFirst('/rooms/$roomId');
|
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -116,7 +113,6 @@ class UrlLauncher {
|
|||||||
if (await showOkCancelAlertDialog(
|
if (await showOkCancelAlertDialog(
|
||||||
context: context,
|
context: context,
|
||||||
title: 'Message user ${user.id}',
|
title: 'Message user ${user.id}',
|
||||||
useRootNavigator: false,
|
|
||||||
) ==
|
) ==
|
||||||
OkCancelResult.ok) {
|
OkCancelResult.ok) {
|
||||||
roomId = (await showFutureLoadingDialog(
|
roomId = (await showFutureLoadingDialog(
|
||||||
@ -126,8 +122,7 @@ class UrlLauncher {
|
|||||||
.result;
|
.result;
|
||||||
|
|
||||||
if (roomId != null) {
|
if (roomId != null) {
|
||||||
await AdaptivePageLayout.of(context)
|
VRouter.of(context).push('/rooms/$roomId');
|
||||||
.pushNamedAndRemoveUntilIsFirst('/rooms/$roomId');
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,12 +1,13 @@
|
|||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
|
|
||||||
import 'package:adaptive_dialog/adaptive_dialog.dart';
|
import 'package:adaptive_dialog/adaptive_dialog.dart';
|
||||||
import 'package:adaptive_page_layout/adaptive_page_layout.dart';
|
|
||||||
import 'package:famedlysdk/famedlysdk.dart';
|
import 'package:famedlysdk/famedlysdk.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_gen/gen_l10n/l10n.dart';
|
import 'package:flutter_gen/gen_l10n/l10n.dart';
|
||||||
|
|
||||||
import 'package:future_loading_dialog/future_loading_dialog.dart';
|
import 'package:future_loading_dialog/future_loading_dialog.dart';
|
||||||
|
import 'package:vrouter/vrouter.dart';
|
||||||
import 'matrix.dart';
|
import 'matrix.dart';
|
||||||
|
|
||||||
class ChatSettingsPopupMenu extends StatefulWidget {
|
class ChatSettingsPopupMenu extends StatefulWidget {
|
||||||
@ -68,7 +69,6 @@ class _ChatSettingsPopupMenuState extends State<ChatSettingsPopupMenu> {
|
|||||||
case 'leave':
|
case 'leave':
|
||||||
final confirmed = await showOkCancelAlertDialog(
|
final confirmed = await showOkCancelAlertDialog(
|
||||||
context: context,
|
context: context,
|
||||||
useRootNavigator: false,
|
|
||||||
title: L10n.of(context).areYouSure,
|
title: L10n.of(context).areYouSure,
|
||||||
okLabel: L10n.of(context).ok,
|
okLabel: L10n.of(context).ok,
|
||||||
cancelLabel: L10n.of(context).cancel,
|
cancelLabel: L10n.of(context).cancel,
|
||||||
@ -77,8 +77,7 @@ class _ChatSettingsPopupMenuState extends State<ChatSettingsPopupMenu> {
|
|||||||
final success = await showFutureLoadingDialog(
|
final success = await showFutureLoadingDialog(
|
||||||
context: context, future: () => widget.room.leave());
|
context: context, future: () => widget.room.leave());
|
||||||
if (success.error == null) {
|
if (success.error == null) {
|
||||||
await AdaptivePageLayout.of(context)
|
VRouter.of(context).push('/rooms');
|
||||||
.pushNamedAndRemoveAllOthers('/');
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -95,12 +94,7 @@ class _ChatSettingsPopupMenuState extends State<ChatSettingsPopupMenu> {
|
|||||||
widget.room.setPushRuleState(PushRuleState.notify));
|
widget.room.setPushRuleState(PushRuleState.notify));
|
||||||
break;
|
break;
|
||||||
case 'details':
|
case 'details':
|
||||||
if (!AdaptivePageLayout.of(context).columnMode(context) ||
|
VRouter.of(context).push('/rooms/${widget.room.id}/details');
|
||||||
AdaptivePageLayout.of(context).viewDataStack.length < 3) {
|
|
||||||
await AdaptivePageLayout.of(context)
|
|
||||||
.pushNamed('/rooms/${widget.room.id}/details');
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -4,9 +4,9 @@ import 'package:famedlysdk/famedlysdk.dart';
|
|||||||
import 'package:fluffychat/widgets/avatar.dart';
|
import 'package:fluffychat/widgets/avatar.dart';
|
||||||
import 'package:fluffychat/widgets/matrix.dart';
|
import 'package:fluffychat/widgets/matrix.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:vrouter/vrouter.dart';
|
||||||
import '../utils/matrix_sdk_extensions.dart/client_presence_extension.dart';
|
import '../utils/matrix_sdk_extensions.dart/client_presence_extension.dart';
|
||||||
import '../utils/matrix_sdk_extensions.dart/presence_extension.dart';
|
import '../utils/matrix_sdk_extensions.dart/presence_extension.dart';
|
||||||
import 'package:adaptive_page_layout/adaptive_page_layout.dart';
|
|
||||||
|
|
||||||
class ContactsList extends StatefulWidget {
|
class ContactsList extends StatefulWidget {
|
||||||
final TextEditingController searchController;
|
final TextEditingController searchController;
|
||||||
@ -102,9 +102,8 @@ class _ContactListTile extends StatelessWidget {
|
|||||||
fontWeight: FontWeight.bold,
|
fontWeight: FontWeight.bold,
|
||||||
)
|
)
|
||||||
: null),
|
: null),
|
||||||
onTap: () => AdaptivePageLayout.of(context)
|
onTap: () => VRouter.of(context).push(
|
||||||
.pushNamedAndRemoveUntilIsFirst(
|
'/rooms/${Matrix.of(context).client.getDirectChatFromUserId(contact.senderId)}'),
|
||||||
'/rooms/${Matrix.of(context).client.getDirectChatFromUserId(contact.senderId)}'),
|
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -1,12 +1,12 @@
|
|||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
|
|
||||||
import 'package:adaptive_dialog/adaptive_dialog.dart';
|
import 'package:adaptive_dialog/adaptive_dialog.dart';
|
||||||
import 'package:adaptive_page_layout/adaptive_page_layout.dart';
|
|
||||||
import 'package:famedlysdk/famedlysdk.dart';
|
import 'package:famedlysdk/famedlysdk.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_gen/gen_l10n/l10n.dart';
|
import 'package:flutter_gen/gen_l10n/l10n.dart';
|
||||||
|
|
||||||
import 'package:future_loading_dialog/future_loading_dialog.dart';
|
import 'package:future_loading_dialog/future_loading_dialog.dart';
|
||||||
|
import 'package:vrouter/vrouter.dart';
|
||||||
import 'matrix.dart';
|
import 'matrix.dart';
|
||||||
|
|
||||||
class EncryptionButton extends StatefulWidget {
|
class EncryptionButton extends StatefulWidget {
|
||||||
@ -21,14 +21,13 @@ class _EncryptionButtonState extends State<EncryptionButton> {
|
|||||||
|
|
||||||
void _enableEncryptionAction() async {
|
void _enableEncryptionAction() async {
|
||||||
if (widget.room.encrypted) {
|
if (widget.room.encrypted) {
|
||||||
await AdaptivePageLayout.of(context)
|
VRouter.of(context).push('/rooms/${widget.room.id}/encryption');
|
||||||
.pushNamed('/rooms/${widget.room.id}/encryption');
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (widget.room.joinRules == JoinRules.public) {
|
if (widget.room.joinRules == JoinRules.public) {
|
||||||
await showOkAlertDialog(
|
await showOkAlertDialog(
|
||||||
context: context,
|
context: context,
|
||||||
useRootNavigator: false,
|
|
||||||
okLabel: L10n.of(context).ok,
|
okLabel: L10n.of(context).ok,
|
||||||
message: L10n.of(context).noEncryptionForPublicRooms,
|
message: L10n.of(context).noEncryptionForPublicRooms,
|
||||||
);
|
);
|
||||||
@ -36,7 +35,7 @@ class _EncryptionButtonState extends State<EncryptionButton> {
|
|||||||
}
|
}
|
||||||
if (await showOkCancelAlertDialog(
|
if (await showOkCancelAlertDialog(
|
||||||
context: context,
|
context: context,
|
||||||
useRootNavigator: false,
|
|
||||||
title: L10n.of(context).enableEncryption,
|
title: L10n.of(context).enableEncryption,
|
||||||
message: widget.room.client.encryptionEnabled
|
message: widget.room.client.encryptionEnabled
|
||||||
? L10n.of(context).enableEncryptionWarning
|
? L10n.of(context).enableEncryptionWarning
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
import 'dart:io';
|
import 'dart:io';
|
||||||
|
|
||||||
import 'package:adaptive_page_layout/adaptive_page_layout.dart';
|
|
||||||
import 'package:audioplayers/audioplayers.dart';
|
import 'package:audioplayers/audioplayers.dart';
|
||||||
import 'package:famedlysdk/famedlysdk.dart';
|
import 'package:famedlysdk/famedlysdk.dart';
|
||||||
import 'package:fluffychat/utils/sentry_controller.dart';
|
import 'package:fluffychat/utils/sentry_controller.dart';
|
||||||
@ -95,7 +94,7 @@ class _AudioPlayerState extends State<AudioPlayerWidget> {
|
|||||||
_playAction();
|
_playAction();
|
||||||
} catch (e, s) {
|
} catch (e, s) {
|
||||||
Logs().v('Could not download audio file', e, s);
|
Logs().v('Could not download audio file', e, s);
|
||||||
AdaptivePageLayout.of(context).showSnackBar(
|
ScaffoldMessenger.of(context).showSnackBar(
|
||||||
SnackBar(
|
SnackBar(
|
||||||
content: Text(e.toLocalizedString(context)),
|
content: Text(e.toLocalizedString(context)),
|
||||||
),
|
),
|
||||||
@ -135,7 +134,7 @@ class _AudioPlayerState extends State<AudioPlayerWidget> {
|
|||||||
onPlayerStateChanged ??= audioPlayer.onPlayerStateChanged
|
onPlayerStateChanged ??= audioPlayer.onPlayerStateChanged
|
||||||
.listen((_) => setState(() => null));
|
.listen((_) => setState(() => null));
|
||||||
onPlayerError ??= audioPlayer.onPlayerError.listen((e) {
|
onPlayerError ??= audioPlayer.onPlayerError.listen((e) {
|
||||||
AdaptivePageLayout.of(context).showSnackBar(
|
ScaffoldMessenger.of(context).showSnackBar(
|
||||||
SnackBar(
|
SnackBar(
|
||||||
content: Text(L10n.of(context).oopsSomethingWentWrong),
|
content: Text(L10n.of(context).oopsSomethingWentWrong),
|
||||||
),
|
),
|
||||||
|
@ -1,4 +1,3 @@
|
|||||||
import 'package:adaptive_page_layout/adaptive_page_layout.dart';
|
|
||||||
import 'package:famedlysdk/encryption/utils/key_verification.dart';
|
import 'package:famedlysdk/encryption/utils/key_verification.dart';
|
||||||
import 'package:famedlysdk/famedlysdk.dart';
|
import 'package:famedlysdk/famedlysdk.dart';
|
||||||
import 'package:fluffychat/widgets/event_content/audio_player.dart';
|
import 'package:fluffychat/widgets/event_content/audio_player.dart';
|
||||||
@ -27,7 +26,7 @@ class MessageContent extends StatelessWidget {
|
|||||||
|
|
||||||
void _verifyOrRequestKey(BuildContext context) async {
|
void _verifyOrRequestKey(BuildContext context) async {
|
||||||
if (event.content['can_request_session'] != true) {
|
if (event.content['can_request_session'] != true) {
|
||||||
AdaptivePageLayout.of(context).showSnackBar(SnackBar(
|
ScaffoldMessenger.of(context).showSnackBar(SnackBar(
|
||||||
content: Text(
|
content: Text(
|
||||||
event.type == EventTypes.Encrypted
|
event.type == EventTypes.Encrypted
|
||||||
? L10n.of(context).needPantalaimonWarning
|
? L10n.of(context).needPantalaimonWarning
|
||||||
@ -61,7 +60,7 @@ class MessageContent extends StatelessWidget {
|
|||||||
future: () => event.requestKey(),
|
future: () => event.requestKey(),
|
||||||
);
|
);
|
||||||
if (success.error == null) {
|
if (success.error == null) {
|
||||||
AdaptivePageLayout.of(context).showSnackBar(SnackBar(
|
ScaffoldMessenger.of(context).showSnackBar(SnackBar(
|
||||||
content: Text(L10n.of(context).requestToReadOlderMessages)));
|
content: Text(L10n.of(context).requestToReadOlderMessages)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
import 'package:adaptive_page_layout/adaptive_page_layout.dart';
|
import 'package:famedlysdk/famedlysdk.dart';
|
||||||
|
import 'package:vrouter/vrouter.dart';
|
||||||
import 'package:fluffychat/widgets/matrix.dart';
|
import 'package:fluffychat/widgets/matrix.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
@ -6,8 +7,10 @@ class LoadingView extends StatelessWidget {
|
|||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
if (Matrix.of(context).loginState != null) {
|
if (Matrix.of(context).loginState != null) {
|
||||||
WidgetsBinding.instance.addPostFrameCallback((_) =>
|
WidgetsBinding.instance.addPostFrameCallback((_) => context.vRouter.push(
|
||||||
AdaptivePageLayout.of(context).pushNamedAndRemoveAllOthers('/'));
|
Matrix.of(context).loginState == LoginState.logged
|
||||||
|
? '/rooms'
|
||||||
|
: '/home'));
|
||||||
}
|
}
|
||||||
return Scaffold(body: Center(child: CircularProgressIndicator()));
|
return Scaffold(body: Center(child: CircularProgressIndicator()));
|
||||||
}
|
}
|
||||||
|
40
lib/widgets/layouts/two_column_layout.dart
Normal file
40
lib/widgets/layouts/two_column_layout.dart
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
import 'package:fluffychat/config/app_config.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
|
class TwoColumnLayout extends StatelessWidget {
|
||||||
|
final Widget mainView;
|
||||||
|
final Widget sideView;
|
||||||
|
|
||||||
|
const TwoColumnLayout(
|
||||||
|
{Key key, @required this.mainView, @required this.sideView})
|
||||||
|
: super(key: key);
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
if (MediaQuery.of(context).size.width <= AppConfig.columnWidth * 2) {
|
||||||
|
return mainView;
|
||||||
|
}
|
||||||
|
return Scaffold(
|
||||||
|
body: ScaffoldMessenger(
|
||||||
|
child: Row(
|
||||||
|
children: [
|
||||||
|
Container(
|
||||||
|
clipBehavior: Clip.antiAlias,
|
||||||
|
decoration: BoxDecoration(),
|
||||||
|
width: 360.0,
|
||||||
|
child: mainView,
|
||||||
|
),
|
||||||
|
Container(
|
||||||
|
width: 1.0,
|
||||||
|
color: Theme.of(context).dividerColor,
|
||||||
|
),
|
||||||
|
Expanded(
|
||||||
|
child: ClipRRect(
|
||||||
|
child: sideView,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
@ -1,5 +1,5 @@
|
|||||||
import 'package:adaptive_dialog/adaptive_dialog.dart';
|
import 'package:adaptive_dialog/adaptive_dialog.dart';
|
||||||
import 'package:adaptive_page_layout/adaptive_page_layout.dart';
|
|
||||||
import 'package:famedlysdk/famedlysdk.dart';
|
import 'package:famedlysdk/famedlysdk.dart';
|
||||||
import 'package:fluffychat/config/themes.dart';
|
import 'package:fluffychat/config/themes.dart';
|
||||||
import 'package:fluffychat/utils/matrix_sdk_extensions.dart/event_extension.dart';
|
import 'package:fluffychat/utils/matrix_sdk_extensions.dart/event_extension.dart';
|
||||||
@ -9,6 +9,7 @@ import 'package:fluffychat/utils/room_status_extension.dart';
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_gen/gen_l10n/l10n.dart';
|
import 'package:flutter_gen/gen_l10n/l10n.dart';
|
||||||
import 'package:pedantic/pedantic.dart';
|
import 'package:pedantic/pedantic.dart';
|
||||||
|
import 'package:vrouter/vrouter.dart';
|
||||||
|
|
||||||
import '../../utils/date_time_extension.dart';
|
import '../../utils/date_time_extension.dart';
|
||||||
import '../avatar.dart';
|
import '../avatar.dart';
|
||||||
@ -46,7 +47,7 @@ class ChatListItem extends StatelessWidget {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (room.membership == Membership.ban) {
|
if (room.membership == Membership.ban) {
|
||||||
AdaptivePageLayout.of(context).showSnackBar(
|
ScaffoldMessenger.of(context).showSnackBar(
|
||||||
SnackBar(
|
SnackBar(
|
||||||
content: Text(L10n.of(context).youHaveBeenBannedFromThisChat),
|
content: Text(L10n.of(context).youHaveBeenBannedFromThisChat),
|
||||||
),
|
),
|
||||||
@ -96,15 +97,13 @@ class ChatListItem extends StatelessWidget {
|
|||||||
file: Matrix.of(context).shareContent['file'],
|
file: Matrix.of(context).shareContent['file'],
|
||||||
room: room,
|
room: room,
|
||||||
),
|
),
|
||||||
useRootNavigator: false,
|
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
unawaited(room.sendEvent(Matrix.of(context).shareContent));
|
unawaited(room.sendEvent(Matrix.of(context).shareContent));
|
||||||
}
|
}
|
||||||
Matrix.of(context).shareContent = null;
|
Matrix.of(context).shareContent = null;
|
||||||
}
|
}
|
||||||
await AdaptivePageLayout.of(context)
|
context.vRouter.push('/rooms/${room.id}');
|
||||||
.pushNamedAndRemoveUntilIsFirst('/rooms/${room.id}');
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -126,7 +125,6 @@ class ChatListItem extends StatelessWidget {
|
|||||||
title: L10n.of(context).areYouSure,
|
title: L10n.of(context).areYouSure,
|
||||||
okLabel: L10n.of(context).yes,
|
okLabel: L10n.of(context).yes,
|
||||||
cancelLabel: L10n.of(context).no,
|
cancelLabel: L10n.of(context).no,
|
||||||
useRootNavigator: false,
|
|
||||||
);
|
);
|
||||||
if (confirmed == OkCancelResult.cancel) return;
|
if (confirmed == OkCancelResult.cancel) return;
|
||||||
await showFutureLoadingDialog(
|
await showFutureLoadingDialog(
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
import 'package:adaptive_page_layout/adaptive_page_layout.dart';
|
|
||||||
import 'package:famedlysdk/famedlysdk.dart';
|
import 'package:famedlysdk/famedlysdk.dart';
|
||||||
import 'package:future_loading_dialog/future_loading_dialog.dart';
|
import 'package:future_loading_dialog/future_loading_dialog.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_gen/gen_l10n/l10n.dart';
|
import 'package:flutter_gen/gen_l10n/l10n.dart';
|
||||||
|
import 'package:vrouter/vrouter.dart';
|
||||||
|
|
||||||
import '../avatar.dart';
|
import '../avatar.dart';
|
||||||
import '../matrix.dart';
|
import '../matrix.dart';
|
||||||
@ -18,8 +18,7 @@ class PublicRoomListItem extends StatelessWidget {
|
|||||||
future: () => _joinRoomAndWait(context),
|
future: () => _joinRoomAndWait(context),
|
||||||
);
|
);
|
||||||
if (success.error == null) {
|
if (success.error == null) {
|
||||||
await AdaptivePageLayout.of(context)
|
VRouter.of(context).pushNamed('/rooms/${success.result}');
|
||||||
.pushNamed('/rooms/${success.result}');
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -13,7 +13,7 @@ class _LogViewerState extends State<LogViewer> {
|
|||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
final outputEvents = Logs()
|
final outputEvents = Logs()
|
||||||
.outputEvents
|
.outputEvents
|
||||||
.where((e) => e.level.index >= logLevel.index)
|
.where((e) => e.level.index <= logLevel.index)
|
||||||
.toList();
|
.toList();
|
||||||
return Scaffold(
|
return Scaffold(
|
||||||
backgroundColor: Colors.black,
|
backgroundColor: Colors.black,
|
||||||
@ -44,7 +44,12 @@ class _LogViewerState extends State<LogViewer> {
|
|||||||
itemCount: outputEvents.length,
|
itemCount: outputEvents.length,
|
||||||
itemBuilder: (context, i) => SingleChildScrollView(
|
itemBuilder: (context, i) => SingleChildScrollView(
|
||||||
scrollDirection: Axis.horizontal,
|
scrollDirection: Axis.horizontal,
|
||||||
child: Text(outputEvents[i].toDisplayString()),
|
child: SelectableText(
|
||||||
|
outputEvents[i].toDisplayString(),
|
||||||
|
style: TextStyle(
|
||||||
|
color: outputEvents[i].color,
|
||||||
|
),
|
||||||
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
@ -52,8 +57,26 @@ class _LogViewerState extends State<LogViewer> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
extension on LogEvent {
|
extension on LogEvent {
|
||||||
|
Color get color {
|
||||||
|
switch (level) {
|
||||||
|
case Level.wtf:
|
||||||
|
return Colors.purple;
|
||||||
|
case Level.error:
|
||||||
|
return Colors.red;
|
||||||
|
case Level.warning:
|
||||||
|
return Colors.orange;
|
||||||
|
case Level.info:
|
||||||
|
return Colors.green;
|
||||||
|
case Level.debug:
|
||||||
|
return Colors.white;
|
||||||
|
case Level.verbose:
|
||||||
|
default:
|
||||||
|
return Colors.grey;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
String toDisplayString() {
|
String toDisplayString() {
|
||||||
var str = '# $title';
|
var str = '# [${level.toString().split('.').last.toUpperCase()}] $title';
|
||||||
if (exception != null) {
|
if (exception != null) {
|
||||||
str += ' - ${exception.toString()}';
|
str += ' - ${exception.toString()}';
|
||||||
}
|
}
|
||||||
|
@ -3,7 +3,6 @@ import 'dart:io';
|
|||||||
import 'dart:convert';
|
import 'dart:convert';
|
||||||
|
|
||||||
import 'package:adaptive_dialog/adaptive_dialog.dart';
|
import 'package:adaptive_dialog/adaptive_dialog.dart';
|
||||||
import 'package:adaptive_page_layout/adaptive_page_layout.dart';
|
|
||||||
import 'package:famedlysdk/encryption.dart';
|
import 'package:famedlysdk/encryption.dart';
|
||||||
import 'package:famedlysdk/famedlysdk.dart';
|
import 'package:famedlysdk/famedlysdk.dart';
|
||||||
import 'package:fluffychat/utils/matrix_sdk_extensions.dart/matrix_locals.dart';
|
import 'package:fluffychat/utils/matrix_sdk_extensions.dart/matrix_locals.dart';
|
||||||
@ -14,7 +13,6 @@ import 'package:flutter/material.dart';
|
|||||||
import 'package:flutter_app_lock/flutter_app_lock.dart';
|
import 'package:flutter_app_lock/flutter_app_lock.dart';
|
||||||
import 'package:flutter_gen/gen_l10n/l10n.dart';
|
import 'package:flutter_gen/gen_l10n/l10n.dart';
|
||||||
import 'package:flutter_secure_storage/flutter_secure_storage.dart';
|
import 'package:flutter_secure_storage/flutter_secure_storage.dart';
|
||||||
import 'package:future_loading_dialog/future_loading_dialog.dart';
|
|
||||||
import 'package:provider/provider.dart';
|
import 'package:provider/provider.dart';
|
||||||
import 'package:universal_html/html.dart' as html;
|
import 'package:universal_html/html.dart' as html;
|
||||||
import 'package:http/http.dart' as http;
|
import 'package:http/http.dart' as http;
|
||||||
@ -22,7 +20,6 @@ import 'package:url_launcher/url_launcher.dart';
|
|||||||
import 'package:desktop_notifications/desktop_notifications.dart';
|
import 'package:desktop_notifications/desktop_notifications.dart';
|
||||||
|
|
||||||
import '../utils/beautify_string_extension.dart';
|
import '../utils/beautify_string_extension.dart';
|
||||||
import '../utils/localized_exception_extension.dart';
|
|
||||||
import '../utils/famedlysdk_store.dart';
|
import '../utils/famedlysdk_store.dart';
|
||||||
import '../pages/key_verification_dialog.dart';
|
import '../pages/key_verification_dialog.dart';
|
||||||
import '../utils/platform_infos.dart';
|
import '../utils/platform_infos.dart';
|
||||||
@ -30,13 +27,14 @@ import '../config/app_config.dart';
|
|||||||
import '../config/setting_keys.dart';
|
import '../config/setting_keys.dart';
|
||||||
import '../utils/matrix_sdk_extensions.dart/fluffy_client.dart';
|
import '../utils/matrix_sdk_extensions.dart/fluffy_client.dart';
|
||||||
import '../utils/background_push.dart';
|
import '../utils/background_push.dart';
|
||||||
|
import 'package:vrouter/vrouter.dart';
|
||||||
|
|
||||||
class Matrix extends StatefulWidget {
|
class Matrix extends StatefulWidget {
|
||||||
static const String callNamespace = 'chat.fluffy.jitsi_call';
|
static const String callNamespace = 'chat.fluffy.jitsi_call';
|
||||||
|
|
||||||
final Widget child;
|
final Widget child;
|
||||||
|
|
||||||
final GlobalKey<AdaptivePageLayoutState> apl;
|
final GlobalKey<VRouterState> router;
|
||||||
|
|
||||||
final BuildContext context;
|
final BuildContext context;
|
||||||
|
|
||||||
@ -44,7 +42,7 @@ class Matrix extends StatefulWidget {
|
|||||||
|
|
||||||
Matrix({
|
Matrix({
|
||||||
this.child,
|
this.child,
|
||||||
@required this.apl,
|
@required this.router,
|
||||||
@required this.context,
|
@required this.context,
|
||||||
this.testClient,
|
this.testClient,
|
||||||
Key key,
|
Key key,
|
||||||
@ -137,7 +135,6 @@ class MatrixState extends State<Matrix> with WidgetsBindingObserver {
|
|||||||
title: L10n.of(context).pleaseEnterYourPassword,
|
title: L10n.of(context).pleaseEnterYourPassword,
|
||||||
okLabel: L10n.of(context).ok,
|
okLabel: L10n.of(context).ok,
|
||||||
cancelLabel: L10n.of(context).cancel,
|
cancelLabel: L10n.of(context).cancel,
|
||||||
useRootNavigator: false,
|
|
||||||
textFields: [
|
textFields: [
|
||||||
DialogTextField(
|
DialogTextField(
|
||||||
minLines: 1,
|
minLines: 1,
|
||||||
@ -190,7 +187,6 @@ class MatrixState extends State<Matrix> with WidgetsBindingObserver {
|
|||||||
await showOkCancelAlertDialog(
|
await showOkCancelAlertDialog(
|
||||||
message: L10n.of(context).pleaseFollowInstructionsOnWeb,
|
message: L10n.of(context).pleaseFollowInstructionsOnWeb,
|
||||||
context: context,
|
context: context,
|
||||||
useRootNavigator: false,
|
|
||||||
okLabel: L10n.of(context).next,
|
okLabel: L10n.of(context).next,
|
||||||
cancelLabel: L10n.of(context).cancel,
|
cancelLabel: L10n.of(context).cancel,
|
||||||
)) {
|
)) {
|
||||||
@ -287,9 +283,6 @@ class MatrixState extends State<Matrix> with WidgetsBindingObserver {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
client = FluffyClient();
|
client = FluffyClient();
|
||||||
LoadingDialog.defaultTitle = L10n.of(context).loadingPleaseWait;
|
|
||||||
LoadingDialog.defaultBackLabel = L10n.of(context).close;
|
|
||||||
LoadingDialog.defaultOnError = (Object e) => e.toLocalizedString(context);
|
|
||||||
|
|
||||||
onRoomKeyRequestSub ??=
|
onRoomKeyRequestSub ??=
|
||||||
client.onRoomKeyRequest.stream.listen((RoomKeyRequest request) async {
|
client.onRoomKeyRequest.stream.listen((RoomKeyRequest request) async {
|
||||||
@ -300,7 +293,6 @@ class MatrixState extends State<Matrix> with WidgetsBindingObserver {
|
|||||||
final sender = room.getUserByMXIDSync(request.sender);
|
final sender = room.getUserByMXIDSync(request.sender);
|
||||||
if (await showOkCancelAlertDialog(
|
if (await showOkCancelAlertDialog(
|
||||||
context: context,
|
context: context,
|
||||||
useRootNavigator: false,
|
|
||||||
title: L10n.of(context).requestToReadOlderMessages,
|
title: L10n.of(context).requestToReadOlderMessages,
|
||||||
message:
|
message:
|
||||||
'${sender.id}\n\n${L10n.of(context).device}:\n${request.requestingDevice.deviceId}\n\n${L10n.of(context).publicKey}:\n${request.requestingDevice.ed25519Key.beautified}',
|
'${sender.id}\n\n${L10n.of(context).device}:\n${request.requestingDevice.deviceId}\n\n${L10n.of(context).publicKey}:\n${request.requestingDevice.ed25519Key.beautified}',
|
||||||
@ -324,7 +316,6 @@ class MatrixState extends State<Matrix> with WidgetsBindingObserver {
|
|||||||
};
|
};
|
||||||
if (await showOkCancelAlertDialog(
|
if (await showOkCancelAlertDialog(
|
||||||
context: context,
|
context: context,
|
||||||
useRootNavigator: false,
|
|
||||||
title: L10n.of(context).newVerificationRequest,
|
title: L10n.of(context).newVerificationRequest,
|
||||||
message: L10n.of(context).askVerificationRequest(request.userId),
|
message: L10n.of(context).askVerificationRequest(request.userId),
|
||||||
okLabel: L10n.of(context).ok,
|
okLabel: L10n.of(context).ok,
|
||||||
@ -350,7 +341,8 @@ class MatrixState extends State<Matrix> with WidgetsBindingObserver {
|
|||||||
onLoginStateChanged ??= client.onLoginStateChanged.stream.listen((state) {
|
onLoginStateChanged ??= client.onLoginStateChanged.stream.listen((state) {
|
||||||
if (loginState != state) {
|
if (loginState != state) {
|
||||||
loginState = state;
|
loginState = state;
|
||||||
widget.apl.currentState.pushNamedAndRemoveAllOthers('/');
|
widget.router.currentState
|
||||||
|
.push(loginState == LoginState.logged ? '/rooms' : '/home');
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -380,7 +372,7 @@ class MatrixState extends State<Matrix> with WidgetsBindingObserver {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (PlatformInfos.isMobile) {
|
if (PlatformInfos.isMobile) {
|
||||||
_backgroundPush = BackgroundPush(client, context, widget.apl);
|
_backgroundPush = BackgroundPush(client, context, widget.router);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
35
pubspec.lock
35
pubspec.lock
@ -15,13 +15,6 @@ packages:
|
|||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.10.0+5"
|
version: "0.10.0+5"
|
||||||
adaptive_page_layout:
|
|
||||||
dependency: "direct main"
|
|
||||||
description:
|
|
||||||
name: adaptive_page_layout
|
|
||||||
url: "https://pub.dartlang.org"
|
|
||||||
source: hosted
|
|
||||||
version: "0.2.4"
|
|
||||||
adaptive_theme:
|
adaptive_theme:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
@ -627,6 +620,13 @@ packages:
|
|||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "4.2.1"
|
version: "4.2.1"
|
||||||
|
move_to_background:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: move_to_background
|
||||||
|
url: "https://pub.dartlang.org"
|
||||||
|
source: hosted
|
||||||
|
version: "1.0.2"
|
||||||
native_imaging:
|
native_imaging:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
@ -762,6 +762,13 @@ packages:
|
|||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.0.0"
|
version: "2.0.0"
|
||||||
|
path_to_regexp:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: path_to_regexp
|
||||||
|
url: "https://pub.dartlang.org"
|
||||||
|
source: hosted
|
||||||
|
version: "0.4.0"
|
||||||
pedantic:
|
pedantic:
|
||||||
dependency: "direct dev"
|
dependency: "direct dev"
|
||||||
description:
|
description:
|
||||||
@ -1187,6 +1194,13 @@ packages:
|
|||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.0.0"
|
version: "2.0.0"
|
||||||
|
url_strategy:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: url_strategy
|
||||||
|
url: "https://pub.dartlang.org"
|
||||||
|
source: hosted
|
||||||
|
version: "0.2.0"
|
||||||
uuid:
|
uuid:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@ -1208,6 +1222,13 @@ packages:
|
|||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "4.2.0"
|
version: "4.2.0"
|
||||||
|
vrouter:
|
||||||
|
dependency: "direct main"
|
||||||
|
description:
|
||||||
|
name: vrouter
|
||||||
|
url: "https://pub.dartlang.org"
|
||||||
|
source: hosted
|
||||||
|
version: "1.1.2+5"
|
||||||
watcher:
|
watcher:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
@ -8,7 +8,6 @@ environment:
|
|||||||
|
|
||||||
dependencies:
|
dependencies:
|
||||||
adaptive_dialog: ^0.10.0+5
|
adaptive_dialog: ^0.10.0+5
|
||||||
adaptive_page_layout: ^0.2.4
|
|
||||||
adaptive_theme: ^2.2.0
|
adaptive_theme: ^2.2.0
|
||||||
android_path_provider: ^0.2.1
|
android_path_provider: ^0.2.1
|
||||||
audioplayers: ^0.18.3
|
audioplayers: ^0.18.3
|
||||||
@ -70,6 +69,7 @@ dependencies:
|
|||||||
unifiedpush: ^1.0.2
|
unifiedpush: ^1.0.2
|
||||||
universal_html: ^2.0.8
|
universal_html: ^2.0.8
|
||||||
url_launcher: ^6.0.3
|
url_launcher: ^6.0.3
|
||||||
|
vrouter: ^1.1.2+5
|
||||||
|
|
||||||
dev_dependencies:
|
dev_dependencies:
|
||||||
dapackages: ^1.6.0
|
dapackages: ^1.6.0
|
||||||
|
@ -6,10 +6,7 @@ void main() {
|
|||||||
testWidgets('Test if the widget can be created', (WidgetTester tester) async {
|
testWidgets('Test if the widget can be created', (WidgetTester tester) async {
|
||||||
await tester.pumpWidget(
|
await tester.pumpWidget(
|
||||||
FluffyChatApp(
|
FluffyChatApp(
|
||||||
testWidget: SignUpPassword(
|
testWidget: SignUpPassword(),
|
||||||
'test_user',
|
|
||||||
displayname: 'Test User',
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
Loading…
Reference in New Issue
Block a user