Skip to content

Commit 438fa96

Browse files
committed
chore: cleanup
1 parent 98bea2b commit 438fa96

25 files changed

+2629
-45
lines changed

packages/ionic-portals/README.md

Lines changed: 305 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,314 @@
11
# @nativescript/ionic-portals
22

3-
```javascript
3+
## Contents
4+
5+
* [Intro](#intro)
6+
* [Installation](#installation)
7+
* [Enable Ionic Portals in your app](#enable-ionic-portals-in-your-app)
8+
* [Get a Portal API Key](#1-get-a-portal-api-key)
9+
* [Register portals on app boot](#2-register-portals)
10+
* [Add portals view to markup](#3-add-portals-view-to-markup)
11+
* [Core](#core)
12+
* [Angular](#angular)
13+
* [Vue](#vue)
14+
* [Svelte](#svelte)
15+
* [Send events from NativeScript to any web portal](#send-events-from-nativescript-to-any-web-portal)
16+
* [Subscribe to events sent from web portals](#subscribe-to-events-sent-from-web-portals)
17+
* [Unsubscribe to events sent from web portals](#unsubscribe-from-events-sent-from-web-portals)
18+
* [IonicPortalManager API](#ionicportalmanager-api)
19+
* [register()](#register)
20+
* [setInitialContext()](#setinitialcontext)
21+
* [sendAndroidPlugins](#setandroidplugins)
22+
* [publishTopic()](#publishtopic)
23+
* [subscribeToTopic()](#subscribetotopic)
24+
* [unsubscribeFromTopic()](#unsubscribefromtopic)
25+
* [configureLiveUpdates()](#configureliveupdates)
26+
* [syncNow()](#syncnow)
27+
* [getLastSync()](#getlastsync)
28+
* [Using Capacitor Plugins with Ionic Portals](#using-capacitor-plugins-with-ionic-portals)
29+
* [Notes](#notes)
30+
* [Additional Resources](#additional-resources)
31+
* [License](#license)
32+
33+
## Intro
34+
35+
A plugin that allows you to use [Ionic Portals](https://ionic.io/docs/portals) in NativeScript.
36+
37+
> Ionic Portals are supercharged native WebView components for iOS and Android that let you add web-based experiences to native mobile apps.
38+
39+
![Ionic Portal View](/packages/ionic-portals/images/ionic-portal-ios.png)
40+
41+
## Installation
42+
43+
To install the plugin, run the following command from the root of your project:
44+
45+
```cli
446
npm install @nativescript/ionic-portals
547
```
648

7-
## Usage
49+
## Enable Ionic portals in your app
50+
51+
Below are the steps to enable Ionic Portal in your app.
52+
53+
### 1. Get a Portal API Key
54+
55+
[Get a Portal API Key here](https://ionic.io/docs/portals/getting-started/guide).
56+
57+
### 2. Register portals
58+
59+
Register your Ionic Portals, by calling the [IonicPortalManager] class's [register()](#register) method with the [Portal API key](#1-get-a-portal-api-key).
60+
61+
```ts
62+
import { Application } from '@nativescript/core';
63+
64+
import { IonicPortalManager } from '@nativescript/ionic-portals';
65+
66+
Application.on(Application.launchEvent, () => {
67+
// Register IonicPortals
68+
IonicPortalManager.register('<portal-api-key>');
69+
});
70+
71+
// boot app here, for example:
72+
Application.run({ moduleName: 'app-root' });
73+
```
74+
75+
Create as many Portals as you need to use in your app.
76+
77+
The app will look for folders within its resources where the folder name is equal to the portal `id` you used to define each portal.
78+
79+
Given the following examples, ensure your web portal is built into the following folders:
80+
81+
* For iOS: `App_Resources/iOS/webPortal`
82+
* For Android: `App_Resources/Android/src/main/asssets/webPortal`
83+
84+
### 3. Add portals view to markup
85+
86+
#### Core
87+
88+
1. Register the plugin namespace with Page's `xmlns` attribute providing your prefix( `ionic`, for example).
89+
90+
```xml
91+
<Page xmlns:ionic="@nativescript/ionic-portals">
92+
```
93+
2. Access the `IonicPortal` view through the prefix and add it to markup.
94+
95+
```xml
96+
<ionic:IonicPortal id="webPortal">
97+
</ionic:IonicPortal>
98+
```
99+
**Full code**
100+
101+
```xml
102+
<Page xmlns="http://schemas.nativescript.org/tns.xsd"
103+
xmlns:ionic="@nativescript/ionic-portals">
104+
<StackLayout class="p-20">
105+
<ionic:IonicPortal id="webPortal">
106+
</ionic:IonicPortal>
107+
</StackLayout>
108+
</Page>
109+
```
110+
111+
#### Angular
112+
113+
1. To add the `IonicPortal` view to the markup of any component, register it by adding the following code to the `main.ts` file:
114+
115+
```ts
116+
import { registerElement } from '@nativescript/angular';
117+
import { IonicPortal } from '@nativescript/ionic-portals';
118+
registerElement('IonicPortal', () => IonicPortal);
119+
```
120+
121+
2. Add `IonicPortal` to markup.
122+
```html
123+
<IonicPortal id="webPortal"></IonicPortal>;
124+
```
125+
126+
#### Vue
127+
128+
1. To add the `IonicPortal` view in the markup of any component, register it by adding the following code to the `app.ts` file:
129+
130+
```ts
131+
import { IonicPortal } from '@nativescript/ionic-portals';
132+
133+
registerElement("IonicPortal", ()=> IonicPortal)
134+
```
135+
2. Add `IonicPortal` to markup.
136+
137+
```xml
138+
<GridLayout height="300" class="mt-3 p-3">
139+
<IonicPortal id="webPortal"/>
140+
</GridLayout>
141+
```
142+
#### Svelte
143+
144+
1. To use the `IonicPortal` view in the markup of any component, register it by adding the following code to the `app.ts` file:
145+
146+
```ts
147+
import { IonicPortal } from '@nativescript/ionic-portals';
148+
149+
import {registerNativeViewElement} from "svelte-native/dom"
150+
registerNativeViewElement("ionicPortal", ()=> IonicPortal)
151+
```
152+
153+
2. Add `IonicPortal` to markup.
154+
```xml
155+
<gridLayout height="300" class="mt-3 p-3">
156+
<ionicPortal id="webPortal"/>
157+
</gridLayout>
158+
```
159+
### Send events from NativeScript to any web portal
160+
161+
To send events from NativeScript to any web portal, use the [publishTopic()](#publishtopic) method:
162+
163+
```ts
164+
IonicPortalManager.publishTopic('hello', { name: 'data from NativeScript' });
165+
```
166+
167+
#### Subscribe to events sent from web portals
168+
169+
To subscribe to events sent from any web portal, call the [subscribeToTopic](#subscribetotopic) method with the event name as the first argument and the event handler as the second argument.
170+
171+
```ts
172+
const subscriptionId = IonicPortalManager.subscribeToTopic('useful-web-event', result => {
173+
console.log('received web portal useful-web-event with data:', result.data);
174+
});
175+
```
176+
177+
#### Unsubscribe from events sent from web portals
178+
179+
To unsubscribe from events sent from any web portal, call the [unsubscribeFromTopic()](#unsubscribefromtopic) method with the event name as the first argument and the subscription id as the second argument.
180+
```ts
181+
IonicPortalManager.unsubscribeFromTopic('useful-web-event', subscriptionId);
182+
```
183+
184+
## IonicPortalManager API
185+
186+
Allows you to interact with and configure portals via the following APIs.
187+
188+
### register()
189+
190+
```ts
191+
IonicPortalManager.register(apiKey)
192+
```
193+
194+
Registers portals. Call it in the `main.ts` file, before the app boots, in the handler of the `Application.launchEvent` event.
195+
196+
| Parameter | Type | Description
197+
|:----------|:-----|:-----------
198+
| `apiKey` | `string` | Your portal API key
199+
200+
201+
### setInitialContext()
202+
```ts
203+
IonicPortalManager.setInitialContext(id,initialContext)
204+
```
205+
Used to set the initial context of any portal id before the portal is shown.
206+
207+
| Parameter | Type | Description
208+
|:----------|:-----|:-----------
209+
| `id` | `string` | The portal id.
210+
| `initialContext` | `string` | Data provided as the initial context to the portal.
211+
212+
---
213+
### setAndroidPlugins()
214+
```ts
215+
IonicPortalManager.setAndroidPlugins(plugins)
216+
```
217+
218+
Defines the usage of non-official Capacitor Plugins via Android package names
219+
220+
| Parameter | Type | Description
221+
|:----------|:-----|:-----------
222+
| `plugins` | ` Array<string>` | A list of non-official Capacitor package names.
223+
224+
225+
### publishTopic()
226+
```ts
227+
IonicPortalManager.publishTopic(topic, data)
228+
```
229+
230+
Sends a message to any web portal by publishing a topic (aka. event)
231+
232+
| Parameter | Type | Description
233+
|:----------|:-----|:-----------
234+
| `topic` | ` string` | The name of the topic/event
235+
| `data` | ` any` | _Optional_: The payload to send with the topic.
236+
237+
### subscribeToTopic()
238+
239+
```ts
240+
subscriptionId: number = IonicPortalManager.subscribeToTopic(topic, (data?: any) => void))
241+
```
242+
Listens to any message sent from any web portal by subscribing to the specified topic. It returns a subscription id used to later unsubscribe from the `topic`.
243+
244+
| Parameter | Type | Description
245+
|:----------|:-----|:-----------
246+
| `topic` | ` string` | The name of the topic/event to subscribe to.
247+
| `callback` | `function` | The function invoked every time a message is sent via the topic with an optional `data` parameter.
248+
249+
---
250+
### unsubscribeFromTopic()
251+
252+
```ts
253+
IonicPortalManager.unsubscribeFromTopic(topic, subscriptionId)
254+
```
255+
| Parameter | Type | Description
256+
|:----------|:-----|:-----------
257+
| `topic` | ` string` | The name of the topic/event to unsubscribe from.
258+
| `subscriptionId` | `number` | The subscription id returned by [subscribeToTopic()](#subscribetotopic).
259+
260+
### configureLiveUpdates()
261+
262+
Note: configure before displaying the portal.
263+
264+
```ts
265+
IonicPortalManager.configureLiveUpdates('webPortal', {
266+
appId: 'e2abc12',
267+
channel: 'production',
268+
syncOnAdd: true
269+
})
270+
```
271+
| Parameter | Type | Description
272+
|:----------|:-----|:-----------
273+
| `portalId` | ` string` | The portal id.
274+
| `config` | `IonicPortalLiveUpdateConfig` | Live update configuration.
275+
276+
### syncNow()
277+
278+
```ts
279+
IonicPortalManager.syncNow(['e2abc12'], false, status => {
280+
console.log('sync complete:', status)
281+
})
282+
```
283+
| Parameter | Type | Description
284+
|:----------|:-----|:-----------
285+
| `appIds` | `Array<string>` | Portal app ids to sync.
286+
| `isParallel` | `boolean` | Whether to sync in parallel or not.
287+
| `complete` | `(status: string) => void` | Complete callback.
288+
289+
### getLastSync()
290+
291+
```ts
292+
const lastSync = IonicPortalManager.getLastSync('e2abc12')
293+
```
294+
| Parameter | Type | Description
295+
|:----------|:-----|:-----------
296+
| `appId` | `string` | Portal app id to check last sync.
297+
298+
## Using Capacitor Plugins with Ionic Portals
299+
300+
Refer to [this blog post](https://blog.nativescript.org/ionic-portals-with-capacitor-plugins).
301+
302+
## Notes
303+
304+
> For iOS:
305+
> You may need to add `IPHONEOS_DEPLOYMENT_TARGET = 12.0` to your `App_Resources/iOS/build.xcconfig` file.
306+
> If your project contains `App_Resources/iOS/Podfile`, you may need to remove any post install handling which removes deployment targets, for example:
307+
> Remove anything like this: `config.build_settings.delete 'IPHONEOS_DEPLOYMENT_TARGET'`
8308
9-
// TODO
309+
## Additional Resources
310+
- You can learn more about Ionic Portals at [Opening Doors with Portals](https://www.youtube.com/watch?v=lGeeUjIMjTQ&t=609s)
311+
- Find the video's repo [here](https://github.com/NathanWalker/ioniconf2022)
10312

11313
## License
12314

packages/ionic-portals/common.ts

Lines changed: 58 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,59 @@
1-
import { Observable } from '@nativescript/core';
1+
import { View } from '@nativescript/core';
22

3-
export class IonicPortalsCommon extends Observable {}
3+
export interface IonicPortalLiveUpdateConfig {
4+
appId: string;
5+
channel: string;
6+
syncOnAdd?: boolean;
7+
}
8+
export class IonicPortalManagerCommon {
9+
static AndroidPlugins: Array<string>;
10+
static InitialContexts: { [key: string]: any };
11+
static LiveUpdateConfigs: { [key: string]: IonicPortalLiveUpdateConfig };
12+
static Listeners: { [key: string]: Array<{ callback: (data?: any) => void; subscriptionId: number }> };
13+
static setAndroidPlugins(plugins: Array<string>) {
14+
if (!IonicPortalManagerCommon.AndroidPlugins) {
15+
IonicPortalManagerCommon.AndroidPlugins = [];
16+
}
17+
for (const plugin of plugins) {
18+
if (!IonicPortalManagerCommon.AndroidPlugins.includes(plugin)) {
19+
IonicPortalManagerCommon.AndroidPlugins.push(plugin);
20+
}
21+
}
22+
}
23+
static configureLiveUpdates(portalId: string, config: IonicPortalLiveUpdateConfig) {
24+
if (!IonicPortalManagerCommon.LiveUpdateConfigs) {
25+
IonicPortalManagerCommon.LiveUpdateConfigs = {};
26+
}
27+
IonicPortalManagerCommon.LiveUpdateConfigs[portalId] = config;
28+
}
29+
static setInitialContext(id: string, initialContext: any) {
30+
if (!IonicPortalManagerCommon.InitialContexts) {
31+
IonicPortalManagerCommon.InitialContexts = {};
32+
}
33+
IonicPortalManagerCommon.InitialContexts[id] = initialContext;
34+
}
35+
36+
static subscribeToTopic(topic: string, callback: (data?: any) => void): number {
37+
if (!this.Listeners) {
38+
this.Listeners = {};
39+
}
40+
if (!this.Listeners[topic]) {
41+
this.Listeners[topic] = [];
42+
}
43+
return 0;
44+
}
45+
46+
static unsubscribeFromTopic(topic: string, subscriptionId: number) {
47+
if (this.Listeners && this.Listeners[topic]) {
48+
const index = this.Listeners[topic].findIndex((ref) => ref.subscriptionId === subscriptionId);
49+
if (index > -1) {
50+
this.Listeners[topic].splice(index, 1);
51+
}
52+
}
53+
}
54+
}
55+
56+
export class IonicPortalCommon extends View {
57+
initialContext: any;
58+
reload(): void {}
59+
}
Loading

0 commit comments

Comments
 (0)