## Classes
Client
CabalDetails
## Client * [Client](#Client) * [new Client([opts])](#new_Client_new) * _instance_ * [.readCabalSettingsFile()](#Client+readCabalSettingsFile) ⇒ object * [.getCabalSettings(key)](#Client+getCabalSettings) ⇒ object * [.writeCabalSettings(key, settings)](#Client+writeCabalSettings) * [.resolveName(name, [cb])](#Client+resolveName) * [.createCabal()](#Client+createCabal) ⇒ Promise * [.addCabal(key, opts, cb)](#Client+addCabal) ⇒ Promise * [.focusCabal(key)](#Client+focusCabal) * [.removeCabal(key, cb)](#Client+removeCabal) * [.getDetails()](#Client+getDetails) ⇒ [CabalDetails](#CabalDetails) * [.getCabalKeys()](#Client+getCabalKeys) ⇒ Array.<string> * [.getCurrentCabal()](#Client+getCurrentCabal) ⇒ [CabalDetails](#CabalDetails) * [.addCommand([name], [cmd])](#Client+addCommand) * [.removeCommand([name])](#Client+removeCommand) * [.getCommands()](#Client+getCommands) * [.addAlias([longCmd], [shortCmd])](#Client+addAlias) * [.cabalToDetails([cabal])](#Client+cabalToDetails) ⇒ [CabalDetails](#CabalDetails) * [.addStatusMessage(message, channel, [cabal])](#Client+addStatusMessage) * [.clearStatusMessages(channel, [cabal])](#Client+clearStatusMessages) * [.getUsers([cabal])](#Client+getUsers) ⇒ Array.<Object> * [.getJoinedChannels([cabal])](#Client+getJoinedChannels) ⇒ Array.<Object> * [.getChannels([cabal])](#Client+getChannels) ⇒ Array.<Object> * [.subscribe(listener, [cabal])](#Client+subscribe) * [.unsubscribe(listener, [cabal])](#Client+unsubscribe) * [.getMessages([opts], [cb], [cabal])](#Client+getMessages) * [.searchMessages([searchString], [opts], [cabal])](#Client+searchMessages) ⇒ Promise * [.getNumberUnreadMessages(channel, [cabal])](#Client+getNumberUnreadMessages) ⇒ number * [.getNumberMentions([channel], [cabal])](#Client+getNumberMentions) * [.getMentions([channel], [cabal])](#Client+getMentions) * [.focusChannel([channel], [keepUnread], [cabal])](#Client+focusChannel) * [.unfocusChannel([channel], [newChannel], [cabal])](#Client+unfocusChannel) * [.getCurrentChannel()](#Client+getCurrentChannel) ⇒ string * [.markChannelRead(channel, [cabal])](#Client+markChannelRead) * _static_ * [.getDatabaseVersion()](#Client.getDatabaseVersion) ⇒ string * [.generateKey()](#Client.generateKey) ⇒ string * [.scrubKey(key)](#Client.scrubKey) ⇒ string * [.getCabalDirectory()](#Client.getCabalDirectory) ⇒ string * [.getCabalSettingsFile()](#Client.getCabalSettingsFile) ⇒ string * * * ### new Client([opts]) Create a client instance from which to manage multiple [`cabal-core`](https://github.com/cabal-club/cabal-core/) instances. **Params** - *opts* object - aliases object - key/value pairs of `alias` -> `command name` - commands object - key/value pairs of `command name` -> `command object`, which has the following properties: - call function - command function with the following signature `command.call(cabal, res, arg)` - help function - return the help string for this command - category Array.<string> - a list of categories this commands belongs to - alias Array.<string> - a list of command aliases - config object - temp boolean - if `temp` is true no data is persisted to disk. - *dbdir* string - the directory to store the cabal data - *preferredPort* string - the port cabal will listen on for traffic - *maxFeeds* number = 1000 - max amount of feeds to sync - *persistentCache* object - specify a `read` and `write` to create a persistent DNS cache - read function - async cache lookup function - write function - async cache write function * * * ### client.readCabalSettingsFile() ⇒ object Read and parse the contents of the settings.yml file. If the file doesn't exist, return {}. **Returns**: object - the contents of the settings file * * * ### client.getCabalSettings(key) ⇒ object Get the settings for a given cabal from the settings.yml file. If the file doesn't exist or the given cabal has no settings, return the default settings. **Returns**: object - the cabal settings **Params** - key string - the cabal * * * ### client.writeCabalSettings(key, settings) Reads the settings from the settings.yml file, updates the settings for the given cabal, then writes the revised settings to the settings.yml file. **Params** - key string - the cabal - settings object - the cabal settings * * * ### client.resolveName(name, [cb]) Resolve the DNS shortname `name`. If `name` is already a cabal key, it will be returned and the DNS lookup is aborted. If `name` is a whisper:// key, a DHT lookup for the passed-in key will occur. Once a match is found, it is assumed to be a cabal key, which is returned. Returns the cabal key in `cb`. If `cb` is null a Promise is returned. **Params** - name string - the DNS shortname, or whisper:// shortname - *cb* function - The callback to be called when lookup succeeds * * * ### client.createCabal() ⇒ Promise Create a new cabal. **Returns**: Promise - a promise that resolves into a `CabalDetails` instance. * * * ### client.addCabal(key, opts, cb) ⇒ Promise Add/load the cabal at `key`. **Returns**: Promise - a promise that resolves into a `CabalDetails` instance. **Params** - key string - opts object - cb function - a function to be called when the cabal has been initialized. * * * ### client.focusCabal(key) Focus the cabal at `key`, used when you want to switch from one open cabal to another. **Params** - key string * * * ### client.removeCabal(key, cb) Remove the cabal `key`. Destroys everything related to it (the data is however still persisted to disk, fret not!). **Params** - key string - cb function * * * ### client.getDetails() ⇒ [CabalDetails](#CabalDetails) Returns the details of a cabal for the given key. * * * ### client.getCabalKeys() ⇒ Array.<string> Returns a list of cabal keys, one for each open cabal. * * * ### client.getCurrentCabal() ⇒ [CabalDetails](#CabalDetails) Get the current cabal. * * * ### client.addCommand([name], [cmd]) Add a command to the set of supported commands. **Params** - *name* string - the long-form command name - *cmd* object - the command object - *help* function - function returning help text - *alias* array - array of string aliases - *call* function - implementation of the command receiving (cabal, res, arg) arguments * * * ### client.removeCommand([name]) Remove a command. **Params** - *name* string - the command name * * * ### client.getCommands() Get an object mapping command names to command objects. * * * ### client.addAlias([longCmd], [shortCmd]) Add an alias `shortCmd` for `longCmd` **Params** - *longCmd* string - command to be aliased - *shortCmd* string - alias * * * ### client.cabalToDetails([cabal]) ⇒ [CabalDetails](#CabalDetails) Returns a `CabalDetails` instance for the passed in `cabal-core` instance. **Params** - *cabal* Cabal = this.currentCabal * * * ### client.addStatusMessage(message, channel, [cabal]) Add a status message, displayed client-side only, to the specified channel and cabal. If no cabal is specified, the currently focused cabal is used. **Params** - message object - channel string - *cabal* Cabal = this.currentCabal * * * ### client.clearStatusMessages(channel, [cabal]) Clear status messages for the specified channel. **Params** - channel string - *cabal* Cabal = this.currentCabal * * * ### client.getUsers([cabal]) ⇒ Array.<Object> Returns a list of all the users for the specified cabal. If no cabal is specified, the currently focused cabal is used. **Returns**: Array.<Object> - the list of users **Params** - *cabal* Cabal = this.currentCabal * * * ### client.getJoinedChannels([cabal]) ⇒ Array.<Object> Returns a list of channels the user has joined for the specified cabal. If no cabal is specified, the currently focused cabal is used. **Returns**: Array.<Object> - the list of Channels **Params** - *cabal* Cabal = this.currentCabal * * * ### client.getChannels([cabal]) ⇒ Array.<Object> Returns a list of all channels for the specified cabal. If no cabal is specified, the currently focused cabal is used. **Returns**: Array.<Object> - the list of Channels **Params** - *cabal* Cabal = this.currentCabal * * * ### client.subscribe(listener, [cabal]) Add a new listener for the `update` event. **Params** - listener function - *cabal* Cabal = this.currentCabal * * * ### client.unsubscribe(listener, [cabal]) Remove a previously added listener. **Params** - listener function - *cabal* Cabal = this.currentCabal * * * ### client.getMessages([opts], [cb], [cabal]) Returns a list of messages according to `opts`. If `cb` is null, a Promise is returned. **Params** - *opts* Object - *olderThan* number - timestamp in epoch time. we want to get messages that are *older* than this ts - *newerThan* number - timestamp in epoch time. we want to get messages that are *newer* than this ts - *amount* number - amount of messages to get - *channel* string - channel to get messages from. defaults to currently focused channel - *cb* function - the callback to be called when messages are retreived - *cabal* Cabal = this.currentCabal * * * ### client.searchMessages([searchString], [opts], [cabal]) ⇒ Promise Searches for messages that include the search string according to `opts`. Each returned match contains a message string and a matchedIndexes array containing the indexes at which the search string was found in the message **Returns**: Promise - a promise that resolves into a list of matches. **Params** - *searchString* string - string to match messages against - *opts* Object - *olderThan* number - timestamp in epoch time. we want to search through messages that are *older* than this ts - *newerThan* number - timestamp in epoch time. we want to search through messages that are *newer* than this ts - *amount* number - amount of messages to be search through - *channel* string - channel to get messages from. defaults to currently focused channel - *cabal* Cabal = this.currentCabal * * * ### client.getNumberUnreadMessages(channel, [cabal]) ⇒ number Returns the number of unread messages for `channel`. **Params** - channel string - *cabal* Cabal = this.currentCabal * * * ### client.getNumberMentions([channel], [cabal]) Returns the number of mentions in `channel`. **Params** - *channel* string = "this.getCurrentChannel()" - *cabal* Cabal = this.currentCabal * * * ### client.getMentions([channel], [cabal]) Returns a list of messages that triggered a mention in channel. **Params** - *channel* string = "this.getCurrentChannel()" - *cabal* Cabal = this.currentCabal * * * ### client.focusChannel([channel], [keepUnread], [cabal]) View `channel`, closing the previously focused channel. **Params** - *channel* \* = this.getCurrentChannel() - *keepUnread* boolean = false - *cabal* Cabal = this.currentCabal * * * ### client.unfocusChannel([channel], [newChannel], [cabal]) Close `channel`. **Params** - *channel* string = "this.getCurrentChannel()" - *newChannel* string = null - *cabal* Cabal = this.currentCabal * * * ### client.getCurrentChannel() ⇒ string Returns the currently focused channel name. * * * ### client.markChannelRead(channel, [cabal]) Mark the channel as read. **Params** - channel string - *cabal* Cabal = this.currentCabal * * * ### Client.getDatabaseVersion() ⇒ string Get the current database version. * * * ### Client.generateKey() ⇒ string Returns a 64 character hex string i.e. a newly generated cabal key. Useful if you want to programmatically create a new cabal as part of a shell pipeline. * * * ### Client.scrubKey(key) ⇒ string Removes URI scheme, URI search params (if present), and returns the cabal key as a 64 character hex string **Returns**: string - the scrubbed key **Params** - key string - the key to scrub **Example** ```js Client.scrubKey('cabal://12345678...?admin=7331b4b..') // => '12345678...' ``` * * * ### Client.getCabalDirectory() ⇒ string Returns a string path of where all of the cabals are stored on the hard drive. **Returns**: string - the cabal directory * * * ### Client.getCabalSettingsFile() ⇒ string Returns a string path of where the cabal settings are stored on the hard drive. **Returns**: string - the cabal settings file path * * * ## CabalDetails **Emits**: [update](#CabalDetails+event_update), [init](#CabalDetails+event_init), [info](#CabalDetails+event_info), [user-updated](#CabalDetails+event_user-updated), [new-channel](#CabalDetails+event_new-channel), [new-message](#CabalDetails+event_new-message), [private-message](#CabalDetails+event_private-message), [publish-message](#CabalDetails+event_publish-message), [publish-private-message](#CabalDetails+event_publish-private-message), [publish-nick](#CabalDetails+event_publish-nick), [status-message](#CabalDetails+event_status-message), [topic](#CabalDetails+event_topic), [channel-focus](#CabalDetails+event_channel-focus), [channel-join](#CabalDetails+event_channel-join), [channel-leave](#CabalDetails+event_channel-leave), [cabal-focus](#CabalDetails+event_cabal-focus), [started-peering](#CabalDetails+event_started-peering), [stopped-peering](#CabalDetails+event_stopped-peering) * [CabalDetails](#CabalDetails) * [new CabalDetails({, done)](#new_CabalDetails_new) * [.processLine([line], [cb])](#CabalDetails+processLine) * [.publishMessage(msg, [opts], [cb])](#CabalDetails+publishMessage) * [.publishNick(nick, [cb])](#CabalDetails+publishNick) * [.publishChannelTopic([channel], topic, cb)](#CabalDetails+publishChannelTopic) * [.getTopic([channel])](#CabalDetails+getTopic) ⇒ string * [.getChannelMembers([channel])](#CabalDetails+getChannelMembers) ⇒ Array.<object> * [.addStatusMessage(message, [channel])](#CabalDetails+addStatusMessage) * [.getChannels([opts])](#CabalDetails+getChannels) ⇒ Array.<string> * [.getCurrentChannel()](#CabalDetails+getCurrentChannel) ⇒ string * [.getCurrentChannelDetails()](#CabalDetails+getCurrentChannelDetails) ⇒ ChannelDetails * [.clearVirtualMessages([channel])](#CabalDetails+clearVirtualMessages) * [.getPrivateMessageList()](#CabalDetails+getPrivateMessageList) * [.isChannelPrivate()](#CabalDetails+isChannelPrivate) * [.joinPrivateMessage(channel)](#CabalDetails+joinPrivateMessage) * [.leavePrivateMessage(channel)](#CabalDetails+leavePrivateMessage) * [.publishPrivateMessage(msg, recipientKey, [cb])](#CabalDetails+publishPrivateMessage) * [.getJoinedChannels()](#CabalDetails+getJoinedChannels) ⇒ Array.<string> * [.getLocalUser()](#CabalDetails+getLocalUser) ⇒ user * [.getLocalName()](#CabalDetails+getLocalName) ⇒ string * [.joinChannel(channel)](#CabalDetails+joinChannel) * [.leaveChannel(channel)](#CabalDetails+leaveChannel) * [.archiveChannel(channel, [reason], cb(err))](#CabalDetails+archiveChannel) * [.unarchiveChannel(channel, [reason], cb(err))](#CabalDetails+unarchiveChannel) * [.getUsers()](#CabalDetails+getUsers) ⇒ object * [._destroy()](#CabalDetails+_destroy) * ["update"](#CabalDetails+event_update) * ["init"](#CabalDetails+event_init) * ["user-updated"](#CabalDetails+event_user-updated) * ["new-channel"](#CabalDetails+event_new-channel) * ["new-message"](#CabalDetails+event_new-message) * ["private-message"](#CabalDetails+event_private-message) * ["publish-message"](#CabalDetails+event_publish-message) * ["publish-private-message"](#CabalDetails+event_publish-private-message) * ["publish-nick"](#CabalDetails+event_publish-nick) * ["status-message"](#CabalDetails+event_status-message) * ["topic"](#CabalDetails+event_topic) * ["channel-focus"](#CabalDetails+event_channel-focus) * ["channel-join"](#CabalDetails+event_channel-join) * ["channel-leave"](#CabalDetails+event_channel-leave) * ["cabal-focus"](#CabalDetails+event_cabal-focus) * ["started-peering"](#CabalDetails+event_started-peering) * ["stopped-peering"](#CabalDetails+event_stopped-peering) * ["update"](#CabalDetails+event_update) * ["info"](#CabalDetails+event_info) * * * ### new CabalDetails({, done) **Params** - { object - cabal , commands, aliases } - done function - the function to be called after the cabal is initialized * * * ### cabalDetails.processLine([line], [cb]) Interpret a line of input from the user. This may involve running a command or publishing a message to the current channel. **Params** - *line* string - input from the user - *cb* function - callback called when the input is processed * * * ### cabalDetails.publishMessage(msg, [opts], [cb]) Publish a message up to consumer. See [`cabal-core`](https://github.com/cabal-club/cabal-core/) for the full list of options. **Params** - msg object - the full message object - *opts* object - options passed down to cabal.publish - *cb* function - callback function called when message is published **Example** ```js cabalDetails.publishMessage({ type: 'chat/text', content: { text: 'hello world', channel: 'cabal-dev' } }) ``` * * * ### cabalDetails.publishNick(nick, [cb]) Announce a new nickname. **Params** - nick string - *cb* function - will be called after the nick is published * * * ### cabalDetails.publishChannelTopic([channel], topic, cb) Publish a new channel topic to `channel`. **Params** - *channel* string = "this.chname" - topic string - cb function - will be called when publishing has finished. * * * ### cabalDetails.getTopic([channel]) ⇒ string **Returns**: string - The current topic of `channel` as a string **Params** - *channel* string = "this.chname" * * * ### cabalDetails.getChannelMembers([channel]) ⇒ Array.<object> Return the list of users that have joined `channel`. Note: this can be a subset of all of the users in a cabal. **Params** - *channel* string = "this.chname" * * * ### cabalDetails.addStatusMessage(message, [channel]) Add a status message, visible locally only. **Params** - message object - *channel* string = "this.chname" * * * ### cabalDetails.getChannels([opts]) ⇒ Array.<string> **Returns**: Array.<string> - a list of all the channels in this cabal. Does not return channels with 0 members. **Params** - *opts* object **Properties** | Name | Type | Description | | --- | --- | --- | | includeArchived | boolean | Determines whether to include archived channels or not. Defaults to false. | | includePM | boolean | Determines whether to include private message channels or not. Defaults to false. | | onlyJoined | boolean | Determines whether to limit returned channels to only those that are joined or not. Defaults to false. | * * * ### cabalDetails.getCurrentChannel() ⇒ string **Returns**: string - The name of the current channel * * * ### cabalDetails.getCurrentChannelDetails() ⇒ ChannelDetails **Returns**: ChannelDetails - A ChannelDetails object for the current chanel * * * ### cabalDetails.clearVirtualMessages([channel]) Remove all of the virtual (i.e. status) messages associated with this channel. Virtual messages are local only. **Params** - *channel* string = "this.chname" * * * ### cabalDetails.getPrivateMessageList() Get the list of currently opened private message channels. **Returns{string[]}**: A list of all public keys you have an open PM with (hidden users are removed from list). * * * ### cabalDetails.isChannelPrivate() Query if the passed in channel name is private or not **Returns{boolean}**: true if channel is private, false if not (or if it doesn't exist) * * * ### cabalDetails.joinPrivateMessage(channel) Join a private message channel if it is not already joined. **Params** - channel string - the key of the PM to join * * * ### cabalDetails.leavePrivateMessage(channel) Leave a private message channel if it has not already been left. **Params** - channel string - the key of the PM to leave * * * ### cabalDetails.publishPrivateMessage(msg, recipientKey, [cb]) Send a private message to a recipient. Open and focus a new private message channel if one doesn't exist already. **Params** - msg string - a message object conforming to any type of chat message (e.g. `chat/text` or `chat/emote`), see CabalDetails.publishMessage for more information - recipientKey string - the public key of the recipient - *cb* function - optional callback triggered after trying to publish (returns err if failed) * * * ### cabalDetails.getJoinedChannels() ⇒ Array.<string> **Returns**: Array.<string> - A list of all of the channel names the user has joined. Excludes private message channels. * * * ### cabalDetails.getLocalUser() ⇒ user **Returns**: user - The local user for this cabal. * * * ### cabalDetails.getLocalName() ⇒ string **Returns**: string - The local user's username (or their truncated public key, if their username is not set) * * * ### cabalDetails.joinChannel(channel) Join a channel. This is distinct from focusing a channel, as this actually tracks changes and publishes a message announcing that you have joined the channel **Params** - channel string * * * ### cabalDetails.leaveChannel(channel) Leave a joined channel. This publishes a message announcing that you have left the channel. **Params** - channel string * * * ### cabalDetails.archiveChannel(channel, [reason], cb(err)) Archive a channel. Publishes a message announcing that you have archived the channel, applying it to the views of others who have you as a moderator/admin. **Params** - channel string - *reason* string - cb(err) function - callback invoked when the operation has finished, with error as its only parameter * * * ### cabalDetails.unarchiveChannel(channel, [reason], cb(err)) Unarchive a channel. Publishes a message announcing that you have unarchived the channel. **Params** - channel string - *reason* string - cb(err) function - callback invoked when the operation has finished, with error as its only parameter * * * ### cabalDetails.getUsers() ⇒ object **Returns**: object - all of the users in this cabal. Each key is the public key of its corresponding user. * * * ### cabalDetails.\_destroy() Destroy all of the listeners associated with this `details` instance * * * ### "update" **Kind**: event emitted by [CabalDetails](#CabalDetails) **Properties** | Name | Type | Description | | --- | --- | --- | | local | boolean | | | online | boolean | | | name | string | The user's username | | key | string | The user's public key | | flags | Map.<string, string> | The user's array of flags per channel ("@" means cabal-wide"). Possible flags include {"admin", "mod", "normal", "hide", "mute", "block"}. | * * * ### "init" Fires when the cabal has finished initialization **Kind**: event emitted by [CabalDetails](#CabalDetails) * * * ### "user-updated" Fires when a user has updated their nickname **Kind**: event emitted by [CabalDetails](#CabalDetails) **Properties** | Name | Type | Description | | --- | --- | --- | | key | string | Public key of the updated user | | user | object | Object containing user information | | user.name | string | Current nickname of the updated user | * * * ### "new-channel" Fires when a new channel has been created **Kind**: event emitted by [CabalDetails](#CabalDetails) **Properties** | Name | Type | Description | | --- | --- | --- | | channel | string | Name of the created channel | * * * ### "new-message" Fires when a new message has been posted **Kind**: event emitted by [CabalDetails](#CabalDetails) **Properties** | Name | Type | Description | | --- | --- | --- | | channel | string | Name of the channel the message was posted to | | author | object | Object containing the user that posted the message | | author.name | string | Nickname of the user | | author.key | string | Public key of the user | | author.local | boolean | True if user is the local user (i.e. at the keyboard and not someone else in the cabal) | | author.online | boolean | True if the user is currently online | | message | object | The message that was posted. See `cabal-core` for more complete message documentation. | | message.key | string | Public key of the user posting the message (again, it's a quirk) | | message.seq | number | Sequence number of the message in the user's append-only log | | message.value | object | Message content, see `cabal-core` documentation for more information. | * * * ### "private-message" Fires when a new private message has been posted **Kind**: event emitted by [CabalDetails](#CabalDetails) **Properties** | Name | Type | Description | | --- | --- | --- | | channel | string | The public key corresponding to the private message channel | | author | object | Object containing the user that posted the message | | author.name | string | Nickname of the user | | author.key | string | Public key of the user | | author.local | boolean | True if user is the local user (i.e. at the keyboard and not someone else in the cabal) | | author.online | boolean | True if the user is currently online | | message | object | The message that was posted. See `cabal-core` for more complete message documentation. | | message.key | string | Public key of the user posting the message (again, it's a quirk) | | message.seq | number | Sequence number of the message in the user's append-only log | | message.value | object | Message content, see `cabal-core` documentation for more information. | * * * ### "publish-message" Fires when the local user has published a new message **Kind**: event emitted by [CabalDetails](#CabalDetails) **Properties** | Name | Type | Description | | --- | --- | --- | | message | object | The message that was posted. See `cabal-core` for more complete message documentation. | | message.type | string | Message type that was posted, e.g. `chat/text` or `chat/emote` | | message.content | string | Message contents, e.g. channel and text if `chat/text` | | message.timestamp | number | The time the message was published | * * * ### "publish-private-message" Fires when the local user has published a new private message **Kind**: event emitted by [CabalDetails](#CabalDetails) **Properties** | Name | Type | Description | | --- | --- | --- | | message | object | The message that was posted. See `cabal-core` for more complete message documentation. | | message.type | string | Message type that was posted, e.g. `chat/text` or `chat/emote` | | message.content | string | Message contents, e.g. channel and text if `chat/text` | | message.timestamp | number | The time the message was published | * * * ### "publish-nick" Fires when the local user has published a new nickname **Kind**: event emitted by [CabalDetails](#CabalDetails) **Properties** | Name | Type | Description | | --- | --- | --- | | name | string | The nickname that was published | * * * ### "status-message" Fires when a status message has been created. These are only visible by the local user. **Kind**: event emitted by [CabalDetails](#CabalDetails) **Properties** | Name | Type | Description | | --- | --- | --- | | channel | string | Name of the channel the message was published to | | message | object | | | message.timestamp | number | Publish timestamp | | message.text | string | The published status message contents | * * * ### "topic" Fires when a new channel topic has been set **Kind**: event emitted by [CabalDetails](#CabalDetails) **Properties** | Name | Type | Description | | --- | --- | --- | | channel | string | Name of the channel with the new topic | | topic | string | Name of the channel with the new topic | * * * ### "channel-focus" Fires when the user has focused (i.e. switched to) a new channel **Kind**: event emitted by [CabalDetails](#CabalDetails) **Properties** | Name | Type | Description | | --- | --- | --- | | channel | string | Name of the focused channel | * * * ### "channel-join" Fires when a user has joined a channel **Kind**: event emitted by [CabalDetails](#CabalDetails) **Properties** | Name | Type | Description | | --- | --- | --- | | channel | string | Name of the joined channel | | key | string | Public key of the user joining the channel | | isLocal | boolean | True if it was the local user joining a new channel | * * * ### "channel-leave" Fires when a user has leaveed a channel **Kind**: event emitted by [CabalDetails](#CabalDetails) **Properties** | Name | Type | Description | | --- | --- | --- | | channel | string | Name of the leaved channel | | key | string | Public key of the user leaving the channel | | isLocal | boolean | True if it was the local user leaving a new channel | * * * ### "cabal-focus" Fires when another cabal has been focused **Kind**: event emitted by [CabalDetails](#CabalDetails) **Properties** | Name | Type | Description | | --- | --- | --- | | key | string | Key of the focused cabal | * * * ### "started-peering" Fires when the local user has connected directly with another peer **Kind**: event emitted by [CabalDetails](#CabalDetails) **Properties** | Name | Type | Description | | --- | --- | --- | | key | string | Public key of the other peer | | name- | string | Name of the other peer | * * * ### "stopped-peering" Fires when the local user has disconnected with another peer **Kind**: event emitted by [CabalDetails](#CabalDetails) **Properties** | Name | Type | Description | | --- | --- | --- | | key | string | Public key of the other peer | | name- | string | Name of the other peer | * * * ### "update" Fires when any kind of change has happened to the cabal. **Kind**: event emitted by [CabalDetails](#CabalDetails) * * * ### "info" Fires when a valid slash-command (/) emits output. See src/commands.js for all commands & their payloads. **Kind**: event emitted by [CabalDetails](#CabalDetails) **Properties** | Name | Type | Description | | --- | --- | --- | | command | string | The command that triggered the event & has emitted output | * * *