about summary refs log tree commit diff
path: root/src/state/models/media/gallery.ts
blob: 04023bf820b852197659a84654da5851cee6ca6f (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
import {makeAutoObservable, runInAction} from 'mobx'
import {ImageModel} from './image'
import {Image as RNImage} from 'react-native-image-crop-picker'
import {openPicker} from 'lib/media/picker'
import {getImageDim} from 'lib/media/manip'

export class GalleryModel {
  images: ImageModel[] = []

  constructor() {
    makeAutoObservable(this)
  }

  get isEmpty() {
    return this.size === 0
  }

  get size() {
    return this.images.length
  }

  get needsAltText() {
    return this.images.some(image => image.altText.trim() === '')
  }

  async add(image_: Omit<RNImage, 'size'>) {
    if (this.size >= 4) {
      return
    }

    // Temporarily enforce uniqueness but can eventually also use index
    if (!this.images.some(i => i.path === image_.path)) {
      const image = new ImageModel(image_)

      // Initial resize
      image.manipulate({})
      this.images.push(image)
    }
  }

  async paste(uri: string) {
    if (this.size >= 4) {
      return
    }

    const {width, height} = await getImageDim(uri)

    const image = {
      path: uri,
      height,
      width,
      mime: 'image/jpeg',
    }

    runInAction(() => {
      this.add(image)
    })
  }

  setAltText(image: ImageModel, altText: string) {
    image.setAltText(altText)
  }

  crop(image: ImageModel) {
    image.crop()
  }

  remove(image: ImageModel) {
    const index = this.images.findIndex(image_ => image_.path === image.path)
    this.images.splice(index, 1)
  }

  async previous(image: ImageModel) {
    image.previous()
  }

  async pick() {
    const images = await openPicker({
      selectionLimit: 4 - this.size,
      allowsMultipleSelection: true,
    })

    return await Promise.all(
      images.map(image => {
        this.add(image)
      }),
    )
  }
}