Skip to content

Commit

Permalink
feat(ext/twitch): inject pronouns badge next to streamer names
Browse files Browse the repository at this point in the history
closes #116
  • Loading branch information
cyyynthia committed Apr 16, 2024
1 parent c74ad53 commit 53009e1
Show file tree
Hide file tree
Showing 2 changed files with 42 additions and 7 deletions.
9 changes: 5 additions & 4 deletions packages/extension/src/modules/twitch/components/badge.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ const BADGE_WRAPPER = css({
color: 'var(--color-background-base)',
marginRight: '4px',
bottom: '-1px',
textDecoration: 'none',
})

const BADGE = css({
Expand Down Expand Up @@ -67,10 +68,10 @@ const BADGE_BORDER_WRAPPER = css({

const BADGE_BORDER_CONTAINER = css({
position: 'absolute',
width: '100%',
top: '50%',
left: '50%',
transform: 'translate(-50%, -50%)',
width: 'calc(100% + 4px)',
top: '-2px',
left: '-2px',
transform: 'translateY(-25%)',
})

const BADGE_BORDER_ELEMENT = css({
Expand Down
40 changes: 37 additions & 3 deletions packages/extension/src/modules/twitch/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -178,7 +178,7 @@ async function injectWhisperHeader (header: HTMLElement) {
if (!pronouns || !pronouns.sets.en) return

const badge = badgeComponent(pronouns)
badge.setAttribute('style', css({ position: 'absolute', top: '50%', transform: 'translateY(-50%)' }))
badge.setAttribute('style', css({ position: 'absolute', top: '50%', transform: 'translateY(-50%)', color: badge.style.color }))

const username = header.querySelector('span')
username!.parentElement!.appendChild(
Expand Down Expand Up @@ -221,6 +221,30 @@ async function injectViewerCard (element: HTMLElement) {
)
}

async function injectStreamerHeader (header: HTMLElement) {
let container: HTMLElement | SVGElement | null = header.parentElement
if (!container) return

const streamerId = await fetchReactProp(header, [ { $find: 'channelID', $in: [ 'return', 'memoizedProps' ] }, 'channelID' ])
if (!streamerId) return

const pronouns = await fetchPronouns('twitch', streamerId)
if (!pronouns || !pronouns.sets.en) return

const badge = badgeComponent(pronouns)
badge.style.marginRight = '0'
badge.style.marginLeft = '1rem'

if (window.getComputedStyle(container).display !== 'flex') {
container.removeChild(header)
container.prepend(container = h('div', { style: css({ display: 'flex', alignItems: 'center' }) }, header))
} else {
badge.style.bottom = ''
}

container.appendChild(badge)
}

async function injectStreamerAbout () {
const channelInfo = document.querySelector<HTMLElement>('.channel-info-content')
if (!channelInfo) return
Expand Down Expand Up @@ -270,7 +294,7 @@ function bind7tvCompat () {

// Send inject request
const send = () => window.postMessage({ source: 'pronoundb', payload: { action: 'ttv.inject-chat' } })
const interval = setInterval(send, 1e3)
const interval = setInterval(send, 5e3)
send()

// Await for the acknowledgement of injection
Expand All @@ -291,7 +315,7 @@ function bind7tvCompat () {
function handleMutation (nodes: MutationRecord[]) {
for (const { addedNodes } of nodes) {
for (const added of addedNodes) {
if (added instanceof HTMLElement) {
if (added instanceof HTMLElement && added.tagName !== 'BR' && added.tagName !== 'LINK' && added.tagName !== 'SCRIPT') {
if (settings.chat) {
const displayName = added.querySelector<HTMLElement>('.chat-author__display-name')
// Chat message
Expand All @@ -306,6 +330,13 @@ function handleMutation (nodes: MutationRecord[]) {
continue
}

// Big channel info
if (added.querySelector('[data-target="channel-header-right"]')) {
const streamerTitle = added.querySelector<HTMLElement>('a:has(.tw-title)')
if (streamerTitle) injectStreamerHeader(streamerTitle)
continue
}

// 7TV compat, cuz why respect Twitch semantics :D
if (added.className === 'seventv-message') {
const userMessage = added.querySelector<HTMLElement>('.seventv-user-message')
Expand Down Expand Up @@ -382,6 +413,9 @@ export function inject () {
document.querySelectorAll<HTMLElement>('.chat-author__display-name').forEach((el) => injectChat(el))
if (document.querySelector('.about-section')) injectStreamerAbout()

const existingStreamerTitle = document.querySelector<HTMLElement>('.home-header-sticky:has([data-target="channel-header-right"]) a:has(.tw-title)')
if (existingStreamerTitle) injectStreamerHeader(existingStreamerTitle)

// Inject 7tv compat code
window.addEventListener('message', handle7tvMessage)
if (document.querySelector('.seventv-chat-scroller')) {
Expand Down

0 comments on commit 53009e1

Please sign in to comment.