using AIStudio.Tools.Rust; using AIStudio.Tools.Services; using Microsoft.AspNetCore.Components; using Timer = System.Timers.Timer; namespace AIStudio.Components; public partial class ConfigurationFile : ConfigurationBaseCore { /// /// The text used for the textfield. /// [Parameter] public Func Text { get; set; } = () => string.Empty; /// /// An action which is called when the text was changed. /// [Parameter] public Action TextUpdate { get; set; } = _ => { }; /// /// The icon to display next to the textfield. /// [Parameter] public string Icon { get; set; } = Icons.Material.Filled.AttachFile; /// /// The color of the icon to use. /// [Parameter] public Color IconColor { get; set; } = Color.Default; /// /// The title of the file selection dialog. /// [Parameter] public string FileDialogTitle { get; set; } = "Select File"; /// /// The optional file type filter for the file selection dialog. /// [Parameter] public FileTypeFilter[]? Filter { get; set; } [Inject] private RustService RustService { get; init; } = null!; private string internalText = string.Empty; private readonly Timer timer = new(TimeSpan.FromMilliseconds(500)) { AutoReset = false }; #region Overrides of ConfigurationBase /// protected override bool Stretch => true; protected override Variant Variant => Variant.Outlined; protected override string Label => this.OptionDescription; #endregion #region Overrides of ConfigurationBase protected override async Task OnInitializedAsync() { this.timer.Elapsed += async (_, _) => await this.InvokeAsync(async () => await this.OptionChanged(this.internalText)); await base.OnInitializedAsync(); } protected override async Task OnParametersSetAsync() { this.internalText = this.Text(); await base.OnParametersSetAsync(); } #endregion private void InternalUpdate(string text) { this.timer.Stop(); this.internalText = text; this.timer.Start(); } private async Task OpenFileDialog() { var response = await this.RustService.SelectFile(this.FileDialogTitle, this.Filter, string.IsNullOrWhiteSpace(this.internalText) ? null : this.internalText); if (response.UserCancelled) return; this.timer.Stop(); this.internalText = response.SelectedFilePath; await this.OptionChanged(response.SelectedFilePath); } private async Task OptionChanged(string updatedText) { this.TextUpdate(updatedText); await this.SettingsManager.StoreSettings(); await this.InformAboutChange(); } #region Overrides of MSGComponentBase protected override void DisposeResources() { try { this.timer.Stop(); this.timer.Dispose(); } catch { // ignore } base.DisposeResources(); } #endregion }