Polish Telegram auth UI state
All checks were successful
Build and deploy Flutter Web / build (push) Successful in 2m15s
All checks were successful
Build and deploy Flutter Web / build (push) Successful in 2m15s
This commit is contained in:
@@ -44,6 +44,9 @@ class _MapContent extends ConsumerWidget {
|
||||
@override
|
||||
Widget build(BuildContext context, WidgetRef ref) {
|
||||
final selected = state.selectedPlace;
|
||||
final availableTraits = {
|
||||
for (final place in state.recommendations) ...place.traits,
|
||||
}.toList();
|
||||
|
||||
return Scaffold(
|
||||
body: Stack(
|
||||
@@ -78,10 +81,20 @@ class _MapContent extends ConsumerWidget {
|
||||
),
|
||||
SafeArea(
|
||||
child: Align(
|
||||
alignment: Alignment.topCenter,
|
||||
child: _TraitBar(selectedTrait: state.selectedTrait),
|
||||
alignment: Alignment.topLeft,
|
||||
child: _UserAvatar(user: state.currentUser),
|
||||
),
|
||||
),
|
||||
if (availableTraits.isNotEmpty)
|
||||
SafeArea(
|
||||
child: Align(
|
||||
alignment: Alignment.topCenter,
|
||||
child: _TraitBar(
|
||||
selectedTrait: state.selectedTrait,
|
||||
traits: availableTraits,
|
||||
),
|
||||
),
|
||||
),
|
||||
Align(
|
||||
alignment: Alignment.bottomCenter,
|
||||
child: SafeArea(
|
||||
@@ -124,6 +137,48 @@ class _MapContent extends ConsumerWidget {
|
||||
}
|
||||
}
|
||||
|
||||
class _UserAvatar extends StatelessWidget {
|
||||
const _UserAvatar({required this.user});
|
||||
|
||||
final AppUser? user;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final photoUrl = user?.photoUrl;
|
||||
final fallback = _fallbackText();
|
||||
|
||||
return Padding(
|
||||
padding: const EdgeInsets.only(left: 12, top: 8),
|
||||
child: CircleAvatar(
|
||||
radius: 22,
|
||||
backgroundColor: const Color(0xFFFFFBF5),
|
||||
foregroundColor: const Color(0xFF17211D),
|
||||
backgroundImage: photoUrl == null ? null : NetworkImage(photoUrl),
|
||||
child: photoUrl == null
|
||||
? Text(
|
||||
fallback,
|
||||
style: const TextStyle(fontWeight: FontWeight.w900),
|
||||
)
|
||||
: null,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
String _fallbackText() {
|
||||
final firstName = user?.firstName?.trim();
|
||||
if (firstName != null && firstName.isNotEmpty) {
|
||||
return firstName.characters.first.toUpperCase();
|
||||
}
|
||||
|
||||
final username = user?.username?.trim();
|
||||
if (username != null && username.isNotEmpty) {
|
||||
return username.characters.first.toUpperCase();
|
||||
}
|
||||
|
||||
return 'M';
|
||||
}
|
||||
}
|
||||
|
||||
class _TelegramLoginScreen extends StatelessWidget {
|
||||
const _TelegramLoginScreen({required this.onAuthenticated});
|
||||
|
||||
@@ -264,23 +319,24 @@ class _MapAttribution extends StatelessWidget {
|
||||
}
|
||||
|
||||
class _TraitBar extends ConsumerWidget {
|
||||
const _TraitBar({required this.selectedTrait});
|
||||
const _TraitBar({required this.selectedTrait, required this.traits});
|
||||
|
||||
final PlaceTrait selectedTrait;
|
||||
final List<PlaceTrait> traits;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context, WidgetRef ref) {
|
||||
final controller = ref.read(placeControllerProvider.notifier);
|
||||
|
||||
return Container(
|
||||
height: 58,
|
||||
margin: const EdgeInsets.fromLTRB(10, 8, 10, 0),
|
||||
return SizedBox(
|
||||
height: 54,
|
||||
child: ListView.separated(
|
||||
scrollDirection: Axis.horizontal,
|
||||
itemCount: PlaceTrait.values.length,
|
||||
separatorBuilder: (_, _) => const SizedBox(width: 8),
|
||||
padding: const EdgeInsets.fromLTRB(68, 8, 12, 0),
|
||||
itemCount: traits.length,
|
||||
separatorBuilder: (_, _) => const SizedBox(width: 6),
|
||||
itemBuilder: (context, index) {
|
||||
final item = PlaceTrait.values[index];
|
||||
final item = traits[index];
|
||||
return ChoiceChip(
|
||||
avatar: Icon(item.icon, size: 17),
|
||||
label: Text(item.label),
|
||||
@@ -288,7 +344,9 @@ class _TraitBar extends ConsumerWidget {
|
||||
onSelected: (_) => controller.selectTrait(item),
|
||||
backgroundColor: const Color(0xFFFFFBF5),
|
||||
selectedColor: Theme.of(context).colorScheme.primaryContainer,
|
||||
padding: const EdgeInsets.symmetric(horizontal: 10, vertical: 10),
|
||||
side: BorderSide.none,
|
||||
shape: const StadiumBorder(),
|
||||
padding: const EdgeInsets.symmetric(horizontal: 10, vertical: 9),
|
||||
);
|
||||
},
|
||||
),
|
||||
|
||||
Reference in New Issue
Block a user