diff --git a/blocksuite/affine/blocks/block-root/src/widgets/keyboard-toolbar/index.ts b/blocksuite/affine/blocks/block-root/src/widgets/keyboard-toolbar/index.ts index 5d9792cf24..bab0abbfc2 100644 --- a/blocksuite/affine/blocks/block-root/src/widgets/keyboard-toolbar/index.ts +++ b/blocksuite/affine/blocks/block-root/src/widgets/keyboard-toolbar/index.ts @@ -1,9 +1,13 @@ import { getDocTitleByEditorHost } from '@blocksuite/affine-fragment-doc-title'; import type { RootBlockModel } from '@blocksuite/affine-model'; -import { FeatureFlagService } from '@blocksuite/affine-shared/services'; +import { + FeatureFlagService, + VirtualKeyboardProvider, + type VirtualKeyboardProviderWithAction, +} from '@blocksuite/affine-shared/services'; import { IS_MOBILE } from '@blocksuite/global/env'; import { WidgetComponent } from '@blocksuite/std'; -import { signal } from '@preact/signals-core'; +import { effect, signal } from '@preact/signals-core'; import { html, nothing } from 'lit'; import type { PageRootBlockComponent } from '../../page/page-root-block.js'; @@ -22,6 +26,7 @@ export class AffineKeyboardToolbarWidget extends WidgetComponent< if (blur) { if (document.activeElement === this._docTitle?.inlineEditorContainer) { this._docTitle?.inlineEditor?.setInlineRange(null); + this._docTitle?.inlineEditor?.eventSource?.blur(); } else if (document.activeElement === this.block?.rootComponent) { this.std.selection.clear(); } @@ -31,6 +36,27 @@ export class AffineKeyboardToolbarWidget extends WidgetComponent< private readonly _show$ = signal(false); + private _initialInputMode: string = ''; + + get keyboard(): VirtualKeyboardProviderWithAction { + return { + // fallback keyboard actions + show: () => { + const rootComponent = this.block?.rootComponent; + if (rootComponent && rootComponent === document.activeElement) { + rootComponent.inputMode = this._initialInputMode; + } + }, + hide: () => { + const rootComponent = this.block?.rootComponent; + if (rootComponent && rootComponent === document.activeElement) { + rootComponent.inputMode = 'none'; + } + }, + ...this.std.get(VirtualKeyboardProvider), + }; + } + private get _docTitle() { return getDocTitleByEditorHost(this.std.host); } @@ -48,12 +74,25 @@ export class AffineKeyboardToolbarWidget extends WidgetComponent< const rootComponent = this.block?.rootComponent; if (rootComponent) { + this._initialInputMode = rootComponent.inputMode; + this.disposables.add(() => { + rootComponent.inputMode = this._initialInputMode; + }); this.disposables.addFromEvent(rootComponent, 'focus', () => { this._show$.value = true; }); this.disposables.addFromEvent(rootComponent, 'blur', () => { this._show$.value = false; }); + + this.disposables.add( + effect(() => { + // recover input mode when keyboard toolbar is hidden + if (!this._show$.value) { + rootComponent.inputMode = this._initialInputMode; + } + }) + ); } if (this._docTitle) { @@ -84,10 +123,11 @@ export class AffineKeyboardToolbarWidget extends WidgetComponent< return html` `} + >`} >`; } } diff --git a/blocksuite/affine/blocks/block-root/src/widgets/keyboard-toolbar/keyboard-toolbar.ts b/blocksuite/affine/blocks/block-root/src/widgets/keyboard-toolbar/keyboard-toolbar.ts index 7c6a876dc0..6f67b0e055 100644 --- a/blocksuite/affine/blocks/block-root/src/widgets/keyboard-toolbar/keyboard-toolbar.ts +++ b/blocksuite/affine/blocks/block-root/src/widgets/keyboard-toolbar/keyboard-toolbar.ts @@ -1,5 +1,5 @@ import { getSelectedModelsCommand } from '@blocksuite/affine-shared/commands'; -import { VirtualKeyboardProvider } from '@blocksuite/affine-shared/services'; +import { type VirtualKeyboardProviderWithAction } from '@blocksuite/affine-shared/services'; import { SignalWatcher, WithDisposable } from '@blocksuite/global/lit'; import { ArrowLeftBigIcon, KeyboardIcon } from '@blocksuite/icons/lit'; import { @@ -50,10 +50,6 @@ export class AffineKeyboardToolbar extends SignalWatcher( return this.rootComponent.std; } - get keyboard() { - return this._context.std.get(VirtualKeyboardProvider); - } - get panelOpened() { return this._currentPanelIndex$.value !== -1; } @@ -324,6 +320,9 @@ export class AffineKeyboardToolbar extends SignalWatcher( `; } + @property({ attribute: false }) + accessor keyboard!: VirtualKeyboardProviderWithAction; + @property({ attribute: false }) accessor close: (blur: boolean) => void = () => {}; diff --git a/blocksuite/affine/blocks/block-root/src/widgets/linked-doc/mobile-linked-doc-menu.ts b/blocksuite/affine/blocks/block-root/src/widgets/linked-doc/mobile-linked-doc-menu.ts index 9ef5fe348c..2ffd5df74a 100644 --- a/blocksuite/affine/blocks/block-root/src/widgets/linked-doc/mobile-linked-doc-menu.ts +++ b/blocksuite/affine/blocks/block-root/src/widgets/linked-doc/mobile-linked-doc-menu.ts @@ -230,9 +230,6 @@ export class AffineMobileLinkedDocMenu extends SignalWatcher( } override firstUpdated() { - if (!this.keyboard.visible$.value) { - this.keyboard.show(); - } this._scrollInputToTop(); } diff --git a/blocksuite/affine/shared/src/services/virtual-keyboard-service.ts b/blocksuite/affine/shared/src/services/virtual-keyboard-service.ts index 57cbe0af0a..c086cad05d 100644 --- a/blocksuite/affine/shared/src/services/virtual-keyboard-service.ts +++ b/blocksuite/affine/shared/src/services/virtual-keyboard-service.ts @@ -2,11 +2,16 @@ import { createIdentifier } from '@blocksuite/global/di'; import type { ReadonlySignal } from '@preact/signals-core'; export interface VirtualKeyboardProvider { - show: () => void; - hide: () => void; readonly visible$: ReadonlySignal; readonly height$: ReadonlySignal; } -export const VirtualKeyboardProvider = - createIdentifier('VirtualKeyboardProvider'); +export interface VirtualKeyboardProviderWithAction + extends VirtualKeyboardProvider { + show: () => void; + hide: () => void; +} + +export const VirtualKeyboardProvider = createIdentifier< + VirtualKeyboardProvider | VirtualKeyboardProviderWithAction +>('VirtualKeyboardProvider'); diff --git a/packages/frontend/apps/ios/src/index.tsx b/packages/frontend/apps/ios/src/index.tsx index 3ee551fada..9b39259655 100644 --- a/packages/frontend/apps/ios/src/index.tsx +++ b/packages/frontend/apps/ios/src/index.tsx @@ -12,9 +12,6 @@ import { NbStoreNativeDBApis } from './plugins/nbstore'; bindNativeDBApis(NbStoreNativeDBApis); -// TODO(@L-Sun) Uncomment this when the `show` method implement by `@capacitor/keyboard` in ios -// import './virtual-keyboard'; - function mountApp() { // oxlint-disable-next-line @typescript-eslint/no-non-null-assertion const root = document.getElementById('app')!; diff --git a/packages/frontend/core/src/blocksuite/extensions/entry/enable-mobile.ts b/packages/frontend/core/src/blocksuite/extensions/entry/enable-mobile.ts index 6b30103ece..7aaacc37dc 100644 --- a/packages/frontend/core/src/blocksuite/extensions/entry/enable-mobile.ts +++ b/packages/frontend/core/src/blocksuite/extensions/entry/enable-mobile.ts @@ -10,9 +10,9 @@ import type { } from '@blocksuite/affine/global/di'; import { DisposableGroup } from '@blocksuite/affine/global/disposable'; import { - DocModeProvider, FeatureFlagService, VirtualKeyboardProvider as BSVirtualKeyboardProvider, + type VirtualKeyboardProviderWithAction, } from '@blocksuite/affine/shared/services'; import type { SpecBuilder } from '@blocksuite/affine/shared/utils'; import { @@ -69,35 +69,12 @@ function KeyboardToolbarExtension(framework: FrameworkProvider): ExtensionType { private readonly _disposables = new DisposableGroup(); - private get _rootContentEditable() { - const editorMode = this.std.get(DocModeProvider).getEditorMode(); - if (editorMode !== 'page') return null; - - if (!this.std.host.doc.root) return; - return this.std.view.getBlock(this.std.host.doc.root.id); - } - // eslint-disable-next-line rxjs/finnish readonly visible$ = signal(false); // eslint-disable-next-line rxjs/finnish readonly height$ = signal(0); - show() { - if ('show' in affineVirtualKeyboardProvider) { - affineVirtualKeyboardProvider.show(); - } else if (this._rootContentEditable) { - this._rootContentEditable.inputMode = ''; - } - } - hide() { - if ('hide' in affineVirtualKeyboardProvider) { - affineVirtualKeyboardProvider.hide(); - } else if (this._rootContentEditable) { - this._rootContentEditable.inputMode = 'none'; - } - } - static override setup(di: Container) { super.setup(di); di.addImpl(BSVirtualKeyboardProvider, provider => { @@ -125,6 +102,20 @@ function KeyboardToolbarExtension(framework: FrameworkProvider): ExtensionType { } } + if ('show' in affineVirtualKeyboardProvider) { + return class + extends BSVirtualKeyboardService + implements VirtualKeyboardProviderWithAction + { + show() { + affineVirtualKeyboardProvider.show(); + } + hide() { + affineVirtualKeyboardProvider.hide(); + } + }; + } + return BSVirtualKeyboardService; }