diff --git a/package-lock.json b/package-lock.json index 1a08218..ddba3c0 100644 --- a/package-lock.json +++ b/package-lock.json @@ -8,6 +8,10 @@ "name": "scoreko-dev", "version": "3.0.0", "license": "MIT", + "dependencies": { + "country-list": "^2.4.1", + "flag-icons": "^7.5.0" + }, "devDependencies": { "@eslint/js": "^9.39.0", "@quasar/extras": "^1.17.0", @@ -5266,6 +5270,12 @@ } } }, + "node_modules/country-list": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/country-list/-/country-list-2.4.1.tgz", + "integrity": "sha512-KhVV/UfUV3dSNpsWIqHTQxLpYDKPKz1UwkRjadt+YbX2PRhyCEihEoS5XgB7J7AMXpkicvl+tRHvkNI5wbji/g==", + "license": "MIT" + }, "node_modules/cross-spawn": { "version": "7.0.6", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", @@ -6523,6 +6533,12 @@ "desandro-matches-selector": "^2.0.0" } }, + "node_modules/flag-icons": { + "version": "7.5.0", + "resolved": "https://registry.npmjs.org/flag-icons/-/flag-icons-7.5.0.tgz", + "integrity": "sha512-kd+MNXviFIg5hijH766tt+3x76ele1AXlo4zDdCxIvqWZhKt4T83bOtxUOOMlTx/EcFdUMH5yvQgYlFh1EqqFg==", + "license": "MIT" + }, "node_modules/flat-cache": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-4.0.1.tgz", diff --git a/package.json b/package.json index f8f3bc8..adcdd43 100644 --- a/package.json +++ b/package.json @@ -88,5 +88,9 @@ "vite-plugin-nodecg": { "vite": "$vite" } + }, + "dependencies": { + "country-list": "^2.4.1", + "flag-icons": "^7.5.0" } } diff --git a/src/dashboard/example/views/Players.vue b/src/dashboard/example/views/Players.vue index a134dd6..6342364 100644 --- a/src/dashboard/example/views/Players.vue +++ b/src/dashboard/example/views/Players.vue @@ -1,8 +1,9 @@ @@ -69,20 +117,46 @@ const roundText = computed(() => scoreboard.value.round || 'Round');
+ + {{ leftTeam }} + {{ leftName }}
+ +
+
+ +
+
+ + {{ rightTeam }} + {{ rightName }}
+ +
+
+ +
+
@@ -107,6 +181,11 @@ const roundText = computed(() => scoreboard.value.round || 'Round'); var(--name-panel-height) * 0.5 - (var(--name-text-height) * 0.5) ); + --flag-width: 38px; + --flag-height: 26px; + --flag-offset-x: 16px; + --flag-offset-y: 12px; + --games-text-width: calc(var(--main-panel-width) * 0.11); --games-text-height: calc(var(--main-panel-height) * 0.8); --games-text-offset-x: calc(var(--main-panel-width) * 0.04); @@ -233,6 +312,40 @@ img { text-overflow: ellipsis; } +.team-text { + color: #a5a5a5; + margin-right: 8px; +} + +.flag-wrapper { + position: absolute; + top: var(--flag-offset-y); + height: var(--flag-height); + width: var(--flag-width); + z-index: 1; +} + +#p1-flag-wrapper { + left: var(--flag-offset-x); +} + +#p2-flag-wrapper { + right: var(--flag-offset-x); +} + +.flag-mask { + width: 100%; + height: 100%; + border-radius: 4px; + overflow: hidden; +} + +.flag { + width: 100%; + height: 100%; + object-fit: cover; +} + .games-text-wrapper { position: absolute; top: var(--games-text-offset-y); diff --git a/src/shared/countries.ts b/src/shared/countries.ts new file mode 100644 index 0000000..96cefdc --- /dev/null +++ b/src/shared/countries.ts @@ -0,0 +1,49 @@ +import { getData, type CountryRecord } from 'country-list'; + +export interface CountryOption { + value: string; + label: string; +} + +const baseCountries = getData(); + +export const countryOptions: CountryOption[] = baseCountries + .map((country: CountryRecord) => ({ + value: country.code, + label: country.name, + })) + .sort((a: CountryOption, b: CountryOption) => a.label.localeCompare(b.label)); + +const countryByCode = new Map( + countryOptions.map((country) => [country.value.toUpperCase(), country.label]), +); +const countryByName = new Map( + countryOptions.map((country) => [country.label.toLowerCase(), country.value]), +); + +export const resolveCountryCode = (value?: string) => { + if (!value) { + return ''; + } + const trimmed = value.trim(); + if (!trimmed) { + return ''; + } + const upper = trimmed.toUpperCase(); + if (countryByCode.has(upper)) { + return upper; + } + const byName = countryByName.get(trimmed.toLowerCase()); + return byName ?? ''; +}; + +export const getCountryLabel = (value?: string) => { + if (!value) { + return ''; + } + const resolved = resolveCountryCode(value); + if (!resolved) { + return value; + } + return countryByCode.get(resolved) ?? value; +}; diff --git a/src/types/country-list.d.ts b/src/types/country-list.d.ts new file mode 100644 index 0000000..587780e --- /dev/null +++ b/src/types/country-list.d.ts @@ -0,0 +1,8 @@ +declare module 'country-list' { + export interface CountryRecord { + code: string; + name: string; + } + + export const getData: () => CountryRecord[]; +} diff --git a/src/types/vite-env.d.ts b/src/types/vite-env.d.ts new file mode 100644 index 0000000..11f02fe --- /dev/null +++ b/src/types/vite-env.d.ts @@ -0,0 +1 @@ +///