mirror of
https://github.com/Qortal/chrome-extension.git
synced 2025-02-16 04:05:50 +00:00
finished apps feature for mobile
This commit is contained in:
parent
44c6b5ad32
commit
6b3a1f51ba
@ -576,7 +576,6 @@ const showSaveFilePicker = async (data) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
chrome.runtime?.onMessage.addListener( function (message, sender, sendResponse) {
|
chrome.runtime?.onMessage.addListener( function (message, sender, sendResponse) {
|
||||||
console.log('message', message)
|
|
||||||
if (message.type === "LOGOUT") {
|
if (message.type === "LOGOUT") {
|
||||||
// Notify the web page
|
// Notify the web page
|
||||||
window.postMessage(
|
window.postMessage(
|
||||||
@ -812,7 +811,6 @@ if (!window.hasAddedQortalListener) {
|
|||||||
|
|
||||||
const sendMessageToRuntime = (message, eventPort) => {
|
const sendMessageToRuntime = (message, eventPort) => {
|
||||||
chrome?.runtime?.sendMessage(message, (response) => {
|
chrome?.runtime?.sendMessage(message, (response) => {
|
||||||
console.log('response', response);
|
|
||||||
if (response.error) {
|
if (response.error) {
|
||||||
eventPort.postMessage({
|
eventPort.postMessage({
|
||||||
result: null,
|
result: null,
|
||||||
@ -829,13 +827,11 @@ if (!window.hasAddedQortalListener) {
|
|||||||
|
|
||||||
// Check if action is included in the predefined list of UI requests
|
// Check if action is included in the predefined list of UI requests
|
||||||
if (UIQortalRequests.includes(event.data.action)) {
|
if (UIQortalRequests.includes(event.data.action)) {
|
||||||
console.log('event?.data', event?.data);
|
|
||||||
sendMessageToRuntime(
|
sendMessageToRuntime(
|
||||||
{ action: event.data.action, type: 'qortalRequest', payload: event.data },
|
{ action: event.data.action, type: 'qortalRequest', payload: event.data },
|
||||||
event.ports[0]
|
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') {
|
} 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;
|
let data;
|
||||||
try {
|
try {
|
||||||
data = await storeFilesInIndexedDB(event.data);
|
data = await storeFilesInIndexedDB(event.data);
|
||||||
|
291
src/App.tsx
291
src/App.tsx
@ -100,8 +100,9 @@ import { Settings } from "./components/Group/Settings";
|
|||||||
import { MainAvatar } from "./components/MainAvatar";
|
import { MainAvatar } from "./components/MainAvatar";
|
||||||
import { useRetrieveDataLocalStorage } from "./useRetrieveDataLocalStorage";
|
import { useRetrieveDataLocalStorage } from "./useRetrieveDataLocalStorage";
|
||||||
import { useQortalGetSaveSettings } from "./useQortalGetSaveSettings";
|
import { useQortalGetSaveSettings } from "./useQortalGetSaveSettings";
|
||||||
import { useResetRecoilState } from "recoil";
|
import { useRecoilState, useResetRecoilState } from "recoil";
|
||||||
import { canSaveSettingToQdnAtom, oldPinnedAppsAtom, settingsLocalLastUpdatedAtom, settingsQDNLastUpdatedAtom, sortablePinnedAppsAtom } from "./atoms/global";
|
import { canSaveSettingToQdnAtom, fullScreenAtom, hasSettingsChangedAtom, oldPinnedAppsAtom, settingsLocalLastUpdatedAtom, settingsQDNLastUpdatedAtom, sortablePinnedAppsAtom } from "./atoms/global";
|
||||||
|
import { useAppFullScreen } from "./useAppFullscreen";
|
||||||
|
|
||||||
type extStates =
|
type extStates =
|
||||||
| "not-authenticated"
|
| "not-authenticated"
|
||||||
@ -297,10 +298,12 @@ function App() {
|
|||||||
const [txList, setTxList] = useState([]);
|
const [txList, setTxList] = useState([]);
|
||||||
const [memberGroups, setMemberGroups] = useState([]);
|
const [memberGroups, setMemberGroups] = useState([]);
|
||||||
const [isFocused, setIsFocused] = useState(true);
|
const [isFocused, setIsFocused] = useState(true);
|
||||||
|
const [hasSettingsChanged, setHasSettingsChanged] = useRecoilState(hasSettingsChangedAtom)
|
||||||
const holdRefExtState = useRef<extStates>("not-authenticated");
|
const holdRefExtState = useRef<extStates>("not-authenticated");
|
||||||
const isFocusedRef = useRef<boolean>(true);
|
const isFocusedRef = useRef<boolean>(true);
|
||||||
const { isShow, onCancel, onOk, show, message } = useModal();
|
const { isShow, onCancel, onOk, show, message } = useModal();
|
||||||
|
const { isShow: isShowUnsavedChanges, onCancel: onCancelUnsavedChanges, onOk: onOkUnsavedChanges, show: showUnsavedChanges, message: messageUnsavedChanges } = useModal();
|
||||||
|
|
||||||
const {
|
const {
|
||||||
onCancel: onCancelQortalRequest,
|
onCancel: onCancelQortalRequest,
|
||||||
onOk: onOkQortalRequest,
|
onOk: onOkQortalRequest,
|
||||||
@ -308,6 +311,13 @@ function App() {
|
|||||||
isShow: isShowQortalRequest,
|
isShow: isShowQortalRequest,
|
||||||
message: messageQortalRequest,
|
message: messageQortalRequest,
|
||||||
} = useModal();
|
} = useModal();
|
||||||
|
const {
|
||||||
|
onCancel: onCancelQortalRequestExtension,
|
||||||
|
onOk: onOkQortalRequestExtension,
|
||||||
|
show: showQortalRequestExtension,
|
||||||
|
isShow: isShowQortalRequestExtension,
|
||||||
|
message: messageQortalRequestExtension,
|
||||||
|
} = useModal();
|
||||||
|
|
||||||
const [openRegisterName, setOpenRegisterName] = useState(false);
|
const [openRegisterName, setOpenRegisterName] = useState(false);
|
||||||
const registerNamePopoverRef = useRef(null);
|
const registerNamePopoverRef = useRef(null);
|
||||||
@ -328,7 +338,24 @@ function App() {
|
|||||||
const qortalRequestCheckbox1Ref = useRef(null);
|
const qortalRequestCheckbox1Ref = useRef(null);
|
||||||
useRetrieveDataLocalStorage()
|
useRetrieveDataLocalStorage()
|
||||||
useQortalGetSaveSettings(userInfo?.name)
|
useQortalGetSaveSettings(userInfo?.name)
|
||||||
|
const [fullScreen, setFullScreen] = useRecoilState(fullScreenAtom);
|
||||||
|
|
||||||
|
const { toggleFullScreen } = useAppFullScreen(setFullScreen);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
// Attach a global event listener for double-click
|
||||||
|
const handleDoubleClick = () => {
|
||||||
|
toggleFullScreen();
|
||||||
|
};
|
||||||
|
|
||||||
|
// Add the event listener to the root HTML document
|
||||||
|
document.documentElement.addEventListener('dblclick', handleDoubleClick);
|
||||||
|
|
||||||
|
// Clean up the event listener on unmount
|
||||||
|
return () => {
|
||||||
|
document.documentElement.removeEventListener('dblclick', handleDoubleClick);
|
||||||
|
};
|
||||||
|
}, [toggleFullScreen]);
|
||||||
//resets for recoil
|
//resets for recoil
|
||||||
const resetAtomSortablePinnedAppsAtom = useResetRecoilState(sortablePinnedAppsAtom);
|
const resetAtomSortablePinnedAppsAtom = useResetRecoilState(sortablePinnedAppsAtom);
|
||||||
const resetAtomCanSaveSettingToQdnAtom = useResetRecoilState(canSaveSettingToQdnAtom);
|
const resetAtomCanSaveSettingToQdnAtom = useResetRecoilState(canSaveSettingToQdnAtom);
|
||||||
@ -588,15 +615,10 @@ function App() {
|
|||||||
const qortalRequestPermisson = async (message, sender, sendResponse) => {
|
const qortalRequestPermisson = async (message, sender, sendResponse) => {
|
||||||
if (message.action === "QORTAL_REQUEST_PERMISSION" && !isMainWindow) {
|
if (message.action === "QORTAL_REQUEST_PERMISSION" && !isMainWindow) {
|
||||||
try {
|
try {
|
||||||
console.log("payloadbefore", message.payload);
|
|
||||||
|
|
||||||
await showQortalRequest(message?.payload);
|
await showQortalRequest(message?.payload);
|
||||||
console.log("payload", message.payload);
|
|
||||||
if (message?.payload?.checkbox1) {
|
if (message?.payload?.checkbox1) {
|
||||||
console.log(
|
|
||||||
"qortalRequestCheckbox1Ref.current",
|
|
||||||
qortalRequestCheckbox1Ref.current
|
|
||||||
);
|
|
||||||
sendResponse({
|
sendResponse({
|
||||||
accepted: true,
|
accepted: true,
|
||||||
checkbox1: qortalRequestCheckbox1Ref.current,
|
checkbox1: qortalRequestCheckbox1Ref.current,
|
||||||
@ -605,7 +627,6 @@ function App() {
|
|||||||
}
|
}
|
||||||
sendResponse({ accepted: true });
|
sendResponse({ accepted: true });
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.log("error", error);
|
|
||||||
sendResponse({ accepted: false });
|
sendResponse({ accepted: false });
|
||||||
} finally {
|
} finally {
|
||||||
window.close();
|
window.close();
|
||||||
@ -615,13 +636,11 @@ function App() {
|
|||||||
const qortalRequestPermissonFromExtension = async (message, sender, sendResponse) => {
|
const qortalRequestPermissonFromExtension = async (message, sender, sendResponse) => {
|
||||||
if (message.action === "QORTAL_REQUEST_PERMISSION" && isMainWindow) {
|
if (message.action === "QORTAL_REQUEST_PERMISSION" && isMainWindow) {
|
||||||
try {
|
try {
|
||||||
console.log("payloadbefore", message.payload);
|
|
||||||
|
|
||||||
await show('do you accept?');
|
await showQortalRequestExtension(message?.payload);
|
||||||
|
|
||||||
sendResponse({ accepted: true });
|
sendResponse({ accepted: true });
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.log("error", error);
|
|
||||||
sendResponse({ accepted: false });
|
sendResponse({ accepted: false });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -695,7 +714,6 @@ function App() {
|
|||||||
// Call the permission request handler for "QORTAL_REQUEST_PERMISSION"
|
// Call the permission request handler for "QORTAL_REQUEST_PERMISSION"
|
||||||
qortalRequestPermisson(message, sender, sendResponse);
|
qortalRequestPermisson(message, sender, sendResponse);
|
||||||
if (message.action === "QORTAL_REQUEST_PERMISSION" && !isMainWindow) {
|
if (message.action === "QORTAL_REQUEST_PERMISSION" && !isMainWindow) {
|
||||||
console.log("isMainWindow", isMainWindow, window?.location?.href);
|
|
||||||
return true; // Return true to indicate an async response is coming
|
return true; // Return true to indicate an async response is coming
|
||||||
}
|
}
|
||||||
if (message.action === "QORTAL_REQUEST_PERMISSION" && isMainWindow && message?.isFromExtension) {
|
if (message.action === "QORTAL_REQUEST_PERMISSION" && isMainWindow && message?.isFromExtension) {
|
||||||
@ -994,8 +1012,11 @@ function App() {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const logoutFunc = () => {
|
const logoutFunc = async () => {
|
||||||
try {
|
try {
|
||||||
|
if(hasSettingsChanged){
|
||||||
|
await showUnsavedChanges({message: 'Your settings have changed. If you logout you will lose your changes. Click on the save button in the header to keep your changed settings.'})
|
||||||
|
}
|
||||||
chrome?.runtime?.sendMessage({ action: "logout" }, (response) => {
|
chrome?.runtime?.sendMessage({ action: "logout" }, (response) => {
|
||||||
if (response) {
|
if (response) {
|
||||||
resetAllStates();
|
resetAllStates();
|
||||||
@ -2762,6 +2783,246 @@ function App() {
|
|||||||
</Button>
|
</Button>
|
||||||
</DialogActions>
|
</DialogActions>
|
||||||
</Dialog>
|
</Dialog>
|
||||||
|
)}
|
||||||
|
{isShowUnsavedChanges && (
|
||||||
|
<Dialog
|
||||||
|
open={isShowUnsavedChanges}
|
||||||
|
aria-labelledby="alert-dialog-title"
|
||||||
|
aria-describedby="alert-dialog-description"
|
||||||
|
>
|
||||||
|
<DialogTitle id="alert-dialog-title">{"Warning"}</DialogTitle>
|
||||||
|
<DialogContent>
|
||||||
|
<DialogContentText id="alert-dialog-description">
|
||||||
|
{messageUnsavedChanges.message}
|
||||||
|
</DialogContentText>
|
||||||
|
</DialogContent>
|
||||||
|
<DialogActions>
|
||||||
|
<Button variant="contained" onClick={onCancelUnsavedChanges}>
|
||||||
|
Cancel
|
||||||
|
</Button>
|
||||||
|
<Button variant="contained" onClick={onOkUnsavedChanges} autoFocus>
|
||||||
|
Continue to Logout
|
||||||
|
</Button>
|
||||||
|
</DialogActions>
|
||||||
|
</Dialog>
|
||||||
|
)}
|
||||||
|
{isShowQortalRequestExtension && isMainWindow && (
|
||||||
|
<Dialog
|
||||||
|
open={isShowQortalRequestExtension}
|
||||||
|
aria-labelledby="alert-dialog-title"
|
||||||
|
aria-describedby="alert-dialog-description"
|
||||||
|
>
|
||||||
|
<CountdownCircleTimer
|
||||||
|
isPlaying
|
||||||
|
duration={30}
|
||||||
|
colors={["#004777", "#F7B801", "#A30000", "#A30000"]}
|
||||||
|
colorsTime={[7, 5, 2, 0]}
|
||||||
|
onComplete={() => {
|
||||||
|
onCancelQortalRequestExtension()
|
||||||
|
}}
|
||||||
|
size={50}
|
||||||
|
strokeWidth={5}
|
||||||
|
>
|
||||||
|
{({ remainingTime }) => <TextP>{remainingTime}</TextP>}
|
||||||
|
</CountdownCircleTimer>
|
||||||
|
<Box sx={{
|
||||||
|
display: 'flex',
|
||||||
|
padding: '20px',
|
||||||
|
flexDirection: 'column',
|
||||||
|
alignItems: 'center',
|
||||||
|
justifyContent: 'flex-start',
|
||||||
|
minHeight: '400px',
|
||||||
|
maxHeight: '90vh',
|
||||||
|
overflow: 'auto'
|
||||||
|
}}>
|
||||||
|
<Box
|
||||||
|
sx={{
|
||||||
|
display: "flex",
|
||||||
|
justifyContent: "center",
|
||||||
|
width: "100%",
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<TextP
|
||||||
|
sx={{
|
||||||
|
lineHeight: 1.2,
|
||||||
|
maxWidth: "90%",
|
||||||
|
textAlign: "center",
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{messageQortalRequestExtension?.text1}
|
||||||
|
</TextP>
|
||||||
|
</Box>
|
||||||
|
{messageQortalRequestExtension?.text2 && (
|
||||||
|
<>
|
||||||
|
<Spacer height="10px" />
|
||||||
|
<Box
|
||||||
|
sx={{
|
||||||
|
display: "flex",
|
||||||
|
justifyContent: "flex-start",
|
||||||
|
width: "90%",
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<TextP
|
||||||
|
sx={{
|
||||||
|
lineHeight: 1.2,
|
||||||
|
fontSize: "16px",
|
||||||
|
fontWeight: "normal",
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{messageQortalRequestExtension?.text2}
|
||||||
|
</TextP>
|
||||||
|
</Box>
|
||||||
|
<Spacer height="15px" />
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
{messageQortalRequestExtension?.text3 && (
|
||||||
|
<>
|
||||||
|
<Box
|
||||||
|
sx={{
|
||||||
|
display: "flex",
|
||||||
|
justifyContent: "flex-start",
|
||||||
|
width: "90%",
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<TextP
|
||||||
|
sx={{
|
||||||
|
lineHeight: 1.2,
|
||||||
|
fontSize: "16px",
|
||||||
|
fontWeight: "normal",
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{messageQortalRequestExtension?.text3}
|
||||||
|
</TextP>
|
||||||
|
<Spacer height="15px" />
|
||||||
|
</Box>
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{messageQortalRequestExtension?.text4 && (
|
||||||
|
<Box
|
||||||
|
sx={{
|
||||||
|
display: "flex",
|
||||||
|
justifyContent: "flex-start",
|
||||||
|
width: "90%",
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<TextP
|
||||||
|
sx={{
|
||||||
|
lineHeight: 1.2,
|
||||||
|
fontSize: "16px",
|
||||||
|
fontWeight: "normal",
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{messageQortalRequestExtension?.text4}
|
||||||
|
</TextP>
|
||||||
|
</Box>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{messageQortalRequestExtension?.html && (
|
||||||
|
<div
|
||||||
|
dangerouslySetInnerHTML={{ __html: messageQortalRequestExtension?.html }}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
<Spacer height="15px" />
|
||||||
|
|
||||||
|
<TextP
|
||||||
|
sx={{
|
||||||
|
textAlign: "center",
|
||||||
|
lineHeight: 1.2,
|
||||||
|
fontSize: "16px",
|
||||||
|
fontWeight: 700,
|
||||||
|
maxWidth: "90%",
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{messageQortalRequestExtension?.highlightedText}
|
||||||
|
</TextP>
|
||||||
|
|
||||||
|
{messageQortalRequestExtension?.fee && (
|
||||||
|
<>
|
||||||
|
<Spacer height="15px" />
|
||||||
|
|
||||||
|
<TextP
|
||||||
|
sx={{
|
||||||
|
textAlign: "center",
|
||||||
|
lineHeight: 1.2,
|
||||||
|
fontSize: "16px",
|
||||||
|
fontWeight: "normal",
|
||||||
|
maxWidth: "90%",
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{'Fee: '}{messageQortalRequestExtension?.fee}{' QORT'}
|
||||||
|
</TextP>
|
||||||
|
<Spacer height="15px" />
|
||||||
|
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
{messageQortalRequestExtension?.checkbox1 && (
|
||||||
|
<Box
|
||||||
|
sx={{
|
||||||
|
display: "flex",
|
||||||
|
gap: "10px",
|
||||||
|
alignItems: "center",
|
||||||
|
justifyContent: "center",
|
||||||
|
width: "90%",
|
||||||
|
marginTop: "20px",
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Checkbox
|
||||||
|
onChange={(e) => {
|
||||||
|
qortalRequestCheckbox1Ref.current = e.target.checked;
|
||||||
|
}}
|
||||||
|
edge="start"
|
||||||
|
tabIndex={-1}
|
||||||
|
disableRipple
|
||||||
|
defaultChecked={messageQortalRequestExtension?.checkbox1?.value}
|
||||||
|
sx={{
|
||||||
|
"&.Mui-checked": {
|
||||||
|
color: "white", // Customize the color when checked
|
||||||
|
},
|
||||||
|
"& .MuiSvgIcon-root": {
|
||||||
|
color: "white",
|
||||||
|
},
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
|
||||||
|
<Typography
|
||||||
|
sx={{
|
||||||
|
fontSize: "14px",
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{messageQortalRequestExtension?.checkbox1?.label}
|
||||||
|
</Typography>
|
||||||
|
</Box>
|
||||||
|
)}
|
||||||
|
|
||||||
|
<Spacer height="29px" />
|
||||||
|
<Box
|
||||||
|
sx={{
|
||||||
|
display: "flex",
|
||||||
|
alignItems: "center",
|
||||||
|
gap: "14px",
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<CustomButton
|
||||||
|
sx={{
|
||||||
|
minWidth: "102px",
|
||||||
|
}}
|
||||||
|
onClick={() => onOkQortalRequestExtension("accepted")}
|
||||||
|
>
|
||||||
|
accept
|
||||||
|
</CustomButton>
|
||||||
|
<CustomButton
|
||||||
|
sx={{
|
||||||
|
minWidth: "102px",
|
||||||
|
}}
|
||||||
|
onClick={() => onCancelQortalRequestExtension()}
|
||||||
|
>
|
||||||
|
decline
|
||||||
|
</CustomButton>
|
||||||
|
</Box>
|
||||||
|
<ErrorText>{sendPaymentError}</ErrorText>
|
||||||
|
</Box>
|
||||||
|
</Dialog>
|
||||||
)}
|
)}
|
||||||
<Popover
|
<Popover
|
||||||
open={openRegisterName}
|
open={openRegisterName}
|
||||||
|
@ -25,3 +25,13 @@ export const oldPinnedAppsAtom = atom({
|
|||||||
key: 'oldPinnedAppsAtom',
|
key: 'oldPinnedAppsAtom',
|
||||||
default: [],
|
default: [],
|
||||||
});
|
});
|
||||||
|
|
||||||
|
export const fullScreenAtom = atom({
|
||||||
|
key: 'fullScreenAtom',
|
||||||
|
default: false,
|
||||||
|
});
|
||||||
|
|
||||||
|
export const hasSettingsChangedAtom = atom({
|
||||||
|
key: 'hasSettingsChangedAtom',
|
||||||
|
default: false,
|
||||||
|
});
|
@ -1,8 +1,7 @@
|
|||||||
import React, { useEffect, useMemo, useState } from "react";
|
import React from "react";
|
||||||
import {
|
import {
|
||||||
AppCircle,
|
AppCircle,
|
||||||
AppCircleContainer,
|
AppCircleContainer,
|
||||||
AppCircleLabel,
|
|
||||||
AppDownloadButton,
|
AppDownloadButton,
|
||||||
AppDownloadButtonText,
|
AppDownloadButtonText,
|
||||||
AppInfoAppName,
|
AppInfoAppName,
|
||||||
@ -11,10 +10,8 @@ import {
|
|||||||
AppInfoSnippetMiddle,
|
AppInfoSnippetMiddle,
|
||||||
AppInfoSnippetRight,
|
AppInfoSnippetRight,
|
||||||
AppInfoUserName,
|
AppInfoUserName,
|
||||||
AppsLibraryContainer,
|
|
||||||
} from "./Apps-styles";
|
} from "./Apps-styles";
|
||||||
import { Avatar, Box, ButtonBase, InputBase } from "@mui/material";
|
import { Avatar, ButtonBase } from "@mui/material";
|
||||||
import { Add } from "@mui/icons-material";
|
|
||||||
import { getBaseApiReact } from "../../App";
|
import { getBaseApiReact } from "../../App";
|
||||||
import LogoSelected from "../../assets/svgs/LogoSelected.svg";
|
import LogoSelected from "../../assets/svgs/LogoSelected.svg";
|
||||||
|
|
||||||
@ -22,8 +19,7 @@ import { Spacer } from "../../common/Spacer";
|
|||||||
import { executeEvent } from "../../utils/events";
|
import { executeEvent } from "../../utils/events";
|
||||||
import { AppRating } from "./AppRating";
|
import { AppRating } from "./AppRating";
|
||||||
|
|
||||||
export const AppInfoSnippet = ({ app, myName }) => {
|
export const AppInfoSnippet = ({ app, myName, isFromCategory }) => {
|
||||||
|
|
||||||
|
|
||||||
const isInstalled = app?.status?.status === 'READY'
|
const isInstalled = app?.status?.status === 'READY'
|
||||||
return (
|
return (
|
||||||
@ -35,6 +31,12 @@ export const AppInfoSnippet = ({ app, myName }) => {
|
|||||||
width: "60px",
|
width: "60px",
|
||||||
}}
|
}}
|
||||||
onClick={()=> {
|
onClick={()=> {
|
||||||
|
if(isFromCategory){
|
||||||
|
executeEvent("selectedAppInfoCategory", {
|
||||||
|
data: app,
|
||||||
|
});
|
||||||
|
return
|
||||||
|
}
|
||||||
executeEvent("selectedAppInfo", {
|
executeEvent("selectedAppInfo", {
|
||||||
data: app,
|
data: app,
|
||||||
});
|
});
|
||||||
@ -73,6 +75,12 @@ export const AppInfoSnippet = ({ app, myName }) => {
|
|||||||
</ButtonBase>
|
</ButtonBase>
|
||||||
<AppInfoSnippetMiddle>
|
<AppInfoSnippetMiddle>
|
||||||
<ButtonBase onClick={()=> {
|
<ButtonBase onClick={()=> {
|
||||||
|
if(isFromCategory){
|
||||||
|
executeEvent("selectedAppInfoCategory", {
|
||||||
|
data: app,
|
||||||
|
});
|
||||||
|
return
|
||||||
|
}
|
||||||
executeEvent("selectedAppInfo", {
|
executeEvent("selectedAppInfo", {
|
||||||
data: app,
|
data: app,
|
||||||
});
|
});
|
||||||
@ -91,6 +99,7 @@ export const AppInfoSnippet = ({ app, myName }) => {
|
|||||||
</AppInfoSnippetLeft>
|
</AppInfoSnippetLeft>
|
||||||
<AppInfoSnippetRight>
|
<AppInfoSnippetRight>
|
||||||
<AppDownloadButton onClick={()=> {
|
<AppDownloadButton onClick={()=> {
|
||||||
|
|
||||||
executeEvent("addTab", {
|
executeEvent("addTab", {
|
||||||
data: app
|
data: app
|
||||||
})
|
})
|
||||||
|
@ -25,9 +25,7 @@ export const AppRating = ({ app, myName, ratingCountPosition = "right" }) => {
|
|||||||
const [openSnack, setOpenSnack] = useState(false);
|
const [openSnack, setOpenSnack] = useState(false);
|
||||||
const [infoSnack, setInfoSnack] = useState(null);
|
const [infoSnack, setInfoSnack] = useState(null);
|
||||||
const hasCalledRef = useRef(false);
|
const hasCalledRef = useRef(false);
|
||||||
console.log(`pollinfo-${app?.service}-${app?.name}`, value);
|
|
||||||
|
|
||||||
console.log("hasPublishedRating", hasPublishedRating);
|
|
||||||
const getRating = useCallback(async (name, service) => {
|
const getRating = useCallback(async (name, service) => {
|
||||||
try {
|
try {
|
||||||
hasCalledRef.current = true;
|
hasCalledRef.current = true;
|
||||||
@ -42,7 +40,6 @@ export const AppRating = ({ app, myName, ratingCountPosition = "right" }) => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
const responseData = await response.json();
|
const responseData = await response.json();
|
||||||
console.log("responseData", responseData);
|
|
||||||
if (responseData?.message?.includes("POLL_NO_EXISTS")) {
|
if (responseData?.message?.includes("POLL_NO_EXISTS")) {
|
||||||
setHasPublishedRating(false);
|
setHasPublishedRating(false);
|
||||||
} else if (responseData?.pollName) {
|
} else if (responseData?.pollName) {
|
||||||
@ -67,14 +64,12 @@ export const AppRating = ({ app, myName, ratingCountPosition = "right" }) => {
|
|||||||
const initialValueVote = voteCount.find((vote) =>
|
const initialValueVote = voteCount.find((vote) =>
|
||||||
vote.optionName.startsWith("initialValue-")
|
vote.optionName.startsWith("initialValue-")
|
||||||
);
|
);
|
||||||
console.log("initialValueVote", initialValueVote);
|
|
||||||
if (initialValueVote) {
|
if (initialValueVote) {
|
||||||
// Convert "initialValue-X" to just "X" and add it to the ratingVotes array
|
// Convert "initialValue-X" to just "X" and add it to the ratingVotes array
|
||||||
const initialRating = parseInt(
|
const initialRating = parseInt(
|
||||||
initialValueVote.optionName.split("-")[1],
|
initialValueVote.optionName.split("-")[1],
|
||||||
10
|
10
|
||||||
);
|
);
|
||||||
console.log("initialRating", initialRating);
|
|
||||||
ratingVotes.push({
|
ratingVotes.push({
|
||||||
optionName: initialRating.toString(),
|
optionName: initialRating.toString(),
|
||||||
voteCount: 1,
|
voteCount: 1,
|
||||||
@ -91,14 +86,12 @@ export const AppRating = ({ app, myName, ratingCountPosition = "right" }) => {
|
|||||||
totalScore += rating * count; // Weighted score
|
totalScore += rating * count; // Weighted score
|
||||||
totalVotes += count; // Total number of votes
|
totalVotes += count; // Total number of votes
|
||||||
});
|
});
|
||||||
console.log("ratingVotes", ratingVotes, totalScore, totalVotes);
|
|
||||||
|
|
||||||
// Calculate average rating (ensure no division by zero)
|
// Calculate average rating (ensure no division by zero)
|
||||||
const averageRating = totalVotes > 0 ? totalScore / totalVotes : 0;
|
const averageRating = totalVotes > 0 ? totalScore / totalVotes : 0;
|
||||||
setValue(averageRating);
|
setValue(averageRating);
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.log("error rating", error);
|
|
||||||
if (error?.message?.includes("POLL_NO_EXISTS")) {
|
if (error?.message?.includes("POLL_NO_EXISTS")) {
|
||||||
setHasPublishedRating(false);
|
setHasPublishedRating(false);
|
||||||
}
|
}
|
||||||
@ -114,7 +107,6 @@ export const AppRating = ({ app, myName, ratingCountPosition = "right" }) => {
|
|||||||
try {
|
try {
|
||||||
if (!myName) throw new Error("You need a name to rate.");
|
if (!myName) throw new Error("You need a name to rate.");
|
||||||
if (!app?.name) return;
|
if (!app?.name) return;
|
||||||
console.log("newValue", newValue);
|
|
||||||
const fee = await getFee("ARBITRARY");
|
const fee = await getFee("ARBITRARY");
|
||||||
|
|
||||||
await show({
|
await show({
|
||||||
@ -138,7 +130,6 @@ export const AppRating = ({ app, myName, ratingCountPosition = "right" }) => {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
(response) => {
|
(response) => {
|
||||||
console.log("response", response);
|
|
||||||
if (response.error) {
|
if (response.error) {
|
||||||
rej(response?.message);
|
rej(response?.message);
|
||||||
return;
|
return;
|
||||||
@ -172,7 +163,6 @@ export const AppRating = ({ app, myName, ratingCountPosition = "right" }) => {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
(response) => {
|
(response) => {
|
||||||
console.log("response", response);
|
|
||||||
if (response.error) {
|
if (response.error) {
|
||||||
rej(response?.message);
|
rej(response?.message);
|
||||||
return;
|
return;
|
||||||
@ -197,11 +187,7 @@ export const AppRating = ({ app, myName, ratingCountPosition = "right" }) => {
|
|||||||
setOpenSnack(true);
|
setOpenSnack(true);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
console.log(
|
|
||||||
"vvotes",
|
|
||||||
(votesInfo?.totalVotes ?? 0) + votesInfo?.voteCounts?.length === 6 ? 1 : 0,
|
|
||||||
votesInfo
|
|
||||||
);
|
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
<Box
|
<Box
|
||||||
|
@ -8,17 +8,7 @@ const AppViewerContainer = ({app, isSelected, hide}) => {
|
|||||||
const { rootHeight } = useContext(MyContext);
|
const { rootHeight } = useContext(MyContext);
|
||||||
const frameRef = useRef(null);
|
const frameRef = useRef(null);
|
||||||
|
|
||||||
const refreshAppFunc = (e) => {
|
|
||||||
console.log('getting refresh', e)
|
|
||||||
};
|
|
||||||
|
|
||||||
// useEffect(() => {
|
|
||||||
// subscribeToEvent("refreshAPp", refreshAppFunc);
|
|
||||||
|
|
||||||
// return () => {
|
|
||||||
// unsubscribeFromEvent("refreshApp", refreshAppFunc);
|
|
||||||
// };
|
|
||||||
// }, []);
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Frame id={`browser-iframe-${app?.tabId}` } ref={frameRef} head={
|
<Frame id={`browser-iframe-${app?.tabId}` } ref={frameRef} head={
|
||||||
|
@ -2,7 +2,6 @@ import React, { useCallback, useContext, useEffect, useMemo, useRef, useState }
|
|||||||
import { AppsHome } from "./AppsHome";
|
import { AppsHome } from "./AppsHome";
|
||||||
import { Spacer } from "../../common/Spacer";
|
import { Spacer } from "../../common/Spacer";
|
||||||
import { MyContext, getBaseApiReact } from "../../App";
|
import { MyContext, getBaseApiReact } from "../../App";
|
||||||
import { AppsLibrary } from "./AppsLibrary";
|
|
||||||
import { AppInfo } from "./AppInfo";
|
import { AppInfo } from "./AppInfo";
|
||||||
import {
|
import {
|
||||||
executeEvent,
|
executeEvent,
|
||||||
@ -16,12 +15,15 @@ import AppViewerContainer from "./AppViewerContainer";
|
|||||||
import ShortUniqueId from "short-unique-id";
|
import ShortUniqueId from "short-unique-id";
|
||||||
import { AppPublish } from "./AppPublish";
|
import { AppPublish } from "./AppPublish";
|
||||||
import { useRecoilState } from "recoil";
|
import { useRecoilState } from "recoil";
|
||||||
|
import { AppsCategory } from "./AppsCategory";
|
||||||
|
import { AppsLibrary } from "./AppsLibrary";
|
||||||
|
|
||||||
const uid = new ShortUniqueId({ length: 8 });
|
const uid = new ShortUniqueId({ length: 8 });
|
||||||
|
|
||||||
export const Apps = ({ mode, setMode, show , myName}) => {
|
export const Apps = ({ mode, setMode, show , myName}) => {
|
||||||
const [availableQapps, setAvailableQapps] = useState([]);
|
const [availableQapps, setAvailableQapps] = useState([]);
|
||||||
const [selectedAppInfo, setSelectedAppInfo] = useState(null);
|
const [selectedAppInfo, setSelectedAppInfo] = useState(null);
|
||||||
|
const [selectedCategory, setSelectedCategory] = useState(null)
|
||||||
const [tabs, setTabs] = useState([]);
|
const [tabs, setTabs] = useState([]);
|
||||||
const [selectedTab, setSelectedTab] = useState(null);
|
const [selectedTab, setSelectedTab] = useState(null);
|
||||||
const [isNewTabWindow, setIsNewTabWindow] = useState(false);
|
const [isNewTabWindow, setIsNewTabWindow] = useState(false);
|
||||||
@ -85,7 +87,6 @@ export const Apps = ({ mode, setMode, show , myName}) => {
|
|||||||
});
|
});
|
||||||
if (!response?.ok) return;
|
if (!response?.ok) return;
|
||||||
const responseData = await response.json();
|
const responseData = await response.json();
|
||||||
console.log('responseData', responseData)
|
|
||||||
const urlWebsites = `${getBaseApiReact()}/arbitrary/resources/search?service=WEBSITE&mode=ALL&limit=0&includestatus=true&includemetadata=true`;
|
const urlWebsites = `${getBaseApiReact()}/arbitrary/resources/search?service=WEBSITE&mode=ALL&limit=0&includestatus=true&includemetadata=true`;
|
||||||
|
|
||||||
const responseWebsites = await fetch(urlWebsites, {
|
const responseWebsites = await fetch(urlWebsites, {
|
||||||
@ -125,8 +126,44 @@ export const Apps = ({ mode, setMode, show , myName}) => {
|
|||||||
};
|
};
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
|
const selectedAppInfoCategoryFunc = (e) => {
|
||||||
|
const data = e.detail?.data;
|
||||||
|
setSelectedAppInfo(data);
|
||||||
|
setMode("appInfo-from-category");
|
||||||
|
};
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
subscribeToEvent("selectedAppInfoCategory", selectedAppInfoCategoryFunc);
|
||||||
|
|
||||||
|
return () => {
|
||||||
|
unsubscribeFromEvent("selectedAppInfoCategory", selectedAppInfoCategoryFunc);
|
||||||
|
};
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
const selectedCategoryFunc = (e) => {
|
||||||
|
const data = e.detail?.data;
|
||||||
|
setSelectedCategory(data);
|
||||||
|
setMode("category");
|
||||||
|
};
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
subscribeToEvent("selectedCategory", selectedCategoryFunc);
|
||||||
|
|
||||||
|
return () => {
|
||||||
|
unsubscribeFromEvent("selectedCategory", selectedCategoryFunc);
|
||||||
|
};
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
|
||||||
const navigateBackFunc = (e) => {
|
const navigateBackFunc = (e) => {
|
||||||
if (mode === "appInfo") {
|
if(mode === 'category'){
|
||||||
|
setMode("library");
|
||||||
|
setSelectedCategory(null)
|
||||||
|
} else if (mode === "appInfo-from-category") {
|
||||||
|
setMode("category");
|
||||||
|
} else if (mode === "appInfo") {
|
||||||
setMode("library");
|
setMode("library");
|
||||||
} else if (mode === "library") {
|
} else if (mode === "library") {
|
||||||
if (isNewTabWindow) {
|
if (isNewTabWindow) {
|
||||||
@ -139,10 +176,8 @@ export const Apps = ({ mode, setMode, show , myName}) => {
|
|||||||
} else {
|
} else {
|
||||||
const iframeId = `browser-iframe-${selectedTab?.tabId}`;
|
const iframeId = `browser-iframe-${selectedTab?.tabId}`;
|
||||||
const iframe = document.getElementById(iframeId);
|
const iframe = document.getElementById(iframeId);
|
||||||
console.log("iframe", iframe);
|
|
||||||
// Go Back in the iframe's history
|
// Go Back in the iframe's history
|
||||||
if (iframe) {
|
if (iframe) {
|
||||||
console.log(iframe.contentWindow);
|
|
||||||
if (iframe && iframe.contentWindow) {
|
if (iframe && iframe.contentWindow) {
|
||||||
const iframeWindow = iframe.contentWindow;
|
const iframeWindow = iframe.contentWindow;
|
||||||
if (iframeWindow && iframeWindow.history) {
|
if (iframeWindow && iframeWindow.history) {
|
||||||
@ -247,6 +282,7 @@ export const Apps = ({ mode, setMode, show , myName}) => {
|
|||||||
};
|
};
|
||||||
}, [tabs]);
|
}, [tabs]);
|
||||||
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<AppsParent
|
<AppsParent
|
||||||
sx={{
|
sx={{
|
||||||
@ -264,9 +300,12 @@ export const Apps = ({ mode, setMode, show , myName}) => {
|
|||||||
setMode={setMode}
|
setMode={setMode}
|
||||||
myName={myName}
|
myName={myName}
|
||||||
hasPublishApp={!!(myApp || myWebsite)}
|
hasPublishApp={!!(myApp || myWebsite)}
|
||||||
|
categories={categories}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
{mode === "appInfo" && <AppInfo app={selectedAppInfo} myName={myName} />}
|
{mode === "appInfo" && <AppInfo app={selectedAppInfo} myName={myName} />}
|
||||||
|
{mode === "appInfo-from-category" && <AppInfo app={selectedAppInfo} myName={myName} />}
|
||||||
|
<AppsCategory availableQapps={availableQapps} isShow={mode === 'category' && !selectedTab} category={selectedCategory} myName={myName} />
|
||||||
{mode === "publish" && <AppPublish names={myName ? [myName] : []} categories={categories} />}
|
{mode === "publish" && <AppPublish names={myName ? [myName] : []} categories={categories} />}
|
||||||
|
|
||||||
{tabs.map((tab) => {
|
{tabs.map((tab) => {
|
||||||
|
188
src/components/Apps/AppsCategory.tsx
Normal file
188
src/components/Apps/AppsCategory.tsx
Normal file
@ -0,0 +1,188 @@
|
|||||||
|
import React, { useCallback, useContext, useEffect, useMemo, useRef, useState } from "react";
|
||||||
|
import {
|
||||||
|
AppCircle,
|
||||||
|
AppCircleContainer,
|
||||||
|
AppCircleLabel,
|
||||||
|
AppLibrarySubTitle,
|
||||||
|
AppsContainer,
|
||||||
|
AppsLibraryContainer,
|
||||||
|
AppsParent,
|
||||||
|
AppsSearchContainer,
|
||||||
|
AppsSearchLeft,
|
||||||
|
AppsSearchRight,
|
||||||
|
AppsWidthLimiter,
|
||||||
|
PublishQAppCTAButton,
|
||||||
|
PublishQAppCTALeft,
|
||||||
|
PublishQAppCTAParent,
|
||||||
|
PublishQAppCTARight,
|
||||||
|
PublishQAppDotsBG,
|
||||||
|
} from "./Apps-styles";
|
||||||
|
import { Avatar, Box, ButtonBase, InputBase, styled } from "@mui/material";
|
||||||
|
import { Add } from "@mui/icons-material";
|
||||||
|
import { MyContext, getBaseApiReact } from "../../App";
|
||||||
|
import LogoSelected from "../../assets/svgs/LogoSelected.svg";
|
||||||
|
import IconSearch from "../../assets/svgs/Search.svg";
|
||||||
|
import IconClearInput from "../../assets/svgs/ClearInput.svg";
|
||||||
|
import qappDevelopText from "../../assets/svgs/qappDevelopText.svg";
|
||||||
|
import qappDots from "../../assets/svgs/qappDots.svg";
|
||||||
|
|
||||||
|
import { Spacer } from "../../common/Spacer";
|
||||||
|
import { AppInfoSnippet } from "./AppInfoSnippet";
|
||||||
|
import { Virtuoso } from "react-virtuoso";
|
||||||
|
import { executeEvent } from "../../utils/events";
|
||||||
|
const officialAppList = [
|
||||||
|
"q-tube",
|
||||||
|
"q-blog",
|
||||||
|
"q-share",
|
||||||
|
"q-support",
|
||||||
|
"q-mail",
|
||||||
|
"qombo",
|
||||||
|
"q-fund",
|
||||||
|
"q-shop",
|
||||||
|
];
|
||||||
|
|
||||||
|
const ScrollerStyled = styled('div')({
|
||||||
|
// Hide scrollbar for WebKit browsers (Chrome, Safari)
|
||||||
|
"::-webkit-scrollbar": {
|
||||||
|
width: "0px",
|
||||||
|
height: "0px",
|
||||||
|
},
|
||||||
|
|
||||||
|
// Hide scrollbar for Firefox
|
||||||
|
scrollbarWidth: "none",
|
||||||
|
|
||||||
|
// Hide scrollbar for IE and older Edge
|
||||||
|
"-ms-overflow-style": "none",
|
||||||
|
});
|
||||||
|
|
||||||
|
const StyledVirtuosoContainer = styled('div')({
|
||||||
|
position: 'relative',
|
||||||
|
width: '100%',
|
||||||
|
display: 'flex',
|
||||||
|
flexDirection: 'column',
|
||||||
|
|
||||||
|
// Hide scrollbar for WebKit browsers (Chrome, Safari)
|
||||||
|
"::-webkit-scrollbar": {
|
||||||
|
width: "0px",
|
||||||
|
height: "0px",
|
||||||
|
},
|
||||||
|
|
||||||
|
// Hide scrollbar for Firefox
|
||||||
|
scrollbarWidth: "none",
|
||||||
|
|
||||||
|
// Hide scrollbar for IE and older Edge
|
||||||
|
"-ms-overflow-style": "none",
|
||||||
|
});
|
||||||
|
|
||||||
|
export const AppsCategory = ({ availableQapps, myName, category, isShow }) => {
|
||||||
|
const [searchValue, setSearchValue] = useState("");
|
||||||
|
const virtuosoRef = useRef();
|
||||||
|
const { rootHeight } = useContext(MyContext);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
const categoryList = useMemo(() => {
|
||||||
|
return availableQapps.filter(
|
||||||
|
(app) =>
|
||||||
|
app?.metadata?.category === category?.id
|
||||||
|
);
|
||||||
|
}, [availableQapps, category]);
|
||||||
|
|
||||||
|
const [debouncedValue, setDebouncedValue] = useState(""); // Debounced value
|
||||||
|
|
||||||
|
// Debounce logic
|
||||||
|
useEffect(() => {
|
||||||
|
const handler = setTimeout(() => {
|
||||||
|
setDebouncedValue(searchValue);
|
||||||
|
}, 350);
|
||||||
|
|
||||||
|
// Cleanup timeout if searchValue changes before the timeout completes
|
||||||
|
return () => {
|
||||||
|
clearTimeout(handler);
|
||||||
|
};
|
||||||
|
}, [searchValue]); // Runs effect when searchValue changes
|
||||||
|
|
||||||
|
// Example: Perform search or other actions based on debouncedValue
|
||||||
|
|
||||||
|
const searchedList = useMemo(() => {
|
||||||
|
if (!debouncedValue) return categoryList
|
||||||
|
return categoryList.filter((app) =>
|
||||||
|
app.name.toLowerCase().includes(debouncedValue.toLowerCase())
|
||||||
|
);
|
||||||
|
}, [debouncedValue, categoryList]);
|
||||||
|
|
||||||
|
const rowRenderer = (index) => {
|
||||||
|
|
||||||
|
let app = searchedList[index];
|
||||||
|
return <AppInfoSnippet key={`${app?.service}-${app?.name}`} app={app} myName={myName} isFromCategory={true} />;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
return (
|
||||||
|
<AppsLibraryContainer sx={{
|
||||||
|
display: !isShow && 'none'
|
||||||
|
}}>
|
||||||
|
<AppsWidthLimiter>
|
||||||
|
<Box
|
||||||
|
sx={{
|
||||||
|
display: "flex",
|
||||||
|
width: "100%",
|
||||||
|
justifyContent: "center",
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<AppsSearchContainer>
|
||||||
|
<AppsSearchLeft>
|
||||||
|
<img src={IconSearch} />
|
||||||
|
<InputBase
|
||||||
|
value={searchValue}
|
||||||
|
onChange={(e) => setSearchValue(e.target.value)}
|
||||||
|
sx={{ ml: 1, flex: 1 }}
|
||||||
|
placeholder="Search for apps"
|
||||||
|
inputProps={{
|
||||||
|
"aria-label": "Search for apps",
|
||||||
|
fontSize: "16px",
|
||||||
|
fontWeight: 400,
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</AppsSearchLeft>
|
||||||
|
<AppsSearchRight>
|
||||||
|
{searchValue && (
|
||||||
|
<ButtonBase
|
||||||
|
onClick={() => {
|
||||||
|
setSearchValue("");
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<img src={IconClearInput} />
|
||||||
|
</ButtonBase>
|
||||||
|
)}
|
||||||
|
</AppsSearchRight>
|
||||||
|
</AppsSearchContainer>
|
||||||
|
</Box>
|
||||||
|
</AppsWidthLimiter>
|
||||||
|
<Spacer height="25px" />
|
||||||
|
<AppsWidthLimiter>
|
||||||
|
<AppLibrarySubTitle>{`Category: ${category?.name}`}</AppLibrarySubTitle>
|
||||||
|
|
||||||
|
<Spacer height="25px" />
|
||||||
|
</AppsWidthLimiter>
|
||||||
|
<AppsWidthLimiter>
|
||||||
|
<StyledVirtuosoContainer sx={{
|
||||||
|
height: rootHeight
|
||||||
|
}}>
|
||||||
|
<Virtuoso
|
||||||
|
ref={virtuosoRef}
|
||||||
|
data={searchedList}
|
||||||
|
itemContent={rowRenderer}
|
||||||
|
atBottomThreshold={50}
|
||||||
|
followOutput="smooth"
|
||||||
|
components={{
|
||||||
|
Scroller: ScrollerStyled // Use the styled scroller component
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</StyledVirtuosoContainer>
|
||||||
|
</AppsWidthLimiter>
|
||||||
|
|
||||||
|
</AppsLibraryContainer>
|
||||||
|
);
|
||||||
|
};
|
@ -74,23 +74,11 @@ const ScrollerStyled = styled('div')({
|
|||||||
"-ms-overflow-style": "none",
|
"-ms-overflow-style": "none",
|
||||||
});
|
});
|
||||||
|
|
||||||
export const AppsLibrary = ({ availableQapps, setMode, myName, hasPublishApp, isShow }) => {
|
export const AppsLibrary = ({ availableQapps, setMode, myName, hasPublishApp, isShow, categories={categories} }) => {
|
||||||
const [searchValue, setSearchValue] = useState("");
|
const [searchValue, setSearchValue] = useState("");
|
||||||
const virtuosoRef = useRef();
|
const virtuosoRef = useRef();
|
||||||
const { rootHeight } = useContext(MyContext);
|
const { rootHeight } = useContext(MyContext);
|
||||||
const [appStates, setAppStates] = useState({});
|
|
||||||
|
|
||||||
const handleStateChange = (appId, newState) => {
|
|
||||||
setAppStates((prevState) => ({
|
|
||||||
...prevState,
|
|
||||||
[appId]: {
|
|
||||||
...(prevState[appId] || {}), // Preserve existing state for the app
|
|
||||||
...newState, // Merge in the new state properties
|
|
||||||
},
|
|
||||||
}));
|
|
||||||
};
|
|
||||||
|
|
||||||
console.log('appStates', appStates)
|
|
||||||
const officialApps = useMemo(() => {
|
const officialApps = useMemo(() => {
|
||||||
return availableQapps.filter(
|
return availableQapps.filter(
|
||||||
(app) =>
|
(app) =>
|
||||||
@ -121,12 +109,10 @@ export const AppsLibrary = ({ availableQapps, setMode, myName, hasPublishApp, i
|
|||||||
app.name.toLowerCase().includes(debouncedValue.toLowerCase())
|
app.name.toLowerCase().includes(debouncedValue.toLowerCase())
|
||||||
);
|
);
|
||||||
}, [debouncedValue]);
|
}, [debouncedValue]);
|
||||||
console.log("officialApps", searchedList);
|
|
||||||
|
|
||||||
const rowRenderer = (index) => {
|
const rowRenderer = (index) => {
|
||||||
|
|
||||||
let app = searchedList[index];
|
let app = searchedList[index];
|
||||||
console.log('appi', app)
|
|
||||||
return <AppInfoSnippet key={`${app?.service}-${app?.name}`} app={app} myName={myName} />;
|
return <AppInfoSnippet key={`${app?.service}-${app?.name}`} app={app} myName={myName} />;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -273,6 +259,49 @@ export const AppsLibrary = ({ availableQapps, setMode, myName, hasPublishApp, i
|
|||||||
|
|
||||||
<Spacer height="18px" />
|
<Spacer height="18px" />
|
||||||
<AppLibrarySubTitle>Categories</AppLibrarySubTitle>
|
<AppLibrarySubTitle>Categories</AppLibrarySubTitle>
|
||||||
|
<Spacer height="18px" />
|
||||||
|
<AppsWidthLimiter sx={{
|
||||||
|
flexDirection: 'row',
|
||||||
|
overflowX: 'auto',
|
||||||
|
width: '100%',
|
||||||
|
gap: '5px',
|
||||||
|
"::-webkit-scrollbar": {
|
||||||
|
width: "0px",
|
||||||
|
height: "0px",
|
||||||
|
},
|
||||||
|
|
||||||
|
// Hide scrollbar for Firefox
|
||||||
|
scrollbarWidth: "none",
|
||||||
|
|
||||||
|
// Hide scrollbar for IE and older Edge
|
||||||
|
"-ms-overflow-style": "none",
|
||||||
|
}}>
|
||||||
|
{categories?.map((category)=> {
|
||||||
|
return (
|
||||||
|
<ButtonBase key={category?.id} onClick={()=> {
|
||||||
|
executeEvent('selectedCategory', {
|
||||||
|
data: category
|
||||||
|
})
|
||||||
|
}}>
|
||||||
|
<Box sx={{
|
||||||
|
display: 'flex',
|
||||||
|
alignItems: 'center',
|
||||||
|
justifyContent: 'center',
|
||||||
|
height: '110px',
|
||||||
|
width: '110px',
|
||||||
|
background: 'linear-gradient(163.47deg, #4BBCFE 27.55%, #1386C9 86.56%)',
|
||||||
|
color: '#1D1D1E',
|
||||||
|
fontWeight: 700,
|
||||||
|
fontSize: '16px',
|
||||||
|
flexShrink: 0,
|
||||||
|
borderRadius: '11px'
|
||||||
|
}}>
|
||||||
|
{category?.name}
|
||||||
|
</Box>
|
||||||
|
</ButtonBase>
|
||||||
|
)
|
||||||
|
})}
|
||||||
|
</AppsWidthLimiter>
|
||||||
</AppsWidthLimiter>
|
</AppsWidthLimiter>
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
|
@ -41,7 +41,6 @@ export function saveToLocalStorage(key, subKey, newValue) {
|
|||||||
// Save combined data back to localStorage
|
// Save combined data back to localStorage
|
||||||
const serializedValue = JSON.stringify(combinedData);
|
const serializedValue = JSON.stringify(combinedData);
|
||||||
localStorage.setItem(key, serializedValue);
|
localStorage.setItem(key, serializedValue);
|
||||||
console.log(`Data saved to localStorage with key: ${key} and subKey: ${subKey}`);
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Error saving to localStorage:', error);
|
console.error('Error saving to localStorage:', error);
|
||||||
}
|
}
|
||||||
@ -57,6 +56,7 @@ export const AppsNavBar = () => {
|
|||||||
const [anchorEl, setAnchorEl] = useState(null);
|
const [anchorEl, setAnchorEl] = useState(null);
|
||||||
const open = Boolean(anchorEl);
|
const open = Boolean(anchorEl);
|
||||||
const [sortablePinnedApps, setSortablePinnedApps] = useRecoilState(sortablePinnedAppsAtom);
|
const [sortablePinnedApps, setSortablePinnedApps] = useRecoilState(sortablePinnedAppsAtom);
|
||||||
|
|
||||||
const setSettingsLocalLastUpdated = useSetRecoilState(settingsLocalLastUpdatedAtom);
|
const setSettingsLocalLastUpdated = useSetRecoilState(settingsLocalLastUpdatedAtom);
|
||||||
|
|
||||||
const handleClick = (event) => {
|
const handleClick = (event) => {
|
||||||
@ -71,7 +71,6 @@ export const AppsNavBar = () => {
|
|||||||
// Scroll to the last tab whenever the tabs array changes (e.g., when a new tab is added)
|
// Scroll to the last tab whenever the tabs array changes (e.g., when a new tab is added)
|
||||||
if (tabsRef.current) {
|
if (tabsRef.current) {
|
||||||
const tabElements = tabsRef.current.querySelectorAll('.MuiTab-root');
|
const tabElements = tabsRef.current.querySelectorAll('.MuiTab-root');
|
||||||
console.log('tabElements', tabElements)
|
|
||||||
if (tabElements.length > 0) {
|
if (tabElements.length > 0) {
|
||||||
const lastTab = tabElements[tabElements.length - 1];
|
const lastTab = tabElements[tabElements.length - 1];
|
||||||
lastTab.scrollIntoView({ behavior: 'smooth', block: 'nearest', inline: 'end' });
|
lastTab.scrollIntoView({ behavior: 'smooth', block: 'nearest', inline: 'end' });
|
||||||
@ -95,7 +94,6 @@ export const AppsNavBar = () => {
|
|||||||
};
|
};
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
console.log('selectedTab', selectedTab)
|
|
||||||
|
|
||||||
const isSelectedAppPinned = !!sortablePinnedApps?.find((item)=> item?.name === selectedTab?.name && item?.service === selectedTab?.service)
|
const isSelectedAppPinned = !!sortablePinnedApps?.find((item)=> item?.name === selectedTab?.name && item?.service === selectedTab?.service)
|
||||||
return (
|
return (
|
||||||
|
@ -14,7 +14,6 @@ import { ContextMenuPinnedApps } from '../ContextMenuPinnedApps';
|
|||||||
|
|
||||||
const SortableItem = ({ id, name, app }) => {
|
const SortableItem = ({ id, name, app }) => {
|
||||||
const { attributes, listeners, setNodeRef, transform, transition } = useSortable({ id });
|
const { attributes, listeners, setNodeRef, transform, transition } = useSortable({ id });
|
||||||
console.log('namednd', name)
|
|
||||||
const style = {
|
const style = {
|
||||||
transform: CSS.Transform.toString(transform),
|
transform: CSS.Transform.toString(transform),
|
||||||
transition,
|
transition,
|
||||||
@ -86,7 +85,6 @@ export const SortablePinnedApps = ({ myWebsite, myApp, availableQapps = [] }) =
|
|||||||
const setSettingsLocalLastUpdated = useSetRecoilState(settingsLocalLastUpdatedAtom);
|
const setSettingsLocalLastUpdated = useSetRecoilState(settingsLocalLastUpdatedAtom);
|
||||||
|
|
||||||
const transformPinnedApps = useMemo(() => {
|
const transformPinnedApps = useMemo(() => {
|
||||||
console.log({ myWebsite, myApp, availableQapps, pinnedApps });
|
|
||||||
|
|
||||||
// Clone the existing pinned apps list
|
// Clone the existing pinned apps list
|
||||||
let pinned = [...pinnedApps];
|
let pinned = [...pinnedApps];
|
||||||
@ -130,27 +128,7 @@ export const SortablePinnedApps = ({ myWebsite, myApp, availableQapps = [] }) =
|
|||||||
return pinned;
|
return pinned;
|
||||||
}, [myApp, myWebsite, pinnedApps, availableQapps]);
|
}, [myApp, myWebsite, pinnedApps, availableQapps]);
|
||||||
|
|
||||||
console.log('transformPinnedApps', transformPinnedApps)
|
|
||||||
// const hasSetPinned = useRef(false)
|
|
||||||
// useEffect(() => {
|
|
||||||
// if (!apps || apps.length === 0) return;
|
|
||||||
|
|
||||||
// setPinnedApps((prevPinnedApps) => {
|
|
||||||
// // Create a map of the previous pinned apps for easy lookup
|
|
||||||
// const pinnedAppsMap = new Map(prevPinnedApps.map(app => [`${app?.service}-${app?.name}`, app]));
|
|
||||||
|
|
||||||
// // Update the pinnedApps list based on new apps
|
|
||||||
// const updatedPinnedApps = apps.map(app => {
|
|
||||||
// const id = `${app?.service}-${app?.name}`;
|
|
||||||
// // Keep the existing app from pinnedApps if it exists
|
|
||||||
// return pinnedAppsMap.get(id) || app;
|
|
||||||
// });
|
|
||||||
|
|
||||||
// return updatedPinnedApps;
|
|
||||||
// });
|
|
||||||
// }, [apps]);
|
|
||||||
|
|
||||||
console.log('dnd',{pinnedApps})
|
|
||||||
const sensors = useSensors(
|
const sensors = useSensors(
|
||||||
useSensor(PointerSensor, {
|
useSensor(PointerSensor, {
|
||||||
activationConstraint: {
|
activationConstraint: {
|
||||||
|
@ -97,7 +97,6 @@ async function handleGetFileFromIndexedDB(fileId, sendResponse) {
|
|||||||
const deleteRequest = deleteObjectStore.delete(fileId);
|
const deleteRequest = deleteObjectStore.delete(fileId);
|
||||||
|
|
||||||
deleteRequest.onsuccess = function () {
|
deleteRequest.onsuccess = function () {
|
||||||
console.log(`File with ID ${fileId} has been removed from IndexedDB`);
|
|
||||||
try {
|
try {
|
||||||
sendResponse({ result: base64String });
|
sendResponse({ result: base64String });
|
||||||
|
|
||||||
@ -171,7 +170,6 @@ const UIQortalRequests = [
|
|||||||
|
|
||||||
async function deleteQortalFilesFromIndexedDB() {
|
async function deleteQortalFilesFromIndexedDB() {
|
||||||
try {
|
try {
|
||||||
console.log("Opening IndexedDB for deleting files...");
|
|
||||||
const db = await openIndexedDB();
|
const db = await openIndexedDB();
|
||||||
const transaction = db.transaction(["files"], "readwrite");
|
const transaction = db.transaction(["files"], "readwrite");
|
||||||
const objectStore = transaction.objectStore("files");
|
const objectStore = transaction.objectStore("files");
|
||||||
@ -262,7 +260,6 @@ const UIQortalRequests = [
|
|||||||
obj.fileId = fileId;
|
obj.fileId = fileId;
|
||||||
delete obj.file;
|
delete obj.file;
|
||||||
}
|
}
|
||||||
console.log(obj, obj.blob instanceof Blob, 'blob')
|
|
||||||
if (obj.blob) {
|
if (obj.blob) {
|
||||||
const fileId = "objFile_qortalfile";
|
const fileId = "objFile_qortalfile";
|
||||||
|
|
||||||
@ -315,7 +312,6 @@ const UIQortalRequests = [
|
|||||||
export const useQortalMessageListener = (frameWindow) => {
|
export const useQortalMessageListener = (frameWindow) => {
|
||||||
const [path, setPath] = useState('')
|
const [path, setPath] = useState('')
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
console.log("Listener added react");
|
|
||||||
|
|
||||||
const listener = async (event) => {
|
const listener = async (event) => {
|
||||||
event.preventDefault(); // Prevent default behavior
|
event.preventDefault(); // Prevent default behavior
|
||||||
@ -325,7 +321,6 @@ export const useQortalMessageListener = (frameWindow) => {
|
|||||||
|
|
||||||
const sendMessageToRuntime = (message, eventPort) => {
|
const sendMessageToRuntime = (message, eventPort) => {
|
||||||
chrome?.runtime?.sendMessage(message, (response) => {
|
chrome?.runtime?.sendMessage(message, (response) => {
|
||||||
console.log('response', response);
|
|
||||||
if (response.error) {
|
if (response.error) {
|
||||||
eventPort.postMessage({
|
eventPort.postMessage({
|
||||||
result: null,
|
result: null,
|
||||||
@ -342,7 +337,6 @@ export const useQortalMessageListener = (frameWindow) => {
|
|||||||
|
|
||||||
// Check if action is included in the predefined list of UI requests
|
// Check if action is included in the predefined list of UI requests
|
||||||
if (UIQortalRequests.includes(event.data.action)) {
|
if (UIQortalRequests.includes(event.data.action)) {
|
||||||
console.log('event?.data', event?.data);
|
|
||||||
sendMessageToRuntime(
|
sendMessageToRuntime(
|
||||||
{ action: event.data.action, type: 'qortalRequest', payload: event.data, isExtension: true },
|
{ action: event.data.action, type: 'qortalRequest', payload: event.data, isExtension: true },
|
||||||
event.ports[0]
|
event.ports[0]
|
||||||
@ -353,7 +347,6 @@ export const useQortalMessageListener = (frameWindow) => {
|
|||||||
event?.data?.action === 'ENCRYPT_DATA' || event?.data?.action === 'SAVE_FILE'
|
event?.data?.action === 'ENCRYPT_DATA' || event?.data?.action === 'SAVE_FILE'
|
||||||
|
|
||||||
) {
|
) {
|
||||||
console.log('event?.data?', event?.data);
|
|
||||||
let data;
|
let data;
|
||||||
try {
|
try {
|
||||||
data = await storeFilesInIndexedDB(event.data);
|
data = await storeFilesInIndexedDB(event.data);
|
||||||
@ -365,7 +358,6 @@ export const useQortalMessageListener = (frameWindow) => {
|
|||||||
});
|
});
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
console.log('data after', data)
|
|
||||||
if (data) {
|
if (data) {
|
||||||
sendMessageToRuntime(
|
sendMessageToRuntime(
|
||||||
{ action: event.data.action, type: 'qortalRequest', payload: data, isExtension: true },
|
{ action: event.data.action, type: 'qortalRequest', payload: data, isExtension: true },
|
||||||
@ -396,7 +388,6 @@ export const useQortalMessageListener = (frameWindow) => {
|
|||||||
}, []); // Empty dependency array to run once when the component mounts
|
}, []); // Empty dependency array to run once when the component mounts
|
||||||
|
|
||||||
chrome.runtime?.onMessage.addListener( function (message, sender, sendResponse) {
|
chrome.runtime?.onMessage.addListener( function (message, sender, sendResponse) {
|
||||||
console.log('SHOWING UP')
|
|
||||||
if(message.action === "SHOW_SAVE_FILE_PICKER"){
|
if(message.action === "SHOW_SAVE_FILE_PICKER"){
|
||||||
showSaveFilePicker(message?.data)
|
showSaveFilePicker(message?.data)
|
||||||
}
|
}
|
||||||
|
@ -127,7 +127,6 @@ export const ChatDirect = ({ myAddress, isNewChat, selectedDirect, setSelectedDi
|
|||||||
|
|
||||||
const forceCloseWebSocket = () => {
|
const forceCloseWebSocket = () => {
|
||||||
if (socketRef.current) {
|
if (socketRef.current) {
|
||||||
console.log('Force closing the WebSocket');
|
|
||||||
clearTimeout(timeoutIdRef.current);
|
clearTimeout(timeoutIdRef.current);
|
||||||
clearTimeout(groupSocketTimeoutRef.current);
|
clearTimeout(groupSocketTimeoutRef.current);
|
||||||
socketRef.current.close(1000, 'forced');
|
socketRef.current.close(1000, 'forced');
|
||||||
@ -161,7 +160,6 @@ export const ChatDirect = ({ myAddress, isNewChat, selectedDirect, setSelectedDi
|
|||||||
socketRef.current = new WebSocket(socketLink);
|
socketRef.current = new WebSocket(socketLink);
|
||||||
|
|
||||||
socketRef.current.onopen = () => {
|
socketRef.current.onopen = () => {
|
||||||
console.log('WebSocket connection opened');
|
|
||||||
setTimeout(pingWebSocket, 50); // Initial ping
|
setTimeout(pingWebSocket, 50); // Initial ping
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -824,98 +824,7 @@ export const Group = ({
|
|||||||
}
|
}
|
||||||
}, [selectedGroup]);
|
}, [selectedGroup]);
|
||||||
|
|
||||||
// const handleNotification = async (data)=> {
|
|
||||||
// try {
|
|
||||||
// if(isFocusedRef.current){
|
|
||||||
// throw new Error('isFocused')
|
|
||||||
// }
|
|
||||||
// const newActiveChats= data
|
|
||||||
// const oldActiveChats = await new Promise((res, rej) => {
|
|
||||||
// chrome?.runtime?.sendMessage(
|
|
||||||
// {
|
|
||||||
// action: "getChatHeads",
|
|
||||||
// },
|
|
||||||
// (response) => {
|
|
||||||
// console.log({ response });
|
|
||||||
// if (!response?.error) {
|
|
||||||
// res(response);
|
|
||||||
// }
|
|
||||||
// rej(response.error);
|
|
||||||
// }
|
|
||||||
// );
|
|
||||||
// });
|
|
||||||
|
|
||||||
// let results = []
|
|
||||||
// newActiveChats?.groups?.forEach(newChat => {
|
|
||||||
// let isNewer = true;
|
|
||||||
// oldActiveChats?.data?.groups?.forEach(oldChat => {
|
|
||||||
// if (newChat?.timestamp <= oldChat?.timestamp) {
|
|
||||||
// isNewer = false;
|
|
||||||
// }
|
|
||||||
// });
|
|
||||||
// if (isNewer) {
|
|
||||||
// results.push(newChat)
|
|
||||||
// console.log('This newChat is newer than all oldChats:', newChat);
|
|
||||||
// }
|
|
||||||
// });
|
|
||||||
|
|
||||||
// if(results?.length > 0){
|
|
||||||
// if (!lastGroupNotification.current || (Date.now() - lastGroupNotification.current >= 60000)) {
|
|
||||||
// console.log((Date.now() - lastGroupNotification.current >= 60000), lastGroupNotification.current)
|
|
||||||
// chrome?.runtime?.sendMessage(
|
|
||||||
// {
|
|
||||||
// action: "notification",
|
|
||||||
// payload: {
|
|
||||||
// },
|
|
||||||
// },
|
|
||||||
// (response) => {
|
|
||||||
// console.log({ response });
|
|
||||||
// if (!response?.error) {
|
|
||||||
|
|
||||||
// }
|
|
||||||
|
|
||||||
// }
|
|
||||||
// );
|
|
||||||
// audio.play();
|
|
||||||
// lastGroupNotification.current = Date.now()
|
|
||||||
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
// } catch (error) {
|
|
||||||
// console.log('error not', error)
|
|
||||||
// if(!isFocusedRef.current){
|
|
||||||
// chrome?.runtime?.sendMessage(
|
|
||||||
// {
|
|
||||||
// action: "notification",
|
|
||||||
// payload: {
|
|
||||||
// },
|
|
||||||
// },
|
|
||||||
// (response) => {
|
|
||||||
// console.log({ response });
|
|
||||||
// if (!response?.error) {
|
|
||||||
|
|
||||||
// }
|
|
||||||
|
|
||||||
// }
|
|
||||||
// );
|
|
||||||
// audio.play();
|
|
||||||
// lastGroupNotification.current = Date.now()
|
|
||||||
// }
|
|
||||||
|
|
||||||
// } finally {
|
|
||||||
|
|
||||||
// chrome?.runtime?.sendMessage(
|
|
||||||
// {
|
|
||||||
// action: "setChatHeads",
|
|
||||||
// payload: {
|
|
||||||
// data,
|
|
||||||
// },
|
|
||||||
// }
|
|
||||||
// );
|
|
||||||
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
const getAdmins = async (groupId) => {
|
const getAdmins = async (groupId) => {
|
||||||
try {
|
try {
|
||||||
|
@ -48,20 +48,7 @@ export const GroupJoinRequests = ({ myAddress, groups, setOpenManageMembers, get
|
|||||||
return true
|
return true
|
||||||
})
|
})
|
||||||
|
|
||||||
// const getJoinGroupRequests = groupsAsAdmin.map(async (group)=> {
|
|
||||||
// console.log('getJoinGroupRequests', group)
|
|
||||||
// const joinRequestResponse = await requestQueueGroupJoinRequests.enqueue(()=> {
|
|
||||||
// return fetch(
|
|
||||||
// `${getBaseApiReact()}/groups/joinrequests/${group.groupId}`
|
|
||||||
// );
|
|
||||||
// })
|
|
||||||
|
|
||||||
// const joinRequestData = await joinRequestResponse.json()
|
|
||||||
// return {
|
|
||||||
// group,
|
|
||||||
// data: joinRequestData
|
|
||||||
// }
|
|
||||||
// })
|
|
||||||
await Promise.all(getAllGroupsAsAdmin)
|
await Promise.all(getAllGroupsAsAdmin)
|
||||||
const res = await Promise.all(groupsAsAdmin.map(async (group)=> {
|
const res = await Promise.all(groupsAsAdmin.map(async (group)=> {
|
||||||
|
|
||||||
|
@ -20,6 +20,10 @@ import { MessagingIcon } from "../../assets/Icons/MessagingIcon";
|
|||||||
import { MessagingIcon2 } from "../../assets/Icons/MessagingIcon2";
|
import { MessagingIcon2 } from "../../assets/Icons/MessagingIcon2";
|
||||||
import { HubsIcon } from "../../assets/Icons/HubsIcon";
|
import { HubsIcon } from "../../assets/Icons/HubsIcon";
|
||||||
import { Save } from "../Save/Save";
|
import { Save } from "../Save/Save";
|
||||||
|
import CloseFullscreenIcon from '@mui/icons-material/CloseFullscreen';
|
||||||
|
import { useRecoilState } from "recoil";
|
||||||
|
import { fullScreenAtom, hasSettingsChangedAtom } from "../../atoms/global";
|
||||||
|
import { useAppFullScreen } from "../../useAppFullscreen";
|
||||||
|
|
||||||
const Header = ({
|
const Header = ({
|
||||||
logoutFunc,
|
logoutFunc,
|
||||||
@ -33,16 +37,11 @@ const Header = ({
|
|||||||
myName,
|
myName,
|
||||||
setSelectedDirect,
|
setSelectedDirect,
|
||||||
setNewChat
|
setNewChat
|
||||||
// selectedGroup,
|
|
||||||
// onHomeClick,
|
|
||||||
// onLogoutClick,
|
|
||||||
// onGroupChange,
|
|
||||||
// onWalletClick,
|
|
||||||
// onNotificationClick,
|
|
||||||
}) => {
|
}) => {
|
||||||
const [anchorEl, setAnchorEl] = useState(null);
|
const [anchorEl, setAnchorEl] = useState(null);
|
||||||
const open = Boolean(anchorEl);
|
const open = Boolean(anchorEl);
|
||||||
|
const [fullScreen, setFullScreen] = useRecoilState(fullScreenAtom);
|
||||||
|
const {exitFullScreen} = useAppFullScreen(setFullScreen)
|
||||||
const handleClick = (event) => {
|
const handleClick = (event) => {
|
||||||
setAnchorEl(event.currentTarget);
|
setAnchorEl(event.currentTarget);
|
||||||
};
|
};
|
||||||
@ -77,10 +76,10 @@ const Header = ({
|
|||||||
width: "75px",
|
width: "75px",
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<IconButton
|
<ButtonBase
|
||||||
edge="start"
|
|
||||||
color="inherit"
|
|
||||||
aria-label="home"
|
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
setMobileViewModeKeepOpen("");
|
setMobileViewModeKeepOpen("");
|
||||||
goToHome();
|
goToHome();
|
||||||
@ -88,15 +87,24 @@ const Header = ({
|
|||||||
// onClick={onHomeClick}
|
// onClick={onHomeClick}
|
||||||
>
|
>
|
||||||
<HomeIcon height={20} width={27} color="rgba(145, 145, 147, 1)" />
|
<HomeIcon height={20} width={27} color="rgba(145, 145, 147, 1)" />
|
||||||
</IconButton>
|
</ButtonBase>
|
||||||
<IconButton
|
<ButtonBase
|
||||||
edge="start"
|
|
||||||
color="inherit"
|
|
||||||
aria-label="home"
|
|
||||||
onClick={handleClick}
|
onClick={handleClick}
|
||||||
>
|
>
|
||||||
<NotificationIcon height={20} width={21} color={hasUnreadDirects || hasUnreadGroups ? "var(--unread)" : "rgba(145, 145, 147, 1)"} />
|
<NotificationIcon height={20} width={21} color={hasUnreadDirects || hasUnreadGroups ? "var(--unread)" : "rgba(145, 145, 147, 1)"} />
|
||||||
</IconButton>
|
</ButtonBase>
|
||||||
|
{fullScreen && (
|
||||||
|
<ButtonBase onClick={()=> {
|
||||||
|
exitFullScreen()
|
||||||
|
setFullScreen(false)
|
||||||
|
}}>
|
||||||
|
<CloseFullscreenIcon sx={{
|
||||||
|
color: 'rgba(145, 145, 147, 1)'
|
||||||
|
}} />
|
||||||
|
</ButtonBase>
|
||||||
|
)}
|
||||||
|
|
||||||
</Box>
|
</Box>
|
||||||
|
|
||||||
{/* Center Title */}
|
{/* Center Title */}
|
||||||
@ -254,6 +262,16 @@ const Header = ({
|
|||||||
>
|
>
|
||||||
<HomeIcon color="rgba(145, 145, 147, 1)" />
|
<HomeIcon color="rgba(145, 145, 147, 1)" />
|
||||||
</ButtonBase>
|
</ButtonBase>
|
||||||
|
{fullScreen && (
|
||||||
|
<ButtonBase onClick={()=> {
|
||||||
|
exitFullScreen()
|
||||||
|
setFullScreen(false)
|
||||||
|
}}>
|
||||||
|
<CloseFullscreenIcon sx={{
|
||||||
|
color: 'rgba(145, 145, 147, 1)'
|
||||||
|
}} />
|
||||||
|
</ButtonBase>
|
||||||
|
)}
|
||||||
</Box>
|
</Box>
|
||||||
{/* Center Title */}
|
{/* Center Title */}
|
||||||
<Typography
|
<Typography
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import React, { useContext, useMemo, useState } from 'react'
|
import React, { useContext, useEffect, useMemo, useState } from 'react'
|
||||||
import { useRecoilState } from 'recoil';
|
import { useRecoilState, useSetRecoilState } from 'recoil';
|
||||||
import isEqual from 'lodash/isEqual'; // Import deep comparison utility
|
import isEqual from 'lodash/isEqual'; // Import deep comparison utility
|
||||||
import { canSaveSettingToQdnAtom, oldPinnedAppsAtom, settingsLocalLastUpdatedAtom, settingsQDNLastUpdatedAtom, sortablePinnedAppsAtom } from '../../atoms/global';
|
import { canSaveSettingToQdnAtom, hasSettingsChangedAtom, oldPinnedAppsAtom, settingsLocalLastUpdatedAtom, settingsQDNLastUpdatedAtom, sortablePinnedAppsAtom } from '../../atoms/global';
|
||||||
import { ButtonBase } from '@mui/material';
|
import { ButtonBase } from '@mui/material';
|
||||||
import { objectToBase64 } from '../../qdn/encryption/group-encryption';
|
import { objectToBase64 } from '../../qdn/encryption/group-encryption';
|
||||||
import { MyContext } from '../../App';
|
import { MyContext } from '../../App';
|
||||||
@ -12,13 +12,14 @@ export const Save = () => {
|
|||||||
const [pinnedApps, setPinnedApps] = useRecoilState(sortablePinnedAppsAtom);
|
const [pinnedApps, setPinnedApps] = useRecoilState(sortablePinnedAppsAtom);
|
||||||
const [settingsQdnLastUpdated, setSettingsQdnLastUpdated] = useRecoilState(settingsQDNLastUpdatedAtom);
|
const [settingsQdnLastUpdated, setSettingsQdnLastUpdated] = useRecoilState(settingsQDNLastUpdatedAtom);
|
||||||
const [settingsLocalLastUpdated] = useRecoilState(settingsLocalLastUpdatedAtom);
|
const [settingsLocalLastUpdated] = useRecoilState(settingsLocalLastUpdatedAtom);
|
||||||
|
const setHasSettingsChangedAtom = useSetRecoilState(hasSettingsChangedAtom);
|
||||||
|
|
||||||
const [canSave] = useRecoilState(canSaveSettingToQdnAtom);
|
const [canSave] = useRecoilState(canSaveSettingToQdnAtom);
|
||||||
const [openSnack, setOpenSnack] = useState(false);
|
const [openSnack, setOpenSnack] = useState(false);
|
||||||
const [isLoading, setIsLoading] = useState(false)
|
const [isLoading, setIsLoading] = useState(false)
|
||||||
const [infoSnack, setInfoSnack] = useState(null);
|
const [infoSnack, setInfoSnack] = useState(null);
|
||||||
const [oldPinnedApps, setOldPinnedApps] = useRecoilState(oldPinnedAppsAtom)
|
const [oldPinnedApps, setOldPinnedApps] = useRecoilState(oldPinnedAppsAtom)
|
||||||
console.log('oldpin', {oldPinnedApps, pinnedApps}, settingsQdnLastUpdated, settingsLocalLastUpdated, settingsQdnLastUpdated < settingsLocalLastUpdated,)
|
|
||||||
const { show } = useContext(MyContext);
|
const { show } = useContext(MyContext);
|
||||||
|
|
||||||
const hasChanged = useMemo(()=> {
|
const hasChanged = useMemo(()=> {
|
||||||
@ -38,11 +39,14 @@ export const Save = () => {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
console.log('!isEqual(oldChanges, newChanges)', !isEqual(oldChanges, newChanges))
|
|
||||||
if(settingsQdnLastUpdated === -100) return false
|
if(settingsQdnLastUpdated === -100) return false
|
||||||
return !isEqual(oldChanges, newChanges) && settingsQdnLastUpdated < settingsLocalLastUpdated
|
return !isEqual(oldChanges, newChanges) && settingsQdnLastUpdated < settingsLocalLastUpdated
|
||||||
}, [oldPinnedApps, pinnedApps, settingsQdnLastUpdated, settingsLocalLastUpdated])
|
}, [oldPinnedApps, pinnedApps, settingsQdnLastUpdated, settingsLocalLastUpdated])
|
||||||
|
|
||||||
|
useEffect(()=> {
|
||||||
|
setHasSettingsChangedAtom(hasChanged)
|
||||||
|
}, [hasChanged])
|
||||||
|
|
||||||
const saveToQdn = async ()=> {
|
const saveToQdn = async ()=> {
|
||||||
try {
|
try {
|
||||||
setIsLoading(true)
|
setIsLoading(true)
|
||||||
@ -64,7 +68,6 @@ export const Save = () => {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
(response) => {
|
(response) => {
|
||||||
console.log("response", response);
|
|
||||||
if (response.error) {
|
if (response.error) {
|
||||||
rej(response?.message);
|
rej(response?.message);
|
||||||
return;
|
return;
|
||||||
@ -102,7 +105,6 @@ export const Save = () => {
|
|||||||
}
|
}
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
console.log('saved', response)
|
|
||||||
if(response?.identifier){
|
if(response?.identifier){
|
||||||
setOldPinnedApps(pinnedApps)
|
setOldPinnedApps(pinnedApps)
|
||||||
setSettingsQdnLastUpdated(Date.now())
|
setSettingsQdnLastUpdated(Date.now())
|
||||||
@ -114,7 +116,6 @@ export const Save = () => {
|
|||||||
setOpenSnack(true);
|
setOpenSnack(true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
console.log('save encryptedData', encryptData)
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
setInfoSnack({
|
setInfoSnack({
|
||||||
type: "error",
|
type: "error",
|
||||||
@ -126,7 +127,6 @@ export const Save = () => {
|
|||||||
setIsLoading(false)
|
setIsLoading(false)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
console.log('settingsQdnLastUpdated', settingsQdnLastUpdated)
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<ButtonBase onClick={saveToQdn} disabled={!hasChanged || !canSave || isLoading || settingsQdnLastUpdated === -100}>
|
<ButtonBase onClick={saveToQdn} disabled={!hasChanged || !canSave || isLoading || settingsQdnLastUpdated === -100}>
|
||||||
|
@ -319,7 +319,6 @@ export const decodeBase64ForUIChatMessages = (messages)=> {
|
|||||||
if (decryptedKey) {
|
if (decryptedKey) {
|
||||||
// Decrypt the data using the symmetric key.
|
// Decrypt the data using the symmetric key.
|
||||||
const decryptedData = nacl.secretbox.open(encryptedData, nonce, decryptedKey)
|
const decryptedData = nacl.secretbox.open(encryptedData, nonce, decryptedKey)
|
||||||
console.log('decryptedData', decryptedData)
|
|
||||||
// If decryption was successful, decryptedData will not be null.
|
// If decryption was successful, decryptedData will not be null.
|
||||||
if (decryptedData) {
|
if (decryptedData) {
|
||||||
return decryptedData
|
return decryptedData
|
||||||
|
@ -61,25 +61,7 @@ export const publishData = async ({
|
|||||||
tag5,
|
tag5,
|
||||||
feeAmount
|
feeAmount
|
||||||
}: any) => {
|
}: any) => {
|
||||||
console.log({
|
|
||||||
registeredName,
|
|
||||||
file,
|
|
||||||
service,
|
|
||||||
identifier,
|
|
||||||
uploadType,
|
|
||||||
isBase64,
|
|
||||||
filename,
|
|
||||||
withFee,
|
|
||||||
title,
|
|
||||||
description,
|
|
||||||
category,
|
|
||||||
tag1,
|
|
||||||
tag2,
|
|
||||||
tag3,
|
|
||||||
tag4,
|
|
||||||
tag5,
|
|
||||||
feeAmount
|
|
||||||
})
|
|
||||||
const validateName = async (receiverName: string) => {
|
const validateName = async (receiverName: string) => {
|
||||||
return await reusableGet(`/names/${receiverName}`)
|
return await reusableGet(`/names/${receiverName}`)
|
||||||
}
|
}
|
||||||
@ -171,7 +153,6 @@ export const publishData = async ({
|
|||||||
fee = feeAmount
|
fee = feeAmount
|
||||||
} else if (withFee) {
|
} else if (withFee) {
|
||||||
const res = await getArbitraryFee()
|
const res = await getArbitraryFee()
|
||||||
console.log('res', res)
|
|
||||||
if (res.fee) {
|
if (res.fee) {
|
||||||
fee = res.fee
|
fee = res.fee
|
||||||
} else {
|
} else {
|
||||||
@ -180,7 +161,6 @@ export const publishData = async ({
|
|||||||
}
|
}
|
||||||
|
|
||||||
let transactionBytes = await uploadData(registeredName, file, fee)
|
let transactionBytes = await uploadData(registeredName, file, fee)
|
||||||
console.log('transactionBytes', transactionBytes)
|
|
||||||
if (!transactionBytes || transactionBytes.error) {
|
if (!transactionBytes || transactionBytes.error) {
|
||||||
throw new Error(transactionBytes?.message || 'Error when uploading')
|
throw new Error(transactionBytes?.message || 'Error when uploading')
|
||||||
} else if (transactionBytes.includes('Error 500 Internal Server Error')) {
|
} else if (transactionBytes.includes('Error 500 Internal Server Error')) {
|
||||||
@ -201,7 +181,6 @@ export const publishData = async ({
|
|||||||
}
|
}
|
||||||
|
|
||||||
const uploadData = async (registeredName: string, file:any, fee: number) => {
|
const uploadData = async (registeredName: string, file:any, fee: number) => {
|
||||||
console.log('uploadData', registeredName, file, fee)
|
|
||||||
|
|
||||||
let postBody = ''
|
let postBody = ''
|
||||||
let urlSuffix = ''
|
let urlSuffix = ''
|
||||||
@ -230,7 +209,6 @@ export const publishData = async ({
|
|||||||
}
|
}
|
||||||
|
|
||||||
let uploadDataUrl = `/arbitrary/${service}/${registeredName}${urlSuffix}`
|
let uploadDataUrl = `/arbitrary/${service}/${registeredName}${urlSuffix}`
|
||||||
console.log('uploadDataUrl', uploadDataUrl)
|
|
||||||
if (identifier?.trim().length > 0) {
|
if (identifier?.trim().length > 0) {
|
||||||
uploadDataUrl = `/arbitrary/${service}/${registeredName}/${identifier}${urlSuffix}`
|
uploadDataUrl = `/arbitrary/${service}/${registeredName}/${identifier}${urlSuffix}`
|
||||||
}
|
}
|
||||||
@ -273,7 +251,6 @@ export const publishData = async ({
|
|||||||
if (tag5 != null && tag5 != 'undefined') {
|
if (tag5 != null && tag5 != 'undefined') {
|
||||||
uploadDataUrl = uploadDataUrl + '&tags=' + encodeURIComponent(tag5)
|
uploadDataUrl = uploadDataUrl + '&tags=' + encodeURIComponent(tag5)
|
||||||
}
|
}
|
||||||
console.log('uploadDataUrl2', uploadDataUrl)
|
|
||||||
|
|
||||||
return await reusablePost(uploadDataUrl, postBody)
|
return await reusablePost(uploadDataUrl, postBody)
|
||||||
|
|
||||||
@ -282,7 +259,6 @@ export const publishData = async ({
|
|||||||
try {
|
try {
|
||||||
return await validate()
|
return await validate()
|
||||||
} catch (error: any) {
|
} catch (error: any) {
|
||||||
console.log('error2', error)
|
|
||||||
throw new Error(error?.message)
|
throw new Error(error?.message)
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -63,7 +63,6 @@ function getLocalStorage(key) {
|
|||||||
|
|
||||||
chrome?.runtime?.onMessage.addListener((request, sender, sendResponse) => {
|
chrome?.runtime?.onMessage.addListener((request, sender, sendResponse) => {
|
||||||
if (request) {
|
if (request) {
|
||||||
console.log('rquest', request)
|
|
||||||
const isFromExtension = request?.isExtension
|
const isFromExtension = request?.isExtension
|
||||||
switch (request.action) {
|
switch (request.action) {
|
||||||
case "GET_USER_ACCOUNT": {
|
case "GET_USER_ACCOUNT": {
|
||||||
@ -106,7 +105,7 @@ chrome?.runtime?.onMessage.addListener((request, sender, sendResponse) => {
|
|||||||
case "GET_LIST_ITEMS": {
|
case "GET_LIST_ITEMS": {
|
||||||
const data = request.payload;
|
const data = request.payload;
|
||||||
|
|
||||||
getListItems(data)
|
getListItems(data, isFromExtension)
|
||||||
.then((res) => {
|
.then((res) => {
|
||||||
sendResponse(res);
|
sendResponse(res);
|
||||||
})
|
})
|
||||||
@ -119,7 +118,7 @@ chrome?.runtime?.onMessage.addListener((request, sender, sendResponse) => {
|
|||||||
case "ADD_LIST_ITEMS": {
|
case "ADD_LIST_ITEMS": {
|
||||||
const data = request.payload;
|
const data = request.payload;
|
||||||
|
|
||||||
addListItems(data)
|
addListItems(data, isFromExtension)
|
||||||
.then((res) => {
|
.then((res) => {
|
||||||
sendResponse(res);
|
sendResponse(res);
|
||||||
})
|
})
|
||||||
@ -132,7 +131,7 @@ chrome?.runtime?.onMessage.addListener((request, sender, sendResponse) => {
|
|||||||
case "DELETE_LIST_ITEM": {
|
case "DELETE_LIST_ITEM": {
|
||||||
const data = request.payload;
|
const data = request.payload;
|
||||||
|
|
||||||
deleteListItems(data)
|
deleteListItems(data, isFromExtension)
|
||||||
.then((res) => {
|
.then((res) => {
|
||||||
sendResponse(res);
|
sendResponse(res);
|
||||||
})
|
})
|
||||||
@ -145,7 +144,7 @@ chrome?.runtime?.onMessage.addListener((request, sender, sendResponse) => {
|
|||||||
case "PUBLISH_QDN_RESOURCE": {
|
case "PUBLISH_QDN_RESOURCE": {
|
||||||
const data = request.payload;
|
const data = request.payload;
|
||||||
|
|
||||||
publishQDNResource(data, sender)
|
publishQDNResource(data, sender, isFromExtension)
|
||||||
.then((res) => {
|
.then((res) => {
|
||||||
sendResponse(res);
|
sendResponse(res);
|
||||||
})
|
})
|
||||||
@ -158,7 +157,7 @@ chrome?.runtime?.onMessage.addListener((request, sender, sendResponse) => {
|
|||||||
case "PUBLISH_MULTIPLE_QDN_RESOURCES": {
|
case "PUBLISH_MULTIPLE_QDN_RESOURCES": {
|
||||||
const data = request.payload;
|
const data = request.payload;
|
||||||
|
|
||||||
publishMultipleQDNResources(data, sender)
|
publishMultipleQDNResources(data, sender, isFromExtension)
|
||||||
.then((res) => {
|
.then((res) => {
|
||||||
sendResponse(res);
|
sendResponse(res);
|
||||||
})
|
})
|
||||||
@ -184,7 +183,7 @@ chrome?.runtime?.onMessage.addListener((request, sender, sendResponse) => {
|
|||||||
case "CREATE_POLL": {
|
case "CREATE_POLL": {
|
||||||
const data = request.payload;
|
const data = request.payload;
|
||||||
|
|
||||||
createPoll(data)
|
createPoll(data, isFromExtension)
|
||||||
.then((res) => {
|
.then((res) => {
|
||||||
sendResponse(res);
|
sendResponse(res);
|
||||||
})
|
})
|
||||||
@ -196,8 +195,7 @@ chrome?.runtime?.onMessage.addListener((request, sender, sendResponse) => {
|
|||||||
}
|
}
|
||||||
case "SEND_CHAT_MESSAGE": {
|
case "SEND_CHAT_MESSAGE": {
|
||||||
const data = request.payload;
|
const data = request.payload;
|
||||||
console.log('data', data)
|
sendChatMessage(data, isFromExtension)
|
||||||
sendChatMessage(data)
|
|
||||||
.then((res) => {
|
.then((res) => {
|
||||||
sendResponse(res);
|
sendResponse(res);
|
||||||
})
|
})
|
||||||
@ -210,7 +208,7 @@ chrome?.runtime?.onMessage.addListener((request, sender, sendResponse) => {
|
|||||||
case "JOIN_GROUP": {
|
case "JOIN_GROUP": {
|
||||||
const data = request.payload;
|
const data = request.payload;
|
||||||
|
|
||||||
joinGroup(data)
|
joinGroup(data, isFromExtension)
|
||||||
.then((res) => {
|
.then((res) => {
|
||||||
sendResponse(res);
|
sendResponse(res);
|
||||||
})
|
})
|
||||||
@ -223,7 +221,7 @@ chrome?.runtime?.onMessage.addListener((request, sender, sendResponse) => {
|
|||||||
case "SAVE_FILE": {
|
case "SAVE_FILE": {
|
||||||
const data = request.payload;
|
const data = request.payload;
|
||||||
|
|
||||||
saveFile(data, sender)
|
saveFile(data, sender, isFromExtension)
|
||||||
.then((res) => {
|
.then((res) => {
|
||||||
sendResponse(res);
|
sendResponse(res);
|
||||||
})
|
})
|
||||||
@ -236,7 +234,7 @@ chrome?.runtime?.onMessage.addListener((request, sender, sendResponse) => {
|
|||||||
case "DEPLOY_AT": {
|
case "DEPLOY_AT": {
|
||||||
const data = request.payload;
|
const data = request.payload;
|
||||||
|
|
||||||
deployAt(data)
|
deployAt(data, isFromExtension)
|
||||||
.then((res) => {
|
.then((res) => {
|
||||||
sendResponse(res);
|
sendResponse(res);
|
||||||
})
|
})
|
||||||
@ -249,7 +247,7 @@ chrome?.runtime?.onMessage.addListener((request, sender, sendResponse) => {
|
|||||||
case "GET_USER_WALLET": {
|
case "GET_USER_WALLET": {
|
||||||
const data = request.payload;
|
const data = request.payload;
|
||||||
|
|
||||||
getUserWallet(data)
|
getUserWallet(data, isFromExtension)
|
||||||
.then((res) => {
|
.then((res) => {
|
||||||
sendResponse(res);
|
sendResponse(res);
|
||||||
})
|
})
|
||||||
@ -262,7 +260,7 @@ chrome?.runtime?.onMessage.addListener((request, sender, sendResponse) => {
|
|||||||
case "GET_WALLET_BALANCE": {
|
case "GET_WALLET_BALANCE": {
|
||||||
const data = request.payload;
|
const data = request.payload;
|
||||||
|
|
||||||
getWalletBalance(data)
|
getWalletBalance(data, false, isFromExtension)
|
||||||
.then((res) => {
|
.then((res) => {
|
||||||
sendResponse(res);
|
sendResponse(res);
|
||||||
})
|
})
|
||||||
@ -276,7 +274,7 @@ chrome?.runtime?.onMessage.addListener((request, sender, sendResponse) => {
|
|||||||
case "GET_USER_WALLET_INFO": {
|
case "GET_USER_WALLET_INFO": {
|
||||||
const data = request.payload;
|
const data = request.payload;
|
||||||
|
|
||||||
getUserWalletInfo(data)
|
getUserWalletInfo(data, isFromExtension)
|
||||||
.then((res) => {
|
.then((res) => {
|
||||||
sendResponse(res);
|
sendResponse(res);
|
||||||
})
|
})
|
||||||
@ -414,7 +412,7 @@ chrome?.runtime?.onMessage.addListener((request, sender, sendResponse) => {
|
|||||||
case "SEND_COIN": {
|
case "SEND_COIN": {
|
||||||
const data = request.payload;
|
const data = request.payload;
|
||||||
|
|
||||||
sendCoin(data)
|
sendCoin(data, isFromExtension)
|
||||||
.then((res) => {
|
.then((res) => {
|
||||||
sendResponse(res);
|
sendResponse(res);
|
||||||
})
|
})
|
||||||
|
@ -38,7 +38,7 @@ const dgbFeePerByte = 0.00000010
|
|||||||
const rvnFeePerByte = 0.00001125
|
const rvnFeePerByte = 0.00001125
|
||||||
|
|
||||||
|
|
||||||
const _createPoll = async (pollName, pollDescription, options) => {
|
const _createPoll = async ({pollName, pollDescription, options}, isFromExtension) => {
|
||||||
const fee = await getFee("CREATE_POLL");
|
const fee = await getFee("CREATE_POLL");
|
||||||
|
|
||||||
const resPermission = await getUserPermission({
|
const resPermission = await getUserPermission({
|
||||||
@ -47,7 +47,7 @@ const _createPoll = async (pollName, pollDescription, options) => {
|
|||||||
text3: `Description: ${pollDescription}`,
|
text3: `Description: ${pollDescription}`,
|
||||||
text4: `Options: ${options?.join(", ")}`,
|
text4: `Options: ${options?.join(", ")}`,
|
||||||
fee: fee.fee,
|
fee: fee.fee,
|
||||||
});
|
}, isFromExtension);
|
||||||
const { accepted } = resPermission;
|
const { accepted } = resPermission;
|
||||||
|
|
||||||
if (accepted) {
|
if (accepted) {
|
||||||
@ -82,13 +82,13 @@ const _createPoll = async (pollName, pollDescription, options) => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const _deployAt = async (
|
const _deployAt = async (
|
||||||
name,
|
{name,
|
||||||
description,
|
description,
|
||||||
tags,
|
tags,
|
||||||
creationBytes,
|
creationBytes,
|
||||||
amount,
|
amount,
|
||||||
assetId,
|
assetId,
|
||||||
atType
|
atType}, isFromExtension
|
||||||
) => {
|
) => {
|
||||||
const fee = await getFee("DEPLOY_AT");
|
const fee = await getFee("DEPLOY_AT");
|
||||||
|
|
||||||
@ -97,7 +97,7 @@ const _deployAt = async (
|
|||||||
text2: `Name: ${name}`,
|
text2: `Name: ${name}`,
|
||||||
text3: `Description: ${description}`,
|
text3: `Description: ${description}`,
|
||||||
fee: fee.fee,
|
fee: fee.fee,
|
||||||
});
|
}, isFromExtension);
|
||||||
|
|
||||||
const { accepted } = resPermission;
|
const { accepted } = resPermission;
|
||||||
|
|
||||||
@ -172,7 +172,6 @@ const _voteOnPoll = async ({pollName, optionIndex, optionName}, isFromExtension)
|
|||||||
});
|
});
|
||||||
const signedBytes = Base58.encode(tx.signedBytes);
|
const signedBytes = Base58.encode(tx.signedBytes);
|
||||||
const res = await processTransactionVersion2(signedBytes);
|
const res = await processTransactionVersion2(signedBytes);
|
||||||
console.log('res', res)
|
|
||||||
if (!res?.signature)
|
if (!res?.signature)
|
||||||
throw new Error(res?.message || "Transaction was not able to be processed");
|
throw new Error(res?.message || "Transaction was not able to be processed");
|
||||||
return res;
|
return res;
|
||||||
@ -182,13 +181,11 @@ const _voteOnPoll = async ({pollName, optionIndex, optionName}, isFromExtension)
|
|||||||
};
|
};
|
||||||
|
|
||||||
function getFileFromContentScript(fileId, sender) {
|
function getFileFromContentScript(fileId, sender) {
|
||||||
console.log("sender", sender);
|
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
chrome.tabs.sendMessage(
|
chrome.tabs.sendMessage(
|
||||||
sender.tab.id,
|
sender.tab.id,
|
||||||
{ action: "getFileFromIndexedDB", fileId: fileId },
|
{ action: "getFileFromIndexedDB", fileId: fileId },
|
||||||
(response) => {
|
(response) => {
|
||||||
console.log("response2", response);
|
|
||||||
if (response && response.result) {
|
if (response && response.result) {
|
||||||
resolve(response.result);
|
resolve(response.result);
|
||||||
} else {
|
} else {
|
||||||
@ -199,7 +196,6 @@ function getFileFromContentScript(fileId, sender) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
function sendToSaveFilePicker(data, sender) {
|
function sendToSaveFilePicker(data, sender) {
|
||||||
console.log("sender", sender);
|
|
||||||
|
|
||||||
chrome.tabs.sendMessage(sender.tab.id, {
|
chrome.tabs.sendMessage(sender.tab.id, {
|
||||||
action: "SHOW_SAVE_FILE_PICKER",
|
action: "SHOW_SAVE_FILE_PICKER",
|
||||||
@ -239,7 +235,6 @@ async function getUserPermission(payload: any, isFromExtension?: boolean) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
console.log('isFromExtension', isFromExtension)
|
|
||||||
if(isFromExtension){
|
if(isFromExtension){
|
||||||
|
|
||||||
|
|
||||||
@ -253,7 +248,6 @@ async function getUserPermission(payload: any, isFromExtension?: boolean) {
|
|||||||
chrome.runtime.sendMessage(
|
chrome.runtime.sendMessage(
|
||||||
{ action: "QORTAL_REQUEST_PERMISSION", payload, isFromExtension },
|
{ action: "QORTAL_REQUEST_PERMISSION", payload, isFromExtension },
|
||||||
(response) => {
|
(response) => {
|
||||||
console.log("permission response", response);
|
|
||||||
if (response === undefined) return;
|
if (response === undefined) return;
|
||||||
clearTimeout(timeout); // Clear the timeout if we get a response
|
clearTimeout(timeout); // Clear the timeout if we get a response
|
||||||
|
|
||||||
@ -268,11 +262,9 @@ async function getUserPermission(payload: any, isFromExtension?: boolean) {
|
|||||||
}
|
}
|
||||||
await new Promise((res) => {
|
await new Promise((res) => {
|
||||||
const popupUrl = chrome.runtime.getURL("index.html?secondary=true");
|
const popupUrl = chrome.runtime.getURL("index.html?secondary=true");
|
||||||
console.log("popupUrl", popupUrl);
|
|
||||||
chrome.windows.getAll(
|
chrome.windows.getAll(
|
||||||
{ populate: true, windowTypes: ["popup"] },
|
{ populate: true, windowTypes: ["popup"] },
|
||||||
(windows) => {
|
(windows) => {
|
||||||
console.log("windows", windows);
|
|
||||||
// Attempt to find an existing popup window that has a tab with the correct URL
|
// Attempt to find an existing popup window that has a tab with the correct URL
|
||||||
const existingPopup = windows.find(
|
const existingPopup = windows.find(
|
||||||
(w) =>
|
(w) =>
|
||||||
@ -340,11 +332,9 @@ async function getUserPermission(payload: any, isFromExtension?: boolean) {
|
|||||||
}, 30000);
|
}, 30000);
|
||||||
|
|
||||||
// Send message to the content script to check focus
|
// Send message to the content script to check focus
|
||||||
console.log("send msg");
|
|
||||||
chrome.runtime.sendMessage(
|
chrome.runtime.sendMessage(
|
||||||
{ action: "QORTAL_REQUEST_PERMISSION", payload },
|
{ action: "QORTAL_REQUEST_PERMISSION", payload },
|
||||||
(response) => {
|
(response) => {
|
||||||
console.log("permission response", response);
|
|
||||||
if (response === undefined) return;
|
if (response === undefined) return;
|
||||||
clearTimeout(timeout); // Clear the timeout if we get a response
|
clearTimeout(timeout); // Clear the timeout if we get a response
|
||||||
|
|
||||||
@ -386,7 +376,6 @@ export const encryptData = async (data, sender) => {
|
|||||||
const parsedData = JSON.parse(resKeyPair);
|
const parsedData = JSON.parse(resKeyPair);
|
||||||
const privateKey = parsedData.privateKey;
|
const privateKey = parsedData.privateKey;
|
||||||
const userPublicKey = parsedData.publicKey;
|
const userPublicKey = parsedData.publicKey;
|
||||||
console.log('data', data)
|
|
||||||
|
|
||||||
const encryptDataResponse = encryptDataGroup({
|
const encryptDataResponse = encryptDataGroup({
|
||||||
data64,
|
data64,
|
||||||
@ -441,7 +430,7 @@ export const decryptData = async (data) => {
|
|||||||
throw new Error("Unable to decrypt");
|
throw new Error("Unable to decrypt");
|
||||||
};
|
};
|
||||||
|
|
||||||
export const getListItems = async (data) => {
|
export const getListItems = async (data, isFromExtension) => {
|
||||||
const localNodeAvailable = await isUsingLocal()
|
const localNodeAvailable = await isUsingLocal()
|
||||||
if(!localNodeAvailable) throw new Error('Please use your local node.')
|
if(!localNodeAvailable) throw new Error('Please use your local node.')
|
||||||
const requiredFields = ["list_name"];
|
const requiredFields = ["list_name"];
|
||||||
@ -474,7 +463,7 @@ export const getListItems = async (data) => {
|
|||||||
value: value,
|
value: value,
|
||||||
label: "Always allow lists to be retrieved automatically",
|
label: "Always allow lists to be retrieved automatically",
|
||||||
},
|
},
|
||||||
});
|
}, isFromExtension);
|
||||||
const { accepted, checkbox1 } = resPermission;
|
const { accepted, checkbox1 } = resPermission;
|
||||||
acceptedVar = accepted;
|
acceptedVar = accepted;
|
||||||
checkbox1Var = checkbox1;
|
checkbox1Var = checkbox1;
|
||||||
@ -483,20 +472,17 @@ export const getListItems = async (data) => {
|
|||||||
|
|
||||||
if (acceptedVar || skip) {
|
if (acceptedVar || skip) {
|
||||||
const url = await createEndpoint(`/lists/${data.list_name}`);
|
const url = await createEndpoint(`/lists/${data.list_name}`);
|
||||||
console.log("url", url);
|
|
||||||
const response = await fetch(url);
|
const response = await fetch(url);
|
||||||
console.log("response", response);
|
|
||||||
if (!response.ok) throw new Error("Failed to fetch");
|
if (!response.ok) throw new Error("Failed to fetch");
|
||||||
|
|
||||||
const list = await response.json();
|
const list = await response.json();
|
||||||
console.log("list", list);
|
|
||||||
return list;
|
return list;
|
||||||
} else {
|
} else {
|
||||||
throw new Error("User declined to share list");
|
throw new Error("User declined to share list");
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
export const addListItems = async (data) => {
|
export const addListItems = async (data, isFromExtension) => {
|
||||||
const localNodeAvailable = await isUsingLocal()
|
const localNodeAvailable = await isUsingLocal()
|
||||||
if(!localNodeAvailable) throw new Error('Please use your local node.')
|
if(!localNodeAvailable) throw new Error('Please use your local node.')
|
||||||
const requiredFields = ["list_name", "items"];
|
const requiredFields = ["list_name", "items"];
|
||||||
@ -519,12 +505,11 @@ export const addListItems = async (data) => {
|
|||||||
text1: "Do you give this application permission to",
|
text1: "Do you give this application permission to",
|
||||||
text2: `Add the following to the list ${list_name}:`,
|
text2: `Add the following to the list ${list_name}:`,
|
||||||
highlightedText: items.join(", "),
|
highlightedText: items.join(", "),
|
||||||
});
|
}, isFromExtension);
|
||||||
const { accepted } = resPermission;
|
const { accepted } = resPermission;
|
||||||
|
|
||||||
if (accepted) {
|
if (accepted) {
|
||||||
const url = await createEndpoint(`/lists/${list_name}`);
|
const url = await createEndpoint(`/lists/${list_name}`);
|
||||||
console.log("url", url);
|
|
||||||
const body = {
|
const body = {
|
||||||
items: items,
|
items: items,
|
||||||
};
|
};
|
||||||
@ -537,7 +522,6 @@ export const addListItems = async (data) => {
|
|||||||
body: bodyToString,
|
body: bodyToString,
|
||||||
});
|
});
|
||||||
|
|
||||||
console.log("response", response);
|
|
||||||
if (!response.ok) throw new Error("Failed to add to list");
|
if (!response.ok) throw new Error("Failed to add to list");
|
||||||
let res;
|
let res;
|
||||||
try {
|
try {
|
||||||
@ -551,7 +535,7 @@ export const addListItems = async (data) => {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
export const deleteListItems = async (data) => {
|
export const deleteListItems = async (data, isFromExtension) => {
|
||||||
const localNodeAvailable = await isUsingLocal()
|
const localNodeAvailable = await isUsingLocal()
|
||||||
if(!localNodeAvailable) throw new Error('Please use your local node.')
|
if(!localNodeAvailable) throw new Error('Please use your local node.')
|
||||||
const requiredFields = ["list_name", "item"];
|
const requiredFields = ["list_name", "item"];
|
||||||
@ -574,12 +558,11 @@ export const deleteListItems = async (data) => {
|
|||||||
text1: "Do you give this application permission to",
|
text1: "Do you give this application permission to",
|
||||||
text2: `Remove the following from the list ${list_name}:`,
|
text2: `Remove the following from the list ${list_name}:`,
|
||||||
highlightedText: item,
|
highlightedText: item,
|
||||||
});
|
}, isFromExtension);
|
||||||
const { accepted } = resPermission;
|
const { accepted } = resPermission;
|
||||||
|
|
||||||
if (accepted) {
|
if (accepted) {
|
||||||
const url = await createEndpoint(`/lists/${list_name}`);
|
const url = await createEndpoint(`/lists/${list_name}`);
|
||||||
console.log("url", url);
|
|
||||||
const body = {
|
const body = {
|
||||||
items: [item],
|
items: [item],
|
||||||
};
|
};
|
||||||
@ -592,7 +575,6 @@ export const deleteListItems = async (data) => {
|
|||||||
body: bodyToString,
|
body: bodyToString,
|
||||||
});
|
});
|
||||||
|
|
||||||
console.log("response", response);
|
|
||||||
if (!response.ok) throw new Error("Failed to add to list");
|
if (!response.ok) throw new Error("Failed to add to list");
|
||||||
let res;
|
let res;
|
||||||
try {
|
try {
|
||||||
@ -606,7 +588,7 @@ export const deleteListItems = async (data) => {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
export const publishQDNResource = async (data: any, sender) => {
|
export const publishQDNResource = async (data: any, sender, isFromExtension) => {
|
||||||
const requiredFields = ["service"];
|
const requiredFields = ["service"];
|
||||||
const missingFields: string[] = [];
|
const missingFields: string[] = [];
|
||||||
requiredFields.forEach((field) => {
|
requiredFields.forEach((field) => {
|
||||||
@ -683,7 +665,7 @@ export const publishQDNResource = async (data: any, sender) => {
|
|||||||
text3: `identifier: ${identifier || null}`,
|
text3: `identifier: ${identifier || null}`,
|
||||||
highlightedText: `isEncrypted: ${!!data.encrypt}`,
|
highlightedText: `isEncrypted: ${!!data.encrypt}`,
|
||||||
fee: fee.fee,
|
fee: fee.fee,
|
||||||
});
|
}, isFromExtension);
|
||||||
const { accepted } = resPermission;
|
const { accepted } = resPermission;
|
||||||
if (accepted) {
|
if (accepted) {
|
||||||
if (data.fileId && !data.encrypt) {
|
if (data.fileId && !data.encrypt) {
|
||||||
@ -718,7 +700,7 @@ export const publishQDNResource = async (data: any, sender) => {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
export const publishMultipleQDNResources = async (data: any, sender) => {
|
export const publishMultipleQDNResources = async (data: any, sender, isFromExtension) => {
|
||||||
const requiredFields = ["resources"];
|
const requiredFields = ["resources"];
|
||||||
const missingFields: string[] = [];
|
const missingFields: string[] = [];
|
||||||
let feeAmount = null;
|
let feeAmount = null;
|
||||||
@ -815,14 +797,12 @@ export const publishMultipleQDNResources = async (data: any, sender) => {
|
|||||||
`,
|
`,
|
||||||
highlightedText: `isEncrypted: ${!!data.encrypt}`,
|
highlightedText: `isEncrypted: ${!!data.encrypt}`,
|
||||||
fee: fee.fee * resources.length,
|
fee: fee.fee * resources.length,
|
||||||
});
|
}, isFromExtension);
|
||||||
const { accepted } = resPermission;
|
const { accepted } = resPermission;
|
||||||
console.log("accepted", accepted);
|
|
||||||
if (!accepted) {
|
if (!accepted) {
|
||||||
throw new Error("User declined request");
|
throw new Error("User declined request");
|
||||||
}
|
}
|
||||||
let failedPublishesIdentifiers = [];
|
let failedPublishesIdentifiers = [];
|
||||||
console.log("resources", resources);
|
|
||||||
for (const resource of resources) {
|
for (const resource of resources) {
|
||||||
try {
|
try {
|
||||||
const requiredFields = ["service"];
|
const requiredFields = ["service"];
|
||||||
@ -934,7 +914,6 @@ export const publishMultipleQDNResources = async (data: any, sender) => {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.log("error", error);
|
|
||||||
failedPublishesIdentifiers.push({
|
failedPublishesIdentifiers.push({
|
||||||
reason: "Unknown error",
|
reason: "Unknown error",
|
||||||
identifier: resource.identifier,
|
identifier: resource.identifier,
|
||||||
@ -990,7 +969,7 @@ export const voteOnPoll = async (data, isFromExtension) => {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
export const createPoll = async (data) => {
|
export const createPoll = async (data, isFromExtension) => {
|
||||||
const requiredFields = [
|
const requiredFields = [
|
||||||
"pollName",
|
"pollName",
|
||||||
"pollDescription",
|
"pollDescription",
|
||||||
@ -1014,10 +993,12 @@ export const createPoll = async (data) => {
|
|||||||
const pollOwnerAddress = data.pollOwnerAddress;
|
const pollOwnerAddress = data.pollOwnerAddress;
|
||||||
try {
|
try {
|
||||||
const resCreatePoll = await _createPoll(
|
const resCreatePoll = await _createPoll(
|
||||||
|
{
|
||||||
pollName,
|
pollName,
|
||||||
pollDescription,
|
pollDescription,
|
||||||
pollOptions,
|
options: pollOptions,
|
||||||
pollOwnerAddress
|
},
|
||||||
|
isFromExtension
|
||||||
);
|
);
|
||||||
return resCreatePoll;
|
return resCreatePoll;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
@ -1025,7 +1006,7 @@ export const createPoll = async (data) => {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
export const sendChatMessage = async (data) => {
|
export const sendChatMessage = async (data, isFromExtension) => {
|
||||||
const message = data.message;
|
const message = data.message;
|
||||||
const recipient = data.destinationAddress;
|
const recipient = data.destinationAddress;
|
||||||
const groupId = data.groupId;
|
const groupId = data.groupId;
|
||||||
@ -1034,7 +1015,7 @@ export const sendChatMessage = async (data) => {
|
|||||||
text1: "Do you give this application permission to send this chat message?",
|
text1: "Do you give this application permission to send this chat message?",
|
||||||
text2: `To: ${isRecipient ? recipient : `group ${groupId}`}`,
|
text2: `To: ${isRecipient ? recipient : `group ${groupId}`}`,
|
||||||
text3: `${message?.slice(0, 25)}${message?.length > 25 ? "..." : ""}`,
|
text3: `${message?.slice(0, 25)}${message?.length > 25 ? "..." : ""}`,
|
||||||
});
|
}, isFromExtension);
|
||||||
|
|
||||||
const { accepted } = resPermission;
|
const { accepted } = resPermission;
|
||||||
if (accepted) {
|
if (accepted) {
|
||||||
@ -1058,11 +1039,7 @@ export const sendChatMessage = async (data) => {
|
|||||||
repliedTo: "",
|
repliedTo: "",
|
||||||
version: 3,
|
version: 3,
|
||||||
};
|
};
|
||||||
try {
|
|
||||||
JSON.stringify(messageObject);
|
|
||||||
} catch (error) {
|
|
||||||
console.log("my error", error);
|
|
||||||
}
|
|
||||||
const stringifyMessageObject = JSON.stringify(messageObject);
|
const stringifyMessageObject = JSON.stringify(messageObject);
|
||||||
|
|
||||||
const balance = await getBalanceInfo();
|
const balance = await getBalanceInfo();
|
||||||
@ -1088,7 +1065,6 @@ export const sendChatMessage = async (data) => {
|
|||||||
// Otherwise, treat it as plain text
|
// Otherwise, treat it as plain text
|
||||||
res = await response.text();
|
res = await response.text();
|
||||||
}
|
}
|
||||||
console.log("res", res);
|
|
||||||
if (res?.error === 102) {
|
if (res?.error === 102) {
|
||||||
key = "";
|
key = "";
|
||||||
hasPublicKey = false;
|
hasPublicKey = false;
|
||||||
@ -1198,7 +1174,7 @@ export const sendChatMessage = async (data) => {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
export const joinGroup = async (data) => {
|
export const joinGroup = async (data, isFromExtension) => {
|
||||||
const requiredFields = ["groupId"];
|
const requiredFields = ["groupId"];
|
||||||
const missingFields: string[] = [];
|
const missingFields: string[] = [];
|
||||||
requiredFields.forEach((field) => {
|
requiredFields.forEach((field) => {
|
||||||
@ -1228,7 +1204,7 @@ export const joinGroup = async (data) => {
|
|||||||
text1: "Confirm joining the group:",
|
text1: "Confirm joining the group:",
|
||||||
highlightedText: `${groupInfo.groupName}`,
|
highlightedText: `${groupInfo.groupName}`,
|
||||||
fee: fee.fee,
|
fee: fee.fee,
|
||||||
});
|
}, isFromExtension);
|
||||||
const { accepted } = resPermission;
|
const { accepted } = resPermission;
|
||||||
|
|
||||||
if (accepted) {
|
if (accepted) {
|
||||||
@ -1249,9 +1225,8 @@ export const joinGroup = async (data) => {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
export const saveFile = async (data, sender) => {
|
export const saveFile = async (data, sender, isFromExtension) => {
|
||||||
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) => {
|
||||||
@ -1270,7 +1245,7 @@ export const saveFile = async (data, sender) => {
|
|||||||
const resPermission = await getUserPermission({
|
const resPermission = await getUserPermission({
|
||||||
text1: "Would you like to download:",
|
text1: "Would you like to download:",
|
||||||
highlightedText: `${filename}`,
|
highlightedText: `${filename}`,
|
||||||
});
|
}, isFromExtension);
|
||||||
const { accepted } = resPermission;
|
const { accepted } = resPermission;
|
||||||
|
|
||||||
if (accepted) {
|
if (accepted) {
|
||||||
@ -1314,7 +1289,7 @@ export const saveFile = async (data, sender) => {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
export const deployAt = async (data) => {
|
export const deployAt = async (data, isFromExtension) => {
|
||||||
const requiredFields = [
|
const requiredFields = [
|
||||||
"name",
|
"name",
|
||||||
"description",
|
"description",
|
||||||
@ -1337,13 +1312,16 @@ export const deployAt = async (data) => {
|
|||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
const resDeployAt = await _deployAt(
|
const resDeployAt = await _deployAt(
|
||||||
data.name,
|
{
|
||||||
data.description,
|
name: data.name,
|
||||||
data.tags,
|
description: data.description,
|
||||||
data.creationBytes,
|
tags: data.tags,
|
||||||
data.amount,
|
creationBytes: data.creationBytes,
|
||||||
data.assetId,
|
amount: data.amount,
|
||||||
data.type
|
assetId: data.assetId,
|
||||||
|
atType: data.type
|
||||||
|
},
|
||||||
|
isFromExtension
|
||||||
);
|
);
|
||||||
return resDeployAt;
|
return resDeployAt;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
@ -1351,7 +1329,7 @@ export const deployAt = async (data) => {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
export const getUserWallet = async (data) => {
|
export const getUserWallet = async (data, isFromExtension) => {
|
||||||
const requiredFields = ["coin"];
|
const requiredFields = ["coin"];
|
||||||
const missingFields: string[] = [];
|
const missingFields: string[] = [];
|
||||||
requiredFields.forEach((field) => {
|
requiredFields.forEach((field) => {
|
||||||
@ -1367,7 +1345,7 @@ export const getUserWallet = async (data) => {
|
|||||||
const resPermission = await getUserPermission({
|
const resPermission = await getUserPermission({
|
||||||
text1:
|
text1:
|
||||||
"Do you give this application permission to get your wallet information?",
|
"Do you give this application permission to get your wallet information?",
|
||||||
});
|
}, isFromExtension);
|
||||||
const { accepted } = resPermission;
|
const { accepted } = resPermission;
|
||||||
|
|
||||||
if (accepted) {
|
if (accepted) {
|
||||||
@ -1437,7 +1415,7 @@ export const getUserWallet = async (data) => {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
export const getWalletBalance = async (data, bypassPermission?: boolean) => {
|
export const getWalletBalance = async (data, bypassPermission?: boolean, isFromExtension) => {
|
||||||
const requiredFields = ["coin"];
|
const requiredFields = ["coin"];
|
||||||
const missingFields: string[] = [];
|
const missingFields: string[] = [];
|
||||||
requiredFields.forEach((field) => {
|
requiredFields.forEach((field) => {
|
||||||
@ -1456,7 +1434,7 @@ export const getWalletBalance = async (data, bypassPermission?: boolean) => {
|
|||||||
resPermission = await getUserPermission({
|
resPermission = await getUserPermission({
|
||||||
text1: "Do you give this application permission to fetch your",
|
text1: "Do you give this application permission to fetch your",
|
||||||
highlightedText: `${data.coin} balance`,
|
highlightedText: `${data.coin} balance`,
|
||||||
});
|
}, isFromExtension);
|
||||||
} else {
|
} else {
|
||||||
resPermission = {
|
resPermission = {
|
||||||
accepted: false
|
accepted: false
|
||||||
@ -1558,7 +1536,6 @@ const getUserWalletFunc = async (coin) => {
|
|||||||
const address = wallet.address0;
|
const address = wallet.address0;
|
||||||
const resKeyPair = await getKeyPair();
|
const resKeyPair = await getKeyPair();
|
||||||
const parsedData = JSON.parse(resKeyPair);
|
const parsedData = JSON.parse(resKeyPair);
|
||||||
console.log('coin', coin)
|
|
||||||
switch (coin) {
|
switch (coin) {
|
||||||
case "QORT":
|
case "QORT":
|
||||||
userWallet["address"] = address;
|
userWallet["address"] = address;
|
||||||
@ -1592,7 +1569,7 @@ const getUserWalletFunc = async (coin) => {
|
|||||||
return userWallet;
|
return userWallet;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const getUserWalletInfo = async (data) => {
|
export const getUserWalletInfo = async (data, isFromExtension) => {
|
||||||
const requiredFields = ["coin"];
|
const requiredFields = ["coin"];
|
||||||
const missingFields: string[] = [];
|
const missingFields: string[] = [];
|
||||||
requiredFields.forEach((field) => {
|
requiredFields.forEach((field) => {
|
||||||
@ -1607,14 +1584,12 @@ export const getUserWalletInfo = async (data) => {
|
|||||||
}
|
}
|
||||||
const resPermission = await getUserPermission({
|
const resPermission = await getUserPermission({
|
||||||
text1: "Do you give this application permission to retrieve your wallet information",
|
text1: "Do you give this application permission to retrieve your wallet information",
|
||||||
});
|
}, isFromExtension);
|
||||||
const { accepted } = resPermission;
|
const { accepted } = resPermission;
|
||||||
|
|
||||||
if (accepted) {
|
if (accepted) {
|
||||||
let coin = data.coin;
|
let coin = data.coin;
|
||||||
let walletKeys = await getUserWalletFunc(coin);
|
let walletKeys = await getUserWalletFunc(coin);
|
||||||
console.log('walletKeys', walletKeys)
|
|
||||||
console.log('walletKeys["publickey"]', walletKeys["publickey"])
|
|
||||||
const _url = await createEndpoint(
|
const _url = await createEndpoint(
|
||||||
`/crosschain/` + data.coin.toLowerCase() + `/addressinfos`
|
`/crosschain/` + data.coin.toLowerCase() + `/addressinfos`
|
||||||
);
|
);
|
||||||
@ -2076,7 +2051,7 @@ export const getTxActivitySummary = async (data) => {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
export const sendCoin = async (data) => {
|
export const sendCoin = async (data, isFromExtension) => {
|
||||||
const requiredFields = ['coin', 'destinationAddress', 'amount']
|
const requiredFields = ['coin', 'destinationAddress', 'amount']
|
||||||
const missingFields: string[] = []
|
const missingFields: string[] = []
|
||||||
requiredFields.forEach((field) => {
|
requiredFields.forEach((field) => {
|
||||||
@ -2105,9 +2080,7 @@ export const sendCoin = async (data) => {
|
|||||||
const recipient = data.destinationAddress
|
const recipient = data.destinationAddress
|
||||||
|
|
||||||
const url = await createEndpoint(`/addresses/balance/${address}`);
|
const url = await createEndpoint(`/addresses/balance/${address}`);
|
||||||
console.log("url", url);
|
|
||||||
const response = await fetch(url);
|
const response = await fetch(url);
|
||||||
console.log("response", response);
|
|
||||||
if (!response.ok) throw new Error("Failed to fetch");
|
if (!response.ok) throw new Error("Failed to fetch");
|
||||||
let walletBalance;
|
let walletBalance;
|
||||||
try {
|
try {
|
||||||
@ -2141,7 +2114,7 @@ export const sendCoin = async (data) => {
|
|||||||
text1: "Do you give this application permission to send coins?",
|
text1: "Do you give this application permission to send coins?",
|
||||||
text2: `To: ${recipient}`,
|
text2: `To: ${recipient}`,
|
||||||
highlightedText: `${amount} ${checkCoin}`,
|
highlightedText: `${amount} ${checkCoin}`,
|
||||||
});
|
}, isFromExtension);
|
||||||
const { accepted } = resPermission;
|
const { accepted } = resPermission;
|
||||||
|
|
||||||
if (accepted) {
|
if (accepted) {
|
||||||
@ -2174,7 +2147,7 @@ export const sendCoin = async (data) => {
|
|||||||
text2: `To: ${recipient}`,
|
text2: `To: ${recipient}`,
|
||||||
highlightedText: `${amount} ${checkCoin}`,
|
highlightedText: `${amount} ${checkCoin}`,
|
||||||
fee: fee
|
fee: fee
|
||||||
});
|
}, isFromExtension);
|
||||||
const { accepted } = resPermission;
|
const { accepted } = resPermission;
|
||||||
|
|
||||||
if (accepted) {
|
if (accepted) {
|
||||||
@ -2231,7 +2204,7 @@ export const sendCoin = async (data) => {
|
|||||||
text2: `To: ${recipient}`,
|
text2: `To: ${recipient}`,
|
||||||
highlightedText: `${amount} ${checkCoin}`,
|
highlightedText: `${amount} ${checkCoin}`,
|
||||||
fee: fee
|
fee: fee
|
||||||
});
|
}, isFromExtension);
|
||||||
const { accepted } = resPermission;
|
const { accepted } = resPermission;
|
||||||
|
|
||||||
if (accepted) {
|
if (accepted) {
|
||||||
@ -2288,7 +2261,7 @@ export const sendCoin = async (data) => {
|
|||||||
text2: `To: ${recipient}`,
|
text2: `To: ${recipient}`,
|
||||||
highlightedText: `${amount} ${checkCoin}`,
|
highlightedText: `${amount} ${checkCoin}`,
|
||||||
fee: fee
|
fee: fee
|
||||||
});
|
}, isFromExtension);
|
||||||
const { accepted } = resPermission;
|
const { accepted } = resPermission;
|
||||||
|
|
||||||
if (accepted) {
|
if (accepted) {
|
||||||
@ -2343,7 +2316,7 @@ export const sendCoin = async (data) => {
|
|||||||
text2: `To: ${recipient}`,
|
text2: `To: ${recipient}`,
|
||||||
highlightedText: `${amount} ${checkCoin}`,
|
highlightedText: `${amount} ${checkCoin}`,
|
||||||
fee: fee
|
fee: fee
|
||||||
});
|
}, isFromExtension);
|
||||||
const { accepted } = resPermission;
|
const { accepted } = resPermission;
|
||||||
|
|
||||||
if (accepted) {
|
if (accepted) {
|
||||||
@ -2401,7 +2374,7 @@ export const sendCoin = async (data) => {
|
|||||||
text2: `To: ${recipient}`,
|
text2: `To: ${recipient}`,
|
||||||
highlightedText: `${amount} ${checkCoin}`,
|
highlightedText: `${amount} ${checkCoin}`,
|
||||||
fee: fee
|
fee: fee
|
||||||
});
|
}, isFromExtension);
|
||||||
const { accepted } = resPermission;
|
const { accepted } = resPermission;
|
||||||
|
|
||||||
if (accepted) {
|
if (accepted) {
|
||||||
@ -2455,7 +2428,7 @@ export const sendCoin = async (data) => {
|
|||||||
text2: `To: ${recipient}`,
|
text2: `To: ${recipient}`,
|
||||||
highlightedText: `${amount} ${checkCoin}`,
|
highlightedText: `${amount} ${checkCoin}`,
|
||||||
fee: fee
|
fee: fee
|
||||||
});
|
}, isFromExtension);
|
||||||
const { accepted } = resPermission;
|
const { accepted } = resPermission;
|
||||||
|
|
||||||
if (accepted) {
|
if (accepted) {
|
||||||
|
65
src/useAppFullscreen.tsx
Normal file
65
src/useAppFullscreen.tsx
Normal file
@ -0,0 +1,65 @@
|
|||||||
|
import { useCallback, useEffect } from 'react';
|
||||||
|
|
||||||
|
export const useAppFullScreen = (setFullScreen) => {
|
||||||
|
const enterFullScreen = useCallback(() => {
|
||||||
|
const element = document.documentElement; // Target the entire HTML document
|
||||||
|
if (element.requestFullscreen) {
|
||||||
|
element.requestFullscreen();
|
||||||
|
} else if (element.mozRequestFullScreen) { // Firefox
|
||||||
|
element.mozRequestFullScreen();
|
||||||
|
} else if (element.webkitRequestFullscreen) { // Chrome, Safari and Opera
|
||||||
|
element.webkitRequestFullscreen();
|
||||||
|
} else if (element.msRequestFullscreen) { // IE/Edge
|
||||||
|
element.msRequestFullscreen();
|
||||||
|
}
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
const exitFullScreen = useCallback(() => {
|
||||||
|
if (document.fullscreenElement) {
|
||||||
|
document.exitFullscreen();
|
||||||
|
} else if (document.mozFullScreenElement) {
|
||||||
|
document.mozCancelFullScreen();
|
||||||
|
} else if (document.webkitFullscreenElement) {
|
||||||
|
document.webkitExitFullscreen();
|
||||||
|
} else if (document.msFullscreenElement) {
|
||||||
|
document.msExitFullscreen();
|
||||||
|
}
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
const toggleFullScreen = useCallback(() => {
|
||||||
|
if (document.fullscreenElement || document.mozFullScreenElement || document.webkitFullscreenElement || document.msFullscreenElement) {
|
||||||
|
exitFullScreen();
|
||||||
|
setFullScreen(false)
|
||||||
|
} else {
|
||||||
|
enterFullScreen();
|
||||||
|
setFullScreen(true)
|
||||||
|
}
|
||||||
|
}, [enterFullScreen, exitFullScreen]);
|
||||||
|
|
||||||
|
// Listen for changes to fullscreen state
|
||||||
|
useEffect(() => {
|
||||||
|
const handleFullScreenChange = () => {
|
||||||
|
if (document.fullscreenElement || document.mozFullScreenElement || document.webkitFullscreenElement || document.msFullscreenElement) {
|
||||||
|
|
||||||
|
} else {
|
||||||
|
setFullScreen(false);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
document.addEventListener('fullscreenchange', handleFullScreenChange);
|
||||||
|
document.addEventListener('webkitfullscreenchange', handleFullScreenChange); // Safari
|
||||||
|
document.addEventListener('mozfullscreenchange', handleFullScreenChange); // Firefox
|
||||||
|
document.addEventListener('MSFullscreenChange', handleFullScreenChange); // IE/Edge
|
||||||
|
|
||||||
|
return () => {
|
||||||
|
document.removeEventListener('fullscreenchange', handleFullScreenChange);
|
||||||
|
document.removeEventListener('webkitfullscreenchange', handleFullScreenChange);
|
||||||
|
document.removeEventListener('mozfullscreenchange', handleFullScreenChange);
|
||||||
|
document.removeEventListener('MSFullscreenChange', handleFullScreenChange);
|
||||||
|
};
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
return { enterFullScreen, exitFullScreen, toggleFullScreen };
|
||||||
|
};
|
||||||
|
|
||||||
|
|
@ -65,7 +65,6 @@ export const useQortalGetSaveSettings = (myName) => {
|
|||||||
const {hasPublishRecord, timestamp} = await getPublishRecord(myName)
|
const {hasPublishRecord, timestamp} = await getPublishRecord(myName)
|
||||||
if(hasPublishRecord){
|
if(hasPublishRecord){
|
||||||
const settings = await getPublish(myName)
|
const settings = await getPublish(myName)
|
||||||
console.log('settings', settings, timestamp, settingsLocalLastUpdated )
|
|
||||||
if(settings?.sortablePinnedApps && timestamp > settingsLocalLastUpdated){
|
if(settings?.sortablePinnedApps && timestamp > settingsLocalLastUpdated){
|
||||||
setSortablePinnedApps(settings.sortablePinnedApps)
|
setSortablePinnedApps(settings.sortablePinnedApps)
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user