Skip to content

Commit 8992717

Browse files
committed
GREPキーワードのハイライト
1 parent 65bd2f9 commit 8992717

File tree

2 files changed

+78
-15
lines changed

2 files changed

+78
-15
lines changed

RemoteLogViewer.Core/Services/Viewer/HighlightService.cs

Lines changed: 19 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4,27 +4,38 @@
44
using System.Text;
55
using System.Text.RegularExpressions;
66

7+
using Microsoft.Extensions.DependencyInjection;
8+
79
using RemoteLogViewer.Composition.Stores.Settings;
810
using RemoteLogViewer.Core.Stores.Settings;
911

1012
namespace RemoteLogViewer.Core.Services.Viewer;
1113

1214
[Inject(InjectServiceLifetime.Transient)]
1315
public class HighlightService {
16+
private readonly IServiceProvider _serviceProvider;
1417
private readonly SettingsStoreModel _settingsStoreModel;
1518
private readonly ConcurrentDictionary<(string pattern, bool ignoreCase), Regex> _regexCache = [];
16-
private (string ClassName, HighlightConditionModel Condition)[] _ruleWithClassName = [];
17-
public HighlightService(SettingsStoreModel settingsStoreModel) {
19+
private readonly List<(string ClassName, HighlightConditionModel Condition)> _ruleWithClassName = [];
20+
21+
public HighlightService(SettingsStoreModel settingsStoreModel, IServiceProvider serviceProvider) {
1822
this._settingsStoreModel = settingsStoreModel;
23+
this._serviceProvider = serviceProvider;
1924
}
2025

21-
public string CreateCss() {
22-
var conditions = this._settingsStoreModel.SettingsModel.HighlightSettings.Rules.SelectMany(x => x.Conditions);
23-
this._ruleWithClassName = conditions.Select((x, i) => ($"c{i}", x)).ToArray();
26+
public string CreateCss(string wrapperSelector) {
27+
var conditions = this._settingsStoreModel.SettingsModel.HighlightSettings.Rules.SelectMany(x => x.Conditions).Where(x => !string.IsNullOrEmpty(x.Pattern.Value));
28+
var grepCondition = this._serviceProvider.GetRequiredService<HighlightConditionModel>();
29+
30+
if (!string.IsNullOrEmpty(grepCondition.Pattern.Value)) {
31+
this._ruleWithClassName.Add(("grep-condition", grepCondition));
32+
}
33+
this._ruleWithClassName.AddRange(conditions.Select((x, i) => ($"c{i}", x)));
34+
2435

25-
return string.Join("", this._ruleWithClassName.Select(x => {
36+
return wrapperSelector + "{" + string.Join("", this._ruleWithClassName.AsEnumerable().Reverse().Select((x, i) => {
2637
var sb = new StringBuilder();
27-
_ = sb.Append($".{x.ClassName}{{");
38+
_ = sb.Append($".{x.ClassName}{string.Join("", Enumerable.Repeat("[class]", i))}{{");
2839
if (x.Condition.ForeColor.Value is { } fore) {
2940
_ = sb.Append($$"""color:rgb({{fore.R}} {{fore.G}} {{fore.B}} / {{(double)fore.A / byte.MaxValue}});""");
3041
}
@@ -33,7 +44,7 @@ public string CreateCss() {
3344
}
3445
_ = sb.Append("}");
3546
return sb.ToString();
36-
}));
47+
})) + "}";
3748
}
3849

3950
public string CreateStyledLine(string content) {

RemoteLogViewer.WinUI/Views/Ssh/FileViewer/TextFileViewer.xaml.cs

Lines changed: 59 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,14 @@
1+
using System.Collections.Generic;
12
using System.Collections.Specialized;
23
using System.IO;
34
using System.Text.Json;
45
using System.Threading.Tasks;
56

7+
using Microsoft.Extensions.DependencyInjection;
68
using Microsoft.Extensions.Logging;
79
using Microsoft.Web.WebView2.Core;
810

11+
using RemoteLogViewer.Composition.Stores.Settings;
912
using RemoteLogViewer.Core.Models.Ssh.FileViewer;
1013
using RemoteLogViewer.Core.Services;
1114
using RemoteLogViewer.Core.Services.Viewer;
@@ -23,7 +26,7 @@ namespace RemoteLogViewer.WinUI.Views.Ssh.FileViewer;
2326
/// テキストファイルビューア。スクロール位置に応じて行を部分的に読み込みます。
2427
/// </summary>
2528
public sealed partial class TextFileViewer {
26-
private readonly HighlightService _highlightService;
29+
private readonly TabObjectsList _tabObjects = [];
2730
private readonly SettingsStoreModel _settingsStoreModel;
2831
private readonly NotificationService _notificationService;
2932
private readonly ILogger<TextFileViewer> _logger;
@@ -49,7 +52,6 @@ public SshBrowserViewModel? ViewModel {
4952
}
5053

5154
public TextFileViewer() {
52-
this._highlightService = Ioc.Default.GetRequiredService<HighlightService>();
5355
this._settingsStoreModel = Ioc.Default.GetRequiredService<SettingsStoreModel>();
5456
this._notificationService = Ioc.Default.GetRequiredService<NotificationService>();
5557
this._logger = Ioc.Default.GetRequiredService<ILogger<TextFileViewer>>();
@@ -68,7 +70,7 @@ private async Task InitializeWebView() {
6870
this.ContentWebViewer.CoreWebView2.Settings.AreDevToolsEnabled = false;
6971
this.ContentWebViewer.CoreWebView2.Settings.AreBrowserAcceleratorKeysEnabled = false;
7072
#endif
71-
this.ContentWebViewer.CoreWebView2.SetVirtualHostNameToFolderMapping("app", Path.Combine(AppContext.BaseDirectory, "Assets", "Web","dist"), CoreWebView2HostResourceAccessKind.Allow);
73+
this.ContentWebViewer.CoreWebView2.SetVirtualHostNameToFolderMapping("app", Path.Combine(AppContext.BaseDirectory, "Assets", "Web", "dist"), CoreWebView2HostResourceAccessKind.Allow);
7274
this.ContentWebViewer.CoreWebView2.Navigate("https://app/index.html");
7375

7476

@@ -83,6 +85,15 @@ private async Task InitializeWebView() {
8385
this.GetViewerVM(m.pageKey)?.LoadLogsCommand.Execute(new(m.requestId, m.start, m.end));
8486
break;
8587
case StartGrepWebMessage m:
88+
var gc = this._tabObjects.GetGrepCondition(m.pageKey);
89+
gc.Pattern.Value = m.keyword;
90+
gc.IgnoreCase.Value = m.ignoreCase;
91+
gc.PatternType.Value = m.useRegex ? HighlightPatternType.Regex : HighlightPatternType.Exact;
92+
gc.HighlightOnlyMatch.Value = true;
93+
gc.BackColor.Value = new Composition.Utils.Objects.ColorModel() { A = 0xDD, R = 0xFF, G = 0xFF, B = 0 };
94+
this.PostWV2("*", "LineStyleChanged", this._tabObjects.CreateCss());
95+
this.PostWV2(m.pageKey, "ReloadRequested", null);
96+
8697
var vm = this.GetViewerVM(m.pageKey);
8798
if (vm is null) {
8899
return;
@@ -97,7 +108,6 @@ private async Task InitializeWebView() {
97108
this.GetViewerVM(message.pageKey)?.GrepCancelCommand.Execute(Unit.Default);
98109
break;
99110
case ReadyWebMessage:
100-
this.PostWV2("*", "LineStyleChanged", this._highlightService.CreateCss());
101111
this.ViewModel.IsViewerReady.Value = true;
102112
break;
103113
case SaveRangeRequestWebMessage m:
@@ -147,7 +157,7 @@ private async Task InitializeWebView() {
147157
}).AddTo(this.ViewModel.CompositeDisposable);
148158

149159
this._settingsStoreModel.SettingsUpdated.Subscribe(x => {
150-
this.PostWV2("*", "LineStyleChanged", this._highlightService.CreateCss());
160+
this.PostWV2("*", "LineStyleChanged", this._tabObjects.CreateCss());
151161
this.PostWV2("*", "ReloadRequested", null);
152162
this.PostWV2("*", "GrepResultReset", null);
153163
});
@@ -162,6 +172,8 @@ private async Task InitializeWebView() {
162172
case NotifyCollectionChangedAction.Remove:
163173
if (e.NewItems is not null) {
164174
foreach (TextFileViewerViewModel vm in e.NewItems) {
175+
this._tabObjects.Add(new TabObjects(vm.PageKey, Ioc.Default.CreateScope().ServiceProvider));
176+
this.PostWV2("*", "LineStyleChanged", this._tabObjects.CreateCss());
165177
this.PostWV2("*", "FileOpened", new {
166178
pageKey = vm.PageKey,
167179
tabHeader = Path.GetFileName(vm.OpenedFilePath.Value)
@@ -186,7 +198,7 @@ private void RegisterViewerVMEvents(TextFileViewerViewModel vm) {
186198
requestId = x.RequestId,
187199
content = x.Content.Select(x => new {
188200
lineNumber = x.LineNumber,
189-
content = this._highlightService.CreateStyledLine(x.Content)
201+
content = this._tabObjects.GetHighlightService(vm.PageKey).CreateStyledLine(x.Content)
190202
})
191203
});
192204
}).AddTo(vm.CompositeDisposable);
@@ -256,7 +268,11 @@ private void RegisterViewerVMEvents(TextFileViewerViewModel vm) {
256268
if (e.NewItems is null) {
257269
return;
258270
}
259-
this.PostWV2(vm.PageKey, "GrepResultAdded", e.NewItems.Cast<TextLine>().Select(x => new { lineNumber = x.LineNumber, content = this._highlightService.CreateStyledLine(x.Content) }));
271+
this.PostWV2(vm.PageKey, "GrepResultAdded", e.NewItems.Cast<TextLine>().Select(x =>
272+
new {
273+
lineNumber = x.LineNumber,
274+
content = this._tabObjects.GetHighlightService(vm.PageKey).CreateStyledLine(x.Content)
275+
}));
260276
break;
261277
case NotifyCollectionChangedAction.Reset:
262278
this.PostWV2(vm.PageKey, "GrepResultReset", null);
@@ -291,4 +307,40 @@ public void Reset() {
291307
this.ViewModel.IsViewerReady.Value = false;
292308
this.ContentWebViewer.CoreWebView2.Reload();
293309
}
310+
311+
private class TabObjects {
312+
public string PageKey {
313+
get;
314+
}
315+
public HighlightService HighlightService {
316+
get;
317+
}
318+
319+
public HighlightConditionModel GrepCondition {
320+
get;
321+
}
322+
323+
public TabObjects(string pageKey, IServiceProvider scopedServiceProvider) {
324+
this.PageKey = pageKey;
325+
var scopedService = Ioc.Default.CreateScope().ServiceProvider;
326+
this.GrepCondition = scopedService.GetRequiredService<HighlightConditionModel>();
327+
this.HighlightService = scopedService.GetRequiredService<HighlightService>();
328+
}
329+
}
330+
331+
private class TabObjectsList : List<TabObjects> {
332+
public string CreateCss() {
333+
return string.Join("", this.Select(x => x.HighlightService.CreateCss($".{x.PageKey}")));
334+
}
335+
336+
public HighlightService GetHighlightService(string pageKey) {
337+
var tab = this.First(x => x.PageKey == pageKey);
338+
return tab.HighlightService;
339+
}
340+
341+
public HighlightConditionModel GetGrepCondition(string pageKey) {
342+
var tab = this.First(x => x.PageKey == pageKey);
343+
return tab.GrepCondition;
344+
}
345+
}
294346
}

0 commit comments

Comments
 (0)