Merge branch 'krille/switch-to-flutter-lints' into 'main'

refactor: Switch to flutter_lints

See merge request famedly/fluffychat!536
This commit is contained in:
Krille Fear 2021-10-15 08:26:26 +00:00
commit 797161c7f2
101 changed files with 719 additions and 653 deletions

View File

@ -1,4 +1,4 @@
include: package:pedantic/analysis_options.yaml
include: package:flutter_lints/flutter.yaml
linter:
rules:

View File

@ -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);
}

View File

@ -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),

View File

@ -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,

View File

@ -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();
}

View File

@ -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: () =>

View File

@ -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);
}

View File

@ -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),
);

View File

@ -16,17 +16,19 @@ class ChatEncryptionSettings extends StatefulWidget {
class ChatEncryptionSettingsController extends State<ChatEncryptionSettings> {
String get roomId => VRouter.of(context).pathParameters['roomid'];
Future<void> onSelected(
BuildContext context, String action, DeviceKeys key) async {
final room = Matrix.of(context).client.getRoomById(roomId);
final unblock = () async {
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);
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;
}

View File

@ -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();
}

View File

@ -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);

View File

@ -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),
);
}

View File

@ -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),
],
);
}

View File

@ -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,

View File

@ -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();
}

View File

@ -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(),
);
}

View File

@ -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();
}

View File

@ -63,7 +63,7 @@ class _PermissionSliderDialogState extends State<PermissionSliderDialog> {
: _permission >= 50
? '$_permission (${L10n.of(context).moderator})'
: _permission.toString())),
Container(
SizedBox(
height: 56,
child: slider,
),

View File

@ -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,
),

View File

@ -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),
],
),
),

View File

@ -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;

View File

@ -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),
],
);

View File

@ -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);

View File

@ -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();
}

View File

@ -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,

View File

@ -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) {

View File

@ -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();

View File

@ -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() =>

View File

@ -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,

View File

@ -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();

View File

@ -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();
}

View File

@ -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),
),
),

View File

@ -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,

View File

@ -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,

View File

@ -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,
),

View File

@ -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

View File

@ -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,
),

View File

@ -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));
}

View File

@ -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),
),
),
))

View File

@ -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(

View File

@ -34,7 +34,7 @@ class EmptyPage extends StatelessWidget {
Center(
child: SizedBox(
width: _width,
child: LinearProgressIndicator(),
child: const LinearProgressIndicator(),
),
),
],

View File

@ -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,
),

View File

@ -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,

View File

@ -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(

View File

@ -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,
),

View File

@ -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),
),
);
}

View File

@ -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,
);

View File

@ -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),
),
);
}

View File

@ -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,
),
),

View File

@ -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]),
),

View File

@ -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,
),

View File

@ -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,

View File

@ -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();

View File

@ -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: () =>

View File

@ -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(

View File

@ -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(

View File

@ -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,

View File

@ -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,

View File

@ -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),
),

View File

@ -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),
),
),

View File

@ -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),
],
);

View File

@ -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,
)),

View File

@ -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,

View File

@ -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.

View File

@ -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) {

View File

@ -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) {

View File

@ -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),
],

View File

@ -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),
],
),

View File

@ -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,

View File

@ -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(

View File

@ -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),
),
),
],

View File

@ -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('');

View File

@ -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,

View File

@ -18,13 +18,15 @@ class HtmlMessage extends StatelessWidget {
final TextStyle linkStyle;
final double emoteSize;
const HtmlMessage(
{this.html,
const HtmlMessage({
Key key,
this.html,
this.maxLines,
this.room,
this.defaultTextStyle,
this.linkStyle,
this.emoteSize});
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),
'');

View File

@ -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

View File

@ -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,
),

View File

@ -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,

View File

@ -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),

View File

@ -14,8 +14,7 @@ class MessageDownloadContent extends StatelessWidget {
final String filename = event.content.containsKey('filename')
? event.content['filename']
: event.body;
return Container(
child: Column(
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisSize: MainAxisSize.min,
children: <Widget>[
@ -28,8 +27,8 @@ class MessageDownloadContent extends StatelessWidget {
child: Row(
mainAxisSize: MainAxisSize.min,
children: [
Icon(Icons.download_outlined),
SizedBox(width: 8),
const Icon(Icons.download_outlined),
const SizedBox(width: 8),
Expanded(
child: Text(
filename,
@ -49,7 +48,6 @@ class MessageDownloadContent extends StatelessWidget {
),
),
],
),
);
}
}

View File

@ -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) {

View File

@ -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,

View File

@ -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,
),
),

View File

@ -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

View File

@ -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

View File

@ -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(

View File

@ -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);
}
}

View File

@ -22,7 +22,7 @@ class MaxWidthBody extends StatelessWidget {
);
return withScrolling
? SingleChildScrollView(
physics: ScrollPhysics(),
physics: const ScrollPhysics(),
child: Padding(
padding: padding,
child: child,

View File

@ -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,

View File

@ -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,
),

View File

@ -19,7 +19,7 @@ class TwoColumnLayout extends StatelessWidget {
children: [
Container(
clipBehavior: Clip.antiAlias,
decoration: BoxDecoration(),
decoration: const BoxDecoration(),
width: 360.0,
child: mainView,
),

View File

@ -27,14 +27,17 @@ class ChatListItem extends StatelessWidget {
final Function onTap;
final Function onLongPress;
const ChatListItem(this.room,
{this.activeChat = false,
const ChatListItem(
this.room, {
this.activeChat = false,
this.selected = false,
this.onTap,
this.onLongPress,
this.onForget});
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,
),

View File

@ -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),

View File

@ -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)),
],
),

View File

@ -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

View File

@ -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 {

View File

@ -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>(

View File

@ -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(

View File

@ -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),
],
);
}),

View File

@ -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,
),

View File

@ -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