enlarge back btn, increased qr timeout to 60secs

This commit is contained in:
PhilReact 2025-04-07 21:20:29 +03:00
parent 15f6acfda1
commit 63c96f5ea0
8 changed files with 262 additions and 14 deletions

View File

@ -19,6 +19,7 @@ import {
DialogContent, DialogContent,
DialogContentText, DialogContentText,
DialogTitle, DialogTitle,
FormControlLabel,
Input, Input,
InputLabel, InputLabel,
Popover, Popover,
@ -48,6 +49,7 @@ import CloseIcon from "@mui/icons-material/Close";
import './utils/seedPhrase/RandomSentenceGenerator'; import './utils/seedPhrase/RandomSentenceGenerator';
import EngineeringIcon from '@mui/icons-material/Engineering'; import EngineeringIcon from '@mui/icons-material/Engineering';
import AccountBalanceWalletIcon from '@mui/icons-material/AccountBalanceWallet'; import AccountBalanceWalletIcon from '@mui/icons-material/AccountBalanceWallet';
import PriorityHighIcon from '@mui/icons-material/PriorityHigh';
import { import {
createAccount, createAccount,
generateRandomSentence, generateRandomSentence,
@ -427,6 +429,7 @@ function App() {
}); });
const [useLocalNode, setUseLocalNode] = useState(false); const [useLocalNode, setUseLocalNode] = useState(false);
const [confirmRequestRead, setConfirmRequestRead] = useState(false);
const [isSettingsOpen, setIsSettingsOpen] = useState(false); const [isSettingsOpen, setIsSettingsOpen] = useState(false);
const [showSeed, setShowSeed] = useState(false) const [showSeed, setShowSeed] = useState(false)
const [creationStep, setCreationStep] = useState(1) const [creationStep, setCreationStep] = useState(1)
@ -798,6 +801,7 @@ function App() {
qortalRequestCheckbox1Ref.current = qortalRequestCheckbox1Ref.current =
message?.payload?.checkbox1?.value || false; message?.payload?.checkbox1?.value || false;
} }
setConfirmRequestRead(false)
await showQortalRequestExtension(message?.payload); await showQortalRequestExtension(message?.payload);
if (qortalRequestCheckbox1Ref.current) { if (qortalRequestCheckbox1Ref.current) {
@ -2043,11 +2047,13 @@ function App() {
justifyContent: "flex-start", justifyContent: "flex-start",
paddingLeft: "22px", paddingLeft: "22px",
boxSizing: "border-box", boxSizing: "border-box",
maxWidth: '700px'
}} }}
> >
<img <img
style={{ style={{
cursor: "pointer", cursor: "pointer",
height: '24px'
}} }}
onClick={returnToMain} onClick={returnToMain}
src={Return} src={Return}
@ -2546,11 +2552,13 @@ function App() {
justifyContent: "flex-start", justifyContent: "flex-start",
paddingLeft: "22px", paddingLeft: "22px",
boxSizing: "border-box", boxSizing: "border-box",
maxWidth: '700px'
}} }}
> >
<img <img
style={{ style={{
cursor: "pointer", cursor: "pointer",
height: '24px'
}} }}
onClick={() => { onClick={() => {
setRawWallet(null); setRawWallet(null);
@ -2574,11 +2582,13 @@ function App() {
justifyContent: "flex-start", justifyContent: "flex-start",
paddingLeft: "22px", paddingLeft: "22px",
boxSizing: "border-box", boxSizing: "border-box",
maxWidth: '700px'
}} }}
> >
<img <img
style={{ style={{
cursor: "pointer", cursor: "pointer",
height: '24px'
}} }}
onClick={() => { onClick={() => {
setRawWallet(null); setRawWallet(null);
@ -2679,11 +2689,13 @@ function App() {
justifyContent: "flex-start", justifyContent: "flex-start",
paddingLeft: "22px", paddingLeft: "22px",
boxSizing: "border-box", boxSizing: "border-box",
maxWidth: '700px'
}} }}
> >
<img <img
style={{ style={{
cursor: "pointer", cursor: "pointer",
height: '24px'
}} }}
onClick={returnToMain} onClick={returnToMain}
src={Return} src={Return}
@ -2769,11 +2781,13 @@ function App() {
justifyContent: "flex-start", justifyContent: "flex-start",
paddingLeft: "22px", paddingLeft: "22px",
boxSizing: "border-box", boxSizing: "border-box",
maxWidth: '700px'
}} }}
> >
<img <img
style={{ style={{
cursor: "pointer", cursor: "pointer",
height: '24px'
}} }}
onClick={() => { onClick={() => {
if(creationStep === 2){ if(creationStep === 2){
@ -3205,7 +3219,7 @@ function App() {
> >
<CountdownCircleTimer <CountdownCircleTimer
isPlaying isPlaying
duration={30} duration={60}
colors={["#004777", "#F7B801", "#A30000", "#A30000"]} colors={["#004777", "#F7B801", "#A30000", "#A30000"]}
colorsTime={[7, 5, 2, 0]} colorsTime={[7, 5, 2, 0]}
onComplete={() => { onComplete={() => {
@ -3438,6 +3452,36 @@ function App() {
</Box> </Box>
)} )}
{messageQortalRequestExtension?.confirmCheckbox && (
<FormControlLabel
control={
<Checkbox
onChange={(e) => setConfirmRequestRead(e.target.checked)}
checked={confirmRequestRead}
edge="start"
tabIndex={-1}
disableRipple
sx={{
"&.Mui-checked": {
color: "white",
},
"& .MuiSvgIcon-root": {
color: "white",
},
}}
/>
}
label={
<Box sx={{ display: 'flex', alignItems: 'center' }}>
<Typography sx={{ fontSize: "14px" }}>
I have read this request
</Typography>
<PriorityHighIcon color="warning" />
</Box>
}
/>
)}
<Spacer height="29px" /> <Spacer height="29px" />
<Box <Box
sx={{ sx={{
@ -3451,8 +3495,16 @@ function App() {
bgColor="var(--green)" bgColor="var(--green)"
sx={{ sx={{
minWidth: "102px", minWidth: "102px",
opacity: messageQortalRequestExtension?.confirmCheckbox && !confirmRequestRead ? 0.1 : 0.7,
cursor: messageQortalRequestExtension?.confirmCheckbox && !confirmRequestRead ? 'default' : 'pointer',
"&:hover": {
opacity: messageQortalRequestExtension?.confirmCheckbox && !confirmRequestRead ? 0.1 : 1,
}
}}
onClick={() => {
if(messageQortalRequestExtension?.confirmCheckbox && !confirmRequestRead) return
onOkQortalRequestExtension("accepted")
}} }}
onClick={() => onOkQortalRequestExtension("accepted")}
> >
accept accept
</CustomButtonAccept> </CustomButtonAccept>

View File

@ -2309,6 +2309,48 @@ export async function createGroup({
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;
} }
export async function updateGroup({
groupId,
newOwner,
newIsOpen,
newDescription,
newApprovalThreshold,
newMinimumBlockDelay,
newMaximumBlockDelay
}) {
const wallet = await getSaveWallet();
const address = wallet.address0;
if (!address) throw new Error("Cannot find user");
const lastReference = await getLastRef();
const feeres = await getFee("UPDATE_GROUP");
const resKeyPair = await getKeyPair();
const parsedData = resKeyPair;
const uint8PrivateKey = Base58.decode(parsedData.privateKey);
const uint8PublicKey = Base58.decode(parsedData.publicKey);
const keyPair = {
privateKey: uint8PrivateKey,
publicKey: uint8PublicKey,
};
const tx = await createTransaction(23, keyPair, {
fee: feeres.fee,
_groupId: groupId,
newOwner,
newIsOpen,
newDescription,
newApprovalThreshold,
newMinimumBlockDelay,
newMaximumBlockDelay,
lastReference: lastReference,
});
const signedBytes = Base58.encode(tx.signedBytes);
const res = await processTransactionVersion2(signedBytes);
if (!res?.signature)
throw new Error(res?.message || "Transaction was not able to be processed");
return res;
}
export async function inviteToGroup({ groupId, qortalAddress, inviteTime }) { export async function inviteToGroup({ groupId, qortalAddress, inviteTime }) {
const address = await getNameOrAddress(qortalAddress); const address = await getNameOrAddress(qortalAddress);
if (!address) throw new Error("Cannot find user"); if (!address) throw new Error("Cannot find user");

View File

@ -255,7 +255,8 @@ export const listOfAllQortalRequests = [
'GET_NODE_INFO', 'GET_NODE_INFO',
'GET_NODE_STATUS', 'GET_NODE_STATUS',
'GET_ARRR_SYNC_STATUS', 'GET_ARRR_SYNC_STATUS',
'SHOW_PDF_READER' 'SHOW_PDF_READER',
'UPDATE_GROUP'
] ]
export const UIQortalRequests = [ export const UIQortalRequests = [
@ -311,7 +312,8 @@ export const UIQortalRequests = [
'GET_NODE_INFO', 'GET_NODE_INFO',
'GET_NODE_STATUS', 'GET_NODE_STATUS',
'GET_ARRR_SYNC_STATUS', 'GET_ARRR_SYNC_STATUS',
'SHOW_PDF_READER' 'SHOW_PDF_READER',
'UPDATE_GROUP'
]; ];
@ -575,7 +577,7 @@ isDOMContentLoaded: false
result: null, result: null,
error: { error: {
error: response?.error, error: response?.error,
message: typeof response?.error === 'string' ? response?.error : 'An error has occurred' message: typeof response?.error === 'string' ? response?.error : typeof response?.message === 'string' ? response?.message : 'An error has occurred'
}, },
}); });
} else { } else {

View File

@ -24,7 +24,7 @@ window.addEventListener("message", (event) => {
} }
}); });
export const sendMessageBackground = (action, data = {}, timeout = 180000, isExtension, appInfo, skipAuth) => { export const sendMessageBackground = (action, data = {}, timeout = 240000, isExtension, appInfo, skipAuth) => {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
const requestId = generateRequestId(); // Unique ID for each request const requestId = generateRequestId(); // Unique ID for each request
callbackMap.set(requestId, { resolve, reject }); // Store both resolve and reject callbacks callbackMap.set(requestId, { resolve, reject }); // Store both resolve and reject callbacks

View File

@ -1,6 +1,6 @@
import { gateways, getApiKeyFromStorage } from "./background"; import { gateways, getApiKeyFromStorage } from "./background";
import { listOfAllQortalRequests } from "./components/Apps/useQortalMessageListener"; import { listOfAllQortalRequests } from "./components/Apps/useQortalMessageListener";
import { addForeignServer, addGroupAdminRequest, addListItems, adminAction, banFromGroupRequest, cancelGroupBanRequest, cancelGroupInviteRequest, cancelSellOrder, createAndCopyEmbedLink, createBuyOrder, createGroupRequest, createPoll, createSellOrder, decryptAESGCMRequest, decryptData, decryptDataWithSharingKey, decryptQortalGroupData, deleteHostedData, deleteListItems, deployAt, encryptData, encryptDataWithSharingKey, encryptQortalGroupData, getCrossChainServerInfo, getDaySummary, getNodeInfo, getNodeStatus, getForeignFee, getHostedData, getListItems, getServerConnectionHistory, getTxActivitySummary, getUserAccount, getUserWallet, getUserWalletInfo, getUserWalletTransactions, getWalletBalance, inviteToGroupRequest, joinGroup, kickFromGroupRequest, leaveGroupRequest, openNewTab, publishMultipleQDNResources, publishQDNResource, registerNameRequest, removeForeignServer, removeGroupAdminRequest, saveFile, sendChatMessage, sendCoin, setCurrentForeignServer, signTransaction, updateForeignFee, updateNameRequest, voteOnPoll, getArrrSyncStatus } from "./qortalRequests/get"; import { addForeignServer, addGroupAdminRequest, addListItems, adminAction, banFromGroupRequest, cancelGroupBanRequest, cancelGroupInviteRequest, cancelSellOrder, createAndCopyEmbedLink, createBuyOrder, createGroupRequest, createPoll, createSellOrder, decryptAESGCMRequest, decryptData, decryptDataWithSharingKey, decryptQortalGroupData, deleteHostedData, deleteListItems, deployAt, encryptData, encryptDataWithSharingKey, encryptQortalGroupData, getCrossChainServerInfo, getDaySummary, getNodeInfo, getNodeStatus, getForeignFee, getHostedData, getListItems, getServerConnectionHistory, getTxActivitySummary, getUserAccount, getUserWallet, getUserWalletInfo, getUserWalletTransactions, getWalletBalance, inviteToGroupRequest, joinGroup, kickFromGroupRequest, leaveGroupRequest, openNewTab, publishMultipleQDNResources, publishQDNResource, registerNameRequest, removeForeignServer, removeGroupAdminRequest, saveFile, sendChatMessage, sendCoin, setCurrentForeignServer, signTransaction, updateForeignFee, updateNameRequest, voteOnPoll, getArrrSyncStatus, updateGroupRequest } from "./qortalRequests/get";
import { getData, storeData } from "./utils/chromeStorage"; import { getData, storeData } from "./utils/chromeStorage";
import { executeEvent } from "./utils/events"; import { executeEvent } from "./utils/events";
@ -1195,6 +1195,25 @@ export const isRunningGateway = async ()=> {
} }
break; break;
} }
case "UPDATE_GROUP" : {
try {
const res = await updateGroupRequest(request.payload, isFromExtension)
event.source.postMessage({
requestId: request.requestId,
action: request.action,
payload: res,
type: "backgroundMessageResponse",
}, event.origin);
} catch (error) {
event.source.postMessage({
requestId: request.requestId,
action: request.action,
error: error?.message,
type: "backgroundMessageResponse",
}, event.origin);
}
break;
}
case "GET_ARRR_SYNC_STATUS": { case "GET_ARRR_SYNC_STATUS": {
try { try {

View File

@ -30,6 +30,7 @@ import {
removeAdmin, removeAdmin,
cancelInvitationToGroup, cancelInvitationToGroup,
createGroup, createGroup,
updateGroup,
} from "../background"; } from "../background";
import { getNameInfo, uint8ArrayToObject } from "../backgroundFunctions/encryption"; import { getNameInfo, uint8ArrayToObject } from "../backgroundFunctions/encryption";
import { showSaveFilePicker } from "../components/Apps/useQortalMessageListener"; import { showSaveFilePicker } from "../components/Apps/useQortalMessageListener";
@ -122,7 +123,7 @@ export async function retryTransaction(fn, args, throwError, retries = MAX_RETRI
if(throwError){ if(throwError){
throw new Error(error?.message || "Unable to process transaction") throw new Error(error?.message || "Unable to process transaction")
} else { } else {
return null throw new Error(error?.message || "Unable to process transaction")
} }
} }
await new Promise(res => setTimeout(res, 10000)); await new Promise(res => setTimeout(res, 10000));
@ -391,7 +392,7 @@ async function getUserPermission(payload, isFromExtension) {
responseResolvers.get(requestId)(false); // Resolve with `false` if no response responseResolvers.get(requestId)(false); // Resolve with `false` if no response
responseResolvers.delete(requestId); responseResolvers.delete(requestId);
} }
}, 30000); // 30-second timeout }, 60000); // 30-second timeout
}); });
} }
@ -1349,6 +1350,7 @@ export const publishMultipleQDNResources = async (
failedPublishesIdentifiers.push({ failedPublishesIdentifiers.push({
reason: errorMsg, reason: errorMsg,
identifier: resource.identifier, identifier: resource.identifier,
service: resource.service,
}); });
continue; continue;
} }
@ -1357,6 +1359,7 @@ export const publishMultipleQDNResources = async (
failedPublishesIdentifiers.push({ failedPublishesIdentifiers.push({
reason: errorMsg, reason: errorMsg,
identifier: resource.identifier, identifier: resource.identifier,
service: resource.service,
}); });
continue; continue;
} }
@ -1386,6 +1389,7 @@ export const publishMultipleQDNResources = async (
failedPublishesIdentifiers.push({ failedPublishesIdentifiers.push({
reason: errorMsg, reason: errorMsg,
identifier: resource.identifier, identifier: resource.identifier,
service: resource.service,
}); });
continue; continue;
} }
@ -1413,6 +1417,7 @@ export const publishMultipleQDNResources = async (
failedPublishesIdentifiers.push({ failedPublishesIdentifiers.push({
reason: errorMsg, reason: errorMsg,
identifier: resource.identifier, identifier: resource.identifier,
service: resource.service,
}); });
continue; continue;
} }
@ -1439,7 +1444,7 @@ export const publishMultipleQDNResources = async (
apiVersion: 2, apiVersion: 2,
withFee: true, withFee: true,
}, },
], false); ], true);
await new Promise((res) => { await new Promise((res) => {
setTimeout(() => { setTimeout(() => {
res(); res();
@ -1450,17 +1455,21 @@ export const publishMultipleQDNResources = async (
failedPublishesIdentifiers.push({ failedPublishesIdentifiers.push({
reason: errorMsg, reason: errorMsg,
identifier: resource.identifier, identifier: resource.identifier,
service: resource.service,
}); });
} }
} catch (error) { } catch (error) {
failedPublishesIdentifiers.push({ failedPublishesIdentifiers.push({
reason: error?.message || "Unknown error", reason: error?.message || "Unknown error",
identifier: resource.identifier, identifier: resource.identifier,
service: resource.service,
}); });
} }
} }
if (failedPublishesIdentifiers.length > 0) { if (failedPublishesIdentifiers.length > 0) {
const obj = {}; const obj = {
message: "Some resources have failed to publish.",
};
obj["error"] = { obj["error"] = {
unsuccessfulPublishes: failedPublishesIdentifiers, unsuccessfulPublishes: failedPublishesIdentifiers,
}; };
@ -3078,6 +3087,7 @@ export const sendCoin = async (data, isFromExtension) => {
text2: `To: ${recipient}`, text2: `To: ${recipient}`,
highlightedText: `${amount} ${checkCoin}`, highlightedText: `${amount} ${checkCoin}`,
fee: fee, fee: fee,
confirmCheckbox: true
}, },
isFromExtension isFromExtension
); );
@ -4522,15 +4532,15 @@ export const cancelGroupInviteRequest = async (data, isFromExtension) => {
export const createGroupRequest = async (data, isFromExtension) => { export const createGroupRequest = async (data, isFromExtension) => {
const requiredFields = ["groupId", "qortalAddress"]; const requiredFields = ["groupId", "qortalAddress", "groupName", "type", "approvalThreshold", "minBlock", "maxBlock"];
const missingFields: string[] = []; const missingFields: string[] = [];
requiredFields.forEach((field) => { requiredFields.forEach((field) => {
if (!data[field]) { if (data[field] !== undefined && data[field] !== null) {
missingFields.push(field); missingFields.push(field);
} }
}); });
const groupName = data.groupName const groupName = data.groupName
const description = data?.description const description = data?.description || ""
const type = +data.type const type = +data.type
const approvalThreshold = +data?.approvalThreshold const approvalThreshold = +data?.approvalThreshold
const minBlock = +data?.minBlock const minBlock = +data?.minBlock
@ -4563,6 +4573,65 @@ export const createGroupRequest = async (data, isFromExtension) => {
} }
}; };
export const updateGroupRequest = async (data, isFromExtension) => {
const requiredFields = ["groupId", "newOwner", "type", "approvalThreshold", "minBlock", "maxBlock"];
const missingFields: string[] = [];
requiredFields.forEach((field) => {
if (data[field] !== undefined && data[field] !== null) {
missingFields.push(field);
}
});
const groupId = +data.groupId
const newOwner = data.newOwner
const description = data?.description || ""
const type = +data.type
const approvalThreshold = +data?.approvalThreshold
const minBlock = +data?.minBlock
const maxBlock = +data.maxBlock
let groupInfo = null;
try {
const url = await createEndpoint(`/groups/${groupId}`);
const response = await fetch(url);
if (!response.ok) throw new Error("Failed to fetch group");
groupInfo = await response.json();
} catch (error) {
const errorMsg = (error && error.message) || "Group not found";
throw new Error(errorMsg);
}
const displayInvitee = await getNameInfoForOthers(newOwner)
const fee = await getFee("CREATE_GROUP");
const resPermission = await getUserPermission(
{
text1: `Do you give this application permission to update this group?`,
text2: `New owner: ${displayInvitee || newOwner}`,
highlightedText: `Group: ${groupInfo.groupName}`,
fee: fee.fee,
},
isFromExtension
);
const { accepted } = resPermission;
if (accepted) {
const response = await updateGroup({
groupId,
newOwner,
newIsOpen: type,
newDescription: description,
newApprovalThreshold: approvalThreshold,
newMinimumBlockDelay: minBlock,
newMaximumBlockDelay: maxBlock
})
return response
} else {
throw new Error("User declined request");
}
};
export const decryptAESGCMRequest = async (data, isFromExtension) => { export const decryptAESGCMRequest = async (data, isFromExtension) => {
const requiredFields = ["encryptedData", "iv", "senderPublicKey"]; const requiredFields = ["encryptedData", "iv", "senderPublicKey"];
requiredFields.forEach((field) => { requiredFields.forEach((field) => {

View File

@ -0,0 +1,62 @@
// @ts-nocheck
import { QORT_DECIMALS } from "../constants/constants";
import TransactionBase from "./TransactionBase";
export default class UpdateGroupTransaction extends TransactionBase {
constructor() {
super()
this.type = 23
}
set fee(fee) {
this._fee = fee * QORT_DECIMALS
this._feeBytes = this.constructor.utils.int64ToBytes(this._fee)
}
set newOwner(newOwner) {
this._newOwner = newOwner instanceof Uint8Array ? newOwner : this.constructor.Base58.decode(newOwner)
}
set newIsOpen(newIsOpen) {
this._rGroupType = new Uint8Array(1)
this._rGroupType[0] = newIsOpen
}
set newDescription(newDescription) {
this._rGroupDescBytes = this.constructor.utils.stringtoUTF8Array(newDescription.toLocaleLowerCase())
this._rGroupDescLength = this.constructor.utils.int32ToBytes(this._rGroupDescBytes.length)
}
set newApprovalThreshold(newApprovalThreshold) {
this._rGroupApprovalThreshold = new Uint8Array(1)
this._rGroupApprovalThreshold[0] = newApprovalThreshold;
}
set newMinimumBlockDelay(newMinimumBlockDelay) {
this._rGroupMinimumBlockDelayBytes = this.constructor.utils.int32ToBytes(newMinimumBlockDelay)
}
set newMaximumBlockDelay(newMaximumBlockDelay) {
this._rGroupMaximumBlockDelayBytes = this.constructor.utils.int32ToBytes(newMaximumBlockDelay)
}
set _groupId(_groupId){
this._groupBytes = this.constructor.utils.int32ToBytes(_groupId)
}
get params() {
const params = super.params
params.push(
this._groupBytes,
this._newOwner,
this._rGroupDescLength,
this._rGroupDescBytes,
this._rGroupType,
this._rGroupApprovalThreshold,
this._rGroupMinimumBlockDelayBytes,
this._rGroupMaximumBlockDelayBytes,
this._feeBytes
)
return params
}
}

View File

@ -20,6 +20,7 @@ import DeployAtTransaction from './DeployAtTransaction.js'
import RewardShareTransaction from './RewardShareTransaction.js' import RewardShareTransaction from './RewardShareTransaction.js'
import RemoveRewardShareTransaction from './RemoveRewardShareTransaction.js' import RemoveRewardShareTransaction from './RemoveRewardShareTransaction.js'
import UpdateNameTransaction from './UpdateNameTransaction.js' import UpdateNameTransaction from './UpdateNameTransaction.js'
import UpdateGroupTransaction from './UpdateGroupTransaction.js'
export const transactionTypes = { export const transactionTypes = {
@ -32,6 +33,7 @@ export const transactionTypes = {
18: ChatTransaction, 18: ChatTransaction,
181: GroupChatTransaction, 181: GroupChatTransaction,
22: CreateGroupTransaction, 22: CreateGroupTransaction,
23: UpdateGroupTransaction,
24: AddGroupAdminTransaction, 24: AddGroupAdminTransaction,
25: RemoveGroupAdminTransaction, 25: RemoveGroupAdminTransaction,
26: GroupBanTransaction, 26: GroupBanTransaction,