diff --git a/js-miniapp-bridge/src/common-bridge.ts b/js-miniapp-bridge/src/common-bridge.ts index c40a373f..c11f11d4 100644 --- a/js-miniapp-bridge/src/common-bridge.ts +++ b/js-miniapp-bridge/src/common-bridge.ts @@ -735,6 +735,22 @@ export class MiniAppBridge { }); } + /** + * Associating miniAppFinishedLoading function to MiniAppBridge object. + * @returns Promise resolve with string + * Host app can implement an interface miniAppFinishedLoading to perform any operations after the miniapp is loaded. + */ + miniAppFinishedLoading() { + return new Promise((resolve, reject) => { + return this.executor.exec( + 'miniAppFinishedLoading', + null, + success => resolve(success), + error => reject(error) + ); + }); + } + /** * This will retrieve the list of products details available for In-App Purchases associated with Mini App in the Platform. * @returns List of In-app purchase products @@ -883,6 +899,23 @@ export class MiniAppBridge { clearMiniAppPreferences() { return this.preferences.clearMiniAppPreferences(); } + + /** + * This interface will get you the list of all features that is supported by the SDK and Host application + * @returns List of features for eg., ["GET_UNIQUE_ID", "GET_USERNAME", "GET_PROFILE_PHOTO", "IS_DARK_MODE"] + */ + getFeatureList() { + return new Promise((resolve, reject) => { + return this.executor.exec( + 'getFeatureList', + null, + response => { + resolve(JSON.parse(response) as string[]); + }, + error => reject(parseMiniAppError(error)) + ); + }); + } } /** diff --git a/js-miniapp-sample/src/App.js b/js-miniapp-sample/src/App.js index 78425825..1bd97e1f 100644 --- a/js-miniapp-sample/src/App.js +++ b/js-miniapp-sample/src/App.js @@ -1,4 +1,4 @@ -import React from 'react'; +import React, { useEffect, useState } from 'react'; import ConsoleView from './pages/console-view'; import { makeStyles, ThemeProvider } from '@material-ui/core'; @@ -7,22 +7,67 @@ import { Provider } from 'react-redux'; import Home from './pages/home'; import store from './services/store'; import Theme from './theme'; +import MiniApp from 'js-miniapp-sdk'; const useStyles = makeStyles((theme) => ({ App: { width: '100%', textAlign: 'center', }, + toastStyle: { + position: 'fixed', + top: '50%', + left: '50%', + transform: 'translate(-50%, -50%)', + padding: '10px', + backgroundColor: '#444', + color: 'white', + borderRadius: '5px', + zIndex: '9999', + textAlign: 'center', + }, })); function App() { const classes = useStyles(); + const [toastVisible, setToastVisible] = useState(false); + + useEffect(() => { + try { + if (document.readyState === 'complete') { + miniAppDidFinishLoad(); + console.log('Called Miniapp FinishedLoad()'); + } + } catch (e) { + console.log(e); + } + }, []); + + function miniAppDidFinishLoad() { + MiniApp.miniappUtils + .miniAppFinishedLoading() + .then((response) => { + console.log('miniAppFinishedLoading(): ', response); + setToastVisible(true); + const timer = setTimeout(() => setToastVisible(false), 5000); + return () => clearTimeout(timer); + }) + .catch((miniAppError) => { + console.log('miniAppFinishedLoading - Error: ', miniAppError); + }); + } + return (
+ {toastVisible && ( +
+ HostApp was notified successfully. +
+ )}
diff --git a/js-miniapp-sample/src/pages/feature-list.js b/js-miniapp-sample/src/pages/feature-list.js new file mode 100644 index 00000000..e6476a48 --- /dev/null +++ b/js-miniapp-sample/src/pages/feature-list.js @@ -0,0 +1,91 @@ +import React, { useEffect, useState } from 'react'; + +import { makeStyles } from '@material-ui/core'; +import MiniApp from 'js-miniapp-sdk'; +import ListItem from '@mui/material/ListItem'; +import ListItemButton from '@mui/material/ListItemButton'; +import ListItemIcon from '@mui/material/ListItemIcon'; +import ListItemText from '@mui/material/ListItemText'; +import Brightness1Icon from '@mui/icons-material/Brightness1'; + +const useStyles = makeStyles((theme) => ({ + content: { + height: '25%', + justifyContent: 'center', + display: 'flex', + flexDirection: 'column', + alignItems: 'center', + fontSize: 18, + color: theme.color.primary, + fontWeight: 'bold', + }, + card: { + marginTop: '40px', + }, + actions: { + justifyContent: 'center', + flexDirection: 'column', + }, + button: { + marginTop: '20px', + width: '80%', + maxWidth: 280, + }, + textfield: { + width: '80%', + maxWidth: 300, + '& input': { + color: theme.color.primary, + lineHeight: '1.5em', + fontSize: '1.2em', + background: 'white', + }, + }, + scrollable: { + overflowY: 'auto', + width: '100%', + paddingBottom: 20, + }, +})); + +function FeatureListComponent() { + const classes = useStyles(); + const [featureList, setFeatureList] = useState(); + useEffect(() => { + try { + getFeatureList(); + } catch (e) { + console.log(e); + } + }); + + function getFeatureList() { + MiniApp.miniappUtils + .getFeatureList() + .then((response) => { + setFeatureList(response); + console.log('getFeatureList SUCCESS: ', response); + }) + .catch((error) => { + console.log('getFeatureList ERROR: ', error); + }); + } + + return ( +
+ {featureList && + featureList.map((item) => ( + + + + + + + + + ))} +
+ ); +} + +export default FeatureListComponent; diff --git a/js-miniapp-sample/src/routes.js b/js-miniapp-sample/src/routes.js index f96a4d54..46a497d2 100644 --- a/js-miniapp-sample/src/routes.js +++ b/js-miniapp-sample/src/routes.js @@ -23,6 +23,7 @@ import ShareIcon from '@material-ui/icons/Share'; import StorageIcon from '@material-ui/icons/Storage'; import VpnKeyIcon from '@material-ui/icons/VpnKey'; import ArtTrackIcon from '@material-ui/icons/ArtTrack'; +import FormatListNumberedIcon from '@material-ui/icons/FormatListNumbered'; import Ads from './pages/ads'; import { CloseConfirmAlert } from './pages/app-close-alert'; @@ -47,6 +48,7 @@ import WebLocation from './pages/web-location'; import WindowActions from './pages/window-actions'; import CookieManagerComponent from './pages/cookie-manager'; import { MiniAppPreferenceComponent } from './pages/miniapp-preferences'; +import FeatureListComponent from './pages/feature-list'; //default root location when using ios const iosHomeNavLink = { navLink: '/index.html', label: 'Home' }; @@ -117,6 +119,10 @@ const miniAppPreferenceNavLink = { navLink: '/miniapp-preference', label: 'MiniApp Preference', }; +const miniFeatureListNavLink = { + navLink: '/miniapp-feature-list', + label: 'Feature List', +}; const navLinks = [ iosHomeNavLink, @@ -145,6 +151,7 @@ const navLinks = [ universalBridgeNavLink, colorThemeNavLink, cookieManagerNavLink, + miniFeatureListNavLink, ]; const homeItem = [ @@ -289,6 +296,12 @@ const appItems = [ navLink: cookieManagerNavLink.navLink, element: , }, + { + icon: , + label: miniFeatureListNavLink.label, + navLink: miniFeatureListNavLink.navLink, + element: , + }, ]; const navItems: Object[] = homeItem.concat( diff --git a/js-miniapp-sdk/CHANGELOG.md b/js-miniapp-sdk/CHANGELOG.md index e52f9f06..be5a71de 100644 --- a/js-miniapp-sdk/CHANGELOG.md +++ b/js-miniapp-sdk/CHANGELOG.md @@ -3,7 +3,9 @@ ### 1.20.0 (2024-xx-xx) - **Feature:** Added new interfaces `set(key: string, value: string)`, `get(key: string)`, `remove(key: string)`, `clearMiniAppPreferences()` which uses the native storage features like Shared Preferences/User defaults to store anything from MiniApp. - **Feature:** Updated HostEnvironmentInfo to have `hostBuildType`, `deviceToken` and `pushToken` +- **Feature:** Added new interface `miniAppFinishedLoading()` which can be used by miniapp to notify the host app that it has finished loading. - **Fix:** Few Contacts with special characters is failed to retrieve, its fixed now +- **Feature:** Added new interface `getFeatureList()` that will return the list if features supported by the Host and MiniApp SDK. ### 1.19.0 (2023-11-02) - **Feature:** Added new interface `getAllCookies()` to get `CookieInfo` which contains `name` and `value` of the cookie diff --git a/js-miniapp-sdk/README.md b/js-miniapp-sdk/README.md index e2b0964a..991130f3 100644 --- a/js-miniapp-sdk/README.md +++ b/js-miniapp-sdk/README.md @@ -144,6 +144,8 @@ Here is the example of manifest. You can also see [it](https://github.com/rakute - [Send Analytics](#send-analytics) - [Get Cookies](#get-cookies) - [MiniApp Storage][#miniapp-storage] +- [MiniApp Finished Loading](#miniapp-finished-loading) +- [Get Feature list][#get-feature-list] ### Retrieve a unique ID @@ -1186,6 +1188,32 @@ import MiniApp from 'js-miniapp-sdk'; MiniApp.miniappUtils.sendAnalytics(analyticsInfo); ``` +
+ +## MiniApp Finished Loading Available from v1.20.0 + +
+
+ +**API:** [Platform.miniAppFinishedLoading](api/interfaces/miniapputilsprovider.html#miniAppFinishedLoading) + +Using the following interface the Miniapp can notify the host app that it has finished loading. + +```javascript +import MiniApp from 'js-miniapp-sdk'; + +MiniApp.miniappUtils + .miniAppFinishedLoading() + .then((response) => { + console.log(response); + }) + .catch((miniAppError) => { + console.log('miniAppFinishedLoading - Error: ', miniAppError); + }); +``` + +
+
## Get Cookies from host application Available from v1.19.0 @@ -1308,6 +1336,29 @@ MiniApp.preferences ``` + +
+ +## Get feature list Available from v1.20.0 + +This interface will help the MiniApps to get the list of features that is supported by the MiniApp native SDK also with the list of other features that is supported by the Host app + +```javascript +import MiniApp from 'js-miniapp-sdk'; + +MiniApp.miniappUtils + .getFeatureList() + .then((response) => { + // Array of strings/features that is supported + // For eg., ["GET_USERNAME", "IS_DARK_MODE", "GET_ALL_COOKIES"] + console.log(response); + }) + .catch((error) => { + console.log(error); + }); + +``` + ## Advanced Usage
diff --git a/js-miniapp-sdk/src/modules/utils.ts b/js-miniapp-sdk/src/modules/utils.ts index d7156935..d345793b 100644 --- a/js-miniapp-sdk/src/modules/utils.ts +++ b/js-miniapp-sdk/src/modules/utils.ts @@ -22,6 +22,12 @@ export interface MiniAppUtilsProvider { */ closeMiniApp(withConfirmation: boolean): Promise; + /** + * Miniapp can notify the host app that it has finished loading using this call. + * Host app can implement this interface to perform any other actions after the miniapp has loaded. + */ + miniAppFinishedLoading(): Promise; + /** * Interface that is used to get the Color theme used in the Host application */ @@ -37,6 +43,11 @@ export interface MiniAppUtilsProvider { * @param analyticsInfo Analytics info */ sendAnalytics(analytics: MAAnalyticsInfo): Promise; + + /** + * Interface to get list of features supported by the SDK and Host + */ + getFeatureList(): Promise; } /** @internal */ @@ -44,6 +55,9 @@ export class MiniAppUtils implements MiniAppUtilsProvider { closeMiniApp(withConfirmation: boolean): Promise { return getBridge().closeMiniApp(withConfirmation); } + miniAppFinishedLoading(): Promise { + return getBridge().miniAppFinishedLoading(); + } setCloseAlert(alertInfo: CloseAlertInfo): Promise { return getBridge().setCloseAlert(alertInfo); } @@ -59,4 +73,7 @@ export class MiniAppUtils implements MiniAppUtilsProvider { } return Promise.reject('sendAnalytics Error'); } + getFeatureList(): Promise { + return getBridge().getFeatureList(); + } } diff --git a/yarn.lock b/yarn.lock index c5e70874..0aafeeb2 100644 --- a/yarn.lock +++ b/yarn.lock @@ -4977,19 +4977,21 @@ es-to-primitive@^1.2.1: is-date-object "^1.0.1" is-symbol "^1.0.2" -es5-ext@^0.10.35, es5-ext@^0.10.46, es5-ext@^0.10.50, es5-ext@~0.10.14: - version "0.10.53" - resolved "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.53.tgz" +es5-ext@^0.10.35, es5-ext@^0.10.46, es5-ext@^0.10.50, es5-ext@^0.10.62, es5-ext@~0.10.14: + version "0.10.63" + resolved "https://registry.yarnpkg.com/es5-ext/-/es5-ext-0.10.63.tgz#9c222a63b6a332ac80b1e373b426af723b895bd6" + integrity sha512-hUCZd2Byj/mNKjfP9jXrdVZ62B8KuA/VoK7X8nUh5qT+AxDmcbvZz041oDVZdbIN1qW6XY9VDNwzkvKnZvK2TQ== dependencies: - es6-iterator "~2.0.3" - es6-symbol "~3.1.3" - next-tick "~1.0.0" + es6-iterator "^2.0.3" + es6-symbol "^3.1.3" + esniff "^2.0.1" + next-tick "^1.1.0" es6-error@^4.0.1: version "4.1.1" resolved "https://registry.npmjs.org/es6-error/-/es6-error-4.1.1.tgz" -es6-iterator@2.0.3, es6-iterator@^2.0.3, es6-iterator@~2.0.1, es6-iterator@~2.0.3: +es6-iterator@2.0.3, es6-iterator@^2.0.3, es6-iterator@~2.0.1: version "2.0.3" resolved "https://registry.npmjs.org/es6-iterator/-/es6-iterator-2.0.3.tgz" dependencies: @@ -5025,7 +5027,7 @@ es6-symbol@3.1.1: d "1" es5-ext "~0.10.14" -es6-symbol@^3.1.1, es6-symbol@~3.1.1, es6-symbol@~3.1.3: +es6-symbol@^3.1.1, es6-symbol@^3.1.3, es6-symbol@~3.1.1: version "3.1.3" resolved "https://registry.npmjs.org/es6-symbol/-/es6-symbol-3.1.3.tgz" dependencies: @@ -5358,6 +5360,16 @@ eslint@^8.29.0: strip-json-comments "^3.1.0" text-table "^0.2.0" +esniff@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/esniff/-/esniff-2.0.1.tgz#a4d4b43a5c71c7ec51c51098c1d8a29081f9b308" + integrity sha512-kTUIGKQ/mDPFoJ0oVfcmyJn4iBDRptjNVIzwIFR7tqWXdVI9xfA2RMwY/gbSpJG3lkdWNEjLap/NqVHZiJsdfg== + dependencies: + d "^1.0.1" + es5-ext "^0.10.62" + event-emitter "^0.3.5" + type "^2.7.2" + espree@^6.1.2: version "6.2.1" resolved "https://registry.npmjs.org/espree/-/espree-6.2.1.tgz" @@ -5440,7 +5452,7 @@ etag@~1.8.1: version "1.8.1" resolved "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz" -event-emitter@~0.3.5: +event-emitter@^0.3.5, event-emitter@~0.3.5: version "0.3.5" resolved "https://registry.npmjs.org/event-emitter/-/event-emitter-0.3.5.tgz" dependencies: @@ -8945,9 +8957,10 @@ neo-async@^2.5.0, neo-async@^2.6.0, neo-async@^2.6.1: version "2.6.2" resolved "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz" -next-tick@~1.0.0: - version "1.0.0" - resolved "https://registry.npmjs.org/next-tick/-/next-tick-1.0.0.tgz" +next-tick@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/next-tick/-/next-tick-1.1.0.tgz#1836ee30ad56d67ef281b22bd199f709449b35eb" + integrity sha512-CXdUiJembsNjuToQvxayPZF9Vqht7hewsvy2sOWafLvi2awflj9mOC6bHIg50orX8IJvWKY9wYQ/zB2kogPslQ== nice-try@^1.0.4: version "1.0.5" @@ -12783,6 +12796,11 @@ type@^2.0.0: version "2.0.0" resolved "https://registry.npmjs.org/type/-/type-2.0.0.tgz" +type@^2.7.2: + version "2.7.2" + resolved "https://registry.yarnpkg.com/type/-/type-2.7.2.tgz#2376a15a3a28b1efa0f5350dcf72d24df6ef98d0" + integrity sha512-dzlvlNlt6AXU7EBSfpAscydQ7gXB+pPGsPnfJnZpiNJBDj7IaJzQlBZYGdEi4R9HmPdBv2XmWJ6YUtoTa7lmCw== + typed-array-length@^1.0.4: version "1.0.4" resolved "https://registry.yarnpkg.com/typed-array-length/-/typed-array-length-1.0.4.tgz#89d83785e5c4098bec72e08b319651f0eac9c1bb"