import 'package:flutter/material.dart'; import 'package:latlong2/latlong.dart'; enum PlaceTrait { calm, alive, cozy, cold, status, simple, free, formal, private, open, social, solo, beautiful, neutral, unusual, clear, focused, transit, } extension PlaceTraitText on PlaceTrait { String get label { return switch (this) { PlaceTrait.calm => 'спокойное', PlaceTrait.alive => 'живое', PlaceTrait.cozy => 'уютное', PlaceTrait.cold => 'холодное', PlaceTrait.status => 'статусное', PlaceTrait.simple => 'простое', PlaceTrait.free => 'свободное', PlaceTrait.formal => 'формальное', PlaceTrait.private => 'приватное', PlaceTrait.open => 'открытое', PlaceTrait.social => 'для общения', PlaceTrait.solo => 'для себя', PlaceTrait.beautiful => 'красивое', PlaceTrait.neutral => 'нейтральное', PlaceTrait.unusual => 'необычное', PlaceTrait.clear => 'понятное', PlaceTrait.focused => 'помогает собраться', PlaceTrait.transit => 'транзитное', }; } } enum UserIntent { exhale, date, meet, focus, move, surprise, alone, impress } extension UserIntentText on UserIntent { String get title { return switch (this) { UserIntent.exhale => 'выдохнуть', UserIntent.date => 'свидание', UserIntent.meet => 'встретиться', UserIntent.focus => 'поработать', UserIntent.move => 'движ', UserIntent.surprise => 'удивиться', UserIntent.alone => 'побыть одному', UserIntent.impress => 'привести кого-то', }; } String get subtitle { return switch (this) { UserIntent.exhale => 'тихо, мягко, без давления', UserIntent.date => 'красиво и лично', UserIntent.meet => 'общение без лишней формальности', UserIntent.focus => 'собраться и не выпадать', UserIntent.move => 'живо, шумно, с энергией', UserIntent.surprise => 'не как обычно', UserIntent.alone => 'быть в своем ритме', UserIntent.impress => 'место должно держать момент', }; } IconData get icon { return switch (this) { UserIntent.exhale => Icons.air_outlined, UserIntent.date => Icons.favorite_border, UserIntent.meet => Icons.forum_outlined, UserIntent.focus => Icons.center_focus_strong_outlined, UserIntent.move => Icons.bolt_outlined, UserIntent.surprise => Icons.auto_awesome_outlined, UserIntent.alone => Icons.person_outline, UserIntent.impress => Icons.diamond_outlined, }; } Set get traits { return switch (this) { UserIntent.exhale => {PlaceTrait.calm, PlaceTrait.cozy, PlaceTrait.solo}, UserIntent.date => { PlaceTrait.private, PlaceTrait.beautiful, PlaceTrait.social, }, UserIntent.meet => {PlaceTrait.social, PlaceTrait.free, PlaceTrait.alive}, UserIntent.focus => { PlaceTrait.focused, PlaceTrait.calm, PlaceTrait.neutral, }, UserIntent.move => {PlaceTrait.alive, PlaceTrait.open, PlaceTrait.social}, UserIntent.surprise => { PlaceTrait.unusual, PlaceTrait.alive, PlaceTrait.open, }, UserIntent.alone => {PlaceTrait.solo, PlaceTrait.free, PlaceTrait.calm}, UserIntent.impress => { PlaceTrait.status, PlaceTrait.beautiful, PlaceTrait.private, }, }; } } class PlaceRecommendation { const PlaceRecommendation({ required this.id, required this.name, required this.area, required this.photoUrls, required this.coordinate, required this.traits, }); final String id; final String name; final String area; final List photoUrls; final LatLng coordinate; final Set traits; String get coverPhotoUrl => photoUrls.first; } class VoiceReviewDraft { const VoiceReviewDraft({ required this.placeName, required this.duration, required this.extractedTraits, required this.suggestedIntents, required this.evidence, }); final String placeName; final Duration duration; final Set extractedTraits; final Set suggestedIntents; final List evidence; bool get isLongEnough => duration.inSeconds >= 30; VoiceReviewDraft copyWith({ String? placeName, Duration? duration, Set? extractedTraits, Set? suggestedIntents, List? evidence, }) { return VoiceReviewDraft( placeName: placeName ?? this.placeName, duration: duration ?? this.duration, extractedTraits: extractedTraits ?? this.extractedTraits, suggestedIntents: suggestedIntents ?? this.suggestedIntents, evidence: evidence ?? this.evidence, ); } }