Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
23 changes: 20 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,10 @@

**WARNING:** this relies on undocumented features of Rumble. If Rumble changes their site, this may break.

Add support for capturing the paid Rumble Rants for [Rumble.com](https://rumble.com/) livestreams.
Add support for capturing the paid Rumble Rants for [Rumble.com](https://rumble.com/), gifted subscriptions, and raids for livestreams.
Rants are shown past their normal expiration date in the chat.

Rants can be shown as a sidebar on the stream page or in a separate window. After a stream ends, cached data can be
viewed by loading the stream page again.
Rants can be shown as a sidebar on the stream page or in a separate window. After a stream ends, cached data can be viewed by loading the stream page again.

Additionally, all cached data can be viewed and managed from the Cached Rants page.

Expand Down Expand Up @@ -124,6 +123,24 @@ Options:
- Unchecked: display as sidebar (Default)
- Checked: open as popup

**Include Gifts**

Include gifted subscriptions in the sidebar

Options:

- Unchecked: gifted subscriptions are not captured
- Checked: gifted subscriptions are captured (Default)

**Include Raids**

Include incoming raids in the sidebar

Options:

- Unchecked: incoming raids are not captured
- Checked: incoming raids are captured (Default)

### Page Links

Click "View Cached Rants" to open the Cached Rants page
Expand Down
1 change: 1 addition & 0 deletions eslint.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ module.exports = [
...jsdoc.configs.recommended.rules,
"prettier/prettier": "error",
"sonarjs/todo-tag": "warn",
"sonarjs/cognitive-complexity": "off",
"import/no-extraneous-dependencies": ["error", { devDependencies: true }],
"no-underscore-dangle": "off",
"@typescript-eslint/no-unused-vars": ["error", { argsIgnorePattern: "^_" }],
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "rantstats-extension",
"version": "1.5.0",
"version": "1.5.1",
"packageManager": "yarn@4.6.0",
"description": "Add support for capturing paid Rumble Rants for Rumble.com livestreams.",
"main": "output/pages/content/content.js",
Expand Down
7 changes: 4 additions & 3 deletions src/components/open-chat/open-chat.ts
Original file line number Diff line number Diff line change
Expand Up @@ -82,9 +82,10 @@ const addCacheButtonToNode = (parentClassName: string, onclick: () => void): boo
}

/**
*
* @param parentClassName
* @param onclick
* Add button to open cached data below video player
* @param parentClassName class name of section to add button to
* @param onclick function to handle button click
* @returns true if button added
*/
const addCacheButtonToActions = (parentClassName: string, onclick: () => void): boolean => {
// get related videos list
Expand Down
88 changes: 51 additions & 37 deletions src/components/rants/rant.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,12 @@
import { cacheMessage, getAllCachedMessageIds, getBadge, getBadges, getUser, updateCachedMessage } from "../../cache"
import {
cacheMessage,
getAllCachedMessageIds,
getBadge,
getBadges,
getOptions,
getUser,
updateCachedMessage,
} from "../../cache"
import { CacheBadge, GiftPurchaseNotification, Notification } from "../../types/cache"
import { CONSTS } from "../../types/consts"
import { SortOrder } from "../../types/option-types"
Expand Down Expand Up @@ -396,16 +404,17 @@ const renderRant = async (
}

/**
*
* @param messageId
* @param time
* @param text
* @param raidNotification
* @param username
* @param userImage
* @param badges
* @param read
* @param cachePage
* Render a raid notification
* @param messageId id of the message
* @param time Time message was posted
* @param text text of the notification
* @param raidNotification raid notification information
* @param username Username for user
* @param userImage Optional path to profile image
* @param badges badges for user
* @param read true: message should be marked read
* @param cachePage true: data being displayed on cache page
* @returns A void promise
*/
const renderRaidNotification = async (
messageId: string,
Expand Down Expand Up @@ -673,19 +682,20 @@ const renderGiftNotification = async (
const GIFTED_REGEX = /Was gifted a membership by (?<giver_name>.+?) /

/**
*
* @param text
* Checks if the text indicates the user received a gift
* @param text the notification text
* @returns true if text matches gift receiver text
*/
export const isGiftReceiver = (text: string): boolean => {
return GIFTED_REGEX.exec(text) !== null
}

/**
*
* @param messageId
* @param time
* @param text
* @param username
* Render a notification
* @param messageId id of the message
* @param time Time message was posted
* @param text text of the notification
* @param username Username for user
*/
export const addGiftReceiver = (messageId: string, time: string, text: string, username: string): void => {
if (text === undefined || text === "") {
Expand Down Expand Up @@ -813,32 +823,36 @@ export const renderMessage = async (

const messageIdNotification = `${messageId}-notification`

const options = await getOptions()

if (isGiftReceiver(text)) {
addGiftReceiver(messageId, time, text, realUsername)
} else if (raid_notification) {
await renderRaidNotification(
messageId,
time,
text,
raid_notification,
realUsername,
realUserImage,
badges,
read,
cachePage,
)
if (options?.includeRaids)
await renderRaidNotification(
messageId,
time,
text,
raid_notification,
realUsername,
realUserImage,
badges,
read,
cachePage,
)
} else if (rant && text !== "") {
// subscription may not have a message text so don't render
await renderRant(messageId, time, text, rant, realUsername, realUserImage, badges, read, cachePage)
} else if (giftPurchaseNotification) {
await renderGiftNotification(
messageIdNotification,
time,
giftPurchaseNotification,
realUsername,
realUserImage,
cachePage,
)
if (options?.includeRaids)
await renderGiftNotification(
messageIdNotification,
time,
giftPurchaseNotification,
realUsername,
realUserImage,
cachePage,
)
} else if (notification) {
await renderNotification(messageIdNotification, time, notification, realUsername, realUserImage, cachePage)
}
Expand Down
2 changes: 1 addition & 1 deletion src/manifest.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"manifest_version": 3,
"name": "RantStats Extension for Rumble.com",
"version": "1.5.0",
"version": "1.5.1",
"description": "Add support for capturing paid Rumble Rants for Rumble.com livestreams.",
"icons": {
"16": "images/icon-16.png",
Expand Down
34 changes: 28 additions & 6 deletions src/pages/options/options.html
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<!doctype html>
<html class="rantstats">
<html class="rantstats" lang="en">
<head>
<title>Options | RantStats Extension for Rumble.com</title>

Expand Down Expand Up @@ -79,11 +79,7 @@ <h1>RantStats Extension Options</h1>

<div class="option">
<div class="option-info">
<label
class="name"
for="open-location"
title="Opens the Rant Stats data in a popup instead of sidebar"
>
<label class="name" for="open-location" title="Open Rant Stats in a popup instead of sidebar">
Open as Popup</label
>
<p class="description">Open Rant Stats in a popup instead of sidebar</p>
Expand All @@ -93,6 +89,32 @@ <h1>RantStats Extension Options</h1>
<input type="checkbox" id="open-location" />
</div>
</div>

<div class="option">
<div class="option-info">
<label class="name" for="include-gifts" title="Include gifted subscriptions in the sidebar">
Include Gifts</label
>
<p class="description">Include gifted subscriptions in the sidebar</p>
</div>

<div class="selector">
<input type="checkbox" id="include-gifts" />
</div>
</div>

<div class="option">
<div class="option-info">
<label class="name" for="include-raids" title="Include incoming raids in the sidebar">
Include Raids</label
>
<p class="description">Include incoming raids in the sidebar</p>
</div>

<div class="selector">
<input type="checkbox" id="include-raids" />
</div>
</div>
</div>

<footer>
Expand Down
8 changes: 8 additions & 0 deletions src/pages/options/options.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ const themeSelect = document.getElementById("theme") as HTMLSelectElement
const openLocationCheckbox = document.getElementById("open-location") as HTMLInputElement
const bytesUseSpan = document.getElementById(CONSTS.BYTES_USE_ID) as HTMLSpanElement
const alternateColorsCheckbox = document.getElementById("alternate-colors") as HTMLInputElement
const includeGiftsCheckbox = document.getElementById("include-gifts") as HTMLInputElement
const includeRaidsCheckbox = document.getElementById("include-raids") as HTMLInputElement

// temporary options before saving
let tempOptions: Options = null
Expand Down Expand Up @@ -60,6 +62,8 @@ const setOptions = (options: Options): void => {
themeSelect.value = options.theme.toString()
openLocationCheckbox.checked = options.asPopup
alternateColorsCheckbox.checked = options.alternateColors
includeGiftsCheckbox.checked = options.includeGifts
includeRaidsCheckbox.checked = options.includeRaids

tempOptions = options

Expand All @@ -77,6 +81,8 @@ const getCurrentOptions = (): Options => {
theme: themeSelect.value,
asPopup: openLocationCheckbox.checked,
alternateColors: alternateColorsCheckbox.checked,
includeGifts: includeGiftsCheckbox.checked,
includeRaids: includeRaidsCheckbox.checked,
}
}

Expand Down Expand Up @@ -200,6 +206,8 @@ themeSelect.addEventListener("change", optionChanged)
openLocationCheckbox.addEventListener("change", optionChanged)
bytesUseSpan.addEventListener("change", optionChanged)
alternateColorsCheckbox.addEventListener("change", optionChanged)
includeGiftsCheckbox.addEventListener("change", optionChanged)
includeRaidsCheckbox.addEventListener("change", optionChanged)
document.getElementById("clear").addEventListener("click", clearOptions)
document.getElementById("open-rants").addEventListener("click", triggerOpenRantsPage)
document.getElementById("open-about").addEventListener("click", triggerOpenAboutPage)
Expand Down
10 changes: 10 additions & 0 deletions src/types/option-types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,14 @@ export type Options = {
* Alternate colors of messages in chat
*/
alternateColors: boolean
/**
* Include gifted subscriptions
*/
includeGifts: boolean
/**
* Include raid notifications
*/
includeRaids: boolean
}

/**
Expand All @@ -79,4 +87,6 @@ export const defaultOptions: Options = {
theme: Theme.Rumble.toString(),
asPopup: false,
alternateColors: false,
includeGifts: true,
includeRaids: true,
}
Loading