import { isError } from '$gql/Utils'; import type { ImageFragment } from '$gql/graphql'; import type { BeforeNavigate } from '@sveltejs/kit'; import type { OperationResultState } from '@urql/svelte'; import { openModal } from 'svelte-modals'; import ConfirmDeletion from './dialogs/ConfirmDeletion.svelte'; export function range(from: number, to: number) { return Array.from({ length: to - from + 1 }, (_, k) => k + from); } export function getRandomInt(min: number, max: number) { const minCeiled = Math.ceil(min); const maxFloored = Math.floor(max); return Math.floor(Math.random() * (maxFloored - minCeiled) + minCeiled); } export interface ListItem { id: number | string; name: string; } export interface ResultState { fetching: boolean; message?: string; } export function getResultState(state: OperationResultState): ResultState { let message: string | undefined; if (state.error) { message = `${state.error.name}: ${state.error.message}`; } else if (state.data) { // eslint-disable-next-line @typescript-eslint/no-unsafe-argument const obj = Object.values(state.data)[0]; if (isError(obj)) { message = obj.message; } } return { fetching: state.fetching, message: message }; } export function src(image: ImageFragment, type: 'full' | 'thumb' = 'thumb') { const dir = image.hash.slice(0, 2); const file = image.hash.slice(2); return `/objects/${dir}/${file}_${type}.webp`; } export function numKeys(obj?: object | null, ignore: string[] = []) { if (!obj) return 0; const len = Object.keys(obj).length; let ignored = 0; for (const i of ignore) { if (Object.hasOwn(obj, i)) ignored++; } return len - ignored; } export function confirmDeletion( typename: string, names: string | string[], callback: () => void, warning?: string ) { openModal( ConfirmDeletion, { names: Array.isArray(names) ? names : [names], typename, callback: callback, warning }, { replace: true } ); } export function idFromLabel(label: string) { return label.toLowerCase().replaceAll(' ', '-'); } export function pluralize(singular: string, size: number) { return `${singular}${size > 1 ? 's' : ''}`; } export function formatListSize(word: string, size: number) { return `${size} ${pluralize(word, size)}`; } export function joinText(items: string[], separator = ', ') { return items.filter((i) => i).join(separator); } export function confirmPending() { return confirm('There are pending changes. Click Cancel to keep editing or OK to dismiss them.'); } export function preventOnPending({ to, cancel }: BeforeNavigate, pending: boolean) { if (!pending) return; if (to) { if (confirmPending()) { return; } } cancel(); }