mirror of
https://gitlab.com/famedly/fluffychat.git
synced 2024-11-23 20:49:26 +01:00
refactor: Switch to flutter_lints
This commit is contained in:
parent
d775174e97
commit
44ce92e8fb
@ -1,4 +1,4 @@
|
||||
include: package:pedantic/analysis_options.yaml
|
||||
include: package:flutter_lints/flutter.yaml
|
||||
|
||||
linter:
|
||||
rules:
|
||||
|
@ -45,52 +45,52 @@ class AppRoutes {
|
||||
List<VRouteElement> get _mobileRoutes => [
|
||||
VWidget(
|
||||
path: '/rooms',
|
||||
widget: ChatList(),
|
||||
widget: const ChatList(),
|
||||
stackedRoutes: [
|
||||
VWidget(
|
||||
path: '/spaces/:roomid',
|
||||
widget: ChatDetails(),
|
||||
widget: const ChatDetails(),
|
||||
stackedRoutes: _chatDetailsRoutes,
|
||||
),
|
||||
VWidget(path: ':roomid', widget: Chat(), stackedRoutes: [
|
||||
VWidget(path: ':roomid', widget: const Chat(), stackedRoutes: [
|
||||
VWidget(
|
||||
path: 'encryption',
|
||||
widget: ChatEncryptionSettings(),
|
||||
widget: const ChatEncryptionSettings(),
|
||||
),
|
||||
VWidget(
|
||||
path: 'invite',
|
||||
widget: InvitationSelection(),
|
||||
widget: const InvitationSelection(),
|
||||
),
|
||||
VWidget(
|
||||
path: 'details',
|
||||
widget: ChatDetails(),
|
||||
widget: const ChatDetails(),
|
||||
stackedRoutes: _chatDetailsRoutes,
|
||||
),
|
||||
]),
|
||||
VWidget(
|
||||
path: '/settings',
|
||||
widget: Settings(),
|
||||
widget: const Settings(),
|
||||
stackedRoutes: _settingsRoutes,
|
||||
),
|
||||
VWidget(
|
||||
path: '/search',
|
||||
widget: Search(),
|
||||
widget: const Search(),
|
||||
),
|
||||
VWidget(
|
||||
path: '/archive',
|
||||
widget: Archive(),
|
||||
widget: const Archive(),
|
||||
),
|
||||
VWidget(
|
||||
path: '/newprivatechat',
|
||||
widget: NewPrivateChat(),
|
||||
widget: const NewPrivateChat(),
|
||||
),
|
||||
VWidget(
|
||||
path: '/newgroup',
|
||||
widget: NewGroup(),
|
||||
widget: const NewGroup(),
|
||||
),
|
||||
VWidget(
|
||||
path: '/newspace',
|
||||
widget: NewSpace(),
|
||||
widget: const NewSpace(),
|
||||
),
|
||||
],
|
||||
),
|
||||
@ -99,64 +99,64 @@ class AppRoutes {
|
||||
VNester(
|
||||
path: '/rooms',
|
||||
widgetBuilder: (child) => TwoColumnLayout(
|
||||
mainView: ChatList(),
|
||||
mainView: const ChatList(),
|
||||
sideView: child,
|
||||
),
|
||||
buildTransition: _fadeTransition,
|
||||
nestedRoutes: [
|
||||
VWidget(
|
||||
path: '',
|
||||
widget: EmptyPage(),
|
||||
widget: const EmptyPage(),
|
||||
buildTransition: _fadeTransition,
|
||||
stackedRoutes: [
|
||||
VWidget(
|
||||
path: '/spaces/:roomid',
|
||||
widget: ChatDetails(),
|
||||
widget: const ChatDetails(),
|
||||
buildTransition: _fadeTransition,
|
||||
stackedRoutes: _chatDetailsRoutes,
|
||||
),
|
||||
VWidget(
|
||||
path: '/newprivatechat',
|
||||
widget: NewPrivateChat(),
|
||||
widget: const NewPrivateChat(),
|
||||
buildTransition: _fadeTransition,
|
||||
),
|
||||
VWidget(
|
||||
path: '/newgroup',
|
||||
widget: NewGroup(),
|
||||
widget: const NewGroup(),
|
||||
buildTransition: _fadeTransition,
|
||||
),
|
||||
VWidget(
|
||||
path: '/newspace',
|
||||
widget: NewSpace(),
|
||||
widget: const NewSpace(),
|
||||
buildTransition: _fadeTransition,
|
||||
),
|
||||
VNester(
|
||||
path: ':roomid',
|
||||
widgetBuilder: (child) => SideViewLayout(
|
||||
mainView: Chat(),
|
||||
mainView: const Chat(),
|
||||
sideView: child,
|
||||
),
|
||||
buildTransition: _fadeTransition,
|
||||
nestedRoutes: [
|
||||
VWidget(
|
||||
path: '',
|
||||
widget: Chat(),
|
||||
widget: const Chat(),
|
||||
buildTransition: _fadeTransition,
|
||||
),
|
||||
VWidget(
|
||||
path: 'encryption',
|
||||
widget: ChatEncryptionSettings(),
|
||||
widget: const ChatEncryptionSettings(),
|
||||
buildTransition: _fadeTransition,
|
||||
),
|
||||
VWidget(
|
||||
path: 'details',
|
||||
widget: ChatDetails(),
|
||||
widget: const ChatDetails(),
|
||||
buildTransition: _fadeTransition,
|
||||
stackedRoutes: _chatDetailsRoutes,
|
||||
),
|
||||
VWidget(
|
||||
path: 'invite',
|
||||
widget: InvitationSelection(),
|
||||
widget: const InvitationSelection(),
|
||||
buildTransition: _fadeTransition,
|
||||
),
|
||||
],
|
||||
@ -167,7 +167,7 @@ class AppRoutes {
|
||||
),
|
||||
VWidget(
|
||||
path: '/rooms',
|
||||
widget: TwoColumnLayout(
|
||||
widget: const TwoColumnLayout(
|
||||
mainView: ChatList(),
|
||||
sideView: EmptyPage(),
|
||||
),
|
||||
@ -176,14 +176,14 @@ class AppRoutes {
|
||||
VNester(
|
||||
path: '/settings',
|
||||
widgetBuilder: (child) => TwoColumnLayout(
|
||||
mainView: Settings(),
|
||||
mainView: const Settings(),
|
||||
sideView: child,
|
||||
),
|
||||
buildTransition: _dynamicTransition,
|
||||
nestedRoutes: [
|
||||
VWidget(
|
||||
path: '',
|
||||
widget: EmptyPage(),
|
||||
widget: const EmptyPage(),
|
||||
buildTransition: _dynamicTransition,
|
||||
stackedRoutes: _settingsRoutes,
|
||||
),
|
||||
@ -191,7 +191,7 @@ class AppRoutes {
|
||||
),
|
||||
VWidget(
|
||||
path: '/search',
|
||||
widget: TwoColumnLayout(
|
||||
widget: const TwoColumnLayout(
|
||||
mainView: Search(),
|
||||
sideView: EmptyPage(),
|
||||
),
|
||||
@ -199,7 +199,7 @@ class AppRoutes {
|
||||
),
|
||||
VWidget(
|
||||
path: '/archive',
|
||||
widget: TwoColumnLayout(
|
||||
widget: const TwoColumnLayout(
|
||||
mainView: Archive(),
|
||||
sideView: EmptyPage(),
|
||||
),
|
||||
@ -210,25 +210,25 @@ class AppRoutes {
|
||||
];
|
||||
|
||||
List<VRouteElement> get _homeRoutes => [
|
||||
VWidget(path: '/', widget: LoadingView()),
|
||||
VWidget(path: '/', widget: const LoadingView()),
|
||||
VWidget(
|
||||
path: '/home',
|
||||
widget: HomeserverPicker(),
|
||||
widget: const HomeserverPicker(),
|
||||
buildTransition: _fadeTransition,
|
||||
stackedRoutes: [
|
||||
VWidget(
|
||||
path: 'login',
|
||||
widget: Login(),
|
||||
widget: const Login(),
|
||||
buildTransition: _fadeTransition,
|
||||
),
|
||||
VWidget(
|
||||
path: 'signup',
|
||||
widget: SignupPage(),
|
||||
widget: const SignupPage(),
|
||||
buildTransition: _fadeTransition,
|
||||
),
|
||||
VWidget(
|
||||
path: 'logs',
|
||||
widget: LogViewer(),
|
||||
widget: const LogViewer(),
|
||||
buildTransition: _dynamicTransition,
|
||||
),
|
||||
],
|
||||
@ -238,27 +238,27 @@ class AppRoutes {
|
||||
List<VRouteElement> get _chatDetailsRoutes => [
|
||||
VWidget(
|
||||
path: 'permissions',
|
||||
widget: ChatPermissionsSettings(),
|
||||
widget: const ChatPermissionsSettings(),
|
||||
buildTransition: _dynamicTransition,
|
||||
),
|
||||
VWidget(
|
||||
path: 'invite',
|
||||
widget: InvitationSelection(),
|
||||
widget: const InvitationSelection(),
|
||||
buildTransition: _dynamicTransition,
|
||||
),
|
||||
VWidget(
|
||||
path: 'multiple_emotes',
|
||||
widget: MultipleEmotesSettings(),
|
||||
widget: const MultipleEmotesSettings(),
|
||||
buildTransition: _dynamicTransition,
|
||||
),
|
||||
VWidget(
|
||||
path: 'emotes',
|
||||
widget: EmotesSettings(),
|
||||
widget: const EmotesSettings(),
|
||||
buildTransition: _dynamicTransition,
|
||||
),
|
||||
VWidget(
|
||||
path: 'emotes/:state_key',
|
||||
widget: EmotesSettings(),
|
||||
widget: const EmotesSettings(),
|
||||
buildTransition: _dynamicTransition,
|
||||
),
|
||||
];
|
||||
@ -266,49 +266,49 @@ class AppRoutes {
|
||||
List<VRouteElement> get _settingsRoutes => [
|
||||
VWidget(
|
||||
path: 'notifications',
|
||||
widget: SettingsNotifications(),
|
||||
widget: const SettingsNotifications(),
|
||||
buildTransition: _dynamicTransition,
|
||||
),
|
||||
VWidget(
|
||||
path: 'chat',
|
||||
widget: SettingsChat(),
|
||||
widget: const SettingsChat(),
|
||||
buildTransition: _dynamicTransition,
|
||||
stackedRoutes: [
|
||||
VWidget(
|
||||
path: 'emotes',
|
||||
widget: EmotesSettings(),
|
||||
widget: const EmotesSettings(),
|
||||
buildTransition: _dynamicTransition,
|
||||
),
|
||||
VWidget(
|
||||
path: 'style',
|
||||
widget: SettingsStyle(),
|
||||
widget: const SettingsStyle(),
|
||||
buildTransition: _dynamicTransition,
|
||||
),
|
||||
],
|
||||
),
|
||||
VWidget(
|
||||
path: 'account',
|
||||
widget: SettingsAccount(),
|
||||
widget: const SettingsAccount(),
|
||||
buildTransition: _dynamicTransition,
|
||||
stackedRoutes: [
|
||||
VWidget(
|
||||
path: 'devices',
|
||||
widget: DevicesSettings(),
|
||||
widget: const DevicesSettings(),
|
||||
buildTransition: _dynamicTransition,
|
||||
),
|
||||
VWidget(
|
||||
path: 'add',
|
||||
widget: HomeserverPicker(),
|
||||
widget: const HomeserverPicker(),
|
||||
buildTransition: _fadeTransition,
|
||||
stackedRoutes: [
|
||||
VWidget(
|
||||
path: 'login',
|
||||
widget: Login(),
|
||||
widget: const Login(),
|
||||
buildTransition: _fadeTransition,
|
||||
),
|
||||
VWidget(
|
||||
path: 'signup',
|
||||
widget: SignupPage(),
|
||||
widget: const SignupPage(),
|
||||
buildTransition: _fadeTransition,
|
||||
),
|
||||
],
|
||||
@ -317,31 +317,31 @@ class AppRoutes {
|
||||
),
|
||||
VWidget(
|
||||
path: 'security',
|
||||
widget: SettingsSecurity(),
|
||||
widget: const SettingsSecurity(),
|
||||
buildTransition: _dynamicTransition,
|
||||
stackedRoutes: [
|
||||
VWidget(
|
||||
path: 'ignorelist',
|
||||
widget: SettingsIgnoreList(),
|
||||
widget: const SettingsIgnoreList(),
|
||||
buildTransition: _dynamicTransition,
|
||||
),
|
||||
VWidget(
|
||||
path: '3pid',
|
||||
widget: Settings3Pid(),
|
||||
widget: const Settings3Pid(),
|
||||
buildTransition: _dynamicTransition,
|
||||
),
|
||||
],
|
||||
),
|
||||
VWidget(
|
||||
path: 'logs',
|
||||
widget: LogViewer(),
|
||||
widget: const LogViewer(),
|
||||
buildTransition: _dynamicTransition,
|
||||
),
|
||||
];
|
||||
|
||||
final _fadeTransition = (animation1, _, child) =>
|
||||
FadeTransition(opacity: animation1, child: child);
|
||||
|
||||
FadeTransition Function(dynamic, dynamic, dynamic) get _dynamicTransition =>
|
||||
columnMode ? _fadeTransition : null;
|
||||
|
||||
FadeTransition _fadeTransition(animation1, _, child) =>
|
||||
FadeTransition(opacity: animation1, child: child);
|
||||
}
|
||||
|
@ -14,8 +14,8 @@ abstract class FluffyThemes {
|
||||
static const fallbackTextStyle =
|
||||
TextStyle(fontFamily: 'Roboto', fontFamilyFallback: ['NotoEmoji']);
|
||||
|
||||
static var fallback_text_theme = PlatformInfos.isDesktop
|
||||
? TextTheme(
|
||||
static var fallbackTextTheme = PlatformInfos.isDesktop
|
||||
? const TextTheme(
|
||||
bodyText1: fallbackTextStyle,
|
||||
bodyText2: fallbackTextStyle,
|
||||
button: fallbackTextStyle,
|
||||
@ -29,12 +29,12 @@ abstract class FluffyThemes {
|
||||
headline6: fallbackTextStyle,
|
||||
subtitle1: fallbackTextStyle,
|
||||
subtitle2: fallbackTextStyle)
|
||||
: TextTheme();
|
||||
: const TextTheme();
|
||||
|
||||
static ThemeData light = ThemeData(
|
||||
visualDensity: VisualDensity.standard,
|
||||
primaryColorDark: Colors.white,
|
||||
primaryColorLight: Color(0xff121212),
|
||||
primaryColorLight: const Color(0xff121212),
|
||||
brightness: Brightness.light,
|
||||
primaryColor: AppConfig.primaryColor,
|
||||
colorScheme: ThemeData.light().colorScheme.copyWith(
|
||||
@ -43,11 +43,11 @@ abstract class FluffyThemes {
|
||||
secondaryVariant: AppConfig.secondaryColor,
|
||||
),
|
||||
backgroundColor: Colors.white,
|
||||
secondaryHeaderColor: Color(0xffeeeffe),
|
||||
secondaryHeaderColor: const Color(0xffeeeffe),
|
||||
scaffoldBackgroundColor: Colors.white,
|
||||
textTheme: Typography.material2018().black.merge(fallback_text_theme),
|
||||
snackBarTheme: SnackBarThemeData(behavior: SnackBarBehavior.floating),
|
||||
pageTransitionsTheme: PageTransitionsTheme(
|
||||
textTheme: Typography.material2018().black.merge(fallbackTextTheme),
|
||||
snackBarTheme: const SnackBarThemeData(behavior: SnackBarBehavior.floating),
|
||||
pageTransitionsTheme: const PageTransitionsTheme(
|
||||
builders: {
|
||||
TargetPlatform.fuchsia: ZoomPageTransitionsBuilder(),
|
||||
TargetPlatform.android: ZoomPageTransitionsBuilder(),
|
||||
@ -75,7 +75,7 @@ abstract class FluffyThemes {
|
||||
borderRadius: BorderRadius.circular(AppConfig.borderRadius),
|
||||
),
|
||||
),
|
||||
floatingActionButtonTheme: FloatingActionButtonThemeData(
|
||||
floatingActionButtonTheme: const FloatingActionButtonThemeData(
|
||||
backgroundColor: AppConfig.primaryColor,
|
||||
foregroundColor: Colors.white,
|
||||
),
|
||||
@ -86,7 +86,7 @@ abstract class FluffyThemes {
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(AppConfig.borderRadius),
|
||||
),
|
||||
padding: EdgeInsets.all(12),
|
||||
padding: const EdgeInsets.all(12),
|
||||
),
|
||||
),
|
||||
cardTheme: CardTheme(
|
||||
@ -108,7 +108,7 @@ abstract class FluffyThemes {
|
||||
filled: true,
|
||||
fillColor: lighten(AppConfig.primaryColor, .51),
|
||||
),
|
||||
appBarTheme: AppBarTheme(
|
||||
appBarTheme: const AppBarTheme(
|
||||
elevation: 2,
|
||||
systemOverlayStyle: SystemUiOverlayStyle.dark,
|
||||
backgroundColor: Colors.white,
|
||||
@ -122,10 +122,10 @@ abstract class FluffyThemes {
|
||||
|
||||
static ThemeData dark = ThemeData.dark().copyWith(
|
||||
visualDensity: VisualDensity.standard,
|
||||
primaryColorDark: Color(0xff121212),
|
||||
primaryColorDark: const Color(0xff121212),
|
||||
primaryColorLight: Colors.white,
|
||||
primaryColor: AppConfig.primaryColor,
|
||||
errorColor: Color(0xFFCF6679),
|
||||
errorColor: const Color(0xFFCF6679),
|
||||
backgroundColor: Colors.black,
|
||||
scaffoldBackgroundColor: Colors.black,
|
||||
colorScheme: ThemeData.dark().colorScheme.copyWith(
|
||||
@ -133,8 +133,8 @@ abstract class FluffyThemes {
|
||||
secondary: AppConfig.primaryColorLight,
|
||||
secondaryVariant: AppConfig.secondaryColor,
|
||||
),
|
||||
secondaryHeaderColor: Color(0xff232543),
|
||||
textTheme: Typography.material2018().white.merge(fallback_text_theme),
|
||||
secondaryHeaderColor: const Color(0xff232543),
|
||||
textTheme: Typography.material2018().white.merge(fallbackTextTheme),
|
||||
dialogTheme: DialogTheme(
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(AppConfig.borderRadius),
|
||||
@ -152,7 +152,7 @@ abstract class FluffyThemes {
|
||||
),
|
||||
clipBehavior: Clip.hardEdge,
|
||||
),
|
||||
pageTransitionsTheme: PageTransitionsTheme(
|
||||
pageTransitionsTheme: const PageTransitionsTheme(
|
||||
builders: {
|
||||
TargetPlatform.fuchsia: ZoomPageTransitionsBuilder(),
|
||||
TargetPlatform.android: ZoomPageTransitionsBuilder(),
|
||||
@ -162,7 +162,7 @@ abstract class FluffyThemes {
|
||||
TargetPlatform.iOS: CupertinoPageTransitionsBuilder(),
|
||||
},
|
||||
),
|
||||
floatingActionButtonTheme: FloatingActionButtonThemeData(
|
||||
floatingActionButtonTheme: const FloatingActionButtonThemeData(
|
||||
backgroundColor: AppConfig.primaryColor,
|
||||
foregroundColor: Colors.white,
|
||||
),
|
||||
@ -192,11 +192,11 @@ abstract class FluffyThemes {
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(AppConfig.borderRadius),
|
||||
),
|
||||
padding: EdgeInsets.all(12),
|
||||
padding: const EdgeInsets.all(12),
|
||||
),
|
||||
),
|
||||
snackBarTheme: SnackBarThemeData(behavior: SnackBarBehavior.floating),
|
||||
appBarTheme: AppBarTheme(
|
||||
snackBarTheme: const SnackBarThemeData(behavior: SnackBarBehavior.floating),
|
||||
appBarTheme: const AppBarTheme(
|
||||
elevation: 2,
|
||||
systemOverlayStyle: SystemUiOverlayStyle.light,
|
||||
backgroundColor: Color(0xff1D1D1D),
|
||||
|
@ -53,7 +53,7 @@ void main() async {
|
||||
clients: clients,
|
||||
queryParameters: queryParameters,
|
||||
),
|
||||
lockScreen: LockScreen(),
|
||||
lockScreen: const LockScreen(),
|
||||
enabled: false,
|
||||
)
|
||||
: FluffyChatApp(clients: clients, queryParameters: queryParameters)),
|
||||
@ -117,7 +117,7 @@ class _FluffyChatAppState extends State<FluffyChatApp> {
|
||||
}
|
||||
return VRouter(
|
||||
key: _router,
|
||||
title: '${AppConfig.applicationName}',
|
||||
title: AppConfig.applicationName,
|
||||
theme: theme,
|
||||
scrollBehavior: CustomScrollBehavior(),
|
||||
logs: kReleaseMode ? VLogs.none : VLogs.info,
|
||||
|
@ -7,6 +7,8 @@ import 'package:future_loading_dialog/future_loading_dialog.dart';
|
||||
import 'package:flutter_gen/gen_l10n/l10n.dart';
|
||||
|
||||
class Archive extends StatefulWidget {
|
||||
const Archive({Key key}) : super(key: key);
|
||||
|
||||
@override
|
||||
ArchiveController createState() => ArchiveController();
|
||||
}
|
||||
|
@ -71,8 +71,8 @@ class _BootstrapDialogState extends State<BootstrapDialog> {
|
||||
_wipe ??= widget.wipe;
|
||||
final buttons = <AdaptiveFlatButton>[];
|
||||
Widget body = PlatformInfos.isCupertinoStyle
|
||||
? CupertinoActivityIndicator()
|
||||
: LinearProgressIndicator();
|
||||
? const CupertinoActivityIndicator()
|
||||
: const LinearProgressIndicator();
|
||||
titleText = L10n.of(context).loadingPleaseWait;
|
||||
|
||||
if (bootstrap == null) {
|
||||
@ -96,7 +96,7 @@ class _BootstrapDialogState extends State<BootstrapDialog> {
|
||||
appBar: AppBar(
|
||||
centerTitle: true,
|
||||
leading: IconButton(
|
||||
icon: Icon(Icons.close),
|
||||
icon: const Icon(Icons.close),
|
||||
onPressed: Navigator.of(context).pop,
|
||||
),
|
||||
title: Text(L10n.of(context).securityKey),
|
||||
@ -104,7 +104,7 @@ class _BootstrapDialogState extends State<BootstrapDialog> {
|
||||
body: Center(
|
||||
child: ConstrainedBox(
|
||||
constraints:
|
||||
BoxConstraints(maxWidth: FluffyThemes.columnWidth * 1.5),
|
||||
const BoxConstraints(maxWidth: FluffyThemes.columnWidth * 1.5),
|
||||
child: ListView(
|
||||
padding: const EdgeInsets.all(16.0),
|
||||
children: [
|
||||
@ -116,7 +116,7 @@ class _BootstrapDialogState extends State<BootstrapDialog> {
|
||||
),
|
||||
const SizedBox(height: 16),
|
||||
ElevatedButton.icon(
|
||||
icon: Icon(Icons.copy_outlined),
|
||||
icon: const Icon(Icons.copy_outlined),
|
||||
label: Text(L10n.of(context).copyToClipboard),
|
||||
onPressed: () => Clipboard.setData(ClipboardData(text: key)),
|
||||
),
|
||||
@ -126,7 +126,7 @@ class _BootstrapDialogState extends State<BootstrapDialog> {
|
||||
primary: Theme.of(context).secondaryHeaderColor,
|
||||
onPrimary: Theme.of(context).primaryColor,
|
||||
),
|
||||
icon: Icon(Icons.check_outlined),
|
||||
icon: const Icon(Icons.check_outlined),
|
||||
label: Text(L10n.of(context).iWroteDownTheKey),
|
||||
onPressed: () => setState(() => _recoveryKeyStored = true),
|
||||
),
|
||||
@ -170,7 +170,7 @@ class _BootstrapDialogState extends State<BootstrapDialog> {
|
||||
appBar: AppBar(
|
||||
centerTitle: true,
|
||||
leading: IconButton(
|
||||
icon: Icon(Icons.close),
|
||||
icon: const Icon(Icons.close),
|
||||
onPressed: Navigator.of(context).pop,
|
||||
),
|
||||
title: Text(L10n.of(context).pleaseEnterSecurityKey),
|
||||
@ -178,7 +178,7 @@ class _BootstrapDialogState extends State<BootstrapDialog> {
|
||||
body: Center(
|
||||
child: ConstrainedBox(
|
||||
constraints:
|
||||
BoxConstraints(maxWidth: FluffyThemes.columnWidth * 1.5),
|
||||
const BoxConstraints(maxWidth: FluffyThemes.columnWidth * 1.5),
|
||||
child: ListView(
|
||||
padding: const EdgeInsets.all(16.0),
|
||||
children: [
|
||||
@ -199,7 +199,7 @@ class _BootstrapDialogState extends State<BootstrapDialog> {
|
||||
),
|
||||
const SizedBox(height: 16),
|
||||
ElevatedButton.icon(
|
||||
icon: Icon(Icons.lock_open_outlined),
|
||||
icon: const Icon(Icons.lock_open_outlined),
|
||||
label: Text(L10n.of(context).unlockChatBackup),
|
||||
onPressed: () async {
|
||||
setState(() {
|
||||
@ -222,12 +222,12 @@ class _BootstrapDialogState extends State<BootstrapDialog> {
|
||||
}),
|
||||
const SizedBox(height: 16),
|
||||
Row(children: [
|
||||
Expanded(child: Divider()),
|
||||
const Expanded(child: Divider()),
|
||||
Padding(
|
||||
padding: const EdgeInsets.all(12.0),
|
||||
child: Text(L10n.of(context).or),
|
||||
),
|
||||
Expanded(child: Divider()),
|
||||
const Expanded(child: Divider()),
|
||||
]),
|
||||
const SizedBox(height: 16),
|
||||
ElevatedButton.icon(
|
||||
@ -235,7 +235,7 @@ class _BootstrapDialogState extends State<BootstrapDialog> {
|
||||
primary: Theme.of(context).secondaryHeaderColor,
|
||||
onPrimary: Theme.of(context).primaryColor,
|
||||
),
|
||||
icon: Icon(Icons.transfer_within_a_station_outlined),
|
||||
icon: const Icon(Icons.transfer_within_a_station_outlined),
|
||||
label: Text(L10n.of(context).transferFromAnotherDevice),
|
||||
onPressed: () async {
|
||||
final req = await showFutureLoadingDialog(
|
||||
@ -256,7 +256,7 @@ class _BootstrapDialogState extends State<BootstrapDialog> {
|
||||
primary: Theme.of(context).secondaryHeaderColor,
|
||||
onPrimary: Colors.red,
|
||||
),
|
||||
icon: Icon(Icons.delete_outlined),
|
||||
icon: const Icon(Icons.delete_outlined),
|
||||
label: Text(L10n.of(context).securityKeyLost),
|
||||
onPressed: () async {
|
||||
if (OkCancelResult.ok ==
|
||||
@ -305,7 +305,7 @@ class _BootstrapDialogState extends State<BootstrapDialog> {
|
||||
break;
|
||||
case BootstrapState.error:
|
||||
titleText = L10n.of(context).oopsSomethingWentWrong;
|
||||
body = Icon(Icons.error_outline, color: Colors.red, size: 40);
|
||||
body = const Icon(Icons.error_outline, color: Colors.red, size: 40);
|
||||
buttons.add(AdaptiveFlatButton(
|
||||
label: L10n.of(context).close,
|
||||
onPressed: () =>
|
||||
|
@ -37,7 +37,7 @@ import '../utils/account_bundles.dart';
|
||||
class Chat extends StatefulWidget {
|
||||
final Widget sideView;
|
||||
|
||||
Chat({Key key, this.sideView}) : super(key: key);
|
||||
const Chat({Key key, this.sideView}) : super(key: key);
|
||||
|
||||
@override
|
||||
ChatController createState() => ChatController();
|
||||
@ -269,7 +269,7 @@ class ChatController extends State<Chat> {
|
||||
parseCommands: parseCommands);
|
||||
sendController.value = TextEditingValue(
|
||||
text: pendingText,
|
||||
selection: TextSelection.collapsed(offset: 0),
|
||||
selection: const TextSelection.collapsed(offset: 0),
|
||||
);
|
||||
|
||||
setState(() {
|
||||
@ -360,7 +360,7 @@ class ChatController extends State<Chat> {
|
||||
final result = await showDialog<String>(
|
||||
context: context,
|
||||
useRootNavigator: false,
|
||||
builder: (c) => RecordingDialog(),
|
||||
builder: (c) => const RecordingDialog(),
|
||||
);
|
||||
if (result == null) return;
|
||||
final audioFile = File(result);
|
||||
@ -705,11 +705,11 @@ class ChatController extends State<Chat> {
|
||||
|
||||
int findChildIndexCallback(Key key, Map<String, int> thisEventsKeyMap) {
|
||||
// this method is called very often. As such, it has to be optimized for speed.
|
||||
if (!(key is ValueKey)) {
|
||||
if (key is! ValueKey) {
|
||||
return null;
|
||||
}
|
||||
final eventId = (key as ValueKey).value;
|
||||
if (!(eventId is String)) {
|
||||
if (eventId is! String) {
|
||||
return null;
|
||||
}
|
||||
// first fetch the last index the event was at
|
||||
@ -764,18 +764,18 @@ class ChatController extends State<Chat> {
|
||||
}
|
||||
}
|
||||
typingCoolDown?.cancel();
|
||||
typingCoolDown = Timer(Duration(seconds: 2), () {
|
||||
typingCoolDown = Timer(const Duration(seconds: 2), () {
|
||||
typingCoolDown = null;
|
||||
currentlyTyping = false;
|
||||
room.setTyping(false);
|
||||
});
|
||||
typingTimeout ??= Timer(Duration(seconds: 30), () {
|
||||
typingTimeout ??= Timer(const Duration(seconds: 30), () {
|
||||
typingTimeout = null;
|
||||
currentlyTyping = false;
|
||||
});
|
||||
if (!currentlyTyping) {
|
||||
currentlyTyping = true;
|
||||
room.setTyping(true, timeout: Duration(seconds: 30).inMilliseconds);
|
||||
room.setTyping(true, timeout: const Duration(seconds: 30).inMilliseconds);
|
||||
}
|
||||
setState(() => inputText = text);
|
||||
}
|
||||
|
@ -17,7 +17,7 @@ import 'package:vrouter/vrouter.dart';
|
||||
enum AliasActions { copy, delete, setCanonical }
|
||||
|
||||
class ChatDetails extends StatefulWidget {
|
||||
const ChatDetails();
|
||||
const ChatDetails({Key key}) : super(key: key);
|
||||
|
||||
@override
|
||||
ChatDetailsController createState() => ChatDetailsController();
|
||||
@ -297,7 +297,7 @@ class ChatDetailsController extends State<ChatDetails> {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
members ??= Matrix.of(context).client.getRoomById(roomId).getParticipants();
|
||||
return Container(
|
||||
return SizedBox(
|
||||
width: 360.0,
|
||||
child: ChatDetailsView(this),
|
||||
);
|
||||
|
@ -16,17 +16,19 @@ class ChatEncryptionSettings extends StatefulWidget {
|
||||
|
||||
class ChatEncryptionSettingsController extends State<ChatEncryptionSettings> {
|
||||
String get roomId => VRouter.of(context).pathParameters['roomid'];
|
||||
|
||||
Future<void> unblock(DeviceKeys key) async {
|
||||
if (key.blocked) {
|
||||
await key.setBlocked(false);
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> onSelected(
|
||||
BuildContext context, String action, DeviceKeys key) async {
|
||||
final room = Matrix.of(context).client.getRoomById(roomId);
|
||||
final unblock = () async {
|
||||
if (key.blocked) {
|
||||
await key.setBlocked(false);
|
||||
}
|
||||
};
|
||||
switch (action) {
|
||||
case 'verify':
|
||||
await unblock();
|
||||
await unblock(key);
|
||||
final req = key.startVerification();
|
||||
req.onUpdate = () {
|
||||
if (req.state == KeyVerificationState.done) {
|
||||
@ -36,7 +38,7 @@ class ChatEncryptionSettingsController extends State<ChatEncryptionSettings> {
|
||||
await KeyVerificationDialog(request: req).show(context);
|
||||
break;
|
||||
case 'verify_user':
|
||||
await unblock();
|
||||
await unblock(key);
|
||||
final req =
|
||||
await room.client.userDeviceKeys[key.userId].startVerification();
|
||||
req.onUpdate = () {
|
||||
@ -54,7 +56,7 @@ class ChatEncryptionSettingsController extends State<ChatEncryptionSettings> {
|
||||
setState(() => null);
|
||||
break;
|
||||
case 'unblock':
|
||||
await unblock();
|
||||
await unblock(key);
|
||||
setState(() => null);
|
||||
break;
|
||||
}
|
||||
|
@ -10,6 +10,8 @@ import 'package:flutter_gen/gen_l10n/l10n.dart';
|
||||
import '../widgets/matrix.dart';
|
||||
|
||||
class DevicesSettings extends StatefulWidget {
|
||||
const DevicesSettings({Key key}) : super(key: key);
|
||||
|
||||
@override
|
||||
DevicesSettingsController createState() => DevicesSettingsController();
|
||||
}
|
||||
|
@ -20,6 +20,8 @@ import 'package:uni_links/uni_links.dart';
|
||||
import '../main.dart';
|
||||
|
||||
class HomeserverPicker extends StatefulWidget {
|
||||
const HomeserverPicker({Key key}) : super(key: key);
|
||||
|
||||
@override
|
||||
HomeserverPickerController createState() => HomeserverPickerController();
|
||||
}
|
||||
@ -37,7 +39,7 @@ class HomeserverPickerController extends State<HomeserverPicker> {
|
||||
this.domain = domain;
|
||||
_coolDown?.cancel();
|
||||
if (domain.isNotEmpty) {
|
||||
_coolDown = Timer(Duration(seconds: 1), checkHomeserverAction);
|
||||
_coolDown = Timer(const Duration(seconds: 1), checkHomeserverAction);
|
||||
}
|
||||
}
|
||||
|
||||
@ -133,7 +135,7 @@ class HomeserverPickerController extends State<HomeserverPicker> {
|
||||
AppConfig.jitsiInstance = jitsi;
|
||||
}
|
||||
} catch (e) {
|
||||
setState(() => error = '${(e as Object).toLocalizedString(context)}');
|
||||
setState(() => error = (e as Object).toLocalizedString(context));
|
||||
} finally {
|
||||
if (mounted) {
|
||||
setState(() => isLoading = false);
|
||||
|
@ -70,7 +70,7 @@ class InvitationSelectionController extends State<InvitationSelection> {
|
||||
void searchUserWithCoolDown(String text) async {
|
||||
coolDown?.cancel();
|
||||
coolDown = Timer(
|
||||
Duration(seconds: 1),
|
||||
const Duration(seconds: 1),
|
||||
() => searchUser(context, text),
|
||||
);
|
||||
}
|
||||
|
@ -31,9 +31,10 @@ class KeyVerificationDialog extends StatefulWidget {
|
||||
|
||||
final KeyVerification request;
|
||||
|
||||
KeyVerificationDialog({
|
||||
const KeyVerificationDialog({
|
||||
Key key,
|
||||
this.request,
|
||||
});
|
||||
}) : super(key: key);
|
||||
|
||||
@override
|
||||
_KeyVerificationPageState createState() => _KeyVerificationPageState();
|
||||
@ -76,6 +77,33 @@ class _KeyVerificationPageState extends State<KeyVerificationDialog> {
|
||||
|
||||
Profile profile;
|
||||
|
||||
Future<void> checkInput(String input) async {
|
||||
if (input == null || input.isEmpty) {
|
||||
return;
|
||||
}
|
||||
final valid = await showFutureLoadingDialog(
|
||||
context: context,
|
||||
future: () async {
|
||||
// make sure the loading spinner shows before we test the keys
|
||||
await Future.delayed(const Duration(milliseconds: 100));
|
||||
var valid = false;
|
||||
try {
|
||||
await widget.request.openSSSS(keyOrPassphrase: input);
|
||||
valid = true;
|
||||
} catch (_) {
|
||||
valid = false;
|
||||
}
|
||||
return valid;
|
||||
});
|
||||
if (valid.error != null) {
|
||||
await showOkAlertDialog(
|
||||
useRootNavigator: false,
|
||||
context: context,
|
||||
message: L10n.of(context).incorrectPassphraseOrKey,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
User user;
|
||||
@ -96,39 +124,13 @@ class _KeyVerificationPageState extends State<KeyVerificationDialog> {
|
||||
// prompt the user for their ssss passphrase / key
|
||||
final textEditingController = TextEditingController();
|
||||
String input;
|
||||
final checkInput = () async {
|
||||
if (input == null || input.isEmpty) {
|
||||
return;
|
||||
}
|
||||
final valid = await showFutureLoadingDialog(
|
||||
context: context,
|
||||
future: () async {
|
||||
// make sure the loading spinner shows before we test the keys
|
||||
await Future.delayed(Duration(milliseconds: 100));
|
||||
var valid = false;
|
||||
try {
|
||||
await widget.request.openSSSS(keyOrPassphrase: input);
|
||||
valid = true;
|
||||
} catch (_) {
|
||||
valid = false;
|
||||
}
|
||||
return valid;
|
||||
});
|
||||
if (valid.error != null) {
|
||||
await showOkAlertDialog(
|
||||
useRootNavigator: false,
|
||||
context: context,
|
||||
message: L10n.of(context).incorrectPassphraseOrKey,
|
||||
);
|
||||
}
|
||||
};
|
||||
body = Container(
|
||||
margin: EdgeInsets.only(left: 8.0, right: 8.0),
|
||||
margin: const EdgeInsets.only(left: 8.0, right: 8.0),
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: <Widget>[
|
||||
Text(L10n.of(context).askSSSSSign,
|
||||
style: TextStyle(fontSize: 20)),
|
||||
style: const TextStyle(fontSize: 20)),
|
||||
Container(height: 10),
|
||||
TextField(
|
||||
controller: textEditingController,
|
||||
@ -136,7 +138,7 @@ class _KeyVerificationPageState extends State<KeyVerificationDialog> {
|
||||
autocorrect: false,
|
||||
onSubmitted: (s) {
|
||||
input = s;
|
||||
checkInput();
|
||||
checkInput(input);
|
||||
},
|
||||
minLines: 1,
|
||||
maxLines: 1,
|
||||
@ -145,7 +147,7 @@ class _KeyVerificationPageState extends State<KeyVerificationDialog> {
|
||||
hintText: L10n.of(context).passphraseOrKey,
|
||||
prefixStyle: TextStyle(color: Theme.of(context).primaryColor),
|
||||
suffixStyle: TextStyle(color: Theme.of(context).primaryColor),
|
||||
border: OutlineInputBorder(),
|
||||
border: const OutlineInputBorder(),
|
||||
),
|
||||
),
|
||||
],
|
||||
@ -155,7 +157,7 @@ class _KeyVerificationPageState extends State<KeyVerificationDialog> {
|
||||
label: L10n.of(context).submit,
|
||||
onPressed: () {
|
||||
input = textEditingController.text;
|
||||
checkInput();
|
||||
checkInput(input);
|
||||
},
|
||||
));
|
||||
buttons.add(AdaptiveFlatButton(
|
||||
@ -171,7 +173,7 @@ class _KeyVerificationPageState extends State<KeyVerificationDialog> {
|
||||
Row(children: [
|
||||
if (!PlatformInfos.isCupertinoStyle)
|
||||
Avatar(user?.avatarUrl, displayName),
|
||||
SizedBox(width: 12),
|
||||
const SizedBox(width: 12),
|
||||
Expanded(
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
@ -181,11 +183,11 @@ class _KeyVerificationPageState extends State<KeyVerificationDialog> {
|
||||
children: [
|
||||
Text(
|
||||
displayName,
|
||||
style: TextStyle(fontSize: 16),
|
||||
style: const TextStyle(fontSize: 16),
|
||||
),
|
||||
Text(
|
||||
'${widget.request.userId} - ${widget.request.deviceId}',
|
||||
style: TextStyle(
|
||||
style: const TextStyle(
|
||||
fontWeight: FontWeight.w300,
|
||||
fontSize: 14,
|
||||
),
|
||||
@ -222,7 +224,7 @@ class _KeyVerificationPageState extends State<KeyVerificationDialog> {
|
||||
children: <Widget>[
|
||||
Image.asset('assets/verification.png', fit: BoxFit.contain),
|
||||
const SizedBox(height: 16),
|
||||
CircularProgressIndicator.adaptive(strokeWidth: 2),
|
||||
const CircularProgressIndicator.adaptive(strokeWidth: 2),
|
||||
const SizedBox(height: 16),
|
||||
Text(
|
||||
L10n.of(context).waitingPartnerAcceptRequest,
|
||||
@ -269,7 +271,7 @@ class _KeyVerificationPageState extends State<KeyVerificationDialog> {
|
||||
final numbers = widget.request.sasNumbers;
|
||||
final numbstr = '${numbers[0]}-${numbers[1]}-${numbers[2]}';
|
||||
compareWidget =
|
||||
TextSpan(text: numbstr, style: TextStyle(fontSize: 40));
|
||||
TextSpan(text: numbstr, style: const TextStyle(fontSize: 40));
|
||||
}
|
||||
body = Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
@ -277,11 +279,11 @@ class _KeyVerificationPageState extends State<KeyVerificationDialog> {
|
||||
Center(
|
||||
child: Text(
|
||||
compareText,
|
||||
style: TextStyle(fontSize: 16),
|
||||
style: const TextStyle(fontSize: 16),
|
||||
textAlign: TextAlign.center,
|
||||
),
|
||||
),
|
||||
SizedBox(height: 10),
|
||||
const SizedBox(height: 10),
|
||||
Text.rich(
|
||||
compareWidget,
|
||||
textAlign: TextAlign.center,
|
||||
@ -305,8 +307,8 @@ class _KeyVerificationPageState extends State<KeyVerificationDialog> {
|
||||
body = Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: <Widget>[
|
||||
CircularProgressIndicator.adaptive(strokeWidth: 2),
|
||||
SizedBox(height: 10),
|
||||
const CircularProgressIndicator.adaptive(strokeWidth: 2),
|
||||
const SizedBox(height: 10),
|
||||
Text(
|
||||
acceptText,
|
||||
textAlign: TextAlign.center,
|
||||
@ -318,8 +320,9 @@ class _KeyVerificationPageState extends State<KeyVerificationDialog> {
|
||||
body = Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: <Widget>[
|
||||
Icon(Icons.check_circle_outlined, color: Colors.green, size: 200.0),
|
||||
SizedBox(height: 10),
|
||||
const Icon(Icons.check_circle_outlined,
|
||||
color: Colors.green, size: 200.0),
|
||||
const SizedBox(height: 10),
|
||||
Text(
|
||||
L10n.of(context).verifySuccess,
|
||||
textAlign: TextAlign.center,
|
||||
@ -335,8 +338,8 @@ class _KeyVerificationPageState extends State<KeyVerificationDialog> {
|
||||
body = Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: <Widget>[
|
||||
Icon(Icons.cancel, color: Colors.red, size: 200.0),
|
||||
SizedBox(height: 10),
|
||||
const Icon(Icons.cancel, color: Colors.red, size: 200.0),
|
||||
const SizedBox(height: 10),
|
||||
Text(
|
||||
'Error ${widget.request.canceledCode}: ${widget.request.canceledReason}',
|
||||
textAlign: TextAlign.center,
|
||||
@ -355,7 +358,7 @@ class _KeyVerificationPageState extends State<KeyVerificationDialog> {
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
SizedBox(height: 16),
|
||||
const SizedBox(height: 16),
|
||||
body,
|
||||
],
|
||||
),
|
||||
@ -379,7 +382,7 @@ class _Emoji extends StatelessWidget {
|
||||
final KeyVerificationEmoji emoji;
|
||||
final List<dynamic> sasEmoji;
|
||||
|
||||
_Emoji(this.emoji, this.sasEmoji);
|
||||
const _Emoji(this.emoji, this.sasEmoji);
|
||||
|
||||
String getLocalizedName() {
|
||||
if (sasEmoji == null) {
|
||||
@ -410,9 +413,9 @@ class _Emoji extends StatelessWidget {
|
||||
return Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: <Widget>[
|
||||
Text(emoji.emoji, style: TextStyle(fontSize: 50)),
|
||||
Text(emoji.emoji, style: const TextStyle(fontSize: 50)),
|
||||
Text(getLocalizedName()),
|
||||
Container(height: 10, width: 5),
|
||||
const SizedBox(height: 10, width: 5),
|
||||
],
|
||||
);
|
||||
}
|
||||
|
@ -16,6 +16,8 @@ import '../config/setting_keys.dart';
|
||||
import 'views/login_view.dart';
|
||||
|
||||
class Login extends StatefulWidget {
|
||||
const Login({Key key}) : super(key: key);
|
||||
|
||||
@override
|
||||
LoginController createState() => LoginController();
|
||||
}
|
||||
@ -89,7 +91,7 @@ class LoginController extends State<Login> {
|
||||
void checkWellKnownWithCoolDown(String userId) async {
|
||||
_coolDown?.cancel();
|
||||
_coolDown = Timer(
|
||||
Duration(seconds: 1),
|
||||
const Duration(seconds: 1),
|
||||
() => _checkWellKnown(userId),
|
||||
);
|
||||
}
|
||||
@ -202,7 +204,7 @@ class LoginController extends State<Login> {
|
||||
okLabel: L10n.of(context).ok,
|
||||
cancelLabel: L10n.of(context).cancel,
|
||||
textFields: [
|
||||
DialogTextField(
|
||||
const DialogTextField(
|
||||
hintText: '******',
|
||||
obscureText: true,
|
||||
minLines: 1,
|
||||
|
@ -6,6 +6,8 @@ import 'package:flutter/material.dart';
|
||||
import 'package:vrouter/vrouter.dart';
|
||||
|
||||
class NewGroup extends StatefulWidget {
|
||||
const NewGroup({Key key}) : super(key: key);
|
||||
|
||||
@override
|
||||
NewGroupController createState() => NewGroupController();
|
||||
}
|
||||
|
@ -9,6 +9,8 @@ import 'package:flutter_gen/gen_l10n/l10n.dart';
|
||||
import 'package:permission_handler/permission_handler.dart';
|
||||
|
||||
class NewPrivateChat extends StatefulWidget {
|
||||
const NewPrivateChat({Key key}) : super(key: key);
|
||||
|
||||
@override
|
||||
NewPrivateChatController createState() => NewPrivateChatController();
|
||||
}
|
||||
@ -54,7 +56,7 @@ class NewPrivateChatController extends State<NewPrivateChat> {
|
||||
context: context,
|
||||
useRootNavigator: false,
|
||||
//useSafeArea: false,
|
||||
builder: (_) => QrScannerModal(),
|
||||
builder: (_) => const QrScannerModal(),
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -7,6 +7,8 @@ import 'package:matrix/matrix.dart';
|
||||
import 'package:vrouter/vrouter.dart';
|
||||
|
||||
class NewSpace extends StatefulWidget {
|
||||
const NewSpace({Key key}) : super(key: key);
|
||||
|
||||
@override
|
||||
NewSpaceController createState() => NewSpaceController();
|
||||
}
|
||||
|
@ -63,7 +63,7 @@ class _PermissionSliderDialogState extends State<PermissionSliderDialog> {
|
||||
: _permission >= 50
|
||||
? '$_permission (${L10n.of(context).moderator})'
|
||||
: _permission.toString())),
|
||||
Container(
|
||||
SizedBox(
|
||||
height: 56,
|
||||
child: slider,
|
||||
),
|
||||
|
@ -32,7 +32,7 @@ class _QrScannerModalState extends State<QrScannerModal> {
|
||||
return Scaffold(
|
||||
appBar: AppBar(
|
||||
leading: IconButton(
|
||||
icon: Icon(Icons.close_outlined),
|
||||
icon: const Icon(Icons.close_outlined),
|
||||
onPressed: Navigator.of(context).pop,
|
||||
tooltip: L10n.of(context).close,
|
||||
),
|
||||
|
@ -45,10 +45,10 @@ class _RecordingDialogState extends State<RecordingDialog> {
|
||||
setState(() => _duration = Duration.zero);
|
||||
_recorderSubscription?.cancel();
|
||||
_recorderSubscription =
|
||||
Timer.periodic(Duration(milliseconds: 100), (_) async {
|
||||
Timer.periodic(const Duration(milliseconds: 100), (_) async {
|
||||
_amplitude = await _audioRecorder.getAmplitude();
|
||||
setState(() {
|
||||
_duration += Duration(milliseconds: 100);
|
||||
_duration += const Duration(milliseconds: 100);
|
||||
});
|
||||
});
|
||||
} catch (e, s) {
|
||||
@ -92,7 +92,7 @@ class _RecordingDialogState extends State<RecordingDialog> {
|
||||
height: maxDecibalWidth,
|
||||
alignment: Alignment.center,
|
||||
child: AnimatedContainer(
|
||||
duration: Duration(milliseconds: 100),
|
||||
duration: const Duration(milliseconds: 100),
|
||||
width: decibalWidth,
|
||||
height: decibalWidth,
|
||||
decoration: BoxDecoration(
|
||||
@ -101,11 +101,11 @@ class _RecordingDialogState extends State<RecordingDialog> {
|
||||
),
|
||||
),
|
||||
),
|
||||
SizedBox(width: 8),
|
||||
const SizedBox(width: 8),
|
||||
Expanded(
|
||||
child: Text(
|
||||
'${L10n.of(context).recording}: $time',
|
||||
style: TextStyle(
|
||||
style: const TextStyle(
|
||||
fontSize: 18,
|
||||
),
|
||||
),
|
||||
@ -163,8 +163,8 @@ class _RecordingDialogState extends State<RecordingDialog> {
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: <Widget>[
|
||||
Text(L10n.of(context).send.toUpperCase()),
|
||||
SizedBox(width: 4),
|
||||
Icon(Icons.send_outlined, size: 15),
|
||||
const SizedBox(width: 4),
|
||||
const Icon(Icons.send_outlined, size: 15),
|
||||
],
|
||||
),
|
||||
),
|
||||
|
@ -28,7 +28,7 @@ class SearchController extends State<Search> {
|
||||
setState(() => null);
|
||||
_coolDown?.cancel();
|
||||
_coolDown = Timer(
|
||||
Duration(milliseconds: 500),
|
||||
const Duration(milliseconds: 500),
|
||||
() => setState(() {
|
||||
genericSearchTerm = query;
|
||||
publicRoomsResponse = null;
|
||||
|
@ -57,12 +57,12 @@ class _SendLocationDialogState extends State<SendLocationDialog> {
|
||||
try {
|
||||
_position = await Geolocator.getCurrentPosition(
|
||||
desiredAccuracy: LocationAccuracy.best,
|
||||
timeLimit: Duration(seconds: 30),
|
||||
timeLimit: const Duration(seconds: 30),
|
||||
);
|
||||
} on TimeoutException {
|
||||
_position = await Geolocator.getCurrentPosition(
|
||||
desiredAccuracy: LocationAccuracy.medium,
|
||||
timeLimit: Duration(seconds: 30),
|
||||
timeLimit: const Duration(seconds: 30),
|
||||
);
|
||||
}
|
||||
setState(() => position = _position);
|
||||
@ -104,8 +104,8 @@ class _SendLocationDialogState extends State<SendLocationDialog> {
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
CupertinoActivityIndicator(),
|
||||
SizedBox(width: 12),
|
||||
const CupertinoActivityIndicator(),
|
||||
const SizedBox(width: 12),
|
||||
Text(L10n.of(context).obtainingLocation),
|
||||
],
|
||||
);
|
||||
|
@ -16,6 +16,8 @@ import 'package:future_loading_dialog/future_loading_dialog.dart';
|
||||
import '../widgets/matrix.dart';
|
||||
|
||||
class Settings extends StatefulWidget {
|
||||
const Settings({Key key}) : super(key: key);
|
||||
|
||||
@override
|
||||
SettingsController createState() => SettingsController();
|
||||
}
|
||||
@ -117,7 +119,7 @@ class SettingsController extends State<Settings> {
|
||||
context: context,
|
||||
future: () async {
|
||||
// make sure the loading spinner shows before we test the keys
|
||||
await Future.delayed(Duration(milliseconds: 100));
|
||||
await Future.delayed(const Duration(milliseconds: 100));
|
||||
var valid = false;
|
||||
try {
|
||||
await handle.unlock(recoveryKey: input.single);
|
||||
|
@ -10,6 +10,8 @@ import 'views/settings_3pid_view.dart';
|
||||
class Settings3Pid extends StatefulWidget {
|
||||
static int sendAttempt = 0;
|
||||
|
||||
const Settings3Pid({Key key}) : super(key: key);
|
||||
|
||||
@override
|
||||
Settings3PidController createState() => Settings3PidController();
|
||||
}
|
||||
|
@ -124,7 +124,7 @@ class SettingsAccountController extends State<SettingsAccount> {
|
||||
okLabel: L10n.of(context).ok,
|
||||
cancelLabel: L10n.of(context).cancel,
|
||||
textFields: [
|
||||
DialogTextField(
|
||||
const DialogTextField(
|
||||
obscureText: true,
|
||||
hintText: '******',
|
||||
minLines: 1,
|
||||
|
@ -13,7 +13,7 @@ import '../widgets/matrix.dart';
|
||||
import '../utils/resize_image.dart';
|
||||
|
||||
class EmotesSettings extends StatefulWidget {
|
||||
EmotesSettings({Key key}) : super(key: key);
|
||||
const EmotesSettings({Key key}) : super(key: key);
|
||||
|
||||
@override
|
||||
EmotesSettingsController createState() => EmotesSettingsController();
|
||||
@ -80,13 +80,13 @@ class EmotesSettingsController extends State<EmotesSettings> {
|
||||
final content = client.accountData['im.ponies.emote_rooms']?.content ??
|
||||
<String, dynamic>{};
|
||||
if (active) {
|
||||
if (!(content['rooms'] is Map)) {
|
||||
if (content['rooms'] is! Map) {
|
||||
content['rooms'] = <String, dynamic>{};
|
||||
}
|
||||
if (!(content['rooms'][room.id] is Map)) {
|
||||
if (content['rooms'][room.id] is! Map) {
|
||||
content['rooms'][room.id] = <String, dynamic>{};
|
||||
}
|
||||
if (!(content['rooms'][room.id][stateKey ?? ''] is Map)) {
|
||||
if (content['rooms'][room.id][stateKey ?? ''] is! Map) {
|
||||
content['rooms'][room.id][stateKey ?? ''] = <String, dynamic>{};
|
||||
}
|
||||
} else if (content['rooms'] is Map && content['rooms'][room.id] is Map) {
|
||||
|
@ -7,7 +7,7 @@ import '../widgets/matrix.dart';
|
||||
class SettingsIgnoreList extends StatefulWidget {
|
||||
final String initialUserId;
|
||||
|
||||
SettingsIgnoreList({Key key, this.initialUserId}) : super(key: key);
|
||||
const SettingsIgnoreList({Key key, this.initialUserId}) : super(key: key);
|
||||
|
||||
@override
|
||||
SettingsIgnoreListController createState() => SettingsIgnoreListController();
|
||||
|
@ -4,7 +4,7 @@ import 'package:vrouter/vrouter.dart';
|
||||
import 'views/settings_multiple_emotes_view.dart';
|
||||
|
||||
class MultipleEmotesSettings extends StatefulWidget {
|
||||
MultipleEmotesSettings({Key key}) : super(key: key);
|
||||
const MultipleEmotesSettings({Key key}) : super(key: key);
|
||||
|
||||
@override
|
||||
MultipleEmotesSettingsController createState() =>
|
||||
|
@ -49,6 +49,8 @@ class NotificationSettingsItem {
|
||||
}
|
||||
|
||||
class SettingsNotifications extends StatefulWidget {
|
||||
const SettingsNotifications({Key key}) : super(key: key);
|
||||
|
||||
@override
|
||||
SettingsNotificationsController createState() =>
|
||||
SettingsNotificationsController();
|
||||
@ -57,7 +59,7 @@ class SettingsNotifications extends StatefulWidget {
|
||||
class SettingsNotificationsController extends State<SettingsNotifications> {
|
||||
void openAndroidNotificationSettingsAction() async {
|
||||
await NotificationSetting.configureChannel(
|
||||
NotificationDetails(
|
||||
const NotificationDetails(
|
||||
android: AndroidNotificationDetails(
|
||||
AppConfig.pushNotificationsChannelId,
|
||||
AppConfig.pushNotificationsChannelName,
|
||||
|
@ -55,7 +55,7 @@ class SettingsSecurityController extends State<SettingsSecurity> {
|
||||
|
||||
void setAppLockAction() async {
|
||||
final currentLock =
|
||||
await FlutterSecureStorage().read(key: SettingKeys.appLockKey);
|
||||
await const FlutterSecureStorage().read(key: SettingKeys.appLockKey);
|
||||
if (currentLock?.isNotEmpty ?? false) {
|
||||
await AppLock.of(context).showLockScreen();
|
||||
}
|
||||
@ -81,7 +81,7 @@ class SettingsSecurityController extends State<SettingsSecurity> {
|
||||
],
|
||||
);
|
||||
if (newLock != null) {
|
||||
await FlutterSecureStorage()
|
||||
await const FlutterSecureStorage()
|
||||
.write(key: SettingKeys.appLockKey, value: newLock.single);
|
||||
if (newLock.single.isEmpty) {
|
||||
AppLock.of(context).disable();
|
||||
|
@ -10,6 +10,8 @@ import 'views/settings_style_view.dart';
|
||||
import '../widgets/matrix.dart';
|
||||
|
||||
class SettingsStyle extends StatefulWidget {
|
||||
const SettingsStyle({Key key}) : super(key: key);
|
||||
|
||||
@override
|
||||
SettingsStyleController createState() => SettingsStyleController();
|
||||
}
|
||||
|
@ -24,6 +24,7 @@ class StickerPickerDialogState extends State<StickerPickerDialog> {
|
||||
final stickerPacks = widget.room.getImagePacks(ImagePackUsage.sticker);
|
||||
final packSlugs = stickerPacks.keys.toList();
|
||||
|
||||
// ignore: prefer_function_declarations_over_variables
|
||||
final _packBuilder = (BuildContext context, int packIndex) {
|
||||
final pack = stickerPacks[packSlugs[packIndex]];
|
||||
final filteredImagePackImageEntried = pack.images.entries.toList();
|
||||
@ -43,7 +44,7 @@ class StickerPickerDialogState extends State<StickerPickerDialog> {
|
||||
final packName = pack.pack.displayName ?? packSlugs[packIndex];
|
||||
return Column(
|
||||
children: <Widget>[
|
||||
if (packIndex != 0) SizedBox(height: 20),
|
||||
if (packIndex != 0) const SizedBox(height: 20),
|
||||
if (packName != 'user')
|
||||
ListTile(
|
||||
leading: Avatar(
|
||||
@ -53,13 +54,13 @@ class StickerPickerDialogState extends State<StickerPickerDialog> {
|
||||
),
|
||||
title: Text(packName),
|
||||
),
|
||||
SizedBox(height: 6),
|
||||
const SizedBox(height: 6),
|
||||
GridView.builder(
|
||||
itemCount: imageKeys.length,
|
||||
gridDelegate: SliverGridDelegateWithMaxCrossAxisExtent(
|
||||
gridDelegate: const SliverGridDelegateWithMaxCrossAxisExtent(
|
||||
maxCrossAxisExtent: 100),
|
||||
shrinkWrap: true,
|
||||
physics: NeverScrollableScrollPhysics(),
|
||||
physics: const NeverScrollableScrollPhysics(),
|
||||
itemBuilder: (BuildContext context, int imageIndex) {
|
||||
final image = pack.images[imageKeys[imageIndex]];
|
||||
final fakeEvent = Event.fromJson(<String, dynamic>{
|
||||
@ -99,7 +100,7 @@ class StickerPickerDialogState extends State<StickerPickerDialog> {
|
||||
};
|
||||
|
||||
return Scaffold(
|
||||
body: Container(
|
||||
body: SizedBox(
|
||||
width: double.maxFinite,
|
||||
child: CustomScrollView(
|
||||
slivers: <Widget>[
|
||||
@ -110,13 +111,13 @@ class StickerPickerDialogState extends State<StickerPickerDialog> {
|
||||
titleSpacing: 0,
|
||||
backgroundColor: Theme.of(context).dialogBackgroundColor,
|
||||
leading: IconButton(
|
||||
icon: Icon(Icons.close),
|
||||
icon: const Icon(Icons.close),
|
||||
onPressed: Navigator.of(context, rootNavigator: false).pop,
|
||||
),
|
||||
title: DefaultAppBarSearchField(
|
||||
autofocus: false,
|
||||
hintText: L10n.of(context).search,
|
||||
suffix: Icon(Icons.search_outlined),
|
||||
suffix: const Icon(Icons.search_outlined),
|
||||
onChanged: (s) => setState(() => searchFilter = s),
|
||||
),
|
||||
),
|
||||
|
@ -28,6 +28,7 @@ class UserBottomSheet extends StatefulWidget {
|
||||
|
||||
class UserBottomSheetController extends State<UserBottomSheet> {
|
||||
void participantAction(String action) async {
|
||||
// ignore: prefer_function_declarations_over_variables
|
||||
final Function _askConfirmation =
|
||||
() async => (await showOkCancelAlertDialog(
|
||||
useRootNavigator: false,
|
||||
|
@ -15,7 +15,7 @@ class ArchiveView extends StatelessWidget {
|
||||
future: controller.getArchive(context),
|
||||
builder: (BuildContext context, snapshot) => Scaffold(
|
||||
appBar: AppBar(
|
||||
leading: BackButton(),
|
||||
leading: const BackButton(),
|
||||
title: Text(L10n.of(context).archive),
|
||||
actions: [
|
||||
if (snapshot.hasData &&
|
||||
@ -37,12 +37,12 @@ class ArchiveView extends StatelessWidget {
|
||||
));
|
||||
}
|
||||
if (!snapshot.hasData) {
|
||||
return Center(
|
||||
return const Center(
|
||||
child: CircularProgressIndicator.adaptive(strokeWidth: 2));
|
||||
} else {
|
||||
controller.archive = snapshot.data;
|
||||
if (controller.archive.isEmpty) {
|
||||
return Center(child: Icon(Icons.archive_outlined, size: 80));
|
||||
return const Center(child: Icon(Icons.archive_outlined, size: 80));
|
||||
}
|
||||
return ListView.builder(
|
||||
itemCount: controller.archive.length,
|
||||
|
@ -51,7 +51,7 @@ class ChatDetailsView extends StatelessWidget {
|
||||
(BuildContext context, bool innerBoxIsScrolled) => <Widget>[
|
||||
SliverAppBar(
|
||||
leading: IconButton(
|
||||
icon: Icon(Icons.close_outlined),
|
||||
icon: const Icon(Icons.close_outlined),
|
||||
onPressed: () =>
|
||||
VRouter.of(context).path.startsWith('/spaces/')
|
||||
? VRouter.of(context).pop()
|
||||
@ -66,7 +66,7 @@ class ChatDetailsView extends StatelessWidget {
|
||||
if (room.canonicalAlias?.isNotEmpty ?? false)
|
||||
IconButton(
|
||||
tooltip: L10n.of(context).share,
|
||||
icon: Icon(Icons.share_outlined),
|
||||
icon: const Icon(Icons.share_outlined),
|
||||
onPressed: () => FluffyShare.share(
|
||||
AppConfig.inviteLinkPrefix + room.canonicalAlias,
|
||||
context),
|
||||
@ -107,7 +107,7 @@ class ChatDetailsView extends StatelessWidget {
|
||||
.scaffoldBackgroundColor,
|
||||
foregroundColor: Colors.grey,
|
||||
radius: Avatar.defaultSize / 2,
|
||||
child: Icon(Icons.edit_outlined),
|
||||
child: const Icon(Icons.edit_outlined),
|
||||
)
|
||||
: null,
|
||||
title: Text(
|
||||
@ -121,7 +121,7 @@ class ChatDetailsView extends StatelessWidget {
|
||||
text: room.topic?.isEmpty ?? true
|
||||
? L10n.of(context).addGroupDescription
|
||||
: room.topic,
|
||||
linkStyle: TextStyle(color: Colors.blueAccent),
|
||||
linkStyle: const TextStyle(color: Colors.blueAccent),
|
||||
textStyle: TextStyle(
|
||||
fontSize: 14,
|
||||
color: Theme.of(context)
|
||||
@ -136,7 +136,7 @@ class ChatDetailsView extends StatelessWidget {
|
||||
? controller.setTopicAction
|
||||
: null,
|
||||
),
|
||||
Divider(thickness: 1),
|
||||
const Divider(thickness: 1),
|
||||
ListTile(
|
||||
title: Text(
|
||||
L10n.of(context).settings,
|
||||
@ -153,7 +153,7 @@ class ChatDetailsView extends StatelessWidget {
|
||||
backgroundColor:
|
||||
Theme.of(context).scaffoldBackgroundColor,
|
||||
foregroundColor: Colors.grey,
|
||||
child: Icon(Icons.people_outlined),
|
||||
child: const Icon(Icons.people_outlined),
|
||||
),
|
||||
title: Text(
|
||||
L10n.of(context).changeTheNameOfTheGroup),
|
||||
@ -167,7 +167,7 @@ class ChatDetailsView extends StatelessWidget {
|
||||
backgroundColor:
|
||||
Theme.of(context).scaffoldBackgroundColor,
|
||||
foregroundColor: Colors.grey,
|
||||
child: Icon(Icons.link_outlined),
|
||||
child: const Icon(Icons.link_outlined),
|
||||
),
|
||||
onTap: controller.editAliases,
|
||||
title: Text(L10n.of(context).editRoomAliases),
|
||||
@ -181,7 +181,7 @@ class ChatDetailsView extends StatelessWidget {
|
||||
backgroundColor:
|
||||
Theme.of(context).scaffoldBackgroundColor,
|
||||
foregroundColor: Colors.grey,
|
||||
child: Icon(Icons.insert_emoticon_outlined),
|
||||
child: const Icon(Icons.insert_emoticon_outlined),
|
||||
),
|
||||
title: Text(L10n.of(context).emoteSettings),
|
||||
subtitle: Text(L10n.of(context).setCustomEmotes),
|
||||
@ -211,7 +211,7 @@ class ChatDetailsView extends StatelessWidget {
|
||||
backgroundColor: Theme.of(context)
|
||||
.scaffoldBackgroundColor,
|
||||
foregroundColor: Colors.grey,
|
||||
child: Icon(Icons.public_outlined)),
|
||||
child: const Icon(Icons.public_outlined)),
|
||||
title: Text(L10n.of(context)
|
||||
.whoIsAllowedToJoinThisGroup),
|
||||
subtitle: Text(
|
||||
@ -258,7 +258,7 @@ class ChatDetailsView extends StatelessWidget {
|
||||
backgroundColor:
|
||||
Theme.of(context).scaffoldBackgroundColor,
|
||||
foregroundColor: Colors.grey,
|
||||
child: Icon(Icons.visibility_outlined),
|
||||
child: const Icon(Icons.visibility_outlined),
|
||||
),
|
||||
title: Text(L10n.of(context)
|
||||
.visibilityOfTheChatHistory),
|
||||
@ -297,7 +297,7 @@ class ChatDetailsView extends StatelessWidget {
|
||||
backgroundColor: Theme.of(context)
|
||||
.scaffoldBackgroundColor,
|
||||
foregroundColor: Colors.grey,
|
||||
child: Icon(Icons.info_outline),
|
||||
child: const Icon(Icons.info_outline),
|
||||
),
|
||||
title: Text(
|
||||
L10n.of(context).areGuestsAllowedToJoin),
|
||||
@ -315,12 +315,12 @@ class ChatDetailsView extends StatelessWidget {
|
||||
backgroundColor:
|
||||
Theme.of(context).scaffoldBackgroundColor,
|
||||
foregroundColor: Colors.grey,
|
||||
child: Icon(Icons.edit_attributes_outlined),
|
||||
child: const Icon(Icons.edit_attributes_outlined),
|
||||
),
|
||||
onTap: () =>
|
||||
VRouter.of(context).to('permissions'),
|
||||
),
|
||||
Divider(thickness: 1),
|
||||
const Divider(thickness: 1),
|
||||
ListTile(
|
||||
title: Text(
|
||||
actualMembersCount > 1
|
||||
@ -342,7 +342,7 @@ class ChatDetailsView extends StatelessWidget {
|
||||
Theme.of(context).primaryColor,
|
||||
foregroundColor: Colors.white,
|
||||
radius: Avatar.defaultSize / 2,
|
||||
child: Icon(Icons.add_outlined),
|
||||
child: const Icon(Icons.add_outlined),
|
||||
),
|
||||
onTap: () =>
|
||||
VRouter.of(context).to('invite'),
|
||||
@ -361,7 +361,7 @@ class ChatDetailsView extends StatelessWidget {
|
||||
leading: CircleAvatar(
|
||||
backgroundColor:
|
||||
Theme.of(context).scaffoldBackgroundColor,
|
||||
child: Icon(
|
||||
child: const Icon(
|
||||
Icons.refresh,
|
||||
color: Colors.grey,
|
||||
),
|
||||
|
@ -21,19 +21,19 @@ class ChatEncryptionSettingsView extends StatelessWidget {
|
||||
return Scaffold(
|
||||
appBar: AppBar(
|
||||
leading: IconButton(
|
||||
icon: Icon(Icons.close_outlined),
|
||||
icon: const Icon(Icons.close_outlined),
|
||||
onPressed: () =>
|
||||
VRouter.of(context).toSegments(['rooms', controller.roomId]),
|
||||
),
|
||||
title: Text(L10n.of(context).tapOnDeviceToVerify),
|
||||
bottom: PreferredSize(
|
||||
preferredSize: Size.fromHeight(56),
|
||||
preferredSize: const Size.fromHeight(56),
|
||||
child: ListTile(
|
||||
title: Text(L10n.of(context).deviceVerifyDescription),
|
||||
leading: CircleAvatar(
|
||||
backgroundColor: Theme.of(context).secondaryHeaderColor,
|
||||
foregroundColor: Theme.of(context).colorScheme.secondary,
|
||||
child: Icon(Icons.lock),
|
||||
child: const Icon(Icons.lock),
|
||||
),
|
||||
),
|
||||
),
|
||||
@ -54,14 +54,14 @@ class ChatEncryptionSettingsView extends StatelessWidget {
|
||||
);
|
||||
}
|
||||
if (!snapshot.hasData) {
|
||||
return Center(
|
||||
return const Center(
|
||||
child:
|
||||
CircularProgressIndicator.adaptive(strokeWidth: 2));
|
||||
}
|
||||
final deviceKeys = snapshot.data;
|
||||
return ListView.builder(
|
||||
shrinkWrap: true,
|
||||
physics: NeverScrollableScrollPhysics(),
|
||||
physics: const NeverScrollableScrollPhysics(),
|
||||
itemCount: deviceKeys.length,
|
||||
itemBuilder: (BuildContext context, int i) => Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
@ -69,7 +69,7 @@ class ChatEncryptionSettingsView extends StatelessWidget {
|
||||
if (i == 0 ||
|
||||
deviceKeys[i].userId !=
|
||||
deviceKeys[i - 1].userId) ...{
|
||||
Divider(height: 1, thickness: 1),
|
||||
const Divider(height: 1, thickness: 1),
|
||||
PopupMenuButton(
|
||||
onSelected: (action) => controller.onSelected(
|
||||
context, action, deviceKeys[i]),
|
||||
@ -103,7 +103,7 @@ class ChatEncryptionSettingsView extends StatelessWidget {
|
||||
),
|
||||
subtitle: Text(
|
||||
deviceKeys[i].userId,
|
||||
style: TextStyle(fontWeight: FontWeight.w300),
|
||||
style: const TextStyle(fontWeight: FontWeight.w300),
|
||||
),
|
||||
),
|
||||
),
|
||||
@ -152,9 +152,9 @@ class ChatEncryptionSettingsView extends StatelessWidget {
|
||||
children: [
|
||||
Text(
|
||||
deviceKeys[i].deviceId,
|
||||
style: TextStyle(fontWeight: FontWeight.w300),
|
||||
style: const TextStyle(fontWeight: FontWeight.w300),
|
||||
),
|
||||
Spacer(),
|
||||
const Spacer(),
|
||||
Text(
|
||||
deviceKeys[i].blocked
|
||||
? L10n.of(context).blocked
|
||||
|
@ -101,12 +101,12 @@ class ChatListView extends StatelessWidget {
|
||||
? null
|
||||
: Builder(
|
||||
builder: (context) => IconButton(
|
||||
icon: Icon(Icons.group_work_outlined),
|
||||
icon: const Icon(Icons.group_work_outlined),
|
||||
onPressed: Scaffold.of(context).openDrawer,
|
||||
))
|
||||
: IconButton(
|
||||
tooltip: L10n.of(context).cancel,
|
||||
icon: Icon(Icons.close_outlined),
|
||||
icon: const Icon(Icons.close_outlined),
|
||||
onPressed: controller.cancelAction,
|
||||
color: Theme.of(context).colorScheme.primary,
|
||||
),
|
||||
@ -125,7 +125,7 @@ class ChatListView extends StatelessWidget {
|
||||
.isDirectChat)
|
||||
IconButton(
|
||||
tooltip: L10n.of(context).addToSpace,
|
||||
icon: Icon(Icons.group_work_outlined),
|
||||
icon: const Icon(Icons.group_work_outlined),
|
||||
onPressed: controller.addOrRemoveToSpace,
|
||||
),
|
||||
if (controller.selectedRoomIds.length == 1)
|
||||
@ -143,7 +143,7 @@ class ChatListView extends StatelessWidget {
|
||||
if (controller.selectedRoomIds.length == 1)
|
||||
IconButton(
|
||||
tooltip: L10n.of(context).toggleFavorite,
|
||||
icon: Icon(Icons.push_pin_outlined),
|
||||
icon: const Icon(Icons.push_pin_outlined),
|
||||
onPressed: controller.toggleFavouriteRoom,
|
||||
),
|
||||
if (controller.selectedRoomIds.length == 1)
|
||||
@ -160,14 +160,14 @@ class ChatListView extends StatelessWidget {
|
||||
onPressed: controller.toggleMuted,
|
||||
),
|
||||
IconButton(
|
||||
icon: Icon(Icons.delete_outlined),
|
||||
icon: const Icon(Icons.delete_outlined),
|
||||
tooltip: L10n.of(context).archive,
|
||||
onPressed: controller.archiveAction,
|
||||
),
|
||||
]
|
||||
: [
|
||||
IconButton(
|
||||
icon: Icon(Icons.search_outlined),
|
||||
icon: const Icon(Icons.search_outlined),
|
||||
tooltip: L10n.of(context).search,
|
||||
onPressed: () =>
|
||||
VRouter.of(context).to('/search'),
|
||||
@ -180,8 +180,8 @@ class ChatListView extends StatelessWidget {
|
||||
child: Row(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
Icon(Icons.edit_outlined),
|
||||
SizedBox(width: 12),
|
||||
const Icon(Icons.edit_outlined),
|
||||
const SizedBox(width: 12),
|
||||
Text(L10n.of(context).setStatus),
|
||||
],
|
||||
),
|
||||
@ -191,8 +191,8 @@ class ChatListView extends StatelessWidget {
|
||||
child: Row(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
Icon(Icons.group_add_outlined),
|
||||
SizedBox(width: 12),
|
||||
const Icon(Icons.group_add_outlined),
|
||||
const SizedBox(width: 12),
|
||||
Text(L10n.of(context).createNewGroup),
|
||||
],
|
||||
),
|
||||
@ -202,8 +202,8 @@ class ChatListView extends StatelessWidget {
|
||||
child: Row(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
Icon(Icons.group_work_outlined),
|
||||
SizedBox(width: 12),
|
||||
const Icon(Icons.group_work_outlined),
|
||||
const SizedBox(width: 12),
|
||||
Text(L10n.of(context).createNewSpace),
|
||||
],
|
||||
),
|
||||
@ -213,8 +213,8 @@ class ChatListView extends StatelessWidget {
|
||||
child: Row(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
Icon(Icons.share_outlined),
|
||||
SizedBox(width: 12),
|
||||
const Icon(Icons.share_outlined),
|
||||
const SizedBox(width: 12),
|
||||
Text(L10n.of(context).inviteContact),
|
||||
],
|
||||
),
|
||||
@ -224,8 +224,8 @@ class ChatListView extends StatelessWidget {
|
||||
child: Row(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
Icon(Icons.archive_outlined),
|
||||
SizedBox(width: 12),
|
||||
const Icon(Icons.archive_outlined),
|
||||
const SizedBox(width: 12),
|
||||
Text(L10n.of(context).archive),
|
||||
],
|
||||
),
|
||||
@ -235,8 +235,8 @@ class ChatListView extends StatelessWidget {
|
||||
child: Row(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
Icon(Icons.settings_outlined),
|
||||
SizedBox(width: 12),
|
||||
const Icon(Icons.settings_outlined),
|
||||
const SizedBox(width: 12),
|
||||
Text(L10n.of(context).settings),
|
||||
],
|
||||
),
|
||||
@ -256,7 +256,7 @@ class ChatListView extends StatelessWidget {
|
||||
.displayname),
|
||||
),
|
||||
body: Column(children: [
|
||||
ConnectionStatusHeader(),
|
||||
const ConnectionStatusHeader(),
|
||||
Expanded(child: _ChatListViewBody(controller)),
|
||||
]),
|
||||
floatingActionButton: selectMode == SelectMode.normal
|
||||
@ -265,14 +265,14 @@ class ChatListView extends StatelessWidget {
|
||||
heroTag: 'main_fab',
|
||||
onPressed: () =>
|
||||
VRouter.of(context).to('/newprivatechat'),
|
||||
icon: Icon(CupertinoIcons.chat_bubble),
|
||||
icon: const Icon(CupertinoIcons.chat_bubble),
|
||||
label: Text(L10n.of(context).newChat),
|
||||
)
|
||||
: FloatingActionButton(
|
||||
heroTag: 'main_fab',
|
||||
onPressed: () =>
|
||||
VRouter.of(context).to('/newprivatechat'),
|
||||
child: Icon(CupertinoIcons.chat_bubble),
|
||||
child: const Icon(CupertinoIcons.chat_bubble),
|
||||
)
|
||||
: null,
|
||||
bottomNavigationBar: Matrix.of(context).isMultiAccount
|
||||
@ -291,7 +291,7 @@ class ChatListView extends StatelessWidget {
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
Divider(height: 1),
|
||||
const Divider(height: 1),
|
||||
Builder(builder: (context) {
|
||||
final items = getBottomBarItems(context);
|
||||
if (items.length == 1) {
|
||||
@ -378,7 +378,7 @@ class ChatListView extends StatelessWidget {
|
||||
backgroundColor:
|
||||
Theme.of(context).primaryColor,
|
||||
radius: Avatar.defaultSize / 2,
|
||||
child: Icon(Icons.home_outlined),
|
||||
child: const Icon(Icons.home_outlined),
|
||||
),
|
||||
title: Text(L10n.of(context).allChats),
|
||||
onTap: () =>
|
||||
@ -399,7 +399,7 @@ class ChatListView extends StatelessWidget {
|
||||
onTap: () => controller.setActiveSpaceId(
|
||||
context, space.id),
|
||||
trailing: IconButton(
|
||||
icon: Icon(Icons.edit_outlined),
|
||||
icon: const Icon(Icons.edit_outlined),
|
||||
onPressed: () =>
|
||||
controller.editSpace(context, space.id),
|
||||
),
|
||||
@ -425,7 +425,7 @@ class _ChatListViewBody extends StatelessWidget {
|
||||
.onSync
|
||||
.stream
|
||||
.where((s) => s.hasRoomUpdate)
|
||||
.rateLimit(Duration(seconds: 1)),
|
||||
.rateLimit(const Duration(seconds: 1)),
|
||||
builder: (context, snapshot) {
|
||||
return FutureBuilder<void>(
|
||||
future: controller.waitForFirstSync(),
|
||||
@ -441,7 +441,7 @@ class _ChatListViewBody extends StatelessWidget {
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: <Widget>[
|
||||
Icon(
|
||||
const Icon(
|
||||
Icons.maps_ugc_outlined,
|
||||
size: 80,
|
||||
color: Colors.grey,
|
||||
@ -450,7 +450,7 @@ class _ChatListViewBody extends StatelessWidget {
|
||||
child: Text(
|
||||
L10n.of(context).startYourFirstChat,
|
||||
textAlign: TextAlign.start,
|
||||
style: TextStyle(
|
||||
style: const TextStyle(
|
||||
color: Colors.grey,
|
||||
fontSize: 16,
|
||||
),
|
||||
|
@ -21,7 +21,7 @@ class ChatPermissionsSettingsView extends StatelessWidget {
|
||||
leading: VRouter.of(context).path.startsWith('/spaces/')
|
||||
? null
|
||||
: IconButton(
|
||||
icon: Icon(Icons.close_outlined),
|
||||
icon: const Icon(Icons.close_outlined),
|
||||
onPressed: () => VRouter.of(context)
|
||||
.toSegments(['rooms', controller.roomId]),
|
||||
),
|
||||
@ -37,10 +37,10 @@ class ChatPermissionsSettingsView extends StatelessWidget {
|
||||
final powerLevelsContent = Map<String, dynamic>.from(
|
||||
room.getState(EventTypes.RoomPowerLevels).content);
|
||||
final powerLevels = Map<String, dynamic>.from(powerLevelsContent)
|
||||
..removeWhere((k, v) => !(v is int));
|
||||
..removeWhere((k, v) => v is! int);
|
||||
final eventsPowerLevels =
|
||||
Map<String, dynamic>.from(powerLevelsContent['events'] ?? {})
|
||||
..removeWhere((k, v) => !(v is int));
|
||||
..removeWhere((k, v) => v is! int);
|
||||
return Column(
|
||||
children: [
|
||||
Column(
|
||||
@ -53,7 +53,7 @@ class ChatPermissionsSettingsView extends StatelessWidget {
|
||||
onTap: () => controller.editPowerLevel(
|
||||
context, entry.key, entry.value),
|
||||
),
|
||||
Divider(thickness: 1),
|
||||
const Divider(thickness: 1),
|
||||
ListTile(
|
||||
title: Text(
|
||||
L10n.of(context).notifications,
|
||||
@ -64,7 +64,7 @@ class ChatPermissionsSettingsView extends StatelessWidget {
|
||||
),
|
||||
),
|
||||
Builder(builder: (context) {
|
||||
final key = 'rooms';
|
||||
const key = 'rooms';
|
||||
final int value = powerLevelsContent
|
||||
.containsKey('notifications')
|
||||
? powerLevelsContent['notifications']['rooms'] ?? 0
|
||||
@ -78,7 +78,7 @@ class ChatPermissionsSettingsView extends StatelessWidget {
|
||||
category: 'notifications'),
|
||||
);
|
||||
}),
|
||||
Divider(thickness: 1),
|
||||
const Divider(thickness: 1),
|
||||
ListTile(
|
||||
title: Text(
|
||||
L10n.of(context).configureChat,
|
||||
@ -99,12 +99,12 @@ class ChatPermissionsSettingsView extends StatelessWidget {
|
||||
category: 'events'),
|
||||
),
|
||||
if (room.canSendEvent(EventTypes.RoomTombstone)) ...{
|
||||
Divider(thickness: 1),
|
||||
const Divider(thickness: 1),
|
||||
FutureBuilder<Capabilities>(
|
||||
future: room.client.getCapabilities(),
|
||||
builder: (context, snapshot) {
|
||||
if (!snapshot.hasData) {
|
||||
return Center(
|
||||
return const Center(
|
||||
child: CircularProgressIndicator.adaptive(
|
||||
strokeWidth: 2));
|
||||
}
|
||||
|
@ -66,7 +66,7 @@ class ChatView extends StatelessWidget {
|
||||
},
|
||||
child: StreamBuilder(
|
||||
stream: controller.room.onUpdate.stream
|
||||
.rateLimit(Duration(milliseconds: 250)),
|
||||
.rateLimit(const Duration(milliseconds: 250)),
|
||||
builder: (context, snapshot) => Scaffold(
|
||||
appBar: AppBar(
|
||||
actionsIconTheme: IconThemeData(
|
||||
@ -76,7 +76,7 @@ class ChatView extends StatelessWidget {
|
||||
),
|
||||
leading: controller.selectMode
|
||||
? IconButton(
|
||||
icon: Icon(Icons.close),
|
||||
icon: const Icon(Icons.close),
|
||||
onPressed: controller.clearSelectedEvents,
|
||||
tooltip: L10n.of(context).close,
|
||||
color: Theme.of(context).colorScheme.primary,
|
||||
@ -117,7 +117,7 @@ class ChatView extends StatelessWidget {
|
||||
.where((p) =>
|
||||
p.senderId ==
|
||||
controller.room.directChatMatrixID)
|
||||
.rateLimit(Duration(seconds: 1)),
|
||||
.rateLimit(const Duration(seconds: 1)),
|
||||
builder: (context, snapshot) => Text(
|
||||
controller.room.getLocalizedStatus(context),
|
||||
maxLines: 1,
|
||||
@ -129,7 +129,7 @@ class ChatView extends StatelessWidget {
|
||||
color:
|
||||
Theme.of(context).colorScheme.secondary,
|
||||
size: 13),
|
||||
SizedBox(width: 4),
|
||||
const SizedBox(width: 4),
|
||||
Expanded(
|
||||
child: Text(
|
||||
controller.room
|
||||
@ -150,24 +150,24 @@ class ChatView extends StatelessWidget {
|
||||
? <Widget>[
|
||||
if (controller.canEditSelectedEvents)
|
||||
IconButton(
|
||||
icon: Icon(Icons.edit_outlined),
|
||||
icon: const Icon(Icons.edit_outlined),
|
||||
tooltip: L10n.of(context).edit,
|
||||
onPressed: controller.editSelectedEventAction,
|
||||
),
|
||||
IconButton(
|
||||
icon: Icon(Icons.copy_outlined),
|
||||
icon: const Icon(Icons.copy_outlined),
|
||||
tooltip: L10n.of(context).copy,
|
||||
onPressed: controller.copyEventsAction,
|
||||
),
|
||||
if (controller.selectedEvents.length == 1)
|
||||
IconButton(
|
||||
icon: Icon(Icons.report_outlined),
|
||||
icon: const Icon(Icons.report_outlined),
|
||||
tooltip: L10n.of(context).reportMessage,
|
||||
onPressed: controller.reportEventAction,
|
||||
),
|
||||
if (controller.canRedactSelectedEvents)
|
||||
IconButton(
|
||||
icon: Icon(Icons.delete_outlined),
|
||||
icon: const Icon(Icons.delete_outlined),
|
||||
tooltip: L10n.of(context).redactMessage,
|
||||
onPressed: controller.redactEventsAction,
|
||||
),
|
||||
@ -176,7 +176,7 @@ class ChatView extends StatelessWidget {
|
||||
if (controller.room.canSendDefaultStates)
|
||||
IconButton(
|
||||
tooltip: L10n.of(context).videoCall,
|
||||
icon: Icon(Icons.video_call_outlined),
|
||||
icon: const Icon(Icons.video_call_outlined),
|
||||
onPressed: controller.startCallAction,
|
||||
),
|
||||
ChatSettingsPopupMenu(
|
||||
@ -211,7 +211,7 @@ class ChatView extends StatelessWidget {
|
||||
children: <Widget>[
|
||||
if (controller.room.getState(EventTypes.RoomTombstone) !=
|
||||
null)
|
||||
Container(
|
||||
SizedBox(
|
||||
height: 72,
|
||||
child: Material(
|
||||
color: Theme.of(context).secondaryHeaderColor,
|
||||
@ -222,7 +222,7 @@ class ChatView extends StatelessWidget {
|
||||
Theme.of(context).colorScheme.secondary,
|
||||
backgroundColor:
|
||||
Theme.of(context).backgroundColor,
|
||||
child: Icon(Icons.upgrade_outlined),
|
||||
child: const Icon(Icons.upgrade_outlined),
|
||||
),
|
||||
title: Text(
|
||||
controller.room
|
||||
@ -242,7 +242,7 @@ class ChatView extends StatelessWidget {
|
||||
future: controller.getTimeline(),
|
||||
builder: (BuildContext context, snapshot) {
|
||||
if (controller.timeline == null) {
|
||||
return Center(
|
||||
return const Center(
|
||||
child: CircularProgressIndicator.adaptive(
|
||||
strokeWidth: 2),
|
||||
);
|
||||
@ -266,7 +266,7 @@ class ChatView extends StatelessWidget {
|
||||
);
|
||||
|
||||
return ListView.custom(
|
||||
padding: EdgeInsets.only(
|
||||
padding: const EdgeInsets.only(
|
||||
top: 16,
|
||||
bottom: 4,
|
||||
),
|
||||
@ -279,7 +279,7 @@ class ChatView extends StatelessWidget {
|
||||
(BuildContext context, int i) {
|
||||
return i == controller.filteredEvents.length + 1
|
||||
? controller.timeline.isRequestingHistory
|
||||
? Center(
|
||||
? const Center(
|
||||
child: CircularProgressIndicator
|
||||
.adaptive(strokeWidth: 2),
|
||||
)
|
||||
@ -303,8 +303,8 @@ class ChatView extends StatelessWidget {
|
||||
? AnimatedContainer(
|
||||
height: seenByText.isEmpty ? 0 : 24,
|
||||
duration: seenByText.isEmpty
|
||||
? Duration(milliseconds: 0)
|
||||
: Duration(milliseconds: 300),
|
||||
? const Duration(milliseconds: 0)
|
||||
: const Duration(milliseconds: 300),
|
||||
alignment: controller.filteredEvents
|
||||
.isNotEmpty &&
|
||||
controller.filteredEvents
|
||||
@ -312,13 +312,13 @@ class ChatView extends StatelessWidget {
|
||||
client.userID
|
||||
? Alignment.topRight
|
||||
: Alignment.topLeft,
|
||||
padding: EdgeInsets.only(
|
||||
padding: const EdgeInsets.only(
|
||||
left: 8,
|
||||
right: 8,
|
||||
bottom: 8,
|
||||
),
|
||||
child: Container(
|
||||
padding: EdgeInsets.symmetric(
|
||||
padding: const EdgeInsets.symmetric(
|
||||
horizontal: 4),
|
||||
decoration: BoxDecoration(
|
||||
color: Theme.of(context)
|
||||
@ -349,7 +349,7 @@ class ChatView extends StatelessWidget {
|
||||
key: ValueKey(controller
|
||||
.filteredEvents[i - 1]
|
||||
.eventId),
|
||||
background: Padding(
|
||||
background: const Padding(
|
||||
padding: EdgeInsets.symmetric(
|
||||
horizontal: 12.0),
|
||||
child: Center(
|
||||
@ -409,10 +409,10 @@ class ChatView extends StatelessWidget {
|
||||
},
|
||||
),
|
||||
),
|
||||
ConnectionStatusHeader(),
|
||||
const ConnectionStatusHeader(),
|
||||
if (!controller.showEmojiPicker)
|
||||
AnimatedContainer(
|
||||
duration: Duration(milliseconds: 300),
|
||||
duration: const Duration(milliseconds: 300),
|
||||
height: (controller.editEvent == null &&
|
||||
controller.replyEvent == null &&
|
||||
controller.room.canSendDefaultMessages &&
|
||||
@ -437,12 +437,12 @@ class ChatView extends StatelessWidget {
|
||||
event.room.client.userID &&
|
||||
event.type == 'm.reaction');
|
||||
|
||||
allReactionEvents.forEach((event) {
|
||||
for (final event in allReactionEvents) {
|
||||
try {
|
||||
emojis.remove(
|
||||
event.content['m.relates_to']['key']);
|
||||
} catch (_) {}
|
||||
});
|
||||
}
|
||||
return ListView.builder(
|
||||
scrollDirection: Axis.horizontal,
|
||||
itemCount: emojis.length + 1,
|
||||
@ -455,7 +455,7 @@ class ChatView extends StatelessWidget {
|
||||
width: 56,
|
||||
height: 56,
|
||||
alignment: Alignment.center,
|
||||
child: Icon(Icons.add_outlined),
|
||||
child: const Icon(Icons.add_outlined),
|
||||
),
|
||||
)
|
||||
: InkWell(
|
||||
@ -468,7 +468,7 @@ class ChatView extends StatelessWidget {
|
||||
alignment: Alignment.center,
|
||||
child: Text(
|
||||
emojis[i],
|
||||
style: TextStyle(fontSize: 30),
|
||||
style: const TextStyle(fontSize: 30),
|
||||
),
|
||||
),
|
||||
),
|
||||
@ -477,7 +477,7 @@ class ChatView extends StatelessWidget {
|
||||
),
|
||||
),
|
||||
AnimatedContainer(
|
||||
duration: Duration(milliseconds: 300),
|
||||
duration: const Duration(milliseconds: 300),
|
||||
height: controller.editEvent != null ||
|
||||
controller.replyEvent != null
|
||||
? 56
|
||||
@ -488,7 +488,7 @@ class ChatView extends StatelessWidget {
|
||||
children: <Widget>[
|
||||
IconButton(
|
||||
tooltip: L10n.of(context).close,
|
||||
icon: Icon(Icons.close),
|
||||
icon: const Icon(Icons.close),
|
||||
onPressed: controller.cancelReplyEventAction,
|
||||
),
|
||||
Expanded(
|
||||
@ -502,7 +502,7 @@ class ChatView extends StatelessWidget {
|
||||
),
|
||||
),
|
||||
),
|
||||
Divider(height: 1),
|
||||
const Divider(height: 1),
|
||||
if (controller.room.canSendDefaultMessages &&
|
||||
controller.room.membership == Membership.join &&
|
||||
!controller.showEmojiPicker)
|
||||
@ -515,13 +515,13 @@ class ChatView extends StatelessWidget {
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: controller.selectMode
|
||||
? <Widget>[
|
||||
Container(
|
||||
SizedBox(
|
||||
height: 56,
|
||||
child: TextButton(
|
||||
onPressed: controller.forwardEventsAction,
|
||||
child: Row(
|
||||
children: <Widget>[
|
||||
Icon(Icons
|
||||
const Icon(Icons
|
||||
.keyboard_arrow_left_outlined),
|
||||
Text(L10n.of(context).forward),
|
||||
],
|
||||
@ -534,7 +534,7 @@ class ChatView extends StatelessWidget {
|
||||
controller.timeline)
|
||||
.status >
|
||||
0
|
||||
? Container(
|
||||
? SizedBox(
|
||||
height: 56,
|
||||
child: TextButton(
|
||||
onPressed:
|
||||
@ -543,13 +543,13 @@ class ChatView extends StatelessWidget {
|
||||
children: <Widget>[
|
||||
Text(
|
||||
L10n.of(context).reply),
|
||||
Icon(Icons
|
||||
const Icon(Icons
|
||||
.keyboard_arrow_right),
|
||||
],
|
||||
),
|
||||
),
|
||||
)
|
||||
: Container(
|
||||
: SizedBox(
|
||||
height: 56,
|
||||
child: TextButton(
|
||||
onPressed:
|
||||
@ -558,8 +558,8 @@ class ChatView extends StatelessWidget {
|
||||
children: <Widget>[
|
||||
Text(L10n.of(context)
|
||||
.tryToSendAgain),
|
||||
SizedBox(width: 4),
|
||||
Icon(Icons.send_outlined,
|
||||
const SizedBox(width: 4),
|
||||
const Icon(Icons.send_outlined,
|
||||
size: 16),
|
||||
],
|
||||
),
|
||||
@ -569,15 +569,15 @@ class ChatView extends StatelessWidget {
|
||||
]
|
||||
: <Widget>[
|
||||
AnimatedContainer(
|
||||
duration: Duration(milliseconds: 200),
|
||||
duration: const Duration(milliseconds: 200),
|
||||
height: 56,
|
||||
width:
|
||||
controller.inputText.isEmpty ? 56 : 0,
|
||||
alignment: Alignment.center,
|
||||
clipBehavior: Clip.hardEdge,
|
||||
decoration: BoxDecoration(),
|
||||
decoration: const BoxDecoration(),
|
||||
child: PopupMenuButton<String>(
|
||||
icon: Icon(Icons.add_outlined),
|
||||
icon: const Icon(Icons.add_outlined),
|
||||
onSelected: controller
|
||||
.onAddPopupMenuButtonSelected,
|
||||
itemBuilder: (BuildContext context) =>
|
||||
@ -585,7 +585,7 @@ class ChatView extends StatelessWidget {
|
||||
PopupMenuItem<String>(
|
||||
value: 'file',
|
||||
child: ListTile(
|
||||
leading: CircleAvatar(
|
||||
leading: const CircleAvatar(
|
||||
backgroundColor: Colors.green,
|
||||
foregroundColor: Colors.white,
|
||||
child: Icon(
|
||||
@ -593,27 +593,27 @@ class ChatView extends StatelessWidget {
|
||||
),
|
||||
title:
|
||||
Text(L10n.of(context).sendFile),
|
||||
contentPadding: EdgeInsets.all(0),
|
||||
contentPadding: const EdgeInsets.all(0),
|
||||
),
|
||||
),
|
||||
PopupMenuItem<String>(
|
||||
value: 'image',
|
||||
child: ListTile(
|
||||
leading: CircleAvatar(
|
||||
leading: const CircleAvatar(
|
||||
backgroundColor: Colors.blue,
|
||||
foregroundColor: Colors.white,
|
||||
child: Icon(Icons.image_outlined),
|
||||
),
|
||||
title: Text(
|
||||
L10n.of(context).sendImage),
|
||||
contentPadding: EdgeInsets.all(0),
|
||||
contentPadding: const EdgeInsets.all(0),
|
||||
),
|
||||
),
|
||||
if (PlatformInfos.isMobile)
|
||||
PopupMenuItem<String>(
|
||||
value: 'camera',
|
||||
child: ListTile(
|
||||
leading: CircleAvatar(
|
||||
leading: const CircleAvatar(
|
||||
backgroundColor: Colors.purple,
|
||||
foregroundColor: Colors.white,
|
||||
child: Icon(
|
||||
@ -621,7 +621,7 @@ class ChatView extends StatelessWidget {
|
||||
),
|
||||
title: Text(
|
||||
L10n.of(context).openCamera),
|
||||
contentPadding: EdgeInsets.all(0),
|
||||
contentPadding: const EdgeInsets.all(0),
|
||||
),
|
||||
),
|
||||
if (controller.room
|
||||
@ -631,7 +631,7 @@ class ChatView extends StatelessWidget {
|
||||
PopupMenuItem<String>(
|
||||
value: 'sticker',
|
||||
child: ListTile(
|
||||
leading: CircleAvatar(
|
||||
leading: const CircleAvatar(
|
||||
backgroundColor: Colors.orange,
|
||||
foregroundColor: Colors.white,
|
||||
child: Icon(Icons
|
||||
@ -639,14 +639,14 @@ class ChatView extends StatelessWidget {
|
||||
),
|
||||
title: Text(
|
||||
L10n.of(context).sendSticker),
|
||||
contentPadding: EdgeInsets.all(0),
|
||||
contentPadding: const EdgeInsets.all(0),
|
||||
),
|
||||
),
|
||||
if (PlatformInfos.isMobile)
|
||||
PopupMenuItem<String>(
|
||||
value: 'voice',
|
||||
child: ListTile(
|
||||
leading: CircleAvatar(
|
||||
leading: const CircleAvatar(
|
||||
backgroundColor: Colors.red,
|
||||
foregroundColor: Colors.white,
|
||||
child: Icon(
|
||||
@ -654,14 +654,14 @@ class ChatView extends StatelessWidget {
|
||||
),
|
||||
title: Text(L10n.of(context)
|
||||
.voiceMessage),
|
||||
contentPadding: EdgeInsets.all(0),
|
||||
contentPadding: const EdgeInsets.all(0),
|
||||
),
|
||||
),
|
||||
if (PlatformInfos.isMobile)
|
||||
PopupMenuItem<String>(
|
||||
value: 'location',
|
||||
child: ListTile(
|
||||
leading: CircleAvatar(
|
||||
leading: const CircleAvatar(
|
||||
backgroundColor: Colors.brown,
|
||||
foregroundColor: Colors.white,
|
||||
child: Icon(
|
||||
@ -669,7 +669,7 @@ class ChatView extends StatelessWidget {
|
||||
),
|
||||
title: Text(L10n.of(context)
|
||||
.shareLocation),
|
||||
contentPadding: EdgeInsets.all(0),
|
||||
contentPadding: const EdgeInsets.all(0),
|
||||
),
|
||||
),
|
||||
],
|
||||
@ -725,7 +725,7 @@ class ChatView extends StatelessWidget {
|
||||
alignment: Alignment.center,
|
||||
child: IconButton(
|
||||
tooltip: L10n.of(context).voiceMessage,
|
||||
icon: Icon(Icons.mic_none_outlined),
|
||||
icon: const Icon(Icons.mic_none_outlined),
|
||||
onPressed:
|
||||
controller.voiceMessageAction,
|
||||
),
|
||||
@ -736,7 +736,7 @@ class ChatView extends StatelessWidget {
|
||||
height: 56,
|
||||
alignment: Alignment.center,
|
||||
child: IconButton(
|
||||
icon: Icon(Icons.send_outlined),
|
||||
icon: const Icon(Icons.send_outlined),
|
||||
onPressed: controller.send,
|
||||
tooltip: L10n.of(context).send,
|
||||
),
|
||||
@ -745,7 +745,7 @@ class ChatView extends StatelessWidget {
|
||||
),
|
||||
),
|
||||
AnimatedContainer(
|
||||
duration: Duration(milliseconds: 300),
|
||||
duration: const Duration(milliseconds: 300),
|
||||
height: controller.showEmojiPicker
|
||||
? MediaQuery.of(context).size.height / 2
|
||||
: 0,
|
||||
@ -770,7 +770,7 @@ class ChatView extends StatelessWidget {
|
||||
class _EditContent extends StatelessWidget {
|
||||
final Event event;
|
||||
|
||||
_EditContent(this.event);
|
||||
const _EditContent(this.event);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
@ -840,7 +840,7 @@ class _ChatAccountPicker extends StatelessWidget {
|
||||
),
|
||||
title:
|
||||
Text(snapshot.data?.displayName ?? client.userID),
|
||||
contentPadding: EdgeInsets.all(0),
|
||||
contentPadding: const EdgeInsets.all(0),
|
||||
),
|
||||
),
|
||||
))
|
||||
|
@ -14,7 +14,7 @@ class DevicesSettingsView extends StatelessWidget {
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
appBar: AppBar(
|
||||
leading: BackButton(),
|
||||
leading: const BackButton(),
|
||||
title: Text(L10n.of(context).devices),
|
||||
),
|
||||
body: MaxWidthBody(
|
||||
@ -26,14 +26,14 @@ class DevicesSettingsView extends StatelessWidget {
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: <Widget>[
|
||||
Icon(Icons.error_outlined),
|
||||
const Icon(Icons.error_outlined),
|
||||
Text(snapshot.error.toString()),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
if (!snapshot.hasData || controller.devices == null) {
|
||||
return Center(
|
||||
return const Center(
|
||||
child: CircularProgressIndicator.adaptive(strokeWidth: 2));
|
||||
}
|
||||
return Column(
|
||||
@ -47,23 +47,23 @@ class DevicesSettingsView extends StatelessWidget {
|
||||
block: controller.blockDeviceAction,
|
||||
unblock: controller.unblockDeviceAction,
|
||||
),
|
||||
Divider(height: 1),
|
||||
const Divider(height: 1),
|
||||
if (controller.notThisDevice.isNotEmpty)
|
||||
ListTile(
|
||||
title: Text(
|
||||
controller.errorDeletingDevices ??
|
||||
L10n.of(context).removeAllOtherDevices,
|
||||
style: TextStyle(color: Colors.red),
|
||||
style: const TextStyle(color: Colors.red),
|
||||
),
|
||||
trailing: controller.loadingDeletingDevices
|
||||
? CircularProgressIndicator.adaptive(strokeWidth: 2)
|
||||
: Icon(Icons.delete_outline),
|
||||
? const CircularProgressIndicator.adaptive(strokeWidth: 2)
|
||||
: const Icon(Icons.delete_outline),
|
||||
onTap: controller.loadingDeletingDevices
|
||||
? null
|
||||
: () => controller
|
||||
.removeDevicesAction(controller.notThisDevice),
|
||||
),
|
||||
Divider(height: 1),
|
||||
const Divider(height: 1),
|
||||
Expanded(
|
||||
child: controller.notThisDevice.isEmpty
|
||||
? Center(
|
||||
@ -75,7 +75,7 @@ class DevicesSettingsView extends StatelessWidget {
|
||||
)
|
||||
: ListView.separated(
|
||||
separatorBuilder: (BuildContext context, int i) =>
|
||||
Divider(height: 1),
|
||||
const Divider(height: 1),
|
||||
itemCount: controller.notThisDevice.length,
|
||||
itemBuilder: (BuildContext context, int i) =>
|
||||
UserDeviceListItem(
|
||||
|
@ -34,7 +34,7 @@ class EmptyPage extends StatelessWidget {
|
||||
Center(
|
||||
child: SizedBox(
|
||||
width: _width,
|
||||
child: LinearProgressIndicator(),
|
||||
child: const LinearProgressIndicator(),
|
||||
),
|
||||
),
|
||||
],
|
||||
|
@ -32,7 +32,7 @@ class HomeserverPickerView extends StatelessWidget {
|
||||
prefixText: 'https://',
|
||||
hintText: L10n.of(context).enterYourHomeserver,
|
||||
searchController: controller.homeserverController,
|
||||
suffix: Icon(Icons.edit_outlined),
|
||||
suffix: const Icon(Icons.edit_outlined),
|
||||
padding: EdgeInsets.zero,
|
||||
onChanged: controller.setDomain,
|
||||
readOnly: !AppConfig.allowOtherHomeservers,
|
||||
@ -44,12 +44,12 @@ class HomeserverPickerView extends StatelessWidget {
|
||||
elevation: 0,
|
||||
),
|
||||
body: ListView(children: [
|
||||
Hero(
|
||||
const Hero(
|
||||
tag: 'loginBanner',
|
||||
child: FluffyBanner(),
|
||||
),
|
||||
controller.isLoading
|
||||
? Center(
|
||||
? const Center(
|
||||
child: CircularProgressIndicator.adaptive(strokeWidth: 2))
|
||||
: controller.error != null
|
||||
? Center(
|
||||
@ -77,7 +77,7 @@ class HomeserverPickerView extends StatelessWidget {
|
||||
);
|
||||
}
|
||||
if (!snapshot.hasData) {
|
||||
return Center(
|
||||
return const Center(
|
||||
child: CircularProgressIndicator.adaptive(
|
||||
strokeWidth: 2));
|
||||
}
|
||||
@ -98,7 +98,7 @@ class HomeserverPickerView extends StatelessWidget {
|
||||
onPressed: () => controller
|
||||
.ssoLoginAction(identityProvider.id),
|
||||
icon: identityProvider.icon == null
|
||||
? Icon(Icons.web_outlined)
|
||||
? const Icon(Icons.web_outlined)
|
||||
: CachedNetworkImage(
|
||||
imageUrl: Uri.parse(
|
||||
identityProvider.icon)
|
||||
@ -118,12 +118,12 @@ class HomeserverPickerView extends StatelessWidget {
|
||||
if (controller.registrationSupported ||
|
||||
controller.passwordLoginSupported)
|
||||
Row(children: [
|
||||
Expanded(child: Divider()),
|
||||
const Expanded(child: Divider()),
|
||||
Padding(
|
||||
padding: const EdgeInsets.all(12.0),
|
||||
child: Text(L10n.of(context).or),
|
||||
),
|
||||
Expanded(child: Divider()),
|
||||
const Expanded(child: Divider()),
|
||||
]),
|
||||
},
|
||||
Row(
|
||||
@ -133,13 +133,13 @@ class HomeserverPickerView extends StatelessWidget {
|
||||
child: _LoginButton(
|
||||
onPressed: () =>
|
||||
VRouter.of(context).to('login'),
|
||||
icon: Icon(Icons.login_outlined),
|
||||
icon: const Icon(Icons.login_outlined),
|
||||
labelText: L10n.of(context).login,
|
||||
),
|
||||
),
|
||||
if (controller.registrationSupported &&
|
||||
controller.passwordLoginSupported)
|
||||
SizedBox(width: 12),
|
||||
const SizedBox(width: 12),
|
||||
if (controller.registrationSupported &&
|
||||
// Registration is broken on matrix.org
|
||||
Matrix.of(context)
|
||||
@ -150,7 +150,8 @@ class HomeserverPickerView extends StatelessWidget {
|
||||
Expanded(
|
||||
child: _LoginButton(
|
||||
onPressed: controller.signUpAction,
|
||||
icon: Icon(Icons.add_box_outlined),
|
||||
icon:
|
||||
const Icon(Icons.add_box_outlined),
|
||||
labelText: L10n.of(context).register,
|
||||
),
|
||||
),
|
||||
@ -160,7 +161,8 @@ class HomeserverPickerView extends StatelessWidget {
|
||||
.map(
|
||||
(widget) => Container(
|
||||
height: 64,
|
||||
padding: EdgeInsets.only(bottom: 12),
|
||||
padding:
|
||||
const EdgeInsets.only(bottom: 12),
|
||||
child: widget),
|
||||
)
|
||||
.toList(),
|
||||
@ -174,7 +176,7 @@ class HomeserverPickerView extends StatelessWidget {
|
||||
onPressed: () => launch(AppConfig.privacyUrl),
|
||||
child: Text(
|
||||
L10n.of(context).privacy,
|
||||
style: TextStyle(
|
||||
style: const TextStyle(
|
||||
decoration: TextDecoration.underline,
|
||||
color: Colors.blueGrey,
|
||||
),
|
||||
@ -184,7 +186,7 @@ class HomeserverPickerView extends StatelessWidget {
|
||||
onPressed: () => PlatformInfos.showDialog(context),
|
||||
child: Text(
|
||||
L10n.of(context).about,
|
||||
style: TextStyle(
|
||||
style: const TextStyle(
|
||||
decoration: TextDecoration.underline,
|
||||
color: Colors.blueGrey,
|
||||
),
|
||||
@ -213,7 +215,7 @@ class _LoginButton extends StatelessWidget {
|
||||
Widget build(BuildContext context) {
|
||||
return OutlinedButton.icon(
|
||||
style: OutlinedButton.styleFrom(
|
||||
minimumSize: Size(256, 56),
|
||||
minimumSize: const Size(256, 56),
|
||||
side: BorderSide(
|
||||
color: Theme.of(context).textTheme.bodyText1.color,
|
||||
),
|
||||
|
@ -16,21 +16,21 @@ class ImageViewerView extends StatelessWidget {
|
||||
appBar: AppBar(
|
||||
elevation: 0,
|
||||
leading: IconButton(
|
||||
icon: Icon(Icons.close),
|
||||
icon: const Icon(Icons.close),
|
||||
onPressed: Navigator.of(context).pop,
|
||||
color: Colors.white,
|
||||
tooltip: L10n.of(context).close,
|
||||
),
|
||||
backgroundColor: Color(0x44000000),
|
||||
backgroundColor: const Color(0x44000000),
|
||||
actions: [
|
||||
IconButton(
|
||||
icon: Icon(Icons.reply_outlined),
|
||||
icon: const Icon(Icons.reply_outlined),
|
||||
onPressed: controller.forwardAction,
|
||||
color: Colors.white,
|
||||
tooltip: L10n.of(context).share,
|
||||
),
|
||||
IconButton(
|
||||
icon: Icon(Icons.download_outlined),
|
||||
icon: const Icon(Icons.download_outlined),
|
||||
onPressed: controller.saveFileAction,
|
||||
color: Colors.white,
|
||||
tooltip: L10n.of(context).downloadFile,
|
||||
|
@ -24,7 +24,7 @@ class InvitationSelectionView extends StatelessWidget {
|
||||
leading: VRouter.of(context).path.startsWith('/spaces/')
|
||||
? null
|
||||
: IconButton(
|
||||
icon: Icon(Icons.close_outlined),
|
||||
icon: const Icon(Icons.close_outlined),
|
||||
onPressed: () => VRouter.of(context)
|
||||
.toSegments(['rooms', controller.roomId]),
|
||||
),
|
||||
@ -39,7 +39,7 @@ class InvitationSelectionView extends StatelessWidget {
|
||||
withScrolling: true,
|
||||
child: controller.foundProfiles.isNotEmpty
|
||||
? ListView.builder(
|
||||
physics: NeverScrollableScrollPhysics(),
|
||||
physics: const NeverScrollableScrollPhysics(),
|
||||
shrinkWrap: true,
|
||||
itemCount: controller.foundProfiles.length,
|
||||
itemBuilder: (BuildContext context, int i) => ListTile(
|
||||
@ -61,13 +61,13 @@ class InvitationSelectionView extends StatelessWidget {
|
||||
future: controller.getContacts(context),
|
||||
builder: (BuildContext context, snapshot) {
|
||||
if (!snapshot.hasData) {
|
||||
return Center(
|
||||
return const Center(
|
||||
child: CircularProgressIndicator.adaptive(strokeWidth: 2),
|
||||
);
|
||||
}
|
||||
final contacts = snapshot.data;
|
||||
return ListView.builder(
|
||||
physics: NeverScrollableScrollPhysics(),
|
||||
physics: const NeverScrollableScrollPhysics(),
|
||||
shrinkWrap: true,
|
||||
itemCount: contacts.length,
|
||||
itemBuilder: (BuildContext context, int i) => ListTile(
|
||||
|
@ -15,7 +15,7 @@ class LoginView extends StatelessWidget {
|
||||
return OnePageCard(
|
||||
child: Scaffold(
|
||||
appBar: AppBar(
|
||||
leading: controller.loading ? Container() : BackButton(),
|
||||
leading: controller.loading ? Container() : const BackButton(),
|
||||
elevation: 0,
|
||||
title: Text(
|
||||
L10n.of(context).logInTo(Matrix.of(context)
|
||||
@ -40,7 +40,7 @@ class LoginView extends StatelessWidget {
|
||||
autofillHints:
|
||||
controller.loading ? null : [AutofillHints.username],
|
||||
decoration: InputDecoration(
|
||||
prefixIcon: Icon(Icons.account_box_outlined),
|
||||
prefixIcon: const Icon(Icons.account_box_outlined),
|
||||
hintText: L10n.of(context).username,
|
||||
errorText: controller.usernameError,
|
||||
labelText: L10n.of(context).username),
|
||||
@ -57,7 +57,7 @@ class LoginView extends StatelessWidget {
|
||||
obscureText: !controller.showPassword,
|
||||
onSubmitted: controller.login,
|
||||
decoration: InputDecoration(
|
||||
prefixIcon: Icon(Icons.lock_outlined),
|
||||
prefixIcon: const Icon(Icons.lock_outlined),
|
||||
hintText: '****',
|
||||
errorText: controller.passwordError,
|
||||
suffixIcon: IconButton(
|
||||
@ -71,17 +71,17 @@ class LoginView extends StatelessWidget {
|
||||
),
|
||||
),
|
||||
),
|
||||
SizedBox(height: 12),
|
||||
const SizedBox(height: 12),
|
||||
Hero(
|
||||
tag: 'loginButton',
|
||||
child: Padding(
|
||||
padding: EdgeInsets.symmetric(horizontal: 12),
|
||||
padding: const EdgeInsets.symmetric(horizontal: 12),
|
||||
child: ElevatedButton(
|
||||
onPressed: controller.loading
|
||||
? null
|
||||
: () => controller.login(context),
|
||||
child: controller.loading
|
||||
? LinearProgressIndicator()
|
||||
? const LinearProgressIndicator()
|
||||
: Text(L10n.of(context).login),
|
||||
),
|
||||
),
|
||||
@ -91,7 +91,7 @@ class LoginView extends StatelessWidget {
|
||||
onPressed: controller.passwordForgotten,
|
||||
child: Text(
|
||||
L10n.of(context).passwordForgotten,
|
||||
style: TextStyle(
|
||||
style: const TextStyle(
|
||||
color: Colors.blue,
|
||||
decoration: TextDecoration.underline,
|
||||
),
|
||||
|
@ -12,7 +12,7 @@ class NewGroupView extends StatelessWidget {
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
appBar: AppBar(
|
||||
leading: BackButton(),
|
||||
leading: const BackButton(),
|
||||
title: Text(L10n.of(context).createNewGroup),
|
||||
elevation: 0,
|
||||
),
|
||||
@ -30,7 +30,7 @@ class NewGroupView extends StatelessWidget {
|
||||
onSubmitted: controller.submitAction,
|
||||
decoration: InputDecoration(
|
||||
labelText: L10n.of(context).optionalGroupName,
|
||||
prefixIcon: Icon(Icons.people_outlined),
|
||||
prefixIcon: const Icon(Icons.people_outlined),
|
||||
hintText: L10n.of(context).enterAGroupName),
|
||||
),
|
||||
),
|
||||
@ -47,7 +47,7 @@ class NewGroupView extends StatelessWidget {
|
||||
),
|
||||
floatingActionButton: FloatingActionButton(
|
||||
onPressed: controller.submitAction,
|
||||
child: Icon(Icons.arrow_forward_outlined),
|
||||
child: const Icon(Icons.arrow_forward_outlined),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
@ -21,7 +21,7 @@ class NewPrivateChatView extends StatelessWidget {
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
appBar: AppBar(
|
||||
leading: BackButton(),
|
||||
leading: const BackButton(),
|
||||
title: Text(L10n.of(context).newChat),
|
||||
backgroundColor: Theme.of(context).scaffoldBackgroundColor,
|
||||
elevation: 0,
|
||||
@ -39,9 +39,9 @@ class NewPrivateChatView extends StatelessWidget {
|
||||
child: ListView(
|
||||
children: [
|
||||
Container(
|
||||
margin: EdgeInsets.all(_qrCodePadding),
|
||||
margin: const EdgeInsets.all(_qrCodePadding),
|
||||
alignment: Alignment.center,
|
||||
padding: EdgeInsets.all(_qrCodePadding * 2),
|
||||
padding: const EdgeInsets.all(_qrCodePadding * 2),
|
||||
child: InkWell(
|
||||
onTap: controller.inviteAction,
|
||||
borderRadius: BorderRadius.circular(12),
|
||||
@ -54,25 +54,25 @@ class NewPrivateChatView extends StatelessWidget {
|
||||
'https://matrix.to/#/${Matrix.of(context).client.userID}',
|
||||
version: QrVersions.auto,
|
||||
size: min(MediaQuery.of(context).size.width - 16, 200),
|
||||
embeddedImage: AssetImage('assets/share.png'),
|
||||
embeddedImage: const AssetImage('assets/share.png'),
|
||||
embeddedImageStyle: QrEmbeddedImageStyle(
|
||||
size: Size(48, 48),
|
||||
size: const Size(48, 48),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
Divider(),
|
||||
const Divider(),
|
||||
ListTile(
|
||||
subtitle: Text(L10n.of(context).createNewChatExplaination),
|
||||
trailing: Padding(
|
||||
padding: const EdgeInsets.all(8.0),
|
||||
trailing: const Padding(
|
||||
padding: EdgeInsets.all(8.0),
|
||||
child: Icon(Icons.info_outline_rounded),
|
||||
),
|
||||
),
|
||||
Divider(),
|
||||
const Divider(),
|
||||
Padding(
|
||||
padding: EdgeInsets.all(12),
|
||||
padding: const EdgeInsets.all(12),
|
||||
child: Form(
|
||||
key: controller.formKey,
|
||||
child: TextFormField(
|
||||
@ -86,7 +86,7 @@ class NewPrivateChatView extends StatelessWidget {
|
||||
hintText: '@username',
|
||||
prefixText: 'https://matrix.to/#/',
|
||||
suffixIcon: IconButton(
|
||||
icon: Icon(Icons.send_outlined),
|
||||
icon: const Icon(Icons.send_outlined),
|
||||
onPressed: controller.submitAction,
|
||||
),
|
||||
),
|
||||
@ -107,7 +107,7 @@ class NewPrivateChatView extends StatelessWidget {
|
||||
? FloatingActionButton.extended(
|
||||
onPressed: controller.openScannerAction,
|
||||
label: Text(L10n.of(context).scanQrCode),
|
||||
icon: Icon(Icons.camera_alt_outlined),
|
||||
icon: const Icon(Icons.camera_alt_outlined),
|
||||
)
|
||||
: null,
|
||||
);
|
||||
|
@ -13,7 +13,7 @@ class NewSpaceView extends StatelessWidget {
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
appBar: AppBar(
|
||||
leading: BackButton(),
|
||||
leading: const BackButton(),
|
||||
title: Text(L10n.of(context).createNewSpace),
|
||||
elevation: 0,
|
||||
),
|
||||
@ -31,7 +31,7 @@ class NewSpaceView extends StatelessWidget {
|
||||
onSubmitted: controller.submitAction,
|
||||
decoration: InputDecoration(
|
||||
labelText: L10n.of(context).spaceName,
|
||||
prefixIcon: Icon(Icons.people_outlined),
|
||||
prefixIcon: const Icon(Icons.people_outlined),
|
||||
hintText: L10n.of(context).enterASpacepName),
|
||||
),
|
||||
),
|
||||
@ -48,7 +48,7 @@ class NewSpaceView extends StatelessWidget {
|
||||
),
|
||||
floatingActionButton: FloatingActionButton(
|
||||
onPressed: controller.submitAction,
|
||||
child: Icon(Icons.arrow_forward_outlined),
|
||||
child: const Icon(Icons.arrow_forward_outlined),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
@ -69,21 +69,21 @@ class SearchView extends StatelessWidget {
|
||||
controller.controller.text?.startsWith('#') ?? false ? 0 : 1,
|
||||
child: Scaffold(
|
||||
appBar: AppBar(
|
||||
leading: BackButton(),
|
||||
leading: const BackButton(),
|
||||
titleSpacing: 0,
|
||||
title: DefaultAppBarSearchField(
|
||||
autofocus: true,
|
||||
hintText: L10n.of(context).search,
|
||||
searchController: controller.controller,
|
||||
suffix: Icon(Icons.search_outlined),
|
||||
suffix: const Icon(Icons.search_outlined),
|
||||
onChanged: controller.search,
|
||||
),
|
||||
bottom: TabBar(
|
||||
indicatorColor: Theme.of(context).colorScheme.secondary,
|
||||
labelColor: Theme.of(context).colorScheme.secondary,
|
||||
unselectedLabelColor: Theme.of(context).textTheme.bodyText1.color,
|
||||
labelStyle: TextStyle(fontSize: 16),
|
||||
labelPadding: EdgeInsets.symmetric(
|
||||
labelStyle: const TextStyle(fontSize: 16),
|
||||
labelPadding: const EdgeInsets.symmetric(
|
||||
horizontal: 8,
|
||||
vertical: 0,
|
||||
),
|
||||
@ -101,12 +101,12 @@ class SearchView extends StatelessWidget {
|
||||
? ScrollViewKeyboardDismissBehavior.onDrag
|
||||
: ScrollViewKeyboardDismissBehavior.manual,
|
||||
children: [
|
||||
SizedBox(height: 12),
|
||||
const SizedBox(height: 12),
|
||||
ListTile(
|
||||
leading: CircleAvatar(
|
||||
foregroundColor: Theme.of(context).colorScheme.secondary,
|
||||
backgroundColor: Theme.of(context).secondaryHeaderColor,
|
||||
child: Icon(Icons.edit_outlined),
|
||||
child: const Icon(Icons.edit_outlined),
|
||||
),
|
||||
title: Text(L10n.of(context).changeTheServer),
|
||||
onTap: controller.setServer,
|
||||
@ -119,8 +119,8 @@ class SearchView extends StatelessWidget {
|
||||
return Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
SizedBox(height: 32),
|
||||
Icon(
|
||||
const SizedBox(height: 32),
|
||||
const Icon(
|
||||
Icons.error_outlined,
|
||||
size: 80,
|
||||
color: Colors.grey,
|
||||
@ -129,7 +129,7 @@ class SearchView extends StatelessWidget {
|
||||
child: Text(
|
||||
snapshot.error.toLocalizedString(context),
|
||||
textAlign: TextAlign.center,
|
||||
style: TextStyle(
|
||||
style: const TextStyle(
|
||||
color: Colors.grey,
|
||||
fontSize: 16,
|
||||
),
|
||||
@ -139,7 +139,7 @@ class SearchView extends StatelessWidget {
|
||||
);
|
||||
}
|
||||
if (snapshot.connectionState != ConnectionState.done) {
|
||||
return Center(
|
||||
return const Center(
|
||||
child: CircularProgressIndicator.adaptive(
|
||||
strokeWidth: 2));
|
||||
}
|
||||
@ -148,8 +148,8 @@ class SearchView extends StatelessWidget {
|
||||
return Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
SizedBox(height: 32),
|
||||
Icon(
|
||||
const SizedBox(height: 32),
|
||||
const Icon(
|
||||
Icons.search_outlined,
|
||||
size: 80,
|
||||
color: Colors.grey,
|
||||
@ -158,7 +158,7 @@ class SearchView extends StatelessWidget {
|
||||
child: Text(
|
||||
L10n.of(context).noPublicRoomsFound,
|
||||
textAlign: TextAlign.center,
|
||||
style: TextStyle(
|
||||
style: const TextStyle(
|
||||
color: Colors.grey,
|
||||
fontSize: 16,
|
||||
),
|
||||
@ -169,9 +169,9 @@ class SearchView extends StatelessWidget {
|
||||
}
|
||||
return GridView.builder(
|
||||
shrinkWrap: true,
|
||||
padding: EdgeInsets.all(12),
|
||||
physics: NeverScrollableScrollPhysics(),
|
||||
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
|
||||
padding: const EdgeInsets.all(12),
|
||||
physics: const NeverScrollableScrollPhysics(),
|
||||
gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
|
||||
crossAxisCount: 2,
|
||||
childAspectRatio: 1,
|
||||
crossAxisSpacing: 16,
|
||||
@ -195,7 +195,7 @@ class SearchView extends StatelessWidget {
|
||||
publicRoomsResponse.chunk[i].name),
|
||||
Text(
|
||||
publicRoomsResponse.chunk[i].name,
|
||||
style: TextStyle(
|
||||
style: const TextStyle(
|
||||
fontSize: 16,
|
||||
fontWeight: FontWeight.bold,
|
||||
),
|
||||
@ -207,7 +207,7 @@ class SearchView extends StatelessWidget {
|
||||
publicRoomsResponse
|
||||
.chunk[i].numJoinedMembers ??
|
||||
0),
|
||||
style: TextStyle(fontSize: 10.5),
|
||||
style: const TextStyle(fontSize: 10.5),
|
||||
maxLines: 1,
|
||||
textAlign: TextAlign.center,
|
||||
),
|
||||
@ -262,13 +262,13 @@ class SearchView extends StatelessWidget {
|
||||
title: Text(
|
||||
foundProfile.displayName ??
|
||||
foundProfile.userId.localpart,
|
||||
style: TextStyle(),
|
||||
style: const TextStyle(),
|
||||
maxLines: 1,
|
||||
),
|
||||
subtitle: Text(
|
||||
foundProfile.userId,
|
||||
maxLines: 1,
|
||||
style: TextStyle(
|
||||
style: const TextStyle(
|
||||
fontSize: 12,
|
||||
),
|
||||
),
|
||||
|
@ -15,11 +15,11 @@ class Settings3PidView extends StatelessWidget {
|
||||
controller.request ??= Matrix.of(context).client.getAccount3PIDs();
|
||||
return Scaffold(
|
||||
appBar: AppBar(
|
||||
leading: BackButton(),
|
||||
leading: const BackButton(),
|
||||
title: Text(L10n.of(context).passwordRecovery),
|
||||
actions: [
|
||||
IconButton(
|
||||
icon: Icon(Icons.add_outlined),
|
||||
icon: const Icon(Icons.add_outlined),
|
||||
onPressed: controller.add3PidAction,
|
||||
tooltip: L10n.of(context).addEmail,
|
||||
)
|
||||
@ -39,7 +39,7 @@ class Settings3PidView extends StatelessWidget {
|
||||
);
|
||||
}
|
||||
if (!snapshot.hasData) {
|
||||
return Center(
|
||||
return const Center(
|
||||
child: CircularProgressIndicator.adaptive(strokeWidth: 2));
|
||||
}
|
||||
final identifier = snapshot.data;
|
||||
@ -63,7 +63,7 @@ class Settings3PidView extends StatelessWidget {
|
||||
.withTheseAddressesRecoveryDescription,
|
||||
),
|
||||
),
|
||||
Divider(height: 1),
|
||||
const Divider(height: 1),
|
||||
Expanded(
|
||||
child: ListView.builder(
|
||||
itemCount: identifier.length,
|
||||
@ -76,7 +76,7 @@ class Settings3PidView extends StatelessWidget {
|
||||
title: Text(identifier[i].address),
|
||||
trailing: IconButton(
|
||||
tooltip: L10n.of(context).delete,
|
||||
icon: Icon(Icons.delete_forever_outlined),
|
||||
icon: const Icon(Icons.delete_forever_outlined),
|
||||
color: Colors.red,
|
||||
onPressed: () => controller.delete3Pid(identifier[i]),
|
||||
),
|
||||
|
@ -22,51 +22,51 @@ class SettingsAccountView extends StatelessWidget {
|
||||
child: Column(
|
||||
children: [
|
||||
ListTile(
|
||||
trailing: Icon(Icons.add_box_outlined),
|
||||
trailing: const Icon(Icons.add_box_outlined),
|
||||
title: Text(L10n.of(context).addAccount),
|
||||
subtitle: Text(L10n.of(context).enableMultiAccounts),
|
||||
onTap: controller.addAccountAction,
|
||||
),
|
||||
Divider(height: 1),
|
||||
const Divider(height: 1),
|
||||
ListTile(
|
||||
title: Text(L10n.of(context).yourUserId),
|
||||
subtitle: Text(Matrix.of(context).client.userID),
|
||||
trailing: Icon(Icons.copy_outlined),
|
||||
trailing: const Icon(Icons.copy_outlined),
|
||||
onTap: () => FluffyShare.share(
|
||||
Matrix.of(context).client.userID,
|
||||
context,
|
||||
),
|
||||
),
|
||||
ListTile(
|
||||
trailing: Icon(Icons.edit_outlined),
|
||||
trailing: const Icon(Icons.edit_outlined),
|
||||
title: Text(L10n.of(context).editDisplayname),
|
||||
subtitle: Text(controller.profile?.displayName ??
|
||||
Matrix.of(context).client.userID.localpart),
|
||||
onTap: controller.setDisplaynameAction,
|
||||
),
|
||||
ListTile(
|
||||
trailing: Icon(Icons.phone_outlined),
|
||||
trailing: const Icon(Icons.phone_outlined),
|
||||
title: Text(L10n.of(context).editJitsiInstance),
|
||||
subtitle: Text(AppConfig.jitsiInstance),
|
||||
onTap: controller.setJitsiInstanceAction,
|
||||
),
|
||||
ListTile(
|
||||
trailing: Icon(Icons.devices_other_outlined),
|
||||
trailing: const Icon(Icons.devices_other_outlined),
|
||||
title: Text(L10n.of(context).devices),
|
||||
onTap: () => VRouter.of(context).to('devices'),
|
||||
),
|
||||
Divider(height: 1),
|
||||
const Divider(height: 1),
|
||||
ListTile(
|
||||
trailing: Icon(Icons.exit_to_app_outlined),
|
||||
trailing: const Icon(Icons.exit_to_app_outlined),
|
||||
title: Text(L10n.of(context).logout),
|
||||
onTap: controller.logoutAction,
|
||||
),
|
||||
Divider(height: 1),
|
||||
const Divider(height: 1),
|
||||
ListTile(
|
||||
trailing: Icon(Icons.delete_forever_outlined),
|
||||
trailing: const Icon(Icons.delete_forever_outlined),
|
||||
title: Text(
|
||||
L10n.of(context).deleteAccount,
|
||||
style: TextStyle(color: Colors.red),
|
||||
style: const TextStyle(color: Colors.red),
|
||||
),
|
||||
onTap: controller.deleteAccountAction,
|
||||
),
|
||||
|
@ -24,14 +24,14 @@ class SettingsChatView extends StatelessWidget {
|
||||
ListTile(
|
||||
title: Text(L10n.of(context).changeTheme),
|
||||
onTap: () => VRouter.of(context).to('style'),
|
||||
trailing: Icon(Icons.style_outlined),
|
||||
trailing: const Icon(Icons.style_outlined),
|
||||
),
|
||||
ListTile(
|
||||
title: Text(L10n.of(context).emoteSettings),
|
||||
onTap: () => VRouter.of(context).to('emotes'),
|
||||
trailing: Icon(Icons.insert_emoticon_outlined),
|
||||
trailing: const Icon(Icons.insert_emoticon_outlined),
|
||||
),
|
||||
Divider(height: 1),
|
||||
const Divider(height: 1),
|
||||
SettingsSwitchListTile(
|
||||
title: L10n.of(context).renderRichContent,
|
||||
onChanged: (b) => AppConfig.renderHtml = b,
|
||||
|
@ -20,13 +20,13 @@ class EmotesSettingsView extends StatelessWidget {
|
||||
final imageKeys = controller.pack.images.keys.toList();
|
||||
return Scaffold(
|
||||
appBar: AppBar(
|
||||
leading: BackButton(),
|
||||
leading: const BackButton(),
|
||||
title: Text(L10n.of(context).emoteSettings),
|
||||
),
|
||||
floatingActionButton: controller.showSave
|
||||
? FloatingActionButton(
|
||||
onPressed: controller.saveAction,
|
||||
child: Icon(Icons.save_outlined, color: Colors.white),
|
||||
child: const Icon(Icons.save_outlined, color: Colors.white),
|
||||
)
|
||||
: null,
|
||||
body: MaxWidthBody(
|
||||
@ -34,16 +34,16 @@ class EmotesSettingsView extends StatelessWidget {
|
||||
children: <Widget>[
|
||||
if (!controller.readonly)
|
||||
Container(
|
||||
padding: EdgeInsets.symmetric(
|
||||
padding: const EdgeInsets.symmetric(
|
||||
vertical: 8.0,
|
||||
),
|
||||
child: ListTile(
|
||||
leading: Container(
|
||||
width: 180.0,
|
||||
height: 38,
|
||||
padding: EdgeInsets.symmetric(horizontal: 8),
|
||||
padding: const EdgeInsets.symmetric(horizontal: 8),
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: BorderRadius.all(Radius.circular(10)),
|
||||
borderRadius: const BorderRadius.all(Radius.circular(10)),
|
||||
color: Theme.of(context).secondaryHeaderColor,
|
||||
),
|
||||
child: TextField(
|
||||
@ -73,7 +73,7 @@ class EmotesSettingsView extends StatelessWidget {
|
||||
),
|
||||
trailing: InkWell(
|
||||
onTap: controller.addImageAction,
|
||||
child: Icon(
|
||||
child: const Icon(
|
||||
Icons.add_outlined,
|
||||
color: Colors.green,
|
||||
size: 32.0,
|
||||
@ -99,10 +99,10 @@ class EmotesSettingsView extends StatelessWidget {
|
||||
child: imageKeys.isEmpty
|
||||
? Center(
|
||||
child: Padding(
|
||||
padding: EdgeInsets.all(16),
|
||||
padding: const EdgeInsets.all(16),
|
||||
child: Text(
|
||||
L10n.of(context).noEmotesFound,
|
||||
style: TextStyle(fontSize: 20),
|
||||
style: const TextStyle(fontSize: 20),
|
||||
),
|
||||
),
|
||||
)
|
||||
@ -124,10 +124,10 @@ class EmotesSettingsView extends StatelessWidget {
|
||||
leading: Container(
|
||||
width: 180.0,
|
||||
height: 38,
|
||||
padding: EdgeInsets.symmetric(horizontal: 8),
|
||||
padding: const EdgeInsets.symmetric(horizontal: 8),
|
||||
decoration: BoxDecoration(
|
||||
borderRadius:
|
||||
BorderRadius.all(Radius.circular(10)),
|
||||
const BorderRadius.all(Radius.circular(10)),
|
||||
color: Theme.of(context).secondaryHeaderColor,
|
||||
),
|
||||
child: Shortcuts(
|
||||
@ -193,7 +193,7 @@ class EmotesSettingsView extends StatelessWidget {
|
||||
: InkWell(
|
||||
onTap: () =>
|
||||
controller.removeImageAction(imageCode),
|
||||
child: Icon(
|
||||
child: const Icon(
|
||||
Icons.delete_forever_outlined,
|
||||
color: Colors.red,
|
||||
size: 32.0,
|
||||
@ -212,11 +212,11 @@ class EmotesSettingsView extends StatelessWidget {
|
||||
|
||||
class _EmoteImage extends StatelessWidget {
|
||||
final Uri mxc;
|
||||
_EmoteImage(this.mxc);
|
||||
const _EmoteImage(this.mxc);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final size = 38.0;
|
||||
const size = 38.0;
|
||||
final devicePixelRatio = MediaQuery.of(context).devicePixelRatio;
|
||||
final url = mxc?.getThumbnail(
|
||||
Matrix.of(context).client,
|
||||
@ -238,7 +238,7 @@ class _ImagePicker extends StatefulWidget {
|
||||
|
||||
final void Function(ValueNotifier<ImagePackImageContent>) onPressed;
|
||||
|
||||
_ImagePicker({@required this.controller, @required this.onPressed});
|
||||
const _ImagePicker({@required this.controller, @required this.onPressed});
|
||||
|
||||
@override
|
||||
_ImagePickerState createState() => _ImagePickerState();
|
||||
|
@ -18,7 +18,7 @@ class SettingsIgnoreListView extends StatelessWidget {
|
||||
final client = Matrix.of(context).client;
|
||||
return Scaffold(
|
||||
appBar: AppBar(
|
||||
leading: BackButton(),
|
||||
leading: const BackButton(),
|
||||
title: Text(L10n.of(context).ignoredUsers),
|
||||
),
|
||||
body: MaxWidthBody(
|
||||
@ -35,26 +35,26 @@ class SettingsIgnoreListView extends StatelessWidget {
|
||||
textInputAction: TextInputAction.done,
|
||||
onSubmitted: (_) => controller.ignoreUser(context),
|
||||
decoration: InputDecoration(
|
||||
border: OutlineInputBorder(),
|
||||
border: const OutlineInputBorder(),
|
||||
hintText: 'bad_guy:domain.abc',
|
||||
prefixText: '@',
|
||||
labelText: L10n.of(context).ignoreUsername,
|
||||
suffixIcon: IconButton(
|
||||
tooltip: L10n.of(context).ignore,
|
||||
icon: Icon(Icons.done_outlined),
|
||||
icon: const Icon(Icons.done_outlined),
|
||||
onPressed: () => controller.ignoreUser(context),
|
||||
),
|
||||
),
|
||||
),
|
||||
SizedBox(height: 16),
|
||||
const SizedBox(height: 16),
|
||||
Text(
|
||||
L10n.of(context).ignoreListDescription,
|
||||
style: TextStyle(color: Colors.orange),
|
||||
style: const TextStyle(color: Colors.orange),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
Divider(height: 1),
|
||||
const Divider(height: 1),
|
||||
Expanded(
|
||||
child: StreamBuilder<Object>(
|
||||
stream: client.onAccountData.stream
|
||||
@ -74,7 +74,7 @@ class SettingsIgnoreListView extends StatelessWidget {
|
||||
s.data?.displayName ?? client.ignoredUsers[i]),
|
||||
trailing: IconButton(
|
||||
tooltip: L10n.of(context).delete,
|
||||
icon: Icon(Icons.delete_forever_outlined),
|
||||
icon: const Icon(Icons.delete_forever_outlined),
|
||||
onPressed: () => showFutureLoadingDialog(
|
||||
context: context,
|
||||
future: () =>
|
||||
|
@ -8,14 +8,14 @@ import 'package:vrouter/vrouter.dart';
|
||||
class MultipleEmotesSettingsView extends StatelessWidget {
|
||||
final MultipleEmotesSettingsController controller;
|
||||
|
||||
MultipleEmotesSettingsView(this.controller, {Key key}) : super(key: key);
|
||||
const MultipleEmotesSettingsView(this.controller, {Key key}) : super(key: key);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final room = Matrix.of(context).client.getRoomById(controller.roomId);
|
||||
return Scaffold(
|
||||
appBar: AppBar(
|
||||
leading: BackButton(),
|
||||
leading: const BackButton(),
|
||||
title: Text(L10n.of(context).emotePacks),
|
||||
),
|
||||
body: StreamBuilder(
|
||||
|
@ -20,7 +20,7 @@ class SettingsNotificationsView extends StatelessWidget {
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
appBar: AppBar(
|
||||
leading: BackButton(),
|
||||
leading: const BackButton(),
|
||||
title: Text(L10n.of(context).notifications),
|
||||
),
|
||||
body: MaxWidthBody(
|
||||
@ -56,11 +56,11 @@ class SettingsNotificationsView extends StatelessWidget {
|
||||
backgroundColor:
|
||||
Theme.of(context).scaffoldBackgroundColor,
|
||||
foregroundColor: Colors.grey,
|
||||
child: Icon(Icons.edit_outlined),
|
||||
child: const Icon(Icons.edit_outlined),
|
||||
),
|
||||
onTap: controller.openAndroidNotificationSettingsAction,
|
||||
),
|
||||
Divider(thickness: 1),
|
||||
const Divider(thickness: 1),
|
||||
ListTile(
|
||||
title: Text(
|
||||
L10n.of(context).pushRules,
|
||||
@ -78,7 +78,7 @@ class SettingsNotificationsView extends StatelessWidget {
|
||||
controller.setNotificationSetting(item, enabled),
|
||||
),
|
||||
},
|
||||
Divider(thickness: 1),
|
||||
const Divider(thickness: 1),
|
||||
ListTile(
|
||||
title: Text(
|
||||
L10n.of(context).devices,
|
||||
@ -99,13 +99,13 @@ class SettingsNotificationsView extends StatelessWidget {
|
||||
);
|
||||
}
|
||||
if (snapshot.connectionState != ConnectionState.done) {
|
||||
Center(
|
||||
const Center(
|
||||
child: CircularProgressIndicator.adaptive(
|
||||
strokeWidth: 2));
|
||||
}
|
||||
final pushers = snapshot.data ?? [];
|
||||
return ListView.builder(
|
||||
physics: NeverScrollableScrollPhysics(),
|
||||
physics: const NeverScrollableScrollPhysics(),
|
||||
shrinkWrap: true,
|
||||
itemCount: pushers.length,
|
||||
itemBuilder: (_, i) => ListTile(
|
||||
|
@ -22,27 +22,27 @@ class SettingsSecurityView extends StatelessWidget {
|
||||
child: Column(
|
||||
children: [
|
||||
ListTile(
|
||||
trailing: Icon(Icons.block_outlined),
|
||||
trailing: const Icon(Icons.block_outlined),
|
||||
title: Text(L10n.of(context).ignoredUsers),
|
||||
onTap: () => VRouter.of(context).to('ignorelist'),
|
||||
),
|
||||
ListTile(
|
||||
trailing: Icon(Icons.security_outlined),
|
||||
trailing: const Icon(Icons.security_outlined),
|
||||
title: Text(
|
||||
L10n.of(context).changePassword,
|
||||
),
|
||||
onTap: controller.changePasswordAccountAction,
|
||||
),
|
||||
ListTile(
|
||||
trailing: Icon(Icons.email_outlined),
|
||||
trailing: const Icon(Icons.email_outlined),
|
||||
title: Text(L10n.of(context).passwordRecovery),
|
||||
onTap: () => VRouter.of(context).to('3pid'),
|
||||
),
|
||||
if (Matrix.of(context).client.encryption != null) ...{
|
||||
Divider(thickness: 1),
|
||||
const Divider(thickness: 1),
|
||||
if (PlatformInfos.isMobile)
|
||||
ListTile(
|
||||
trailing: Icon(Icons.lock_outlined),
|
||||
trailing: const Icon(Icons.lock_outlined),
|
||||
title: Text(L10n.of(context).appLock),
|
||||
onTap: controller.setAppLockAction,
|
||||
),
|
||||
@ -55,11 +55,11 @@ class SettingsSecurityView extends StatelessWidget {
|
||||
message: Matrix.of(context).client.fingerprintKey.beautified,
|
||||
okLabel: L10n.of(context).ok,
|
||||
),
|
||||
trailing: Icon(Icons.vpn_key_outlined),
|
||||
trailing: const Icon(Icons.vpn_key_outlined),
|
||||
),
|
||||
ListTile(
|
||||
title: Text(L10n.of(context).cachedKeys),
|
||||
trailing: Icon(Icons.wb_cloudy_outlined),
|
||||
trailing: const Icon(Icons.wb_cloudy_outlined),
|
||||
subtitle: Text(
|
||||
'${Matrix.of(context).client.encryption.keyManager.enabled ? L10n.of(context).onlineKeyBackupEnabled : L10n.of(context).onlineKeyBackupDisabled}\n${Matrix.of(context).client.encryption.crossSigning.enabled ? L10n.of(context).crossSigningEnabled : L10n.of(context).crossSigningDisabled}'),
|
||||
onTap: controller.bootstrapSettingsAction,
|
||||
|
@ -17,7 +17,7 @@ class SettingsStyleView extends StatelessWidget {
|
||||
controller.currentTheme ??= AdaptiveTheme.of(context).mode;
|
||||
return Scaffold(
|
||||
appBar: AppBar(
|
||||
leading: BackButton(),
|
||||
leading: const BackButton(),
|
||||
title: Text(L10n.of(context).changeTheme),
|
||||
),
|
||||
body: MaxWidthBody(
|
||||
@ -42,7 +42,7 @@ class SettingsStyleView extends StatelessWidget {
|
||||
title: Text(L10n.of(context).darkTheme),
|
||||
onChanged: controller.switchTheme,
|
||||
),
|
||||
Divider(height: 1),
|
||||
const Divider(height: 1),
|
||||
ListTile(
|
||||
title: Text(
|
||||
L10n.of(context).wallpaper,
|
||||
@ -59,7 +59,7 @@ class SettingsStyleView extends StatelessWidget {
|
||||
height: 38,
|
||||
fit: BoxFit.cover,
|
||||
),
|
||||
trailing: Icon(
|
||||
trailing: const Icon(
|
||||
Icons.delete_forever_outlined,
|
||||
color: Colors.red,
|
||||
),
|
||||
@ -68,11 +68,11 @@ class SettingsStyleView extends StatelessWidget {
|
||||
Builder(builder: (context) {
|
||||
return ListTile(
|
||||
title: Text(L10n.of(context).changeWallpaper),
|
||||
trailing: Icon(Icons.wallpaper_outlined),
|
||||
trailing: const Icon(Icons.wallpaper_outlined),
|
||||
onTap: controller.setWallpaperAction,
|
||||
);
|
||||
}),
|
||||
Divider(height: 1),
|
||||
const Divider(height: 1),
|
||||
ListTile(
|
||||
title: Text(
|
||||
L10n.of(context).fontSize,
|
||||
|
@ -38,38 +38,38 @@ class SettingsView extends StatelessWidget {
|
||||
body: ListView(
|
||||
children: <Widget>[
|
||||
ListTile(
|
||||
leading: Icon(Icons.notifications_outlined),
|
||||
leading: const Icon(Icons.notifications_outlined),
|
||||
title: Text(L10n.of(context).notifications),
|
||||
onTap: () => VRouter.of(context).to('/settings/notifications'),
|
||||
),
|
||||
ListTile(
|
||||
leading: Icon(Icons.chat_bubble_outline),
|
||||
leading: const Icon(Icons.chat_bubble_outline),
|
||||
title: Text(L10n.of(context).chat),
|
||||
onTap: () => VRouter.of(context).to('/settings/chat'),
|
||||
),
|
||||
ListTile(
|
||||
leading: Icon(Icons.account_box_outlined),
|
||||
leading: const Icon(Icons.account_box_outlined),
|
||||
title: Text(L10n.of(context).account),
|
||||
onTap: () => VRouter.of(context).to('/settings/account'),
|
||||
),
|
||||
ListTile(
|
||||
leading: Icon(Icons.security_outlined),
|
||||
leading: const Icon(Icons.security_outlined),
|
||||
title: Text(L10n.of(context).security),
|
||||
onTap: () => VRouter.of(context).to('/settings/security'),
|
||||
),
|
||||
Divider(thickness: 1),
|
||||
const Divider(thickness: 1),
|
||||
ListTile(
|
||||
leading: Icon(Icons.help_outlined),
|
||||
leading: const Icon(Icons.help_outlined),
|
||||
title: Text(L10n.of(context).help),
|
||||
onTap: () => launch(AppConfig.supportUrl),
|
||||
),
|
||||
ListTile(
|
||||
leading: Icon(Icons.privacy_tip_outlined),
|
||||
leading: const Icon(Icons.privacy_tip_outlined),
|
||||
title: Text(L10n.of(context).privacy),
|
||||
onTap: () => launch(AppConfig.privacyUrl),
|
||||
),
|
||||
ListTile(
|
||||
leading: Icon(Icons.link_outlined),
|
||||
leading: const Icon(Icons.link_outlined),
|
||||
title: Text(L10n.of(context).about),
|
||||
onTap: () => PlatformInfos.showDialog(context),
|
||||
),
|
||||
|
@ -32,7 +32,7 @@ class SignupPageView extends StatelessWidget {
|
||||
autofillHints:
|
||||
controller.loading ? null : [AutofillHints.username],
|
||||
decoration: InputDecoration(
|
||||
prefixIcon: Icon(Icons.account_box_outlined),
|
||||
prefixIcon: const Icon(Icons.account_box_outlined),
|
||||
hintText: L10n.of(context).username,
|
||||
errorText: controller.usernameError,
|
||||
labelText: L10n.of(context).username,
|
||||
@ -41,7 +41,7 @@ class SignupPageView extends StatelessWidget {
|
||||
':${Matrix.of(context).getLoginClient().homeserver.host}'),
|
||||
),
|
||||
),
|
||||
Divider(),
|
||||
const Divider(),
|
||||
ListTile(
|
||||
title: Text(L10n.of(context).chooseAStrongPassword),
|
||||
subtitle: Text(L10n.of(context).newPasswordDescription),
|
||||
@ -57,7 +57,7 @@ class SignupPageView extends StatelessWidget {
|
||||
obscureText: !controller.showPassword,
|
||||
onSubmitted: controller.signup,
|
||||
decoration: InputDecoration(
|
||||
prefixIcon: Icon(Icons.lock_outlined),
|
||||
prefixIcon: const Icon(Icons.lock_outlined),
|
||||
hintText: '****',
|
||||
errorText: controller.passwordError,
|
||||
suffixIcon: IconButton(
|
||||
@ -71,16 +71,16 @@ class SignupPageView extends StatelessWidget {
|
||||
),
|
||||
),
|
||||
),
|
||||
Divider(),
|
||||
SizedBox(height: 12),
|
||||
const Divider(),
|
||||
const SizedBox(height: 12),
|
||||
Hero(
|
||||
tag: 'loginButton',
|
||||
child: Padding(
|
||||
padding: EdgeInsets.symmetric(horizontal: 12),
|
||||
padding: const EdgeInsets.symmetric(horizontal: 12),
|
||||
child: ElevatedButton(
|
||||
onPressed: controller.loading ? null : controller.signup,
|
||||
child: controller.loading
|
||||
? LinearProgressIndicator()
|
||||
? const LinearProgressIndicator()
|
||||
: Text(L10n.of(context).signUp),
|
||||
),
|
||||
),
|
||||
|
@ -21,7 +21,7 @@ class UserBottomSheetView extends StatelessWidget {
|
||||
final client = Matrix.of(context).client;
|
||||
final presence = client.presences[user.id];
|
||||
return Center(
|
||||
child: Container(
|
||||
child: SizedBox(
|
||||
width: min(
|
||||
MediaQuery.of(context).size.width, FluffyThemes.columnWidth * 1.5),
|
||||
child: Material(
|
||||
@ -34,7 +34,7 @@ class UserBottomSheetView extends StatelessWidget {
|
||||
backgroundColor:
|
||||
Theme.of(context).scaffoldBackgroundColor.withOpacity(0.5),
|
||||
leading: IconButton(
|
||||
icon: Icon(Icons.arrow_downward_outlined),
|
||||
icon: const Icon(Icons.arrow_downward_outlined),
|
||||
onPressed: Navigator.of(context, rootNavigator: false).pop,
|
||||
tooltip: L10n.of(context).close,
|
||||
),
|
||||
@ -109,7 +109,7 @@ class UserBottomSheetView extends StatelessWidget {
|
||||
ListTile(
|
||||
title: Text(L10n.of(context).username),
|
||||
subtitle: Text(user.id),
|
||||
trailing: Icon(Icons.share_outlined),
|
||||
trailing: const Icon(Icons.share_outlined),
|
||||
onTap: () => FluffyShare.share(
|
||||
user.id, controller.widget.outerContext),
|
||||
),
|
||||
@ -149,7 +149,7 @@ class _TextWithIcon extends StatelessWidget {
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
Icon(iconData),
|
||||
SizedBox(width: 16),
|
||||
const SizedBox(width: 16),
|
||||
Text(text),
|
||||
],
|
||||
);
|
||||
|
@ -16,21 +16,21 @@ class VideoViewerView extends StatelessWidget {
|
||||
appBar: AppBar(
|
||||
elevation: 0,
|
||||
leading: IconButton(
|
||||
icon: Icon(Icons.close),
|
||||
icon: const Icon(Icons.close),
|
||||
onPressed: Navigator.of(context).pop,
|
||||
color: Colors.white,
|
||||
tooltip: L10n.of(context).close,
|
||||
),
|
||||
backgroundColor: Color(0x44000000),
|
||||
backgroundColor: const Color(0x44000000),
|
||||
actions: [
|
||||
IconButton(
|
||||
icon: Icon(Icons.reply_outlined),
|
||||
icon: const Icon(Icons.reply_outlined),
|
||||
onPressed: controller.forwardAction,
|
||||
color: Colors.white,
|
||||
tooltip: L10n.of(context).share,
|
||||
),
|
||||
IconButton(
|
||||
icon: Icon(Icons.download_outlined),
|
||||
icon: const Icon(Icons.download_outlined),
|
||||
onPressed: controller.saveFileAction,
|
||||
color: Colors.white,
|
||||
tooltip: L10n.of(context).downloadFile,
|
||||
@ -41,7 +41,7 @@ class VideoViewerView extends StatelessWidget {
|
||||
child: controller.error != null
|
||||
? Text(controller.error.toString())
|
||||
: (controller.chewieController == null
|
||||
? CircularProgressIndicator.adaptive(strokeWidth: 2)
|
||||
? const CircularProgressIndicator.adaptive(strokeWidth: 2)
|
||||
: Chewie(
|
||||
controller: controller.chewieController,
|
||||
)),
|
||||
|
@ -97,7 +97,9 @@ class BackgroundPush {
|
||||
{final void Function(String errorMsg, {Uri link}) onFcmError}) {
|
||||
final instance = BackgroundPush.clientOnly(_client);
|
||||
instance.context = _context;
|
||||
// ignore: prefer_initializing_formals
|
||||
instance.router = router;
|
||||
// ignore: prefer_initializing_formals
|
||||
instance.onFcmError = onFcmError;
|
||||
instance.fullInit();
|
||||
return instance;
|
||||
@ -301,7 +303,7 @@ class BackgroundPush {
|
||||
}
|
||||
|
||||
// initialise the plugin. app_icon needs to be a added as a drawable resource to the Android head project
|
||||
final initializationSettingsAndroid =
|
||||
const initializationSettingsAndroid =
|
||||
AndroidInitializationSettings('notifications_icon');
|
||||
final initializationSettingsIOS =
|
||||
IOSInitializationSettings(onDidReceiveLocalNotification: (i, a, b, c) {
|
||||
@ -596,11 +598,6 @@ class BackgroundPush {
|
||||
// load the locale
|
||||
await loadLocale();
|
||||
|
||||
// Count all unread events
|
||||
var unreadEvents = 0;
|
||||
client.rooms
|
||||
.forEach((Room room) => unreadEvents += room.notificationCount ?? 0);
|
||||
|
||||
// Calculate title
|
||||
final title = l10n.unreadMessages(room.notificationCount ?? 0);
|
||||
|
||||
@ -645,7 +642,7 @@ class BackgroundPush {
|
||||
),
|
||||
ticker: l10n.newMessageInFluffyChat,
|
||||
);
|
||||
final iOSPlatformChannelSpecifics = IOSNotificationDetails();
|
||||
const iOSPlatformChannelSpecifics = IOSNotificationDetails();
|
||||
final platformChannelSpecifics = NotificationDetails(
|
||||
android: androidPlatformChannelSpecifics,
|
||||
iOS: iOSPlatformChannelSpecifics,
|
||||
@ -681,7 +678,7 @@ class BackgroundPush {
|
||||
|
||||
// Display notification
|
||||
final androidPlatformChannelSpecifics = _getAndroidNotificationDetails();
|
||||
final iOSPlatformChannelSpecifics = IOSNotificationDetails();
|
||||
const iOSPlatformChannelSpecifics = IOSNotificationDetails();
|
||||
final platformChannelSpecifics = NotificationDetails(
|
||||
android: androidPlatformChannelSpecifics,
|
||||
iOS: iOSPlatformChannelSpecifics,
|
||||
@ -702,7 +699,7 @@ class BackgroundPush {
|
||||
AndroidNotificationDetails _getAndroidNotificationDetails(
|
||||
{MessagingStyleInformation styleInformation, String ticker}) {
|
||||
final color = (context != null ? Theme.of(context).primaryColor : null) ??
|
||||
Color(0xFF5625BA);
|
||||
const Color(0xFF5625BA);
|
||||
|
||||
return AndroidNotificationDetails(
|
||||
AppConfig.pushNotificationsChannelId,
|
||||
|
@ -22,7 +22,7 @@ extension DateTimeExtension on DateTime {
|
||||
/// Two message events can belong to the same environment. That means that they
|
||||
/// don't need to display the time they were sent because they are close
|
||||
/// enaugh.
|
||||
static final minutesBetweenEnvironments = 5;
|
||||
static const minutesBetweenEnvironments = 5;
|
||||
|
||||
/// Checks if two DateTimes are close enough to belong to the same
|
||||
/// environment.
|
||||
|
@ -31,7 +31,7 @@ class Store {
|
||||
static final _mutex = AsyncMutex();
|
||||
|
||||
Store()
|
||||
: secureStorage = PlatformInfos.isMobile ? FlutterSecureStorage() : null;
|
||||
: secureStorage = PlatformInfos.isMobile ? const FlutterSecureStorage() : null;
|
||||
|
||||
Future<void> _setupLocalStorage() async {
|
||||
if (storage == null) {
|
||||
|
@ -55,7 +55,7 @@ class FlutterMatrixHiveStore extends FamedlySdkHiveDatabase {
|
||||
// Workaround for secure storage is calling Platform.operatingSystem on web
|
||||
if (kIsWeb) throw MissingPluginException();
|
||||
|
||||
final secureStorage = const FlutterSecureStorage();
|
||||
const secureStorage = FlutterSecureStorage();
|
||||
final containsEncryptionKey =
|
||||
await secureStorage.containsKey(key: _hiveCipherStorageKey);
|
||||
if (!containsEncryptionKey) {
|
||||
|
@ -53,11 +53,11 @@ abstract class PlatformInfos {
|
||||
),
|
||||
OutlinedButton(
|
||||
onPressed: () => launch(AppConfig.emojiFontUrl),
|
||||
child: Text(AppConfig.emojiFontName),
|
||||
child: const Text(AppConfig.emojiFontName),
|
||||
),
|
||||
OutlinedButton(
|
||||
onPressed: () => VRouter.of(context).to('logs'),
|
||||
child: Text('Logs'),
|
||||
child: const Text('Logs'),
|
||||
),
|
||||
SentrySwitchListTile(label: L10n.of(context).sendBugReports),
|
||||
],
|
||||
|
@ -45,8 +45,8 @@ class _ChatSettingsPopupMenuState extends State<ChatSettingsPopupMenu> {
|
||||
value: 'mute',
|
||||
child: Row(
|
||||
children: [
|
||||
Icon(Icons.notifications_off_outlined),
|
||||
SizedBox(width: 12),
|
||||
const Icon(Icons.notifications_off_outlined),
|
||||
const SizedBox(width: 12),
|
||||
Text(L10n.of(context).muteChat),
|
||||
],
|
||||
),
|
||||
@ -55,8 +55,8 @@ class _ChatSettingsPopupMenuState extends State<ChatSettingsPopupMenu> {
|
||||
value: 'unmute',
|
||||
child: Row(
|
||||
children: [
|
||||
Icon(Icons.notifications_on_outlined),
|
||||
SizedBox(width: 12),
|
||||
const Icon(Icons.notifications_on_outlined),
|
||||
const SizedBox(width: 12),
|
||||
Text(L10n.of(context).unmuteChat),
|
||||
],
|
||||
),
|
||||
@ -65,8 +65,8 @@ class _ChatSettingsPopupMenuState extends State<ChatSettingsPopupMenu> {
|
||||
value: 'leave',
|
||||
child: Row(
|
||||
children: [
|
||||
Icon(Icons.delete_outlined),
|
||||
SizedBox(width: 12),
|
||||
const Icon(Icons.delete_outlined),
|
||||
const SizedBox(width: 12),
|
||||
Text(L10n.of(context).leave),
|
||||
],
|
||||
),
|
||||
@ -79,8 +79,8 @@ class _ChatSettingsPopupMenuState extends State<ChatSettingsPopupMenu> {
|
||||
value: 'details',
|
||||
child: Row(
|
||||
children: [
|
||||
Icon(Icons.info_outline_rounded),
|
||||
SizedBox(width: 12),
|
||||
const Icon(Icons.info_outline_rounded),
|
||||
const SizedBox(width: 12),
|
||||
Text(L10n.of(context).chatDetails),
|
||||
],
|
||||
),
|
||||
|
@ -7,6 +7,8 @@ import 'package:flutter_gen/gen_l10n/l10n.dart';
|
||||
import 'matrix.dart';
|
||||
|
||||
class ConnectionStatusHeader extends StatefulWidget {
|
||||
const ConnectionStatusHeader({Key key}) : super(key: key);
|
||||
|
||||
@override
|
||||
_ConnectionStatusHeaderState createState() => _ConnectionStatusHeaderState();
|
||||
}
|
||||
@ -19,7 +21,8 @@ class _ConnectionStatusHeaderState extends State<ConnectionStatusHeader> {
|
||||
_lastSyncReceived.millisecondsSinceEpoch <
|
||||
(Matrix.of(context).client.sendMessageTimeoutSeconds + 2) * 1000;
|
||||
static DateTime _lastSyncReceived = DateTime(0);
|
||||
SyncStatusUpdate _status = SyncStatusUpdate(SyncStatus.waitingForResponse);
|
||||
SyncStatusUpdate _status =
|
||||
const SyncStatusUpdate(SyncStatus.waitingForResponse);
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
@ -44,12 +47,12 @@ class _ConnectionStatusHeaderState extends State<ConnectionStatusHeader> {
|
||||
);
|
||||
|
||||
return AnimatedContainer(
|
||||
duration: Duration(milliseconds: 200),
|
||||
duration: const Duration(milliseconds: 200),
|
||||
curve: Curves.bounceInOut,
|
||||
height: _connected ? 0 : 36,
|
||||
clipBehavior: Clip.hardEdge,
|
||||
decoration: BoxDecoration(color: Theme.of(context).secondaryHeaderColor),
|
||||
padding: EdgeInsets.symmetric(horizontal: 12),
|
||||
padding: const EdgeInsets.symmetric(horizontal: 12),
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
@ -61,7 +64,7 @@ class _ConnectionStatusHeaderState extends State<ConnectionStatusHeader> {
|
||||
value: _connected ? 1.0 : _status.progress,
|
||||
),
|
||||
),
|
||||
SizedBox(width: 12),
|
||||
const SizedBox(width: 12),
|
||||
Text(
|
||||
_status.toLocalizedString(context),
|
||||
maxLines: 1,
|
||||
|
@ -44,7 +44,7 @@ class _ContactsState extends State<ContactsList> {
|
||||
_lastSetState.millisecondsSinceEpoch <
|
||||
1000) {
|
||||
_coolDown?.cancel();
|
||||
_coolDown = Timer(Duration(seconds: 1), _updateView);
|
||||
_coolDown = Timer(const Duration(seconds: 1), _updateView);
|
||||
} else {
|
||||
_updateView();
|
||||
}
|
||||
@ -77,7 +77,7 @@ class _ContactListTile extends StatelessWidget {
|
||||
snapshot.data?.displayName ?? contact.senderId.localpart;
|
||||
final avatarUrl = snapshot.data?.avatarUrl;
|
||||
return ListTile(
|
||||
leading: Container(
|
||||
leading: SizedBox(
|
||||
width: Avatar.defaultSize,
|
||||
height: Avatar.defaultSize,
|
||||
child: Stack(
|
||||
|
@ -63,14 +63,14 @@ class ContentBanner extends StatelessWidget {
|
||||
),
|
||||
if (onEdit != null)
|
||||
Container(
|
||||
margin: EdgeInsets.all(8),
|
||||
margin: const EdgeInsets.all(8),
|
||||
alignment: Alignment.bottomRight,
|
||||
child: FloatingActionButton(
|
||||
mini: true,
|
||||
onPressed: onEdit,
|
||||
backgroundColor: Theme.of(context).backgroundColor,
|
||||
foregroundColor: Theme.of(context).textTheme.bodyText1.color,
|
||||
child: Icon(Icons.camera_alt_outlined),
|
||||
child: const Icon(Icons.camera_alt_outlined),
|
||||
),
|
||||
),
|
||||
],
|
||||
|
@ -18,7 +18,7 @@ class DefaultAppBarSearchField extends StatefulWidget {
|
||||
final bool unfocusOnClear;
|
||||
final bool autocorrect;
|
||||
|
||||
DefaultAppBarSearchField({
|
||||
const DefaultAppBarSearchField({
|
||||
Key key,
|
||||
this.searchController,
|
||||
this.onChanged,
|
||||
@ -78,7 +78,7 @@ class DefaultAppBarSearchFieldState extends State<DefaultAppBarSearchField> {
|
||||
Widget build(BuildContext context) {
|
||||
return Container(
|
||||
height: 40,
|
||||
padding: widget.padding ?? EdgeInsets.only(right: 12),
|
||||
padding: widget.padding ?? const EdgeInsets.only(right: 12),
|
||||
child: TextField(
|
||||
autofocus: widget.autofocus,
|
||||
autocorrect: widget.autocorrect,
|
||||
@ -97,7 +97,7 @@ class DefaultAppBarSearchFieldState extends State<DefaultAppBarSearchField> {
|
||||
borderSide:
|
||||
BorderSide(color: Theme.of(context).secondaryHeaderColor),
|
||||
),
|
||||
contentPadding: EdgeInsets.only(
|
||||
contentPadding: const EdgeInsets.only(
|
||||
top: 8,
|
||||
bottom: 8,
|
||||
left: 16,
|
||||
@ -110,7 +110,7 @@ class DefaultAppBarSearchFieldState extends State<DefaultAppBarSearchField> {
|
||||
(_searchController.text?.isNotEmpty ?? false)))
|
||||
? IconButton(
|
||||
tooltip: L10n.of(context).clearText,
|
||||
icon: Icon(Icons.backspace_outlined),
|
||||
icon: const Icon(Icons.backspace_outlined),
|
||||
onPressed: () {
|
||||
_searchController.clear();
|
||||
widget.onChanged?.call('');
|
||||
|
@ -132,10 +132,10 @@ class _AudioPlayerState extends State<AudioPlayerWidget> {
|
||||
return Row(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: <Widget>[
|
||||
Container(
|
||||
SizedBox(
|
||||
width: 30,
|
||||
child: status == AudioPlayerStatus.downloading
|
||||
? CircularProgressIndicator.adaptive(strokeWidth: 2)
|
||||
? const CircularProgressIndicator.adaptive(strokeWidth: 2)
|
||||
: IconButton(
|
||||
icon: Icon(
|
||||
audioPlayer.state == PlayerState.PLAYING
|
||||
@ -172,7 +172,7 @@ class _AudioPlayerState extends State<AudioPlayerWidget> {
|
||||
color: widget.color,
|
||||
),
|
||||
),
|
||||
SizedBox(width: 8),
|
||||
const SizedBox(width: 8),
|
||||
IconButton(
|
||||
icon: Icon(
|
||||
Icons.download_outlined,
|
||||
|
@ -18,13 +18,15 @@ class HtmlMessage extends StatelessWidget {
|
||||
final TextStyle linkStyle;
|
||||
final double emoteSize;
|
||||
|
||||
const HtmlMessage(
|
||||
{this.html,
|
||||
this.maxLines,
|
||||
this.room,
|
||||
this.defaultTextStyle,
|
||||
this.linkStyle,
|
||||
this.emoteSize});
|
||||
const HtmlMessage({
|
||||
Key key,
|
||||
this.html,
|
||||
this.maxLines,
|
||||
this.room,
|
||||
this.defaultTextStyle,
|
||||
this.linkStyle,
|
||||
this.emoteSize,
|
||||
}) : super(key: key);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
@ -35,7 +37,7 @@ class HtmlMessage extends StatelessWidget {
|
||||
// miss-matching tags, and this way we actually correctly identify what we want to strip and, well,
|
||||
// strip it.
|
||||
final renderHtml = html.replaceAll(
|
||||
RegExp('<mx-reply>.*<\/mx-reply>',
|
||||
RegExp('<mx-reply>.*</mx-reply>',
|
||||
caseSensitive: false, multiLine: false, dotAll: true),
|
||||
'');
|
||||
|
||||
|
@ -205,8 +205,8 @@ class _ImageBubbleState extends State<ImageBubble> {
|
||||
child: Row(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
Icon(Icons.download_outlined),
|
||||
SizedBox(width: 8),
|
||||
const Icon(Icons.download_outlined),
|
||||
const SizedBox(width: 8),
|
||||
Text(
|
||||
filename,
|
||||
overflow: TextOverflow.fade,
|
||||
@ -217,7 +217,7 @@ class _ImageBubbleState extends State<ImageBubble> {
|
||||
),
|
||||
),
|
||||
if (widget.event.sizeString != null) Text(widget.event.sizeString),
|
||||
SizedBox(height: 8),
|
||||
const SizedBox(height: 8),
|
||||
Text((error ?? _error).toString()),
|
||||
],
|
||||
),
|
||||
@ -249,7 +249,7 @@ class _ImageBubbleState extends State<ImageBubble> {
|
||||
children: <Widget>[
|
||||
if (blurhash != null) blurhash,
|
||||
Center(
|
||||
child: child ?? CircularProgressIndicator.adaptive(strokeWidth: 2),
|
||||
child: child ?? const CircularProgressIndicator.adaptive(strokeWidth: 2),
|
||||
),
|
||||
],
|
||||
);
|
||||
@ -412,7 +412,7 @@ class _ImageBubbleState extends State<ImageBubble> {
|
||||
child: Hero(
|
||||
tag: widget.event.eventId,
|
||||
child: AnimatedSwitcher(
|
||||
duration: Duration(milliseconds: 1000),
|
||||
duration: const Duration(milliseconds: 1000),
|
||||
child: Container(
|
||||
key: ValueKey(key),
|
||||
constraints: widget.maxSize
|
||||
|
@ -42,7 +42,7 @@ class MapBubble extends StatelessWidget {
|
||||
markers: [
|
||||
Marker(
|
||||
point: LatLng(latitude, longitude),
|
||||
builder: (context) => Icon(
|
||||
builder: (context) => const Icon(
|
||||
Icons.location_pin,
|
||||
color: Colors.red,
|
||||
),
|
||||
|
@ -33,7 +33,9 @@ class Message extends StatelessWidget {
|
||||
this.scrollToEventId,
|
||||
@required this.unfold,
|
||||
this.selected,
|
||||
this.timeline});
|
||||
this.timeline,
|
||||
Key key})
|
||||
: super(key: key);
|
||||
|
||||
/// Indicates wheither the user may use a mouse instead
|
||||
/// of touchscreen.
|
||||
@ -99,8 +101,8 @@ class Message extends StatelessWidget {
|
||||
),
|
||||
padding:
|
||||
const EdgeInsets.symmetric(vertical: 6, horizontal: 10),
|
||||
constraints:
|
||||
BoxConstraints(maxWidth: FluffyThemes.columnWidth * 1.5),
|
||||
constraints: const BoxConstraints(
|
||||
maxWidth: FluffyThemes.columnWidth * 1.5),
|
||||
child: Stack(
|
||||
children: <Widget>[
|
||||
Column(
|
||||
@ -134,7 +136,8 @@ class Message extends StatelessWidget {
|
||||
},
|
||||
child: AbsorbPointer(
|
||||
child: Container(
|
||||
margin: EdgeInsets.symmetric(vertical: 4.0),
|
||||
margin: const EdgeInsets.symmetric(
|
||||
vertical: 4.0),
|
||||
child: ReplyContent(replyEvent,
|
||||
lightText: ownMessage,
|
||||
timeline: timeline),
|
||||
@ -147,7 +150,7 @@ class Message extends StatelessWidget {
|
||||
displayEvent,
|
||||
textColor: textColor,
|
||||
),
|
||||
SizedBox(height: 3),
|
||||
const SizedBox(height: 3),
|
||||
Opacity(
|
||||
opacity: 0,
|
||||
child: _MetaRow(
|
||||
@ -181,7 +184,7 @@ class Message extends StatelessWidget {
|
||||
),
|
||||
];
|
||||
final avatarOrSizedBox = sameSender
|
||||
? SizedBox(width: Avatar.defaultSize)
|
||||
? const SizedBox(width: Avatar.defaultSize)
|
||||
: Avatar(
|
||||
event.sender.avatarUrl,
|
||||
event.sender.calcDisplayname(),
|
||||
@ -224,10 +227,11 @@ class Message extends StatelessWidget {
|
||||
color: selected
|
||||
? Theme.of(context).primaryColor.withAlpha(100)
|
||||
: Theme.of(context).primaryColor.withAlpha(0),
|
||||
constraints: BoxConstraints(maxWidth: FluffyThemes.columnWidth * 2.5),
|
||||
constraints:
|
||||
const BoxConstraints(maxWidth: FluffyThemes.columnWidth * 2.5),
|
||||
child: Padding(
|
||||
padding:
|
||||
EdgeInsets.only(left: 8.0, right: 8.0, bottom: 4.0, top: 4.0),
|
||||
padding: const EdgeInsets.only(
|
||||
left: 8.0, right: 8.0, bottom: 4.0, top: 4.0),
|
||||
child: container,
|
||||
),
|
||||
),
|
||||
@ -267,7 +271,7 @@ class _MetaRow extends StatelessWidget {
|
||||
.withAlpha(200),
|
||||
),
|
||||
),
|
||||
if (showDisplayname) SizedBox(width: 4),
|
||||
if (showDisplayname) const SizedBox(width: 4),
|
||||
Text(
|
||||
event.originServerTs.localizedTime(context),
|
||||
style: TextStyle(
|
||||
@ -284,7 +288,7 @@ class _MetaRow extends StatelessWidget {
|
||||
color: color,
|
||||
),
|
||||
),
|
||||
if (ownMessage) SizedBox(width: 2),
|
||||
if (ownMessage) const SizedBox(width: 2),
|
||||
if (ownMessage)
|
||||
Icon(
|
||||
displayEvent.statusIcon,
|
||||
|
@ -26,7 +26,7 @@ class MessageContent extends StatelessWidget {
|
||||
final Event event;
|
||||
final Color textColor;
|
||||
|
||||
const MessageContent(this.event, {this.textColor});
|
||||
const MessageContent(this.event, {Key key,this.textColor}) : super(key: key);
|
||||
|
||||
void _verifyOrRequestKey(BuildContext context) async {
|
||||
if (event.content['can_request_session'] != true) {
|
||||
@ -50,7 +50,7 @@ class MessageContent extends StatelessWidget {
|
||||
if (await client.encryption.keyManager.isCached()) {
|
||||
break;
|
||||
}
|
||||
await Future.delayed(Duration(seconds: 1));
|
||||
await Future.delayed(const Duration(seconds: 1));
|
||||
}
|
||||
final timeline = await event.room.getTimeline();
|
||||
timeline.requestKeys();
|
||||
@ -121,7 +121,7 @@ class MessageContent extends StatelessWidget {
|
||||
fit: BoxFit.cover,
|
||||
tapToView: false,
|
||||
),
|
||||
Icon(Icons.play_circle_outline,
|
||||
const Icon(Icons.play_circle_outline,
|
||||
size: 200, color: Colors.grey),
|
||||
],
|
||||
),
|
||||
@ -169,7 +169,7 @@ class MessageContent extends StatelessWidget {
|
||||
onPrimary: Theme.of(context).textTheme.bodyText1.color,
|
||||
),
|
||||
onPressed: () => _verifyOrRequestKey(context),
|
||||
icon: Icon(Icons.lock_outline),
|
||||
icon: const Icon(Icons.lock_outline),
|
||||
label: Text(L10n.of(context).encrypted),
|
||||
);
|
||||
case MessageTypes.Location:
|
||||
@ -194,7 +194,7 @@ class MessageContent extends StatelessWidget {
|
||||
latitude: latlong.first,
|
||||
longitude: latlong.last,
|
||||
),
|
||||
SizedBox(height: 6),
|
||||
const SizedBox(height: 6),
|
||||
OutlinedButton.icon(
|
||||
icon: Icon(Icons.location_on_outlined, color: textColor),
|
||||
onPressed:
|
||||
@ -219,7 +219,7 @@ class MessageContent extends StatelessWidget {
|
||||
onPrimary: Theme.of(context).textTheme.bodyText1.color,
|
||||
),
|
||||
onPressed: () => launch(event.body),
|
||||
icon: Icon(Icons.phone_outlined, color: Colors.green),
|
||||
icon: const Icon(Icons.phone_outlined, color: Colors.green),
|
||||
label: Text(L10n.of(context).videoCall),
|
||||
);
|
||||
}
|
||||
@ -228,7 +228,7 @@ class MessageContent extends StatelessWidget {
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
Icon(Icons.delete_forever_outlined, color: textColor),
|
||||
SizedBox(width: 4),
|
||||
const SizedBox(width: 4),
|
||||
Text(
|
||||
event.getLocalizedBody(MatrixLocals(L10n.of(context)),
|
||||
hideReply: true),
|
||||
|
@ -14,42 +14,40 @@ class MessageDownloadContent extends StatelessWidget {
|
||||
final String filename = event.content.containsKey('filename')
|
||||
? event.content['filename']
|
||||
: event.body;
|
||||
return Container(
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: <Widget>[
|
||||
ElevatedButton(
|
||||
style: ElevatedButton.styleFrom(
|
||||
primary: Theme.of(context).scaffoldBackgroundColor,
|
||||
onPrimary: Theme.of(context).textTheme.bodyText1.color,
|
||||
),
|
||||
onPressed: () => event.saveFile(context),
|
||||
child: Row(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
Icon(Icons.download_outlined),
|
||||
SizedBox(width: 8),
|
||||
Expanded(
|
||||
child: Text(
|
||||
filename,
|
||||
overflow: TextOverflow.fade,
|
||||
softWrap: false,
|
||||
maxLines: 1,
|
||||
),
|
||||
return Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: <Widget>[
|
||||
ElevatedButton(
|
||||
style: ElevatedButton.styleFrom(
|
||||
primary: Theme.of(context).scaffoldBackgroundColor,
|
||||
onPrimary: Theme.of(context).textTheme.bodyText1.color,
|
||||
),
|
||||
onPressed: () => event.saveFile(context),
|
||||
child: Row(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
const Icon(Icons.download_outlined),
|
||||
const SizedBox(width: 8),
|
||||
Expanded(
|
||||
child: Text(
|
||||
filename,
|
||||
overflow: TextOverflow.fade,
|
||||
softWrap: false,
|
||||
maxLines: 1,
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
if (event.sizeString != null)
|
||||
Text(
|
||||
event.sizeString,
|
||||
style: TextStyle(
|
||||
color: textColor,
|
||||
),
|
||||
),
|
||||
if (event.sizeString != null)
|
||||
Text(
|
||||
event.sizeString,
|
||||
style: TextStyle(
|
||||
color: textColor,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -12,7 +12,8 @@ class MessageReactions extends StatelessWidget {
|
||||
final Event event;
|
||||
final Timeline timeline;
|
||||
|
||||
const MessageReactions(this.event, this.timeline);
|
||||
const MessageReactions(this.event, this.timeline, {Key key})
|
||||
: super(key: key);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
|
@ -74,7 +74,7 @@ class ReplyContent extends StatelessWidget {
|
||||
height: fontSize * 2 + 6,
|
||||
color: lightText ? Colors.white : Theme.of(context).primaryColor,
|
||||
),
|
||||
SizedBox(width: 6),
|
||||
const SizedBox(width: 6),
|
||||
Flexible(
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
|
@ -8,7 +8,8 @@ import '../../config/app_config.dart';
|
||||
class StateMessage extends StatelessWidget {
|
||||
final Event event;
|
||||
final void Function(String) unfold;
|
||||
const StateMessage(this.event, {@required this.unfold});
|
||||
const StateMessage(this.event, {@required this.unfold, Key key})
|
||||
: super(key: key);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
@ -52,7 +53,7 @@ class StateMessage extends StatelessWidget {
|
||||
if (counter != 0)
|
||||
Text(
|
||||
L10n.of(context).moreEvents(counter),
|
||||
style: TextStyle(
|
||||
style: const TextStyle(
|
||||
fontWeight: FontWeight.bold,
|
||||
),
|
||||
),
|
||||
|
@ -8,7 +8,8 @@ class VerificationRequestContent extends StatelessWidget {
|
||||
final Event event;
|
||||
final Timeline timeline;
|
||||
|
||||
const VerificationRequestContent({this.event, this.timeline});
|
||||
const VerificationRequestContent({this.event, this.timeline, Key key})
|
||||
: super(key: key);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
@ -22,13 +23,13 @@ class VerificationRequestContent extends StatelessWidget {
|
||||
final started = start.isNotEmpty;
|
||||
final canceled = cancel.isNotEmpty;
|
||||
return Padding(
|
||||
padding: EdgeInsets.symmetric(
|
||||
padding: const EdgeInsets.symmetric(
|
||||
horizontal: 8.0,
|
||||
vertical: 4.0,
|
||||
),
|
||||
child: Center(
|
||||
child: Container(
|
||||
padding: EdgeInsets.all(8),
|
||||
padding: const EdgeInsets.all(8),
|
||||
decoration: BoxDecoration(
|
||||
border: Border.all(
|
||||
color: Theme.of(context).dividerColor,
|
||||
@ -44,7 +45,7 @@ class VerificationRequestContent extends StatelessWidget {
|
||||
color: canceled
|
||||
? Colors.red
|
||||
: (fullyDone ? Colors.green : Colors.grey)),
|
||||
SizedBox(width: 8),
|
||||
const SizedBox(width: 8),
|
||||
Text(canceled
|
||||
? 'Error ${cancel.first.content.tryGet<String>('code')}: ${cancel.first.content.tryGet<String>('reason')}'
|
||||
: (fullyDone
|
||||
|
@ -1,6 +1,8 @@
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
class FluffyBanner extends StatelessWidget {
|
||||
const FluffyBanner({Key key}) : super(key: key);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Image.asset(Theme.of(context).brightness == Brightness.dark
|
||||
|
@ -24,7 +24,7 @@ class InputBar extends StatelessWidget {
|
||||
final ValueChanged<String> onChanged;
|
||||
final bool autofocus;
|
||||
|
||||
InputBar({
|
||||
const InputBar({
|
||||
this.room,
|
||||
this.minLines,
|
||||
this.maxLines,
|
||||
@ -36,7 +36,8 @@ class InputBar extends StatelessWidget {
|
||||
this.onChanged,
|
||||
this.autofocus,
|
||||
this.textInputAction,
|
||||
});
|
||||
Key key,
|
||||
}) : super(key: key);
|
||||
|
||||
List<Map<String, String>> getSuggestions(String text) {
|
||||
if (controller.selection.baseOffset != controller.selection.extentOffset ||
|
||||
@ -220,7 +221,7 @@ class InputBar extends StatelessWidget {
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text('/' + command, style: TextStyle(fontFamily: 'monospace')),
|
||||
Text('/' + command, style: const TextStyle(fontFamily: 'monospace')),
|
||||
Text(_commandHint(L10n.of(context), command),
|
||||
style: Theme.of(context).textTheme.caption),
|
||||
],
|
||||
@ -246,7 +247,7 @@ class InputBar extends StatelessWidget {
|
||||
width: size,
|
||||
height: size,
|
||||
),
|
||||
SizedBox(width: 6),
|
||||
const SizedBox(width: 6),
|
||||
Text(suggestion['name']),
|
||||
Expanded(
|
||||
child: Align(
|
||||
@ -281,7 +282,7 @@ class InputBar extends StatelessWidget {
|
||||
size: size,
|
||||
client: client,
|
||||
),
|
||||
SizedBox(width: 6),
|
||||
const SizedBox(width: 6),
|
||||
Text(suggestion['displayname'] ?? suggestion['mxid']),
|
||||
],
|
||||
),
|
||||
@ -395,7 +396,7 @@ class InputBar extends StatelessWidget {
|
||||
hideOnEmpty: true,
|
||||
hideOnLoading: true,
|
||||
keepSuggestionsOnSuggestionSelected: true,
|
||||
debounceDuration: Duration(
|
||||
debounceDuration: const Duration(
|
||||
milliseconds:
|
||||
50), // show suggestions after 50ms idle time (default is 300)
|
||||
textFieldConfiguration: TextFieldConfiguration(
|
||||
|
@ -5,6 +5,8 @@ import 'package:fluffychat/widgets/matrix.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
class LoadingView extends StatelessWidget {
|
||||
const LoadingView({Key key}) : super(key: key);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
if (Matrix.of(context)
|
||||
@ -23,6 +25,6 @@ class LoadingView extends StatelessWidget {
|
||||
),
|
||||
);
|
||||
}
|
||||
return EmptyPage(loading: true);
|
||||
return const EmptyPage(loading: true);
|
||||
}
|
||||
}
|
||||
|
@ -22,7 +22,7 @@ class MaxWidthBody extends StatelessWidget {
|
||||
);
|
||||
return withScrolling
|
||||
? SingleChildScrollView(
|
||||
physics: ScrollPhysics(),
|
||||
physics: const ScrollPhysics(),
|
||||
child: Padding(
|
||||
padding: padding,
|
||||
child: child,
|
||||
|
@ -17,7 +17,7 @@ class OnePageCard extends StatelessWidget {
|
||||
Matrix.of(context).client.isLogged()
|
||||
? child
|
||||
: Container(
|
||||
decoration: BoxDecoration(
|
||||
decoration: const BoxDecoration(
|
||||
image: DecorationImage(
|
||||
image: AssetImage('assets/login_wallpaper.jpg'),
|
||||
fit: BoxFit.cover,
|
||||
|
@ -28,9 +28,9 @@ class SideViewLayout extends StatelessWidget {
|
||||
color: Theme.of(context).dividerColor,
|
||||
),
|
||||
AnimatedContainer(
|
||||
duration: Duration(milliseconds: 300),
|
||||
duration: const Duration(milliseconds: 300),
|
||||
clipBehavior: Clip.antiAlias,
|
||||
decoration: BoxDecoration(),
|
||||
decoration: const BoxDecoration(),
|
||||
width: hideSideView ? 0 : 360.0,
|
||||
child: hideSideView ? null : sideView,
|
||||
),
|
||||
|
@ -19,7 +19,7 @@ class TwoColumnLayout extends StatelessWidget {
|
||||
children: [
|
||||
Container(
|
||||
clipBehavior: Clip.antiAlias,
|
||||
decoration: BoxDecoration(),
|
||||
decoration: const BoxDecoration(),
|
||||
width: 360.0,
|
||||
child: mainView,
|
||||
),
|
||||
|
@ -27,14 +27,17 @@ class ChatListItem extends StatelessWidget {
|
||||
final Function onTap;
|
||||
final Function onLongPress;
|
||||
|
||||
const ChatListItem(this.room,
|
||||
{this.activeChat = false,
|
||||
this.selected = false,
|
||||
this.onTap,
|
||||
this.onLongPress,
|
||||
this.onForget});
|
||||
const ChatListItem(
|
||||
this.room, {
|
||||
this.activeChat = false,
|
||||
this.selected = false,
|
||||
this.onTap,
|
||||
this.onLongPress,
|
||||
this.onForget,
|
||||
Key key,
|
||||
}) : super(key: key);
|
||||
|
||||
void clickAction(BuildContext context) async {
|
||||
dynamic clickAction(BuildContext context) async {
|
||||
if (onTap != null) return onTap();
|
||||
if (!activeChat) {
|
||||
if (room.membership == Membership.invite &&
|
||||
@ -161,13 +164,13 @@ class ChatListItem extends StatelessWidget {
|
||||
: Theme.of(context).secondaryHeaderColor,
|
||||
onLongPress: onLongPress,
|
||||
leading: selected
|
||||
? Container(
|
||||
? SizedBox(
|
||||
width: Avatar.defaultSize,
|
||||
height: Avatar.defaultSize,
|
||||
child: Material(
|
||||
color: Theme.of(context).primaryColor,
|
||||
borderRadius: BorderRadius.circular(Avatar.defaultSize),
|
||||
child: Icon(Icons.check, color: Colors.white),
|
||||
child: const Icon(Icons.check, color: Colors.white),
|
||||
),
|
||||
)
|
||||
: Avatar(room.avatar, room.displayname, onTap: onLongPress),
|
||||
@ -188,8 +191,8 @@ class ChatListItem extends StatelessWidget {
|
||||
),
|
||||
),
|
||||
if (isMuted)
|
||||
Padding(
|
||||
padding: const EdgeInsets.only(left: 4.0),
|
||||
const Padding(
|
||||
padding: EdgeInsets.only(left: 4.0),
|
||||
child: Icon(
|
||||
Icons.notifications_off_outlined,
|
||||
size: 16,
|
||||
@ -227,15 +230,15 @@ class ChatListItem extends StatelessWidget {
|
||||
room.lastEvent.statusIcon,
|
||||
size: 14,
|
||||
),
|
||||
SizedBox(width: 4),
|
||||
const SizedBox(width: 4),
|
||||
},
|
||||
AnimatedContainer(
|
||||
width: typingText.isEmpty ? 0 : 18,
|
||||
clipBehavior: Clip.hardEdge,
|
||||
decoration: BoxDecoration(),
|
||||
duration: Duration(milliseconds: 300),
|
||||
decoration: const BoxDecoration(),
|
||||
duration: const Duration(milliseconds: 300),
|
||||
curve: Curves.bounceInOut,
|
||||
padding: EdgeInsets.only(right: 4),
|
||||
padding: const EdgeInsets.only(right: 4),
|
||||
child: Icon(
|
||||
Icons.edit_outlined,
|
||||
color: Theme.of(context).colorScheme.secondary,
|
||||
@ -286,11 +289,11 @@ class ChatListItem extends StatelessWidget {
|
||||
),
|
||||
),
|
||||
),
|
||||
SizedBox(width: 8),
|
||||
const SizedBox(width: 8),
|
||||
AnimatedContainer(
|
||||
duration: Duration(milliseconds: 300),
|
||||
duration: const Duration(milliseconds: 300),
|
||||
curve: Curves.bounceInOut,
|
||||
padding: EdgeInsets.symmetric(horizontal: 7),
|
||||
padding: const EdgeInsets.symmetric(horizontal: 7),
|
||||
height: unreadBubbleSize,
|
||||
width: room.notificationCount == 0 && !unread
|
||||
? 0
|
||||
@ -307,7 +310,7 @@ class ChatListItem extends StatelessWidget {
|
||||
child: room.notificationCount > 0
|
||||
? Text(
|
||||
room.notificationCount.toString(),
|
||||
style: TextStyle(
|
||||
style: const TextStyle(
|
||||
color: Colors.white,
|
||||
fontSize: 13,
|
||||
),
|
||||
|
@ -8,7 +8,7 @@ import '../../pages/user_bottom_sheet.dart';
|
||||
class ParticipantListItem extends StatelessWidget {
|
||||
final User user;
|
||||
|
||||
const ParticipantListItem(this.user);
|
||||
const ParticipantListItem(this.user, {Key key}) : super(key: key);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
@ -38,8 +38,8 @@ class ParticipantListItem extends StatelessWidget {
|
||||
permissionBatch.isEmpty
|
||||
? Container()
|
||||
: Container(
|
||||
padding: EdgeInsets.all(4),
|
||||
margin: EdgeInsets.symmetric(horizontal: 8),
|
||||
padding: const EdgeInsets.all(4),
|
||||
margin: const EdgeInsets.symmetric(horizontal: 8),
|
||||
decoration: BoxDecoration(
|
||||
color: Theme.of(context).secondaryHeaderColor,
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
@ -49,8 +49,8 @@ class ParticipantListItem extends StatelessWidget {
|
||||
membershipBatch[user.membership].isEmpty
|
||||
? Container()
|
||||
: Container(
|
||||
padding: EdgeInsets.all(4),
|
||||
margin: EdgeInsets.symmetric(horizontal: 8),
|
||||
padding: const EdgeInsets.all(4),
|
||||
margin: const EdgeInsets.symmetric(horizontal: 8),
|
||||
decoration: BoxDecoration(
|
||||
color: Theme.of(context).secondaryHeaderColor,
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
|
@ -69,13 +69,13 @@ class PermissionsListTile extends StatelessWidget {
|
||||
leading: CircleAvatar(
|
||||
backgroundColor: Theme.of(context).scaffoldBackgroundColor,
|
||||
foregroundColor: Colors.grey,
|
||||
child: Icon(Icons.edit_attributes_outlined),
|
||||
child: const Icon(Icons.edit_attributes_outlined),
|
||||
),
|
||||
title: Text(getLocalizedPowerLevelString(context)),
|
||||
subtitle: Row(
|
||||
children: [
|
||||
Container(
|
||||
padding: EdgeInsets.all(4),
|
||||
padding: const EdgeInsets.all(4),
|
||||
decoration: BoxDecoration(
|
||||
color: Theme.of(context).secondaryHeaderColor,
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
@ -84,7 +84,7 @@ class PermissionsListTile extends StatelessWidget {
|
||||
child: Text(permission.toString()),
|
||||
),
|
||||
),
|
||||
SizedBox(width: 8),
|
||||
const SizedBox(width: 8),
|
||||
Text(permission.toLocalizedPowerLevelString(context)),
|
||||
],
|
||||
),
|
||||
|
@ -110,7 +110,7 @@ class UserDeviceListItem extends StatelessWidget {
|
||||
maxLines: 1,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
),
|
||||
Spacer(),
|
||||
const Spacer(),
|
||||
if (userDevice.lastSeenTs != null)
|
||||
Text(DateTime.fromMillisecondsSinceEpoch(userDevice.lastSeenTs)
|
||||
.localizedTimeShort(context)),
|
||||
@ -120,9 +120,9 @@ class UserDeviceListItem extends StatelessWidget {
|
||||
children: <Widget>[
|
||||
Text(
|
||||
userDevice.deviceId,
|
||||
style: TextStyle(fontWeight: FontWeight.w300),
|
||||
style: const TextStyle(fontWeight: FontWeight.w300),
|
||||
),
|
||||
Spacer(),
|
||||
const Spacer(),
|
||||
if (keys != null)
|
||||
Text(
|
||||
keys.blocked
|
||||
|
@ -10,6 +10,8 @@ import 'package:flutter_gen/gen_l10n/l10n.dart';
|
||||
import 'layouts/one_page_card.dart';
|
||||
|
||||
class LockScreen extends StatefulWidget {
|
||||
const LockScreen({Key key}) : super(key: key);
|
||||
|
||||
@override
|
||||
_LockScreenState createState() => _LockScreenState();
|
||||
}
|
||||
@ -42,7 +44,7 @@ class _LockScreenState extends State<LockScreen> {
|
||||
gradient: LinearGradient(
|
||||
begin: Alignment.topRight,
|
||||
end: Alignment.bottomLeft,
|
||||
stops: [
|
||||
stops: const [
|
||||
0.1,
|
||||
0.4,
|
||||
0.6,
|
||||
@ -62,12 +64,12 @@ class _LockScreenState extends State<LockScreen> {
|
||||
controller: _textEditingController,
|
||||
focusNode: _focusNode,
|
||||
pinBoxRadius: AppConfig.borderRadius,
|
||||
pinTextStyle: TextStyle(fontSize: 32),
|
||||
pinTextStyle: const TextStyle(fontSize: 32),
|
||||
hideCharacter: true,
|
||||
hasError: _wrongInput,
|
||||
onDone: (String input) async {
|
||||
if (input ==
|
||||
await FlutterSecureStorage()
|
||||
await const FlutterSecureStorage()
|
||||
.read(key: SettingKeys.appLockKey)) {
|
||||
AppLock.of(context).didUnlock();
|
||||
} else {
|
||||
|
@ -2,6 +2,8 @@ import 'package:matrix/matrix.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
class LogViewer extends StatefulWidget {
|
||||
const LogViewer({Key key}) : super(key: key);
|
||||
|
||||
@override
|
||||
_LogViewerState createState() => _LogViewerState();
|
||||
}
|
||||
@ -19,14 +21,14 @@ class _LogViewerState extends State<LogViewer> {
|
||||
backgroundColor: Colors.black,
|
||||
appBar: AppBar(
|
||||
title: Text(logLevel.toString()),
|
||||
leading: BackButton(),
|
||||
leading: const BackButton(),
|
||||
actions: [
|
||||
IconButton(
|
||||
icon: Icon(Icons.zoom_in_outlined),
|
||||
icon: const Icon(Icons.zoom_in_outlined),
|
||||
onPressed: () => setState(() => fontSize++),
|
||||
),
|
||||
IconButton(
|
||||
icon: Icon(Icons.zoom_out_outlined),
|
||||
icon: const Icon(Icons.zoom_out_outlined),
|
||||
onPressed: () => setState(() => fontSize--),
|
||||
),
|
||||
PopupMenuButton<Level>(
|
||||
|
@ -41,7 +41,7 @@ class Matrix extends StatefulWidget {
|
||||
|
||||
final Map<String, String> queryParameters;
|
||||
|
||||
Matrix({
|
||||
const Matrix({
|
||||
this.child,
|
||||
@required this.router,
|
||||
@required this.context,
|
||||
@ -209,7 +209,7 @@ class MatrixState extends State<Matrix> with WidgetsBindingObserver {
|
||||
|
||||
set cachedPassword(String p) => _cachedPassword = p;
|
||||
|
||||
void _onUiaRequest(UiaRequest uiaRequest) async {
|
||||
Future _onUiaRequest(UiaRequest uiaRequest) async {
|
||||
try {
|
||||
if (uiaRequest.state != UiaRequestState.waitForUser ||
|
||||
uiaRequest.nextStages.isEmpty) return;
|
||||
@ -224,7 +224,7 @@ class MatrixState extends State<Matrix> with WidgetsBindingObserver {
|
||||
okLabel: L10n.of(widget.context).ok,
|
||||
cancelLabel: L10n.of(widget.context).cancel,
|
||||
textFields: [
|
||||
DialogTextField(
|
||||
const DialogTextField(
|
||||
minLines: 1,
|
||||
maxLines: 1,
|
||||
obscureText: true,
|
||||
@ -481,7 +481,9 @@ class MatrixState extends State<Matrix> with WidgetsBindingObserver {
|
||||
// Display the app lock
|
||||
if (PlatformInfos.isMobile) {
|
||||
WidgetsBinding.instance.addPostFrameCallback((_) {
|
||||
FlutterSecureStorage().read(key: SettingKeys.appLockKey).then((lock) {
|
||||
const FlutterSecureStorage()
|
||||
.read(key: SettingKeys.appLockKey)
|
||||
.then((lock) {
|
||||
if (lock?.isNotEmpty ?? false) {
|
||||
AppLock.of(widget.context).enable();
|
||||
AppLock.of(widget.context).showLockScreen();
|
||||
@ -507,11 +509,11 @@ class MatrixState extends State<Matrix> with WidgetsBindingObserver {
|
||||
context,
|
||||
widget.router,
|
||||
onFcmError: (errorMsg, {Uri link}) => Timer(
|
||||
Duration(seconds: 1),
|
||||
const Duration(seconds: 1),
|
||||
() {
|
||||
final banner = SnackBar(
|
||||
content: Text(errorMsg),
|
||||
duration: Duration(seconds: 30),
|
||||
duration: const Duration(seconds: 30),
|
||||
action: link == null
|
||||
? null
|
||||
: SnackBarAction(
|
||||
|
@ -45,7 +45,7 @@ class ProfileBottomSheet extends StatelessWidget {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Center(
|
||||
child: Container(
|
||||
child: SizedBox(
|
||||
width: min(
|
||||
MediaQuery.of(context).size.width, FluffyThemes.columnWidth * 1.5),
|
||||
child: Material(
|
||||
@ -58,7 +58,7 @@ class ProfileBottomSheet extends StatelessWidget {
|
||||
backgroundColor:
|
||||
Theme.of(context).scaffoldBackgroundColor.withOpacity(0.5),
|
||||
leading: IconButton(
|
||||
icon: Icon(Icons.arrow_downward_outlined),
|
||||
icon: const Icon(Icons.arrow_downward_outlined),
|
||||
onPressed: Navigator.of(context, rootNavigator: false).pop,
|
||||
tooltip: L10n.of(context).close,
|
||||
),
|
||||
@ -79,7 +79,7 @@ class ProfileBottomSheet extends StatelessWidget {
|
||||
child: snapshot.hasError
|
||||
? Text(snapshot.error
|
||||
.toLocalizedString(context))
|
||||
: CircularProgressIndicator.adaptive(
|
||||
: const CircularProgressIndicator.adaptive(
|
||||
strokeWidth: 2),
|
||||
)
|
||||
: ContentBanner(
|
||||
@ -91,18 +91,18 @@ class ProfileBottomSheet extends StatelessWidget {
|
||||
ListTile(
|
||||
title: Text(profile?.displayName ?? userId.localpart),
|
||||
subtitle: Text(userId),
|
||||
trailing: Icon(Icons.account_box_outlined),
|
||||
trailing: const Icon(Icons.account_box_outlined),
|
||||
),
|
||||
Container(
|
||||
width: double.infinity,
|
||||
padding: EdgeInsets.all(12),
|
||||
padding: const EdgeInsets.all(12),
|
||||
child: ElevatedButton.icon(
|
||||
onPressed: () => _startDirectChat(context),
|
||||
label: Text(L10n.of(context).newChat),
|
||||
icon: Icon(Icons.send_outlined),
|
||||
icon: const Icon(Icons.send_outlined),
|
||||
),
|
||||
),
|
||||
SizedBox(height: 8),
|
||||
const SizedBox(height: 8),
|
||||
],
|
||||
);
|
||||
}),
|
||||
|
@ -16,7 +16,7 @@ class UnreadBadgeBackButton extends StatelessWidget {
|
||||
Widget build(BuildContext context) {
|
||||
return Stack(
|
||||
children: [
|
||||
Center(child: BackButton()),
|
||||
const Center(child: BackButton()),
|
||||
StreamBuilder(
|
||||
stream: Matrix.of(context).client.onSync.stream,
|
||||
builder: (context, _) {
|
||||
@ -31,8 +31,8 @@ class UnreadBadgeBackButton extends StatelessWidget {
|
||||
? Align(
|
||||
alignment: Alignment.bottomRight,
|
||||
child: Container(
|
||||
padding: EdgeInsets.all(4),
|
||||
margin: EdgeInsets.only(bottom: 4, right: 8),
|
||||
padding: const EdgeInsets.all(4),
|
||||
margin: const EdgeInsets.only(bottom: 4, right: 8),
|
||||
decoration: BoxDecoration(
|
||||
color: Theme.of(context).primaryColor,
|
||||
borderRadius:
|
||||
@ -40,7 +40,7 @@ class UnreadBadgeBackButton extends StatelessWidget {
|
||||
),
|
||||
child: Text(
|
||||
'$unreadCount',
|
||||
style: TextStyle(
|
||||
style: const TextStyle(
|
||||
fontSize: 12,
|
||||
color: Colors.white,
|
||||
),
|
||||
|
16
pubspec.lock
16
pubspec.lock
@ -384,6 +384,13 @@ packages:
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "2.0.0"
|
||||
flutter_lints:
|
||||
dependency: "direct dev"
|
||||
description:
|
||||
name: flutter_lints
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.0.4"
|
||||
flutter_local_notifications:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
@ -665,6 +672,13 @@ packages:
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.8.0"
|
||||
lints:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: lints
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.0.1"
|
||||
lists:
|
||||
dependency: transitive
|
||||
description:
|
||||
@ -913,7 +927,7 @@ packages:
|
||||
source: hosted
|
||||
version: "2.0.0"
|
||||
pedantic:
|
||||
dependency: "direct dev"
|
||||
dependency: transitive
|
||||
description:
|
||||
name: pedantic
|
||||
url: "https://pub.dartlang.org"
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user