mirror of
https://github.com/Qortal/Qortal-Hub.git
synced 2025-05-15 22:26:58 +00:00
fixes
This commit is contained in:
parent
1a14a5f62c
commit
ab1eaeb338
34
src/App.tsx
34
src/App.tsx
@ -1028,12 +1028,7 @@ function App() {
|
||||
|
||||
const logoutFunc = useCallback(async () => {
|
||||
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.',
|
||||
}); // TODO translate
|
||||
} else if (extState === 'authenticated') {
|
||||
if (extState === 'authenticated') {
|
||||
await showUnsavedChanges({
|
||||
message: 'Are you sure you would like to logout?',
|
||||
});
|
||||
@ -3014,13 +3009,16 @@ function App() {
|
||||
})}
|
||||
</TextP>
|
||||
<Spacer height="100px" />
|
||||
<CustomButton
|
||||
<ButtonBase
|
||||
autoFocus
|
||||
onClick={() => {
|
||||
returnToMain();
|
||||
}}
|
||||
>
|
||||
{t('core:action.continue', { postProcess: 'capitalize' })}
|
||||
</CustomButton>
|
||||
<CustomButton>
|
||||
{t('core:action.continue', { postProcess: 'capitalize' })}
|
||||
</CustomButton>
|
||||
</ButtonBase>
|
||||
</Box>
|
||||
)}
|
||||
{extState === 'transfer-success-request' && (
|
||||
@ -3221,7 +3219,7 @@ function App() {
|
||||
onClick={onOkUnsavedChanges}
|
||||
autoFocus
|
||||
>
|
||||
{t('core:action.decline', {
|
||||
{t('core:action.continue_logout', {
|
||||
postProcess: 'capitalize',
|
||||
})}
|
||||
</Button>
|
||||
@ -3270,6 +3268,8 @@ function App() {
|
||||
lineHeight: 1.2,
|
||||
maxWidth: '90%',
|
||||
textAlign: 'center',
|
||||
fontSize: '16px',
|
||||
marginBottom: '10px',
|
||||
}}
|
||||
>
|
||||
{messageQortalRequestExtension?.text1}
|
||||
@ -3342,11 +3342,15 @@ function App() {
|
||||
)}
|
||||
|
||||
{messageQortalRequestExtension?.html && (
|
||||
<div
|
||||
dangerouslySetInnerHTML={{
|
||||
__html: messageQortalRequestExtension?.html,
|
||||
}}
|
||||
/>
|
||||
<>
|
||||
<Spacer height="15px" />
|
||||
|
||||
<div
|
||||
dangerouslySetInnerHTML={{
|
||||
__html: messageQortalRequestExtension?.html,
|
||||
}}
|
||||
/>
|
||||
</>
|
||||
)}
|
||||
<Spacer height="15px" />
|
||||
|
||||
|
@ -414,8 +414,23 @@ export const AppsDesktop = ({
|
||||
setDesktopViewMode('dev');
|
||||
}}
|
||||
>
|
||||
<IconWrapper label="Dev" disableWidth>
|
||||
<AppsIcon height={30} />
|
||||
<IconWrapper
|
||||
color={
|
||||
desktopViewMode === 'dev'
|
||||
? theme.palette.text.primary
|
||||
: theme.palette.text.secondary
|
||||
}
|
||||
label="Dev"
|
||||
disableWidth
|
||||
>
|
||||
<AppsIcon
|
||||
color={
|
||||
desktopViewMode === 'dev'
|
||||
? theme.palette.text.primary
|
||||
: theme.palette.text.secondary
|
||||
}
|
||||
height={30}
|
||||
/>
|
||||
</IconWrapper>
|
||||
</ButtonBase>
|
||||
)}
|
||||
|
@ -158,6 +158,12 @@ export const QortPayment = ({ balance, show, onSuccess, defaultPaymentTo }) => {
|
||||
value={paymentPassword}
|
||||
onChange={(e) => setPaymentPassword(e.target.value)}
|
||||
autoComplete="off"
|
||||
onKeyDown={(e) => {
|
||||
if (e.key === 'Enter') {
|
||||
if (isLoadingSendCoin) return;
|
||||
sendCoinFunc();
|
||||
}
|
||||
}}
|
||||
/>
|
||||
</Box>
|
||||
|
||||
|
@ -27,15 +27,25 @@ export const ReactionPicker = ({ onReaction }) => {
|
||||
if (showPicker) {
|
||||
setShowPicker(false);
|
||||
} else {
|
||||
// Get the button's position
|
||||
const buttonRect = buttonRef.current.getBoundingClientRect();
|
||||
const pickerWidth = 350;
|
||||
const pickerHeight = 400; // Match Picker height prop
|
||||
|
||||
// Calculate position to align the right edge of the picker with the button's right edge
|
||||
setPickerPosition({
|
||||
top: buttonRect.bottom + window.scrollY, // Position below the button
|
||||
left: buttonRect.right + window.scrollX - pickerWidth, // Align right edges
|
||||
});
|
||||
// Initial position (below the button)
|
||||
let top = buttonRect.bottom + window.scrollY;
|
||||
let left = buttonRect.right + window.scrollX - pickerWidth;
|
||||
|
||||
// If picker would overflow bottom, show it above the button
|
||||
const overflowBottom =
|
||||
top + pickerHeight > window.innerHeight + window.scrollY;
|
||||
if (overflowBottom) {
|
||||
top = buttonRect.top + window.scrollY - pickerHeight;
|
||||
}
|
||||
|
||||
// Optional: prevent overflow on the left too
|
||||
if (left < 0) left = 0;
|
||||
|
||||
setPickerPosition({ top, left });
|
||||
setShowPicker(true);
|
||||
}
|
||||
};
|
||||
@ -92,12 +102,13 @@ export const ReactionPicker = ({ onReaction }) => {
|
||||
allowExpandReactions={true}
|
||||
autoFocusSearch={false}
|
||||
emojiStyle={EmojiStyle.NATIVE}
|
||||
height="450"
|
||||
height={400}
|
||||
onEmojiClick={handlePicker}
|
||||
onReactionClick={handleReaction}
|
||||
reactionsDefaultOpen={true}
|
||||
// reactionsDefaultOpen={true}
|
||||
// open={true}
|
||||
theme={Theme.DARK}
|
||||
width="350"
|
||||
width={350}
|
||||
/>
|
||||
</div>,
|
||||
document.body
|
||||
|
@ -25,7 +25,7 @@ const ThemeContext = createContext({
|
||||
toggleTheme: () => {},
|
||||
userThemes: [defaultTheme],
|
||||
addUserTheme: (themes) => {},
|
||||
setUserTheme: (theme) => {},
|
||||
setUserTheme: (theme, themes) => {},
|
||||
currentThemeId: 'default',
|
||||
});
|
||||
|
||||
@ -83,13 +83,13 @@ export const ThemeProvider = ({ children }) => {
|
||||
saveSettings(themes);
|
||||
};
|
||||
|
||||
const setUserTheme = (theme) => {
|
||||
const setUserTheme = (theme, themes) => {
|
||||
if (theme.id === 'default') {
|
||||
setCurrentThemeId('default');
|
||||
saveSettings(userThemes, themeMode, 'default');
|
||||
saveSettings(themes || userThemes, themeMode, 'default');
|
||||
} else {
|
||||
setCurrentThemeId(theme.id);
|
||||
saveSettings(userThemes, themeMode, theme.id);
|
||||
saveSettings(themes || userThemes, themeMode, theme.id);
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -119,7 +119,7 @@ export default function ThemeManager() {
|
||||
const newTheme = { ...themeDraft, id: uid.rnd() };
|
||||
const updatedThemes = [...userThemes, newTheme];
|
||||
addUserTheme(updatedThemes);
|
||||
setUserTheme(newTheme);
|
||||
setUserTheme(newTheme, updatedThemes);
|
||||
}
|
||||
setOpenEditor(false);
|
||||
};
|
||||
@ -135,19 +135,22 @@ export default function ThemeManager() {
|
||||
);
|
||||
|
||||
if (defaultTheme) {
|
||||
setUserTheme(defaultTheme);
|
||||
setUserTheme(defaultTheme, updatedThemes);
|
||||
} else {
|
||||
// Emergency fallback
|
||||
setUserTheme({
|
||||
light: lightThemeOptions,
|
||||
dark: darkThemeOptions,
|
||||
});
|
||||
setUserTheme(
|
||||
{
|
||||
light: lightThemeOptions,
|
||||
dark: darkThemeOptions,
|
||||
},
|
||||
updatedThemes
|
||||
);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const handleApplyTheme = (theme) => {
|
||||
setUserTheme(theme);
|
||||
setUserTheme(theme, null);
|
||||
};
|
||||
|
||||
const handleColorChange = (mode, fieldPath, color) => {
|
||||
@ -210,7 +213,8 @@ export default function ThemeManager() {
|
||||
const newTheme = { ...importedTheme, id: uid.rnd() };
|
||||
const updatedThemes = [...userThemes, newTheme];
|
||||
addUserTheme(updatedThemes);
|
||||
setUserTheme(newTheme);
|
||||
|
||||
setUserTheme(newTheme, updatedThemes);
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
}
|
||||
|
@ -2680,7 +2680,7 @@ export const updateForeignFee = async (data) => {
|
||||
|
||||
const { coin, type, value } = data;
|
||||
const url = `/crosschain/${coin.toLowerCase()}/update${type}`;
|
||||
|
||||
const valueStringified = JSON.stringify(+value);
|
||||
try {
|
||||
const endpoint = await createEndpoint(url);
|
||||
const response = await fetch(endpoint, {
|
||||
@ -2689,7 +2689,7 @@ export const updateForeignFee = async (data) => {
|
||||
Accept: '*/*',
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
body: JSON.stringify({ value }),
|
||||
body: valueStringified,
|
||||
});
|
||||
|
||||
if (!response.ok) throw new Error('Failed to update foreign fee');
|
||||
@ -3493,6 +3493,35 @@ export const sendCoin = async (data, isFromExtension) => {
|
||||
}
|
||||
};
|
||||
|
||||
function calculateFeeFromRate(feePerKb, sizeInBytes) {
|
||||
return (feePerKb / 1000) * sizeInBytes;
|
||||
}
|
||||
|
||||
const getBuyingFees = async (foreignBlockchain) => {
|
||||
const ticker = sellerForeignFee[foreignBlockchain].ticker;
|
||||
if (!ticker) throw new Error('invalid foreign blockchain');
|
||||
const unlockFee = await getForeignFee({
|
||||
coin: ticker,
|
||||
type: 'feerequired',
|
||||
});
|
||||
const lockFee = await getForeignFee({
|
||||
coin: ticker,
|
||||
type: 'feekb',
|
||||
});
|
||||
return {
|
||||
ticker: ticker,
|
||||
lock: {
|
||||
sats: lockFee,
|
||||
fee: lockFee / QORT_DECIMALS,
|
||||
},
|
||||
unlock: {
|
||||
sats: unlockFee,
|
||||
fee: unlockFee / QORT_DECIMALS,
|
||||
byteFee300: calculateFeeFromRate(+unlockFee, 300) / QORT_DECIMALS,
|
||||
},
|
||||
};
|
||||
};
|
||||
|
||||
export const createBuyOrder = async (data, isFromExtension) => {
|
||||
const requiredFields = ['crosschainAtInfo', 'foreignBlockchain'];
|
||||
const missingFields: string[] = [];
|
||||
@ -3528,6 +3557,7 @@ export const createBuyOrder = async (data, isFromExtension) => {
|
||||
|
||||
const crosschainAtInfo = await Promise.all(atPromises);
|
||||
try {
|
||||
const buyingFees = await getBuyingFees(foreignBlockchain);
|
||||
const resPermission = await getUserPermission(
|
||||
{
|
||||
text1:
|
||||
@ -3541,10 +3571,45 @@ export const createBuyOrder = async (data, isFromExtension) => {
|
||||
return latest + +cur?.expectedForeignAmount;
|
||||
}, 0)
|
||||
)}
|
||||
${` ${crosschainAtInfo?.[0]?.foreignBlockchain}`}`,
|
||||
${` ${buyingFees.ticker}`}`,
|
||||
highlightedText: `Is using public node: ${isGateway}`,
|
||||
fee: '',
|
||||
foreignFee: `${sellerForeignFee[foreignBlockchain].value} ${sellerForeignFee[foreignBlockchain].ticker}`,
|
||||
html: `
|
||||
<div style="max-height: 30vh; overflow-y: auto; font-family: sans-serif;">
|
||||
<style>
|
||||
.fee-container {
|
||||
background-color: #1e1e1e;
|
||||
color: #e0e0e0;
|
||||
border: 1px solid #444;
|
||||
border-radius: 8px;
|
||||
padding: 16px;
|
||||
margin-bottom: 12px;
|
||||
}
|
||||
.fee-label {
|
||||
font-weight: bold;
|
||||
color: #bb86fc;
|
||||
margin-bottom: 4px;
|
||||
}
|
||||
.fee-description {
|
||||
font-size: 14px;
|
||||
color: #cccccc;
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
</style>
|
||||
|
||||
<div class="fee-container">
|
||||
<div class="fee-label">Total Unlocking Fee:</div>
|
||||
<div>${(+buyingFees?.unlock?.byteFee300 * atAddresses?.length)?.toFixed(8)} ${buyingFees.ticker}</div>
|
||||
<div class="fee-description">
|
||||
This fee is an estimate based on ${atAddresses?.length} ${atAddresses?.length > 1 ? 'orders' : 'order'} at a 300 byte cost of ${buyingFees?.unlock?.byteFee300?.toFixed(8)}
|
||||
</div>
|
||||
|
||||
<div class="fee-label">Total Locking Fee:</div>
|
||||
<div>${+buyingFees?.unlock.fee.toFixed(8)} ${buyingFees.ticker} per kb</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
`,
|
||||
},
|
||||
isFromExtension
|
||||
);
|
||||
|
Loading…
x
Reference in New Issue
Block a user