fix: use WindowSizeManager to zoom on mobile (#7215)

This commit is contained in:
Morn 2025-01-20 17:54:26 +08:00 committed by GitHub
parent cfe481759f
commit e3ce6e8b4b
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 120 additions and 20 deletions

View File

@ -0,0 +1,48 @@
import 'package:appflowy/generated/locale_keys.g.dart';
import 'package:appflowy/mobile/presentation/home/setting/settings_popup_menu.dart';
import 'package:appflowy/workspace/presentation/home/hotkeys.dart';
import 'package:appflowy/workspace/presentation/widgets/more_view_actions/widgets/font_size_stepper.dart';
import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:integration_test/integration_test.dart';
import '../../shared/util.dart';
void main() {
IntegrationTestWidgetsFlutterBinding.ensureInitialized();
testWidgets('test for change scale factor', (tester) async {
await tester.launchInAnonymousMode();
/// tap [Setting] button
await tester.tapButton(find.byType(HomePageSettingsPopupMenu));
await tester
.tapButton(find.text(LocaleKeys.settings_popupMenuItem_settings.tr()));
/// tap [Font Scale Factor]
await tester.tapButton(
find.text(LocaleKeys.settings_appearance_fontScaleFactor.tr()),
);
/// drag slider
final slider = find.descendant(
of: find.byType(FontSizeStepper),
matching: find.byType(Slider),
);
await tester.slideToValue(slider, 0.8);
expect(appflowyScaleFactor, 0.8);
await tester.slideToValue(slider, 0.9);
expect(appflowyScaleFactor, 0.9);
await tester.slideToValue(slider, 1.0);
expect(appflowyScaleFactor, 1.0);
await tester.slideToValue(slider, 1.1);
expect(appflowyScaleFactor, 1.1);
await tester.slideToValue(slider, 1.2);
expect(appflowyScaleFactor, 1.2);
});
}

View File

@ -13,6 +13,7 @@ import 'package:appflowy/workspace/application/settings/prelude.dart';
import 'package:flowy_infra/uuid.dart';
import 'package:flowy_infra_ui/flowy_infra_ui.dart';
import 'package:flutter/gestures.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:path/path.dart' as p;
@ -235,6 +236,25 @@ extension AppFlowyTestBase on WidgetTester {
Future<void> wait(int milliseconds) async {
await pumpAndSettle(Duration(milliseconds: milliseconds));
}
Future<void> slideToValue(
Finder slider,
double value, {
double paddingOffset = 24.0,
}) async {
final sliderWidget = slider.evaluate().first.widget as Slider;
final range = sliderWidget.max - sliderWidget.min;
final initialRate = (value - sliderWidget.min) / range;
final totalWidth = getSize(slider).width - (2 * paddingOffset);
final zeroPoint = getTopLeft(slider) +
Offset(
paddingOffset + initialRate * totalWidth,
getSize(slider).height / 2,
);
final calculatedOffset = value * (totalWidth / 100);
await dragFrom(zeroPoint, Offset(calculatedOffset, 0));
await pumpAndSettle();
}
}
extension AppFlowyFinderTestBase on CommonFinders {

View File

@ -1,39 +1,55 @@
import 'package:flutter/material.dart';
import 'package:appflowy/generated/locale_keys.g.dart';
import 'package:appflowy/mobile/presentation/bottom_sheet/bottom_sheet.dart';
import 'package:appflowy/workspace/application/settings/appearance/appearance_cubit.dart';
import 'package:appflowy/startup/startup.dart';
import 'package:appflowy/startup/tasks/app_window_size_manager.dart';
import 'package:appflowy/workspace/presentation/home/hotkeys.dart';
import 'package:appflowy/workspace/presentation/widgets/more_view_actions/widgets/font_size_stepper.dart';
import 'package:easy_localization/easy_localization.dart';
import 'package:flowy_infra_ui/flowy_infra_ui.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:flutter/material.dart';
import 'package:scaled_app/scaled_app.dart';
import '../setting.dart';
const int _divisions = 4;
const double _minMobileScaleFactor = 0.8;
const double _maxMobileScaleFactor = 1.2;
class TextScaleSetting extends StatelessWidget {
class TextScaleSetting extends StatefulWidget {
const TextScaleSetting({
super.key,
});
@override
State<TextScaleSetting> createState() => _TextScaleSettingState();
}
class _TextScaleSettingState extends State<TextScaleSetting> {
double scaleFactor = 1.0;
final windowSizeManager = WindowSizeManager();
@override
void initState() {
super.initState();
windowSizeManager.getScaleFactor().then((v) {
if (v != scaleFactor && mounted) {
setState(() {
scaleFactor = v;
});
}
});
}
@override
Widget build(BuildContext context) {
final theme = Theme.of(context);
final textScaleFactor =
context.watch<AppearanceSettingsCubit>().state.textScaleFactor;
return MobileSettingItem(
name: LocaleKeys.settings_appearance_fontScaleFactor.tr(),
trailing: Row(
mainAxisSize: MainAxisSize.min,
children: [
FlowyText(
// map the text scale factor to the 0-1
// 0.8 - 0.0
// 0.9 - 0.5
// 1.0 - 1.0
((_divisions + 1) * textScaleFactor - _divisions)
.toStringAsFixed(2),
scaleFactor.toStringAsFixed(2),
color: theme.colorScheme.onSurface,
),
const Icon(Icons.chevron_right),
@ -48,14 +64,12 @@ class TextScaleSetting extends StatelessWidget {
title: LocaleKeys.settings_appearance_fontScaleFactor.tr(),
builder: (context) {
return FontSizeStepper(
value: textScaleFactor,
minimumValue: 0.8,
maximumValue: 1.0,
value: scaleFactor,
minimumValue: _minMobileScaleFactor,
maximumValue: _maxMobileScaleFactor,
divisions: _divisions,
onChanged: (newTextScaleFactor) {
context
.read<AppearanceSettingsCubit>()
.setTextScaleFactor(newTextScaleFactor);
onChanged: (newScaleFactor) async {
await _setScale(newScaleFactor);
},
);
},
@ -63,4 +77,22 @@ class TextScaleSetting extends StatelessWidget {
},
);
}
Future<void> _setScale(double value) async {
if (FlowyRunner.currentMode == IntegrationMode.integrationTest) {
// The integration test will fail if we check the scale factor in the test.
// #0 ScaledWidgetsFlutterBinding.Eval ()
// #1 ScaledWidgetsFlutterBinding.instance (package:scaled_app/scaled_app.dart:66:62)
// ignore: invalid_use_of_visible_for_testing_member
appflowyScaleFactor = value;
} else {
ScaledWidgetsFlutterBinding.instance.scaleFactor = (_) => value;
}
if (mounted) {
setState(() {
scaleFactor = value;
});
}
await windowSizeManager.setScaleFactor(value);
}
}