feat: unified 1..9 words session narrative, dice input before reveal, dedicated results screen, and clean session history grouping
This commit is contained in:
@@ -1,93 +1,124 @@
|
||||
class HistoryEntry {
|
||||
final String id;
|
||||
final DateTime timestamp;
|
||||
import 'dart:convert';
|
||||
import 'word_model.dart';
|
||||
|
||||
class SessionWord {
|
||||
final String word;
|
||||
final int sessionNumber;
|
||||
final String partOfSpeech;
|
||||
final String category;
|
||||
final String symbolicMeaning;
|
||||
final String readingType;
|
||||
final String? positionTitle;
|
||||
final String? question;
|
||||
final String? aiInterpretation;
|
||||
|
||||
const HistoryEntry({
|
||||
required this.id,
|
||||
required this.timestamp,
|
||||
const SessionWord({
|
||||
required this.word,
|
||||
required this.sessionNumber,
|
||||
required this.partOfSpeech,
|
||||
required this.category,
|
||||
required this.symbolicMeaning,
|
||||
this.readingType = 'Жребий',
|
||||
this.positionTitle,
|
||||
});
|
||||
|
||||
String get formattedSessionNumber => sessionNumber.toString().padLeft(3, '0');
|
||||
|
||||
Map<String, dynamic> toMap() => {
|
||||
'word': word,
|
||||
'sessionNumber': sessionNumber,
|
||||
'partOfSpeech': partOfSpeech,
|
||||
'category': category,
|
||||
'symbolicMeaning': symbolicMeaning,
|
||||
if (positionTitle != null) 'positionTitle': positionTitle,
|
||||
};
|
||||
|
||||
factory SessionWord.fromMap(Map<String, dynamic> map) => SessionWord(
|
||||
word: map['word'] as String? ?? '',
|
||||
sessionNumber: map['sessionNumber'] as int? ?? 0,
|
||||
partOfSpeech: map['partOfSpeech'] as String? ?? '',
|
||||
category: map['category'] as String? ?? '',
|
||||
symbolicMeaning: map['symbolicMeaning'] as String? ?? '',
|
||||
positionTitle: map['positionTitle'] as String?,
|
||||
);
|
||||
|
||||
factory SessionWord.fromWordItem(WordItem item, {String? positionTitle}) => SessionWord(
|
||||
word: item.word,
|
||||
sessionNumber: item.sessionNumber,
|
||||
partOfSpeech: item.partOfSpeech,
|
||||
category: item.category,
|
||||
symbolicMeaning: item.description,
|
||||
positionTitle: positionTitle,
|
||||
);
|
||||
}
|
||||
|
||||
class OracleSession {
|
||||
final String id;
|
||||
final DateTime timestamp;
|
||||
final String? question;
|
||||
final int wordsCount;
|
||||
final List<SessionWord> words;
|
||||
final String? aiInterpretation;
|
||||
|
||||
const OracleSession({
|
||||
required this.id,
|
||||
required this.timestamp,
|
||||
this.question,
|
||||
required this.wordsCount,
|
||||
required this.words,
|
||||
this.aiInterpretation,
|
||||
});
|
||||
|
||||
HistoryEntry copyWith({
|
||||
OracleSession copyWith({
|
||||
String? id,
|
||||
DateTime? timestamp,
|
||||
String? word,
|
||||
int? sessionNumber,
|
||||
String? partOfSpeech,
|
||||
String? symbolicMeaning,
|
||||
String? readingType,
|
||||
String? positionTitle,
|
||||
String? question,
|
||||
int? wordsCount,
|
||||
List<SessionWord>? words,
|
||||
String? aiInterpretation,
|
||||
}) {
|
||||
return HistoryEntry(
|
||||
return OracleSession(
|
||||
id: id ?? this.id,
|
||||
timestamp: timestamp ?? this.timestamp,
|
||||
word: word ?? this.word,
|
||||
sessionNumber: sessionNumber ?? this.sessionNumber,
|
||||
partOfSpeech: partOfSpeech ?? this.partOfSpeech,
|
||||
symbolicMeaning: symbolicMeaning ?? this.symbolicMeaning,
|
||||
readingType: readingType ?? this.readingType,
|
||||
positionTitle: positionTitle ?? this.positionTitle,
|
||||
question: question ?? this.question,
|
||||
wordsCount: wordsCount ?? this.wordsCount,
|
||||
words: words ?? this.words,
|
||||
aiInterpretation: aiInterpretation ?? this.aiInterpretation,
|
||||
);
|
||||
}
|
||||
|
||||
String get formattedSessionNumber => sessionNumber.toString().padLeft(3, '0');
|
||||
|
||||
String get formattedDate {
|
||||
final day = timestamp.day.toString().padLeft(2, '0');
|
||||
final month = timestamp.month.toString().padLeft(2, '0');
|
||||
final year = timestamp.year.toString();
|
||||
final hour = timestamp.hour.toString().padLeft(2, '0');
|
||||
final minute = timestamp.minute.toString().padLeft(2, '0');
|
||||
final second = timestamp.second.toString().padLeft(2, '0');
|
||||
return '$day.$month.$year $hour:$minute:$second';
|
||||
final min = timestamp.minute.toString().padLeft(2, '0');
|
||||
final sec = timestamp.second.toString().padLeft(2, '0');
|
||||
return '$day.$month.$year $hour:$min:$sec';
|
||||
}
|
||||
|
||||
Map<String, dynamic> toMap() {
|
||||
return {
|
||||
'id': id,
|
||||
'timestamp': timestamp.toIso8601String(),
|
||||
'word': word,
|
||||
'sessionNumber': sessionNumber,
|
||||
'partOfSpeech': partOfSpeech,
|
||||
'symbolicMeaning': symbolicMeaning,
|
||||
'readingType': readingType,
|
||||
'positionTitle': positionTitle,
|
||||
'question': question,
|
||||
'aiInterpretation': aiInterpretation,
|
||||
};
|
||||
}
|
||||
Map<String, dynamic> toMap() => {
|
||||
'id': id,
|
||||
'timestamp': timestamp.toIso8601String(),
|
||||
if (question != null) 'question': question,
|
||||
'wordsCount': wordsCount,
|
||||
'words': words.map((w) => w.toMap()).toList(),
|
||||
if (aiInterpretation != null) 'aiInterpretation': aiInterpretation,
|
||||
};
|
||||
|
||||
factory HistoryEntry.fromMap(Map<String, dynamic> map) {
|
||||
return HistoryEntry(
|
||||
id: map['id'] as String? ?? DateTime.now().millisecondsSinceEpoch.toString(),
|
||||
factory OracleSession.fromMap(Map<String, dynamic> map) {
|
||||
return OracleSession(
|
||||
id: map['id'] as String? ?? '',
|
||||
timestamp: DateTime.tryParse(map['timestamp'] as String? ?? '') ?? DateTime.now(),
|
||||
word: map['word'] as String? ?? '',
|
||||
sessionNumber: map['sessionNumber'] as int? ?? 0,
|
||||
partOfSpeech: map['partOfSpeech'] as String? ?? '',
|
||||
symbolicMeaning: map['symbolicMeaning'] as String? ?? '',
|
||||
readingType: map['readingType'] as String? ?? 'Жребий',
|
||||
positionTitle: map['positionTitle'] as String?,
|
||||
question: map['question'] as String?,
|
||||
wordsCount: map['wordsCount'] as int? ?? (map['words'] as List?)?.length ?? 1,
|
||||
words: (map['words'] as List<dynamic>?)
|
||||
?.map((item) => SessionWord.fromMap(item as Map<String, dynamic>))
|
||||
.toList() ??
|
||||
[],
|
||||
aiInterpretation: map['aiInterpretation'] as String?,
|
||||
);
|
||||
}
|
||||
|
||||
String toJson() => jsonEncode(toMap());
|
||||
factory OracleSession.fromJson(String source) => OracleSession.fromMap(jsonDecode(source));
|
||||
}
|
||||
|
||||
// Backward compatibility alias
|
||||
typedef HistoryEntry = OracleSession;
|
||||
|
||||
Reference in New Issue
Block a user