Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat/block-chat-phrases: Add blocked phrases feature #514

Closed
wants to merge 32 commits into from
Closed
Show file tree
Hide file tree
Changes from 12 commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
1142762
feat/block-chat-phrases: Add blocked phrases feature
berghall Apr 15, 2023
11d27dd
feat/block-chat-phrases: Use Object.values instead of for..in
berghall Apr 15, 2023
3b46c7e
feat/block-chat-phrases: Fix CI issues
berghall Apr 15, 2023
feb3fba
feat/block-chat-phrases: Remove unnecessary loop keys
berghall Apr 15, 2023
30d9dac
Merge branch 'master' into feat/block-chat-phrases
berghall Apr 17, 2023
94e5bda
feat/block-chat-phrases: A highlight can now be blocked
berghall Apr 17, 2023
b7d9264
Merge branch 'master' into feat/block-chat-phrases
berghall Apr 17, 2023
1056671
feat/block-chat-phrases: make format
berghall Apr 17, 2023
5bccbeb
Merge branch 'master' into feat/block-chat-phrases
berghall Apr 18, 2023
3365c30
feat/block-chat-phrases: Untracked .github issue templates
berghall Apr 18, 2023
57a282a
feat/block-chat-phrases: Change terminology from blocked to ignore
berghall Apr 18, 2023
b380930
feat/block-chat-phrases: make format
berghall Apr 18, 2023
7d57472
feat/block-chat-phrases: Move ignores into their own settings section
berghall Apr 19, 2023
d8937ea
feat/block-chat-phrases: make format
berghall Apr 19, 2023
faf5544
feat/block-chat-phrases: fix js lints
berghall Apr 19, 2023
617b76e
Merge branch 'master' into feat/block-chat-phrases
berghall Apr 19, 2023
9cee1eb
feat/block-chat-phrases: Fix build and update changelog
berghall Apr 19, 2023
c50e09c
feat/block-chat-phrases: Remove unused import
berghall Apr 19, 2023
f9de628
feat/block-chat-phrases: Re-use highlight template and composable for…
berghall Apr 20, 2023
04252a8
feat/block-chat-phrases: make format and lint
berghall Apr 20, 2023
5725559
Merge branch 'master' into feat/block-chat-phrases
berghall Apr 22, 2023
f25d427
feat/block-chat-phrases: Add wrapper for ignores
berghall Apr 22, 2023
50b4a1d
feat/block-chat-phrases: make format
berghall Apr 22, 2023
5df40d2
feat/block-chat-phrases: fix types
berghall Apr 22, 2023
fc39a41
feat/block-chat-phrases: Update CHANGELOG
berghall Apr 24, 2023
fe04601
Merge branch 'master' into feat/block-chat-phrases
berghall Apr 27, 2023
9ef161d
Update CHANGELOG
berghall May 9, 2023
94ed48d
Merge branch 'master' into feat/block-chat-phrases
berghall May 12, 2023
8d03aae
Merge master
berghall May 18, 2023
e9d0976
Merge branch 'master' into feat/block-chat-phrases
berghall May 20, 2023
09f7872
Merge branch 'master' into feat/block-chat-phrases
berghall Jul 20, 2023
8be7ad4
Merge branch 'feat/block-chat-phrases' of github.com:berghall/Extensi…
berghall Jul 20, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG-nightly.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

- Links in chat messages now respect known TLDs instead of matching any url-like pattern
- Added an option to show timeouts/bans directly in the chat without being a moderator
- Added an option to ignore messages via highlights
- Added options to change what emotes are displayed in the colon list and tab-completion carousel
- Added an option to show the text bit for BTTV and FFZ emote modifiers
- Added an option to hide monitored suspicious user highlights
Expand Down
32 changes: 30 additions & 2 deletions src/composable/chat/useChatHighlights.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ export interface HighlightDef {

color: string;
label: string;
isIgnored?: boolean;
caseSensitive?: boolean;
flashTitle?: boolean;
flashTitleFn?: (msg: ChatMessage) => string;
Expand All @@ -38,6 +39,7 @@ export interface HighlightDef {
const m = new WeakMap<ChannelContext, ChatHighlights>();

const customHighlights = useConfig<Map<string, HighlightDef>>("highlights.custom");
const ignores = useConfig<Map<string, HighlightDef>>("highlights.ignores");
const soundVolume = useConfig<number>("highlights.sound_volume");

export function useChatHighlights(ctx: ChannelContext) {
Expand Down Expand Up @@ -80,6 +82,24 @@ export function useChatHighlights(ctx: ChannelContext) {
m.set(ctx, data);
}

const saveAsIgnored = debounceFn(function (id: string, isIgnored: boolean): void {
if (!data) return;

// Add ignored highlights to their own config
if (isIgnored) {
const items: [string, HighlightDef][] = Array.from(Object.values(data.highlights))
.filter((h) => h.persist)
.filter((h) => h.isIgnored)
.map((h) => [h.id, toRaw(h)]);
ignores.value = new Map(items);
} else {
// Remove as ignored highlight and re-instate as normal highlight
ignores.value.delete(id);
}

save();
}, 250);

const save = debounceFn(function (): void {
if (!data) return;

Expand Down Expand Up @@ -138,10 +158,11 @@ export function useChatHighlights(ctx: ChannelContext) {
if (!data) return;

delete data.highlights[id];
ignores.value.delete(id);
save();
}

function checkMatch(key: string, msg: ChatMessage): boolean {
function checkMatch(key: string, msg: ChatMessage, skipMatchHighlight?: boolean): boolean {
if (!data) return false;

const h = data?.highlights[key];
Expand Down Expand Up @@ -172,7 +193,7 @@ export function useChatHighlights(ctx: ChannelContext) {
ok = h.test(msg);
}

if (ok) {
if (ok && !skipMatchHighlight) {
msg.setHighlight(h.color, h.label);

if (h.soundDef && !msg.historical) {
Expand Down Expand Up @@ -236,14 +257,21 @@ export function useChatHighlights(ctx: ChannelContext) {
save();
}

function checkIgnored(message: ChatMessage<ComponentFactory>) {
const allIgnores = Object.values(getAll()).filter((f) => f.isIgnored);
return allIgnores.some((s) => checkMatch(s.id, message, true));
}

return {
define,
remove,
getAll,
save,
saveAsIgnored,
updateId,
checkMatch,
updateSoundData,
updateFlashTitle,
checkIgnored,
};
}
40 changes: 34 additions & 6 deletions src/site/global/settings/SettingsConfigHighlights.vue
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,10 @@
<div class="item heading">
<div>Pattern</div>
<div>Label</div>
<div class="centered">Flash Title</div>
<div>Ignored</div>
<div class="centered">RegExp</div>
<div>Case Sensitive</div>
<div class="centered">Flash Title</div>
<div>Color</div>
</div>

Expand All @@ -34,9 +35,8 @@
/>
</div>

<!-- Checkbox: Flash Title -->
<div name="flash-title" class="centered">
<FormCheckbox :checked="!!h.flashTitle" @update:checked="onFlashTitleChange(h, $event)" />
<div name="is-ignored">
<FormCheckbox :checked="!!h.isIgnored" @update:checked="onModeChange(h, $event)" />
</div>

<!-- Checkbox: RegExp -->
Expand All @@ -52,12 +52,27 @@
/>
</div>

<!-- Checkbox: Flash Title -->
<div name="flash-title" class="centered">
<FormCheckbox
v-if="!h.isIgnored"
:checked="!!h.flashTitle"
@update:checked="onFlashTitleChange(h, $event)"
/>
</div>

<div name="color">
<input v-model="h.color" type="color" @input="onColorChange(h, $event as InputEvent)" />
<input
v-if="!h.isIgnored"
v-model="h.color"
type="color"
@input="onColorChange(h, $event as InputEvent)"
/>
</div>

<div ref="interactRef" name="interact">
<button
v-if="!h.isIgnored"
ref="soundEffectButton"
class="sound-button"
:class="{ 'has-sound': !!h.soundFile }"
Expand Down Expand Up @@ -141,6 +156,11 @@ function onInputBlur(h: HighlightDef, inputName: keyof typeof inputs): void {
highlights.save();
}

function onModeChange(h: HighlightDef, checked: boolean): void {
h.isIgnored = checked;
highlights.saveAsIgnored(h.id, checked);
}

function onFlashTitleChange(h: HighlightDef, checked: boolean): void {
h.flashTitle = checked;
highlights.updateFlashTitle(h);
Expand Down Expand Up @@ -257,6 +277,7 @@ main.seventv-settings-custom-highlights {
grid-template-rows: 1fr;
grid-area: tabs;
}

.list {
display: grid;
grid-area: list;
Expand All @@ -265,12 +286,13 @@ main.seventv-settings-custom-highlights {
.item {
display: grid;
grid-auto-flow: row dense;
grid-template-columns: 20% 9rem 1fr 1fr 1fr 1fr 1fr;
grid-template-columns: 20% 9rem repeat(6, 1fr);
column-gap: 3rem;
padding: 1rem;

> div {
align-self: center;

&.centered {
justify-self: center;
}
Expand Down Expand Up @@ -301,6 +323,7 @@ main.seventv-settings-custom-highlights {

&:focus-within {
padding: 0;

span {
display: none;
}
Expand All @@ -317,6 +340,7 @@ main.seventv-settings-custom-highlights {
&::-webkit-color-swatch-wrapper {
padding: 0;
}

&::-webkit-color-swatch {
border: none;
}
Expand Down Expand Up @@ -357,6 +381,7 @@ main.seventv-settings-custom-highlights {
input {
display: none;
}

label {
cursor: pointer;
}
Expand All @@ -371,9 +396,11 @@ main.seventv-settings-custom-highlights {
p {
color: var(--seventv-muted);
}

&:hover {
border-color: var(--seventv-primary);
}

&[active="true"] {
color: var(--seventv-primary);
}
Expand All @@ -383,6 +410,7 @@ main.seventv-settings-custom-highlights {
svg {
cursor: pointer;
font-size: 2rem;

&:hover {
color: var(--seventv-primary);
}
Expand Down
8 changes: 8 additions & 0 deletions src/site/twitch.tv/modules/chat/ChatController.vue
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ import { defineFunctionHook, definePropertyHook, unsetPropertyHook } from "@/com
import { ChatMessage } from "@/common/chat/ChatMessage";
import { useChannelContext } from "@/composable/channel/useChannelContext";
import { useChatEmotes } from "@/composable/chat/useChatEmotes";
import { useChatHighlights } from "@/composable/chat/useChatHighlights";
import { useChatMessages } from "@/composable/chat/useChatMessages";
import { useChatProperties } from "@/composable/chat/useChatProperties";
import { useChatScroller } from "@/composable/chat/useChatScroller";
Expand Down Expand Up @@ -93,6 +94,7 @@ const scroller = useChatScroller(ctx, {
});
const properties = useChatProperties(ctx);
const tools = useChatTools(ctx);
const chatHighlights = useChatHighlights(ctx);

// line limit
const lineLimit = useConfig("chat.line_limit", 150);
Expand Down Expand Up @@ -253,6 +255,10 @@ watch(messageBufferComponentDbc, (msgBuf, old) => {
m.historical = true;
chatList.value?.onChatMessage(m, msg as Twitch.ChatMessage, false);

if (chatHighlights.checkIgnored(m)) {
continue;
}

historical.push(m);
continue;
}
Expand Down Expand Up @@ -455,9 +461,11 @@ seventv-container.seventv-chat-list {

.community-highlight {
background-color: var(--seventv-background-transparent-1) !important;

@at-root .seventv-transparent & {
backdrop-filter: blur(1em);
}

transition: background-color 0.25s;

&:hover {
Expand Down
8 changes: 7 additions & 1 deletion src/site/twitch.tv/modules/chat/ChatList.vue
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,9 @@ const onMessage = (msgData: Twitch.AnyMessage): boolean => {
};

function onChatMessage(msg: ChatMessage, msgData: Twitch.AnyMessage, shouldRender = true) {
let shouldRenderMessage = shouldRender;
berghall marked this conversation as resolved.
Show resolved Hide resolved
const c = getMessageComponent(msgData.type);

if (c) {
msg.setComponent(c, { msgData: msgData });
}
Expand Down Expand Up @@ -293,14 +295,18 @@ function onChatMessage(msg: ChatMessage, msgData: Twitch.AnyMessage, shouldRende
chatHighlights.checkMatch(highlightID, msg);
}

if (chatHighlights.checkIgnored(msg)) {
shouldRenderMessage = false;
}

if (properties.isModerator) {
msg.pinnable = true;
msg.deletable = true;
}

// Add message to store
// it will be rendered on the next tick
if (shouldRender) messages.add(msg);
if (shouldRenderMessage) messages.add(msg);
}

function onModerationMessage(msgData: Twitch.ModerationMessage) {
Expand Down
8 changes: 6 additions & 2 deletions src/site/twitch.tv/modules/chat/ChatModule.vue
Original file line number Diff line number Diff line change
Expand Up @@ -389,10 +389,14 @@ export const config = [
component: markRaw(SettingsConfigHighlights),
gridMode: "new-row",
},
label: "Custom Highlights",
hint: "Create custom highlights for specific words or phrases",
label: "Custom Highlights and Ignored terms",
hint: "Create custom highlights and ignored terms",
defaultValue: new Map(),
}),
declareConfig<Map<string, string>>("highlights.ignores", "NONE", {
defaultValue: new Map(),
label: "",
}),
declareConfig<number>("highlights.sound_volume", "SLIDER", {
path: ["Highlights", "Built-In"],
label: "Highlight Sound Volume",
Expand Down