fixed rating, added open new tab qortal request

This commit is contained in:
PhilReact 2024-11-25 08:59:42 +02:00
parent f098d04551
commit 45a15b3823
7 changed files with 234 additions and 53 deletions

View File

@ -57,6 +57,7 @@ import {
import { decryptGroupEncryption, encryptAndPublishSymmetricKeyGroupChat, publishGroupEncryptedResource, publishOnQDN } from "./backgroundFunctions/encryption"; import { decryptGroupEncryption, encryptAndPublishSymmetricKeyGroupChat, publishGroupEncryptedResource, publishOnQDN } from "./backgroundFunctions/encryption";
import { PUBLIC_NOTIFICATION_CODE_FIRST_SECRET_KEY } from "./constants/codes"; import { PUBLIC_NOTIFICATION_CODE_FIRST_SECRET_KEY } from "./constants/codes";
import { encryptSingle } from "./qdn/encryption/group-encryption"; import { encryptSingle } from "./qdn/encryption/group-encryption";
import { _createPoll, _voteOnPoll } from "./qortalRequests/get";
import { getData, storeData } from "./utils/chromeStorage"; import { getData, storeData } from "./utils/chromeStorage";
export function versionCase(request, event) { export function versionCase(request, event) {
@ -1801,3 +1802,65 @@ export async function publishGroupEncryptedResourceCase(request, event) {
); );
} }
} }
export async function createPollCase(request, event) {
try {
console.log('request', event)
const { pollName, pollDescription, pollOptions } = request.payload;
const resCreatePoll = await _createPoll(
{
pollName,
pollDescription,
options: pollOptions,
},
true,
true // skip permission
);
event.source.postMessage(
{
requestId: request.requestId,
action: "registerName",
payload: resCreatePoll,
type: "backgroundMessageResponse",
},
event.origin
);
} catch (error) {
event.source.postMessage(
{
requestId: request.requestId,
action: "registerName",
error: error?.message,
type: "backgroundMessageResponse",
},
event.origin
);
}
}
export async function voteOnPollCase(request, event) {
try {
const res = await _voteOnPoll(request.payload, true, true);
event.source.postMessage(
{
requestId: request.requestId,
action: "registerName",
payload: res,
type: "backgroundMessageResponse",
},
event.origin
);
} catch (error) {
event.source.postMessage(
{
requestId: request.requestId,
action: "registerName",
error: error?.message,
type: "backgroundMessageResponse",
},
event.origin
);
}
}

View File

@ -96,6 +96,8 @@ import {
userInfoCase, userInfoCase,
validApiCase, validApiCase,
versionCase, versionCase,
createPollCase,
voteOnPollCase,
} from "./background-cases"; } from "./background-cases";
import { getData, removeKeysAndLogout, storeData } from "./utils/chromeStorage"; import { getData, removeKeysAndLogout, storeData } from "./utils/chromeStorage";
import {BackgroundFetch} from '@transistorsoft/capacitor-background-fetch'; import {BackgroundFetch} from '@transistorsoft/capacitor-background-fetch';
@ -2858,6 +2860,12 @@ function setupMessageListener() {
case "sendChatGroup": case "sendChatGroup":
sendChatGroupCase(request, event); sendChatGroupCase(request, event);
break; break;
case "createPoll":
createPollCase(request, event);
break;
case "voteOnPoll":
voteOnPollCase(request, event);
break;
case "sendChatDirect": case "sendChatDirect":
sendChatDirectCase(request, event); sendChatDirectCase(request, event);
break; break;

View File

@ -103,28 +103,30 @@ export const AppRating = ({ app, myName, ratingCountPosition = "right" }) => {
getRating(app?.name, app?.service); getRating(app?.name, app?.service);
}, [getRating, app?.name]); }, [getRating, app?.name]);
const rateFunc = async (event, newValue) => { const rateFunc = async (event, chosenValue, currentValue) => {
try { try {
const newValue = chosenValue || currentValue
console.log('event', newValue)
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;
const fee = await getFee("ARBITRARY"); const fee = await getFee("CREATE_POLL");
await show({ await show({
message: `Would you like to rate this app a rating of ${newValue}?`, message: `Would you like to rate this app a rating of ${newValue}?. It will create a POLL tx.`,
publishFee: fee.fee + " QORT", publishFee: fee.fee + " QORT",
}); });
console.log('hasPublishedRating', hasPublishedRating)
if (hasPublishedRating === false) { if (hasPublishedRating === false) {
const pollName = `app-library-${app.service}-rating-${app.name}`; const pollName = `app-library-${app.service}-rating-${app.name}`;
const pollOptions = [`1, 2, 3, 4, 5, initialValue-${newValue}`]; const pollOptions = [`1, 2, 3, 4, 5, initialValue-${newValue}`];
await new Promise((res, rej) => { await new Promise((res, rej) => {
window.sendMessage("CREATE_POLL", { window.sendMessage("createPoll", {
payload: {
pollName: pollName, pollName: pollName,
pollDescription: `Rating for ${app.service} ${app.name}`, pollDescription: `Rating for ${app.service} ${app.name}`,
pollOptions: pollOptions, pollOptions: pollOptions,
pollOwnerAddress: myName, pollOwnerAddress: myName,
},
}, 60000) }, 60000)
.then((response) => { .then((response) => {
if (response.error) { if (response.error) {
@ -147,17 +149,19 @@ export const AppRating = ({ app, myName, ratingCountPosition = "right" }) => {
}); });
} else { } else {
const pollName = `app-library-${app.service}-rating-${app.name}`; const pollName = `app-library-${app.service}-rating-${app.name}`;
const optionIndex = pollInfo?.pollOptions.findIndex( const optionIndex = pollInfo?.pollOptions.findIndex(
(option) => +option.optionName === +newValue (option) => +option.optionName === +newValue
); );
console.log('optionIndex', optionIndex, newValue)
if (isNaN(optionIndex) || optionIndex === -1) if (isNaN(optionIndex) || optionIndex === -1)
throw new Error("Cannot find rating option"); throw new Error("Cannot find rating option");
await new Promise((res, rej) => { await new Promise((res, rej) => {
window.sendMessage("VOTE_ON_POLL", { window.sendMessage("voteOnPoll", {
payload: {
pollName: pollName, pollName: pollName,
optionIndex, optionIndex,
},
}, 60000) }, 60000)
.then((response) => { .then((response) => {
if (response.error) { if (response.error) {
@ -180,9 +184,10 @@ export const AppRating = ({ app, myName, ratingCountPosition = "right" }) => {
}); });
} }
} catch (error) { } catch (error) {
console.log('error', error)
setInfoSnack({ setInfoSnack({
type: "error", type: "error",
message: error.message || "An error occurred while trying to rate.", message: error?.message || "Unable to rate",
}); });
setOpenSnack(true); setOpenSnack(true);
} }
@ -212,7 +217,7 @@ export const AppRating = ({ app, myName, ratingCountPosition = "right" }) => {
<Rating <Rating
value={value} value={value}
onChange={rateFunc} onChange={(event, rating)=> rateFunc(event, rating, value)}
precision={1} precision={1}
readOnly={hasPublishedRating === null} readOnly={hasPublishedRating === null}
size="small" size="small"

View File

@ -184,7 +184,7 @@ const UIQortalRequests = [
'GET_TX_ACTIVITY_SUMMARY', 'GET_FOREIGN_FEE', 'UPDATE_FOREIGN_FEE', 'GET_TX_ACTIVITY_SUMMARY', 'GET_FOREIGN_FEE', 'UPDATE_FOREIGN_FEE',
'GET_SERVER_CONNECTION_HISTORY', 'SET_CURRENT_FOREIGN_SERVER', 'GET_SERVER_CONNECTION_HISTORY', 'SET_CURRENT_FOREIGN_SERVER',
'ADD_FOREIGN_SERVER', 'REMOVE_FOREIGN_SERVER', 'GET_DAY_SUMMARY', 'CREATE_TRADE_BUY_ORDER', 'ADD_FOREIGN_SERVER', 'REMOVE_FOREIGN_SERVER', 'GET_DAY_SUMMARY', 'CREATE_TRADE_BUY_ORDER',
'CREATE_TRADE_SELL_ORDER', 'CANCEL_TRADE_SELL_ORDER', 'IS_USING_GATEWAY', 'ADMIN_ACTION' 'CREATE_TRADE_SELL_ORDER', 'CANCEL_TRADE_SELL_ORDER', 'IS_USING_GATEWAY', 'ADMIN_ACTION', 'OPEN_NEW_TAB'
]; ];

View File

@ -4,7 +4,7 @@ import './styles.css';
import { executeEvent } from '../../utils/events'; import { executeEvent } from '../../utils/events';
import { Browser } from '@capacitor/browser'; import { Browser } from '@capacitor/browser';
const extractComponents = (url) => { export const extractComponents = (url) => {
if (!url || !url.startsWith("qortal://")) { // Check if url exists and starts with "qortal://" if (!url || !url.startsWith("qortal://")) { // Check if url exists and starts with "qortal://"
return null; return null;
} }

View File

@ -1,5 +1,5 @@
import { gateways, getApiKeyFromStorage } from "./background"; import { gateways, getApiKeyFromStorage } from "./background";
import { addForeignServer, addListItems, adminAction, cancelSellOrder, createBuyOrder, createPoll, decryptData, deleteListItems, deployAt, encryptData, getCrossChainServerInfo, getDaySummary, getForeignFee, getListItems, getServerConnectionHistory, getTxActivitySummary, getUserAccount, getUserWallet, getUserWalletInfo, getWalletBalance, joinGroup, publishMultipleQDNResources, publishQDNResource, removeForeignServer, saveFile, sendChatMessage, sendCoin, setCurrentForeignServer, updateForeignFee, voteOnPoll } from "./qortalRequests/get"; import { addForeignServer, addListItems, adminAction, cancelSellOrder, createBuyOrder, createPoll, decryptData, deleteListItems, deployAt, encryptData, getCrossChainServerInfo, getDaySummary, getForeignFee, getListItems, getServerConnectionHistory, getTxActivitySummary, getUserAccount, getUserWallet, getUserWalletInfo, getWalletBalance, joinGroup, openNewTab, publishMultipleQDNResources, publishQDNResource, removeForeignServer, saveFile, sendChatMessage, sendCoin, setCurrentForeignServer, updateForeignFee, voteOnPoll } from "./qortalRequests/get";
import { getData, storeData } from "./utils/chromeStorage"; import { getData, storeData } from "./utils/chromeStorage";
@ -277,7 +277,7 @@ export const isRunningGateway = async ()=> {
case "SEND_CHAT_MESSAGE": { case "SEND_CHAT_MESSAGE": {
try { try {
const res = await sendChatMessage(request.payload, isFromExtension); const res = await sendChatMessage(request.payload, isFromExtension, appInfo);
event.source.postMessage({ event.source.postMessage({
requestId: request.requestId, requestId: request.requestId,
action: request.action, action: request.action,
@ -675,6 +675,26 @@ export const isRunningGateway = async ()=> {
break; break;
} }
case "OPEN_NEW_TAB": {
try {
const res = await openNewTab(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;
}
default: default:
break; break;
} }

View File

@ -35,6 +35,8 @@ import { mimeToExtensionMap } from "../utils/memeTypes";
import TradeBotCreateRequest from "../transactions/TradeBotCreateRequest"; import TradeBotCreateRequest from "../transactions/TradeBotCreateRequest";
import DeleteTradeOffer from "../transactions/TradeBotDeleteRequest"; import DeleteTradeOffer from "../transactions/TradeBotDeleteRequest";
import signTradeBotTransaction from "../transactions/signTradeBotTransaction"; import signTradeBotTransaction from "../transactions/signTradeBotTransaction";
import { executeEvent } from "../utils/events";
import { extractComponents } from "../components/Chat/MessageDisplay";
const btcFeePerByte = 0.00000100 const btcFeePerByte = 0.00000100
const ltcFeePerByte = 0.00000030 const ltcFeePerByte = 0.00000030
@ -54,19 +56,28 @@ function roundUpToDecimals(number, decimals = 8) {
return Math.ceil(+number * factor) / factor; return Math.ceil(+number * factor) / factor;
} }
const _createPoll = async ({pollName, pollDescription, options}, isFromExtension) => { export const _createPoll = async (
{ pollName, pollDescription, options },
isFromExtension, skipPermission
) => {
const fee = await getFee("CREATE_POLL"); const fee = await getFee("CREATE_POLL");
let resPermission = {}
const resPermission = await getUserPermission({ if(!skipPermission){
resPermission = await getUserPermission(
{
text1: "You are requesting to create the poll below:", text1: "You are requesting to create the poll below:",
text2: `Poll: ${pollName}`, text2: `Poll: ${pollName}`,
text3: `Description: ${pollDescription}`, text3: `Description: ${pollDescription}`,
text4: `Options: ${options?.join(", ")}`, text4: `Options: ${options?.join(", ")}`,
fee: fee.fee, fee: fee.fee,
}, isFromExtension); },
const { accepted } = resPermission; isFromExtension
);
}
if (accepted) { const { accepted = false } = resPermission;
if (accepted || skipPermission) {
const wallet = await getSaveWallet(); const wallet = await getSaveWallet();
const address = wallet.address0; const address = wallet.address0;
const resKeyPair = await getKeyPair(); const resKeyPair = await getKeyPair();
@ -90,7 +101,9 @@ const _createPoll = async ({pollName, pollDescription, options}, isFromExtension
const signedBytes = Base58.encode(tx.signedBytes); const signedBytes = Base58.encode(tx.signedBytes);
const res = await processTransactionVersion2(signedBytes); const res = await processTransactionVersion2(signedBytes);
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;
} else { } else {
throw new Error("User declined request"); throw new Error("User declined request");
@ -155,18 +168,27 @@ const _deployAt = async (
} }
}; };
const _voteOnPoll = async ({pollName, optionIndex, optionName}, isFromExtension) => { export const _voteOnPoll = async (
{ pollName, optionIndex, optionName },
isFromExtension, skipPermission
) => {
const fee = await getFee("VOTE_ON_POLL"); const fee = await getFee("VOTE_ON_POLL");
let resPermission = {}
const resPermission = await getUserPermission({ if(!skipPermission){
resPermission = await getUserPermission(
{
text1: "You are being requested to vote on the poll below:", text1: "You are being requested to vote on the poll below:",
text2: `Poll: ${pollName}`, text2: `Poll: ${pollName}`,
text3: `Option: ${optionName}`, text3: `Option: ${optionName}`,
fee: fee.fee, fee: fee.fee,
}, isFromExtension); },
const { accepted } = resPermission; isFromExtension
);
}
if (accepted) { const { accepted = false } = resPermission;
if (accepted || skipPermission) {
const wallet = await getSaveWallet(); const wallet = await getSaveWallet();
const address = wallet.address0; const address = wallet.address0;
const resKeyPair = await getKeyPair(); const resKeyPair = await getKeyPair();
@ -189,7 +211,9 @@ 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);
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;
} else { } else {
throw new Error("User declined request"); throw new Error("User declined request");
@ -971,19 +995,40 @@ export const createPoll = async (data, isFromExtension) => {
} }
}; };
export const sendChatMessage = async (data, isFromExtension) => { export const sendChatMessage = async (data, isFromExtension, appInfo) => {
const message = data.message; const message = data?.message;
const fullMessageObject = data?.fullMessageObject
const recipient = data.destinationAddress; const recipient = data.destinationAddress;
const groupId = data.groupId; const groupId = data.groupId;
const isRecipient = !groupId; const isRecipient = !groupId;
const resPermission = await getUserPermission({
text1: "Do you give this application permission to send this chat message?", const value =
(await getPermission(`qAPPSendChatMessage-${appInfo?.name}`)) || false;
let skip = false;
if (value) {
skip = true;
}
let resPermission;
if (!skip) {
resPermission = await getUserPermission(
{
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); checkbox1: {
value: false,
const { accepted } = resPermission; label: "Always allow chat messages from this app",
if (accepted) { },
},
isFromExtension
);
}
const { accepted = false, checkbox1 = false } = resPermission || {};
if (resPermission && accepted) {
setPermission(`qAPPSendChatMessage-${appInfo?.name}`, checkbox1);
}
if (accepted || skip) {
const tiptapJson = { const tiptapJson = {
type: "doc", type: "doc",
content: [ content: [
@ -998,7 +1043,7 @@ export const sendChatMessage = async (data, isFromExtension) => {
}, },
], ],
}; };
const messageObject = { const messageObject = fullMessageObject ? fullMessageObject : {
messageText: tiptapJson, messageText: tiptapJson,
images: [""], images: [""],
repliedTo: "", repliedTo: "",
@ -1072,9 +1117,14 @@ export const sendChatMessage = async (data, isFromExtension) => {
isEncrypted: 1, isEncrypted: 1,
isText: 1, isText: 1,
}); });
const chatBytes = tx.chatBytes; const chatBytes = tx.chatBytes;
const difficulty = 8; const difficulty = 8;
const { nonce, chatBytesArray } = await performPowTask(chatBytes, difficulty); const { nonce, chatBytesArray } = await performPowTask(
chatBytes,
difficulty
);
let _response = await signChatFunc(chatBytesArray, nonce, null, keyPair); let _response = await signChatFunc(chatBytesArray, nonce, null, keyPair);
if (_response?.error) { if (_response?.error) {
throw new Error(_response?.message); throw new Error(_response?.message);
@ -1094,7 +1144,6 @@ export const sendChatMessage = async (data, isFromExtension) => {
publicKey: uint8PublicKey, publicKey: uint8PublicKey,
}; };
const txBody = { const txBody = {
timestamp: Date.now(), timestamp: Date.now(),
groupID: Number(groupId), groupID: Number(groupId),
@ -1112,9 +1161,14 @@ export const sendChatMessage = async (data, isFromExtension) => {
// if (!hasEnoughBalance) { // if (!hasEnoughBalance) {
// throw new Error("Must have at least 4 QORT to send a chat message"); // throw new Error("Must have at least 4 QORT to send a chat message");
// } // }
const chatBytes = tx.chatBytes; const chatBytes = tx.chatBytes;
const difficulty = 8; const difficulty = 8;
const { nonce, chatBytesArray } = await performPowTask(chatBytes, difficulty); const { nonce, chatBytesArray } = await performPowTask(
chatBytes,
difficulty
);
let _response = await signChatFunc(chatBytesArray, nonce, null, keyPair); let _response = await signChatFunc(chatBytesArray, nonce, null, keyPair);
if (_response?.error) { if (_response?.error) {
throw new Error(_response?.message); throw new Error(_response?.message);
@ -2796,3 +2850,34 @@ export const adminAction = async (data, isFromExtension) => {
} }
}; };
export const openNewTab = async (data, isFromExtension) => {
const requiredFields = [
"qortalLink",
];
const missingFields: string[] = [];
requiredFields.forEach((field) => {
if (!data[field]) {
missingFields.push(field);
}
});
if (missingFields.length > 0) {
const missingFieldsString = missingFields.join(", ");
const errorMsg = `Missing fields: ${missingFieldsString}`;
throw new Error(errorMsg);
}
const res = extractComponents(data.qortalLink);
if (res) {
const { service, name, identifier, path } = res;
if(!service && !name) throw new Error('Invalid qortal link')
executeEvent("addTab", { data: { service, name, identifier, path } });
executeEvent("open-apps-mode", { });
return true
} else {
throw new Error("Invalid qortal link")
}
};