fix(editor): android bs keyboard provider error (#11647)

### What Changes
- fixed keyboard service can not be initialized since a anonymous `BSKeyboardWithActionService` class was provider to di
- fixed tool panel was not closed when focus on other pragraph by clicking
- optimized code structure of fallback `show` and `hide` of keyboard
This commit is contained in:
L-Sun
2025-04-13 09:59:24 +00:00
parent 076c5ba044
commit e1cb8198f1
5 changed files with 43 additions and 33 deletions
@@ -1,4 +1,5 @@
import { ViewportElementExtension } from '@blocksuite/affine-shared/services';
import { IS_MOBILE } from '@blocksuite/global/env';
import { BlockViewExtension, WidgetViewExtension } from '@blocksuite/std';
import type { ExtensionType } from '@blocksuite/store';
import { literal, unsafeStatic } from 'lit/static-html.js';
@@ -31,7 +32,7 @@ const PageCommonExtension: ExtensionType[] = [
export const PageRootBlockSpec: ExtensionType[] = [
...PageCommonExtension,
BlockViewExtension('affine:page', literal`affine-page-root`),
keyboardToolbarWidget,
IS_MOBILE ? [keyboardToolbarWidget] : [],
PageClipboard,
].flat();
@@ -2,6 +2,7 @@ import { getDocTitleByEditorHost } from '@blocksuite/affine-fragment-doc-title';
import type { RootBlockModel } from '@blocksuite/affine-model';
import {
FeatureFlagService,
isVirtualKeyboardProviderWithAction,
VirtualKeyboardProvider,
type VirtualKeyboardProviderWithAction,
} from '@blocksuite/affine-shared/services';
@@ -34,7 +35,10 @@ export class AffineKeyboardToolbarWidget extends WidgetComponent<RootBlockModel>
private _initialInputMode: string = '';
get keyboard(): VirtualKeyboardProviderWithAction {
get keyboard(): VirtualKeyboardProviderWithAction & { fallback?: boolean } {
const provider = this.std.get(VirtualKeyboardProvider);
if (isVirtualKeyboardProviderWithAction(provider)) return provider;
return {
// fallback keyboard actions
show: () => {
@@ -49,7 +53,7 @@ export class AffineKeyboardToolbarWidget extends WidgetComponent<RootBlockModel>
rootComponent.inputMode = 'none';
}
},
...this.std.get(VirtualKeyboardProvider),
...provider,
};
}
@@ -70,10 +74,6 @@ export class AffineKeyboardToolbarWidget extends WidgetComponent<RootBlockModel>
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;
});
@@ -81,14 +81,20 @@ export class AffineKeyboardToolbarWidget extends WidgetComponent<RootBlockModel>
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.keyboard.fallback) {
this._initialInputMode = rootComponent.inputMode;
this.disposables.add(() => {
rootComponent.inputMode = this._initialInputMode;
});
this.disposables.add(
effect(() => {
// recover input mode when keyboard toolbar is hidden
if (!this._show$.value) {
rootComponent.inputMode = this._initialInputMode;
}
})
);
}
}
if (this._docTitle) {
@@ -55,10 +55,8 @@ export class AffineKeyboardToolbar extends SignalWatcher(
}
private readonly _closeToolPanel = () => {
if (!this.panelOpened) return;
this._currentPanelIndex$.value = -1;
this.keyboard.show();
if (!this.keyboard.visible$.peek()) this.keyboard.show();
};
private readonly _currentPanelIndex$ = signal(-1);
@@ -255,6 +253,16 @@ export class AffineKeyboardToolbar extends SignalWatcher(
})
);
this.disposables.add(
effect(() => {
// sometime the keyboard will auto show when user click into different paragraph in Android,
// so we need to close the tool panel explicitly when the keyboard is visible
if (this.keyboard.visible$.value) {
this._closeToolPanel();
}
})
);
this._watchAutoShow();
}
@@ -15,3 +15,9 @@ export interface VirtualKeyboardProviderWithAction
export const VirtualKeyboardProvider = createIdentifier<
VirtualKeyboardProvider | VirtualKeyboardProviderWithAction
>('VirtualKeyboardProvider');
export function isVirtualKeyboardProviderWithAction(
provider: VirtualKeyboardProvider
): provider is VirtualKeyboardProviderWithAction {
return 'show' in provider && 'hide' in provider;
}
@@ -4,10 +4,7 @@ import {
codeToolbarWidget,
} from '@blocksuite/affine/blocks/code';
import { ParagraphBlockConfigExtension } from '@blocksuite/affine/blocks/paragraph';
import type {
Container,
ServiceIdentifier,
} from '@blocksuite/affine/global/di';
import type { Container } from '@blocksuite/affine/global/di';
import { DisposableGroup } from '@blocksuite/affine/global/disposable';
import {
FeatureFlagService,
@@ -15,11 +12,7 @@ import {
type VirtualKeyboardProviderWithAction,
} from '@blocksuite/affine/shared/services';
import type { SpecBuilder } from '@blocksuite/affine/shared/utils';
import {
type BlockStdScope,
LifeCycleWatcher,
LifeCycleWatcherIdentifier,
} from '@blocksuite/affine/std';
import { type BlockStdScope, LifeCycleWatcher } from '@blocksuite/affine/std';
import type { ExtensionType } from '@blocksuite/affine/store';
import { SlashMenuExtension } from '@blocksuite/affine/widgets/slash-menu';
import { toolbarWidget } from '@blocksuite/affine/widgets/toolbar';
@@ -78,11 +71,7 @@ function KeyboardToolbarExtension(framework: FrameworkProvider): ExtensionType {
static override setup(di: Container) {
super.setup(di);
di.addImpl(BSVirtualKeyboardProvider, provider => {
return provider.get(
LifeCycleWatcherIdentifier(
this.key
) as ServiceIdentifier<BSVirtualKeyboardService>
);
return provider.get(this);
});
}
@@ -103,7 +92,7 @@ function KeyboardToolbarExtension(framework: FrameworkProvider): ExtensionType {
}
if ('show' in affineVirtualKeyboardProvider) {
return class
return class BSVirtualKeyboardWithActionService
extends BSVirtualKeyboardService
implements VirtualKeyboardProviderWithAction
{