#stage-discussion

1 messages ยท Page 9 of 1

daring gale
#

theres a 1.5x box as well

vapid veldt
#

looks pretty good

daring gale
#

for slightly larger than 1:1

unkempt hill
#

anyone feel like eating a cum glazed donut

daring gale
#

ill pass

eternal iron
#

not really

unkempt hill
#

oh

#

i have extras

#

are you sure

#

i bought a bakers dozen

finite monolith
#

i'd like a normal donut

#

i'm not a cum enjoyer

unkempt hill
#

why is that a thing anyways

#

like why 13

#

and why is a dozen 12

#

i guess bakers only deal in prime numbers

daring gale
#

"douze" in french stands for 12 forsenScoots

unkempt hill
#

more like douche

finite monolith
vapid veldt
unkempt hill
#

forsenmidlyamused

#

forsenlookingatyousideways

#

sadL what ever happened to the original OMGScoots

#

people only use the pajlada one now

finite monolith
#

$origin OMGScoots

twilit haloBOT
#

treuks, https://supinic.com/data/origin/detail/368 channel FFZ emote: Crudely drawn version of the original OMGScoots face, which was a photo of SirScoots's face giving a "Oh really?" look. It used to be a global emote, but was removed because of SirScoots requesting it to be taken down. Added on 2017-02-27. Made by @pomegranateflea.

vapid veldt
#

i asked him if it could be a 7tv global

unkempt hill
#

oh yeah

#

I remember that

vapid veldt
unkempt hill
finite monolith
#

yeah

#

i mean

#

paja is good enough

unkempt hill
#

Nerdge but does he even own the copyright

#

we should ask the photographer

#

for usage rights

vapid veldt
#

that'd be fucked LULE

unkempt hill
#

i mean

#

twitch does that

#

thats what happened to lul

#

but in reverse

finite monolith
#

rip

unkempt hill
#

guy was ok with it but photographer sued

vapid veldt
#

paja's likeness is owned by twitch right

#

so can't use that

finite monolith
vapid veldt
#

another forsen global LULE

daring gale
#

i dont think you can own someone's "likeness" OMEGALUL

vapid veldt
#

well idfk how to works LULE

unkempt hill
#

yeah you can own rights to use it

#

but also

#

why would they

daring gale
#

well yeah rights, but not exclusivity

unkempt hill
#

no not exclusivily

#

but also why would twitch give a fuck about pajlada

#

its not like he's a mascot

finite monolith
#

literally no reason

unkempt hill
#

for them

finite monolith
#

he's one of the

vapid veldt
#

make pajascoots global arnoldHalt

daring gale
#

yeah hes just a dev

finite monolith
#

10000 twitch employees

unkempt hill
#

oh

#

thats why

#

he made it a sub emote

#

ReallyMad taking a global and putting it behind a paywall

finite monolith
#

cmonBRUH

#

is there something special i need to make eslint have the same checks as the ci does

#

stylelint?

#

dank

unkempt hill
#

nope

#

had this problem

#

forever

#

@daring gale idk did we ever actually come up with a solution for this, it was like this on the trainwrecks site too wasnt it\

#

like its fucking desynced

#

github actions uses different rules

#

than local

#

which still

#

makes no sense to me

daring gale
#

yeah not sure ApuThink maybe make the linter versions fixed

unkempt hill
#

and I dont understand how its even possible in the first place

daring gale
#

remove the ^ symbol

#

github might have a different version cached

finite monolith
#

is there some kind of a way to use stylelint inside of .vue files though

unkempt hill
#

it should by itself

finite monolith
#

not for css

unkempt hill
#

with volar

finite monolith
unkempt hill
#

and you can run the linter manually

#

and it'll just spit out the errors across the whole project

#

just run yarn lint

finite monolith
#
WARNING: You are currently running a version of TypeScript which is not officially supported by @typescript-eslint/typescript-estree.

You may find that it works just fine, or you may not.

SUPPORTED TYPESCRIPT VERSIONS: >=3.3.1 <4.8.0

YOUR TYPESCRIPT VERSION: 4.9.4
green wing
#

is this meant to happen with the new version on chrome?

#

first 1-2 lines are like mostly unreadable

jolly marten
daring gale
#

here

jolly marten
#

oh cool it has autofill preview and tab completion

#

thanks

#

wish it had priority in some way like ffz has favorites

green wing
jolly marten
#

just overwrite the folder and reload in extentions

green wing
#

new extension shows emotes as clickable in chat, though obviously it doesn't do anything rn. is it possible that in the future, clicking on an emote in chat types that emote into the user's message box thingy?

jolly marten
#

/user you mean? that works only for mods. most litely its gonan be an emote preview like ffz

woeful stirrup
#

I think he meant clicking the emote would copy and paste the emote name into the chatbox,
so you dont have to manually highlight the emote text then cvPaste

jolly marten
#

rereading it you might be right

woeful stirrup
#

But i think there is other planned feature for clicking emotes, like emote card and link to the emote page

daring gale
#

it is the time

#

for the GIGA CACHE on cosmetics v2

#

im making it 24h to start troll

finite monolith
#

Aware

polar magnet
#

MegaLUL put "giga" in front of everything

vapid veldt
delicate robin
finite monolith
#

@daring gale

daring gale
finite monolith
#

css pixels are not actual pixels

daring gale
#

whatever they are
they sure aint responsive

finite monolith
#

ok well

#

i replaced them already

#

also

#

can you please clarify this

daring gale
#
  1. the srcset code is duplicated in several places. move it into a utility
finite monolith
#

do i put it in here

daring gale
#
  1. the tooltips rescales after the image loads, so wrap the image in div with defined width/height
#

yeah make it a file called Image or something then export function imageHostToSrcset(host: ImageHost): string

finite monolith
#

honestly

#

i'll move this into there too

#

could be useful

daring gale
#

ye

eternal iron
#

Do you think a 1/5 box could be usefull aswell?

daring gale
#

for the tiny emotes? ApuThink

eternal iron
#

No meaning a 5th of the total width

#

We currently do 1/2 1/3 1/4 1/6

#

1/5 can only group with itself tho

#

Would be like 6/5 units wide

#

A bit more due to the margin

daring gale
#

idk

#

i think its fine as is unless that makes it look better

eternal iron
#

Would allow for some of the slightly wider than 1x1 emotes to fit more tightly, but wouldnt make it look better most likely

polar magnet
#

should it be based on pixel dimensions rather than ratio?

#

in case non-128-pixel-tall emotes become a thing ( FeelsStrongMan )

eternal iron
#

Well, the ratio is calculated based on how they tile in this grid

#

So moving the determineRatio isnt really nessesary since its only needed in the emote menu

#

Everywhere else should just use the actual dimentions

#

@finite monolith

finite monolith
polar magnet
#

const ratio = L + youFellOff+ ripbozo;

finite monolith
#

my vscode and the formatter disagree on the formatting

unkempt hill
#

but they most certainly are

#

what people online mean when they are referring to this

#

is that they scale on retina or hidpi displays

#

or that when you zoom in the px size changes, but thats without saying

#

em and rem are based on the font size and therefor much more accessable

#

ie if a user has trouble seeing, they can elect to make the font size larger

#

so its not completely applicable everywhere but in most places it makes sense

#

i prefer rem over em though

daring gale
#

rem is reset

#

em inherits

unkempt hill
#

yeah

#

em can get confusing fast since if you were to set the font size to 2em that just means 2 times whatever the parent font size was

#

so it chains up

finite monolith
#

tf !.

#

shirley

#

that won't crash everything

#

ok it didn't and it works well

#

the only problem is that this returns a size that's okay for the actual chat

#

but not for the display

eternal iron
#

Just calculate based on the bounding box

finite monolith
eternal iron
#

if your max-width is 8rem just do (8rem*height)/width

#

I guess that wouldnt work very well for narrow emotes

#

hmm

finite monolith
#

ideally

#

i just need to show a 3x or a 4x

#

based on how big the bounding box is

#

this is the value used for the actual chat emotes

#

i could probably just pass in a size var into this to make the tooltip emotes of a size -1

#

so they would be bigger

#

but it feels kinda donk

#

i'm Clueless

eternal iron
#

I believe the function might give incorrect values in some cases right now aswell

#

since we map all emote types to the ActiveEmote

#

But we dont have a guarantee that they have sizes 1, 2, 3, 4

finite monolith
#

yeah

#

that did happen already

eternal iron
#

7tv emotes do, but the other providers might now

finite monolith
#

before

#

especially for the special cases of

#

emotes only having size 1

#

so being just 16x16

#

i need to get the size that's the closest to the bounding box size

#

and i'm a bit clueless

#

on how i can do that

eternal iron
#

You could probably replace the ```ts
${i + 1}x

with ```ts
`${f.name.charAt()}x`
#

Since all the filenames are formated like 1x or 1.0 or 1

daring gale
#

no

#

dont do that

finite monolith
#

forsenInsane what the fuck do i do

eternal iron
#

I guess the proper way would be to implement different reducers for each provider

daring gale
#

there's no guarantee the file names are gonna keep having a number

finite monolith
#

ffz file names don't have a number

eternal iron
#

Different reducers it is then

daring gale
#

for 7TV it's simple the width/Height values are provided

#

for the rest

#

just set a fixed size then fit the image in it

unkempt hill
#

32 72 98?

eternal iron
finite monolith
daring gale
#

not many ffz wides exist and no one uses bttv wide emotes so just default it to a square if it's non-7tv

finite monolith
#

BAND

unkempt hill
#

does bttv let you do wide emotes now

finite monolith
#

yes

unkempt hill
#

i feel like i remember him adding that

finite monolith
#

BAND on forsens chat

#

is a bttv emote

unkempt hill
#

same time he added his version of the event api

daring gale
#

yeah a couple months back just before night went on twitter to bitch about 7tv

unkempt hill
#

these fucks are so bad i copied their shit

daring gale
finite monolith
#

i guess i can try just forcing the emotes to a specific height

#

that would make their size a good size

eternal iron
#

We talked about calculating emote dimensions in the sharedworker

#

But probably wont be a thing for at least a little while

daring gale
#

i thought about it but like

eternal iron
#

Would require the worker to dl all the emotes

daring gale
#

itd require sending a network request to download every emote ahead of time

#

perhaps with wasm it would be possible to download only the headers

#

but thats dank territory

eternal iron
#

I think i need to change some stuff on the Emote component aswell

finite monolith
#

PagChomp rust in the extension

eternal iron
#

Since the v-if unload happens on the same tick as the srcSet gets set to ""

#

So the img request is actually never canceled

#

Which renders the intersection observer kinda useless

unkempt hill
#

with wasm you cant download anything

daring gale
#

LULE nice

unkempt hill
#

you need to message pass to a js glue script

#

to access

#

any api

#

thats why it sucks

#

and is super slow

daring gale
eternal iron
#

Lets make v4.0.0 right now POG

unkempt hill
#

also

#

why are we concerned about image dimensions

#

we know the image dimensions

#

atleast the aspect

#

the aspect should be identical

eternal iron
#

Not for other providers?

daring gale
#

of 7TV emotes

unkempt hill
#

well no that doesnt matter

#

we can just enforce whatever multiple we choose

eternal iron
unkempt hill
#

we dont have to follow the images version of 4x or whatever multiple

#

we just say the height is always 3 times the height of 1x

#

and force the image into that box

daring gale
#

yes

unkempt hill
#

then we know the height before hand

#

with no requests

#

or calculation

daring gale
#

though it means non-7TV will always be fit into squares

#

but thats fine tbh

unkempt hill
#

not neccissarily

#

we know the aspect too

#

because we have the original 1x image

#

already downloaded

#

(ideally)

eternal iron
#

No?

unkempt hill
#

yes its a hover card

daring gale
#

i suppose yea

unkempt hill
#

you cant hover something thats not there

#

so we know the exact aspect ratio

#

we just need to scale it

#

and force whatever higher res image we download

#

to be that scaled size we expected

#

even if its a different multiple

#

this is better anyways

eternal iron
#

You could, if your internet is slow enough i guess PEPW

unkempt hill
#

because it'll be consistent

#

in that case

#

we just do a 1:1

#

assumption

eternal iron
#

yea

unkempt hill
#

it'll pop in

#

but so will the emote

#

so thats fine

finite monolith
#

oh

#

that's a good idea

daring gale
finite monolith
#

just use the ratio of the 1x emote to force the tooltip to that ratio beforehand

eternal iron
#

We could go 1 step further tho

eternal iron
#

Since it would also be nice to know the emote dimentions before inserting them into the chat

unkempt hill
#

emote size atlas

#

every emote

eternal iron
#

To avoid any popin

unkempt hill
#

on our servers

#

all the time

eternal iron
unkempt hill
#

no

#

bad idea?

daring gale
#

which is fine

unkempt hill
#

offload to the user

eternal iron
unkempt hill
#

give users an option

#

image popin the first time they see an emote

#

or delay rendering

#

if you think you have fast enough internet

#

that youd just rather wait the additional ms to download

#

before you see anything

daring gale
#

i think

unkempt hill
#

then its their fault

#

they chose it

#

lesser of two evils

finite monolith
#

therefore i am

daring gale
#

we just make a loading box

#

assume it's 1:1

unkempt hill
#

yes this is fine

eternal iron
#

Yea, like the emote menu

daring gale
#

unless it's 7tv and has dimensions in api

#

so yeah

#

apply the same thing as in the emote menu for chat

#

then it looks clean for slow internet ppl

#

also im thinking of defaulting the emote menu to static

#

and animating only on hover

finite monolith
#

yeah

#

i thought of that too

daring gale
#

or animating only on hover, in a radius around the cursor

unkempt hill
#

double the requests

finite monolith
#

just track where the user is looking

#

and then only animate that

daring gale
#

request amount dont matter with media

eternal iron
#

We are already doing that @finite monolith

unkempt hill
#

also for that to work the static images on the api need to work first

daring gale
#

its the bandwidth that matter

#

http/2 carries

unkempt hill
finite monolith
#

yes

unkempt hill
#

and making a bad joke about foviated rendering

finite monolith
#

i am

daring gale
#

yeah i'll fix the api , i dont rly like the static_name property tho

finite monolith
#

static_nam

unkempt hill
#

we should

#

drop that

#

completely

#

and do like twitch does

#

with a templated format

daring gale
#

yea

unkempt hill
#

just specify somewhere in the api what the template is

#

not hardcoded

#

then you dont even need an image property

#

because it can be assumed that

#

if an emote really doenst have an image

#

the request will just fail

daring gale
#

i mean other than that the ImageHost is fine i believe

unkempt hill
#

with a known error

#

its rarely neccissary

#

to enumerate

#

because you know before hand

#

what you will need

finite monolith
#

Clueless surely this tooltip idea will be easy enough

#

Clueless ๐Ÿค™ clueeeeeeeeeee

daring gale
#

whats so hard about it

#

yust set a ref on the img tag in ChatEmote and extract the width/height values

finite monolith
#

4me

daring gale
#

then when the tooltip is called you pass those values as props

#

multiply by 3

#

PagStick done

#

PagStick no way that was so easy

unkempt hill
#
  • some css
#

to force either height or width

#

to our expected value

#

if it isnt

daring gale
#

or actually @unkempt hill ref or onload?

#

does onload pass the img element

unkempt hill
#

technically

#

you can extract it

#

event.target

daring gale
#

yea do that then @finite monolith set a onload listener on the img tag in ChatEmote

#

and assign the width/height values to refs that are passed as props to the tooltip

unkempt hill
#

yea store them in refs, should be easy to do

finite monolith
#

okay egg

unkempt hill
#

maybe we should use naturalWidth

#

idk @daring gale do we ever restrict the size of emotes in chat

#

or do we always follow the image size

#

if its the latter than regular width should be fine

eternal iron
#

There is no max size

finite monolith
#

SubHype

daring gale
#

let's not restrict size so we can be the last bastion of hope and fun next time people find an exploit to upload big emotes

finite monolith
eternal iron
#

I remember that day PepeLa

unkempt hill
#

just thinking because width will be wrong if the size was restricted

finite monolith
#

lets intentionally restrict the size in the tooltip so you can see it better though

unkempt hill
#

like if you imagine the width was restricted to 32px and the emote was wider, img.height would be wrong, the aspect would be right but we couldnt just multiply by 3 to get our size

#

.naturalHeight always represents the actual image size though pretty sure

daring gale
#

me on my way to put a gigantic emote in my personal set that only i can use because i manually uploaded it to the cdn

unkempt hill
#

sadL personal emotes implemented poorly

#

cant troll now

finite monolith
unkempt hill
#

imagine if you could just have any emote at any time

finite monolith
#

you can just get a huge badge

unkempt hill
#

technically you could but you'd have to swap out the set details every time

finite monolith
#

fourtf had an account with the gnome meme gif

#

that was like 128x128

daring gale
#

fourtf does that yea

unkempt hill
#

yeah ive seen that fucking badge

#

actual internet terrorist

finite monolith
unkempt hill
daring gale
#

i mean why imagine tho

#

technically that is the case

unkempt hill
#

le epic admin troll

daring gale
#

although it's artificially limited in the sense that personal sets have restrictions

unkempt hill
#

nah i meant like even more le epic troll

daring gale
#

like you can only update a given personal slot once an hour atm

finite monolith
unkempt hill
#

like using a random collection of emotes from anywhere on the site in any message at will tf

finite monolith
#

huge 256x512 personal emote

#

at all ratios

daring gale
#

oh LULE

eternal iron
#

Basically a /clear in any chat LULE

finite monolith
#

as long as i can spam

#

AINTNOWAY

#

i am happy

unkempt hill
#

ant no way

eternal iron
#

Anyone know why the different twitch sub plans are named like Prime, 1000, 2000, 3000 ?

finite monolith
#

thats weird

daring gale
#

dank thats why

#

but its about the tiers

eternal iron
#

"Maybe we need a tier 1.5 in the future" Pepega

finite monolith
#

new 7tv idea

polar magnet
#

floating point tiers

eternal iron
#

Well i've just assumed that 1000 is tier 1

finite monolith
#

$js "0.3 - 0.1"

twilit haloBOT
#

treuks, 0.3 - 0.1

finite monolith
#

feelsdonkman

polar magnet
#

0.2 5Head

finite monolith
#

$js 0.2 + 0.1

twilit haloBOT
#

treuks, 0.30000000000000004

finite monolith
#

there we go

unkempt hill
eternal iron
#

wdym

unkempt hill
#

ie teir 3 20 month sub badge is 3020

eternal iron
#

ahh

polar magnet
#

Pft. I have a 3060 and it's way faster EZ

finite monolith
#

i have a 1030 Sadeg

eternal iron
#

3080 GIGACHAD

polar magnet
#

"I'm richer than you" GIGACHAD

eternal iron
#

"You manage your money better than me" GIGACHAD

polar magnet
#

true LULE

eternal iron
#

Could have sold it for 2.5x the price tho

unkempt hill
#

any gtx 650 users

polar magnet
#

4060 will probably outperform a 3070 for the price of a 3060

#

waiting = free performance

polar magnet
finite monolith
#

Not managing my money better, just poor LULE

finite monolith
#

how do i use the vue @onload directive

#

i cant figure out how i can get the emote size

#

on load

eternal iron
#

onload is in when the img has finished loading?

finite monolith
#

yeah

#

i think so

#

oh

#

lol

eternal iron
#

<img has an @ load i believe

finite monolith
#

yeah figured that one out

#

Apu how do i extract the width out of the loaded image

eternal iron
#

Mind sending what your code looks like now?

finite monolith
#

uhh

#

i can send the entire chat emote file

#

what

#

i'm in a discord server??????????????????

#
<template>
    <div class="emote-box">
        <img
            v-if="srcSet"
            ref="imgRef"
            class="chat-emote"
            :srcset="srcSet"
            :alt="emote.name"
            :class="{ blur: hideUnlisted && emote.data?.listed === false }"
            @click="openCard"
            @load="let height = `NaM`;"
            @mouseenter="show(imgRef)"
            @mouseleave="hide()"
        />
        <template v-for="(e, index) of emote.overlaid" :key="index">
            <img
                class="chat-emote zero-width-emote"
                :class="{ blur: hideUnlisted && e.data?.listed === false }"
                :srcset="getSrcSet(e)"
                :alt="' ' + e.name"
            />
        </template>
    </div>
</template>

<script setup lang="ts">
import { computed, ref } from "vue";
import { useConfig } from "@/composable/useSettings";
import { useTooltip } from "@/composable/useTooltip";
import { tools } from "@/site/twitch.tv/modules/chat/ChatBackend";
import ChatEmoteTooltip from "@/site/twitch.tv/modules/chat/components/ChatEmoteTooltip.vue";

const props = withDefaults(
    defineProps<{
        emote: SevenTV.ActiveEmote;
        imageFormat?: SevenTV.ImageFormat;
        unload?: boolean;
    }>(),
    { unload: false, imageFormat: "WEBP" },
);

const srcSet = computed(() => (props.unload ? "" : getSrcSet(props.emote)));

function getSrcSet(emote: SevenTV.ActiveEmote) {
    const host = emote.data?.host ?? { url: "", files: [] };
    const format = host.files.some((fi) => fi.format === props.imageFormat) ? props.imageFormat : host.files[0]?.format;

    return host.files
        .filter((f) => f.format === format)
        .map((f, i) => `${host.url}/${f.name} ${i + 1}x`)
        .join(", ");
}

const imgRef = ref<HTMLElement>();

const { show, hide } = useTooltip(ChatEmoteTooltip, {
    emote: props.emote,
    width: Number,
    height: Number,
});
#

there we go

eternal iron
#

Change this
const imgRef = ref<HTMLElement>();
to
const imgRef = ref<HTMLImageElement>();

daring gale
#

define a function, with Event as argument, then set @load="onImageLoaded" (your func name)

#

then define 2 refs

#
const width = ref(0);
const height = ref(0);```
eternal iron
#

Do we even need the onload here?

daring gale
#

in onImageLoaded, grab evt.target (which should be a HTMLImageElement)

eternal iron
#

Cant we just use the naturalWidth directly?

daring gale
#

you cannot, the image width will be 0 if its not loaded

eternal iron
#

Yes, but it will be loaded when we hover right?

daring gale
#

not necessarily

eternal iron
#

Its 0 by default with the @ load aswell ?

#

so same result

daring gale
#

doesnt matter onload is better here

#

we don't need a permanent ref to the image

#

we only care about extracting its size once

finite monolith
#

how does ref work

eternal iron
#

its just a proxied value

#

So the setter and getter triggers side effects which lets vue have its reactivity

finite monolith
#

ok

#

i got what that is used for

#

i guess

eternal iron
#

In the script you have to use asd.value to get or set

#

but in the <template it does it automatically

finite monolith
#

do i use the natural sizes

daring gale
#

regular sizes are fine here

eternal iron
#

Probably dosnt matter

daring gale
#

but yeah dont actually hold a ref to the image, just take evt.target in the onload event

eternal iron
#

we already hold a ref to the image

daring gale
#

what for?

finite monolith
daring gale
#
const target = event.target as HTMLImageElement;```
eternal iron
#

we pass it to the show()

#

show(imgRef)

finite monolith
#

oh nice

daring gale
#

i think i'll set up a directive for tooltips

finite monolith
#

is this right

daring gale
#

not a huge fan of the show() and hide() thing when it could just be setting v-tooltip on the img tag

eternal iron
#

true

daring gale
#

seems right yea, do an additional check here

if (!(ev.target instanceof HTMLImageElement)) return;```
#

actually im not sure about the performance of instanceof

#

maybe @unkempt hill knows

#

a null check is fine too i think

finite monolith
#

oh yeah

daring gale
#

realistically it cannot be anything other than null or an image element

#

so instance check might be overkill

finite monolith
#

yeah

#

i'll just check for null

#

okay egg

#

alright this should work now

#

so

eternal iron
#

I mean, this is literally the same, since the values get updated once the img loads anyway ```ts
const { show, hide } = useTooltip(ChatEmoteTooltip, {
emote: props.emote,
width: imgRef.value.width,
height: imgRef.value.height,
});

#

And we already have the ref

finite monolith
#

The electricity cut off is forcing me to finish this tomorrow I guess

eternal iron
finite monolith
#

Other than that

#

Wow Vue is super fucking simple

eternal iron
#

Yea, super nice

finite monolith
#

I expect things to be complicated and then it's as easy as this

daring gale
#

generally the tooltip composable isnt ideal

#

it can just be a directive

#

i'll make that change later, keep it with an onload listener for future proofing

daring gale
finite monolith
#

Anyways I also thought of something

#

Aren't bttv 3x emotes 112px

daring gale
#

some are

#

but others are like 155px tall

finite monolith
#

But the 1x is always like 16px right

eternal iron
#

no

#

usually 24

daring gale
#

if youre trying to get at some constant its not going to work

finite monolith
#

Nah what I'm saying is

eternal iron
#

28*

finite monolith
#

Ok

#

Nvm then

#

Multiplying by 3 will work

daring gale
eternal iron
#

uh, how will this work for high resolution stuff?

daring gale
#

what high resolution stuff

eternal iron
#

Nah, im overthinking i believe

finite monolith
#

Like if the chat is using 3x emotes?

#

Will just setting the image size in the img tag work

daring gale
#

no use css instead

#
width: v-bind("width");
height: v-bind("height");
finite monolith
#

Holy shit

#

That's op

daring gale
#

LULE welcome to vue 3

finite monolith
daring gale
#

react copers are afraid of this channel

gleaming dagger
daring gale
finite monolith
#

I bet that would take like 10 lines of react to do

#

Nvm

daring gale
#

more than 10

#

ever tried styling stuff in react AINTNOWAY

#

holy fuck AINTNOWAY

finite monolith
#

No I thankfully never used react in my life

daring gale
gleaming dagger
daring gale
#

life expectancy raised by 10 years

daring gale
gleaming dagger
#

FeelsDankMan reactive value

#

FeelsDankMan so like a state?

daring gale
#

react brain LULE

finite monolith
daring gale
#

AINTNOWAY they dont have reactive values

#

AINTNOWAY everything has to go through predefined states only accessible inside the component

finite monolith
#

Pure functional "programming"

gleaming dagger
#

im sure you can do that with some fucking library with 3 weekly downloads

daring gale
#

๐Ÿ’€ holy fuck the cope is unreal

gleaming dagger
#

i never said that was a good thing โœ‹

daring gale
#

keep having fun with your entire component tree rerendering once you update one prop FeelsOkayMan

finite monolith
gleaming dagger
#

thanks i will keep having fun :3

#

have fun with ur green thing

daring gale
#

the thing about react is it was created at a time where the DOM performance was really really bad

#

so back then it made sense

#

but how it achieved what it did with its "virtual dom" was banking on the idea that they can just do a lot of calculations outside the DOM, and only issue dom mutations for things that did change

#

however this is a very primitive strategy

#

youre still gonna have hundreds or thousands of internal rerenders, which these days have not much difference with just mutating the DOM this many times

finite monolith
#

It's funny

#

All modern frameworks just use raw Dom elements

daring gale
#

ya

#

frameworks have gotten smarter since the days of react

#

its a matter of time until facebook completely abandons it

finite monolith
#

Clueless

daring gale
#

or facebook itself collapses

#

whichever happens first

finite monolith
#

Copesen

#

As much as id like both

#

Neither of those will happen

daring gale
#

i like how workers can create caches that will withstand a nuclear bomb

#

the metaphorical nuclear bomb being when the user clears their cache the normal way

#

you have to go all the way to application tab -> storage and tick the thing at the very bottom in the devtools to clear it happE

polar magnet
#

Even if โ€”disk-cache-dir and โ€”media-cache-dir are both set to a tmpfs directory?

daring gale
#

Legacy cosmetics v2 support added

#

its cached to absolute hell though

#

i dont even know long

#

probably until you reset your entire goddamn pc LULE

peak shuttle
polar magnet
#

BatChest ๐Ÿค™ CAAAAAAACHE

daring gale
#

i think i'll

#

like

#

add a button to clear the legacy cosmetics cache

#

but never actually clear it automatically

#

cause theres honestly 0 need to. its just there for the transitory period until all clients are updated

woeful stirrup
#

KUKLE CATSH

vapid veldt
polar magnet
#

I can't wait until everyone sees me using my heckin personal emotes

#

I just have to sit and be filled with Despairge

#

when a situation happens where an emote is perfect but xqc is dumb and doesn't have the emote madashell

#

tf add a random usernamd and prefix to the popup though, to make it look like a sub emote tf tf tf tf tf

#

people can't get mad at 7tv then

vapid veldt
#

GachiPls elis emotes in xqc chat

ruby otter
peak shuttle
#

It would be nice if 7TV showed the active 7TV users in the chat , so that I can do the math on 7TV viewers - current viewers = Plebs that won't get my emote enabled super doper funny money comment.

unkempt hill
#

ive never tested

#

but theoretically its like barely any check

#

its just looking at the prototype

#

probably slightly worse the more inheritance you have

#

but we need to do this check anyways, or we should rather, because typescript is correct

#

when it says that target isnt always going to be the element you expect it to be

#

i dont think onload bubbles but there are other conditions i beleive where target might be incorrect, it could also just be null

#

and an instanceof check does both of those

daring gale
#

@unkempt hill for mapping user IDs to messages, can we actually use a WeakMap here ApuThink

#

im trying to think of a way

#

to avoid doing iterations when handling a user getting timed out/banned

#

to modify the message properties

unkempt hill
#

you cant iterate a weakmap

daring gale
#

yeah not to iterate

#

but b asically

#

the event for a timeout only gives us a user id

#

so we need to map user ids to messages

unkempt hill
#

weakmap is basically just equivalent to setting a symbol'ed prop

#

on an object

#

except

#

it doesnt need to be an object

daring gale
#

weakmap needs a pointer right

unkempt hill
#

yeah

daring gale
#

as the key

unkempt hill
#

you still need referential access

#

to the object to retrieve its value

#

i think a regular map is fine

#

and not really any more overhead

#

we just need to keep it in sync

#

when we flush messages

#

flush the indexes too

daring gale
#

the issue with regular map tho

#

is how do we clear it out without iterating

unkempt hill
#

wdym

#

you can just clear a map

#

map.clear()

#

resets all keys and values

daring gale
#

yeah but it's mapped to user ids

#

so when the buffer clears old messages we'd need to iterate

unkempt hill
#

im not sure i really see what the issue is

#

oh you mean like that

#

ApuThink just do two maps then 5Head

#

like a jagged array but a map

eternal iron
#

Wasnt the idea that we dont want to iterate

unkempt hill
#

you iterate already though

#

you know exactly what messages you remove

eternal iron
#

And we'd need one that has a message id as the key to handle deletions

unkempt hill
#

no matter how you do it, you always know what you removed

eternal iron
#

and one that has userid's to handle bans/timeouts

unkempt hill
#

you could keep message ids sort of like how i did the usermap in the trainwrecks site

eternal iron
unkempt hill
#

cant you just keep two synced arrays and a map

eternal iron
#

wdym

unkempt hill
#

like just keep a map of user ids to message ids and a map of message ids to message objects

#

when you flush the message buffer take all the messages ids you just removed

#

and remove them from the map of their user

#

you know exactly what messages you remove when you flush, so you should know what users those were from

#

iterating 10 messages is better

#

than iterating all of the messages

#

every time you want to delete

#
        flushUserCache() {
            if (this.seenUsers.indexed.length < 60) return;

            const index = this.seenUsers.indexed;
            const map = this.seenUsers.users;

            const removed = index.splice(0, index.length - 31);

            for (const id of removed) {
                map.delete(id);
            }

            for (let i = 0; i < index.length; i++) {
                const stale = map.get(index[i]);

                if (stale) {
                    stale[0] = i;
                }
            }
        },

        updateUserCache(user: ChatUser) {
            this.flushUserCache();

            const stale = this.seenUsers.users.get(user.id);

            if (stale) {
                const index = stale[0];

                this.seenUsers.indexed.splice(index, 1);
            }

            const index = this.seenUsers.indexed.push(user.id) - 1;

            this.seenUsers.users.set(user.id, [index, user]);
        },
    },
``` this concept but without the index part
eternal iron
#

We also have the issue of the scrollBuffer

unkempt hill
#

just append to user maps when you receive a message

#

and only destroy them on flush

eternal iron
#

When the scrollbuffer overflows it never calls a flush tho

unkempt hill
#

why do we let the scroll buffer overflow on its own?

#

just do the same thing then there

#

when we splice

#

grab the message objects we removed

#

lookup their users in the user table

#

and delete them from that set

#

so the structs are like
Map(UserID, Set(MessageID))
Map(MessageID, Set(Message))
Message[]

#

where the messages in the set

#

are referentially equal

#

to the messages in the array

#

yeah that should change actually, that should be a Map(MessageID, Index)

#

and we just keep it in sync

#

like the above code does for seen users

#

so message[] is the only place messages actually are stored in their full form

#

when we lookup we just grab index so we can splice out of the array

#

and delete from map

#

when we flush we just lookup in each of our maps, and delete, we have to order them though in a good way

#

to avoid having to reindex

#

every time we flush

#

if you reverse that maybe its better, so the map is the source of truth for the messages and the array is just the order

#

no reindexing issue then

#

so

Map(UserID, Set(MessageID))
Map(MessageID, Message)
MessageID[]
#

then when you flush the messages you retrieve from the map what you just removed, pull off the user and grab its message id set, and remove the message id from it

eternal iron
#

Uh, we use the Message[] for the chat-list

unkempt hill
#

well then reindexing is unavoidable

#

you have to iterate

#

at some point

#

you will need to iterate

#

you could i suppose make messages like a node tree

#

just a big linked list

#

no reindexing or ordering problems

#

because you just pop out and update references

#

rendering then sucks though

#

because you must do it in order

#

you cant say give me message 100

#

but does vue even render like this?

#

if not then probably not a problem no?

eternal iron
#

im pretty sure it just needs an iterator

unkempt hill
#

so like i mean

head = &Message
length = int
ids = Map(ID, &Message) 

Message {
  previous: &Message,
  next: &Message,
  user: &User,
  contents: {}
}

User {
  messages: &Message[],
}
#

ignore the heavy mixed language pseudo code

#

then when you want to delete a message by id

#

you just grab the message object

#

and update the previous node's next pointer

#

to your next pointer

#

or you can do this for as many messages as you'd like

#

if you want to delete an entire users messages, just do that for all of them

#

when you want to flush just start at head

#

and remove X nodes

#

you need to keep a length counter

#

somewhere

#

making an iterator is not a problem if thats what vue needs

#

in this structure the only thing that needs iteration is the user message map

#

but that will in all likelyhood be very small

#

comparitively

#

@daring gale I think this makes sense no?

daring gale
unkempt hill
#

thats if we can actually get vue to render this

#

but I think vue always renders from top to bottom

#

anyways

#

so

#

probably not a big deal

#

vue takes in any iteratable iirc

#

so a generator function should work just fine

#

that walks the nodes

#

so also to clarify here I mean for this to completely replace

#

the message list array

#

with a linked list

#

reindexing, poping, and deletions then are non issues

#

because we can store direct pointers to the nodes

#

and update their ancestors and children

#

without ever needing to iterate the whole thing

eternal iron
#

How would we use it together with the messageBuffer and scrollBuffer?

unkempt hill
#

eliminate the scroll buffer and message buffer

#

just keep a different "head"

#

for the scroll

#

and then when we want to append

#

just set the tails parent

#

to the head of the scroll

#

when flushing we just go to the message head

#

and compare our length count

eternal iron
#

Think you would be able to implement this in a 10th of the time it would take me x0r6ztGiggle

unkempt hill
#

and remove however many nodes

#

we need to

#

its kind of like the same way git works sort of, if that helps to visualize it

#

where branches are just different head nodes

daring gale
#

@eternal iron keep the iteration on mod messages for now tbh LULE we can look into this later

eternal iron
#

Thinking the same

#

Also just gonna ignore the scroll buffer for now

#

Worst case is that someone sees a message that should have been removed Gasp

daring gale
#

whats scroll buffer?

unkempt hill
#

he means messages

#

that are hidden

#

while the chat is paused

daring gale
#

oh that

eternal iron
#

yea

daring gale
#

oh like as in those dont get updated by mod actions if chat is paused?

eternal iron
#

correct

daring gale
#

ok thats fine

unkempt hill
#

just for beta though right

daring gale
#

yeah

unkempt hill
#

i wouldnt keep that for full

#

beta is fine who cares

daring gale
#

we will need to fix it

#

but right now its w/e

eternal iron
#

So much stuff that needs to be done boatyDeleteImmediately

daring gale
#

just add a ticket on clickup so we remember

#

we're past much of the biggest tasks

#

@unkempt hill where the emojis Okayeg

unkempt hill
#

๐Ÿ˜ญ ๐Ÿ˜น ๐Ÿฅš ๐Ÿ†

teal knoll
#

nice emojis

unkempt hill
#

yeah @teal knoll where are the emojis

finite monolith
#

๐Ÿ˜‚

teal knoll
#

๐Ÿ˜‚ right here

finite monolith
#

Wtf is going on

daring gale
#

@eternal iron i think for card opener functions we might have to come back to the initial solution with the dummy message

unkempt hill
#

i beleive this is the only solution

#

no

eternal iron
#

Depends, we might be able to hook something

unkempt hill
#

needs to be a bit more intelegent though

#

like we need to keep the message around

#

because eventually

#

twitch's native

#

can overflow

#

if too many fallback messages render

eternal iron
#

Is the dummy message so that twitch creates a msg instance we can hook?

unkempt hill
#

and I beleive didn't that opener stop working

#

once

#

the message was gone

daring gale
#

i think so

#

i also was only able to get emote cards working

#

not user cards

unkempt hill
#

so we need to keep its rendered instance and move it around

daring gale
#

but i mightve been doing it wrong

unkempt hill
#

in our hooked render func

daring gale
#

merging cosmetics

eternal iron
#

I wonder how the merge into my branch is gonna look boatyDeleteImmediately

finite monolith
daring gale
unkempt hill
daring gale
#

its gonna conflict pretty sure

eternal iron
#

Mine will probably have conflicts with master after this

unkempt hill
#

fix conflicts when you merge to master

eternal iron
#

Wont that result in 2 commits on master?

finite monolith
#

Merge master into your branch I guess?

unkempt hill
#

not if you do it properly

#

merge commits are commits

#

they usually are meant to contain the conflict fixes

#

in themselves

#

and then they have two parents

#

one to the original head

#

and another to your branch

#

github wont let you do it this way though

#

if you merge through gui

finite monolith
#

Btw

#

What should we do with badge tooltips

eternal iron
#

Make them look good

vapid veldt
daring gale
#

i was gonna mention, add the base style with the border and background blur to the base tooltip style

#

then replicate a somewhat similar layout

#

badge title and provider logo

#

or actually eh no provider logo

#

badge name would say it

#

just the image and the title

eternal iron
#

Lets make an option for the paint to cover the entire message when doing /me PagMan

daring gale
#

reserved for tier 3 subs

finite monolith
#

Sadeg

#

How will I kill people with epilepsy without that

eternal iron
#

Imagine animated paints then LULE

finite monolith
#

Speaking of epilepsy

#

Do you think it would make sense to disable animations and make them work on hover if you have reduced motions enabled

unkempt hill
#

yes but

#

i think we need to more consider

#

the animated emotes option in native twitch

#

that should take precidence

#

as well as ffz's option

#

maybe just an or is sufficient here

finite monolith
#

Oh fuck

unkempt hill
#

any of the above being limited motion

finite monolith
#

That's a dank idea

unkempt hill
#

should mean we should do that as well

eternal iron
#

Hooking the twitch option should be trivial

daring gale
#

hook twitch option for timestamps too

#

it doesnt need to be a 7tv setting

eternal iron
#

Yea

finite monolith
#

Truee

eternal iron
#

I think i commented saying that i should do that instead

finite monolith
#

That's a good idea

#

I like when we reuse twitch stuff

eternal iron
#

I hooked the useReadableColors

#

I wonder if timestamps are there aswell

daring gale
#

how was the merge

finite monolith
#

Mereg

eternal iron
#

Not bad

#

A couple lines in badges

finite monolith
#

I should make it into an emote when I get the time to

daring gale
#

mer-ge Okayge

finite monolith
#

FFmpega TeaTime

eternal iron
#

The prop is on the same thing i hooked earlier for primaryColor and ReadableColors pOg

unkempt hill
unkempt hill
#

a git logo

#

with a ge face

daring gale
#

i guess we should also add in mod icons later

#

just to make it look exactly like normal chat

eternal iron
#

...but the slider Sadge

daring gale
#

slider is pog but i can already see it

#

angry jannies coming into the discord

#

asking

#

where the FUCK is my permaban button

unkempt hill
#

tf mod slider shouldnt be part of core tho

#

tf addon

daring gale
#

true mod slider should probably be a separate module

#

altho

#

we need to do like

#

i guess we could add slots in various places

#

for other modules to hook onto

unkempt hill
#

yeah just like a namespace key modular hook system

#

core:message

#

then addons who make their own hooks

#

can be addon:hookname

daring gale
#

yea

eternal iron
#

The slider benefits from wrapping the chatline tho

#

But it dosnt need to be solved that way

daring gale
#

yeah thats why we can use vue <slot />

eternal iron
#

It does

daring gale
#

place named <slot /> in various places where it might be useful for other modules to add content

unkempt hill
eternal iron
#

Its part of the code right now since it was easy to port

unkempt hill
#

expressjs

#

style modules

eternal iron
#

can be moved later

unkempt hill
#

explicit next();

eternal iron
#

It could also just be a composeable

#

Instead of a module

unkempt hill
#

compost bin

eternal iron
#

I feel like the useChatApi should be changed a bit in the future

#

Right now it feels like we bind anything and everything there

#

Which makes it return a lot of stuff we dont need

daring gale
#

yeah it could be broken up a bit

eternal iron
#

Leave it to handle the actual chat and scroll

#

And move props to somewhere else

daring gale
#

useChatMessages, useChatStates, useEmotes