Files
999/lib/screens/houses_result_screen.dart

965 lines
37 KiB
Dart
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
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,
),
),
),
),
),
],
),
);
},
);
},
);
}
}