little better fix audio 3/07/1403
This commit is contained in:
parent
f72228b339
commit
fbb9db5103
|
|
@ -99,20 +99,21 @@ class Prompts {
|
|||
bool? error;
|
||||
bool? audio;
|
||||
FilesModel? fileLocal;
|
||||
int? duration;
|
||||
|
||||
Prompts({
|
||||
this.id,
|
||||
this.chatId,
|
||||
this.text,
|
||||
this.file,
|
||||
this.fileName,
|
||||
this.role,
|
||||
this.createdAt,
|
||||
this.finished,
|
||||
this.error,
|
||||
this.fileLocal,
|
||||
this.audio,
|
||||
});
|
||||
Prompts(
|
||||
{this.id,
|
||||
this.chatId,
|
||||
this.text,
|
||||
this.file,
|
||||
this.fileName,
|
||||
this.role,
|
||||
this.createdAt,
|
||||
this.finished,
|
||||
this.error,
|
||||
this.fileLocal,
|
||||
this.audio,
|
||||
this.duration});
|
||||
|
||||
Prompts.fromJson(Map<String, dynamic> json) {
|
||||
id = json['id'];
|
||||
|
|
@ -123,6 +124,7 @@ class Prompts {
|
|||
role = json['role'];
|
||||
createdAt = json['createdAt'];
|
||||
audio = json['audio'];
|
||||
duration = json['duration'];
|
||||
}
|
||||
|
||||
Map<String, dynamic> toJson() {
|
||||
|
|
@ -135,21 +137,24 @@ class Prompts {
|
|||
data['role'] = role;
|
||||
data['createdAt'] = createdAt;
|
||||
data['audio'] = audio;
|
||||
data['duration'] = duration;
|
||||
return data;
|
||||
}
|
||||
|
||||
Prompts copyWith(
|
||||
{int? id,
|
||||
int? chatId,
|
||||
String? text,
|
||||
String? file,
|
||||
String? fileName,
|
||||
FilesModel? fileLocal,
|
||||
String? role,
|
||||
String? createdAt,
|
||||
bool? finished,
|
||||
bool? error,
|
||||
bool? audio}) {
|
||||
Prompts copyWith({
|
||||
int? id,
|
||||
int? chatId,
|
||||
String? text,
|
||||
String? file,
|
||||
String? fileName,
|
||||
FilesModel? fileLocal,
|
||||
String? role,
|
||||
String? createdAt,
|
||||
bool? finished,
|
||||
bool? error,
|
||||
bool? audio,
|
||||
int? duration,
|
||||
}) {
|
||||
return Prompts(
|
||||
id: id ?? this.id,
|
||||
chatId: chatId ?? this.chatId,
|
||||
|
|
@ -162,6 +167,7 @@ class Prompts {
|
|||
finished: finished ?? this.finished,
|
||||
error: error ?? this.error,
|
||||
audio: audio ?? this.audio,
|
||||
duration: duration ?? this.duration,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -14,6 +14,7 @@ class FilesModel {
|
|||
final bool? image;
|
||||
final bool? network;
|
||||
final Uint8List? bytes;
|
||||
final Duration? duration;
|
||||
|
||||
FilesModel(
|
||||
this.path, {
|
||||
|
|
@ -23,6 +24,7 @@ class FilesModel {
|
|||
this.image,
|
||||
this.network,
|
||||
this.bytes,
|
||||
this.duration,
|
||||
}) {
|
||||
basename = name ?? p.basename(path);
|
||||
extname = p.extension(path);
|
||||
|
|
|
|||
|
|
@ -33,7 +33,11 @@ class AiApiService {
|
|||
if (edite != null) {
|
||||
request.fields['edit'] = edite.toString().toLowerCase();
|
||||
}
|
||||
|
||||
if (file != null) {
|
||||
if (file.duration != null) {
|
||||
request.fields['duration'] = file.duration!.inSeconds.toString();
|
||||
}
|
||||
Uint8List bytes;
|
||||
String filename;
|
||||
String mimeType;
|
||||
|
|
@ -45,6 +49,8 @@ class AiApiService {
|
|||
final Uri audioUri = Uri.parse(file.path.replaceAll('%3A', ':'));
|
||||
final http.Response audioResponse = await http.get(audioUri);
|
||||
bytes = audioResponse.bodyBytes;
|
||||
// final f = File.fromUri(Uri.parse(file.path));
|
||||
// bytes = await f.readAsBytes();
|
||||
|
||||
// Fetch the blob using JavaScript interop
|
||||
// final blob = await html.window
|
||||
|
|
|
|||
|
|
@ -34,7 +34,6 @@ class MediaService {
|
|||
String tag;
|
||||
tag =
|
||||
'${currentPodcast?.description == 'radar' ? 'radar' : isVoiceMessage ? 'message' : 'podcast'}-$id';
|
||||
print("tag: $tag");
|
||||
if (!isVoiceMessage && MediaProvider.downloadedItemIds.contains(id)) {
|
||||
audioSource = '${StorageService.appDocsDir}/podcasts/podcast-$id.mp3';
|
||||
isNetworkAudio = false;
|
||||
|
|
|
|||
|
|
@ -1,4 +1,3 @@
|
|||
import 'package:didvan/services/media/media.dart';
|
||||
import 'package:didvan/services/network/request.dart';
|
||||
import 'package:didvan/services/network/request_helper.dart';
|
||||
import 'package:flutter/foundation.dart';
|
||||
|
|
@ -52,13 +51,19 @@ class VoiceService {
|
|||
return duration;
|
||||
}
|
||||
|
||||
static Future<void> voiceHelper({required String src}) async {
|
||||
static Future<void> voiceHelper(
|
||||
{required String src,
|
||||
final Duration? duration,
|
||||
final Function()? startTimer,
|
||||
final Function()? stopTimer}) async {
|
||||
try {
|
||||
if (VoiceService.src == src) {
|
||||
if (audioPlayer.playing) {
|
||||
await audioPlayer.pause();
|
||||
stopTimer?.call();
|
||||
} else {
|
||||
await audioPlayer.play();
|
||||
startTimer?.call();
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
|
@ -88,6 +93,8 @@ class VoiceService {
|
|||
await audioPlayer.setFilePath(src);
|
||||
}
|
||||
await audioPlayer.play();
|
||||
|
||||
startTimer?.call();
|
||||
} catch (e) {
|
||||
resetVoicePlayer();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,7 +3,6 @@
|
|||
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;
|
||||
|
|
|
|||
|
|
@ -348,8 +348,6 @@ class ActionSheetUtils {
|
|||
),
|
||||
)
|
||||
: ListView.builder(
|
||||
padding:
|
||||
const EdgeInsets.symmetric(vertical: 12),
|
||||
itemCount: state.bots.length,
|
||||
physics: const BouncingScrollPhysics(),
|
||||
shrinkWrap: true,
|
||||
|
|
|
|||
|
|
@ -1,5 +1,7 @@
|
|||
// ignore_for_file: library_private_types_in_public_api
|
||||
|
||||
import 'dart:math';
|
||||
|
||||
import 'package:cached_network_image/cached_network_image.dart';
|
||||
import 'package:didvan/config/design_config.dart';
|
||||
import 'package:didvan/config/theme_data.dart';
|
||||
|
|
@ -9,6 +11,7 @@ import 'package:didvan/models/ai/ai_chat_args.dart';
|
|||
import 'package:didvan/routes/routes.dart';
|
||||
import 'package:didvan/utils/action_sheet.dart';
|
||||
import 'package:didvan/views/ai/history_ai_chat_state.dart';
|
||||
import 'package:didvan/views/ai/widgets/message_bar_btn.dart';
|
||||
import 'package:didvan/views/home/home.dart';
|
||||
import 'package:didvan/views/widgets/didvan/text.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
|
@ -83,38 +86,66 @@ class _AiState extends State<Ai> {
|
|||
onTap: () => ActionSheetUtils(context)
|
||||
.botsDialogSelect(
|
||||
context: context, state: state),
|
||||
child: Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
Row(
|
||||
child: Container(
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: BorderRadius.circular(360),
|
||||
border: Border.all(
|
||||
width: 1,
|
||||
color:
|
||||
Theme.of(context).colorScheme.text)),
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.symmetric(
|
||||
vertical: 8.0, horizontal: 18),
|
||||
child: Row(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
Icon(
|
||||
DidvanIcons.caret_down_solid,
|
||||
color:
|
||||
Theme.of(context).colorScheme.title,
|
||||
Row(
|
||||
mainAxisAlignment:
|
||||
MainAxisAlignment.center,
|
||||
children: [
|
||||
Column(
|
||||
children: [
|
||||
Transform.rotate(
|
||||
angle: 180 * pi / 180,
|
||||
child: Icon(
|
||||
DidvanIcons.caret_down_solid,
|
||||
color: Theme.of(context)
|
||||
.colorScheme
|
||||
.title,
|
||||
),
|
||||
),
|
||||
Icon(
|
||||
DidvanIcons.caret_down_solid,
|
||||
color: Theme.of(context)
|
||||
.colorScheme
|
||||
.title,
|
||||
),
|
||||
],
|
||||
),
|
||||
const SizedBox(
|
||||
width: 12,
|
||||
),
|
||||
DidvanText(bot.name.toString(),
|
||||
color: Theme.of(context)
|
||||
.colorScheme
|
||||
.title),
|
||||
],
|
||||
),
|
||||
const SizedBox(
|
||||
width: 12,
|
||||
),
|
||||
DidvanText(bot.name.toString(),
|
||||
color: Theme.of(context)
|
||||
.colorScheme
|
||||
.title),
|
||||
ClipOval(
|
||||
child: CachedNetworkImage(
|
||||
width: 46,
|
||||
height: 46,
|
||||
imageUrl: bot.image.toString(),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
const SizedBox(
|
||||
width: 12,
|
||||
),
|
||||
ClipOval(
|
||||
child: CachedNetworkImage(
|
||||
width: 46,
|
||||
height: 46,
|
||||
imageUrl: bot.image.toString(),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
const SizedBox(
|
||||
|
|
@ -161,43 +192,71 @@ class _AiState extends State<Ai> {
|
|||
arguments: AiChatArgs(
|
||||
bot: bot,
|
||||
)),
|
||||
child: Container(
|
||||
decoration: BoxDecoration(
|
||||
boxShadow: DesignConfig.defaultShadow,
|
||||
color: Theme.of(context).colorScheme.surface,
|
||||
border: Border.all(
|
||||
color: Theme.of(context).colorScheme.border),
|
||||
borderRadius: DesignConfig.highBorderRadius),
|
||||
child: Row(
|
||||
children: [
|
||||
const SizedBox(
|
||||
width: 8,
|
||||
child: Row(
|
||||
children: [
|
||||
Expanded(
|
||||
child: Container(
|
||||
decoration: BoxDecoration(
|
||||
boxShadow: DesignConfig.defaultShadow,
|
||||
color: Theme.of(context).colorScheme.surface,
|
||||
border: Border.all(
|
||||
color: Theme.of(context).colorScheme.border),
|
||||
borderRadius: DesignConfig.highBorderRadius),
|
||||
child: Row(
|
||||
children: [
|
||||
const SizedBox(
|
||||
width: 8,
|
||||
),
|
||||
Expanded(
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.symmetric(
|
||||
horizontal: 8.0,
|
||||
),
|
||||
child: Form(
|
||||
child: Row(
|
||||
children: [
|
||||
const MessageBarBtn(
|
||||
enable: false,
|
||||
icon: DidvanIcons.mic_regular),
|
||||
const SizedBox(
|
||||
width: 8,
|
||||
),
|
||||
Expanded(
|
||||
child: TextFormField(
|
||||
textInputAction:
|
||||
TextInputAction.newline,
|
||||
style: Theme.of(context)
|
||||
.textTheme
|
||||
.bodyMedium,
|
||||
minLines: 1,
|
||||
enabled: false,
|
||||
decoration: InputDecoration(
|
||||
border: InputBorder.none,
|
||||
hintText: 'بنویسید...',
|
||||
hintStyle: Theme.of(context)
|
||||
.textTheme
|
||||
.bodySmall!
|
||||
.copyWith(
|
||||
color: Theme.of(context)
|
||||
.colorScheme
|
||||
.disabledText),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
))))
|
||||
],
|
||||
),
|
||||
),
|
||||
Expanded(
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.symmetric(
|
||||
horizontal: 8.0,
|
||||
),
|
||||
child: Form(
|
||||
child: TextFormField(
|
||||
textInputAction: TextInputAction.newline,
|
||||
style: Theme.of(context).textTheme.bodyMedium,
|
||||
minLines: 1,
|
||||
enabled: false,
|
||||
decoration: InputDecoration(
|
||||
border: InputBorder.none,
|
||||
hintText: 'بنویسید...',
|
||||
hintStyle: Theme.of(context)
|
||||
.textTheme
|
||||
.bodySmall!
|
||||
.copyWith(
|
||||
color: Theme.of(context)
|
||||
.colorScheme
|
||||
.disabledText),
|
||||
),
|
||||
))))
|
||||
],
|
||||
),
|
||||
),
|
||||
const SizedBox(
|
||||
width: 18,
|
||||
),
|
||||
Icon(
|
||||
Icons.attach_file_rounded,
|
||||
color: Theme.of(context).colorScheme.focusedBorder,
|
||||
),
|
||||
],
|
||||
)),
|
||||
),
|
||||
],
|
||||
|
|
|
|||
|
|
@ -232,23 +232,29 @@ class _AiChatPageState extends State<AiChatPage> {
|
|||
const SizedBox(
|
||||
height: 24,
|
||||
),
|
||||
SizedBox(
|
||||
width: MediaQuery.sizeOf(context).height / 5,
|
||||
height: MediaQuery.sizeOf(context).height / 5,
|
||||
child: ClipOval(
|
||||
child: CachedNetworkImage(
|
||||
imageUrl: widget.args.bot.image.toString(),
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
DidvanText(widget.args.bot.name.toString()),
|
||||
const SizedBox(
|
||||
width: 12,
|
||||
),
|
||||
),
|
||||
ClipOval(
|
||||
child: CachedNetworkImage(
|
||||
width: 46,
|
||||
height: 46,
|
||||
imageUrl: widget.args.bot.image.toString(),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
const SizedBox(
|
||||
height: 24,
|
||||
),
|
||||
Padding(
|
||||
padding:
|
||||
const EdgeInsets.symmetric(horizontal: 20.0),
|
||||
const Padding(
|
||||
padding: EdgeInsets.symmetric(horizontal: 20.0),
|
||||
child: Text(
|
||||
"به هوشان, هوش مصنوعی دیدوان خوش آمدید. \nبرای شروع گفتگو پیام مورد نظر خود را در کادر زیر بنویسید.\n دریافت پاسخ از: ${widget.args.bot.name}",
|
||||
"به هوشان, هوش مصنوعی دیدوان خوش آمدید. \nبرای شروع گفتگو پیام مورد نظر خود را در کادر زیر بنویسید.",
|
||||
textAlign: TextAlign.center,
|
||||
),
|
||||
)
|
||||
|
|
@ -324,7 +330,12 @@ class _AiChatPageState extends State<AiChatPage> {
|
|||
Widget messageBubble(Prompts message, BuildContext context, AiChatState state,
|
||||
int index, int mIndex) {
|
||||
FilesModel? file = message.fileLocal ??
|
||||
(message.file == null ? null : FilesModel(message.file.toString()));
|
||||
(message.file == null
|
||||
? null
|
||||
: FilesModel(message.file.toString(),
|
||||
duration: message.duration != null
|
||||
? Duration(seconds: message.duration!)
|
||||
: null));
|
||||
|
||||
MarkdownStyleSheet defaultMarkdownStyleSheet = MarkdownStyleSheet(
|
||||
pPadding: const EdgeInsets.all(0.8),
|
||||
|
|
@ -427,7 +438,10 @@ class _AiChatPageState extends State<AiChatPage> {
|
|||
? Padding(
|
||||
padding: const EdgeInsets.symmetric(
|
||||
horizontal: 16, vertical: 8),
|
||||
child: AudioWave(file: file.path),
|
||||
child: AudioWave(
|
||||
file: file.path,
|
||||
totalDuration: file.duration,
|
||||
),
|
||||
)
|
||||
: file.isImage()
|
||||
? Padding(
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@ import 'package:didvan/models/ai/chats_model.dart';
|
|||
import 'package:didvan/models/ai/files_model.dart';
|
||||
import 'package:didvan/models/ai/messages_model.dart';
|
||||
import 'package:didvan/services/media/media.dart';
|
||||
import 'package:didvan/services/media/voice.dart';
|
||||
import 'package:didvan/utils/action_sheet.dart';
|
||||
import 'package:didvan/utils/date_time.dart';
|
||||
import 'package:didvan/views/ai/ai_chat_state.dart';
|
||||
|
|
@ -337,13 +338,21 @@ class _AiMessageBarState extends State<AiMessageBar> {
|
|||
path = await record
|
||||
.stop();
|
||||
|
||||
Duration? duration =
|
||||
await VoiceService
|
||||
.getDuration(
|
||||
src: path ??
|
||||
'');
|
||||
|
||||
state.file = FilesModel(
|
||||
path.toString(),
|
||||
name:
|
||||
'${DateTime.now().millisecondsSinceEpoch ~/ 1000}.m4a',
|
||||
isRecorded: true,
|
||||
audio: true,
|
||||
image: false);
|
||||
image: false,
|
||||
duration:
|
||||
duration);
|
||||
_timer.cancel();
|
||||
_countTimer.value = 0;
|
||||
state.update();
|
||||
|
|
@ -371,7 +380,7 @@ class _AiMessageBarState extends State<AiMessageBar> {
|
|||
.hasPermission()) {
|
||||
try {
|
||||
String path =
|
||||
'';
|
||||
'${DateTime.now().millisecondsSinceEpoch ~/ 1000}.m4a';
|
||||
//
|
||||
if (!kIsWeb) {
|
||||
Directory?
|
||||
|
|
|
|||
|
|
@ -6,7 +6,6 @@ import 'package:audio_video_progress_bar/audio_video_progress_bar.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/services/media/media.dart';
|
||||
import 'package:didvan/services/media/voice.dart';
|
||||
import 'package:didvan/views/ai/widgets/message_bar_btn.dart';
|
||||
import 'package:flutter/foundation.dart';
|
||||
|
|
@ -17,7 +16,12 @@ import 'package:just_audio/just_audio.dart';
|
|||
class AudioWave extends StatefulWidget {
|
||||
final String file;
|
||||
final double loadingPaddingSize;
|
||||
const AudioWave({Key? key, required this.file, this.loadingPaddingSize = 0})
|
||||
final Duration? totalDuration;
|
||||
const AudioWave(
|
||||
{Key? key,
|
||||
required this.file,
|
||||
this.loadingPaddingSize = 0,
|
||||
this.totalDuration})
|
||||
: super(key: key);
|
||||
|
||||
@override
|
||||
|
|
@ -35,14 +39,18 @@ class _AudioWaveState extends State<AudioWave> {
|
|||
void initState() {
|
||||
super.initState();
|
||||
WidgetsBinding.instance.addPostFrameCallback((_) async {
|
||||
await VoiceService.getDuration(src: widget.file).then((duration) {
|
||||
setState(() {
|
||||
totalDuration = duration;
|
||||
if (kDebugMode) {
|
||||
print(totalDuration!.inSeconds);
|
||||
}
|
||||
if (widget.totalDuration == null) {
|
||||
await VoiceService.getDuration(src: widget.file).then((duration) {
|
||||
setState(() {
|
||||
totalDuration = duration;
|
||||
if (kDebugMode) {
|
||||
print(totalDuration!.inSeconds);
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
} else {
|
||||
totalDuration = widget.totalDuration;
|
||||
}
|
||||
});
|
||||
// listeners();
|
||||
}
|
||||
|
|
@ -63,18 +71,18 @@ class _AudioWaveState extends State<AudioWave> {
|
|||
mainAxisSize: MainAxisSize.min,
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
children: [
|
||||
StreamBuilder<PlayerState>(
|
||||
stream: VoiceService.audioPlayer.playerStateStream,
|
||||
StreamBuilder<PlaybackEvent>(
|
||||
stream: VoiceService.audioPlayer.playbackEventStream,
|
||||
builder: (context, snapshot) {
|
||||
if (!snapshot.hasData) {
|
||||
return const SizedBox();
|
||||
}
|
||||
|
||||
if (snapshot.data!.processingState ==
|
||||
ProcessingState.completed) {
|
||||
VoiceService.audioPlayer.pause();
|
||||
VoiceService.audioPlayer.seek(Duration.zero);
|
||||
}
|
||||
print(snapshot.data);
|
||||
if ((snapshot.data!.processingState ==
|
||||
ProcessingState.loading ||
|
||||
snapshot.data!.processingState ==
|
||||
|
|
@ -91,7 +99,7 @@ class _AudioWaveState extends State<AudioWave> {
|
|||
}
|
||||
return MessageBarBtn(
|
||||
enable: true,
|
||||
icon: snapshot.data!.playing &&
|
||||
icon: VoiceService.audioPlayer.playing &&
|
||||
VoiceService.src == widget.file
|
||||
? DidvanIcons.pause_solid
|
||||
: DidvanIcons.play_solid,
|
||||
|
|
@ -107,7 +115,12 @@ class _AudioWaveState extends State<AudioWave> {
|
|||
if (!snapshot.hasData) {
|
||||
return const SizedBox();
|
||||
}
|
||||
return totalDuration == null
|
||||
return totalDuration == null ||
|
||||
(totalDuration != null &&
|
||||
VoiceService.audioPlayer.playing &&
|
||||
VoiceService.audioPlayer.duration!.inSeconds !=
|
||||
totalDuration!.inSeconds &&
|
||||
VoiceService.src == widget.file)
|
||||
? Padding(
|
||||
padding: EdgeInsets.symmetric(
|
||||
vertical: widget.loadingPaddingSize),
|
||||
|
|
|
|||
|
|
@ -1,5 +1,4 @@
|
|||
import 'package:didvan/config/theme_data.dart';
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_spinkit/flutter_spinkit.dart';
|
||||
|
||||
|
|
@ -44,7 +43,6 @@ class MessageBarBtn extends StatelessWidget {
|
|||
child: Padding(
|
||||
padding: EdgeInsets.all(8.0),
|
||||
child: SpinKitCircle(
|
||||
size: 24,
|
||||
color: Colors.white,
|
||||
),
|
||||
))
|
||||
|
|
|
|||
|
|
@ -17,12 +17,14 @@ class AudioWidget extends StatelessWidget {
|
|||
final File? audioFile;
|
||||
final int id;
|
||||
final StudioDetailsData? audioMetaData;
|
||||
final Duration? duration;
|
||||
const AudioWidget({
|
||||
Key? key,
|
||||
this.audioUrl,
|
||||
this.audioFile,
|
||||
required this.id,
|
||||
this.audioMetaData,
|
||||
this.duration,
|
||||
}) : super(key: key);
|
||||
|
||||
@override
|
||||
|
|
@ -43,7 +45,8 @@ class AudioWidget extends StatelessWidget {
|
|||
tag: audioMetaData != null
|
||||
? '${audioMetaData!.type}-$id'
|
||||
: 'message-$id',
|
||||
duration: audioMetaData?.duration,
|
||||
duration:
|
||||
audioMetaData?.duration ?? duration?.inSeconds,
|
||||
showTimer: true,
|
||||
),
|
||||
),
|
||||
|
|
@ -88,6 +91,11 @@ class _AudioControllerButton extends StatelessWidget {
|
|||
return StreamBuilder<PlayerState>(
|
||||
stream: MediaService.audioPlayer.playerStateStream,
|
||||
builder: (context, snapshot) {
|
||||
if (snapshot.hasData &&
|
||||
snapshot.data!.processingState == ProcessingState.completed) {
|
||||
MediaService.audioPlayer.pause();
|
||||
MediaService.audioPlayer.seek(Duration.zero);
|
||||
}
|
||||
return DidvanIconButton(
|
||||
icon: MediaService.audioPlayer.playing && _nowPlaying
|
||||
? DidvanIcons.pause_circle_solid
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ import 'package:didvan/config/design_config.dart';
|
|||
import 'package:didvan/config/theme_data.dart';
|
||||
import 'package:didvan/constants/app_icons.dart';
|
||||
import 'package:didvan/models/message_data/message_data.dart';
|
||||
import 'package:didvan/services/media/voice.dart';
|
||||
import 'package:didvan/utils/date_time.dart';
|
||||
import 'package:didvan/views/direct/direct_state.dart';
|
||||
import 'package:didvan/views/direct/widgets/audio_widget.dart';
|
||||
|
|
@ -9,6 +10,7 @@ import 'package:didvan/views/widgets/didvan/divider.dart';
|
|||
import 'package:didvan/views/widgets/didvan/text.dart';
|
||||
import 'package:didvan/views/widgets/skeleton_image.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_spinkit/flutter_spinkit.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import 'package:persian_number_utility/persian_number_utility.dart';
|
||||
|
||||
|
|
@ -84,11 +86,34 @@ class Message extends StatelessWidget {
|
|||
children: [
|
||||
if (message.text != null) DidvanText(message.text!),
|
||||
if (message.audio != null || message.audioFile != null)
|
||||
AudioWidget(
|
||||
audioFile: message.audioFile,
|
||||
audioUrl: message.audio,
|
||||
id: message.id,
|
||||
),
|
||||
FutureBuilder(
|
||||
future: VoiceService.getDuration(
|
||||
src: message.audioFile == null
|
||||
? message.audio!
|
||||
: message.audioFile!.path),
|
||||
builder: (context, snapshot) {
|
||||
if (!snapshot.hasData) {
|
||||
return Row(
|
||||
mainAxisAlignment:
|
||||
MainAxisAlignment.center,
|
||||
children: List.generate(
|
||||
5,
|
||||
(index) => SpinKitWave(
|
||||
color: Theme.of(context)
|
||||
.colorScheme
|
||||
.primary
|
||||
.withOpacity(0.4),
|
||||
size: 32,
|
||||
itemCount: 10,
|
||||
)));
|
||||
}
|
||||
return AudioWidget(
|
||||
audioFile: message.audioFile,
|
||||
audioUrl: message.audio,
|
||||
id: message.id,
|
||||
duration: snapshot.data,
|
||||
);
|
||||
}),
|
||||
if (message.radar != null || message.news != null)
|
||||
const DidvanDivider(),
|
||||
if (message.radar != null || message.news != null)
|
||||
|
|
|
|||
|
|
@ -21,7 +21,6 @@ class AudioSlider extends StatelessWidget {
|
|||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
print(MediaService.audioPlayerTag);
|
||||
return IgnorePointer(
|
||||
ignoring: !_isPlaying,
|
||||
child: Directionality(
|
||||
|
|
|
|||
|
|
@ -73,14 +73,6 @@ packages:
|
|||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.8.2"
|
||||
azblob:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: azblob
|
||||
sha256: e9e8689280bd8fa19c1c21a476547de80d2a770c81d2da9da68173c7f5479c7b
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "4.0.0"
|
||||
boolean_selector:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
|
|
|||
|
|
@ -95,7 +95,6 @@ dependencies:
|
|||
flutter_local_notifications: ^17.2.2
|
||||
flutter_background_service: ^5.0.10
|
||||
js: ^0.6.7
|
||||
azblob: ^4.0.0
|
||||
# url_launcher: ^6.3.0
|
||||
|
||||
dev_dependencies:
|
||||
|
|
|
|||
Loading…
Reference in New Issue