diff --git a/apps/teams-test-app/src/components/OfflineAPIs.tsx b/apps/teams-test-app/src/components/OfflineAPIs.tsx new file mode 100644 index 0000000000..6c3a1957d7 --- /dev/null +++ b/apps/teams-test-app/src/components/OfflineAPIs.tsx @@ -0,0 +1,56 @@ +import { offline, SdkError } from '@microsoft/teams-js'; +import React, { ReactElement } from 'react'; + +import { ApiWithoutInput, ApiWithTextInput } from './utils'; +import { ModuleWrapper } from './utils/ModuleWrapper'; +import { off } from 'process'; + +const CheckOfflineCapability = (): React.ReactElement => + ApiWithoutInput({ + name: 'CheckOfflineCapability', + title: 'Check offline Capability', + onClick: async () => `offline ${offline.isSupported() ? 'is' : 'is not'} supported`, + }); + + const EnableOfflineMode = (): React.ReactElement => + ApiWithTextInput({ + name: 'CheckOfflineCapability', + title: 'CheckOfflineCapability', + onClick: { + validateInput: (input) => { + if (!input.invalidationUrl) { + throw new Error('invalidationurl is needed'); + } + }, + submit: { + withPromise: async (input) => { + await offline.enableOfflineMode(input); + return 'enabled'; + }, + withCallback: (input, setResult) => { + const callback = (error?: SdkError): void => { + if (error) { + setResult(JSON.stringify(error)); + } + }; + offline + .enableOfflineMode(input) + .then() + .catch((error) => callback(error)); + }, + }, + }, + defaultInput: JSON.stringify({ + invalidationUrl: 'https://localhost:4000'}), + }); + + + +const OfflineAPIs = (): ReactElement => ( + + + + +); + +export default OfflineAPIs; \ No newline at end of file diff --git a/apps/teams-test-app/src/pages/TestApp.tsx b/apps/teams-test-app/src/pages/TestApp.tsx index 78ef804a75..94c131e774 100644 --- a/apps/teams-test-app/src/pages/TestApp.tsx +++ b/apps/teams-test-app/src/pages/TestApp.tsx @@ -62,6 +62,7 @@ import Version from '../components/Version'; import VideoAPIs from '../components/VideoEffectsApis'; import VisualMediaAPIs from '../components/VisualMediaAPIs'; import WebStorageAPIs from '../components/WebStorageAPIs'; +import OfflineAPIs from '../components/OfflineAPIs'; export const TestApp: React.FC = () => { const dialogWindowRef = React.useRef(null); @@ -129,6 +130,7 @@ export const TestApp: React.FC = () => { + diff --git a/packages/teams-js/src/internal/telemetry.ts b/packages/teams-js/src/internal/telemetry.ts index d7049ec8d5..557f21b286 100644 --- a/packages/teams-js/src/internal/telemetry.ts +++ b/packages/teams-js/src/internal/telemetry.ts @@ -297,6 +297,7 @@ export const enum ApiName { Sharing_History_GetContent = 'sharing.history.getContent', Sharing_ShareWebContent = 'sharing.shareWebContent', StageView_Open = 'stageView.open', + Offline_enableOfflineMode = 'offline.enableOfflineMode', Tasks_StartTask = 'tasks.startTask', Tasks_SubmitTask = 'tasks.submitTask', Tasks_UpdateTask = 'tasks.updateTask', diff --git a/packages/teams-js/src/public/index.ts b/packages/teams-js/src/public/index.ts index c496cbef71..76a984ac24 100644 --- a/packages/teams-js/src/public/index.ts +++ b/packages/teams-js/src/public/index.ts @@ -75,6 +75,7 @@ export { stageView } from './stageView'; export { version } from './version'; export { visualMedia } from './visualMedia'; export { webStorage } from './webStorage'; +export { offline } from './offline'; export { call } from './call'; export { appInitialization } from './appInitialization'; export { thirdPartyCloudStorage } from './thirdPartyCloudStorage'; diff --git a/packages/teams-js/src/public/offline.ts b/packages/teams-js/src/public/offline.ts new file mode 100644 index 0000000000..b1bfeef105 --- /dev/null +++ b/packages/teams-js/src/public/offline.ts @@ -0,0 +1,55 @@ +import { sendAndHandleSdkError } from '../internal/communication'; +import { ensureInitialized } from '../internal/internalAPIs'; +import { ApiName, ApiVersionNumber, getApiVersionTag } from '../internal/telemetry'; +import { errorNotSupportedOnPlatform } from './constants'; +import { runtime } from './runtime'; + +/** + * Namespace to interact with the offline specific part of the SDK. + * + * @beta + */ +export namespace offline { + /** + * Parameters to enable offline mode. + */ + export interface OfflineModeParams { + /** + * The invalidation URL for the app. + */ + invalidationUrl: string; + } + + /** + * + * Enabled offline mode for the app + * @beta + * @param offlineModeParams - The parameters to pass into the enable offline mode. + * @returns Promise that resolves or rejects with an error once the is closed. + */ + export function enableOfflineMode(offlineModeParams: OfflineModeParams): Promise { + return new Promise((resolve) => { + ensureInitialized(runtime); + + if (!isSupported()) { + throw errorNotSupportedOnPlatform; + } + + if (!offlineModeParams) { + throw new Error('[offline.enableOfflineMode] Offline params cannot be null'); + } + + resolve( + sendAndHandleSdkError( + getApiVersionTag(ApiVersionNumber.V_2, ApiName.Offline_enableOfflineMode), + 'offline.enableOfflineMode', + offlineModeParams, + ), + ); + }); + } + + export function isSupported(): boolean { + return ensureInitialized(runtime) && runtime.supports.offline ? true : false; + } +} diff --git a/packages/teams-js/src/public/runtime.ts b/packages/teams-js/src/public/runtime.ts index 5eb8918197..2f3a8ff383 100644 --- a/packages/teams-js/src/public/runtime.ts +++ b/packages/teams-js/src/public/runtime.ts @@ -78,6 +78,7 @@ interface IRuntimeV1 extends IBaseRuntime { readonly sharedFrame?: {}; }; readonly webStorage?: {}; + readonly offline?: {}; }; } @@ -142,6 +143,7 @@ interface IRuntimeV2 extends IBaseRuntime { readonly sharedFrame?: {}; }; readonly webStorage?: {}; + readonly offline?: {}; }; } @@ -214,6 +216,7 @@ interface IRuntimeV3 extends IBaseRuntime { readonly image?: {}; }; readonly webStorage?: {}; + readonly offline?: {}; }; } @@ -295,6 +298,7 @@ interface IRuntimeV4 extends IBaseRuntime { readonly image?: {}; }; readonly webStorage?: {}; + readonly offline?: {}; }; } // Constant used to set the runtime configuration @@ -370,6 +374,7 @@ export const versionAndPlatformAgnosticTeamsRuntimeConfig: Runtime = { video: { sharedFrame: {}, }, + offline: {}, }, };