Skip to content

Commit

Permalink
Add new options for showing/hiding messages
Browse files Browse the repository at this point in the history
Re-work logging
General cleanup
  • Loading branch information
stevencrader committed Oct 24, 2023
1 parent 4e1c2ff commit 47ef6cc
Show file tree
Hide file tree
Showing 28 changed files with 1,163 additions and 242 deletions.
10 changes: 4 additions & 6 deletions src/background.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { consoleLog } from "./log"
import { Message, Messages } from "./types/messages"
import { Options, Theme } from "./types/option-types"

Expand Down Expand Up @@ -38,10 +39,7 @@ const handlePageLoaded = (tabUrl: string): void => {
try {
openTabs.set(tab.id, tab)
} catch (e) {
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
// eslint-disable-next-line no-console
if (DEBUG) console.log(`error adding tab: ${tab.url}`)
consoleLog(`error adding tab: ${tab.url}`)
}
})
})
Expand Down Expand Up @@ -78,7 +76,7 @@ const handleUpdateOptions = (options: Options): void => {
{},
() => {
if (chrome.runtime.lastError) {
// console.log("update options error", chrome.runtime.lastError, "for tab", tab)
// consoleLog("update options error", chrome.runtime.lastError, "for tab", tab)
// if unable to send message, assume closed, stop tracking
openTabs.delete(tab.id)
}
Expand All @@ -104,7 +102,7 @@ const handleRumbleThemeChanged = (theme: Theme): void => {
{},
() => {
if (chrome.runtime.lastError) {
// console.log("update theme error", chrome.runtime.lastError, "for tab", tab)
// consoleLog("update theme error", chrome.runtime.lastError, "for tab", tab)
// if unable to send message, assume closed, stop tracking
openTabs.delete(tab.id)
}
Expand Down
73 changes: 73 additions & 0 deletions src/components/chat-watcher/chat-watcher.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
import { checkForMutedWordsChat } from "./muted-words"

let preserveMessageData = true

/**
* Get whether the received chat message data should be preserved
* @returns preserve received chats
*/
export const getPreserveMessageData = (): boolean => {
return preserveMessageData
}

/**
* Set whether the received chat message data should be preserved
* Note: slightly increases memory usage
* @param value preserve received chats
*/
export const setPreserveMessageData = (value: boolean): void => {
preserveMessageData = value
}

/**
* Save message data for use later
* @param node received chat node
*/
const saveMessageData = (node: HTMLLIElement): void => {
// const userId = node.getAttribute("data-message-user-id")
const messageId = node.getAttribute("data-message-id")
const message = node.querySelector(".chat-history--message")
if (message !== null) {
const liveChat: HTMLLIElement = document.querySelector(`[data-message-id='${messageId}']`)
liveChat.setAttribute("data-message", message.textContent)
}
}

/**
* Handle new chat node received
* @param node received chat node
*/
const newChatReceived = (node: HTMLLIElement): void => {
if (preserveMessageData) {
saveMessageData(node)
}
checkForMutedWordsChat(node)
}

/**
* Handle changes made to the chat.
*
* Used to catch new chat messages
* @param mutations list of mutations
*/
const chatObserverCallback = (mutations: Array<MutationRecord>): void => {
mutations.forEach((mutation) => {
if (mutation.type === "childList") {
// mutation.removedNodes.forEach((node: HTMLLIElement) => {
// consoleLog("node removed", node)
// })
mutation.addedNodes.forEach((node: HTMLLIElement) => newChatReceived(node))
}
})
}

/**
* Register observer for catching new chat messages
*/
export const registerChatMessageObserver = (): void => {
const chatList = document.getElementById("chat-history-list")
if (chatList !== null) {
const headObserver = new MutationObserver(chatObserverCallback)
headObserver.observe(chatList, { childList: true, attributes: false, subtree: false })
}
}
77 changes: 77 additions & 0 deletions src/components/chat-watcher/muteWords.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
anal
anus
arse
ass
ballsack
balls
bastard
bitch
biatch
bloody
blowjob
blow job
bollock
bollok
boner
boob
bugger
bum
butt
buttplug
clitoris
cock
coon
crap
cunt
damn
dick
dildo
dyke
fag
feck
fellate
fellatio
felching
fuck
f u c k
fudgepacker
fudge packer
flange
Goddamn
God damn
hell
homo
jerk
jizz
knobend
knob end
labia
lmao
lmfao
muff
nigger
nigga
omg
penis
piss
poop
prick
pube
pussy
queer
scrotum
sex
shit
s hit
sh1t
slut
smegma
spunk
tit
tosser
turd
twat
vagina
wank
whore
wtf
177 changes: 177 additions & 0 deletions src/components/chat-watcher/muted-words.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,177 @@
import mutedWords from "./muteWords.txt"

let runMutedWordChecker = true
let runMutedWordCheckerInChat = true
let runMutedWordCheckerInRantStats = true
let mutedWordRegEx: RegExp = null

/**
* Get whether the muted word checker should be run or not
* @returns run muted word checker
*/
export const getRunMutedWordChecker = (): boolean => {
return runMutedWordChecker
}

/**
* Set the muted words
*
* Sets the value returned by {@link getRunMutedWordChecker} to true if `runCheck` is true and at least one word in `word`
* @param runCheck should muted word check run or not
* @param words list of muted words
* @param muteInChat should chat messages and Rumble Rants in chat be muted
* @param muteInRantStats should Rumble Rants in Rant Stats sidebar/popout be muted
*/
export const setMutedWords = (
runCheck: boolean,
words: Array<string>,
muteInChat: boolean = true,
muteInRantStats: boolean = true,
): void => {
runMutedWordChecker = false // assume disabled
runMutedWordCheckerInChat = muteInChat
runMutedWordCheckerInRantStats = muteInRantStats

if (runCheck) {
const cleanWords: Set<string> = new Set<string>()
words.forEach((word) => {
if (word.trim() !== "" && word.trimStart()[0] !== "#") {
const idx = word.indexOf("#")
if (idx >= 0) {
cleanWords.add(word.substring(0, idx).trim())
} else {
cleanWords.add(word)
}
}
})

if (cleanWords.size > 0) {
const wordFilter = Array.from(cleanWords).join("|")
mutedWordRegEx = new RegExp(`\\b(${wordFilter})\\b`, "imu")
runMutedWordChecker = muteInChat || muteInRantStats
}
}
}

/**
* Get the list of default words to mute
* @returns list of default words
*/
export const getDefaultMutedWords = (): Array<string> => {
return mutedWords.split(/\r?\n/)
}

/**
* Check if any of the muted words were found in the text
* @param text The text to search for words in
* @returns Indicate if muted word found
*/
const mutedWordInText = (text: string): boolean => {
if (mutedWordRegEx === null) return false
return mutedWordRegEx.test(text)
}

/**
* Checks to see if button has already been added to node.
* @param node node to check if parent has a button
* @returns true if button already exists
*/
const hasButton = (node: HTMLElement): boolean => {
const buttonNodes = node.parentElement.querySelectorAll(".show-muted-text-button")
return buttonNodes.length > 0
}

/**
* Add button to show/hide the textNode
* @param textNode The node to show/hide. Button will be added before this node.
* @param buttonTitle Tooltip text for button
* @param buttonTextToShow Text to show on button when textNode is hidden
* @param buttonTextToHide Text to show on button when textNode is visible
*/
export const addButtonToggle = (
textNode: HTMLElement,
buttonTitle: string = "",
buttonTextToShow: string = "Show muted text",
buttonTextToHide: string = "Hide muted text",
): void => {
if (hasButton(textNode)) {
return
}

const showButton = document.createElement("button")
showButton.classList.add("show-muted-text-button")
showButton.textContent = buttonTextToShow
showButton.title = buttonTitle
textNode.parentElement.insertBefore(showButton, textNode)

/**
* When clicked, hide self and show hidden text
*/
showButton.onclick = (): void => {
if (textNode.classList.contains("hidden")) {
textNode.classList.remove("hidden")
showButton.textContent = buttonTextToHide
} else {
textNode.classList.add("hidden")
showButton.textContent = buttonTextToShow
}
}
}

/**
* Add mute button if text should be muted
*
* Press button to reveal muted text. Press again to hide text.
*
* Hover over button to reveal text without showing it in the page.
* @param node root node containing message/rant data
* @param textNodeSelector name of node containing text
* @param text The text to search for words in
* @param chat Indicates if source is from chat.
*/
export const addMutedButton = (node: HTMLElement, textNodeSelector: string, text: string, chat: boolean): void => {
// don't check if type should not be filtered
if (chat) {
if (!runMutedWordCheckerInChat) {
return
}
} else if (!runMutedWordCheckerInRantStats) {
return
}

if (mutedWordInText(text)) {
node.classList.add("muted-chat")
const textNode: HTMLElement = node.querySelector(textNodeSelector)
textNode.classList.add("hidden")
addButtonToggle(textNode, text)
}
}

/**
* Mute chat if muted word found in message
* @param node received chat node
*/
export const checkForMutedWordsChat = (node: HTMLLIElement): void => {
if (!runMutedWordChecker) return

let text = "" // get message text

// check if Rant message
let selector = ".chat-history--rant-text"
const rantText = node.querySelector(selector)
if (rantText !== null) {
text = rantText.textContent
}

// check if normal chat
const message = node.querySelector(".chat-history--message")
if (message !== null) {
selector = ".chat-history--message"
text = message.textContent
}

// exit if no text found
if (text === "") return

addMutedButton(node, selector, text, true)
}
2 changes: 1 addition & 1 deletion src/components/events/send-action.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ export const sendAction = (
} as Message,
() => {
if (chrome.runtime.lastError) {
// console.log("action error", chrome.runtime.lastError)
// consoleLog("action error", chrome.runtime.lastError)
}
},
)
Expand Down
Loading

0 comments on commit 47ef6cc

Please sign in to comment.