Files
DodoSSH/src/DodoSSH.Client.Shell/Terminal/AvaloniaTerminalAssetProvider.cs
T
jaap-jan 6806e542f9
ci / build and test (push) Successful in 3m37s
ci / android head (push) Successful in 3m45s
ci / api image (push) Successful in 8s
ci / desktop nightly (push) Successful in 1m44s
Terminal: measure characters with Unicode 11 widths, so an emoji takes the two columns the remote counts
2026-10-04 13:55:20 +02:00

47 lines
2.0 KiB
C#

using Avalonia.Platform;
using DodoSSH.Client.Terminal;
namespace DodoSSH.Client.Shell.Terminal;
/// <summary>
/// Serves the renderer's files from the assembly's embedded resources.
/// </summary>
/// <remarks>
/// Read once at startup and cached. The files are a few hundred kilobytes in total, dominated by the
/// xterm bundle, and a terminal that stalled on a resource stream read while output was arriving
/// would be a strange way to save a rounding error of memory.
/// </remarks>
internal sealed class AvaloniaTerminalAssetProvider : ITerminalAssetProvider
{
private const string ResourceRoot = "avares://DodoSSH.Client.Shell/WebAssets";
private static readonly (string Path, string File, string ContentType)[] Files =
[
(TerminalDataPlane.PagePath, "terminal.html", "text/html; charset=utf-8"),
("/terminal.js", "terminal.js", "text/javascript; charset=utf-8"),
("/terminal.css", "terminal.css", "text/css; charset=utf-8"),
("/vendor/xterm.js", "vendor/xterm.js", "text/javascript; charset=utf-8"),
("/vendor/xterm.css", "vendor/xterm.css", "text/css; charset=utf-8"),
("/vendor/addon-fit.js", "vendor/addon-fit.js", "text/javascript; charset=utf-8"),
("/vendor/addon-webgl.js", "vendor/addon-webgl.js", "text/javascript; charset=utf-8"),
("/vendor/addon-unicode11.js", "vendor/addon-unicode11.js", "text/javascript; charset=utf-8"),
];
private readonly Dictionary<string, TerminalAsset> assets = new(StringComparer.Ordinal);
internal AvaloniaTerminalAssetProvider()
{
foreach (var (path, file, contentType) in Files)
{
using var stream = AssetLoader.Open(new Uri($"{ResourceRoot}/{file}", UriKind.Absolute));
using var buffer = new MemoryStream();
stream.CopyTo(buffer);
assets[path] = new TerminalAsset(contentType, buffer.ToArray());
}
}
/// <inheritdoc />
public TerminalAsset? Find(string path) => assets.GetValueOrDefault(path);
}