Merge branch 'main' into merge
4
.gitignore
vendored
|
@ -8,6 +8,10 @@
|
||||||
# Coingecko export data
|
# Coingecko export data
|
||||||
/coingecko.json
|
/coingecko.json
|
||||||
/coingecko-original.json
|
/coingecko-original.json
|
||||||
|
/coingecko-currencies.json
|
||||||
|
|
||||||
|
# Secret files
|
||||||
|
/secrets.php
|
||||||
|
|
||||||
# Compiled files
|
# Compiled files
|
||||||
/js/
|
/js/
|
||||||
|
|
22
README.md
|
@ -39,13 +39,13 @@ This is a fork of the original project by [nice42q](https://github.com/nice42q/m
|
||||||
To convert XMR to a fiat currency, simply visit:
|
To convert XMR to a fiat currency, simply visit:
|
||||||
|
|
||||||
```
|
```
|
||||||
https://monerooo.private.coffee/?in=USD
|
https://calc.revuo-xmr.com/?in=USD
|
||||||
```
|
```
|
||||||
|
|
||||||
Replace `USD` with your preferred currency code. You can also specify the amount of XMR to convert:
|
Replace `USD` with your preferred currency code. You can also specify the amount of XMR to convert:
|
||||||
|
|
||||||
```
|
```
|
||||||
https://monerooo.private.coffee/?in=USD&xmr=1
|
https://calc.revuo-xmr.com/?in=USD&xmr=1
|
||||||
```
|
```
|
||||||
|
|
||||||
The `xmr` parameter specifies the amount of XMR to convert.
|
The `xmr` parameter specifies the amount of XMR to convert.
|
||||||
|
@ -55,7 +55,7 @@ The `xmr` parameter specifies the amount of XMR to convert.
|
||||||
To convert a fiat currency to XMR, visit:
|
To convert a fiat currency to XMR, visit:
|
||||||
|
|
||||||
```
|
```
|
||||||
https://monerooo.private.coffee/?in=USD&fiat=1&direction=1
|
https://calc.revuo-xmr.com/?in=USD&fiat=1&direction=1
|
||||||
```
|
```
|
||||||
|
|
||||||
The `fiat` parameter specifies the amount of fiat currency to convert. The `direction` parameter is set to `1` to indicate conversion from fiat to XMR.
|
The `fiat` parameter specifies the amount of fiat currency to convert. The `direction` parameter is set to `1` to indicate conversion from fiat to XMR.
|
||||||
|
@ -64,7 +64,7 @@ The `fiat` parameter specifies the amount of fiat currency to convert. The `dire
|
||||||
|
|
||||||
1. Select field A1.
|
1. Select field A1.
|
||||||
2. Go to `Data` → `Link to external data...`.
|
2. Go to `Data` → `Link to external data...`.
|
||||||
3. Input the URL `https://moner.ooo/` and confirm.
|
3. Input the URL `calc.revuo-xmr.com` and confirm.
|
||||||
4. Confirm the import options and select `HTML_1`.
|
4. Confirm the import options and select `HTML_1`.
|
||||||
|
|
||||||
For an example, see [kuno.anne.media](https://kuno.anne.media/donate/onml/).
|
For an example, see [kuno.anne.media](https://kuno.anne.media/donate/onml/).
|
||||||
|
@ -82,7 +82,7 @@ For an example, see [kuno.anne.media](https://kuno.anne.media/donate/onml/).
|
||||||
1. Clone the repository:
|
1. Clone the repository:
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
git clone https://github.com/nice42q/moner.ooo.git
|
git clone https://github.com/rottenwheel/moner.ooo.git
|
||||||
cd moner.ooo
|
cd moner.ooo
|
||||||
```
|
```
|
||||||
|
|
||||||
|
@ -117,6 +117,18 @@ return [
|
||||||
];
|
];
|
||||||
```
|
```
|
||||||
|
|
||||||
|
Create a `secrets.php` file in the root directory to store CoinGecko API keys. Example:
|
||||||
|
|
||||||
|
```php
|
||||||
|
<?php
|
||||||
|
return [
|
||||||
|
'coingecko_api_key' => 'CG-xxxx',
|
||||||
|
'coingecko_key_is_demo' => true,
|
||||||
|
];
|
||||||
|
```
|
||||||
|
|
||||||
|
**Note:** The `secrets.dist.php` file should not be accessible from the web server.
|
||||||
|
|
||||||
### Fetching Exchange Rates
|
### Fetching Exchange Rates
|
||||||
|
|
||||||
Exchange rates are fetched from the CoinGecko API. The `coingecko.php` file handles the API requests and attempts to update exchange rates every 5 seconds. Due to the rate limits of the CoinGecko API, actual update intervals may vary and are closer to 60 seconds.
|
Exchange rates are fetched from the CoinGecko API. The `coingecko.php` file handles the API requests and attempts to update exchange rates every 5 seconds. Due to the rate limits of the CoinGecko API, actual update intervals may vary and are closer to 60 seconds.
|
||||||
|
|
145
coingecko.php
|
@ -6,77 +6,120 @@ date_default_timezone_set('Europe/Berlin');
|
||||||
// Define currencies that should *not* be included in the list
|
// Define currencies that should *not* be included in the list
|
||||||
$excludedCurrencies = ['bits', 'sats'];
|
$excludedCurrencies = ['bits', 'sats'];
|
||||||
|
|
||||||
// Fetch the previously stored data
|
// Fetch JSON data from a file and decode it
|
||||||
$previousData = json_decode(file_get_contents("coingecko.json"), true);
|
function fetchJson($filename) {
|
||||||
$output = $previousData;
|
return json_decode(file_get_contents($filename), true);
|
||||||
|
|
||||||
$currentTime = time();
|
|
||||||
|
|
||||||
// Check if five seconds have passed since the last update
|
|
||||||
if (($currentTime - $previousData['time']) >= 5) {
|
|
||||||
// Fetch the available currencies from CoinGecko API
|
|
||||||
$availableCurrenciesApi = "https://api.coingecko.com/api/v3/simple/supported_vs_currencies";
|
|
||||||
|
|
||||||
$currenciesCh = curl_init($availableCurrenciesApi);
|
|
||||||
curl_setopt($currenciesCh, CURLOPT_RETURNTRANSFER, true);
|
|
||||||
$availableCurrenciesJson = curl_exec($currenciesCh);
|
|
||||||
|
|
||||||
$currenciesHttpCode = curl_getinfo($currenciesCh, CURLINFO_HTTP_CODE);
|
|
||||||
|
|
||||||
curl_close($currenciesCh);
|
|
||||||
|
|
||||||
if ($currenciesHttpCode == 200) {
|
|
||||||
$availableCurrencies = json_decode($availableCurrenciesJson, true);
|
|
||||||
} else {
|
|
||||||
$availableCurrencies = array_keys($previousData);
|
|
||||||
unset($availableCurrencies[array_search('time', $availableCurrencies)]);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Remove excluded currencies
|
// Make an API request and return the JSON response
|
||||||
$availableCurrencies = array_diff($availableCurrencies, $excludedCurrencies);
|
function makeApiRequest($url) {
|
||||||
|
$ch = curl_init($url);
|
||||||
$currencies = array_map('strtoupper', $availableCurrencies);
|
|
||||||
|
|
||||||
// Fetch the latest data from CoinGecko API
|
|
||||||
$apiUrl = 'https://api.coingecko.com/api/v3/simple/price?ids=monero&vs_currencies=' . implode('%2C', array_map('strtolower', $currencies)) . '&include_market_cap=true&include_24hr_vol=true&include_24hr_change=true&include_last_updated_at=true';
|
|
||||||
|
|
||||||
$ch = curl_init($apiUrl);
|
|
||||||
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
|
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
|
||||||
$json = curl_exec($ch);
|
$json = curl_exec($ch);
|
||||||
|
|
||||||
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
|
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
|
||||||
curl_close($ch);
|
curl_close($ch);
|
||||||
|
|
||||||
// If the request worked and was not rate-limited
|
|
||||||
if ($httpCode == 200) {
|
if ($httpCode == 200) {
|
||||||
// Decode the fetched data
|
return json_decode($json, true);
|
||||||
$fetchedData = json_decode($json, true);
|
}
|
||||||
$moneroData = $fetchedData['monero'];
|
|
||||||
|
|
||||||
// Initialize new data array
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get CoinGecko key URL parameter
|
||||||
|
function getCoinGeckoApiUrl($path, $params = []) {
|
||||||
|
$secrets = require_once 'secrets.php';
|
||||||
|
$key = $secrets['coingecko_api_key'];
|
||||||
|
$demo = $secrets['coingecko_key_is_demo'];
|
||||||
|
|
||||||
|
$paramName = $demo ? 'x_cg_demo_api_key' : 'x_cg_pro_api_key';
|
||||||
|
$baseUrl = $demo ? "https://api.coingecko.com/api/v3/" : "https://pro-api.coingecko.com/api/v3/";
|
||||||
|
|
||||||
|
$params[$paramName] = $key;
|
||||||
|
$url = $baseUrl . $path;
|
||||||
|
|
||||||
|
if (!empty($params)) {
|
||||||
|
$url .= '?' . http_build_query($params);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $url;
|
||||||
|
}
|
||||||
|
|
||||||
|
$currentTime = time();
|
||||||
|
|
||||||
|
// Fetch list of available currencies from CoinGecko API
|
||||||
|
// Available currencies are cached for 24 hours
|
||||||
|
function fetchAvailableCurrencies() {
|
||||||
|
$cacheFile = 'coingecko-currencies.json';
|
||||||
|
$cacheTime = 86400;
|
||||||
|
|
||||||
|
// Return cached data if it exists and is less than 24 hours old
|
||||||
|
if (file_exists($cacheFile) && (time() - filemtime($cacheFile) < $cacheTime)) {
|
||||||
|
return fetchJson($cacheFile);
|
||||||
|
}
|
||||||
|
|
||||||
|
$apiUrl = getCoinGeckoApiUrl('simple/supported_vs_currencies');
|
||||||
|
$data = makeApiRequest($apiUrl);
|
||||||
|
|
||||||
|
if ($data) {
|
||||||
|
file_put_contents($cacheFile, json_encode($data, JSON_PRETTY_PRINT));
|
||||||
|
return $data;
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fetch currency data from CoinGecko API
|
||||||
|
function fetchCurrencyData($currencies) {
|
||||||
|
$apiUrl = getCoinGeckoApiUrl('simple/price', ['ids' => 'monero', 'vs_currencies' => implode(',', array_map('strtolower', $currencies))]);
|
||||||
|
return makeApiRequest($apiUrl);
|
||||||
|
}
|
||||||
|
|
||||||
|
$currencyFile = 'coingecko.json';
|
||||||
|
$originalFile = 'coingecko-original.json';
|
||||||
|
|
||||||
|
// Function to process currency data
|
||||||
|
function processCurrencyData($availableCurrencies, $previousData, $currentTime, $excludedCurrencies) {
|
||||||
|
// Remove excluded currencies
|
||||||
|
$availableCurrencies = array_diff($availableCurrencies, $excludedCurrencies);
|
||||||
|
$currencies = array_map('strtoupper', $availableCurrencies);
|
||||||
|
|
||||||
|
// Fetch the latest data from CoinGecko API
|
||||||
|
$fetchedData = fetchCurrencyData($currencies);
|
||||||
|
|
||||||
|
if ($fetchedData) {
|
||||||
|
$moneroData = $fetchedData['monero'];
|
||||||
$newData = ['time' => $currentTime];
|
$newData = ['time' => $currentTime];
|
||||||
|
|
||||||
// Update the data for each currency
|
// Update the data for each currency
|
||||||
foreach ($currencies as $currency) {
|
foreach ($currencies as $currency) {
|
||||||
$currencyLower = strtolower($currency);
|
$currencyLower = strtolower($currency);
|
||||||
if (isset($moneroData[$currencyLower])) {
|
|
||||||
$newData[$currencyLower] = [
|
$newData[$currencyLower] = [
|
||||||
'lastValue' => $moneroData[$currencyLower],
|
'lastValue' => $moneroData[$currencyLower] ?? $previousData[$currencyLower]['lastValue'] ?? null,
|
||||||
'lastDate' => $currentTime
|
'lastDate' => $currentTime
|
||||||
];
|
];
|
||||||
} else {
|
|
||||||
$newData[$currencyLower] = [
|
|
||||||
'lastValue' => $previousData[$currencyLower]['lastValue'] ?? null,
|
|
||||||
'lastDate' => $previousData[$currencyLower]['lastDate'] ?? null
|
|
||||||
];
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Save the new data to JSON files
|
return $newData;
|
||||||
file_put_contents("coingecko.json", json_encode($newData, JSON_PRETTY_PRINT));
|
}
|
||||||
file_put_contents("coingecko-original.json", json_encode($moneroData, JSON_PRETTY_PRINT));
|
|
||||||
|
|
||||||
$output = $newData;
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
$previousData = fetchJson($currencyFile);
|
||||||
|
$output = $previousData;
|
||||||
|
|
||||||
|
// Check if five seconds have passed since the last update
|
||||||
|
if (($currentTime - $previousData['time']) >= 5) {
|
||||||
|
$availableCurrencies = fetchAvailableCurrencies();
|
||||||
|
if ($availableCurrencies !== null) {
|
||||||
|
$output = processCurrencyData($availableCurrencies, $previousData, $currentTime, $excludedCurrencies);
|
||||||
|
|
||||||
|
// Save the data if the API call was successful
|
||||||
|
if ($output !== null) {
|
||||||
|
file_put_contents($currencyFile, json_encode($output, JSON_PRETTY_PRINT));
|
||||||
|
file_put_contents($originalFile, json_encode($output, JSON_PRETTY_PRINT));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2,13 +2,13 @@
|
||||||
return [
|
return [
|
||||||
'attribution' => '', // Custom attribution HTML to show in the info text
|
'attribution' => '', // Custom attribution HTML to show in the info text
|
||||||
'footer_links' => [ // Custom links to show in the footer
|
'footer_links' => [ // Custom links to show in the footer
|
||||||
['text' => 'Clearnet', 'url' => 'https://monerooo.private.coffee/'],
|
['text' => 'Clearnet', 'url' => 'https://calc.revuo-xmr.com'],
|
||||||
['text' => 'Tor', 'url' => 'http://monerooo.coffee2m3bjsrrqqycx6ghkxrnejl2q6nl7pjw2j4clchjj6uk5zozad.onion'],
|
['text' => 'Tor', 'url' => 'http://calc.revuo75joezkbeitqmas4ab6spbrkr4vzbhjmeuv75ovrfqfp47mtjid.onion'],
|
||||||
['text' => 'Private.coffee', 'url' => 'https://private.coffee']
|
['text' => 'Revuo Monero', 'url' => 'https://www.revuo-xmr.com/']
|
||||||
],
|
],
|
||||||
'preferred_currencies' => [ // Currencies that should be displayed at the top of the lists
|
'preferred_currencies' => [ // Currencies that should be displayed at the top of the lists
|
||||||
'usd', 'eur', 'gbp', 'cad', 'btc', 'eth', 'ltc'
|
'usd', 'eur', 'gbp', 'cad', 'btc', 'eth', 'ltc'
|
||||||
],
|
],
|
||||||
'github_url' => 'https://git.private.coffee/kumi/moner.ooo/', // URL to the GitHub repository - replace if you forked the project
|
'github_url' => 'https://github.com/rottenwheel/moner.ooo/', // URL to the GitHub repository - replace if you forked the project
|
||||||
'servers_guru' => false, // Show the "Servers Guru" attribution link in the info text - here for upstream compatibility
|
'servers_guru' => false, // Show the "Servers Guru" attribution link in the info text - here for upstream compatibility
|
||||||
];
|
];
|
Before Width: | Height: | Size: 8.6 KiB |
Before Width: | Height: | Size: 7.1 KiB |
Before Width: | Height: | Size: 4.5 KiB |
Before Width: | Height: | Size: 14 KiB |
Before Width: | Height: | Size: 2.9 KiB |
Before Width: | Height: | Size: 2.6 KiB |
Before Width: | Height: | Size: 2.2 KiB |
Before Width: | Height: | Size: 4.3 KiB |
BIN
img/favicon-114x114.png
Normal file
After Width: | Height: | Size: 3.9 KiB |
BIN
img/favicon-120x120.png
Normal file
After Width: | Height: | Size: 4.1 KiB |
Before Width: | Height: | Size: 7 KiB |
BIN
img/favicon-128x128.png
Normal file
After Width: | Height: | Size: 4.4 KiB |
BIN
img/favicon-144x144.png
Normal file
After Width: | Height: | Size: 4.8 KiB |
BIN
img/favicon-152x152.png
Normal file
After Width: | Height: | Size: 5.1 KiB |
Before Width: | Height: | Size: 570 B After Width: | Height: | Size: 952 B |
Before Width: | Height: | Size: 12 KiB After Width: | Height: | Size: 2.3 KiB |
Before Width: | Height: | Size: 1.2 KiB After Width: | Height: | Size: 589 B |
BIN
img/favicon-57x57.png
Normal file
After Width: | Height: | Size: 2.3 KiB |
BIN
img/favicon-60x60.png
Normal file
After Width: | Height: | Size: 2.3 KiB |
BIN
img/favicon-72x72.png
Normal file
After Width: | Height: | Size: 2.7 KiB |
BIN
img/favicon-76x76.png
Normal file
After Width: | Height: | Size: 2.8 KiB |
Before Width: | Height: | Size: 3.5 KiB After Width: | Height: | Size: 3.4 KiB |
BIN
img/favicon.ico
Before Width: | Height: | Size: 34 KiB |
Before Width: | Height: | Size: 4.5 KiB |
Before Width: | Height: | Size: 15 KiB |
Before Width: | Height: | Size: 65 KiB |
Before Width: | Height: | Size: 108 KiB |
Before Width: | Height: | Size: 7 KiB |
BIN
img/qr.jpg
Normal file
After Width: | Height: | Size: 32 KiB |
|
@ -20,13 +20,14 @@ $api_cg = json_decode(file_get_contents('coingecko.json'), true);
|
||||||
// Configuration file
|
// Configuration file
|
||||||
$config = [];
|
$config = [];
|
||||||
if (file_exists('config.php')) {
|
if (file_exists('config.php')) {
|
||||||
$config = require 'config.php';
|
$config = require_once 'config.php';
|
||||||
}
|
}
|
||||||
|
|
||||||
$display_servers_guru = isset($config['servers_guru']) && $config['servers_guru'] === true;
|
$display_servers_guru = isset($config['servers_guru']) && $config['servers_guru'] === true;
|
||||||
$attribution = isset($config['attribution']) ? $config['attribution'] : '';
|
$attribution = isset($config['attribution']) ? $config['attribution'] : '';
|
||||||
$preferred_currencies = isset($config['preferred_currencies']) ? $config['preferred_currencies'] : [];
|
$preferred_currencies = isset($config['preferred_currencies']) ? $config['preferred_currencies'] : [];
|
||||||
$github_url = isset($config['github_url']) ? $config['github_url'] : 'https://git.private.coffee/kumi/moner.ooo/';
|
$github_url = isset($config['github_url']) ? $config['github_url'] : 'https://github.com/rottenwheel/moner.ooo/';
|
||||||
|
$footer_html = isset($config['footer_html']) ? $config['footer_html'] : '';
|
||||||
|
|
||||||
// Extract the keys
|
// Extract the keys
|
||||||
$currencies = array_map('strtoupper', array_keys($api_cg));
|
$currencies = array_map('strtoupper', array_keys($api_cg));
|
||||||
|
@ -77,7 +78,7 @@ foreach ($language_files as $language_file) {
|
||||||
|
|
||||||
// Calculation through GET parameters
|
// Calculation through GET parameters
|
||||||
|
|
||||||
$xmr_in = isset($_GET["in"]) ? strtoupper(htmlspecialchars($_GET["in"])) : 'EUR';
|
$xmr_in = isset($_GET["in"]) ? strtoupper(htmlspecialchars($_GET["in"])) : 'USD';
|
||||||
$xmr_amount = isset($_GET["xmr"]) ? floatval($_GET["xmr"]) : 1;
|
$xmr_amount = isset($_GET["xmr"]) ? floatval($_GET["xmr"]) : 1;
|
||||||
$fiat_amount = isset($_GET["fiat"]) ? floatval($_GET["fiat"]) : '';
|
$fiat_amount = isset($_GET["fiat"]) ? floatval($_GET["fiat"]) : '';
|
||||||
$conversion_direction = isset($_GET["direction"]) ? intval($_GET["direction"]) : 0;
|
$conversion_direction = isset($_GET["direction"]) ? intval($_GET["direction"]) : 0;
|
||||||
|
@ -105,5 +106,5 @@ foreach (array_reverse($preferred_currencies) as $currency) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Output the HTML
|
// Output the HTML
|
||||||
require 'templates/index.php';
|
require_once 'templates/index.php';
|
||||||
?>
|
?>
|
73
package-lock.json
generated
|
@ -124,30 +124,10 @@
|
||||||
"url": "https://opencollective.com/popperjs"
|
"url": "https://opencollective.com/popperjs"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@types/eslint": {
|
|
||||||
"version": "8.56.10",
|
|
||||||
"resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-8.56.10.tgz",
|
|
||||||
"integrity": "sha512-Shavhk87gCtY2fhXDctcfS3e6FdxWkCx1iUZ9eEUbh7rTqlZT0/IzOkCOVt0fCjcFuZ9FPYfuezTBImfHCDBGQ==",
|
|
||||||
"license": "MIT",
|
|
||||||
"dependencies": {
|
|
||||||
"@types/estree": "*",
|
|
||||||
"@types/json-schema": "*"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/@types/eslint-scope": {
|
|
||||||
"version": "3.7.7",
|
|
||||||
"resolved": "https://registry.npmjs.org/@types/eslint-scope/-/eslint-scope-3.7.7.tgz",
|
|
||||||
"integrity": "sha512-MzMFlSLBqNF2gcHWO0G1vP/YQyfvrxZ0bF+u7mzUdZ1/xK4A4sru+nraZz5i3iEIk1l1uyicaDVTB4QbbEkAYg==",
|
|
||||||
"license": "MIT",
|
|
||||||
"dependencies": {
|
|
||||||
"@types/eslint": "*",
|
|
||||||
"@types/estree": "*"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/@types/estree": {
|
"node_modules/@types/estree": {
|
||||||
"version": "1.0.5",
|
"version": "1.0.6",
|
||||||
"resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.5.tgz",
|
"resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.6.tgz",
|
||||||
"integrity": "sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==",
|
"integrity": "sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==",
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
"node_modules/@types/json-schema": {
|
"node_modules/@types/json-schema": {
|
||||||
|
@ -379,10 +359,10 @@
|
||||||
"node": ">=0.4.0"
|
"node": ">=0.4.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/acorn-import-assertions": {
|
"node_modules/acorn-import-attributes": {
|
||||||
"version": "1.9.0",
|
"version": "1.9.5",
|
||||||
"resolved": "https://registry.npmjs.org/acorn-import-assertions/-/acorn-import-assertions-1.9.0.tgz",
|
"resolved": "https://registry.npmjs.org/acorn-import-attributes/-/acorn-import-attributes-1.9.5.tgz",
|
||||||
"integrity": "sha512-cmMwop9x+8KFhxvKrKfPYmN6/pKTYYHBqLa0DfvVZcKMJWNyWLnaqND7dx/qn66R7ewM1UX5XMaDVP5wlVTaVA==",
|
"integrity": "sha512-n02Vykv5uA3eHGM/Z2dQrcD56kL8TyDb2p1+0P83PClMnC/nc+anbQRhIOWnSq4Ke/KvDPrY3C9hDtC/A3eHnQ==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"peerDependencies": {
|
"peerDependencies": {
|
||||||
"acorn": "^8"
|
"acorn": "^8"
|
||||||
|
@ -833,9 +813,9 @@
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
"node_modules/enhanced-resolve": {
|
"node_modules/enhanced-resolve": {
|
||||||
"version": "5.16.1",
|
"version": "5.17.1",
|
||||||
"resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.16.1.tgz",
|
"resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.17.1.tgz",
|
||||||
"integrity": "sha512-4U5pNsuDl0EhuZpq46M5xPslstkviJuhrdobaRDBk2Jy2KO37FDAJl4lb2KlNabxT0m4MTK2UHNrsAcphE8nyw==",
|
"integrity": "sha512-LMHl3dXhTcfv8gM4kEzIUeTQ+7fpdA0l2tUf34BddXPkz2A5xJ5L/Pchd5BL6rdccM9QGvu0sWZzK1Z1t4wwyg==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"graceful-fs": "^4.2.4",
|
"graceful-fs": "^4.2.4",
|
||||||
|
@ -1587,9 +1567,9 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/picocolors": {
|
"node_modules/picocolors": {
|
||||||
"version": "1.0.1",
|
"version": "1.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.0.tgz",
|
||||||
"integrity": "sha512-anP1Z8qwhkbmu7MFP5iTt+wQKXgwzf7zTyGlcdzabySa9vd0Xt392U0rVmz9poOaBj0uHJKyyo9/upk0HrEQew==",
|
"integrity": "sha512-TQ92mBOW0l3LeMeyLV6mzy/kWr8lkd/hp3mTg7wYK7zJhuBStmGMBG0BdeDZS/dZx1IukaX6Bk11zcln25o1Aw==",
|
||||||
"license": "ISC"
|
"license": "ISC"
|
||||||
},
|
},
|
||||||
"node_modules/pkg-dir": {
|
"node_modules/pkg-dir": {
|
||||||
|
@ -1605,9 +1585,9 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/postcss": {
|
"node_modules/postcss": {
|
||||||
"version": "8.4.38",
|
"version": "8.4.47",
|
||||||
"resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.38.tgz",
|
"resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.47.tgz",
|
||||||
"integrity": "sha512-Wglpdk03BSfXkHoQa3b/oulrotAkwrlLDRSOb9D0bN86FdRyE9lppSp33aHNPgBa0JKCoB+drFLZkQoRRYae5A==",
|
"integrity": "sha512-56rxCq7G/XfB4EkXq9Egn5GCqugWvDFjafDOThIdMBsI15iqPqR5r15TfSr1YPYeEI19YeaXMCbY6u88Y76GLQ==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"funding": [
|
"funding": [
|
||||||
{
|
{
|
||||||
|
@ -1626,8 +1606,8 @@
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"nanoid": "^3.3.7",
|
"nanoid": "^3.3.7",
|
||||||
"picocolors": "^1.0.0",
|
"picocolors": "^1.1.0",
|
||||||
"source-map-js": "^1.2.0"
|
"source-map-js": "^1.2.1"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": "^10 || ^12 || >=14"
|
"node": "^10 || ^12 || >=14"
|
||||||
|
@ -1965,9 +1945,9 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/source-map-js": {
|
"node_modules/source-map-js": {
|
||||||
"version": "1.2.0",
|
"version": "1.2.1",
|
||||||
"resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.0.tgz",
|
"resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz",
|
||||||
"integrity": "sha512-itJW8lvSA0TXEphiRoawsCksnlf8SyvmFzIhltqAHluXd88pkCd+cXJVHTDwdCr0IzwptSm035IHQktUu1QUMg==",
|
"integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "BSD-3-Clause",
|
"license": "BSD-3-Clause",
|
||||||
"engines": {
|
"engines": {
|
||||||
|
@ -2248,21 +2228,20 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/webpack": {
|
"node_modules/webpack": {
|
||||||
"version": "5.91.0",
|
"version": "5.95.0",
|
||||||
"resolved": "https://registry.npmjs.org/webpack/-/webpack-5.91.0.tgz",
|
"resolved": "https://registry.npmjs.org/webpack/-/webpack-5.95.0.tgz",
|
||||||
"integrity": "sha512-rzVwlLeBWHJbmgTC/8TvAcu5vpJNII+MelQpylD4jNERPwpBJOE2lEcko1zJX3QJeLjTTAnQxn/OJ8bjDzVQaw==",
|
"integrity": "sha512-2t3XstrKULz41MNMBF+cJ97TyHdyQ8HCt//pqErqDvNjU9YQBnZxIHa11VXsi7F3mb5/aO2tuDxdeTPdU7xu9Q==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@types/eslint-scope": "^3.7.3",
|
|
||||||
"@types/estree": "^1.0.5",
|
"@types/estree": "^1.0.5",
|
||||||
"@webassemblyjs/ast": "^1.12.1",
|
"@webassemblyjs/ast": "^1.12.1",
|
||||||
"@webassemblyjs/wasm-edit": "^1.12.1",
|
"@webassemblyjs/wasm-edit": "^1.12.1",
|
||||||
"@webassemblyjs/wasm-parser": "^1.12.1",
|
"@webassemblyjs/wasm-parser": "^1.12.1",
|
||||||
"acorn": "^8.7.1",
|
"acorn": "^8.7.1",
|
||||||
"acorn-import-assertions": "^1.9.0",
|
"acorn-import-attributes": "^1.9.5",
|
||||||
"browserslist": "^4.21.10",
|
"browserslist": "^4.21.10",
|
||||||
"chrome-trace-event": "^1.0.2",
|
"chrome-trace-event": "^1.0.2",
|
||||||
"enhanced-resolve": "^5.16.0",
|
"enhanced-resolve": "^5.17.1",
|
||||||
"es-module-lexer": "^1.2.1",
|
"es-module-lexer": "^1.2.1",
|
||||||
"eslint-scope": "5.1.1",
|
"eslint-scope": "5.1.1",
|
||||||
"events": "^3.2.0",
|
"events": "^3.2.0",
|
||||||
|
|
2
robots.txt
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
User-agent: *
|
||||||
|
Allow: /
|
|
@ -1,7 +1,5 @@
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
// Just here for compatibility with the rottenwheel fork
|
|
||||||
|
|
||||||
return [
|
return [
|
||||||
'coingecko_api_key' => 'CG-xxxx',
|
'coingecko_api_key' => 'CG-xxxx',
|
||||||
'coingecko_key_is_demo' => true,
|
'coingecko_key_is_demo' => true,
|
||||||
|
|
|
@ -1,9 +1,8 @@
|
||||||
html {
|
html {
|
||||||
width: 100%;
|
background-color: black;
|
||||||
height: 100%;
|
color: #cecece;
|
||||||
background-image: linear-gradient(to bottom right, #013c4a 0, #193e4c 44%, #004b5b 100%) !important;
|
|
||||||
color: #fff;
|
|
||||||
font-style: normal;
|
font-style: normal;
|
||||||
|
font-family: Arial, sans-serif;
|
||||||
}
|
}
|
||||||
|
|
||||||
body {
|
body {
|
||||||
|
@ -16,7 +15,7 @@ p.fiat-info {
|
||||||
|
|
||||||
p.fiat-info span,
|
p.fiat-info span,
|
||||||
a.fiat-tooltip {
|
a.fiat-tooltip {
|
||||||
color: white;
|
color: #cecece;
|
||||||
}
|
}
|
||||||
|
|
||||||
.btn {
|
.btn {
|
||||||
|
@ -48,17 +47,17 @@ input.form-control {
|
||||||
|
|
||||||
.equals-box {
|
.equals-box {
|
||||||
text-align: center;
|
text-align: center;
|
||||||
color: #e9ecef;
|
color: #ff6600;
|
||||||
font-weight: 800;
|
font-weight: 800;
|
||||||
font-size: 42px;
|
font-size: 42px;
|
||||||
padding-bottom: 1;
|
padding-bottom: 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
.btn-arrow {
|
.btn-arrow {
|
||||||
border: 1px solid white;
|
border: 1px solid #ff6600;
|
||||||
border-radius: 10px;
|
border-radius: 10px;
|
||||||
font-size: 38px !important;
|
font-size: 38px !important;
|
||||||
color: white;
|
color: #ff6600;
|
||||||
padding: 0;
|
padding: 0;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
|
@ -70,13 +69,13 @@ input.form-control {
|
||||||
|
|
||||||
.btn-equals {
|
.btn-equals {
|
||||||
font-size: 38px !important;
|
font-size: 38px !important;
|
||||||
color: white;
|
color: #ff6600;
|
||||||
padding: 0;
|
padding: 0;
|
||||||
cursor: default;
|
cursor: default;
|
||||||
}
|
}
|
||||||
|
|
||||||
.btn-equals:hover {
|
.btn-equals:hover {
|
||||||
color: black;
|
color: #cecece;
|
||||||
}
|
}
|
||||||
|
|
||||||
.equals-text {
|
.equals-text {
|
||||||
|
@ -84,7 +83,7 @@ input.form-control {
|
||||||
}
|
}
|
||||||
|
|
||||||
p {
|
p {
|
||||||
color: #e9ecef;
|
color: #cecece;
|
||||||
}
|
}
|
||||||
|
|
||||||
.gold {
|
.gold {
|
||||||
|
@ -122,6 +121,18 @@ p {
|
||||||
.btn {
|
.btn {
|
||||||
min-width: 38px;
|
min-width: 38px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#donation-qr {
|
||||||
|
width: auto;
|
||||||
|
height: 80vh;
|
||||||
|
max-width: 250px;
|
||||||
|
max-height: 250px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#donation-qr-container {
|
||||||
|
height: auto;
|
||||||
|
padding: 20px 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.bs-tooltip-auto {
|
.bs-tooltip-auto {
|
||||||
|
@ -137,3 +148,18 @@ p {
|
||||||
border-width: 0.4rem 0.4rem 0;
|
border-width: 0.4rem 0.4rem 0;
|
||||||
border-top-color: #000;
|
border-top-color: #000;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#donation-qr-container {
|
||||||
|
display: none;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
#donation-qr {
|
||||||
|
width: 100%;
|
||||||
|
height: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
#donation-qr-toggle:checked ~ #donation-qr-container {
|
||||||
|
display: flex;
|
||||||
|
}
|
162
src/js/main.js
|
@ -1,22 +1,66 @@
|
||||||
import 'bootstrap/dist/css/bootstrap.min.css';
|
import 'bootstrap/dist/css/bootstrap.min.css';
|
||||||
import 'bootstrap/dist/js/bootstrap.bundle.min';
|
|
||||||
|
|
||||||
import '../css/custom.css';
|
import '../css/custom.css';
|
||||||
|
|
||||||
import Tooltip from "bootstrap/js/dist/tooltip";
|
import Tooltip from 'bootstrap/js/dist/tooltip';
|
||||||
var tooltipTriggerList = [].slice.call(
|
|
||||||
document.querySelectorAll('[data-toggle="tooltip"]')
|
/////
|
||||||
);
|
let inactivityTimeout = 30; // in seconds
|
||||||
var tooltipList = tooltipTriggerList.map(function (tooltipTriggerEl) {
|
let fetchInterval = 30; // in seconds
|
||||||
return new Tooltip(tooltipTriggerEl, { placement: "top" });
|
/////
|
||||||
});
|
|
||||||
|
inactivityTimeout = inactivityTimeout * 1000;
|
||||||
|
fetchInterval = fetchInterval * 1000;
|
||||||
|
|
||||||
|
const tooltipTriggerList = Array.from(document.querySelectorAll('[data-toggle="tooltip"]'));
|
||||||
|
const tooltipList = tooltipTriggerList.map(tooltipTriggerEl => new Tooltip(tooltipTriggerEl, { placement: 'top' }));
|
||||||
console.log(tooltipList);
|
console.log(tooltipList);
|
||||||
|
|
||||||
let lastModifiedField = 'xmr';
|
let lastModifiedField = 'xmr';
|
||||||
|
const exchangeRates = {};
|
||||||
|
|
||||||
var exchangeRates = {};
|
const runConvert = () =>
|
||||||
|
lastModifiedField === 'xmr' ? xmrConvert() : fiatConvert();
|
||||||
|
|
||||||
document.addEventListener('DOMContentLoaded', function () {
|
let updateInterval
|
||||||
|
const startFetching = () => updateInterval = setInterval(fetchUpdatedExchangeRates, fetchInterval);
|
||||||
|
const stopFetching = () => {
|
||||||
|
clearInterval(updateInterval)
|
||||||
|
updateInterval = null;
|
||||||
|
};
|
||||||
|
|
||||||
|
let lastActivity = Date.now()
|
||||||
|
|
||||||
|
const resetActivity = () => lastActivity = Date.now()
|
||||||
|
const checkInactivity = () => {
|
||||||
|
if (Date.now() - lastActivity > inactivityTimeout) {
|
||||||
|
console.log('Inactivity detected, stopping exchange rate updates');
|
||||||
|
stopFetching();
|
||||||
|
} else {
|
||||||
|
requestAnimationFrame(checkInactivity);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
document.addEventListener('focus', () => {
|
||||||
|
const focused = document.hasFocus();
|
||||||
|
console.log(`Page is ${focused ? 'visible' : 'hidden'}`);
|
||||||
|
|
||||||
|
if (focused && !updateInterval) {
|
||||||
|
console.log('Restarting exchange rate updates');
|
||||||
|
startFetching();
|
||||||
|
|
||||||
|
resetActivity();
|
||||||
|
requestAnimationFrame(checkInactivity);
|
||||||
|
} else {
|
||||||
|
stopFetching();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
window.addEventListener('mousemove', resetActivity);
|
||||||
|
window.addEventListener('keydown', resetActivity);
|
||||||
|
window.addEventListener('touchstart', resetActivity);
|
||||||
|
|
||||||
|
requestAnimationFrame(checkInactivity);
|
||||||
|
|
||||||
|
document.addEventListener('DOMContentLoaded', () => {
|
||||||
const copyXMRBtn = document.getElementById('copyXMRBtn');
|
const copyXMRBtn = document.getElementById('copyXMRBtn');
|
||||||
const copyFiatBtn = document.getElementById('copyFiatBtn');
|
const copyFiatBtn = document.getElementById('copyFiatBtn');
|
||||||
const xmrInput = document.getElementById('xmrInput');
|
const xmrInput = document.getElementById('xmrInput');
|
||||||
|
@ -31,66 +75,50 @@ document.addEventListener('DOMContentLoaded', function () {
|
||||||
button.addEventListener('click', (e) => {
|
button.addEventListener('click', (e) => {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
selectBox.value = button.textContent;
|
selectBox.value = button.textContent;
|
||||||
if (lastModifiedField === 'xmr') {
|
runConvert();
|
||||||
xmrConvert();
|
|
||||||
} else {
|
|
||||||
fiatConvert();
|
|
||||||
}
|
|
||||||
history.pushState(null, '', `?in=${button.textContent}`);
|
history.pushState(null, '', `?in=${button.textContent}`);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
// Add event listeners for the copy buttons
|
// Add event listeners for the copy buttons
|
||||||
copyXMRBtn.addEventListener('click', copyToClipBoardXMR);
|
copyXMRBtn.addEventListener('click', copyToClipboardXMR);
|
||||||
copyFiatBtn.addEventListener('click', copyToClipBoardFiat);
|
copyFiatBtn.addEventListener('click', copyToClipboardFiat);
|
||||||
|
|
||||||
// Add event listeners for the XMR input field
|
// Add event listeners for the XMR input field
|
||||||
xmrInput.addEventListener('change', () => xmrConvert(xmrInput.value));
|
xmrInput.addEventListener('change', xmrConvert);
|
||||||
xmrInput.addEventListener('keyup', () => {
|
xmrInput.addEventListener('keyup', () => {
|
||||||
xmrInput.value = xmrInput.value.replace(/[^\.^,\d]/g, '');
|
xmrInput.value = xmrInput.value.replace(/[^\.^,\d]/g, '').replace(/\,/, '.');
|
||||||
xmrInput.value = xmrInput.value.replace(/\,/, '.');
|
|
||||||
if (xmrInput.value.split('.').length > 2) {
|
if (xmrInput.value.split('.').length > 2) {
|
||||||
xmrInput.value = xmrInput.value.slice(0, -1);
|
xmrInput.value = xmrInput.value.slice(0, -1);
|
||||||
}
|
}
|
||||||
xmrConvert(xmrInput.value);
|
xmrConvert();
|
||||||
});
|
|
||||||
xmrInput.addEventListener('input', () => {
|
|
||||||
lastModifiedField = 'xmr';
|
|
||||||
});
|
});
|
||||||
|
xmrInput.addEventListener('input', () => lastModifiedField = 'xmr');
|
||||||
|
|
||||||
// Add event listeners for the fiat input field
|
// Add event listeners for the fiat input field
|
||||||
fiatInput.addEventListener('change', () => fiatConvert(fiatInput.value));
|
fiatInput.addEventListener('change', fiatConvert);
|
||||||
fiatInput.addEventListener('keyup', () => {
|
fiatInput.addEventListener('keyup', () => {
|
||||||
fiatInput.value = fiatInput.value.replace(/[^\.^,\d]/g, '');
|
fiatInput.value = fiatInput.value.replace(/[^\.^,\d]/g, '').replace(/\,/, '.');
|
||||||
fiatInput.value = fiatInput.value.replace(/\,/, '.');
|
|
||||||
if (fiatInput.value.split('.').length > 2) {
|
if (fiatInput.value.split('.').length > 2) {
|
||||||
fiatInput.value = fiatInput.value.slice(0, -1);
|
fiatInput.value = fiatInput.value.slice(0, -1);
|
||||||
}
|
}
|
||||||
fiatConvert(fiatInput.value);
|
fiatConvert();
|
||||||
});
|
|
||||||
fiatInput.addEventListener('input', () => {
|
|
||||||
lastModifiedField = 'fiat';
|
|
||||||
});
|
});
|
||||||
|
fiatInput.addEventListener('input', () => lastModifiedField = 'fiat');
|
||||||
|
|
||||||
// Add event listener for the select box to change the conversion
|
// Add event listener for the select box to change the conversion
|
||||||
selectBox.addEventListener('change', () => {
|
selectBox.addEventListener('change', runConvert);
|
||||||
if (lastModifiedField === 'xmr') {
|
|
||||||
xmrConvert(selectBox.value)
|
|
||||||
} else {
|
|
||||||
fiatConvert(selectBox.value)
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// Hide the conversion buttons if JavaScript is enabled
|
// Hide the conversion buttons if JavaScript is enabled
|
||||||
convertXMRToFiatBtn.style.display = 'none';
|
convertXMRToFiatBtn.style.display = 'none';
|
||||||
convertFiatToXMRBtn.style.display = 'none';
|
convertFiatToXMRBtn.style.display = 'none';
|
||||||
|
|
||||||
// Fetch updated exchange rates immediately, then every 5 seconds
|
// Fetch updated exchange rates immediately, then every 5 seconds
|
||||||
fetchUpdatedExchangeRates();
|
fetchUpdatedExchangeRates(true)
|
||||||
setInterval(fetchUpdatedExchangeRates, 5000);
|
startFetching();
|
||||||
});
|
});
|
||||||
|
|
||||||
function fetchUpdatedExchangeRates() {
|
function fetchUpdatedExchangeRates(showAlert = false) {
|
||||||
fetch('/coingecko.php')
|
fetch('/coingecko.php')
|
||||||
.then(response => response.json())
|
.then(response => response.json())
|
||||||
.then(data => {
|
.then(data => {
|
||||||
|
@ -102,13 +130,12 @@ function fetchUpdatedExchangeRates() {
|
||||||
updateTimeElement(data.time);
|
updateTimeElement(data.time);
|
||||||
|
|
||||||
// Re-execute the appropriate conversion function
|
// Re-execute the appropriate conversion function
|
||||||
if (lastModifiedField === 'xmr') {
|
runConvert();
|
||||||
xmrConvert();
|
|
||||||
} else {
|
|
||||||
fiatConvert();
|
|
||||||
}
|
|
||||||
})
|
})
|
||||||
.catch(error => console.error('Error fetching exchange rates:', error));
|
.catch(e => {
|
||||||
|
const msg = `Error fetching exchange rates: ${e}`;
|
||||||
|
showAlert ? alert(msg) : console.error(msg);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function updateTimeElement(unixTimestamp) {
|
function updateTimeElement(unixTimestamp) {
|
||||||
|
@ -123,41 +150,40 @@ function updateTimeElement(unixTimestamp) {
|
||||||
u.parentElement.innerHTML = u.parentElement.innerHTML.replace('Europe/Berlin', Intl.DateTimeFormat().resolvedOptions().timeZone);
|
u.parentElement.innerHTML = u.parentElement.innerHTML.replace('Europe/Berlin', Intl.DateTimeFormat().resolvedOptions().timeZone);
|
||||||
}
|
}
|
||||||
|
|
||||||
function copyToClipBoardXMR() {
|
function copyToClipboardXMR() {
|
||||||
var content = document.getElementById('xmrInput');
|
const content = document.getElementById('xmrInput');
|
||||||
content.select();
|
content.select();
|
||||||
|
|
||||||
|
// Using deprecated execCommand for compatibility with older browsers
|
||||||
document.execCommand('copy');
|
document.execCommand('copy');
|
||||||
}
|
}
|
||||||
|
|
||||||
function copyToClipBoardFiat() {
|
function copyToClipboardFiat() {
|
||||||
var content = document.getElementById('fiatInput');
|
const content = document.getElementById('fiatInput');
|
||||||
content.select();
|
content.select();
|
||||||
|
|
||||||
|
// Using deprecated execCommand for compatibility with older browsers
|
||||||
document.execCommand('copy');
|
document.execCommand('copy');
|
||||||
}
|
}
|
||||||
|
|
||||||
function fiatConvert(value) {
|
function fiatConvert() {
|
||||||
let fiatAmount = document.getElementById("fiatInput").value;
|
const fiatAmount = document.getElementById('fiatInput').value;
|
||||||
let xmrValue = document.getElementById("xmrInput");
|
const xmrValue = document.getElementById('xmrInput');
|
||||||
let selectBox = document.getElementById("selectBox").value;
|
const selectBox = document.getElementById('selectBox').value;
|
||||||
|
|
||||||
if (exchangeRates[selectBox]) {
|
if (exchangeRates[selectBox]) {
|
||||||
let value = fiatAmount / exchangeRates[selectBox];
|
const value = fiatAmount / exchangeRates[selectBox];
|
||||||
xmrValue.value = value.toFixed(12);
|
xmrValue.value = value.toFixed(12);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function xmrConvert(value) {
|
function xmrConvert() {
|
||||||
let xmrAmount = document.getElementById("xmrInput").value;
|
const xmrAmount = document.getElementById('xmrInput').value;
|
||||||
let fiatValue = document.getElementById("fiatInput");
|
const fiatValue = document.getElementById('fiatInput');
|
||||||
let selectBox = document.getElementById("selectBox").value;
|
const selectBox = document.getElementById('selectBox').value;
|
||||||
|
|
||||||
if (exchangeRates[selectBox]) {
|
if (exchangeRates[selectBox]) {
|
||||||
let value = xmrAmount * exchangeRates[selectBox];
|
const value = xmrAmount * exchangeRates[selectBox];
|
||||||
fiatValue.value = value.toFixed(selectBox == 'BTC' || selectBox == 'LTC' || selectBox == 'ETH' || selectBox == 'XAG' || selectBox == 'XAU' ? 8 : 2);
|
fiatValue.value = value.toFixed(['BTC', 'LTC', 'ETH', 'XAG', 'XAU'].includes(selectBox) ? 8 : 2);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
window.copyToClipBoardXMR = copyToClipBoardXMR;
|
|
||||||
window.copyToClipBoardFiat = copyToClipBoardFiat;
|
|
||||||
window.fiatConvert = fiatConvert;
|
|
||||||
window.xmrConvert = xmrConvert;
|
|
|
@ -15,32 +15,45 @@
|
||||||
|
|
||||||
<meta property="og:title" content="<?php echo $page_title; ?>" />
|
<meta property="og:title" content="<?php echo $page_title; ?>" />
|
||||||
<meta property="og:description" content="<?php echo $meta_description; ?>" />
|
<meta property="og:description" content="<?php echo $meta_description; ?>" />
|
||||||
<meta property="og:image" content="<?php echo $parentUrl; ?>/img/mstile-310x150.png" />
|
<meta property="og:image" content="<?php echo $parentUrl; ?>/img/favicon-196x196.png" />
|
||||||
<meta property="og:type" content="website" />
|
<meta property="og:type" content="website" />
|
||||||
|
|
||||||
<link rel="apple-touch-icon-precomposed" sizes="57x57" href="img/apple-touch-icon-57x57.png" />
|
<link rel="apple-touch-icon-precomposed" sizes="196x196" href="img/favicon-196x196.png" />
|
||||||
<link rel="apple-touch-icon-precomposed" sizes="114x114" href="img/apple-touch-icon-114x114.png" />
|
<link rel="apple-touch-icon-precomposed" sizes="152x152" href="img/favicon-152x152.png" />
|
||||||
<link rel="apple-touch-icon-precomposed" sizes="72x72" href="img/apple-touch-icon-72x72.png" />
|
<link rel="apple-touch-icon-precomposed" sizes="144x144" href="img/favicon-144x144.png" />
|
||||||
<link rel="apple-touch-icon-precomposed" sizes="144x144" href="img/apple-touch-icon-144x144.png" />
|
<link rel="apple-touch-icon-precomposed" sizes="128x128" href="img/favicon-128x128.png" />
|
||||||
<link rel="apple-touch-icon-precomposed" sizes="60x60" href="img/apple-touch-icon-60x60.png" />
|
<link rel="apple-touch-icon-precomposed" sizes="120x120" href="img/favicon-120x120.png" />
|
||||||
<link rel="apple-touch-icon-precomposed" sizes="120x120" href="img/apple-touch-icon-120x120.png" />
|
<link rel="apple-touch-icon-precomposed" sizes="114x114" href="img/favicon-114x114.png" />
|
||||||
<link rel="apple-touch-icon-precomposed" sizes="76x76" href="img/apple-touch-icon-76x76.png" />
|
<link rel="apple-touch-icon-precomposed" sizes="96x96" href="img/favicon-96x96.png" />
|
||||||
<link rel="apple-touch-icon-precomposed" sizes="152x152" href="img/apple-touch-icon-152x152.png" />
|
<link rel="apple-touch-icon-precomposed" sizes="76x76" href="img/favicon-76x76.png" />
|
||||||
|
<link rel="apple-touch-icon-precomposed" sizes="72x72" href="img/favicon-72x72.png" />
|
||||||
|
<link rel="apple-touch-icon-precomposed" sizes="64x64" href="img/favicon-64x64.png" />
|
||||||
|
<link rel="apple-touch-icon-precomposed" sizes="60x60" href="img/favicon-60x60.png" />
|
||||||
|
<link rel="apple-touch-icon-precomposed" sizes="57x57" href="img/favicon-57x57.png" />
|
||||||
|
<link rel="apple-touch-icon-precomposed" sizes="32x32" href="img/favicon-32x32.png" />
|
||||||
|
<link rel="apple-touch-icon-precomposed" sizes="16x16" href="img/favicon-16x16.png" />
|
||||||
<link rel="apple-touch-startup-image" href="img/favicon-196x196.png" />
|
<link rel="apple-touch-startup-image" href="img/favicon-196x196.png" />
|
||||||
|
|
||||||
<link rel="icon" type="image/png" href="img/favicon-196x196.png" sizes="196x196" />
|
<link rel="icon" type="image/png" href="img/favicon-196x196.png" sizes="196x196" />
|
||||||
|
<link rel="icon" type="image/png" href="img/favicon-152x152.png" sizes="152x152" />
|
||||||
|
<link rel="icon" type="image/png" href="img/favicon-144x144.png" sizes="144x144" />
|
||||||
|
<link rel="icon" type="image/png" href="img/favicon-128x128.png" sizes="128x128" />
|
||||||
|
<link rel="icon" type="image/png" href="img/favicon-120x120.png" sizes="120x120" />
|
||||||
|
<link rel="icon" type="image/png" href="img/favicon-114x114.png" sizes="114x114" />
|
||||||
<link rel="icon" type="image/png" href="img/favicon-96x96.png" sizes="96x96" />
|
<link rel="icon" type="image/png" href="img/favicon-96x96.png" sizes="96x96" />
|
||||||
|
<link rel="icon" type="image/png" href="img/favicon-76x76.png" sizes="76x76" />
|
||||||
|
<link rel="icon" type="image/png" href="img/favicon-72x72.png" sizes="72x72" />
|
||||||
|
<link rel="icon" type="image/png" href="img/favicon-64x64.png" sizes="64x64" />
|
||||||
|
<link rel="icon" type="image/png" href="img/favicon-60x60.png" sizes="60x60" />
|
||||||
|
<link rel="icon" type="image/png" href="img/favicon-57x57.png" sizes="57x57" />
|
||||||
<link rel="icon" type="image/png" href="img/favicon-32x32.png" sizes="32x32" />
|
<link rel="icon" type="image/png" href="img/favicon-32x32.png" sizes="32x32" />
|
||||||
<link rel="icon" type="image/png" href="img/favicon-16x16.png" sizes="16x16" />
|
<link rel="icon" type="image/png" href="img/favicon-16x16.png" sizes="16x16" />
|
||||||
<link rel="icon" type="image/png" href="img/favicon-128.png" sizes="128x128" />
|
|
||||||
<meta name="application-name" content="Moner.ooo" />
|
<meta name="application-name" content="Revuo Calc" />
|
||||||
<meta name="msapplication-TileColor" content="#ffffff" />
|
<meta name="msapplication-TileColor" content="#ffffff" />
|
||||||
<meta name="msapplication-TileImage" content="img/mstile-144x144.png" />
|
<meta name="msapplication-TileImage" content="img/favicon-196x196.png" />
|
||||||
<meta name="msapplication-square70x70logo" content="img/mstile-70x70.png" />
|
|
||||||
<meta name="msapplication-square150x150logo" content="img/mstile-150x150.png" />
|
|
||||||
<meta name="msapplication-wide310x150logo" content="img/mstile-310x150.png" />
|
|
||||||
<meta name="msapplication-square310x310logo" content="img/mstile-310x310.png" />
|
|
||||||
<meta name="theme-color" content="#193e4c" />
|
<meta name="theme-color" content="#193e4c" />
|
||||||
<meta name="apple-mobile-web-app-title" content="Moner.ooo" />
|
<meta name="apple-mobile-web-app-title" content="Revuo Calc" />
|
||||||
<meta name="apple-mobile-web-app-status-bar-style" content="#193e4c" />
|
<meta name="apple-mobile-web-app-status-bar-style" content="#193e4c" />
|
||||||
|
|
||||||
<link href="css/main.css" rel="stylesheet" />
|
<link href="css/main.css" rel="stylesheet" />
|
||||||
|
@ -123,7 +136,7 @@
|
||||||
<?php echo $info;
|
<?php echo $info;
|
||||||
if ($display_servers_guru) {
|
if ($display_servers_guru) {
|
||||||
echo $servers_guru;
|
echo $servers_guru;
|
||||||
};
|
}
|
||||||
echo $attribution; ?>
|
echo $attribution; ?>
|
||||||
</small>
|
</small>
|
||||||
<hr />
|
<hr />
|
||||||
|
@ -140,6 +153,7 @@
|
||||||
|
|
||||||
<small class="cursor-default text-white" lang="<?php echo $lang_meta; ?>">
|
<small class="cursor-default text-white" lang="<?php echo $lang_meta; ?>">
|
||||||
<?php echo $footer_links . $getmonero . $countrymonero; ?>
|
<?php echo $footer_links . $getmonero . $countrymonero; ?>
|
||||||
|
<?php echo $footer_html; ?>
|
||||||
</small>
|
</small>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
|
@ -29,9 +29,11 @@ module.exports = {
|
||||||
}),
|
}),
|
||||||
new PurgeCSSPlugin({
|
new PurgeCSSPlugin({
|
||||||
paths: glob.sync([
|
paths: glob.sync([
|
||||||
path.join(__dirname, 'index.php')
|
path.join(__dirname, 'index.php'),
|
||||||
|
path.join(__dirname, 'src/js/*.js'),
|
||||||
|
path.join(__dirname, 'templates/*.php'),
|
||||||
]),
|
]),
|
||||||
safelist: ['tooltip', 'fade', 'show', 'bs-tooltip-top', 'tooltip-inner', 'tooltip-arrow', 'btn-equals', 'btn-arrow', 'alert', 'alert-warning']
|
safelist: ['tooltip', 'fade', 'show', 'bs-tooltip-top', 'tooltip-inner', 'tooltip-arrow', 'btn-equals', 'btn-arrow', 'alert', 'alert-warning', 'donation-qr', 'donation-qr-toggle', 'donation-qr-container']
|
||||||
})
|
})
|
||||||
]
|
]
|
||||||
};
|
};
|