Use ontology traits in map UI
All checks were successful
Build and deploy Flutter Web / build (push) Successful in 3m17s

This commit is contained in:
Ruslan Bakiev
2026-05-08 16:22:36 +07:00
parent 238521b11b
commit 277888c407
4 changed files with 47 additions and 123 deletions

View File

@@ -9,23 +9,22 @@ final placeControllerProvider =
class PlaceState {
const PlaceState({
required this.intent,
required this.selectedTrait,
required this.places,
required this.selectedPlaceId,
required this.reviewDraft,
});
final UserIntent intent;
final PlaceTrait selectedTrait;
final List<PlaceRecommendation> places;
final String? selectedPlaceId;
final VoiceReviewDraft reviewDraft;
List<PlaceRecommendation> get recommendations {
final wanted = intent.traits;
final ranked = [...places]
..sort((a, b) {
final aScore = a.traits.intersection(wanted).length;
final bScore = b.traits.intersection(wanted).length;
final aScore = a.traits.contains(selectedTrait) ? 1 : 0;
final bScore = b.traits.contains(selectedTrait) ? 1 : 0;
return bScore.compareTo(aScore);
});
return ranked.take(4).toList();
@@ -41,13 +40,13 @@ class PlaceState {
}
PlaceState copyWith({
UserIntent? intent,
PlaceTrait? selectedTrait,
List<PlaceRecommendation>? places,
String? selectedPlaceId,
VoiceReviewDraft? reviewDraft,
}) {
return PlaceState(
intent: intent ?? this.intent,
selectedTrait: selectedTrait ?? this.selectedTrait,
places: places ?? this.places,
selectedPlaceId: selectedPlaceId ?? this.selectedPlaceId,
reviewDraft: reviewDraft ?? this.reviewDraft,
@@ -62,30 +61,29 @@ class PlaceController extends AsyncNotifier<PlaceState> {
Future<PlaceState> build() async {
final places = await _api.fetchPlaces();
return PlaceState(
intent: UserIntent.exhale,
selectedTrait: PlaceTrait.calm,
places: places,
selectedPlaceId: places.isEmpty ? null : places.first.id,
reviewDraft: const VoiceReviewDraft(
placeName: '',
duration: Duration.zero,
extractedTraits: {},
suggestedIntents: {},
evidence: [],
),
);
}
void selectIntent(UserIntent intent) {
void selectTrait(PlaceTrait trait) {
final value = state.requireValue;
PlaceRecommendation? next;
for (final place in value.places) {
if (place.traits.intersection(intent.traits).isNotEmpty) {
if (place.traits.contains(trait)) {
next = place;
break;
}
}
state = AsyncData(
value.copyWith(intent: intent, selectedPlaceId: next?.id),
value.copyWith(selectedTrait: trait, selectedPlaceId: next?.id),
);
}
@@ -138,7 +136,6 @@ class PlaceController extends AsyncNotifier<PlaceState> {
placeName: '',
duration: Duration.zero,
extractedTraits: {},
suggestedIntents: {},
evidence: [],
),
),