Files
flutter/lib/models/place_models.dart
Ruslan Bakiev fbf9104d2d
Some checks failed
Build and deploy Flutter Web / build (push) Failing after 14s
Add admin review debug screen
2026-05-14 08:44:20 +07:00

223 lines
5.9 KiB
Dart

import 'package:flutter/material.dart';
import 'package:latlong2/latlong.dart';
class AppUser {
const AppUser({
required this.id,
required this.telegramId,
required this.username,
required this.firstName,
required this.lastName,
required this.photoUrl,
required this.languageCode,
required this.isAdmin,
});
factory AppUser.fromJson(Map<String, dynamic> json) {
return AppUser(
id: json['id'] as String,
telegramId: json['telegramId'] as String,
username: json['username'] as String?,
firstName: json['firstName'] as String?,
lastName: json['lastName'] as String?,
photoUrl: json['photoUrl'] as String?,
languageCode: json['languageCode'] as String?,
isAdmin: json['isAdmin'] as bool? ?? false,
);
}
final String id;
final String telegramId;
final String? username;
final String? firstName;
final String? lastName;
final String? photoUrl;
final String? languageCode;
final bool isAdmin;
}
class VoiceExperienceDebug {
const VoiceExperienceDebug({
required this.id,
required this.placeName,
required this.userName,
required this.status,
required this.durationSeconds,
required this.transcript,
required this.analysis,
required this.createdAt,
});
factory VoiceExperienceDebug.fromJson(Map<String, dynamic> json) {
final place = json['place'] as Map<String, dynamic>;
final user = json['user'] as Map<String, dynamic>?;
final firstName = user?['firstName'] as String?;
final username = user?['username'] as String?;
final telegramId = user?['telegramId'] as String?;
return VoiceExperienceDebug(
id: json['id'] as String,
placeName: place['name'] as String,
userName: firstName?.trim().isNotEmpty == true
? firstName!
: username?.trim().isNotEmpty == true
? '@$username'
: telegramId ?? '',
status: json['status'] as String,
durationSeconds: json['durationSeconds'] as int,
transcript: json['transcript'] as String?,
analysis: json['analysis'] as Map<String, dynamic>?,
createdAt: DateTime.parse(json['createdAt'] as String),
);
}
final String id;
final String placeName;
final String userName;
final String status;
final int durationSeconds;
final String? transcript;
final Map<String, dynamic>? analysis;
final DateTime createdAt;
}
enum PlaceTrait {
calm,
dynamic,
intimate,
open,
solo,
group,
reset,
impress,
transit,
clean,
expressive,
}
extension PlaceTraitText on PlaceTrait {
String get label {
return switch (this) {
PlaceTrait.calm => 'спокойное',
PlaceTrait.dynamic => 'живое',
PlaceTrait.intimate => 'камерное',
PlaceTrait.open => 'открытое',
PlaceTrait.solo => 'для себя',
PlaceTrait.group => 'для компании',
PlaceTrait.reset => 'выдохнуть',
PlaceTrait.impress => 'впечатлить',
PlaceTrait.transit => 'транзитное',
PlaceTrait.clean => 'чистое',
PlaceTrait.expressive => 'выразительное',
};
}
IconData get icon {
return switch (this) {
PlaceTrait.calm => Icons.air_outlined,
PlaceTrait.dynamic => Icons.bolt_outlined,
PlaceTrait.intimate => Icons.lock_outline,
PlaceTrait.open => Icons.public_outlined,
PlaceTrait.solo => Icons.person_outline,
PlaceTrait.group => Icons.forum_outlined,
PlaceTrait.reset => Icons.spa_outlined,
PlaceTrait.impress => Icons.diamond_outlined,
PlaceTrait.transit => Icons.near_me_outlined,
PlaceTrait.clean => Icons.wb_sunny_outlined,
PlaceTrait.expressive => Icons.auto_awesome_outlined,
};
}
}
class PlaceRecommendation {
const PlaceRecommendation({
required this.id,
required this.googlePlaceId,
required this.name,
required this.area,
required this.photoUrls,
required this.coordinate,
required this.traits,
required this.googlePrimaryType,
required this.googleTypes,
});
final String id;
final String googlePlaceId;
final String name;
final String area;
final List<String> photoUrls;
final LatLng coordinate;
final Set<PlaceTrait> traits;
final String? googlePrimaryType;
final List<String> googleTypes;
String get coverPhotoUrl => photoUrls.first;
}
class VoiceReviewDraft {
const VoiceReviewDraft({
required this.placeName,
required this.duration,
required this.extractedTraits,
required this.evidence,
});
final String placeName;
final Duration duration;
final Set<PlaceTrait> extractedTraits;
final List<String> evidence;
bool get isLongEnough => duration.inSeconds >= 30;
VoiceReviewDraft copyWith({
String? placeName,
Duration? duration,
Set<PlaceTrait>? extractedTraits,
List<String>? evidence,
}) {
return VoiceReviewDraft(
placeName: placeName ?? this.placeName,
duration: duration ?? this.duration,
extractedTraits: extractedTraits ?? this.extractedTraits,
evidence: evidence ?? this.evidence,
);
}
}
class TelegramBotLogin {
const TelegramBotLogin({
required this.token,
required this.botUrl,
required this.expiresAt,
});
factory TelegramBotLogin.fromJson(Map<String, dynamic> json) {
return TelegramBotLogin(
token: json['token'] as String,
botUrl: json['botUrl'] as String,
expiresAt: DateTime.parse(json['expiresAt'] as String),
);
}
final String token;
final String botUrl;
final DateTime expiresAt;
}
class TelegramBotLoginSession {
const TelegramBotLoginSession({
required this.sessionToken,
required this.user,
});
factory TelegramBotLoginSession.fromJson(Map<String, dynamic> json) {
return TelegramBotLoginSession(
sessionToken: json['sessionToken'] as String,
user: AppUser.fromJson(json['user'] as Map<String, dynamic>),
);
}
final String sessionToken;
final AppUser user;
}