feat: complete academic symbol lexicon heal, 2-column Cooper extraction, and updated assets

This commit is contained in:
2026-10-09 15:26:58 +05:00
parent 7f91366201
commit 0b12e4583b
244 changed files with 611461 additions and 1617 deletions
+964
View File
@@ -0,0 +1,964 @@
import '../models/syncretic_session_model.dart';
import '../services/words_repository.dart';
import '../models/history_entry_model.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import '../models/houses_session_model.dart';
import '../models/word_model.dart';
import '../services/ai_oracle_service.dart';
import '../widgets/gradient_star_badge.dart';
import 'house_chains_screen.dart';
import 'matrix_geometry_screen.dart';
import '../services/oracle_master_prompt_generator.dart';
import 'symbol_detail_screen.dart';
class HousesResultScreen extends StatefulWidget {
final HousesSession session;
const HousesResultScreen({super.key, required this.session});
@override
State<HousesResultScreen> createState() => _HousesResultScreenState();
}
class _HousesResultScreenState extends State<HousesResultScreen> {
final _aiService = AiOracleService();
String? _aiInterpretation;
bool _isLoadingAi = false;
@override
void initState() {
super.initState();
// Auto-record Houses Session into active Syncretic Day Session
final session = widget.session;
final items = session.selectedHouses.map((h) {
final g = h.guestWord ?? h.houseWord;
return ReadingSignItem(
title: 'Дом #${(h.houseIndex + 1).toString().padLeft(3, "0")} «${g.word.toUpperCase()}»',
subtitle: 'Архонт: ${session.sectors[h.sectorIndex].archonWord.word}',
symbol: '🏛️',
lore: g.core.isNotEmpty ? g.core : g.description,
linkedWord: g,
);
}).toList();
WordsRepository().addReadingToSyncreticSession(
SyncreticReading(
id: 'reading_${session.id}',
systemId: 'matrix',
systemName: 'Матрица 33×30 (Дома)',
systemIcon: '🏛️',
timestamp: session.createdAt,
layoutTitle: '${items.length} ${items.length == 1 ? "дом" : "домов"}',
inputMethod: 'dice',
items: items,
question: session.question,
),
question: session.question,
);
// Auto-record Calculated House Chains into active Syncretic Day Session
if (session.chains.isNotEmpty) {
final chainItems = session.chains.map((chain) {
final pathStr = chain.steps.map((s) => '«${s.guest.word.toUpperCase()}»').join(' ➔ ');
final startWord = chain.startingHouse.houseWord;
return ReadingSignItem(
title: 'Цепочка #${chain.chainIndex}: ${chain.endTypeTitle}',
subtitle: 'Старт: Дом #${chain.startingHouse.houseIndex + 1} «${startWord.word}» • Шагов: ${chain.steps.length}',
symbol: chain.hasLoop ? '🔄' : (chain.endType == ChainEndType.archonThrone ? '👑' : '🔗'),
lore: 'Траектория: ' + pathStr + '\n' + chain.description,
linkedWord: chain.steps.isNotEmpty ? chain.steps.last.guest : startWord,
meta: {
'chainIndex': chain.chainIndex,
'endType': chain.endType.name,
'stepsCount': chain.steps.length,
'path': pathStr,
},
);
}).toList();
WordsRepository().addReadingToSyncreticSession(
SyncreticReading(
id: 'chains_${session.id}',
systemId: 'matrix_chains',
systemName: 'Матрица 33×30: Цепочки Домов',
systemIcon: '🔗',
timestamp: session.createdAt,
layoutTitle: '${session.chains.length} ${session.chains.length == 1 ? "цепочка" : (session.chains.length < 5 ? "цепочки" : "цепочек")}',
inputMethod: 'dice',
items: chainItems,
question: session.question,
),
question: session.question,
);
}
_aiInterpretation = widget.session.aiInterpretation;
}
Future<void> _requestAiInterpretation() async {
setState(() => _isLoadingAi = true);
HapticFeedback.lightImpact();
final buffer = StringBuffer();
buffer.writeln('Ты — верховный оракул, читающий расклад Домов 33×30 в традиции Оракула 999.');
buffer.writeln('В раскладе участвуют 3 уровня реальности:');
buffer.writeln('1. Небесный Архонт Сектора — высший закон и климат триады столбцов.');
buffer.writeln('2. Земной Дом — конкретная сфера и почва действия.');
buffer.writeln('3. Знак-Гость — сила, прибывшая в дом по жребию.\n');
buffer.writeln('ПОСЛЕДОВАТЕЛЬНОСТЬ ОТКРЫТЫХ ДОМОВ:');
for (int i = 0; i < widget.session.selectedHouses.length; i++) {
final h = widget.session.selectedHouses[i];
final sector = widget.session.sectors[h.sectorIndex];
final guest = h.guestWord!;
buffer.writeln(
'Позиция ${i + 1}: Архонт «${sector.archonWord.word.toUpperCase()}» ➔ Дом «${h.houseWord.word.toUpperCase()}» ➔ Гость «${guest.word.toUpperCase()}»',
);
if (guest.core.isNotEmpty) {
buffer.writeln(' Суть гостя: ${guest.core}');
}
}
if (widget.session.chains.isNotEmpty) {
buffer.writeln('\nЦЕПОЧКИ ДОМОВ:');
for (final c in widget.session.chains) {
buffer.writeln('• Цепочка #${c.chainIndex} (${c.hasLoop ? "петля" : "вектор"}): ${c.description}');
}
}
buffer.writeln('\nДай развернутое, цельное толкование расклада: как разворачивается путь от первого шага к исходу, как гости чувствуют себя в домах под властью своих Архонтов, и какой главный совет даёт оракул.');
try {
final res = await _aiService.interpretSession(
words: widget.session.selectedHouses
.map((h) => SessionWord.fromWordItem(
h.guestWord!,
positionTitle: 'Дом #${h.houseIndex + 1} «${h.houseWord.word}»',
))
.toList(),
question: widget.session.question ?? 'Расклад Домов 33×30',
);
if (mounted) {
setState(() {
_aiInterpretation = res;
_isLoadingAi = false;
});
}
} catch (e) {
if (mounted) {
setState(() {
_aiInterpretation = 'Ошибка связи с оракулом: $e';
_isLoadingAi = false;
});
}
}
}
void _openWordDossier(WordItem word) {
HapticFeedback.selectionClick();
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => SymbolDetailScreen(word: word),
),
);
}
void _copyAll() {
final buffer = StringBuffer();
buffer.writeln('🔮 ОРАКУЛ — РАСКЛАД ДОМОВ 33×30');
if (widget.session.question != null && widget.session.question!.isNotEmpty) {
buffer.writeln('Вопрос: «${widget.session.question}»');
}
buffer.writeln('Открыто домов: ${widget.session.selectedHouses.length}\n');
for (int i = 0; i < widget.session.selectedHouses.length; i++) {
final h = widget.session.selectedHouses[i];
final sector = widget.session.sectors[h.sectorIndex];
final guest = h.guestWord!;
buffer.writeln(
'#${i + 1} [Сектор: Архонт ${sector.archonWord.word.toUpperCase()}]',
);
buffer.writeln(' 🏛️ Дом #${(h.houseIndex + 1).toString().padLeft(3, '0')} «${h.houseWord.word.toUpperCase()}»');
buffer.writeln(' ✨ Гость: «${guest.word.toUpperCase()}»');
if (guest.core.isNotEmpty) {
buffer.writeln(' Закон: ${guest.core}');
}
buffer.writeln();
}
if (_aiInterpretation != null) {
buffer.writeln('🤖 Толкование Оракула:\n$_aiInterpretation\n');
}
Clipboard.setData(ClipboardData(text: buffer.toString()));
HapticFeedback.mediumImpact();
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(
content: Text('Полный расклад домов скопирован в буфер'),
behavior: SnackBarBehavior.floating,
),
);
}
@override
Widget build(BuildContext context) {
final session = widget.session;
final activeSectorIndices = session.selectedHouses.map((h) => h.sectorIndex).toSet();
return Scaffold(
backgroundColor: const Color(0xFF0A0C16),
appBar: AppBar(
title: const Row(
children: [
GradientStar(size: 20),
SizedBox(width: 8),
Text('Расклад Домов 33×30', style: TextStyle(fontWeight: FontWeight.bold, fontSize: 17)),
],
),
actions: [
IconButton(
tooltip: 'Цепочки Домов',
icon: Badge(
label: Text('${session.chains.length}'),
backgroundColor: const Color(0xFFFFD54F),
textColor: Colors.black,
child: const Icon(Icons.hub_outlined, color: Color(0xFFFFD54F)),
),
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => HouseChainsScreen(session: session),
),
);
},
),
IconButton(
tooltip: 'Узоры Матрицы 33×30',
icon: const Icon(Icons.auto_awesome_mosaic_rounded, color: Color(0xFFFFD54F)),
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => MatrixGeometryScreen(session: session),
),
);
},
),
IconButton(
tooltip: 'Скопировать расклад',
icon: const Icon(Icons.copy_rounded),
onPressed: _copyAll,
),
],
),
body: ListView(
padding: const EdgeInsets.fromLTRB(16, 12, 16, 40),
children: [
// Querent (Significator) Card
_buildQuerentSection(session),
const SizedBox(height: 16),
// Revealed Archons Banner
_buildArchonsRevealSection(activeSectorIndices),
const SizedBox(height: 16),
// Houses sequence header
Row(
children: [
const Icon(Icons.format_list_numbered_rounded, color: Color(0xFFFFD54F), size: 18),
const SizedBox(width: 8),
Text(
'ПОСЛЕДОВАТЕЛЬНОСТЬ ДОМОВ (${session.selectedHouses.length}):',
style: const TextStyle(
color: Color(0xFFFFD54F),
fontWeight: FontWeight.w900,
fontSize: 13,
letterSpacing: 0.8,
),
),
],
),
const SizedBox(height: 12),
// Houses Cards
for (int i = 0; i < session.selectedHouses.length; i++) ...[
_buildHouseStepCard(session.selectedHouses[i], i + 1),
const SizedBox(height: 12),
],
const SizedBox(height: 12),
// 1. Master Prompt for Advanced LLMs (Grok / Claude / Gemini / GPT-4)
ElevatedButton.icon(
style: ElevatedButton.styleFrom(
backgroundColor: const Color(0xFF261D48),
foregroundColor: const Color(0xFFFFD54F),
padding: const EdgeInsets.symmetric(vertical: 14),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(16),
side: const BorderSide(color: Color(0xFFFFD54F), width: 1.4),
),
elevation: 6,
shadowColor: const Color(0x66FFD54F),
),
onPressed: () => _showMasterPromptDialog(context, session),
icon: const Icon(Icons.psychology_alt_rounded, color: Color(0xFFFFD54F), size: 22),
label: const Text(
'🧠 Мастер-Промпт для Нейросети (Grok / Claude / Gemini)',
style: TextStyle(fontWeight: FontWeight.w900, fontSize: 13.5, letterSpacing: 0.3),
),
),
const SizedBox(height: 12),
// 2. Matrix Geometry & Constellation Pattern
ElevatedButton.icon(
style: ElevatedButton.styleFrom(
backgroundColor: const Color(0xFF19203C),
foregroundColor: const Color(0xFF00E5FF),
padding: const EdgeInsets.symmetric(vertical: 14),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(16),
side: const BorderSide(color: Color(0xFF00E5FF), width: 1.2),
),
elevation: 4,
),
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => MatrixGeometryScreen(session: session),
),
);
},
icon: const Icon(Icons.auto_awesome_mosaic_rounded, color: Color(0xFF00E5FF)),
label: Text(
'Узор на Матрице 33×30 (${session.selectedHouses.length} узлов)',
style: const TextStyle(fontWeight: FontWeight.bold, fontSize: 14.5),
),
),
const SizedBox(height: 12),
// Action Button: House Chains Explorer
ElevatedButton.icon(
style: ElevatedButton.styleFrom(
backgroundColor: const Color(0xFF1E2238),
foregroundColor: const Color(0xFFFFD54F),
padding: const EdgeInsets.symmetric(vertical: 14),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(16),
side: const BorderSide(color: Color(0xFFFFD54F), width: 1.2),
),
),
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => HouseChainsScreen(session: session),
),
);
},
icon: const Icon(Icons.hub_outlined, color: Color(0xFFFFD54F)),
label: Text(
'Исследовать Цепочки Домов (${session.chains.length})',
style: const TextStyle(fontWeight: FontWeight.bold, fontSize: 15),
),
),
const SizedBox(height: 16),
// AI Interpretation Section
_buildAiSection(),
],
),
);
}
Widget _buildArchonsRevealSection(Set<int> activeSectors) {
return Container(
padding: const EdgeInsets.all(16),
decoration: BoxDecoration(
color: const Color(0xFF131627),
borderRadius: BorderRadius.circular(20),
border: Border.all(color: const Color(0xFF3949AB).withValues(alpha: 0.4)),
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
const Row(
children: [
Icon(Icons.shield_moon_rounded, color: Color(0xFFFFD54F), size: 20),
SizedBox(width: 8),
Text(
'АРХОНТЫ АКТИВНЫХ СЕКТОРОВ',
style: TextStyle(
color: Color(0xFFFFF9C4),
fontWeight: FontWeight.w900,
fontSize: 13,
letterSpacing: 0.8,
),
),
],
),
const SizedBox(height: 10),
Wrap(
spacing: 8,
runSpacing: 8,
children: activeSectors.map((sectorIdx) {
final sector = widget.session.sectors[sectorIdx];
return InkWell(
onTap: () => _openWordDossier(sector.archonWord),
borderRadius: BorderRadius.circular(10),
child: Container(
padding: const EdgeInsets.symmetric(horizontal: 10, vertical: 6),
decoration: BoxDecoration(
color: sector.sectorColor.withValues(alpha: 0.18),
borderRadius: BorderRadius.circular(10),
border: Border.all(color: sector.sectorColor, width: 1.2),
),
child: Row(
mainAxisSize: MainAxisSize.min,
children: [
Container(
width: 8,
height: 8,
decoration: BoxDecoration(
color: sector.sectorColor,
shape: BoxShape.circle,
),
),
const SizedBox(width: 6),
Text(
'Триада ${sectorIdx + 1}: «${sector.archonWord.word.toUpperCase()}»',
style: TextStyle(
color: sector.sectorColor,
fontWeight: FontWeight.bold,
fontSize: 12,
),
),
],
),
),
);
}).toList(),
),
],
),
);
}
Widget _buildHouseStepCard(HouseCell cell, int order) {
final sector = widget.session.sectors[cell.sectorIndex];
final guest = cell.guestWord!;
return Container(
padding: const EdgeInsets.all(16),
decoration: BoxDecoration(
color: const Color(0xFF141729),
borderRadius: BorderRadius.circular(20),
border: Border.all(color: sector.sectorColor.withValues(alpha: 0.4), width: 1.2),
boxShadow: [
BoxShadow(
color: Colors.black.withValues(alpha: 0.25),
blurRadius: 10,
offset: const Offset(0, 4),
),
],
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
// Header: Order, Archon triad
Row(
children: [
Container(
width: 26,
height: 26,
decoration: BoxDecoration(
color: const Color(0xFFFFD54F),
borderRadius: BorderRadius.circular(8),
),
child: Center(
child: Text(
'$order',
style: const TextStyle(
color: Colors.black,
fontWeight: FontWeight.w900,
fontSize: 14,
),
),
),
),
const SizedBox(width: 10),
Expanded(
child: Row(
children: [
Container(
width: 8,
height: 8,
decoration: BoxDecoration(
color: sector.sectorColor,
shape: BoxShape.circle,
),
),
const SizedBox(width: 6),
Text(
'Под властью Архонта «${sector.archonWord.word.toUpperCase()}» (Триада ${cell.sectorIndex + 1})',
style: TextStyle(
color: sector.sectorColor,
fontSize: 12,
fontWeight: FontWeight.bold,
),
),
],
),
),
],
),
const SizedBox(height: 12),
// Host & Guest Banner
Container(
padding: const EdgeInsets.all(12),
decoration: BoxDecoration(
color: const Color(0xFF1C2038),
borderRadius: BorderRadius.circular(14),
border: Border.all(color: const Color(0xFF2A2D4A)),
),
child: Column(
children: [
// Host row
InkWell(
onTap: () => _openWordDossier(cell.houseWord),
child: Row(
children: [
const Icon(Icons.home_work_rounded, color: Color(0xFF90A4AE), size: 18),
const SizedBox(width: 8),
Text(
'Дом #${(cell.houseIndex + 1).toString().padLeft(3, '0')}:',
style: const TextStyle(color: Color(0xFF90A4AE), fontSize: 13),
),
const SizedBox(width: 6),
Text(
cell.houseWord.word.toUpperCase(),
style: const TextStyle(
color: Colors.white,
fontWeight: FontWeight.w900,
fontSize: 15,
),
),
const Spacer(),
const Icon(Icons.arrow_forward_ios_rounded, size: 12, color: Color(0xFF5C6280)),
],
),
),
const Divider(color: Color(0xFF2A2D4A), height: 16),
// Guest row
InkWell(
onTap: () => _openWordDossier(guest),
child: Row(
children: [
const Icon(Icons.auto_awesome_rounded, color: Color(0xFFFFD54F), size: 18),
const SizedBox(width: 8),
const Text(
'Пришедший Гость:',
style: TextStyle(color: Color(0xFFFFD54F), fontSize: 13, fontWeight: FontWeight.w600),
),
const SizedBox(width: 6),
Text(
guest.word.toUpperCase(),
style: const TextStyle(
color: Color(0xFFFFF9C4),
fontWeight: FontWeight.w900,
fontSize: 16,
letterSpacing: 0.5,
),
),
const Spacer(),
const Icon(Icons.arrow_forward_ios_rounded, size: 12, color: Color(0xFFFFD54F)),
],
),
),
],
),
),
const SizedBox(height: 12),
// Guest Core / Meaning
if (guest.core.isNotEmpty) ...[
Text(
'✨ Закон знака: ${guest.core}',
style: const TextStyle(
color: Color(0xFFE0E0E0),
fontSize: 13,
height: 1.4,
),
),
const SizedBox(height: 8),
],
if (guest.oracle.isNotEmpty) ...[
Text(
guest.oracle,
maxLines: 3,
overflow: TextOverflow.ellipsis,
style: const TextStyle(
color: Color(0xFFB0BEC5),
fontSize: 12,
height: 1.35,
),
),
],
],
),
);
}
Widget _buildAiSection() {
return Container(
padding: const EdgeInsets.all(16),
decoration: BoxDecoration(
color: const Color(0xFF151829),
borderRadius: BorderRadius.circular(20),
border: Border.all(color: const Color(0xFFFFD54F).withValues(alpha: 0.4)),
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
children: [
const GradientStar(size: 20),
const SizedBox(width: 8),
const Text(
'Толкование Оракула (AI)',
style: TextStyle(
color: Color(0xFFFFF9C4),
fontWeight: FontWeight.bold,
fontSize: 15,
),
),
const Spacer(),
if (!_isLoadingAi)
IconButton(
tooltip: 'Запросить толкование',
icon: const Icon(Icons.auto_awesome, color: Color(0xFFFFD54F)),
onPressed: _requestAiInterpretation,
),
],
),
const SizedBox(height: 10),
if (_isLoadingAi) ...[
const Center(
child: Padding(
padding: EdgeInsets.symmetric(vertical: 24),
child: Column(
children: [
CircularProgressIndicator(color: Color(0xFFFFD54F)),
SizedBox(height: 12),
Text('Оракул синтезирует Архонтов, Дома и Цепочки...', style: TextStyle(color: Color(0xFF90A4AE), fontSize: 13)),
],
),
),
),
] else if (_aiInterpretation != null) ...[
Text(
_aiInterpretation!,
style: const TextStyle(color: Color(0xFFECEFF1), fontSize: 14, height: 1.5),
),
] else ...[
const Text(
'Нажмите кнопку ниже, чтобы нейросеть Оракула соединила энергии 10 Архонтов, открытых Домов и Цепочек судьбы в единое предсказание.',
style: TextStyle(color: Color(0xFF90A4AE), fontSize: 13, height: 1.4),
),
const SizedBox(height: 14),
ElevatedButton.icon(
style: ElevatedButton.styleFrom(
backgroundColor: const Color(0xFF2A2D4A),
foregroundColor: const Color(0xFFFFD54F),
minimumSize: const Size.fromHeight(44),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(14),
side: const BorderSide(color: Color(0xFFFFD54F), width: 0.8),
),
),
onPressed: _requestAiInterpretation,
icon: const Icon(Icons.auto_awesome_rounded),
label: const Text('Получить толкование Оракула'),
),
],
],
),
);
}
Widget _buildQuerentSection(HousesSession session) {
final q = session.querentWord;
return Container(
padding: const EdgeInsets.all(16),
decoration: BoxDecoration(
gradient: const LinearGradient(
colors: [Color(0xFF2A164D), Color(0xFF161933)],
begin: Alignment.topLeft,
end: Alignment.bottomRight,
),
borderRadius: BorderRadius.circular(20),
border: Border.all(color: const Color(0xFFFFD54F), width: 1.5),
boxShadow: const [
BoxShadow(
color: Color(0x55FFD54F),
blurRadius: 16,
offset: Offset(0, 4),
),
],
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
children: [
Container(
padding: const EdgeInsets.all(8),
decoration: BoxDecoration(
shape: BoxShape.circle,
color: const Color(0xFFFFD54F).withValues(alpha: 0.18),
border: Border.all(color: const Color(0xFFFFD54F), width: 1.2),
),
child: const Icon(Icons.workspace_premium_rounded, color: Color(0xFFFFD54F), size: 20),
),
const SizedBox(width: 10),
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
const Text(
'КВЕРЕНТ / СИГНИФИКАТОР РАСКЛАДА',
style: TextStyle(
color: Color(0xFFFFD54F),
fontSize: 10.5,
fontWeight: FontWeight.w900,
letterSpacing: 1.0,
),
),
const SizedBox(height: 2),
Text(
q != null ? q.word.toUpperCase() : 'ОТКРЫТЫЙ ФОКУС',
style: const TextStyle(
color: Colors.white,
fontSize: 18,
fontWeight: FontWeight.bold,
letterSpacing: 0.5,
),
),
],
),
),
if (session.querentHouseIndex != null)
Container(
padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 4),
decoration: BoxDecoration(
color: const Color(0xFF3B246B),
borderRadius: BorderRadius.circular(10),
border: Border.all(color: const Color(0xFFFFD54F), width: 0.8),
),
child: Text(
'Дом #${(session.querentHouseIndex! + 1).toString().padLeft(3, "0")}',
style: const TextStyle(color: Color(0xFFFFD54F), fontSize: 11, fontWeight: FontWeight.bold),
),
),
],
),
if (q != null) ...[
const SizedBox(height: 10),
if (q.core.isNotEmpty) ...[
Text(
'Суть объекта: ${q.core}',
style: const TextStyle(color: Color(0xFFCFD8DC), fontSize: 13, height: 1.4),
),
const SizedBox(height: 4),
],
Row(
children: [
Container(
padding: const EdgeInsets.symmetric(horizontal: 6, vertical: 2),
decoration: BoxDecoration(
color: Colors.white.withValues(alpha: 0.08),
borderRadius: BorderRadius.circular(6),
),
child: Text(
q.category,
style: const TextStyle(color: Color(0xFF9FA8DA), fontSize: 10.5),
),
),
const SizedBox(width: 8),
Text(
q.partOfSpeech,
style: const TextStyle(color: Color(0xFF78909C), fontSize: 11, fontStyle: FontStyle.italic),
),
],
),
],
if (session.question != null && session.question!.trim().isNotEmpty) ...[
const SizedBox(height: 10),
Container(
padding: const EdgeInsets.all(10),
decoration: BoxDecoration(
color: const Color(0xFF101323),
borderRadius: BorderRadius.circular(12),
border: Border.all(color: const Color(0xFF33385C), width: 0.8),
),
child: Row(
children: [
const Icon(Icons.help_outline_rounded, size: 16, color: Color(0xFFFFD54F)),
const SizedBox(width: 8),
Expanded(
child: Text(
'Вопрос: «${session.question!.trim()}»',
style: const TextStyle(color: Color(0xFFFFF9C4), fontSize: 12.5, fontWeight: FontWeight.w500),
),
),
],
),
),
],
],
),
);
}
void _showMasterPromptDialog(BuildContext context, HousesSession session) {
HapticFeedback.mediumImpact();
final prompt = OracleMasterPromptGenerator.generate(session);
showModalBottomSheet(
context: context,
isScrollControlled: true,
backgroundColor: const Color(0xFF0F1222),
shape: const RoundedRectangleBorder(
borderRadius: BorderRadius.vertical(top: Radius.circular(24)),
),
builder: (ctx) {
return DraggableScrollableSheet(
initialChildSize: 0.85,
minChildSize: 0.5,
maxChildSize: 0.95,
expand: false,
builder: (context, scrollController) {
return Container(
padding: const EdgeInsets.fromLTRB(20, 12, 20, 20),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Center(
child: Container(
width: 44,
height: 4,
decoration: BoxDecoration(
color: Colors.white24,
borderRadius: BorderRadius.circular(2),
),
),
),
const SizedBox(height: 14),
Row(
children: [
const Icon(Icons.psychology_alt_rounded, color: Color(0xFFFFD54F), size: 24),
const SizedBox(width: 10),
const Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
'Мастер-Промпт для Нейросети',
style: TextStyle(color: Colors.white, fontSize: 17, fontWeight: FontWeight.bold),
),
Text(
'Для Grok, Claude 3.5 Sonnet, Gemini 1.5 Pro, GPT-4',
style: TextStyle(color: Color(0xFF90A4AE), fontSize: 11),
),
],
),
),
IconButton(
icon: const Icon(Icons.close_rounded, color: Color(0xFF90A4AE)),
onPressed: () => Navigator.pop(ctx),
),
],
),
const SizedBox(height: 12),
// Quick Actions Bar
Row(
children: [
Container(
padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 4),
decoration: BoxDecoration(
color: const Color(0xFF1C223D),
borderRadius: BorderRadius.circular(8),
),
child: Text(
'${prompt.length} символов • ${prompt.split(RegExp(r"\s+")).length} слов',
style: const TextStyle(color: Color(0xFF90CAF9), fontSize: 11),
),
),
const Spacer(),
ElevatedButton.icon(
style: ElevatedButton.styleFrom(
backgroundColor: const Color(0xFFFFD54F),
foregroundColor: Colors.black,
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(12)),
padding: const EdgeInsets.symmetric(horizontal: 14, vertical: 8),
),
onPressed: () {
Clipboard.setData(ClipboardData(text: prompt));
HapticFeedback.heavyImpact();
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(
content: Text('Мастер-промпт скопирован в буфер обмена! Вставьте в Grok или Claude.'),
backgroundColor: Color(0xFF388E3C),
behavior: SnackBarBehavior.floating,
),
);
},
icon: const Icon(Icons.copy_rounded, size: 16),
label: const Text('Скопировать всё', style: TextStyle(fontWeight: FontWeight.bold, fontSize: 12.5)),
),
],
),
const SizedBox(height: 12),
// Scrollable Prompt Text Area
Expanded(
child: Container(
padding: const EdgeInsets.all(14),
decoration: BoxDecoration(
color: const Color(0xFF090A14),
borderRadius: BorderRadius.circular(16),
border: Border.all(color: const Color(0xFF232742), width: 1.0),
),
child: SingleChildScrollView(
controller: scrollController,
child: SelectableText(
prompt,
style: const TextStyle(
color: Color(0xFFECEFF1),
fontFamily: 'monospace',
fontSize: 11.5,
height: 1.45,
),
),
),
),
),
],
),
);
},
);
},
);
}
}