hyper-tuner-cloud/src/hooks/useServerStorage.ts

123 lines
3.7 KiB
TypeScript

import { notification } from 'antd';
import * as Sentry from '@sentry/browser';
import { Models } from 'appwrite';
import { storage } from '../appwrite';
import { fetchEnv } from '../utils/env';
const PUBLIC_PATH = 'public';
const INI_PATH = `${PUBLIC_PATH}/ini`;
export const CDN_URL = fetchEnv('VITE_CDN_URL');
export type ServerFile = Models.File;
const genericError = (error: Error) => notification.error({ message: 'Storage Error', description: error.message });
const fetchFromServer = async (path: string): Promise<ArrayBuffer> => {
const response = await fetch(`${CDN_URL}/${path}`);
return Promise.resolve(response.arrayBuffer());
};
const useServerStorage = () => {
const getINIFile = async (signature: string) => {
const { version, baseVersion } = /.+?(?<version>(?<baseVersion>\d+)(-\w+)*)/.exec(signature)?.groups || { version: null, baseVersion: null };
try {
return fetchFromServer(`${INI_PATH}/${version}.ini.gz`);
} catch (error) {
Sentry.captureException(error);
console.error(error);
notification.warning({
message: 'INI not found',
description: `INI version: "${version}" not found. Trying base version: "${baseVersion}"!`,
});
try {
return fetchFromServer(`${INI_PATH}/${baseVersion}.ini.gz`);
} catch (err) {
Sentry.captureException(err);
console.error(err);
notification.error({
message: 'INI not found',
description: `INI version: "${baseVersion}" not found. Try uploading custom INI file!`,
});
}
return Promise.reject(error);
}
};
const removeFile = async (bucketId: string, fileId: string) => {
try {
await storage.deleteFile(bucketId, fileId);
return Promise.resolve();
} catch (error) {
Sentry.captureException(error);
console.error(error);
genericError(error as Error);
return Promise.reject(error);
}
};
const uploadFile = async (userId: string, bucketId: string, file: File) => {
try {
const createdFile = await storage.createFile(
bucketId,
'unique()',
file,
['role:all'],
[`user:${userId}`],
);
return Promise.resolve(createdFile);
} catch (error) {
Sentry.captureException(error);
console.error(error);
genericError(error as Error);
return Promise.reject(error);
}
};
const getFile = async (id: string, bucketId: string) => {
try {
const file = await storage.getFile(bucketId, id);
return Promise.resolve(file);
} catch (error) {
Sentry.captureException(error);
console.error(error);
genericError(error as Error);
return Promise.reject(error);
}
};
const getFileForDownload = async (id: string, bucketId: string) => {
try {
const file = storage.getFileView(bucketId, id);
const response = await fetch(file.href);
return Promise.resolve(response.arrayBuffer());
} catch (error) {
Sentry.captureException(error);
console.error(error);
genericError(error as Error);
return Promise.reject(error);
}
};
return {
getFile: (id: string, bucketId: string): Promise<Models.File> => getFile(id, bucketId),
getINIFile: (signature: string): Promise<ArrayBuffer> => getINIFile(signature),
removeFile: (bucketId: string, fileId: string): Promise<void> => removeFile(bucketId, fileId),
getFileForDownload: (bucketId: string, fileId: string): Promise<ArrayBuffer> => getFileForDownload(bucketId, fileId),
uploadFile: (userId: string, bucketId: string, file: File): Promise<ServerFile> => uploadFile(userId, bucketId, file),
};
};
export default useServerStorage;