b54a3139c7
Includes QWB, Qortal Web, and Q-Shops Q-Apps with shared packages and build scripts. Co-authored-by: Cursor <cursoragent@cursor.com>
180 lines
6.3 KiB
HTML
180 lines
6.3 KiB
HTML
<!doctype html>
|
|
<html lang="en" data-qshops-theme="dark">
|
|
<head>
|
|
<meta charset="UTF-8" />
|
|
<script>
|
|
(function () {
|
|
try {
|
|
var p = location.pathname;
|
|
if (/\.html?$/i.test(p)) p = p.replace(/\/[^/]+$/, '/');
|
|
else if (p !== '/' && !p.endsWith('/')) p += '/';
|
|
if (p.length < 1 || p.charAt(0) !== '/') return;
|
|
var b = document.createElement('base');
|
|
b.href = p;
|
|
document.head.insertBefore(b, document.head.firstChild);
|
|
} catch (_e) {
|
|
/* */
|
|
}
|
|
})();
|
|
</script>
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0, viewport-fit=cover" />
|
|
<title>Q-Shops · Qortal Marketplace</title>
|
|
<link rel="icon" href="./favicon.svg" type="image/svg+xml" />
|
|
</head>
|
|
<body>
|
|
<script>
|
|
/**
|
|
* Q-Shops ZIP has no WEBSITE shell. When Hub has not injected `qortalRequest` yet, or when
|
|
* this APP runs inside an embedded iframe (parent = QWB `site.html`), we must expose the same
|
|
* MessageChannel forward path as builder `site.html` / `dev.html` so catalogs can load.
|
|
*/
|
|
(function () {
|
|
if (typeof window.qortalRequest === 'function') return;
|
|
|
|
function qwbStubForwardTimeoutMs(action) {
|
|
if (!action) return 60000;
|
|
switch (action) {
|
|
case 'GET_USER_ACCOUNT':
|
|
case 'SAVE_FILE':
|
|
case 'SIGN_TRANSACTION':
|
|
case 'DECRYPT_DATA':
|
|
return 60 * 60 * 1000;
|
|
case 'SEARCH_QDN_RESOURCES':
|
|
return 30 * 1000;
|
|
case 'FETCH_QDN_RESOURCE':
|
|
return 60 * 1000;
|
|
case 'PUBLISH_QDN_RESOURCE':
|
|
case 'PUBLISH_MULTIPLE_QDN_RESOURCES':
|
|
return 60 * 60 * 1000;
|
|
case 'SEND_CHAT_MESSAGE':
|
|
return 60 * 1000;
|
|
case 'CREATE_TRADE_BUY_ORDER':
|
|
case 'CREATE_TRADE_SELL_ORDER':
|
|
case 'CANCEL_TRADE_SELL_ORDER':
|
|
case 'VOTE_ON_POLL':
|
|
case 'CREATE_POLL':
|
|
case 'JOIN_GROUP':
|
|
case 'DEPLOY_AT':
|
|
case 'SEND_COIN':
|
|
case 'TRANSFER_ASSET':
|
|
case 'SEND_PAYMENT':
|
|
return 5 * 60 * 1000;
|
|
case 'GET_WALLET_BALANCE':
|
|
return 2 * 60 * 1000;
|
|
case 'GET_NAME_DATA':
|
|
case 'GET_ACCOUNT_DATA':
|
|
case 'GET_ACCOUNT_NAMES':
|
|
return 5 * 60 * 1000;
|
|
default:
|
|
return 5 * 60 * 1000;
|
|
}
|
|
}
|
|
|
|
function forwardToParent(request, timeoutMs) {
|
|
return new Promise(function (resolve, reject) {
|
|
var channel = new MessageChannel();
|
|
var done = false;
|
|
var waitMs =
|
|
timeoutMs != null && timeoutMs > 0 ? timeoutMs : qwbStubForwardTimeoutMs(request && request.action);
|
|
channel.port1.onmessage = function (ev) {
|
|
if (done) return;
|
|
done = true;
|
|
try {
|
|
channel.port1.close();
|
|
} catch (e) {
|
|
/* */
|
|
}
|
|
var d = ev && ev.data;
|
|
if (d && typeof d === 'object' && !Array.isArray(d) && ('result' in d || 'error' in d)) {
|
|
var err = d.error;
|
|
if (err) {
|
|
var msg;
|
|
if (typeof err === 'string') msg = err;
|
|
else if (err && typeof err === 'object') msg = err.message || err.error || JSON.stringify(err);
|
|
else msg = String(err);
|
|
reject(new Error(msg));
|
|
return;
|
|
}
|
|
d = d.result;
|
|
} else if (d && typeof d === 'object' && !Array.isArray(d)) {
|
|
if ('data' in d && d.data !== undefined && !('address' in d && 'publicKey' in d)) d = d.data;
|
|
else if ('response' in d && d.response !== undefined) d = d.response;
|
|
}
|
|
if (d && d.error) {
|
|
reject(new Error(typeof d.error === 'string' ? d.error : JSON.stringify(d.error)));
|
|
} else {
|
|
resolve(d);
|
|
}
|
|
};
|
|
channel.port1.onmessageerror = function () {
|
|
if (done) return;
|
|
done = true;
|
|
reject(new Error('qortalRequest MessageChannel error'));
|
|
};
|
|
try {
|
|
var payload = Object.assign({}, request || {}, { requestedHandler: 'UI' });
|
|
if (window.parent && window.parent !== window) {
|
|
window.parent.postMessage(payload, '*', [channel.port2]);
|
|
} else {
|
|
window.postMessage(payload, '*', [channel.port2]);
|
|
}
|
|
} catch (e) {
|
|
if (done) return;
|
|
done = true;
|
|
reject(e);
|
|
return;
|
|
}
|
|
setTimeout(function () {
|
|
if (done) return;
|
|
done = true;
|
|
try {
|
|
channel.port1.close();
|
|
} catch (e) {
|
|
/* */
|
|
}
|
|
reject(new Error('qortalRequest timed out'));
|
|
}, waitMs);
|
|
});
|
|
}
|
|
|
|
try {
|
|
window.__QWB_QORTAL_BRIDGE_STUB__ = true;
|
|
} catch (e) {
|
|
/* */
|
|
}
|
|
|
|
function install(name, wrapper) {
|
|
try {
|
|
if (typeof window[name] !== 'function') window[name] = wrapper;
|
|
} catch (e) {
|
|
/* */
|
|
}
|
|
}
|
|
|
|
install('qortalRequest', function (request) {
|
|
return forwardToParent(request, null);
|
|
});
|
|
install('qortalRequestWithNoTimeout', function (request, effectiveTimeoutMs) {
|
|
var ms =
|
|
effectiveTimeoutMs != null && effectiveTimeoutMs > 0
|
|
? effectiveTimeoutMs
|
|
: qwbStubForwardTimeoutMs(request && request.action);
|
|
return forwardToParent(request, ms);
|
|
});
|
|
install('qortalRequestWithTimeout', function (req, ms) {
|
|
var outer = ms != null && ms > 0 ? ms : qwbStubForwardTimeoutMs(req && req.action);
|
|
return forwardToParent(req, outer);
|
|
});
|
|
})();
|
|
</script>
|
|
<div id="root">
|
|
<p
|
|
style="padding: 2rem; font: 14px system-ui, sans-serif; color: #7a8a7e; margin: 0"
|
|
>
|
|
Loading…
|
|
</p>
|
|
</div>
|
|
<script type="module" src="/src/main.tsx"></script>
|
|
</body>
|
|
</html>
|