Merge branch 'main' into adamve/nfc_activity_widget

This commit is contained in:
Adam Velebil 2024-09-06 13:49:04 +02:00
commit b2a183ebfd
No known key found for this signature in database
GPG Key ID: C9B1E4A3CBBD2E10
15 changed files with 78 additions and 36 deletions

View File

@ -1,2 +1,2 @@
FLUTTER=3.24.1
FLUTTER=3.24.2
PYVER=3.12.5

View File

@ -56,13 +56,6 @@ jobs:
- run: flutter config --enable-macos-desktop
- run: flutter --version
- name: Apply Flutter Patch
run: |
cd $FLUTTER_ROOT
git apply $GITHUB_WORKSPACE/macos_assemble.patch
env:
GITHUB_WORKSPACE: ${{ github.workspace }}
- name: Run lints/tests
env:
SKIP: ${{ steps.cache-helper.outputs.cache-hit == 'true' && 'mypy,flake8,black,bandit' || ''}}

View File

@ -186,8 +186,13 @@ class Ctap2Node(RpcNode):
try:
self.ctap.reset(event=event)
except CtapError as e:
if e.code == CtapError.ERR.USER_ACTION_TIMEOUT:
if e.code in (
# Different keys respond with different errors here
CtapError.ERR.USER_ACTION_TIMEOUT,
CtapError.ERR.ACTION_TIMEOUT,
):
raise InactivityException()
raise
self._info = self.ctap.get_info()
self._token = None
return RpcResponse(dict(), ["device_info"])

View File

@ -132,7 +132,7 @@ class _DialogProvider extends Notifier<int> {
return setNfcView(
NfcContentWidget(
title: l10n.s_nfc_ready_to_scan,
subtitle: l10n.s_nfc_done,
subtitle: l10n.s_done,
icon: const NfcIconSuccess(),
),
showIfHidden: false);

View File

@ -62,7 +62,6 @@ final _navKey = GlobalKey();
final _navExpandedKey = GlobalKey();
final _sliverTitleGlobalKey = GlobalKey();
final _sliverTitleWrapperGlobalKey = GlobalKey();
final _headerSliverGlobalKey = GlobalKey();
final _detailsViewGlobalKey = GlobalKey();
final _mainContentGlobalKey = GlobalKey();
@ -446,16 +445,19 @@ class _AppPageState extends ConsumerState<AppPage> {
targetKey: _sliverTitleGlobalKey,
controller: _sliverTitleController,
subTargetKey:
widget.headerSliver != null ? _headerSliverGlobalKey : null,
widget.headerSliver != null ? headerSliverGlobalKey : null,
subController:
widget.headerSliver != null ? _headerSliverController : null,
subAnchorKey:
widget.headerSliver != null ? _sliverTitleWrapperGlobalKey : null,
child: CustomScrollView(
physics: isAndroid
? const ClampingScrollPhysics(
parent: AlwaysScrollableScrollPhysics())
: null,
? const _NoImplicitScrollPhysics(
parent: ClampingScrollPhysics(
parent: AlwaysScrollableScrollPhysics(),
),
)
: const _NoImplicitScrollPhysics(),
controller: _sliverTitleScrollController,
key: _mainContentGlobalKey,
slivers: [
@ -487,11 +489,11 @@ class _AppPageState extends ConsumerState<AppPage> {
_sliverTitleScrollController,
_headerSliverController.scrollDirection,
_headerSliverController,
_headerSliverGlobalKey,
headerSliverGlobalKey,
_sliverTitleWrapperGlobalKey);
return Container(
key: _headerSliverGlobalKey,
key: headerSliverGlobalKey,
child: widget.headerSliver);
},
))
@ -1041,3 +1043,15 @@ class _SliverTitleDelegate extends SliverPersistentHeaderDelegate {
@override
bool shouldRebuild(_SliverTitleDelegate oldDelegate) => true;
}
class _NoImplicitScrollPhysics extends ScrollPhysics {
const _NoImplicitScrollPhysics({super.parent});
@override
bool get allowImplicitScrolling => false;
@override
_NoImplicitScrollPhysics applyTo(ScrollPhysics? ancestor) {
return _NoImplicitScrollPhysics(parent: buildParent(ancestor));
}
}

View File

@ -18,6 +18,7 @@ import 'package:flutter/material.dart';
// global keys
final scaffoldGlobalKey = GlobalKey<ScaffoldState>();
final headerSliverGlobalKey = GlobalKey();
// This is global so we can access it from the global Ctrl+F shortcut.
final searchField = GlobalKey();

View File

@ -238,7 +238,23 @@ class _FidoUnlockedPageState extends ConsumerState<_FidoUnlockedPage> {
super.dispose();
}
void _scrollSearchField() {
// Ensures the search field is fully visible when in focus
final headerSliverContext = headerSliverGlobalKey.currentContext;
if (searchFocus.hasFocus && headerSliverContext != null) {
final scrollable = Scrollable.of(headerSliverContext);
if (scrollable.deltaToScrollOrigin.dy > 0) {
scrollable.position.animateTo(
0,
duration: const Duration(milliseconds: 100),
curve: Curves.ease,
);
}
}
}
void _onFocusChange() {
_scrollSearchField();
setState(() {});
}
@ -518,6 +534,7 @@ class _FidoUnlockedPageState extends ConsumerState<_FidoUnlockedPage> {
ref
.read(passkeysSearchProvider.notifier)
.setFilter(value);
_scrollSearchField();
setState(() {});
},
textInputAction: TextInputAction.next,
@ -587,7 +604,8 @@ class _FidoUnlockedPageState extends ConsumerState<_FidoUnlockedPage> {
builder: (context, ref, child) {
final layout = ref.watch(passkeysLayoutProvider);
return Padding(
padding: const EdgeInsets.symmetric(horizontal: 10.0),
padding:
const EdgeInsets.only(left: 10.0, right: 10.0, top: 8.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [

View File

@ -38,6 +38,7 @@
"s_calculate": "Berechnen",
"s_import": "Importieren",
"s_overwrite": "Überschreiben",
"s_done": null,
"s_label": "Beschriftung",
"s_name": "Name",
"s_usb": "USB",
@ -898,11 +899,11 @@
"l_launch_app_on_usb_off": "Andere Anwendungen können den YubiKey über USB nutzen",
"s_allow_screenshots": "Bildschirmfotos erlauben",
"@_nfc": {},
"s_nfc_ready_to_scan": null,
"s_nfc_scanning": null,
"s_nfc_tap_your_yubikey": null,
"l_nfc_failed_to_scan": null,
"s_nfc_done": null,
"@_ndef": {},
"p_ndef_set_otp": "OTP-Code wurde erfolgreich von Ihrem YubiKey in die Zwischenablage kopiert.",

View File

@ -38,6 +38,7 @@
"s_calculate": "Calculate",
"s_import": "Import",
"s_overwrite": "Overwrite",
"s_done": "Done",
"s_label": "Label",
"s_name": "Name",
"s_usb": "USB",
@ -898,11 +899,11 @@
"l_launch_app_on_usb_off": "Other apps can use the YubiKey over USB",
"s_allow_screenshots": "Allow screenshots",
"@_nfc": {},
"s_nfc_ready_to_scan": "Ready to scan",
"s_nfc_scanning": "Scanning\u2026",
"s_nfc_tap_your_yubikey": "Tap your YubiKey",
"l_nfc_failed_to_scan": "Failed to scan, try again",
"s_nfc_done": "Done",
"@_ndef": {},
"p_ndef_set_otp": "Successfully copied OTP code from YubiKey to clipboard.",

View File

@ -38,6 +38,7 @@
"s_calculate": "Calculer",
"s_import": "Importer",
"s_overwrite": "Écraser",
"s_done": null,
"s_label": "Étiquette",
"s_name": "Nom",
"s_usb": "USB",
@ -898,11 +899,11 @@
"l_launch_app_on_usb_off": "D'autres applications peuvent utiliser la YubiKey en USB",
"s_allow_screenshots": "Autoriser captures d'écran",
"@_nfc": {},
"s_nfc_ready_to_scan": null,
"s_nfc_scanning": null,
"s_nfc_tap_your_yubikey": null,
"l_nfc_failed_to_scan": null,
"s_nfc_done": null,
"@_ndef": {},
"p_ndef_set_otp": "Code OTP copié de la YubiKey dans le presse-papiers.",

View File

@ -38,6 +38,7 @@
"s_calculate": "計算",
"s_import": "インポート",
"s_overwrite": "上書き",
"s_done": null,
"s_label": "ラベル",
"s_name": "名前",
"s_usb": "USB",
@ -898,11 +899,11 @@
"l_launch_app_on_usb_off": "他のアプリがUSB経由でYubiKeyを使用できます",
"s_allow_screenshots": "スクリーンショットを許可",
"@_nfc": {},
"s_nfc_ready_to_scan": null,
"s_nfc_scanning": null,
"s_nfc_tap_your_yubikey": null,
"l_nfc_failed_to_scan": null,
"s_nfc_done": null,
"@_ndef": {},
"p_ndef_set_otp": "OTPコードがYubiKeyからクリップボードに正常にコピーされました。",

View File

@ -38,6 +38,7 @@
"s_calculate": "Oblicz",
"s_import": "Importuj",
"s_overwrite": "Nadpisz",
"s_done": null,
"s_label": "Etykieta",
"s_name": "Nazwa",
"s_usb": "USB",
@ -898,11 +899,11 @@
"l_launch_app_on_usb_off": "Inne aplikacje mogą korzystać z YubiKey przez USB",
"s_allow_screenshots": "Zezwalaj na zrzuty ekranu",
"@_nfc": {},
"s_nfc_ready_to_scan": null,
"s_nfc_scanning": null,
"s_nfc_tap_your_yubikey": null,
"l_nfc_failed_to_scan": null,
"s_nfc_done": null,
"@_ndef": {},
"p_ndef_set_otp": "OTP zostało skopiowane do schowka.",

View File

@ -38,6 +38,7 @@
"s_calculate": "Tính toán",
"s_import": "Nhập khẩu",
"s_overwrite": "Ghi đè",
"s_done": null,
"s_label": "Nhãn",
"s_name": "Tên",
"s_usb": "USB",
@ -898,11 +899,11 @@
"l_launch_app_on_usb_off": "Các ứng dụng khác có thể sử dụng YubiKey qua USB",
"s_allow_screenshots": "Cho phép chụp ảnh màn hình",
"@_nfc": {},
"s_nfc_ready_to_scan": null,
"s_nfc_scanning": null,
"s_nfc_tap_your_yubikey": null,
"l_nfc_failed_to_scan": null,
"s_nfc_done": null,
"@_ndef": {},
"p_ndef_set_otp": "Đã sao chép mã OTP từ YubiKey vào clipboard.",

View File

@ -154,7 +154,23 @@ class _UnlockedViewState extends ConsumerState<_UnlockedView> {
super.dispose();
}
void _scrollSearchField() {
// Ensures the search field is fully visible when in focus
final headerSliverContext = headerSliverGlobalKey.currentContext;
if (searchFocus.hasFocus && headerSliverContext != null) {
final scrollable = Scrollable.of(headerSliverContext);
if (scrollable.deltaToScrollOrigin.dy > 0) {
scrollable.position.animateTo(
0,
duration: const Duration(milliseconds: 100),
curve: Curves.ease,
);
}
}
}
void _onFocusChange() {
_scrollSearchField();
setState(() {});
}
@ -563,6 +579,7 @@ class _UnlockedViewState extends ConsumerState<_UnlockedView> {
ref
.read(accountsSearchProvider.notifier)
.setFilter(value);
_scrollSearchField();
setState(() {});
},
textInputAction: TextInputAction.next,

View File

@ -1,12 +0,0 @@
diff --git a/packages/flutter_tools/bin/macos_assemble.sh b/packages/flutter_tools/bin/macos_assemble.sh
index 40c6a5051f..a7f05d9113 100755
--- a/packages/flutter_tools/bin/macos_assemble.sh
+++ b/packages/flutter_tools/bin/macos_assemble.sh
@@ -222,6 +222,7 @@ EmbedFrameworks() {
# Iterate through all .frameworks in native assets directory.
for native_asset in "${native_assets_path}"*.framework; do
+ [ -e "$native_asset" ] || continue # Skip when there are no matches.
# Codesign the framework inside the app bundle.
RunCommand codesign --force --verbose --sign "${EXPANDED_CODE_SIGN_IDENTITY}" -- "${xcode_frameworks_dir}/$(basename "$native_asset")"
done