mirror of
https://github.com/chenasraf/nextcloud-autocurrency.git
synced 2026-05-17 17:28:06 +00:00
feat: add more fiat currencies + add many crypto currencies
This commit is contained in:
@@ -1,7 +1,4 @@
|
||||
{
|
||||
"plugins": [
|
||||
"prettier-plugin-vue"
|
||||
],
|
||||
"printWidth": 100,
|
||||
"semi": false,
|
||||
"singleQuote": true,
|
||||
|
||||
@@ -123,6 +123,47 @@ class ApiController extends OCSController {
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get crypto currencies with pagination and search
|
||||
*
|
||||
* @param string|null $search Search query to filter by code or name
|
||||
* @param int<1, 200> $limit Max results per page
|
||||
* @param int $offset Offset for pagination
|
||||
* @return DataResponse<Http::STATUS_OK, array{
|
||||
* currencies: list<array{code: string, symbol: string, name: string}>,
|
||||
* total: int
|
||||
* }, array{}>
|
||||
*
|
||||
* 200: Data returned
|
||||
*/
|
||||
#[NoAdminRequired]
|
||||
#[ApiRoute(verb: 'GET', url: '/api/crypto-currencies')]
|
||||
public function getCryptoCurrencies(
|
||||
?string $search = null,
|
||||
int $limit = 50,
|
||||
int $offset = 0,
|
||||
): DataResponse {
|
||||
$all = $this->service->getCryptoSymbols();
|
||||
|
||||
if ($search !== null && trim($search) !== '') {
|
||||
$q = mb_strtolower(trim($search), 'UTF-8');
|
||||
$all = array_filter($all, function ($sym) use ($q) {
|
||||
return str_contains(mb_strtolower((string)($sym['code'] ?? ''), 'UTF-8'), $q)
|
||||
|| str_contains(mb_strtolower((string)($sym['name'] ?? ''), 'UTF-8'), $q);
|
||||
});
|
||||
}
|
||||
|
||||
$total = count($all);
|
||||
$page = array_slice(array_values($all), $offset, max(1, min($limit, 200)));
|
||||
|
||||
$currencies = array_map(
|
||||
fn ($sym): array => ['name' => $sym['name'], 'code' => $sym['code'], 'symbol' => $sym['symbol']],
|
||||
$page
|
||||
);
|
||||
|
||||
return new DataResponse(['currencies' => $currencies, 'total' => $total]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Run cron immediately
|
||||
*
|
||||
@@ -224,7 +265,7 @@ class ApiController extends OCSController {
|
||||
* @param string|null $currency Quoted currency code to filter (e.g. "eur")
|
||||
* @param string|null $from ISO-8601 datetime (inclusive)
|
||||
* @param string|null $to ISO-8601 datetime (inclusive)
|
||||
* @param int|null $limit Max rows to return (optional)
|
||||
* @param int<1, 1000>|null $limit Max rows to return (optional)
|
||||
* @param int|null $offset Offset for pagination (optional)
|
||||
*
|
||||
* @return DataResponse<Http::STATUS_OK, array{
|
||||
|
||||
@@ -28,10 +28,17 @@ use Psr\Log\LoggerInterface;
|
||||
class FetchCurrenciesService {
|
||||
private static $EXCHANGE_URL = 'https://cdn.jsdelivr.net/npm/@fawazahmed0/currency-api@latest/v1/currencies/{base}.json';
|
||||
private static $SYMBOLS_FILE = __DIR__ . '/symbols.json';
|
||||
private static $CRYPTO_SYMBOLS_FILE = __DIR__ . '/symbols-crypto.json';
|
||||
|
||||
/** @var array<string, mixed> */
|
||||
/** @var array<string, mixed> Fiat currencies (displayed in UI) */
|
||||
public array $symbols = [];
|
||||
|
||||
/** @var array<string, mixed>|null Crypto currencies (lazy-loaded) */
|
||||
private ?array $cryptoSymbols = null;
|
||||
|
||||
/** @var array<string, mixed>|null All currencies including crypto (lazy-loaded) */
|
||||
private ?array $allSymbols = null;
|
||||
|
||||
/** @var array<string, mixed> */
|
||||
private array $symbolPreference = [];
|
||||
|
||||
@@ -489,7 +496,7 @@ class FetchCurrenciesService {
|
||||
$lower = mb_strtolower($original, 'UTF-8');
|
||||
|
||||
// Prefer explicit 3-letter code tokens (e.g., "US Dollar (USD)")
|
||||
foreach ($this->symbols as $code => $currency) {
|
||||
foreach ($this->getAllSymbols() as $code => $currency) {
|
||||
$id = mb_strtolower((string)$code, 'UTF-8');
|
||||
if (preg_match('/\b' . preg_quote($id, '/') . '\b/u', $lower)) {
|
||||
return $id;
|
||||
@@ -501,7 +508,7 @@ class FetchCurrenciesService {
|
||||
// Collect all codes hit by symbols, then resolve with preference.
|
||||
$hitsBySymbol = [];
|
||||
|
||||
foreach ($this->symbols as $code => $currency) {
|
||||
foreach ($this->getAllSymbols() as $code => $currency) {
|
||||
if (empty($currency['symbol'])) {
|
||||
continue;
|
||||
}
|
||||
@@ -543,10 +550,35 @@ class FetchCurrenciesService {
|
||||
return null;
|
||||
}
|
||||
|
||||
/** Load symbols from the symbols.json file */
|
||||
/**
|
||||
* Get crypto symbols (lazy-loaded)
|
||||
* @return array<string, mixed>
|
||||
*/
|
||||
public function getCryptoSymbols(): array {
|
||||
if ($this->cryptoSymbols === null) {
|
||||
$cryptoFile = FetchCurrenciesService::$CRYPTO_SYMBOLS_FILE;
|
||||
$this->cryptoSymbols = file_exists($cryptoFile)
|
||||
? (json_decode(file_get_contents($cryptoFile), true) ?? [])
|
||||
: [];
|
||||
}
|
||||
return $this->cryptoSymbols;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all symbols - fiat + crypto (lazy-loaded)
|
||||
* @return array<string, mixed>
|
||||
*/
|
||||
public function getAllSymbols(): array {
|
||||
if ($this->allSymbols === null) {
|
||||
$this->allSymbols = array_merge($this->symbols, $this->getCryptoSymbols());
|
||||
}
|
||||
return $this->allSymbols;
|
||||
}
|
||||
|
||||
/** Load fiat symbols from JSON file */
|
||||
private function loadSymbols(): void {
|
||||
$this->symbols = json_decode(file_get_contents(FetchCurrenciesService::$SYMBOLS_FILE), true);
|
||||
$this->logger->debug('Loaded symbols: ' . json_encode($this->symbols));
|
||||
$this->symbols = json_decode(file_get_contents(FetchCurrenciesService::$SYMBOLS_FILE), true) ?? [];
|
||||
$this->logger->debug('Loaded ' . count($this->symbols) . ' fiat symbols');
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
63533
lib/Service/symbols-crypto.json
Normal file
63533
lib/Service/symbols-crypto.json
Normal file
File diff suppressed because it is too large
Load Diff
@@ -35,6 +35,24 @@
|
||||
"code": "AMD",
|
||||
"name_plural": "Armenian drams"
|
||||
},
|
||||
"ANG": {
|
||||
"symbol": "ANG",
|
||||
"name": "Netherlands Antillean Guilder",
|
||||
"symbol_native": "ƒ",
|
||||
"decimal_digits": 2,
|
||||
"rounding": 0,
|
||||
"code": "ANG",
|
||||
"name_plural": "Netherlands Antillean guilders"
|
||||
},
|
||||
"AOA": {
|
||||
"symbol": "AOA",
|
||||
"name": "Angolan Kwanza",
|
||||
"symbol_native": "Kz",
|
||||
"decimal_digits": 2,
|
||||
"rounding": 0,
|
||||
"code": "AOA",
|
||||
"name_plural": "Angolan kwanzas"
|
||||
},
|
||||
"ARS": {
|
||||
"symbol": "AR$",
|
||||
"name": "Argentine Peso",
|
||||
@@ -53,6 +71,15 @@
|
||||
"code": "AUD",
|
||||
"name_plural": "Australian dollars"
|
||||
},
|
||||
"AWG": {
|
||||
"symbol": "AWG",
|
||||
"name": "Aruban Florin",
|
||||
"symbol_native": "ƒ",
|
||||
"decimal_digits": 2,
|
||||
"rounding": 0,
|
||||
"code": "AWG",
|
||||
"name_plural": "Aruban florin"
|
||||
},
|
||||
"AZN": {
|
||||
"symbol": "man.",
|
||||
"name": "Azerbaijani Manat",
|
||||
@@ -71,6 +98,15 @@
|
||||
"code": "BAM",
|
||||
"name_plural": "Bosnia-Herzegovina convertible marks"
|
||||
},
|
||||
"BBD": {
|
||||
"symbol": "BBD",
|
||||
"name": "Barbadian Dollar",
|
||||
"symbol_native": "$",
|
||||
"decimal_digits": 2,
|
||||
"rounding": 0,
|
||||
"code": "BBD",
|
||||
"name_plural": "Barbadian dollars"
|
||||
},
|
||||
"BDT": {
|
||||
"symbol": "Tk",
|
||||
"name": "Bangladeshi Taka",
|
||||
@@ -107,6 +143,15 @@
|
||||
"code": "BIF",
|
||||
"name_plural": "Burundian francs"
|
||||
},
|
||||
"BMD": {
|
||||
"symbol": "BMD",
|
||||
"name": "Bermudian Dollar",
|
||||
"symbol_native": "$",
|
||||
"decimal_digits": 2,
|
||||
"rounding": 0,
|
||||
"code": "BMD",
|
||||
"name_plural": "Bermudian dollars"
|
||||
},
|
||||
"BND": {
|
||||
"symbol": "BN$",
|
||||
"name": "Brunei Dollar",
|
||||
@@ -134,6 +179,24 @@
|
||||
"code": "BRL",
|
||||
"name_plural": "Brazilian reals"
|
||||
},
|
||||
"BSD": {
|
||||
"symbol": "BSD",
|
||||
"name": "Bahamian Dollar",
|
||||
"symbol_native": "$",
|
||||
"decimal_digits": 2,
|
||||
"rounding": 0,
|
||||
"code": "BSD",
|
||||
"name_plural": "Bahamian dollars"
|
||||
},
|
||||
"BTN": {
|
||||
"symbol": "BTN",
|
||||
"name": "Bhutanese Ngultrum",
|
||||
"symbol_native": "Nu.",
|
||||
"decimal_digits": 2,
|
||||
"rounding": 0,
|
||||
"code": "BTN",
|
||||
"name_plural": "Bhutanese ngultrums"
|
||||
},
|
||||
"BWP": {
|
||||
"symbol": "BWP",
|
||||
"name": "Botswanan Pula",
|
||||
@@ -224,6 +287,15 @@
|
||||
"code": "CRC",
|
||||
"name_plural": "Costa Rican colóns"
|
||||
},
|
||||
"CUC": {
|
||||
"symbol": "CUC",
|
||||
"name": "Cuban Convertible Peso",
|
||||
"symbol_native": "$",
|
||||
"decimal_digits": 2,
|
||||
"rounding": 0,
|
||||
"code": "CUC",
|
||||
"name_plural": "Cuban Convertible Pesos"
|
||||
},
|
||||
"CUP": {
|
||||
"symbol": "MN$",
|
||||
"name": "Cuban peso",
|
||||
@@ -296,6 +368,15 @@
|
||||
"code": "EGP",
|
||||
"name_plural": "Egyptian pounds"
|
||||
},
|
||||
"ERN": {
|
||||
"symbol": "ERN",
|
||||
"name": "Eritrean Nakfa",
|
||||
"symbol_native": "Nfk",
|
||||
"decimal_digits": 2,
|
||||
"rounding": 0,
|
||||
"code": "ERN",
|
||||
"name_plural": "Eritrean nakfas"
|
||||
},
|
||||
"ETB": {
|
||||
"symbol": "Br",
|
||||
"name": "Ethiopian Birr",
|
||||
@@ -314,6 +395,24 @@
|
||||
"code": "EUR",
|
||||
"name_plural": "Euros"
|
||||
},
|
||||
"FJD": {
|
||||
"symbol": "FJD",
|
||||
"name": "Fijian Dollar",
|
||||
"symbol_native": "$",
|
||||
"decimal_digits": 2,
|
||||
"rounding": 0,
|
||||
"code": "FJD",
|
||||
"name_plural": "Fijian dollars"
|
||||
},
|
||||
"FKP": {
|
||||
"symbol": "FKP",
|
||||
"name": "Falkland Islands Pound",
|
||||
"symbol_native": "£",
|
||||
"decimal_digits": 2,
|
||||
"rounding": 0,
|
||||
"code": "FKP",
|
||||
"name_plural": "Falkland Islands pounds"
|
||||
},
|
||||
"GBP": {
|
||||
"symbol": "£",
|
||||
"name": "British Pound Sterling",
|
||||
@@ -332,6 +431,15 @@
|
||||
"code": "GEL",
|
||||
"name_plural": "Georgian laris"
|
||||
},
|
||||
"GGP": {
|
||||
"symbol": "GGP",
|
||||
"name": "GamingGoProject",
|
||||
"symbol_native": "GGP",
|
||||
"decimal_digits": 8,
|
||||
"rounding": 0,
|
||||
"code": "GGP",
|
||||
"name_plural": "GamingGoProject"
|
||||
},
|
||||
"GHS": {
|
||||
"symbol": "GH₵",
|
||||
"name": "Ghanaian Cedi",
|
||||
@@ -341,6 +449,24 @@
|
||||
"code": "GHS",
|
||||
"name_plural": "Ghanaian cedis"
|
||||
},
|
||||
"GIP": {
|
||||
"symbol": "GIP",
|
||||
"name": "Gibraltar Pound",
|
||||
"symbol_native": "£",
|
||||
"decimal_digits": 2,
|
||||
"rounding": 0,
|
||||
"code": "GIP",
|
||||
"name_plural": "Gibraltar pounds"
|
||||
},
|
||||
"GMD": {
|
||||
"symbol": "GMD",
|
||||
"name": "Gambian Dalasi",
|
||||
"symbol_native": "D",
|
||||
"decimal_digits": 2,
|
||||
"rounding": 0,
|
||||
"code": "GMD",
|
||||
"name_plural": "Gambian dalasis"
|
||||
},
|
||||
"GNF": {
|
||||
"symbol": "FG",
|
||||
"name": "Guinean Franc",
|
||||
@@ -359,6 +485,15 @@
|
||||
"code": "GTQ",
|
||||
"name_plural": "Guatemalan quetzals"
|
||||
},
|
||||
"GYD": {
|
||||
"symbol": "GYD",
|
||||
"name": "Guyanese Dollar",
|
||||
"symbol_native": "$",
|
||||
"decimal_digits": 2,
|
||||
"rounding": 0,
|
||||
"code": "GYD",
|
||||
"name_plural": "Guyanese dollars"
|
||||
},
|
||||
"HKD": {
|
||||
"symbol": "HK$",
|
||||
"name": "Hong Kong Dollar",
|
||||
@@ -377,6 +512,24 @@
|
||||
"code": "HNL",
|
||||
"name_plural": "Honduran lempiras"
|
||||
},
|
||||
"HRK": {
|
||||
"symbol": "HRK",
|
||||
"name": "Croatian Kuna",
|
||||
"symbol_native": "HRK",
|
||||
"decimal_digits": 8,
|
||||
"rounding": 0,
|
||||
"code": "HRK",
|
||||
"name_plural": "Croatian Kuna"
|
||||
},
|
||||
"HTG": {
|
||||
"symbol": "HTG",
|
||||
"name": "Haitian Gourde",
|
||||
"symbol_native": "G",
|
||||
"decimal_digits": 2,
|
||||
"rounding": 0,
|
||||
"code": "HTG",
|
||||
"name_plural": "Haitian gourdes"
|
||||
},
|
||||
"HUF": {
|
||||
"symbol": "Ft",
|
||||
"name": "Hungarian Forint",
|
||||
@@ -404,6 +557,15 @@
|
||||
"code": "ILS",
|
||||
"name_plural": "Israeli new sheqels"
|
||||
},
|
||||
"IMP": {
|
||||
"symbol": "IMP",
|
||||
"name": "Ether Kingdoms Token",
|
||||
"symbol_native": "IMP",
|
||||
"decimal_digits": 8,
|
||||
"rounding": 0,
|
||||
"code": "IMP",
|
||||
"name_plural": "Ether Kingdoms Token"
|
||||
},
|
||||
"INR": {
|
||||
"symbol": "₹",
|
||||
"name": "Indian Rupee",
|
||||
@@ -440,6 +602,15 @@
|
||||
"code": "ISK",
|
||||
"name_plural": "Icelandic krónur"
|
||||
},
|
||||
"JEP": {
|
||||
"symbol": "JEP",
|
||||
"name": "Jersey Pound",
|
||||
"symbol_native": "JEP",
|
||||
"decimal_digits": 8,
|
||||
"rounding": 0,
|
||||
"code": "JEP",
|
||||
"name_plural": "Jersey Pound"
|
||||
},
|
||||
"JMD": {
|
||||
"symbol": "J$",
|
||||
"name": "Jamaican Dollar",
|
||||
@@ -476,6 +647,15 @@
|
||||
"code": "KES",
|
||||
"name_plural": "Kenyan shillings"
|
||||
},
|
||||
"KGS": {
|
||||
"symbol": "KGS",
|
||||
"name": "Kyrgyzstani Som",
|
||||
"symbol_native": "с",
|
||||
"decimal_digits": 2,
|
||||
"rounding": 0,
|
||||
"code": "KGS",
|
||||
"name_plural": "Kyrgyzstani soms"
|
||||
},
|
||||
"KHR": {
|
||||
"symbol": "KHR",
|
||||
"name": "Cambodian Riel",
|
||||
@@ -494,6 +674,15 @@
|
||||
"code": "KMF",
|
||||
"name_plural": "Comorian francs"
|
||||
},
|
||||
"KPW": {
|
||||
"symbol": "KPW",
|
||||
"name": "North Korean Won",
|
||||
"symbol_native": "₩",
|
||||
"decimal_digits": 2,
|
||||
"rounding": 0,
|
||||
"code": "KPW",
|
||||
"name_plural": "North Korean won"
|
||||
},
|
||||
"KRW": {
|
||||
"symbol": "₩",
|
||||
"name": "South Korean Won",
|
||||
@@ -512,6 +701,15 @@
|
||||
"code": "KWD",
|
||||
"name_plural": "Kuwaiti dinars"
|
||||
},
|
||||
"KYD": {
|
||||
"symbol": "KYD",
|
||||
"name": "Cayman Islands Dollar",
|
||||
"symbol_native": "$",
|
||||
"decimal_digits": 2,
|
||||
"rounding": 0,
|
||||
"code": "KYD",
|
||||
"name_plural": "Cayman Islands dollars"
|
||||
},
|
||||
"KZT": {
|
||||
"symbol": "KZT",
|
||||
"name": "Kazakhstani Tenge",
|
||||
@@ -521,6 +719,15 @@
|
||||
"code": "KZT",
|
||||
"name_plural": "Kazakhstani tenges"
|
||||
},
|
||||
"LAK": {
|
||||
"symbol": "LAK",
|
||||
"name": "Lao Kip",
|
||||
"symbol_native": "₭",
|
||||
"decimal_digits": 2,
|
||||
"rounding": 0,
|
||||
"code": "LAK",
|
||||
"name_plural": "Lao kips"
|
||||
},
|
||||
"LBP": {
|
||||
"symbol": "L.L.",
|
||||
"name": "Lebanese Pound",
|
||||
@@ -539,6 +746,24 @@
|
||||
"code": "LKR",
|
||||
"name_plural": "Sri Lankan rupees"
|
||||
},
|
||||
"LRD": {
|
||||
"symbol": "LRD",
|
||||
"name": "Liberian Dollar",
|
||||
"symbol_native": "$",
|
||||
"decimal_digits": 2,
|
||||
"rounding": 0,
|
||||
"code": "LRD",
|
||||
"name_plural": "Liberian dollars"
|
||||
},
|
||||
"LSL": {
|
||||
"symbol": "LSL",
|
||||
"name": "Lesotho Loti",
|
||||
"symbol_native": "L",
|
||||
"decimal_digits": 2,
|
||||
"rounding": 0,
|
||||
"code": "LSL",
|
||||
"name_plural": "Lesotho maloti"
|
||||
},
|
||||
"LYD": {
|
||||
"symbol": "LD",
|
||||
"name": "Libyan Dinar",
|
||||
@@ -593,6 +818,15 @@
|
||||
"code": "MMK",
|
||||
"name_plural": "Myanma kyats"
|
||||
},
|
||||
"MNT": {
|
||||
"symbol": "MNT",
|
||||
"name": "Mongolian Tugrik",
|
||||
"symbol_native": "₮",
|
||||
"decimal_digits": 2,
|
||||
"rounding": 0,
|
||||
"code": "MNT",
|
||||
"name_plural": "Mongolian tugriks"
|
||||
},
|
||||
"MOP": {
|
||||
"symbol": "MOP$",
|
||||
"name": "Macanese Pataca",
|
||||
@@ -602,6 +836,24 @@
|
||||
"code": "MOP",
|
||||
"name_plural": "Macanese patacas"
|
||||
},
|
||||
"MRO": {
|
||||
"symbol": "MRO",
|
||||
"name": "Mauritanian Ouguiya",
|
||||
"symbol_native": "MRO",
|
||||
"decimal_digits": 8,
|
||||
"rounding": 0,
|
||||
"code": "MRO",
|
||||
"name_plural": "Mauritanian Ouguiya"
|
||||
},
|
||||
"MRU": {
|
||||
"symbol": "MRU",
|
||||
"name": "Mauritanian Ouguiya",
|
||||
"symbol_native": "UM",
|
||||
"decimal_digits": 2,
|
||||
"rounding": 0,
|
||||
"code": "MRU",
|
||||
"name_plural": "Mauritanian ouguiyas"
|
||||
},
|
||||
"MUR": {
|
||||
"symbol": "MURs",
|
||||
"name": "Mauritian Rupee",
|
||||
@@ -611,6 +863,24 @@
|
||||
"code": "MUR",
|
||||
"name_plural": "Mauritian rupees"
|
||||
},
|
||||
"MVR": {
|
||||
"symbol": "MVR",
|
||||
"name": "Maldivian Rufiyaa",
|
||||
"symbol_native": ".ރ",
|
||||
"decimal_digits": 2,
|
||||
"rounding": 0,
|
||||
"code": "MVR",
|
||||
"name_plural": "Maldivian rufiyaas"
|
||||
},
|
||||
"MWK": {
|
||||
"symbol": "MWK",
|
||||
"name": "Malawian Kwacha",
|
||||
"symbol_native": "MK",
|
||||
"decimal_digits": 2,
|
||||
"rounding": 0,
|
||||
"code": "MWK",
|
||||
"name_plural": "Malawian kwachas"
|
||||
},
|
||||
"MXN": {
|
||||
"symbol": "MX$",
|
||||
"name": "Mexican Peso",
|
||||
@@ -719,6 +989,15 @@
|
||||
"code": "PEN",
|
||||
"name_plural": "Peruvian nuevos soles"
|
||||
},
|
||||
"PGK": {
|
||||
"symbol": "PGK",
|
||||
"name": "Papua New Guinean Kina",
|
||||
"symbol_native": "K",
|
||||
"decimal_digits": 2,
|
||||
"rounding": 0,
|
||||
"code": "PGK",
|
||||
"name_plural": "Papua New Guinean kina"
|
||||
},
|
||||
"PHP": {
|
||||
"symbol": "₱",
|
||||
"name": "Philippine Peso",
|
||||
@@ -809,6 +1088,24 @@
|
||||
"code": "SAR",
|
||||
"name_plural": "Saudi riyals"
|
||||
},
|
||||
"SBD": {
|
||||
"symbol": "SBD",
|
||||
"name": "Solomon Islands Dollar",
|
||||
"symbol_native": "$",
|
||||
"decimal_digits": 2,
|
||||
"rounding": 0,
|
||||
"code": "SBD",
|
||||
"name_plural": "Solomon Islands dollars"
|
||||
},
|
||||
"SCR": {
|
||||
"symbol": "SCR",
|
||||
"name": "Seychellois Rupee",
|
||||
"symbol_native": "₨",
|
||||
"decimal_digits": 2,
|
||||
"rounding": 0,
|
||||
"code": "SCR",
|
||||
"name_plural": "Seychellois rupees"
|
||||
},
|
||||
"SDG": {
|
||||
"symbol": "SDG",
|
||||
"name": "Sudanese Pound",
|
||||
@@ -836,6 +1133,33 @@
|
||||
"code": "SGD",
|
||||
"name_plural": "Singapore dollars"
|
||||
},
|
||||
"SHP": {
|
||||
"symbol": "SHP",
|
||||
"name": "Saint Helena Pound",
|
||||
"symbol_native": "£",
|
||||
"decimal_digits": 2,
|
||||
"rounding": 0,
|
||||
"code": "SHP",
|
||||
"name_plural": "Saint Helena pounds"
|
||||
},
|
||||
"SLE": {
|
||||
"symbol": "SLE",
|
||||
"name": "Sierra Leonean Leone",
|
||||
"symbol_native": "SLE",
|
||||
"decimal_digits": 8,
|
||||
"rounding": 0,
|
||||
"code": "SLE",
|
||||
"name_plural": "Sierra Leonean Leone"
|
||||
},
|
||||
"SLL": {
|
||||
"symbol": "SLL",
|
||||
"name": "Sierra Leonean Leone (Old)",
|
||||
"symbol_native": "Le",
|
||||
"decimal_digits": 2,
|
||||
"rounding": 0,
|
||||
"code": "SLL",
|
||||
"name_plural": "Sierra Leonean leones"
|
||||
},
|
||||
"SOS": {
|
||||
"symbol": "Ssh",
|
||||
"name": "Somali Shilling",
|
||||
@@ -845,6 +1169,78 @@
|
||||
"code": "SOS",
|
||||
"name_plural": "Somali shillings"
|
||||
},
|
||||
"SPL": {
|
||||
"symbol": "SPL",
|
||||
"name": "Seborgan Luigino",
|
||||
"symbol_native": "SPL",
|
||||
"decimal_digits": 8,
|
||||
"rounding": 0,
|
||||
"code": "SPL",
|
||||
"name_plural": "Seborgan Luigino"
|
||||
},
|
||||
"SRD": {
|
||||
"symbol": "SRD",
|
||||
"name": "Surinamese Dollar",
|
||||
"symbol_native": "$",
|
||||
"decimal_digits": 2,
|
||||
"rounding": 0,
|
||||
"code": "SRD",
|
||||
"name_plural": "Surinamese dollars"
|
||||
},
|
||||
"SSP": {
|
||||
"symbol": "SSP",
|
||||
"name": "South Sudanese Pound",
|
||||
"symbol_native": "£",
|
||||
"decimal_digits": 2,
|
||||
"rounding": 0,
|
||||
"code": "SSP",
|
||||
"name_plural": "South Sudanese pounds"
|
||||
},
|
||||
"STD": {
|
||||
"symbol": "STD",
|
||||
"name": "Sao Tomean Dobra",
|
||||
"symbol_native": "STD",
|
||||
"decimal_digits": 8,
|
||||
"rounding": 0,
|
||||
"code": "STD",
|
||||
"name_plural": "Sao Tomean Dobra"
|
||||
},
|
||||
"STN": {
|
||||
"symbol": "STN",
|
||||
"name": "São Tomé and Príncipe Dobra",
|
||||
"symbol_native": "Db",
|
||||
"decimal_digits": 2,
|
||||
"rounding": 0,
|
||||
"code": "STN",
|
||||
"name_plural": "São Tomé and Príncipe dobras"
|
||||
},
|
||||
"SVC": {
|
||||
"symbol": "SVC",
|
||||
"name": "Salvadoran Colon",
|
||||
"symbol_native": "SVC",
|
||||
"decimal_digits": 8,
|
||||
"rounding": 0,
|
||||
"code": "SVC",
|
||||
"name_plural": "Salvadoran Colon"
|
||||
},
|
||||
"SYP": {
|
||||
"symbol": "SYP",
|
||||
"name": "Syrian Pound",
|
||||
"symbol_native": "ل.س",
|
||||
"decimal_digits": 2,
|
||||
"rounding": 0,
|
||||
"code": "SYP",
|
||||
"name_plural": "Syrian pounds"
|
||||
},
|
||||
"SZL": {
|
||||
"symbol": "SZL",
|
||||
"name": "Swazi Lilangeni",
|
||||
"symbol_native": "E",
|
||||
"decimal_digits": 2,
|
||||
"rounding": 0,
|
||||
"code": "SZL",
|
||||
"name_plural": "Swazi emalangeni"
|
||||
},
|
||||
"THB": {
|
||||
"symbol": "฿",
|
||||
"name": "Thai Baht",
|
||||
@@ -854,6 +1250,24 @@
|
||||
"code": "THB",
|
||||
"name_plural": "Thai baht"
|
||||
},
|
||||
"TJS": {
|
||||
"symbol": "TJS",
|
||||
"name": "Tajikistani Somoni",
|
||||
"symbol_native": "SM",
|
||||
"decimal_digits": 2,
|
||||
"rounding": 0,
|
||||
"code": "TJS",
|
||||
"name_plural": "Tajikistani somonis"
|
||||
},
|
||||
"TMT": {
|
||||
"symbol": "TMT",
|
||||
"name": "Turkmenistani Manat",
|
||||
"symbol_native": "m",
|
||||
"decimal_digits": 2,
|
||||
"rounding": 0,
|
||||
"code": "TMT",
|
||||
"name_plural": "Turkmenistani manats"
|
||||
},
|
||||
"TND": {
|
||||
"symbol": "DT",
|
||||
"name": "Tunisian Dinar",
|
||||
@@ -890,6 +1304,15 @@
|
||||
"code": "TTD",
|
||||
"name_plural": "Trinidad and Tobago dollars"
|
||||
},
|
||||
"TVD": {
|
||||
"symbol": "TVD",
|
||||
"name": "Tuvaluan Dollar",
|
||||
"symbol_native": "TVD",
|
||||
"decimal_digits": 8,
|
||||
"rounding": 0,
|
||||
"code": "TVD",
|
||||
"name_plural": "Tuvaluan Dollar"
|
||||
},
|
||||
"TWD": {
|
||||
"symbol": "NT$",
|
||||
"name": "New Taiwan Dollar",
|
||||
@@ -953,6 +1376,15 @@
|
||||
"code": "UZS",
|
||||
"name_plural": "Uzbekistan som"
|
||||
},
|
||||
"VES": {
|
||||
"symbol": "VES",
|
||||
"name": "Venezuelan Bolívar",
|
||||
"symbol_native": "Bs.",
|
||||
"decimal_digits": 2,
|
||||
"rounding": 0,
|
||||
"code": "VES",
|
||||
"name_plural": "Venezuelan bolívars"
|
||||
},
|
||||
"VND": {
|
||||
"symbol": "₫",
|
||||
"name": "Vietnamese Dong",
|
||||
@@ -962,6 +1394,24 @@
|
||||
"code": "VND",
|
||||
"name_plural": "Vietnamese dong"
|
||||
},
|
||||
"VUV": {
|
||||
"symbol": "VUV",
|
||||
"name": "Vanuatu Vatu",
|
||||
"symbol_native": "VT",
|
||||
"decimal_digits": 0,
|
||||
"rounding": 0,
|
||||
"code": "VUV",
|
||||
"name_plural": "Vanuatu vatus"
|
||||
},
|
||||
"WST": {
|
||||
"symbol": "WST",
|
||||
"name": "Samoan Tala",
|
||||
"symbol_native": "T",
|
||||
"decimal_digits": 2,
|
||||
"rounding": 0,
|
||||
"code": "WST",
|
||||
"name_plural": "Samoan tala"
|
||||
},
|
||||
"XAF": {
|
||||
"symbol": "FCFA",
|
||||
"name": "CFA Franc BEAC",
|
||||
@@ -980,6 +1430,15 @@
|
||||
"code": "XCD",
|
||||
"name_plural": "Eastern Caribbean dollars"
|
||||
},
|
||||
"XDR": {
|
||||
"symbol": "XDR",
|
||||
"name": "IMF Special Drawing Rights",
|
||||
"symbol_native": "XDR",
|
||||
"decimal_digits": 8,
|
||||
"rounding": 0,
|
||||
"code": "XDR",
|
||||
"name_plural": "IMF Special Drawing Rights"
|
||||
},
|
||||
"XOF": {
|
||||
"symbol": "CFA",
|
||||
"name": "CFA Franc BCEAO",
|
||||
@@ -989,6 +1448,15 @@
|
||||
"code": "XOF",
|
||||
"name_plural": "CFA francs BCEAO"
|
||||
},
|
||||
"XPF": {
|
||||
"symbol": "XPF",
|
||||
"name": "CFP Franc",
|
||||
"symbol_native": "₣",
|
||||
"decimal_digits": 0,
|
||||
"rounding": 0,
|
||||
"code": "XPF",
|
||||
"name_plural": "CFP francs"
|
||||
},
|
||||
"YER": {
|
||||
"symbol": "YR",
|
||||
"name": "Yemeni Rial",
|
||||
@@ -1006,5 +1474,32 @@
|
||||
"rounding": 0,
|
||||
"code": "ZAR",
|
||||
"name_plural": "South African rand"
|
||||
},
|
||||
"ZMW": {
|
||||
"symbol": "ZMW",
|
||||
"name": "Zambian Kwacha",
|
||||
"symbol_native": "ZK",
|
||||
"decimal_digits": 2,
|
||||
"rounding": 0,
|
||||
"code": "ZMW",
|
||||
"name_plural": "Zambian kwachas"
|
||||
},
|
||||
"ZWD": {
|
||||
"symbol": "ZWD",
|
||||
"name": "Zimbabwean Dollar",
|
||||
"symbol_native": "ZWD",
|
||||
"decimal_digits": 8,
|
||||
"rounding": 0,
|
||||
"code": "ZWD",
|
||||
"name_plural": "Zimbabwean Dollar"
|
||||
},
|
||||
"ZWL": {
|
||||
"symbol": "ZWL",
|
||||
"name": "Zimbabwean Dollar",
|
||||
"symbol_native": "ZWL",
|
||||
"decimal_digits": 8,
|
||||
"rounding": 0,
|
||||
"code": "ZWL",
|
||||
"name_plural": "Zimbabwean Dollar"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1409,6 +1409,159 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"/ocs/v2.php/apps/autocurrency/api/crypto-currencies": {
|
||||
"get": {
|
||||
"operationId": "api-get-crypto-currencies",
|
||||
"summary": "Get crypto currencies with pagination and search",
|
||||
"tags": [
|
||||
"api"
|
||||
],
|
||||
"security": [
|
||||
{
|
||||
"bearer_auth": []
|
||||
},
|
||||
{
|
||||
"basic_auth": []
|
||||
}
|
||||
],
|
||||
"parameters": [
|
||||
{
|
||||
"name": "search",
|
||||
"in": "query",
|
||||
"description": "Search query to filter by code or name",
|
||||
"schema": {
|
||||
"type": "string",
|
||||
"nullable": true,
|
||||
"default": null
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "limit",
|
||||
"in": "query",
|
||||
"description": "Max results per page",
|
||||
"schema": {
|
||||
"type": "integer",
|
||||
"format": "int64",
|
||||
"default": 50,
|
||||
"minimum": 1,
|
||||
"maximum": 200
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "offset",
|
||||
"in": "query",
|
||||
"description": "Offset for pagination",
|
||||
"schema": {
|
||||
"type": "integer",
|
||||
"format": "int64",
|
||||
"default": 0
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "OCS-APIRequest",
|
||||
"in": "header",
|
||||
"description": "Required to be true for the API request to pass",
|
||||
"required": true,
|
||||
"schema": {
|
||||
"type": "boolean",
|
||||
"default": true
|
||||
}
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "Data returned",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"ocs"
|
||||
],
|
||||
"properties": {
|
||||
"ocs": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"meta",
|
||||
"data"
|
||||
],
|
||||
"properties": {
|
||||
"meta": {
|
||||
"$ref": "#/components/schemas/OCSMeta"
|
||||
},
|
||||
"data": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"currencies",
|
||||
"total"
|
||||
],
|
||||
"properties": {
|
||||
"currencies": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"code",
|
||||
"symbol",
|
||||
"name"
|
||||
],
|
||||
"properties": {
|
||||
"code": {
|
||||
"type": "string"
|
||||
},
|
||||
"symbol": {
|
||||
"type": "string"
|
||||
},
|
||||
"name": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"total": {
|
||||
"type": "integer",
|
||||
"format": "int64"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"401": {
|
||||
"description": "Current user is not logged in",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"ocs"
|
||||
],
|
||||
"properties": {
|
||||
"ocs": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"meta",
|
||||
"data"
|
||||
],
|
||||
"properties": {
|
||||
"meta": {
|
||||
"$ref": "#/components/schemas/OCSMeta"
|
||||
},
|
||||
"data": {}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/ocs/v2.php/apps/autocurrency/api/projects": {
|
||||
"get": {
|
||||
"operationId": "api-get-projects",
|
||||
@@ -1589,7 +1742,9 @@
|
||||
"type": "integer",
|
||||
"format": "int64",
|
||||
"nullable": true,
|
||||
"default": null
|
||||
"default": null,
|
||||
"minimum": 1,
|
||||
"maximum": 1000
|
||||
}
|
||||
},
|
||||
{
|
||||
|
||||
157
openapi.json
157
openapi.json
@@ -163,6 +163,159 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"/ocs/v2.php/apps/autocurrency/api/crypto-currencies": {
|
||||
"get": {
|
||||
"operationId": "api-get-crypto-currencies",
|
||||
"summary": "Get crypto currencies with pagination and search",
|
||||
"tags": [
|
||||
"api"
|
||||
],
|
||||
"security": [
|
||||
{
|
||||
"bearer_auth": []
|
||||
},
|
||||
{
|
||||
"basic_auth": []
|
||||
}
|
||||
],
|
||||
"parameters": [
|
||||
{
|
||||
"name": "search",
|
||||
"in": "query",
|
||||
"description": "Search query to filter by code or name",
|
||||
"schema": {
|
||||
"type": "string",
|
||||
"nullable": true,
|
||||
"default": null
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "limit",
|
||||
"in": "query",
|
||||
"description": "Max results per page",
|
||||
"schema": {
|
||||
"type": "integer",
|
||||
"format": "int64",
|
||||
"default": 50,
|
||||
"minimum": 1,
|
||||
"maximum": 200
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "offset",
|
||||
"in": "query",
|
||||
"description": "Offset for pagination",
|
||||
"schema": {
|
||||
"type": "integer",
|
||||
"format": "int64",
|
||||
"default": 0
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "OCS-APIRequest",
|
||||
"in": "header",
|
||||
"description": "Required to be true for the API request to pass",
|
||||
"required": true,
|
||||
"schema": {
|
||||
"type": "boolean",
|
||||
"default": true
|
||||
}
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "Data returned",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"ocs"
|
||||
],
|
||||
"properties": {
|
||||
"ocs": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"meta",
|
||||
"data"
|
||||
],
|
||||
"properties": {
|
||||
"meta": {
|
||||
"$ref": "#/components/schemas/OCSMeta"
|
||||
},
|
||||
"data": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"currencies",
|
||||
"total"
|
||||
],
|
||||
"properties": {
|
||||
"currencies": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"code",
|
||||
"symbol",
|
||||
"name"
|
||||
],
|
||||
"properties": {
|
||||
"code": {
|
||||
"type": "string"
|
||||
},
|
||||
"symbol": {
|
||||
"type": "string"
|
||||
},
|
||||
"name": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"total": {
|
||||
"type": "integer",
|
||||
"format": "int64"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"401": {
|
||||
"description": "Current user is not logged in",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"ocs"
|
||||
],
|
||||
"properties": {
|
||||
"ocs": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"meta",
|
||||
"data"
|
||||
],
|
||||
"properties": {
|
||||
"meta": {
|
||||
"$ref": "#/components/schemas/OCSMeta"
|
||||
},
|
||||
"data": {}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/ocs/v2.php/apps/autocurrency/api/projects": {
|
||||
"get": {
|
||||
"operationId": "api-get-projects",
|
||||
@@ -343,7 +496,9 @@
|
||||
"type": "integer",
|
||||
"format": "int64",
|
||||
"nullable": true,
|
||||
"default": null
|
||||
"default": null,
|
||||
"minimum": 1,
|
||||
"maximum": 1000
|
||||
}
|
||||
},
|
||||
{
|
||||
|
||||
@@ -21,9 +21,11 @@
|
||||
<li>❌ <code>US Dollar</code></li>
|
||||
<li>❌ <code>United States Dollar</code></li>
|
||||
</ul>
|
||||
</NcSettingsSection>
|
||||
|
||||
<NcSettingsSection :name="strings.supportedCurrenciesTitle">
|
||||
<div class="currency-list">
|
||||
<p>{{ strings.supportedCurrencies }}</p>
|
||||
<p>{{ strings.supportedFiatCurrencies(supportedCurrencies.length) }}</p>
|
||||
|
||||
<div style="max-width: 300px">
|
||||
<NcTextField
|
||||
@@ -53,6 +55,41 @@
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<div class="currency-list mt">
|
||||
<p>{{ strings.supportedCryptoCurrencies(cryptoTotalAll) }}</p>
|
||||
|
||||
<div style="max-width: 300px">
|
||||
<NcTextField
|
||||
v-model="cryptoSearch"
|
||||
:label="strings.currencySearchLabel"
|
||||
trailing-button-icon="close"
|
||||
:placeholder="strings.cryptoSearchPlaceholder"
|
||||
:show-trailing-button="cryptoSearch !== ''"
|
||||
@trailing-button-click="clearCryptoSearch"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>{{ strings.tableSymbol }}</th>
|
||||
<th>{{ strings.tableCode }}</th>
|
||||
<th>{{ strings.tableName }}</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody ref="cryptoTbody" @scroll="onCryptoScroll">
|
||||
<tr v-for="currency in cryptoCurrencies" :key="currency.code">
|
||||
<td>{{ currency.symbol }}</td>
|
||||
<td>{{ currency.code }}</td>
|
||||
<td>{{ currency.name }}</td>
|
||||
</tr>
|
||||
<tr v-if="cryptoLoading">
|
||||
<td colspan="3" style="text-align: center">{{ strings.loading }}</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</NcSettingsSection>
|
||||
|
||||
<NcSettingsSection :name="strings.historyHeader">
|
||||
@@ -154,6 +191,14 @@ export default {
|
||||
loading: true as boolean,
|
||||
supportedCurrencies: [] as SupportedCurrency[],
|
||||
currencySearch: '' as string,
|
||||
cryptoCurrencies: [] as SupportedCurrency[],
|
||||
cryptoSearch: '' as string,
|
||||
cryptoSearchDebounce: null as ReturnType<typeof setTimeout> | null,
|
||||
cryptoTotalAll: 0 as number,
|
||||
cryptoTotal: 0 as number,
|
||||
cryptoOffset: 0 as number,
|
||||
cryptoLoading: false as boolean,
|
||||
cryptoHasMore: true as boolean,
|
||||
projectsLoading: true as boolean,
|
||||
projects: [] as Project[],
|
||||
selectedProject: null as Project | null,
|
||||
@@ -204,7 +249,13 @@ export default {
|
||||
{ escape: false },
|
||||
),
|
||||
exampleHeader: t(APP_ID, 'Example names:'),
|
||||
supportedCurrencies: t(APP_ID, 'Supported currencies:'),
|
||||
supportedCurrenciesTitle: t(APP_ID, 'Supported currencies'),
|
||||
supportedFiatCurrencies: (count: number) =>
|
||||
t(APP_ID, 'Supported fiat currencies ({count}):', { count: count.toLocaleString() }),
|
||||
supportedCryptoCurrencies: (count: number) =>
|
||||
t(APP_ID, 'Supported cryptocurrencies ({count}):', { count: count.toLocaleString() }),
|
||||
loading: t(APP_ID, 'Loading…'),
|
||||
cryptoSearchPlaceholder: t(APP_ID, 'e.g. BTC, Bitcoin'),
|
||||
currencySearchLabel: t(APP_ID, 'Search'),
|
||||
currencySearchPlaceholder: t(APP_ID, 'e.g. $, USD, US Dollar'),
|
||||
tableSymbol: t(APP_ID, 'Symbol'),
|
||||
@@ -223,6 +274,7 @@ export default {
|
||||
},
|
||||
async created() {
|
||||
await this.fetchSettings()
|
||||
this.fetchCryptoCurrencies()
|
||||
await this.fetchProjects()
|
||||
},
|
||||
watch: {
|
||||
@@ -246,6 +298,15 @@ export default {
|
||||
showReversed() {
|
||||
this.$nextTick(() => this.renderChart())
|
||||
},
|
||||
cryptoSearch() {
|
||||
if (this.cryptoSearchDebounce) clearTimeout(this.cryptoSearchDebounce)
|
||||
this.cryptoSearchDebounce = setTimeout(() => {
|
||||
this.cryptoCurrencies = []
|
||||
this.cryptoOffset = 0
|
||||
this.cryptoHasMore = true
|
||||
this.fetchCryptoCurrencies()
|
||||
}, 300)
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
formatDate(value: Date | string | null | undefined): string {
|
||||
@@ -254,8 +315,8 @@ export default {
|
||||
value instanceof Date
|
||||
? value
|
||||
: typeof value === 'string'
|
||||
? parseDate(value)
|
||||
: new Date(value as any)
|
||||
? parseDate(value)
|
||||
: new Date(value as any)
|
||||
|
||||
if (!isValid(d)) {
|
||||
console.warn('Invalid date received:', value)
|
||||
@@ -288,6 +349,45 @@ export default {
|
||||
this.currencySearch = ''
|
||||
},
|
||||
|
||||
clearCryptoSearch() {
|
||||
this.cryptoSearch = ''
|
||||
},
|
||||
|
||||
async fetchCryptoCurrencies() {
|
||||
if (this.cryptoLoading || !this.cryptoHasMore) return
|
||||
try {
|
||||
this.cryptoLoading = true
|
||||
const params: Record<string, string | number> = {
|
||||
limit: 50,
|
||||
offset: this.cryptoOffset,
|
||||
}
|
||||
if (this.cryptoSearch.trim()) {
|
||||
params.search = this.cryptoSearch.trim()
|
||||
}
|
||||
const resp = await ocs.get('/crypto-currencies', { params })
|
||||
const data = resp.data ?? {}
|
||||
const items: SupportedCurrency[] = data.currencies ?? []
|
||||
this.cryptoTotal = data.total ?? 0
|
||||
if (this.cryptoTotalAll === 0) {
|
||||
this.cryptoTotalAll = this.cryptoTotal
|
||||
}
|
||||
this.cryptoCurrencies = [...this.cryptoCurrencies, ...items]
|
||||
this.cryptoOffset += items.length
|
||||
this.cryptoHasMore = this.cryptoOffset < this.cryptoTotal
|
||||
} catch (e) {
|
||||
console.error('Failed to fetch crypto currencies', e)
|
||||
} finally {
|
||||
this.cryptoLoading = false
|
||||
}
|
||||
},
|
||||
|
||||
onCryptoScroll(e: Event) {
|
||||
const el = e.target as HTMLElement
|
||||
if (el.scrollTop + el.clientHeight >= el.scrollHeight - 40) {
|
||||
this.fetchCryptoCurrencies()
|
||||
}
|
||||
},
|
||||
|
||||
async fetchProjects() {
|
||||
try {
|
||||
this.projectsLoading = true
|
||||
@@ -571,7 +671,10 @@ export default {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 8px;
|
||||
margin-top: 2em;
|
||||
|
||||
&.mt {
|
||||
margin-top: 2em;
|
||||
}
|
||||
}
|
||||
|
||||
.history-block {
|
||||
@@ -586,7 +689,7 @@ export default {
|
||||
@media (max-width: 1280px) {
|
||||
grid-template-columns: 1fr 1fr;
|
||||
|
||||
>* {
|
||||
> * {
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -58,6 +58,10 @@ final class FetchCurrenciesServiceTest extends TestCase {
|
||||
$propSymbols = $ref->getProperty('symbols');
|
||||
$propSymbols->setAccessible(true);
|
||||
$propSymbols->setValue($this->resolver, $symbols);
|
||||
|
||||
$propAllSymbols = $ref->getProperty('allSymbols');
|
||||
$propAllSymbols->setAccessible(true);
|
||||
$propAllSymbols->setValue($this->resolver, $symbols);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -31,8 +31,12 @@ async function main() {
|
||||
console.log(`Fetched ${Object.keys(rates.usd).length} currencies`)
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
||||
const symbols = require('../lib/Service/symbols.json')
|
||||
const finalJson = findIntersections(symbols, rates)
|
||||
const fiatSymbols = require('../lib/Service/symbols.json')
|
||||
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
||||
const cryptoSymbols = require('../lib/Service/symbols-crypto.json')
|
||||
|
||||
const allSymbols = { ...fiatSymbols, ...cryptoSymbols }
|
||||
const finalJson = findIntersections(allSymbols, rates)
|
||||
|
||||
console.log(JSON.stringify(finalJson, null, 2))
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user