initial commit

This commit is contained in:
Hampus Kraft
2026-01-01 20:42:59 +00:00
commit 2f557eda8c
9029 changed files with 1490197 additions and 0 deletions

View File

@@ -0,0 +1,272 @@
/*
* Copyright (C) 2026 Fluxer Contributors
*
* This file is part of Fluxer.
*
* Fluxer is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Fluxer is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with Fluxer. If not, see <https://www.gnu.org/licenses/>.
*/
import CountryCodeStore from '~/stores/CountryCodeStore';
export interface CountryCode {
code: string;
dialCode: string;
flag: string;
format?: string;
}
export const COUNTRY_CODES: ReadonlyArray<CountryCode> = [
{code: 'US', dialCode: '+1', flag: '🇺🇸', format: '(###) ###-####'},
{code: 'CA', dialCode: '+1', flag: '🇨🇦', format: '(###) ###-####'},
{code: 'BS', dialCode: '+1-242', flag: '🇧🇸'},
{code: 'BB', dialCode: '+1-246', flag: '🇧🇧'},
{code: 'AG', dialCode: '+1-268', flag: '🇦🇬'},
{code: 'DM', dialCode: '+1-767', flag: '🇩🇲'},
{code: 'DO', dialCode: '+1-809', flag: '🇩🇴'},
{code: 'JM', dialCode: '+1-876', flag: '🇯🇲'},
{code: 'TT', dialCode: '+1-868', flag: '🇹🇹'},
{code: 'EG', dialCode: '+20', flag: '🇪🇬', format: '### ### ####'},
{code: 'ZA', dialCode: '+27', flag: '🇿🇦', format: '## ### ####'},
{code: 'DZ', dialCode: '+213', flag: '🇩🇿'},
{code: 'MA', dialCode: '+212', flag: '🇲🇦'},
{code: 'TN', dialCode: '+216', flag: '🇹🇳'},
{code: 'LY', dialCode: '+218', flag: '🇱🇾'},
{code: 'GM', dialCode: '+220', flag: '🇬🇲'},
{code: 'SN', dialCode: '+221', flag: '🇸🇳'},
{code: 'MR', dialCode: '+222', flag: '🇲🇷'},
{code: 'ML', dialCode: '+223', flag: '🇲🇱'},
{code: 'GN', dialCode: '+224', flag: '🇬🇳'},
{code: 'CI', dialCode: '+225', flag: '🇨🇮'},
{code: 'BF', dialCode: '+226', flag: '🇧🇫'},
{code: 'NE', dialCode: '+227', flag: '🇳🇪'},
{code: 'TG', dialCode: '+228', flag: '🇹🇬'},
{code: 'BJ', dialCode: '+229', flag: '🇧🇯'},
{code: 'MU', dialCode: '+230', flag: '🇲🇺'},
{code: 'LR', dialCode: '+231', flag: '🇱🇷'},
{code: 'SL', dialCode: '+232', flag: '🇸🇱'},
{code: 'GH', dialCode: '+233', flag: '🇬🇭'},
{code: 'NG', dialCode: '+234', flag: '🇳🇬', format: '### ### ####'},
{code: 'TD', dialCode: '+235', flag: '🇹🇩'},
{code: 'CF', dialCode: '+236', flag: '🇨🇫'},
{code: 'CM', dialCode: '+237', flag: '🇨🇲'},
{code: 'CV', dialCode: '+238', flag: '🇨🇻'},
{code: 'ST', dialCode: '+239', flag: '🇸🇹'},
{code: 'GQ', dialCode: '+240', flag: '🇬🇶'},
{code: 'GA', dialCode: '+241', flag: '🇬🇦'},
{code: 'CG', dialCode: '+242', flag: '🇨🇬'},
{code: 'CD', dialCode: '+243', flag: '🇨🇩'},
{code: 'AO', dialCode: '+244', flag: '🇦🇴'},
{code: 'GW', dialCode: '+245', flag: '🇬🇼'},
{code: 'SC', dialCode: '+248', flag: '🇸🇨'},
{code: 'SD', dialCode: '+249', flag: '🇸🇩'},
{code: 'RW', dialCode: '+250', flag: '🇷🇼'},
{code: 'ET', dialCode: '+251', flag: '🇪🇹'},
{code: 'SO', dialCode: '+252', flag: '🇸🇴'},
{code: 'DJ', dialCode: '+253', flag: '🇩🇯'},
{code: 'KE', dialCode: '+254', flag: '🇰🇪'},
{code: 'TZ', dialCode: '+255', flag: '🇹🇿'},
{code: 'UG', dialCode: '+256', flag: '🇺🇬'},
{code: 'BI', dialCode: '+257', flag: '🇧🇮'},
{code: 'MZ', dialCode: '+258', flag: '🇲🇿'},
{code: 'ZM', dialCode: '+260', flag: '🇿🇲'},
{code: 'MG', dialCode: '+261', flag: '🇲🇬'},
{code: 'RE', dialCode: '+262', flag: '🇷🇪'},
{code: 'ZW', dialCode: '+263', flag: '🇿🇼'},
{code: 'NA', dialCode: '+264', flag: '🇳🇦'},
{code: 'MW', dialCode: '+265', flag: '🇲🇼'},
{code: 'LS', dialCode: '+266', flag: '🇱🇸'},
{code: 'BW', dialCode: '+267', flag: '🇧🇼'},
{code: 'SZ', dialCode: '+268', flag: '🇸🇿'},
{code: 'KM', dialCode: '+269', flag: '🇰🇲'},
{code: 'GR', dialCode: '+30', flag: '🇬🇷', format: '### ### ####'},
{code: 'NL', dialCode: '+31', flag: '🇳🇱', format: '## ########'},
{code: 'BE', dialCode: '+32', flag: '🇧🇪', format: '### ## ## ##'},
{code: 'FR', dialCode: '+33', flag: '🇫🇷', format: '# ## ## ## ##'},
{code: 'ES', dialCode: '+34', flag: '🇪🇸', format: '### ### ###'},
{code: 'HU', dialCode: '+36', flag: '🇭🇺', format: '## ### ####'},
{code: 'IT', dialCode: '+39', flag: '🇮🇹', format: '### ### ####'},
{code: 'RO', dialCode: '+40', flag: '🇷🇴', format: '### ### ###'},
{code: 'CH', dialCode: '+41', flag: '🇨🇭', format: '## ### ## ##'},
{code: 'AT', dialCode: '+43', flag: '🇦🇹', format: '### ######'},
{code: 'GB', dialCode: '+44', flag: '🇬🇧', format: '#### ### ####'},
{code: 'DK', dialCode: '+45', flag: '🇩🇰', format: '## ## ## ##'},
{code: 'SE', dialCode: '+46', flag: '🇸🇪', format: '## ### ## ##'},
{code: 'NO', dialCode: '+47', flag: '🇳🇴', format: '### ## ###'},
{code: 'PL', dialCode: '+48', flag: '🇵🇱', format: '### ### ###'},
{code: 'DE', dialCode: '+49', flag: '🇩🇪', format: '### ########'},
{code: 'PE', dialCode: '+51', flag: '🇵🇪'},
{code: 'MX', dialCode: '+52', flag: '🇲🇽', format: '### ### ####'},
{code: 'CU', dialCode: '+53', flag: '🇨🇺'},
{code: 'AR', dialCode: '+54', flag: '🇦🇷', format: '## ####-####'},
{code: 'BR', dialCode: '+55', flag: '🇧🇷', format: '(##) #####-####'},
{code: 'CL', dialCode: '+56', flag: '🇨🇱', format: '# #### ####'},
{code: 'CO', dialCode: '+57', flag: '🇨🇴', format: '### #######'},
{code: 'VE', dialCode: '+58', flag: '🇻🇪'},
{code: 'MY', dialCode: '+60', flag: '🇲🇾', format: '##-### ####'},
{code: 'AU', dialCode: '+61', flag: '🇦🇺', format: '#### ### ###'},
{code: 'ID', dialCode: '+62', flag: '🇮🇩', format: '###-###-####'},
{code: 'PH', dialCode: '+63', flag: '🇵🇭', format: '#### ### ####'},
{code: 'NZ', dialCode: '+64', flag: '🇳🇿', format: '## ### ####'},
{code: 'SG', dialCode: '+65', flag: '🇸🇬', format: '#### ####'},
{code: 'TH', dialCode: '+66', flag: '🇹🇭', format: '## ### ####'},
{code: 'JP', dialCode: '+81', flag: '🇯🇵', format: '##-####-####'},
{code: 'KR', dialCode: '+82', flag: '🇰🇷', format: '##-####-####'},
{code: 'VN', dialCode: '+84', flag: '🇻🇳', format: '### ### ####'},
{code: 'CN', dialCode: '+86', flag: '🇨🇳', format: '### #### ####'},
{code: 'TR', dialCode: '+90', flag: '🇹🇷', format: '(###) ### ## ##'},
{code: 'IN', dialCode: '+91', flag: '🇮🇳', format: '##### #####'},
{code: 'PK', dialCode: '+92', flag: '🇵🇰', format: '### #######'},
{code: 'AF', dialCode: '+93', flag: '🇦🇫'},
{code: 'LK', dialCode: '+94', flag: '🇱🇰'},
{code: 'MM', dialCode: '+95', flag: '🇲🇲'},
{code: 'IR', dialCode: '+98', flag: '🇮🇷'},
{code: 'FI', dialCode: '+358', flag: '🇫🇮', format: '## ### ####'},
{code: 'BG', dialCode: '+359', flag: '🇧🇬'},
{code: 'LT', dialCode: '+370', flag: '🇱🇹'},
{code: 'LV', dialCode: '+371', flag: '🇱🇻'},
{code: 'EE', dialCode: '+372', flag: '🇪🇪'},
{code: 'MD', dialCode: '+373', flag: '🇲🇩'},
{code: 'AM', dialCode: '+374', flag: '🇦🇲'},
{code: 'BY', dialCode: '+375', flag: '🇧🇾'},
{code: 'AD', dialCode: '+376', flag: '🇦🇩'},
{code: 'MC', dialCode: '+377', flag: '🇲🇨'},
{code: 'SM', dialCode: '+378', flag: '🇸🇲'},
{code: 'VA', dialCode: '+379', flag: '🇻🇦'},
{code: 'UA', dialCode: '+380', flag: '🇺🇦', format: '## ### ####'},
{code: 'RS', dialCode: '+381', flag: '🇷🇸'},
{code: 'ME', dialCode: '+382', flag: '🇲🇪'},
{code: 'HR', dialCode: '+385', flag: '🇭🇷'},
{code: 'SI', dialCode: '+386', flag: '🇸🇮'},
{code: 'BA', dialCode: '+387', flag: '🇧🇦'},
{code: 'MK', dialCode: '+389', flag: '🇲🇰'},
{code: 'CZ', dialCode: '+420', flag: '🇨🇿', format: '### ### ###'},
{code: 'SK', dialCode: '+421', flag: '🇸🇰'},
{code: 'BZ', dialCode: '+501', flag: '🇧🇿'},
{code: 'GT', dialCode: '+502', flag: '🇬🇹'},
{code: 'SV', dialCode: '+503', flag: '🇸🇻'},
{code: 'HN', dialCode: '+504', flag: '🇭🇳'},
{code: 'NI', dialCode: '+505', flag: '🇳🇮'},
{code: 'CR', dialCode: '+506', flag: '🇨🇷'},
{code: 'PA', dialCode: '+507', flag: '🇵🇦'},
{code: 'HT', dialCode: '+509', flag: '🇭🇹'},
{code: 'BO', dialCode: '+591', flag: '🇧🇴'},
{code: 'GY', dialCode: '+592', flag: '🇬🇾'},
{code: 'EC', dialCode: '+593', flag: '🇪🇨'},
{code: 'PY', dialCode: '+595', flag: '🇵🇾'},
{code: 'SR', dialCode: '+597', flag: '🇸🇷'},
{code: 'UY', dialCode: '+598', flag: '🇺🇾'},
{code: 'BN', dialCode: '+673', flag: '🇧🇳'},
{code: 'NR', dialCode: '+674', flag: '🇳🇷'},
{code: 'PG', dialCode: '+675', flag: '🇵🇬'},
{code: 'TO', dialCode: '+676', flag: '🇹🇴'},
{code: 'SB', dialCode: '+677', flag: '🇸🇧'},
{code: 'VU', dialCode: '+678', flag: '🇻🇺'},
{code: 'FJ', dialCode: '+679', flag: '🇫🇯'},
{code: 'PW', dialCode: '+680', flag: '🇵🇼'},
{code: 'WS', dialCode: '+685', flag: '🇼🇸'},
{code: 'KI', dialCode: '+686', flag: '🇰🇮'},
{code: 'NC', dialCode: '+687', flag: '🇳🇨'},
{code: 'TV', dialCode: '+688', flag: '🇹🇻'},
{code: 'PF', dialCode: '+689', flag: '🇵🇫'},
{code: 'RU', dialCode: '+7', flag: '🇷🇺', format: '(###) ###-##-##'},
{code: 'KZ', dialCode: '+7', flag: '🇰🇿'},
{code: 'HK', dialCode: '+852', flag: '🇭🇰', format: '#### ####'},
{code: 'MO', dialCode: '+853', flag: '🇲🇴'},
{code: 'KH', dialCode: '+855', flag: '🇰🇭'},
{code: 'LA', dialCode: '+856', flag: '🇱🇦'},
{code: 'BD', dialCode: '+880', flag: '🇧🇩', format: '####-######'},
{code: 'TW', dialCode: '+886', flag: '🇹🇼', format: '#### ####'},
{code: 'MV', dialCode: '+960', flag: '🇲🇻'},
{code: 'LB', dialCode: '+961', flag: '🇱🇧'},
{code: 'JO', dialCode: '+962', flag: '🇯🇴'},
{code: 'SY', dialCode: '+963', flag: '🇸🇾'},
{code: 'IQ', dialCode: '+964', flag: '🇮🇶'},
{code: 'KW', dialCode: '+965', flag: '🇰🇼'},
{code: 'SA', dialCode: '+966', flag: '🇸🇦', format: '## ### ####'},
{code: 'YE', dialCode: '+967', flag: '🇾🇪'},
{code: 'OM', dialCode: '+968', flag: '🇴🇲'},
{code: 'PS', dialCode: '+970', flag: '🇵🇸'},
{code: 'AE', dialCode: '+971', flag: '🇦🇪', format: '## ### ####'},
{code: 'IL', dialCode: '+972', flag: '🇮🇱', format: '##-###-####'},
{code: 'BH', dialCode: '+973', flag: '🇧🇭'},
{code: 'QA', dialCode: '+974', flag: '🇶🇦'},
{code: 'BT', dialCode: '+975', flag: '🇧🇹'},
{code: 'MN', dialCode: '+976', flag: '🇲🇳'},
{code: 'NP', dialCode: '+977', flag: '🇳🇵'},
{code: 'TJ', dialCode: '+992', flag: '🇹🇯'},
{code: 'TM', dialCode: '+993', flag: '🇹🇲'},
{code: 'AZ', dialCode: '+994', flag: '🇦🇿'},
{code: 'GE', dialCode: '+995', flag: '🇬🇪'},
{code: 'KG', dialCode: '+996', flag: '🇰🇬'},
{code: 'UZ', dialCode: '+998', flag: '🇺🇿'},
{code: 'PT', dialCode: '+351', flag: '🇵🇹', format: '### ### ###'},
{code: 'LU', dialCode: '+352', flag: '🇱🇺'},
{code: 'IE', dialCode: '+353', flag: '🇮🇪', format: '## ### ####'},
{code: 'IS', dialCode: '+354', flag: '🇮🇸'},
{code: 'AL', dialCode: '+355', flag: '🇦🇱'},
{code: 'MT', dialCode: '+356', flag: '🇲🇹'},
{code: 'CY', dialCode: '+357', flag: '🇨🇾'},
] as const;
export const getDefaultCountry = (): CountryCode => {
const countryCode = CountryCodeStore.countryCode;
const country = COUNTRY_CODES.find((c) => c.code === countryCode);
return country || COUNTRY_CODES.find((c) => c.code === 'US')!;
};
export const formatPhoneNumber = (value: string, country: CountryCode): string => {
const digits = value.replace(/\D/g, '');
if (!country.format) {
return digits;
}
let formatted = '';
let digitIndex = 0;
for (const char of country.format) {
if (char === '#') {
if (digitIndex < digits.length) {
formatted += digits[digitIndex];
digitIndex++;
} else {
break;
}
} else {
if (digitIndex > 0 && digitIndex < digits.length) {
formatted += char;
}
}
}
return formatted;
};
export const getE164PhoneNumber = (phoneNumber: string, country: CountryCode): string => {
const digits = phoneNumber.replace(/\D/g, '');
return `${country.dialCode}${digits}`;
};
export const getCountryName = (countryCode: string, locale: string): string => {
const regionNames = new Intl.DisplayNames([locale], {type: 'region'});
return regionNames.of(countryCode) || countryCode;
};

View File

@@ -0,0 +1,119 @@
[
{
"emoji": "angry",
"shortcuts": [">:(", ">:-(", ">=(", ">=-("]
},
{
"emoji": "blush",
"shortcuts": [":\")", ":-\")", "=\")", "=-\")"]
},
{
"emoji": "broken_heart",
"shortcuts": ["</3", "<\\3"]
},
{
"emoji": "confused",
"shortcuts": [":-\\", ":-/", "=-\\", "=-/"]
},
{
"emoji": "cry",
"shortcuts": [":'(", ":'-(", ":,(", ":,-(", "='(", "='-(", "=,(", "=,-("]
},
{
"emoji": "frowning",
"shortcuts": [":(", ":-(", "=(", "=-("]
},
{
"emoji": "heart",
"shortcuts": ["<3", "♡"]
},
{
"emoji": "imp",
"shortcuts": ["]:(", "]:-(", "]=(", "]=-("]
},
{
"emoji": "innocent",
"shortcuts": ["o:)", "O:)", "o:-)", "O:-)", "0:)", "0:-)", "o=)", "O=)", "o=-)", "O=-)", "0=)", "0=-)"]
},
{
"emoji": "joy",
"shortcuts": [
":')",
":'-)",
":,)",
":,-)",
":'D",
":'-D",
":,D",
":,-D",
"=')",
"='-)",
"=,)",
"=,-)",
"='D",
"='-D",
"=,D",
"=,-D"
]
},
{
"emoji": "kissing",
"shortcuts": [":*", ":-*", "=*", "=-*"]
},
{
"emoji": "laughing",
"shortcuts": ["x-)", "X-)"]
},
{
"emoji": "neutral_face",
"shortcuts": [":|", ":-|", "=|", "=-|"]
},
{
"emoji": "open_mouth",
"shortcuts": [":o", ":-o", ":O", ":-O", "=o", "=-o", "=O", "=-O"]
},
{
"emoji": "rage",
"shortcuts": [":@", ":-@", "=@", "=-@"]
},
{
"emoji": "smile",
"shortcuts": [":D", ":-D", "=D", "=-D"]
},
{
"emoji": "smiley",
"shortcuts": [":)", ":-)", "=)", "=-)"]
},
{
"emoji": "smiling_imp",
"shortcuts": ["]:)", "]:-)", "]=)", "]=-)"]
},
{
"emoji": "sob",
"shortcuts": [":,'(", ":,'-(", ";(", ";-(", "=,'(", "=,'-("]
},
{
"emoji": "stuck_out_tongue",
"shortcuts": [":P", ":-P", "=P", "=-P"]
},
{
"emoji": "sunglasses",
"shortcuts": ["8-)", "B-)"]
},
{
"emoji": "sweat",
"shortcuts": [",:(", ",:-(", ",=(", ",=-("]
},
{
"emoji": "sweat_smile",
"shortcuts": [",:)", ",:-)", ",=)", ",=-)"]
},
{
"emoji": "unamused",
"shortcuts": [":s", ":-S", ":z", ":-Z", ":$", ":-$", "=s", "=-S", "=z", "=-Z", "=$", "=-$"]
},
{
"emoji": "wink",
"shortcuts": [";)", ";-)"]
}
]

File diff suppressed because one or more lines are too long