From b0e8cc3e8b096266e55dce917e4966638b82f56f Mon Sep 17 00:00:00 2001 From: LordTocs Date: Fri, 19 Jul 2024 12:37:35 -0400 Subject: [PATCH 01/17] Add little note that you can type TwitchNames in full --- .../data/base-components/AutocompleteDropList.vue | 2 ++ .../renderer/src/components/viewer/TwitchViewerInput.vue | 7 ++++++- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/libs/castmate-ui-core/src/components/data/base-components/AutocompleteDropList.vue b/libs/castmate-ui-core/src/components/data/base-components/AutocompleteDropList.vue index 9ba4094f..73be09b3 100644 --- a/libs/castmate-ui-core/src/components/data/base-components/AutocompleteDropList.vue +++ b/libs/castmate-ui-core/src/components/data/base-components/AutocompleteDropList.vue @@ -34,6 +34,7 @@ + @@ -49,6 +50,7 @@ import { getNextItem, getPrevItem, findItem, + groupItems, } from "../../../util/autocomplete-helpers" import { usePropagationStop } from "../../../main" diff --git a/plugins/twitch/renderer/src/components/viewer/TwitchViewerInput.vue b/plugins/twitch/renderer/src/components/viewer/TwitchViewerInput.vue index fcb73e0d..18b10b5e 100644 --- a/plugins/twitch/renderer/src/components/viewer/TwitchViewerInput.vue +++ b/plugins/twitch/renderer/src/components/viewer/TwitchViewerInput.vue @@ -49,6 +49,9 @@ {{ item.displayName }} + @@ -127,7 +130,9 @@ const groupedSuggestions = computed(() => { const result: TwitchViewerDisplayData[][] = [] const suggestions = fuzzySuggestions.value - result.push(suggestions) + if (fuzzySuggestions.value.length > 0) { + result.push(suggestions) + } return result }) From c45305e4079e88cacaa16ac953493425c76d9b37 Mon Sep 17 00:00:00 2001 From: LordTocs Date: Fri, 19 Jul 2024 15:00:53 -0400 Subject: [PATCH 02/17] Mouse Input Simulation Fixes Fix mouse up function actually calling mouse down --- plugins/input/main/src/mouse.ts | 7 +++++++ plugins/input/native/src/input-interface.cc | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/plugins/input/main/src/mouse.ts b/plugins/input/main/src/mouse.ts index a0830057..efba5c4d 100644 --- a/plugins/input/main/src/mouse.ts +++ b/plugins/input/main/src/mouse.ts @@ -15,10 +15,17 @@ export function setupMouse(inputInterface: InputInterface) { name: "Button", default: "left", enum: ["left", "right", "middle", "mouse4", "mouse5"], + required: true, }, duration: { type: Duration, name: "Duration", required: true, default: 0.1 }, }, }, + duration: { + dragType: "length", + rightSlider: { + sliderProp: "duration", + }, + }, async invoke(config, contextData, abortSignal) { inputInterface.simulateMouseDown(config.button as MouseButton) diff --git a/plugins/input/native/src/input-interface.cc b/plugins/input/native/src/input-interface.cc index 42cc4b8e..1235884d 100644 --- a/plugins/input/native/src/input-interface.cc +++ b/plugins/input/native/src/input-interface.cc @@ -13,7 +13,7 @@ Napi::Object input_interface::init(Napi::Env env, Napi::Object exports) InstanceMethod("simulateKeyDown", &input_interface::simulate_key_down), InstanceMethod("simulateKeyUp", &input_interface::simulate_key_up), InstanceMethod("simulateMouseDown", &input_interface::simulate_mouse_down), - InstanceMethod("simulateMouseUp", &input_interface::simulate_mouse_down), + InstanceMethod("simulateMouseUp", &input_interface::simulate_mouse_up), InstanceMethod("startEvents", &input_interface::start_events), InstanceMethod("stopEvents", &input_interface::stop_events), InstanceMethod("isKeyDown", &input_interface::is_key_down), From c8f6163297a13f0b7856e24bc450f1b858401c81 Mon Sep 17 00:00:00 2001 From: LordTocs Date: Mon, 22 Jul 2024 17:08:00 -0400 Subject: [PATCH 03/17] Add handling for anonymous viewers in bits and gifted subs --- plugins/twitch/main/src/chat.ts | 4 +-- plugins/twitch/main/src/group.ts | 8 +++++ plugins/twitch/main/src/subscriptions.ts | 11 ++++-- plugins/twitch/main/src/viewer-cache.ts | 23 +++++++++++-- .../src/components/TwitchViewerGroupEdit.vue | 4 ++- .../src/components/TwitchViewerGroupInput.vue | 2 +- .../groups/TwitchViewerGroupLogicOp.vue | 3 ++ .../groups/TwitchViewerGroupPropertyEdit.vue | 34 +++++++++++++++---- .../groups/TwitchViewerGroupRuleNegator.vue | 6 ++++ plugins/twitch/renderer/src/util/group.ts | 8 +++++ plugins/twitch/shared/src/resources/group.ts | 2 ++ plugins/twitch/shared/src/viewers/viewer.ts | 14 ++++++++ 12 files changed, 102 insertions(+), 17 deletions(-) diff --git a/plugins/twitch/main/src/chat.ts b/plugins/twitch/main/src/chat.ts index 58481c20..5643e416 100644 --- a/plugins/twitch/main/src/chat.ts +++ b/plugins/twitch/main/src/chat.ts @@ -252,7 +252,7 @@ export function setupChat() { type: Object, properties: { bits: { type: Range, name: "Bits Cheered", required: true, default: {} }, - group: { type: TwitchViewerGroup, name: "Viewer Group", required: true, default: {} }, + group: { type: TwitchViewerGroup, name: "Viewer Group", required: true, default: {}, anonymous: true }, }, }, context: { @@ -307,7 +307,7 @@ export function setupChat() { bits({ bits: event.bits, - viewer: event.userId ?? "anonymouse", + viewer: event.userId ?? "anonymous", message: event.message, }) }) diff --git a/plugins/twitch/main/src/group.ts b/plugins/twitch/main/src/group.ts index bdf85f80..d7eb45ee 100644 --- a/plugins/twitch/main/src/group.ts +++ b/plugins/twitch/main/src/group.ts @@ -163,6 +163,10 @@ async function satisfiesRule(userId: string, rule: TwitchViewerGroupRule): Promi return false } else if ("properties" in rule) { //Todo: Make this not silly hardcoded + if (rule.properties.anonymous && userId == "anonymous") return true + + if (userId == "anonymous") return false + if (rule.properties.following) { if (await ViewerCache.getInstance().getIsFollowing(userId)) return true } @@ -198,6 +202,10 @@ async function satisfiesRule(userId: string, rule: TwitchViewerGroupRule): Promi return false } +export async function isEmptyTwitchViewerGroup(group: TwitchViewerGroup) { + return !group?.rule +} + export async function inTwitchViewerGroup(userId: string, group: TwitchViewerGroup) { if (!group?.rule) return true //Empty is everyone diff --git a/plugins/twitch/main/src/subscriptions.ts b/plugins/twitch/main/src/subscriptions.ts index 0725a8ba..65c39b22 100644 --- a/plugins/twitch/main/src/subscriptions.ts +++ b/plugins/twitch/main/src/subscriptions.ts @@ -6,7 +6,7 @@ import { Range } from "castmate-schema" import { TwitchAPIService, onBotAuth, onChannelAuth } from "./api-harness" import { ViewerCache } from "./viewer-cache" import { TwitchViewer, TwitchViewerGroup } from "castmate-plugin-twitch-shared" -import { inTwitchViewerGroup } from "./group" +import { inTwitchViewerGroup, isEmptyTwitchViewerGroup } from "./group" export function setupSubscriptions() { const logger = usePluginLogger() @@ -63,13 +63,17 @@ export function setupSubscriptions() { config: { type: Object, properties: { + tier1: { type: Boolean, name: "Tier 1", required: true, default: true }, + tier2: { type: Boolean, name: "Tier 2", required: true, default: true }, + tier3: { type: Boolean, name: "Tier 3", required: true, default: true }, subs: { type: Range, name: "Subs Gifted", required: true, default: { min: 1 } }, - group: { type: TwitchViewerGroup, name: "Viewer Group", required: true }, + group: { type: TwitchViewerGroup, name: "Viewer Group", required: true, anonymous: true }, }, }, context: { type: Object, properties: { + tier: { type: Number, required: true, default: 1 }, gifter: { type: TwitchViewer, required: true, default: "27082158" }, subs: { type: Number, required: true, default: 2 }, }, @@ -165,7 +169,8 @@ export function setupSubscriptions() { } giftSub({ - gifter: event.gifterId, + tier, + gifter: event.isAnonymous ? "anonymous" : event.gifterId, subs: event.amount, }) }) diff --git a/plugins/twitch/main/src/viewer-cache.ts b/plugins/twitch/main/src/viewer-cache.ts index d4acfa2d..a423ee53 100644 --- a/plugins/twitch/main/src/viewer-cache.ts +++ b/plugins/twitch/main/src/viewer-cache.ts @@ -47,6 +47,8 @@ interface CachedTwitchViewer extends Partial { } function getNValues(set: Set, requiredValues: T[], n: number): T[] { + requiredValues = requiredValues.filter((id) => id != "anonymous") + const result = [...requiredValues] if (result.length >= n) { @@ -245,6 +247,7 @@ export const ViewerCache = Service( private getOrCreate(userId: string) { if (userId == "") throw new Error("No empty IDs!") + if (userId == "anonymous") throw new Error("No anonymous!") let cached = this._viewerLookup.get(userId) if (!cached) { @@ -280,6 +283,8 @@ export const ViewerCache = Service( } async getChatColor(userId: string): Promise { + if (userId == "anonymous") return "default" + const cached = this.getOrCreate(userId) if (cached.color != null) { return cached.color @@ -345,6 +350,8 @@ export const ViewerCache = Service( } cacheGiftSubEvent(event: EventSubChannelSubscriptionGiftEvent) { + if (event.isAnonymous) return + const cached = this.getOrCreate(event.gifterId) this.markSeen(cached) this.updateNameCache(cached, event.gifterDisplayName) @@ -376,6 +383,8 @@ export const ViewerCache = Service( private async queryFollowing(...userIds: string[]) { try { + userIds = userIds.filter((id) => id != "anonymous") + //Annoyingly check each follow independently const followingPromises = userIds.map((id) => TwitchAccount.channel.apiClient.channels.getChannelFollowers(TwitchAccount.channel.twitchId, id) @@ -402,6 +411,8 @@ export const ViewerCache = Service( } async getIsFollowing(userId: string): Promise { + if (userId == "anonymous") return false + const cached = this.getOrCreate(userId) if (cached.following != null) { return cached.following @@ -517,7 +528,10 @@ export const ViewerCache = Service( const neededUserInfoIds: string[] = [] const neededFollowerIds: string[] = [] - const cachedUsers = userIds.map((id) => this.getOrCreate(id)) + const cachedUsers = userIds.map((id) => { + if (id == "anonymous") return TwitchViewer.anonymous + return this.getOrCreate(id) + }) for (const cached of cachedUsers) { if (cached.subbed == null || (cached.subbed === true && cached.sub == null)) { @@ -573,7 +587,10 @@ export const ViewerCache = Service( } async getDisplayDatasByIds(userIds: string[]): Promise { - const users = userIds.map((id) => this.getOrCreate(id)) + const users = userIds.map((id) => { + if (id == "anonymous") return TwitchViewer.anonymous + return this.getOrCreate(id) + }) const needsColors: string[] = [] const needsUserInfo: string[] = [] @@ -611,7 +628,7 @@ export const ViewerCache = Service( async getDisplayDataById(userId: string): Promise { if (!userId) return undefined - const cached = this.getOrCreate(userId) + const cached = userId == "anonymous" ? TwitchViewer.anonymous : this.getOrCreate(userId) const queries: Promise[] = [] diff --git a/plugins/twitch/renderer/src/components/TwitchViewerGroupEdit.vue b/plugins/twitch/renderer/src/components/TwitchViewerGroupEdit.vue index b8a79905..73b34742 100644 --- a/plugins/twitch/renderer/src/components/TwitchViewerGroupEdit.vue +++ b/plugins/twitch/renderer/src/components/TwitchViewerGroupEdit.vue @@ -5,6 +5,7 @@ Customize diff --git a/plugins/twitch/renderer/src/components/groups/TwitchViewerGroupRuleNegator.vue b/plugins/twitch/renderer/src/components/groups/TwitchViewerGroupRuleNegator.vue index 0ec321cb..01b4e582 100644 --- a/plugins/twitch/renderer/src/components/groups/TwitchViewerGroupRuleNegator.vue +++ b/plugins/twitch/renderer/src/components/groups/TwitchViewerGroupRuleNegator.vue @@ -7,24 +7,28 @@ v-model="internalModel" v-model:excluded="excluded" @delete="emit('delete')" + :schema="schema" /> @@ -39,6 +43,7 @@ import { isGroupResourceRef, isInlineViewerGroup, isViewerGroupPropertyRule, + SchemaTwitchViewerGroup, } from "castmate-plugin-twitch-shared" import TwitchViewerGroupLogicOp from "./TwitchViewerGroupLogicOp.vue" import TwitchViewerGroupResourceRef from "./TwitchViewerGroupResourceRef.vue" @@ -49,6 +54,7 @@ import PButton from "primevue/button" const props = defineProps<{ modelValue: TwitchViewerGroupRule + schema: SchemaTwitchViewerGroup }>() const model = useModel(props, "modelValue") diff --git a/plugins/twitch/renderer/src/util/group.ts b/plugins/twitch/renderer/src/util/group.ts index df2bffb0..9e4d9f74 100644 --- a/plugins/twitch/renderer/src/util/group.ts +++ b/plugins/twitch/renderer/src/util/group.ts @@ -29,6 +29,10 @@ export function getGroupPhrase(group: TwitchViewerGroup, resourceStore: ReturnTy words.push("Followers") } + if (rule.properties.anonymous) { + words.push("Anonymous") + } + const subTier1 = rule.properties.subTier1 const subTier2 = rule.properties.subTier1 const subTier3 = rule.properties.subTier1 @@ -145,6 +149,10 @@ export function getGroupSpanItems(group: TwitchViewerGroup | undefined): GroupSp words.push("Followers") } + if (rule.properties.anonymous) { + words.push("Anonymous") + } + const subTier1 = rule.properties.subTier1 const subTier2 = rule.properties.subTier2 const subTier3 = rule.properties.subTier3 diff --git a/plugins/twitch/shared/src/resources/group.ts b/plugins/twitch/shared/src/resources/group.ts index f07869a2..ec2f69bc 100644 --- a/plugins/twitch/shared/src/resources/group.ts +++ b/plugins/twitch/shared/src/resources/group.ts @@ -7,6 +7,7 @@ export interface TwitchViewerGroupConfig { export interface TwitchViewerGroupProperties { properties: { + anonymous?: boolean following?: boolean vip?: boolean subTier1?: boolean @@ -60,6 +61,7 @@ export const TwitchViewerGroup: TwitchViewerGroupFactory = { export interface SchemaTwitchViewerGroup extends SchemaBase { type: TwitchViewerGroupFactory + anonymous?: boolean } declare module "castmate-schema" { diff --git a/plugins/twitch/shared/src/viewers/viewer.ts b/plugins/twitch/shared/src/viewers/viewer.ts index f5cd160b..48f0fa14 100644 --- a/plugins/twitch/shared/src/viewers/viewer.ts +++ b/plugins/twitch/shared/src/viewers/viewer.ts @@ -43,6 +43,20 @@ export const TwitchViewer = { }, } }, + get anonymous(): TwitchViewer { + return { + id: "anonymous", + displayName: "Anonymous", + description: "", + profilePicture: "", + color: "#000000", + following: false, + subbed: false, + [Symbol.toPrimitive](hint: "default" | "string" | "number") { + return this.displayName + }, + } + }, } type TwitchViewerFactory = typeof TwitchViewer From bca374ac92470502da227eb55bf6ff1053cd4d6d Mon Sep 17 00:00:00 2001 From: LordTocs Date: Mon, 22 Jul 2024 17:09:31 -0400 Subject: [PATCH 04/17] Fix labeling on Queue Gap --- packages/castmate/src/renderer/util/queues.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/castmate/src/renderer/util/queues.ts b/packages/castmate/src/renderer/util/queues.ts index 47acb23e..f0a2b9c7 100644 --- a/packages/castmate/src/renderer/util/queues.ts +++ b/packages/castmate/src/renderer/util/queues.ts @@ -27,7 +27,7 @@ export function initializeQueues() { properties: { name: { type: String, name: "Name", required: true }, paused: { type: Boolean, name: "Paused", required: true, default: false }, - gap: { type: Duration, name: "Duration", required: true, default: 0 }, + gap: { type: Duration, name: "Gap", required: true, default: 0 }, }, }) resourceStore.registerEditComponent("ActionQueue", ResourceSchemaEdit) From bb018ac5f1bd85a1aef2a15db793862c5b24174d Mon Sep 17 00:00:00 2001 From: LordTocs Date: Mon, 22 Jul 2024 17:15:04 -0400 Subject: [PATCH 05/17] Change Twitch Viewer Group delete icons to trash cans --- .../groups/TwitchViewerGroupInlineGroup.vue | 4 ++-- .../groups/TwitchViewerGroupLogicOp.vue | 2 +- .../groups/TwitchViewerGroupPropertyEdit.vue | 8 ++------ .../groups/TwitchViewerGroupResourceRef.vue | 2 +- .../components/groups/TwitchViewerGroupRule.vue | 17 ----------------- 5 files changed, 6 insertions(+), 27 deletions(-) delete mode 100644 plugins/twitch/renderer/src/components/groups/TwitchViewerGroupRule.vue diff --git a/plugins/twitch/renderer/src/components/groups/TwitchViewerGroupInlineGroup.vue b/plugins/twitch/renderer/src/components/groups/TwitchViewerGroupInlineGroup.vue index c543ebc0..710fee8f 100644 --- a/plugins/twitch/renderer/src/components/groups/TwitchViewerGroupInlineGroup.vue +++ b/plugins/twitch/renderer/src/components/groups/TwitchViewerGroupInlineGroup.vue @@ -9,11 +9,11 @@ :icon="excluded ? 'mdi mdi-equal' : 'mdi mdi-not-equal-variant'" @click="excluded = !excluded" > - +
- +
diff --git a/plugins/twitch/renderer/src/components/groups/TwitchViewerGroupLogicOp.vue b/plugins/twitch/renderer/src/components/groups/TwitchViewerGroupLogicOp.vue index 69709225..2a315d9f 100644 --- a/plugins/twitch/renderer/src/components/groups/TwitchViewerGroupLogicOp.vue +++ b/plugins/twitch/renderer/src/components/groups/TwitchViewerGroupLogicOp.vue @@ -20,7 +20,7 @@ @click="excluded = !excluded" v-if="!root" > - +
- +
- - From b8efe92831a622607a17d38e2b610467bebb94e2 Mon Sep 17 00:00:00 2001 From: LordTocs Date: Mon, 22 Jul 2024 17:17:09 -0400 Subject: [PATCH 06/17] Fix some type issues on GroupPage --- plugins/twitch/renderer/src/components/groups/GroupPage.vue | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/plugins/twitch/renderer/src/components/groups/GroupPage.vue b/plugins/twitch/renderer/src/components/groups/GroupPage.vue index 05ca944e..4084bb97 100644 --- a/plugins/twitch/renderer/src/components/groups/GroupPage.vue +++ b/plugins/twitch/renderer/src/components/groups/GroupPage.vue @@ -79,7 +79,7 @@ const memberUsers = ref([]) const viewerStore = useViewerStore() async function queryMembers() { - memberUsers.value = await viewerStore.getUsersByIds([...resource.value.config.userIds]) + memberUsers.value = await viewerStore.getUsersByIds([...(resource.value?.config?.userIds ?? [])]) } const removeId = useResourceIPCCaller<(userId: string) => any>( @@ -123,7 +123,7 @@ onMounted(() => { }) watch( - () => resource.value.config.userIds, + () => resource.value?.config?.userIds, () => { queryMembers() }, From 8c4d28b3ee92ed4113913de46e1ce48f7ab64a0d Mon Sep 17 00:00:00 2001 From: LordTocs Date: Mon, 22 Jul 2024 17:34:26 -0400 Subject: [PATCH 07/17] Still throw errors during Create for ChannelPointRewards --- plugins/twitch/main/src/channelpoints.ts | 54 +++++++++++++----------- 1 file changed, 29 insertions(+), 25 deletions(-) diff --git a/plugins/twitch/main/src/channelpoints.ts b/plugins/twitch/main/src/channelpoints.ts index c183f965..bbda4357 100644 --- a/plugins/twitch/main/src/channelpoints.ts +++ b/plugins/twitch/main/src/channelpoints.ts @@ -159,7 +159,7 @@ export class ChannelPointReward extends Resource): Promise { await super.applyConfig(config) - await this.updateTwitchServers() + await this.updateServersSafe() await this.initializeReactivity() await this.save() return true @@ -167,7 +167,7 @@ export class ChannelPointReward extends Resource { await super.setConfig(config) - await this.updateTwitchServers() + await this.updateServersSafe() await this.initializeReactivity() await this.save() return true @@ -384,7 +384,7 @@ export class ChannelPointReward extends Resource { - await this.updateTwitchServers() + await this.updateServersSafe() }, 300) async initializeReactivity() { @@ -392,30 +392,34 @@ export class ChannelPointReward extends Resource await this.getHelixRewardData(), this.updateServerDebounced) } - private async updateTwitchServers() { + private async updateServersSafe() { try { - if (!this.config.controllable) return - if (this.config.transient) return - - if (!TwitchAccount.channel.config.isAffiliate) return - - const helixData = await this.getHelixRewardData() - if (this.config.twitchId) { - const update = await TwitchAccount.channel.apiClient.channelPoints.updateCustomReward( - TwitchAccount.channel.twitchId, - this.config.twitchId, - helixData - ) - await this.updateFromTwurple(update) - } else { - const created = await TwitchAccount.channel.apiClient.channelPoints.createCustomReward( - TwitchAccount.channel.twitchId, - helixData - ) - await this.updateFromTwurple(created) - } + await this.updateTwitchServers() } catch (err) { - logger.error("Error Updating Channel Point Reward", this.config.name, err) + logger.error("Error Updating ChannelPointReward", this.id, err) + } + } + + private async updateTwitchServers() { + if (!this.config.controllable) return + if (this.config.transient) return + + if (!TwitchAccount.channel.config.isAffiliate) return + + const helixData = await this.getHelixRewardData() + if (this.config.twitchId) { + const update = await TwitchAccount.channel.apiClient.channelPoints.updateCustomReward( + TwitchAccount.channel.twitchId, + this.config.twitchId, + helixData + ) + await this.updateFromTwurple(update) + } else { + const created = await TwitchAccount.channel.apiClient.channelPoints.createCustomReward( + TwitchAccount.channel.twitchId, + helixData + ) + await this.updateFromTwurple(created) } } } From 0e01826f49c3c14f5cb8cd42dc237431a10a78e4 Mon Sep 17 00:00:00 2001 From: LordTocs Date: Fri, 2 Aug 2024 17:29:58 -0400 Subject: [PATCH 08/17] Don't overwrite old backups incase migration runs twice --- packages/castmate/src/main/migration/old-migration.ts | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/packages/castmate/src/main/migration/old-migration.ts b/packages/castmate/src/main/migration/old-migration.ts index ab964d63..09046181 100644 --- a/packages/castmate/src/main/migration/old-migration.ts +++ b/packages/castmate/src/main/migration/old-migration.ts @@ -2426,6 +2426,11 @@ defineIPCFunc("oldMigration", "finishMigrate", () => { async function createBackup() { const backupPath = resolveProjectPath("../backup_04.zip") + if (fsSync.existsSync(backupPath)) { + //Backup already exists, don't overwrite + return + } + logger.log("Creating Backup") const outStream = fsSync.createWriteStream(backupPath) @@ -2438,6 +2443,7 @@ async function createBackup() { const archive = archiver("zip", { zlib: { level: 9 } }) + //@ts-ignore archive.pipe(outStream) function archiveDir(dir: string) { From 17316472551d20a07594e30ca00b4be30871115e Mon Sep 17 00:00:00 2001 From: LordTocs Date: Sat, 3 Aug 2024 16:09:56 -0400 Subject: [PATCH 09/17] Fix missing scrollbar on Variables page --- .../renderer/src/components/VariablesPage.vue | 116 ++++++++++-------- 1 file changed, 66 insertions(+), 50 deletions(-) diff --git a/plugins/variables/renderer/src/components/VariablesPage.vue b/plugins/variables/renderer/src/components/VariablesPage.vue index 842dbc70..f8023039 100644 --- a/plugins/variables/renderer/src/components/VariablesPage.vue +++ b/plugins/variables/renderer/src/components/VariablesPage.vue @@ -1,57 +1,64 @@