#400 accessibility: apply bold font system setting

This commit is contained in:
Thibault Deckers 2022-11-14 23:11:53 +01:00
parent eaa335919d
commit 126059ee48
4 changed files with 73 additions and 24 deletions

View file

@ -4,6 +4,10 @@ All notable changes to this project will be documented in this file.
## <a id="unreleased"></a>[Unreleased]
### Added
- Accessibility: apply bold font system setting
## <a id="v1.7.4"></a>[v1.7.4] - 2022-11-11
### Added

View file

@ -3,6 +3,7 @@ package deckers.thibault.aves.channel.calls
import android.annotation.SuppressLint
import android.content.Context
import android.content.ContextWrapper
import android.content.res.Configuration
import android.os.Build
import android.provider.Settings
import android.util.Log
@ -19,6 +20,7 @@ class AccessibilityHandler(private val contextWrapper: ContextWrapper) : MethodC
"areAnimationsRemoved" -> safe(call, result, ::areAnimationsRemoved)
"hasRecommendedTimeouts" -> safe(call, result, ::hasRecommendedTimeouts)
"getRecommendedTimeoutMillis" -> safe(call, result, ::getRecommendedTimeoutMillis)
"shouldUseBoldFont" -> safe(call, result, ::shouldUseBoldFont)
else -> result.notImplemented()
}
}
@ -76,8 +78,28 @@ class AccessibilityHandler(private val contextWrapper: ContextWrapper) : MethodC
result.success(millis)
}
// Flutter v3.4 already checks the system `Configuration.fontWeightAdjustment` to update `MediaQuery`
// but we need to also check the non-standard Samsung field `bf` representing the bold font toggle
private fun shouldUseBoldFont(@Suppress("unused_parameter") call: MethodCall, result: MethodChannel.Result) {
var shouldBold = false
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
val config = contextWrapper.resources.configuration
val fontWeightAdjustment = config.fontWeightAdjustment
shouldBold = if (fontWeightAdjustment != Configuration.FONT_WEIGHT_ADJUSTMENT_UNDEFINED && fontWeightAdjustment != 0) {
fontWeightAdjustment >= BOLD_TEXT_WEIGHT_ADJUSTMENT
} else {
// fallback to Samsung non-standard field
Regex(" bf=([01]) ").find(config.toString())?.groups?.get(1)?.value == "1"
}
}
result.success(shouldBold)
}
companion object {
private val LOG_TAG = LogUtils.createTag<AccessibilityHandler>()
const val CHANNEL = "deckers.thibault/aves/accessibility"
// match Flutter way: https://github.com/flutter/engine/blob/main/shell/platform/android/io/flutter/view/AccessibilityBridge.java#L125
const val BOLD_TEXT_WEIGHT_ADJUSTMENT = 300
}
}

View file

@ -4,6 +4,16 @@ import 'package:flutter/services.dart';
class AccessibilityService {
static const _platform = MethodChannel('deckers.thibault/aves/accessibility');
static Future<bool> shouldUseBoldFont() async {
try {
final result = await _platform.invokeMethod('shouldUseBoldFont');
if (result != null) return result as bool;
} on PlatformException catch (e, stack) {
await reportService.recordError(e, stack);
}
return false;
}
static Future<bool> areAnimationsRemoved() async {
try {
final result = await _platform.invokeMethod('areAnimationsRemoved');

View file

@ -108,6 +108,7 @@ class AvesApp extends StatefulWidget {
class _AvesAppState extends State<AvesApp> with WidgetsBindingObserver {
final ValueNotifier<AppMode> appModeNotifier = ValueNotifier(AppMode.main);
late final Future<void> _appSetup;
late final Future<bool> _shouldUseBoldFontLoader;
late final Future<CorePalette?> _dynamicColorPaletteLoader;
final CollectionSource _mediaStoreSource = MediaStoreSource();
final Debouncer _mediaStoreChangeDebouncer = Debouncer(delay: Durations.mediaContentChangeDebounceDelay);
@ -129,6 +130,7 @@ class _AvesAppState extends State<AvesApp> with WidgetsBindingObserver {
_appSetup = _setup();
// remember screen size to use it later, when `context` and `window` are no longer reliable
_screenSize = _getScreenSize();
_shouldUseBoldFontLoader = AccessibilityService.shouldUseBoldFont();
_dynamicColorPaletteLoader = DynamicColorPlugin.getCorePalette();
_mediaStoreChangeChannel.receiveBroadcastStream().listen((event) => _onMediaStoreChange(event as String?));
_newIntentChannel.receiveBroadcastStream().listen((event) => _onNewIntent(event as Map?));
@ -205,6 +207,12 @@ class _AvesAppState extends State<AvesApp> with WidgetsBindingObserver {
lightAccent = Color(tonalPalette?.get(60) ?? defaultAccent.value);
darkAccent = Color(tonalPalette?.get(70) ?? defaultAccent.value);
}
return FutureBuilder<bool>(
future: _shouldUseBoldFontLoader,
builder: (context, snapshot) {
// Flutter v3.4 already checks the system `Configuration.fontWeightAdjustment` to update `MediaQuery`
// but we need to also check the non-standard Samsung field `bf` representing the bold font toggle
final shouldUseBoldFont = snapshot.data ?? false;
return MaterialApp(
navigatorKey: AvesApp.navigatorKey,
home: home,
@ -213,13 +221,16 @@ class _AvesAppState extends State<AvesApp> with WidgetsBindingObserver {
if (initialized) {
WidgetsBinding.instance.addPostFrameCallback((_) => AvesApp.setSystemUIStyle(context));
}
return AvesColorsProvider(
return MediaQuery(
data: MediaQuery.of(context).copyWith(boldText: shouldUseBoldFont),
child: AvesColorsProvider(
child: Theme(
data: Theme.of(context).copyWith(
pageTransitionsTheme: pageTransitionsTheme,
),
child: child!,
),
),
);
},
onGenerateTitle: (context) => context.l10n.appName,
@ -237,6 +248,8 @@ class _AvesAppState extends State<AvesApp> with WidgetsBindingObserver {
},
);
},
);
},
),
),
),