capacitor-community / electron

Deploy your Capacitor apps to Linux, Mac, and Windows desktops, with the Electron platform! 🖥️
https://capacitor-community.github.io/electron/
MIT License
335 stars 59 forks source link

Remove all listeners for a plugin #185

Open hampoelz opened 2 years ago

hampoelz commented 2 years ago

Match removeAllListeners() function with Capacitor API to remove all listeners of a plugin.

Refs #137

matallui commented 2 years ago

Is there any documentation on how to use events on a Capacitor Electron plugin? I'm still having issues understanding how to use/implement this, and can't find any implementation examples.

hampoelz commented 2 years ago

@matallui You can find a small example in the createplugin-documentation: https://github.com/capacitor-community/electron/blob/main/docs-site/docs/creatingplugins.md

matallui commented 2 years ago

@hampoelz thanks! I have something similar but it's not working. I'm just confused what to put in each file of the plugin codebase.

src/definitions.ts:

export interface SomePlugin {
    echo(s: string): Promise<string>;
}

electron/src/index.ts

export class Some extends EventEmitter implements SomePlugin {
    echo(s: string): Promise<string> {
        return Promise.resolve(s);
    }
}

It sounds like the above example would let you do something like this, from the client code:

import { Some } from 'some-plugin';

const hello = await Some.echo('hello');

const id = Some.addListener('some-event', () => console.log('fired'));
Some.removeListener(id);

But the last two lines won't work because those methods are not implemented on the plugin.

I also don't understand what this means from the example:

CapacitorCustomPlatform.plugins.MyPlugin.addListener('my-event', console.log);

Where do I access CapacitorCustomPlatform from?

Any help is much appreciated!

hampoelz commented 2 years ago

@matallui your code looks good to me.

If you're using Capacitor with the bundled Capacitor-Core you can access your plugin with Capacitor.Plugins.yourPlugin or on Electron with CapacitorCustomPlatform.plugins.yourPlugin. (Capacitor and CapacitorCustomPlatform are globally scoped)

(I'm using const myPlugin = Capacitor.Plugins.myPlugin || CapacitorCustomPlatform.plugins.myPlugin; to access my plugin cross-platform)

matallui commented 2 years ago

@hampoelz thanks! I actually got it working by simply type casting the plugin to any:

import { Some } from 'some-plugin';

let listener: any;

listener = (Some as any).addListener('some-event', console.log).then(res => (listener = res));

// some code

if (listener) {
  if (listener.remove) {
    // iOS & Android
    listener.remove();
  } else {
    // electron case
    (Some as any).removeListener(listener);
  }
}

This is what is working for me right now.

I guess those methods are added at runtime, so Typescript was not letting me access methods that were not defined by the plugin. At least that's my take on this.

Gangceen commented 3 months ago

@matallui may I ask what are the contents of "SomePlugin" in your case when you got the addListener to work? while I am a bit unfamiliar with typescript, my interface has this method:

addListener(
    eventName: 'sampleStatusChange',
    listenerFunc: SampleStatusChangeListener,
): Promise<PluginListenerHandle> & PluginListenerHandle;

and my class is written similarly as yours where it "extends EventEmitter and Implements SamplePlugin" but I don't call addListener and it returns an error:

electron/src/index.ts(8,14): error TS2420: Class 'SampleElectron' incorrectly implements interface 'SamplePlugin'.
         The types returned by 'addListener(...)' are incompatible between these types.
           Type 'this' is not assignable to type 'Promise<PluginListenerHandle> & PluginListenerHandle'.
             Type 'SampleElectron' is not assignable to type 'Promise<PluginListenerHandle> & PluginListenerHandle'.
               Type 'SampleElectron' is not assignable to type 'Promise<PluginListenerHandle>'.
                 Type 'this' is not assignable to type 'Promise<PluginListenerHandle>'.
                   Type 'SampleElectron' is not assignable to type 'Promise<PluginListenerHandle>'.
                     Type 'SampleElectron' is missing the following properties from type 'Promise<PluginListenerHandle>': then, catch, [Symbol.toStringTag], finally

I have gotten my other functions to work when it doesn't involve addling listeners so I'm hoping someone could help me out with this one.

matallui commented 3 months ago

@Gangceen I used Capacitor once about 2 years ago, at a previous job. I can't remember exactly what I did back then, and I don't have access to that code to share, unfortunately.

If the info here is not enough, not sure I can really be of much help.