This commit is contained in:
mmrbnjd
2025-08-10 21:02:51 +03:30
parent 0856c8ae59
commit 11608c4f6d

View File

@@ -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()