mirror of
https://github.com/Yubico/yubioath-flutter.git
synced 2024-12-22 17:51:29 +03:00
Merge branch 'main' into adamve/nfc_activity_widget
This commit is contained in:
commit
b2a183ebfd
2
.github/workflows/env
vendored
2
.github/workflows/env
vendored
@ -1,2 +1,2 @@
|
||||
FLUTTER=3.24.1
|
||||
FLUTTER=3.24.2
|
||||
PYVER=3.12.5
|
||||
|
7
.github/workflows/macos.yml
vendored
7
.github/workflows/macos.yml
vendored
@ -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' || ''}}
|
||||
|
@ -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"])
|
||||
|
@ -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);
|
||||
|
@ -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));
|
||||
}
|
||||
}
|
||||
|
@ -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();
|
||||
|
||||
|
@ -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: [
|
||||
|
@ -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.",
|
||||
|
@ -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.",
|
||||
|
@ -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.",
|
||||
|
@ -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からクリップボードに正常にコピーされました。",
|
||||
|
@ -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.",
|
||||
|
@ -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.",
|
||||
|
@ -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,
|
||||
|
@ -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
|
Loading…
Reference in New Issue
Block a user