LANCommander/LANCommander.Server/UI/Pages/Servers/Components/TextEditor.razor
2024-08-04 18:44:33 -05:00

222 lines
6.2 KiB
Text

@using LANCommander.Server.Extensions;
<GridRow Class="text-editor">
<GridCol Span="6">
<Tree TItem="FileTreeNode"
DataSource="FileTree"
TitleExpression="x => x.DataItem.Name"
ChildrenExpression="x => x.DataItem.Children"
IsLeafExpression="x => !x.DataItem.HasChildren"
OnDblClick="(args) => OpenFile(args.Node.DataItem)">
</Tree>
</GridCol>
<GridCol Span="18">
<Tabs Type="@TabType.EditableCard" HideAdd @bind-ActiveKey="ActiveFile" OnClose="OnTabClose">
@foreach (var file in OpenFiles)
{
<TextEditorPane FilePath="@file" />
}
</Tabs>
</GridCol>
</GridRow>
<style>
.monaco-editor-container {
min-height: 600px;
}
.text-editor {
background: #252525;
min-height: 600px;
}
.text-editor .ant-tree {
background: none;
color: #ccc;
padding-top: 16px;
padding-left: 8px;
}
.text-editor .ant-tree-node-content-wrapper:hover {
background: none;
}
.text-editor .ant-tree-treenode:hover {
background: #37373d;
}
.text-editor .text-editor-info-bar {
padding-left: 16px;
padding-right: 16px;
margin-top: 0;
margin-bottom: 0;
padding-top: 8px;
padding-bottom: 8px;
background: #1e1e1e;
}
.text-editor .text-editor-info-bar .ant-breadcrumb,
.text-editor .ant-breadcrumb-separator,
.text-editor .ant-breadcrumb li:last-child {
color: #a9a9a9;
}
.text-editor .ant-tabs-card.ant-tabs-top > .ant-tabs-nav .ant-tabs-tab,
.text-editor .ant-tabs-card.ant-tabs-top > div > .ant-tabs-nav .ant-tabs-tab {
border-radius: 0;
background: #2d2d2d;
padding: 4px 10px;
color: #a9a9a9;
border: none;
}
.text-editor .ant-tabs-card > .ant-tabs-nav .ant-tabs-tab-active,
.text-editor .ant-tabs-card > div > .ant-tabs-nav .ant-tabs-tab-active {
background: #1e1e1e !important;
}
.text-editor .ant-tabs-tab .ant-tabs-tab-remove .anticon {
color: #a9a9a9;
}
.text-editor .ant-tabs-tab.ant-tabs-tab-active .ant-tabs-tab-btn,
.text-editor .ant-tabs-tab.ant-tabs-tab-active .ant-tabs-tab-remove .anticon {
color: #fff;
}
.text-editor .ant-tabs-top > .ant-tabs-nav::before {
border: none;
}
.text-editor .ant-tabs-nav {
margin: 0;
}
</style>
@code {
[Parameter] public string WorkingDirectory { get; set; }
StandaloneCodeEditor? Editor;
IEnumerable<string> Files;
HashSet<FileTreeNode> FileTree { get; set; } = new HashSet<FileTreeNode>();
string CurrentFile = "";
List<string> OpenFiles = new List<string>();
string ActiveFile;
private StandaloneEditorConstructionOptions EditorConstructionOptions(StandaloneCodeEditor editor)
{
return new StandaloneEditorConstructionOptions
{
AutomaticLayout = true,
Theme = "vs-dark"
};
}
protected override async Task OnParametersSetAsync()
{
var root = new FileTreeNode
{
Name = "/",
FullName = WorkingDirectory,
IsExpanded = true
};
root.PopulateChildren(WorkingDirectory);
foreach (var child in root.Children)
{
FileTree.Add(child);
}
}
private void OpenFile(FileTreeNode node)
{
if (!OpenFiles.Contains(node.FullName))
OpenFiles.Add(node.FullName);
ActiveFile = node.FullName;
StateHasChanged();
}
private void OnTabClose(string key)
{
OpenFiles.Remove(key);
StateHasChanged();
}
public class FileTreeNode
{
public string Name { get; set; }
public string FullName { get; set; }
public bool IsExpanded { get; set; } = false;
public bool IsDirectory { get; set; } = false;
public bool HasChildren => Children != null && Children.Count > 0;
public HashSet<FileTreeNode> Children { get; set; } = new HashSet<FileTreeNode>();
public void PopulateChildren(string path)
{
if (Directory.Exists(path))
{
try
{
foreach (var file in Directory.GetFiles(path))
{
var fileInfo = new FileInfo(file);
Children.Add(new FileTreeNode
{
Name = fileInfo.Name,
FullName = fileInfo.FullName,
IsDirectory = false
});
}
}
catch { }
try
{
foreach (var directory in Directory.GetDirectories(path))
{
var directoryInfo = new DirectoryInfo(directory);
var child = new FileTreeNode
{
Name = directoryInfo.Name,
FullName = directoryInfo.FullName,
IsDirectory = true
};
child.PopulateChildren(directoryInfo.FullName);
Children.Add(child);
}
}
catch { }
}
}
public void PopulateChildren(IEnumerable<string> paths)
{
var childPaths = paths.Where(p => p.StartsWith(FullName) && p.EndsWith(Path.PathSeparator));
var directChildren = childPaths.Where(p => p != FullName && p.Substring(FullName.Length + 1).TrimEnd(Path.PathSeparator).Split(Path.PathSeparator).Length == 1);
foreach (var directChild in directChildren)
{
var child = new FileTreeNode()
{
FullName = directChild,
Name = directChild.Substring(FullName.Length).TrimEnd(Path.PathSeparator)
};
child.PopulateChildren(paths);
Children.Add(child);
}
}
}
}