Skip to content

Commit

Permalink
feat: add numpadSubtract as zoom out keycode (AppFlowy-IO#6380)
Browse files Browse the repository at this point in the history
* feat: add numpadSubtract as zoom out keycode

* test: add zoom in/out and reset zoom refacotr test

* fix: zoom in test assertion

* fix: zoom in/out test

* test: exclude LogicalKeyboardKey.add & LogicalKeyboardKey.numpadSubtract in linux test
  • Loading branch information
LucasXu0 authored Sep 23, 2024
1 parent 2dc7dc1 commit 0d28412
Show file tree
Hide file tree
Showing 4 changed files with 181 additions and 22 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
import 'package:appflowy/startup/tasks/app_window_size_manager.dart';
import 'package:appflowy/workspace/presentation/home/hotkeys.dart';
import 'package:flutter/services.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:hotkey_manager/hotkey_manager.dart';
import 'package:integration_test/integration_test.dart';
import 'package:universal_platform/universal_platform.dart';

import '../../shared/base.dart';
import '../../shared/common_operations.dart';

void main() {
IntegrationTestWidgetsFlutterBinding.ensureInitialized();

group('Zoom in/out: ', () {
Future<void> resetAppFlowyScaleFactor(
WindowSizeManager windowSizeManager,
) async {
appflowyScaleFactor = 1.0;
await windowSizeManager.setScaleFactor(1.0);
}

testWidgets('Zoom in', (tester) async {
await tester.initializeAppFlowy();
await tester.tapAnonymousSignInButton();

double currentScaleFactor = 1.0;

// this value can't be defined in the setUp method, because the windowSizeManager is not initialized yet.
final windowSizeManager = WindowSizeManager();
await resetAppFlowyScaleFactor(windowSizeManager);

// zoom in 2 times
for (final keycode in zoomInKeyCodes) {
if (UniversalPlatform.isLinux &&
keycode.logicalKey == LogicalKeyboardKey.add) {
// Key LogicalKeyboardKey#79c9b(keyId: "0x0000002b", keyLabel: "+", debugName: "Add") not found in
// linux keyCode map
continue;
}

// test each keycode 2 times
for (var i = 0; i < 2; i++) {
await tester.simulateKeyEvent(
keycode.logicalKey,
isControlPressed: !UniversalPlatform.isMacOS,
isMetaPressed: UniversalPlatform.isMacOS,
// Register the physical key for the "Add" key, otherwise the test will fail and throw an error:
// Physical key for LogicalKeyboardKey#79c9b(keyId: "0x0000002b", keyLabel: "+", debugName: "Add")
// not found in known physical keys
physicalKey: keycode.logicalKey == LogicalKeyboardKey.add
? PhysicalKeyboardKey.equal
: null,
);

await tester.pumpAndSettle();

currentScaleFactor += 0.1;

final scaleFactor = await windowSizeManager.getScaleFactor();
expect(currentScaleFactor, appflowyScaleFactor);
expect(currentScaleFactor, scaleFactor);
}
}
});

testWidgets('Reset zoom', (tester) async {
await tester.initializeAppFlowy();
await tester.tapAnonymousSignInButton();

final windowSizeManager = WindowSizeManager();

for (final keycode in resetZoomKeyCodes) {
await tester.simulateKeyEvent(
keycode.logicalKey,
isControlPressed: !UniversalPlatform.isMacOS,
isMetaPressed: UniversalPlatform.isMacOS,
);
await tester.pumpAndSettle();

final scaleFactor = await windowSizeManager.getScaleFactor();
expect(1.0, appflowyScaleFactor);
expect(1.0, scaleFactor);
}
});

testWidgets('Zoom out', (tester) async {
await tester.initializeAppFlowy();
await tester.tapAnonymousSignInButton();

double currentScaleFactor = 1.0;

final windowSizeManager = WindowSizeManager();
await resetAppFlowyScaleFactor(windowSizeManager);

// zoom out 2 times
for (final keycode in zoomOutKeyCodes) {
if (UniversalPlatform.isLinux &&
keycode.logicalKey == LogicalKeyboardKey.numpadSubtract) {
// Key LogicalKeyboardKey#2c39f(keyId: "0x20000022d", keyLabel: "Numpad Subtract", debugName: "Numpad
// Subtract") not found in linux keyCode map
continue;
}
// test each keycode 2 times
for (var i = 0; i < 2; i++) {
await tester.simulateKeyEvent(
keycode.logicalKey,
isControlPressed: !UniversalPlatform.isMacOS,
isMetaPressed: UniversalPlatform.isMacOS,
);
await tester.pumpAndSettle();

currentScaleFactor -= 0.1;

final scaleFactor = await windowSizeManager.getScaleFactor();
expect(currentScaleFactor, appflowyScaleFactor);
expect(currentScaleFactor, scaleFactor);
}
}
});
});
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,12 @@ import 'package:integration_test/integration_test.dart';
import 'desktop/board/board_test_runner.dart' as board_test_runner;
import 'desktop/database/database_row_cover_test.dart'
as database_row_cover_test;
import 'desktop/grid/grid_reopen_test.dart' as grid_reopen_test_runner;
import 'desktop/grid/grid_create_row_test.dart' as grid_create_row_test_runner;
import 'desktop/grid/grid_reorder_row_test.dart'
as grid_reorder_row_test_runner;
import 'desktop/grid/grid_filter_and_sort_test.dart'
as grid_filter_and_sort_test_runner;
import 'desktop/grid/grid_reopen_test.dart' as grid_reopen_test_runner;
import 'desktop/grid/grid_reorder_row_test.dart'
as grid_reorder_row_test_runner;
import 'desktop/settings/settings_runner.dart' as settings_test_runner;
import 'desktop/sidebar/sidebar_test_runner.dart' as sidebar_test_runner;
import 'desktop/uncategorized/emoji_shortcut_test.dart' as emoji_shortcut_test;
Expand All @@ -17,6 +17,7 @@ import 'desktop/uncategorized/hotkeys_test.dart' as hotkeys_test;
import 'desktop/uncategorized/import_files_test.dart' as import_files_test;
import 'desktop/uncategorized/share_markdown_test.dart' as share_markdown_test;
import 'desktop/uncategorized/tabs_test.dart' as tabs_test;
import 'desktop/uncategorized/zoom_in_out_test.dart' as zoom_in_out_test;

Future<void> main() async {
await runIntegration3OnDesktop();
Expand All @@ -43,4 +44,6 @@ Future<void> runIntegration3OnDesktop() async {
grid_create_row_test_runner.main();
grid_reorder_row_test_runner.main();
grid_filter_and_sort_test_runner.main();

zoom_in_out_test.main();
}
Original file line number Diff line number Diff line change
Expand Up @@ -412,6 +412,7 @@ extension CommonOperations on WidgetTester {
bool isShiftPressed = false,
bool isAltPressed = false,
bool isMetaPressed = false,
PhysicalKeyboardKey? physicalKey,
}) async {
if (isControlPressed) {
await simulateKeyDownEvent(LogicalKeyboardKey.control);
Expand All @@ -425,8 +426,14 @@ extension CommonOperations on WidgetTester {
if (isMetaPressed) {
await simulateKeyDownEvent(LogicalKeyboardKey.meta);
}
await simulateKeyDownEvent(key);
await simulateKeyUpEvent(key);
await simulateKeyDownEvent(
key,
physicalKey: physicalKey,
);
await simulateKeyUpEvent(
key,
physicalKey: physicalKey,
);
if (isControlPressed) {
await simulateKeyUpEvent(LogicalKeyboardKey.control);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,17 @@ typedef KeyDownHandler = void Function(HotKey hotKey);
ValueNotifier<int> switchToTheNextSpace = ValueNotifier(0);
ValueNotifier<int> createNewPageNotifier = ValueNotifier(0);

@visibleForTesting
final zoomInKeyCodes = [KeyCode.equal, KeyCode.numpadAdd, KeyCode.add];
@visibleForTesting
final zoomOutKeyCodes = [KeyCode.minus, KeyCode.numpadSubtract];
@visibleForTesting
final resetZoomKeyCodes = [KeyCode.digit0, KeyCode.numpad0];

// Use a global value to store the zoom level and update it in the hotkeys.
@visibleForTesting
double appflowyScaleFactor = 1.0;

/// Helper class that utilizes the global [HotKeyManager] to easily
/// add a [HotKey] with different handlers.
///
Expand Down Expand Up @@ -138,7 +149,7 @@ class _HomeHotKeysState extends State<HomeHotKeys> {

// Scale up/down the app
// In some keyboards, the system returns equal as + keycode, while others may return add as + keycode, so add them both as zoom in key.
...[KeyCode.equal, KeyCode.add].map(
...zoomInKeyCodes.map(
(keycode) => HotKeyItem(
hotKey: HotKey(
keycode,
Expand All @@ -151,23 +162,31 @@ class _HomeHotKeysState extends State<HomeHotKeys> {
),
),

HotKeyItem(
hotKey: HotKey(
KeyCode.minus,
modifiers: [Platform.isMacOS ? KeyModifier.meta : KeyModifier.control],
scope: HotKeyScope.inapp,
...zoomOutKeyCodes.map(
(keycode) => HotKeyItem(
hotKey: HotKey(
keycode,
modifiers: [
Platform.isMacOS ? KeyModifier.meta : KeyModifier.control,
],
scope: HotKeyScope.inapp,
),
keyDownHandler: (_) => _scaleWithStep(-0.1),
),
keyDownHandler: (_) => _scaleWithStep(-0.1),
),

// Reset app scaling
HotKeyItem(
hotKey: HotKey(
KeyCode.digit0,
modifiers: [Platform.isMacOS ? KeyModifier.meta : KeyModifier.control],
scope: HotKeyScope.inapp,
...resetZoomKeyCodes.map(
(keycode) => HotKeyItem(
hotKey: HotKey(
keycode,
modifiers: [
Platform.isMacOS ? KeyModifier.meta : KeyModifier.control,
],
scope: HotKeyScope.inapp,
),
keyDownHandler: (_) => _scale(1),
),
keyDownHandler: (_) => _scaleToSize(1),
),

// Switch to the next space
Expand Down Expand Up @@ -229,11 +248,19 @@ class _HomeHotKeysState extends State<HomeHotKeys> {

Log.info('scale the app from $currentScaleFactor to $textScale');

await _scaleToSize(textScale);
await _scale(textScale);
}

Future<void> _scaleToSize(double size) async {
ScaledWidgetsFlutterBinding.instance.scaleFactor = (_) => size;
await windowSizeManager.setScaleFactor(size);
Future<void> _scale(double scaleFactor) 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)
appflowyScaleFactor = scaleFactor;
} else {
ScaledWidgetsFlutterBinding.instance.scaleFactor = (_) => scaleFactor;
}

await windowSizeManager.setScaleFactor(scaleFactor);
}
}

0 comments on commit 0d28412

Please sign in to comment.