Run eslint and fix all issues

This commit is contained in:
dragongoose 2023-03-18 13:49:02 -04:00
parent 0c38345bd1
commit c31def6221
14 changed files with 333 additions and 272 deletions

View File

@ -11,5 +11,6 @@ module.exports = {
], ],
parserOptions: { parserOptions: {
ecmaVersion: 'latest' ecmaVersion: 'latest'
} },
'ignorePatterns': ["*.config.*"]
} }

View File

@ -1,6 +1,6 @@
<script setup lang="ts"> <script setup lang="ts">
import { RouterView } from 'vue-router' import { RouterView } from 'vue-router'
import NavbarItem from './components/Navbar.vue' import NavbarItem from './components/NavbarView.vue'
</script> </script>
<template> <template>

View File

@ -1,27 +1,22 @@
import type { VideoJsPlayer } from "video.js"; import 'videojs-contrib-quality-levels'
import "videojs-contrib-quality-levels"; import type { QualityLevelList } from 'videojs-contrib-quality-levels'
import type { QualityLevelList } from "videojs-contrib-quality-levels";
export const createQualitySelector = (player: VideoJsPlayer) => { export const createQualitySelector = (player: any) => {
const qualityLevels: QualityLevelList = player.qualityLevels() const qualityLevels: QualityLevelList = player.qualityLevels()
let currentIndex = 0
player.hlsQualitySelector() const myButton = player.controlBar.addChild('button')
var myButton = player.controlBar.addChild("button"); const myButtonDom = myButton.el()
var myButtonDom = myButton.el(); myButtonDom.innerHTML = 'Hello'
myButtonDom.innerHTML = "Hello";
myButtonDom.addEventListener('click', () => { myButtonDom.addEventListener('click', () => {})
}) qualityLevels.on('change', function () {
console.log('Quality Level changed!')
qualityLevels.on('change', function() { console.log('New level:', qualityLevels[qualityLevels.selectedIndex])
console.log('Quality Level changed!');
console.log('New level:', qualityLevels[qualityLevels.selectedIndex]);
console.log(qualityLevels) console.log(qualityLevels)
const qualityLabel = qualityLevels[qualityLevels.selectedIndex].height?.toString() + 'p' const qualityLabel = qualityLevels[qualityLevels.selectedIndex].height?.toString() + 'p'
myButtonDom.textContent = qualityLabel ?? '' myButtonDom.textContent = qualityLabel ?? ''
}); })
} }

View File

@ -1,26 +0,0 @@
<script lang="ts">
export default {};
import { RouterLink } from 'vue-router'
</script>
<template>
<div class="p-4 flex items-center justify-between bg-ctp-base text-white">
<h1 class="font-bold text-2xl">Naqvbar</h1>
<div>
<form class="relative">
<label for="searchBar" class="hidden">Search</label>
<v-icon name="io-search-outline" class="text-black absolute my-auto inset-y-0 left-2"></v-icon>
<input type="text" id="searchBar" name="searchBar" placeholder="Search" class="rounded-md p-1 pl-8 text-black">
</form>
</div>
<ul class="inline-flex space-x-6 font-medium">
<router-link to="">Github</router-link>
<router-link to="/preferences">Preferences</router-link>
<router-link to="/about">About</router-link>
</ul>
</div>
</template>

View File

@ -0,0 +1,32 @@
<script lang="ts">
export default {}
</script>
<template>
<div class="p-4 flex items-center justify-between bg-ctp-base text-white">
<h1 class="font-bold text-2xl">Naqvbar</h1>
<div>
<form class="relative">
<label for="searchBar" class="hidden">Search</label>
<v-icon
name="io-search-outline"
class="text-black absolute my-auto inset-y-0 left-2"
></v-icon>
<input
type="text"
id="searchBar"
name="searchBar"
placeholder="Search"
class="rounded-md p-1 pl-8 text-black"
/>
</form>
</div>
<ul class="inline-flex space-x-6 font-medium">
<router-link to="">Github</router-link>
<router-link to="/preferences">Preferences</router-link>
<router-link to="/about">About</router-link>
</ul>
</div>
</template>

View File

@ -1,16 +1,66 @@
<script lang="ts"> <script lang="ts">
export default { import { ref, type Ref } from 'vue'
export default {
props: { props: {
isLive: { isLive: {
type: Boolean, type: Boolean,
default() { default() {
return false; return false
}
} }
}, },
channelName: {
type: String
} }
},
setup(props) {
let messages: Ref<
{ username: string; channel: string; message: string; messageType: string }[]
> = ref([])
let ws = new WebSocket('ws://localhost:7000')
return {
ws,
messages,
props
}
},
mounted() {
const chatList = this.$refs.chatList as Element
this.ws.onmessage = (message) => {
if (message.data !== 'OK') {
this.messages.push(JSON.parse(message.data))
this.scrollToBottom(chatList)
}
}
this.ws.onopen = (data) => {
console.log(data)
this.ws.send('JOIN ' + this.props.channelName)
}
},
methods: {
getChat() {
return this.messages
},
scrollToBottom(el: Element) {
el.scrollTop = el.scrollHeight
}
}
}
</script> </script>
<template> <template>
<div v-if="isLive" class="p-3 bg-ctp-crust rounded-lg w-full max-w-xs"> <div v-if="isLive" class="p-3 bg-ctp-crust rounded-lg w-full max-w-xs flex flex-col">
<ul class="overflow-y-scroll h-[82vh]" ref="chatList">
<li v-for="message in getChat()" :key="messages.indexOf(message)">
<div class="text-white inline-flex">
<p class="text-sm">
<strong class="text-ctp-pink font-bold text-sm">{{ message.username }}</strong
>: {{ message.message }}
</p>
</div>
</li>
</ul>
</div> </div>
</template> </template>

View File

@ -5,10 +5,12 @@
</template> </template>
<script lang="ts"> <script lang="ts">
// Importing video-js // Importing video-js
import videojs from 'video.js'; import videojs from 'video.js'
import { createQualitySelector } from '../assets/qualitySelector' import qualitySelector from 'videojs-hls-quality-selector'
import "videojs-contrib-quality-levels"; import qualityLevels from 'videojs-contrib-quality-levels'
import "../assets/vjs-theme.css"
videojs.registerPlugin('qualityLevels', qualityLevels)
videojs.registerPlugin('hlsQualitySelector', qualitySelector)
export default { export default {
name: 'VideoJsPlayer', name: 'VideoJsPlayer',
@ -16,7 +18,7 @@ export default {
options: { options: {
type: Object, type: Object,
default() { default() {
return {}; return {}
} }
} }
}, },
@ -30,22 +32,8 @@ export default {
// when the component is being mounted // when the component is being mounted
mounted() { mounted() {
this.player = videojs('video-player', this.options, () => { this.player = videojs('video-player', this.options, () => {
this.player.log('video player ready', this); this.player.hlsQualitySelector({ displayCurrentQuality: true })
})
this.player.hlsQualitySelector({
displayCurrentQuality: true,
});
createQualitySelector(this.player)
});
},
// destroying the video player
// when the component is being destroyed
beforeDestroy() {
if (this.player) {
this.player.dispose();
}
} }
} }
</script><link rel="stylesheet" href="style.css"> </script>

View File

@ -8,13 +8,29 @@ import 'video.js/dist/video-js.css'
const app = createApp(App) const app = createApp(App)
import { OhVueIcon, addIcons } from "oh-vue-icons"; import { OhVueIcon, addIcons } from 'oh-vue-icons'
import { IoSearchOutline, IoLink, FaCircleNotch, BiTwitter, BiInstagram, BiDiscord, BiYoutube, BiTiktok } from "oh-vue-icons/icons"; import {
IoSearchOutline,
IoLink,
FaCircleNotch,
BiTwitter,
BiInstagram,
BiDiscord,
BiYoutube,
BiTiktok
} from 'oh-vue-icons/icons'
addIcons(IoSearchOutline, IoLink, FaCircleNotch, BiTwitter, BiInstagram, BiDiscord, BiYoutube, BiTiktok) addIcons(
IoSearchOutline,
IoLink,
FaCircleNotch,
BiTwitter,
BiInstagram,
BiDiscord,
BiYoutube,
BiTiktok
)
app.component("v-icon", OhVueIcon); app.component('v-icon', OhVueIcon)
app.use(router) app.use(router)
app.mount('#app') app.mount('#app')

View File

@ -1,5 +1,4 @@
import { createRouter, createWebHistory } from 'vue-router' import { createRouter, createWebHistory } from 'vue-router'
import HomeView from '../views/HomeView.vue'
import UserView from '../views/UserView.vue' import UserView from '../views/UserView.vue'
import PageNotFound from '../views/PageNotFound.vue' import PageNotFound from '../views/PageNotFound.vue'
import PrivacyPageView from '../views/PrivacyPageView.vue' import PrivacyPageView from '../views/PrivacyPageView.vue'
@ -7,11 +6,6 @@ import PrivacyPageView from '../views/PrivacyPageView.vue'
const router = createRouter({ const router = createRouter({
history: createWebHistory(import.meta.env.BASE_URL), history: createWebHistory(import.meta.env.BASE_URL),
routes: [ routes: [
{
path: '/',
name: 'home',
component: HomeView
},
{ {
path: '/privacy', path: '/privacy',
name: 'about', name: 'about',
@ -21,7 +15,7 @@ const router = createRouter({
path: '/:username', path: '/:username',
component: UserView component: UserView
}, },
{ path: '/:pathMatch(.*)*', component: PageNotFound} { path: '/:pathMatch(.*)*', component: PageNotFound }
] ]
}) })

View File

@ -1,7 +0,0 @@
<script setup lang="ts">
</script>
<template>
</template>

View File

@ -1,5 +1,5 @@
<script lang="ts"> <script lang="ts">
export default {}; export default {}
</script> </script>
<template> <template>

View File

@ -1,26 +1,24 @@
<script lang="ts"> <script lang="ts">
export default {}; export default {}
</script> </script>
<template> <template>
<article class="prose prose-invert border-2 border-ctp-peach max-w-prose bg-ctp-crust rounded-lg mx-auto p-8 pt-10 text-white"> <article
class="prose prose-invert border-2 border-ctp-peach max-w-prose bg-ctp-crust rounded-lg mx-auto p-8 pt-10 text-white"
>
<h1>Privacy Policy</h1> <h1>Privacy Policy</h1>
<p>For the oficial instance, no logs are kept except for <p>
when an error is met that affects the user is encounered. For the oficial instance, no logs are kept except for when an error is met that affects the
An example of this is when data retrieval fails when a user user is encounered. An example of this is when data retrieval fails when a user requests. No
requests. No identifying information is kept except for the identifying information is kept except for the time of request. below is an example of this
time of request. below is an example of this data</p> data
</p>
<code class=""> <code class="">
{ { "endpoint":"/api/users/chibidoki", "level":"warn","message": "No element found for selector:
"endpoint":"/api/users/chibidoki", li.InjectLayout-sc-1i43xsx-0:nth-child(2) > a:nth-child(1) > div:nth-child(1) >
"level":"warn","message": div:nth-child(1) > p:nth-child(1)", "origin":"http://localhost:5173",
"No element found for selector: li.InjectLayout-sc-1i43xsx-0:nth-child(2) > a:nth-child(1) > div:nth-child(1) > div:nth-child(1) > p:nth-child(1)", "reqId":"fed6f1f6-403f-4d6a-9943-3d07ea7bf9bb", "timestamp":"2023-03-07T22:42:37.982Z" }
"origin":"http://localhost:5173",
"reqId":"fed6f1f6-403f-4d6a-9943-3d07ea7bf9bb",
"timestamp":"2023-03-07T22:42:37.982Z"
}
</code> </code>
</article> </article>
</template> </template>

View File

@ -1,6 +1,6 @@
<script lang="ts" > <script lang="ts">
import { ref, onMounted } from 'vue' import { ref, onMounted } from 'vue'
import { useRoute } from "vue-router"; import { useRoute } from 'vue-router'
import type { StreamerData } from '../../../server/types/scraping/Streamer' import type { StreamerData } from '../../../server/types/scraping/Streamer'
import VideoPlayer from '../components/VideoPlayer.vue' import VideoPlayer from '../components/VideoPlayer.vue'
import TwitchChat from '../components/TwitchChat.vue' import TwitchChat from '../components/TwitchChat.vue'
@ -16,17 +16,16 @@ export default {
if (res.status !== 200) { if (res.status !== 200) {
const data = await res.json() const data = await res.json()
if(!data.code) { if (!data.code) {
return { return {
status: "error", status: 'error',
code: "error" code: 'error'
} }
} }
return { return {
...data ...data
} }
} }
const data: StreamerData = await res.json() const data: StreamerData = await res.json()
@ -47,10 +46,10 @@ export default {
controls: true, controls: true,
sources: [ sources: [
{ {
src: src: `http://localhost:7000/proxy/stream/${username}/hls.m3u8`,
`http://localhost:7000/proxy/stream/${username}/hls.m3u8`, type: 'application/vnd.apple.mpegurl'
type: 'application/vnd.apple.mpegurl', }
}], ],
fluid: true fluid: true
} }
} }
@ -62,32 +61,39 @@ export default {
methods: { methods: {
truncate(value: string, length: number) { truncate(value: string, length: number) {
if (value.length > length) { if (value.length > length) {
return value.substring(0, length) + "..."; return value.substring(0, length) + '...'
} else { } else {
return value; return value
}
}
} }
},
},
} }
</script> </script>
<template> <template>
<div v-if="!data" id="loadingDiv" class="flex mx-auto justify-center bg-ctp-crust rounded-lg w-2/3 p-2 text-white"> <div
v-if="!data"
id="loadingDiv"
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>
<div v-else-if="data.status === 'error'" class="flex flex-col max-w-prose justify-center text-center mx-auto p-6 bg-ctp-crust rounded-lg text-white"> <div
v-else-if="data.status === 'error'"
class="flex flex-col max-w-prose justify-center text-center mx-auto p-6 bg-ctp-crust rounded-lg text-white"
>
<div class="mb-6"> <div class="mb-6">
<h1 class="font-bold text-5xl">oops...</h1> <h1 class="font-bold text-5xl">oops...</h1>
<p class="font-bold text-3xl">this wasn't supposed to happen</p> <p class="font-bold text-3xl">this wasn't supposed to happen</p>
</div> </div>
<p class="text-xl">
<p class="text-xl">the server was encountered an error while retriving the data, and now we're here :3</p> the server was encountered an error while retriving the data, and now we're here :3
</p>
<div class="mt-5"> <div class="mt-5">
<p class="text-xl">please contact the administrator with this code</p> <p class="text-xl">please contact the administrator with this code</p>
@ -98,40 +104,56 @@ export default {
<div v-else class="w-full inline-flex space-x-4 justify-center p-4"> <div v-else class="w-full inline-flex space-x-4 justify-center p-4">
<div class="flex flex-wrap bg-ctp-crust p-6 rounded-lg max-w-prose min-w-[65ch] text-white"> <div class="flex flex-wrap bg-ctp-crust p-6 rounded-lg max-w-prose min-w-[65ch] text-white">
<div v-if="data.isLive" class="w-full mx-auto rounded-lg mb-5"> <div v-if="data.isLive" class="w-full mx-auto rounded-lg mb-5">
<video-player <video-player :options="videoOptions"> </video-player>
:options="videoOptions">
</video-player>
</div> </div>
<div class="w-full flex-wrap p-3"> <div class="w-full flex-wrap p-3">
<div class="inline-flex w-2/3"> <div class="inline-flex w-2/3">
<div class="w-20 h-20 relative"> <div class="w-20 h-20 relative">
<img :src="data.pfp" class="rounded-full border-4 p-0.5 w-auto h-20" :style="`border-color: ${data.colorHex};`"> <img
<span v-if="data.isLive" class="absolute top-16 right-[1.2rem] bg-ctp-red font-bold text-sm p-1.5 py-0.5 rounded-md">LIVE</span> :src="data.pfp"
class="rounded-full border-4 p-0.5 w-auto h-20"
:style="`border-color: ${data.colorHex};`"
/>
<span
v-if="data.isLive"
class="absolute top-16 right-[1.2rem] bg-ctp-red font-bold text-sm p-1.5 py-0.5 rounded-md"
>LIVE</span
>
</div> </div>
<div class="ml-3 content-between"> <div class="ml-3 content-between">
<h1 class="text-4xl font-bold">{{ data.username }}</h1> <h1 class="text-4xl font-bold">{{ data.username }}</h1>
<h1 v-if="!data.stream" class="font-bold text-md self-end ">{{ data.followersAbbv }} Followers</h1> <h1 v-if="!data.stream" class="font-bold text-md self-end">
{{ data.followersAbbv }} Followers
</h1>
<div v-else class="w-[12rem]"> <div v-else class="w-[12rem]">
<p class="text-sm font-bold text-gray-200 self-end"> {{ truncate(data.stream.title, 75) }} </p> <p class="text-sm font-bold text-gray-200 self-end">
{{ truncate(data.stream.title, 75) }}
</p>
</div> </div>
</div> </div>
</div> </div>
<div class="inline-flex w-1/3 float-right h-full text-right"> <div class="inline-flex w-1/3 float-right h-full text-right">
<div v-if="!data.isLive" class="w-full"> <div v-if="!data.isLive" class="w-full">
<p class="font-bold bg-ctp-mantle p-3 py-2 rounded-lg w-min float-right border-2 border-ctp-red">OFFLINE</p> <p
class="font-bold bg-ctp-mantle p-3 py-2 rounded-lg w-min float-right border-2 border-ctp-red"
>
OFFLINE
</p>
</div> </div>
<div v-else class="w-full"> <div v-else class="w-full">
<ul class="text-xs font-bold text-right space-x-1 space-y-1 overflow-y-auto"> <ul class="text-xs font-bold text-right space-x-1 space-y-1 overflow-y-auto">
<li v-for="tag in data.stream.tags" class="inline-flex bg-ctp-mantle p-1.5 px-2 rounded-md"> <li
v-for="tag in data.stream.tags"
:key="tag"
class="inline-flex bg-ctp-mantle p-1.5 px-2 rounded-md"
>
{{ tag }} {{ tag }}
</li> </li>
</ul> </ul>
</div> </div>
</div> </div>
</div> </div>
@ -145,7 +167,7 @@ export default {
<hr class="my-auto w-full bg-gray-200 rounded-full opacity-40" /> <hr class="my-auto w-full bg-gray-200 rounded-full opacity-40" />
<ul class="flex font-semibold text-md justify-start flex-wrap flex-row"> <ul class="flex font-semibold text-md justify-start flex-wrap flex-row">
<li v-for="link in data.socials"> <li v-for="link in data.socials" :key="link">
<a :href="link.link" class="text-white hover:text-gray-400 mr-4"> <a :href="link.link" class="text-white hover:text-gray-400 mr-4">
<v-icon :name="`bi-${link.type}`" class="w-6 h-6 mr-1"></v-icon> <v-icon :name="`bi-${link.type}`" class="w-6 h-6 mr-1"></v-icon>
<span>{{ link.name }}</span> <span>{{ link.name }}</span>
@ -155,8 +177,6 @@ export default {
</div> </div>
</div> </div>
<twitch-chat :isLive="data.isLive" :channelName="data.username"></twitch-chat>
<twitch-chat :isLive="data.isLive"></twitch-chat>
</div> </div>
</template> </template>