Usage

Choose a file and send it

tsx
import { Button, Text, VStack, fileSystem, mediaPicker, signal, task } from 'kuito';

export default function PhotoUpload() {
  const progress = signal(0);
  const selected = signal<string | null>(null);
  const upload = task(
    async () => {
      if (!selected.value) {
        const result = await mediaPicker.pick({
          mediaTypes: ['images'],
          maxWidth: 2048,
          quality: 0.8,
        });
        if (result.canceled || !result.assets[0]) return;
        selected.value = result.assets[0].uri;
      }
      progress.value = 0;
      const result = await fileSystem.upload('https://example.com/photos', selected.value, {
        onProgress: ({ bytes, total }) => {
          progress.value = total ? bytes / total : 0;
        },
      });
      if (result.status < 200 || result.status >= 300)
        throw new Error(`Upload failed: ${result.status}`);
      selected.value = null;
    },
    { policy: 'drop' },
  );

  return (
    <VStack padding={24} gap={12}>
      <Button disabled={upload.running.value} onPress={() => void upload.run().catch(() => {})}>
        {selected.value ? 'Retry upload' : 'Choose photo'}
      </Button>
      <Text>
        {upload.running.value
          ? `${Math.round(progress.value * 100)}%`
          : upload.error.value
            ? String(upload.error.value)
            : ''}
      </Text>
    </VStack>
  );
}

Type declaration

ts
export type UploadResult = { status: number; headers: Record<string, string>; body: string };

Members 3

NameTypeRequiredDescription
statusnumberYes—
headersRecord<string, string>Yes—
bodystringYes—
Generated from the public TypeScript declarations: signatures, props and defaults come from the checked source, descriptions from its JSDoc. No defaults are invented.