big store uwu
This commit is contained in:
parent
3e9ac5f2e8
commit
408099ac29
@ -15,23 +15,29 @@
|
|||||||
</section>
|
</section>
|
||||||
|
|
||||||
<section class="queue">
|
<section class="queue">
|
||||||
{#await entriesPromise}
|
{#if $entries}
|
||||||
Loading radio please wait
|
{#await $entries}
|
||||||
{:then entries}
|
Loading radio please wait
|
||||||
<ul>
|
{:then entries}
|
||||||
{#each entries as entry}
|
<ul>
|
||||||
<li class="entry" class:active={entry === selectedEntry} on:click={selectEntry(entry)}>
|
{#each entries as entry}
|
||||||
<b>{entry.status.account.acct}</b>
|
<li class="entry" class:active={entry === selectedEntry} on:click={selectEntry(entry)}>
|
||||||
<small>{entry.tags}</small>
|
<b>{entry.status.account.acct}</b>
|
||||||
</li>
|
<small>{entry.tags}</small>
|
||||||
{/each}
|
</li>
|
||||||
</ul>
|
{/each}
|
||||||
{:catch error}
|
</ul>
|
||||||
Oops, something went wrong : {error}
|
{:catch error}
|
||||||
{/await}
|
Oops, something went wrong : {error}
|
||||||
|
{/await}
|
||||||
|
{:else}
|
||||||
|
Your queue
|
||||||
|
{/if}
|
||||||
|
|
||||||
<header>
|
<header>
|
||||||
<a href="https://{domain}/">{domain}</a> - {@html hashtags.map(hashtag => `<a href="https://${domain}/tags/${hashtag}">#${hashtag}</a>`)}
|
<a href="https://{$domain}/">{$domain}</a> - {@html $hashtags.map(hashtag => `<a href="https://${$domain}/tags/${hashtag}">#${hashtag}</a>`)}
|
||||||
|
|
||||||
|
<button on:click={() => entries.load()}>LOAD MOAR</button>
|
||||||
</header>
|
</header>
|
||||||
</section>
|
</section>
|
||||||
</main>
|
</main>
|
||||||
@ -39,13 +45,9 @@
|
|||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { onMount } from 'svelte'
|
import { onMount } from 'svelte'
|
||||||
import { fetchEntries } from './util.js'
|
|
||||||
import YoutubeViewer from './YoutubeViewer.svelte'
|
import YoutubeViewer from './YoutubeViewer.svelte'
|
||||||
|
import { domain, hashtags, entries } from './store.js'
|
||||||
|
|
||||||
export let domain
|
|
||||||
export let hashtags
|
|
||||||
|
|
||||||
let entriesPromise = new Promise(() => {})
|
|
||||||
let selectedEntry = null
|
let selectedEntry = null
|
||||||
|
|
||||||
const selectEntry = entry => {
|
const selectEntry = entry => {
|
||||||
@ -53,11 +55,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
onMount(() => {
|
onMount(() => {
|
||||||
entriesPromise = fetchEntries(domain, hashtags)
|
entries.load()
|
||||||
|
|
||||||
entriesPromise.then(entries => {
|
|
||||||
[selectedEntry] = entries
|
|
||||||
})
|
|
||||||
})
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
<div>
|
<div>
|
||||||
<div bind:this={element}></div>
|
<div bind:this={element}></div>
|
||||||
|
|
||||||
|
<button on:click={player.play()}>PLAY UWU</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
@ -12,16 +14,13 @@
|
|||||||
let player
|
let player
|
||||||
|
|
||||||
$: if (player && videoId) {
|
$: if (player && videoId) {
|
||||||
console.log(`loada ${videoId}`)
|
|
||||||
player.load(videoId, true)
|
player.load(videoId, true)
|
||||||
}
|
}
|
||||||
|
|
||||||
onMount(() => {
|
onMount(() => {
|
||||||
player = new YoutubePlayer(element, {
|
player = new YoutubePlayer(element, {
|
||||||
width: 200,
|
|
||||||
height: 200,
|
|
||||||
autoplay: true,
|
autoplay: true,
|
||||||
controls: false, // debug only
|
controls: true, // debug only
|
||||||
keyboard: false,
|
keyboard: false,
|
||||||
fullscreen: false,
|
fullscreen: false,
|
||||||
modestBranding: true,
|
modestBranding: true,
|
||||||
|
11
src/main.js
11
src/main.js
@ -1,16 +1,7 @@
|
|||||||
import App from './App.svelte'
|
import App from './App.svelte'
|
||||||
|
|
||||||
const app = new App({
|
const app = new App({
|
||||||
target: document.body,
|
target: document.body
|
||||||
props: {
|
|
||||||
domain: 'eldritch.cafe',
|
|
||||||
hashtags: [
|
|
||||||
'np',
|
|
||||||
'nowplaying',
|
|
||||||
'tootradio',
|
|
||||||
'pouetradio'
|
|
||||||
]
|
|
||||||
}
|
|
||||||
})
|
})
|
||||||
|
|
||||||
export default app
|
export default app
|
71
src/store.js
Normal file
71
src/store.js
Normal file
@ -0,0 +1,71 @@
|
|||||||
|
import { writable, get } from 'svelte/store'
|
||||||
|
import { getUrls, getYoutubeId, isSupportedUrl, intersection } from './util.js'
|
||||||
|
|
||||||
|
export const domain = writable('eldritch.cafe')
|
||||||
|
|
||||||
|
export const hashtags = writable([
|
||||||
|
'np',
|
||||||
|
'nowplaying',
|
||||||
|
'tootradio',
|
||||||
|
'pouetradio'
|
||||||
|
])
|
||||||
|
|
||||||
|
export const entries = entriesStore()
|
||||||
|
|
||||||
|
function entriesStore() {
|
||||||
|
let loading = false
|
||||||
|
let next = `https://eldritch.cafe/api/v1/timelines/tag/np`
|
||||||
|
|
||||||
|
const store = writable(null)
|
||||||
|
const { set, subscribe } = store
|
||||||
|
|
||||||
|
const load = async () => {
|
||||||
|
if (loading) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
loading = true
|
||||||
|
|
||||||
|
const responseP = fetch(next)
|
||||||
|
|
||||||
|
responseP.then(response => {
|
||||||
|
next = Array.from(getUrls(response.headers.get('link')))[0] // need to better parse that
|
||||||
|
})
|
||||||
|
|
||||||
|
const entriesP = responseP
|
||||||
|
.then(response => response.json())
|
||||||
|
.then(statuses => {
|
||||||
|
return statuses
|
||||||
|
.map(status => {
|
||||||
|
const [url] = Array.from(getUrls(status.content)).filter(isSupportedUrl)
|
||||||
|
|
||||||
|
return { status, url }
|
||||||
|
})
|
||||||
|
.filter(entry => entry.url != null)
|
||||||
|
.map(({ status, url }) => {
|
||||||
|
const id = getYoutubeId(url)
|
||||||
|
const tags = intersection(status.tags.map(tag => tag.name), [
|
||||||
|
'np',
|
||||||
|
'nowplaying',
|
||||||
|
'tootradio',
|
||||||
|
'pouetradio'
|
||||||
|
])
|
||||||
|
|
||||||
|
return { status, url, id, tags }
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
const previousEntriesP = get(store)
|
||||||
|
|
||||||
|
if (previousEntriesP) {
|
||||||
|
const [previousEntries, entries] = await Promise.all([previousEntriesP, entriesP])
|
||||||
|
set(Promise.resolve([...previousEntries, ...entries]))
|
||||||
|
} else {
|
||||||
|
set(entriesP)
|
||||||
|
}
|
||||||
|
|
||||||
|
loading = false
|
||||||
|
}
|
||||||
|
|
||||||
|
return { subscribe, load }
|
||||||
|
}
|
29
src/util.js
29
src/util.js
@ -1,31 +1,10 @@
|
|||||||
import getUrls from 'get-urls'
|
export { default as getUrls } from 'get-urls'
|
||||||
import getYoutubeId from 'get-youtube-id'
|
export { default as getYoutubeId } from 'get-youtube-id'
|
||||||
|
|
||||||
export async function fetchEntries(domain, hashtags) {
|
export function isSupportedUrl(url) {
|
||||||
const response = await fetch(`https://${domain}/api/v1/timelines/tag/${hashtags[0]}`)
|
|
||||||
const statuses = await response.json()
|
|
||||||
|
|
||||||
const entries = statuses
|
|
||||||
.map(status => {
|
|
||||||
const [url] = Array.from(getUrls(status.content)).filter(isSupportedUrl)
|
|
||||||
|
|
||||||
return { status, url }
|
|
||||||
})
|
|
||||||
.filter(entry => entry.url != null)
|
|
||||||
.map(({ status, url }) => {
|
|
||||||
const id = getYoutubeId(url)
|
|
||||||
const tags = intersection(status.tags.map(tag => tag.name), hashtags)
|
|
||||||
|
|
||||||
return { status, url, id, tags }
|
|
||||||
})
|
|
||||||
|
|
||||||
return entries
|
|
||||||
}
|
|
||||||
|
|
||||||
function isSupportedUrl(url) {
|
|
||||||
return (new URL(url)).hostname === 'youtube.com'
|
return (new URL(url)).hostname === 'youtube.com'
|
||||||
}
|
}
|
||||||
|
|
||||||
function intersection(xs, ys) {
|
export function intersection(xs, ys) {
|
||||||
return xs.filter(x => ys.includes(x));
|
return xs.filter(x => ys.includes(x));
|
||||||
}
|
}
|
Loading…
x
Reference in New Issue
Block a user