feat(ios): ai button feature flag (#13280)

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

* **New Features**
  * Added a global API to check the AI button feature flag status.

* **Bug Fixes**
* Improved handling for the AI button feature: the app now checks the
feature flag before proceeding and provides a clear error if the feature
is disabled.

* **Refactor**
  * Removed all AI button presentation and dismissal logic from the app.
* Deleted unused plugin interfaces and registration related to the AI
button feature.

* **Chores**
  * Updated project metadata and build configuration for iOS.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
This commit is contained in:
EYHN
2025-07-21 18:07:32 +08:00
committed by GitHub
parent 06eb17387a
commit 43f8d852d8
8 changed files with 27 additions and 31 deletions
@@ -3,7 +3,7 @@
archiveVersion = 1;
classes = {
};
objectVersion = 56;
objectVersion = 77;
objects = {
/* Begin PBXBuildFile section */
@@ -90,8 +90,6 @@
/* Begin PBXFileSystemSynchronizedRootGroup section */
C45499AB2D140B5000E21978 /* NBStore */ = {
isa = PBXFileSystemSynchronizedRootGroup;
exceptions = (
);
path = NBStore;
sourceTree = "<group>";
};
@@ -339,9 +337,13 @@
);
inputFileListPaths = (
);
inputPaths = (
);
name = "[CP] Embed Pods Frameworks";
outputFileListPaths = (
);
outputPaths = (
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-AFFiNE/Pods-AFFiNE-frameworks.sh\"\n";
@@ -17,6 +17,7 @@ enum BridgedWindowScript: String {
case getCurrentServerBaseUrl = "window.getCurrentServerBaseUrl()"
case getCurrentWorkspaceId = "window.getCurrentWorkspaceId();"
case getCurrentDocId = "window.getCurrentDocId();"
case getAiButtonFeatureFlag = "window.getAiButtonFeatureFlag();"
case getCurrentI18nLocale = "window.getCurrentI18nLocale();"
case createNewDocByMarkdownInCurrentWorkspace = "return await window.createNewDocByMarkdownInCurrentWorkspace(markdown, title);"
@@ -17,6 +17,7 @@ extension IntelligentContext {
(.currentWorkspaceId, .getCurrentWorkspaceId),
(.currentServerBaseUrl, .getCurrentServerBaseUrl),
(.currentI18nLocale, .getCurrentI18nLocale),
(.currentAiButtonFeatureFlag, .getAiButtonFeatureFlag),
]
for (key, script) in keysAndScripts {
DispatchQueue.main.async {
@@ -40,6 +40,7 @@ public class IntelligentContext {
case currentWorkspaceId
case currentServerBaseUrl
case currentI18nLocale
case currentAiButtonFeatureFlag
}
@Published public private(set) var currentSession: ChatSessionObject?
@@ -53,6 +54,7 @@ public class IntelligentContext {
public enum IntelligentError: Error, LocalizedError {
case loginRequired(String)
case sessionCreationFailed(String)
case featureClosed
public var errorDescription: String? {
switch self {
@@ -60,6 +62,8 @@ public class IntelligentContext {
"Login required: \(reason)"
case let .sessionCreationFailed(reason):
"Session creation failed: \(reason)"
case let .featureClosed:
"Intelligent feature closed"
}
}
}
@@ -81,6 +85,11 @@ public class IntelligentContext {
}
webViewGroup.wait()
webViewMetadata = webViewMetadataResult
if webViewMetadataResult[.currentAiButtonFeatureFlag] as? Bool == false {
completion(.failure(IntelligentError.featureClosed))
return
}
// Check required webView metadata
guard let baseUrlString = webViewMetadataResult[.currentServerBaseUrl] as? String,
+6 -6
View File
@@ -45,13 +45,13 @@ EXTERNAL SOURCES:
:path: "../../../../../node_modules/capacitor-plugin-app-tracking-transparency"
SPEC CHECKSUMS:
Capacitor: 03bc7cbdde6a629a8b910a9d7d78c3cc7ed09ea7
CapacitorApp: febecbb9582cb353aed037e18ec765141f880fe9
CapacitorBrowser: 6299776d496e968505464884d565992faa20444a
Capacitor: 106e7a4205f4618d582b886a975657c61179138d
CapacitorApp: d63334c052278caf5d81585d80b21905c6f93f39
CapacitorBrowser: 081852cf532acf77b9d2953f3a88fe5b9711fb06
CapacitorCordova: 5967b9ba03915ef1d585469d6e31f31dc49be96f
CapacitorHaptics: 1f1e17041f435d8ead9ff2a34edd592c6aa6a8d6
CapacitorKeyboard: 09fd91dcde4f8a37313e7f11bde553ad1ed52036
CapacitorPluginAppTrackingTransparency: 92ae9c1cfb5cf477753db9269689332a686f675a
CapacitorHaptics: 70e47470fa1a6bd6338cd102552e3846b7f9a1b3
CapacitorKeyboard: 969647d0ca2e5c737d7300088e2517aa832434e2
CapacitorPluginAppTrackingTransparency: 2a2792623a5a72795f2e8f9ab3f1147573732fd8
CryptoSwift: 967f37cea5a3294d9cce358f78861652155be483
PODFILE CHECKSUM: 2c1e4be82121f2d9724ecf7e31dd14e165aeb082
+5 -10
View File
@@ -7,7 +7,6 @@ import { NavigationGestureProvider } from '@affine/core/mobile/modules/navigatio
import { VirtualKeyboardProvider } from '@affine/core/mobile/modules/virtual-keyboard';
import { router } from '@affine/core/mobile/router';
import { configureCommonModules } from '@affine/core/modules';
import { AIButtonProvider } from '@affine/core/modules/ai-button';
import {
AuthProvider,
AuthService,
@@ -18,6 +17,7 @@ import {
ValidatorProvider,
} from '@affine/core/modules/cloud';
import { DocsService } from '@affine/core/modules/doc';
import { FeatureFlagService } from '@affine/core/modules/feature-flag';
import { GlobalContextService } from '@affine/core/modules/global-context';
import { I18nProvider } from '@affine/core/modules/i18n';
import { LifecycleService } from '@affine/core/modules/lifecycle';
@@ -62,7 +62,6 @@ import { BlocksuiteMenuConfigProvider } from './bs-menu-config';
import { ModalConfigProvider } from './modal-config';
import { Auth } from './plugins/auth';
import { Hashcash } from './plugins/hashcash';
import { Intelligents } from './plugins/intelligents';
import { NbStoreNativeDBApis } from './plugins/nbstore';
import { writeEndpointToken } from './proxy';
import { enableNavigationGesture$ } from './web-navigation-control';
@@ -162,14 +161,6 @@ framework.impl(HapticProvider, {
selectionChanged: () => Haptics.selectionChanged(),
selectionEnd: () => Haptics.selectionEnd(),
});
framework.impl(AIButtonProvider, {
presentAIButton: () => {
return Intelligents.presentIntelligentsButton();
},
dismissAIButton: () => {
return Intelligents.dismissIntelligentsButton();
},
});
framework.scope(ServerScope).override(AuthProvider, resolver => {
const serverService = resolver.get(ServerService);
const endpoint = serverService.server.baseUrl;
@@ -224,6 +215,10 @@ const frameworkProvider = framework.provider();
(window as any).getCurrentI18nLocale = () => {
return I18n.language;
};
(window as any).getAiButtonFeatureFlag = () => {
const featureFlagService = frameworkProvider.get(FeatureFlagService);
return featureFlagService.flags.enable_mobile_ai_button.value;
};
(window as any).getCurrentWorkspaceId = () => {
const globalContextService = frameworkProvider.get(GlobalContextService);
return globalContextService.globalContext.workspaceId.get();
@@ -1,4 +0,0 @@
export interface IntelligentsPlugin {
presentIntelligentsButton(): Promise<void>;
dismissIntelligentsButton(): Promise<void>;
}
@@ -1,8 +0,0 @@
import { registerPlugin } from '@capacitor/core';
import type { IntelligentsPlugin } from './definitions';
const Intelligents = registerPlugin<IntelligentsPlugin>('Intelligents');
export * from './definitions';
export { Intelligents };