Using widgets

Let's take a closer look at how to write the main module of a dapplet, what it consists of, how to add a widget, and how to use some Core API methods.

Here is the initial code for this example: ex01-add-button-exercise.

The basic template for your_dapplet/src/index.ts looks like this:

1import {} from '@dapplets/dapplet-extension'
2import EXAMPLE_IMG from './icons/ex01.png'
3
4@Injectable
5export default class TwitterFeature {
6 @Inject('twitter-config.dapplet-base.eth')
7 public adapter
8
9 activate() {
10 const { button } = this.adapter.exports
11 this.adapter.attachConfig({
12 POST: (ctx) =>
13 button({
14 DEFAULT: {
15 img: EXAMPLE_IMG,
16 exec: () => Core.alert('Hello Word!'),
17 },
18 }),
19 })
20 }
21}

The dapplet injects a button to every Tweet on a Twitter page. This button is displayed below the main content, near the buttons Like, Retweet etc. The function passed to POST takes ctx and returns the widget, the array of widgets or null.

ctx - is an object that contains parameters of the current context where the dapplet widgets were injected. Parameters are defined by the adapter.

POST: (ctx) => [ button({ ... }) ]

or

POST: (ctx) => button({})

Before using the button or/and other widgets in this.adapter.attachConfig() it has to be received from this.adapter.exports.

Our button has only one state - DEFAULT. In this case you can choose not to set the initial state and delete this field.

1button({
2 DEFAULT: {
3 img: EXAMPLE_IMG,
4 exec: () => Core.alert('Hello, World!'),
5 },
6})

When you don’t have the DEFAULT state you have to set the initial state as above.

1button({
2 initial: 'FIRST_STATE', // or SECOND_STATE
3
4 // First state button
5 FIRST_STATE: {
6 img: LIKE_IMG,
7 exec: () => Core.alert('Hello, World!'),
8 },
9
10 // Second state button
11 SECOND_STATE: {
12 img: DISLIKE_IMG,
13 exec: () => Core.alert('Hello, World!'),
14 },
15})

The label, img and exec are defined in the state. In this case exec takes the function that will be executed with a button click.

The whole list of widgets and contexts is defined in the adapter. The twitter-config API can be found here.

Let’s add a counter to the button label in POST to show how we can manipulate the widget’s state.

Add a label with a counter.

label: 0

Listen for the button click - output into console.

1exec: async (ctx, me) => {
2 console.log(ctx)
3 console.log(me)
4}

The extension provides exec function with two parameters:

  • ctx — the current parsed context;
  • me — a Proxy of the widget.

We got the ctx object earlier so in our example we don't need to get it here.

Using me we can change the widget's parameters and its state.

1// Changing the state
2exec: (ctx, me) => (me.state = 'SECOND')
3
4// Changing the label
5exec: (ctx, me) => (me.label = 'Hello')

Increase the counter value on the button click.

me.label += 1

Let's display a message in the browser alert by clicking on the widget. We will also give an opportunity to customize the message text in the extension’s dapplet settings.

The dapplet settings are as follows:

Dapplet's User Settings

To do this, add the following code to the dapplet's exec:

const message1 = await Core.storage.get('exampleString')
const message2 = await Core.storage.get('exampleHiddenString')
Core.alert(`I wrote: ${message1}. Then wrote: ${message2}.`)

Here is the complete exec code:

1exec: async (_, me) => {
2 console.log(ctx)
3 console.log(me)
4 me.label += 1
5 const message1 = await Core.storage.get('exampleString')
6 const message2 = await Core.storage.get('exampleHiddenString')
7 Core.alert(`I wrote: ${message1}. Then wrote: ${message2}.`)
8}

In the config/default.json define your own defaults.

1{
2 "main": {
3 "exampleString": "some string value",
4 "exampleHiddenString": "some string value"
5 },
6 "test": {
7 "exampleString": "TEST: shown",
8 "exampleHiddenString": "TEST: hidden"
9 },
10 "dev": {
11 "exampleString": "some string value",
12 "exampleHiddenString": "some string value"
13 }
14}

Run the dapplet in your terminal

npm start

If you don't know how to run the dapplet in a browser, see Get Started.

Here is the result code of the example: ex01-add-button-solution

In the browser:

video

If you want to save counters' values and get them from the server, look at Server Connection.