From 1fcaaa040b07d2329b83e4264e8104db962f9449 Mon Sep 17 00:00:00 2001 From: EugeneTes Date: Wed, 4 Feb 2026 14:59:16 +0100 Subject: [PATCH] fully functional editor --- .../Printers/TM-T30IIITranslated.cs | 8 +- .../Printers/TM-U220IITranslated.cs | 20 ++-- .../Components/Pages/Home.razor | 91 +++++++++++++++++++ ...spectron.PrintServer.TemplateEditor.csproj | 5 + .../wwwroot/app.css | 35 ++++++- .../wwwroot/receiptLanguage.js | 5 + 6 files changed, 151 insertions(+), 13 deletions(-) diff --git a/Inspectron.Epson/PrintServer/Printers/TM-T30IIITranslated.cs b/Inspectron.Epson/PrintServer/Printers/TM-T30IIITranslated.cs index db808f5..ec1214f 100644 --- a/Inspectron.Epson/PrintServer/Printers/TM-T30IIITranslated.cs +++ b/Inspectron.Epson/PrintServer/Printers/TM-T30IIITranslated.cs @@ -7,6 +7,8 @@ public class TM_T30IIITranslated : IPrinter { private readonly IEpsonPrinter _printer; + public bool SkipDelays { get; set; } + public TM_T30IIITranslated(IEpsonPrinter printer) { _printer = printer; @@ -22,7 +24,7 @@ public class TM_T30IIITranslated : IPrinter await _printer.FeedLinesAsync(1); await _printer.SetAbsolutePrintPosition(100); await _printer.LoadImageAsync(path, 384); - await Task.Delay(100); + if (!SkipDelays) await Task.Delay(100); if (_printer is HtmlPrinter) { await _printer.PrintLoadedImage(); @@ -65,12 +67,12 @@ public class TM_T30IIITranslated : IPrinter await _printer.SetDefaultLineSpacing(); await _printer.FeedLinesAsync(10); - await Task.Delay(200); + if (!SkipDelays) await Task.Delay(200); } public async Task Cut() { await _printer.CutAsync(); - await Task.Delay(200); + if (!SkipDelays) await Task.Delay(200); } } \ No newline at end of file diff --git a/Inspectron.Epson/PrintServer/Printers/TM-U220IITranslated.cs b/Inspectron.Epson/PrintServer/Printers/TM-U220IITranslated.cs index 7151295..4ad9bd2 100644 --- a/Inspectron.Epson/PrintServer/Printers/TM-U220IITranslated.cs +++ b/Inspectron.Epson/PrintServer/Printers/TM-U220IITranslated.cs @@ -8,6 +8,8 @@ public class TM_U220IITranslated : IPrinter { private readonly IEpsonPrinter _printer; + public bool SkipDelays { get; set; } + public TM_U220IITranslated(IEpsonPrinter printer) { _printer = printer; @@ -16,7 +18,7 @@ public class TM_U220IITranslated : IPrinter public async Task InitAsync() { await _printer.InitAsync(); - await Task.Delay(200); + if (!SkipDelays) await Task.Delay(200); } public Task PrintImageAsync(string path) @@ -39,28 +41,28 @@ public class TM_U220IITranslated : IPrinter if (command.IsCut) { await _printer.FeedLinesAsync(10); - await Task.Delay(200 * 5); + if (!SkipDelays) await Task.Delay(200 * 5); await _printer.CutAsync(false); - await Task.Delay(200); + if (!SkipDelays) await Task.Delay(200); continue; } await _printer.SetBiggerFontTM220(command.IsBig, command.IsTall | command.IsBig); - await Task.Delay(200); + if (!SkipDelays) await Task.Delay(200); await _printer.SetRedColor(command.IsRed); - await Task.Delay(200); + if (!SkipDelays) await Task.Delay(200); await _printer.SetEmphasized(command.IsBold); - await Task.Delay(200); + if (!SkipDelays) await Task.Delay(200); await _printer.PrintTextAsync(command.Text + "\n"); - await Task.Delay(200); + if (!SkipDelays) await Task.Delay(200); } await _printer.FeedLinesAsync(10); - await Task.Delay(1000); + if (!SkipDelays) await Task.Delay(1000); } public async Task Cut() { await _printer.CutAsync(); - await Task.Delay(200); + if (!SkipDelays) await Task.Delay(200); } } \ No newline at end of file diff --git a/Inspectron.PrintServer.TemplateEditor/Components/Pages/Home.razor b/Inspectron.PrintServer.TemplateEditor/Components/Pages/Home.razor index 31ac06f..31672f7 100644 --- a/Inspectron.PrintServer.TemplateEditor/Components/Pages/Home.razor +++ b/Inspectron.PrintServer.TemplateEditor/Components/Pages/Home.razor @@ -3,6 +3,9 @@ @using BlazorMonaco.Editor @using BlazorMonaco.Languages @using CommunityToolkit.Maui.Storage +@using Inspectron.Epson +@using Inspectron.Epson.PrintServer.Printers +@using Inspectron.Epson.TemplateEngine @using Inspectron.PrintServer.TemplateEditor.Services @inject IJSRuntime JSRuntime @@ -20,6 +23,11 @@ { @_loadedJsonFile } +
+
@@ -34,6 +42,11 @@
Preview
+ @if (!string.IsNullOrEmpty(_previewError)) + { +
@_previewError
+ } +
@@ -48,6 +61,12 @@ private string? _currentFilePath; private string _savedContent = ""; + private string? _jsonContent; + private string? _previewHtml; + private string? _previewError; + private string _selectedPrinterModel = "TM-T30III"; + private CancellationTokenSource? _debounceCts; + private bool HasUnsavedChanges => _editorContent != _savedContent; private string FileDisplayName => _currentFilePath is not null @@ -87,6 +106,24 @@ private async Task OnContentChanged(ModelContentChangedEvent e) { _editorContent = await _editor.GetValue(); + + _debounceCts?.Cancel(); + _debounceCts = new CancellationTokenSource(); + var token = _debounceCts.Token; + + _ = Task.Run(async () => + { + try + { + await Task.Delay(500, token); + await InvokeAsync(async () => + { + await RenderPreviewAsync(); + StateHasChanged(); + }); + } + catch (TaskCanceledException) { } + }); } private async Task NewFileAsync() @@ -95,6 +132,9 @@ _savedContent = ""; _editorContent = ""; await _editor.SetValue(""); + _previewHtml = null; + _previewError = null; + await JSRuntime.InvokeVoidAsync("setPreviewContent", ""); } private async Task OpenFileAsync() @@ -121,6 +161,7 @@ _savedContent = content; _editorContent = content; await _editor.SetValue(content); + await RenderPreviewAsync(); } catch (Exception) { @@ -183,10 +224,13 @@ using var reader = new StreamReader(stream); var json = await reader.ReadToEndAsync(); + _jsonContent = json; + var paths = JsonPathExtractor.Extract(json); _completionProvider.SetJsonPaths(paths); _loadedJsonFile = result.FileName; + await RenderPreviewAsync(); StateHasChanged(); } catch (Exception) @@ -194,4 +238,51 @@ // User cancelled or file read failed } } + + private async Task OnPrinterModelChanged(ChangeEventArgs e) + { + _selectedPrinterModel = e.Value?.ToString() ?? "TM-T30III"; + await RenderPreviewAsync(); + } + + private async Task RenderPreviewAsync() + { + if (string.IsNullOrWhiteSpace(_editorContent) || string.IsNullOrWhiteSpace(_jsonContent)) + return; + + try + { + _previewError = null; + + var engine = new ReceiptTemplateEngine(); + var commands = engine.Render(_editorContent, _jsonContent); + + var htmlBuilder = new HtmlPrintBuilder(); + await htmlBuilder.ConnectAsync("preview"); + + if (_selectedPrinterModel == "TM-U220II") + { + var printer = new TM_U220IITranslated(htmlBuilder) { SkipDelays = true }; + await printer.InitAsync(); + await printer.PrintAsync(commands); + await printer.Cut(); + } + else + { + var printer = new TM_T30IIITranslated(htmlBuilder) { SkipDelays = true }; + await printer.InitAsync(); + await printer.PrintAsync(commands); + await printer.Cut(); + } + + _previewHtml = htmlBuilder.GetHtml(); + await JSRuntime.InvokeVoidAsync("setPreviewContent", _previewHtml); + } + catch (Exception ex) + { + _previewError = ex.Message; + _previewHtml = null; + await JSRuntime.InvokeVoidAsync("setPreviewContent", ""); + } + } } diff --git a/Inspectron.PrintServer.TemplateEditor/Inspectron.PrintServer.TemplateEditor.csproj b/Inspectron.PrintServer.TemplateEditor/Inspectron.PrintServer.TemplateEditor.csproj index b860b14..ac080a0 100644 --- a/Inspectron.PrintServer.TemplateEditor/Inspectron.PrintServer.TemplateEditor.csproj +++ b/Inspectron.PrintServer.TemplateEditor/Inspectron.PrintServer.TemplateEditor.csproj @@ -53,6 +53,11 @@ + + + + + diff --git a/Inspectron.PrintServer.TemplateEditor/wwwroot/app.css b/Inspectron.PrintServer.TemplateEditor/wwwroot/app.css index 6e0a7c7..c67e92b 100644 --- a/Inspectron.PrintServer.TemplateEditor/wwwroot/app.css +++ b/Inspectron.PrintServer.TemplateEditor/wwwroot/app.css @@ -111,9 +111,42 @@ html, body { .preview-content { flex: 1; - padding: 16px; + padding: 0; overflow: auto; color: #cccccc; + display: flex; + flex-direction: column; +} + +#preview-iframe { + flex: 1; + width: 100%; + border: none; + background: #f0f0f0; +} + +.preview-error { + padding: 8px 12px; + color: #f44747; + background: #2a1515; + border-bottom: 1px solid #5a2020; + font-size: 12px; + font-family: 'Courier New', monospace; + white-space: pre-wrap; +} + +.toolbar-select { + padding: 4px 8px; + background: #3c3c3c; + color: #cccccc; + border: 1px solid #555; + border-radius: 3px; + cursor: pointer; + font-size: 13px; +} + +.toolbar-select:hover { + background: #505050; } .valid.modified:not([type=checkbox]) { outline: 1px solid #26b050; diff --git a/Inspectron.PrintServer.TemplateEditor/wwwroot/receiptLanguage.js b/Inspectron.PrintServer.TemplateEditor/wwwroot/receiptLanguage.js index 61baf44..08c66ac 100644 --- a/Inspectron.PrintServer.TemplateEditor/wwwroot/receiptLanguage.js +++ b/Inspectron.PrintServer.TemplateEditor/wwwroot/receiptLanguage.js @@ -156,3 +156,8 @@ window.receiptLanguage = { return ''; } }; + +window.setPreviewContent = function(html) { + var iframe = document.getElementById('preview-iframe'); + if (iframe) iframe.srcdoc = html; +};