mirror of
https://github.com/feeddeck/feeddeck.git
synced 2026-05-27 22:16:16 -05:00
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.
68 lines
1.9 KiB
TypeScript
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;
|
|
}
|
|
};
|