diff --git a/package-lock.json b/package-lock.json index 9f16a98..26bb1e9 100644 --- a/package-lock.json +++ b/package-lock.json @@ -3018,6 +3018,11 @@ "locate-path": "^3.0.0" } }, + "folktale": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/folktale/-/folktale-2.3.2.tgz", + "integrity": "sha512-+8GbtQBwEqutP0v3uajDDoN64K2ehmHd0cjlghhxh0WpcfPzAIjPA03e1VvHlxL02FVGR0A6lwXsNQKn3H1RNQ==" + }, "for-in": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz", diff --git a/package.json b/package.json index e20d5b4..a008b50 100644 --- a/package.json +++ b/package.json @@ -21,6 +21,7 @@ "dependencies": { "@babel/runtime-corejs3": "^7.7.7", "date-fns": "^2.9.0", + "folktale": "^2.3.2", "get-urls": "^9.2.0", "iter-tools": "^7.0.0-rc.0", "yt-player": "^3.4.3" diff --git a/src/components/Controls.svelte b/src/components/Controls.svelte index f80ded4..10dd45a 100644 --- a/src/components/Controls.svelte +++ b/src/components/Controls.svelte @@ -30,7 +30,7 @@ </div> <script> - import { paused, volume, muted, entry } from '/store.js' + import { paused, volume, muted, entry } from '/stores.js' </script> <style> diff --git a/src/components/Queue.svelte b/src/components/Queue.svelte index f5106f8..e133d9e 100644 --- a/src/components/Queue.svelte +++ b/src/components/Queue.svelte @@ -27,7 +27,7 @@ <script> import { onMount } from 'svelte' - import { paused, entry as currentEntry, entries } from '/store.js' + import { paused, entry as currentEntry, entries } from '/stores.js' const toggleEntry = (entry) => { if (entry !== $currentEntry) { diff --git a/src/components/Viewer.svelte b/src/components/Viewer.svelte index faacf70..f33d67a 100644 --- a/src/components/Viewer.svelte +++ b/src/components/Viewer.svelte @@ -14,7 +14,7 @@ import { onMount, onDestroy } from 'svelte' import { get } from 'svelte/store' import YoutubePlayer from 'yt-player' - import { entry, paused, muted, volume } from '/store.js' + import { entry, paused, muted, volume } from '/stores.js' import { secondsToElapsedTime } from '/util.js' let element diff --git a/src/store.js b/src/services/store.js similarity index 56% rename from src/store.js rename to src/services/store.js index c225f9f..75edd0e 100644 --- a/src/store.js +++ b/src/services/store.js @@ -1,49 +1,69 @@ import { writable, get } from 'svelte/store' -import * as util from '/util.js' +import { mkTracksIterator } from '/util.js' -export const domain = writableLocalStorage('domain', 'eldritch.cafe') - -export const hashtags = writableLocalStorage('hashtags', [ - 'np', - 'nowplaying', - 'tootradio', - 'pouetradio' -]) - -export const paused = writable(false) -export const muted = writableLocalStorage('muted', false) -export const volume = writableLocalStorage('volume', 100) - -export const entries = entriesStore(get(domain), get(hashtags)) -export const entry = entryStore(entries) - - - - -function writableLocalStorage(key, value) { +export const writableLocalStorage = (key, value) => { const item = JSON.parse(localStorage.getItem(key)) const store = writable(item === null ? value : item) - const unsubscribe = store.subscribe(x => localStorage.setItem(key, JSON.stringify(x))) + + store.subscribe(x => localStorage.setItem(key, JSON.stringify(x))) + return store } -function entryStore(entries) { +export const stackStore = (domain, hashtags) => { + const tracksIterator = mkTracksIterator(domain, hashtags) + + const store = writable([]) + const { update, subscribe } = store + + let promise = Promise.resolve() + const buffer = [] + + const load = async () => { + + + const n = 5 - buffer.length + + for (let i = 0; i < n; i++) { + const iteratorResult = await tracksIterator.next() + + if (iteratorResult.value) { + update(entries => [...entries, iteratorResult.value]) + } else { + // iterator don't have new entries for now + break + } + } + } + + const unshift = async () => { + let promise = promise.then(() => { + + }) + } + + promise = load() + + return { subscribe, unshift } +} + +export const entryStore = (entriesStore) => { const store = writable(null) const { set, update, subscribe } = store const select = (entry) => { update(() => entry) - const entriesList = get(entries) + const entriesList = get(entriesStore) const index = entriesList.indexOf(entry) if (index === entriesList.length - 1) { - entries.load(1) + entriesStore.load(1) } } const previous = () => { - const entriesList = get(entries) + const entriesList = get(entriesStore) update(currentEntry => { const index = entriesList.indexOf(currentEntry) @@ -53,7 +73,7 @@ function entryStore(entries) { } const next = () => { - const entriesList = get(entries) + const entriesList = get(entriesStore) update(oldEntry => { if (entriesList.length === 0) { @@ -79,8 +99,8 @@ function entryStore(entries) { return { subscribe, set: select, previous, next } } -function entriesStore(domain, hashtags) { - const tracksIterator = util.mkTracksIterator(domain, hashtags) +export const entriesStore = (domain, hashtags) => { + const tracksIterator = mkTracksIterator(domain, hashtags) const store = writable([]) const { update, subscribe } = store @@ -99,4 +119,4 @@ function entriesStore(domain, hashtags) { } return { subscribe, load } -} +} \ No newline at end of file diff --git a/src/stores.js b/src/stores.js new file mode 100644 index 0000000..986af98 --- /dev/null +++ b/src/stores.js @@ -0,0 +1,84 @@ +import { writable, get } from 'svelte/store' +import { writableLocalStorage, entriesStore, entryStore } from '/services/store.js' + +export const domain = writableLocalStorage('domain', 'eldritch.cafe') + +export const hashtags = writableLocalStorage('hashtags', [ + 'np', + 'nowplaying', + 'tootradio', + 'pouetradio' +]) + +export const paused = writable(false) +export const muted = writableLocalStorage('muted', false) +export const volume = writableLocalStorage('volume', 100) + +export const entries = entriesStore(get(domain), get(hashtags)) +export const entry = entryStore(entries) + + + + +const tracksIterator = mkTracksIterator(get(domain), get(hashtags)) + + + +export const track = writable(null) +export const queue = writable([]) +export const stack = writable([]) + +export const state = writable({ + current: null, + queue: [] +}) + +export const enqueue = () => { + const { value: newTrack } = await tracksIterator.next() + + if (!newTrack) { + state.update(s => ({ ...s, queue: [...s.queue, newTrack] })) + } +} + +export const select = (track) => { + state.update(s => ({ ...s, current: track })) +} + +export const selectPrevious = () => { + state.update(s => { + if (s.current === null) return s + + const + return + }) + + const tracks = get(queue) + + track.update(oldTrack => { + const index = tracks.indexOf(oldTrack) + return index > 0 ? tracks[index - 1] : null + }) +} + +export const selectNext = () => { + const tracks = get(queue) + const oldTrack = get(track) + + + + track.update(oldTrack => { + const index = tracks.indexOf(oldTrack) + + if (index !== -1 && ) { + return null + } + + return index !== -1 && index + 1 < tracks.length + ? tracks[index + 1] + : null + }) + + + enqueueIfTrack(track) +} diff --git a/src/util.js b/src/util.js index d646d6c..5640ca3 100644 --- a/src/util.js +++ b/src/util.js @@ -37,6 +37,7 @@ export async function* mkStatusesIterator(initialLink) { while (true) { const now = Date.now() + if (latestPreviousFetch + 5 * minute < now) { console.log('fetch newer') const previous = await fetchTimeline(previousLink)