Files
feeddeck/supabase/functions/_shared/feed/utils/uploadFile.ts
Rico Berger 4a8776ee31 [core] Improve Media Handling (#5)
Improve the media handling within the app. We do not save the media
files for items to the Supabase storage anymore. The source icons are
now only saved in the Supabase storage, the usage of an url as source
icon is not possible anymore.

The media files for items are directly retrieved from the corresponding
url or for the web version from the "image-proxy-v1" Supabase function.
If the image is retireved from the Supabase function we cache the image
in the browser via the cache control headers. If the image is directly
retrieved from it's url it's cached by the "CachedNetworkImage" widget.
2023-09-08 22:08:43 +02:00

68 lines
1.9 KiB
TypeScript

import { SupabaseClient } from "@supabase/supabase-js";
import { ISource } from "../../models/source.ts";
import { fetchWithTimeout } from "../../utils/fetchWithTimeout.ts";
import { log } from "../../utils/log.ts";
/**
* `uploadSourceIcon` uploads the `icon` of the provided `source` to the Supabase storage, to avoid CORS issues within
* our web app and to make use of the built-in CDN. If the upload was successfull the path of the uploaded icon is
* returned. If the upload failed `undefined` is returned.
*/
export const uploadSourceIcon = async (
supabaseClient: SupabaseClient,
source: ISource,
): Promise<string | undefined> => {
if (!source.icon || source.icon === "") {
return undefined;
}
return await uploadFile(
supabaseClient,
"sources",
source.icon,
`${source.userId}/${source.id}.${source.icon.split(".").pop()}`,
);
};
/**
* `uploadFile` uploads the provided file via it's `sourcePath` to the `targetPath` within the provided `bucket`. For
* this we have to fetch the file first and then upload it to the Supabase storage.
*/
const uploadFile = async (
supabaseClient: SupabaseClient,
bucket: string,
sourcePath: string,
targetPath: string,
): Promise<string | undefined> => {
try {
const fileResponse = await fetchWithTimeout(
sourcePath,
{ method: "get" },
5000,
);
const file = await fileResponse.blob();
const { data: uploadData, error: uploadError } = await supabaseClient
.storage.from(bucket)
.upload(
targetPath,
file,
{
upsert: true,
},
);
if (uploadError) {
log("error", "Failed to upload source icon", {
"error": uploadError,
});
return undefined;
}
return uploadData?.path;
} catch (err) {
log("error", "Failed to upload source icon", { "error": err.toString() });
return undefined;
}
};