mirror of
https://github.com/toeverything/AFFiNE.git
synced 2026-08-10 21:48:48 +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:
@@ -0,0 +1,79 @@
|
||||
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';
|
||||
|
||||
import {
|
||||
getImageFilesFromLocal,
|
||||
registerNativeImageFilesPicker,
|
||||
} from '../../utils';
|
||||
|
||||
describe('getImageFilesFromLocal', () => {
|
||||
let originalShowPicker: ((this: HTMLInputElement) => void) | undefined;
|
||||
|
||||
beforeEach(() => {
|
||||
originalShowPicker = (
|
||||
HTMLInputElement.prototype as HTMLInputElement & {
|
||||
showPicker?: (this: HTMLInputElement) => void;
|
||||
}
|
||||
).showPicker;
|
||||
|
||||
(
|
||||
HTMLInputElement.prototype as HTMLInputElement & {
|
||||
showPicker?: (this: HTMLInputElement) => void;
|
||||
}
|
||||
).showPicker = vi.fn(function (this: HTMLInputElement) {
|
||||
this.dispatchEvent(new Event('cancel'));
|
||||
});
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
if (originalShowPicker) {
|
||||
(
|
||||
HTMLInputElement.prototype as HTMLInputElement & {
|
||||
showPicker?: (this: HTMLInputElement) => void;
|
||||
}
|
||||
).showPicker = originalShowPicker;
|
||||
} else {
|
||||
delete (
|
||||
HTMLInputElement.prototype as unknown as {
|
||||
showPicker?: unknown;
|
||||
}
|
||||
).showPicker;
|
||||
}
|
||||
|
||||
registerNativeImageFilesPicker(null);
|
||||
vi.restoreAllMocks();
|
||||
});
|
||||
|
||||
it('prefers the registered native image picker when available', async () => {
|
||||
const file = new File(['picked-image'], 'picked.png', {
|
||||
type: 'image/png',
|
||||
lastModified: 123,
|
||||
});
|
||||
const nativePicker = vi.fn(async () => [file]);
|
||||
registerNativeImageFilesPicker(nativePicker);
|
||||
|
||||
const files = await getImageFilesFromLocal();
|
||||
|
||||
expect(nativePicker).toHaveBeenCalledTimes(1);
|
||||
expect(files).toEqual([file]);
|
||||
});
|
||||
|
||||
it('falls back to the standard picker when the native picker rejects', async () => {
|
||||
vi.spyOn(console, 'error').mockImplementation(() => {});
|
||||
const nativePicker = vi.fn(async () => {
|
||||
throw new Error('Native picker failed');
|
||||
});
|
||||
registerNativeImageFilesPicker(nativePicker);
|
||||
|
||||
const files = await getImageFilesFromLocal();
|
||||
|
||||
expect(nativePicker).toHaveBeenCalledTimes(1);
|
||||
expect(files).toEqual([]);
|
||||
expect(
|
||||
(
|
||||
HTMLInputElement.prototype as HTMLInputElement & {
|
||||
showPicker?: (this: HTMLInputElement) => void;
|
||||
}
|
||||
).showPicker
|
||||
).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user