Skip to content

Commit

Permalink
feat(frontend): Update app auto-refresh button (#1062)
Browse files Browse the repository at this point in the history
* feat(frontend): Update interval selector

* fix(frontend): Interval

* feat(frontend): Resource saving

* fix(frontend): Update selector labels

* label
  • Loading branch information
adam-kov committed Jan 2, 2023
1 parent 39e7fc6 commit 34e3331
Show file tree
Hide file tree
Showing 2 changed files with 80 additions and 28 deletions.
2 changes: 1 addition & 1 deletion frontend/src/lib/components/Dropdown.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
</script>

<Menu {placement} let:close>
<Button nonCaptureEvent color="light" size="xs" {btnClasses} slot="trigger">
<Button nonCaptureEvent color="light" size="xs" {btnClasses} {...$$restProps} slot="trigger">
{#if !$$slots.default}
<MoreHorizontal size={20} />
{:else}
Expand Down
106 changes: 79 additions & 27 deletions frontend/src/lib/components/apps/editor/RecomputeAllComponents.svelte
Original file line number Diff line number Diff line change
@@ -1,43 +1,95 @@
<script lang="ts">
import Dropdown from '$lib/components/Dropdown.svelte'
import Toggle from '$lib/components/Toggle.svelte'
import { RefreshCw } from 'lucide-svelte'
import { getContext } from 'svelte'
import { ChevronDown, RefreshCw } from 'lucide-svelte'
import { getContext, onMount } from 'svelte'
import Button from '../../common/button/Button.svelte'
import type { AppEditorContext } from '../types'
const { runnableComponents } = getContext<AppEditorContext>('AppEditorContext')
let loading: boolean = false
let timeout: NodeJS.Timer | undefined = undefined
let interval: number | undefined = undefined
let shouldRefresh = false
$: componentNumber = Object.keys($runnableComponents).length
function onClick(stopAfterClear = true) {
if(timeout) {
clearInterval(timeout)
timeout = undefined
shouldRefresh = false
if(stopAfterClear) return;
}
refresh()
if(interval) {
shouldRefresh = true
timeout = setInterval(refresh, interval)
}
}
async function onRefresh() {
function setInter(inter: number | undefined) {
interval = inter
onClick(!inter)
}
function refresh() {
loading = true
await Promise.all(
Promise.all(
Object.keys($runnableComponents).map((id) => {
return $runnableComponents?.[id]?.()
})
)
loading = false
).finally(() => {
loading = false
})
}
function visChange() {
if(document.visibilityState === 'hidden') {
if(timeout) {
clearInterval(timeout)
timeout = undefined
}
} else if(shouldRefresh) {
timeout = setInterval(refresh, interval)
}
}
let timeout: NodeJS.Timeout | undefined = undefined
onMount(() => {
document.addEventListener('visibilitychange', visChange)
return () => {
document.removeEventListener('visibilitychange', visChange)
if(timeout) clearInterval(timeout)
}
})
</script>

<div class="flex gap-4 items-center">
<button
on:click|preventDefault|stopPropagation={onRefresh}
class="center-center p-1 rounded border bg-white/60 hover:bg-gray-200 inline-flex gap-2"
>
<RefreshCw class={loading ? 'animate-spin' : ''} size={20} /> ({Object.keys($runnableComponents)
.length})
</button>
<Toggle
<div class="flex items-center">
<Button
on:click={() => onClick()}
color="{timeout ? 'blue' : 'light'}"
variant="{timeout ? 'contained' : 'border'}"
size="xs"
on:change={(e) => {
if (e.detail) {
timeout = setInterval(onRefresh, 15000)
} else {
timeout && clearInterval(timeout)
}
}}
options={{ right: 'auto (15s)' }}
/>
btnClasses="!rounded-r-none {timeout ? '!border !border-blue-500' : ''}"
title="Refresh {componentNumber} component{componentNumber > 1 ? 's' : ''} {interval ? `every ${interval / 1000} seconds` : 'once'}"
>
<RefreshCw class={loading ? 'animate-spin' : ''} size={16} />
</Button>
<Dropdown
btnClasses="!rounded-l-none !border-l-0 min-w-[4rem] !px-2"
color="{timeout ? 'blue' : 'light'}"
variant="border"
dropdownItems={[
{
displayName: 'Once',
action: () => setInter(undefined)
},
...[1, 2, 3, 4, 5, 6].map((i) => ({
displayName: `Every ${i * 5} seconds`,
action: () => setInter(i * 5000)
})),
]}
>
<span class="grow text center">{interval ? `${interval / 1000}s` : 'once'}</span>
<ChevronDown class="ml-0.5" size={14} />
</Dropdown>
</div>

0 comments on commit 34e3331

Please sign in to comment.