diff --git a/CHANGELOG-nightly.md b/CHANGELOG-nightly.md index 1e1911849..efddeeb29 100644 --- a/CHANGELOG-nightly.md +++ b/CHANGELOG-nightly.md @@ -7,6 +7,7 @@ - Added option to highlight messages of specific usernames - Added option to highlight messages based on badges - Added button to user card to toggle highlighting for a users messages +- Added mod icon for warning users to chat mod icons and user card ### 3.1.1.3000 diff --git a/locale/en_US.yaml b/locale/en_US.yaml index 911c0c238..e91e93d1c 100644 --- a/locale/en_US.yaml +++ b/locale/en_US.yaml @@ -32,6 +32,7 @@ user_card: unban_button: Unban mod_button: Mod unmod_button: Unmod + warn_button: Warn # Emote Menu # This interface allows the user to pick from available emotes diff --git a/src/app/chat/UserCard.vue b/src/app/chat/UserCard.vue index 70f6fecbb..c5d1c99ca 100644 --- a/src/app/chat/UserCard.vue +++ b/src/app/chat/UserCard.vue @@ -102,6 +102,7 @@ v-if="ctx.actor.roles.has('MODERATOR')" :active-tab="data.activeTab" :message-count="data.count.messages" + :warning-count="data.count.warnings" :ban-count="data.count.bans" :timeout-count="data.count.timeouts" :comment-count="data.count.comments" @@ -215,12 +216,14 @@ const data = reactive({ messageCursors: new WeakMap(), timelines: { messages: {} as Record, + warnings: {} as Record, bans: {} as Record, timeouts: {} as Record, comments: {} as Record, } as Record>, count: { messages: 0, + warnings: 0, bans: 0, timeouts: 0, comments: 0, @@ -277,6 +280,7 @@ async function fetchModeratorData(): Promise { if (!resp || resp.errors?.length || !resp.data.channelUser) return; data.count.messages = resp.data.viewerCardModLogs.messages.count ?? 0; + data.count.warnings = resp.data.viewerCardModLogs.warnings.count ?? 0; data.count.bans = resp.data.viewerCardModLogs.bans.count ?? 0; data.count.timeouts = resp.data.viewerCardModLogs.timeouts.count ?? 0; data.count.comments = resp.data.viewerCardModLogs.comments.edges.length ?? 0; @@ -285,11 +289,13 @@ async function fetchModeratorData(): Promise { const timeouts = resp.data.viewerCardModLogs.timeouts.edges; const bans = resp.data.viewerCardModLogs.bans.edges; + const warnings = resp.data.viewerCardModLogs.warnings.edges; - // Add timeouts and bans to the timeline + // Add warnings, timeouts and bans to the timeline for (const [tabName, a] of [ ["timeouts", timeouts] as [UserCardTabName, typeof timeouts], ["bans", bans] as [UserCardTabName, typeof bans], + ["warnings", warnings] as [UserCardTabName, typeof warnings], ]) { const result = [] as ChatMessage[]; @@ -542,7 +548,7 @@ onMounted(async () => { diff --git a/src/app/chat/UserCardTabs.vue b/src/app/chat/UserCardTabs.vue index 23b2e4435..01850eb2d 100644 --- a/src/app/chat/UserCardTabs.vue +++ b/src/app/chat/UserCardTabs.vue @@ -15,11 +15,12 @@ diff --git a/src/types/twitch.d.ts b/src/types/twitch.d.ts index 87fff0d77..9f4dbc550 100644 --- a/src/types/twitch.d.ts +++ b/src/types/twitch.d.ts @@ -119,6 +119,11 @@ declare module Twitch { }; }; + export enum WarnUserPopoverPlacement { + CHAT = 0, + VIEWERS_LIST = 1, + } + export type ChatControllerComponent = ReactExtended.WritableComponent<{ authToken: string | undefined; channelDisplayName: string; @@ -161,6 +166,10 @@ declare module Twitch { userDisplayName: string | undefined; userID: string | undefined; userLogin: string | undefined; + warnUserTargetLogin: string | undefined; + warnUserTargetID: string | undefined; + setWarnUserTarget: (target: { targetUserLogin: string; targetUserID: string }) => void; + setWarnUserPopoverPlacement: (placement: WarnUserPopoverPlacement | null) => void; }> & { pushMessage: (msg: Partial) => void; sendMessage: (msg: string, n?: any) => void;