...
This commit is contained in:
@@ -175,15 +175,15 @@
|
|||||||
<Button Color="ButtonColor.Secondary" Size=ButtonSize.Small Outline="true" @onclick="OpenFileDialog" Class="attach-btn" title="افزودن تصویر">
|
<Button Color="ButtonColor.Secondary" Size=ButtonSize.Small Outline="true" @onclick="OpenFileDialog" Class="attach-btn" title="افزودن تصویر">
|
||||||
<Icon Name="IconName.Image" />
|
<Icon Name="IconName.Image" />
|
||||||
</Button>
|
</Button>
|
||||||
|
|
||||||
<!-- Audio Recording Button -->
|
<!-- Audio Recording Button -->
|
||||||
<Button Color="@(IsRecording ? ButtonColor.Danger : ButtonColor.Secondary)"
|
<Button Color="@(IsRecording ? ButtonColor.Danger : ButtonColor.Secondary)"
|
||||||
Size=ButtonSize.Small
|
Size=ButtonSize.Small
|
||||||
Outline="true"
|
Outline="true"
|
||||||
@onclick="ToggleAudioRecording"
|
@onclick="ToggleAudioRecording"
|
||||||
class=@($"audio-btn {(IsRecording ? "recording" : "")}")
|
class=@($"audio-btn {(IsRecording ? "recording" : "")}")
|
||||||
title="@(IsRecording ? "توقف ضبط" : "ضبط صدا")"
|
title="@(IsRecording ? "توقف ضبط" : "ضبط صدا")"
|
||||||
>
|
>
|
||||||
@if (IsRecording)
|
@if (IsRecording)
|
||||||
{
|
{
|
||||||
<Icon Name="IconName.StopCircle" Class="recording-pulse" />
|
<Icon Name="IconName.StopCircle" Class="recording-pulse" />
|
||||||
@@ -193,12 +193,12 @@
|
|||||||
<Icon Name="IconName.Mic" />
|
<Icon Name="IconName.Mic" />
|
||||||
}
|
}
|
||||||
</Button>
|
</Button>
|
||||||
|
|
||||||
<Button Color="ButtonColor.Primary" Size=ButtonSize.Small @onclick="OnClickSendMsg" Class="send-btn" title="ارسال">
|
<Button Color="ButtonColor.Primary" Size=ButtonSize.Small @onclick="OnClickSendMsg" Class="send-btn" title="ارسال">
|
||||||
<Icon Name="IconName.Send" />
|
<Icon Name="IconName.Send" />
|
||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Image Preview -->
|
<!-- Image Preview -->
|
||||||
@if (SelectedImagePreview != null)
|
@if (SelectedImagePreview != null)
|
||||||
{
|
{
|
||||||
@@ -207,7 +207,7 @@
|
|||||||
<Button Color="ButtonColor.Secondary" Size=ButtonSize.ExtraSmall Outline="true" @onclick="ClearSelectedImage">حذف تصویر</Button>
|
<Button Color="ButtonColor.Secondary" Size=ButtonSize.ExtraSmall Outline="true" @onclick="ClearSelectedImage">حذف تصویر</Button>
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
|
|
||||||
<!-- Audio Preview -->
|
<!-- Audio Preview -->
|
||||||
@if (RecordedAudioBytes != null)
|
@if (RecordedAudioBytes != null)
|
||||||
{
|
{
|
||||||
@@ -223,7 +223,7 @@
|
|||||||
<Button Color="ButtonColor.Danger" Size=ButtonSize.ExtraSmall Outline="true" @onclick="ClearRecordedAudio">حذف صدا</Button>
|
<Button Color="ButtonColor.Danger" Size=ButtonSize.ExtraSmall Outline="true" @onclick="ClearRecordedAudio">حذف صدا</Button>
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
|
|
||||||
<!-- Recording Status -->
|
<!-- Recording Status -->
|
||||||
@if (IsRecording)
|
@if (IsRecording)
|
||||||
{
|
{
|
||||||
@@ -278,7 +278,7 @@
|
|||||||
IBrowserFile? SelectedImageFile = null;
|
IBrowserFile? SelectedImageFile = null;
|
||||||
byte[]? SelectedImageBytes = null;
|
byte[]? SelectedImageBytes = null;
|
||||||
string? SelectedImagePreview = null;
|
string? SelectedImagePreview = null;
|
||||||
|
|
||||||
// Audio recording properties
|
// Audio recording properties
|
||||||
bool IsRecording = false;
|
bool IsRecording = false;
|
||||||
string RecordingTime = "00:00";
|
string RecordingTime = "00:00";
|
||||||
@@ -287,7 +287,7 @@
|
|||||||
string RecordedAudioDuration = "00:00";
|
string RecordedAudioDuration = "00:00";
|
||||||
private System.Threading.Timer? recordingTimer;
|
private System.Threading.Timer? recordingTimer;
|
||||||
private DateTime recordingStartTime;
|
private DateTime recordingStartTime;
|
||||||
|
|
||||||
bool chatloading = false;
|
bool chatloading = false;
|
||||||
public bool IsLogin { get; set; } = false;
|
public bool IsLogin { get; set; } = false;
|
||||||
public bool IsEndFirstProcess { get; set; } = false;
|
public bool IsEndFirstProcess { get; set; } = false;
|
||||||
@@ -317,7 +317,7 @@
|
|||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Audio recording methods
|
// Audio recording methods
|
||||||
private async Task ToggleAudioRecording()
|
private async Task ToggleAudioRecording()
|
||||||
{
|
{
|
||||||
@@ -330,7 +330,7 @@
|
|||||||
await StartAudioRecording();
|
await StartAudioRecording();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task StartAudioRecording()
|
private async Task StartAudioRecording()
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
@@ -353,7 +353,7 @@
|
|||||||
toastService.Notify(new ToastMessage(ToastType.Danger, $"خطا در ضبط صدا: {ex.Message}"));
|
toastService.Notify(new ToastMessage(ToastType.Danger, $"خطا در ضبط صدا: {ex.Message}"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task StopAudioRecording()
|
private async Task StopAudioRecording()
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
@@ -366,10 +366,11 @@
|
|||||||
RecordedAudioBytes = Convert.FromBase64String(base64Data);
|
RecordedAudioBytes = Convert.FromBase64String(base64Data);
|
||||||
RecordedAudioUrl = audioData;
|
RecordedAudioUrl = audioData;
|
||||||
RecordedAudioDuration = RecordingTime;
|
RecordedAudioDuration = RecordingTime;
|
||||||
|
|
||||||
IsRecording = false;
|
IsRecording = false;
|
||||||
recordingTimer?.Dispose();
|
recordingTimer?.Dispose();
|
||||||
recordingTimer = null;
|
recordingTimer = null;
|
||||||
|
await ClearSelectedImage();
|
||||||
StateHasChanged();
|
StateHasChanged();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -385,14 +386,14 @@
|
|||||||
StateHasChanged();
|
StateHasChanged();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void UpdateRecordingTime(object? state)
|
private void UpdateRecordingTime(object? state)
|
||||||
{
|
{
|
||||||
var elapsed = DateTime.Now - recordingStartTime;
|
var elapsed = DateTime.Now - recordingStartTime;
|
||||||
RecordingTime = $"{elapsed.Minutes:D2}:{elapsed.Seconds:D2}";
|
RecordingTime = $"{elapsed.Minutes:D2}:{elapsed.Seconds:D2}";
|
||||||
InvokeAsync(StateHasChanged);
|
InvokeAsync(StateHasChanged);
|
||||||
}
|
}
|
||||||
|
|
||||||
private Task ClearRecordedAudio()
|
private Task ClearRecordedAudio()
|
||||||
{
|
{
|
||||||
RecordedAudioBytes = null;
|
RecordedAudioBytes = null;
|
||||||
@@ -400,17 +401,17 @@
|
|||||||
RecordedAudioDuration = "00:00";
|
RecordedAudioDuration = "00:00";
|
||||||
return Task.CompletedTask;
|
return Task.CompletedTask;
|
||||||
}
|
}
|
||||||
|
|
||||||
private string GetAudioDataUrl(string? fileType, byte[]? content)
|
private string GetAudioDataUrl(string? fileType, byte[]? content)
|
||||||
=> (string.IsNullOrWhiteSpace(fileType) || content == null || content.Length == 0)
|
=> (string.IsNullOrWhiteSpace(fileType) || content == null || content.Length == 0)
|
||||||
? string.Empty
|
? string.Empty
|
||||||
: $"data:{fileType};base64,{Convert.ToBase64String(content)}";
|
: $"data:{fileType};base64,{Convert.ToBase64String(content)}";
|
||||||
|
|
||||||
private string GetAudioDuration(byte[]? content)
|
private string GetAudioDuration(byte[]? content)
|
||||||
{
|
{
|
||||||
// Simple duration calculation based on file size (approximate)
|
// Simple duration calculation based on file size (approximate)
|
||||||
if (content == null || content.Length == 0) return "00:00";
|
if (content == null || content.Length == 0) return "00:00";
|
||||||
|
|
||||||
// Assuming 16-bit PCM at 44.1kHz, mono
|
// Assuming 16-bit PCM at 44.1kHz, mono
|
||||||
var bytesPerSecond = 44100 * 2; // 44.1kHz * 2 bytes per sample
|
var bytesPerSecond = 44100 * 2; // 44.1kHz * 2 bytes per sample
|
||||||
var durationSeconds = content.Length / bytesPerSecond;
|
var durationSeconds = content.Length / bytesPerSecond;
|
||||||
@@ -428,7 +429,7 @@
|
|||||||
{
|
{
|
||||||
Common.Enums.ConversationType type = Common.Enums.ConversationType.UE;
|
Common.Enums.ConversationType type = Common.Enums.ConversationType.UE;
|
||||||
ChatItemResponseDto? model;
|
ChatItemResponseDto? model;
|
||||||
|
|
||||||
if (SelectedImageFile != null)
|
if (SelectedImageFile != null)
|
||||||
{
|
{
|
||||||
var bytes = SelectedImageBytes ?? Array.Empty<byte>();
|
var bytes = SelectedImageBytes ?? Array.Empty<byte>();
|
||||||
@@ -456,7 +457,7 @@
|
|||||||
{
|
{
|
||||||
model = await chatService.ADDChatResponse(LastOpenChat.ID, MsgInput, type);
|
model = await chatService.ADDChatResponse(LastOpenChat.ID, MsgInput, type);
|
||||||
}
|
}
|
||||||
|
|
||||||
LastOpenChat?.Responses.Add(model);
|
LastOpenChat?.Responses.Add(model);
|
||||||
LastOpenChat.LastText = MsgInput;
|
LastOpenChat.LastText = MsgInput;
|
||||||
|
|
||||||
@@ -486,7 +487,7 @@
|
|||||||
SelectedImageFile = null;
|
SelectedImageFile = null;
|
||||||
SelectedImageBytes = null;
|
SelectedImageBytes = null;
|
||||||
SelectedImagePreview = null;
|
SelectedImagePreview = null;
|
||||||
|
|
||||||
// Clear recorded audio after sending
|
// Clear recorded audio after sending
|
||||||
RecordedAudioBytes = null;
|
RecordedAudioBytes = null;
|
||||||
RecordedAudioUrl = null;
|
RecordedAudioUrl = null;
|
||||||
@@ -701,6 +702,7 @@
|
|||||||
await file.OpenReadStream().CopyToAsync(memoryStream);
|
await file.OpenReadStream().CopyToAsync(memoryStream);
|
||||||
SelectedImageBytes = memoryStream.ToArray();
|
SelectedImageBytes = memoryStream.ToArray();
|
||||||
SelectedImagePreview = $"data:{file.ContentType};base64,{Convert.ToBase64String(SelectedImageBytes)}";
|
SelectedImagePreview = $"data:{file.ContentType};base64,{Convert.ToBase64String(SelectedImageBytes)}";
|
||||||
|
await ClearRecordedAudio();
|
||||||
}
|
}
|
||||||
|
|
||||||
private Task ClearSelectedImage()
|
private Task ClearSelectedImage()
|
||||||
|
Reference in New Issue
Block a user