fix bugs
This commit is contained in:
parent
7bec995377
commit
f28592c421
|
|
@ -16,6 +16,7 @@ import 'package:didvan/views/widgets/skeleton_image.dart';
|
||||||
import 'package:didvan/views/widgets/state_handlers/empty_state.dart';
|
import 'package:didvan/views/widgets/state_handlers/empty_state.dart';
|
||||||
import 'package:flutter/foundation.dart';
|
import 'package:flutter/foundation.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:provider/provider.dart';
|
||||||
|
|
||||||
class ActionSheetUtils {
|
class ActionSheetUtils {
|
||||||
final BuildContext context;
|
final BuildContext context;
|
||||||
|
|
@ -286,118 +287,83 @@ class ActionSheetUtils {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> botsDialogSelect(
|
Future<void> botsDialogSelect({
|
||||||
{required final BuildContext context,
|
required final BuildContext context,
|
||||||
required final HistoryAiChatState state}) async {
|
}) async {
|
||||||
ActionSheetUtils(context).openDialog(
|
ActionSheetUtils(context).openDialog(
|
||||||
data: ActionSheetData(
|
data: ActionSheetData(
|
||||||
hasConfirmButton: false,
|
hasConfirmButton: false,
|
||||||
hasDismissButton: false,
|
hasDismissButton: false,
|
||||||
content: Column(
|
content: SizedBox(
|
||||||
children: [
|
width: double.infinity,
|
||||||
// Row(
|
height: MediaQuery.sizeOf(context).height / 3,
|
||||||
// mainAxisAlignment: MainAxisAlignment.end,
|
child: Consumer<HistoryAiChatState>(
|
||||||
// children: [
|
builder: (context, state, child) {
|
||||||
// Padding(
|
return state.loadingBots
|
||||||
// padding: const EdgeInsets.symmetric(vertical: 8.0),
|
? Center(
|
||||||
// child: InkWell(
|
child: Image.asset(
|
||||||
// onTap: () {
|
Assets.loadingAnimation,
|
||||||
// ActionSheetUtils.pop();
|
width: 60,
|
||||||
// },
|
height: 60,
|
||||||
// child: const Icon(DidvanIcons.close_solid)),
|
),
|
||||||
// )
|
)
|
||||||
// ],
|
: state.bots.isEmpty
|
||||||
// ),
|
? Padding(
|
||||||
// SearchField(
|
padding:
|
||||||
// title: 'هوش مصنوعی',
|
const EdgeInsets.symmetric(horizontal: 12.0),
|
||||||
// value: state.search,
|
child: EmptyState(
|
||||||
// onChanged: (value) {
|
asset: Assets.emptyResult,
|
||||||
// state.search = value;
|
title: 'نتیجهای پیدا نشد',
|
||||||
// if (value.isEmpty) {
|
height: 120,
|
||||||
// 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<bool>(
|
|
||||||
valueListenable: state.loadingBots,
|
|
||||||
builder: (context, value, child) => value
|
|
||||||
? Center(
|
|
||||||
child: Image.asset(
|
|
||||||
Assets.loadingAnimation,
|
|
||||||
width: 60,
|
|
||||||
height: 60,
|
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
: state.bots.isEmpty
|
: ListView.builder(
|
||||||
? Padding(
|
itemCount: state.bots.length,
|
||||||
padding: const EdgeInsets.symmetric(
|
physics: const BouncingScrollPhysics(),
|
||||||
horizontal: 12.0),
|
shrinkWrap: true,
|
||||||
child: EmptyState(
|
itemBuilder: (context, index) {
|
||||||
asset: Assets.emptyResult,
|
final bot = state.bots[index];
|
||||||
title: 'نتیجهای پیدا نشد',
|
return InkWell(
|
||||||
height: 120,
|
onTap: () {
|
||||||
),
|
ActionSheetUtils(context).pop();
|
||||||
)
|
state.bot = bot;
|
||||||
: ListView.builder(
|
state.update();
|
||||||
itemCount: state.bots.length,
|
},
|
||||||
physics: const BouncingScrollPhysics(),
|
child: Container(
|
||||||
shrinkWrap: true,
|
alignment: Alignment.center,
|
||||||
itemBuilder: (context, index) {
|
padding:
|
||||||
final bot = state.bots[index];
|
const EdgeInsets.symmetric(vertical: 8),
|
||||||
return InkWell(
|
decoration: BoxDecoration(
|
||||||
onTap: () {
|
border: index == state.bots.length - 1
|
||||||
ActionSheetUtils(context).pop();
|
? null
|
||||||
state.bot = bot;
|
: Border(
|
||||||
state.update();
|
bottom: BorderSide(
|
||||||
},
|
color: Theme.of(context)
|
||||||
child: Container(
|
.colorScheme
|
||||||
alignment: Alignment.center,
|
.border,
|
||||||
padding: const EdgeInsets.symmetric(
|
width: 1))),
|
||||||
vertical: 8),
|
child: Row(
|
||||||
decoration: BoxDecoration(
|
children: [
|
||||||
border: index == state.bots.length - 1
|
SkeletonImage(
|
||||||
? null
|
imageUrl: bot.image.toString(),
|
||||||
: Border(
|
width: 42,
|
||||||
bottom: BorderSide(
|
height: 42,
|
||||||
color: Theme.of(context)
|
borderRadius:
|
||||||
.colorScheme
|
BorderRadius.circular(360),
|
||||||
.border,
|
|
||||||
width: 1))),
|
|
||||||
child: Row(
|
|
||||||
children: [
|
|
||||||
SkeletonImage(
|
|
||||||
imageUrl: bot.image.toString(),
|
|
||||||
width: 42,
|
|
||||||
height: 42,
|
|
||||||
borderRadius:
|
|
||||||
BorderRadius.circular(360),
|
|
||||||
),
|
|
||||||
const SizedBox(width: 12),
|
|
||||||
Expanded(
|
|
||||||
child: DidvanText(
|
|
||||||
bot.name.toString(),
|
|
||||||
maxLines: 1,
|
|
||||||
overflow: TextOverflow.ellipsis,
|
|
||||||
))
|
|
||||||
],
|
|
||||||
),
|
),
|
||||||
),
|
const SizedBox(width: 12),
|
||||||
);
|
Expanded(
|
||||||
}),
|
child: DidvanText(
|
||||||
),
|
bot.name.toString(),
|
||||||
)
|
maxLines: 1,
|
||||||
],
|
overflow: TextOverflow.ellipsis,
|
||||||
|
))
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
});
|
||||||
|
}),
|
||||||
)));
|
)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -34,9 +34,9 @@ class _AiState extends State<Ai> {
|
||||||
Future.delayed(
|
Future.delayed(
|
||||||
Duration.zero,
|
Duration.zero,
|
||||||
() {
|
() {
|
||||||
if (context.read<HistoryAiChatState>().refresh) {
|
if (state.refresh) {
|
||||||
context.read<HistoryAiChatState>().getChats();
|
state.getBots();
|
||||||
context.read<HistoryAiChatState>().refresh = false;
|
state.refresh = false;
|
||||||
}
|
}
|
||||||
state.getBots();
|
state.getBots();
|
||||||
},
|
},
|
||||||
|
|
@ -85,8 +85,7 @@ class _AiState extends State<Ai> {
|
||||||
),
|
),
|
||||||
InkWell(
|
InkWell(
|
||||||
onTap: () => ActionSheetUtils(context)
|
onTap: () => ActionSheetUtils(context)
|
||||||
.botsDialogSelect(
|
.botsDialogSelect(context: context),
|
||||||
context: context, state: state),
|
|
||||||
child: Container(
|
child: Container(
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
borderRadius:
|
borderRadius:
|
||||||
|
|
@ -287,26 +286,29 @@ class _AiState extends State<Ai> {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
Positioned(
|
Consumer<HistoryAiChatState>(builder: (context, state, child) {
|
||||||
top: 32,
|
if (state.bots.isEmpty) return const SizedBox();
|
||||||
right: 0,
|
return Positioned(
|
||||||
child: InkWell(
|
top: 32,
|
||||||
onTap: () => homeScaffKey.currentState!.openDrawer(),
|
right: 0,
|
||||||
child: Container(
|
child: InkWell(
|
||||||
width: 46,
|
onTap: () => homeScaffKey.currentState!.openDrawer(),
|
||||||
height: 46,
|
child: Container(
|
||||||
decoration: BoxDecoration(
|
width: 46,
|
||||||
color: Theme.of(context).colorScheme.surface,
|
height: 46,
|
||||||
borderRadius: const BorderRadius.only(
|
decoration: BoxDecoration(
|
||||||
topLeft: Radius.circular(12),
|
color: Theme.of(context).colorScheme.surface,
|
||||||
bottomLeft: Radius.circular(12)),
|
borderRadius: const BorderRadius.only(
|
||||||
boxShadow: DesignConfig.defaultShadow),
|
topLeft: Radius.circular(12),
|
||||||
child: Icon(
|
bottomLeft: Radius.circular(12)),
|
||||||
DidvanIcons.angle_left_light,
|
boxShadow: DesignConfig.defaultShadow),
|
||||||
color: Theme.of(context).colorScheme.title,
|
child: Icon(
|
||||||
),
|
DidvanIcons.angle_left_light,
|
||||||
)),
|
color: Theme.of(context).colorScheme.title,
|
||||||
)
|
),
|
||||||
|
)),
|
||||||
|
);
|
||||||
|
})
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -63,7 +63,7 @@ class _CreateBotAssistantsPageState extends State<CreateBotAssistantsPage> {
|
||||||
super.initState();
|
super.initState();
|
||||||
}
|
}
|
||||||
|
|
||||||
void onConfirm(CreateBotAssistantsState state, int selectedBotId) async {
|
void onConfirm(CreateBotAssistantsState state) async {
|
||||||
bool isValid = true;
|
bool isValid = true;
|
||||||
// if (!_formYouTubeKey.currentState!.validate()) {
|
// if (!_formYouTubeKey.currentState!.validate()) {
|
||||||
// isValid = false;
|
// isValid = false;
|
||||||
|
|
@ -95,7 +95,7 @@ class _CreateBotAssistantsPageState extends State<CreateBotAssistantsPage> {
|
||||||
type: state.selectedBotType,
|
type: state.selectedBotType,
|
||||||
name: state.name,
|
name: state.name,
|
||||||
description: state.desc,
|
description: state.desc,
|
||||||
botId: selectedBotId,
|
botId: state.initialBot!.id!,
|
||||||
prompt: state.prompt,
|
prompt: state.prompt,
|
||||||
webLinks:
|
webLinks:
|
||||||
state.countOfLink.first.isEmpty ? null : state.countOfLink,
|
state.countOfLink.first.isEmpty ? null : state.countOfLink,
|
||||||
|
|
@ -135,9 +135,6 @@ class _CreateBotAssistantsPageState extends State<CreateBotAssistantsPage> {
|
||||||
),
|
),
|
||||||
body: Consumer<CreateBotAssistantsState>(builder: (BuildContext context,
|
body: Consumer<CreateBotAssistantsState>(builder: (BuildContext context,
|
||||||
CreateBotAssistantsState state, Widget? child) {
|
CreateBotAssistantsState state, Widget? child) {
|
||||||
int selectedBotId = state.selectedBotType == 'text'
|
|
||||||
? state.allBots.first.id!
|
|
||||||
: state.imageBots.first.id!;
|
|
||||||
return state.loading
|
return state.loading
|
||||||
? Center(
|
? Center(
|
||||||
child: SpinKitThreeBounce(
|
child: SpinKitThreeBounce(
|
||||||
|
|
@ -400,7 +397,7 @@ class _CreateBotAssistantsPageState extends State<CreateBotAssistantsPage> {
|
||||||
.surface),
|
.surface),
|
||||||
// hintText: "انتخاب کنید",
|
// hintText: "انتخاب کنید",
|
||||||
onChanged: (value) {
|
onChanged: (value) {
|
||||||
selectedBotId = value!.id!;
|
state.initialBot = value;
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|
@ -804,7 +801,7 @@ class _CreateBotAssistantsPageState extends State<CreateBotAssistantsPage> {
|
||||||
? ' '
|
? ' '
|
||||||
: 'ذخیره تغییرات',
|
: 'ذخیره تغییرات',
|
||||||
onPressed: () async =>
|
onPressed: () async =>
|
||||||
onConfirm(state, selectedBotId),
|
onConfirm(state),
|
||||||
),
|
),
|
||||||
if (state.loadingCreate)
|
if (state.loadingCreate)
|
||||||
const Positioned.fill(
|
const Positioned.fill(
|
||||||
|
|
@ -871,8 +868,7 @@ class _CreateBotAssistantsPageState extends State<CreateBotAssistantsPage> {
|
||||||
DidvanButton(
|
DidvanButton(
|
||||||
title:
|
title:
|
||||||
state.loadingCreate ? ' ' : 'ذخیره',
|
state.loadingCreate ? ' ' : 'ذخیره',
|
||||||
onPressed: () async =>
|
onPressed: () async => onConfirm(state)),
|
||||||
onConfirm(state, selectedBotId)),
|
|
||||||
if (state.loadingCreate)
|
if (state.loadingCreate)
|
||||||
const Positioned.fill(
|
const Positioned.fill(
|
||||||
child: Center(
|
child: Center(
|
||||||
|
|
|
||||||
|
|
@ -29,7 +29,7 @@ class CreateBotAssistantsState extends CoreProvier {
|
||||||
navigatorKey.currentContext!.read<HistoryAiChatState>().bots;
|
navigatorKey.currentContext!.read<HistoryAiChatState>().bots;
|
||||||
|
|
||||||
final List<String> botModels = ['مدل زبانی', 'مدل تصویری'];
|
final List<String> botModels = ['مدل زبانی', 'مدل تصویری'];
|
||||||
BotsModel? initialBot;
|
late BotsModel? initialBot = allBots.first;
|
||||||
|
|
||||||
List<String> countOfLink = [''];
|
List<String> countOfLink = [''];
|
||||||
List<FileCreateAssistantsModel> files = [];
|
List<FileCreateAssistantsModel> files = [];
|
||||||
|
|
@ -123,6 +123,9 @@ class CreateBotAssistantsState extends CoreProvier {
|
||||||
}
|
}
|
||||||
selectedBotType = initialBot?.responseType ?? 'text';
|
selectedBotType = initialBot?.responseType ?? 'text';
|
||||||
}
|
}
|
||||||
|
if (initialBot == null) {
|
||||||
|
selectedBotType == 'text' ? allBots.first : imageBots.first;
|
||||||
|
}
|
||||||
appState = AppState.idle;
|
appState = AppState.idle;
|
||||||
loading = false;
|
loading = false;
|
||||||
update();
|
update();
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,6 @@ import 'package:didvan/providers/core.dart';
|
||||||
import 'package:didvan/services/network/request.dart';
|
import 'package:didvan/services/network/request.dart';
|
||||||
import 'package:didvan/services/network/request_helper.dart';
|
import 'package:didvan/services/network/request_helper.dart';
|
||||||
import 'package:didvan/utils/action_sheet.dart';
|
import 'package:didvan/utils/action_sheet.dart';
|
||||||
import 'package:flutter/cupertino.dart';
|
|
||||||
|
|
||||||
class HistoryAiChatState extends CoreProvier {
|
class HistoryAiChatState extends CoreProvier {
|
||||||
final List<ChatsModel> chats = [];
|
final List<ChatsModel> chats = [];
|
||||||
|
|
@ -17,15 +16,17 @@ class HistoryAiChatState extends CoreProvier {
|
||||||
// final List<int> chatsToDelete = [];
|
// final List<int> chatsToDelete = [];
|
||||||
final List<BotsModel> bots = [];
|
final List<BotsModel> bots = [];
|
||||||
BotsModel? bot;
|
BotsModel? bot;
|
||||||
ValueNotifier<bool> loadingBots = ValueNotifier(false);
|
bool loadingBots = false;
|
||||||
bool loadingchangeTitle = false;
|
bool loadingchangeTitle = false;
|
||||||
bool loadingdeleteAll = false;
|
bool loadingdeleteAll = false;
|
||||||
|
bool loadinggetAll = false;
|
||||||
bool refresh = false;
|
bool refresh = false;
|
||||||
Timer? timer;
|
Timer? timer;
|
||||||
String search = '';
|
String search = '';
|
||||||
|
|
||||||
Future<void> getChats({final bool archived = false}) async {
|
Future<void> getChats({final bool archived = false}) async {
|
||||||
appState = AppState.busy;
|
appState = AppState.busy;
|
||||||
|
loadinggetAll = true;
|
||||||
update();
|
update();
|
||||||
final service = RequestService(
|
final service = RequestService(
|
||||||
archived ? RequestHelper.aiArchived() : RequestHelper.aiChats(),
|
archived ? RequestHelper.aiArchived() : RequestHelper.aiChats(),
|
||||||
|
|
@ -39,10 +40,13 @@ class HistoryAiChatState extends CoreProvier {
|
||||||
.add(ChatsModel.fromJson(messages[i]));
|
.add(ChatsModel.fromJson(messages[i]));
|
||||||
}
|
}
|
||||||
appState = AppState.idle;
|
appState = AppState.idle;
|
||||||
|
loadinggetAll = false;
|
||||||
|
|
||||||
update();
|
update();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
appState = AppState.failed;
|
appState = AppState.failed;
|
||||||
|
loadinggetAll = false;
|
||||||
update();
|
update();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -72,7 +76,9 @@ class HistoryAiChatState extends CoreProvier {
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> getBots() async {
|
Future<void> getBots() async {
|
||||||
loadingBots.value = true;
|
appState = AppState.busy;
|
||||||
|
loadingBots = true;
|
||||||
|
update();
|
||||||
final service = RequestService(
|
final service = RequestService(
|
||||||
RequestHelper.aiBots(),
|
RequestHelper.aiBots(),
|
||||||
);
|
);
|
||||||
|
|
@ -83,19 +89,23 @@ class HistoryAiChatState extends CoreProvier {
|
||||||
for (var i = 0; i < messages.length; i++) {
|
for (var i = 0; i < messages.length; i++) {
|
||||||
bots.add(BotsModel.fromJson(messages[i]));
|
bots.add(BotsModel.fromJson(messages[i]));
|
||||||
}
|
}
|
||||||
appState = AppState.idle;
|
|
||||||
loadingBots.value = false;
|
|
||||||
bot = bots.first;
|
bot = bots.first;
|
||||||
|
appState = AppState.idle;
|
||||||
|
loadingBots = false;
|
||||||
update();
|
update();
|
||||||
|
getChats();
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
appState = AppState.failed;
|
appState = AppState.failed;
|
||||||
loadingBots.value = false;
|
loadingBots = false;
|
||||||
update();
|
update();
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> getSearchBots(String q) async {
|
Future<void> getSearchBots(String q) async {
|
||||||
loadingBots.value = true;
|
appState = AppState.busy;
|
||||||
|
|
||||||
|
loadingBots = true;
|
||||||
final service = RequestService(
|
final service = RequestService(
|
||||||
RequestHelper.aiSearchBots(q),
|
RequestHelper.aiSearchBots(q),
|
||||||
);
|
);
|
||||||
|
|
@ -107,13 +117,13 @@ class HistoryAiChatState extends CoreProvier {
|
||||||
bots.add(BotsModel.fromJson(messages[i]));
|
bots.add(BotsModel.fromJson(messages[i]));
|
||||||
}
|
}
|
||||||
appState = AppState.idle;
|
appState = AppState.idle;
|
||||||
loadingBots.value = false;
|
loadingBots = false;
|
||||||
update();
|
update();
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
appState = AppState.failed;
|
appState = AppState.failed;
|
||||||
loadingBots.value = false;
|
loadingBots = false;
|
||||||
update();
|
update();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -17,7 +17,6 @@ import 'package:didvan/services/media/media.dart';
|
||||||
import 'package:didvan/utils/action_sheet.dart';
|
import 'package:didvan/utils/action_sheet.dart';
|
||||||
import 'package:didvan/utils/date_time.dart';
|
import 'package:didvan/utils/date_time.dart';
|
||||||
import 'package:didvan/views/ai/ai_chat_state.dart';
|
import 'package:didvan/views/ai/ai_chat_state.dart';
|
||||||
import 'package:didvan/views/ai/history_ai_chat_state.dart';
|
|
||||||
import 'package:didvan/views/ai/widgets/audio_wave.dart';
|
import 'package:didvan/views/ai/widgets/audio_wave.dart';
|
||||||
import 'package:didvan/views/ai/widgets/message_bar_btn.dart';
|
import 'package:didvan/views/ai/widgets/message_bar_btn.dart';
|
||||||
import 'package:didvan/views/widgets/animated_visibility.dart';
|
import 'package:didvan/views/widgets/animated_visibility.dart';
|
||||||
|
|
@ -66,7 +65,6 @@ class _AiMessageBarState extends State<AiMessageBar> {
|
||||||
Timer? _timer;
|
Timer? _timer;
|
||||||
final theSource = AudioSource.microphone;
|
final theSource = AudioSource.microphone;
|
||||||
final ValueNotifier<Duration> _countTimer = ValueNotifier(Duration.zero);
|
final ValueNotifier<Duration> _countTimer = ValueNotifier(Duration.zero);
|
||||||
late HistoryAiChatState historyState = context.read<HistoryAiChatState>();
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void initState() {
|
void initState() {
|
||||||
|
|
@ -256,7 +254,7 @@ class _AiMessageBarState extends State<AiMessageBar> {
|
||||||
child: Row(
|
child: Row(
|
||||||
crossAxisAlignment: CrossAxisAlignment.end,
|
crossAxisAlignment: CrossAxisAlignment.end,
|
||||||
children: [
|
children: [
|
||||||
recorderAndSendButton(state, historyState),
|
recorderAndSendButton(state),
|
||||||
if (!(_mRecorder!.isStopped))
|
if (!(_mRecorder!.isStopped))
|
||||||
ValueListenableBuilder(
|
ValueListenableBuilder(
|
||||||
valueListenable: _countTimer,
|
valueListenable: _countTimer,
|
||||||
|
|
@ -453,13 +451,13 @@ class _AiMessageBarState extends State<AiMessageBar> {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
recorderAndSendButton(AiChatState state, HistoryAiChatState historyState) {
|
recorderAndSendButton(AiChatState state) {
|
||||||
return ValueListenableBuilder(
|
return ValueListenableBuilder(
|
||||||
valueListenable: state.message,
|
valueListenable: state.message,
|
||||||
builder: (context, message, child) => Padding(
|
builder: (context, message, child) => Padding(
|
||||||
padding: const EdgeInsets.fromLTRB(12, 0, 12, 8),
|
padding: const EdgeInsets.fromLTRB(12, 0, 12, 8),
|
||||||
child: message.text.isEmpty &&
|
child: message.text.isEmpty &&
|
||||||
historyState.bot!.attachmentType!.contains('audio') &&
|
widget.bot.attachmentType!.contains('audio') &&
|
||||||
state.file == null &&
|
state.file == null &&
|
||||||
widget.bot.attachment != 0
|
widget.bot.attachment != 0
|
||||||
? MessageBarBtn(
|
? MessageBarBtn(
|
||||||
|
|
@ -531,150 +529,6 @@ class _AiMessageBarState extends State<AiMessageBar> {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// AnimatedVisibility attachmentLayout(AiChatState state,
|
|
||||||
// HistoryAiChatState historyState, BuildContext context) {
|
|
||||||
// return AnimatedVisibility(
|
|
||||||
// isVisible: openAttach,
|
|
||||||
// duration: DesignConfig.lowAnimationDuration,
|
|
||||||
// child: Container(
|
|
||||||
// padding: const EdgeInsets.symmetric(horizontal: 0, vertical: 12),
|
|
||||||
// child: state.file != null && !(state.file!.isRecorded)
|
|
||||||
// ? fileContainer()
|
|
||||||
// : Row(
|
|
||||||
// mainAxisAlignment: MainAxisAlignment.center,
|
|
||||||
// children: [
|
|
||||||
// if (historyState.bot!.attachmentType!.contains('pdf'))
|
|
||||||
// attachBtn(
|
|
||||||
// title: "PDF",
|
|
||||||
// icon: CupertinoIcons.doc_fill,
|
|
||||||
// color: Colors.redAccent,
|
|
||||||
// click: () async {
|
|
||||||
// MediaService.onLoadingPickFile(context);
|
|
||||||
// FilePickerResult? result =
|
|
||||||
// await MediaService.pickPdfFile();
|
|
||||||
// if (result != null) {
|
|
||||||
// if (kIsWeb) {
|
|
||||||
// Uint8List? bytes = result.files.first
|
|
||||||
// .bytes; // Access the bytes property
|
|
||||||
// String? name = result.files.first.name;
|
|
||||||
|
|
||||||
// // Store bytes and file name directly in your state or model
|
|
||||||
// state.file = FilesModel(
|
|
||||||
// '', // No need for a file path on web
|
|
||||||
// name: name,
|
|
||||||
// bytes: bytes,
|
|
||||||
// audio: false,
|
|
||||||
// image: false,
|
|
||||||
// );
|
|
||||||
// } else {
|
|
||||||
// state.file = FilesModel(result.files.single.path!,
|
|
||||||
// audio: false, image: false);
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// Future.delayed(
|
|
||||||
// Duration.zero,
|
|
||||||
// () => ActionSheetUtils(context).pop(),
|
|
||||||
// );
|
|
||||||
// },
|
|
||||||
// ),
|
|
||||||
// if (historyState.bot!.attachmentType!.contains('image'))
|
|
||||||
// attachBtn(
|
|
||||||
// title: "تصویر",
|
|
||||||
// icon: CupertinoIcons.photo,
|
|
||||||
// color: Colors.deepOrangeAccent,
|
|
||||||
// click: () async {
|
|
||||||
// MediaService.onLoadingPickFile(context);
|
|
||||||
|
|
||||||
// final pickedFile = await MediaService.pickImage(
|
|
||||||
// source: ImageSource.gallery);
|
|
||||||
// File? file;
|
|
||||||
// if (pickedFile != null && !kIsWeb) {
|
|
||||||
// file = await ImageCropper().cropImage(
|
|
||||||
// sourcePath: pickedFile.path,
|
|
||||||
// androidUiSettings: const AndroidUiSettings(
|
|
||||||
// toolbarTitle: 'برش تصویر'),
|
|
||||||
// iosUiSettings: const IOSUiSettings(
|
|
||||||
// title: 'برش تصویر',
|
|
||||||
// doneButtonTitle: 'تایید',
|
|
||||||
// cancelButtonTitle: 'بازگشت',
|
|
||||||
// ),
|
|
||||||
// compressQuality: 30,
|
|
||||||
// );
|
|
||||||
|
|
||||||
// if (file == null) {
|
|
||||||
// await Future.delayed(
|
|
||||||
// Duration.zero,
|
|
||||||
// () => ActionSheetUtils(context).pop(),
|
|
||||||
// );
|
|
||||||
|
|
||||||
// return;
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// if (pickedFile == null) {
|
|
||||||
// await Future.delayed(
|
|
||||||
// Duration.zero,
|
|
||||||
// () => ActionSheetUtils(context).pop(),
|
|
||||||
// );
|
|
||||||
|
|
||||||
// return;
|
|
||||||
// }
|
|
||||||
// state.file = kIsWeb
|
|
||||||
// ? FilesModel(pickedFile.path,
|
|
||||||
// name: pickedFile.name,
|
|
||||||
// image: true,
|
|
||||||
// audio: false)
|
|
||||||
// : FilesModel(file!.path,
|
|
||||||
// image: true, audio: false);
|
|
||||||
// await Future.delayed(
|
|
||||||
// Duration.zero,
|
|
||||||
// () => ActionSheetUtils(context).pop(),
|
|
||||||
// );
|
|
||||||
// },
|
|
||||||
// ),
|
|
||||||
// // if (!kIsWeb && !Platform.isIOS)
|
|
||||||
// if (historyState.bot!.attachmentType!.contains('audio'))
|
|
||||||
// attachBtn(
|
|
||||||
// title: "صوت",
|
|
||||||
// icon: CupertinoIcons.music_note_2,
|
|
||||||
// color: Colors.indigoAccent,
|
|
||||||
// click: () async {
|
|
||||||
// MediaService.onLoadingPickFile(context);
|
|
||||||
|
|
||||||
// FilePickerResult? result =
|
|
||||||
// await MediaService.pickAudioFile();
|
|
||||||
// if (result != null) {
|
|
||||||
// if (kIsWeb) {
|
|
||||||
// Uint8List? bytes = result.files.first
|
|
||||||
// .bytes; // Access the bytes property
|
|
||||||
// String? name = result.files.first.name;
|
|
||||||
|
|
||||||
// // final blob = html.Blob([bytes]);
|
|
||||||
// // final blobUrl =
|
|
||||||
// // html.Url.createObjectUrlFromBlob(blob);
|
|
||||||
|
|
||||||
// state.file = FilesModel(
|
|
||||||
// "", // No need for a file path on web
|
|
||||||
// name: name,
|
|
||||||
// bytes: bytes,
|
|
||||||
// audio: true,
|
|
||||||
// image: false,
|
|
||||||
// );
|
|
||||||
// } else {
|
|
||||||
// state.file = FilesModel(result.files.single.path!,
|
|
||||||
// audio: true, image: false);
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// await Future.delayed(
|
|
||||||
// Duration.zero,
|
|
||||||
// () => ActionSheetUtils(context).pop(),
|
|
||||||
// );
|
|
||||||
// },
|
|
||||||
// )
|
|
||||||
// ],
|
|
||||||
// ),
|
|
||||||
// ));
|
|
||||||
// }
|
|
||||||
|
|
||||||
AnimatedVisibility attachmentLayout(AiChatState state, BuildContext context) {
|
AnimatedVisibility attachmentLayout(AiChatState state, BuildContext context) {
|
||||||
return AnimatedVisibility(
|
return AnimatedVisibility(
|
||||||
isVisible: openAttach,
|
isVisible: openAttach,
|
||||||
|
|
@ -683,45 +537,48 @@ class _AiMessageBarState extends State<AiMessageBar> {
|
||||||
child: Row(
|
child: Row(
|
||||||
mainAxisAlignment: MainAxisAlignment.center,
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
children: [
|
children: [
|
||||||
if (historyState.bot!.attachmentType!.contains('pdf'))
|
if (widget.bot.attachmentType!.contains('pdf'))
|
||||||
MessageBarBtn(
|
|
||||||
enable: true,
|
|
||||||
icon: CupertinoIcons.doc_fill,
|
|
||||||
click: () async {
|
|
||||||
MediaService.onLoadingPickFile(context);
|
|
||||||
FilePickerResult? result = await MediaService.pickPdfFile();
|
|
||||||
if (result != null) {
|
|
||||||
String? name = result.files.single.name;
|
|
||||||
|
|
||||||
if (kIsWeb) {
|
|
||||||
Uint8List? bytes =
|
|
||||||
result.files.first.bytes; // Access the bytes property
|
|
||||||
|
|
||||||
// Store bytes and file name directly in your state or model
|
|
||||||
state.file = FilesModel(
|
|
||||||
'', // No need for a file path on web
|
|
||||||
name: name,
|
|
||||||
bytes: bytes,
|
|
||||||
audio: false,
|
|
||||||
image: false,
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
state.file = FilesModel(result.files.single.path!,
|
|
||||||
audio: false, image: false, name: name);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Future.delayed(
|
|
||||||
Duration.zero,
|
|
||||||
() => ActionSheetUtils(context).pop(),
|
|
||||||
);
|
|
||||||
openAttach = !openAttach;
|
|
||||||
|
|
||||||
state.update();
|
|
||||||
},
|
|
||||||
),
|
|
||||||
if (historyState.bot!.attachmentType!.contains('image'))
|
|
||||||
Padding(
|
Padding(
|
||||||
padding: const EdgeInsets.symmetric(horizontal: 8.0),
|
padding: const EdgeInsets.only(right: 8.0),
|
||||||
|
child: MessageBarBtn(
|
||||||
|
enable: true,
|
||||||
|
icon: CupertinoIcons.doc_fill,
|
||||||
|
click: () async {
|
||||||
|
MediaService.onLoadingPickFile(context);
|
||||||
|
FilePickerResult? result = await MediaService.pickPdfFile();
|
||||||
|
if (result != null) {
|
||||||
|
String? name = result.files.single.name;
|
||||||
|
|
||||||
|
if (kIsWeb) {
|
||||||
|
Uint8List? bytes = result
|
||||||
|
.files.first.bytes; // Access the bytes property
|
||||||
|
|
||||||
|
// Store bytes and file name directly in your state or model
|
||||||
|
state.file = FilesModel(
|
||||||
|
'', // No need for a file path on web
|
||||||
|
name: name,
|
||||||
|
bytes: bytes,
|
||||||
|
audio: false,
|
||||||
|
image: false,
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
state.file = FilesModel(result.files.single.path!,
|
||||||
|
audio: false, image: false, name: name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Future.delayed(
|
||||||
|
Duration.zero,
|
||||||
|
() => ActionSheetUtils(context).pop(),
|
||||||
|
);
|
||||||
|
openAttach = !openAttach;
|
||||||
|
|
||||||
|
state.update();
|
||||||
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
if (widget.bot.attachmentType!.contains('image'))
|
||||||
|
Padding(
|
||||||
|
padding: const EdgeInsets.only(right: 8.0),
|
||||||
child: MessageBarBtn(
|
child: MessageBarBtn(
|
||||||
enable: true,
|
enable: true,
|
||||||
icon: CupertinoIcons.photo,
|
icon: CupertinoIcons.photo,
|
||||||
|
|
@ -777,86 +634,53 @@ class _AiMessageBarState extends State<AiMessageBar> {
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
// if (!kIsWeb && !Platform.isIOS)
|
// if (!kIsWeb && !Platform.isIOS)
|
||||||
if (historyState.bot!.attachmentType!.contains('audio'))
|
if (widget.bot.attachmentType!.contains('audio'))
|
||||||
MessageBarBtn(
|
Padding(
|
||||||
enable: true,
|
padding: const EdgeInsets.only(right: 8.0),
|
||||||
icon: CupertinoIcons.music_note_2,
|
child: MessageBarBtn(
|
||||||
click: () async {
|
enable: true,
|
||||||
MediaService.onLoadingPickFile(context);
|
icon: CupertinoIcons.music_note_2,
|
||||||
|
click: () async {
|
||||||
|
MediaService.onLoadingPickFile(context);
|
||||||
|
|
||||||
FilePickerResult? result = await MediaService.pickAudioFile();
|
FilePickerResult? result =
|
||||||
if (result != null) {
|
await MediaService.pickAudioFile();
|
||||||
String? name = result.files.first.name;
|
if (result != null) {
|
||||||
|
String? name = result.files.first.name;
|
||||||
|
|
||||||
if (kIsWeb) {
|
if (kIsWeb) {
|
||||||
Uint8List? bytes =
|
Uint8List? bytes = result
|
||||||
result.files.first.bytes; // Access the bytes property
|
.files.first.bytes; // Access the bytes property
|
||||||
|
|
||||||
final blob = html.Blob([bytes]);
|
final blob = html.Blob([bytes]);
|
||||||
final blobUrl = html.Url.createObjectUrlFromBlob(blob);
|
final blobUrl = html.Url.createObjectUrlFromBlob(blob);
|
||||||
|
|
||||||
state.file = FilesModel(
|
state.file = FilesModel(
|
||||||
blobUrl, // No need for a file path on web
|
blobUrl, // No need for a file path on web
|
||||||
name: name,
|
name: name,
|
||||||
bytes: bytes,
|
bytes: bytes,
|
||||||
audio: true,
|
audio: true,
|
||||||
image: false,
|
image: false,
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
state.file = FilesModel(result.files.single.path!,
|
state.file = FilesModel(result.files.single.path!,
|
||||||
name: name, audio: true, image: false);
|
name: name, audio: true, image: false);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
await Future.delayed(
|
||||||
await Future.delayed(
|
Duration.zero,
|
||||||
Duration.zero,
|
() => ActionSheetUtils(context).pop(),
|
||||||
() => ActionSheetUtils(context).pop(),
|
);
|
||||||
);
|
openAttach = !openAttach;
|
||||||
openAttach = !openAttach;
|
|
||||||
|
|
||||||
state.update();
|
state.update();
|
||||||
},
|
},
|
||||||
|
),
|
||||||
)
|
)
|
||||||
],
|
],
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
// InkWell attachBtn(
|
|
||||||
// {required final String title,
|
|
||||||
// required final IconData icon,
|
|
||||||
// final Color? color,
|
|
||||||
// final Function()? click}) {
|
|
||||||
// final state = context.read<AiChatState>();
|
|
||||||
// return InkWell(
|
|
||||||
// onTap: () async {
|
|
||||||
// await click?.call();
|
|
||||||
|
|
||||||
// state.update();
|
|
||||||
// },
|
|
||||||
// child: Column(
|
|
||||||
// children: [
|
|
||||||
// Container(
|
|
||||||
// width: 40,
|
|
||||||
// height: 40,
|
|
||||||
// decoration: BoxDecoration(shape: BoxShape.circle, color: color),
|
|
||||||
// padding: const EdgeInsets.all(0.8),
|
|
||||||
// margin: const EdgeInsets.symmetric(horizontal: 12),
|
|
||||||
// child: Icon(
|
|
||||||
// icon,
|
|
||||||
// size: 20,
|
|
||||||
// color: Theme.of(context).colorScheme.white,
|
|
||||||
// )),
|
|
||||||
// const SizedBox(
|
|
||||||
// height: 4,
|
|
||||||
// ),
|
|
||||||
// DidvanText(
|
|
||||||
// title,
|
|
||||||
// fontSize: 12,
|
|
||||||
// )
|
|
||||||
// ],
|
|
||||||
// ),
|
|
||||||
// );
|
|
||||||
// }
|
|
||||||
|
|
||||||
Widget audioContainer() {
|
Widget audioContainer() {
|
||||||
final state = context.watch<AiChatState>();
|
final state = context.watch<AiChatState>();
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,5 @@
|
||||||
import 'package:didvan/config/theme_data.dart';
|
import 'package:didvan/config/theme_data.dart';
|
||||||
import 'package:didvan/constants/app_icons.dart';
|
import 'package:didvan/constants/app_icons.dart';
|
||||||
import 'package:didvan/constants/assets.dart';
|
|
||||||
import 'package:didvan/main.dart';
|
import 'package:didvan/main.dart';
|
||||||
import 'package:didvan/models/ai/ai_chat_args.dart';
|
import 'package:didvan/models/ai/ai_chat_args.dart';
|
||||||
import 'package:didvan/models/ai/chats_model.dart';
|
import 'package:didvan/models/ai/chats_model.dart';
|
||||||
|
|
@ -15,8 +14,9 @@ import 'package:didvan/views/widgets/didvan/divider.dart';
|
||||||
import 'package:didvan/views/widgets/didvan/text.dart';
|
import 'package:didvan/views/widgets/didvan/text.dart';
|
||||||
import 'package:didvan/views/widgets/shimmer_placeholder.dart';
|
import 'package:didvan/views/widgets/shimmer_placeholder.dart';
|
||||||
import 'package:didvan/views/widgets/skeleton_image.dart';
|
import 'package:didvan/views/widgets/skeleton_image.dart';
|
||||||
|
import 'package:didvan/views/widgets/state_handlers/empty_list.dart';
|
||||||
|
import 'package:didvan/views/widgets/state_handlers/sliver_state_handler.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_svg/svg.dart';
|
|
||||||
import 'package:provider/provider.dart';
|
import 'package:provider/provider.dart';
|
||||||
|
|
||||||
class HoshanDrawer extends StatefulWidget {
|
class HoshanDrawer extends StatefulWidget {
|
||||||
|
|
@ -27,6 +27,11 @@ class HoshanDrawer extends StatefulWidget {
|
||||||
}
|
}
|
||||||
|
|
||||||
class _HoshanDrawerState extends State<HoshanDrawer> {
|
class _HoshanDrawerState extends State<HoshanDrawer> {
|
||||||
|
@override
|
||||||
|
initState() {
|
||||||
|
super.initState();
|
||||||
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return Drawer(
|
return Drawer(
|
||||||
|
|
@ -139,88 +144,28 @@ class _HoshanDrawerState extends State<HoshanDrawer> {
|
||||||
// height: 12,
|
// height: 12,
|
||||||
// ),
|
// ),
|
||||||
Expanded(
|
Expanded(
|
||||||
child: state.loadingdeleteAll ||
|
child: CustomScrollView(
|
||||||
state.appState == AppState.busy
|
slivers: [
|
||||||
? ListView.builder(
|
SliverStateHandler(
|
||||||
shrinkWrap: true,
|
state: state,
|
||||||
itemCount: 10,
|
centerEmptyState: true,
|
||||||
padding: const EdgeInsets.symmetric(
|
emptyState: const EmptyList(),
|
||||||
horizontal: 12),
|
// enableEmptyState: state.chats.isEmpty,
|
||||||
physics:
|
placeholder: chatRowPlaceholder(),
|
||||||
const NeverScrollableScrollPhysics(),
|
placeholderCount: 10,
|
||||||
itemBuilder: (context, index) {
|
builder: (context, state, index) {
|
||||||
return const Padding(
|
final chat = state.chats[index];
|
||||||
padding: EdgeInsets.symmetric(
|
TextEditingController title =
|
||||||
vertical: 12.0),
|
TextEditingController(
|
||||||
child: Row(
|
text: chat.title);
|
||||||
crossAxisAlignment:
|
|
||||||
CrossAxisAlignment.start,
|
return chatRow(chat, title, state, index);
|
||||||
children: [
|
},
|
||||||
ClipOval(
|
childCount: state.chats.length,
|
||||||
child: ShimmerPlaceholder(
|
onRetry: () => state.getChats())
|
||||||
height: 24,
|
],
|
||||||
width: 24,
|
)),
|
||||||
),
|
|
||||||
),
|
|
||||||
SizedBox(width: 12),
|
|
||||||
Expanded(
|
|
||||||
child: ShimmerPlaceholder(
|
|
||||||
height: 24,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
SizedBox(width: 12),
|
|
||||||
ShimmerPlaceholder(
|
|
||||||
height: 24,
|
|
||||||
width: 24,
|
|
||||||
),
|
|
||||||
SizedBox(width: 8),
|
|
||||||
ShimmerPlaceholder(
|
|
||||||
height: 24,
|
|
||||||
width: 12,
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
);
|
|
||||||
},
|
|
||||||
)
|
|
||||||
: state.chats.isEmpty
|
|
||||||
? Padding(
|
|
||||||
padding: const EdgeInsets.all(12.0),
|
|
||||||
child: Column(
|
|
||||||
children: [
|
|
||||||
SvgPicture.asset(
|
|
||||||
Assets.emptyResult,
|
|
||||||
height:
|
|
||||||
MediaQuery.sizeOf(context)
|
|
||||||
.height /
|
|
||||||
10,
|
|
||||||
),
|
|
||||||
const DidvanText(
|
|
||||||
'لیست خالی است',
|
|
||||||
fontSize: 14,
|
|
||||||
fontWeight: FontWeight.bold,
|
|
||||||
)
|
|
||||||
],
|
|
||||||
),
|
|
||||||
)
|
|
||||||
: ListView.builder(
|
|
||||||
shrinkWrap: true,
|
|
||||||
itemCount: state.chats.length,
|
|
||||||
padding: const EdgeInsets.symmetric(
|
|
||||||
horizontal: 12),
|
|
||||||
physics:
|
|
||||||
const BouncingScrollPhysics(),
|
|
||||||
itemBuilder: (context, index) {
|
|
||||||
final chat = state.chats[index];
|
|
||||||
TextEditingController title =
|
|
||||||
TextEditingController(
|
|
||||||
text: chat.title);
|
|
||||||
|
|
||||||
return chatRow(
|
|
||||||
chat, title, state, index);
|
|
||||||
},
|
|
||||||
),
|
|
||||||
),
|
|
||||||
// SizedBox(
|
// SizedBox(
|
||||||
// height: 12,
|
// height: 12,
|
||||||
// ),
|
// ),
|
||||||
|
|
@ -268,6 +213,39 @@ class _HoshanDrawerState extends State<HoshanDrawer> {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Padding chatRowPlaceholder() {
|
||||||
|
return const Padding(
|
||||||
|
padding: EdgeInsets.symmetric(vertical: 12.0),
|
||||||
|
child: Row(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
ClipOval(
|
||||||
|
child: ShimmerPlaceholder(
|
||||||
|
height: 24,
|
||||||
|
width: 24,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
SizedBox(width: 12),
|
||||||
|
Expanded(
|
||||||
|
child: ShimmerPlaceholder(
|
||||||
|
height: 24,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
SizedBox(width: 12),
|
||||||
|
ShimmerPlaceholder(
|
||||||
|
height: 24,
|
||||||
|
width: 24,
|
||||||
|
),
|
||||||
|
SizedBox(width: 8),
|
||||||
|
ShimmerPlaceholder(
|
||||||
|
height: 24,
|
||||||
|
width: 12,
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
Widget drawerBtn(
|
Widget drawerBtn(
|
||||||
{final CrossAxisAlignment? crossAxisAlignment,
|
{final CrossAxisAlignment? crossAxisAlignment,
|
||||||
required final IconData icon,
|
required final IconData icon,
|
||||||
|
|
|
||||||
|
|
@ -142,7 +142,6 @@ class _HomeState extends State<Home>
|
||||||
if (_tabController.index == 2) {
|
if (_tabController.index == 2) {
|
||||||
homeScaffKey.currentState!.closeDrawer();
|
homeScaffKey.currentState!.closeDrawer();
|
||||||
|
|
||||||
context.read<HistoryAiChatState>().getChats();
|
|
||||||
context.read<HistoryAiChatState>().getBots();
|
context.read<HistoryAiChatState>().getBots();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -1,18 +1,18 @@
|
||||||
import 'package:didvan/config/design_config.dart';
|
import 'package:didvan/config/design_config.dart';
|
||||||
import 'package:didvan/config/theme_data.dart';
|
import 'package:didvan/config/theme_data.dart';
|
||||||
import 'package:didvan/constants/app_icons.dart';
|
import 'package:didvan/constants/app_icons.dart';
|
||||||
|
import 'package:didvan/utils/extension.dart';
|
||||||
import 'package:didvan/views/widgets/animated_visibility.dart';
|
import 'package:didvan/views/widgets/animated_visibility.dart';
|
||||||
import 'package:didvan/views/widgets/didvan/text.dart';
|
import 'package:didvan/views/widgets/didvan/text.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter/services.dart';
|
import 'package:flutter/services.dart';
|
||||||
import 'package:persian_number_utility/persian_number_utility.dart';
|
|
||||||
|
|
||||||
class DidvanTextField extends StatefulWidget {
|
class DidvanTextField extends StatefulWidget {
|
||||||
final void Function(String value)? onChanged;
|
final void Function(String value)? onChanged;
|
||||||
final void Function(String value)? onSubmitted;
|
final void Function(String value)? onSubmitted;
|
||||||
final bool enabled;
|
final bool enabled;
|
||||||
final bool autoFocus;
|
final bool autoFocus;
|
||||||
final TextAlign textAlign;
|
final TextAlign? textAlign;
|
||||||
final String? title;
|
final String? title;
|
||||||
final String? hintText;
|
final String? hintText;
|
||||||
final dynamic initialValue;
|
final dynamic initialValue;
|
||||||
|
|
@ -37,7 +37,7 @@ class DidvanTextField extends StatefulWidget {
|
||||||
this.initialValue,
|
this.initialValue,
|
||||||
this.validator,
|
this.validator,
|
||||||
this.textInputType,
|
this.textInputType,
|
||||||
this.textAlign = TextAlign.right,
|
this.textAlign,
|
||||||
this.obsecureText = false,
|
this.obsecureText = false,
|
||||||
this.autoFocus = false,
|
this.autoFocus = false,
|
||||||
this.onSubmitted,
|
this.onSubmitted,
|
||||||
|
|
@ -69,7 +69,7 @@ class _DidvanTextFieldState extends State<DidvanTextField> {
|
||||||
}
|
}
|
||||||
_hideContent = widget.obsecureText;
|
_hideContent = widget.obsecureText;
|
||||||
_focusNode.addListener(() {
|
_focusNode.addListener(() {
|
||||||
setState(() {});
|
// setState(() {});
|
||||||
});
|
});
|
||||||
super.initState();
|
super.initState();
|
||||||
}
|
}
|
||||||
|
|
@ -98,47 +98,58 @@ class _DidvanTextFieldState extends State<DidvanTextField> {
|
||||||
? null
|
? null
|
||||||
: Border.all(color: _borderColor()),
|
: Border.all(color: _borderColor()),
|
||||||
),
|
),
|
||||||
child: TextFormField(
|
child: ValueListenableBuilder(
|
||||||
inputFormatters: <TextInputFormatter>[
|
valueListenable: _controller,
|
||||||
if (!widget.acceptSpace)
|
builder: (context, val, _) {
|
||||||
FilteringTextInputFormatter.allow(RegExp("[0-9a-zA-Z]")),
|
return Directionality(
|
||||||
],
|
textDirection: val.text.startsWithEnglish()
|
||||||
autofocus: widget.autoFocus,
|
? TextDirection.ltr
|
||||||
obscureText: _hideContent,
|
: TextDirection.rtl,
|
||||||
textAlign: widget.textAlign,
|
child: TextFormField(
|
||||||
keyboardType: widget.textInputType,
|
inputFormatters: <TextInputFormatter>[
|
||||||
focusNode: _focusNode,
|
if (!widget.acceptSpace)
|
||||||
controller: _controller,
|
FilteringTextInputFormatter.allow(
|
||||||
onFieldSubmitted: widget.onSubmitted,
|
RegExp("[0-9a-zA-Z]")),
|
||||||
onChanged: _onChanged,
|
],
|
||||||
validator: _validator,
|
autofocus: widget.autoFocus,
|
||||||
maxLines: widget.maxLine,
|
obscureText: _hideContent,
|
||||||
minLines: widget.minLine,
|
textAlign: widget.textAlign ?? TextAlign.start,
|
||||||
maxLength: widget.maxLength,
|
keyboardType: widget.textInputType,
|
||||||
obscuringCharacter: '*',
|
focusNode: _focusNode,
|
||||||
buildCounter: widget.showLen
|
controller: _controller,
|
||||||
? null
|
onFieldSubmitted: widget.onSubmitted,
|
||||||
: (context,
|
onChanged: _onChanged,
|
||||||
{required currentLength,
|
validator: _validator,
|
||||||
required isFocused,
|
maxLines: widget.maxLine,
|
||||||
required maxLength}) =>
|
minLines: widget.minLine,
|
||||||
const SizedBox(),
|
maxLength: widget.maxLength,
|
||||||
style: (widget.isSmall
|
obscuringCharacter: '*',
|
||||||
? Theme.of(context).textTheme.bodySmall!
|
buildCounter: widget.showLen
|
||||||
: Theme.of(context).textTheme.bodyMedium!)
|
? null
|
||||||
.copyWith(fontFamily: DesignConfig.fontFamily.padRight(3)),
|
: (context,
|
||||||
decoration: InputDecoration(
|
{required currentLength,
|
||||||
suffixIcon: _suffixBuilder(),
|
required isFocused,
|
||||||
enabled: widget.enabled,
|
required maxLength}) =>
|
||||||
border: InputBorder.none,
|
const SizedBox(),
|
||||||
hintText: widget.hintText,
|
style: (widget.isSmall
|
||||||
errorStyle: const TextStyle(height: 0.01),
|
? Theme.of(context).textTheme.bodySmall!
|
||||||
hintStyle: (widget.isSmall
|
: Theme.of(context).textTheme.bodyMedium!)
|
||||||
? Theme.of(context).textTheme.bodySmall!
|
.copyWith(
|
||||||
: Theme.of(context).textTheme.bodyMedium!)
|
fontFamily: DesignConfig.fontFamily.padRight(3)),
|
||||||
.copyWith(color: Theme.of(context).colorScheme.hint),
|
decoration: InputDecoration(
|
||||||
),
|
suffixIcon: _suffixBuilder(),
|
||||||
),
|
enabled: widget.enabled,
|
||||||
|
border: InputBorder.none,
|
||||||
|
hintText: widget.hintText,
|
||||||
|
errorStyle: const TextStyle(height: 0.01),
|
||||||
|
hintStyle: (widget.isSmall
|
||||||
|
? Theme.of(context).textTheme.bodySmall!
|
||||||
|
: Theme.of(context).textTheme.bodyMedium!)
|
||||||
|
.copyWith(color: Theme.of(context).colorScheme.hint),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}),
|
||||||
),
|
),
|
||||||
AnimatedVisibility(
|
AnimatedVisibility(
|
||||||
isVisible: _error != null,
|
isVisible: _error != null,
|
||||||
|
|
@ -224,7 +235,7 @@ class _DidvanTextFieldState extends State<DidvanTextField> {
|
||||||
setState(() {
|
setState(() {
|
||||||
_error = null;
|
_error = null;
|
||||||
});
|
});
|
||||||
value = value.toEnglishDigit();
|
// value = value.toEnglishDigit();
|
||||||
widget.onChanged?.call(value);
|
widget.onChanged?.call(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue