Browse Source

Deleted videos no longer appear on Home Page.

SuperLikes and comments publish as file instead of Base64.

Fixed bug causing the minimum Superlike to be 10 QORT when it is supposed to be 1 QORT.
pull/29/head
Qortal Dev 3 months ago
parent
commit
88cd24ae4d
  1. 21
      src/components/Publish/EditPlaylist/EditPlaylist.tsx
  2. 23
      src/components/Publish/EditVideo/EditVideo.tsx
  3. 25
      src/components/common/Comments/CommentEditor.tsx
  4. 75
      src/components/common/ContentButtons/SuperLike.tsx
  5. 39
      src/components/common/SuperLikesList/CommentEditor.tsx
  6. 9
      src/pages/ContentPages/VideoContent/VideoContent.tsx
  7. 147
      src/utils/PublishFormatter.ts

21
src/components/Publish/EditPlaylist/EditPlaylist.tsx

@ -31,7 +31,11 @@ import AddBoxIcon from "@mui/icons-material/AddBox";
import { useDropzone } from "react-dropzone"; import { useDropzone } from "react-dropzone";
import { setNotification } from "../../../state/features/notificationsSlice.ts"; import { setNotification } from "../../../state/features/notificationsSlice.ts";
import { objectToBase64, uint8ArrayToBase64 } from "../../../utils/PublishFormatter.ts"; import {
objectToBase64,
objectToFile,
uint8ArrayToBase64,
} from "../../../utils/PublishFormatter.ts";
import { RootState } from "../../../state/store.ts"; import { RootState } from "../../../state/store.ts";
import { import {
upsertVideosBeginning, upsertVideosBeginning,
@ -165,14 +169,16 @@ export const EditPlaylist = () => {
const responseDataSearchVid = await response.json(); const responseDataSearchVid = await response.json();
if (responseDataSearchVid?.length > 0) { if (responseDataSearchVid?.length > 0) {
let resourceData2 = responseDataSearchVid[0]; const resourceData2 = responseDataSearchVid[0];
videos.push(resourceData2); videos.push(resourceData2);
} }
} }
} }
combinedData.videos = videos; combinedData.videos = videos;
setPlaylistData(combinedData); setPlaylistData(combinedData);
} catch (error) {} } catch (error) {
console.log(error);
}
}, []); }, []);
useEffect(() => { useEffect(() => {
@ -263,13 +269,13 @@ export const EditPlaylist = () => {
if (!descriptionVid) throw new Error("cannot find video code"); if (!descriptionVid) throw new Error("cannot find video code");
// Split the string by ';' // Split the string by ';'
let parts = descriptionVid.split(";"); const parts = descriptionVid.split(";");
// Initialize a variable to hold the code value // Initialize a variable to hold the code value
let codeValue = ""; let codeValue = "";
// Loop through the parts to find the one that starts with 'code:' // Loop through the parts to find the one that starts with 'code:'
for (let part of parts) { for (const part of parts) {
if (part.startsWith("code:")) { if (part.startsWith("code:")) {
codeValue = part.split(":")[1]; codeValue = part.split(":")[1];
break; break;
@ -309,11 +315,10 @@ export const EditPlaylist = () => {
.map(item => `c:${item.code};`) .map(item => `c:${item.code};`)
.slice(0, 10) .slice(0, 10)
.join(""); .join("");
let metadescription = const metadescription =
`**category:${category};subcategory:${subcategory};${codes}**` + `**category:${category};subcategory:${subcategory};${codes}**` +
stringDescription.slice(0, 120); stringDescription.slice(0, 120);
const crowdfundObjectToBase64 = await objectToBase64(playlistObject);
// Description is obtained from raw data // Description is obtained from raw data
let identifier = editVideoProperties?.id; let identifier = editVideoProperties?.id;
@ -333,7 +338,7 @@ export const EditPlaylist = () => {
action: "PUBLISH_QDN_RESOURCE", action: "PUBLISH_QDN_RESOURCE",
name: username, name: username,
service: "PLAYLIST", service: "PLAYLIST",
data64: crowdfundObjectToBase64, file: objectToFile(playlistObject),
title: title.slice(0, 50), title: title.slice(0, 50),
description: metadescription, description: metadescription,
identifier: identifier, identifier: identifier,

23
src/components/Publish/EditVideo/EditVideo.tsx

@ -35,7 +35,11 @@ import AddBoxIcon from "@mui/icons-material/AddBox";
import { useDropzone } from "react-dropzone"; import { useDropzone } from "react-dropzone";
import { setNotification } from "../../../state/features/notificationsSlice.ts"; import { setNotification } from "../../../state/features/notificationsSlice.ts";
import { objectToBase64, objectToFile, uint8ArrayToBase64 } from "../../../utils/PublishFormatter.ts"; import {
objectToBase64,
objectToFile,
uint8ArrayToBase64,
} from "../../../utils/PublishFormatter.ts";
import { RootState } from "../../../state/store.ts"; import { RootState } from "../../../state/store.ts";
import { import {
upsertVideosBeginning, upsertVideosBeginning,
@ -53,7 +57,11 @@ import { extractTextFromHTML } from "../../common/TextEditor/utils.ts";
import { toBase64 } from "../PublishVideo/PublishVideo.tsx"; import { toBase64 } from "../PublishVideo/PublishVideo.tsx";
import { FrameExtractor } from "../../common/FrameExtractor/FrameExtractor.tsx"; import { FrameExtractor } from "../../common/FrameExtractor/FrameExtractor.tsx";
import { QTUBE_VIDEO_BASE } from "../../../constants/Identifiers.ts"; import { QTUBE_VIDEO_BASE } from "../../../constants/Identifiers.ts";
import { maxSize, titleFormatter, videoMaxSize } from "../../../constants/Misc.ts"; import {
maxSize,
titleFormatter,
videoMaxSize,
} from "../../../constants/Misc.ts";
const uid = new ShortUniqueId(); const uid = new ShortUniqueId();
const shortuid = new ShortUniqueId({ length: 5 }); const shortuid = new ShortUniqueId({ length: 5 });
@ -291,13 +299,12 @@ export const EditVideo = () => {
`**category:${category};subcategory:${subcategory};code:${editVideoProperties.code}**` + `**category:${category};subcategory:${subcategory};code:${editVideoProperties.code}**` +
description.slice(0, 150); description.slice(0, 150);
const videoObjectToFile = objectToFile(videoObject);
// Description is obtained from raw data // Description is obtained from raw data
const requestBodyJson: any = { const requestBodyJson: any = {
action: "PUBLISH_QDN_RESOURCE", action: "PUBLISH_QDN_RESOURCE",
name: username, name: username,
service: "DOCUMENT", service: "DOCUMENT",
file: videoObjectToFile, file: objectToFile(videoObject),
title: title.slice(0, 50), title: title.slice(0, 50),
description: metadescription, description: metadescription,
identifier: editVideoProperties.id, identifier: editVideoProperties.id,
@ -394,7 +401,9 @@ export const EditVideo = () => {
compressedFile = file; compressedFile = file;
resolve(); resolve();
}, },
error(error) {console.log(error)}, error(error) {
console.log(error);
},
}); });
}); });
if (!compressedFile) continue; if (!compressedFile) continue;
@ -406,7 +415,9 @@ export const EditVideo = () => {
} }
setImageExtracts(imagesExtracts); setImageExtracts(imagesExtracts);
} catch (error) {console.log(error)} } catch (error) {
console.log(error);
}
}; };
return ( return (

25
src/components/common/Comments/CommentEditor.tsx

@ -4,7 +4,10 @@ import { useDispatch, useSelector } from "react-redux";
import { RootState } from "../../../state/store"; import { RootState } from "../../../state/store";
import ShortUniqueId from "short-unique-id"; import ShortUniqueId from "short-unique-id";
import { setNotification } from "../../../state/features/notificationsSlice"; import { setNotification } from "../../../state/features/notificationsSlice";
import { publishFormatter } from "../../../utils/PublishFormatter.ts"; import {
publishFormatter,
stringToFile,
} from "../../../utils/PublishFormatter.ts";
import localforage from "localforage"; import localforage from "localforage";
import { import {
CommentInput, CommentInput,
@ -30,11 +33,13 @@ export interface Item {
export async function addItem(item: Item): Promise<void> { export async function addItem(item: Item): Promise<void> {
// Get all items // Get all items
let notificationComments: Item[] = const notificationComments: Item[] =
(await notification.getItem("comments")) || []; (await notification.getItem("comments")) || [];
// Find the item with the same id, if it exists // Find the item with the same id, if it exists
let existingItemIndex = notificationComments.findIndex(i => i.id === item.id); const existingItemIndex = notificationComments.findIndex(
i => i.id === item.id
);
if (existingItemIndex !== -1) { if (existingItemIndex !== -1) {
// If the item exists, update its date // If the item exists, update its date
@ -55,10 +60,10 @@ export async function addItem(item: Item): Promise<void> {
} }
export async function updateItemDate(item: any): Promise<void> { export async function updateItemDate(item: any): Promise<void> {
// Get all items // Get all items
let notificationComments: Item[] = const notificationComments: Item[] =
(await notification.getItem("comments")) || []; (await notification.getItem("comments")) || [];
let notificationCreatorComment: any = const notificationCreatorComment: any =
(await notification.getItem("post-comments")) || {}; (await notification.getItem("post-comments")) || {};
const findPostId = notificationCreatorComment[item.postId]; const findPostId = notificationCreatorComment[item.postId];
if (findPostId) { if (findPostId) {
@ -121,13 +126,10 @@ export const CommentEditor = ({
identifier: string, identifier: string,
idForNotification?: string idForNotification?: string
) => { ) => {
let address; const address = user?.address;
let name; const name = user?.name || "";
let errorMsg = ""; let errorMsg = "";
address = user?.address;
name = user?.name || "";
if (!address) { if (!address) {
errorMsg = "Cannot post: your address isn't available"; errorMsg = "Cannot post: your address isn't available";
} }
@ -150,12 +152,11 @@ export const CommentEditor = ({
} }
try { try {
const base64 = utf8ToBase64(value);
const resourceResponse = await qortalRequest({ const resourceResponse = await qortalRequest({
action: "PUBLISH_QDN_RESOURCE", action: "PUBLISH_QDN_RESOURCE",
name: name, name: name,
service: "BLOG_COMMENT", service: "BLOG_COMMENT",
data64: base64, file: stringToFile(value),
identifier: identifier, identifier: identifier,
}); });
dispatch( dispatch(

75
src/components/common/ContentButtons/SuperLike.tsx

@ -21,7 +21,10 @@ import { MultiplePublish } from "../../Publish/MultiplePublish/MultiplePublishAl
import { useDispatch, useSelector } from "react-redux"; import { useDispatch, useSelector } from "react-redux";
import { setNotification } from "../../../state/features/notificationsSlice.ts"; import { setNotification } from "../../../state/features/notificationsSlice.ts";
import ShortUniqueId from "short-unique-id"; import ShortUniqueId from "short-unique-id";
import { objectToBase64 } from "../../../utils/PublishFormatter.ts"; import {
objectToBase64,
objectToFile,
} from "../../../utils/PublishFormatter.ts";
import { minPriceSuperlike } from "../../../constants/Misc.ts"; import { minPriceSuperlike } from "../../../constants/Misc.ts";
import { CommentInput } from "../Comments/Comments-styles.tsx"; import { CommentInput } from "../Comments/Comments-styles.tsx";
import { import {
@ -55,9 +58,7 @@ export const SuperLike = ({
const [isOpen, setIsOpen] = useState<boolean>(false); const [isOpen, setIsOpen] = useState<boolean>(false);
const [superlikeDonationAmount, setSuperlikeDonationAmount] = const [superlikeDonationAmount, setSuperlikeDonationAmount] =
useState<number>(10); useState<number>(minPriceSuperlike);
const [qortalDevDonationAmount, setQortalDevDonationAmount] =
useState<number>(0);
const [currentBalance, setCurrentBalance] = useState<string>(""); const [currentBalance, setCurrentBalance] = useState<string>("");
const [comment, setComment] = useState<string>(""); const [comment, setComment] = useState<string>("");
@ -82,15 +83,12 @@ export const SuperLike = ({
if (!name) throw new Error("Could not retrieve content creator's name"); if (!name) throw new Error("Could not retrieve content creator's name");
const estimatedTransactionFees = 0.1; const estimatedTransactionFees = 0.1;
const donationExceedsBalance = const donationExceedsBalance =
superlikeDonationAmount + superlikeDonationAmount + estimatedTransactionFees >= +currentBalance;
qortalDevDonationAmount +
estimatedTransactionFees >=
+currentBalance;
if (donationExceedsBalance) { if (donationExceedsBalance) {
throw new Error("Total donations exceeds current balance"); throw new Error("Total donations exceeds current balance");
} }
let resName = await qortalRequest({ const resName = await qortalRequest({
action: "GET_NAME_DATA", action: "GET_NAME_DATA",
name: name, name: name,
}); });
@ -106,10 +104,10 @@ export const SuperLike = ({
superlikeDonationAmount < minPriceSuperlike superlikeDonationAmount < minPriceSuperlike
) )
throw new Error( throw new Error(
`The amount needs to be at least ${minPriceSuperlike} QORT` `The amount is ${superlikeDonationAmount}, but it needs to be at least ${minPriceSuperlike} QORT`
); );
let listOfPublishes = []; const listOfPublishes = [];
const res = await qortalRequest({ const res = await qortalRequest({
action: "SEND_COIN", action: "SEND_COIN",
@ -118,24 +116,7 @@ export const SuperLike = ({
amount: superlikeDonationAmount, amount: superlikeDonationAmount,
}); });
const devDonation = qortalDevDonationAmount > 0; const metadescription = `**sig:${
if (devDonation) {
const devFundName = "DevFund";
let devFundNameData = await qortalRequest({
action: "GET_NAME_DATA",
name: devFundName,
});
const devFundAddress = devFundNameData.owner;
const resDevFund = await qortalRequest({
action: "SEND_COIN",
coin: "QORT",
destinationAddress: devFundAddress,
amount: qortalDevDonationAmount,
});
}
let metadescription = `**sig:${
res.signature res.signature
};${FOR}:${name}_${FOR_SUPER_LIKE};nm:${name.slice( };${FOR}:${name}_${FOR_SUPER_LIKE};nm:${name.slice(
0, 0,
@ -148,7 +129,7 @@ export const SuperLike = ({
39 39
)}_${id}`; )}_${id}`;
const superLikeToBase64 = await objectToBase64({ const superLikeToFile = objectToFile({
comment, comment,
transactionReference: res.signature, transactionReference: res.signature,
notificationInformation: { notificationInformation: {
@ -166,7 +147,7 @@ export const SuperLike = ({
action: "PUBLISH_QDN_RESOURCE", action: "PUBLISH_QDN_RESOURCE",
name: username, name: username,
service: "BLOG_COMMENT", service: "BLOG_COMMENT",
data64: superLikeToBase64, file: superLikeToFile,
title: "", title: "",
description: metadescription, description: metadescription,
identifier: identifierSuperLike, identifier: identifierSuperLike,
@ -187,9 +168,9 @@ export const SuperLike = ({
dispatch( dispatch(
setNotification({ setNotification({
msg: msg:
error ||
error?.error || error?.error ||
error?.message || error?.message ||
error ||
"Failed to publish Super Like", "Failed to publish Super Like",
alertType: "error", alertType: "error",
}) })
@ -339,36 +320,6 @@ export const SuperLike = ({
InputLabelProps={{ style: { fontSize: "18px" } }} InputLabelProps={{ style: { fontSize: "18px" } }}
onChange={e => setComment(e.target.value)} onChange={e => setComment(e.target.value)}
/> />
<Spacer height="50px" />
<InputLabel
htmlFor="standard-adornment-amount"
style={{ paddingBottom: "10px" }}
>
Would you like to donate to Qortal Development?
</InputLabel>
<BoundedNumericTextField
minValue={0}
initialValue={""}
maxValue={numberToInt(+currentBalance)}
allowDecimals={false}
value={superlikeDonationAmount}
afterChange={(e: string) => setQortalDevDonationAmount(+e)}
InputProps={{
style: { fontSize: 30, width: textFieldWidth },
startAdornment: (
<InputAdornment position="start">
<img
style={{
height: "40px",
width: "40px",
}}
src={qortImg}
alt={"Qort Icon"}
/>
</InputAdornment>
),
}}
/>
</Box> </Box>
</DialogContent> </DialogContent>
<CrowdfundActionButtonRow> <CrowdfundActionButtonRow>

39
src/components/common/SuperLikesList/CommentEditor.tsx

@ -4,7 +4,12 @@ import { useDispatch, useSelector } from "react-redux";
import { RootState } from "../../../state/store"; import { RootState } from "../../../state/store";
import ShortUniqueId from "short-unique-id"; import ShortUniqueId from "short-unique-id";
import { setNotification } from "../../../state/features/notificationsSlice"; import { setNotification } from "../../../state/features/notificationsSlice";
import { objectToBase64, publishFormatter } from "../../../utils/PublishFormatter.ts"; import {
objectToBase64,
objectToFile,
publishFormatter,
stringToFile,
} from "../../../utils/PublishFormatter.ts";
import localforage from "localforage"; import localforage from "localforage";
import { import {
CommentInput, CommentInput,
@ -30,11 +35,13 @@ export interface Item {
export async function addItem(item: Item): Promise<void> { export async function addItem(item: Item): Promise<void> {
// Get all items // Get all items
let notificationComments: Item[] = const notificationComments: Item[] =
(await notification.getItem("comments")) || []; (await notification.getItem("comments")) || [];
// Find the item with the same id, if it exists // Find the item with the same id, if it exists
let existingItemIndex = notificationComments.findIndex(i => i.id === item.id); const existingItemIndex = notificationComments.findIndex(
i => i.id === item.id
);
if (existingItemIndex !== -1) { if (existingItemIndex !== -1) {
// If the item exists, update its date // If the item exists, update its date
@ -55,10 +62,10 @@ export async function addItem(item: Item): Promise<void> {
} }
export async function updateItemDate(item: any): Promise<void> { export async function updateItemDate(item: any): Promise<void> {
// Get all items // Get all items
let notificationComments: Item[] = const notificationComments: Item[] =
(await notification.getItem("comments")) || []; (await notification.getItem("comments")) || [];
let notificationCreatorComment: any = const notificationCreatorComment: any =
(await notification.getItem("post-comments")) || {}; (await notification.getItem("post-comments")) || {};
const findPostId = notificationCreatorComment[item.postId]; const findPostId = notificationCreatorComment[item.postId];
if (findPostId) { if (findPostId) {
@ -127,13 +134,10 @@ export const CommentEditor = ({
identifier: string, identifier: string,
idForNotification?: string idForNotification?: string
) => { ) => {
let address; const address = user?.address;
let name; const name = user?.name || "";
let errorMsg = ""; let errorMsg = "";
address = user?.address;
name = user?.name || "";
if (!address) { if (!address) {
errorMsg = "Cannot post: your address isn't available"; errorMsg = "Cannot post: your address isn't available";
} }
@ -156,7 +160,7 @@ export const CommentEditor = ({
} }
try { try {
let data64 = null; let dataFile = null;
let description = ""; let description = "";
let tag1 = ""; let tag1 = "";
let superObj = {}; let superObj = {};
@ -177,17 +181,18 @@ export const CommentEditor = ({
notificationInformation: comment.notificationInformation, notificationInformation: comment.notificationInformation,
about: comment.about, about: comment.about,
}; };
const superLikeToBase64 = await objectToBase64(superObj); const superLikeToFile = await objectToFile(superObj);
data64 = superLikeToBase64; dataFile = superLikeToFile;
} }
if (isSuperLike && !data64) throw new Error("unable to edit Super like"); if (isSuperLike && !dataFile)
throw new Error("unable to edit Super like");
const base64 = utf8ToBase64(value); const stringFile = stringToFile(value);
const resourceResponse = await qortalRequest({ const resourceResponse = await qortalRequest({
action: "PUBLISH_QDN_RESOURCE", action: "PUBLISH_QDN_RESOURCE",
name: name, name: name,
service: "BLOG_COMMENT", service: "BLOG_COMMENT",
data64: isSuperLike ? data64 : base64, file: isSuperLike ? dataFile : stringFile,
identifier: identifier, identifier: identifier,
description, description,
tag1, tag1,
@ -248,7 +253,7 @@ export const CommentEditor = ({
let identifier = `${COMMENT_BASE}${postId.slice(-12)}_base_${id}`; let identifier = `${COMMENT_BASE}${postId.slice(-12)}_base_${id}`;
let idForNotification = identifier; let idForNotification = identifier;
let service = "BLOG_COMMENT"; const service = "BLOG_COMMENT";
if (isReply && commentId) { if (isReply && commentId) {
const removeBaseCommentId = commentId; const removeBaseCommentId = commentId;
removeBaseCommentId.replace("_base_", ""); removeBaseCommentId.replace("_base_", "");

9
src/pages/ContentPages/VideoContent/VideoContent.tsx

@ -65,10 +65,10 @@ import { LikeAndDislike } from "../../../components/common/ContentButtons/LikeAn
export function isTimestampWithinRange(resTimestamp, resCreated) { export function isTimestampWithinRange(resTimestamp, resCreated) {
// Calculate the absolute difference in milliseconds // Calculate the absolute difference in milliseconds
var difference = Math.abs(resTimestamp - resCreated); const difference = Math.abs(resTimestamp - resCreated);
// 2 minutes in milliseconds // 2 minutes in milliseconds
var twoMinutesInMilliseconds = 3 * 60 * 1000; const twoMinutesInMilliseconds = 3 * 60 * 1000;
// Check if the difference is within 2 minutes // Check if the difference is within 2 minutes
return difference <= twoMinutesInMilliseconds; return difference <= twoMinutesInMilliseconds;
@ -282,6 +282,7 @@ export const VideoContent = () => {
} }
} }
} catch (error) { } catch (error) {
console.log(error);
} finally { } finally {
dispatch(setIsLoadingGlobal(false)); dispatch(setIsLoadingGlobal(false));
} }
@ -356,7 +357,9 @@ export const VideoContent = () => {
}, },
]; ];
} }
} catch (error) {} } catch (error) {
console.log(error);
}
} }
} }

147
src/utils/PublishFormatter.ts

@ -1,98 +1,107 @@
export const publishFormatter = (file: File): Promise<string | ArrayBuffer | null> => export const publishFormatter = (
file: File
): Promise<string | ArrayBuffer | null> =>
new Promise((resolve, reject) => { new Promise((resolve, reject) => {
const reader = new FileReader() const reader = new FileReader();
reader.readAsDataURL(file) reader.readAsDataURL(file);
reader.onload = () => { reader.onload = () => {
const result = reader.result const result = reader.result;
reader.onload = null // remove onload handler reader.onload = null; // remove onload handler
reader.onerror = null // remove onerror handler reader.onerror = null; // remove onerror handler
resolve(result) resolve(result);
} };
reader.onerror = (error) => { reader.onerror = error => {
reader.onload = null // remove onload handler reader.onload = null; // remove onload handler
reader.onerror = null // remove onerror handler reader.onerror = null; // remove onerror handler
reject(error) reject(error);
} };
}) });
export function objectToBase64(obj: any) { export function objectToBase64(obj: any) {
// Step 1: Convert the object to a JSON string // Step 1: Convert the object to a JSON string
const jsonString = JSON.stringify(obj) const jsonString = JSON.stringify(obj);
// Step 2: Create a Blob from the JSON string // Step 2: Create a Blob from the JSON string
const blob = new Blob([jsonString], { type: 'application/json' }) const blob = new Blob([jsonString], { type: "application/json" });
// Step 3: Create a FileReader to read the Blob as a base64-encoded string // Step 3: Create a FileReader to read the Blob as a base64-encoded string
return new Promise<string>((resolve, reject) => { return new Promise<string>((resolve, reject) => {
const reader = new FileReader() const reader = new FileReader();
reader.onloadend = () => { reader.onloadend = () => {
if (typeof reader.result === 'string') { if (typeof reader.result === "string") {
// Remove 'data:application/json;base64,' prefix // Remove 'data:application/json;base64,' prefix
const base64 = reader.result.replace( const base64 = reader.result.replace(
'data:application/json;base64,', "data:application/json;base64,",
'' ""
) );
resolve(base64) resolve(base64);
} else { } else {
reject(new Error('Failed to read the Blob as a base64-encoded string')) reject(new Error("Failed to read the Blob as a base64-encoded string"));
} }
} };
reader.onerror = () => { reader.onerror = () => {
reject(reader.error) reject(reader.error);
} };
reader.readAsDataURL(blob) reader.readAsDataURL(blob);
}) });
} }
export function objectToFile(obj: any) { export const stringToFile = (text: string) => {
return new File([text], "", {
type: "text/plain",
});
};
export const objectToFile = (obj: object) => {
// Step 1: Convert the object to a JSON string // Step 1: Convert the object to a JSON string
const jsonString = JSON.stringify(obj) const jsonString = JSON.stringify(obj);
const fileType = { type: "application/json" };
// Step 2: Create a Blob from the JSON string // Step 2: Create a Blob from the JSON string
return new Blob([jsonString], { type: 'application/json' }) const blob = new Blob([jsonString], fileType);
} return new File([blob], ``, fileType);
};
export function objectToUint8Array(obj: any) { export function objectToUint8Array(obj: any) {
// Convert the object to a JSON string // Convert the object to a JSON string
const jsonString = JSON.stringify(obj) const jsonString = JSON.stringify(obj);
// Encode the JSON string as a byte array using TextEncoder // Encode the JSON string as a byte array using TextEncoder
const encoder = new TextEncoder() const encoder = new TextEncoder();
const byteArray = encoder.encode(jsonString) const byteArray = encoder.encode(jsonString);
// Create a new Uint8Array and set its content to the encoded byte array // Create a new Uint8Array and set its content to the encoded byte array
const uint8Array = new Uint8Array(byteArray) const uint8Array = new Uint8Array(byteArray);
return uint8Array return uint8Array;
} }
export function uint8ArrayToBase64(uint8Array: Uint8Array): string { export function uint8ArrayToBase64(uint8Array: Uint8Array): string {
const length = uint8Array.length const length = uint8Array.length;
let binaryString = '' let binaryString = "";
const chunkSize = 1024 * 1024 // Process 1MB at a time const chunkSize = 1024 * 1024; // Process 1MB at a time
for (let i = 0; i < length; i += chunkSize) { for (let i = 0; i < length; i += chunkSize) {
const chunkEnd = Math.min(i + chunkSize, length) const chunkEnd = Math.min(i + chunkSize, length);
const chunk = uint8Array.subarray(i, chunkEnd) const chunk = uint8Array.subarray(i, chunkEnd);
binaryString += Array.from(chunk, (byte) => String.fromCharCode(byte)).join( binaryString += Array.from(chunk, byte => String.fromCharCode(byte)).join(
'' ""
) );
} }
return btoa(binaryString) return btoa(binaryString);
} }
export function objectToUint8ArrayFromResponse(obj: any) { export function objectToUint8ArrayFromResponse(obj: any) {
const len = Object.keys(obj).length const len = Object.keys(obj).length;
const result = new Uint8Array(len) const result = new Uint8Array(len);
for (let i = 0; i < len; i++) { for (let i = 0; i < len; i++) {
result[i] = obj[i] result[i] = obj[i];
} }
return result return result;
} }
// export function uint8ArrayToBase64(arrayBuffer: Uint8Array): string { // export function uint8ArrayToBase64(arrayBuffer: Uint8Array): string {
// let binary = '' // let binary = ''
@ -107,46 +116,46 @@ export function objectToUint8ArrayFromResponse(obj: any) {
// } // }
export function base64ToUint8Array(base64: string) { export function base64ToUint8Array(base64: string) {
const binaryString = atob(base64) const binaryString = atob(base64);
const len = binaryString.length const len = binaryString.length;
const bytes = new Uint8Array(len) const bytes = new Uint8Array(len);
for (let i = 0; i < len; i++) { for (let i = 0; i < len; i++) {
bytes[i] = binaryString.charCodeAt(i) bytes[i] = binaryString.charCodeAt(i);
} }
return bytes return bytes;
} }
export function uint8ArrayToObject(uint8Array: Uint8Array) { export function uint8ArrayToObject(uint8Array: Uint8Array) {
// Decode the byte array using TextDecoder // Decode the byte array using TextDecoder
const decoder = new TextDecoder() const decoder = new TextDecoder();
const jsonString = decoder.decode(uint8Array) const jsonString = decoder.decode(uint8Array);
// Convert the JSON string back into an object // Convert the JSON string back into an object
const obj = JSON.parse(jsonString) const obj = JSON.parse(jsonString);
return obj return obj;
} }
export function processFileInChunks(file: File): Promise<Uint8Array> { export function processFileInChunks(file: File): Promise<Uint8Array> {
return new Promise( return new Promise(
(resolve: (value: Uint8Array) => void, reject: (reason?: any) => void) => { (resolve: (value: Uint8Array) => void, reject: (reason?: any) => void) => {
const reader = new FileReader() const reader = new FileReader();
reader.onload = function (event: ProgressEvent<FileReader>) { reader.onload = function (event: ProgressEvent<FileReader>) {
const arrayBuffer = event.target?.result as ArrayBuffer const arrayBuffer = event.target?.result as ArrayBuffer;
const uint8Array = new Uint8Array(arrayBuffer) const uint8Array = new Uint8Array(arrayBuffer);
resolve(uint8Array) resolve(uint8Array);
} };
reader.onerror = function (error: ProgressEvent<FileReader>) { reader.onerror = function (error: ProgressEvent<FileReader>) {
reject(error) reject(error);
} };
reader.readAsArrayBuffer(file) reader.readAsArrayBuffer(file);
} }
) );
} }
// export async function processFileInChunks(file: File, chunkSize = 1024 * 1024): Promise<Uint8Array> { // export async function processFileInChunks(file: File, chunkSize = 1024 * 1024): Promise<Uint8Array> {

Loading…
Cancel
Save