More UI Cleanup

This commit is contained in:
Christien Rioux 2025-05-27 16:43:38 -04:00
parent 3b1cb53b8a
commit 68e8d7fd39
17 changed files with 281 additions and 301 deletions

View file

@ -20,7 +20,6 @@ class ProfileWidget extends StatelessWidget {
// //
@override @override
// ignore: prefer_expression_function_bodies
Widget build(BuildContext context) { Widget build(BuildContext context) {
final theme = Theme.of(context); final theme = Theme.of(context);
final scale = theme.extension<ScaleScheme>()!; final scale = theme.extension<ScaleScheme>()!;
@ -54,7 +53,7 @@ class ProfileWidget extends StatelessWidget {
? scale.primaryScale.border ? scale.primaryScale.border
: scale.primaryScale.borderText), : scale.primaryScale.borderText),
textAlign: TextAlign.left, textAlign: TextAlign.left,
).paddingAll(8), ).paddingAll(8.scaled(context)),
if (_profile.pronouns.isNotEmpty && _showPronouns) if (_profile.pronouns.isNotEmpty && _showPronouns)
Text('(${_profile.pronouns})', Text('(${_profile.pronouns})',
textAlign: TextAlign.right, textAlign: TextAlign.right,
@ -62,7 +61,7 @@ class ProfileWidget extends StatelessWidget {
color: scaleConfig.preferBorders color: scaleConfig.preferBorders
? scale.primaryScale.border ? scale.primaryScale.border
: scale.primaryScale.primary)) : scale.primaryScale.primary))
.paddingAll(8), .paddingAll(8.scaled(context)),
const Spacer() const Spacer()
]), ]),
); );

View file

@ -161,7 +161,7 @@ class _ChatComponentWidgetState extends State<ChatComponentWidget> {
return Column( return Column(
children: [ children: [
Container( Container(
height: 48, height: 40.scaledNoShrink(context),
decoration: BoxDecoration( decoration: BoxDecoration(
color: scale.border, color: scale.border,
), ),
@ -177,7 +177,7 @@ class _ChatComponentWidgetState extends State<ChatComponentWidget> {
)), )),
const Spacer(), const Spacer(),
IconButton( IconButton(
iconSize: 24, iconSize: 24.scaledNoShrink(context),
icon: Icon(Icons.close, color: scale.borderText), icon: Icon(Icons.close, color: scale.borderText),
onPressed: widget._onClose) onPressed: widget._onClose)
.paddingLTRB(0, 0, 8, 0) .paddingLTRB(0, 0, 8, 0)

View file

@ -63,30 +63,34 @@ class ChatListWidget extends StatelessWidget {
title: translate('chat_list.chats'), title: translate('chat_list.chats'),
child: (chatList.isEmpty) child: (chatList.isEmpty)
? const SizedBox.expand(child: EmptyChatListWidget()) ? const SizedBox.expand(child: EmptyChatListWidget())
: SearchableList<proto.Chat>( : TapRegion(
initialList: chatList.map((x) => x.value).toList(), onTapOutside: (_) {
itemBuilder: (c) { FocusScope.of(context).unfocus();
switch (c.whichKind()) {
case proto.Chat_Kind.direct:
return _itemBuilderDirect(
c.direct,
contactMap,
);
case proto.Chat_Kind.group:
return const Text(
'group chats not yet supported!');
case proto.Chat_Kind.notSet:
throw StateError('unknown chat kind');
}
}, },
filter: (value) => child: SearchableList<proto.Chat>(
_itemFilter(contactMap, chatList, value), initialList: chatList.map((x) => x.value).toList(),
searchFieldPadding: itemBuilder: (c) {
const EdgeInsets.fromLTRB(0, 0, 0, 4), switch (c.whichKind()) {
inputDecoration: InputDecoration( case proto.Chat_Kind.direct:
labelText: translate('chat_list.search'), return _itemBuilderDirect(
), c.direct,
).paddingAll(8), contactMap,
);
case proto.Chat_Kind.group:
return const Text(
'group chats not yet supported!');
case proto.Chat_Kind.notSet:
throw StateError('unknown chat kind');
}
},
filter: (value) =>
_itemFilter(contactMap, chatList, value),
searchFieldPadding:
const EdgeInsets.fromLTRB(0, 0, 0, 4),
inputDecoration: InputDecoration(
labelText: translate('chat_list.search'),
),
)).paddingAll(8),
))) )))
.paddingLTRB(8, 0, 8, 8); .paddingLTRB(8, 0, 8, 8);
}); });

View file

@ -5,7 +5,6 @@ import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:flutter_translate/flutter_translate.dart'; import 'package:flutter_translate/flutter_translate.dart';
import 'package:searchable_listview/searchable_listview.dart'; import 'package:searchable_listview/searchable_listview.dart';
import 'package:star_menu/star_menu.dart';
import 'package:veilid_support/veilid_support.dart'; import 'package:veilid_support/veilid_support.dart';
import '../../contact_invitation/contact_invitation.dart'; import '../../contact_invitation/contact_invitation.dart';
@ -90,75 +89,62 @@ class _ContactsBrowserState extends State<ContactsBrowser>
final menuBorderColor = scaleScheme.primaryScale.hoverBorder; final menuBorderColor = scaleScheme.primaryScale.hoverBorder;
final menuParams = StarMenuParameters( PopupMenuEntry<void> makeMenuButton(
shape: MenuShape.linear,
centerOffset: Offset(0, 64.scaled(context)),
boundaryBackground: BoundaryBackground(
color: menuBackgroundColor,
decoration: ShapeDecoration(
color: menuBackgroundColor,
shape: RoundedRectangleBorder(
side: scaleConfig.useVisualIndicators
? BorderSide(
width: 2, color: menuBorderColor, strokeAlign: 0)
: BorderSide.none,
borderRadius: BorderRadius.circular(
8 * scaleConfig.borderRadiusScale)))));
ElevatedButton makeMenuButton(
{required IconData iconData, {required IconData iconData,
required String text, required String text,
required void Function()? onPressed}) => void Function()? onTap}) =>
ElevatedButton.icon( PopupMenuItem(
onPressed: onPressed, onTap: onTap,
icon: Icon( child: DecoratedBox(
iconData, decoration: ShapeDecoration(
size: 32.scaled(context), color: menuBackgroundColor,
).paddingSTEB(0, 8.scaled(context), 0, 8.scaled(context)), shape: RoundedRectangleBorder(
label: Text( side: scaleConfig.useVisualIndicators
text, ? BorderSide(
textScaler: MediaQuery.of(context).textScaler, width: 2,
maxLines: 2, color: menuBorderColor,
textAlign: TextAlign.center, strokeAlign: 0)
).paddingSTEB(0, 8.scaled(context), 0, 8.scaled(context))); : BorderSide.none,
borderRadius: BorderRadius.circular(
8 * scaleConfig.borderRadiusScale))),
child: Row(spacing: 4.scaled(context), children: [
Icon(iconData, size: 32.scaled(context)),
Text(
text,
textScaler: MediaQuery.of(context).textScaler,
maxLines: 2,
textAlign: TextAlign.center,
)
]).paddingAll(4.scaled(context)))
.paddingLTRB(0, 2.scaled(context), 0, 2.scaled(context)));
final inviteMenuItems = [ final inviteMenuItems = [
makeMenuButton( makeMenuButton(
iconData: Icons.paste, iconData: Icons.contact_page,
text: translate('add_contact_sheet.paste_invite'), text: translate('add_contact_sheet.create_invite'),
onPressed: () async { onTap: () async {
_invitationMenuController.closeMenu!(); await CreateInvitationDialog.show(context);
await PasteInvitationDialog.show(context);
}), }),
makeMenuButton( makeMenuButton(
iconData: Icons.qr_code_scanner, iconData: Icons.qr_code_scanner,
text: translate('add_contact_sheet.scan_invite'), text: translate('add_contact_sheet.scan_invite'),
onPressed: () async { onTap: () async {
_invitationMenuController.closeMenu!();
await ScanInvitationDialog.show(context); await ScanInvitationDialog.show(context);
}).paddingLTRB(0, 0, 0, 8.scaled(context)), }),
makeMenuButton( makeMenuButton(
iconData: Icons.contact_page, iconData: Icons.paste,
text: translate('add_contact_sheet.create_invite'), text: translate('add_contact_sheet.paste_invite'),
onPressed: () async { onTap: () async {
_invitationMenuController.closeMenu!(); await PasteInvitationDialog.show(context);
await CreateInvitationDialog.show(context); }),
}).paddingLTRB(0, 0, 0, 8.scaled(context)),
]; ];
return StarMenu( return PopupMenuButton(
items: inviteMenuItems, itemBuilder: (_) => inviteMenuItems,
onItemTapped: (_, controller) { menuPadding: const EdgeInsets.symmetric(vertical: 4).scaled(context),
controller.closeMenu!(); tooltip: translate('add_contact_sheet.add_contact'),
}, child: Icon(
controller: _invitationMenuController, size: 32.scaled(context), Icons.person_add, color: menuIconColor));
params: menuParams,
child: IconButton(
onPressed: () {},
iconSize: 24.scaled(context),
icon: Icon(Icons.person_add, color: menuIconColor),
tooltip: translate('add_contact_sheet.add_contact')),
);
} }
@override @override
@ -253,12 +239,11 @@ class _ContactsBrowserState extends State<ContactsBrowser>
text: translate('contact_list.loading_contacts')) text: translate('contact_list.loading_contacts'))
: const EmptyContactListWidget(), : const EmptyContactListWidget(),
defaultSuffixIconColor: scale.primaryScale.border, defaultSuffixIconColor: scale.primaryScale.border,
closeKeyboardWhenScrolling: true,
searchFieldEnabled: contactList != null, searchFieldEnabled: contactList != null,
inputDecoration: inputDecoration:
InputDecoration(labelText: translate('contact_list.search')), InputDecoration(labelText: translate('contact_list.search')),
secondaryWidget: buildInvitationButton(context) secondaryWidget: buildInvitationButton(context)
.paddingLTRB(4.scaled(context), 0, 0, 0)) .paddingLTRB(8.scaled(context), 0, 0, 0))
.expanded() .expanded()
]); ]);
} }
@ -276,5 +261,4 @@ class _ContactsBrowserState extends State<ContactsBrowser>
} }
//////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////
final _invitationMenuController = StarMenuController();
} }

View file

@ -13,7 +13,7 @@ class DefaultAppBar extends AppBar {
Widget? leading, Widget? leading,
super.actions}) super.actions})
: super( : super(
toolbarHeight: 40.scaled(context), toolbarHeight: 48.scaled(context),
leadingWidth: 40.scaled(context), leadingWidth: 40.scaled(context),
leading: leading ?? leading: leading ??
Container( Container(

View file

@ -31,9 +31,9 @@ class _HomeAccountReadyState extends State<HomeAccountReady> {
return AspectRatio( return AspectRatio(
aspectRatio: 1, aspectRatio: 1,
child: IconButton( child: IconButton(
icon: const Icon( icon: Icon(
size: 32.scaled(context),
Icons.menu, Icons.menu,
applyTextScaling: true,
), ),
color: scaleConfig.preferBorders color: scaleConfig.preferBorders
? scale.primaryScale.border ? scale.primaryScale.border
@ -70,9 +70,9 @@ class _HomeAccountReadyState extends State<HomeAccountReady> {
return AspectRatio( return AspectRatio(
aspectRatio: 1, aspectRatio: 1,
child: IconButton( child: IconButton(
icon: const Icon( icon: Icon(
size: 32.scaled(context),
Icons.contacts, Icons.contacts,
applyTextScaling: true,
), ),
color: scaleConfig.preferBorders color: scaleConfig.preferBorders
? scale.primaryScale.border ? scale.primaryScale.border

View file

@ -5,7 +5,6 @@ import 'package:flutter/gestures.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_translate/flutter_translate.dart'; import 'package:flutter_translate/flutter_translate.dart';
import 'package:flutter_zoom_drawer/flutter_zoom_drawer.dart'; import 'package:flutter_zoom_drawer/flutter_zoom_drawer.dart';
import 'package:keyboard_avoider/keyboard_avoider.dart';
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
import 'package:transitioned_indexed_stack/transitioned_indexed_stack.dart'; import 'package:transitioned_indexed_stack/transitioned_indexed_stack.dart';
import 'package:url_launcher/url_launcher_string.dart'; import 'package:url_launcher/url_launcher_string.dart';
@ -207,36 +206,34 @@ class HomeScreenState extends State<HomeScreen>
.indexWhere((x) => x.superIdentity.recordKey == activeLocalAccount); .indexWhere((x) => x.superIdentity.recordKey == activeLocalAccount);
final canClose = activeIndex != -1; final canClose = activeIndex != -1;
final drawer = ZoomDrawer( final drawer = Scaffold(
controller: _zoomDrawerController, backgroundColor: Colors.transparent,
menuScreen: Builder(builder: (context) { body: ZoomDrawer(
final zoomDrawer = ZoomDrawer.of(context); controller: _zoomDrawerController,
zoomDrawer!.stateNotifier.addListener(() { menuScreen: Builder(builder: (context) {
if (zoomDrawer.isOpen()) { final zoomDrawer = ZoomDrawer.of(context);
FocusManager.instance.primaryFocus?.unfocus(); zoomDrawer!.stateNotifier.addListener(() {
} if (zoomDrawer.isOpen()) {
}); FocusManager.instance.primaryFocus?.unfocus();
return const DrawerMenu(); }
}), });
mainScreen: Provider<ZoomDrawerController>.value( return const DrawerMenu();
value: _zoomDrawerController, }),
child: Builder(builder: _buildAccountPageView)), mainScreen: Provider<ZoomDrawerController>.value(
borderRadius: 0, value: _zoomDrawerController,
angle: 0, child: Builder(builder: _buildAccountPageView)),
openCurve: Curves.fastEaseInToSlowEaseOut, borderRadius: 0,
closeCurve: Curves.fastEaseInToSlowEaseOut, angle: 0,
menuScreenTapClose: canClose, openCurve: Curves.fastEaseInToSlowEaseOut,
mainScreenTapClose: canClose, closeCurve: Curves.fastEaseInToSlowEaseOut,
disableDragGesture: !canClose, menuScreenTapClose: canClose,
mainScreenScale: .25, mainScreenTapClose: canClose,
slideWidth: min(360, MediaQuery.of(context).size.width * 0.9), disableDragGesture: !canClose,
); mainScreenScale: .25,
slideWidth: min(360, MediaQuery.of(context).size.width * 0.9),
));
final drawerWithAvoider = return DefaultTextStyle(style: theme.textTheme.bodySmall!, child: drawer);
isWeb ? drawer : KeyboardAvoider(curve: Curves.ease, child: drawer);
return DefaultTextStyle(
style: theme.textTheme.bodySmall!, child: drawerWithAvoider);
} }
//////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////

View file

@ -69,7 +69,7 @@ Widget buildSettingsPageNotificationPreferences(
softWrap: false, softWrap: false,
style: textTheme.labelMedium, style: textTheme.labelMedium,
textAlign: TextAlign.center, textAlign: TextAlign.center,
))); ).fit(fit: BoxFit.scaleDown)));
} }
return out; return out;
} }
@ -108,170 +108,147 @@ Widget buildSettingsPageNotificationPreferences(
return out; return out;
} }
return InputDecorator( // Invitation accepted
decoration: InputDecoration( Widget notificationSettingsItem(
labelText: translate('settings_page.notifications'), {required String title,
border: OutlineInputBorder( required bool notificationsEnabled,
borderRadius: BorderRadius.circular(8 * scaleConfig.borderRadiusScale), NotificationMode? deliveryValue,
borderSide: BorderSide(width: 2, color: scale.primaryScale.border), SoundEffect? soundValue,
), Future<void> Function(NotificationMode)? onNotificationModeChanged,
), Future<void> Function(SoundEffect)? onSoundChanged}) =>
child: Column(mainAxisSize: MainAxisSize.min, children: [ Column(
// Display Beta Warning crossAxisAlignment: CrossAxisAlignment.start,
StyledCheckbox( spacing: 8.scaled(context),
label: translate('settings_page.display_beta_warning'),
value: notificationsPreference.displayBetaWarning,
onChanged: (value) async {
final newNotificationsPreference =
notificationsPreference.copyWith(displayBetaWarning: value);
await updatePreferences(newNotificationsPreference);
}),
// Enable Badge
StyledCheckbox(
label: translate('settings_page.enable_badge'),
value: notificationsPreference.enableBadge,
onChanged: (value) async {
final newNotificationsPreference =
notificationsPreference.copyWith(enableBadge: value);
await updatePreferences(newNotificationsPreference);
}),
// Enable Notifications
StyledCheckbox(
label: translate('settings_page.enable_notifications'),
value: notificationsPreference.enableNotifications,
onChanged: (value) async {
final newNotificationsPreference =
notificationsPreference.copyWith(enableNotifications: value);
await updatePreferences(newNotificationsPreference);
}),
StyledDropdown<MessageNotificationContent>(
items: messageNotificationContentItems(),
value: notificationsPreference.messageNotificationContent,
decoratorLabel: translate('settings_page.message_notification_content'),
onChanged: !notificationsPreference.enableNotifications
? null
: (value) async {
final newNotificationsPreference = notificationsPreference
.copyWith(messageNotificationContent: value);
await updatePreferences(newNotificationsPreference);
},
).paddingLTRB(0, 4.scaled(context), 0, 4.scaled(context)),
// Notifications
Table(
defaultVerticalAlignment: TableCellVerticalAlignment.middle,
children: [ children: [
TableRow(children: [ Text('$title:', style: textTheme.titleMedium),
Text(translate('settings_page.event'), Wrap(
textAlign: TextAlign.center, spacing: 8.scaled(context), // gap between adjacent chips
style: textTheme.titleMedium!.copyWith( runSpacing: 8.scaled(context), // gap between lines
color: scale.primaryScale.border, children: [
decorationColor: scale.primaryScale.border, if (deliveryValue != null)
decoration: TextDecoration.underline)) IntrinsicWidth(
.paddingAll(8.scaled(context)), child: StyledDropdown<NotificationMode>(
Text(translate('settings_page.delivery'), decoratorLabel: translate('settings_page.delivery'),
textAlign: TextAlign.center, items: notificationModeItems(),
style: textTheme.titleMedium!.copyWith( value: deliveryValue,
color: scale.primaryScale.border, onChanged: !notificationsEnabled
decorationColor: scale.primaryScale.border, ? null
decoration: TextDecoration.underline)) : onNotificationModeChanged,
.paddingAll(8.scaled(context)), )),
Text(translate('settings_page.sound'), if (soundValue != null)
textAlign: TextAlign.center, IntrinsicWidth(
style: textTheme.titleMedium!.copyWith( child: StyledDropdown<SoundEffect>(
color: scale.primaryScale.border, decoratorLabel: translate('settings_page.sound'),
decorationColor: scale.primaryScale.border, items: soundEffectItems(),
decoration: TextDecoration.underline)) value: soundValue,
.paddingAll(8.scaled(context)), onChanged: !notificationsEnabled ? null : onSoundChanged,
]), ))
TableRow(children: [ ])
// Invitation accepted ]).paddingAll(4.scaled(context));
Text(
textAlign: TextAlign.right, return InputDecorator(
translate('settings_page.invitation_accepted')) decoration: InputDecoration(
.paddingAll(4.scaled(context)), labelText: translate('settings_page.notifications'),
StyledDropdown<NotificationMode>( border: OutlineInputBorder(
items: notificationModeItems(), borderRadius:
value: notificationsPreference.onInvitationAcceptedMode, BorderRadius.circular(8 * scaleConfig.borderRadiusScale),
onChanged: !notificationsPreference.enableNotifications borderSide: BorderSide(width: 2, color: scale.primaryScale.border),
? null ),
: (value) async { ),
final newNotificationsPreference = child: Column(
notificationsPreference.copyWith( crossAxisAlignment: CrossAxisAlignment.start,
onInvitationAcceptedMode: value); spacing: 8.scaled(context),
await updatePreferences(newNotificationsPreference); children: [
}, // Display Beta Warning
).paddingAll(4.scaled(context)), StyledCheckbox(
StyledDropdown<SoundEffect>( label: translate('settings_page.display_beta_warning'),
items: soundEffectItems(), value: notificationsPreference.displayBetaWarning,
value: notificationsPreference.onInvitationAcceptedSound, onChanged: (value) async {
onChanged: !notificationsPreference.enableNotifications final newNotificationsPreference = notificationsPreference
? null .copyWith(displayBetaWarning: value);
: (value) async {
final newNotificationsPreference = await updatePreferences(newNotificationsPreference);
notificationsPreference.copyWith( }),
onInvitationAcceptedSound: value); // Enable Badge
await updatePreferences(newNotificationsPreference); StyledCheckbox(
}, label: translate('settings_page.enable_badge'),
).paddingLTRB( value: notificationsPreference.enableBadge,
4.scaled(context), 4.scaled(context), 0, 4.scaled(context)) onChanged: (value) async {
]), final newNotificationsPreference =
notificationsPreference.copyWith(enableBadge: value);
await updatePreferences(newNotificationsPreference);
}),
// Enable Notifications
StyledCheckbox(
label: translate('settings_page.enable_notifications'),
value: notificationsPreference.enableNotifications,
onChanged: (value) async {
final newNotificationsPreference = notificationsPreference
.copyWith(enableNotifications: value);
await updatePreferences(newNotificationsPreference);
}),
StyledDropdown<MessageNotificationContent>(
items: messageNotificationContentItems(),
value: notificationsPreference.messageNotificationContent,
decoratorLabel:
translate('settings_page.message_notification_content'),
onChanged: !notificationsPreference.enableNotifications
? null
: (value) async {
final newNotificationsPreference = notificationsPreference
.copyWith(messageNotificationContent: value);
await updatePreferences(newNotificationsPreference);
},
).paddingAll(4.scaled(context)),
// Notifications
// Invitation accepted
notificationSettingsItem(
title: translate('settings_page.invitation_accepted'),
notificationsEnabled:
notificationsPreference.enableNotifications,
deliveryValue: notificationsPreference.onInvitationAcceptedMode,
soundValue: notificationsPreference.onInvitationAcceptedSound,
onNotificationModeChanged: (value) async {
final newNotificationsPreference = notificationsPreference
.copyWith(onInvitationAcceptedMode: value);
await updatePreferences(newNotificationsPreference);
},
onSoundChanged: (value) async {
final newNotificationsPreference = notificationsPreference
.copyWith(onInvitationAcceptedSound: value);
await updatePreferences(newNotificationsPreference);
}),
// Message received // Message received
TableRow(children: [ notificationSettingsItem(
Text( title: translate('settings_page.message_received'),
textAlign: TextAlign.right, notificationsEnabled:
translate('settings_page.message_received')) notificationsPreference.enableNotifications,
.paddingAll(4.scaled(context)), deliveryValue: notificationsPreference.onMessageReceivedMode,
StyledDropdown<NotificationMode>( soundValue: notificationsPreference.onMessageReceivedSound,
items: notificationModeItems(), onNotificationModeChanged: (value) async {
value: notificationsPreference.onMessageReceivedMode, final newNotificationsPreference = notificationsPreference
onChanged: !notificationsPreference.enableNotifications .copyWith(onMessageReceivedMode: value);
? null await updatePreferences(newNotificationsPreference);
: (value) async { },
final newNotificationsPreference = onSoundChanged: (value) async {
notificationsPreference.copyWith( final newNotificationsPreference = notificationsPreference
onMessageReceivedMode: value); .copyWith(onMessageReceivedSound: value);
await updatePreferences(newNotificationsPreference); await updatePreferences(newNotificationsPreference);
}, }),
).paddingAll(4),
StyledDropdown<SoundEffect>(
items: soundEffectItems(),
value: notificationsPreference.onMessageReceivedSound,
onChanged: !notificationsPreference.enableNotifications
? null
: (value) async {
final newNotificationsPreference =
notificationsPreference.copyWith(
onMessageReceivedSound: value);
await updatePreferences(newNotificationsPreference);
},
).paddingLTRB(
4.scaled(context), 4.scaled(context), 0, 4.scaled(context))
]),
// Message sent // Message sent
TableRow(children: [ notificationSettingsItem(
Text( title: translate('settings_page.message_sent'),
textAlign: TextAlign.right, notificationsEnabled:
translate('settings_page.message_sent')) notificationsPreference.enableNotifications,
.paddingAll(4.scaled(context)), soundValue: notificationsPreference.onMessageSentSound,
const SizedBox.shrink(), onSoundChanged: (value) async {
StyledDropdown<SoundEffect>( final newNotificationsPreference = notificationsPreference
items: soundEffectItems(), .copyWith(onMessageSentSound: value);
value: notificationsPreference.onMessageSentSound, await updatePreferences(newNotificationsPreference);
onChanged: !notificationsPreference.enableNotifications }),
? null ]).paddingAll(4.scaled(context)));
: (value) async {
final newNotificationsPreference =
notificationsPreference.copyWith(
onMessageSentSound: value);
await updatePreferences(newNotificationsPreference);
},
).paddingLTRB(
4.scaled(context), 4.scaled(context), 0, 4.scaled(context))
]),
])
]).paddingAll(8.scaled(context)),
);
} }

View file

@ -23,7 +23,7 @@ class SettingsPage extends StatelessWidget {
title: Text(translate('settings_page.titlebar')), title: Text(translate('settings_page.titlebar')),
leading: IconButton( leading: IconButton(
iconSize: 24.scaled(context), iconSize: 24.scaled(context),
icon: Icon(Icons.arrow_back), icon: const Icon(Icons.arrow_back),
onPressed: () => GoRouterHelper(context).pop(), onPressed: () => GoRouterHelper(context).pop(),
), ),
actions: <Widget>[ actions: <Widget>[
@ -56,7 +56,6 @@ class SettingsPage extends StatelessWidget {
.map((x) => x.paddingLTRB(0, 0, 0, 8.scaled(context))) .map((x) => x.paddingLTRB(0, 0, 0, 8.scaled(context)))
.toList(), .toList(),
).paddingSymmetric(vertical: 4.scaled(context)), ).paddingSymmetric(vertical: 4.scaled(context)),
).paddingSymmetric( ),
horizontal: 8.scaled(context), vertical: 8.scaled(context)),
)); ));
} }

View file

@ -191,6 +191,12 @@ class ScaleTheme extends ThemeExtension<ScaleTheme> {
inputDecorationTheme: inputDecorationTheme:
ScaleInputDecoratorTheme(scheme, config, textTheme), ScaleInputDecoratorTheme(scheme, config, textTheme),
sliderTheme: sliderTheme, sliderTheme: sliderTheme,
popupMenuTheme: PopupMenuThemeData(
color: scheme.primaryScale.subtleBackground,
shadowColor: Colors.transparent,
shape: RoundedRectangleBorder(
borderRadius:
BorderRadius.circular(8 * config.borderRadiusScale))),
extensions: <ThemeExtension<dynamic>>[scheme, config, this]); extensions: <ThemeExtension<dynamic>>[scheme, config, this]);
return themeData; return themeData;

View file

@ -38,6 +38,16 @@ const _scaleNumMult = <double>[
1 + 1 / 1, 1 + 1 / 1,
]; ];
const _scaleNumMultNoShrink = <double>[
1,
1,
1,
1,
1 + 1 / 4,
1 + 1 / 2,
1 + 1 / 1,
];
int displayScaleToIndex(double displayScale) { int displayScaleToIndex(double displayScale) {
final idx = _scales.indexWhere((elem) => elem > displayScale); final idx = _scales.indexWhere((elem) => elem > displayScale);
final currentScaleIdx = idx == -1 ? _scales.length - 1 : max(0, idx - 1); final currentScaleIdx = idx == -1 ? _scales.length - 1 : max(0, idx - 1);
@ -92,6 +102,14 @@ extension DisplayScaledNum on num {
displayScaleToIndex(prefs.themePreference.displayScale); displayScaleToIndex(prefs.themePreference.displayScale);
return this * _scaleNumMult[currentScaleIdx]; return this * _scaleNumMult[currentScaleIdx];
} }
double scaledNoShrink(BuildContext context) {
final prefs = context.watch<PreferencesCubit>().state.asData?.value ??
PreferencesRepository.instance.value;
final currentScaleIdx =
displayScaleToIndex(prefs.themePreference.displayScale);
return this * _scaleNumMultNoShrink[currentScaleIdx];
}
} }
extension DisplayScaledEdgeInsets on EdgeInsets { extension DisplayScaledEdgeInsets on EdgeInsets {

View file

@ -43,7 +43,11 @@ class StyledCheckbox extends StatelessWidget {
await _onChanged(value); await _onChanged(value);
}); });
})), })),
Text(_label, style: textStyle).paddingAll(4.scaled(context)), Text(
_label,
style: textStyle,
overflow: TextOverflow.clip,
).paddingLTRB(4.scaled(context), 0, 0, 0).flexible(),
]); ]);
if (_decoratorLabel != null) { if (_decoratorLabel != null) {

View file

@ -27,7 +27,7 @@ class StyledScaffold extends StatelessWidget {
return GestureDetector( return GestureDetector(
onTap: () => FocusManager.instance.primaryFocus?.unfocus(), onTap: () => FocusManager.instance.primaryFocus?.unfocus(),
child: scaffold /*.paddingAll(enableBorder ? 32 : 0) */); child: scaffold);
} }
//////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////

View file

@ -132,7 +132,7 @@ class StyledSlideTile extends StatelessWidget {
softWrap: false, softWrap: false,
), ),
subtitle: subtitle.isNotEmpty ? Text(subtitle) : null, subtitle: subtitle.isNotEmpty ? Text(subtitle) : null,
contentPadding: const EdgeInsets.fromLTRB(8, 4, 8, 4) contentPadding: const EdgeInsets.fromLTRB(8, 2, 8, 2)
.scaled(context), .scaled(context),
iconColor: scaleTileTheme.textColor, iconColor: scaleTileTheme.textColor,
textColor: scaleTileTheme.textColor, textColor: scaleTileTheme.textColor,

View file

@ -571,6 +571,7 @@ Container clipBorder({
required Color borderColor, required Color borderColor,
required Widget child, required Widget child,
}) => }) =>
// We want to return a container here
// ignore: avoid_unnecessary_containers, use_decorated_box // ignore: avoid_unnecessary_containers, use_decorated_box
Container( Container(
decoration: ShapeDecoration( decoration: ShapeDecoration(

View file

@ -848,14 +848,6 @@ packages:
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "6.9.5" version: "6.9.5"
keyboard_avoider:
dependency: "direct main"
description:
name: keyboard_avoider
sha256: d2917bd52c6612bf8d1ff97f74049ddf3592a81d44e814f0e7b07dcfd245b75c
url: "https://pub.dev"
source: hosted
version: "0.2.0"
lint_hard: lint_hard:
dependency: "direct dev" dependency: "direct dev"
description: description:

View file

@ -56,7 +56,6 @@ dependencies:
image: ^4.5.3 image: ^4.5.3
intl: ^0.19.0 intl: ^0.19.0
json_annotation: ^4.9.0 json_annotation: ^4.9.0
keyboard_avoider: ^0.2.0
loggy: ^2.0.3 loggy: ^2.0.3
meta: ^1.16.0 meta: ^1.16.0
mobile_scanner: ^7.0.0 mobile_scanner: ^7.0.0