-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Refactor MainViewModel and Introduce Services for Better Separation o…
…f Concerns
- Loading branch information
1 parent
9b24d93
commit 7526cd0
Showing
12 changed files
with
383 additions
and
70 deletions.
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
using System; | ||
using Avalonia.Data.Converters; | ||
using Avalonia.Media; | ||
|
||
namespace ChatAAC.Converters; | ||
|
||
public class BooleanToBrushConverter : IValueConverter | ||
{ | ||
public object Convert(object? value, Type targetType, object? parameter, System.Globalization.CultureInfo culture) | ||
{ | ||
return value is bool and true ? Brushes.LightYellow : // Highlight favorites | ||
Brushes.Transparent; | ||
} | ||
|
||
public object ConvertBack(object? value, Type targetType, object? parameter, System.Globalization.CultureInfo culture) | ||
{ | ||
throw new NotSupportedException(); | ||
} | ||
} |
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,9 +1,30 @@ | ||
using System; | ||
using ReactiveUI; | ||
|
||
namespace ChatAAC.Models; | ||
|
||
public class AiResponse(string responseText) | ||
public class AiResponse(string responseText) : ReactiveObject | ||
{ | ||
public string ResponseText { get; set; } = responseText; | ||
public DateTime Timestamp { get; set; } = DateTime.Now; | ||
private string _responseText = responseText; | ||
private bool _isFavorite; | ||
private DateTime _timestamp = DateTime.Now; | ||
|
||
public string ResponseText | ||
{ | ||
get => _responseText; | ||
set => this.RaiseAndSetIfChanged(ref _responseText, value); | ||
} | ||
|
||
public DateTime Timestamp | ||
{ | ||
get => _timestamp; | ||
set => this.RaiseAndSetIfChanged(ref _timestamp, value); | ||
} | ||
|
||
|
||
public bool IsFavorite | ||
{ | ||
get => _isFavorite; | ||
set => this.RaiseAndSetIfChanged(ref _isFavorite, value); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
using System; | ||
using System.Collections.ObjectModel; | ||
using System.IO; | ||
using System.Text.Json; | ||
using ChatAAC.Models; | ||
|
||
public class HistoryService | ||
{ | ||
public ObservableCollection<AiResponse> HistoryItems { get; } = new(); | ||
public string HistoryFilePath { get; } = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "ChatAAC", "ai_response_history.json"); | ||
|
||
public void LoadHistory() | ||
{ | ||
if (!File.Exists(HistoryFilePath)) return; | ||
|
||
try | ||
{ | ||
var json = File.ReadAllText(HistoryFilePath); | ||
var history = JsonSerializer.Deserialize<ObservableCollection<AiResponse>>(json); | ||
if (history != null) | ||
foreach (var item in history) | ||
HistoryItems.Add(item); | ||
} | ||
catch (Exception ex) | ||
{ | ||
Console.WriteLine($"Error loading history: {ex.Message}"); | ||
} | ||
} | ||
|
||
public void SaveHistory() | ||
{ | ||
try | ||
{ | ||
var directory = Path.GetDirectoryName(HistoryFilePath); | ||
if (!string.IsNullOrEmpty(directory) && !Directory.Exists(directory)) | ||
Directory.CreateDirectory(directory); | ||
|
||
var options = new JsonSerializerOptions { WriteIndented = true }; | ||
var json = JsonSerializer.Serialize(HistoryItems, options); | ||
File.WriteAllText(HistoryFilePath, json); | ||
} | ||
catch (Exception ex) | ||
{ | ||
Console.WriteLine($"Error saving history: {ex.Message}"); | ||
} | ||
} | ||
|
||
public void AddToHistory(AiResponse response) | ||
{ | ||
HistoryItems.Add(response); | ||
SaveHistory(); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,101 @@ | ||
using System; | ||
using System.Collections.ObjectModel; | ||
using System.IO; | ||
using System.Linq; | ||
using ReactiveUI; | ||
using System.Reactive; | ||
using System.Text.Json; | ||
using System.Threading.Tasks; | ||
using ChatAAC.Models; | ||
using ChatAAC.Services; | ||
|
||
namespace ChatAAC.ViewModels | ||
{ | ||
public class HistoryViewModel : ReactiveObject | ||
{ | ||
public ObservableCollection<AiResponse> HistoryItems { get; } | ||
public AiResponse? SelectedHistoryItem { get; set; } | ||
|
||
public HistoryViewModel(ObservableCollection<AiResponse> historyItems, string historyPath) | ||
{ | ||
HistoryItems = historyItems; | ||
HistoryFilePath = historyPath; | ||
|
||
SortNewestToOldestCommand = ReactiveCommand.Create(SortNewestToOldest); | ||
SortOldestToNewestCommand = ReactiveCommand.Create(SortOldestToNewest); | ||
SortFavoritesCommand = ReactiveCommand.Create(SortFavorites); | ||
ToggleFavoriteCommand = ReactiveCommand.Create<AiResponse>(ToggleFavorite); | ||
SpeakSelectedEntryCommand = ReactiveCommand.Create(SpeakSelectedEntry); | ||
SelectionChangedCommand = ReactiveCommand.CreateFromTask<AiResponse>(OnSelectionChanged); | ||
} | ||
|
||
private string HistoryFilePath { get; set; } | ||
|
||
public ReactiveCommand<Unit, Unit> SortNewestToOldestCommand { get; } | ||
public ReactiveCommand<Unit, Unit> SortOldestToNewestCommand { get; } | ||
public ReactiveCommand<Unit, Unit> SortFavoritesCommand { get; } | ||
public ReactiveCommand<AiResponse, Unit> ToggleFavoriteCommand { get; } | ||
public ReactiveCommand<Unit, Task> SpeakSelectedEntryCommand { get; } | ||
public ReactiveCommand<AiResponse, Unit> SelectionChangedCommand { get; } | ||
private void SortNewestToOldest() | ||
{ | ||
var sorted = HistoryItems.OrderByDescending(item => item.Timestamp).ToList(); | ||
HistoryItems.Clear(); | ||
foreach (var item in sorted) | ||
HistoryItems.Add(item); | ||
} | ||
|
||
private void SortOldestToNewest() | ||
{ | ||
var sorted = HistoryItems.OrderBy(item => item.Timestamp).ToList(); | ||
HistoryItems.Clear(); | ||
foreach (var item in sorted) | ||
HistoryItems.Add(item); | ||
} | ||
|
||
private void SortFavorites() | ||
{ | ||
var sorted = HistoryItems.OrderByDescending(item => item.IsFavorite).ThenByDescending(item => item.Timestamp).ToList(); | ||
HistoryItems.Clear(); | ||
foreach (var item in sorted) | ||
HistoryItems.Add(item); | ||
} | ||
|
||
private void ToggleFavorite(AiResponse item) | ||
{ | ||
item.IsFavorite = !item.IsFavorite; // Toggle favorite status | ||
SaveHistory(); | ||
} | ||
|
||
private void SaveHistory() | ||
{ | ||
try | ||
{ | ||
var directory = Path.GetDirectoryName(HistoryFilePath); | ||
if (!string.IsNullOrEmpty(directory) && !Directory.Exists(directory)) | ||
Directory.CreateDirectory(directory); | ||
|
||
var options = new JsonSerializerOptions { WriteIndented = true }; | ||
var json = JsonSerializer.Serialize(HistoryItems, options); | ||
File.WriteAllText(HistoryFilePath, json); | ||
} | ||
catch (Exception ex) | ||
{ | ||
Console.WriteLine($"Error saving history: {ex.Message}"); | ||
} | ||
} | ||
private async Task OnSelectionChanged(AiResponse item) | ||
{ | ||
await SpeakSelectedEntry(); // Speak the selected item when changed | ||
} | ||
private async Task SpeakSelectedEntry() | ||
{ | ||
if (SelectedHistoryItem == null) | ||
return; | ||
|
||
// Implement TTS for the selected history item | ||
var ttsService = new TtsService(); // Replace with actual TTS service | ||
await ttsService.SpeakAsync(SelectedHistoryItem.ResponseText); | ||
} | ||
} | ||
} |
Oops, something went wrong.