feat: complete academic symbol lexicon heal, 2-column Cooper extraction, and updated assets
This commit is contained in:
@@ -1,3 +1,4 @@
|
||||
import 'dart:math' as math;
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import '../models/history_entry_model.dart';
|
||||
@@ -7,6 +8,7 @@ import '../services/words_repository.dart';
|
||||
import '../widgets/cleromancy_dialog.dart';
|
||||
import '../widgets/d10_dice_roller_widget.dart';
|
||||
import '../widgets/gradient_star_badge.dart';
|
||||
import '../widgets/interpreter_persona_picker.dart';
|
||||
import 'session_result_screen.dart';
|
||||
|
||||
class HomeSearchScreen extends StatefulWidget {
|
||||
@@ -183,7 +185,7 @@ class _HomeSearchScreenState extends State<HomeSearchScreen> {
|
||||
});
|
||||
}
|
||||
|
||||
Future<void> _reshuffleMatrix() async {
|
||||
Future<void> _rollRandomCleromancy() async {
|
||||
HapticFeedback.heavyImpact();
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
const SnackBar(
|
||||
@@ -193,41 +195,67 @@ class _HomeSearchScreenState extends State<HomeSearchScreen> {
|
||||
SizedBox(width: 10),
|
||||
Expanded(
|
||||
child: Text(
|
||||
'Запрашиваю суточную матрицу у RANDOM.ORG…',
|
||||
'Бросаю священный жребий (3 × d10)…',
|
||||
style: TextStyle(fontWeight: FontWeight.w600),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
duration: Duration(seconds: 2),
|
||||
duration: Duration(milliseconds: 1000),
|
||||
behavior: SnackBarBehavior.floating,
|
||||
),
|
||||
);
|
||||
final source = await _repo.reshuffleSessionNumbers();
|
||||
if (!mounted) return;
|
||||
_resetSession();
|
||||
final viaOrg = source == RandomSource.randomOrg;
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
SnackBar(
|
||||
content: Row(
|
||||
children: [
|
||||
const GradientStar(size: 20),
|
||||
const SizedBox(width: 10),
|
||||
Expanded(
|
||||
child: Text(
|
||||
viaOrg
|
||||
? 'Матрица #000–#999 на сегодня задана RANDOM.ORG'
|
||||
: 'RANDOM.ORG недоступен — матрица собрана локально',
|
||||
style: const TextStyle(fontWeight: FontWeight.w600),
|
||||
|
||||
try {
|
||||
final randomService = TrueRandomService();
|
||||
final roll = await randomService.take(_wordsCount * 3);
|
||||
|
||||
if (!mounted) return;
|
||||
final newDigits = <String>[];
|
||||
for (int i = 0; i < _wordsCount; i++) {
|
||||
final chunk = roll.digits.sublist(i * 3, (i + 1) * 3);
|
||||
newDigits.add(chunk.join());
|
||||
}
|
||||
|
||||
setState(() {
|
||||
_wordsDigits = newDigits;
|
||||
_activeWordIndex = _wordsCount - 1;
|
||||
});
|
||||
|
||||
final viaOrg = roll.source == RandomSource.randomOrg;
|
||||
ScaffoldMessenger.of(context).hideCurrentSnackBar();
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
SnackBar(
|
||||
content: Row(
|
||||
children: [
|
||||
const GradientStar(size: 20),
|
||||
const SizedBox(width: 10),
|
||||
Expanded(
|
||||
child: Text(
|
||||
viaOrg
|
||||
? 'Выпал истинный жребий RANDOM.ORG (3 × d10)'
|
||||
: 'Выпал криптографический жребий (3 × d10)',
|
||||
style: const TextStyle(fontWeight: FontWeight.w600),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
],
|
||||
),
|
||||
duration: const Duration(seconds: 2),
|
||||
behavior: SnackBarBehavior.floating,
|
||||
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(12)),
|
||||
),
|
||||
duration: const Duration(seconds: 3),
|
||||
behavior: SnackBarBehavior.floating,
|
||||
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(12)),
|
||||
),
|
||||
);
|
||||
);
|
||||
} catch (_) {
|
||||
final rng = math.Random();
|
||||
if (!mounted) return;
|
||||
setState(() {
|
||||
_wordsDigits = List.generate(
|
||||
_wordsCount,
|
||||
(_) => List.generate(3, (_) => rng.nextInt(10)).join(),
|
||||
);
|
||||
_activeWordIndex = _wordsCount - 1;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
@@ -244,7 +272,7 @@ class _HomeSearchScreenState extends State<HomeSearchScreen> {
|
||||
GradientStar(size: 24),
|
||||
SizedBox(width: 10),
|
||||
Text(
|
||||
'Оракул 999',
|
||||
'Оракул',
|
||||
style: TextStyle(
|
||||
fontSize: 20,
|
||||
fontWeight: FontWeight.w900,
|
||||
@@ -265,9 +293,9 @@ class _HomeSearchScreenState extends State<HomeSearchScreen> {
|
||||
onPressed: _resetSession,
|
||||
),
|
||||
IconButton(
|
||||
tooltip: 'Новая суточная матрица через RANDOM.ORG',
|
||||
icon: const Icon(Icons.shuffle_rounded),
|
||||
onPressed: _reshuffleMatrix,
|
||||
tooltip: 'Бросить священный жребий (3 × d10)',
|
||||
icon: const Icon(Icons.casino_rounded, color: Color(0xFF64B5F6)),
|
||||
onPressed: _rollRandomCleromancy,
|
||||
),
|
||||
IconButton(
|
||||
tooltip: _showKeypad ? 'Скрыть панель' : 'Показать панель',
|
||||
@@ -284,6 +312,8 @@ class _HomeSearchScreenState extends State<HomeSearchScreen> {
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.stretch,
|
||||
children: [
|
||||
const InterpreterPersonaPicker(),
|
||||
const SizedBox(height: 12),
|
||||
// Row: Question & Words count selector (1..9)
|
||||
Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
@@ -499,20 +529,26 @@ class _HomeSearchScreenState extends State<HomeSearchScreen> {
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Row(
|
||||
children: [
|
||||
const Icon(Icons.casino_outlined, size: 15, color: Color(0xFFFFD54F)),
|
||||
const SizedBox(width: 6),
|
||||
Text(
|
||||
'Ввод граней (Слово ${_activeWordIndex + 1} из $_wordsCount):',
|
||||
style: const TextStyle(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w700,
|
||||
color: Color(0xFFFFD54F),
|
||||
Expanded(
|
||||
child: Row(
|
||||
children: [
|
||||
const Icon(Icons.casino_outlined, size: 15, color: Color(0xFFFFD54F)),
|
||||
const SizedBox(width: 6),
|
||||
Flexible(
|
||||
child: Text(
|
||||
'Ввод граней (Слово ${_activeWordIndex + 1} из $_wordsCount):',
|
||||
style: const TextStyle(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w700,
|
||||
color: Color(0xFFFFD54F),
|
||||
),
|
||||
overflow: TextOverflow.ellipsis,
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
],
|
||||
),
|
||||
),
|
||||
const SizedBox(width: 8),
|
||||
Text(
|
||||
currentActiveDigits.length == 3
|
||||
? 'Код: #$currentActiveDigits'
|
||||
|
||||
Reference in New Issue
Block a user