mirror of
https://github.com/toeverything/AFFiNE.git
synced 2026-07-31 09:09:54 +08:00
fix(ios): stabilize keyboard toolbar, image picker, and scrolling (#15182)
## Summary - keep the editor active when iOS keyboard toolbar interactions move focus into range-sync excluded widgets - use the native iOS image picker/source sheet and sync native presentation with the app theme - pin `ListViewKit` to `1.1.6` so the iOS workspace resolves with Xcode 16.3 - restore vertical scrolling in the iOS `WKWebView` by removing the global `contentOffset` reset while preserving zoom prevention ## Test plan - [x] `yarn vitest --run --config \"vitest.config.ts\" --browser.enabled=false \"src/__tests__/inline/active.unit.spec.ts\"` - [x] `LANG=en_US.UTF-8 LC_ALL=en_US.UTF-8 xcodebuild -resolvePackageDependencies -workspace \"packages/frontend/apps/ios/App/App.xcworkspace\" -scheme \"App\"` - [x] `xcodebuild -workspace \"App.xcworkspace\" -scheme \"App\" -destination \"generic/platform=iOS Simulator\" build CODE_SIGNING_ALLOWED=NO ONLY_ACTIVE_ARCH=YES ARCHS=arm64` - [x] Xcode build validation for the updated PR branch
This commit is contained in:
@@ -14,8 +14,14 @@ interface OpenFilePickerOptions {
|
||||
multiple?: boolean | undefined;
|
||||
}
|
||||
|
||||
export type NativeImageFilesPicker = () => Promise<File[] | null>;
|
||||
|
||||
const NATIVE_IMAGE_FILES_PICKER_KEY =
|
||||
'__AFFINE_NATIVE_IMAGE_FILES_PICKER__' as const;
|
||||
|
||||
declare global {
|
||||
interface Window {
|
||||
[NATIVE_IMAGE_FILES_PICKER_KEY]?: NativeImageFilesPicker;
|
||||
// Window API: showOpenFilePicker
|
||||
showOpenFilePicker?: (
|
||||
options?: OpenFilePickerOptions
|
||||
@@ -29,6 +35,17 @@ declare global {
|
||||
}
|
||||
}
|
||||
|
||||
export function registerNativeImageFilesPicker(
|
||||
picker: NativeImageFilesPicker | null
|
||||
) {
|
||||
if (picker) {
|
||||
window[NATIVE_IMAGE_FILES_PICKER_KEY] = picker;
|
||||
return;
|
||||
}
|
||||
|
||||
delete window[NATIVE_IMAGE_FILES_PICKER_KEY];
|
||||
}
|
||||
|
||||
// Minimal polyfill for FileSystemDirectoryHandle to iterate over files
|
||||
interface FileSystemDirectoryHandle {
|
||||
kind: 'directory';
|
||||
@@ -195,7 +212,18 @@ export async function snapshotFile(file: File, relativePath?: string) {
|
||||
}
|
||||
|
||||
export async function snapshotFiles(files: File[]) {
|
||||
return Promise.all(files.map(file => snapshotFile(file)));
|
||||
const results = await Promise.allSettled(
|
||||
files.map(file => snapshotFile(file))
|
||||
);
|
||||
const snapshots: File[] = [];
|
||||
for (const result of results) {
|
||||
if (result.status === 'fulfilled') {
|
||||
snapshots.push(result.value);
|
||||
} else {
|
||||
console.error('Failed to snapshot file', result.reason);
|
||||
}
|
||||
}
|
||||
return snapshots;
|
||||
}
|
||||
|
||||
function canUseFileSystemAccessAPI(
|
||||
@@ -332,7 +360,11 @@ export async function openDirectory(
|
||||
if (fileHandle.getFile) {
|
||||
const file = await fileHandle.getFile();
|
||||
if (options?.snapshot) {
|
||||
files.push(await snapshotFile(file, relativePath));
|
||||
try {
|
||||
files.push(await snapshotFile(file, relativePath));
|
||||
} catch (error) {
|
||||
console.error('Failed to snapshot file', relativePath, error);
|
||||
}
|
||||
} else {
|
||||
Object.defineProperty(file, 'webkitRelativePath', {
|
||||
value: relativePath,
|
||||
@@ -410,6 +442,15 @@ export async function openSingleFileWith(
|
||||
}
|
||||
|
||||
export async function getImageFilesFromLocal() {
|
||||
const nativePicker = window[NATIVE_IMAGE_FILES_PICKER_KEY];
|
||||
if (nativePicker) {
|
||||
try {
|
||||
return (await nativePicker()) ?? [];
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
}
|
||||
}
|
||||
|
||||
const files = await openFilesWith('Images');
|
||||
return files ?? [];
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user