microsoft/TypeAgent

Public

mirrored fromhttps://github.com/microsoft/TypeAgentAvailable

CodeCommitsIssuesPull requestsActionsInsightsSecurity
78c691a1dc6954d7bec8ba6b3df51daf1480fffe

Branches

Tags

  • No tags available.
0Branches0Tags
Go to file
Add file
Code

Clone

HTTPS

Download ZIP

dotnet/visualStudioTypeAgent/ChatToolWindowControl.xaml.cs

82lines · modecode

1// Copyright (c) Microsoft Corporation.
2// Licensed under the MIT License.
3
4using System;
5using System.Diagnostics;
6using System.IO;
7using System.Reflection;
8using System.Windows.Controls;
9using Microsoft.VisualStudio.Shell;
10using Microsoft.VisualStudio.Threading;
11using Microsoft.Web.WebView2.Core;
12using Newtonsoft.Json.Linq;
13
14namespace Microsoft.TypeAgent.VisualStudio;
15
16public partial class ChatToolWindowControl : UserControl
17{
18 public ChatToolWindowControl()
19 {
20 InitializeComponent();
21 Loaded += OnControlLoaded;
22 }
23
24 private void OnControlLoaded(object sender, System.Windows.RoutedEventArgs e)
25 {
26 // Hand the async work to the JTF and observe the JoinableTask via
27 // FileAndForget so VSTHRD101/VSTHRD110 don't fire.
28#pragma warning disable VSSDK007 // FileAndForget is the documented fire-and-forget observation for JoinableTask.
29 ThreadHelper.JoinableTaskFactory.RunAsync(async () =>
30 {
31 await InitializeWebViewAsync();
32 }).FileAndForget("typeagent/vsix/webview-init");
33#pragma warning restore VSSDK007
34 }
35
36 private async System.Threading.Tasks.Task InitializeWebViewAsync()
37 {
38 // User-data dir lives next to the extension assembly so multiple VS instances
39 // share cookies/cache. Tweak if you need per-instance isolation.
40 var userDataDir = Path.Combine(Path.GetTempPath(), "typeagent-vsix-webview");
41 Directory.CreateDirectory(userDataDir);
42
43 var env = await CoreWebView2Environment.CreateAsync(null, userDataDir);
44 await ChatWebView.EnsureCoreWebView2Async(env);
45
46 // Map the bundled WebView2 content to a virtual host so we can use
47 // simple relative URLs and avoid the file:// CSP weirdness.
48 var assemblyDir = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location)!;
49 var contentDir = Path.Combine(assemblyDir, "webview-content");
50 ChatWebView.CoreWebView2.SetVirtualHostNameToFolderMapping(
51 "typeagent.local",
52 contentDir,
53 CoreWebView2HostResourceAccessKind.Allow);
54
55 // The WebView2 → host channel: chat-ui posts JSON for link clicks etc.
56 ChatWebView.CoreWebView2.WebMessageReceived += OnWebMessageReceived;
57
58 ChatWebView.CoreWebView2.Navigate("https://typeagent.local/index.html");
59 }
60
61 private void OnWebMessageReceived(object sender, CoreWebView2WebMessageReceivedEventArgs e)
62 {
63 try
64 {
65 var root = JObject.Parse(e.WebMessageAsJson);
66 switch (root.Value<string>("type"))
67 {
68 case "openExternal":
69 var url = root.Value<string>("url");
70 if (!string.IsNullOrWhiteSpace(url))
71 {
72 Process.Start(new ProcessStartInfo(url) { UseShellExecute = true });
73 }
74 break;
75 }
76 }
77 catch (Exception ex)
78 {
79 Debug.WriteLine($"[TypeAgent] WebMessageReceived parse failed: {ex.Message}");
80 }
81 }
82}
83