| 128 | const CACHE = new Map<string, Basic[]>() |
| 129 | |
| 130 | async function getRandomPhoto( |
| 131 | image: HTMLImageElement, |
| 132 | seed: number |
| 133 | ): Promise<UnsplashImage | undefined> { |
| 134 | let orientation: Orientation = 'landscape' |
| 135 | let width = 500 |
| 136 | let height = 500 |
| 137 | // TODO: support color |
| 138 | const dims = image.src.match(/\/(\d+)x(\d+)/) |
| 139 | if (dims) { |
| 140 | width = Number.parseInt(dims[1], 10) |
| 141 | height = Number.parseInt(dims[2], 10) |
| 142 | orientation = width > height ? 'landscape' : 'portrait' |
| 143 | if (width === height) { |
| 144 | orientation = 'squarish' |
| 145 | } |
| 146 | } else if (/\/(\d+)/.test(image.src)) { |
| 147 | const match = image.src.match(/\/(\d+)/) |
| 148 | width = Number.parseInt(match?.[1] ?? '500', 10) |
| 149 | height = width |
| 150 | } |
| 151 | let results: Basic[] = CACHE.get(image.alt) ?? [] |
| 152 | let img: Basic | undefined |
| 153 | if (results.length > 0) { |
| 154 | img = results[Math.floor(seed * results.length)] |
| 155 | } |
| 156 | if (!img) { |
| 157 | try { |
| 158 | console.log(`Searching unsplash for ${image.alt} ${image.src}`) |
| 159 | const data = await api.search.getPhotos({ query: image.alt, orientation }) |
| 160 | // TODO: maybe grab a random image from the results |
| 161 | results = data.response?.results ?? [] |
| 162 | if (results.length > 0) { |
| 163 | img = results[Math.floor(seed * results.length)] |
| 164 | CACHE.set(image.alt, results) |
| 165 | } |
| 166 | } catch (error) { |
| 167 | console.error(error) |
| 168 | } |
| 169 | } |
| 170 | |
| 171 | if (img) { |
| 172 | const url = new URL(img.urls.regular) |
| 173 | const params = new URLSearchParams(url.search) |
| 174 | params.set('w', width.toString()) |
| 175 | params.set('h', height.toString()) |
| 176 | params.set('fit', 'crop') |
| 177 | url.search = params.toString() |
| 178 | |
| 179 | return { |
| 180 | url: url.toString(), |
| 181 | width, |
| 182 | height, |
| 183 | blurhash: img.blur_hash ?? undefined |
| 184 | } |
| 185 | } |
| 186 | return undefined |
| 187 | } |