feat(plugins): allow message introspection (#6353)
This allows users to introspect messages (i.e. look at the elements they're made up of). Reviewed-by: Mm2PL <mm2pl+gh@kotmisia.pl>
This commit is contained in:
Vendored
+125
-1
@@ -160,8 +160,24 @@ declare namespace c2 {
|
||||
var WebSocket: WebSocketConstructor;
|
||||
|
||||
interface Message {
|
||||
__dummy: void; // avoid being an empty interface
|
||||
flags: MessageFlag;
|
||||
id: string;
|
||||
parse_time: number;
|
||||
search_text: string;
|
||||
message_text: string;
|
||||
login_name: string;
|
||||
display_name: string;
|
||||
localized_name: string;
|
||||
user_id: string;
|
||||
channel_name: string;
|
||||
username_color: string;
|
||||
server_received_time: number;
|
||||
highlight_color: string | null;
|
||||
frozen: boolean;
|
||||
elements(): MessageElement[];
|
||||
append_element(init: MessageElementInit): void;
|
||||
}
|
||||
|
||||
interface MessageConstructor {
|
||||
new: (this: void, init: MessageInit) => Message;
|
||||
}
|
||||
@@ -184,6 +200,14 @@ declare namespace c2 {
|
||||
elements?: MessageElementInit[];
|
||||
}
|
||||
|
||||
interface MessageElementBase {
|
||||
flags: MessageElementFlag;
|
||||
tooltip: string;
|
||||
trailing_space: boolean;
|
||||
link: Link;
|
||||
add_flags(flags: MessageElementFlag): void;
|
||||
}
|
||||
|
||||
interface MessageElementInitBase {
|
||||
tooltip?: string;
|
||||
trailing_space?: boolean;
|
||||
@@ -192,6 +216,25 @@ declare namespace c2 {
|
||||
|
||||
type MessageColor = "text" | "link" | "system" | string;
|
||||
|
||||
type MessageElement =
|
||||
| TextElement
|
||||
| SingleLineTextElement
|
||||
| MentionElement
|
||||
| TimestampElement
|
||||
| TwitchModerationElement
|
||||
| LinebreakElement
|
||||
| ReplyCurveElement
|
||||
| LinkElement
|
||||
| EmoteElement
|
||||
| LayeredEmoteElement
|
||||
| ImageElement
|
||||
| CircularImageElement
|
||||
| ScalingImageElement
|
||||
| BadgeElement
|
||||
| ModBadgeElement
|
||||
| VipBadgeElement
|
||||
| FfzBadgeElement;
|
||||
|
||||
type MessageElementInit =
|
||||
| TextElementInit
|
||||
| SingleLineTextElementInit
|
||||
@@ -201,6 +244,13 @@ declare namespace c2 {
|
||||
| LinebreakElementInit
|
||||
| ReplyCurveElementInit;
|
||||
|
||||
interface TextElement extends MessageElementBase {
|
||||
type: "text";
|
||||
words: string[];
|
||||
color: string;
|
||||
style: c2.FontStyle;
|
||||
}
|
||||
|
||||
interface TextElementInit extends MessageElementInitBase {
|
||||
type: "text";
|
||||
text: string;
|
||||
@@ -209,6 +259,13 @@ declare namespace c2 {
|
||||
style?: FontStyle;
|
||||
}
|
||||
|
||||
interface SingleLineTextElement extends MessageElementBase {
|
||||
type: "single-line-text";
|
||||
words: string[];
|
||||
color: string;
|
||||
style: c2.FontStyle;
|
||||
}
|
||||
|
||||
interface SingleLineTextElementInit extends MessageElementInitBase {
|
||||
type: "single-line-text";
|
||||
text: string;
|
||||
@@ -217,6 +274,14 @@ declare namespace c2 {
|
||||
style?: FontStyle;
|
||||
}
|
||||
|
||||
interface MentionElement extends Omit<TextElement, "type"> {
|
||||
type: "mention";
|
||||
display_name: string;
|
||||
login_name: string;
|
||||
fallback_color: string;
|
||||
user_color: string;
|
||||
}
|
||||
|
||||
interface MentionElementInit extends MessageElementInitBase {
|
||||
type: "mention";
|
||||
display_name: string;
|
||||
@@ -225,24 +290,83 @@ declare namespace c2 {
|
||||
user_color: MessageColor;
|
||||
}
|
||||
|
||||
interface TimestampElement extends MessageElementBase {
|
||||
type: "timestamp";
|
||||
time: number;
|
||||
}
|
||||
|
||||
interface TimestampElementInit extends MessageElementInitBase {
|
||||
type: "timestamp";
|
||||
time?: number;
|
||||
}
|
||||
|
||||
interface TwitchModerationElement extends MessageElementBase {
|
||||
type: "twitch-moderation";
|
||||
}
|
||||
|
||||
interface TwitchModerationElementInit extends MessageElementInitBase {
|
||||
type: "twitch-moderation";
|
||||
}
|
||||
|
||||
interface LinebreakElement extends MessageElementBase {
|
||||
type: "linebreak";
|
||||
}
|
||||
|
||||
interface LinebreakElementInit extends MessageElementInitBase {
|
||||
type: "linebreak";
|
||||
flags?: MessageElementFlag;
|
||||
}
|
||||
|
||||
interface ReplyCurveElement extends MessageElementBase {
|
||||
type: "reply-curve";
|
||||
}
|
||||
|
||||
interface ReplyCurveElementInit extends MessageElementInitBase {
|
||||
type: "reply-curve";
|
||||
}
|
||||
|
||||
interface LinkElement extends Omit<TextElement, "type"> {
|
||||
type: "link";
|
||||
lowercase: string;
|
||||
original: string;
|
||||
}
|
||||
|
||||
interface EmoteElement extends MessageElementBase {
|
||||
type: "emote";
|
||||
}
|
||||
|
||||
interface LayeredEmoteElement extends MessageElementBase {
|
||||
type: "layered-emote";
|
||||
}
|
||||
|
||||
interface ImageElement extends MessageElementBase {
|
||||
type: "image";
|
||||
}
|
||||
|
||||
interface CircularImageElement extends MessageElementBase {
|
||||
type: "circular-image";
|
||||
}
|
||||
|
||||
interface ScalingImageElement extends MessageElementBase {
|
||||
type: "scaling-image";
|
||||
}
|
||||
|
||||
interface BadgeElement extends MessageElementBase {
|
||||
type: "badge";
|
||||
}
|
||||
|
||||
interface ModBadgeElement extends Omit<BadgeElement, "type"> {
|
||||
type: "mod-badge";
|
||||
}
|
||||
|
||||
interface VipBadgeElement extends Omit<BadgeElement, "type"> {
|
||||
type: "ffz-badge";
|
||||
}
|
||||
|
||||
interface FfzBadgeElement extends Omit<BadgeElement, "type"> {
|
||||
type: "ffz-badge";
|
||||
}
|
||||
|
||||
interface Link {
|
||||
type: LinkType;
|
||||
value: string;
|
||||
|
||||
+150
-50
@@ -299,10 +299,160 @@ function c2.HTTPRequest.create(method, url) end
|
||||
-- Begin src/controllers/plugins/api/Message.hpp
|
||||
|
||||
|
||||
|
||||
---@class c2.MessageElementBase
|
||||
---@field flags c2.MessageElementFlag The element's flags
|
||||
---@field tooltip string The tooltip (if any)
|
||||
---@field trailing_space boolean Whether to add a trailing space after the element
|
||||
---@field link c2.Link An action when clicking on this element. Mention and Link elements don't support this. They manage the link themselves.
|
||||
c2.MessageElementBase = {}
|
||||
-- ^^^ this is kinda fake - this table doesn't exist in Lua, we only declare it to add methods
|
||||
|
||||
--- Add flags to this element
|
||||
---
|
||||
---@param flags c2.MessageElementFlag
|
||||
function c2.MessageElementBase:add_flags(flags) end
|
||||
|
||||
---A base table to initialize a new message element
|
||||
---@class MessageElementInitBase
|
||||
---@field tooltip? string Tooltip text
|
||||
---@field trailing_space? boolean Whether to add a trailing space after the element (default: true)
|
||||
---@field link? c2.Link An action when clicking on this element. Mention and Link elements don't support this. They manage the link themselves.
|
||||
|
||||
---@class c2.TextElement : c2.MessageElementBase
|
||||
---@field type "text"
|
||||
---@field words string[] The words of this element
|
||||
---@field color string The color of the text
|
||||
---@field style c2.FontStyle The font style of the text
|
||||
|
||||
---A table to initialize a new message text element
|
||||
---@class TextElementInit : MessageElementInitBase
|
||||
---@field type "text" The type of the element
|
||||
---@field text string The text of this element
|
||||
---@field flags? c2.MessageElementFlag Message element flags (see `c2.MessageElementFlags`)
|
||||
---@field color? MessageColor The color of the text
|
||||
---@field style? c2.FontStyle The font style of the text
|
||||
|
||||
---@class c2.SingleLineTextElement : c2.MessageElementBase
|
||||
---@field type "single-line-text"
|
||||
---@field words string[] The words of this element
|
||||
---@field color string The color of the text
|
||||
---@field style c2.FontStyle The font style of the text
|
||||
|
||||
---A table to initialize a new message single-line text element
|
||||
---@class SingleLineTextElementInit : MessageElementInitBase
|
||||
---@field type "single-line-text" The type of the element
|
||||
---@field text string The text of this element
|
||||
---@field flags? c2.MessageElementFlag Message element flags (see `c2.MessageElementFlags`)
|
||||
---@field color? MessageColor The color of the text
|
||||
---@field style? c2.FontStyle The font style of the text
|
||||
|
||||
---@class c2.MentionElement : c2.TextElement
|
||||
---@field type "mention"
|
||||
---@field login_name string The login name of the mentioned user
|
||||
---@field fallback_color MessageColor The color of the element in case the "Colorize @usernames" is disabled
|
||||
---@field user_color MessageColor The color of the element in case the "Colorize @usernames" is enabled
|
||||
|
||||
---A table to initialize a new mention element
|
||||
---@class MentionElementInit : MessageElementInitBase
|
||||
---@field type "mention" The type of the element
|
||||
---@field display_name string The display name of the mentioned user
|
||||
---@field login_name string The login name of the mentioned user
|
||||
---@field fallback_color MessageColor The color of the element in case the "Colorize @usernames" is disabled
|
||||
---@field user_color MessageColor The color of the element in case the "Colorize @usernames" is enabled
|
||||
|
||||
---@class c2.TimestampElement : c2.MessageElementBase
|
||||
---@field type "timestamp"
|
||||
---@field time number The time of the timestamp (in milliseconds since epoch).
|
||||
|
||||
---A table to initialize a new timestamp element
|
||||
---@class TimestampElementInit : MessageElementInitBase
|
||||
---@field type "timestamp" The type of the element
|
||||
---@field time number? The time of the timestamp (in milliseconds since epoch). If not provided, the current time is used.
|
||||
|
||||
---@class c2.TwitchModerationElement : c2.MessageElementBase
|
||||
---@field type "twitch-moderation"
|
||||
|
||||
---A table to initialize a new Twitch moderation element (all the custom moderation buttons)
|
||||
---@class TwitchModerationElementInit : MessageElementInitBase
|
||||
---@field type "twitch-moderation" The type of the element
|
||||
|
||||
---@class c2.LinebreakElement : c2.MessageElementBase
|
||||
---@field type "linebreak"
|
||||
|
||||
---A table to initialize a new linebreak element
|
||||
---@class LinebreakElementInit : MessageElementInitBase
|
||||
---@field type "linebreak" The type of the element
|
||||
---@field flags? c2.MessageElementFlag Message element flags (see `c2.MessageElementFlags`)
|
||||
|
||||
---@class c2.ReplyCurveElement : c2.MessageElementBase
|
||||
---@field type "reply-curve"
|
||||
|
||||
---A table to initialize a new reply curve element
|
||||
---@class ReplyCurveElementInit : MessageElementInitBase
|
||||
---@field type "reply-curve" The type of the element
|
||||
|
||||
---@class c2.LinkElement : c2.TextElement
|
||||
---@field type "link"
|
||||
|
||||
---@class c2.EmoteElement : c2.MessageElementBase
|
||||
---@field type "emote"
|
||||
|
||||
---@class c2.LayeredEmoteElement : c2.MessageElementBase
|
||||
---@field type "layered-emote"
|
||||
|
||||
---@class c2.ImageElement : c2.MessageElementBase
|
||||
---@field type "image"
|
||||
|
||||
---@class c2.CircularImageElement : c2.MessageElementBase
|
||||
---@field type "circular-image"
|
||||
|
||||
---@class c2.ScalingImageElement : c2.MessageElementBase
|
||||
---@field type "scaling-image"
|
||||
|
||||
---@class c2.BadgeElement : c2.MessageElementBase
|
||||
---@field type "badge"
|
||||
|
||||
---@class c2.ModBadgeElement : c2.BadgeElement
|
||||
---@field type "mod-badge"
|
||||
|
||||
---@class c2.VipBadgeElement : c2.BadgeElement
|
||||
---@field type "vip-badge"
|
||||
|
||||
---@class c2.FfzBadgeElement : c2.BadgeElement
|
||||
---@field type "ffz-badge"
|
||||
|
||||
---@alias MessageElement c2.TextElement|c2.SingleLineTextElement|c2.MentionElement|c2.TimestampElement|c2.TwitchModerationElement|c2.LinebreakElement|c2.ReplyCurveElement|c2.LinkElement|c2.EmoteElement|c2.LayeredEmoteElement|c2.ImageElement|c2.CircularImageElement|c2.ScalingImageElement|c2.BadgeElement|c2.ModBadgeElement|c2.VipBadgeElement|c2.FfzBadgeElement
|
||||
---@alias MessageElementInit TextElementInit|SingleLineTextElementInit|MentionElementInit|TimestampElementInit|TwitchModerationElementInit|LinebreakElementInit|ReplyCurveElementInit
|
||||
|
||||
---A chat message
|
||||
---@class c2.Message
|
||||
---@field flags c2.MessageFlag The message's flags
|
||||
---@field parse_time number Time the message was parsed (in milliseconds since epoch)
|
||||
---@field id string The message ID
|
||||
---@field search_text string Text to check when searching for messages
|
||||
---@field message_text string Text content of this message (used for filters for example)
|
||||
---@field login_name string The login name of the sender
|
||||
---@field display_name string The dispay name of the sender
|
||||
---@field localized_name string The localized name of the sender (this is used for CJK names, otherwise it's empty)
|
||||
---@field user_id string The ID of the sender
|
||||
---@field channel_name string The name of the channel this message appeared in
|
||||
---@field username_color string The color of the username
|
||||
---@field server_received_time number The time the server received the message (in milliseconds since epoch)
|
||||
---@field highlight_color string The color of the highlight or empty
|
||||
---@field frozen boolean If this is set, Lua plugins can't modify this message (as it's visible to the user).
|
||||
c2.Message = {}
|
||||
|
||||
--- The elements this message is made up of
|
||||
---
|
||||
---@return MessageElement[] elements
|
||||
function c2.Message:elements() end
|
||||
|
||||
--- Add an element to this message.
|
||||
---
|
||||
---@param init MessageElementInit The element to add
|
||||
function c2.Message:append_element(init) end
|
||||
|
||||
---A table to initialize a new message
|
||||
---@class MessageInit
|
||||
---@field flags? c2.MessageFlag Message flags (see `c2.MessageFlags`)
|
||||
@@ -320,58 +470,8 @@ c2.Message = {}
|
||||
---@field highlight_color? string|nil The color of the highlight (if any)
|
||||
---@field elements? MessageElementInit[] The elements of the message
|
||||
|
||||
---A base table to initialize a new message element
|
||||
---@class MessageElementInitBase
|
||||
---@field tooltip? string Tooltip text
|
||||
---@field trailing_space? boolean Whether to add a trailing space after the element (default: true)
|
||||
---@field link? c2.Link An action when clicking on this element. Mention and Link elements don't support this. They manage the link themselves.
|
||||
|
||||
---@alias MessageColor "text"|"link"|"system"|string A color for a text element - "text", "link", and "system" are special values that take the current theme into account
|
||||
|
||||
---A table to initialize a new message text element
|
||||
---@class TextElementInit : MessageElementInitBase
|
||||
---@field type "text" The type of the element
|
||||
---@field text string The text of this element
|
||||
---@field flags? c2.MessageElementFlag Message element flags (see `c2.MessageElementFlags`)
|
||||
---@field color? MessageColor The color of the text
|
||||
---@field style? c2.FontStyle The font style of the text
|
||||
|
||||
---A table to initialize a new message single-line text element
|
||||
---@class SingleLineTextElementInit : MessageElementInitBase
|
||||
---@field type "single-line-text" The type of the element
|
||||
---@field text string The text of this element
|
||||
---@field flags? c2.MessageElementFlag Message element flags (see `c2.MessageElementFlags`)
|
||||
---@field color? MessageColor The color of the text
|
||||
---@field style? c2.FontStyle The font style of the text
|
||||
|
||||
---A table to initialize a new mention element
|
||||
---@class MentionElementInit : MessageElementInitBase
|
||||
---@field type "mention" The type of the element
|
||||
---@field display_name string The display name of the mentioned user
|
||||
---@field login_name string The login name of the mentioned user
|
||||
---@field fallback_color MessageColor The color of the element in case the "Colorize @usernames" is disabled
|
||||
---@field user_color MessageColor The color of the element in case the "Colorize @usernames" is enabled
|
||||
|
||||
---A table to initialize a new timestamp element
|
||||
---@class TimestampElementInit : MessageElementInitBase
|
||||
---@field type "timestamp" The type of the element
|
||||
---@field time number? The time of the timestamp (in milliseconds since epoch). If not provided, the current time is used.
|
||||
|
||||
---A table to initialize a new Twitch moderation element (all the custom moderation buttons)
|
||||
---@class TwitchModerationElementInit : MessageElementInitBase
|
||||
---@field type "twitch-moderation" The type of the element
|
||||
|
||||
---A table to initialize a new linebreak element
|
||||
---@class LinebreakElementInit : MessageElementInitBase
|
||||
---@field type "linebreak" The type of the element
|
||||
---@field flags? c2.MessageElementFlag Message element flags (see `c2.MessageElementFlags`)
|
||||
|
||||
---A table to initialize a new reply curve element
|
||||
---@class ReplyCurveElementInit : MessageElementInitBase
|
||||
---@field type "reply-curve" The type of the element
|
||||
|
||||
---@alias MessageElementInit TextElementInit|SingleLineTextElementInit|MentionElementInit|TimestampElementInit|TwitchModerationElementInit|LinebreakElementInit|ReplyCurveElementInit
|
||||
|
||||
--- Creates a new message
|
||||
---
|
||||
---@param init MessageInit The message initialization table
|
||||
|
||||
+72
-1
@@ -620,7 +620,26 @@ Closes the WebSocket connection.
|
||||
|
||||
#### `Message`
|
||||
|
||||
Allows creation of rich chat messages. This is currently limited but is expected to be expanded soon.
|
||||
Allows creation and modification of rich chat messages. A `Message` is
|
||||
Chatterino's representation of a chat message or any system message.
|
||||
The interface to Lua is currently limited but is expected to be expanded soon.
|
||||
|
||||
Messages can be added to a [`Channel`](#channel). Once a message is added to a
|
||||
channel, it can't be modified anymore (except for its `flags`). These messages
|
||||
are termed "frozen" (immutable). You can check for this using the `frozen`
|
||||
property:
|
||||
|
||||
```lua
|
||||
local my_msg = c2.Message.new({ id = "foobar" })
|
||||
assert(not my_msg.frozen)
|
||||
my_channel:add_message(my_msg)
|
||||
assert(my_msg.frozen)
|
||||
```
|
||||
|
||||
A message has the same properties that it takes in its constructor (e.g.
|
||||
`msg.id` or `msg.flags`). If the message is not frozen (mutable), these
|
||||
properties can be modified. New elements can be added with
|
||||
[`append_element`](#messageappend_elementdata).
|
||||
|
||||
##### `Message.new(data)`
|
||||
|
||||
@@ -654,6 +673,58 @@ end)
|
||||
|
||||
The full range of options can be found in the typing files ([LuaLS](./lua-meta/globals.lua), [TypeScript](./chatterino.d.ts)).
|
||||
|
||||
##### `Message:elements()`
|
||||
|
||||
Gets a reference to the message's elements. This can be indexed or iterated
|
||||
though. Through the return value, you can also remove elements. Note that
|
||||
currently, new elements can't be added here (use `Message:append_element`).
|
||||
|
||||
The return value can be thought of as a table of `MessageElement`s.
|
||||
|
||||
```lua
|
||||
local my_msg = c2.Message.new({
|
||||
id = "foo",
|
||||
elements = {
|
||||
{ type = "text", text = "foo" },
|
||||
{ type = "text", text = "bar" },
|
||||
{ type = "text", text = "baz" },
|
||||
}
|
||||
})
|
||||
local elements = my_msg:elements()
|
||||
assert(#elements == 3)
|
||||
assert(elements[1].words[1] == "foo")
|
||||
assert(elements[2].words[1] == "bar")
|
||||
|
||||
elements:erase(2) -- erase "bar"
|
||||
assert(#elements == 2)
|
||||
assert(elements[1].words[1] == "foo")
|
||||
assert(elements[2].words[1] == "baz")
|
||||
```
|
||||
|
||||
##### `Message:append_element(data)`
|
||||
|
||||
Creates a message element from a table (`data`) and appends it to the message.
|
||||
The structure of the table matches the one taken in `Message.new`'s `elements`.
|
||||
|
||||
```lua
|
||||
local my_msg = c2.Message.new({ id = "foo" })
|
||||
my_msg:append_element({
|
||||
type = "text",
|
||||
text = "My text element",
|
||||
})
|
||||
```
|
||||
|
||||
#### `MessageElement`
|
||||
|
||||
A reference to an element inside a `Message` (essentially an in index into the
|
||||
elements). Note that modifications to the elements of the parent `Message` might
|
||||
change the actual element this is referring to.
|
||||
|
||||
To distinguish different types of elements, check the `type` property. This
|
||||
takes the same values as `element.type` in the `Message` constructor.
|
||||
|
||||
The full range of properties can be found in the typing files ([LuaLS](./lua-meta/globals.lua), [TypeScript](./chatterino.d.ts)).
|
||||
|
||||
#### `LinkType` enum
|
||||
|
||||
This table describes links available to plugins.
|
||||
|
||||
Reference in New Issue
Block a user