Add Plugin.start, make Settings actually start/stop plugins
This commit is contained in:
parent
bac8a648b6
commit
f60ccb766f
10 changed files with 146 additions and 58 deletions
|
@ -1,4 +1,4 @@
|
||||||
lockfileVersion: 5.4
|
lockfileVersion: 5.3
|
||||||
|
|
||||||
specifiers:
|
specifiers:
|
||||||
'@types/flux': ^3.1.11
|
'@types/flux': ^3.1.11
|
||||||
|
|
|
@ -1,24 +1,31 @@
|
||||||
import IPC_EVENTS from './utils/IpcEvents';
|
import IPC_EVENTS from './utils/IpcEvents';
|
||||||
import { IpcRenderer, ipcRenderer } from 'electron';
|
import { IpcRenderer, ipcRenderer } from 'electron';
|
||||||
|
|
||||||
|
function assertEventAllowed(event: string) {
|
||||||
|
if (!(event in IPC_EVENTS)) throw new Error(`Event ${event} not allowed.`);
|
||||||
|
}
|
||||||
export default {
|
export default {
|
||||||
getVersions: () => process.versions,
|
getVersions: () => process.versions,
|
||||||
ipc: {
|
ipc: {
|
||||||
send(event: string, ...args: any[]) {
|
send(event: string, ...args: any[]) {
|
||||||
if (event in IPC_EVENTS) ipcRenderer.send(event, ...args);
|
assertEventAllowed(event);
|
||||||
else throw new Error(`Event ${event} not allowed.`);
|
ipcRenderer.send(event, ...args);
|
||||||
},
|
},
|
||||||
sendSync<T = any>(event: string, ...args: any[]): T {
|
sendSync<T = any>(event: string, ...args: any[]): T {
|
||||||
if (event in IPC_EVENTS) return ipcRenderer.sendSync(event, ...args);
|
assertEventAllowed(event);
|
||||||
else throw new Error(`Event ${event} not allowed.`);
|
return ipcRenderer.sendSync(event, ...args);
|
||||||
},
|
},
|
||||||
on(event: string, listener: Parameters<IpcRenderer["on"]>[1]) {
|
on(event: string, listener: Parameters<IpcRenderer["on"]>[1]) {
|
||||||
if (event in IPC_EVENTS) ipcRenderer.on(event, listener);
|
assertEventAllowed(event);
|
||||||
else throw new Error(`Event ${event} not allowed.`);
|
ipcRenderer.on(event, listener);
|
||||||
|
},
|
||||||
|
off(event: string, listener: Parameters<IpcRenderer["off"]>[1]) {
|
||||||
|
assertEventAllowed(event);
|
||||||
|
ipcRenderer.off(event, listener);
|
||||||
},
|
},
|
||||||
invoke<T = any>(event: string, ...args: any[]): Promise<T> {
|
invoke<T = any>(event: string, ...args: any[]): Promise<T> {
|
||||||
if (event in IPC_EVENTS) return ipcRenderer.invoke(event, ...args);
|
assertEventAllowed(event);
|
||||||
else throw new Error(`Event ${event} not allowed.`);
|
return ipcRenderer.invoke(event, ...args);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
require(mod: string) {
|
require(mod: string) {
|
||||||
|
|
|
@ -3,10 +3,10 @@ import Logger from '../utils/logger';
|
||||||
|
|
||||||
const MessageEventsLogger = new Logger("MessageEvents", "#e5c890");
|
const MessageEventsLogger = new Logger("MessageEvents", "#e5c890");
|
||||||
|
|
||||||
interface Emoji {
|
export interface Emoji {
|
||||||
require_colons: boolean,
|
require_colons: boolean,
|
||||||
originalName: string,
|
originalName: string,
|
||||||
animated: boolean
|
animated: boolean;
|
||||||
guildId: string,
|
guildId: string,
|
||||||
name: string,
|
name: string,
|
||||||
url: string,
|
url: string,
|
||||||
|
@ -15,11 +15,11 @@ interface Emoji {
|
||||||
|
|
||||||
interface MessageObject {
|
interface MessageObject {
|
||||||
content: string,
|
content: string,
|
||||||
validNonShortcutEmojis: Emoji[]
|
validNonShortcutEmojis: Emoji[];
|
||||||
}
|
}
|
||||||
|
|
||||||
type SendListener = (channelId: string, messageObj: MessageObject, extra: any) => void;
|
export type SendListener = (channelId: string, messageObj: MessageObject, extra: any) => void;
|
||||||
type EditListener = (channelId: string, messageId: string, messageObj: MessageObject) => void;
|
export type EditListener = (channelId: string, messageId: string, messageObj: MessageObject) => void;
|
||||||
|
|
||||||
const sendListeners = new Set<SendListener>();
|
const sendListeners = new Set<SendListener>();
|
||||||
const editListeners = new Set<EditListener>();
|
const editListeners = new Set<EditListener>();
|
||||||
|
@ -28,7 +28,7 @@ export function _handlePreSend(channelId: string, messageObj: MessageObject, ext
|
||||||
for (const listener of sendListeners) {
|
for (const listener of sendListeners) {
|
||||||
try {
|
try {
|
||||||
listener(channelId, messageObj, extra);
|
listener(channelId, messageObj, extra);
|
||||||
} catch (e) { MessageEventsLogger.error(`MessageSendHandler: Listener encoutered an unknown error. (${e})`) }
|
} catch (e) { MessageEventsLogger.error(`MessageSendHandler: Listener encoutered an unknown error. (${e})`); }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -36,20 +36,31 @@ export function _handlePreEdit(channeld: string, messageId: string, messageObj:
|
||||||
for (const listener of editListeners) {
|
for (const listener of editListeners) {
|
||||||
try {
|
try {
|
||||||
listener(channeld, messageId, messageObj);
|
listener(channeld, messageId, messageObj);
|
||||||
} catch (e) { MessageEventsLogger.error(`MessageEditHandler: Listener encoutered an unknown error. (${e})`) }
|
} catch (e) { MessageEventsLogger.error(`MessageEditHandler: Listener encoutered an unknown error. (${e})`); }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Note: This event fires off before a message is sent, allowing you to edit the message.
|
* Note: This event fires off before a message is sent, allowing you to edit the message.
|
||||||
*/
|
*/
|
||||||
export function addPreSendListener(listener: SendListener) { sendListeners.add(listener) }
|
export function addPreSendListener(listener: SendListener) {
|
||||||
|
sendListeners.add(listener);
|
||||||
|
return listener;
|
||||||
|
}
|
||||||
/**
|
/**
|
||||||
* Note: This event fires off before a message's edit is applied, allowing you to further edit the message.
|
* Note: This event fires off before a message's edit is applied, allowing you to further edit the message.
|
||||||
*/
|
*/
|
||||||
export function addPreEditListener(listener: EditListener) { editListeners.add(listener) }
|
export function addPreEditListener(listener: EditListener) {
|
||||||
export function removePreSendListener(listener: SendListener) { sendListeners.delete(listener) }
|
editListeners.add(listener);
|
||||||
export function removePreEditListener(listener: EditListener) { editListeners.delete(listener) }
|
return listener;
|
||||||
|
}
|
||||||
|
export function removePreSendListener(listener: SendListener) {
|
||||||
|
return sendListeners.delete(listener);
|
||||||
|
}
|
||||||
|
export function removePreEditListener(listener: EditListener) {
|
||||||
|
return editListeners.delete(listener);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// Message clicks
|
// Message clicks
|
||||||
type ClickListener = (message: Message, channel: Channel, event: MouseEvent) => void;
|
type ClickListener = (message: Message, channel: Channel, event: MouseEvent) => void;
|
||||||
|
@ -60,12 +71,13 @@ export function _handleClick(message, channel, event) {
|
||||||
for (const listener of listeners) {
|
for (const listener of listeners) {
|
||||||
try {
|
try {
|
||||||
listener(message, channel, event);
|
listener(message, channel, event);
|
||||||
} catch (e) { MessageEventsLogger.error(`MessageClickHandler: Listener encoutered an unknown error. (${e})`) }
|
} catch (e) { MessageEventsLogger.error(`MessageClickHandler: Listener encoutered an unknown error. (${e})`); }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export function addClickListener(listener: ClickListener) {
|
export function addClickListener(listener: ClickListener) {
|
||||||
listeners.add(listener);
|
listeners.add(listener);
|
||||||
|
return listener;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function removeClickListener(listener: ClickListener) {
|
export function removeClickListener(listener: ClickListener) {
|
||||||
|
|
|
@ -5,6 +5,8 @@ import IpcEvents from "../utils/IpcEvents";
|
||||||
|
|
||||||
import { Button, ButtonProps, Flex, Switch, Forms } from "../webpack/common";
|
import { Button, ButtonProps, Flex, Switch, Forms } from "../webpack/common";
|
||||||
import ErrorBoundary from "./ErrorBoundary";
|
import ErrorBoundary from "./ErrorBoundary";
|
||||||
|
import { startPlugin } from "../plugins";
|
||||||
|
import { stopPlugin } from '../plugins/index';
|
||||||
|
|
||||||
export default ErrorBoundary.wrap(function Settings(props) {
|
export default ErrorBoundary.wrap(function Settings(props) {
|
||||||
const [settingsDir, , settingsDirPending] = useAwaiter(() => VencordNative.ipc.invoke<string>(IpcEvents.GET_SETTINGS_DIR), "Loading...");
|
const [settingsDir, , settingsDirPending] = useAwaiter(() => VencordNative.ipc.invoke<string>(IpcEvents.GET_SETTINGS_DIR), "Loading...");
|
||||||
|
@ -52,8 +54,19 @@ export default ErrorBoundary.wrap(function Settings(props) {
|
||||||
settings.plugins[p.name].enabled = v;
|
settings.plugins[p.name].enabled = v;
|
||||||
if (v) {
|
if (v) {
|
||||||
p.dependencies?.forEach(d => {
|
p.dependencies?.forEach(d => {
|
||||||
|
// TODO: start every dependency
|
||||||
settings.plugins[d].enabled = true;
|
settings.plugins[d].enabled = true;
|
||||||
});
|
});
|
||||||
|
if (!p.started && !startPlugin(p)) {
|
||||||
|
// TODO show notification
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (p.started && !stopPlugin(p)) {
|
||||||
|
// TODO show notification
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (p.patches) {
|
||||||
|
// TODO show notification
|
||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
note={p.description}
|
note={p.description}
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import Plugins from "plugins";
|
import Plugins from "plugins";
|
||||||
import { Settings } from "../api/settings";
|
import { Settings } from "../api/settings";
|
||||||
import Logger from "../utils/logger";
|
import Logger from "../utils/logger";
|
||||||
import { Patch } from "../utils/types";
|
import { Patch, Plugin } from "../utils/types";
|
||||||
|
|
||||||
const logger = new Logger("PluginManager", "#a6d189");
|
const logger = new Logger("PluginManager", "#a6d189");
|
||||||
|
|
||||||
|
@ -17,12 +17,43 @@ for (const plugin of Plugins) if (plugin.patches && Settings.plugins[plugin.name
|
||||||
}
|
}
|
||||||
|
|
||||||
export function startAll() {
|
export function startAll() {
|
||||||
for (const plugin of plugins) if (plugin.start && Settings.plugins[plugin.name].enabled) {
|
for (const plugin of plugins) if (Settings.plugins[plugin.name].enabled) {
|
||||||
|
startPlugin(plugin);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export function startPlugin(p: Plugin) {
|
||||||
|
if (p.start) {
|
||||||
|
logger.info("Starting plugin", p.name);
|
||||||
|
if (p.started) {
|
||||||
|
logger.warn(`${p.name} already started`);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
try {
|
try {
|
||||||
logger.info("Starting plugin", plugin.name);
|
p.start();
|
||||||
plugin.start();
|
p.started = true;
|
||||||
} catch (err) {
|
return true;
|
||||||
logger.error("Failed to start plugin", plugin.name, err);
|
} catch (err: any) {
|
||||||
|
logger.error(`Failed to start ${p.name}\n`, err);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export function stopPlugin(p: Plugin) {
|
||||||
|
if (p.stop) {
|
||||||
|
logger.info("Stopping plugin", p.name);
|
||||||
|
if (!p.started) {
|
||||||
|
logger.warn(`${p.name} already stopped / never started`);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
p.stop();
|
||||||
|
p.started = false;
|
||||||
|
return true;
|
||||||
|
} catch (err: any) {
|
||||||
|
logger.error(`Failed to stop ${p.name}\n`, err);
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -1,12 +1,17 @@
|
||||||
import { addClickListener } from "../api/MessageEvents";
|
import { addClickListener, removeClickListener } from '../api/MessageEvents';
|
||||||
import definePlugin from "../utils/types";
|
import definePlugin from "../utils/types";
|
||||||
import { find, findByProps } from "../webpack";
|
import { find, findByProps } from "../webpack";
|
||||||
|
|
||||||
|
let isDeletePressed = false;
|
||||||
|
const keydown = (e: KeyboardEvent) => e.key === "Backspace" && (isDeletePressed = true);
|
||||||
|
const keyup = (e: KeyboardEvent) => e.key === "Backspace" && (isDeletePressed = false);
|
||||||
|
|
||||||
export default definePlugin({
|
export default definePlugin({
|
||||||
name: "MessageQuickActions",
|
name: "MessageQuickActions",
|
||||||
description: "Quick Delete, Quick edit",
|
description: "Quick Delete, Quick edit",
|
||||||
author: "Vendicated",
|
author: "Vendicated",
|
||||||
dependencies: ["MessageEventsAPI"],
|
dependencies: ["MessageEventsAPI"],
|
||||||
|
|
||||||
start() {
|
start() {
|
||||||
const { deleteMessage, startEditMessage } = findByProps("deleteMessage");
|
const { deleteMessage, startEditMessage } = findByProps("deleteMessage");
|
||||||
const { can } = findByProps("can", "initialize");
|
const { can } = findByProps("can", "initialize");
|
||||||
|
@ -14,14 +19,10 @@ export default definePlugin({
|
||||||
const { getCurrentUser } = findByProps("getCurrentUser");
|
const { getCurrentUser } = findByProps("getCurrentUser");
|
||||||
|
|
||||||
let isDeletePressed = false;
|
let isDeletePressed = false;
|
||||||
document.addEventListener("keydown", e => {
|
document.addEventListener("keydown", keydown);
|
||||||
if (e.key === "Backspace") isDeletePressed = true;
|
document.addEventListener("keyup", keyup);
|
||||||
});
|
|
||||||
document.addEventListener("keyup", e => {
|
|
||||||
if (e.key === "Backspace") isDeletePressed = false;
|
|
||||||
});
|
|
||||||
|
|
||||||
addClickListener((msg, chan, event) => {
|
this.onClick = addClickListener((msg, chan, event) => {
|
||||||
const isMe = msg.author.id === getCurrentUser().id;
|
const isMe = msg.author.id === getCurrentUser().id;
|
||||||
if (!isDeletePressed) {
|
if (!isDeletePressed) {
|
||||||
if (isMe && event.detail >= 2) {
|
if (isMe && event.detail >= 2) {
|
||||||
|
@ -33,5 +34,11 @@ export default definePlugin({
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
stop() {
|
||||||
|
removeClickListener(this.onClick);
|
||||||
|
document.removeEventListener("keydown", keydown);
|
||||||
|
document.removeEventListener("keyup", keyup);
|
||||||
}
|
}
|
||||||
});
|
});
|
|
@ -1,4 +1,4 @@
|
||||||
import { addPreSendListener, addPreEditListener } from "../api/MessageEvents";
|
import { addPreSendListener, addPreEditListener, SendListener, removePreSendListener, removePreEditListener } from '../api/MessageEvents';
|
||||||
import { findByProps } from "../webpack";
|
import { findByProps } from "../webpack";
|
||||||
import definePlugin from "../utils/types";
|
import definePlugin from "../utils/types";
|
||||||
|
|
||||||
|
@ -22,6 +22,7 @@ export default definePlugin({
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
|
|
||||||
start() {
|
start() {
|
||||||
const { getCustomEmojiById } = findByProps("getCustomEmojiById");
|
const { getCustomEmojiById } = findByProps("getCustomEmojiById");
|
||||||
|
|
||||||
|
@ -33,7 +34,7 @@ export default definePlugin({
|
||||||
delete x.guildPremiumTier;
|
delete x.guildPremiumTier;
|
||||||
});
|
});
|
||||||
|
|
||||||
addPreSendListener((_, messageObj) => {
|
this.preSend = addPreSendListener((_, messageObj) => {
|
||||||
const guildId = window.location.href.split("channels/")[1].split("/")[0];
|
const guildId = window.location.href.split("channels/")[1].split("/")[0];
|
||||||
for (const emoji of messageObj.validNonShortcutEmojis) {
|
for (const emoji of messageObj.validNonShortcutEmojis) {
|
||||||
if (!emoji.require_colons) continue;
|
if (!emoji.require_colons) continue;
|
||||||
|
@ -44,7 +45,7 @@ export default definePlugin({
|
||||||
messageObj.content = messageObj.content.replace(emojiString, ` ${url} `);
|
messageObj.content = messageObj.content.replace(emojiString, ` ${url} `);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
addPreEditListener((_, __, messageObj) => {
|
this.preEdit = addPreEditListener((_, __, messageObj) => {
|
||||||
const guildId = window.location.href.split("channels/")[1].split("/")[0];
|
const guildId = window.location.href.split("channels/")[1].split("/")[0];
|
||||||
|
|
||||||
for (const [emojiStr, _, emojiId] of messageObj.content.matchAll(/(?<!\\)<a?:(\w+):(\d+)>/ig)) {
|
for (const [emojiStr, _, emojiId] of messageObj.content.matchAll(/(?<!\\)<a?:(\w+):(\d+)>/ig)) {
|
||||||
|
@ -56,4 +57,9 @@ export default definePlugin({
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
|
stop() {
|
||||||
|
removePreSendListener(this.preSend);
|
||||||
|
removePreEditListener(this.preEdit);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,27 +1,33 @@
|
||||||
export default class Logger {
|
export default class Logger {
|
||||||
constructor(public name: string, public color: string) { }
|
constructor(public name: string, public color: string) { }
|
||||||
|
|
||||||
private _log(level: "log" | "error" | "warn" | "info" | "debug", args: any[]) {
|
private _log(level: "log" | "error" | "warn" | "info" | "debug", levelColor: string, args: any[]) {
|
||||||
console[level](`%c ${this.name} `, `background: ${this.color}; color: black; font-weight: bold`, ...args);
|
console[level](
|
||||||
|
`%c Vencord %c %c ${this.name} `,
|
||||||
|
`background: ${levelColor}; color: black; font-weight: bold; border-radius: 5px;`,
|
||||||
|
"",
|
||||||
|
`background: ${this.color}; color: black; font-weight: bold; border-radius: 5px;`
|
||||||
|
, ...args
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
public log(...args: any[]) {
|
public log(...args: any[]) {
|
||||||
this._log("log", args);
|
this._log("log", "#a6d189", args);
|
||||||
}
|
}
|
||||||
|
|
||||||
public info(...args: any[]) {
|
public info(...args: any[]) {
|
||||||
this._log("info", args);
|
this._log("info", "#a6d189", args);
|
||||||
}
|
}
|
||||||
|
|
||||||
public error(...args: any[]) {
|
public error(...args: any[]) {
|
||||||
this._log("error", args);
|
this._log("error", "#e78284", args);
|
||||||
}
|
}
|
||||||
|
|
||||||
public warn(...args: any[]) {
|
public warn(...args: any[]) {
|
||||||
this._log("warn", args);
|
this._log("warn", "#e5c890", args);
|
||||||
}
|
}
|
||||||
|
|
||||||
public debug(...args: any[]) {
|
public debug(...args: any[]) {
|
||||||
this._log("debug", args);
|
this._log("debug", "#eebebe", args);
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -1,5 +1,5 @@
|
||||||
// exists to export default definePlugin({...})
|
// exists to export default definePlugin({...})
|
||||||
export default function definePlugin(p: PluginDef) {
|
export default function definePlugin(p: PluginDef & Record<string, any>) {
|
||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -14,17 +14,18 @@ export interface Patch {
|
||||||
replacement: PatchReplacement | PatchReplacement[];
|
replacement: PatchReplacement | PatchReplacement[];
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface Plugin {
|
export interface Plugin extends PluginDef {
|
||||||
|
patches?: Patch[];
|
||||||
|
started: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface PluginDef {
|
||||||
name: string;
|
name: string;
|
||||||
description: string;
|
description: string;
|
||||||
author: string;
|
author: string;
|
||||||
start?(): void;
|
start?(): void;
|
||||||
patches?: Patch[];
|
stop?(): void;
|
||||||
|
patches?: Omit<Patch, "plugin">[];
|
||||||
dependencies?: string[],
|
dependencies?: string[],
|
||||||
required?: boolean;
|
required?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
// @ts-ignore lole
|
|
||||||
interface PluginDef extends Plugin {
|
|
||||||
patches?: Omit<Patch, "plugin">[];
|
|
||||||
}
|
|
|
@ -1,15 +1,19 @@
|
||||||
import { startAll } from "../plugins";
|
import { startAll } from "../plugins";
|
||||||
import { waitFor, filters } from './webpack';
|
import { waitFor, filters } from './webpack';
|
||||||
|
import type Components from "discord-types/components";
|
||||||
|
import type Stores from "discord-types/stores";
|
||||||
|
import type Other from "discord-types/other";
|
||||||
|
|
||||||
export let FluxDispatcher: any;
|
export let FluxDispatcher: Other.FluxDispatcher;
|
||||||
export let React: typeof import("react");
|
export let React: typeof import("react");
|
||||||
export let UserStore: any;
|
export let UserStore: Stores.UserStore;
|
||||||
export let Forms: any;
|
export let Forms: any;
|
||||||
export let Button: any;
|
export let Button: any;
|
||||||
export let ButtonProps: any;
|
export let ButtonProps: any;
|
||||||
export let Switch: any;
|
export let Switch: any;
|
||||||
export let Flex: any;
|
export let Flex: Components.Flex;
|
||||||
export let Card: any;
|
export let Card: Components.Card;
|
||||||
|
export let Tooltip: Components.Tooltip;
|
||||||
|
|
||||||
waitFor("useState", m => React = m);
|
waitFor("useState", m => React = m);
|
||||||
waitFor(["dispatch", "subscribe"], m => {
|
waitFor(["dispatch", "subscribe"], m => {
|
||||||
|
@ -29,3 +33,4 @@ waitFor(["ButtonLooks", "default"], m => {
|
||||||
waitFor(filters.byDisplayName("SwitchItem"), m => Switch = m.default);
|
waitFor(filters.byDisplayName("SwitchItem"), m => Switch = m.default);
|
||||||
waitFor(filters.byDisplayName("Flex"), m => Flex = m.default);
|
waitFor(filters.byDisplayName("Flex"), m => Flex = m.default);
|
||||||
waitFor(filters.byDisplayName("Card"), m => Card = m.default);
|
waitFor(filters.byDisplayName("Card"), m => Card = m.default);
|
||||||
|
waitFor(filters.byDisplayName("Tooltip"), m => Tooltip = m.default);
|
Loading…
Reference in a new issue