mirror of
https://github.com/stashapp/stash.git
synced 2025-12-06 16:34:02 +01:00
Change performer country value to be ISO code (#1922)
* Change performer country value to be ISO code * Localize country names * Use country select for filter Co-authored-by: WithoutPants <53250216+WithoutPants@users.noreply.github.com>
This commit is contained in:
parent
1c0042c4c2
commit
7b7d6758ef
25 changed files with 1103 additions and 58 deletions
296
pkg/scraper/country.go
Normal file
296
pkg/scraper/country.go
Normal file
|
|
@ -0,0 +1,296 @@
|
||||||
|
package scraper
|
||||||
|
|
||||||
|
import (
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"github.com/stashapp/stash/pkg/logger"
|
||||||
|
)
|
||||||
|
|
||||||
|
var countryNameMapping = map[string]string{
|
||||||
|
"afghanistan": "AF",
|
||||||
|
"albania": "AL",
|
||||||
|
"algeria": "DZ",
|
||||||
|
"america": "US",
|
||||||
|
"american": "US",
|
||||||
|
"american samoa": "AS",
|
||||||
|
"andorra": "AD",
|
||||||
|
"angola": "AO",
|
||||||
|
"anguilla": "AI",
|
||||||
|
"antarctica": "AQ",
|
||||||
|
"antigua and barbuda": "AG",
|
||||||
|
"argentina": "AR",
|
||||||
|
"armenia": "AM",
|
||||||
|
"aruba": "AW",
|
||||||
|
"australia": "AU",
|
||||||
|
"austria": "AT",
|
||||||
|
"azerbaijan": "AZ",
|
||||||
|
"bahamas": "BS",
|
||||||
|
"bahrain": "BH",
|
||||||
|
"bangladesh": "BD",
|
||||||
|
"barbados": "BB",
|
||||||
|
"belarus": "BY",
|
||||||
|
"belgium": "BE",
|
||||||
|
"belize": "BZ",
|
||||||
|
"benin": "BJ",
|
||||||
|
"bermuda": "BM",
|
||||||
|
"bhutan": "BT",
|
||||||
|
"bolivia": "BO",
|
||||||
|
"bosnia and herzegovina": "BA",
|
||||||
|
"botswana": "BW",
|
||||||
|
"bouvet island": "BV",
|
||||||
|
"brazil": "BR",
|
||||||
|
"british indian ocean territory": "IO",
|
||||||
|
"brunei darussalam": "BN",
|
||||||
|
"bulgaria": "BG",
|
||||||
|
"burkina faso": "BF",
|
||||||
|
"burundi": "BI",
|
||||||
|
"cambodia": "KH",
|
||||||
|
"cameroon": "CM",
|
||||||
|
"canada": "CA",
|
||||||
|
"cape verde": "CV",
|
||||||
|
"cayman islands": "KY",
|
||||||
|
"central african republic": "CF",
|
||||||
|
"chad": "TD",
|
||||||
|
"chile": "CL",
|
||||||
|
"china": "CN",
|
||||||
|
"christmas island": "CX",
|
||||||
|
"cocos (keeling) islands": "CC",
|
||||||
|
"colombia": "CO",
|
||||||
|
"comoros": "KM",
|
||||||
|
"congo": "CG",
|
||||||
|
"congo the democratic republic of the": "CD",
|
||||||
|
"cook islands": "CK",
|
||||||
|
"costa rica": "CR",
|
||||||
|
"cote d'ivoire": "CI",
|
||||||
|
"croatia": "HR",
|
||||||
|
"cuba": "CU",
|
||||||
|
"cyprus": "CY",
|
||||||
|
"czech republic": "CZ",
|
||||||
|
"czechia": "CZ",
|
||||||
|
"denmark": "DK",
|
||||||
|
"djibouti": "DJ",
|
||||||
|
"dominica": "DM",
|
||||||
|
"dominican republic": "DO",
|
||||||
|
"ecuador": "EC",
|
||||||
|
"egypt": "EG",
|
||||||
|
"el salvador": "SV",
|
||||||
|
"equatorial guinea": "GQ",
|
||||||
|
"eritrea": "ER",
|
||||||
|
"estonia": "EE",
|
||||||
|
"ethiopia": "ET",
|
||||||
|
"falkland islands (malvinas)": "FK",
|
||||||
|
"faroe islands": "FO",
|
||||||
|
"fiji": "FJ",
|
||||||
|
"finland": "FI",
|
||||||
|
"france": "FR",
|
||||||
|
"french guiana": "GF",
|
||||||
|
"french polynesia": "PF",
|
||||||
|
"french southern territories": "TF",
|
||||||
|
"gabon": "GA",
|
||||||
|
"gambia": "GM",
|
||||||
|
"georgia": "GE",
|
||||||
|
"germany": "DE",
|
||||||
|
"ghana": "GH",
|
||||||
|
"gibraltar": "GI",
|
||||||
|
"greece": "GR",
|
||||||
|
"greenland": "GL",
|
||||||
|
"grenada": "GD",
|
||||||
|
"guadeloupe": "GP",
|
||||||
|
"guam": "GU",
|
||||||
|
"guatemala": "GT",
|
||||||
|
"guinea": "GN",
|
||||||
|
"guinea-bissau": "GW",
|
||||||
|
"guyana": "GY",
|
||||||
|
"haiti": "HT",
|
||||||
|
"heard island and mcdonald islands": "HM",
|
||||||
|
"holy see (vatican city state)": "VA",
|
||||||
|
"honduras": "HN",
|
||||||
|
"hong kong": "HK",
|
||||||
|
"hungary": "HU",
|
||||||
|
"iceland": "IS",
|
||||||
|
"india": "IN",
|
||||||
|
"indonesia": "ID",
|
||||||
|
"iran": "IR",
|
||||||
|
"iran islamic republic of": "IR",
|
||||||
|
"iraq": "IQ",
|
||||||
|
"ireland": "IE",
|
||||||
|
"israel": "IL",
|
||||||
|
"italy": "IT",
|
||||||
|
"jamaica": "JM",
|
||||||
|
"japan": "JP",
|
||||||
|
"jordan": "JO",
|
||||||
|
"kazakhstan": "KZ",
|
||||||
|
"kenya": "KE",
|
||||||
|
"kiribati": "KI",
|
||||||
|
"north korea": "KP",
|
||||||
|
"south korea": "KR",
|
||||||
|
"kuwait": "KW",
|
||||||
|
"kyrgyzstan": "KG",
|
||||||
|
"lao people's democratic republic": "LA",
|
||||||
|
"latvia": "LV",
|
||||||
|
"lebanon": "LB",
|
||||||
|
"lesotho": "LS",
|
||||||
|
"liberia": "LR",
|
||||||
|
"libya": "LY",
|
||||||
|
"liechtenstein": "LI",
|
||||||
|
"lithuania": "LT",
|
||||||
|
"luxembourg": "LU",
|
||||||
|
"macao": "MO",
|
||||||
|
"madagascar": "MG",
|
||||||
|
"malawi": "MW",
|
||||||
|
"malaysia": "MY",
|
||||||
|
"maldives": "MV",
|
||||||
|
"mali": "ML",
|
||||||
|
"malta": "MT",
|
||||||
|
"marshall islands": "MH",
|
||||||
|
"martinique": "MQ",
|
||||||
|
"mauritania": "MR",
|
||||||
|
"mauritius": "MU",
|
||||||
|
"mayotte": "YT",
|
||||||
|
"mexico": "MX",
|
||||||
|
"micronesia federated states of": "FM",
|
||||||
|
"moldova": "MD",
|
||||||
|
"moldova republic of": "MD",
|
||||||
|
"moldova, republic of": "MD",
|
||||||
|
"monaco": "MC",
|
||||||
|
"mongolia": "MN",
|
||||||
|
"montserrat": "MS",
|
||||||
|
"morocco": "MA",
|
||||||
|
"mozambique": "MZ",
|
||||||
|
"myanmar": "MM",
|
||||||
|
"namibia": "NA",
|
||||||
|
"nauru": "NR",
|
||||||
|
"nepal": "NP",
|
||||||
|
"netherlands": "NL",
|
||||||
|
"new caledonia": "NC",
|
||||||
|
"new zealand": "NZ",
|
||||||
|
"nicaragua": "NI",
|
||||||
|
"niger": "NE",
|
||||||
|
"nigeria": "NG",
|
||||||
|
"niue": "NU",
|
||||||
|
"norfolk island": "NF",
|
||||||
|
"north macedonia republic of": "MK",
|
||||||
|
"northern mariana islands": "MP",
|
||||||
|
"norway": "NO",
|
||||||
|
"oman": "OM",
|
||||||
|
"pakistan": "PK",
|
||||||
|
"palau": "PW",
|
||||||
|
"palestinian territory occupied": "PS",
|
||||||
|
"panama": "PA",
|
||||||
|
"papua new guinea": "PG",
|
||||||
|
"paraguay": "PY",
|
||||||
|
"peru": "PE",
|
||||||
|
"philippines": "PH",
|
||||||
|
"pitcairn": "PN",
|
||||||
|
"poland": "PL",
|
||||||
|
"portugal": "PT",
|
||||||
|
"puerto rico": "PR",
|
||||||
|
"qatar": "QA",
|
||||||
|
"reunion": "RE",
|
||||||
|
"romania": "RO",
|
||||||
|
"russia": "RU",
|
||||||
|
"russian federation": "RU",
|
||||||
|
"rwanda": "RW",
|
||||||
|
"saint helena": "SH",
|
||||||
|
"saint kitts and nevis": "KN",
|
||||||
|
"saint lucia": "LC",
|
||||||
|
"saint pierre and miquelon": "PM",
|
||||||
|
"saint vincent and the grenadines": "VC",
|
||||||
|
"samoa": "WS",
|
||||||
|
"san marino": "SM",
|
||||||
|
"sao tome and principe": "ST",
|
||||||
|
"saudi arabia": "SA",
|
||||||
|
"senegal": "SN",
|
||||||
|
"seychelles": "SC",
|
||||||
|
"sierra leone": "SL",
|
||||||
|
"singapore": "SG",
|
||||||
|
"slovakia": "SK",
|
||||||
|
"slovak republic": "SK",
|
||||||
|
"slovenia": "SI",
|
||||||
|
"solomon islands": "SB",
|
||||||
|
"somalia": "SO",
|
||||||
|
"south africa": "ZA",
|
||||||
|
"south georgia and the south sandwich islands": "GS",
|
||||||
|
"spain": "ES",
|
||||||
|
"sri lanka": "LK",
|
||||||
|
"sudan": "SD",
|
||||||
|
"suriname": "SR",
|
||||||
|
"svalbard and jan mayen": "SJ",
|
||||||
|
"eswatini": "SZ",
|
||||||
|
"sweden": "SE",
|
||||||
|
"switzerland": "CH",
|
||||||
|
"syrian arab republic": "SY",
|
||||||
|
"taiwan": "TW",
|
||||||
|
"tajikistan": "TJ",
|
||||||
|
"tanzania united republic of": "TZ",
|
||||||
|
"thailand": "TH",
|
||||||
|
"timor-leste": "TL",
|
||||||
|
"togo": "TG",
|
||||||
|
"tokelau": "TK",
|
||||||
|
"tonga": "TO",
|
||||||
|
"trinidad and tobago": "TT",
|
||||||
|
"tunisia": "TN",
|
||||||
|
"turkey": "TR",
|
||||||
|
"turkmenistan": "TM",
|
||||||
|
"turks and caicos islands": "TC",
|
||||||
|
"tuvalu": "TV",
|
||||||
|
"uganda": "UG",
|
||||||
|
"ukraine": "UA",
|
||||||
|
"united arab emirates": "AE",
|
||||||
|
"england": "GB",
|
||||||
|
"great britain": "GB",
|
||||||
|
"united kingdom": "GB",
|
||||||
|
"usa": "US",
|
||||||
|
"united states": "US",
|
||||||
|
"united states of america": "US",
|
||||||
|
"united states minor outlying islands": "UM",
|
||||||
|
"uruguay": "UY",
|
||||||
|
"uzbekistan": "UZ",
|
||||||
|
"vanuatu": "VU",
|
||||||
|
"venezuela": "VE",
|
||||||
|
"vietnam": "VN",
|
||||||
|
"virgin islands british": "VG",
|
||||||
|
"virgin islands u.s.": "VI",
|
||||||
|
"wallis and futuna": "WF",
|
||||||
|
"western sahara": "EH",
|
||||||
|
"yemen": "YE",
|
||||||
|
"zambia": "ZM",
|
||||||
|
"zimbabwe": "ZW",
|
||||||
|
"åland islands": "AX",
|
||||||
|
"bonaire sint eustatius and saba": "BQ",
|
||||||
|
"curaçao": "CW",
|
||||||
|
"guernsey": "GG",
|
||||||
|
"isle of man": "IM",
|
||||||
|
"jersey": "JE",
|
||||||
|
"montenegro": "ME",
|
||||||
|
"saint barthélemy": "BL",
|
||||||
|
"saint martin (french part)": "MF",
|
||||||
|
"serbia": "RS",
|
||||||
|
"sint maarten (dutch part)": "SX",
|
||||||
|
"south sudan": "SS",
|
||||||
|
"kosovo": "XK",
|
||||||
|
}
|
||||||
|
|
||||||
|
func resolveCountryName(name *string) *string {
|
||||||
|
if name == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
trimmedName := strings.TrimSpace(*name)
|
||||||
|
if len(trimmedName) == 2 {
|
||||||
|
// If name is two characters it's likely already an ISO value
|
||||||
|
return &trimmedName
|
||||||
|
} else if len(trimmedName) == 0 {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
v, exists := countryNameMapping[strings.ToLower(trimmedName)]
|
||||||
|
if exists {
|
||||||
|
return &v
|
||||||
|
}
|
||||||
|
|
||||||
|
logger.Debugf("Scraped country was not recognized: %s", trimmedName)
|
||||||
|
|
||||||
|
// return original name
|
||||||
|
return &trimmedName
|
||||||
|
}
|
||||||
|
|
@ -66,6 +66,8 @@ func (c Cache) postScrapePerformer(ctx context.Context, p models.ScrapedPerforme
|
||||||
logger.Warnf("Could not set image using URL %s: %s", *p.Image, err.Error())
|
logger.Warnf("Could not set image using URL %s: %s", *p.Image, err.Error())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
p.Country = resolveCountryName(p.Country)
|
||||||
|
|
||||||
return p, nil
|
return p, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -98,6 +100,8 @@ func (c Cache) postScrapeScenePerformer(ctx context.Context, p models.ScrapedPer
|
||||||
}
|
}
|
||||||
p.Tags = tags
|
p.Tags = tags
|
||||||
|
|
||||||
|
p.Country = resolveCountryName(p.Country)
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -22,7 +22,7 @@ import (
|
||||||
"github.com/stashapp/stash/pkg/logger"
|
"github.com/stashapp/stash/pkg/logger"
|
||||||
)
|
)
|
||||||
|
|
||||||
var appSchemaVersion uint = 36
|
var appSchemaVersion uint = 37
|
||||||
|
|
||||||
//go:embed migrations/*.sql
|
//go:embed migrations/*.sql
|
||||||
var migrationsBox embed.FS
|
var migrationsBox embed.FS
|
||||||
|
|
|
||||||
269
pkg/sqlite/migrations/37_iso_country_names.up.sql
Normal file
269
pkg/sqlite/migrations/37_iso_country_names.up.sql
Normal file
|
|
@ -0,0 +1,269 @@
|
||||||
|
UPDATE `performers`
|
||||||
|
SET `country` = CASE
|
||||||
|
WHEN LENGTH(TRIM(`country`)) == 2 THEN TRIM(`country`)
|
||||||
|
ELSE CASE `country`
|
||||||
|
WHEN 'Afghanistan' THEN 'AF'
|
||||||
|
WHEN 'Albania' THEN 'AL'
|
||||||
|
WHEN 'Algeria' THEN 'DZ'
|
||||||
|
WHEN 'America' THEN 'US'
|
||||||
|
WHEN 'American' THEN 'US'
|
||||||
|
WHEN 'American Samoa' THEN 'AS'
|
||||||
|
WHEN 'Andorra' THEN 'AD'
|
||||||
|
WHEN 'Angola' THEN 'AO'
|
||||||
|
WHEN 'Anguilla' THEN 'AI'
|
||||||
|
WHEN 'Antarctica' THEN 'AQ'
|
||||||
|
WHEN 'Antigua and Barbuda' THEN 'AG'
|
||||||
|
WHEN 'Argentina' THEN 'AR'
|
||||||
|
WHEN 'Armenia' THEN 'AM'
|
||||||
|
WHEN 'Aruba' THEN 'AW'
|
||||||
|
WHEN 'Australia' THEN 'AU'
|
||||||
|
WHEN 'Austria' THEN 'AT'
|
||||||
|
WHEN 'Azerbaijan' THEN 'AZ'
|
||||||
|
WHEN 'Bahamas' THEN 'BS'
|
||||||
|
WHEN 'Bahrain' THEN 'BH'
|
||||||
|
WHEN 'Bangladesh' THEN 'BD'
|
||||||
|
WHEN 'Barbados' THEN 'BB'
|
||||||
|
WHEN 'Belarus' THEN 'BY'
|
||||||
|
WHEN 'Belgium' THEN 'BE'
|
||||||
|
WHEN 'Belize' THEN 'BZ'
|
||||||
|
WHEN 'Benin' THEN 'BJ'
|
||||||
|
WHEN 'Bermuda' THEN 'BM'
|
||||||
|
WHEN 'Bhutan' THEN 'BT'
|
||||||
|
WHEN 'Bolivia' THEN 'BO'
|
||||||
|
WHEN 'Bosnia and Herzegovina' THEN 'BA'
|
||||||
|
WHEN 'Botswana' THEN 'BW'
|
||||||
|
WHEN 'Bouvet Island' THEN 'BV'
|
||||||
|
WHEN 'Brazil' THEN 'BR'
|
||||||
|
WHEN 'British Indian Ocean Territory' THEN 'IO'
|
||||||
|
WHEN 'Brunei Darussalam' THEN 'BN'
|
||||||
|
WHEN 'Bulgaria' THEN 'BG'
|
||||||
|
WHEN 'Burkina Faso' THEN 'BF'
|
||||||
|
WHEN 'Burundi' THEN 'BI'
|
||||||
|
WHEN 'Cambodia' THEN 'KH'
|
||||||
|
WHEN 'Cameroon' THEN 'CM'
|
||||||
|
WHEN 'Canada' THEN 'CA'
|
||||||
|
WHEN 'Cape Verde' THEN 'CV'
|
||||||
|
WHEN 'Cayman Islands' THEN 'KY'
|
||||||
|
WHEN 'Central African Republic' THEN 'CF'
|
||||||
|
WHEN 'Chad' THEN 'TD'
|
||||||
|
WHEN 'Chile' THEN 'CL'
|
||||||
|
WHEN 'China' THEN 'CN'
|
||||||
|
WHEN 'Christmas Island' THEN 'CX'
|
||||||
|
WHEN 'Cocos (Keeling) Islands' THEN 'CC'
|
||||||
|
WHEN 'Colombia' THEN 'CO'
|
||||||
|
WHEN 'Comoros' THEN 'KM'
|
||||||
|
WHEN 'Congo' THEN 'CG'
|
||||||
|
WHEN 'Congo the Democratic Republic of the' THEN 'CD'
|
||||||
|
WHEN 'Cook Islands' THEN 'CK'
|
||||||
|
WHEN 'Costa Rica' THEN 'CR'
|
||||||
|
WHEN 'Cote D''Ivoire' THEN 'CI'
|
||||||
|
WHEN 'Croatia' THEN 'HR'
|
||||||
|
WHEN 'Cuba' THEN 'CU'
|
||||||
|
WHEN 'Cyprus' THEN 'CY'
|
||||||
|
WHEN 'Czech Republic' THEN 'CZ'
|
||||||
|
WHEN 'Czechia' THEN 'CZ'
|
||||||
|
WHEN 'Denmark' THEN 'DK'
|
||||||
|
WHEN 'Djibouti' THEN 'DJ'
|
||||||
|
WHEN 'Dominica' THEN 'DM'
|
||||||
|
WHEN 'Dominican Republic' THEN 'DO'
|
||||||
|
WHEN 'Ecuador' THEN 'EC'
|
||||||
|
WHEN 'Egypt' THEN 'EG'
|
||||||
|
WHEN 'El Salvador' THEN 'SV'
|
||||||
|
WHEN 'Equatorial Guinea' THEN 'GQ'
|
||||||
|
WHEN 'Eritrea' THEN 'ER'
|
||||||
|
WHEN 'Estonia' THEN 'EE'
|
||||||
|
WHEN 'Ethiopia' THEN 'ET'
|
||||||
|
WHEN 'Falkland Islands (Malvinas)' THEN 'FK'
|
||||||
|
WHEN 'Faroe Islands' THEN 'FO'
|
||||||
|
WHEN 'Fiji' THEN 'FJ'
|
||||||
|
WHEN 'Finland' THEN 'FI'
|
||||||
|
WHEN 'France' THEN 'FR'
|
||||||
|
WHEN 'French Guiana' THEN 'GF'
|
||||||
|
WHEN 'French Polynesia' THEN 'PF'
|
||||||
|
WHEN 'French Southern Territories' THEN 'TF'
|
||||||
|
WHEN 'Gabon' THEN 'GA'
|
||||||
|
WHEN 'Gambia' THEN 'GM'
|
||||||
|
WHEN 'Georgia' THEN 'GE'
|
||||||
|
WHEN 'Germany' THEN 'DE'
|
||||||
|
WHEN 'Ghana' THEN 'GH'
|
||||||
|
WHEN 'Gibraltar' THEN 'GI'
|
||||||
|
WHEN 'Greece' THEN 'GR'
|
||||||
|
WHEN 'Greenland' THEN 'GL'
|
||||||
|
WHEN 'Grenada' THEN 'GD'
|
||||||
|
WHEN 'Guadeloupe' THEN 'GP'
|
||||||
|
WHEN 'Guam' THEN 'GU'
|
||||||
|
WHEN 'Guatemala' THEN 'GT'
|
||||||
|
WHEN 'Guinea' THEN 'GN'
|
||||||
|
WHEN 'Guinea-Bissau' THEN 'GW'
|
||||||
|
WHEN 'Guyana' THEN 'GY'
|
||||||
|
WHEN 'Haiti' THEN 'HT'
|
||||||
|
WHEN 'Heard Island and McDonald Islands' THEN 'HM'
|
||||||
|
WHEN 'Holy See (Vatican City State)' THEN 'VA'
|
||||||
|
WHEN 'Honduras' THEN 'HN'
|
||||||
|
WHEN 'Hong Kong' THEN 'HK'
|
||||||
|
WHEN 'Hungary' THEN 'HU'
|
||||||
|
WHEN 'Iceland' THEN 'IS'
|
||||||
|
WHEN 'India' THEN 'IN'
|
||||||
|
WHEN 'Indonesia' THEN 'ID'
|
||||||
|
WHEN 'Iran' THEN 'IR'
|
||||||
|
WHEN 'Iran Islamic Republic of' THEN 'IR'
|
||||||
|
WHEN 'Iraq' THEN 'IQ'
|
||||||
|
WHEN 'Ireland' THEN 'IE'
|
||||||
|
WHEN 'Israel' THEN 'IL'
|
||||||
|
WHEN 'Italy' THEN 'IT'
|
||||||
|
WHEN 'Jamaica' THEN 'JM'
|
||||||
|
WHEN 'Japan' THEN 'JP'
|
||||||
|
WHEN 'Jordan' THEN 'JO'
|
||||||
|
WHEN 'Kazakhstan' THEN 'KZ'
|
||||||
|
WHEN 'Kenya' THEN 'KE'
|
||||||
|
WHEN 'Kiribati' THEN 'KI'
|
||||||
|
WHEN 'North Korea' THEN 'KP'
|
||||||
|
WHEN 'South Korea' THEN 'KR'
|
||||||
|
WHEN 'Kuwait' THEN 'KW'
|
||||||
|
WHEN 'Kyrgyzstan' THEN 'KG'
|
||||||
|
WHEN 'Lao People''s Democratic Republic' THEN 'LA'
|
||||||
|
WHEN 'Latvia' THEN 'LV'
|
||||||
|
WHEN 'Lebanon' THEN 'LB'
|
||||||
|
WHEN 'Lesotho' THEN 'LS'
|
||||||
|
WHEN 'Liberia' THEN 'LR'
|
||||||
|
WHEN 'Libya' THEN 'LY'
|
||||||
|
WHEN 'Liechtenstein' THEN 'LI'
|
||||||
|
WHEN 'Lithuania' THEN 'LT'
|
||||||
|
WHEN 'Luxembourg' THEN 'LU'
|
||||||
|
WHEN 'Macao' THEN 'MO'
|
||||||
|
WHEN 'Madagascar' THEN 'MG'
|
||||||
|
WHEN 'Malawi' THEN 'MW'
|
||||||
|
WHEN 'Malaysia' THEN 'MY'
|
||||||
|
WHEN 'Maldives' THEN 'MV'
|
||||||
|
WHEN 'Mali' THEN 'ML'
|
||||||
|
WHEN 'Malta' THEN 'MT'
|
||||||
|
WHEN 'Marshall Islands' THEN 'MH'
|
||||||
|
WHEN 'Martinique' THEN 'MQ'
|
||||||
|
WHEN 'Mauritania' THEN 'MR'
|
||||||
|
WHEN 'Mauritius' THEN 'MU'
|
||||||
|
WHEN 'Mayotte' THEN 'YT'
|
||||||
|
WHEN 'Mexico' THEN 'MX'
|
||||||
|
WHEN 'Micronesia Federated States of' THEN 'FM'
|
||||||
|
WHEN 'Moldova' THEN 'MD'
|
||||||
|
WHEN 'Moldova Republic of' THEN 'MD'
|
||||||
|
WHEN 'Moldova, Republic of' THEN 'MD'
|
||||||
|
WHEN 'Monaco' THEN 'MC'
|
||||||
|
WHEN 'Mongolia' THEN 'MN'
|
||||||
|
WHEN 'Montserrat' THEN 'MS'
|
||||||
|
WHEN 'Morocco' THEN 'MA'
|
||||||
|
WHEN 'Mozambique' THEN 'MZ'
|
||||||
|
WHEN 'Myanmar' THEN 'MM'
|
||||||
|
WHEN 'Namibia' THEN 'NA'
|
||||||
|
WHEN 'Nauru' THEN 'NR'
|
||||||
|
WHEN 'Nepal' THEN 'NP'
|
||||||
|
WHEN 'Netherlands' THEN 'NL'
|
||||||
|
WHEN 'New Caledonia' THEN 'NC'
|
||||||
|
WHEN 'New Zealand' THEN 'NZ'
|
||||||
|
WHEN 'Nicaragua' THEN 'NI'
|
||||||
|
WHEN 'Niger' THEN 'NE'
|
||||||
|
WHEN 'Nigeria' THEN 'NG'
|
||||||
|
WHEN 'Niue' THEN 'NU'
|
||||||
|
WHEN 'Norfolk Island' THEN 'NF'
|
||||||
|
WHEN 'North Macedonia Republic of' THEN 'MK'
|
||||||
|
WHEN 'Northern Mariana Islands' THEN 'MP'
|
||||||
|
WHEN 'Norway' THEN 'NO'
|
||||||
|
WHEN 'Oman' THEN 'OM'
|
||||||
|
WHEN 'Pakistan' THEN 'PK'
|
||||||
|
WHEN 'Palau' THEN 'PW'
|
||||||
|
WHEN 'Palestinian Territory Occupied' THEN 'PS'
|
||||||
|
WHEN 'Panama' THEN 'PA'
|
||||||
|
WHEN 'Papua New Guinea' THEN 'PG'
|
||||||
|
WHEN 'Paraguay' THEN 'PY'
|
||||||
|
WHEN 'Peru' THEN 'PE'
|
||||||
|
WHEN 'Philippines' THEN 'PH'
|
||||||
|
WHEN 'Pitcairn' THEN 'PN'
|
||||||
|
WHEN 'Poland' THEN 'PL'
|
||||||
|
WHEN 'Portugal' THEN 'PT'
|
||||||
|
WHEN 'Puerto Rico' THEN 'PR'
|
||||||
|
WHEN 'Qatar' THEN 'QA'
|
||||||
|
WHEN 'Reunion' THEN 'RE'
|
||||||
|
WHEN 'Romania' THEN 'RO'
|
||||||
|
WHEN 'Russia' THEN 'RU'
|
||||||
|
WHEN 'Russian Federation' THEN 'RU'
|
||||||
|
WHEN 'Rwanda' THEN 'RW'
|
||||||
|
WHEN 'Saint Helena' THEN 'SH'
|
||||||
|
WHEN 'Saint Kitts and Nevis' THEN 'KN'
|
||||||
|
WHEN 'Saint Lucia' THEN 'LC'
|
||||||
|
WHEN 'Saint Pierre and Miquelon' THEN 'PM'
|
||||||
|
WHEN 'Saint Vincent and the Grenadines' THEN 'VC'
|
||||||
|
WHEN 'Samoa' THEN 'WS'
|
||||||
|
WHEN 'San Marino' THEN 'SM'
|
||||||
|
WHEN 'Sao Tome and Principe' THEN 'ST'
|
||||||
|
WHEN 'Saudi Arabia' THEN 'SA'
|
||||||
|
WHEN 'Senegal' THEN 'SN'
|
||||||
|
WHEN 'Seychelles' THEN 'SC'
|
||||||
|
WHEN 'Sierra Leone' THEN 'SL'
|
||||||
|
WHEN 'Singapore' THEN 'SG'
|
||||||
|
WHEN 'Slovakia' THEN 'SK'
|
||||||
|
WHEN 'Slovak Republic' THEN 'SK'
|
||||||
|
WHEN 'Slovenia' THEN 'SI'
|
||||||
|
WHEN 'Solomon Islands' THEN 'SB'
|
||||||
|
WHEN 'Somalia' THEN 'SO'
|
||||||
|
WHEN 'South Africa' THEN 'ZA'
|
||||||
|
WHEN 'South Georgia and the South Sandwich Islands' THEN 'GS'
|
||||||
|
WHEN 'Spain' THEN 'ES'
|
||||||
|
WHEN 'Sri Lanka' THEN 'LK'
|
||||||
|
WHEN 'Sudan' THEN 'SD'
|
||||||
|
WHEN 'Suriname' THEN 'SR'
|
||||||
|
WHEN 'Svalbard and Jan Mayen' THEN 'SJ'
|
||||||
|
WHEN 'Eswatini' THEN 'SZ'
|
||||||
|
WHEN 'Sweden' THEN 'SE'
|
||||||
|
WHEN 'Switzerland' THEN 'CH'
|
||||||
|
WHEN 'Syrian Arab Republic' THEN 'SY'
|
||||||
|
WHEN 'Taiwan' THEN 'TW'
|
||||||
|
WHEN 'Tajikistan' THEN 'TJ'
|
||||||
|
WHEN 'Tanzania United Republic of' THEN 'TZ'
|
||||||
|
WHEN 'Thailand' THEN 'TH'
|
||||||
|
WHEN 'Timor-Leste' THEN 'TL'
|
||||||
|
WHEN 'Togo' THEN 'TG'
|
||||||
|
WHEN 'Tokelau' THEN 'TK'
|
||||||
|
WHEN 'Tonga' THEN 'TO'
|
||||||
|
WHEN 'Trinidad and Tobago' THEN 'TT'
|
||||||
|
WHEN 'Tunisia' THEN 'TN'
|
||||||
|
WHEN 'Turkey' THEN 'TR'
|
||||||
|
WHEN 'Turkmenistan' THEN 'TM'
|
||||||
|
WHEN 'Turks and Caicos Islands' THEN 'TC'
|
||||||
|
WHEN 'Tuvalu' THEN 'TV'
|
||||||
|
WHEN 'Uganda' THEN 'UG'
|
||||||
|
WHEN 'Ukraine' THEN 'UA'
|
||||||
|
WHEN 'United Arab Emirates' THEN 'AE'
|
||||||
|
WHEN 'England' THEN 'GB'
|
||||||
|
WHEN 'Great Britain' THEN 'GB'
|
||||||
|
WHEN 'United Kingdom' THEN 'GB'
|
||||||
|
WHEN 'USA' THEN 'US'
|
||||||
|
WHEN 'United States' THEN 'US'
|
||||||
|
WHEN 'United States of America' THEN 'US'
|
||||||
|
WHEN 'United States Minor Outlying Islands' THEN 'UM'
|
||||||
|
WHEN 'Uruguay' THEN 'UY'
|
||||||
|
WHEN 'Uzbekistan' THEN 'UZ'
|
||||||
|
WHEN 'Vanuatu' THEN 'VU'
|
||||||
|
WHEN 'Venezuela' THEN 'VE'
|
||||||
|
WHEN 'Vietnam' THEN 'VN'
|
||||||
|
WHEN 'Virgin Islands British' THEN 'VG'
|
||||||
|
WHEN 'Virgin Islands U.S.' THEN 'VI'
|
||||||
|
WHEN 'Wallis and Futuna' THEN 'WF'
|
||||||
|
WHEN 'Western Sahara' THEN 'EH'
|
||||||
|
WHEN 'Yemen' THEN 'YE'
|
||||||
|
WHEN 'Zambia' THEN 'ZM'
|
||||||
|
WHEN 'Zimbabwe' THEN 'ZW'
|
||||||
|
WHEN 'Åland Islands' THEN 'AX'
|
||||||
|
WHEN 'Bonaire Sint Eustatius and Saba' THEN 'BQ'
|
||||||
|
WHEN 'Curaçao' THEN 'CW'
|
||||||
|
WHEN 'Guernsey' THEN 'GG'
|
||||||
|
WHEN 'Isle of Man' THEN 'IM'
|
||||||
|
WHEN 'Jersey' THEN 'JE'
|
||||||
|
WHEN 'Montenegro' THEN 'ME'
|
||||||
|
WHEN 'Saint Barthélemy' THEN 'BL'
|
||||||
|
WHEN 'Saint Martin (French part)' THEN 'MF'
|
||||||
|
WHEN 'Serbia' THEN 'RS'
|
||||||
|
WHEN 'Sint Maarten (Dutch part)' THEN 'SX'
|
||||||
|
WHEN 'South Sudan' THEN 'SS'
|
||||||
|
WHEN 'Kosovo' THEN 'XK'
|
||||||
|
ELSE `country`
|
||||||
|
END
|
||||||
|
END;
|
||||||
|
|
@ -8,7 +8,7 @@ import { ToastProvider } from "src/hooks/Toast";
|
||||||
import LightboxProvider from "src/hooks/Lightbox/context";
|
import LightboxProvider from "src/hooks/Lightbox/context";
|
||||||
import { initPolyfills } from "src/polyfills";
|
import { initPolyfills } from "src/polyfills";
|
||||||
|
|
||||||
import locales from "src/locales";
|
import locales, { registerCountry } from "src/locales";
|
||||||
import {
|
import {
|
||||||
useConfiguration,
|
useConfiguration,
|
||||||
useConfigureUI,
|
useConfigureUI,
|
||||||
|
|
@ -85,6 +85,9 @@ export const App: React.FC = () => {
|
||||||
const defaultMessageLanguage = languageMessageString(defaultLocale);
|
const defaultMessageLanguage = languageMessageString(defaultLocale);
|
||||||
const messageLanguage = languageMessageString(language);
|
const messageLanguage = languageMessageString(language);
|
||||||
|
|
||||||
|
// register countries for the chosen language
|
||||||
|
await registerCountry(language);
|
||||||
|
|
||||||
const defaultMessages = (await locales[defaultMessageLanguage]()).default;
|
const defaultMessages = (await locales[defaultMessageLanguage]()).default;
|
||||||
const mergedMessages = cloneDeep(Object.assign({}, defaultMessages));
|
const mergedMessages = cloneDeep(Object.assign({}, defaultMessages));
|
||||||
const chosenMessages = (await locales[messageLanguage]()).default;
|
const chosenMessages = (await locales[messageLanguage]()).default;
|
||||||
|
|
|
||||||
|
|
@ -28,6 +28,8 @@ import { LabeledIdFilter } from "./Filters/LabeledIdFilter";
|
||||||
import { HierarchicalLabelValueFilter } from "./Filters/HierarchicalLabelValueFilter";
|
import { HierarchicalLabelValueFilter } from "./Filters/HierarchicalLabelValueFilter";
|
||||||
import { OptionsFilter } from "./Filters/OptionsFilter";
|
import { OptionsFilter } from "./Filters/OptionsFilter";
|
||||||
import { InputFilter } from "./Filters/InputFilter";
|
import { InputFilter } from "./Filters/InputFilter";
|
||||||
|
import { CountryCriterion } from "src/models/list-filter/criteria/country";
|
||||||
|
import { CountrySelect } from "../Shared";
|
||||||
|
|
||||||
interface IAddFilterProps {
|
interface IAddFilterProps {
|
||||||
onAddCriterion: (
|
onAddCriterion: (
|
||||||
|
|
@ -173,6 +175,18 @@ export const AddFilterDialog: React.FC<IAddFilterProps> = ({
|
||||||
<NumberFilter criterion={criterion} onValueChanged={onValueChanged} />
|
<NumberFilter criterion={criterion} onValueChanged={onValueChanged} />
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
if (
|
||||||
|
criterion instanceof CountryCriterion &&
|
||||||
|
(criterion.modifier === CriterionModifier.Equals ||
|
||||||
|
criterion.modifier === CriterionModifier.NotEquals)
|
||||||
|
) {
|
||||||
|
return (
|
||||||
|
<CountrySelect
|
||||||
|
value={criterion.value}
|
||||||
|
onChange={(v) => onValueChanged(v)}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
return (
|
return (
|
||||||
<InputFilter criterion={criterion} onValueChanged={onValueChanged} />
|
<InputFilter criterion={criterion} onValueChanged={onValueChanged} />
|
||||||
);
|
);
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@ import React from "react";
|
||||||
import { FormattedMessage, useIntl } from "react-intl";
|
import { FormattedMessage, useIntl } from "react-intl";
|
||||||
import { TagLink } from "src/components/Shared";
|
import { TagLink } from "src/components/Shared";
|
||||||
import * as GQL from "src/core/generated-graphql";
|
import * as GQL from "src/core/generated-graphql";
|
||||||
import { TextUtils, getStashboxBase } from "src/utils";
|
import { TextUtils, getStashboxBase, getCountryByISO } from "src/utils";
|
||||||
import { TextField, URLField } from "src/utils/field";
|
import { TextField, URLField } from "src/utils/field";
|
||||||
|
|
||||||
interface IPerformerDetails {
|
interface IPerformerDetails {
|
||||||
|
|
@ -114,7 +114,12 @@ export const PerformerDetailsPanel: React.FC<IPerformerDetails> = ({
|
||||||
<TextField id="ethnicity" value={performer.ethnicity} />
|
<TextField id="ethnicity" value={performer.ethnicity} />
|
||||||
<TextField id="hair_color" value={performer.hair_color} />
|
<TextField id="hair_color" value={performer.hair_color} />
|
||||||
<TextField id="eye_color" value={performer.eye_color} />
|
<TextField id="eye_color" value={performer.eye_color} />
|
||||||
<TextField id="country" value={performer.country} />
|
<TextField
|
||||||
|
id="country"
|
||||||
|
value={
|
||||||
|
getCountryByISO(performer.country, intl.locale) ?? performer.country
|
||||||
|
}
|
||||||
|
/>
|
||||||
<TextField id="height" value={formatHeight(performer.height)} />
|
<TextField id="height" value={formatHeight(performer.height)} />
|
||||||
<TextField id="weight" value={formatWeight(performer.weight)} />
|
<TextField id="weight" value={formatWeight(performer.weight)} />
|
||||||
<TextField id="measurements" value={performer.measurements} />
|
<TextField id="measurements" value={performer.measurements} />
|
||||||
|
|
|
||||||
|
|
@ -20,9 +20,9 @@ import {
|
||||||
CollapseButton,
|
CollapseButton,
|
||||||
TagSelect,
|
TagSelect,
|
||||||
URLField,
|
URLField,
|
||||||
|
CountrySelect,
|
||||||
} from "src/components/Shared";
|
} from "src/components/Shared";
|
||||||
import { ImageUtils, getStashIDs } from "src/utils";
|
import { ImageUtils, getStashIDs } from "src/utils";
|
||||||
import { getCountryByISO } from "src/utils/country";
|
|
||||||
import { useToast } from "src/hooks";
|
import { useToast } from "src/hooks";
|
||||||
import { Prompt, useHistory } from "react-router-dom";
|
import { Prompt, useHistory } from "react-router-dom";
|
||||||
import { useFormik } from "formik";
|
import { useFormik } from "formik";
|
||||||
|
|
@ -545,7 +545,6 @@ export const PerformerEditPanel: React.FC<IPerformerDetails> = ({
|
||||||
const result: GQL.ScrapedPerformerDataFragment = {
|
const result: GQL.ScrapedPerformerDataFragment = {
|
||||||
...performerResult,
|
...performerResult,
|
||||||
images: performerResult.images ?? undefined,
|
images: performerResult.images ?? undefined,
|
||||||
country: getCountryByISO(performerResult.country),
|
|
||||||
__typename: "ScrapedPerformer",
|
__typename: "ScrapedPerformer",
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -880,7 +879,19 @@ export const PerformerEditPanel: React.FC<IPerformerDetails> = ({
|
||||||
|
|
||||||
{renderTextField("birthdate", "Birthdate", "YYYY-MM-DD")}
|
{renderTextField("birthdate", "Birthdate", "YYYY-MM-DD")}
|
||||||
{renderTextField("death_date", "Death Date", "YYYY-MM-DD")}
|
{renderTextField("death_date", "Death Date", "YYYY-MM-DD")}
|
||||||
{renderTextField("country", "Country")}
|
|
||||||
|
<Form.Group as={Row}>
|
||||||
|
<Form.Label column xs={labelXS} xl={labelXL}>
|
||||||
|
<FormattedMessage id="country" />
|
||||||
|
</Form.Label>
|
||||||
|
<Col xs={fieldXS} xl={fieldXL}>
|
||||||
|
<CountrySelect
|
||||||
|
value={formik.getFieldProps("country").value}
|
||||||
|
onChange={(value) => formik.setFieldValue("country", value)}
|
||||||
|
/>
|
||||||
|
</Col>
|
||||||
|
</Form.Group>
|
||||||
|
|
||||||
{renderTextField("ethnicity", "Ethnicity")}
|
{renderTextField("ethnicity", "Ethnicity")}
|
||||||
{renderTextField("hair_color", "Hair Color")}
|
{renderTextField("hair_color", "Hair Color")}
|
||||||
{renderTextField("eye_color", "Eye Color")}
|
{renderTextField("eye_color", "Eye Color")}
|
||||||
|
|
|
||||||
|
|
@ -8,6 +8,7 @@ import {
|
||||||
ScrapedImageRow,
|
ScrapedImageRow,
|
||||||
ScrapeDialogRow,
|
ScrapeDialogRow,
|
||||||
ScrapedTextAreaRow,
|
ScrapedTextAreaRow,
|
||||||
|
ScrapedCountryRow,
|
||||||
} from "src/components/Shared/ScrapeDialog";
|
} from "src/components/Shared/ScrapeDialog";
|
||||||
import { useTagCreate } from "src/core/StashService";
|
import { useTagCreate } from "src/core/StashService";
|
||||||
import { Form } from "react-bootstrap";
|
import { Form } from "react-bootstrap";
|
||||||
|
|
@ -448,7 +449,7 @@ export const PerformerScrapeDialog: React.FC<IPerformerScrapeDialogProps> = (
|
||||||
result={ethnicity}
|
result={ethnicity}
|
||||||
onChange={(value) => setEthnicity(value)}
|
onChange={(value) => setEthnicity(value)}
|
||||||
/>
|
/>
|
||||||
<ScrapedInputGroupRow
|
<ScrapedCountryRow
|
||||||
title={intl.formatMessage({ id: "country" })}
|
title={intl.formatMessage({ id: "country" })}
|
||||||
result={country}
|
result={country}
|
||||||
onChange={(value) => setCountry(value)}
|
onChange={(value) => setCountry(value)}
|
||||||
|
|
|
||||||
|
|
@ -78,7 +78,7 @@ const PerformerStashBoxModal: React.FC<IProps> = ({
|
||||||
) : performers.length > 0 ? (
|
) : performers.length > 0 ? (
|
||||||
<ul className={CLASSNAME_LIST}>
|
<ul className={CLASSNAME_LIST}>
|
||||||
{performers.map((p) => (
|
{performers.map((p) => (
|
||||||
<li key={p.url}>
|
<li key={p.remote_site_id}>
|
||||||
<Button variant="link" onClick={() => onSelectPerformer(p)}>
|
<Button variant="link" onClick={() => onSelectPerformer(p)}>
|
||||||
{p.name}
|
{p.name}
|
||||||
</Button>
|
</Button>
|
||||||
|
|
|
||||||
|
|
@ -1,21 +1,28 @@
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import { getISOCountry } from "src/utils";
|
import { useIntl } from "react-intl";
|
||||||
|
import { getCountryByISO } from "src/utils";
|
||||||
|
|
||||||
interface ICountryFlag {
|
interface ICountryFlag {
|
||||||
country?: string | null;
|
country?: string | null;
|
||||||
className?: string;
|
className?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
const CountryFlag: React.FC<ICountryFlag> = ({ className, country }) => {
|
const CountryFlag: React.FC<ICountryFlag> = ({
|
||||||
const ISOCountry = getISOCountry(country);
|
className,
|
||||||
if (!ISOCountry?.code) return <></>;
|
country: isoCountry,
|
||||||
|
}) => {
|
||||||
|
const { locale } = useIntl();
|
||||||
|
|
||||||
|
const country = getCountryByISO(isoCountry, locale);
|
||||||
|
|
||||||
|
if (!isoCountry || !country) return <></>;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<span
|
<span
|
||||||
className={`${
|
className={`${
|
||||||
className ?? ""
|
className ?? ""
|
||||||
} flag-icon flag-icon-${ISOCountry.code.toLowerCase()}`}
|
} flag-icon flag-icon-${isoCountry.toLowerCase()}`}
|
||||||
title={ISOCountry.name}
|
title={country}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
|
||||||
24
ui/v2.5/src/components/Shared/CountryLabel.tsx
Normal file
24
ui/v2.5/src/components/Shared/CountryLabel.tsx
Normal file
|
|
@ -0,0 +1,24 @@
|
||||||
|
import React from "react";
|
||||||
|
import { useIntl } from "react-intl";
|
||||||
|
import { CountryFlag } from "src/components/Shared";
|
||||||
|
import { getCountryByISO } from "src/utils";
|
||||||
|
|
||||||
|
interface IProps {
|
||||||
|
country: string | undefined;
|
||||||
|
showFlag?: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
const CountryLabel: React.FC<IProps> = ({ country, showFlag = true }) => {
|
||||||
|
const { locale } = useIntl();
|
||||||
|
|
||||||
|
const fromISO = getCountryByISO(country, locale);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
{showFlag && <CountryFlag className="mr-2" country={country} />}
|
||||||
|
<span>{fromISO ?? country}</span>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default CountryLabel;
|
||||||
51
ui/v2.5/src/components/Shared/CountrySelect.tsx
Normal file
51
ui/v2.5/src/components/Shared/CountrySelect.tsx
Normal file
|
|
@ -0,0 +1,51 @@
|
||||||
|
import React from "react";
|
||||||
|
import Creatable from "react-select/creatable";
|
||||||
|
import { useIntl } from "react-intl";
|
||||||
|
import { getCountries } from "src/utils";
|
||||||
|
import CountryLabel from "./CountryLabel";
|
||||||
|
|
||||||
|
interface IProps {
|
||||||
|
value?: string | undefined;
|
||||||
|
onChange?: (value: string) => void;
|
||||||
|
disabled?: boolean;
|
||||||
|
className?: string;
|
||||||
|
showFlag?: boolean;
|
||||||
|
isClearable?: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
const CountrySelect: React.FC<IProps> = ({
|
||||||
|
value,
|
||||||
|
onChange,
|
||||||
|
disabled = false,
|
||||||
|
isClearable = true,
|
||||||
|
showFlag,
|
||||||
|
className,
|
||||||
|
}) => {
|
||||||
|
const { locale } = useIntl();
|
||||||
|
const options = getCountries(locale);
|
||||||
|
const selected = options.find((opt) => opt.value === value) ?? {
|
||||||
|
label: value,
|
||||||
|
value,
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Creatable
|
||||||
|
classNamePrefix="react-select"
|
||||||
|
value={selected}
|
||||||
|
isClearable={isClearable}
|
||||||
|
formatOptionLabel={(option) => (
|
||||||
|
<CountryLabel country={option.value} showFlag={showFlag} />
|
||||||
|
)}
|
||||||
|
placeholder="Country"
|
||||||
|
options={options}
|
||||||
|
onChange={(selectedOption) => onChange?.(selectedOption?.value ?? "")}
|
||||||
|
isDisabled={disabled || !onChange}
|
||||||
|
components={{
|
||||||
|
IndicatorSeparator: null,
|
||||||
|
}}
|
||||||
|
className={`CountrySelect ${className}`}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default CountrySelect;
|
||||||
|
|
@ -20,6 +20,8 @@ import {
|
||||||
faPlus,
|
faPlus,
|
||||||
faTimes,
|
faTimes,
|
||||||
} from "@fortawesome/free-solid-svg-icons";
|
} from "@fortawesome/free-solid-svg-icons";
|
||||||
|
import { getCountryByISO } from "src/utils";
|
||||||
|
import CountrySelect from "./CountrySelect";
|
||||||
|
|
||||||
export class ScrapeResult<T> {
|
export class ScrapeResult<T> {
|
||||||
public newValue?: T;
|
public newValue?: T;
|
||||||
|
|
@ -392,3 +394,48 @@ export const ScrapeDialog: React.FC<IScrapeDialogProps> = (
|
||||||
</Modal>
|
</Modal>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
interface IScrapedCountryRowProps {
|
||||||
|
title: string;
|
||||||
|
result: ScrapeResult<string>;
|
||||||
|
onChange: (value: ScrapeResult<string>) => void;
|
||||||
|
locked?: boolean;
|
||||||
|
locale?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const ScrapedCountryRow: React.FC<IScrapedCountryRowProps> = ({
|
||||||
|
title,
|
||||||
|
result,
|
||||||
|
onChange,
|
||||||
|
locked,
|
||||||
|
locale,
|
||||||
|
}) => (
|
||||||
|
<ScrapeDialogRow
|
||||||
|
title={title}
|
||||||
|
result={result}
|
||||||
|
renderOriginalField={() => (
|
||||||
|
<FormControl
|
||||||
|
value={
|
||||||
|
getCountryByISO(result.originalValue, locale) ?? result.originalValue
|
||||||
|
}
|
||||||
|
readOnly
|
||||||
|
className="bg-secondary text-white border-secondary"
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
renderNewField={() => (
|
||||||
|
<CountrySelect
|
||||||
|
value={result.newValue}
|
||||||
|
disabled={locked}
|
||||||
|
onChange={(value) => {
|
||||||
|
if (onChange) {
|
||||||
|
onChange(result.cloneWithValue(value));
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
showFlag={false}
|
||||||
|
isClearable={false}
|
||||||
|
className="flex-grow-1"
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
onChange={onChange}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
|
|
||||||
|
|
@ -21,4 +21,7 @@ export { default as DeleteEntityDialog } from "./DeleteEntityDialog";
|
||||||
export { IndeterminateCheckbox } from "./IndeterminateCheckbox";
|
export { IndeterminateCheckbox } from "./IndeterminateCheckbox";
|
||||||
export { OperationButton } from "./OperationButton";
|
export { OperationButton } from "./OperationButton";
|
||||||
export { URLField } from "./URLField";
|
export { URLField } from "./URLField";
|
||||||
|
export { default as CountrySelect } from "./CountrySelect";
|
||||||
|
export { default as CountryLabel } from "./CountryLabel";
|
||||||
|
|
||||||
export const TITLE_SUFFIX = " | Stash";
|
export const TITLE_SUFFIX = " | Stash";
|
||||||
|
|
|
||||||
|
|
@ -298,3 +298,11 @@ button.collapse-button.btn-primary:not(:disabled):not(.disabled):active {
|
||||||
visibility: hidden;
|
visibility: hidden;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.CountrySelect {
|
||||||
|
/* stylelint-disable */
|
||||||
|
.react-select__control:hover {
|
||||||
|
border: none;
|
||||||
|
}
|
||||||
|
/* stylelint-enable */
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -132,7 +132,7 @@ const PerformerModal: React.FC<IPerformerModalProps> = ({
|
||||||
birthdate: performer.birthdate,
|
birthdate: performer.birthdate,
|
||||||
ethnicity: performer.ethnicity,
|
ethnicity: performer.ethnicity,
|
||||||
eye_color: performer.eye_color,
|
eye_color: performer.eye_color,
|
||||||
country: getCountryByISO(performer.country),
|
country: performer.country,
|
||||||
height: performer.height,
|
height: performer.height,
|
||||||
measurements: performer.measurements,
|
measurements: performer.measurements,
|
||||||
fake_tits: performer.fake_tits,
|
fake_tits: performer.fake_tits,
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
### ✨ New Features
|
### ✨ New Features
|
||||||
|
* Added selector for Country field. ([#1922](https://github.com/stashapp/stash/pull/1922))
|
||||||
* Added tag description filter criterion. ([#3011](https://github.com/stashapp/stash/pull/3011))
|
* Added tag description filter criterion. ([#3011](https://github.com/stashapp/stash/pull/3011))
|
||||||
|
|
||||||
### 🐛 Bug fixes
|
### 🐛 Bug fixes
|
||||||
|
|
|
||||||
255
ui/v2.5/src/locales/countryNames/zh-TW.json
Normal file
255
ui/v2.5/src/locales/countryNames/zh-TW.json
Normal file
|
|
@ -0,0 +1,255 @@
|
||||||
|
{
|
||||||
|
"locale": "tw",
|
||||||
|
"countries": {
|
||||||
|
"AD": "安道爾",
|
||||||
|
"AE": "阿聯酋",
|
||||||
|
"AF": "阿富汗",
|
||||||
|
"AG": "安地卡及巴布達",
|
||||||
|
"AI": "安圭拉",
|
||||||
|
"AL": "阿爾巴尼亞",
|
||||||
|
"AM": "亞美尼亞",
|
||||||
|
"AO": "安哥拉",
|
||||||
|
"AQ": "南極洲",
|
||||||
|
"AR": "阿根廷",
|
||||||
|
"AS": "美屬薩摩亞",
|
||||||
|
"AT": "奧地利",
|
||||||
|
"AU": "澳大利亞",
|
||||||
|
"AW": "阿魯巴",
|
||||||
|
"AX": "奧蘭",
|
||||||
|
"AZ": "阿塞拜疆",
|
||||||
|
"BA": "波斯尼亞和黑塞哥維那",
|
||||||
|
"BB": "巴巴多斯",
|
||||||
|
"BD": "孟加拉國",
|
||||||
|
"BE": "比利時",
|
||||||
|
"BF": "布吉納法索",
|
||||||
|
"BG": "保加利亞",
|
||||||
|
"BH": "巴林",
|
||||||
|
"BI": "布隆迪",
|
||||||
|
"BJ": "貝寧",
|
||||||
|
"BL": "聖巴泰勒米",
|
||||||
|
"BM": "百慕大",
|
||||||
|
"BN": "文萊",
|
||||||
|
"BO": "玻利維亞",
|
||||||
|
"BQ": "加勒比荷蘭",
|
||||||
|
"BR": "巴西",
|
||||||
|
"BS": "巴哈馬",
|
||||||
|
"BT": "不丹",
|
||||||
|
"BV": "布韋島",
|
||||||
|
"BW": "博茨瓦納",
|
||||||
|
"BY": "白俄羅斯",
|
||||||
|
"BZ": "伯利茲",
|
||||||
|
"CA": "加拿大",
|
||||||
|
"CC": "科科斯(基林)群島",
|
||||||
|
"CD": "剛果(金)",
|
||||||
|
"CF": "中非",
|
||||||
|
"CG": "剛果(布)",
|
||||||
|
"CH": "瑞士",
|
||||||
|
"CI": "科特迪瓦",
|
||||||
|
"CK": "庫克群島",
|
||||||
|
"CL": "智利",
|
||||||
|
"CM": "喀麥隆",
|
||||||
|
"CN": "中國",
|
||||||
|
"CO": "哥倫比亞",
|
||||||
|
"CR": "哥斯達黎加",
|
||||||
|
"CU": "古巴",
|
||||||
|
"CV": "佛得角",
|
||||||
|
"CW": "庫拉索",
|
||||||
|
"CX": "聖誕島",
|
||||||
|
"CY": "賽普勒斯",
|
||||||
|
"CZ": "捷克",
|
||||||
|
"DE": "德國",
|
||||||
|
"DJ": "吉布提",
|
||||||
|
"DK": "丹麥",
|
||||||
|
"DM": "多米尼克",
|
||||||
|
"DO": "多米尼加",
|
||||||
|
"DZ": "阿爾及利亞",
|
||||||
|
"EC": "厄瓜多爾",
|
||||||
|
"EE": "愛沙尼亞",
|
||||||
|
"EG": "埃及",
|
||||||
|
"EH": "阿拉伯撒哈拉民主共和國",
|
||||||
|
"ER": "厄立特里亞",
|
||||||
|
"ES": "西班牙",
|
||||||
|
"ET": "衣索比亞",
|
||||||
|
"FI": "芬蘭",
|
||||||
|
"FJ": "斐濟",
|
||||||
|
"FK": "福克蘭群島",
|
||||||
|
"FM": "密克羅尼西亞聯邦",
|
||||||
|
"FO": "法羅群島",
|
||||||
|
"FR": "法國",
|
||||||
|
"GA": "加彭",
|
||||||
|
"GB": "英國",
|
||||||
|
"GD": "格瑞那達",
|
||||||
|
"GE": "格魯吉亞",
|
||||||
|
"GF": "法屬圭亞那",
|
||||||
|
"GG": "根西",
|
||||||
|
"GH": "加納",
|
||||||
|
"GI": "直布羅陀",
|
||||||
|
"GL": "格陵蘭",
|
||||||
|
"GM": "岡比亞",
|
||||||
|
"GN": "幾內亞",
|
||||||
|
"GP": "瓜德羅普",
|
||||||
|
"GQ": "赤道幾內亞",
|
||||||
|
"GR": "希臘",
|
||||||
|
"GS": "南喬治亞和南桑威奇群島",
|
||||||
|
"GT": "危地馬拉",
|
||||||
|
"GU": "關島",
|
||||||
|
"GW": "幾內亞比紹",
|
||||||
|
"GY": "圭亞那",
|
||||||
|
"HK": "香港",
|
||||||
|
"HM": "赫德島和麥克唐納群島",
|
||||||
|
"HN": "宏都拉斯",
|
||||||
|
"HR": "克羅地亞",
|
||||||
|
"HT": "海地",
|
||||||
|
"HU": "匈牙利",
|
||||||
|
"ID": "印尼",
|
||||||
|
"IE": "愛爾蘭",
|
||||||
|
"IL": "以色列",
|
||||||
|
"IM": "馬恩島",
|
||||||
|
"IN": "印度",
|
||||||
|
"IO": "英屬印度洋領地",
|
||||||
|
"IQ": "伊拉克",
|
||||||
|
"IR": "伊朗",
|
||||||
|
"IS": "冰島",
|
||||||
|
"IT": "意大利",
|
||||||
|
"JE": "澤西",
|
||||||
|
"JM": "牙買加",
|
||||||
|
"JO": "約旦",
|
||||||
|
"JP": "日本",
|
||||||
|
"KE": "肯尼亞",
|
||||||
|
"KG": "吉爾吉斯斯坦",
|
||||||
|
"KH": "柬埔寨",
|
||||||
|
"KI": "基里巴斯",
|
||||||
|
"KM": "科摩羅",
|
||||||
|
"KN": "聖基茨和尼維斯",
|
||||||
|
"KP": "朝鮮",
|
||||||
|
"KR": "韓國",
|
||||||
|
"KW": "科威特",
|
||||||
|
"KY": "開曼群島",
|
||||||
|
"KZ": "哈薩克斯坦",
|
||||||
|
"LA": "老撾",
|
||||||
|
"LB": "黎巴嫩",
|
||||||
|
"LC": "聖盧西亞",
|
||||||
|
"LI": "列支敦斯登",
|
||||||
|
"LK": "斯里蘭卡",
|
||||||
|
"LR": "利比里亞",
|
||||||
|
"LS": "賴索托",
|
||||||
|
"LT": "立陶宛",
|
||||||
|
"LU": "盧森堡",
|
||||||
|
"LV": "拉脫維亞",
|
||||||
|
"LY": "利比亞",
|
||||||
|
"MA": "摩洛哥",
|
||||||
|
"MC": "摩納哥",
|
||||||
|
"MD": "摩爾多瓦",
|
||||||
|
"ME": "蒙特內哥羅",
|
||||||
|
"MF": "法屬聖馬丁",
|
||||||
|
"MG": "馬達加斯加",
|
||||||
|
"MH": "馬紹爾群島",
|
||||||
|
"MK": "馬其頓",
|
||||||
|
"ML": "馬里",
|
||||||
|
"MM": "緬甸",
|
||||||
|
"MN": "蒙古",
|
||||||
|
"MO": "澳門",
|
||||||
|
"MP": "北馬里亞納群島",
|
||||||
|
"MQ": "馬提尼克",
|
||||||
|
"MR": "毛里塔尼亞",
|
||||||
|
"MS": "蒙特塞拉特",
|
||||||
|
"MT": "馬爾他",
|
||||||
|
"MU": "模里西斯",
|
||||||
|
"MV": "馬爾地夫",
|
||||||
|
"MW": "馬拉維",
|
||||||
|
"MX": "墨西哥",
|
||||||
|
"MY": "馬來西亞",
|
||||||
|
"MZ": "莫桑比克",
|
||||||
|
"NA": "納米比亞",
|
||||||
|
"NC": "新喀裡多尼亞",
|
||||||
|
"NE": "尼日爾",
|
||||||
|
"NF": "諾福克島",
|
||||||
|
"NG": "奈及利亞",
|
||||||
|
"NI": "尼加拉瓜",
|
||||||
|
"NL": "荷蘭",
|
||||||
|
"NO": "挪威",
|
||||||
|
"NP": "尼泊爾",
|
||||||
|
"NR": "瑙魯",
|
||||||
|
"NU": "紐埃",
|
||||||
|
"NZ": "新西蘭",
|
||||||
|
"OM": "阿曼",
|
||||||
|
"PA": "巴拿馬",
|
||||||
|
"PE": "秘魯",
|
||||||
|
"PF": "法屬玻里尼西亞",
|
||||||
|
"PG": "巴布亞新幾內亞",
|
||||||
|
"PH": "菲律賓",
|
||||||
|
"PK": "巴基斯坦",
|
||||||
|
"PL": "波蘭",
|
||||||
|
"PM": "聖皮埃爾和密克隆",
|
||||||
|
"PN": "皮特凱恩群島",
|
||||||
|
"PR": "波多黎各",
|
||||||
|
"PS": "巴勒斯坦",
|
||||||
|
"PT": "葡萄牙",
|
||||||
|
"PW": "帛琉",
|
||||||
|
"PY": "巴拉圭",
|
||||||
|
"QA": "卡塔爾",
|
||||||
|
"RE": "留尼汪",
|
||||||
|
"RO": "羅馬尼亞",
|
||||||
|
"RS": "塞爾維亞",
|
||||||
|
"RU": "俄羅斯",
|
||||||
|
"RW": "盧旺達",
|
||||||
|
"SA": "沙烏地阿拉伯",
|
||||||
|
"SB": "所羅門群島",
|
||||||
|
"SC": "塞舌爾",
|
||||||
|
"SD": "蘇丹",
|
||||||
|
"SE": "瑞典",
|
||||||
|
"SG": "新加坡",
|
||||||
|
"SH": "聖赫勒拿",
|
||||||
|
"SI": "斯洛維尼亞",
|
||||||
|
"SJ": "斯瓦爾巴群島和揚馬延島",
|
||||||
|
"SK": "斯洛伐克",
|
||||||
|
"SL": "塞拉利昂",
|
||||||
|
"SM": "聖馬力諾",
|
||||||
|
"SN": "塞內加爾",
|
||||||
|
"SO": "索馬利亞",
|
||||||
|
"SR": "蘇里南",
|
||||||
|
"SS": "南蘇丹",
|
||||||
|
"ST": "聖多美和普林西比",
|
||||||
|
"SV": "薩爾瓦多",
|
||||||
|
"SX": "荷屬聖馬丁",
|
||||||
|
"SY": "敘利亞",
|
||||||
|
"SZ": "斯威士蘭",
|
||||||
|
"TC": "特克斯和凱科斯群島",
|
||||||
|
"TD": "乍得",
|
||||||
|
"TF": "法屬南部領地",
|
||||||
|
"TG": "多哥",
|
||||||
|
"TH": "泰國",
|
||||||
|
"TJ": "塔吉克斯坦",
|
||||||
|
"TK": "托克勞",
|
||||||
|
"TL": "東帝汶",
|
||||||
|
"TM": "土庫曼斯坦",
|
||||||
|
"TN": "突尼西亞",
|
||||||
|
"TO": "湯加",
|
||||||
|
"TR": "土耳其",
|
||||||
|
"TT": "千里達及托巴哥",
|
||||||
|
"TV": "圖瓦盧",
|
||||||
|
"TW": "臺灣",
|
||||||
|
"TZ": "坦桑尼亞",
|
||||||
|
"UA": "烏克蘭",
|
||||||
|
"UG": "烏干達",
|
||||||
|
"UM": "美國本土外小島嶼",
|
||||||
|
"US": "美國",
|
||||||
|
"UY": "烏拉圭",
|
||||||
|
"UZ": "烏茲別克斯坦",
|
||||||
|
"VA": "梵蒂岡",
|
||||||
|
"VC": "聖文森及格瑞那丁",
|
||||||
|
"VE": "委內瑞拉",
|
||||||
|
"VG": "英屬維爾京群島",
|
||||||
|
"VI": "美屬維爾京群島",
|
||||||
|
"VN": "越南",
|
||||||
|
"VU": "瓦努阿圖",
|
||||||
|
"WF": "瓦利斯和富圖納",
|
||||||
|
"WS": "薩摩亞",
|
||||||
|
"YE": "葉門",
|
||||||
|
"YT": "馬約特",
|
||||||
|
"ZA": "南非",
|
||||||
|
"ZM": "尚比亞",
|
||||||
|
"ZW": "辛巴威",
|
||||||
|
"XK": "科索沃"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,3 +1,40 @@
|
||||||
|
import Countries from "i18n-iso-countries";
|
||||||
|
|
||||||
|
export const localeCountries = {
|
||||||
|
en: () => import("i18n-iso-countries/langs/en.json"),
|
||||||
|
da: () => import("i18n-iso-countries/langs/da.json"),
|
||||||
|
de: () => import("i18n-iso-countries/langs/de.json"),
|
||||||
|
es: () => import("i18n-iso-countries/langs/es.json"),
|
||||||
|
fi: () => import("i18n-iso-countries/langs/fi.json"),
|
||||||
|
fr: () => import("i18n-iso-countries/langs/fr.json"),
|
||||||
|
hr: () => import("i18n-iso-countries/langs/hr.json"),
|
||||||
|
it: () => import("i18n-iso-countries/langs/it.json"),
|
||||||
|
ja: () => import("i18n-iso-countries/langs/ja.json"),
|
||||||
|
ko: () => import("i18n-iso-countries/langs/ko.json"),
|
||||||
|
nl: () => import("i18n-iso-countries/langs/nl.json"),
|
||||||
|
pl: () => import("i18n-iso-countries/langs/pl.json"),
|
||||||
|
pt: () => import("i18n-iso-countries/langs/pt.json"),
|
||||||
|
ru: () => import("i18n-iso-countries/langs/ru.json"),
|
||||||
|
sv: () => import("i18n-iso-countries/langs/sv.json"),
|
||||||
|
tr: () => import("i18n-iso-countries/langs/tr.json"),
|
||||||
|
uk: () => import("i18n-iso-countries/langs/uk.json"),
|
||||||
|
zh: () => import("i18n-iso-countries/langs/zh.json"),
|
||||||
|
tw: () => import("src/locales/countryNames/zh-TW.json"),
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||||
|
} as { [key: string]: any };
|
||||||
|
|
||||||
|
export const getLocaleCode = (code: string) => {
|
||||||
|
if (code === "zh-CN") return "zh";
|
||||||
|
if (code === "zh-TW") return "tw";
|
||||||
|
return code.slice(0, 2);
|
||||||
|
};
|
||||||
|
|
||||||
|
export async function registerCountry(locale: string) {
|
||||||
|
const localeCode = getLocaleCode(locale);
|
||||||
|
const countries = await localeCountries[localeCode]();
|
||||||
|
Countries.registerLocale(countries);
|
||||||
|
}
|
||||||
|
|
||||||
export const localeLoader = {
|
export const localeLoader = {
|
||||||
deDE: () => import("./de-DE.json"),
|
deDE: () => import("./de-DE.json"),
|
||||||
enGB: () => import("./en-GB.json"),
|
enGB: () => import("./en-GB.json"),
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,6 @@
|
||||||
|
import { IntlShape } from "react-intl";
|
||||||
|
import { CriterionModifier } from "src/core/generated-graphql";
|
||||||
|
import { getCountryByISO } from "src/utils";
|
||||||
import { StringCriterion, StringCriterionOption } from "./criterion";
|
import { StringCriterion, StringCriterionOption } from "./criterion";
|
||||||
|
|
||||||
const countryCriterionOption = new StringCriterionOption(
|
const countryCriterionOption = new StringCriterionOption(
|
||||||
|
|
@ -10,4 +13,15 @@ export class CountryCriterion extends StringCriterion {
|
||||||
constructor() {
|
constructor() {
|
||||||
super(countryCriterionOption);
|
super(countryCriterionOption);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public getLabelValue(intl: IntlShape) {
|
||||||
|
if (
|
||||||
|
this.modifier === CriterionModifier.Equals ||
|
||||||
|
this.modifier === CriterionModifier.NotEquals
|
||||||
|
) {
|
||||||
|
return getCountryByISO(this.value, intl.locale) ?? this.value;
|
||||||
|
}
|
||||||
|
|
||||||
|
return super.getLabelValue(intl);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
/* eslint-disable consistent-return */
|
/* eslint-disable consistent-return */
|
||||||
|
/* eslint @typescript-eslint/no-unused-vars: ["error", { "argsIgnorePattern": "^_" }] */
|
||||||
|
|
||||||
import { IntlShape } from "react-intl";
|
import { IntlShape } from "react-intl";
|
||||||
import {
|
import {
|
||||||
|
|
@ -61,7 +62,7 @@ export abstract class Criterion<V extends CriterionValue> {
|
||||||
this._value = newValue;
|
this._value = newValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
public abstract getLabelValue(): string;
|
public abstract getLabelValue(intl: IntlShape): string;
|
||||||
|
|
||||||
constructor(type: CriterionOption, value: V) {
|
constructor(type: CriterionOption, value: V) {
|
||||||
this.criterionOption = type;
|
this.criterionOption = type;
|
||||||
|
|
@ -85,7 +86,7 @@ export abstract class Criterion<V extends CriterionValue> {
|
||||||
this.modifier !== CriterionModifier.IsNull &&
|
this.modifier !== CriterionModifier.IsNull &&
|
||||||
this.modifier !== CriterionModifier.NotNull
|
this.modifier !== CriterionModifier.NotNull
|
||||||
) {
|
) {
|
||||||
valueString = this.getLabelValue();
|
valueString = this.getLabelValue(intl);
|
||||||
}
|
}
|
||||||
|
|
||||||
return intl.formatMessage(
|
return intl.formatMessage(
|
||||||
|
|
@ -215,7 +216,7 @@ export class StringCriterion extends Criterion<string> {
|
||||||
super(type, "");
|
super(type, "");
|
||||||
}
|
}
|
||||||
|
|
||||||
public getLabelValue() {
|
public getLabelValue(_intl: IntlShape) {
|
||||||
return this.value;
|
return this.value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -345,7 +346,7 @@ export class NumberCriterion extends Criterion<INumberValue> {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
public getLabelValue() {
|
public getLabelValue(_intl: IntlShape) {
|
||||||
const { value, value2 } = this.value;
|
const { value, value2 } = this.value;
|
||||||
if (
|
if (
|
||||||
this.modifier === CriterionModifier.Between ||
|
this.modifier === CriterionModifier.Between ||
|
||||||
|
|
@ -393,7 +394,7 @@ export class ILabeledIdCriterionOption extends CriterionOption {
|
||||||
}
|
}
|
||||||
|
|
||||||
export class ILabeledIdCriterion extends Criterion<ILabeledId[]> {
|
export class ILabeledIdCriterion extends Criterion<ILabeledId[]> {
|
||||||
public getLabelValue(): string {
|
public getLabelValue(_intl: IntlShape): string {
|
||||||
return this.value.map((v) => v.label).join(", ");
|
return this.value.map((v) => v.label).join(", ");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -418,7 +419,7 @@ export class IHierarchicalLabeledIdCriterion extends Criterion<IHierarchicalLabe
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
public getLabelValue(): string {
|
public getLabelValue(_intl: IntlShape): string {
|
||||||
const labels = (this.value.items ?? []).map((v) => v.label).join(", ");
|
const labels = (this.value.items ?? []).map((v) => v.label).join(", ");
|
||||||
|
|
||||||
if (this.value.depth === 0) {
|
if (this.value.depth === 0) {
|
||||||
|
|
@ -478,7 +479,7 @@ export class DurationCriterion extends Criterion<INumberValue> {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
public getLabelValue() {
|
public getLabelValue(_intl: IntlShape) {
|
||||||
return this.modifier === CriterionModifier.Between ||
|
return this.modifier === CriterionModifier.Between ||
|
||||||
this.modifier === CriterionModifier.NotBetween
|
this.modifier === CriterionModifier.NotBetween
|
||||||
? `${DurationUtils.secondsToString(
|
? `${DurationUtils.secondsToString(
|
||||||
|
|
|
||||||
|
|
@ -44,6 +44,7 @@ import { InteractiveCriterion } from "./interactive";
|
||||||
import { RatingCriterionOption } from "./rating";
|
import { RatingCriterionOption } from "./rating";
|
||||||
import { DuplicatedCriterion, PhashCriterionOption } from "./phash";
|
import { DuplicatedCriterion, PhashCriterionOption } from "./phash";
|
||||||
import { CaptionCriterion } from "./captions";
|
import { CaptionCriterion } from "./captions";
|
||||||
|
import { CountryCriterion } from "./country";
|
||||||
|
|
||||||
export function makeCriteria(type: CriterionType = "none") {
|
export function makeCriteria(type: CriterionType = "none") {
|
||||||
switch (type) {
|
switch (type) {
|
||||||
|
|
@ -144,8 +145,9 @@ export function makeCriteria(type: CriterionType = "none") {
|
||||||
return new StringCriterion(PhashCriterionOption);
|
return new StringCriterion(PhashCriterionOption);
|
||||||
case "duplicated":
|
case "duplicated":
|
||||||
return new DuplicatedCriterion();
|
return new DuplicatedCriterion();
|
||||||
case "ethnicity":
|
|
||||||
case "country":
|
case "country":
|
||||||
|
return new CountryCriterion();
|
||||||
|
case "ethnicity":
|
||||||
case "hair_color":
|
case "hair_color":
|
||||||
case "eye_color":
|
case "eye_color":
|
||||||
case "height":
|
case "height":
|
||||||
|
|
|
||||||
|
|
@ -1,41 +1,32 @@
|
||||||
import Countries from "i18n-iso-countries";
|
import Countries from "i18n-iso-countries";
|
||||||
import english from "i18n-iso-countries/langs/en.json";
|
import { getLocaleCode } from "src/locales";
|
||||||
|
|
||||||
Countries.registerLocale(english);
|
export const getCountryByISO = (
|
||||||
|
iso: string | null | undefined,
|
||||||
|
locale: string = "en"
|
||||||
|
): string | undefined => {
|
||||||
|
if (!iso) return;
|
||||||
|
|
||||||
const fuzzyDict: Record<string, string> = {
|
const ret = Countries.getName(iso, getLocaleCode(locale));
|
||||||
USA: "US",
|
if (ret) {
|
||||||
"United States": "US",
|
return ret;
|
||||||
America: "US",
|
}
|
||||||
American: "US",
|
|
||||||
Czechia: "CZ",
|
// fallback to english if locale is not en
|
||||||
England: "GB",
|
if (locale !== "en") {
|
||||||
"United Kingdom": "GB",
|
return Countries.getName(iso, "en");
|
||||||
Russia: "RU",
|
}
|
||||||
"Slovak Republic": "SK",
|
|
||||||
Iran: "IR",
|
|
||||||
Moldova: "MD",
|
|
||||||
Laos: "LA",
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const getISOCountry = (country: string | null | undefined) => {
|
export const getCountries = (locale: string = "en") => {
|
||||||
if (!country) return null;
|
let countries = Countries.getNames(getLocaleCode(locale));
|
||||||
|
|
||||||
const code =
|
if (!countries.length) {
|
||||||
fuzzyDict[country] ?? Countries.getAlpha2Code(country, "en") ?? country;
|
countries = Countries.getNames("en");
|
||||||
// Check if code is valid alpha2 iso
|
}
|
||||||
if (!Countries.alpha2ToAlpha3(code)) return null;
|
|
||||||
|
|
||||||
return {
|
return Object.entries(countries).map(([code, name]) => ({
|
||||||
code,
|
label: name,
|
||||||
name: Countries.getName(code, "en"),
|
value: code,
|
||||||
|
}));
|
||||||
};
|
};
|
||||||
};
|
|
||||||
|
|
||||||
export const getCountryByISO = (iso: string | null | undefined) => {
|
|
||||||
if (!iso) return null;
|
|
||||||
|
|
||||||
return Countries.getName(iso, "en") ?? null;
|
|
||||||
};
|
|
||||||
|
|
||||||
export default getISOCountry;
|
|
||||||
|
|
|
||||||
|
|
@ -8,9 +8,10 @@ export { default as FormUtils } from "./form";
|
||||||
export { default as DurationUtils } from "./duration";
|
export { default as DurationUtils } from "./duration";
|
||||||
export { default as SessionUtils } from "./session";
|
export { default as SessionUtils } from "./session";
|
||||||
export { default as flattenMessages } from "./flattenMessages";
|
export { default as flattenMessages } from "./flattenMessages";
|
||||||
export { default as getISOCountry } from "./country";
|
export * from "./country";
|
||||||
export { default as useFocus } from "./focus";
|
export { default as useFocus } from "./focus";
|
||||||
export { default as downloadFile } from "./download";
|
export { default as downloadFile } from "./download";
|
||||||
export * from "./data";
|
export * from "./data";
|
||||||
export { getStashIDs } from "./stashIds";
|
export { getStashIDs } from "./stashIds";
|
||||||
export * from "./stashbox";
|
export * from "./stashbox";
|
||||||
|
export * from "./gender";
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue