Browse Source

Metadata for publishes is now a file instead of Base64.

.eslintrc renamed to cjs to fix error when using ESLint

Max file size is now global variable that coverts file size to binary byte format automatically.

Many small EsLint fixes.

Fixed no key warning in MultiplePublishAll.tsx
pull/29/head
Qortal Dev 3 months ago
parent
commit
0001ea250a
  1. 0
      .eslintrc.cjs
  2. 4
      package-lock.json
  3. 30
      src/components/Publish/EditVideo/EditVideo.tsx
  4. 1
      src/components/Publish/MultiplePublish/MultiplePublishAll.tsx
  5. 60
      src/components/Publish/PublishVideo/PublishVideo.tsx
  6. 2
      src/components/common/ContentButtons/LikeAndDislike-functions.ts
  7. 3
      src/constants/Misc.ts
  8. 17
      src/hooks/useFetchVideos.tsx
  9. 8
      src/utils/toBase64.ts

0
.eslintrc.js → .eslintrc.cjs

4
package-lock.json generated

@ -1,12 +1,12 @@
{
"name": "qtube",
"version": "0.0.0",
"version": "2.0.0",
"lockfileVersion": 2,
"requires": true,
"packages": {
"": {
"name": "qtube",
"version": "0.0.0",
"version": "2.0.0",
"dependencies": {
"@emotion/react": "^11.10.6",
"@emotion/styled": "^11.10.6",

30
src/components/Publish/EditVideo/EditVideo.tsx

@ -35,7 +35,7 @@ import AddBoxIcon from "@mui/icons-material/AddBox";
import { useDropzone } from "react-dropzone";
import { setNotification } from "../../../state/features/notificationsSlice.ts";
import { objectToBase64, uint8ArrayToBase64 } from "../../../utils/toBase64.ts";
import { objectToBase64, objectToFile, uint8ArrayToBase64 } from "../../../utils/toBase64.ts";
import { RootState } from "../../../state/store.ts";
import {
upsertVideosBeginning,
@ -53,7 +53,7 @@ import { extractTextFromHTML } from "../../common/TextEditor/utils.ts";
import { toBase64 } from "../PublishVideo/PublishVideo.tsx";
import { FrameExtractor } from "../../common/FrameExtractor/FrameExtractor.tsx";
import { QTUBE_VIDEO_BASE } from "../../../constants/Identifiers.ts";
import { titleFormatter } from "../../../constants/Misc.ts";
import { maxSize, titleFormatter, videoMaxSize } from "../../../constants/Misc.ts";
const uid = new ShortUniqueId();
const shortuid = new ShortUniqueId({ length: 5 });
@ -103,7 +103,7 @@ export const EditVideo = () => {
"video/*": [],
},
maxFiles: 1,
maxSize: 419430400, // 400 MB in bytes
maxSize,
onDrop: (acceptedFiles, rejectedFiles) => {
const firstFile = acceptedFiles[0];
@ -114,7 +114,7 @@ export const EditVideo = () => {
rejectedFiles.forEach(({ file, errors }) => {
errors.forEach(error => {
if (error.code === "file-too-large") {
errorString = "File must be under 400mb";
errorString = `File must be under ${videoMaxSize}MB`;
}
console.log(`Error with file ${file.name}: ${error.message}`);
});
@ -248,7 +248,7 @@ export const EditVideo = () => {
);
return;
}
let listOfPublishes = [];
const listOfPublishes = [];
const category = selectedCategoryVideos.id;
const subcategory = selectedSubCategoryVideos?.id || "";
@ -259,14 +259,14 @@ export const EditVideo = () => {
fileExtension = fileExtensionSplit?.pop() || "mp4";
}
let filename = title.slice(0, 15);
const filename = title.slice(0, 15);
// Step 1: Replace all white spaces with underscores
// Replace all forms of whitespace (including non-standard ones) with underscores
let stringWithUnderscores = filename.replace(/[\s\uFEFF\xA0]+/g, "_");
const stringWithUnderscores = filename.replace(/[\s\uFEFF\xA0]+/g, "_");
// Remove all non-alphanumeric characters (except underscores)
let alphanumericString = stringWithUnderscores.replace(
const alphanumericString = stringWithUnderscores.replace(
/[^a-zA-Z0-9_]/g,
""
);
@ -287,17 +287,17 @@ export const EditVideo = () => {
filename: `${alphanumericString.trim()}.${fileExtension}`,
};
let metadescription =
const metadescription =
`**category:${category};subcategory:${subcategory};code:${editVideoProperties.code}**` +
description.slice(0, 150);
const crowdfundObjectToBase64 = await objectToBase64(videoObject);
const videoObjectToFile = objectToFile(videoObject);
// Description is obtained from raw data
const requestBodyJson: any = {
action: "PUBLISH_QDN_RESOURCE",
name: username,
service: "DOCUMENT",
data64: crowdfundObjectToBase64,
file: videoObjectToFile,
title: title.slice(0, 50),
description: metadescription,
identifier: editVideoProperties.id,
@ -318,7 +318,7 @@ export const EditVideo = () => {
tag1: QTUBE_VIDEO_BASE,
filename: `${alphanumericString.trim()}.${fileExtension}`,
};
console.log('edit file is: ', file)
listOfPublishes.push(requestBodyVideo);
}
@ -377,7 +377,7 @@ export const EditVideo = () => {
const onFramesExtracted = async imgs => {
try {
let imagesExtracts = [];
const imagesExtracts = [];
for (const img of imgs) {
try {
@ -395,7 +395,7 @@ export const EditVideo = () => {
compressedFile = file;
resolve();
},
error(err) {},
error(error) {console.log(error)},
});
});
if (!compressedFile) continue;
@ -407,7 +407,7 @@ export const EditVideo = () => {
}
setImageExtracts(imagesExtracts);
} catch (error) {}
} catch (error) {console.log(error)}
};
return (

1
src/components/Publish/MultiplePublish/MultiplePublishAll.tsx

@ -125,6 +125,7 @@ export const MultiplePublish = ({
);
return (
<Box
key={publish?.identifier}
sx={{
display: "flex",
gap: "20px",

60
src/components/Publish/PublishVideo/PublishVideo.tsx

@ -38,7 +38,7 @@ import { useDropzone } from "react-dropzone";
import AddIcon from "@mui/icons-material/Add";
import { setNotification } from "../../../state/features/notificationsSlice.ts";
import { objectToBase64, uint8ArrayToBase64 } from "../../../utils/toBase64.ts";
import { objectToBase64, objectToFile, uint8ArrayToBase64 } from "../../../utils/toBase64.ts";
import { RootState } from "../../../state/store.ts";
import {
upsertVideosBeginning,
@ -65,7 +65,7 @@ import {
QTUBE_PLAYLIST_BASE,
QTUBE_VIDEO_BASE,
} from "../../../constants/Identifiers.ts";
import { titleFormatter } from "../../../constants/Misc.ts";
import { maxSize, titleFormatter, videoMaxSize } from "../../../constants/Misc.ts";
import { getFileName } from "../../../utils/stringFunctions.ts";
export const toBase64 = (file: File): Promise<string | ArrayBuffer | null> =>
@ -137,13 +137,16 @@ export const PublishVideo = ({ editId, editContent }: NewCrowdfundProps) => {
const [isCheckDescriptionIsTitle, setIsCheckDescriptionIsTitle] =
useState(false);
const [imageExtracts, setImageExtracts] = useState<any>({});
const { getRootProps, getInputProps } = useDropzone({
accept: {
"video/*": [],
},
maxSize: 419430400, // 400 MB in bytes
maxSize,
onDrop: (acceptedFiles, rejectedFiles) => {
const formatArray = acceptedFiles.map(item => {
console.log('file: ', item)
let filteredTitle = "";
if (isCheckTitleByFile) {
@ -164,7 +167,7 @@ export const PublishVideo = ({ editId, editContent }: NewCrowdfundProps) => {
rejectedFiles.forEach(({ file, errors }) => {
errors.forEach(error => {
if (error.code === "file-too-large") {
errorString = "File must be under 400mb";
errorString = `File must be under ${videoMaxSize}MB`;
}
console.log(`Error with file ${file.name}: ${error.message}`);
});
@ -180,10 +183,10 @@ export const PublishVideo = ({ editId, editContent }: NewCrowdfundProps) => {
},
});
useEffect(() => {
if (editContent) {
}
}, [editContent]);
// useEffect(() => {
// if (editContent) {
// }
// }, [editContent]);
const onClose = () => {
setIsOpen(false);
@ -238,7 +241,7 @@ export const PublishVideo = ({ editId, editContent }: NewCrowdfundProps) => {
return;
}
let listOfPublishes = [];
const listOfPublishes = [];
for (let i = 0; i < files.length; i++) {
const publish = files[i];
@ -274,18 +277,18 @@ export const PublishVideo = ({ editId, editContent }: NewCrowdfundProps) => {
fileExtension = fileExtensionSplit?.pop() || "mp4";
}
let filename = title.slice(0, 15);
const filename = title.slice(0, 15);
// Step 1: Replace all white spaces with underscores
// Replace all forms of whitespace (including non-standard ones) with underscores
let stringWithUnderscores = filename.replace(/[\s\uFEFF\xA0]+/g, "_");
const stringWithUnderscores = filename.replace(/[\s\uFEFF\xA0]+/g, "_");
// Remove all non-alphanumeric characters (except underscores)
let alphanumericString = stringWithUnderscores.replace(
const alphanumericString = stringWithUnderscores.replace(
/[^a-zA-Z0-9_]/g,
""
);
console.log('file size: ', file.size)
const videoObject: any = {
title,
version: 1,
@ -306,17 +309,16 @@ export const PublishVideo = ({ editId, editContent }: NewCrowdfundProps) => {
filename: `${alphanumericString.trim()}.${fileExtension}`,
};
let metadescription =
const metadescription =
`**category:${category};subcategory:${subcategory};code:${code}**` +
fullDescription.slice(0, 150);
const crowdfundObjectToBase64 = await objectToBase64(videoObject);
// Description is obtained from raw data
const requestBodyJson: any = {
action: "PUBLISH_QDN_RESOURCE",
name: name,
service: "DOCUMENT",
data64: crowdfundObjectToBase64,
file: objectToFile(videoObject),
title: title.slice(0, 50),
description: metadescription,
identifier: identifier + "_metadata",
@ -392,17 +394,17 @@ export const PublishVideo = ({ editId, editContent }: NewCrowdfundProps) => {
.slice(0, 10)
.join("");
let metadescription =
const metadescription =
`**category:${category};subcategory:${subcategory};${codes}**` +
stringDescription.slice(0, 120);
const crowdfundObjectToBase64 = await objectToBase64(playlistObject);
// Description is obtained from raw data
const requestBodyJson: any = {
action: "PUBLISH_QDN_RESOURCE",
name: name,
service: "PLAYLIST",
data64: crowdfundObjectToBase64,
file: objectToFile(playlistObject),
title: title.slice(0, 50),
description: metadescription,
identifier: identifier + "_metadata",
@ -447,17 +449,17 @@ export const PublishVideo = ({ editId, editContent }: NewCrowdfundProps) => {
.slice(0, 10)
.join("");
let metadescription =
const metadescription =
`**category:${playlistObject.category};subcategory:${playlistObject.subcategory};${codes}**` +
playlistObject.description.slice(0, 120);
const crowdfundObjectToBase64 = await objectToBase64(playlistObject);
// Description is obtained from raw data
const requestBodyJson: any = {
action: "PUBLISH_QDN_RESOURCE",
name: name,
service: "PLAYLIST",
data64: crowdfundObjectToBase64,
file: objectToFile( playlistObject),
title: playlistObject.title.slice(0, 50),
description: metadescription,
identifier: selectExistingPlaylist.identifier,
@ -480,24 +482,24 @@ export const PublishVideo = ({ editId, editContent }: NewCrowdfundProps) => {
let notificationObj: any = null;
if (typeof error === "string") {
notificationObj = {
msg: error || "Failed to publish crowdfund",
msg: error || "Failed to publish video",
alertType: "error",
};
} else if (typeof error?.error === "string") {
notificationObj = {
msg: error?.error || "Failed to publish crowdfund",
msg: error?.error || "Failed to publish video",
alertType: "error",
};
} else {
notificationObj = {
msg: error?.message || "Failed to publish crowdfund",
msg: error?.message || "Failed to publish video",
alertType: "error",
};
}
if (!notificationObj) return;
dispatch(setNotification(notificationObj));
throw new Error("Failed to publish crowdfund");
throw new Error("Failed to publish video");
}
}
@ -578,7 +580,7 @@ export const PublishVideo = ({ editId, editContent }: NewCrowdfundProps) => {
const onFramesExtracted = async (imgs, index) => {
try {
let imagesExtracts = [];
const imagesExtracts = [];
for (const img of imgs) {
try {
@ -596,7 +598,7 @@ export const PublishVideo = ({ editId, editContent }: NewCrowdfundProps) => {
compressedFile = file;
resolve();
},
error(err) {},
error(error) {console.log(error)},
});
});
if (!compressedFile) continue;
@ -613,7 +615,7 @@ export const PublishVideo = ({ editId, editContent }: NewCrowdfundProps) => {
[index]: imagesExtracts,
};
});
} catch (error) {}
} catch (error) {console.log(error)}
};
return (

2
src/components/common/ContentButtons/LikeAndDislike-functions.ts

@ -14,7 +14,7 @@ export const getCurrentLikeType = async (
});
return response?.likeType;
} catch (e) {
console.log("liketype error: ", e);
// console.log("liketype error: ", e);
return NEUTRAL;
}
};

3
src/constants/Misc.ts

@ -1,3 +1,6 @@
export const minPriceSuperlike = 1;
export const titleFormatter = /[^a-zA-Z0-9\s-_!?()&'",.;:|—~@#$%^*+=<>]/g;
export const titleFormatterOnSave = /[^a-zA-Z0-9\s-_!()&',.;—~@#$%^+=]/g;
export const videoMaxSize = 400; // Size in Megabytes (decimal)
export const maxSize = videoMaxSize *1024*1024

17
src/hooks/useFetchVideos.tsx

@ -72,7 +72,7 @@ export const useFetchVideos = () => {
const getAvatar = React.useCallback(async (author: string) => {
try {
let url = await qortalRequest({
const url = await qortalRequest({
action: "GET_QDN_RESOURCE_URL",
name: author,
service: "THUMBNAIL",
@ -85,14 +85,14 @@ export const useFetchVideos = () => {
url,
})
);
} catch (error) {}
} catch (error) {console.log(error)}
}, []);
const getVideo = async (
user: string,
videoId: string,
content: any,
retries: number = 0
retries = 0
) => {
try {
const res = await fetchAndEvaluateVideos({
@ -183,7 +183,7 @@ export const useFetchVideos = () => {
}
}
}
} catch (error) {
} catch (error) {console.log(error)
} finally {
dispatch(setIsLoadingGlobal(false));
}
@ -311,7 +311,6 @@ export const useFetchVideos = () => {
}
} catch (error) {
console.log({ error });
} finally {
}
},
[videos, hashMapVideos]
@ -370,8 +369,7 @@ export const useFetchVideos = () => {
}
}
}
} catch (error) {
} finally {
} catch (error) {console.log(error)
}
},
[filteredVideos, hashMapVideos]
@ -411,12 +409,12 @@ export const useFetchVideos = () => {
const newArray = responseData.slice(0, findVideo);
dispatch(setCountNewVideos(newArray.length));
return;
} catch (error) {}
} catch (error) {console.log(error)}
}, [videos]);
const getVideosCount = React.useCallback(async () => {
try {
let url = `/arbitrary/resources/search?mode=ALL&includemetadata=false&limit=0&service=DOCUMENT&identifier=${QTUBE_VIDEO_BASE}`;
const url = `/arbitrary/resources/search?mode=ALL&includemetadata=false&limit=0&service=DOCUMENT&identifier=${QTUBE_VIDEO_BASE}`;
const response = await fetch(url, {
method: "GET",
@ -436,7 +434,6 @@ export const useFetchVideos = () => {
dispatch(setVideosPerNamePublished(videosPerNamePublished));
} catch (error) {
console.log({ error });
} finally {
}
}, []);

8
src/utils/toBase64.ts

@ -46,6 +46,14 @@ export function objectToBase64(obj: any) {
})
}
export function objectToFile(obj: any) {
// Step 1: Convert the object to a JSON string
const jsonString = JSON.stringify(obj)
// Step 2: Create a Blob from the JSON string
const blob = new Blob([jsonString], { type: 'application/json' })
return blob
}
export function objectToUint8Array(obj: any) {
// Convert the object to a JSON string
const jsonString = JSON.stringify(obj)

Loading…
Cancel
Save