diff --git a/lib/assets/icons/Dicon.ttf b/lib/assets/icons/Dicon.ttf
index c8fad57..d843dd2 100644
Binary files a/lib/assets/icons/Dicon.ttf and b/lib/assets/icons/Dicon.ttf differ
diff --git a/lib/assets/icons/ai-icon.svg b/lib/assets/icons/ai-icon.svg
new file mode 100644
index 0000000..13a7a9f
--- /dev/null
+++ b/lib/assets/icons/ai-icon.svg
@@ -0,0 +1,9 @@
+
\ No newline at end of file
diff --git a/lib/constants/app_icons.dart b/lib/constants/app_icons.dart
index e85977a..f535aef 100644
--- a/lib/constants/app_icons.dart
+++ b/lib/constants/app_icons.dart
@@ -12,9 +12,12 @@
/// - asset: fonts/Dicon.ttf
///
///
+/// * Material Design Icons, Copyright (C) Google, Inc
+/// Author: Google
+/// License: Apache 2.0 (https://www.apache.org/licenses/LICENSE-2.0)
+/// Homepage: https://design.google.com/icons/
///
// ignore_for_file: constant_identifier_names
-///
import 'package:flutter/widgets.dart';
@@ -74,35 +77,35 @@ class DidvanIcons {
IconData(0xe817, fontFamily: _kFontFam, fontPackage: _kFontPkg);
static const IconData arrow_up_regular =
IconData(0xe818, fontFamily: _kFontFam, fontPackage: _kFontPkg);
- static const IconData arrow_up_solid =
+ static const IconData avatar_regular =
IconData(0xe819, fontFamily: _kFontFam, fontPackage: _kFontPkg);
static const IconData avatar_light =
IconData(0xe81a, fontFamily: _kFontFam, fontPackage: _kFontPkg);
- static const IconData avatar_regular =
- IconData(0xe81b, fontFamily: _kFontFam, fontPackage: _kFontPkg);
static const IconData avatar_solid =
+ IconData(0xe81b, fontFamily: _kFontFam, fontPackage: _kFontPkg);
+ static const IconData filter_regular =
IconData(0xe81c, fontFamily: _kFontFam, fontPackage: _kFontPkg);
- static const IconData back_light =
+ static const IconData arrow_up_solid =
IconData(0xe81d, fontFamily: _kFontFam, fontPackage: _kFontPkg);
- static const IconData back_regular =
+ static const IconData back_light =
IconData(0xe81e, fontFamily: _kFontFam, fontPackage: _kFontPkg);
- static const IconData back_solid =
+ static const IconData back_regular =
IconData(0xe81f, fontFamily: _kFontFam, fontPackage: _kFontPkg);
- static const IconData bitcoin_solid =
+ static const IconData back_solid =
IconData(0xe820, fontFamily: _kFontFam, fontPackage: _kFontPkg);
- static const IconData bookmark_light =
+ static const IconData bitcoin_solid =
IconData(0xe821, fontFamily: _kFontFam, fontPackage: _kFontPkg);
- static const IconData bookmark_regular =
+ static const IconData bookmark_light =
IconData(0xe822, fontFamily: _kFontFam, fontPackage: _kFontPkg);
- static const IconData bookmark_solid =
+ static const IconData bookmark_regular =
IconData(0xe823, fontFamily: _kFontFam, fontPackage: _kFontPkg);
- static const IconData calendar_day_light =
+ static const IconData bookmark_solid =
IconData(0xe824, fontFamily: _kFontFam, fontPackage: _kFontPkg);
- static const IconData calendar_day_regular =
+ static const IconData calendar_day_light =
IconData(0xe825, fontFamily: _kFontFam, fontPackage: _kFontPkg);
- static const IconData calendar_day_solid =
+ static const IconData calendar_day_regular =
IconData(0xe826, fontFamily: _kFontFam, fontPackage: _kFontPkg);
- static const IconData calendar_range_light =
+ static const IconData calendar_day_solid =
IconData(0xe827, fontFamily: _kFontFam, fontPackage: _kFontPkg);
static const IconData calendar_range_regular =
IconData(0xe828, fontFamily: _kFontFam, fontPackage: _kFontPkg);
@@ -116,37 +119,37 @@ class DidvanIcons {
IconData(0xe82c, fontFamily: _kFontFam, fontPackage: _kFontPkg);
static const IconData capital_market_solid =
IconData(0xe82d, fontFamily: _kFontFam, fontPackage: _kFontPkg);
- static const IconData caret_down_regular =
- IconData(0xe82e, fontFamily: _kFontFam, fontPackage: _kFontPkg);
- static const IconData caret_down_solid =
- IconData(0xe82f, fontFamily: _kFontFam, fontPackage: _kFontPkg);
- static const IconData category_light =
- IconData(0xe830, fontFamily: _kFontFam, fontPackage: _kFontPkg);
- static const IconData category_regular =
- IconData(0xe831, fontFamily: _kFontFam, fontPackage: _kFontPkg);
static const IconData caret_down_light =
+ IconData(0xe82e, fontFamily: _kFontFam, fontPackage: _kFontPkg);
+ static const IconData caret_down_regular =
+ IconData(0xe82f, fontFamily: _kFontFam, fontPackage: _kFontPkg);
+ static const IconData caret_down_solid =
+ IconData(0xe830, fontFamily: _kFontFam, fontPackage: _kFontPkg);
+ static const IconData category_light =
+ IconData(0xe831, fontFamily: _kFontFam, fontPackage: _kFontPkg);
+ static const IconData calendar_range_light =
IconData(0xe832, fontFamily: _kFontFam, fontPackage: _kFontPkg);
- static const IconData category_solid =
+ static const IconData category_regular =
IconData(0xe833, fontFamily: _kFontFam, fontPackage: _kFontPkg);
- static const IconData chart_light =
+ static const IconData category_solid =
IconData(0xe834, fontFamily: _kFontFam, fontPackage: _kFontPkg);
- static const IconData chart_regular =
+ static const IconData chart_light =
IconData(0xe835, fontFamily: _kFontFam, fontPackage: _kFontPkg);
- static const IconData chart_solid =
+ static const IconData chart_regular =
IconData(0xe836, fontFamily: _kFontFam, fontPackage: _kFontPkg);
- static const IconData chats_light =
+ static const IconData chart_solid =
IconData(0xe837, fontFamily: _kFontFam, fontPackage: _kFontPkg);
- static const IconData chats_regular =
+ static const IconData chats_light =
IconData(0xe838, fontFamily: _kFontFam, fontPackage: _kFontPkg);
static const IconData chats_solid =
IconData(0xe839, fontFamily: _kFontFam, fontPackage: _kFontPkg);
- static const IconData check_light =
+ static const IconData chats_regular =
IconData(0xe83a, fontFamily: _kFontFam, fontPackage: _kFontPkg);
- static const IconData check_regular =
- IconData(0xe83b, fontFamily: _kFontFam, fontPackage: _kFontPkg);
static const IconData check_solid =
- IconData(0xe83c, fontFamily: _kFontFam, fontPackage: _kFontPkg);
+ IconData(0xe83b, fontFamily: _kFontFam, fontPackage: _kFontPkg);
static const IconData check_circle_light =
+ IconData(0xe83c, fontFamily: _kFontFam, fontPackage: _kFontPkg);
+ static const IconData check_regular =
IconData(0xe83d, fontFamily: _kFontFam, fontPackage: _kFontPkg);
static const IconData check_circle_regular =
IconData(0xe83e, fontFamily: _kFontFam, fontPackage: _kFontPkg);
@@ -170,29 +173,29 @@ class DidvanIcons {
IconData(0xe847, fontFamily: _kFontFam, fontPackage: _kFontPkg);
static const IconData close_circle_solid =
IconData(0xe848, fontFamily: _kFontFam, fontPackage: _kFontPkg);
- static const IconData commodity_solid =
+ static const IconData check_light =
IconData(0xe849, fontFamily: _kFontFam, fontPackage: _kFontPkg);
- static const IconData currency_solid =
+ static const IconData commodity_solid =
IconData(0xe84a, fontFamily: _kFontFam, fontPackage: _kFontPkg);
- static const IconData description_regular =
+ static const IconData currency_solid =
IconData(0xe84b, fontFamily: _kFontFam, fontPackage: _kFontPkg);
- static const IconData didvan_light =
- IconData(0xe84c, fontFamily: _kFontFam, fontPackage: _kFontPkg);
- static const IconData didvan_regular =
- IconData(0xe84d, fontFamily: _kFontFam, fontPackage: _kFontPkg);
- static const IconData didvan_solid =
- IconData(0xe84e, fontFamily: _kFontFam, fontPackage: _kFontPkg);
- static const IconData dislike_light =
- IconData(0xe84f, fontFamily: _kFontFam, fontPackage: _kFontPkg);
- static const IconData dislike_regular =
- IconData(0xe850, fontFamily: _kFontFam, fontPackage: _kFontPkg);
- static const IconData dislike_solid =
- IconData(0xe851, fontFamily: _kFontFam, fontPackage: _kFontPkg);
static const IconData description_light =
- IconData(0xe852, fontFamily: _kFontFam, fontPackage: _kFontPkg);
- static const IconData download_light =
- IconData(0xe853, fontFamily: _kFontFam, fontPackage: _kFontPkg);
+ IconData(0xe84c, fontFamily: _kFontFam, fontPackage: _kFontPkg);
+ static const IconData filter_solid =
+ IconData(0xe84d, fontFamily: _kFontFam, fontPackage: _kFontPkg);
static const IconData description_solid =
+ IconData(0xe84e, fontFamily: _kFontFam, fontPackage: _kFontPkg);
+ static const IconData description_regular =
+ IconData(0xe84f, fontFamily: _kFontFam, fontPackage: _kFontPkg);
+ static const IconData didvan_light =
+ IconData(0xe850, fontFamily: _kFontFam, fontPackage: _kFontPkg);
+ static const IconData didvan_regular =
+ IconData(0xe851, fontFamily: _kFontFam, fontPackage: _kFontPkg);
+ static const IconData didvan_solid =
+ IconData(0xe852, fontFamily: _kFontFam, fontPackage: _kFontPkg);
+ static const IconData dislike_light =
+ IconData(0xe853, fontFamily: _kFontFam, fontPackage: _kFontPkg);
+ static const IconData dislike_regular =
IconData(0xe854, fontFamily: _kFontFam, fontPackage: _kFontPkg);
static const IconData download_regular =
IconData(0xe855, fontFamily: _kFontFam, fontPackage: _kFontPkg);
@@ -202,33 +205,33 @@ class DidvanIcons {
IconData(0xe857, fontFamily: _kFontFam, fontPackage: _kFontPkg);
static const IconData evaluation_regular =
IconData(0xe858, fontFamily: _kFontFam, fontPackage: _kFontPkg);
- static const IconData evaluation_solid =
- IconData(0xe859, fontFamily: _kFontFam, fontPackage: _kFontPkg);
static const IconData exclamation_triangle_light =
- IconData(0xe85a, fontFamily: _kFontFam, fontPackage: _kFontPkg);
+ IconData(0xe859, fontFamily: _kFontFam, fontPackage: _kFontPkg);
static const IconData exclamation_triangle_regular =
- IconData(0xe85b, fontFamily: _kFontFam, fontPackage: _kFontPkg);
+ IconData(0xe85a, fontFamily: _kFontFam, fontPackage: _kFontPkg);
static const IconData exclamation_triangle_solid =
- IconData(0xe85c, fontFamily: _kFontFam, fontPackage: _kFontPkg);
+ IconData(0xe85b, fontFamily: _kFontFam, fontPackage: _kFontPkg);
static const IconData eye_close_solid =
- IconData(0xe85d, fontFamily: _kFontFam, fontPackage: _kFontPkg);
+ IconData(0xe85c, fontFamily: _kFontFam, fontPackage: _kFontPkg);
static const IconData eye_light =
- IconData(0xe85e, fontFamily: _kFontFam, fontPackage: _kFontPkg);
+ IconData(0xe85d, fontFamily: _kFontFam, fontPackage: _kFontPkg);
static const IconData eye_regular =
- IconData(0xe85f, fontFamily: _kFontFam, fontPackage: _kFontPkg);
+ IconData(0xe85e, fontFamily: _kFontFam, fontPackage: _kFontPkg);
static const IconData eye_solid =
- IconData(0xe860, fontFamily: _kFontFam, fontPackage: _kFontPkg);
+ IconData(0xe85f, fontFamily: _kFontFam, fontPackage: _kFontPkg);
static const IconData eye_slash_light =
- IconData(0xe861, fontFamily: _kFontFam, fontPackage: _kFontPkg);
- static const IconData eye_slash_regular =
- IconData(0xe862, fontFamily: _kFontFam, fontPackage: _kFontPkg);
- static const IconData eye_slash_solid =
- IconData(0xe863, fontFamily: _kFontFam, fontPackage: _kFontPkg);
+ IconData(0xe860, fontFamily: _kFontFam, fontPackage: _kFontPkg);
static const IconData filter_light =
+ IconData(0xe861, fontFamily: _kFontFam, fontPackage: _kFontPkg);
+ static const IconData evaluation_solid =
+ IconData(0xe862, fontFamily: _kFontFam, fontPackage: _kFontPkg);
+ static const IconData eye_slash_regular =
+ IconData(0xe863, fontFamily: _kFontFam, fontPackage: _kFontPkg);
+ static const IconData download_light =
IconData(0xe864, fontFamily: _kFontFam, fontPackage: _kFontPkg);
- static const IconData filter_regular =
+ static const IconData dislike_solid =
IconData(0xe865, fontFamily: _kFontFam, fontPackage: _kFontPkg);
- static const IconData filter_solid =
+ static const IconData eye_slash_solid =
IconData(0xe866, fontFamily: _kFontFam, fontPackage: _kFontPkg);
static const IconData fingerprint_light =
IconData(0xe867, fontFamily: _kFontFam, fontPackage: _kFontPkg);
@@ -326,232 +329,246 @@ class DidvanIcons {
IconData(0xe895, fontFamily: _kFontFam, fontPackage: _kFontPkg);
static const IconData media_forward_solid =
IconData(0xe896, fontFamily: _kFontFam, fontPackage: _kFontPkg);
- static const IconData menu_light =
- IconData(0xe897, fontFamily: _kFontFam, fontPackage: _kFontPkg);
- static const IconData menu_regular =
- IconData(0xe898, fontFamily: _kFontFam, fontPackage: _kFontPkg);
- static const IconData menu_solid =
- IconData(0xe899, fontFamily: _kFontFam, fontPackage: _kFontPkg);
- static const IconData message_light =
- IconData(0xe89a, fontFamily: _kFontFam, fontPackage: _kFontPkg);
- static const IconData message_regular =
- IconData(0xe89b, fontFamily: _kFontFam, fontPackage: _kFontPkg);
- static const IconData message_solid =
- IconData(0xe89c, fontFamily: _kFontFam, fontPackage: _kFontPkg);
- static const IconData metal_solid =
- IconData(0xe89d, fontFamily: _kFontFam, fontPackage: _kFontPkg);
- static const IconData mic_light =
- IconData(0xe89e, fontFamily: _kFontFam, fontPackage: _kFontPkg);
- static const IconData mic_regular =
- IconData(0xe89f, fontFamily: _kFontFam, fontPackage: _kFontPkg);
- static const IconData mic_solid =
- IconData(0xe8a0, fontFamily: _kFontFam, fontPackage: _kFontPkg);
- static const IconData minimize_light =
- IconData(0xe8a1, fontFamily: _kFontFam, fontPackage: _kFontPkg);
- static const IconData minimize_regular =
- IconData(0xe8a2, fontFamily: _kFontFam, fontPackage: _kFontPkg);
- static const IconData minimize_solid =
- IconData(0xe8a3, fontFamily: _kFontFam, fontPackage: _kFontPkg);
- static const IconData news_light =
- IconData(0xe8a4, fontFamily: _kFontFam, fontPackage: _kFontPkg);
- static const IconData news_regular =
- IconData(0xe8a5, fontFamily: _kFontFam, fontPackage: _kFontPkg);
- static const IconData news_solid =
- IconData(0xe8a6, fontFamily: _kFontFam, fontPackage: _kFontPkg);
- static const IconData non_tick_square_regular =
- IconData(0xe8a7, fontFamily: _kFontFam, fontPackage: _kFontPkg);
- static const IconData note_solid =
- IconData(0xe8a8, fontFamily: _kFontFam, fontPackage: _kFontPkg);
- static const IconData notification_light =
- IconData(0xe8a9, fontFamily: _kFontFam, fontPackage: _kFontPkg);
- static const IconData notification_regular =
- IconData(0xe8aa, fontFamily: _kFontFam, fontPackage: _kFontPkg);
- static const IconData notification_solid =
- IconData(0xe8ab, fontFamily: _kFontFam, fontPackage: _kFontPkg);
- static const IconData pause_light =
- IconData(0xe8ac, fontFamily: _kFontFam, fontPackage: _kFontPkg);
- static const IconData pause_regular =
- IconData(0xe8ad, fontFamily: _kFontFam, fontPackage: _kFontPkg);
- static const IconData pause_solid =
- IconData(0xe8ae, fontFamily: _kFontFam, fontPackage: _kFontPkg);
- static const IconData pause_circle_light =
- IconData(0xe8af, fontFamily: _kFontFam, fontPackage: _kFontPkg);
- static const IconData pause_circle_regular =
- IconData(0xe8b0, fontFamily: _kFontFam, fontPackage: _kFontPkg);
- static const IconData pause_circle_solid =
- IconData(0xe8b1, fontFamily: _kFontFam, fontPackage: _kFontPkg);
- static const IconData people_solid =
- IconData(0xe8b2, fontFamily: _kFontFam, fontPackage: _kFontPkg);
- static const IconData play_light =
- IconData(0xe8b3, fontFamily: _kFontFam, fontPackage: _kFontPkg);
- static const IconData play_regular =
- IconData(0xe8b4, fontFamily: _kFontFam, fontPackage: _kFontPkg);
- static const IconData play_solid =
- IconData(0xe8b5, fontFamily: _kFontFam, fontPackage: _kFontPkg);
- static const IconData play_circle_light =
- IconData(0xe8b6, fontFamily: _kFontFam, fontPackage: _kFontPkg);
- static const IconData play_circle_regular =
- IconData(0xe8b7, fontFamily: _kFontFam, fontPackage: _kFontPkg);
- static const IconData play_circle_solid =
- IconData(0xe8b8, fontFamily: _kFontFam, fontPackage: _kFontPkg);
- static const IconData podcast_light =
- IconData(0xe8b9, fontFamily: _kFontFam, fontPackage: _kFontPkg);
- static const IconData podcast_regular =
- IconData(0xe8ba, fontFamily: _kFontFam, fontPackage: _kFontPkg);
- static const IconData podcast_solid =
- IconData(0xe8bb, fontFamily: _kFontFam, fontPackage: _kFontPkg);
- static const IconData profile_light =
- IconData(0xe8bc, fontFamily: _kFontFam, fontPackage: _kFontPkg);
- static const IconData profile_regular =
- IconData(0xe8bd, fontFamily: _kFontFam, fontPackage: _kFontPkg);
- static const IconData profile_solid =
- IconData(0xe8be, fontFamily: _kFontFam, fontPackage: _kFontPkg);
- static const IconData puzzle_light =
- IconData(0xe8bf, fontFamily: _kFontFam, fontPackage: _kFontPkg);
- static const IconData puzzle_regular =
- IconData(0xe8c0, fontFamily: _kFontFam, fontPackage: _kFontPkg);
- static const IconData puzzle_solid =
- IconData(0xe8c1, fontFamily: _kFontFam, fontPackage: _kFontPkg);
- static const IconData radar_light =
- IconData(0xe8c2, fontFamily: _kFontFam, fontPackage: _kFontPkg);
- static const IconData radar_regular =
- IconData(0xe8c3, fontFamily: _kFontFam, fontPackage: _kFontPkg);
- static const IconData radar_solid =
- IconData(0xe8c4, fontFamily: _kFontFam, fontPackage: _kFontPkg);
- static const IconData refresh_light =
- IconData(0xe8c5, fontFamily: _kFontFam, fontPackage: _kFontPkg);
- static const IconData refresh_regular =
- IconData(0xe8c6, fontFamily: _kFontFam, fontPackage: _kFontPkg);
- static const IconData refresh_solid =
- IconData(0xe8c7, fontFamily: _kFontFam, fontPackage: _kFontPkg);
- static const IconData saha_light =
- IconData(0xe8c8, fontFamily: _kFontFam, fontPackage: _kFontPkg);
- static const IconData saha_regular =
- IconData(0xe8c9, fontFamily: _kFontFam, fontPackage: _kFontPkg);
- static const IconData saha_solid =
- IconData(0xe8ca, fontFamily: _kFontFam, fontPackage: _kFontPkg);
- static const IconData scanning_light =
- IconData(0xe8cb, fontFamily: _kFontFam, fontPackage: _kFontPkg);
- static const IconData scanning_regular =
- IconData(0xe8cc, fontFamily: _kFontFam, fontPackage: _kFontPkg);
- static const IconData scanning_solid =
- IconData(0xe8cd, fontFamily: _kFontFam, fontPackage: _kFontPkg);
- static const IconData search_light =
- IconData(0xe8ce, fontFamily: _kFontFam, fontPackage: _kFontPkg);
- static const IconData search_regular =
- IconData(0xe8cf, fontFamily: _kFontFam, fontPackage: _kFontPkg);
- static const IconData search_solid =
- IconData(0xe8d0, fontFamily: _kFontFam, fontPackage: _kFontPkg);
- static const IconData send_light =
- IconData(0xe8d1, fontFamily: _kFontFam, fontPackage: _kFontPkg);
- static const IconData send_regular =
- IconData(0xe8d2, fontFamily: _kFontFam, fontPackage: _kFontPkg);
- static const IconData send_solid =
- IconData(0xe8d3, fontFamily: _kFontFam, fontPackage: _kFontPkg);
- static const IconData setting_light =
- IconData(0xe8d4, fontFamily: _kFontFam, fontPackage: _kFontPkg);
- static const IconData setting_regular =
- IconData(0xe8d5, fontFamily: _kFontFam, fontPackage: _kFontPkg);
- static const IconData setting_solid =
- IconData(0xe8d6, fontFamily: _kFontFam, fontPackage: _kFontPkg);
- static const IconData sign_out_light =
- IconData(0xe8d7, fontFamily: _kFontFam, fontPackage: _kFontPkg);
- static const IconData sign_out_regular =
- IconData(0xe8d8, fontFamily: _kFontFam, fontPackage: _kFontPkg);
- static const IconData sign_out_solid =
- IconData(0xe8d9, fontFamily: _kFontFam, fontPackage: _kFontPkg);
- static const IconData sleep_enabled_light =
- IconData(0xe8da, fontFamily: _kFontFam, fontPackage: _kFontPkg);
- static const IconData sleep_enabled_regular =
- IconData(0xe8db, fontFamily: _kFontFam, fontPackage: _kFontPkg);
- static const IconData sleep_enabled_solid =
- IconData(0xe8dc, fontFamily: _kFontFam, fontPackage: _kFontPkg);
- static const IconData sleep_timer_light =
- IconData(0xe8dd, fontFamily: _kFontFam, fontPackage: _kFontPkg);
- static const IconData sleep_timer_regular =
- IconData(0xe8de, fontFamily: _kFontFam, fontPackage: _kFontPkg);
- static const IconData sleep_timer_solid =
- IconData(0xe8df, fontFamily: _kFontFam, fontPackage: _kFontPkg);
- static const IconData sort_light =
- IconData(0xe8e0, fontFamily: _kFontFam, fontPackage: _kFontPkg);
- static const IconData sort_regular =
- IconData(0xe8e1, fontFamily: _kFontFam, fontPackage: _kFontPkg);
- static const IconData sort_solid =
- IconData(0xe8e2, fontFamily: _kFontFam, fontPackage: _kFontPkg);
- static const IconData star_circle_solid =
- IconData(0xe8e3, fontFamily: _kFontFam, fontPackage: _kFontPkg);
- static const IconData star_light =
- IconData(0xe8e4, fontFamily: _kFontFam, fontPackage: _kFontPkg);
- static const IconData star_regular =
- IconData(0xe8e5, fontFamily: _kFontFam, fontPackage: _kFontPkg);
- static const IconData star_solid =
- IconData(0xe8e6, fontFamily: _kFontFam, fontPackage: _kFontPkg);
- static const IconData startup_solid =
- IconData(0xe8e7, fontFamily: _kFontFam, fontPackage: _kFontPkg);
- static const IconData stats__light =
- IconData(0xe8e8, fontFamily: _kFontFam, fontPackage: _kFontPkg);
- static const IconData stats__regular =
- IconData(0xe8e9, fontFamily: _kFontFam, fontPackage: _kFontPkg);
- static const IconData stats__solid =
- IconData(0xe8ea, fontFamily: _kFontFam, fontPackage: _kFontPkg);
- static const IconData stop_circle_light =
- IconData(0xe8eb, fontFamily: _kFontFam, fontPackage: _kFontPkg);
- static const IconData stop_circle_regular =
- IconData(0xe8ec, fontFamily: _kFontFam, fontPackage: _kFontPkg);
- static const IconData stop_circle_solid =
- IconData(0xe8ed, fontFamily: _kFontFam, fontPackage: _kFontPkg);
- static const IconData sub_category_light =
- IconData(0xe8ee, fontFamily: _kFontFam, fontPackage: _kFontPkg);
- static const IconData sub_category_regular =
- IconData(0xe8ef, fontFamily: _kFontFam, fontPackage: _kFontPkg);
- static const IconData sub_category_solid =
- IconData(0xe8f0, fontFamily: _kFontFam, fontPackage: _kFontPkg);
- static const IconData support_light =
- IconData(0xe8f1, fontFamily: _kFontFam, fontPackage: _kFontPkg);
- static const IconData support_regular =
- IconData(0xe8f2, fontFamily: _kFontFam, fontPackage: _kFontPkg);
- static const IconData support_solid =
- IconData(0xe8f3, fontFamily: _kFontFam, fontPackage: _kFontPkg);
- static const IconData technology_solid =
- IconData(0xe8f4, fontFamily: _kFontFam, fontPackage: _kFontPkg);
- static const IconData theme_light =
- IconData(0xe8f5, fontFamily: _kFontFam, fontPackage: _kFontPkg);
- static const IconData theme_regular =
- IconData(0xe8f6, fontFamily: _kFontFam, fontPackage: _kFontPkg);
- static const IconData theme_solid =
- IconData(0xe8f7, fontFamily: _kFontFam, fontPackage: _kFontPkg);
- static const IconData tick_square_regular =
- IconData(0xe8f8, fontFamily: _kFontFam, fontPackage: _kFontPkg);
- static const IconData timer_light =
- IconData(0xe8f9, fontFamily: _kFontFam, fontPackage: _kFontPkg);
- static const IconData timer_regular =
- IconData(0xe8fa, fontFamily: _kFontFam, fontPackage: _kFontPkg);
- static const IconData timer_solid =
- IconData(0xe8fb, fontFamily: _kFontFam, fontPackage: _kFontPkg);
- static const IconData trash_light =
- IconData(0xe8fc, fontFamily: _kFontFam, fontPackage: _kFontPkg);
- static const IconData trash_regular =
- IconData(0xe8fd, fontFamily: _kFontFam, fontPackage: _kFontPkg);
- static const IconData trash_solid =
- IconData(0xe8fe, fontFamily: _kFontFam, fontPackage: _kFontPkg);
- static const IconData user_edit_light =
- IconData(0xe8ff, fontFamily: _kFontFam, fontPackage: _kFontPkg);
- static const IconData user_edit_regular =
- IconData(0xe900, fontFamily: _kFontFam, fontPackage: _kFontPkg);
- static const IconData user_edit_solid =
- IconData(0xe901, fontFamily: _kFontFam, fontPackage: _kFontPkg);
- static const IconData user_shield_light =
- IconData(0xe902, fontFamily: _kFontFam, fontPackage: _kFontPkg);
- static const IconData user_shield_regular =
- IconData(0xe903, fontFamily: _kFontFam, fontPackage: _kFontPkg);
- static const IconData user_shield_solid =
- IconData(0xe904, fontFamily: _kFontFam, fontPackage: _kFontPkg);
- static const IconData video_light =
- IconData(0xe905, fontFamily: _kFontFam, fontPackage: _kFontPkg);
- static const IconData video_regular =
- IconData(0xe906, fontFamily: _kFontFam, fontPackage: _kFontPkg);
- static const IconData video_solid =
- IconData(0xe907, fontFamily: _kFontFam, fontPackage: _kFontPkg);
static const IconData mention_icon =
+ IconData(0xe897, fontFamily: _kFontFam, fontPackage: _kFontPkg);
+ static const IconData menu_light =
+ IconData(0xe898, fontFamily: _kFontFam, fontPackage: _kFontPkg);
+ static const IconData menu_regular =
+ IconData(0xe899, fontFamily: _kFontFam, fontPackage: _kFontPkg);
+ static const IconData menu_solid =
+ IconData(0xe89a, fontFamily: _kFontFam, fontPackage: _kFontPkg);
+ static const IconData message_light =
+ IconData(0xe89b, fontFamily: _kFontFam, fontPackage: _kFontPkg);
+ static const IconData message_regular =
+ IconData(0xe89c, fontFamily: _kFontFam, fontPackage: _kFontPkg);
+ static const IconData message_solid =
+ IconData(0xe89d, fontFamily: _kFontFam, fontPackage: _kFontPkg);
+ static const IconData metal_solid =
+ IconData(0xe89e, fontFamily: _kFontFam, fontPackage: _kFontPkg);
+ static const IconData mic_light =
+ IconData(0xe89f, fontFamily: _kFontFam, fontPackage: _kFontPkg);
+ static const IconData mic_regular =
+ IconData(0xe8a0, fontFamily: _kFontFam, fontPackage: _kFontPkg);
+ static const IconData mic_solid =
+ IconData(0xe8a1, fontFamily: _kFontFam, fontPackage: _kFontPkg);
+ static const IconData minimize_light =
+ IconData(0xe8a2, fontFamily: _kFontFam, fontPackage: _kFontPkg);
+ static const IconData minimize_regular =
+ IconData(0xe8a3, fontFamily: _kFontFam, fontPackage: _kFontPkg);
+ static const IconData minimize_solid =
+ IconData(0xe8a4, fontFamily: _kFontFam, fontPackage: _kFontPkg);
+ static const IconData news_light =
+ IconData(0xe8a5, fontFamily: _kFontFam, fontPackage: _kFontPkg);
+ static const IconData news_regular =
+ IconData(0xe8a6, fontFamily: _kFontFam, fontPackage: _kFontPkg);
+ static const IconData news_solid =
+ IconData(0xe8a7, fontFamily: _kFontFam, fontPackage: _kFontPkg);
+ static const IconData non_tick_square_regular =
+ IconData(0xe8a8, fontFamily: _kFontFam, fontPackage: _kFontPkg);
+ static const IconData note_solid =
+ IconData(0xe8a9, fontFamily: _kFontFam, fontPackage: _kFontPkg);
+ static const IconData notification_light =
+ IconData(0xe8aa, fontFamily: _kFontFam, fontPackage: _kFontPkg);
+ static const IconData notification_regular =
+ IconData(0xe8ab, fontFamily: _kFontFam, fontPackage: _kFontPkg);
+ static const IconData notification_solid =
+ IconData(0xe8ac, fontFamily: _kFontFam, fontPackage: _kFontPkg);
+ static const IconData pause_light =
+ IconData(0xe8ad, fontFamily: _kFontFam, fontPackage: _kFontPkg);
+ static const IconData pause_regular =
+ IconData(0xe8ae, fontFamily: _kFontFam, fontPackage: _kFontPkg);
+ static const IconData pause_solid =
+ IconData(0xe8af, fontFamily: _kFontFam, fontPackage: _kFontPkg);
+ static const IconData pause_circle_light =
+ IconData(0xe8b0, fontFamily: _kFontFam, fontPackage: _kFontPkg);
+ static const IconData pause_circle_regular =
+ IconData(0xe8b1, fontFamily: _kFontFam, fontPackage: _kFontPkg);
+ static const IconData pause_circle_solid =
+ IconData(0xe8b2, fontFamily: _kFontFam, fontPackage: _kFontPkg);
+ static const IconData people_solid =
+ IconData(0xe8b3, fontFamily: _kFontFam, fontPackage: _kFontPkg);
+ static const IconData play_light =
+ IconData(0xe8b4, fontFamily: _kFontFam, fontPackage: _kFontPkg);
+ static const IconData play_regular =
+ IconData(0xe8b5, fontFamily: _kFontFam, fontPackage: _kFontPkg);
+ static const IconData play_solid =
+ IconData(0xe8b6, fontFamily: _kFontFam, fontPackage: _kFontPkg);
+ static const IconData play_circle_light =
+ IconData(0xe8b7, fontFamily: _kFontFam, fontPackage: _kFontPkg);
+ static const IconData play_circle_regular =
+ IconData(0xe8b8, fontFamily: _kFontFam, fontPackage: _kFontPkg);
+ static const IconData play_circle_solid =
+ IconData(0xe8b9, fontFamily: _kFontFam, fontPackage: _kFontPkg);
+ static const IconData podcast_light =
+ IconData(0xe8ba, fontFamily: _kFontFam, fontPackage: _kFontPkg);
+ static const IconData podcast_regular =
+ IconData(0xe8bb, fontFamily: _kFontFam, fontPackage: _kFontPkg);
+ static const IconData podcast_solid =
+ IconData(0xe8bc, fontFamily: _kFontFam, fontPackage: _kFontPkg);
+ static const IconData profile_light =
+ IconData(0xe8bd, fontFamily: _kFontFam, fontPackage: _kFontPkg);
+ static const IconData profile_regular =
+ IconData(0xe8be, fontFamily: _kFontFam, fontPackage: _kFontPkg);
+ static const IconData profile_solid =
+ IconData(0xe8bf, fontFamily: _kFontFam, fontPackage: _kFontPkg);
+ static const IconData puzzle_light =
+ IconData(0xe8c0, fontFamily: _kFontFam, fontPackage: _kFontPkg);
+ static const IconData puzzle_regular =
+ IconData(0xe8c1, fontFamily: _kFontFam, fontPackage: _kFontPkg);
+ static const IconData puzzle_solid =
+ IconData(0xe8c2, fontFamily: _kFontFam, fontPackage: _kFontPkg);
+ static const IconData radar_light =
+ IconData(0xe8c3, fontFamily: _kFontFam, fontPackage: _kFontPkg);
+ static const IconData radar_regular =
+ IconData(0xe8c4, fontFamily: _kFontFam, fontPackage: _kFontPkg);
+ static const IconData radar_solid =
+ IconData(0xe8c5, fontFamily: _kFontFam, fontPackage: _kFontPkg);
+ static const IconData refresh_light =
+ IconData(0xe8c6, fontFamily: _kFontFam, fontPackage: _kFontPkg);
+ static const IconData refresh_regular =
+ IconData(0xe8c7, fontFamily: _kFontFam, fontPackage: _kFontPkg);
+ static const IconData refresh_solid =
+ IconData(0xe8c8, fontFamily: _kFontFam, fontPackage: _kFontPkg);
+ static const IconData saha_light =
+ IconData(0xe8c9, fontFamily: _kFontFam, fontPackage: _kFontPkg);
+ static const IconData saha_regular =
+ IconData(0xe8ca, fontFamily: _kFontFam, fontPackage: _kFontPkg);
+ static const IconData saha_solid =
+ IconData(0xe8cb, fontFamily: _kFontFam, fontPackage: _kFontPkg);
+ static const IconData scanning_light =
+ IconData(0xe8cc, fontFamily: _kFontFam, fontPackage: _kFontPkg);
+ static const IconData scanning_regular =
+ IconData(0xe8cd, fontFamily: _kFontFam, fontPackage: _kFontPkg);
+ static const IconData scanning_solid =
+ IconData(0xe8ce, fontFamily: _kFontFam, fontPackage: _kFontPkg);
+ static const IconData search_light =
+ IconData(0xe8cf, fontFamily: _kFontFam, fontPackage: _kFontPkg);
+ static const IconData search_regular =
+ IconData(0xe8d0, fontFamily: _kFontFam, fontPackage: _kFontPkg);
+ static const IconData search_solid =
+ IconData(0xe8d1, fontFamily: _kFontFam, fontPackage: _kFontPkg);
+ static const IconData send_light =
+ IconData(0xe8d2, fontFamily: _kFontFam, fontPackage: _kFontPkg);
+ static const IconData send_regular =
+ IconData(0xe8d3, fontFamily: _kFontFam, fontPackage: _kFontPkg);
+ static const IconData send_solid =
+ IconData(0xe8d4, fontFamily: _kFontFam, fontPackage: _kFontPkg);
+ static const IconData setting_light =
+ IconData(0xe8d5, fontFamily: _kFontFam, fontPackage: _kFontPkg);
+ static const IconData setting_regular =
+ IconData(0xe8d6, fontFamily: _kFontFam, fontPackage: _kFontPkg);
+ static const IconData setting_solid =
+ IconData(0xe8d7, fontFamily: _kFontFam, fontPackage: _kFontPkg);
+ static const IconData sign_out_light =
+ IconData(0xe8d8, fontFamily: _kFontFam, fontPackage: _kFontPkg);
+ static const IconData sign_out_regular =
+ IconData(0xe8d9, fontFamily: _kFontFam, fontPackage: _kFontPkg);
+ static const IconData sign_out_solid =
+ IconData(0xe8da, fontFamily: _kFontFam, fontPackage: _kFontPkg);
+ static const IconData sleep_enabled_light =
+ IconData(0xe8db, fontFamily: _kFontFam, fontPackage: _kFontPkg);
+ static const IconData sleep_enabled_regular =
+ IconData(0xe8dc, fontFamily: _kFontFam, fontPackage: _kFontPkg);
+ static const IconData sleep_enabled_solid =
+ IconData(0xe8dd, fontFamily: _kFontFam, fontPackage: _kFontPkg);
+ static const IconData sleep_timer_light =
+ IconData(0xe8de, fontFamily: _kFontFam, fontPackage: _kFontPkg);
+ static const IconData sleep_timer_regular =
+ IconData(0xe8df, fontFamily: _kFontFam, fontPackage: _kFontPkg);
+ static const IconData sleep_timer_solid =
+ IconData(0xe8e0, fontFamily: _kFontFam, fontPackage: _kFontPkg);
+ static const IconData sort_light =
+ IconData(0xe8e1, fontFamily: _kFontFam, fontPackage: _kFontPkg);
+ static const IconData sort_regular =
+ IconData(0xe8e2, fontFamily: _kFontFam, fontPackage: _kFontPkg);
+ static const IconData sort_solid =
+ IconData(0xe8e3, fontFamily: _kFontFam, fontPackage: _kFontPkg);
+ static const IconData star_circle_solid =
+ IconData(0xe8e4, fontFamily: _kFontFam, fontPackage: _kFontPkg);
+ static const IconData star_light =
+ IconData(0xe8e5, fontFamily: _kFontFam, fontPackage: _kFontPkg);
+ static const IconData star_regular =
+ IconData(0xe8e6, fontFamily: _kFontFam, fontPackage: _kFontPkg);
+ static const IconData star_solid =
+ IconData(0xe8e7, fontFamily: _kFontFam, fontPackage: _kFontPkg);
+ static const IconData startup_solid =
+ IconData(0xe8e8, fontFamily: _kFontFam, fontPackage: _kFontPkg);
+ static const IconData stats__light =
+ IconData(0xe8e9, fontFamily: _kFontFam, fontPackage: _kFontPkg);
+ static const IconData stats__regular =
+ IconData(0xe8ea, fontFamily: _kFontFam, fontPackage: _kFontPkg);
+ static const IconData stats__solid =
+ IconData(0xe8eb, fontFamily: _kFontFam, fontPackage: _kFontPkg);
+ static const IconData stop_circle_light =
+ IconData(0xe8ec, fontFamily: _kFontFam, fontPackage: _kFontPkg);
+ static const IconData stop_circle_regular =
+ IconData(0xe8ed, fontFamily: _kFontFam, fontPackage: _kFontPkg);
+ static const IconData stop_circle_solid =
+ IconData(0xe8ee, fontFamily: _kFontFam, fontPackage: _kFontPkg);
+ static const IconData sub_category_light =
+ IconData(0xe8ef, fontFamily: _kFontFam, fontPackage: _kFontPkg);
+ static const IconData sub_category_regular =
+ IconData(0xe8f0, fontFamily: _kFontFam, fontPackage: _kFontPkg);
+ static const IconData sub_category_solid =
+ IconData(0xe8f1, fontFamily: _kFontFam, fontPackage: _kFontPkg);
+ static const IconData support_light =
+ IconData(0xe8f2, fontFamily: _kFontFam, fontPackage: _kFontPkg);
+ static const IconData support_regular =
+ IconData(0xe8f3, fontFamily: _kFontFam, fontPackage: _kFontPkg);
+ static const IconData support_solid =
+ IconData(0xe8f4, fontFamily: _kFontFam, fontPackage: _kFontPkg);
+ static const IconData technology_solid =
+ IconData(0xe8f5, fontFamily: _kFontFam, fontPackage: _kFontPkg);
+ static const IconData theme_light =
+ IconData(0xe8f6, fontFamily: _kFontFam, fontPackage: _kFontPkg);
+ static const IconData theme_regular =
+ IconData(0xe8f7, fontFamily: _kFontFam, fontPackage: _kFontPkg);
+ static const IconData theme_solid =
+ IconData(0xe8f8, fontFamily: _kFontFam, fontPackage: _kFontPkg);
+ static const IconData tick_square_regular =
+ IconData(0xe8f9, fontFamily: _kFontFam, fontPackage: _kFontPkg);
+ static const IconData timer_light =
+ IconData(0xe8fa, fontFamily: _kFontFam, fontPackage: _kFontPkg);
+ static const IconData timer_regular =
+ IconData(0xe8fb, fontFamily: _kFontFam, fontPackage: _kFontPkg);
+ static const IconData timer_solid =
+ IconData(0xe8fc, fontFamily: _kFontFam, fontPackage: _kFontPkg);
+ static const IconData trash_light =
+ IconData(0xe8fd, fontFamily: _kFontFam, fontPackage: _kFontPkg);
+ static const IconData trash_regular =
+ IconData(0xe8fe, fontFamily: _kFontFam, fontPackage: _kFontPkg);
+ static const IconData trash_solid =
+ IconData(0xe8ff, fontFamily: _kFontFam, fontPackage: _kFontPkg);
+ static const IconData user_edit_light =
+ IconData(0xe900, fontFamily: _kFontFam, fontPackage: _kFontPkg);
+ static const IconData user_edit_regular =
+ IconData(0xe901, fontFamily: _kFontFam, fontPackage: _kFontPkg);
+ static const IconData user_edit_solid =
+ IconData(0xe902, fontFamily: _kFontFam, fontPackage: _kFontPkg);
+ static const IconData user_shield_light =
+ IconData(0xe903, fontFamily: _kFontFam, fontPackage: _kFontPkg);
+ static const IconData user_shield_regular =
+ IconData(0xe904, fontFamily: _kFontFam, fontPackage: _kFontPkg);
+ static const IconData user_shield_solid =
+ IconData(0xe905, fontFamily: _kFontFam, fontPackage: _kFontPkg);
+ static const IconData video_light =
+ IconData(0xe906, fontFamily: _kFontFam, fontPackage: _kFontPkg);
+ static const IconData video_regular =
+ IconData(0xe907, fontFamily: _kFontFam, fontPackage: _kFontPkg);
+ static const IconData video_solid =
IconData(0xe908, fontFamily: _kFontFam, fontPackage: _kFontPkg);
+ static const IconData contact_us_solid =
+ IconData(0xe909, fontFamily: _kFontFam, fontPackage: _kFontPkg);
+ static const IconData ai_regular =
+ IconData(0xe90a, fontFamily: _kFontFam, fontPackage: _kFontPkg);
+ static const IconData ai_solid =
+ IconData(0xe90b, fontFamily: _kFontFam, fontPackage: _kFontPkg);
+ static const IconData add_regular =
+ IconData(0xe90c, fontFamily: _kFontFam, fontPackage: _kFontPkg);
+ static const IconData copy_regular =
+ IconData(0xe90d, fontFamily: _kFontFam, fontPackage: _kFontPkg);
+ static const IconData note_regular =
+ IconData(0xe90e, fontFamily: _kFontFam, fontPackage: _kFontPkg);
+ static const IconData font_size_solid =
+ IconData(0xe90f, fontFamily: _kFontFam, fontPackage: _kFontPkg);
}
diff --git a/lib/main.dart b/lib/main.dart
index 1d51f59..ae284aa 100644
--- a/lib/main.dart
+++ b/lib/main.dart
@@ -15,6 +15,7 @@ import 'package:didvan/services/app_home_widget/home_widget_repository.dart';
import 'package:didvan/services/media/media.dart';
import 'package:didvan/services/notification/firebase_api.dart';
import 'package:didvan/services/notification/notification_service.dart';
+import 'package:didvan/views/ai/history_ai_chat_state.dart';
import 'package:didvan/views/podcasts/podcasts_state.dart';
import 'package:didvan/views/podcasts/studio_details/studio_details_state.dart';
import 'package:firebase_core/firebase_core.dart';
@@ -140,6 +141,9 @@ class _DidvanState extends State with WidgetsBindingObserver {
ChangeNotifierProvider(
create: (context) => StudioDetailsState(),
),
+ ChangeNotifierProvider(
+ create: (context) => HistoryAiChatState(),
+ ),
],
child: Consumer(
builder: (context, themeProvider, child) => Container(
diff --git a/lib/models/ai/ai_chat_args.dart b/lib/models/ai/ai_chat_args.dart
new file mode 100644
index 0000000..0caf703
--- /dev/null
+++ b/lib/models/ai/ai_chat_args.dart
@@ -0,0 +1,8 @@
+import 'package:didvan/models/ai/bots_model.dart';
+
+class AiChatArgs {
+ final BotsModel bot;
+ final int? chatId;
+
+ AiChatArgs({required this.bot, this.chatId});
+}
diff --git a/lib/models/ai/bots_model.dart b/lib/models/ai/bots_model.dart
new file mode 100644
index 0000000..6a243ab
--- /dev/null
+++ b/lib/models/ai/bots_model.dart
@@ -0,0 +1,21 @@
+class BotsModel {
+ int? id;
+ String? name;
+ String? image;
+
+ BotsModel({this.id, this.name, this.image});
+
+ BotsModel.fromJson(Map json) {
+ id = json['id'];
+ name = json['name'];
+ image = json['image'];
+ }
+
+ Map toJson() {
+ final Map data = {};
+ data['id'] = id;
+ data['name'] = name;
+ data['image'] = image;
+ return data;
+ }
+}
diff --git a/lib/models/ai/chats_model.dart b/lib/models/ai/chats_model.dart
new file mode 100644
index 0000000..20282f4
--- /dev/null
+++ b/lib/models/ai/chats_model.dart
@@ -0,0 +1,108 @@
+import 'package:didvan/models/ai/bots_model.dart';
+
+class ChatsModel {
+ int? id;
+ int? userId;
+ int? botId;
+ String? title;
+ String? createdAt;
+ String? updatedAt;
+ BotsModel? bot;
+ List? prompts;
+
+ ChatsModel(
+ {this.id,
+ this.userId,
+ this.botId,
+ this.title,
+ this.createdAt,
+ this.updatedAt,
+ this.bot,
+ this.prompts});
+
+ ChatsModel.fromJson(Map json) {
+ id = json['id'];
+ userId = json['userId'];
+ botId = json['botId'];
+ title = json['title'];
+ createdAt = json['createdAt'];
+ updatedAt = json['updatedAt'];
+ bot = json['bot'] != null ? BotsModel.fromJson(json['bot']) : null;
+ if (json['prompts'] != null) {
+ prompts = [];
+ json['prompts'].forEach((v) {
+ prompts!.add(Prompts.fromJson(v));
+ });
+ }
+ }
+
+ Map toJson() {
+ final Map data = {};
+ data['id'] = id;
+ data['userId'] = userId;
+ data['botId'] = botId;
+ data['title'] = title;
+ data['createdAt'] = createdAt;
+ data['updatedAt'] = updatedAt;
+ if (bot != null) {
+ data['bot'] = bot!.toJson();
+ }
+ if (prompts != null) {
+ data['prompts'] = prompts!.map((v) => v.toJson()).toList();
+ }
+ return data;
+ }
+}
+
+class Prompts {
+ int? id;
+ int? chatId;
+ String? text;
+ String? role;
+ String? createdAt;
+ bool? finished;
+
+ Prompts(
+ {this.id,
+ this.chatId,
+ this.text,
+ this.role,
+ this.createdAt,
+ this.finished});
+
+ Prompts.fromJson(Map json) {
+ id = json['id'];
+ chatId = json['chatId'];
+ text = json['text'];
+ role = json['role'];
+ createdAt = json['createdAt'];
+ }
+
+ Map toJson() {
+ final Map data = {};
+ data['id'] = id;
+ data['chatId'] = chatId;
+ data['text'] = text;
+ data['role'] = role;
+ data['createdAt'] = createdAt;
+ return data;
+ }
+
+ Prompts copyWith({
+ int? id,
+ int? chatId,
+ String? text,
+ String? role,
+ String? createdAt,
+ bool? finished,
+ }) {
+ return Prompts(
+ id: id ?? this.id,
+ chatId: chatId ?? this.chatId,
+ text: text ?? this.text,
+ role: role ?? this.role,
+ createdAt: createdAt ?? this.createdAt,
+ finished: finished ?? this.finished,
+ );
+ }
+}
diff --git a/lib/models/view/action_sheet_data.dart b/lib/models/view/action_sheet_data.dart
index e695f52..f1b533d 100644
--- a/lib/models/view/action_sheet_data.dart
+++ b/lib/models/view/action_sheet_data.dart
@@ -17,8 +17,7 @@ class ActionSheetData {
final bool isBackgroundDropBlur;
final Color? backgroundColor;
-
- const ActionSheetData( {
+ const ActionSheetData({
required this.content,
this.title,
this.confrimTitle,
diff --git a/lib/routes/route_generator.dart b/lib/routes/route_generator.dart
index f4b9307..6ded8a5 100644
--- a/lib/routes/route_generator.dart
+++ b/lib/routes/route_generator.dart
@@ -1,3 +1,10 @@
+// ignore_for_file: unused_import
+
+import 'package:didvan/models/ai/ai_chat_args.dart';
+import 'package:didvan/views/ai/ai_chat_page.dart';
+import 'package:didvan/views/ai/ai_chat_state.dart';
+import 'package:didvan/views/ai/history_ai_chat_page.dart';
+import 'package:didvan/views/ai/history_ai_chat_state.dart';
import 'package:didvan/views/authentication/authentication.dart';
import 'package:didvan/views/authentication/authentication_state.dart';
import 'package:didvan/views/comments/comments.dart';
@@ -13,6 +20,7 @@ import 'package:didvan/views/home/infography/infography_screen.dart';
import 'package:didvan/views/home/infography/infography_screen_state.dart';
import 'package:didvan/views/home/main/main_page_state.dart';
import 'package:didvan/views/home/home_state.dart';
+import 'package:didvan/views/home/new_statistic/new_statistic.dart';
import 'package:didvan/views/home/new_statistic/new_statistics_state.dart';
import 'package:didvan/views/home/new_statistic/statistics_details/stat_cats_general_screen.dart';
import 'package:didvan/views/home/new_statistic/statistics_details/stat_cats_general_state.dart';
@@ -82,6 +90,11 @@ class RouteGenerator {
)),
);
+ // case Routes.newStatic:
+ // return _createRoute(ChangeNotifierProvider(
+ // create: (context) => NewStatisticState(),
+ // child: const NewStatistic()));
+
case Routes.notificationStatusStep:
return _createRoute(
ChangeNotifierProvider(
@@ -110,12 +123,11 @@ class RouteGenerator {
ChangeNotifierProvider(
create: (context) => StatisticState(),
),
- ChangeNotifierProvider(
- create: (context) => NewStatisticState(),
- ),
ChangeNotifierProvider(
create: (context) => BookmarksState(),
),
+ ChangeNotifierProvider(
+ create: (context) => NewStatisticState())
],
child: const Home(),
),
@@ -126,7 +138,9 @@ class RouteGenerator {
);
case Routes.profile:
return _createRoute(
- const ProfilePage(),
+ ChangeNotifierProvider(
+ create: (context) => GeneralSettingsState(),
+ child: const ProfilePage()),
);
case Routes.generalSettings:
return _createRoute(
@@ -285,6 +299,13 @@ class RouteGenerator {
(settings.arguments as Map)['onDeleted']),
),
);
+
+ case Routes.aiChat:
+ return _createRoute(ChangeNotifierProvider(
+ create: (context) => AiChatState(),
+ child: AiChatPage(
+ args: settings.arguments as AiChatArgs,
+ )));
default:
return _errorRoute(settings.name ?? '');
}
diff --git a/lib/routes/routes.dart b/lib/routes/routes.dart
index a837a47..fd655d5 100644
--- a/lib/routes/routes.dart
+++ b/lib/routes/routes.dart
@@ -1,5 +1,6 @@
class Routes {
static const String splash = '/';
+ static const String aiChat = '/ai-chat';
static const String home = '/home';
static const String radars = '/radars';
static const String news = '/news';
@@ -30,4 +31,5 @@ class Routes {
static const String notificationStatusStep = '/notification-status-step';
static const String notificationTime = '/notification-time';
static const String widgetSetting = '/widget-setting';
+ static const String newStatic = '/new-static';
}
diff --git a/lib/services/ai/ai_api_service.dart b/lib/services/ai/ai_api_service.dart
new file mode 100644
index 0000000..ede12f2
--- /dev/null
+++ b/lib/services/ai/ai_api_service.dart
@@ -0,0 +1,39 @@
+import 'dart:async';
+import 'dart:convert';
+
+import 'package:didvan/services/storage/storage.dart';
+import 'package:http/http.dart' as http;
+import 'package:http/http.dart';
+
+class AiApiService {
+ static const String baseUrl = 'https://api.didvan.app/ai';
+ static final _client = http.Client();
+
+ static Future initial(
+ {required final String url,
+ required final String message,
+ final int? chatId}) async {
+ final headers = {
+ "Content-Type": "application/json",
+ "Authorization": "Bearer ${await StorageService.getValue(key: 'token')}"
+ };
+
+ var request = http.Request('POST', Uri.parse(baseUrl + url))
+ ..headers.addAll(headers);
+
+ var body = {'prompt': message};
+ if (chatId != null) {
+ body.addAll({'chatId': chatId.toString()});
+ }
+ request.body = jsonEncode(body);
+ return request;
+ }
+
+ static Future getResponse(Request request) async {
+ final res = _client.send(request).timeout(
+ const Duration(seconds: 15),
+ );
+ final http.StreamedResponse response = await res;
+ return response.stream;
+ }
+}
diff --git a/lib/services/network/request.dart b/lib/services/network/request.dart
index 0827389..89a4e64 100644
--- a/lib/services/network/request.dart
+++ b/lib/services/network/request.dart
@@ -1,6 +1,9 @@
+// ignore_for_file: empty_catches
+
import 'dart:convert';
import 'dart:developer';
import 'package:didvan/services/storage/storage.dart';
+import 'package:flutter/foundation.dart';
// ignore: depend_on_referenced_packages
import 'package:http/http.dart' as http;
@@ -44,11 +47,11 @@ class RequestService {
if (body != null) _requestBody = body;
if (requestHeaders != null) _headers.addAll(requestHeaders);
if (useAutherization) _headers.addAll({'Authorization': 'Bearer $token'});
- // print('Authorization : Bearer $token');
- // _headers.addAll({
- // 'Authorization':
- // 'Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6NCwicm9sZUlkIjo0LCJhcHBJZCI6MCwiaWF0IjoxNzEzOTM1NzkwfQ.i-SO9tLy0M9j-_C2Wh8tdp01vtYGlDZIBFPygglHQF0'
- // });
+ if (kDebugMode) {
+ try {
+ print('Authorization : Bearer $token');
+ } catch (e) {}
+ }
if (body != null) _requestBody = body;
}
@@ -63,7 +66,7 @@ class RequestService {
headers: _headers,
)
.timeout(
- const Duration(seconds: 30),
+ const Duration(seconds: 100),
)
.catchError(
(e) => throw e,
@@ -83,7 +86,7 @@ class RequestService {
headers: _headers,
)
.timeout(
- const Duration(seconds: 10),
+ const Duration(seconds: 100),
)
.catchError(
(e) {
@@ -105,7 +108,7 @@ class RequestService {
headers: _headers,
)
.timeout(
- const Duration(seconds: 10),
+ const Duration(seconds: 100),
)
.catchError(
(e) => throw e,
@@ -146,7 +149,7 @@ class RequestService {
final streamedResponse = await request
.send()
.timeout(
- const Duration(seconds: 30),
+ const Duration(seconds: 100),
)
.catchError(
(e) => throw e,
@@ -167,7 +170,7 @@ class RequestService {
headers: _headers,
)
.timeout(
- const Duration(seconds: 10),
+ const Duration(seconds: 100),
)
.catchError(
(e) => throw e,
diff --git a/lib/services/network/request_helper.dart b/lib/services/network/request_helper.dart
index 942bd01..39c2d71 100644
--- a/lib/services/network/request_helper.dart
+++ b/lib/services/network/request_helper.dart
@@ -200,6 +200,15 @@ class RequestHelper {
static String deleteComment(int id) => '$baseUrl/comment/$id';
static String reportComment(int id) => '$baseUrl/comment/$id/report';
static String widgetNews() => '$baseUrl/user/widget';
+ static String aiChats() => '$baseUrl/ai/chat';
+ static String aiBots() => '$baseUrl/ai/bot';
+ static String aiSearchBots(String q) =>
+ '$baseUrl/ai/bot${_urlConcatGenerator([
+ MapEntry('q', q),
+ ])}';
+ static String aiAChat(int id) => '$baseUrl/ai/chat/$id';
+ static String aiChatId() => '$baseUrl/ai/chat/id';
+ static String aiDeleteChats() => '$baseUrl/ai/chat';
static String _urlConcatGenerator(List> additions) {
String result = '';
diff --git a/lib/services/notification/notification_service.dart b/lib/services/notification/notification_service.dart
index 2971b52..d1cdfff 100644
--- a/lib/services/notification/notification_service.dart
+++ b/lib/services/notification/notification_service.dart
@@ -1,4 +1,3 @@
-
import 'package:awesome_notifications/awesome_notifications.dart';
import 'package:didvan/models/notification_message.dart';
import 'package:didvan/services/app_home_widget/home_widget_repository.dart';
@@ -153,7 +152,6 @@ class NotificationService {
displayOnBackground: true,
displayOnForeground: true,
wakeUpScreen: true,
- icon: 'resource://drawable/logo',
roundedLargeIcon: data.notificationType!.contains('2'),
payload: data.toPayload()),
);
diff --git a/lib/utils/action_sheet.dart b/lib/utils/action_sheet.dart
index 4288b5b..602ebfc 100644
--- a/lib/utils/action_sheet.dart
+++ b/lib/utils/action_sheet.dart
@@ -180,7 +180,9 @@ class ActionSheetUtils {
await showDialog(
context: context,
builder: (context) => BackdropFilter(
- filter: ImageFilter.blur(sigmaX: data.isBackgroundDropBlur? 10 : 0, sigmaY: data.isBackgroundDropBlur? 10: 0) ,
+ filter: ImageFilter.blur(
+ sigmaX: data.isBackgroundDropBlur ? 10 : 0,
+ sigmaY: data.isBackgroundDropBlur ? 10 : 0),
child: Dialog(
backgroundColor:
data.backgroundColor ?? Theme.of(context).colorScheme.surface,
@@ -243,19 +245,20 @@ class ActionSheetUtils {
style: ButtonStyleMode.flat,
),
),
- if (data.hasDismissButton)
+ if (data.hasDismissButton && data.hasDismissButton)
const SizedBox(
width: 20,
),
- Expanded(
- child: DidvanButton(
- onPressed: () {
- pop();
- data.onConfirmed?.call();
- },
- title: data.confrimTitle ?? 'تایید',
+ if (data.hasDismissButton)
+ Expanded(
+ child: DidvanButton(
+ onPressed: () {
+ pop();
+ data.onConfirmed?.call();
+ },
+ title: data.confrimTitle ?? 'تایید',
+ ),
),
- ),
],
),
],
diff --git a/lib/utils/date_time.dart b/lib/utils/date_time.dart
index 2eb34a0..d6e3387 100644
--- a/lib/utils/date_time.dart
+++ b/lib/utils/date_time.dart
@@ -124,18 +124,22 @@ class DateTimeUtils {
}
static String timeWithAmPm(String input) {
- final dateTime = utcToLocalTime(input);
- bool isAm = true;
- int hour = 0;
- int minute = 0;
- if (dateTime.hour > 12) {
- isAm = false;
- hour = dateTime.hour - 12;
- } else {
- hour = dateTime.hour;
+ try {
+ final dateTime = utcToLocalTime(input);
+ bool isAm = true;
+ int hour = 0;
+ int minute = 0;
+ if (dateTime.hour > 12) {
+ isAm = false;
+ hour = dateTime.hour - 12;
+ } else {
+ hour = dateTime.hour;
+ }
+ minute = dateTime.minute;
+ return '$hour:${_timeNormalizer(minute)} ${isAm ? 'ق.ظ' : 'ب.ظ'}';
+ } catch (e) {
+ return '';
}
- minute = dateTime.minute;
- return '$hour:${_timeNormalizer(minute)} ${isAm ? 'ق.ظ' : 'ب.ظ'}';
}
static DateTime utcToLocalTime(String input) {
diff --git a/lib/views/ai/ai_chat_page.dart b/lib/views/ai/ai_chat_page.dart
new file mode 100644
index 0000000..8814568
--- /dev/null
+++ b/lib/views/ai/ai_chat_page.dart
@@ -0,0 +1,331 @@
+// ignore_for_file: library_private_types_in_public_api, deprecated_member_use
+
+import 'package:cached_network_image/cached_network_image.dart';
+import 'package:didvan/config/design_config.dart';
+import 'package:didvan/config/theme_data.dart';
+import 'package:didvan/constants/app_icons.dart';
+import 'package:didvan/constants/assets.dart';
+import 'package:didvan/main.dart';
+import 'package:didvan/models/ai/ai_chat_args.dart';
+import 'package:didvan/models/ai/chats_model.dart';
+import 'package:didvan/models/enums.dart';
+import 'package:didvan/models/view/alert_data.dart';
+import 'package:didvan/utils/action_sheet.dart';
+import 'package:didvan/utils/date_time.dart';
+import 'package:didvan/views/ai/ai_chat_state.dart';
+import 'package:didvan/views/ai/history_ai_chat_state.dart';
+import 'package:didvan/views/widgets/didvan/icon_button.dart';
+import 'package:didvan/views/widgets/didvan/text.dart';
+import 'package:didvan/views/widgets/state_handlers/empty_state.dart';
+import 'package:flutter/material.dart';
+import 'package:flutter/services.dart';
+import 'package:flutter_markdown/flutter_markdown.dart';
+import 'package:flutter_spinkit/flutter_spinkit.dart';
+import 'package:provider/provider.dart';
+
+class AiChatPage extends StatefulWidget {
+ final AiChatArgs args;
+ const AiChatPage({Key? key, required this.args}) : super(key: key);
+
+ @override
+ _AiChatPageState createState() => _AiChatPageState();
+}
+
+class _AiChatPageState extends State {
+ TextEditingController message = TextEditingController();
+
+ @override
+ void initState() {
+ final state = context.read();
+ state.chatId = widget.args.chatId;
+ if (state.chatId != null) {
+ state.getAllMessages(state.chatId!);
+ }
+ super.initState();
+ }
+
+ @override
+ Widget build(BuildContext context) {
+ return WillPopScope(
+ onWillPop: () async {
+ context.read().getChats();
+ return true;
+ },
+ child: Scaffold(
+ appBar: AppBar(
+ shadowColor: Theme.of(context).colorScheme.border,
+ title: Row(
+ children: [
+ Padding(
+ padding: const EdgeInsets.all(12.0),
+ child: ClipOval(
+ child: CachedNetworkImage(
+ width: 32,
+ height: 32,
+ imageUrl: widget.args.bot.image.toString(),
+ ),
+ ),
+ ),
+ Text('چت با ${widget.args.bot.name}'),
+ ],
+ ),
+ automaticallyImplyLeading: false,
+ actions: [
+ DidvanIconButton(
+ icon: DidvanIcons.angle_left_regular,
+ onPressed: () {
+ context.read().getChats();
+ navigatorKey.currentState!.pop();
+ },
+ )
+ ],
+ ),
+ body: Consumer(
+ builder: (BuildContext context, AiChatState state, Widget? child) {
+ return ValueListenableBuilder(
+ valueListenable: state.loading,
+ builder: (context, value, child) => value
+ ? Center(
+ child: Image.asset(
+ Assets.loadingAnimation,
+ width: 60,
+ height: 60,
+ ),
+ )
+ : state.messages.isEmpty
+ ? Center(
+ child: EmptyState(
+ asset: Assets.emptyChat,
+ title: 'اولین پیام را بنویسید...',
+ ),
+ )
+ : SingleChildScrollView(
+ reverse: true,
+ child: ListView.builder(
+ itemCount: state.messages.length,
+ controller: state.scrollController,
+ shrinkWrap: true,
+ physics: const NeverScrollableScrollPhysics(),
+ padding: const EdgeInsets.only(top: 12, bottom: 90),
+ itemBuilder: (context, index) {
+ final message = state.messages[index];
+ return messageBubble(
+ message, context, state, index);
+ },
+ ),
+ ),
+ );
+ },
+ ),
+ bottomSheet: Container(
+ width: MediaQuery.sizeOf(context).width,
+ padding: const EdgeInsets.symmetric(vertical: 12, horizontal: 8),
+ decoration: BoxDecoration(
+ border: Border(
+ top: BorderSide(
+ color: Theme.of(context).colorScheme.cardBorder,
+ ),
+ ),
+ color: Theme.of(context).colorScheme.surface,
+ ),
+ child: ValueListenableBuilder(
+ valueListenable: context.read().onResponsing,
+ builder: (context, value, child) => Row(
+ crossAxisAlignment: CrossAxisAlignment.start,
+ children: [
+ const SizedBox(
+ width: 12,
+ ),
+ SizedBox(
+ width: 46,
+ height: 46,
+ child: Center(
+ child: value
+ ? Center(
+ child: SpinKitThreeBounce(
+ size: 18,
+ color: Theme.of(context).colorScheme.primary,
+ ),
+ )
+ : DidvanIconButton(
+ icon: DidvanIcons.send_solid,
+ onPressed: () async {
+ if (message.text.isEmpty) {
+ return;
+ }
+
+ final state = context.read();
+ state.messages.add(Prompts(
+ text: message.text,
+ finished: true,
+ role: 'user',
+ createdAt: DateTime.now()
+ .subtract(const Duration(minutes: 210))
+ .toIso8601String(),
+ ));
+ message.clear();
+ await state.postMessage(widget.args.bot);
+ },
+ size: 32,
+ color: Theme.of(context).colorScheme.focusedBorder,
+ ),
+ ),
+ ),
+ const SizedBox(
+ width: 12,
+ ),
+ Expanded(
+ flex: 15,
+ child: Form(
+ child: TextFormField(
+ textInputAction: TextInputAction.newline,
+ style: Theme.of(context).textTheme.bodyMedium,
+ maxLines: 6,
+ minLines: 1,
+ // keyboardType: TextInputType.text,
+ controller: message,
+ enabled: !value,
+ decoration: InputDecoration(
+ border: InputBorder.none,
+ hintText: 'بنویسید...',
+ hintStyle: Theme.of(context)
+ .textTheme
+ .bodySmall!
+ .copyWith(
+ color:
+ Theme.of(context).colorScheme.disabledText),
+ ),
+ onChanged: (value) {},
+ ),
+ ),
+ ),
+ ],
+ ),
+ ),
+ ),
+ ),
+ );
+ }
+
+ Padding messageBubble(
+ Prompts message, BuildContext context, AiChatState state, int index) {
+ MarkdownStyleSheet defaultMarkdownStyleSheet = MarkdownStyleSheet(
+ code: TextStyle(
+ backgroundColor: Theme.of(context).colorScheme.black,
+ color: Theme.of(context).colorScheme.white,
+ ),
+ codeblockPadding: const EdgeInsets.all(8),
+ codeblockDecoration: BoxDecoration(
+ borderRadius: BorderRadius.circular(4),
+ color: Theme.of(context).colorScheme.black));
+ return Padding(
+ padding: const EdgeInsets.symmetric(horizontal: 20, vertical: 4),
+ child: Column(
+ mainAxisSize: MainAxisSize.min,
+ crossAxisAlignment: message.role.toString().contains('user')
+ ? CrossAxisAlignment.start
+ : CrossAxisAlignment.end,
+ children: [
+ Row(
+ mainAxisAlignment: message.role.toString().contains('user')
+ ? MainAxisAlignment.start
+ : MainAxisAlignment.end,
+ children: [
+ Container(
+ padding:
+ const EdgeInsets.symmetric(vertical: 8, horizontal: 16),
+ decoration: BoxDecoration(
+ borderRadius: DesignConfig.mediumBorderRadius.copyWith(
+ bottomLeft: !message.role.toString().contains('user')
+ ? Radius.zero
+ : null,
+ bottomRight: message.role.toString().contains('user')
+ ? Radius.zero
+ : null,
+ ),
+ color: (message.role.toString().contains('user')
+ ? Theme.of(context).colorScheme.surface
+ : Theme.of(context).colorScheme.focused)
+ .withOpacity(0.9),
+ border: Border.all(
+ color: Theme.of(context).colorScheme.border,
+ width: 0.5,
+ ),
+ ),
+ child: Container(
+ constraints: BoxConstraints(
+ maxWidth: MediaQuery.sizeOf(context).width / 1.5),
+ child: state.messages[index].finished != null &&
+ !state.messages[index].finished!
+ ? StreamBuilder(
+ stream: state.messageOnstream,
+ builder: (context, snapshot) {
+ if (!snapshot.hasData) {
+ return const SizedBox();
+ }
+ return Markdown(
+ data: "${snapshot.data}...",
+ selectable: false,
+ shrinkWrap: true,
+ physics: const NeverScrollableScrollPhysics(),
+ styleSheet: defaultMarkdownStyleSheet);
+ },
+ )
+ : Column(
+ children: [
+ Markdown(
+ data: state.messages[index].text.toString(),
+ selectable: true,
+ shrinkWrap: true,
+ physics: const NeverScrollableScrollPhysics(),
+ styleSheet: defaultMarkdownStyleSheet,
+ ),
+ if (!message.role.toString().contains('user'))
+ Row(
+ mainAxisAlignment: MainAxisAlignment.end,
+ children: [
+ Padding(
+ padding: const EdgeInsets.all(8.0),
+ child: InkWell(
+ onTap: () async {
+ await Clipboard.setData(ClipboardData(
+ text: state.messages[index].text
+ .toString()));
+ ActionSheetUtils.showAlert(AlertData(
+ message: "متن با موفقیت کپی شد",
+ aLertType: ALertType.success));
+ },
+ child: Icon(
+ DidvanIcons.copy_regular,
+ size: 18,
+ color: Theme.of(context)
+ .colorScheme
+ .focusedBorder,
+ ),
+ ),
+ )
+ ],
+ )
+ ],
+ ),
+ ),
+ )
+ ],
+ ),
+ const SizedBox(height: 4),
+ Row(
+ mainAxisSize: MainAxisSize.min,
+ children: [
+ DidvanText(
+ DateTimeUtils.timeWithAmPm(message.createdAt.toString()),
+ // DateTimeUtils.timeWithAmPm(message.createdAt),
+ style: Theme.of(context).textTheme.labelSmall,
+ color: Theme.of(context).colorScheme.caption,
+ ),
+ ],
+ ),
+ ],
+ ),
+ );
+ }
+}
diff --git a/lib/views/ai/ai_chat_state.dart b/lib/views/ai/ai_chat_state.dart
new file mode 100644
index 0000000..34726d5
--- /dev/null
+++ b/lib/views/ai/ai_chat_state.dart
@@ -0,0 +1,140 @@
+import 'dart:convert';
+
+import 'package:didvan/models/ai/bots_model.dart';
+import 'package:didvan/models/ai/chats_model.dart';
+import 'package:didvan/models/enums.dart';
+import 'package:didvan/models/view/alert_data.dart';
+import 'package:didvan/providers/core.dart';
+import 'package:didvan/services/ai/ai_api_service.dart';
+import 'package:didvan/services/network/request.dart';
+import 'package:didvan/services/network/request_helper.dart';
+import 'package:didvan/utils/action_sheet.dart';
+import 'package:flutter/cupertino.dart';
+import 'package:flutter/material.dart';
+
+class AiChatState extends CoreProvier {
+ Stream messageOnstream = const Stream.empty();
+ List messages = [];
+ ValueNotifier onResponsing = ValueNotifier(false);
+ ValueNotifier loading = ValueNotifier(false);
+ final ScrollController scrollController = ScrollController();
+ int? chatId;
+
+ Future _scrolledEnd() async {
+ WidgetsBinding.instance.addPostFrameCallback((_) async {
+ await scrollController.animateTo(
+ scrollController.position.minScrollExtent,
+ duration: const Duration(milliseconds: 600),
+ curve: Curves.easeInOut,
+ );
+ });
+ }
+
+ Future _onError(e) async {
+ onResponsing.value = false;
+ messages.removeLast();
+ messages.removeLast();
+ messageOnstream = const Stream.empty();
+
+ await ActionSheetUtils.showAlert(AlertData(
+ message: 'خطا در برقراری ارتباط', aLertType: ALertType.error));
+
+ update();
+ }
+
+ Future getChatId() async {
+ final service = RequestService(
+ RequestHelper.aiChatId(),
+ );
+ await service.httpGet();
+ if (service.isSuccess) {
+ final id = service.result['id'];
+ chatId = id;
+ }
+ return service;
+ }
+
+ Future getAllMessages(int chatId) async {
+ loading.value = true;
+ onResponsing.value = true;
+ final service = RequestService(
+ RequestHelper.aiAChat(chatId),
+ );
+ await service.httpGet();
+ if (service.isSuccess) {
+ messages.clear();
+ final allMessages = service.result['prompts'];
+ for (var i = 0; i < allMessages.length; i++) {
+ messages.add(Prompts.fromJson(allMessages[i]));
+ // chats.add("chats: $chats");
+ }
+ appState = AppState.idle;
+ loading.value = false;
+ onResponsing.value = false;
+
+ // Add this code to scroll to maxScrollExtent after the ListView is built
+ update();
+
+ return;
+ }
+ appState = AppState.failed;
+ loading.value = false;
+ onResponsing.value = false;
+
+ update();
+ }
+
+ Future postMessage(BotsModel bot) async {
+ onResponsing.value = true;
+
+ update();
+ await _scrolledEnd();
+ String message = messages.last.text!;
+
+ messages.add(Prompts(
+ finished: false,
+ text: '...',
+ role: 'bot',
+ createdAt: DateTime.now()
+ .subtract(const Duration(minutes: 210))
+ .toIso8601String()));
+ final req = await AiApiService.initial(
+ url: '/${bot.id}/${bot.name}'.toLowerCase(),
+ message: message,
+ chatId: chatId);
+ final res = await AiApiService.getResponse(req).catchError((e) {
+ _onError(e);
+ throw e;
+ });
+ String responseMessgae = '';
+ var r = res.listen((value) async {
+ var str = utf8.decode(value);
+ responseMessgae += str;
+ messageOnstream = Stream.value(responseMessgae);
+
+ update();
+ _scrolledEnd();
+ });
+
+ r.onDone(() async {
+ if (chatId == null) {
+ final service = await getChatId();
+ if (!service.isSuccess) {
+ _onError(null);
+ return;
+ }
+ }
+ onResponsing.value = false;
+ messages.last = messages.last.copyWith(
+ finished: true,
+ text: responseMessgae,
+ );
+ messageOnstream = const Stream.empty();
+
+ update();
+ _scrolledEnd();
+ });
+
+ r.onError(_onError);
+ }
+}
diff --git a/lib/views/ai/history_ai_chat_page.dart b/lib/views/ai/history_ai_chat_page.dart
new file mode 100644
index 0000000..9081880
--- /dev/null
+++ b/lib/views/ai/history_ai_chat_page.dart
@@ -0,0 +1,367 @@
+// ignore_for_file: library_private_types_in_public_api
+
+import 'dart:async';
+
+import 'package:cached_network_image/cached_network_image.dart';
+import 'package:didvan/config/theme_data.dart';
+import 'package:didvan/constants/app_icons.dart';
+import 'package:didvan/constants/assets.dart';
+import 'package:didvan/main.dart';
+import 'package:didvan/models/ai/ai_chat_args.dart';
+import 'package:didvan/models/view/action_sheet_data.dart';
+import 'package:didvan/routes/routes.dart';
+import 'package:didvan/utils/action_sheet.dart';
+import 'package:didvan/utils/date_time.dart';
+import 'package:didvan/views/ai/history_ai_chat_state.dart';
+import 'package:didvan/views/widgets/didvan/scaffold.dart';
+import 'package:didvan/views/widgets/didvan/text.dart';
+import 'package:didvan/views/widgets/shimmer_placeholder.dart';
+import 'package:didvan/views/widgets/state_handlers/empty_state.dart';
+import 'package:didvan/views/widgets/state_handlers/sliver_state_handler.dart';
+import 'package:flutter/material.dart';
+import 'package:provider/provider.dart';
+
+class HistoryAiChatPage extends StatefulWidget {
+ const HistoryAiChatPage({Key? key}) : super(key: key);
+
+ @override
+ _HistoryAiChatPageState createState() => _HistoryAiChatPageState();
+}
+
+class _HistoryAiChatPageState extends State {
+ ScrollController scrollController = ScrollController();
+ @override
+ void initState() {
+ final state = context.read();
+ Future.delayed(
+ Duration.zero,
+ () => state.getChats(),
+ );
+
+ super.initState();
+ }
+
+ @override
+ Widget build(BuildContext context) {
+ return DidvanScaffold(
+ hidePlayer: true,
+ physics: const BouncingScrollPhysics(),
+ padding: const EdgeInsets.only(left: 16, right: 16, bottom: 92),
+ floatingActionButton: openAiListBtn(context),
+ scrollController: scrollController,
+ slivers: [
+ Consumer(
+ builder: (context, state, child) {
+ return SliverStateHandler(
+ state: state,
+ emptyState: EmptyState(
+ asset: Assets.emptyResult,
+ title: 'لیست خالی است',
+ ),
+ enableEmptyState: state.chats.isEmpty,
+ placeholder: const _HistoryPlaceholder(),
+ placeholderCount: 8,
+
+ // builder: (context, state, index) => _HistoryPlaceholder(),
+ builder: (context, state, index) {
+ final chat = state.chats[index];
+
+ return InkWell(
+ onTap: () {
+ if (state.chatsToDelete.isEmpty) {
+ navigatorKey.currentState!.pushNamed(Routes.aiChat,
+ arguments:
+ AiChatArgs(bot: chat.bot!, chatId: chat.id!));
+ } else {
+ if (state.chatsToDelete.contains(chat.id)) {
+ state.chatsToDelete.remove(chat.id!);
+ } else {
+ state.chatsToDelete.add(chat.id!);
+ }
+ }
+ state.update();
+ },
+ onLongPress: () {
+ if (state.chatsToDelete.isEmpty) {
+ state.chatsToDelete.add(chat.id!);
+ }
+ state.update();
+ },
+ child: Container(
+ padding: const EdgeInsets.all(12),
+ decoration: BoxDecoration(
+ border: Border(
+ bottom: BorderSide(
+ color:
+ Theme.of(context).colorScheme.border))),
+ child: Stack(
+ children: [
+ Row(
+ crossAxisAlignment: CrossAxisAlignment.center,
+ children: [
+ const SizedBox(
+ width: 46,
+ height: 46,
+ ),
+ const SizedBox(
+ width: 18,
+ ),
+ Expanded(
+ child: Column(
+ crossAxisAlignment: CrossAxisAlignment.start,
+ children: [
+ Row(
+ mainAxisAlignment:
+ MainAxisAlignment.spaceBetween,
+ children: [
+ DidvanText(
+ chat.bot!.name.toString(),
+ fontWeight: FontWeight.bold,
+ ),
+ DidvanText(
+ DateTimeUtils.momentGenerator(
+ chat.updatedAt.toString()),
+ style:
+ const TextStyle(fontSize: 12)),
+ ],
+ ),
+ SizedBox(
+ child: DidvanText(
+ chat.prompts![0].text.toString(),
+ maxLines: 1,
+ overflow: TextOverflow.ellipsis,
+ ),
+ ),
+ ],
+ ),
+ ),
+ ],
+ ),
+ Positioned(
+ bottom: 0,
+ right: 0,
+ top: 0,
+ child: Padding(
+ padding: const EdgeInsets.all(4.0),
+ child: ClipOval(
+ child: CachedNetworkImage(
+ imageUrl: chat.bot!.image.toString(),
+ ),
+ ),
+ ),
+ ),
+ if (state.chatsToDelete.contains(chat.id))
+ Positioned(
+ right: 32,
+ bottom: 0,
+ child: Container(
+ // ignore: prefer_const_constructors
+ decoration: BoxDecoration(
+ color: Theme.of(context)
+ .scaffoldBackgroundColor,
+ shape: BoxShape.circle),
+ child: Icon(DidvanIcons.check_circle_solid,
+ size: 20,
+ color:
+ Theme.of(context).colorScheme.success),
+ ),
+ )
+ ],
+ ),
+ ),
+ );
+ },
+ childCount: state.chats.length,
+ onRetry: state.getChats);
+ },
+ )
+ ],
+ appBarData: null,
+ );
+ }
+
+ Widget openAiListBtn(BuildContext context) {
+ final watch = context.watch();
+ final state = context.read();
+ return FloatingActionButton(
+ backgroundColor: watch.chatsToDelete.isEmpty
+ ? Theme.of(context).colorScheme.primary
+ : Theme.of(context).colorScheme.error,
+ shape: const OvalBorder(),
+ mini: true,
+ onPressed: () {
+ if (watch.chatsToDelete.isEmpty) {
+ state.getBots();
+ state.search = '';
+ _botsDialogSelect(context);
+ } else {
+ state.addChatToDelete();
+ }
+ },
+ child: watch.chatsToDelete.isEmpty
+ ? const Icon(DidvanIcons.add_regular)
+ : const Icon(DidvanIcons.trash_regular),
+ );
+ }
+
+ void _botsDialogSelect(BuildContext context) {
+ final state = context.read();
+
+ ActionSheetUtils.context = context;
+ ActionSheetUtils.openDialog(
+ data: ActionSheetData(
+ hasConfirmButton: false,
+ hasDismissButton: false,
+ content: Column(
+ children: [
+ // Row(
+ // mainAxisAlignment: MainAxisAlignment.end,
+ // children: [
+ // Padding(
+ // padding: const EdgeInsets.symmetric(vertical: 8.0),
+ // child: InkWell(
+ // onTap: () {
+ // ActionSheetUtils.pop();
+ // },
+ // child: const Icon(DidvanIcons.close_solid)),
+ // )
+ // ],
+ // ),
+ // SearchField(
+ // title: 'هوش مصنوعی',
+ // value: state.search,
+ // onChanged: (value) {
+ // state.search = value;
+ // if (value.isEmpty) {
+ // state.getBots();
+ // return;
+ // }
+ // state.timer?.cancel();
+ // state.timer = Timer(const Duration(seconds: 1), () {
+ // state.getSearchBots(value);
+ // });
+ // },
+ // focusNode: FocusNode()),
+ // const SizedBox(
+ // height: 12,
+ // ),
+ SizedBox(
+ width: double.infinity,
+ height: MediaQuery.sizeOf(context).height / 3,
+ child: ValueListenableBuilder(
+ valueListenable: state.loadingBots,
+ builder: (context, value, child) => value
+ ? Center(
+ child: Image.asset(
+ Assets.loadingAnimation,
+ width: 60,
+ height: 60,
+ ),
+ )
+ : state.bots.isEmpty
+ ? Padding(
+ padding: const EdgeInsets.symmetric(
+ horizontal: 12.0),
+ child: EmptyState(
+ asset: Assets.emptyResult,
+ title: 'نتیجهای پیدا نشد',
+ height: 120,
+ ),
+ )
+ : ListView.builder(
+ padding:
+ const EdgeInsets.symmetric(vertical: 12),
+ itemCount: state.bots.length,
+ physics: const BouncingScrollPhysics(),
+ shrinkWrap: true,
+ itemBuilder: (context, index) {
+ final bot = state.bots[index];
+ return InkWell(
+ onTap: () {
+ ActionSheetUtils.pop();
+ navigatorKey.currentState!.pushNamed(
+ Routes.aiChat,
+ arguments: AiChatArgs(bot: bot));
+ },
+ child: Container(
+ alignment: Alignment.center,
+ padding: const EdgeInsets.symmetric(
+ vertical: 8),
+ decoration: BoxDecoration(
+ border: Border(
+ bottom: BorderSide(
+ color: Theme.of(context)
+ .colorScheme
+ .border,
+ width: 1))),
+ child: Row(
+ children: [
+ ClipOval(
+ child: CachedNetworkImage(
+ imageUrl: bot.image.toString(),
+ width: 42,
+ height: 42,
+ ),
+ ),
+ const SizedBox(width: 12),
+ Text(bot.name.toString())
+ ],
+ ),
+ ),
+ );
+ }),
+ ),
+ )
+ ],
+ )));
+ }
+}
+
+class _HistoryPlaceholder extends StatelessWidget {
+ const _HistoryPlaceholder({Key? key}) : super(key: key);
+
+ @override
+ Widget build(BuildContext context) {
+ return const Padding(
+ padding: EdgeInsets.symmetric(vertical: 12.0),
+ child: Row(
+ crossAxisAlignment: CrossAxisAlignment.start,
+ children: [
+ ClipOval(
+ child: ShimmerPlaceholder(
+ height: 42,
+ width: 42,
+ ),
+ ),
+ SizedBox(width: 16),
+ Expanded(
+ child: Column(
+ crossAxisAlignment: CrossAxisAlignment.start,
+ children: [
+ Row(
+ mainAxisAlignment: MainAxisAlignment.spaceBetween,
+ children: [
+ ShimmerPlaceholder(
+ height: 20,
+ width: 100,
+ ),
+ ShimmerPlaceholder(
+ height: 14,
+ width: 100,
+ ),
+ ],
+ ),
+ SizedBox(height: 12),
+ ShimmerPlaceholder(
+ height: 16,
+ width: double.infinity,
+ ),
+ SizedBox(height: 8),
+ ],
+ ),
+ ),
+ ],
+ ),
+ );
+ }
+}
diff --git a/lib/views/ai/history_ai_chat_state.dart b/lib/views/ai/history_ai_chat_state.dart
new file mode 100644
index 0000000..6da7030
--- /dev/null
+++ b/lib/views/ai/history_ai_chat_state.dart
@@ -0,0 +1,111 @@
+import 'dart:async';
+
+import 'package:didvan/models/ai/bots_model.dart';
+import 'package:didvan/models/ai/chats_model.dart';
+import 'package:didvan/models/enums.dart';
+import 'package:didvan/models/view/alert_data.dart';
+import 'package:didvan/providers/core.dart';
+import 'package:didvan/services/network/request.dart';
+import 'package:didvan/services/network/request_helper.dart';
+import 'package:didvan/utils/action_sheet.dart';
+import 'package:flutter/cupertino.dart';
+
+class HistoryAiChatState extends CoreProvier {
+ final List chats = [];
+ final List chatsToDelete = [];
+ final List bots = [];
+ ValueNotifier loadingBots = ValueNotifier(false);
+ Timer? timer;
+ String search = '';
+
+ Future getChats() async {
+ final service = RequestService(
+ RequestHelper.aiChats(),
+ );
+ await service.httpGet();
+ if (service.isSuccess) {
+ chats.clear();
+ final messages = service.result['chats'];
+ for (var i = 0; i < messages.length; i++) {
+ chats.add(ChatsModel.fromJson(messages[i]));
+ }
+ appState = AppState.idle;
+ update();
+ return;
+ }
+ appState = AppState.failed;
+ update();
+ }
+
+ Future getBots() async {
+ loadingBots.value = true;
+ final service = RequestService(
+ RequestHelper.aiBots(),
+ );
+ await service.httpGet();
+ if (service.isSuccess) {
+ bots.clear();
+ final messages = service.result['bots'];
+ for (var i = 0; i < messages.length; i++) {
+ bots.add(BotsModel.fromJson(messages[i]));
+ }
+ appState = AppState.idle;
+ loadingBots.value = false;
+ update();
+ return;
+ }
+ appState = AppState.failed;
+ loadingBots.value = false;
+ update();
+ }
+
+ Future getSearchBots(String q) async {
+ loadingBots.value = true;
+ final service = RequestService(
+ RequestHelper.aiSearchBots(q),
+ );
+ await service.httpGet();
+ if (service.isSuccess) {
+ bots.clear();
+ final messages = service.result['bots'];
+ for (var i = 0; i < messages.length; i++) {
+ bots.add(BotsModel.fromJson(messages[i]));
+ }
+ appState = AppState.idle;
+ loadingBots.value = false;
+ update();
+
+ return;
+ }
+ appState = AppState.failed;
+ loadingBots.value = false;
+ update();
+ }
+
+ Future addChatToDelete() async {
+ final service = RequestService(RequestHelper.aiDeleteChats(),
+ body: {"ids": chatsToDelete});
+ await service.delete();
+ if (service.isSuccess) {
+ final List cs = [];
+ for (var chat in chats) {
+ if (!chatsToDelete.contains(chat.id)) {
+ cs.add(chat);
+ }
+ }
+ chatsToDelete.clear();
+ chats.clear();
+ chats.addAll(cs);
+
+ appState = AppState.idle;
+ update();
+
+ return;
+ }
+ appState = AppState.failed;
+ await ActionSheetUtils.showAlert(AlertData(
+ message: 'خطا در برقراری ارتباط', aLertType: ALertType.error));
+
+ update();
+ }
+}
diff --git a/lib/views/home/bookmarks/bookmarks.dart b/lib/views/home/bookmarks/bookmarks.dart
index 92790b7..ef4ff4a 100644
--- a/lib/views/home/bookmarks/bookmarks.dart
+++ b/lib/views/home/bookmarks/bookmarks.dart
@@ -2,8 +2,10 @@ import 'dart:async';
import 'package:didvan/config/design_config.dart';
import 'package:didvan/constants/app_icons.dart';
+import 'package:didvan/models/view/app_bar_data.dart';
import 'package:didvan/routes/routes.dart';
import 'package:didvan/views/home/bookmarks/bookmark_state.dart';
+import 'package:didvan/views/widgets/didvan/scaffold.dart';
import 'package:didvan/views/widgets/menu_item.dart';
import 'package:didvan/views/widgets/overview/multitype.dart';
// import 'package:didvan/views/widgets/search_field.dart';
@@ -39,7 +41,11 @@ class _BookmarksState extends State {
@override
Widget build(BuildContext context) {
final state = context.watch();
- return CustomScrollView(
+ return DidvanScaffold(
+ appBarData: AppBarData(title: 'رصدخانه من', hasBack: true, isSmall: true),
+ physics: const BouncingScrollPhysics(),
+ padding: const EdgeInsets.all(8.0),
+ hidePlayer: true,
slivers: [
SliverPadding(
padding: const EdgeInsets.symmetric(horizontal: 16),
diff --git a/lib/views/home/home.dart b/lib/views/home/home.dart
index 0ae4bb9..b989425 100644
--- a/lib/views/home/home.dart
+++ b/lib/views/home/home.dart
@@ -7,7 +7,7 @@ import 'package:didvan/providers/theme.dart';
import 'package:didvan/services/app_initalizer.dart';
import 'package:didvan/services/notification/notification_service.dart';
import 'package:didvan/utils/action_sheet.dart';
-import 'package:didvan/views/home/bookmarks/bookmarks.dart';
+import 'package:didvan/views/ai/history_ai_chat_page.dart';
import 'package:didvan/views/home/categories/categories_page.dart';
import 'package:didvan/views/home/main/main_page.dart';
import 'package:didvan/views/home/home_state.dart';
@@ -100,10 +100,11 @@ class _HomeState extends State
controller: _tabController,
children: const [
MainPage(),
+ CategoriesPage(),
+ HistoryAiChatPage(),
NewStatistic(),
//Statistic(),
- CategoriesPage(),
- Bookmarks(),
+ // Bookmarks(),
],
),
),
diff --git a/lib/views/home/new_statistic/new_statistic.dart b/lib/views/home/new_statistic/new_statistic.dart
index e9bb535..4c23bed 100644
--- a/lib/views/home/new_statistic/new_statistic.dart
+++ b/lib/views/home/new_statistic/new_statistic.dart
@@ -38,266 +38,172 @@ class _NewStatisticState extends State {
@override
Widget build(BuildContext context) {
- return Padding(
- padding: const EdgeInsets.all(8.0),
- child: SingleChildScrollView(
- child: Column(
- mainAxisAlignment: MainAxisAlignment.center,
- crossAxisAlignment: CrossAxisAlignment.stretch,
- children: [
- Center(
- child: Container(
- padding: const EdgeInsets.symmetric(horizontal: 12),
- color: Theme.of(context).colorScheme.background,
- child: DidvanText(
- 'دستهبندیهای کلان',
- color: Theme.of(context).colorScheme.title,
- style: Theme.of(context).textTheme.titleMedium,
- ),
+ return SingleChildScrollView(
+ child: Column(
+ mainAxisAlignment: MainAxisAlignment.center,
+ crossAxisAlignment: CrossAxisAlignment.stretch,
+ children: [
+ Center(
+ child: Container(
+ padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 16),
+ color: Theme.of(context).colorScheme.background,
+ child: DidvanText(
+ 'دستهبندیهای کلان',
+ color: Theme.of(context).colorScheme.title,
+ style: Theme.of(context).textTheme.titleMedium,
),
),
- const Padding(
- padding: EdgeInsets.only(
- left: 20,
- right: 20,
- top: 16,
- ),
- child: NewStatisticCategories(),
+ ),
+ const Padding(
+ padding: EdgeInsets.symmetric(
+ horizontal: 20,
),
- const DidvanDivider(
- verticalPadding: 4,
- ),
- StateHandler(
- enableEmptyState: false,
- onRetry: context.read().init,
- state: context.watch(),
- placeholder: Padding(
- padding: const EdgeInsets.only(top: 48.0),
- child: Column(
- children: [
- placeholder,
- const SizedBox(
- height: 8,
- ),
- placeholder,
- const SizedBox(
- height: 8,
- ),
- placeholder,
- const SizedBox(
- height: 8,
- ),
- placeholder,
- ],
- ),
- ),
- builder: (context, state) => Column(
- crossAxisAlignment: CrossAxisAlignment.stretch,
+ child: NewStatisticCategories(),
+ ),
+ const DidvanDivider(
+ verticalPadding: 4,
+ ),
+ StateHandler(
+ enableEmptyState: false,
+ onRetry: context.read().init,
+ state: context.watch(),
+ placeholder: Padding(
+ padding: const EdgeInsets.only(top: 48.0),
+ child: Column(
children: [
- GestureDetector(
- onTap: () => Future.delayed(Duration.zero, () {
- Navigator.of(context)
- .pushNamed(Routes.statGeneral, arguments: {
- "id": 7,
- "title": state.contents[0].header,
- }).then((value) => _reset());
- }),
- child: StatHeader(
- header: state.contents[0].header,
- icon: DidvanIcons.star_circle_solid,
- )),
- SizedBox(
- height: 100,
- width: 80,
- child: ListView.builder(
- scrollDirection: Axis.horizontal,
- shrinkWrap: true,
- physics: const ScrollPhysics(),
- itemCount: state.contents[0].contents.length,
- itemBuilder: (context, index) => StatMainCard(
- statistic: state.contents[0].contents[index],
- ),
- ),
+ placeholder,
+ const SizedBox(
+ height: 46,
),
- const DidvanDivider(
- verticalPadding: 4,
+ placeholder,
+ const SizedBox(
+ height: 46,
),
- GestureDetector(
- onTap: () => Future.delayed(Duration.zero, () {
- Navigator.of(context).pushNamed(Routes.statGeneral,
- arguments: {
- "id": 1,
- "title": state.contents[1].header
- });
- }).then((value) => _reset()),
- child: StatHeader(
- header: state.contents[1].header,
- icon: DidvanIcons.currency_solid,
- )),
- SizedBox(
- height: 100,
- width: 80,
- child: ListView.builder(
- scrollDirection: Axis.horizontal,
- shrinkWrap: true,
- physics: const ScrollPhysics(),
- itemCount: state.contents[1].contents.length,
- itemBuilder: (context, index) => StatMainCard(
- statistic: state.contents[1].contents[index]))),
- const DidvanDivider(
- verticalPadding: 4,
+ placeholder,
+ const SizedBox(
+ height: 46,
),
- GestureDetector(
- onTap: () => Future.delayed(Duration.zero, () {
- Navigator.of(context).pushNamed(Routes.statGeneral,
- arguments: {
- "id": 2,
- "title": state.contents[2].header
- }).then((value) => _reset());
- }),
- child: StatHeader(
- header: state.contents[2].header,
- icon: DidvanIcons.bitcoin_solid,
- )),
- SizedBox(
- height: 100,
- width: 80,
- child: ListView.builder(
- scrollDirection: Axis.horizontal,
- shrinkWrap: true,
- physics: const ScrollPhysics(),
- itemCount: state.contents[2].contents.length,
- itemBuilder: (context, index) => StatMainCard(
- statistic: state.contents[2].contents[index]))),
- const DidvanDivider(
- verticalPadding: 4,
- ),
- GestureDetector(
- onTap: () => Future.delayed(Duration.zero, () {
- Navigator.of(context).pushNamed(Routes.statGeneral,
- arguments: {
- "id": 3,
- "title": state.contents[3].header
- });
- }).then((value) => _reset()),
- child: StatHeader(
- header: state.contents[3].header,
- icon: DidvanIcons.metal_solid,
- ),
- ),
- SizedBox(
- height: 100,
- width: 80,
- child: ListView.builder(
- scrollDirection: Axis.horizontal,
- shrinkWrap: true,
- physics: const ScrollPhysics(),
- itemCount: state.contents[3].contents.length,
- itemBuilder: (context, index) => StatMainCard(
- statistic: state.contents[3].contents[index]))),
- const DidvanDivider(
- verticalPadding: 4,
- ),
- GestureDetector(
- onTap: () => Future.delayed(Duration.zero, () {
- Navigator.of(context).pushNamed(Routes.statGeneral,
- arguments: {
- "id": 4,
- "title": state.contents[4].header
- }).then((value) => _reset());
- }),
- child: StatHeader(
- header: state.contents[4].header,
- icon: DidvanIcons.commodity_solid,
- )),
- SizedBox(
- height: 100,
- width: 80,
- child: ListView.builder(
- scrollDirection: Axis.horizontal,
- shrinkWrap: true,
- physics: const ScrollPhysics(),
- itemCount: state.contents[4].contents.length,
- itemBuilder: (context, index) => StatMainCard(
- statistic: state.contents[4].contents[index]))),
- const DidvanDivider(
- verticalPadding: 4,
- ),
- GestureDetector(
- onTap: () => Future.delayed(Duration.zero, () {
- Navigator.of(context)
- .pushNamed(Routes.statGeneral, arguments: {
- "id": 5,
- "title": state.contents[5].header,
- }).then((value) => _reset());
- }),
- child: StatHeader(
- header: state.contents[5].header,
- icon: DidvanIcons.industry_solid,
- )),
- SizedBox(
- height: 100,
- width: 80,
- child: ListView.builder(
- scrollDirection: Axis.horizontal,
- shrinkWrap: true,
- physics: const ScrollPhysics(),
- itemCount: state.contents[5].contents.length,
- itemBuilder: (context, index) => StatMainCard(
- id: 5,
- statistic: state.contents[5].contents[index]))),
+ placeholder,
],
),
),
- ],
- ),
+ builder: (context, state) => Column(
+ crossAxisAlignment: CrossAxisAlignment.stretch,
+ children: [
+ itemsInStatics(context, state, 0),
+ itemsInStatics(context, state, 1),
+ itemsInStatics(context, state, 2),
+ itemsInStatics(context, state, 3),
+ itemsInStatics(context, state, 4),
+ itemsInStatics(context, state, 5, hasDivider: false),
+ ],
+ ),
+ ),
+ ],
),
);
}
+ Widget itemsInStatics(BuildContext context, NewStatisticState state, int id,
+ {final bool? hasDivider}) {
+ bool d = hasDivider ?? true;
+ return state.contents[id].contents.isEmpty
+ ? const SizedBox()
+ : Padding(
+ padding: const EdgeInsets.only(top: 12.0),
+ child: Column(
+ crossAxisAlignment: CrossAxisAlignment.stretch,
+ children: [
+ GestureDetector(
+ onTap: () => Future.delayed(Duration.zero, () {
+ Navigator.of(context)
+ .pushNamed(Routes.statGeneral, arguments: {
+ "id": id == 0 ? 7 : id,
+ "title": state.contents[id].header,
+ }).then((value) => _reset());
+ }),
+ child: StatHeader(
+ header: state.contents[id].header,
+ icon: DidvanIcons.star_circle_solid,
+ )),
+ SizedBox(
+ height: 100,
+ width: 80,
+ child: ListView.builder(
+ scrollDirection: Axis.horizontal,
+ shrinkWrap: true,
+ physics: const ScrollPhysics(),
+ itemCount: state.contents[id].contents.length,
+ itemBuilder: (context, index) => StatMainCard(
+ statistic: state.contents[id].contents[index],
+ ),
+ ),
+ ),
+ if (d)
+ const DidvanDivider(
+ verticalPadding: 4,
+ ),
+ ],
+ ),
+ );
+ }
+
static Widget get placeholder => const Column(
children: [
- Row(
- mainAxisAlignment: MainAxisAlignment.spaceBetween,
- children: [
- ShimmerPlaceholder(
- height: 16,
- width: 100,
- ),
- ShimmerPlaceholder(
- height: 16,
- width: 50,
- )
- ],
+ Padding(
+ padding: EdgeInsets.symmetric(horizontal: 8.0),
+ child: Row(
+ mainAxisAlignment: MainAxisAlignment.spaceBetween,
+ children: [
+ ShimmerPlaceholder(
+ height: 16,
+ width: 100,
+ ),
+ ShimmerPlaceholder(
+ height: 16,
+ width: 50,
+ )
+ ],
+ ),
),
SizedBox(
- height: 8,
+ height: 18,
),
- Row(
+ Flex(
+ direction: Axis.horizontal,
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
- DidvanCard(
- child: ShimmerPlaceholder(
- height: 80,
- width: 60,
+ Flexible(
+ flex: 1,
+ child: Padding(
+ padding: EdgeInsets.symmetric(horizontal: 8.0),
+ child: DidvanCard(
+ child: ShimmerPlaceholder(
+ height: 60,
+ ),
+ ),
),
),
- DidvanCard(
- child: ShimmerPlaceholder(
- height: 80,
- width: 60,
+ Flexible(
+ flex: 1,
+ child: Padding(
+ padding: EdgeInsets.symmetric(horizontal: 8.0),
+ child: DidvanCard(
+ child: ShimmerPlaceholder(
+ height: 60,
+ ),
+ ),
),
),
- DidvanCard(
- child: ShimmerPlaceholder(
- height: 80,
- width: 60,
- ),
- ),
- DidvanCard(
- child: ShimmerPlaceholder(
- height: 80,
- width: 60,
+ Flexible(
+ flex: 1,
+ child: Padding(
+ padding: EdgeInsets.symmetric(horizontal: 8.0),
+ child: DidvanCard(
+ child: ShimmerPlaceholder(
+ height: 60,
+ ),
+ ),
),
),
],
diff --git a/lib/views/home/widgets/categories.dart b/lib/views/home/widgets/categories.dart
index ced79fd..5bce41f 100644
--- a/lib/views/home/widgets/categories.dart
+++ b/lib/views/home/widgets/categories.dart
@@ -19,8 +19,8 @@ class MainCategories extends StatelessWidget {
);
} else if (link.startsWith('tab-')) {
final state = context.read();
- state.currentPageIndex = 1;
- state.tabController.animateTo(1);
+ state.currentPageIndex = 3;
+ state.tabController.animateTo(3);
} else {
Navigator.of(context).pushNamed(link);
}
diff --git a/lib/views/profile/general_settings/settings_state.dart b/lib/views/profile/general_settings/settings_state.dart
index 3474fc6..46871b2 100644
--- a/lib/views/profile/general_settings/settings_state.dart
+++ b/lib/views/profile/general_settings/settings_state.dart
@@ -1,4 +1,5 @@
import 'package:didvan/models/enums.dart';
+import 'package:didvan/models/home_page_content/home_page_content.dart';
import 'package:didvan/providers/core.dart';
import 'package:didvan/services/network/request.dart';
import 'package:didvan/services/network/request_helper.dart';
@@ -15,6 +16,41 @@ class GeneralSettingsState extends CoreProvier {
String _brightness = 'light';
String time = "";
+ bool showSettings = false;
+ bool showThemes = false;
+ bool showContactUs = false;
+
+ int unread = 10;
+ late MainPageContent content;
+
+ void markChangeHandler(String type, int id, bool value) {
+ content.lists
+ .firstWhere((element) => element.type == type)
+ .contents
+ .firstWhere((element) => element.id == id)
+ .marked = value;
+ notifyListeners();
+ }
+
+ Future _getMainPageContent() async {
+ final service = RequestService(RequestHelper.mainPageContent);
+
+ await service.httpGet();
+ if (service.isSuccess) {
+ content = MainPageContent.fromJson(service.result);
+ unread = service.result['unread'];
+ appState = AppState.idle;
+ return;
+ }
+ appState = AppState.failed;
+ }
+
+ void init() {
+ Future.delayed(Duration.zero, () {
+ _getMainPageContent();
+ });
+ }
+
Future getTime() async {
appState = AppState.busy;
@@ -23,7 +59,7 @@ class GeneralSettingsState extends CoreProvier {
);
await service.httpGet();
if (service.isSuccess) {
- time = service.data('time');
+ time = service.data('time');
appState = AppState.idle;
} else {
@@ -33,7 +69,6 @@ class GeneralSettingsState extends CoreProvier {
update();
}
-
set notificationTimeRange(List value) {
_notificationTimeRange = value;
StorageService.setValue(
diff --git a/lib/views/profile/profile.dart b/lib/views/profile/profile.dart
index a736c23..2fda0e0 100644
--- a/lib/views/profile/profile.dart
+++ b/lib/views/profile/profile.dart
@@ -1,102 +1,453 @@
+import 'package:didvan/config/design_config.dart';
+import 'package:didvan/config/theme_data.dart';
import 'package:didvan/constants/app_icons.dart';
+import 'package:didvan/constants/assets.dart';
+import 'package:didvan/models/view/action_sheet_data.dart';
import 'package:didvan/models/view/app_bar_data.dart';
+import 'package:didvan/providers/theme.dart';
import 'package:didvan/providers/user.dart';
import 'package:didvan/routes/routes.dart';
import 'package:didvan/services/storage/storage.dart';
+import 'package:didvan/utils/action_sheet.dart';
+import 'package:didvan/views/profile/general_settings/settings_state.dart';
+import 'package:didvan/views/widgets/animated_visibility.dart';
+import 'package:didvan/views/widgets/didvan/radial_button.dart';
import 'package:didvan/views/widgets/menu_item.dart';
import 'package:didvan/views/widgets/didvan/card.dart';
import 'package:didvan/views/widgets/didvan/divider.dart';
import 'package:didvan/views/widgets/didvan/scaffold.dart';
import 'package:didvan/views/widgets/didvan/text.dart';
import 'package:didvan/views/widgets/item_title.dart';
+import 'package:didvan/views/widgets/state_handlers/state_handler.dart';
import 'package:flutter/material.dart';
+import 'package:flutter_svg/svg.dart';
import 'package:provider/provider.dart';
import 'package:url_launcher/url_launcher.dart';
-class ProfilePage extends StatelessWidget {
+class ProfilePage extends StatefulWidget {
const ProfilePage({Key? key}) : super(key: key);
@override
- Widget build(BuildContext context) {
- return DidvanScaffold(
- padding: const EdgeInsets.all(16),
- appBarData: AppBarData(
- title: 'تنظیمات',
- ),
- children: [
- DidvanCard(
- child: Column(
- children: [
- MenuOption(
- title: 'ویرایش پروفایل',
- icon: DidvanIcons.user_edit_regular,
- suffix: context.watch().user.fullName,
- onTap: () =>
- Navigator.of(context).pushNamed(Routes.editProfile),
- ),
- const DidvanDivider(),
- MenuOption(
- title: 'تنظیمات',
- icon: DidvanIcons.setting_regular,
- onTap: () =>
- Navigator.of(context).pushNamed(Routes.generalSettings),
- ),
- const DidvanDivider(),
- MenuOption(
- title: 'خروج از حساب کاربری',
- icon: DidvanIcons.sign_out_regular,
- color: Theme.of(context).colorScheme.secondary,
- onTap: () async {
- StorageService.delete(key: 'token');
- Navigator.of(context).pushNamedAndRemoveUntil(
- Routes.splash,
- (_) => false,
- );
- },
- ),
- ],
- ),
- ),
- const ItemTitle(
- title: 'درباره ما',
- ),
- DidvanCard(
- child: Column(
- crossAxisAlignment: CrossAxisAlignment.start,
- children: [
- MenuOption(
- icon: DidvanIcons.info_circle_regular,
- title: 'معرفی دیدوان',
- onTap: () => launchUrl(Uri.parse('https://didvan.app/#info')),
- ),
- const DidvanDivider(),
- MenuOption(
- icon: DidvanIcons.support_regular,
- title: 'پیام به پشتیبانی',
- onTap: () {
- Navigator.of(context).pushNamed(
- Routes.direct,
- arguments: {'type': 'پشتیبانی اپلیکیشن'},
- );
- },
- ),
- const DidvanDivider(),
- MenuOption(
- icon: DidvanIcons.alert_regular,
- title: 'حریم خصوصی',
- onTap: () => launchUrl(
- Uri.parse('https://didvan.app/terms-of-use#privacy'),
- ),
- ),
- ],
- ),
- ),
- const SizedBox(height: 16),
- DidvanText(
- 'نسخه نرمافزار: 3.2.2',
- style: Theme.of(context).textTheme.bodySmall,
- ),
- ],
+ State createState() => _ProfilePageState();
+}
+
+class _ProfilePageState extends State {
+ String fontScaleSuffix(double fontSizeScale) {
+ final fontScale = fontSizeScale;
+ if (fontScale == 1) return 'متوسط';
+ if (fontScale == 1.15) return 'بزرگ';
+ return 'کوچک';
+ }
+
+ @override
+ void initState() {
+ super.initState();
+ context.read().init();
+
+ final state = context.read();
+ Future.delayed(
+ Duration.zero,
+ () => state.getTime(),
);
}
-}
\ No newline at end of file
+
+ @override
+ Widget build(BuildContext context) {
+ return Consumer(
+ builder: (context, state, child) => StateHandler(
+ onRetry: context.read().init,
+ state: context.read(),
+ builder: (context, state) => DidvanScaffold(
+ padding: const EdgeInsets.all(16),
+ appBarData: AppBarData(title: 'تنظیمات', hasBack: true),
+ children: [
+ DidvanCard(
+ child: Column(
+ children: [
+ MenuOption(
+ title: 'ویرایش پروفایل',
+ icon: DidvanIcons.user_edit_regular,
+ suffix: context.watch().user.fullName,
+ onTap: () => Navigator.of(context)
+ .pushNamed(Routes.editProfile),
+ ),
+ const DidvanDivider(),
+ MenuOption(
+ title: 'تنظیمات',
+ icon: DidvanIcons.setting_regular,
+ onTap: () {
+ state.showSettings = !state.showSettings;
+ state.update();
+ },
+ trailing: Icon(
+ state.showSettings
+ ? DidvanIcons.angle_up_regular
+ : DidvanIcons.angle_down_regular,
+ size: 18,
+ color: Theme.of(context).colorScheme.title,
+ )),
+ AnimatedVisibility(
+ duration: DesignConfig.lowAnimationDuration,
+ isVisible: state.showSettings,
+ child: Padding(
+ padding: const EdgeInsets.only(right: 8.0, top: 8),
+ child: Column(
+ children: [
+ Padding(
+ padding: const EdgeInsets.symmetric(
+ vertical: 12.0),
+ child: MenuOption(
+ title: 'زمان دریافت اعلان',
+ onTap: () =>
+ Navigator.of(context).pushNamed(
+ Routes.notificationTime,
+ arguments: {
+ "fromFav": false,
+ 'onTimeChanged': () => Future.delayed(
+ Duration.zero,
+ () => state.getTime(),
+ )
+ },
+ ),
+ icon: DidvanIcons.notification_regular,
+ suffix: state.time,
+ // suffix: 'از${DateTimeUtils.normalizeTimeDuration(
+ // Duration(minutes: state.notificationTimeRange[0]),
+ // )} تا ${DateTimeUtils.normalizeTimeDuration(
+ // Duration(minutes: state.notificationTimeRange[1]),
+ // )}',
+ ),
+ ),
+ Padding(
+ padding: const EdgeInsets.symmetric(
+ vertical: 12.0),
+ child: MenuOption(
+ title: 'شخصی سازی محتوا',
+ onTap: () => Navigator.of(context)
+ .pushNamed(Routes.favouritesStep,
+ arguments: {"toTimer": false}),
+ icon: DidvanIcons.note_regular,
+ // suffix: 'از${DateTimeUtils.normalizeTimeDuration(
+ // Duration(minutes: state.notificationTimeRange[0]),
+ // )} تا ${DateTimeUtils.normalizeTimeDuration(
+ // Duration(minutes: state.notificationTimeRange[1]),
+ // )}',
+ ),
+ ),
+ Padding(
+ padding: const EdgeInsets.symmetric(
+ vertical: 12.0),
+ child: MenuOption(
+ suffix: state.fontFamily == 'Dana-FA'
+ ? 'دانا'
+ : 'ایران سنس',
+ title: 'فونت برنامه',
+ onTap: _showFontFamilyBottomSheet,
+ icon: DidvanIcons.font_regular,
+ ),
+ ),
+ Padding(
+ padding: const EdgeInsets.symmetric(
+ vertical: 12.0),
+ child: MenuOption(
+ suffix:
+ fontScaleSuffix(state.fontSizeScale),
+ title: 'اندازه متن',
+ onTap: _showFontScaleBottomSheet,
+ icon: DidvanIcons.font_size_solid,
+ )),
+ Padding(
+ padding: const EdgeInsets.symmetric(
+ vertical: 12.0),
+ child: MenuOption(
+ title: 'ظاهر برنامه',
+ onTap: () {
+ state.showThemes = !state.showThemes;
+ state.update();
+ },
+ icon: DidvanIcons.theme_regular,
+ trailing: Icon(
+ state.showThemes
+ ? DidvanIcons.angle_up_regular
+ : DidvanIcons.angle_down_regular,
+ size: 18,
+ color: Theme.of(context)
+ .colorScheme
+ .title,
+ ))),
+ AnimatedVisibility(
+ isVisible: state.showThemes,
+ duration: DesignConfig.lowAnimationDuration,
+ child: Padding(
+ padding: const EdgeInsets.symmetric(
+ vertical: 12.0),
+ child: Row(
+ mainAxisAlignment:
+ MainAxisAlignment.spaceAround,
+ children: [
+ _themeItem(context, state, 'light'),
+ _themeItem(context, state, 'dark'),
+ ],
+ ),
+ ),
+ ),
+ ],
+ ),
+ ),
+ ),
+ const DidvanDivider(),
+ MenuOption(
+ title: 'خروج از حساب کاربری',
+ icon: DidvanIcons.sign_out_regular,
+ color: Theme.of(context).colorScheme.secondary,
+ onTap: () async {
+ StorageService.delete(key: 'token');
+ Navigator.of(context).pushNamedAndRemoveUntil(
+ Routes.splash,
+ (_) => false,
+ );
+ },
+ ),
+ ],
+ ),
+ ),
+ const ItemTitle(
+ title: 'درباره ما',
+ ),
+ DidvanCard(
+ child: Column(
+ crossAxisAlignment: CrossAxisAlignment.start,
+ children: [
+ MenuOption(
+ icon: DidvanIcons.info_circle_regular,
+ title: 'معرفی دیدوان',
+ onTap: () =>
+ launchUrl(Uri.parse('https://didvan.app/#info')),
+ ),
+ const DidvanDivider(),
+ MenuOption(
+ icon: DidvanIcons.contact_us_solid,
+ title: 'تماس با ما',
+ onTap: () {
+ state.showContactUs = !state.showContactUs;
+ state.update();
+ },
+ trailing: Icon(
+ state.showContactUs
+ ? DidvanIcons.angle_up_regular
+ : DidvanIcons.angle_down_regular,
+ size: 18,
+ color: Theme.of(context).colorScheme.title,
+ )),
+ AnimatedVisibility(
+ isVisible: state.showContactUs,
+ duration: DesignConfig.lowAnimationDuration,
+ child: Padding(
+ padding:
+ const EdgeInsets.only(right: 8.0, top: 8),
+ child: Column(
+ children: [
+ Padding(
+ padding: const EdgeInsets.symmetric(
+ vertical: 12),
+ child: MenuOption(
+ icon: DidvanIcons.support_regular,
+ title: 'پیام به پشتیبانی',
+ onTap: () {
+ Navigator.of(context).pushNamed(
+ Routes.direct,
+ arguments: {
+ 'type': 'پشتیبانی اپلیکیشن'
+ },
+ );
+ },
+ ),
+ ),
+ Padding(
+ padding: const EdgeInsets.only(top: 12),
+ child: MenuOption(
+ icon: DidvanIcons.chats_regular,
+ title: 'صندوق پیام',
+ onTap: () {
+ Navigator.of(context)
+ .pushNamed(Routes.directList)
+ .then(
+ (value) => state.init(),
+ );
+ },
+ trailing: Row(
+ children: [
+ if (state.unread > 0)
+ Container(
+ width: 18,
+ height: 18,
+ decoration: BoxDecoration(
+ shape: BoxShape.circle,
+ color: Theme.of(context)
+ .colorScheme
+ .secondary,
+ ),
+ alignment: Alignment.center,
+ child: DidvanText(
+ state.unread.toString(),
+ color: Colors.white,
+ fontSize: 12,
+ ),
+ ),
+ const SizedBox(
+ width: 12,
+ ),
+ Icon(
+ DidvanIcons.angle_left_regular,
+ size: 18,
+ color: Theme.of(context)
+ .colorScheme
+ .title,
+ )
+ ],
+ ),
+ ),
+ ),
+ ],
+ ),
+ )),
+ const DidvanDivider(),
+ MenuOption(
+ icon: DidvanIcons.alert_regular,
+ title: 'حریم خصوصی',
+ onTap: () => launchUrl(
+ Uri.parse(
+ 'https://didvan.app/terms-of-use#privacy'),
+ ),
+ ),
+ ],
+ ),
+ ),
+ const SizedBox(height: 16),
+ DidvanText(
+ 'نسخه نرمافزار: 3.2.2',
+ style: Theme.of(context).textTheme.bodySmall,
+ ),
+ ],
+ ),
+ ));
+ }
+
+ Future _showFontFamilyBottomSheet() async {
+ final themeProvider = context.read();
+ final state = context.read();
+ final family = state.fontFamily;
+ await ActionSheetUtils.showBottomSheet(
+ data: ActionSheetData(
+ content: StatefulBuilder(
+ builder: (context, setState) => Column(
+ children: [
+ DidvanRadialButton(
+ title: 'دانا',
+ fontFamily: 'Dana-FA',
+ onSelected: () {
+ state.fontFamily = 'Dana-FA';
+ setState(() {});
+ },
+ value: state.fontFamily == 'Dana-FA',
+ ),
+ const SizedBox(height: 24),
+ DidvanRadialButton(
+ title: 'ایران سنس',
+ fontFamily: 'Iransans-FA',
+ onSelected: () {
+ state.fontFamily = 'Iransans-FA';
+ setState(() {});
+ },
+ value: state.fontFamily == 'Iransans-FA',
+ ),
+ ],
+ ),
+ ),
+ title: 'انتخاب فونت برنامه',
+ titleIcon: DidvanIcons.font_regular,
+ onDismissed: () => state.fontFamily = family,
+ onConfirmed: () => themeProvider.fontFamily = state.fontFamily,
+ ),
+ );
+ }
+
+ Future _showFontScaleBottomSheet() async {
+ final themeProvider = context.read();
+ final state = context.read();
+ final scale = state.fontSizeScale;
+ await ActionSheetUtils.showBottomSheet(
+ data: ActionSheetData(
+ content: StatefulBuilder(
+ builder: (context, setState) => Column(
+ children: [
+ DidvanRadialButton(
+ title: 'بزرگ',
+ fontSize: 15 * 1.15,
+ onSelected: () {
+ state.fontSizeScale = 1.15;
+ setState(() {});
+ },
+ value: state.fontSizeScale == 1.15,
+ ),
+ const SizedBox(height: 24),
+ DidvanRadialButton(
+ title: 'متوسط',
+ onSelected: () {
+ state.fontSizeScale = 1;
+ setState(() {});
+ },
+ value: state.fontSizeScale == 1,
+ ),
+ const SizedBox(height: 24),
+ DidvanRadialButton(
+ title: 'کوچک',
+ fontSize: 15 * 0.85,
+ onSelected: () {
+ state.fontSizeScale = 0.85;
+ setState(() {});
+ },
+ value: state.fontSizeScale == 0.85,
+ ),
+ ],
+ ),
+ ),
+ title: 'انتخاب اندازه متن',
+ titleIcon: DidvanIcons.font_regular,
+ onDismissed: () => state.fontSizeScale = scale,
+ onConfirmed: () => themeProvider.fontScale = state.fontSizeScale,
+ ),
+ );
+ }
+
+ Widget _themeItem(
+ BuildContext context, GeneralSettingsState state, String brightness) {
+ final bool isDarkTheme = brightness == 'dark';
+ return GestureDetector(
+ onTap: () {
+ state.brightness = brightness;
+ if (isDarkTheme && DesignConfig.isDark) {
+ return;
+ } else if (!isDarkTheme && !DesignConfig.isDark) {
+ return;
+ } else {
+ if (isDarkTheme) {
+ context.read().themeMode = ThemeMode.dark;
+ } else {
+ context.read().themeMode = ThemeMode.light;
+ }
+ DesignConfig.updateSystemUiOverlayStyle();
+ }
+ },
+ child: Column(
+ children: [
+ SvgPicture.asset(isDarkTheme ? Assets.darkTheme : Assets.lightTheme),
+ const SizedBox(height: 8),
+ DidvanText(
+ isDarkTheme ? 'تیره' : 'روشن',
+ ),
+ ],
+ ),
+ );
+ }
+}
diff --git a/lib/views/widgets/didvan/app_bar.dart b/lib/views/widgets/didvan/app_bar.dart
index 2966f72..a805b89 100644
--- a/lib/views/widgets/didvan/app_bar.dart
+++ b/lib/views/widgets/didvan/app_bar.dart
@@ -36,17 +36,20 @@ class DidvanAppBar extends StatelessWidget implements PreferredSizeWidget {
),
child: Row(
children: [
- appBarData.hasBack? Column(
- children: [
- IconButton(
- onPressed: () => Navigator.of(context).pop(),
- color: Theme.of(context).colorScheme.title,
- icon: const Icon(
- DidvanIcons.back_regular,
- ),
- ),
- ],
- ):const SizedBox(),
+ appBarData.hasBack
+ ? Column(
+ mainAxisAlignment: MainAxisAlignment.center,
+ children: [
+ IconButton(
+ onPressed: () => Navigator.of(context).pop(),
+ color: Theme.of(context).colorScheme.title,
+ icon: const Icon(
+ DidvanIcons.back_regular,
+ ),
+ ),
+ ],
+ )
+ : const SizedBox(),
const SizedBox(width: 16),
Expanded(
child: Align(
diff --git a/lib/views/widgets/didvan/bnb.dart b/lib/views/widgets/didvan/bnb.dart
index 2b5d175..06eb1ca 100644
--- a/lib/views/widgets/didvan/bnb.dart
+++ b/lib/views/widgets/didvan/bnb.dart
@@ -52,23 +52,23 @@ class DidvanBNB extends StatelessWidget {
),
_NavBarItem(
isSelected: currentTabIndex == 1,
- title: 'آمار و داده',
- selectedIcon: DidvanIcons.stats__solid,
- unselectedIcon: DidvanIcons.stats__light,
+ title: 'دستهبندی',
+ selectedIcon: DidvanIcons.category_solid,
+ unselectedIcon: DidvanIcons.category_light,
onTap: () => onTabChanged(1),
),
_NavBarItem(
isSelected: currentTabIndex == 2,
- title: 'دستهبندی',
- selectedIcon: DidvanIcons.category_solid,
- unselectedIcon: DidvanIcons.category_light,
+ title: 'هوش مصنوعی',
+ selectedIcon: DidvanIcons.ai_solid,
+ unselectedIcon: DidvanIcons.ai_regular,
onTap: () => onTabChanged(2),
),
_NavBarItem(
isSelected: currentTabIndex == 3,
- title: 'رصدخانه من',
- selectedIcon: DidvanIcons.antenna_solid,
- unselectedIcon: DidvanIcons.antenna_light,
+ title: 'آمار و داده',
+ selectedIcon: DidvanIcons.stats__solid,
+ unselectedIcon: DidvanIcons.stats__light,
onTap: () => onTabChanged(3),
),
],
diff --git a/lib/views/widgets/didvan/scaffold.dart b/lib/views/widgets/didvan/scaffold.dart
index c16c0d7..d64fdd7 100644
--- a/lib/views/widgets/didvan/scaffold.dart
+++ b/lib/views/widgets/didvan/scaffold.dart
@@ -15,6 +15,7 @@ class DidvanScaffold extends StatefulWidget {
final ScrollController? scrollController;
final bool showSliversFirst;
final bool hidePlayer;
+ final Widget? floatingActionButton;
const DidvanScaffold({
Key? key,
@@ -28,6 +29,7 @@ class DidvanScaffold extends StatefulWidget {
this.scrollController,
this.showSliversFirst = false,
this.hidePlayer = false,
+ this.floatingActionButton,
}) : super(key: key);
@override
@@ -60,6 +62,7 @@ class _DidvanScaffoldState extends State {
MediaQuery.of(context).padding.bottom;
return Scaffold(
backgroundColor: widget.backgroundColor,
+ floatingActionButton: widget.floatingActionButton,
body: Padding(
padding: widget.appBarData == null
? EdgeInsets.zero
diff --git a/lib/views/widgets/logo_app_bar.dart b/lib/views/widgets/logo_app_bar.dart
index 2b65a9d..7cdcb6e 100644
--- a/lib/views/widgets/logo_app_bar.dart
+++ b/lib/views/widgets/logo_app_bar.dart
@@ -56,38 +56,25 @@ class LogoAppBar extends StatelessWidget implements PreferredSizeWidget {
),
Row(
children: [
- DidvanIconButton(
- icon: DidvanIcons.profile_light,
- size: 32,
- onPressed: () =>
- Navigator.of(context).pushNamed(Routes.profile),
- ),
- Container(
- height: 32,
- width: 1,
- color: Theme.of(context).colorScheme.border,
- ),
Consumer(
builder: (_, state, __) => Stack(
children: [
DidvanIconButton(
- icon: state.unread == 0
- ? DidvanIcons.message_light
- : DidvanIcons.message_solid,
+ icon: DidvanIcons.profile_light,
size: 32,
onPressed: () => Navigator.of(context)
- .pushNamed(Routes.directList)
+ .pushNamed(Routes.profile)
.then(
(value) => state.init(),
),
),
if (state.unread > 0)
Positioned(
- top: 8,
- right: 4,
+ bottom: 15,
+ right: 12,
child: Container(
- height: 12,
- width: 12,
+ height: 10,
+ width: 10,
decoration: BoxDecoration(
shape: BoxShape.circle,
color: Theme.of(context).colorScheme.secondary,
@@ -96,7 +83,18 @@ class LogoAppBar extends StatelessWidget implements PreferredSizeWidget {
),
],
),
- )
+ ),
+ Container(
+ height: 32,
+ width: 1,
+ color: Theme.of(context).colorScheme.border,
+ ),
+ DidvanIconButton(
+ icon: DidvanIcons.antenna_light,
+ size: 32,
+ onPressed: () =>
+ Navigator.of(context).pushNamed(Routes.bookmarks),
+ ),
],
),
],
diff --git a/lib/views/widgets/state_handlers/empty_state.dart b/lib/views/widgets/state_handlers/empty_state.dart
index c1e99bb..ce76662 100644
--- a/lib/views/widgets/state_handlers/empty_state.dart
+++ b/lib/views/widgets/state_handlers/empty_state.dart
@@ -11,6 +11,7 @@ class EmptyState extends StatelessWidget {
final String? buttonTitle;
final VoidCallback? action;
final Color? titleColor;
+ final double? height;
const EmptyState({
Key? key,
@@ -20,6 +21,7 @@ class EmptyState extends StatelessWidget {
this.buttonTitle,
this.subtitle,
this.titleColor,
+ this.height,
}) : super(key: key);
@override
@@ -27,7 +29,7 @@ class EmptyState extends StatelessWidget {
return Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
- SizedBox(height: 210, child: SvgPicture.asset(asset)),
+ SizedBox(height: height ?? 210, child: SvgPicture.asset(asset)),
const SizedBox(height: 16),
DidvanText(
title,
diff --git a/lib/views/widgets/state_handlers/sliver_state_handler.dart b/lib/views/widgets/state_handlers/sliver_state_handler.dart
index 8338a49..b05cbbe 100644
--- a/lib/views/widgets/state_handlers/sliver_state_handler.dart
+++ b/lib/views/widgets/state_handlers/sliver_state_handler.dart
@@ -14,6 +14,7 @@ class SliverStateHandler extends SliverList {
final EdgeInsets? itemPadding;
final bool centerEmptyState;
final bool hasConstraints;
+ final int placeholderCount;
SliverStateHandler({
Key? key,
required this.state,
@@ -26,6 +27,7 @@ class SliverStateHandler extends SliverList {
this.enableEmptyState = false,
this.centerEmptyState = true,
this.hasConstraints = false,
+ this.placeholderCount = 3,
}) : super(
key: key,
delegate: SliverChildBuilderDelegate(
@@ -65,7 +67,7 @@ class SliverStateHandler extends SliverList {
? 1
: childCount
: state.appState == AppState.busy
- ? 3
+ ? placeholderCount
: 1,
),
);
diff --git a/pubspec.lock b/pubspec.lock
index cc66b4a..d51cec8 100644
--- a/pubspec.lock
+++ b/pubspec.lock
@@ -371,6 +371,14 @@ packages:
description: flutter
source: sdk
version: "0.0.0"
+ flutter_markdown:
+ dependency: "direct main"
+ description:
+ name: flutter_markdown
+ sha256: a23c41ee57573e62fc2190a1f36a0480c4d90bde3a8a8d7126e5d5992fb53fb7
+ url: "https://pub.dev"
+ source: hosted
+ version: "0.7.3+1"
flutter_plugin_android_lifecycle:
dependency: transitive
description:
@@ -661,6 +669,14 @@ packages:
url: "https://pub.dev"
source: hosted
version: "1.0.2"
+ markdown:
+ dependency: transitive
+ description:
+ name: markdown
+ sha256: ef2a1298144e3f985cc736b22e0ccdaf188b5b3970648f2d9dc13efd1d9df051
+ url: "https://pub.dev"
+ source: hosted
+ version: "7.2.2"
matcher:
dependency: transitive
description:
@@ -1066,6 +1082,14 @@ packages:
url: "https://pub.dev"
source: hosted
version: "1.3.2"
+ typewritertext:
+ dependency: "direct main"
+ description:
+ name: typewritertext
+ sha256: acfe197417b49943694618140ee7080c8361e4011ab8b0e64898ba35b403f9c7
+ url: "https://pub.dev"
+ source: hosted
+ version: "3.0.8"
universal_html:
dependency: "direct main"
description:
diff --git a/pubspec.yaml b/pubspec.yaml
index 79e2f3e..5b0594a 100644
--- a/pubspec.yaml
+++ b/pubspec.yaml
@@ -86,6 +86,8 @@ dependencies:
just_audio: ^0.9.39
video_player: ^2.8.7
chewie: ^1.8.3
+ typewritertext: ^3.0.8
+ flutter_markdown: ^0.7.3+1
# onesignal_flutter: ^3.5.0
dev_dependencies: