Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
93 changes: 60 additions & 33 deletions src/api/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@

// Update base URL whenever currentBaseURL changes
const updateBaseURL = () => {
instance.defaults.baseURL = currentBaseURL.value

Check warning on line 15 in src/api/index.ts

View workflow job for this annotation

GitHub Actions / lint

Unsafe assignment of an `any` value
}

// Set initial base URL and watch for changes
Expand All @@ -23,6 +23,11 @@
token: string
}

export type UploadedImage = {
token: string,
src: string
}

export type UploadedImages = {
token: string,
src: string // used for preview images
Expand All @@ -30,8 +35,8 @@

export async function getFactories (range: number, lng: number, lat: number): Promise<FactoriesResponse> {
try {
const { data } = await instance.get(`/factories?range=${range}&lng=${lng}&lat=${lat}`)

Check warning on line 38 in src/api/index.ts

View workflow job for this annotation

GitHub Actions / lint

Unsafe array destructuring of a tuple element with an `any` value
return data

Check warning on line 39 in src/api/index.ts

View workflow job for this annotation

GitHub Actions / lint

Unsafe return of an `any` typed value
} catch (err) {
console.error(err)
throw new TypeError('Get factory failed')
Expand All @@ -40,35 +45,45 @@

export async function getFactory (factoryId: string): Promise<FactoryData> {
try {
const { data } = await instance.get(`/factories/${factoryId}`)

Check warning on line 48 in src/api/index.ts

View workflow job for this annotation

GitHub Actions / lint

Unsafe array destructuring of a tuple element with an `any` value
return data

Check warning on line 49 in src/api/index.ts

View workflow job for this annotation

GitHub Actions / lint

Unsafe return of an `any` typed value
} catch (err) {
console.error(err)
throw new TypeError('Get factory failed')
}
}

const IMGUR_CLIENT_ID = '39048813b021935'
async function uploadImageDirectly (file: File): Promise<UploadedImage> {
// For general images, use the existing backend pattern
// The backend may not have a general /images/upload endpoint yet
// So we upload the file and let the backend handle it using the existing /images endpoint

async function uploadToImgur (file: File) {
const formData = new FormData()
formData.append('image', file)

const { data } = await axios({
method: 'POST',
url: 'https://api.imgur.com/3/image',
data: formData,
const exifData = await readImageExif(file)

// Append EXIF data to form
if (exifData.Latitude) {
formData.append('Latitude', exifData.Latitude.toString())
}
if (exifData.Longitude) {
formData.append('Longitude', exifData.Longitude.toString())
}
if (exifData.DateTimeOriginal) {
formData.append('DateTimeOriginal', exifData.DateTimeOriginal)
}

const { data }: { data: ImageResponse } = await instance.post('/images', formData, {
headers: {
'Content-Type': 'multipart/form-data',
Authorization: `Client-ID ${IMGUR_CLIENT_ID}`
'Content-Type': 'multipart/form-data'
}
})

return {
link: data.data.link as string,
deletehash: data.data.deletehash as string,
file
}
token: data.token,
src: URL.createObjectURL(file)
} as UploadedImage
}

const convertTurple2Number = (input: [number, number, number]) => input[0] + (input[1] / 60) + (input[2] / 3600)
Expand All @@ -84,7 +99,7 @@
resolve({})
return
}
const data: ExifData = EXIF.readFromBinaryFile(e.target.result)

Check warning on line 102 in src/api/index.ts

View workflow job for this annotation

GitHub Actions / lint

Unsafe assignment of an `any` value

const result: AfterExifData = {}
if (data.GPSLatitude) {
Expand All @@ -103,35 +118,47 @@
})
}

export type UploadedImage = {
token: string,
src: string
}

async function uploadExifAndGetToken ({ link, file, deletehash }: { link: string, file: File, deletehash: string }) {
const exifData = await readImageExif(file)
const { data }: { data: ImageResponse } = await instance.post('/images', { url: link, ...exifData, deletehash })

return {
token: data.token,
src: URL.createObjectURL(file)
} as UploadedImage
}

export async function uploadImages (files: FileList): Promise<UploadedImages> {
return Promise.all(
Array.from(files).map((file) => uploadToImgur(file).then((el) => uploadExifAndGetToken(el)))
Array.from(files).map((file) => uploadImageDirectly(file))
)
}

export async function updateFactoryImages (factoryId: string, files: FileList, { nickname, contact }: { nickname?: string, contact?: string }) {
return Promise.all(
Array.from(files).map((file) => uploadToImgur(file).then((el) => (async () => {
const exifData = await readImageExif(el.file)
const { data }: { data: FactoryImage } = await instance.post(`/factories/${factoryId}/images`, { url: el.link, ...exifData, nickname, contact, deletehash: el.deletehash })
data.image_path = el.link
Array.from(files).map(async (file) => {
const formData = new FormData()
formData.append('image', file)

const exifData = await readImageExif(file)

// Append EXIF data to form
if (exifData.Latitude) {
formData.append('Latitude', exifData.Latitude.toString())
}
if (exifData.Longitude) {
formData.append('Longitude', exifData.Longitude.toString())
}
if (exifData.DateTimeOriginal) {
formData.append('DateTimeOriginal', exifData.DateTimeOriginal)
}

// Append contact info if provided
if (nickname) {
formData.append('nickname', nickname)
}
if (contact) {
formData.append('contact', contact)
}

const { data }: { data: FactoryImage } = await instance.post(`/factories/${factoryId}/images/upload`, formData, {
headers: {
'Content-Type': 'multipart/form-data'
}
})

return data
})()))
})
)
}

Expand Down
Loading