From ccd8c1eaa4e6bdbe07079a75073fc232f1153c8b Mon Sep 17 00:00:00 2001 From: Felix Seidl Date: Fri, 10 Apr 2020 13:52:23 +0200 Subject: [PATCH] improve settings import/export --- .../Exceptions/ReadTextFileException.cs | 23 ++ .../ITrayProcessCommunicationService.cs | 2 + .../Implementation/SettingsService.cs | 21 +- .../TrayProcessCommunicationService.cs | 12 + FluentTerminal.App/App.xaml.cs | 341 ++++++++++-------- .../CommandLineArguments/RunVerb.cs | 4 +- .../CommandLineArguments/SettingsVerb.cs | 4 +- FluentTerminal.Models/MessageIdentifiers.cs | 3 +- .../Requests/ReadTextFileRequest.cs | 9 + .../Responses/CommonResponse.cs | 8 +- .../Responses/CreateTerminalResponse.cs | 4 +- .../Responses/PauseTerminalOutputResponse.cs | 4 +- .../Responses/TerminalResponse.cs | 9 +- .../Services/AppCommunicationService.cs | 28 ++ FluentTerminal.SystemTray/Utilities.cs | 5 + 15 files changed, 296 insertions(+), 181 deletions(-) create mode 100644 FluentTerminal.App.Services/Exceptions/ReadTextFileException.cs create mode 100644 FluentTerminal.Models/Requests/ReadTextFileRequest.cs diff --git a/FluentTerminal.App.Services/Exceptions/ReadTextFileException.cs b/FluentTerminal.App.Services/Exceptions/ReadTextFileException.cs new file mode 100644 index 0000000..a2bdcd6 --- /dev/null +++ b/FluentTerminal.App.Services/Exceptions/ReadTextFileException.cs @@ -0,0 +1,23 @@ +using System; + +namespace FluentTerminal.App.Services.Exceptions +{ + public class ReadTextFileException : Exception + { + public ReadTextFileException() : base() + { + } + + public ReadTextFileException(string message) : base(message) + { + } + + public ReadTextFileException(string message, Exception innerException) : base(message, innerException) + { + } + + protected ReadTextFileException(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context) : base(info, context) + { + } + } +} diff --git a/FluentTerminal.App.Services/ITrayProcessCommunicationService.cs b/FluentTerminal.App.Services/ITrayProcessCommunicationService.cs index 3cde226..8f43fb2 100644 --- a/FluentTerminal.App.Services/ITrayProcessCommunicationService.cs +++ b/FluentTerminal.App.Services/ITrayProcessCommunicationService.cs @@ -35,6 +35,8 @@ namespace FluentTerminal.App.Services Task SaveTextFileAsync(string path, string content); + Task ReadTextFileAsync(string path); + Task GetSshConfigDirAsync(); Task GetFilesFromSshConfigDirAsync(); diff --git a/FluentTerminal.App.Services/Implementation/SettingsService.cs b/FluentTerminal.App.Services/Implementation/SettingsService.cs index 4390ea8..c92031c 100644 --- a/FluentTerminal.App.Services/Implementation/SettingsService.cs +++ b/FluentTerminal.App.Services/Implementation/SettingsService.cs @@ -71,7 +71,7 @@ namespace FluentTerminal.App.Services.Implementation config.Themes.Add(theme); } - foreach (var profile in GetShellProfiles().Where(x => !x.PreInstalled)) + foreach (var profile in GetShellProfiles()) { config.Profiles.Add(profile); } @@ -117,21 +117,18 @@ namespace FluentTerminal.App.Services.Implementation SaveTheme(theme, existingTheme != null); } - // Can't create pre-installed profiles - foreach (var profile in config.Profiles.Where(x => !x.PreInstalled)) + foreach (var profile in config.Profiles) { var existingProfile = GetShellProfile(profile.Id); - var isNew = existingProfile.EqualTo(default); + var isNew = existingProfile == default; - // You can only edit certain parts of preinstalled profiles if (!isNew && existingProfile.PreInstalled) { - existingProfile.WorkingDirectory = profile.WorkingDirectory; - existingProfile.Arguments = profile.Arguments; - existingProfile.TabThemeId = profile.TabThemeId; - existingProfile.TerminalThemeId = profile.TerminalThemeId; - existingProfile.KeyBindings = profile.KeyBindings; - SaveShellProfile(profile, isNew); + // those cannot be edited + profile.Name = existingProfile.Name; + profile.Location = existingProfile.Location; + + SaveShellProfile(profile, false); continue; } SaveShellProfile(profile, isNew); @@ -140,7 +137,7 @@ namespace FluentTerminal.App.Services.Implementation foreach (var profile in config.SshProfiles) { var existingProfile = GetSshProfile(profile.Id); - var isNew = existingProfile.EqualTo(default(SshProfile)); + var isNew = existingProfile == default; SaveSshProfile(profile, isNew); } diff --git a/FluentTerminal.App.Services/Implementation/TrayProcessCommunicationService.cs b/FluentTerminal.App.Services/Implementation/TrayProcessCommunicationService.cs index 37a3bd0..a94597e 100644 --- a/FluentTerminal.App.Services/Implementation/TrayProcessCommunicationService.cs +++ b/FluentTerminal.App.Services/Implementation/TrayProcessCommunicationService.cs @@ -84,6 +84,18 @@ namespace FluentTerminal.App.Services.Implementation } } + public async Task ReadTextFileAsync(string path) + { + var response = await GetResponseAsync(new ReadTextFileRequest { Path = path }).ConfigureAwait(false); + + if (!response.Success) + { + throw new ReadTextFileException(string.IsNullOrWhiteSpace(response.Error) ? "Failed to read the file." : response.Error); + } + + return response.Value; + } + public async Task GetSshConfigDirAsync() { if (!string.IsNullOrEmpty(_sshConfigDir)) diff --git a/FluentTerminal.App/App.xaml.cs b/FluentTerminal.App/App.xaml.cs index 27780c8..fe52edb 100755 --- a/FluentTerminal.App/App.xaml.cs +++ b/FluentTerminal.App/App.xaml.cs @@ -47,6 +47,7 @@ namespace FluentTerminal.App private readonly ISettingsService _settingsService; private readonly ITrayProcessCommunicationService _trayProcessCommunicationService; private readonly IDialogService _dialogService; + private readonly INotificationService _notificationService; private bool _alreadyLaunched; private bool _isLaunching; private ApplicationSettings _applicationSettings; @@ -116,6 +117,7 @@ namespace FluentTerminal.App Messenger.Default.Register(this, OnApplicationSettingsChanged); _settingsService = _container.Resolve(); + _notificationService = _container.Resolve(); var shellProfileMigrationService = _container.Resolve(); foreach (var profile in _settingsService.GetShellProfiles()) @@ -185,7 +187,189 @@ namespace FluentTerminal.App protected override async void OnActivated(IActivatedEventArgs args) { - if (args is ProtocolActivatedEventArgs protocolActivated) + await OnLaunchOrActivate(args); + base.OnActivated(args); + } + + private async Task ParseCommandLineArgumentsAsync(object verb, CommandLineActivatedEventArgs commandLineActivated) + { + using var deferral = commandLineActivated.Operation.GetDeferral(); + + if (verb is SettingsVerb settingsVerb) + { + if (string.IsNullOrWhiteSpace(settingsVerb.Import) && !settingsVerb.Export) + { + await ShowSettingsAsync(); + } + else if (settingsVerb.Export) + { + var settings = _settingsService.ExportSettings(); + var path = Path.Combine(commandLineActivated.Operation.CurrentDirectoryPath, "config.json"); + try + { + await StartSystemTray().ConfigureAwait(false); + await _trayProcessCommunicationService.SaveTextFileAsync(path, settings).ConfigureAwait(false); + _notificationService.ShowNotification("Export settings", $"Settings were exported to {path}."); + } + catch (Exception e) + { + _notificationService.ShowNotification("Export settings", $"Failed with error: {e.Message}"); + commandLineActivated.Operation.ExitCode = 1; + } + + if (!_isLaunching && !_alreadyLaunched) + { + Exit(); + } + } + else if (!string.IsNullOrWhiteSpace(settingsVerb.Import)) + { + var path = Path.Combine(commandLineActivated.Operation.CurrentDirectoryPath, settingsVerb.Import.Replace(".\\", string.Empty)); + try + { + await StartSystemTray().ConfigureAwait(false); + var content = await _trayProcessCommunicationService.ReadTextFileAsync(path).ConfigureAwait(false); + _settingsService.ImportSettings(content); + _notificationService.ShowNotification("Import settings", $"Successfully imported settings from {path}."); + } + catch (Exception e) + { + _notificationService.ShowNotification("Import settings", $"Failed with error: {e.Message}"); + commandLineActivated.Operation.ExitCode = 1; + } + + if (!_isLaunching && !_alreadyLaunched) + { + Exit(); + } + } + } + else if (verb is NewVerb newVerb) + { + var profile = default(ShellProfile); + if (!string.IsNullOrWhiteSpace(newVerb.Profile)) + { + profile = _settingsService.GetShellProfiles().FirstOrDefault(x => x.Name.Equals(newVerb.Profile, StringComparison.CurrentCultureIgnoreCase)); + } + + if (profile == null) + { + profile = _settingsService.GetDefaultShellProfile(); + } + + if (!string.IsNullOrWhiteSpace(newVerb.Directory) && newVerb.Directory != ".") + { + profile.WorkingDirectory = newVerb.Directory; + } + else + { + profile.WorkingDirectory = commandLineActivated.Operation.CurrentDirectoryPath; + } + + var location = newVerb.Target == Target.Default ? _applicationSettings.NewTerminalLocation + : newVerb.Target == Target.Tab ? NewTerminalLocation.Tab + : NewTerminalLocation.Window; + + await CreateTerminalAsync(profile, location); + } + else if (verb is RunVerb runVerb) + { + var profile = new ShellProfile + { + Id = Guid.Empty, + Location = null, + Arguments = runVerb.Command, + WorkingDirectory = runVerb.Directory + }; + + if (runVerb.SmartBuffer.HasValue) + { + profile.UseBuffer = runVerb.SmartBuffer.Value; + } + + if (!string.IsNullOrWhiteSpace(runVerb.Theme)) + { + var theme = _settingsService.GetThemes().FirstOrDefault(x => x.Name.Equals(runVerb.Theme, StringComparison.CurrentCultureIgnoreCase)); + if (theme != null) + { + profile.TerminalThemeId = theme.Id; + } + } + + if (string.IsNullOrWhiteSpace(profile.WorkingDirectory)) + { + profile.WorkingDirectory = commandLineActivated.Operation.CurrentDirectoryPath; + } + + var location = runVerb.Target == Target.Default ? _applicationSettings.NewTerminalLocation + : runVerb.Target == Target.Tab ? NewTerminalLocation.Tab + : NewTerminalLocation.Window; + + await CreateTerminalAsync(profile, location); + } + } + + private Task ShowOrCreateWindowAsync(ActivationViewSwitcher viewSwitcher) + { + var viewModel = _mainViewModels.Find(o => o.ApplicationView.Id == _activeWindowId) ?? + _mainViewModels.LastOrDefault(); + + return viewModel == null + ? CreateTerminalAsync(_settingsService.GetDefaultShellProfile(), NewTerminalLocation.Tab, viewSwitcher) + : ShowAsStandaloneAsync(viewModel, viewSwitcher); + } + + protected override async void OnLaunched(LaunchActivatedEventArgs args) + { + await OnLaunchOrActivate(args); + } + + public async Task OnLaunchOrActivate(IActivatedEventArgs args) + { + if (args is LaunchActivatedEventArgs launchActivated) + { + if (_isLaunching) + { + return; + } + + _isLaunching = true; + + if (!_alreadyLaunched) + { + await InitializeLoggerAsync(); + + // ReSharper disable once AssignmentIsFullyDiscarded + _ = JumpListHelper.UpdateAsync(_settingsService); + + var viewModel = _container.Resolve(); + if (launchActivated.Arguments.StartsWith(JumpListHelper.ShellProfileFlag)) + { + await viewModel.AddProfileByGuidAsync(Guid.Parse(launchActivated.Arguments.Replace(JumpListHelper.ShellProfileFlag, string.Empty))); + } + else + { + await viewModel.AddDefaultProfileAsync(NewTerminalLocation.Tab); + } + await CreateMainViewAsync(typeof(MainPage), viewModel, true); + Window.Current.Activate(); + } + else if (launchActivated.Arguments.StartsWith(JumpListHelper.ShellProfileFlag)) + { + var location = _applicationSettings.NewTerminalLocation; + var profile = _settingsService.GetShellProfile(Guid.Parse(launchActivated.Arguments.Replace(JumpListHelper.ShellProfileFlag, string.Empty))); + await CreateTerminalAsync(profile, location, launchActivated.ViewSwitcher); + } + else + { + var viewModel = await CreateNewTerminalWindowAsync(); + await viewModel.AddDefaultProfileAsync(NewTerminalLocation.Tab); + await ShowAsStandaloneAsync(viewModel, launchActivated.ViewSwitcher); + } + + _isLaunching = false; + } + else if (args is ProtocolActivatedEventArgs protocolActivated) { if (protocolActivated.Uri == new Uri("ftcmd://fluent.terminal?focus")) { @@ -261,7 +445,7 @@ namespace FluentTerminal.App var error = await vm.AcceptChangesAsync(true); - var profile = (SshProfile) vm.Model; + var profile = (SshProfile)vm.Model; if (!string.IsNullOrEmpty(error)) { @@ -346,8 +530,7 @@ namespace FluentTerminal.App return; } - - if (args is CommandLineActivatedEventArgs commandLineActivated) + else if (args is CommandLineActivatedEventArgs commandLineActivated) { var arguments = commandLineActivated.Operation.Arguments; if (string.IsNullOrWhiteSpace(arguments)) @@ -357,153 +540,10 @@ namespace FluentTerminal.App _commandLineParser .ParseArguments(SplitArguments(arguments), typeof(NewVerb), typeof(RunVerb), typeof(SettingsVerb)) - .WithParsed(async verb => await CliRunAsync(verb, commandLineActivated)); + .WithParsed(async verb => await ParseCommandLineArgumentsAsync(verb, commandLineActivated)); } } - private async Task CliRunAsync(object verb, CommandLineActivatedEventArgs commandLineActivated) - { - if (verb is SettingsVerb settingsVerb) - { - if (!settingsVerb.Import && !settingsVerb.Export) - { - await ShowSettingsAsync(); - } - else if (settingsVerb.Export) - { - var exportFile = await ApplicationData.Current.LocalFolder.CreateFileAsync("config.json", CreationCollisionOption.OpenIfExists); - - var settings = _settingsService.ExportSettings(); - await FileIO.WriteTextAsync(exportFile, settings); - await new MessageDialog($"{I18N.Translate("SettingsExported")} {exportFile.Path}").ShowAsync(); - } - else if (settingsVerb.Import) - { - var file = await ApplicationData.Current.LocalFolder.GetFileAsync("config.json"); - var content = await FileIO.ReadTextAsync(file); - _settingsService.ImportSettings(content); - await new MessageDialog($"{I18N.Translate("SettingsImported")} {file.Path}").ShowAsync(); - } - } - else if (verb is NewVerb newVerb) - { - var profile = default(ShellProfile); - if (!string.IsNullOrWhiteSpace(newVerb.Profile)) - { - profile = _settingsService.GetShellProfiles().FirstOrDefault(x => x.Name.Equals(newVerb.Profile, StringComparison.CurrentCultureIgnoreCase)); - } - - if (profile == null) - { - profile = _settingsService.GetDefaultShellProfile(); - } - - if (!string.IsNullOrWhiteSpace(newVerb.Directory) && newVerb.Directory != ".") - { - profile.WorkingDirectory = newVerb.Directory; - } - else - { - profile.WorkingDirectory = commandLineActivated.Operation.CurrentDirectoryPath; - } - - var location = newVerb.Target == Target.Default ? _applicationSettings.NewTerminalLocation - : newVerb.Target == Target.Tab ? NewTerminalLocation.Tab - : NewTerminalLocation.Window; - - await CreateTerminalAsync(profile, location); - } - else if (verb is RunVerb runVerb) - { - var profile = new ShellProfile - { - Id = Guid.Empty, - Location = null, - Arguments = runVerb.Command, - WorkingDirectory = runVerb.Directory - }; - - if (!string.IsNullOrEmpty(runVerb.Buffer) && bool.TryParse(runVerb.Buffer, out var useBuffer)) - { - profile.UseBuffer = useBuffer; - } - - if (!string.IsNullOrWhiteSpace(runVerb.Theme)) - { - var theme = _settingsService.GetThemes().FirstOrDefault(x => x.Name.Equals(runVerb.Theme, StringComparison.CurrentCultureIgnoreCase)); - if (theme != null) - { - profile.TerminalThemeId = theme.Id; - } - } - - if (string.IsNullOrWhiteSpace(profile.WorkingDirectory)) - { - profile.WorkingDirectory = commandLineActivated.Operation.CurrentDirectoryPath; - } - - var location = runVerb.Target == Target.Default ? _applicationSettings.NewTerminalLocation - : runVerb.Target == Target.Tab ? NewTerminalLocation.Tab - : NewTerminalLocation.Window; - - await CreateTerminalAsync(profile, location); - } - } - - private Task ShowOrCreateWindowAsync(ActivationViewSwitcher viewSwitcher) - { - var viewModel = _mainViewModels.Find(o => o.ApplicationView.Id == _activeWindowId) ?? - _mainViewModels.LastOrDefault(); - - return viewModel == null - ? CreateTerminalAsync(_settingsService.GetDefaultShellProfile(), NewTerminalLocation.Tab, viewSwitcher) - : ShowAsStandaloneAsync(viewModel, viewSwitcher); - } - - protected override async void OnLaunched(LaunchActivatedEventArgs args) - { - if (_isLaunching) - { - return; - } - - _isLaunching = true; - - if (!_alreadyLaunched) - { - await InitializeLoggerAsync(); - - // ReSharper disable once AssignmentIsFullyDiscarded - _ = JumpListHelper.UpdateAsync(_settingsService); - - var viewModel = _container.Resolve(); - if (args.Arguments.StartsWith(JumpListHelper.ShellProfileFlag)) - { - await viewModel.AddProfileByGuidAsync(Guid.Parse(args.Arguments.Replace(JumpListHelper.ShellProfileFlag, string.Empty))); - } - else - { - await viewModel.AddDefaultProfileAsync(NewTerminalLocation.Tab); - } - await CreateMainViewAsync(typeof(MainPage), viewModel, true); - Window.Current.Activate(); - } - else if (args.Arguments.StartsWith(JumpListHelper.ShellProfileFlag)) - { - var location = _applicationSettings.NewTerminalLocation; - var profile = _settingsService.GetShellProfile(Guid.Parse(args.Arguments.Replace(JumpListHelper.ShellProfileFlag, string.Empty))); - await CreateTerminalAsync(profile, location, args.ViewSwitcher); - } - else - { - var viewModel = await CreateNewTerminalWindowAsync(); - await viewModel.AddDefaultProfileAsync(NewTerminalLocation.Tab); - await ShowAsStandaloneAsync(viewModel, args.ViewSwitcher); - } - - _isLaunching = false; - } - private static async Task InitializeLoggerAsync() { var logDirectory = await ApplicationData.Current.LocalCacheFolder.CreateFolderAsync("Logs", CreationCollisionOption.OpenIfExists); @@ -758,6 +798,11 @@ namespace FluentTerminal.App private Task StartSystemTray() { + if (_trayReady.Task.IsCompleted) + { + return Task.CompletedTask; + } + var launch = FullTrustProcessLauncher.LaunchFullTrustProcessForCurrentAppAsync("AppLaunchedParameterGroup").AsTask(); return Task.WhenAll(launch, _trayReady.Task).ContinueWith( diff --git a/FluentTerminal.App/CommandLineArguments/RunVerb.cs b/FluentTerminal.App/CommandLineArguments/RunVerb.cs index 3c13f84..1ad7f19 100644 --- a/FluentTerminal.App/CommandLineArguments/RunVerb.cs +++ b/FluentTerminal.App/CommandLineArguments/RunVerb.cs @@ -14,8 +14,8 @@ namespace FluentTerminal.App.CommandLineArguments [Option("theme")] public string Theme { get; set; } - [Option("buffer")] - public string Buffer { get; set; } + [Option("smart-buffer")] + public bool? SmartBuffer { get; set; } [Option("target")] public Target Target { get; set; } diff --git a/FluentTerminal.App/CommandLineArguments/SettingsVerb.cs b/FluentTerminal.App/CommandLineArguments/SettingsVerb.cs index b7a5a61..7cce192 100755 --- a/FluentTerminal.App/CommandLineArguments/SettingsVerb.cs +++ b/FluentTerminal.App/CommandLineArguments/SettingsVerb.cs @@ -6,8 +6,8 @@ namespace FluentTerminal.App.CommandLineArguments public class SettingsVerb { [Option('i', "import", - HelpText = "Import settings.")] - public bool Import { get; set; } + HelpText = "Import settings from specified file.")] + public string Import { get; set; } [Option('e', "export", HelpText = "Export settings.")] diff --git a/FluentTerminal.Models/MessageIdentifiers.cs b/FluentTerminal.Models/MessageIdentifiers.cs index bd9bfb8..b49747f 100644 --- a/FluentTerminal.Models/MessageIdentifiers.cs +++ b/FluentTerminal.Models/MessageIdentifiers.cs @@ -20,6 +20,7 @@ GetCommandPathRequest = 15, PauseTerminalOutputRequest = 16, PauseTerminalOutputResponse = 17, - QuitApplicationRequest = 18 + QuitApplicationRequest = 18, + ReadTextFileRequest = 19 } } \ No newline at end of file diff --git a/FluentTerminal.Models/Requests/ReadTextFileRequest.cs b/FluentTerminal.Models/Requests/ReadTextFileRequest.cs new file mode 100644 index 0000000..e6ba792 --- /dev/null +++ b/FluentTerminal.Models/Requests/ReadTextFileRequest.cs @@ -0,0 +1,9 @@ +namespace FluentTerminal.Models.Requests +{ + public class ReadTextFileRequest : IMessage + { + public byte Identifier => (byte)MessageIdentifiers.ReadTextFileRequest; + + public string Path { get; set; } + } +} diff --git a/FluentTerminal.Models/Responses/CommonResponse.cs b/FluentTerminal.Models/Responses/CommonResponse.cs index b6bbba1..f9f40a5 100644 --- a/FluentTerminal.Models/Responses/CommonResponse.cs +++ b/FluentTerminal.Models/Responses/CommonResponse.cs @@ -1,11 +1,7 @@ namespace FluentTerminal.Models.Responses { - public class CommonResponse : IMessage + public class CommonResponse : TerminalResponse { - public virtual byte Identifier => (byte) MessageIdentifiers.CommonResponse; - - public bool Success { get; set; } - - public string Error { get; set; } + public override byte Identifier => (byte) MessageIdentifiers.CommonResponse; } } \ No newline at end of file diff --git a/FluentTerminal.Models/Responses/CreateTerminalResponse.cs b/FluentTerminal.Models/Responses/CreateTerminalResponse.cs index ccc4f91..8574853 100644 --- a/FluentTerminal.Models/Responses/CreateTerminalResponse.cs +++ b/FluentTerminal.Models/Responses/CreateTerminalResponse.cs @@ -1,8 +1,8 @@ namespace FluentTerminal.Models.Responses { - public class CreateTerminalResponse : TerminalResponse, IMessage + public class CreateTerminalResponse : TerminalResponse { - public byte Identifier => (byte) MessageIdentifiers.CreateTerminalResponse; + public override byte Identifier => (byte) MessageIdentifiers.CreateTerminalResponse; public string Name { get; set; } } diff --git a/FluentTerminal.Models/Responses/PauseTerminalOutputResponse.cs b/FluentTerminal.Models/Responses/PauseTerminalOutputResponse.cs index 3d1d98b..63c6960 100644 --- a/FluentTerminal.Models/Responses/PauseTerminalOutputResponse.cs +++ b/FluentTerminal.Models/Responses/PauseTerminalOutputResponse.cs @@ -1,7 +1,7 @@ namespace FluentTerminal.Models.Responses { - public class PauseTerminalOutputResponse : TerminalResponse, IMessage + public class PauseTerminalOutputResponse : TerminalResponse { - public byte Identifier => (byte) MessageIdentifiers.PauseTerminalOutputResponse; + public override byte Identifier => (byte) MessageIdentifiers.PauseTerminalOutputResponse; } } \ No newline at end of file diff --git a/FluentTerminal.Models/Responses/TerminalResponse.cs b/FluentTerminal.Models/Responses/TerminalResponse.cs index df3bb5e..665eff9 100644 --- a/FluentTerminal.Models/Responses/TerminalResponse.cs +++ b/FluentTerminal.Models/Responses/TerminalResponse.cs @@ -1,11 +1,8 @@ -using System; -using System.Collections.Generic; -using System.Text; - -namespace FluentTerminal.Models.Responses +namespace FluentTerminal.Models.Responses { - public class TerminalResponse + public abstract class TerminalResponse : IMessage { + public abstract byte Identifier { get; } public bool Success { get; set; } public string Error { get; set; } } diff --git a/FluentTerminal.SystemTray/Services/AppCommunicationService.cs b/FluentTerminal.SystemTray/Services/AppCommunicationService.cs index e2fd005..d162037 100644 --- a/FluentTerminal.SystemTray/Services/AppCommunicationService.cs +++ b/FluentTerminal.SystemTray/Services/AppCommunicationService.cs @@ -134,6 +134,9 @@ namespace FluentTerminal.SystemTray.Services case MessageIdentifiers.QuitApplicationRequest: HandleQuitApplicationRequest(); return; + case MessageIdentifiers.ReadTextFileRequest: + await HandleReadTextFileRequestAsync(args).ConfigureAwait(false); + return; default: Logger.Instance.Error("Received unknown message type: {messageType}", messageType); return; @@ -214,6 +217,31 @@ namespace FluentTerminal.SystemTray.Services deferral.Complete(); } + private async Task HandleReadTextFileRequestAsync(AppServiceRequestReceivedEventArgs args) + { + var deferreal = args.GetDeferral(); + var deferral = args.GetDeferral(); + var messageContent = (string)args.Request.Message[MessageKeys.Content]; + var request = JsonConvert.DeserializeObject(messageContent); + var response = new StringValueResponse(); + + try + { + var content = Utilities.ReadFile(request.Path); + response.Success = true; + response.Value = content; + } + catch (Exception e) + { + response.Success = false; + response.Error = e.Message; + } + + await args.Request.SendResponseAsync(CreateMessage(response)); + + deferral.Complete(); + } + private async Task HandleGetSshConfigFolderRequestAsync(AppServiceRequestReceivedEventArgs args) { var deferral = args.GetDeferral(); diff --git a/FluentTerminal.SystemTray/Utilities.cs b/FluentTerminal.SystemTray/Utilities.cs index 19bf007..c978c51 100644 --- a/FluentTerminal.SystemTray/Utilities.cs +++ b/FluentTerminal.SystemTray/Utilities.cs @@ -536,6 +536,11 @@ namespace FluentTerminal.SystemTray } } + internal static string ReadFile(string path) + { + return File.ReadAllText(path); + } + private static bool? MuteProcess(int id, bool mute, bool force = false) { bool? isAudioSessionMuted = VolumeControl.GetAudioSessionMute(id);