Improve accessability
This commit is contained in:
@@ -29,10 +29,15 @@
|
|||||||
"profile": {
|
"profile": {
|
||||||
"overviewPageTitle": "Profiles",
|
"overviewPageTitle": "Profiles",
|
||||||
"detailsPageTitle": "Profile",
|
"detailsPageTitle": "Profile",
|
||||||
|
"activeProfileNameSemanticLabel": "Active profile name: ${name}",
|
||||||
|
"nonActiveProfileNameSemanticLabel": "Profile name: ${name}",
|
||||||
|
"activeProfileBtnSemanticLabel": "View all profiles",
|
||||||
|
"nonActiveProfileBtnSemanticLabel": "Select ${name} as active",
|
||||||
"subscription": {
|
"subscription": {
|
||||||
"traffic": "Traffic",
|
"traffic": "Traffic",
|
||||||
"updatedTimeAgo": "Updated ${timeago}",
|
"updatedTimeAgo": "Updated ${timeago}",
|
||||||
"remainingDuration": "${duration} Days Remaining",
|
"remainingDuration": "${duration} Days Remaining",
|
||||||
|
"remainingTrafficSemanticLabel": "${consumed} of ${total} traffic consumed",
|
||||||
"expired": "Expired",
|
"expired": "Expired",
|
||||||
"noTraffic": "No more traffic"
|
"noTraffic": "No more traffic"
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -29,10 +29,15 @@
|
|||||||
"profile": {
|
"profile": {
|
||||||
"overviewPageTitle": "پروفایلها",
|
"overviewPageTitle": "پروفایلها",
|
||||||
"detailsPageTitle": "پروفایل",
|
"detailsPageTitle": "پروفایل",
|
||||||
|
"activeProfileNameSemanticLabel": "نام پروفایل فعال: ${name}",
|
||||||
|
"nonActiveProfileNameSemanticLabel": "نام پروفایل: ${name}",
|
||||||
|
"activeProfileBtnSemanticLabel": "همهی پروفایلها",
|
||||||
|
"nonActiveProfileBtnSemanticLabel": "انتخاب ${name} به عنوان پروفایل فعال",
|
||||||
"subscription": {
|
"subscription": {
|
||||||
"traffic": "ترافیک",
|
"traffic": "ترافیک",
|
||||||
"updatedTimeAgo": "بروزرسانی شده در ${timeago}",
|
"updatedTimeAgo": "بروزرسانی شده در ${timeago}",
|
||||||
"remainingDuration": "${duration} روز باقی مانده",
|
"remainingDuration": "${duration} روز باقی مانده",
|
||||||
|
"remainingTrafficSemanticLabel": "${consumed} از ${total} ترافیک مصرف شده",
|
||||||
"expired": "منقضی شده",
|
"expired": "منقضی شده",
|
||||||
"noTraffic": "پایان ترافیک"
|
"noTraffic": "پایان ترافیک"
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import 'package:flutter_localizations/flutter_localizations.dart';
|
|||||||
import 'package:hiddify/core/core_providers.dart';
|
import 'package:hiddify/core/core_providers.dart';
|
||||||
import 'package:hiddify/core/prefs/prefs.dart';
|
import 'package:hiddify/core/prefs/prefs.dart';
|
||||||
import 'package:hiddify/core/router/router.dart';
|
import 'package:hiddify/core/router/router.dart';
|
||||||
|
import 'package:hiddify/domain/constants.dart';
|
||||||
import 'package:hiddify/features/common/common_controllers.dart';
|
import 'package:hiddify/features/common/common_controllers.dart';
|
||||||
import 'package:hiddify/utils/utils.dart';
|
import 'package:hiddify/utils/utils.dart';
|
||||||
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||||
@@ -20,12 +21,13 @@ class AppView extends HookConsumerWidget with PresLogger {
|
|||||||
ref.watch(commonControllersProvider);
|
ref.watch(commonControllersProvider);
|
||||||
|
|
||||||
return MaterialApp.router(
|
return MaterialApp.router(
|
||||||
builder: (context, child) {
|
// builder: (context, child) {
|
||||||
return AccessibilityTools(
|
// return AccessibilityTools(
|
||||||
checkFontOverflows: true,
|
// checkFontOverflows: true,
|
||||||
child: child,
|
// child: child,
|
||||||
);
|
// );
|
||||||
},
|
// },
|
||||||
|
// showSemanticsDebugger: true,
|
||||||
routerConfig: router,
|
routerConfig: router,
|
||||||
locale: locale,
|
locale: locale,
|
||||||
supportedLocales: AppLocaleUtils.supportedLocales,
|
supportedLocales: AppLocaleUtils.supportedLocales,
|
||||||
@@ -34,7 +36,7 @@ class AppView extends HookConsumerWidget with PresLogger {
|
|||||||
themeMode: theme.mode,
|
themeMode: theme.mode,
|
||||||
theme: theme.light(),
|
theme: theme.light(),
|
||||||
darkTheme: theme.dark(),
|
darkTheme: theme.dark(),
|
||||||
title: 'Hiddify Next',
|
title: Constants.appName,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
abstract class Constants {
|
abstract class Constants {
|
||||||
|
static const appName = "Hiddify Next";
|
||||||
static const geoipFileName = "geoip.db";
|
static const geoipFileName = "geoip.db";
|
||||||
static const geositeFileName = "geosite.db";
|
static const geositeFileName = "geosite.db";
|
||||||
static const configsFolderName = "configs";
|
static const configsFolderName = "configs";
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter/rendering.dart';
|
||||||
import 'package:gap/gap.dart';
|
import 'package:gap/gap.dart';
|
||||||
import 'package:go_router/go_router.dart';
|
import 'package:go_router/go_router.dart';
|
||||||
import 'package:hiddify/core/core_providers.dart';
|
import 'package:hiddify/core/core_providers.dart';
|
||||||
@@ -48,7 +49,6 @@ class ProfileTile extends HookConsumerWidget {
|
|||||||
profile.active ? theme.colorScheme.outlineVariant : Colors.transparent;
|
profile.active ? theme.colorScheme.outlineVariant : Colors.transparent;
|
||||||
|
|
||||||
return Card(
|
return Card(
|
||||||
semanticContainer: false,
|
|
||||||
margin: effectiveMargin,
|
margin: effectiveMargin,
|
||||||
elevation: effectiveElevation,
|
elevation: effectiveElevation,
|
||||||
shape: RoundedRectangleBorder(
|
shape: RoundedRectangleBorder(
|
||||||
@@ -62,7 +62,10 @@ class ProfileTile extends HookConsumerWidget {
|
|||||||
children: [
|
children: [
|
||||||
SizedBox(
|
SizedBox(
|
||||||
width: 48,
|
width: 48,
|
||||||
child: ProfileActionButton(profile, !isMain),
|
child: Semantics(
|
||||||
|
sortKey: const OrdinalSortKey(1),
|
||||||
|
child: ProfileActionButton(profile, !isMain),
|
||||||
|
),
|
||||||
),
|
),
|
||||||
VerticalDivider(
|
VerticalDivider(
|
||||||
width: 1,
|
width: 1,
|
||||||
@@ -71,9 +74,14 @@ class ProfileTile extends HookConsumerWidget {
|
|||||||
Flexible(
|
Flexible(
|
||||||
child: Semantics(
|
child: Semantics(
|
||||||
button: true,
|
button: true,
|
||||||
|
sortKey: isMain ? const OrdinalSortKey(0) : null,
|
||||||
|
focused: isMain,
|
||||||
|
liveRegion: isMain,
|
||||||
|
namesRoute: isMain,
|
||||||
label: isMain
|
label: isMain
|
||||||
? t.profile.overviewPageTitle
|
? t.profile.activeProfileBtnSemanticLabel
|
||||||
: t.profile.edit.selectActiveTxt,
|
: t.profile
|
||||||
|
.nonActiveProfileBtnSemanticLabel(name: profile.name),
|
||||||
child: InkWell(
|
child: InkWell(
|
||||||
onTap: () {
|
onTap: () {
|
||||||
if (isMain) {
|
if (isMain) {
|
||||||
@@ -110,6 +118,10 @@ class ProfileTile extends HookConsumerWidget {
|
|||||||
Flexible(
|
Flexible(
|
||||||
child: Text(
|
child: Text(
|
||||||
profile.name,
|
profile.name,
|
||||||
|
semanticsLabel: t.profile
|
||||||
|
.activeProfileNameSemanticLabel(
|
||||||
|
name: profile.name,
|
||||||
|
),
|
||||||
style: theme.textTheme.titleMedium,
|
style: theme.textTheme.titleMedium,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@@ -121,6 +133,10 @@ class ProfileTile extends HookConsumerWidget {
|
|||||||
else
|
else
|
||||||
Text(
|
Text(
|
||||||
profile.name,
|
profile.name,
|
||||||
|
semanticsLabel:
|
||||||
|
t.profile.nonActiveProfileNameSemanticLabel(
|
||||||
|
name: profile.name,
|
||||||
|
),
|
||||||
style: theme.textTheme.titleMedium,
|
style: theme.textTheme.titleMedium,
|
||||||
),
|
),
|
||||||
if (subInfo != null) ...[
|
if (subInfo != null) ...[
|
||||||
@@ -320,6 +336,11 @@ class ProfileSubscriptionInfo extends HookConsumerWidget {
|
|||||||
subInfo.total > 10 * 1099511627776 //10TB
|
subInfo.total > 10 * 1099511627776 //10TB
|
||||||
? "∞ GiB"
|
? "∞ GiB"
|
||||||
: subInfo.consumption.sizeOf(subInfo.total),
|
: subInfo.consumption.sizeOf(subInfo.total),
|
||||||
|
semanticsLabel:
|
||||||
|
t.profile.subscription.remainingTrafficSemanticLabel(
|
||||||
|
consumed: subInfo.consumption.sizeGB(),
|
||||||
|
total: subInfo.total.sizeGB(),
|
||||||
|
),
|
||||||
style: theme.textTheme.bodySmall,
|
style: theme.textTheme.bodySmall,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ import 'dart:io';
|
|||||||
|
|
||||||
import 'package:hiddify/core/core_providers.dart';
|
import 'package:hiddify/core/core_providers.dart';
|
||||||
import 'package:hiddify/domain/connectivity/connectivity.dart';
|
import 'package:hiddify/domain/connectivity/connectivity.dart';
|
||||||
|
import 'package:hiddify/domain/constants.dart';
|
||||||
import 'package:hiddify/features/common/connectivity/connectivity_controller.dart';
|
import 'package:hiddify/features/common/connectivity/connectivity_controller.dart';
|
||||||
import 'package:hiddify/features/common/window/window_controller.dart';
|
import 'package:hiddify/features/common/window/window_controller.dart';
|
||||||
import 'package:hiddify/gen/assets.gen.dart';
|
import 'package:hiddify/gen/assets.gen.dart';
|
||||||
@@ -22,6 +23,7 @@ class SystemTrayController extends _$SystemTrayController
|
|||||||
_trayIconPath,
|
_trayIconPath,
|
||||||
isTemplate: Platform.isMacOS,
|
isTemplate: Platform.isMacOS,
|
||||||
);
|
);
|
||||||
|
if (!Platform.isLinux) await trayManager.setToolTip(Constants.appName);
|
||||||
trayManager.addListener(this);
|
trayManager.addListener(this);
|
||||||
_initialized = true;
|
_initialized = true;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,6 +6,8 @@ extension ByteFormatter on int {
|
|||||||
static final _sizeOfFormat =
|
static final _sizeOfFormat =
|
||||||
InformationSizeFormat(permissibleValueUnits: {InformationUnit.gibibyte});
|
InformationSizeFormat(permissibleValueUnits: {InformationUnit.gibibyte});
|
||||||
|
|
||||||
|
String sizeGB() => _sizeOfFormat.format(bytes());
|
||||||
|
|
||||||
String sizeOf(int total) =>
|
String sizeOf(int total) =>
|
||||||
"${_sizeOfFormat.format(bytes())} / ${_sizeOfFormat.format(total.bytes())}";
|
"${_sizeOfFormat.format(bytes())} / ${_sizeOfFormat.format(total.bytes())}";
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user