mirror of
https://codeberg.org/SafeTwitch/safetwitch.git
synced 2025-02-01 17:18:44 -05:00
Format and eslint
This commit is contained in:
parent
d27ef3560c
commit
a8ae6be436
11 changed files with 128 additions and 127 deletions
|
@ -1,30 +1,30 @@
|
||||||
import type { Badge, ParsedMessage } from './types';
|
import type { Badge, ParsedMessage } from './types'
|
||||||
|
|
||||||
export function getBadges(badges: Badge[], badgesToFind: { setId: string; version: string; }[]) {
|
export function getBadges(badges: Badge[], badgesToFind: { setId: string; version: string }[]) {
|
||||||
const foundBadges = [];
|
const foundBadges = []
|
||||||
if(!badges) return
|
if (!badges) return
|
||||||
|
|
||||||
for (let badgeToFind of badgesToFind) {
|
for (const badgeToFind of badgesToFind) {
|
||||||
const badge = badges
|
const badge = badges
|
||||||
.filter((badge) => badge.setId === badgeToFind.setId)
|
.filter((badge) => badge.setId === badgeToFind.setId)
|
||||||
.find((badge) => badge.version === badgeToFind.version);
|
.find((badge) => badge.version === badgeToFind.version)
|
||||||
|
|
||||||
if (badge) {
|
if (badge) {
|
||||||
foundBadges.push(badge);
|
foundBadges.push(badge)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return foundBadges;
|
return foundBadges
|
||||||
}
|
}
|
||||||
|
|
||||||
export const getBadgesFromMessage = (message: ParsedMessage, allBadges: Badge[]) => {
|
export const getBadgesFromMessage = (message: ParsedMessage, allBadges: Badge[]) => {
|
||||||
let badgesString = message.data.tags.badges;
|
const badgesString = message.data.tags.badges
|
||||||
if (!badgesString) return;
|
if (!badgesString) return
|
||||||
let badges = badgesString.split(',');
|
const badges = badgesString.split(',')
|
||||||
let formatedBadges = badges.map((badgeWithVersion: string) => {
|
const formatedBadges = badges.map((badgeWithVersion: string) => {
|
||||||
const [setId, version] = badgeWithVersion.split('/');
|
const [setId, version] = badgeWithVersion.split('/')
|
||||||
return { setId, version };
|
return { setId, version }
|
||||||
});
|
})
|
||||||
|
|
||||||
return getBadges(allBadges, formatedBadges);
|
return getBadges(allBadges, formatedBadges)
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,48 +1,46 @@
|
||||||
import type { Badge, ParsedMessage } from "./types";
|
import type { Badge, ParsedMessage } from './types'
|
||||||
import { getBadgesFromMessage } from './badges'
|
import { getBadgesFromMessage } from './badges'
|
||||||
|
|
||||||
|
|
||||||
export function parseMessage(messageData: string, allBadges: Badge[]): ParsedMessage {
|
export function parseMessage(messageData: string, allBadges: Badge[]): ParsedMessage {
|
||||||
const message = JSON.parse(messageData);
|
const message = JSON.parse(messageData)
|
||||||
|
|
||||||
switch (message.type) {
|
switch (message.type) {
|
||||||
case "PRIVMSG": {
|
case 'PRIVMSG': {
|
||||||
const tags = message.tags
|
const tags = message.tags
|
||||||
const username = message.username
|
const username = message.username
|
||||||
const data: ParsedMessage = {
|
const data: ParsedMessage = {
|
||||||
type: "PRIVMSG",
|
type: 'PRIVMSG',
|
||||||
data: { message: message.message, username, tags },
|
data: { message: message.message, username, tags }
|
||||||
};
|
|
||||||
|
|
||||||
const badges = getBadgesFromMessage(data, allBadges);
|
|
||||||
data.data.badges = badges
|
|
||||||
|
|
||||||
return data
|
|
||||||
}
|
}
|
||||||
case "USERNOTICE": {
|
|
||||||
const username = message.tags.login;
|
const badges = getBadgesFromMessage(data, allBadges)
|
||||||
const resub = message.tags["msg-id"] === "resub";
|
data.data.badges = badges
|
||||||
const months = parseInt(message.tags["msg-param-cumulative-months"]);
|
|
||||||
return {
|
return data
|
||||||
type: "USERNOTICE",
|
}
|
||||||
data: { username, resub, months },
|
case 'USERNOTICE': {
|
||||||
};
|
const username = message.tags.login
|
||||||
|
const resub = message.tags['msg-id'] === 'resub'
|
||||||
|
const months = parseInt(message.tags['msg-param-cumulative-months'])
|
||||||
|
return {
|
||||||
|
type: 'USERNOTICE',
|
||||||
|
data: { username, resub, months }
|
||||||
}
|
}
|
||||||
case "CLEARMSG": {
|
}
|
||||||
return {
|
case 'CLEARMSG': {
|
||||||
type: "CLEARMSG",
|
return {
|
||||||
data: {
|
type: 'CLEARMSG',
|
||||||
username: message.tags['@login'],
|
data: {
|
||||||
}
|
username: message.tags['@login']
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Add more cases for other message types here
|
}
|
||||||
default: {
|
// Add more cases for other message types here
|
||||||
return {
|
default: {
|
||||||
type: "UNKNOWN",
|
return {
|
||||||
data: { message },
|
type: 'UNKNOWN',
|
||||||
};
|
data: { message }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -6,14 +6,14 @@ import type { QualityLevelList, QualityLevel } from 'videojs-contrib-quality-lev
|
||||||
|
|
||||||
export const createQualitySelector = (player: any) => {
|
export const createQualitySelector = (player: any) => {
|
||||||
const qualityLevels: QualityLevelList = player.qualityLevels()
|
const qualityLevels: QualityLevelList = player.qualityLevels()
|
||||||
const MenuButton = videojs.getComponent('MenuButton');
|
const MenuButton = videojs.getComponent('MenuButton')
|
||||||
const MenuItem = videojs.getComponent('MenuItem');
|
const MenuItem = videojs.getComponent('MenuItem')
|
||||||
let formatedQualities: {name: string, index: number, id:string}[];
|
let formatedQualities: { name: string; index: number; id: string }[]
|
||||||
|
|
||||||
const setQuality = (id: string) => {
|
const setQuality = (id: string) => {
|
||||||
const found = formatedQualities.find(i => i.id === id)
|
const found = formatedQualities.find((i) => i.id === id)
|
||||||
for(let quality of qualityLevels.levels_) {
|
for (const quality of qualityLevels.levels_) {
|
||||||
if(quality.id !== id) {
|
if (quality.id !== id) {
|
||||||
quality.enabled = false
|
quality.enabled = false
|
||||||
} else {
|
} else {
|
||||||
quality.enabled = true
|
quality.enabled = true
|
||||||
|
@ -21,7 +21,7 @@ export const createQualitySelector = (player: any) => {
|
||||||
}
|
}
|
||||||
|
|
||||||
qualityLevels.selectedIndex_ = found?.index
|
qualityLevels.selectedIndex_ = found?.index
|
||||||
qualityLevels.trigger({ type: 'change', selectedIndex: found?.index})
|
qualityLevels.trigger({ type: 'change', selectedIndex: found?.index })
|
||||||
}
|
}
|
||||||
|
|
||||||
class CustomMenuButton extends MenuButton {
|
class CustomMenuButton extends MenuButton {
|
||||||
|
@ -30,13 +30,13 @@ export const createQualitySelector = (player: any) => {
|
||||||
createItems() {
|
createItems() {
|
||||||
const player = this.player()
|
const player = this.player()
|
||||||
|
|
||||||
return this.options_.items.map((item : {name: string}) => {
|
return this.options_.items.map((item: { name: string }) => {
|
||||||
const qualitySelectorButton = new MenuItem(player, { label: item.name })
|
const qualitySelectorButton = new MenuItem(player, { label: item.name })
|
||||||
qualitySelectorButton.handleClick = (data) => {
|
qualitySelectorButton.handleClick = (data) => {
|
||||||
const qualityClicked = data.currentTarget.innerText
|
const qualityClicked = data.currentTarget.innerText
|
||||||
const id = formatedQualities.find(i => i.name === qualityClicked)?.id
|
const id = formatedQualities.find((i) => i.name === qualityClicked)?.id
|
||||||
|
|
||||||
if(id) {
|
if (id) {
|
||||||
setQuality(id)
|
setQuality(id)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -45,7 +45,7 @@ export const createQualitySelector = (player: any) => {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
videojs.registerComponent('CustomMenuButton', CustomMenuButton);
|
videojs.registerComponent('CustomMenuButton', CustomMenuButton)
|
||||||
|
|
||||||
qualityLevels.on('addqualitylevel', () => {
|
qualityLevels.on('addqualitylevel', () => {
|
||||||
formatedQualities = qualityLevels.levels_.map((quality: QualityLevel) => {
|
formatedQualities = qualityLevels.levels_.map((quality: QualityLevel) => {
|
||||||
|
@ -56,14 +56,13 @@ export const createQualitySelector = (player: any) => {
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
||||||
player.controlBar.addChild('CustomMenuButton', {
|
player.controlBar.addChild('CustomMenuButton', {
|
||||||
title: 'Qualities',
|
title: 'Qualities',
|
||||||
items: formatedQualities
|
items: formatedQualities
|
||||||
});
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
qualityLevels.on('change', function () {
|
qualityLevels.on('change', function () {
|
||||||
const qualityLabel = qualityLevels[qualityLevels.selectedIndex].height?.toString() + 'p'
|
// TODO: Change label off button
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
export interface Badge {
|
export interface Badge {
|
||||||
id: string,
|
id: string
|
||||||
title: string,
|
title: string
|
||||||
setId: string,
|
setId: string
|
||||||
version: string,
|
version: string
|
||||||
images: { [k:string]: string }
|
images: { [k: string]: string }
|
||||||
}
|
}
|
|
@ -1,5 +1,4 @@
|
||||||
export interface ParsedMessage {
|
export interface ParsedMessage {
|
||||||
type: string;
|
type: string
|
||||||
data: { [k: string]: any };
|
data: { [k: string]: any }
|
||||||
};
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
<template>
|
<template>
|
||||||
<div class="flex mx-auto justify-center bg-ctp-crust rounded-lg w-2/3 p-2 text-white">
|
<div class="flex mx-auto justify-center bg-ctp-crust rounded-lg w-2/3 p-2 text-white">
|
||||||
<div class="flex space-x-3">
|
<div class="flex space-x-3">
|
||||||
<h1 class="text-4xl font-bold">Searching...</h1>
|
<h1 class="text-4xl font-bold">Searching...</h1>
|
||||||
<v-icon name="fa-circle-notch" class="animate-spin w-10 h-10"></v-icon>
|
<v-icon name="fa-circle-notch" class="animate-spin w-10 h-10"></v-icon>
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
</template>
|
</template>
|
|
@ -29,7 +29,7 @@ export default {
|
||||||
)
|
)
|
||||||
const data = await streamDataFetch.json()
|
const data = await streamDataFetch.json()
|
||||||
|
|
||||||
if(data.stream) {
|
if (data.stream) {
|
||||||
data.stream.streamer = { name: props.name, pfp: data.pfp }
|
data.stream.streamer = { name: props.name, pfp: data.pfp }
|
||||||
streamData = data.stream
|
streamData = data.stream
|
||||||
}
|
}
|
||||||
|
@ -60,25 +60,25 @@ export default {
|
||||||
<template>
|
<template>
|
||||||
<div v-if="streamData">
|
<div v-if="streamData">
|
||||||
<div class="bg-ctp-crust rounded-lg w-[27rem]">
|
<div class="bg-ctp-crust rounded-lg w-[27rem]">
|
||||||
<RouterLink :to="'/' + streamData.streamer.name">
|
<RouterLink :to="'/' + streamData.streamer.name">
|
||||||
<img :src="streamData.preview" class="rounded-lg rounded-b-none" />
|
<img :src="streamData.preview" class="rounded-lg rounded-b-none" />
|
||||||
</RouterLink>
|
</RouterLink>
|
||||||
<div class="text-white p-2 inline-flex space-x-2 w-full h-16">
|
<div class="text-white p-2 inline-flex space-x-2 w-full h-16">
|
||||||
<div class="inline-flex">
|
|
||||||
<div class="inline-flex">
|
<div class="inline-flex">
|
||||||
<img :src="streamData.streamer.pfp" class="rounded-full mr-2" />
|
<div class="inline-flex">
|
||||||
<div class="w-full">
|
<img :src="streamData.streamer.pfp" class="rounded-full mr-2" />
|
||||||
<p class="font-bold w-[22.9rem] truncate">{{ streamData.title }}</p>
|
<div class="w-full">
|
||||||
<div class="inline-flex w-full justify-between">
|
<p class="font-bold w-[22.9rem] truncate">{{ streamData.title }}</p>
|
||||||
<p class="text-gray-300">{{ streamData.streamer.name }}</p>
|
<div class="inline-flex w-full justify-between">
|
||||||
<p class="self-end float-right">
|
<p class="text-gray-300">{{ streamData.streamer.name }}</p>
|
||||||
<v-icon name="io-person"></v-icon> {{ abbreviate(streamData.viewers) }}
|
<p class="self-end float-right">
|
||||||
</p>
|
<v-icon name="io-person"></v-icon> {{ abbreviate(streamData.viewers) }}
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
</template>
|
</template>
|
||||||
|
|
|
@ -20,15 +20,17 @@ export default {
|
||||||
const game: string = this.$route.params.game.toString()
|
const game: string = this.$route.params.game.toString()
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const res = await fetch(`${protocol}${import.meta.env.VITE_BACKEND_DOMAIN}/api/discover/${game}`)
|
const res = await fetch(
|
||||||
if (!res.ok) {
|
`${protocol}${import.meta.env.VITE_BACKEND_DOMAIN}/api/discover/${game}`
|
||||||
return this.data = { status: 'error' }
|
)
|
||||||
}
|
if (!res.ok) {
|
||||||
this.data = await res.json()
|
return (this.data = { status: 'error' })
|
||||||
} catch (err) {
|
|
||||||
this.data = { status: 'error' }
|
|
||||||
console.error(err)
|
|
||||||
}
|
}
|
||||||
|
this.data = await res.json()
|
||||||
|
} catch (err) {
|
||||||
|
this.data = { status: 'error' }
|
||||||
|
console.error(err)
|
||||||
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
abbreviate(text: number) {
|
abbreviate(text: number) {
|
||||||
|
|
|
@ -11,7 +11,6 @@ export default {
|
||||||
let data: Ref<any | undefined> = ref()
|
let data: Ref<any | undefined> = ref()
|
||||||
let frontend_url = protocol + import.meta.env.VITE_INSTANCE_DOMAIN
|
let frontend_url = protocol + import.meta.env.VITE_INSTANCE_DOMAIN
|
||||||
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
data,
|
data,
|
||||||
protocol,
|
protocol,
|
||||||
|
@ -30,7 +29,7 @@ export default {
|
||||||
},
|
},
|
||||||
|
|
||||||
filterSearches(toFilter: string) {
|
filterSearches(toFilter: string) {
|
||||||
const categories: HTMLCollectionOf<Element> = this.$refs.categoryItem as HTMLCollectionOf<Element>
|
const categories = this.$refs.categoryItem
|
||||||
const wantedTags: string[] = toFilter.split(',').filter((v) => v.toLowerCase())
|
const wantedTags: string[] = toFilter.split(',').filter((v) => v.toLowerCase())
|
||||||
|
|
||||||
for (let category of categories as any) {
|
for (let category of categories as any) {
|
||||||
|
@ -100,7 +99,6 @@ export default {
|
||||||
console.error(error)
|
console.error(error)
|
||||||
this.data = { status: 'error' }
|
this.data = { status: 'error' }
|
||||||
}
|
}
|
||||||
|
|
||||||
},
|
},
|
||||||
components: {
|
components: {
|
||||||
StreamPreviewVue,
|
StreamPreviewVue,
|
||||||
|
@ -111,7 +109,6 @@ export default {
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
|
|
||||||
<loading-screen v-if="!data"></loading-screen>
|
<loading-screen v-if="!data"></loading-screen>
|
||||||
<error-message v-else-if="data.status === 'error'"></error-message>
|
<error-message v-else-if="data.status === 'error'"></error-message>
|
||||||
|
|
||||||
|
@ -120,7 +117,11 @@ export default {
|
||||||
<h1 class="font-bold text-5xl">Following</h1>
|
<h1 class="font-bold text-5xl">Following</h1>
|
||||||
<p class="text-xl">Streamers you follow</p>
|
<p class="text-xl">Streamers you follow</p>
|
||||||
<ul class="flex overflow-x-scroll flex-nowrap h-80 space-x-1">
|
<ul class="flex overflow-x-scroll flex-nowrap h-80 space-x-1">
|
||||||
<li v-for="streamer in following" :key="streamer" class="inline-block hover:scale-105 transition-transform">
|
<li
|
||||||
|
v-for="streamer in following"
|
||||||
|
:key="streamer"
|
||||||
|
class="inline-block hover:scale-105 transition-transform"
|
||||||
|
>
|
||||||
<stream-preview-vue :name="streamer"></stream-preview-vue>
|
<stream-preview-vue :name="streamer"></stream-preview-vue>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { ref, onMounted } from 'vue'
|
import { ref } from 'vue'
|
||||||
import { useRoute } from 'vue-router'
|
import { useRoute } from 'vue-router'
|
||||||
import VideoPlayer from '@/components/VideoPlayer.vue'
|
import VideoPlayer from '@/components/VideoPlayer.vue'
|
||||||
import TwitchChat from '@/components/TwitchChat.vue'
|
import TwitchChat from '@/components/TwitchChat.vue'
|
||||||
|
@ -15,13 +15,15 @@ export default {
|
||||||
|
|
||||||
const getUser = async () => {
|
const getUser = async () => {
|
||||||
try {
|
try {
|
||||||
const res = await fetch(`${protocol}${import.meta.env.VITE_BACKEND_DOMAIN}/api/users/${username}`)
|
const res = await fetch(
|
||||||
|
`${protocol}${import.meta.env.VITE_BACKEND_DOMAIN}/api/users/${username}`
|
||||||
|
)
|
||||||
const data = await res.json()
|
const data = await res.json()
|
||||||
return data
|
return data
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error(error)
|
console.error(error)
|
||||||
return {
|
return {
|
||||||
status: 'error',
|
status: 'error'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -32,7 +34,9 @@ export default {
|
||||||
controls: true,
|
controls: true,
|
||||||
sources: [
|
sources: [
|
||||||
{
|
{
|
||||||
src: `${protocol}${import.meta.env.VITE_BACKEND_DOMAIN}/proxy/stream/${username}/hls.m3u8`,
|
src: `${protocol}${
|
||||||
|
import.meta.env.VITE_BACKEND_DOMAIN
|
||||||
|
}/proxy/stream/${username}/hls.m3u8`,
|
||||||
type: 'application/vnd.apple.mpegurl'
|
type: 'application/vnd.apple.mpegurl'
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
|
@ -46,11 +50,11 @@ export default {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
components: {
|
components: {
|
||||||
VideoPlayer,
|
VideoPlayer,
|
||||||
TwitchChat,
|
TwitchChat,
|
||||||
ErrorMessage,
|
ErrorMessage,
|
||||||
FollowButton,
|
FollowButton,
|
||||||
LoadingScreen
|
LoadingScreen
|
||||||
},
|
},
|
||||||
async mounted() {
|
async mounted() {
|
||||||
const fetchedUser = await this.getUser()
|
const fetchedUser = await this.getUser()
|
||||||
|
@ -68,9 +72,7 @@ export default {
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
|
|
||||||
<loading-screen v-if="!data"></loading-screen>
|
<loading-screen v-if="!data"></loading-screen>
|
||||||
|
|
||||||
<error-message v-else-if="data.status === 'error'"></error-message>
|
<error-message v-else-if="data.status === 'error'"></error-message>
|
||||||
|
|
Loading…
Add table
Reference in a new issue