Update src/

This commit is contained in:
freearhey 2025-04-14 21:53:33 +03:00
parent 09b07e9b24
commit 86743c74f5
132 changed files with 4418 additions and 1907 deletions

View file

@ -1,58 +1,101 @@
<script>
import OutlineButton from '~/components/OutlineButton.svelte'
import { selected, filteredChannels, channels } from '~/store'
<script lang="ts">
import { selected, channels, hasQuery, searchResults } from '~/store'
import { Collection } from '@freearhey/core/browser'
import IconButton from './IconButton.svelte'
import { Channel } from '~/models'
import * as Icon from '~/icons'
$: hasStreams = $channels.filter(c => c.streams > 0)
$: isAllSelected = $selected.length === hasStreams.length
const channelsWithStreams: Collection = $channels.filter((channel: Channel) =>
channel.hasStreams()
)
let filteredChannelsWithStreams: Collection = channelsWithStreams
let filteredChannels: Collection = $channels
let isLoading = false
let isAllSelected = false
searchResults.subscribe((_searchResults: Collection) => {
onSearchResultsChange(_searchResults)
})
function onSearchResultsChange(_searchResults: Collection) {
if ($hasQuery) {
if (_searchResults.isEmpty()) {
filteredChannels = new Collection()
} else {
filteredChannels = $channels.intersectsBy(_searchResults, (channel: Channel) => channel.id)
}
} else {
filteredChannels = $channels
}
filteredChannelsWithStreams = filteredChannels.filter((channel: Channel) =>
channel.hasStreams()
)
updateState()
}
selected.subscribe((_selected: Collection) => {
updateState()
})
function updateState() {
let _selected = $selected
isAllSelected = true
filteredChannelsWithStreams.forEach((channel: Channel) => {
const isChannelSelected = _selected.includes(
(selectedChannel: Channel) => selectedChannel.id === channel.id
)
if (!isChannelSelected) {
isAllSelected = false
return
}
})
}
function selectAll() {
selected.set(hasStreams)
isLoading = true
setTimeout(() => {
let _selected = $selected
filteredChannelsWithStreams.forEach((channel: Channel) => {
const isChannelSelected = _selected.includes(
(selectedChannel: Channel) => selectedChannel.id === channel.id
)
if (!isChannelSelected) {
_selected.add(channel)
}
})
selected.set(_selected)
isLoading = false
}, 0)
}
function deselectAll() {
selected.set([])
isLoading = true
setTimeout(() => {
let _selected = $selected
filteredChannelsWithStreams.forEach((channel: Channel) => {
_selected.remove((selectedChannel: Channel) => selectedChannel.id === channel.id)
})
selected.set(_selected)
isLoading = false
}, 0)
}
</script>
{#if isAllSelected}
<OutlineButton on:click={deselectAll} aria-label="Deselect All">
<span class="text-gray-500 dark:text-white">
<svg
fill="currentColor"
class="w-5 h-5"
clip-rule="evenodd"
fill-rule="evenodd"
stroke-linejoin="round"
stroke-miterlimit="2"
viewBox="0 0 24 24"
xmlns="http://www.w3.org/2000/svg"
><path
d="m17.5 11c2.484 0 4.5 2.016 4.5 4.5s-2.016 4.5-4.5 4.5-4.5-2.016-4.5-4.5 2.016-4.5 4.5-4.5zm-5.979 5c.043.522.153 1.025.321 1.5h-9.092c-.414 0-.75-.336-.75-.75s.336-.75.75-.75zm7.979-1c-.592 0-3.408 0-4 0-.265 0-.5.235-.5.5s.235.5.5.5h4c.265 0 .5-.235.5-.5s-.235-.5-.5-.5zm-6.873-3c-.328.456-.594.96-.785 1.5h-9.092c-.414 0-.75-.336-.75-.75s.336-.75.75-.75zm7.373-3.25c0-.414-.336-.75-.75-.75h-16.5c-.414 0-.75.336-.75.75s.336.75.75.75h16.5c.414 0 .75-.336.75-.75zm0-4c0-.414-.336-.75-.75-.75h-16.5c-.414 0-.75.336-.75.75s.336.75.75.75h16.5c.414 0 .75-.336.75-.75z"
fill-rule="nonzero"
/></svg
>
</span>
<span class="hidden md:inline">Deselect All</span>
</OutlineButton>
{#if isLoading}
<div class="h-10 w-10 flex items-center justify-center text-gray-100">
<Icon.Spinner size={21} />
</div>
{:else if isAllSelected}
<IconButton onClick={deselectAll} aria-label="Deselect All" title="Deselect All" variant="light">
<Icon.DeselectAll size={24} />
</IconButton>
{:else}
<OutlineButton on:click={selectAll} aria-label="Select All">
<span class="text-gray-500 dark:text-white">
<svg
fill="currentColor"
class="w-5 h-5"
clip-rule="evenodd"
fill-rule="evenodd"
stroke-linejoin="round"
stroke-miterlimit="2"
viewBox="0 0 24 24"
xmlns="http://www.w3.org/2000/svg"
><path
d="m17.5 11c2.484 0 4.5 2.016 4.5 4.5s-2.016 4.5-4.5 4.5-4.5-2.016-4.5-4.5 2.016-4.5 4.5-4.5zm-5.979 5c.043.522.153 1.025.321 1.5h-9.092c-.414 0-.75-.336-.75-.75s.336-.75.75-.75zm3.704-.024 1.442 1.285c.095.085.215.127.333.127.136 0 .271-.055.37-.162l2.441-2.669c.088-.096.131-.217.131-.336 0-.274-.221-.499-.5-.499-.136 0-.271.055-.37.162l-2.108 2.304-1.073-.956c-.096-.085-.214-.127-.333-.127-.277 0-.5.224-.5.499 0 .137.056.273.167.372zm-2.598-3.976c-.328.456-.594.96-.785 1.5h-9.092c-.414 0-.75-.336-.75-.75s.336-.75.75-.75zm7.373-3.25c0-.414-.336-.75-.75-.75h-16.5c-.414 0-.75.336-.75.75s.336.75.75.75h16.5c.414 0 .75-.336.75-.75zm0-4c0-.414-.336-.75-.75-.75h-16.5c-.414 0-.75.336-.75.75s.336.75.75.75h16.5c.414 0 .75-.336.75-.75z"
fill-rule="nonzero"
/></svg
>
</span>
<span class="hidden md:inline">Select All</span>
</OutlineButton>
<IconButton onClick={selectAll} aria-label="Select All" title="Select All" variant="light">
<Icon.SelectAll size={24} />
</IconButton>
{/if}