167 lines
4.8 KiB
Dart
167 lines
4.8 KiB
Dart
import 'package:flutter/material.dart';
|
|
import 'package:material_symbols_icons/symbols.dart';
|
|
import 'package:komet/core/config/countries.dart';
|
|
import 'package:komet/l10n/app_localizations.dart';
|
|
|
|
class SelectCountryScreen extends StatefulWidget {
|
|
final CountryName selectedCountry;
|
|
final List<CountryName> countries;
|
|
|
|
SelectCountryScreen({
|
|
super.key,
|
|
required this.selectedCountry,
|
|
List<CountryName>? countries,
|
|
}) : countries = countries ?? allCountries;
|
|
|
|
@override
|
|
State<SelectCountryScreen> createState() => _SelectCountryScreenState();
|
|
}
|
|
|
|
class _CountrySearchEntry {
|
|
final CountryName country;
|
|
final String ruLower;
|
|
final String enLower;
|
|
|
|
const _CountrySearchEntry(this.country, this.ruLower, this.enLower);
|
|
}
|
|
|
|
class _SelectCountryScreenState extends State<SelectCountryScreen> {
|
|
bool _isSearching = false;
|
|
final TextEditingController _searchController = TextEditingController();
|
|
late List<CountryName> _filteredCountries;
|
|
late final List<_CountrySearchEntry> _searchEntries;
|
|
|
|
@override
|
|
void initState() {
|
|
super.initState();
|
|
_filteredCountries = widget.countries;
|
|
_searchEntries = widget.countries
|
|
.map(
|
|
(c) => _CountrySearchEntry(c, c.ru.toLowerCase(), c.en.toLowerCase()),
|
|
)
|
|
.toList();
|
|
}
|
|
|
|
@override
|
|
void dispose() {
|
|
_searchController.dispose();
|
|
super.dispose();
|
|
}
|
|
|
|
void _filterCountries(String query) {
|
|
setState(() {
|
|
if (query.isEmpty) {
|
|
_filteredCountries = widget.countries;
|
|
} else {
|
|
final q = query.toLowerCase();
|
|
_filteredCountries = _searchEntries
|
|
.where(
|
|
(e) =>
|
|
e.ruLower.contains(q) ||
|
|
e.enLower.contains(q) ||
|
|
e.country.phoneCode.contains(q),
|
|
)
|
|
.map((e) => e.country)
|
|
.toList();
|
|
}
|
|
});
|
|
}
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
final cs = Theme.of(context).colorScheme;
|
|
final l10n = AppLocalizations.of(context)!;
|
|
final lang = Localizations.localeOf(context).languageCode;
|
|
|
|
return Scaffold(
|
|
backgroundColor: cs.surface,
|
|
appBar: AppBar(
|
|
backgroundColor: cs.surface,
|
|
surfaceTintColor: Colors.transparent,
|
|
leading: IconButton(
|
|
onPressed: () => Navigator.pop(context),
|
|
icon: Icon(Symbols.arrow_back, color: cs.onSurface),
|
|
),
|
|
title: _isSearching
|
|
? TextField(
|
|
controller: _searchController,
|
|
autofocus: true,
|
|
style: TextStyle(
|
|
color: cs.onSurface,
|
|
fontSize: 18,
|
|
fontWeight: FontWeight.w400,
|
|
),
|
|
decoration: InputDecoration(
|
|
hintText: l10n.selectCountrySearchHint,
|
|
hintStyle: TextStyle(
|
|
color: cs.onSurfaceVariant,
|
|
fontSize: 18,
|
|
fontWeight: FontWeight.w400,
|
|
),
|
|
border: InputBorder.none,
|
|
),
|
|
onChanged: _filterCountries,
|
|
)
|
|
: Text(
|
|
l10n.selectCountryTitle,
|
|
style: TextStyle(
|
|
color: cs.onSurface,
|
|
fontSize: 20,
|
|
fontWeight: FontWeight.w500,
|
|
),
|
|
),
|
|
centerTitle: true,
|
|
actions: [
|
|
IconButton(
|
|
onPressed: () {
|
|
setState(() {
|
|
_isSearching = !_isSearching;
|
|
if (!_isSearching) {
|
|
_searchController.clear();
|
|
_filteredCountries = widget.countries;
|
|
}
|
|
});
|
|
},
|
|
icon: Icon(
|
|
_isSearching ? Symbols.close : Symbols.search,
|
|
color: cs.onSurface,
|
|
),
|
|
),
|
|
],
|
|
),
|
|
body: ListView.builder(
|
|
itemCount: _filteredCountries.length,
|
|
itemBuilder: (context, index) {
|
|
final country = _filteredCountries[index];
|
|
final isSelected = country.code == widget.selectedCountry.code;
|
|
|
|
return ListTile(
|
|
leading: Text(
|
|
country.phoneCode,
|
|
style: TextStyle(
|
|
color: cs.onSurfaceVariant,
|
|
fontSize: 14,
|
|
fontWeight: FontWeight.w400,
|
|
),
|
|
),
|
|
title: Text(
|
|
country.displayName(lang),
|
|
style: TextStyle(
|
|
color: cs.onSurface,
|
|
fontSize: 16,
|
|
fontWeight: isSelected ? FontWeight.w600 : FontWeight.w400,
|
|
),
|
|
),
|
|
trailing: isSelected
|
|
? Icon(Symbols.check, color: cs.primary)
|
|
: null,
|
|
onTap: () {
|
|
Navigator.pop(context, country);
|
|
},
|
|
);
|
|
},
|
|
),
|
|
);
|
|
}
|
|
}
|