mirror of
https://gitlab.com/veilid/veilidchat.git
synced 2025-07-21 13:48:43 -04:00
Accessibility update
This commit is contained in:
parent
be8014c97a
commit
3b1cb53b8a
55 changed files with 1089 additions and 807 deletions
|
@ -2,21 +2,27 @@ import 'package:awesome_extensions/awesome_extensions.dart';
|
|||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_svg/flutter_svg.dart';
|
||||
|
||||
import '../theme/theme.dart';
|
||||
|
||||
class DefaultAppBar extends AppBar {
|
||||
DefaultAppBar(
|
||||
{super.title,
|
||||
{required BuildContext context,
|
||||
super.title,
|
||||
super.flexibleSpace,
|
||||
super.key,
|
||||
Widget? leading,
|
||||
super.actions})
|
||||
: super(
|
||||
toolbarHeight: 40.scaled(context),
|
||||
leadingWidth: 40.scaled(context),
|
||||
leading: leading ??
|
||||
Container(
|
||||
margin: const EdgeInsets.all(4),
|
||||
margin: const EdgeInsets.all(4).scaled(context),
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.black.withAlpha(32),
|
||||
shape: BoxShape.circle),
|
||||
child:
|
||||
SvgPicture.asset('assets/images/vlogo.svg', height: 24)
|
||||
.paddingAll(4)));
|
||||
child: SvgPicture.asset('assets/images/vlogo.svg',
|
||||
width: 24.scaled(context),
|
||||
height: 24.scaled(context))
|
||||
.paddingAll(4.scaled(context))));
|
||||
}
|
||||
|
|
|
@ -95,19 +95,15 @@ class _DrawerMenuState extends State<DrawerMenu> {
|
|||
activeBorder = scale.primary;
|
||||
}
|
||||
|
||||
final avatar = AvatarWidget(
|
||||
final avatar = StyledAvatar(
|
||||
name: name,
|
||||
size: 34,
|
||||
borderColor: border,
|
||||
foregroundColor: loggedIn ? scale.primaryText : scale.subtleText,
|
||||
backgroundColor: loggedIn ? scale.primary : scale.elementBackground,
|
||||
scaleConfig: scaleConfig,
|
||||
textStyle: theme.textTheme.titleLarge!,
|
||||
size: 34.scaled(context),
|
||||
);
|
||||
|
||||
return AnimatedPadding(
|
||||
padding: EdgeInsets.fromLTRB(selected ? 0 : 8, selected ? 0 : 2,
|
||||
selected ? 0 : 8, selected ? 0 : 2),
|
||||
selected ? 0 : 8, selected ? 0 : 2)
|
||||
.scaled(context),
|
||||
duration: const Duration(milliseconds: 50),
|
||||
child: MenuItemWidget(
|
||||
title: name,
|
||||
|
@ -144,7 +140,7 @@ class _DrawerMenuState extends State<DrawerMenu> {
|
|||
(scaleConfig.preferBorders || scaleConfig.useVisualIndicators)
|
||||
? null
|
||||
: activeBorder,
|
||||
minHeight: 48,
|
||||
minHeight: 48.scaled(context),
|
||||
));
|
||||
}
|
||||
|
||||
|
@ -196,7 +192,8 @@ class _DrawerMenuState extends State<DrawerMenu> {
|
|||
color: scaleScheme.errorScale.subtleBorder,
|
||||
borderRadius: 12 * scaleConfig.borderRadiusScale),
|
||||
);
|
||||
loggedInAccounts.add(loggedInAccount.paddingLTRB(0, 0, 0, 8));
|
||||
loggedInAccounts
|
||||
.add(loggedInAccount.paddingLTRB(0, 0, 0, 8.scaled(context)));
|
||||
} else {
|
||||
// Account is not logged in
|
||||
final scale = theme.extension<ScaleScheme>()!.grayScale;
|
||||
|
@ -246,8 +243,8 @@ class _DrawerMenuState extends State<DrawerMenu> {
|
|||
}
|
||||
return IconButton(
|
||||
icon: icon,
|
||||
padding: const EdgeInsets.all(12),
|
||||
color: border,
|
||||
constraints: const BoxConstraints.expand(height: 48, width: 48),
|
||||
style: ButtonStyle(
|
||||
backgroundColor: WidgetStateProperty.resolveWith((states) {
|
||||
if (states.contains(WidgetState.hovered)) {
|
||||
|
@ -286,7 +283,10 @@ class _DrawerMenuState extends State<DrawerMenu> {
|
|||
final scale = scaleScheme.scale(_scaleKind);
|
||||
|
||||
final settingsButton = _getButton(
|
||||
icon: const Icon(Icons.settings),
|
||||
icon: const Icon(
|
||||
Icons.settings,
|
||||
applyTextScaling: true,
|
||||
),
|
||||
tooltip: translate('menu.settings_tooltip'),
|
||||
scale: scale,
|
||||
scaleConfig: scaleConfig,
|
||||
|
@ -295,7 +295,10 @@ class _DrawerMenuState extends State<DrawerMenu> {
|
|||
}).paddingLTRB(0, 0, 16, 0);
|
||||
|
||||
final addButton = _getButton(
|
||||
icon: const Icon(Icons.add),
|
||||
icon: const Icon(
|
||||
Icons.add,
|
||||
applyTextScaling: true,
|
||||
),
|
||||
tooltip: translate('menu.add_account_tooltip'),
|
||||
scale: scale,
|
||||
scaleConfig: scaleConfig,
|
||||
|
@ -364,7 +367,7 @@ class _DrawerMenuState extends State<DrawerMenu> {
|
|||
// : null)
|
||||
// .paddingLTRB(0, 0, 16, 0),
|
||||
GestureDetector(
|
||||
onLongPress: () async {
|
||||
onLongPress: () {
|
||||
context
|
||||
.findAncestorWidgetOfExactType<KeyboardShortcuts>()!
|
||||
.reloadTheme(context);
|
||||
|
|
|
@ -2,6 +2,8 @@ import 'package:awesome_extensions/awesome_extensions.dart';
|
|||
import 'package:flutter/foundation.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
import '../../../theme/views/preferences/preferences.dart';
|
||||
|
||||
class MenuItemWidget extends StatelessWidget {
|
||||
const MenuItemWidget({
|
||||
required this.title,
|
||||
|
@ -81,7 +83,7 @@ class MenuItemWidget extends StatelessWidget {
|
|||
hoverColor: footerButtonIconHoverColor,
|
||||
icon: Icon(
|
||||
footerButtonIcon,
|
||||
size: 24,
|
||||
size: 24.scaled(context),
|
||||
),
|
||||
onPressed: footerCallback),
|
||||
],
|
||||
|
|
|
@ -28,73 +28,81 @@ class _HomeAccountReadyState extends State<HomeAccountReady> {
|
|||
final theme = Theme.of(context);
|
||||
final scale = theme.extension<ScaleScheme>()!;
|
||||
final scaleConfig = theme.extension<ScaleConfig>()!;
|
||||
return IconButton(
|
||||
icon: const Icon(Icons.menu),
|
||||
color: scaleConfig.preferBorders
|
||||
? scale.primaryScale.border
|
||||
: scale.primaryScale.borderText,
|
||||
constraints: const BoxConstraints.expand(height: 40, width: 40),
|
||||
style: ButtonStyle(
|
||||
backgroundColor: WidgetStateProperty.all(
|
||||
scaleConfig.preferBorders
|
||||
? scale.primaryScale.hoverElementBackground
|
||||
: scale.primaryScale.hoverBorder),
|
||||
shape: WidgetStateProperty.all(
|
||||
RoundedRectangleBorder(
|
||||
side: !scaleConfig.useVisualIndicators
|
||||
? BorderSide.none
|
||||
: BorderSide(
|
||||
strokeAlign: BorderSide.strokeAlignCenter,
|
||||
color: scaleConfig.preferBorders
|
||||
? scale.primaryScale.border
|
||||
: scale.primaryScale.borderText,
|
||||
width: 2),
|
||||
borderRadius: BorderRadius.all(
|
||||
Radius.circular(8 * scaleConfig.borderRadiusScale))),
|
||||
)),
|
||||
tooltip: translate('menu.accounts_menu_tooltip'),
|
||||
onPressed: () async {
|
||||
final ctrl = context.read<ZoomDrawerController>();
|
||||
await ctrl.toggle?.call();
|
||||
});
|
||||
return AspectRatio(
|
||||
aspectRatio: 1,
|
||||
child: IconButton(
|
||||
icon: const Icon(
|
||||
Icons.menu,
|
||||
applyTextScaling: true,
|
||||
),
|
||||
color: scaleConfig.preferBorders
|
||||
? scale.primaryScale.border
|
||||
: scale.primaryScale.borderText,
|
||||
style: ButtonStyle(
|
||||
backgroundColor: WidgetStateProperty.all(
|
||||
scaleConfig.preferBorders
|
||||
? scale.primaryScale.hoverElementBackground
|
||||
: scale.primaryScale.hoverBorder),
|
||||
shape: WidgetStateProperty.all(
|
||||
RoundedRectangleBorder(
|
||||
side: !scaleConfig.useVisualIndicators
|
||||
? BorderSide.none
|
||||
: BorderSide(
|
||||
strokeAlign: BorderSide.strokeAlignCenter,
|
||||
color: scaleConfig.preferBorders
|
||||
? scale.primaryScale.border
|
||||
: scale.primaryScale.borderText,
|
||||
width: 2),
|
||||
borderRadius: BorderRadius.all(Radius.circular(
|
||||
8 * scaleConfig.borderRadiusScale))),
|
||||
)),
|
||||
tooltip: translate('menu.accounts_menu_tooltip'),
|
||||
onPressed: () async {
|
||||
final ctrl = context.read<ZoomDrawerController>();
|
||||
await ctrl.toggle?.call();
|
||||
}));
|
||||
});
|
||||
|
||||
Widget buildContactsButton() => Builder(builder: (context) {
|
||||
final theme = Theme.of(context);
|
||||
final scale = theme.extension<ScaleScheme>()!;
|
||||
final scaleConfig = theme.extension<ScaleConfig>()!;
|
||||
return IconButton(
|
||||
icon: const Icon(Icons.contacts),
|
||||
color: scaleConfig.preferBorders
|
||||
? scale.primaryScale.border
|
||||
: scale.primaryScale.borderText,
|
||||
constraints: const BoxConstraints.expand(height: 40, width: 40),
|
||||
style: ButtonStyle(
|
||||
backgroundColor: WidgetStateProperty.all(
|
||||
scaleConfig.preferBorders
|
||||
? scale.primaryScale.hoverElementBackground
|
||||
: scale.primaryScale.hoverBorder),
|
||||
shape: WidgetStateProperty.all(
|
||||
RoundedRectangleBorder(
|
||||
side: !scaleConfig.useVisualIndicators
|
||||
? BorderSide.none
|
||||
: BorderSide(
|
||||
strokeAlign: BorderSide.strokeAlignCenter,
|
||||
color: scaleConfig.preferBorders
|
||||
? scale.primaryScale.border
|
||||
: scale.primaryScale.borderText,
|
||||
width: 2),
|
||||
borderRadius: BorderRadius.all(
|
||||
Radius.circular(8 * scaleConfig.borderRadiusScale))),
|
||||
)),
|
||||
tooltip: translate('menu.contacts_tooltip'),
|
||||
onPressed: () async {
|
||||
await Navigator.of(context).push(
|
||||
MaterialPageRoute<void>(
|
||||
builder: (_) => const ContactsPage(),
|
||||
return AspectRatio(
|
||||
aspectRatio: 1,
|
||||
child: IconButton(
|
||||
icon: const Icon(
|
||||
Icons.contacts,
|
||||
applyTextScaling: true,
|
||||
),
|
||||
);
|
||||
});
|
||||
color: scaleConfig.preferBorders
|
||||
? scale.primaryScale.border
|
||||
: scale.primaryScale.borderText,
|
||||
style: ButtonStyle(
|
||||
backgroundColor: WidgetStateProperty.all(
|
||||
scaleConfig.preferBorders
|
||||
? scale.primaryScale.hoverElementBackground
|
||||
: scale.primaryScale.hoverBorder),
|
||||
shape: WidgetStateProperty.all(
|
||||
RoundedRectangleBorder(
|
||||
side: !scaleConfig.useVisualIndicators
|
||||
? BorderSide.none
|
||||
: BorderSide(
|
||||
strokeAlign: BorderSide.strokeAlignCenter,
|
||||
color: scaleConfig.preferBorders
|
||||
? scale.primaryScale.border
|
||||
: scale.primaryScale.borderText,
|
||||
width: 2),
|
||||
borderRadius: BorderRadius.all(Radius.circular(
|
||||
8 * scaleConfig.borderRadiusScale))),
|
||||
)),
|
||||
tooltip: translate('menu.contacts_tooltip'),
|
||||
onPressed: () async {
|
||||
await Navigator.of(context).push(
|
||||
MaterialPageRoute<void>(
|
||||
builder: (_) => const ContactsPage(),
|
||||
),
|
||||
);
|
||||
}));
|
||||
});
|
||||
|
||||
Widget buildLeftPane(BuildContext context) => Builder(
|
||||
|
@ -112,14 +120,17 @@ class _HomeAccountReadyState extends State<HomeAccountReady> {
|
|||
? scale.primaryScale.subtleBackground
|
||||
: scale.primaryScale.subtleBorder,
|
||||
child: Column(children: <Widget>[
|
||||
Row(children: [
|
||||
buildMenuButton().paddingLTRB(0, 0, 8, 0),
|
||||
ProfileWidget(
|
||||
profile: profile,
|
||||
showPronouns: false,
|
||||
).expanded(),
|
||||
buildContactsButton().paddingLTRB(8, 0, 0, 0),
|
||||
]).paddingAll(8),
|
||||
IntrinsicHeight(
|
||||
child: Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.stretch,
|
||||
children: [
|
||||
buildMenuButton().paddingLTRB(0, 0, 8, 0),
|
||||
ProfileWidget(
|
||||
profile: profile,
|
||||
showPronouns: false,
|
||||
).expanded(),
|
||||
buildContactsButton().paddingLTRB(8, 0, 0, 0),
|
||||
])).paddingAll(8),
|
||||
const ChatListWidget().expanded()
|
||||
]));
|
||||
})));
|
||||
|
|
|
@ -71,8 +71,9 @@ class HomeScreenState extends State<HomeScreen>
|
|||
context: context,
|
||||
title: translate('splash.beta_title'),
|
||||
child: Column(mainAxisAlignment: MainAxisAlignment.center, children: [
|
||||
const Icon(Icons.warning, size: 64),
|
||||
Icon(Icons.warning, size: 64.scaled(context)),
|
||||
RichText(
|
||||
textScaler: MediaQuery.of(context).textScaler,
|
||||
textAlign: TextAlign.center,
|
||||
text: TextSpan(
|
||||
children: <TextSpan>[
|
||||
|
@ -206,34 +207,36 @@ class HomeScreenState extends State<HomeScreen>
|
|||
.indexWhere((x) => x.superIdentity.recordKey == activeLocalAccount);
|
||||
final canClose = activeIndex != -1;
|
||||
|
||||
final drawer = ZoomDrawer(
|
||||
controller: _zoomDrawerController,
|
||||
menuScreen: Builder(builder: (context) {
|
||||
final zoomDrawer = ZoomDrawer.of(context);
|
||||
zoomDrawer!.stateNotifier.addListener(() {
|
||||
if (zoomDrawer.isOpen()) {
|
||||
FocusManager.instance.primaryFocus?.unfocus();
|
||||
}
|
||||
});
|
||||
return const DrawerMenu();
|
||||
}),
|
||||
mainScreen: Provider<ZoomDrawerController>.value(
|
||||
value: _zoomDrawerController,
|
||||
child: Builder(builder: _buildAccountPageView)),
|
||||
borderRadius: 0,
|
||||
angle: 0,
|
||||
openCurve: Curves.fastEaseInToSlowEaseOut,
|
||||
closeCurve: Curves.fastEaseInToSlowEaseOut,
|
||||
menuScreenTapClose: canClose,
|
||||
mainScreenTapClose: canClose,
|
||||
disableDragGesture: !canClose,
|
||||
mainScreenScale: .25,
|
||||
slideWidth: min(360, MediaQuery.of(context).size.width * 0.9),
|
||||
);
|
||||
|
||||
final drawerWithAvoider =
|
||||
isWeb ? drawer : KeyboardAvoider(curve: Curves.ease, child: drawer);
|
||||
|
||||
return DefaultTextStyle(
|
||||
style: theme.textTheme.bodySmall!,
|
||||
child: KeyboardAvoider(
|
||||
curve: Curves.ease,
|
||||
child: ZoomDrawer(
|
||||
controller: _zoomDrawerController,
|
||||
menuScreen: Builder(builder: (context) {
|
||||
final zoomDrawer = ZoomDrawer.of(context);
|
||||
zoomDrawer!.stateNotifier.addListener(() {
|
||||
if (zoomDrawer.isOpen()) {
|
||||
FocusManager.instance.primaryFocus?.unfocus();
|
||||
}
|
||||
});
|
||||
return const DrawerMenu();
|
||||
}),
|
||||
mainScreen: Provider<ZoomDrawerController>.value(
|
||||
value: _zoomDrawerController,
|
||||
child: Builder(builder: _buildAccountPageView)),
|
||||
borderRadius: 0,
|
||||
angle: 0,
|
||||
openCurve: Curves.fastEaseInToSlowEaseOut,
|
||||
closeCurve: Curves.fastEaseInToSlowEaseOut,
|
||||
menuScreenTapClose: canClose,
|
||||
mainScreenTapClose: canClose,
|
||||
disableDragGesture: !canClose,
|
||||
mainScreenScale: .25,
|
||||
slideWidth: min(360, MediaQuery.of(context).size.width * 0.9),
|
||||
)));
|
||||
style: theme.textTheme.bodySmall!, child: drawerWithAvoider);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue