This commit is contained in:
2023-10-15 18:24:43 +02:00
parent 78f3961b11
commit 5bee1b6382
5 changed files with 94 additions and 43 deletions

View File

@@ -8,9 +8,10 @@ const db = new Database(dbName);
export function getStreams() { export function getStreams() {
const indexData = db.prepare('SELECT id, stream_date, title, tags, length_seconds ' + const indexData = db.prepare('SELECT id, stream_date, title, tags, length_seconds ' +
'FROM Stream ORDER BY id DESC').all(); 'FROM Stream ORDER BY id DESC').all();
indexData.forEach(stream => indexData.forEach(stream => {
stream['stream_date'] = Date.parse(stream['stream_date']) stream['stream_date'] = Date.parse(stream['stream_date']);
); stream['tags'] = JSON.parse(stream['tags']);
});
return indexData; return indexData;
} }

View File

@@ -2,6 +2,33 @@ import { writable } from 'svelte/store';
export const currentStream = writable({}); export const currentStream = writable({});
export const currentSongIndex = writable(0); export const currentSongIndex = writable(0);
export const tagList = [
'acoustic',
'electronic',
'orchestral',
'rock',
'pop',
'metal',
'aggressive',
'folk',
'jazzy',
'dance.music',
'untz',
'breakbeats',
'electronica',
'chiptune',
'left.field',
'denpa',
'vocaloid',
'funky',
'lush',
'noisy',
'psychedelic',
'dark',
'calm',
'moody',
'uplifting'
];
let timestampList; let timestampList;

View File

@@ -1,6 +1,13 @@
<script> <script>
import { goto } from '$app/navigation'; import { goto } from '$app/navigation';
import TagSelect from './TagSelect.svelte';
export let streams; export let streams;
let filteredTags = [];
let listOpen;
$: displayedStreams = streamsToDisplay(filteredTags);
$: remainingTags = getRemainingTags(displayedStreams);
function formatSecondsToHms(s) { function formatSecondsToHms(s) {
s = Number(s); s = Number(s);
@@ -17,14 +24,48 @@
const formattedDate = date.toISOString().split('T')[0]; const formattedDate = date.toISOString().split('T')[0];
return formattedDate; return formattedDate;
} }
function streamsToDisplay(filteredTags) {
const displayedStreams = streams.filter(
(stream) =>
!('tags' in stream) || filteredTags.every((tag) => stream['tags'].includes(tag))
);
// close tagselect dropdown if we can't select anything else
if (displayedStreams.length == 1) {
listOpen = !listOpen;
}
return displayedStreams;
}
function getRemainingTags(displayedStreams) {
let tagCounts = displayedStreams.reduce((tags, stream) => {
stream['tags'].forEach((tag) => (tag in tags ? (tags[tag] += 1) : (tags[tag] = 1)));
return tags;
}, {});
return Object.entries(tagCounts)
.filter((el) => el[1] != displayedStreams.length)
.map((el) => el[0]);
}
function getDisplayedTagsInList(streamTags, remainingTags) {
return streamTags.filter((tag) => remainingTags.includes(tag));
}
</script> </script>
<h1>streams</h1> <h1>streams</h1>
<TagSelect bind:listOpen bind:checked={filteredTags} {remainingTags} />
<div> <div>
<ul class="stream-list"> <ul class="stream-list">
{#each streams as stream} {#each streams as stream}
<li class="stream-item" id="stream-{stream['id']}"> <li
hidden={!displayedStreams.includes(stream)}
class="stream-item"
id="stream-{stream['id']}"
>
<button <button
class="stream-item-button" class="stream-item-button"
on:click={() => goto('/streams/' + stream['id'])} on:click={() => goto('/streams/' + stream['id'])}
@@ -34,7 +75,10 @@
<span class="stream-item-length" <span class="stream-item-length"
>{formatSecondsToHms(stream['length_seconds'])}</span >{formatSecondsToHms(stream['length_seconds'])}</span
> >
<span class="stream-item-data">{JSON.stringify(stream)}</span> <span class="stream-item-data">title: {stream['title']}</span>
<span class="stream-item-data"
>{getDisplayedTagsInList(stream['tags'], remainingTags)}</span
>
</button> </button>
</li> </li>
{/each} {/each}
@@ -57,6 +101,7 @@
.stream-item-button { .stream-item-button {
border-radius: 0; border-radius: 0;
min-width: 100%;
border: none; border: none;
} }
</style> </style>

View File

@@ -1,15 +1,14 @@
<script> <script>
import Select from 'svelte-select'; import Select from 'svelte-select';
import { tagList } from '$lib/stores.js';
let items = [ let items = tagList.map((x) => ({ value: x, label: x }));
{ value: 'one', label: 'One' },
{ value: 'two', label: 'Two' },
{ value: 'three', label: 'Three' }
];
let value = []; let value = [];
let checked = []; export let checked = [];
let isChecked = {}; let isChecked = {};
export let remainingTags = [];
export let listOpen;
$: computeValue(checked); $: computeValue(checked);
$: computeIsChecked(checked); $: computeIsChecked(checked);
@@ -25,7 +24,6 @@
function handleSelectable() { function handleSelectable() {
items = items.map((item) => { items = items.map((item) => {
console.log(item);
return { ...item, selectable: !checked.includes(item.value) }; return { ...item, selectable: !checked.includes(item.value) };
}); });
} }
@@ -38,16 +36,25 @@
: (checked = [...checked, e.detail.value]); : (checked = [...checked, e.detail.value]);
handleSelectable(); handleSelectable();
} }
let itemFilter = function (label, filterText, option) {
return (
remainingTags.includes(option['value']) &&
label.toLowerCase().includes(filterText.toLowerCase())
);
};
</script> </script>
<Select <Select
{items} {items}
{value} {value}
bind:listOpen
multiple={true} multiple={true}
filterSelectedItems={false} filterSelectedItems={true}
closeListOnChange={false} closeListOnChange={false}
on:select={handleChange} on:select={handleChange}
on:clear={handleChange} on:clear={handleChange}
{itemFilter}
> >
<div class="item" slot="item" let:item> <div class="item" slot="item" let:item>
<label for={item.value}> <label for={item.value}>

View File

@@ -1,39 +1,10 @@
<script> <script>
import { page } from '$app/stores'; import { page } from '$app/stores';
import { tagList } from '$lib/stores.js';
export let original; export let original;
let tagList = [];
let tagMap = new Map(); let tagMap = new Map();
tagList = [
'acoustic',
'electronic',
'orchestral',
'rock',
'pop',
'metal',
'aggressive',
'folk',
'jazzy',
'dance.music',
'untz',
'breakbeats',
'electronica',
'chiptune',
'left.field',
'denpa',
'vocaloid',
'funky',
'lush',
'noisy',
'psychedelic',
'dark',
'calm',
'moody',
'uplifting'
];
// Create a mapping of tags and their checked status // Create a mapping of tags and their checked status
let reloadTags = (original) => { let reloadTags = (original) => {
tagList.forEach((tag) => { tagList.forEach((tag) => {