mirror of
https://github.com/Qortal/qortal-mobile.git
synced 2025-04-24 20:07:52 +00:00
added qortal requests for browser
This commit is contained in:
parent
54b1725585
commit
020366477a
@ -2830,6 +2830,8 @@ async function getChatHeadsDirect() {
|
|||||||
chrome?.runtime?.onMessage.addListener((request, sender, sendResponse) => {
|
chrome?.runtime?.onMessage.addListener((request, sender, sendResponse) => {
|
||||||
if (request) {
|
if (request) {
|
||||||
|
|
||||||
|
console.log('REQUEST MESSAGE', request)
|
||||||
|
|
||||||
switch (request.action) {
|
switch (request.action) {
|
||||||
case "version":
|
case "version":
|
||||||
// Example: respond with the version
|
// Example: respond with the version
|
||||||
|
@ -87,7 +87,11 @@ export const AppInfo = ({ app }) => {
|
|||||||
</AppInfoSnippetRight>
|
</AppInfoSnippetRight>
|
||||||
</AppInfoSnippetContainer>
|
</AppInfoSnippetContainer>
|
||||||
<Spacer height="11px" />
|
<Spacer height="11px" />
|
||||||
<AppDownloadButton sx={{
|
<AppDownloadButton onClick={()=> {
|
||||||
|
executeEvent("addTab", {
|
||||||
|
data: app
|
||||||
|
})
|
||||||
|
}} sx={{
|
||||||
backgroundColor: isInstalled ? '#0091E1' : '#247C0E',
|
backgroundColor: isInstalled ? '#0091E1' : '#247C0E',
|
||||||
width: '100%',
|
width: '100%',
|
||||||
maxWidth: '320px',
|
maxWidth: '320px',
|
||||||
|
@ -88,7 +88,11 @@ export const AppInfoSnippet = ({ app }) => {
|
|||||||
</AppInfoSnippetMiddle>
|
</AppInfoSnippetMiddle>
|
||||||
</AppInfoSnippetLeft>
|
</AppInfoSnippetLeft>
|
||||||
<AppInfoSnippetRight>
|
<AppInfoSnippetRight>
|
||||||
<AppDownloadButton sx={{
|
<AppDownloadButton onClick={()=> {
|
||||||
|
executeEvent("addTab", {
|
||||||
|
data: app
|
||||||
|
})
|
||||||
|
}} sx={{
|
||||||
backgroundColor: isInstalled ? '#0091E1' : '#247C0E',
|
backgroundColor: isInstalled ? '#0091E1' : '#247C0E',
|
||||||
|
|
||||||
}}>
|
}}>
|
||||||
|
@ -21,22 +21,27 @@ import LogoSelected from "../../assets/svgs/LogoSelected.svg";
|
|||||||
|
|
||||||
import { Spacer } from "../../common/Spacer";
|
import { Spacer } from "../../common/Spacer";
|
||||||
import { executeEvent } from "../../utils/events";
|
import { executeEvent } from "../../utils/events";
|
||||||
|
import { useFrame } from "react-frame-component";
|
||||||
|
import { useQortalMessageListener } from "./useQortalMessageListener";
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
export const AppViewer = ({ app }) => {
|
export const AppViewer = ({ app }) => {
|
||||||
const { rootHeight } = useContext(MyContext);
|
const { rootHeight } = useContext(MyContext);
|
||||||
const iframeRef = useRef(null);
|
const iframeRef = useRef(null);
|
||||||
|
const { document, window } = useFrame();
|
||||||
|
useQortalMessageListener(window)
|
||||||
|
|
||||||
const url = useMemo(()=> {
|
const url = useMemo(()=> {
|
||||||
return `${getBaseApiReact()}/render/${app?.service}/${app?.name}${app?.path != null ? app?.path : ''}?theme=dark&identifier=${(app?.identifier != null && app?.identifier != 'null') ? app?.identifier : ''}`
|
return `${getBaseApiReact()}/render/${app?.service}/${app?.name}${app?.path != null ? app?.path : ''}?theme=dark&identifier=${(app?.identifier != null && app?.identifier != 'null') ? app?.identifier : ''}`
|
||||||
}, [app?.service, app?.name, app?.identifier, app?.path])
|
}, [app?.service, app?.name, app?.identifier, app?.path])
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<iframe ref={iframeRef} style={{
|
<iframe ref={iframeRef} style={{
|
||||||
height: `calc(${rootHeight} - 60px - 45px)`,
|
height: `calc(${rootHeight} - 60px - 45px - 20px)`,
|
||||||
border: 'none',
|
border: 'none',
|
||||||
width: '100%'
|
width: '100%'
|
||||||
}} id="browser-iframe" src={url} sandbox="allow-scripts allow-same-origin allow-forms allow-downloads allow-modals" allow="fullscreen">
|
}} id="browser-iframe" src={url} sandbox="allow-scripts allow-same-origin allow-forms allow-downloads allow-modals" allow="fullscreen">
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import React, { useContext, useRef } from 'react'
|
import React, { useContext, useEffect, useRef } from 'react'
|
||||||
import { AppViewer } from './AppViewer'
|
import { AppViewer } from './AppViewer'
|
||||||
import Frame from 'react-frame-component';
|
import Frame from 'react-frame-component';
|
||||||
import { MyContext } from '../../App';
|
import { MyContext } from '../../App';
|
||||||
@ -7,6 +7,7 @@ const AppViewerContainer = ({app, isSelected, hide}) => {
|
|||||||
const { rootHeight } = useContext(MyContext);
|
const { rootHeight } = useContext(MyContext);
|
||||||
const frameRef = useRef(null);
|
const frameRef = useRef(null);
|
||||||
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Frame id={`browser-iframe-${app?.tabId}` } ref={frameRef} head={
|
<Frame id={`browser-iframe-${app?.tabId}` } ref={frameRef} head={
|
||||||
<>
|
<>
|
||||||
|
@ -210,10 +210,13 @@ if (iframe) {
|
|||||||
};
|
};
|
||||||
}, [tabs]);
|
}, [tabs]);
|
||||||
|
|
||||||
if(!show) return null
|
|
||||||
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<AppsParent>
|
<AppsParent sx={{
|
||||||
|
display: !show && 'none'
|
||||||
|
}}>
|
||||||
{mode !== 'viewer' && (
|
{mode !== 'viewer' && (
|
||||||
<Spacer height="30px" />
|
<Spacer height="30px" />
|
||||||
|
|
||||||
|
@ -36,8 +36,8 @@ const TabComponent = ({isSelected, app}) => {
|
|||||||
) }
|
) }
|
||||||
<Avatar
|
<Avatar
|
||||||
sx={{
|
sx={{
|
||||||
height: "31px",
|
height: "28px",
|
||||||
width: "31px",
|
width: "28px",
|
||||||
}}
|
}}
|
||||||
alt={app?.name}
|
alt={app?.name}
|
||||||
src={`${getBaseApiReact()}/arbitrary/THUMBNAIL/${
|
src={`${getBaseApiReact()}/arbitrary/THUMBNAIL/${
|
||||||
@ -46,7 +46,7 @@ const TabComponent = ({isSelected, app}) => {
|
|||||||
>
|
>
|
||||||
<img
|
<img
|
||||||
style={{
|
style={{
|
||||||
width: "31px",
|
width: "28px",
|
||||||
height: "auto",
|
height: "auto",
|
||||||
}}
|
}}
|
||||||
src={LogoSelected}
|
src={LogoSelected}
|
||||||
|
405
src/components/Apps/useQortalMessageListener.tsx
Normal file
405
src/components/Apps/useQortalMessageListener.tsx
Normal file
@ -0,0 +1,405 @@
|
|||||||
|
import { useEffect } from 'react';
|
||||||
|
|
||||||
|
class Semaphore {
|
||||||
|
constructor(count) {
|
||||||
|
this.count = count
|
||||||
|
this.waiting = []
|
||||||
|
}
|
||||||
|
acquire() {
|
||||||
|
return new Promise(resolve => {
|
||||||
|
if (this.count > 0) {
|
||||||
|
this.count--
|
||||||
|
resolve()
|
||||||
|
} else {
|
||||||
|
this.waiting.push(resolve)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
release() {
|
||||||
|
if (this.waiting.length > 0) {
|
||||||
|
const resolve = this.waiting.shift()
|
||||||
|
resolve()
|
||||||
|
} else {
|
||||||
|
this.count++
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
let semaphore = new Semaphore(1)
|
||||||
|
let reader = new FileReader()
|
||||||
|
|
||||||
|
const fileToBase64 = (file) => new Promise(async (resolve, reject) => {
|
||||||
|
if (!reader) {
|
||||||
|
reader = new FileReader()
|
||||||
|
}
|
||||||
|
await semaphore.acquire()
|
||||||
|
reader.readAsDataURL(file)
|
||||||
|
reader.onload = () => {
|
||||||
|
const dataUrl = reader.result
|
||||||
|
if (typeof dataUrl === "string") {
|
||||||
|
const base64String = dataUrl.split(',')[1]
|
||||||
|
reader.onload = null
|
||||||
|
reader.onerror = null
|
||||||
|
resolve(base64String)
|
||||||
|
} else {
|
||||||
|
reader.onload = null
|
||||||
|
reader.onerror = null
|
||||||
|
reject(new Error('Invalid data URL'))
|
||||||
|
}
|
||||||
|
semaphore.release()
|
||||||
|
}
|
||||||
|
reader.onerror = (error) => {
|
||||||
|
reader.onload = null
|
||||||
|
reader.onerror = null
|
||||||
|
reject(error)
|
||||||
|
semaphore.release()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
function openIndexedDB() {
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
const request = indexedDB.open("fileStorageDB", 1);
|
||||||
|
|
||||||
|
request.onupgradeneeded = function (event) {
|
||||||
|
const db = event.target.result;
|
||||||
|
if (!db.objectStoreNames.contains("files")) {
|
||||||
|
db.createObjectStore("files", { keyPath: "id" });
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
request.onsuccess = function (event) {
|
||||||
|
resolve(event.target.result);
|
||||||
|
};
|
||||||
|
|
||||||
|
request.onerror = function () {
|
||||||
|
reject("Error opening IndexedDB");
|
||||||
|
};
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
async function handleGetFileFromIndexedDB(fileId, sendResponse) {
|
||||||
|
try {
|
||||||
|
const db = await openIndexedDB();
|
||||||
|
const transaction = db.transaction(["files"], "readonly");
|
||||||
|
const objectStore = transaction.objectStore("files");
|
||||||
|
|
||||||
|
const getRequest = objectStore.get(fileId);
|
||||||
|
|
||||||
|
getRequest.onsuccess = async function (event) {
|
||||||
|
if (getRequest.result) {
|
||||||
|
const file = getRequest.result.data;
|
||||||
|
|
||||||
|
try {
|
||||||
|
const base64String = await fileToBase64(file);
|
||||||
|
|
||||||
|
// Create a new transaction to delete the file
|
||||||
|
const deleteTransaction = db.transaction(["files"], "readwrite");
|
||||||
|
const deleteObjectStore = deleteTransaction.objectStore("files");
|
||||||
|
const deleteRequest = deleteObjectStore.delete(fileId);
|
||||||
|
|
||||||
|
deleteRequest.onsuccess = function () {
|
||||||
|
console.log(`File with ID ${fileId} has been removed from IndexedDB`);
|
||||||
|
try {
|
||||||
|
sendResponse({ result: base64String });
|
||||||
|
|
||||||
|
} catch (error) {
|
||||||
|
console.log('error', error)
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
deleteRequest.onerror = function () {
|
||||||
|
console.error(`Error deleting file with ID ${fileId} from IndexedDB`);
|
||||||
|
sendResponse({ result: null, error: "Failed to delete file from IndexedDB" });
|
||||||
|
};
|
||||||
|
} catch (error) {
|
||||||
|
console.error("Error converting file to Base64:", error);
|
||||||
|
sendResponse({ result: null, error: "Failed to convert file to Base64" });
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
console.error(`File with ID ${fileId} not found in IndexedDB`);
|
||||||
|
sendResponse({ result: null, error: "File not found in IndexedDB" });
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
getRequest.onerror = function () {
|
||||||
|
console.error(`Error retrieving file with ID ${fileId} from IndexedDB`);
|
||||||
|
sendResponse({ result: null, error: "Error retrieving file from IndexedDB" });
|
||||||
|
};
|
||||||
|
} catch (error) {
|
||||||
|
console.error("Error opening IndexedDB:", error);
|
||||||
|
sendResponse({ result: null, error: "Error opening IndexedDB" });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const UIQortalRequests = [
|
||||||
|
'GET_USER_ACCOUNT', 'DECRYPT_DATA', 'SEND_COIN', 'GET_LIST_ITEMS',
|
||||||
|
'ADD_LIST_ITEMS', 'DELETE_LIST_ITEM', 'VOTE_ON_POLL', 'CREATE_POLL',
|
||||||
|
'SEND_CHAT_MESSAGE', 'JOIN_GROUP', 'DEPLOY_AT', 'GET_USER_WALLET',
|
||||||
|
'GET_WALLET_BALANCE', 'GET_USER_WALLET_INFO', 'GET_CROSSCHAIN_SERVER_INFO',
|
||||||
|
'GET_TX_ACTIVITY_SUMMARY', 'GET_FOREIGN_FEE', 'UPDATE_FOREIGN_FEE',
|
||||||
|
'GET_SERVER_CONNECTION_HISTORY', 'SET_CURRENT_FOREIGN_SERVER',
|
||||||
|
'ADD_FOREIGN_SERVER', 'REMOVE_FOREIGN_SERVER', 'GET_DAY_SUMMARY'
|
||||||
|
];
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
async function retrieveFileFromIndexedDB(fileId) {
|
||||||
|
const db = await openIndexedDB();
|
||||||
|
const transaction = db.transaction(["files"], "readwrite");
|
||||||
|
const objectStore = transaction.objectStore("files");
|
||||||
|
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
const getRequest = objectStore.get(fileId);
|
||||||
|
|
||||||
|
getRequest.onsuccess = function (event) {
|
||||||
|
if (getRequest.result) {
|
||||||
|
// File found, resolve it and delete from IndexedDB
|
||||||
|
const file = getRequest.result.data;
|
||||||
|
objectStore.delete(fileId);
|
||||||
|
resolve(file);
|
||||||
|
} else {
|
||||||
|
reject("File not found in IndexedDB");
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
getRequest.onerror = function () {
|
||||||
|
reject("Error retrieving file from IndexedDB");
|
||||||
|
};
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
async function deleteQortalFilesFromIndexedDB() {
|
||||||
|
try {
|
||||||
|
console.log("Opening IndexedDB for deleting files...");
|
||||||
|
const db = await openIndexedDB();
|
||||||
|
const transaction = db.transaction(["files"], "readwrite");
|
||||||
|
const objectStore = transaction.objectStore("files");
|
||||||
|
|
||||||
|
// Create a request to get all keys
|
||||||
|
const getAllKeysRequest = objectStore.getAllKeys();
|
||||||
|
|
||||||
|
getAllKeysRequest.onsuccess = function (event) {
|
||||||
|
const keys = event.target.result;
|
||||||
|
|
||||||
|
// Iterate through keys to find and delete those containing '_qortalfile'
|
||||||
|
for (let key of keys) {
|
||||||
|
if (key.includes("_qortalfile")) {
|
||||||
|
const deleteRequest = objectStore.delete(key);
|
||||||
|
|
||||||
|
deleteRequest.onsuccess = function () {
|
||||||
|
console.log(`File with key '${key}' has been deleted from IndexedDB`);
|
||||||
|
};
|
||||||
|
|
||||||
|
deleteRequest.onerror = function () {
|
||||||
|
console.error(`Failed to delete file with key '${key}' from IndexedDB`);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
getAllKeysRequest.onerror = function () {
|
||||||
|
console.error("Failed to retrieve keys from IndexedDB");
|
||||||
|
};
|
||||||
|
|
||||||
|
transaction.oncomplete = function () {
|
||||||
|
console.log("Transaction complete for deleting files from IndexedDB");
|
||||||
|
};
|
||||||
|
|
||||||
|
transaction.onerror = function () {
|
||||||
|
console.error("Error occurred during transaction for deleting files");
|
||||||
|
};
|
||||||
|
} catch (error) {
|
||||||
|
console.error("Error opening IndexedDB:", error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const showSaveFilePicker = async (data) => {
|
||||||
|
try {
|
||||||
|
const {filename, mimeType, fileHandleOptions, fileId} = data
|
||||||
|
const blob = await retrieveFileFromIndexedDB(fileId)
|
||||||
|
const fileHandle = await window.showSaveFilePicker({
|
||||||
|
suggestedName: filename,
|
||||||
|
types: [
|
||||||
|
{
|
||||||
|
description: mimeType,
|
||||||
|
...fileHandleOptions
|
||||||
|
}
|
||||||
|
]
|
||||||
|
})
|
||||||
|
const writeFile = async (fileHandle, contents) => {
|
||||||
|
const writable = await fileHandle.createWritable()
|
||||||
|
await writable.write(contents)
|
||||||
|
await writable.close()
|
||||||
|
}
|
||||||
|
writeFile(fileHandle, blob).then(() => console.log("FILE SAVED"))
|
||||||
|
} catch (error) {
|
||||||
|
FileSaver.saveAs(blob, filename)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async function storeFilesInIndexedDB(obj) {
|
||||||
|
// First delete any existing files in IndexedDB with '_qortalfile' in their ID
|
||||||
|
await deleteQortalFilesFromIndexedDB();
|
||||||
|
|
||||||
|
// Open the IndexedDB
|
||||||
|
const db = await openIndexedDB();
|
||||||
|
const transaction = db.transaction(["files"], "readwrite");
|
||||||
|
const objectStore = transaction.objectStore("files");
|
||||||
|
|
||||||
|
// Handle the obj.file if it exists and is a File instance
|
||||||
|
if (obj.file) {
|
||||||
|
const fileId = "objFile_qortalfile";
|
||||||
|
|
||||||
|
// Store the file in IndexedDB
|
||||||
|
const fileData = {
|
||||||
|
id: fileId,
|
||||||
|
data: obj.file,
|
||||||
|
};
|
||||||
|
objectStore.put(fileData);
|
||||||
|
|
||||||
|
// Replace the file object with the file ID in the original object
|
||||||
|
obj.fileId = fileId;
|
||||||
|
delete obj.file;
|
||||||
|
}
|
||||||
|
console.log(obj, obj.blob instanceof Blob, 'blob')
|
||||||
|
if (obj.blob) {
|
||||||
|
const fileId = "objFile_qortalfile";
|
||||||
|
|
||||||
|
// Store the file in IndexedDB
|
||||||
|
const fileData = {
|
||||||
|
id: fileId,
|
||||||
|
data: obj.blob,
|
||||||
|
};
|
||||||
|
objectStore.put(fileData);
|
||||||
|
|
||||||
|
// Replace the file object with the file ID in the original object
|
||||||
|
let blobObj = {
|
||||||
|
type: obj.blob?.type
|
||||||
|
}
|
||||||
|
obj.fileId = fileId;
|
||||||
|
delete obj.blob;
|
||||||
|
obj.blob = blobObj
|
||||||
|
}
|
||||||
|
|
||||||
|
// Iterate through resources to find files and save them to IndexedDB
|
||||||
|
for (let resource of (obj?.resources || [])) {
|
||||||
|
if (resource.file) {
|
||||||
|
const fileId = resource.identifier + "_qortalfile";
|
||||||
|
|
||||||
|
// Store the file in IndexedDB
|
||||||
|
const fileData = {
|
||||||
|
id: fileId,
|
||||||
|
data: resource.file,
|
||||||
|
};
|
||||||
|
objectStore.put(fileData);
|
||||||
|
|
||||||
|
// Replace the file object with the file ID in the original object
|
||||||
|
resource.fileId = fileId;
|
||||||
|
delete resource.file;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set transaction completion handlers
|
||||||
|
transaction.oncomplete = function () {
|
||||||
|
console.log("Files saved successfully to IndexedDB");
|
||||||
|
};
|
||||||
|
|
||||||
|
transaction.onerror = function () {
|
||||||
|
console.error("Error saving files to IndexedDB");
|
||||||
|
};
|
||||||
|
|
||||||
|
return obj; // Updated object with references to stored files
|
||||||
|
}
|
||||||
|
|
||||||
|
export const useQortalMessageListener = (frameWindow) => {
|
||||||
|
useEffect(() => {
|
||||||
|
console.log("Listener added react");
|
||||||
|
|
||||||
|
const listener = async (event) => {
|
||||||
|
event.preventDefault(); // Prevent default behavior
|
||||||
|
event.stopImmediatePropagation(); // Stop other listeners from firing
|
||||||
|
|
||||||
|
if (event?.data?.requestedHandler !== 'UI') return;
|
||||||
|
|
||||||
|
const sendMessageToRuntime = (message, eventPort) => {
|
||||||
|
chrome?.runtime?.sendMessage(message, (response) => {
|
||||||
|
console.log('response', response);
|
||||||
|
if (response.error) {
|
||||||
|
eventPort.postMessage({
|
||||||
|
result: null,
|
||||||
|
error: response,
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
eventPort.postMessage({
|
||||||
|
result: response,
|
||||||
|
error: null,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
// Check if action is included in the predefined list of UI requests
|
||||||
|
if (UIQortalRequests.includes(event.data.action)) {
|
||||||
|
console.log('event?.data', event?.data);
|
||||||
|
sendMessageToRuntime(
|
||||||
|
{ action: event.data.action, type: 'qortalRequest', payload: event.data },
|
||||||
|
event.ports[0]
|
||||||
|
);
|
||||||
|
} else if (
|
||||||
|
event?.data?.action === 'PUBLISH_MULTIPLE_QDN_RESOURCES' ||
|
||||||
|
event?.data?.action === 'PUBLISH_QDN_RESOURCE' ||
|
||||||
|
event?.data?.action === 'ENCRYPT_DATA' || event?.data?.action === 'SAVE_FILE'
|
||||||
|
|
||||||
|
) {
|
||||||
|
console.log('event?.data?', event?.data);
|
||||||
|
let data;
|
||||||
|
try {
|
||||||
|
data = await storeFilesInIndexedDB(event.data);
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Error storing files in IndexedDB:', error);
|
||||||
|
event.ports[0].postMessage({
|
||||||
|
result: null,
|
||||||
|
error: 'Failed to store files in IndexedDB',
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
console.log('data after', data)
|
||||||
|
if (data) {
|
||||||
|
sendMessageToRuntime(
|
||||||
|
{ action: event.data.action, type: 'qortalRequest', payload: data },
|
||||||
|
event.ports[0]
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
event.ports[0].postMessage({
|
||||||
|
result: null,
|
||||||
|
error: 'Failed to prepare data for publishing',
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Add the listener for messages coming from the frameWindow
|
||||||
|
frameWindow.addEventListener('message', listener);
|
||||||
|
|
||||||
|
// Cleanup function to remove the event listener when the component is unmounted
|
||||||
|
return () => {
|
||||||
|
frameWindow.removeEventListener('message', listener);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
}, []); // Empty dependency array to run once when the component mounts
|
||||||
|
|
||||||
|
chrome.runtime?.onMessage.addListener( function (message, sender, sendResponse) {
|
||||||
|
console.log('SHOWING UP')
|
||||||
|
if(message.action === "SHOW_SAVE_FILE_PICKER"){
|
||||||
|
showSaveFilePicker(message?.data)
|
||||||
|
}
|
||||||
|
|
||||||
|
else if (message.action === "getFileFromIndexedDB") {
|
||||||
|
handleGetFileFromIndexedDB(message.fileId, sendResponse);
|
||||||
|
return true; // Keep the message channel open for async response
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
@ -1208,6 +1208,7 @@ export const joinGroup = async (data) => {
|
|||||||
|
|
||||||
export const saveFile = async (data, sender) => {
|
export const saveFile = async (data, sender) => {
|
||||||
try {
|
try {
|
||||||
|
console.log('save file', data)
|
||||||
const requiredFields = ["filename", "fileId"];
|
const requiredFields = ["filename", "fileId"];
|
||||||
const missingFields: string[] = [];
|
const missingFields: string[] = [];
|
||||||
requiredFields.forEach((field) => {
|
requiredFields.forEach((field) => {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user