From 1e1b75190654856c5629567858be0d6a99ac87cf Mon Sep 17 00:00:00 2001 From: Paul Schneider Date: Sun, 27 Sep 2026 23:42:52 +0100 Subject: [PATCH] localization + AudiRecorder --- src/PostIt/Directory.Packages.props | 3 + src/PostIt/PostIt/App.axaml.cs | 16 +++-- src/PostIt/PostIt/Interfaces/IPCMProcessor.cs | 6 ++ src/PostIt/PostIt/Lang/Resources.Designer.cs | 72 +++++++++++++++++++ src/PostIt/PostIt/Lang/Resources.en-EN.resx | 5 ++ src/PostIt/PostIt/Lang/Resources.pt-PT.resx | 5 ++ src/PostIt/PostIt/Lang/Resources.resx | 5 ++ src/PostIt/PostIt/PostIt.csproj | 21 +++++- src/PostIt/PostIt/Services/AudioRecorder.cs | 67 +++++++++++++++++ .../PostIt/ViewModels/Settings/Settings.cs | 13 +++- src/PostIt/PostIt/Views/Layout/HomePage.axaml | 3 +- 11 files changed, 205 insertions(+), 11 deletions(-) create mode 100644 src/PostIt/PostIt/Interfaces/IPCMProcessor.cs create mode 100644 src/PostIt/PostIt/Lang/Resources.Designer.cs create mode 100644 src/PostIt/PostIt/Lang/Resources.en-EN.resx create mode 100644 src/PostIt/PostIt/Lang/Resources.pt-PT.resx create mode 100644 src/PostIt/PostIt/Lang/Resources.resx create mode 100644 src/PostIt/PostIt/Services/AudioRecorder.cs diff --git a/src/PostIt/Directory.Packages.props b/src/PostIt/Directory.Packages.props index 42d09cd55..c9e77bf1d 100644 --- a/src/PostIt/Directory.Packages.props +++ b/src/PostIt/Directory.Packages.props @@ -16,6 +16,7 @@ + @@ -23,6 +24,8 @@ + + diff --git a/src/PostIt/PostIt/App.axaml.cs b/src/PostIt/PostIt/App.axaml.cs index 9a04ffd03..0c4f0a7ca 100644 --- a/src/PostIt/PostIt/App.axaml.cs +++ b/src/PostIt/PostIt/App.axaml.cs @@ -11,6 +11,7 @@ using PostIt.Services; using PostIt.ViewModels; using PostIt.Views; using PostIt.Helpers; +using System.Globalization; namespace PostIt; @@ -36,6 +37,7 @@ public partial class App : Application public override void Initialize() { AvaloniaXamlLoader.Load(this); + } public override void OnFrameworkInitializationCompleted() @@ -65,7 +67,7 @@ public partial class App : Application { singleViewPlatform.MainView = View = ServiceProvider!.GetRequiredService(); ConfigureRootView(View); - ApplyDarkMode(settings); + ApplyStettings(settings); } public void InitializeActivityLifetime(Settings settings, IActivityApplicationLifetime singleViewFactoryApplicationLifetime) @@ -74,7 +76,7 @@ public partial class App : Application () => { this.ConfigureRootView(ServiceProvider!.GetRequiredService()); - ApplyDarkMode(settings); + ApplyStettings(settings); return View!; }; } @@ -85,7 +87,7 @@ public partial class App : Application desktop.MainWindow = window; this.ConfigureRootView(window.MainView); - ApplyDarkMode(settings); + ApplyStettings(settings); } public void ConfigureRootView(MainView rootView) @@ -126,10 +128,12 @@ public partial class App : Application View = mainView ?? throw new ArgumentNullException(nameof(mainView)); } - private static void ApplyDarkMode(Settings settings) + private static void ApplyStettings(Settings settings) { - Application.Current!.RequestedThemeVariant = - settings.DarkMode ? ThemeVariant.Dark : ThemeVariant.Light; + if (!string.IsNullOrWhiteSpace(settings.SelectedLanguage)) + Yavsc.Lang.Resources.Culture = new CultureInfo(settings.SelectedLanguage); + Current!.RequestedThemeVariant = + settings.DarkMode ? ThemeVariant.Dark : ThemeVariant.Light; } /// diff --git a/src/PostIt/PostIt/Interfaces/IPCMProcessor.cs b/src/PostIt/PostIt/Interfaces/IPCMProcessor.cs new file mode 100644 index 000000000..e8e61070e --- /dev/null +++ b/src/PostIt/PostIt/Interfaces/IPCMProcessor.cs @@ -0,0 +1,6 @@ +using System; + +public interface IPCMProcessor : IDisposable +{ + void Process(short[] audioFrame); +} diff --git a/src/PostIt/PostIt/Lang/Resources.Designer.cs b/src/PostIt/PostIt/Lang/Resources.Designer.cs new file mode 100644 index 000000000..5537f5924 --- /dev/null +++ b/src/PostIt/PostIt/Lang/Resources.Designer.cs @@ -0,0 +1,72 @@ +//------------------------------------------------------------------------------ +// +// This code was generated by a tool. +// Runtime Version:4.0.30319.42000 +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ + +namespace Yavsc.Lang { + using System; + + + /// + /// A strongly-typed resource class, for looking up localized strings, etc. + /// + // This class was auto-generated by the StronglyTypedResourceBuilder + // class via a tool like ResGen or Visual Studio. + // To add or remove a member, edit your .ResX file then rerun ResGen + // with the /str option, or rebuild your VS project. + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "17.0.0.0")] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + public class Resources { + + private static global::System.Resources.ResourceManager resourceMan; + + private static global::System.Globalization.CultureInfo resourceCulture; + + [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] + public Resources() { + } + + /// + /// Returns the cached ResourceManager instance used by this class. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + public static global::System.Resources.ResourceManager ResourceManager { + get { + if (object.ReferenceEquals(resourceMan, null)) { + global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("Yavsc.Lang.Resources", typeof(Resources).Assembly); + resourceMan = temp; + } + return resourceMan; + } + } + + /// + /// Overrides the current thread's CurrentUICulture property for all + /// resource lookups using this strongly typed resource class. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + public static global::System.Globalization.CultureInfo Culture { + get { + return resourceCulture; + } + set { + resourceCulture = value; + } + } + + /// + /// Looks up a localized string similar to Bienvenue dans PostIt!. + /// + public static string GreetingText { + get { + return ResourceManager.GetString("GreetingText", resourceCulture); + } + } + } +} diff --git a/src/PostIt/PostIt/Lang/Resources.en-EN.resx b/src/PostIt/PostIt/Lang/Resources.en-EN.resx new file mode 100644 index 000000000..6128bca8d --- /dev/null +++ b/src/PostIt/PostIt/Lang/Resources.en-EN.resx @@ -0,0 +1,5 @@ + + + Welcome to PostIt! + + diff --git a/src/PostIt/PostIt/Lang/Resources.pt-PT.resx b/src/PostIt/PostIt/Lang/Resources.pt-PT.resx new file mode 100644 index 000000000..049c25316 --- /dev/null +++ b/src/PostIt/PostIt/Lang/Resources.pt-PT.resx @@ -0,0 +1,5 @@ + + + Bemvindo em PostIt! + + diff --git a/src/PostIt/PostIt/Lang/Resources.resx b/src/PostIt/PostIt/Lang/Resources.resx new file mode 100644 index 000000000..ae18ff220 --- /dev/null +++ b/src/PostIt/PostIt/Lang/Resources.resx @@ -0,0 +1,5 @@ + + + Bienvenue dans PostIt! + + diff --git a/src/PostIt/PostIt/PostIt.csproj b/src/PostIt/PostIt/PostIt.csproj index 9cdf71299..5057bde8c 100644 --- a/src/PostIt/PostIt/PostIt.csproj +++ b/src/PostIt/PostIt/PostIt.csproj @@ -7,6 +7,8 @@ 1.1.0.0 1.1.0-estimate.1+364.Branch.feature-estimate.Sha.3d6ab6e72f9ba4ccfa250a1cce154b550281405e 1.1.0-estimate.1 + true + @@ -30,6 +32,7 @@ None All + @@ -37,9 +40,25 @@ + + - \ No newline at end of file + + + PublicResXFileCodeGenerator + Resources.Designer.cs + + + + + + True + True + Lang/Resources.resx + + + diff --git a/src/PostIt/PostIt/Services/AudioRecorder.cs b/src/PostIt/PostIt/Services/AudioRecorder.cs new file mode 100644 index 000000000..43e7f5c1b --- /dev/null +++ b/src/PostIt/PostIt/Services/AudioRecorder.cs @@ -0,0 +1,67 @@ +using System; +using System.Threading; +using Pv; + +public class AudioRecorder : IDisposable +{ + private int frameLength; + PvRecorder recorder; + + Thread thread; + short[] audioFrame; + IPCMProcessor processor; + + public bool processing { get; private set; } + + public AudioRecorder(IPCMProcessor processor, int frameLength=512, int deviceIndex = -1) + { + this.frameLength = frameLength; + this.recorder = PvRecorder.Create(frameLength: frameLength, deviceIndex: deviceIndex); + this.audioFrame = new short[frameLength]; + this.processor=processor; + } + + public static string [] GetAvailableDevices() + { + return PvRecorder.GetAvailableDevices(); + } + + public void Start() + { + recorder.Start(); + thread = new Thread(ThreadLoop); + thread.Start(); + } + + public void ThreadLoop() + { + while (recorder.IsRecording) + { + if (thread.ThreadState != ThreadState.Running) + { + break; + } + if (processing) + { + Thread.Sleep(10); + continue; + } + processing = true; + audioFrame = recorder.Read(); + processor.Process(audioFrame); + processing = false; + } + } + + public void Stop() + { + thread.Interrupt(); + thread.Join(); + recorder.Stop(); + thread = null; + } + public void Dispose() + { + recorder.Dispose(); + } +} diff --git a/src/PostIt/PostIt/ViewModels/Settings/Settings.cs b/src/PostIt/PostIt/ViewModels/Settings/Settings.cs index 5576f01cd..e92bf9385 100644 --- a/src/PostIt/PostIt/ViewModels/Settings/Settings.cs +++ b/src/PostIt/PostIt/ViewModels/Settings/Settings.cs @@ -8,6 +8,7 @@ using System.IO; using System.Net.Http; using System.Text.Json; using System.Text.Json.Serialization; +using System.Globalization; [assembly: InternalsVisibleTo("PostIt.Tests")] @@ -44,6 +45,7 @@ public partial class Settings : ViewModelBase public partial StatusNotice ActionStatus { get; set; } = StatusNotice.Info("Pret."); + [JsonIgnore] public bool Loaded { get; private set; } = false; @@ -59,8 +61,16 @@ public partial class Settings : ViewModelBase /// . /// [ObservableProperty] + [JsonIgnore] public partial bool IsDirty { get; private set; } = false; + [JsonIgnore] + public override bool CanNavigateNext { get => false; protected set => throw new System.NotImplementedException(); } + + [JsonIgnore] + public override bool CanNavigatePrevious { get => true; protected set => throw new System.NotImplementedException(); } + + public string SelectedLanguage { get; internal set; } = CultureInfo.CurrentUICulture.Name; /// /// Guards every mutation of the observable state. [ObservableProperty] @@ -532,7 +542,4 @@ public partial class Settings : ViewModelBase /// partial void OnIsDirtyChanged(bool value) => SaveCommand.NotifyCanExecuteChanged(); - - public override bool CanNavigateNext { get => false; protected set => throw new System.NotImplementedException(); } - public override bool CanNavigatePrevious { get => true; protected set => throw new System.NotImplementedException(); } } diff --git a/src/PostIt/PostIt/Views/Layout/HomePage.axaml b/src/PostIt/PostIt/Views/Layout/HomePage.axaml index 31dd5851b..4172cb159 100644 --- a/src/PostIt/PostIt/Views/Layout/HomePage.axaml +++ b/src/PostIt/PostIt/Views/Layout/HomePage.axaml @@ -1,6 +1,7 @@ @@ -10,7 +11,7 @@ -