2021-10-03 10:40:21 +02:00
|
|
|
import * as currencies from '@dinero.js/currencies';
|
2022-02-02 20:07:33 +01:00
|
|
|
import { DataSource } from '@prisma/client';
|
2021-07-26 22:13:09 +02:00
|
|
|
import { getDate, getMonth, getYear, parse, subDays } from 'date-fns';
|
2021-04-13 21:53:58 +02:00
|
|
|
|
2022-04-05 21:02:07 +02:00
|
|
|
import { ghostfolioScraperApiSymbolPrefix, locale } from './config';
|
2022-05-27 10:03:37 +02:00
|
|
|
import { Benchmark } from './interfaces';
|
2021-04-21 21:15:49 +02:00
|
|
|
|
2021-04-13 21:53:58 +02:00
|
|
|
export function capitalize(aString: string) {
|
|
|
|
return aString.charAt(0).toUpperCase() + aString.slice(1).toLowerCase();
|
|
|
|
}
|
|
|
|
|
2022-02-02 20:07:33 +01:00
|
|
|
export function decodeDataSource(encodedDataSource: string) {
|
|
|
|
return Buffer.from(encodedDataSource, 'hex').toString();
|
|
|
|
}
|
|
|
|
|
2022-04-15 10:53:40 +02:00
|
|
|
export function downloadAsFile({
|
|
|
|
content,
|
|
|
|
contentType = 'text/plain',
|
|
|
|
fileName,
|
|
|
|
format
|
|
|
|
}: {
|
|
|
|
content: unknown;
|
|
|
|
contentType?: string;
|
|
|
|
fileName: string;
|
|
|
|
format: 'json' | 'string';
|
|
|
|
}) {
|
2022-02-05 20:26:10 +01:00
|
|
|
const a = document.createElement('a');
|
2022-04-15 10:53:40 +02:00
|
|
|
|
|
|
|
if (format === 'json') {
|
|
|
|
content = JSON.stringify(content, undefined, ' ');
|
|
|
|
}
|
|
|
|
|
|
|
|
const file = new Blob([<string>content], {
|
|
|
|
type: contentType
|
2022-02-05 20:26:10 +01:00
|
|
|
});
|
|
|
|
a.href = URL.createObjectURL(file);
|
2022-04-15 10:53:40 +02:00
|
|
|
a.download = fileName;
|
2022-02-05 20:26:10 +01:00
|
|
|
a.click();
|
|
|
|
}
|
|
|
|
|
2022-02-02 20:07:33 +01:00
|
|
|
export function encodeDataSource(aDataSource: DataSource) {
|
|
|
|
return Buffer.from(aDataSource, 'utf-8').toString('hex');
|
|
|
|
}
|
|
|
|
|
2021-05-15 10:09:07 +02:00
|
|
|
export function getBackgroundColor() {
|
|
|
|
return getCssVariable(
|
|
|
|
window.matchMedia('(prefers-color-scheme: dark)').matches
|
|
|
|
? '--dark-background'
|
|
|
|
: '--light-background'
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
export function getCssVariable(aCssVariable: string) {
|
|
|
|
return getComputedStyle(document.documentElement).getPropertyValue(
|
|
|
|
aCssVariable
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
2022-04-05 21:02:07 +02:00
|
|
|
export function getDateFormatString(aLocale?: string) {
|
|
|
|
const formatObject = new Intl.DateTimeFormat(aLocale).formatToParts(
|
|
|
|
new Date()
|
|
|
|
);
|
|
|
|
|
|
|
|
return formatObject
|
|
|
|
.map((object) => {
|
|
|
|
switch (object.type) {
|
|
|
|
case 'day':
|
|
|
|
return 'dd';
|
|
|
|
case 'month':
|
|
|
|
return 'MM';
|
|
|
|
case 'year':
|
|
|
|
return 'yyyy';
|
|
|
|
default:
|
|
|
|
return object.value;
|
|
|
|
}
|
|
|
|
})
|
|
|
|
.join('');
|
|
|
|
}
|
|
|
|
|
|
|
|
export function getLocale() {
|
|
|
|
return navigator.languages?.length
|
|
|
|
? navigator.languages[0]
|
|
|
|
: navigator.language ?? locale;
|
|
|
|
}
|
|
|
|
|
|
|
|
export function getNumberFormatDecimal(aLocale?: string) {
|
|
|
|
const formatObject = new Intl.NumberFormat(aLocale).formatToParts(9999.99);
|
|
|
|
|
|
|
|
return formatObject.find((object) => {
|
|
|
|
return object.type === 'decimal';
|
|
|
|
}).value;
|
|
|
|
}
|
|
|
|
|
|
|
|
export function getNumberFormatGroup(aLocale?: string) {
|
|
|
|
const formatObject = new Intl.NumberFormat(aLocale).formatToParts(9999.99);
|
|
|
|
|
|
|
|
return formatObject.find((object) => {
|
|
|
|
return object.type === 'group';
|
|
|
|
}).value;
|
|
|
|
}
|
|
|
|
|
2021-05-15 10:09:07 +02:00
|
|
|
export function getTextColor() {
|
2021-07-05 21:53:30 +02:00
|
|
|
const cssVariable = getCssVariable(
|
2021-05-15 10:09:07 +02:00
|
|
|
window.matchMedia('(prefers-color-scheme: dark)').matches
|
|
|
|
? '--light-primary-text'
|
|
|
|
: '--dark-primary-text'
|
|
|
|
);
|
2021-07-05 21:53:30 +02:00
|
|
|
|
|
|
|
const [r, g, b] = cssVariable.split(',');
|
|
|
|
|
|
|
|
return `${r}, ${g}, ${b}`;
|
2021-05-15 10:09:07 +02:00
|
|
|
}
|
|
|
|
|
2021-04-13 21:53:58 +02:00
|
|
|
export function getToday() {
|
|
|
|
const year = getYear(new Date());
|
|
|
|
const month = getMonth(new Date());
|
|
|
|
const day = getDate(new Date());
|
|
|
|
|
|
|
|
return new Date(Date.UTC(year, month, day));
|
|
|
|
}
|
|
|
|
|
|
|
|
export function getUtc(aDateString: string) {
|
|
|
|
const [yearString, monthString, dayString] = aDateString.split('-');
|
|
|
|
|
|
|
|
return new Date(
|
|
|
|
Date.UTC(
|
2021-10-21 22:11:12 +02:00
|
|
|
parseInt(yearString, 10),
|
|
|
|
parseInt(monthString, 10) - 1,
|
|
|
|
parseInt(dayString, 10)
|
2021-04-13 21:53:58 +02:00
|
|
|
)
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
export function getYesterday() {
|
|
|
|
const year = getYear(new Date());
|
|
|
|
const month = getMonth(new Date());
|
|
|
|
const day = getDate(new Date());
|
|
|
|
|
|
|
|
return subDays(new Date(Date.UTC(year, month, day)), 1);
|
|
|
|
}
|
|
|
|
|
|
|
|
export function groupBy<T, K extends keyof T>(
|
|
|
|
key: K,
|
|
|
|
arr: T[]
|
|
|
|
): Map<T[K], T[]> {
|
|
|
|
const map = new Map<T[K], T[]>();
|
|
|
|
arr.forEach((t) => {
|
|
|
|
if (!map.has(t[key])) {
|
|
|
|
map.set(t[key], []);
|
|
|
|
}
|
|
|
|
map.get(t[key])!.push(t);
|
|
|
|
});
|
|
|
|
return map;
|
|
|
|
}
|
|
|
|
|
|
|
|
export function isCurrency(aSymbol = '') {
|
2021-10-03 10:40:21 +02:00
|
|
|
return currencies[aSymbol];
|
2021-04-13 21:53:58 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
export function resetHours(aDate: Date) {
|
|
|
|
const year = getYear(aDate);
|
|
|
|
const month = getMonth(aDate);
|
|
|
|
const day = getDate(aDate);
|
|
|
|
|
|
|
|
return new Date(Date.UTC(year, month, day));
|
|
|
|
}
|
|
|
|
|
|
|
|
export function resolveFearAndGreedIndex(aValue: number) {
|
|
|
|
if (aValue <= 25) {
|
|
|
|
return { emoji: '🥵', text: 'Extreme Fear' };
|
|
|
|
} else if (aValue <= 45) {
|
|
|
|
return { emoji: '😨', text: 'Fear' };
|
|
|
|
} else if (aValue <= 55) {
|
|
|
|
return { emoji: '😐', text: 'Neutral' };
|
|
|
|
} else if (aValue < 75) {
|
|
|
|
return { emoji: '😜', text: 'Greed' };
|
2021-09-20 20:45:58 +02:00
|
|
|
} else {
|
2021-04-13 21:53:58 +02:00
|
|
|
return { emoji: '🤪', text: 'Extreme Greed' };
|
|
|
|
}
|
|
|
|
}
|
2021-07-26 22:13:09 +02:00
|
|
|
|
2022-05-27 10:03:37 +02:00
|
|
|
export function resolveMarketCondition(
|
|
|
|
aMarketCondition: Benchmark['marketCondition']
|
|
|
|
) {
|
|
|
|
if (aMarketCondition === 'BEAR_MARKET') {
|
|
|
|
return { emoji: '🐻' };
|
|
|
|
} else if (aMarketCondition === 'BULL_MARKET') {
|
|
|
|
return { emoji: '🐮' };
|
|
|
|
} else {
|
|
|
|
return { emoji: '⚪' };
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-07-26 22:13:09 +02:00
|
|
|
export const DATE_FORMAT = 'yyyy-MM-dd';
|
|
|
|
|
|
|
|
export function parseDate(date: string) {
|
|
|
|
return parse(date, DATE_FORMAT, new Date());
|
|
|
|
}
|
2021-11-01 20:29:16 +01:00
|
|
|
|
|
|
|
export function prettifySymbol(aSymbol: string): string {
|
|
|
|
return aSymbol?.replace(ghostfolioScraperApiSymbolPrefix, '');
|
|
|
|
}
|
2022-04-10 20:02:31 +02:00
|
|
|
|
|
|
|
export function transformTickToAbbreviation(value: number) {
|
|
|
|
return value < 1000000 ? `${value / 1000}K` : `${value / 1000000}M`;
|
|
|
|
}
|