feat: clarify project agent onboarding

This commit is contained in:
Hamza Ayed
2026-10-04 04:08:57 +03:00
parent b82f73990e
commit e6a2a3b7da
3 changed files with 152 additions and 59 deletions
@@ -1411,7 +1411,7 @@ class _ChatPageState extends State<ChatPage> {
FilledButton.tonalIcon(
onPressed: chat.isSending ? null : _addWorkspaceProject,
icon: const Icon(Icons.create_new_folder_outlined),
label: const Text('إضافة مجلد مشروع'),
label: const Text('تسجيل مجلد مشروع موجود'),
)
else
IconButton.filledTonal(
@@ -1762,70 +1762,158 @@ class _ChatPageState extends State<ChatPage> {
}
}
Widget _welcome() => Center(
child: SingleChildScrollView(
padding: const EdgeInsets.all(24),
child: ConstrainedBox(
constraints: const BoxConstraints(maxWidth: 680),
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
Align(
alignment: Alignment.centerRight,
child: Container(
width: 62,
height: 62,
alignment: Alignment.center,
decoration: BoxDecoration(
color: const Color(0xFFDCEAE3),
borderRadius: BorderRadius.circular(20),
),
child: const Icon(
Icons.waving_hand_rounded,
color: _green,
size: 30,
Widget _welcome() {
final chat = context.watch<ChatCubit>().state;
final selectedProject =
chat.selectedWorkspacePath == null
? null
: _workspaceName(chat.selectedWorkspacePath!);
return Center(
child: SingleChildScrollView(
padding: const EdgeInsets.all(24),
child: ConstrainedBox(
constraints: const BoxConstraints(maxWidth: 680),
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
Align(
alignment: Alignment.centerRight,
child: Container(
width: 62,
height: 62,
alignment: Alignment.center,
decoration: BoxDecoration(
color: const Color(0xFFDCEAE3),
borderRadius: BorderRadius.circular(20),
),
child: const Icon(
Icons.waving_hand_rounded,
color: _green,
size: 30,
),
),
),
),
const SizedBox(height: 22),
const Text(
'أهلًا، خلّينا نجرّب',
style: TextStyle(
color: _ink,
fontSize: 30,
fontWeight: FontWeight.w700,
),
),
const SizedBox(height: 8),
Text(
context.watch<ChatCubit>().state.isWorkspaceMode
? 'الوكيل المحلي: قد يستخدم حتى ثلاث خطوات متتابعة، مثل البحث في الملفات والحساب؛ واقتراح تعديل الملف يعرض معاينة تنتظر موافقتك.'
: context.watch<ChatCubit>().state.isWebSearchMode
? 'بحث عميق: يجلب مصادر ويب متعددة ويلخصها مع الروابط.'
: 'اكتب سؤالك، وسأرسله إلى النموذج المحلي على جهازك.',
style: const TextStyle(color: Color(0xFF718078), fontSize: 14),
),
const SizedBox(height: 28),
Wrap(
spacing: 10,
runSpacing: 10,
children: [
_suggestion('اكتب مثال Python يجمع رقمين', Icons.code_rounded),
_suggestion(
'اشرح لي ما هو الـ API',
Icons.lightbulb_outline_rounded,
const SizedBox(height: 22),
const Text(
'أهلًا، خلّينا نجرّب',
style: TextStyle(
color: _ink,
fontSize: 30,
fontWeight: FontWeight.w700,
),
_suggestion(
'اقترح خطوات لبناء وكيل بسيط',
Icons.account_tree_outlined,
),
const SizedBox(height: 8),
Text(
chat.isWorkspaceMode
? 'الوكيل المحلي: قد يستخدم حتى ثلاث خطوات متتابعة، مثل البحث في الملفات والحساب؛ واقتراح تعديل الملف يعرض معاينة تنتظر موافقتك.'
: chat.isWebSearchMode
? 'بحث عميق: يجلب مصادر ويب متعددة ويلخصها مع الروابط.'
: 'اكتب سؤالك، وسأرسله إلى النموذج المحلي على جهازك.',
style: const TextStyle(color: Color(0xFF718078), fontSize: 14),
),
if (!chat.isWorkspaceMode) ...[
const SizedBox(height: 20),
Card(
elevation: 0,
color: const Color(0xFFF0F5F1),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(16),
side: const BorderSide(color: Color(0xFFDCE7DE)),
),
child: Padding(
padding: const EdgeInsets.all(16),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
const Text(
'جرّب الوكيل على مشروعك',
style: TextStyle(
color: _ink,
fontSize: 15,
fontWeight: FontWeight.w700,
),
),
const SizedBox(height: 6),
Text(
chat.savedWorkspacePaths.isEmpty
? 'سجّل مجلد مشروع موجود على جهازك؛ بعدها يقرأ الوكيل الملفات التي تختارها ويجيب عنها.'
: 'اختر مجلد مشروع مسجلًا من «مشاريعي»، أو سجّل مجلدًا موجودًا جديدًا ليقرأ الوكيل ملفاته.',
style: const TextStyle(
color: Color(0xFF617168),
fontSize: 13,
),
),
const SizedBox(height: 10),
FilledButton.icon(
onPressed:
chat.isSending ? null : _addWorkspaceProject,
icon: const Icon(Icons.folder_open_outlined),
label: const Text('اختيار مجلد مشروع موجود'),
),
],
),
),
),
] else if (selectedProject != null) ...[
const SizedBox(height: 20),
Card(
elevation: 0,
color: const Color(0xFFF0F5F1),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(16),
side: const BorderSide(color: Color(0xFFDCE7DE)),
),
child: Padding(
padding: const EdgeInsets.all(16),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
'الوكيل يعمل على: $selectedProject',
style: const TextStyle(
color: _ink,
fontSize: 15,
fontWeight: FontWeight.w700,
),
),
const SizedBox(height: 6),
Text(
'يمكنه البحث والقراءة واقتراح تعديل مع معاينة وموافقتك. تشغيل أوامر البناء والاختبار داخل المشروع لم يُفعّل بعد.',
style: const TextStyle(
color: Color(0xFF617168),
fontSize: 13,
),
),
],
),
),
),
],
),
],
const SizedBox(height: 28),
Wrap(
spacing: 10,
runSpacing: 10,
children: [
_suggestion(
'اكتب مثال Python يجمع رقمين',
Icons.code_rounded,
),
_suggestion(
'اشرح لي ما هو الـ API',
Icons.lightbulb_outline_rounded,
),
_suggestion(
'اقترح خطوات لبناء وكيل بسيط',
Icons.account_tree_outlined,
),
],
),
],
),
),
),
),
);
);
}
Widget _suggestion(String text, IconData icon) => ActionChip(
onPressed: () => _send(text),