using FluentTerminal.Models; using FluentTerminal.Models.Enums; using FluentTerminal.Models.Responses; using System; using System.Threading.Tasks; namespace FluentTerminal.App.Services { public class Terminal { private readonly ITrayProcessCommunicationService _trayProcessCommunicationService; private Func> _selectedTextCallback; public Terminal(ITrayProcessCommunicationService trayProcessCommunicationService) { _trayProcessCommunicationService = trayProcessCommunicationService; _trayProcessCommunicationService.TerminalExited += OnTerminalExited; Id = _trayProcessCommunicationService.GetNextTerminalId(); } private void OnTerminalExited(object sender, int e) { if (e == Id) { Closed?.Invoke(this, System.EventArgs.Empty); } } /// /// To be observed by both view and viewmodel /// public event EventHandler Closed; /// /// to be observed by viewmodel /// public event EventHandler KeyboardCommandReceived; /// /// to be observed by view /// public event EventHandler OutputReceived; /// /// to be observed by viewmodel /// public event EventHandler SizeChanged; /// /// to be observed by viewmodel /// public event EventHandler TitleChanged; public string FallbackTitle { get; private set; } public int Id { get; } /// /// To be called by either view or viewmodel /// public async Task Close() { await _trayProcessCommunicationService.CloseTerminal(Id).ConfigureAwait(true); } /// /// to be called by viewmodel /// /// public Task GetSelectedText() { return _selectedTextCallback(); } /// /// to be called by view /// public void ProcessKeyboardCommand(string command) { KeyboardCommandReceived?.Invoke(this, command); } /// /// To be set by view /// public void RegisterSelectedTextCallback(Func> selectedTextCallback) { _selectedTextCallback = selectedTextCallback; } /// /// To be called by view /// public async Task SetSize(TerminalSize size) { await _trayProcessCommunicationService.ResizeTerminal(Id, size); SizeChanged?.Invoke(this, size); } /// /// to be called by view /// public void SetTitle(string title) { if (string.IsNullOrWhiteSpace(title)) { title = FallbackTitle; } TitleChanged?.Invoke(this, title); } /// /// to be called by view when ready /// /// /// /// public async Task StartShellProcess(ShellProfile shellProfile, TerminalSize size, SessionType sessionType) { _trayProcessCommunicationService.SubscribeForTerminalOutput(Id, t => OutputReceived?.Invoke(this, t)); var response = await _trayProcessCommunicationService.CreateTerminal(Id, size, shellProfile, sessionType).ConfigureAwait(true); if (response.Success) { FallbackTitle = response.ShellExecutableName; SetTitle(FallbackTitle); } return response; } public Task Write(byte[] data) { return _trayProcessCommunicationService.Write(Id, data); } /// /// Tells the ViewModel that this view failed to launch and can be closed. /// public void ReportLauchFailed() { Closed?.Invoke(this, System.EventArgs.Empty); } } }