121 lines
4.2 KiB
C#
121 lines
4.2 KiB
C#
using System;
|
|
using System.IO;
|
|
using System.Reactive.Linq;
|
|
using DynamicData;
|
|
using Intromat.Model.Compiler;
|
|
using Intromat.PersistentModel;
|
|
using Intromat.ViewModels;
|
|
using Intromat.ViewModels.Editors;
|
|
using Intromat.ViewModels.Previews;
|
|
using Intromat.Views;
|
|
using NodeNetwork.Toolkit.ValueNode;
|
|
using NodeNetwork.Utilities;
|
|
using ReactiveUI;
|
|
using RxFileSystemWatcher;
|
|
using Splat;
|
|
|
|
namespace Intromat.Nodes.Code
|
|
{
|
|
public class StringFileNode : CodeGenNodeViewModel
|
|
{
|
|
private readonly ObservableAsPropertyHelper<ObservableFileSystemWatcher> _fileWatcher;
|
|
private readonly ObservableAsPropertyHelper<string> _fullPath;
|
|
|
|
static StringFileNode()
|
|
{
|
|
Locator.CurrentMutable.Register(() => new CodeGenNodeView(), typeof(IViewFor<StringFileNode>));
|
|
}
|
|
|
|
public StringFileNode()
|
|
: base(NodeType.Literal)
|
|
{
|
|
Name = "String (file)";
|
|
|
|
Path = new CodeGenInputViewModel<string?>(EPortType.String)
|
|
{
|
|
Name = "Path",
|
|
Editor = PathEditor,
|
|
};
|
|
Inputs.Add(Path);
|
|
|
|
Contents = new CodeGenOutputViewModel<ITypedExpression<string?>>(EPortType.String)
|
|
{
|
|
Name = "Contents",
|
|
};
|
|
|
|
var stringPreview = new StringPreviewViewModel();
|
|
Preview = stringPreview;
|
|
|
|
this.WhenAnyValue(vm => vm.Parent, vm => vm.Path.Value)
|
|
.Where(pair => pair.Item1 != null && pair.Item2 != null)
|
|
.Select(pair => System.IO.Path.Combine(((CodeGenNetworkViewModel)pair.Item1).Document.Parent.FullPath, pair.Item2!))
|
|
.StartWith(string.Empty)
|
|
.ToProperty(this, vm => vm.FullPath, out _fullPath);
|
|
|
|
this.WhenAnyValue(vm => vm.FullPath)
|
|
.Where(File.Exists)
|
|
.Select(path => new ObservableFileSystemWatcher(c =>
|
|
{
|
|
c.Path = System.IO.Path.GetDirectoryName(path)!;
|
|
}))
|
|
.ToProperty(this, vm => vm.FileWatcher, out _fileWatcher);
|
|
|
|
Contents.Value = this.WhenAnyValue(vm => vm.FileWatcher)
|
|
.PairWithPreviousValue()
|
|
.Select(pair =>
|
|
{
|
|
var oldWatcher = pair.OldValue;
|
|
var newWatcher = pair.NewValue;
|
|
|
|
oldWatcher?.Dispose();
|
|
if (newWatcher != null)
|
|
{
|
|
stringPreview.Value = Path.Value!;
|
|
var result =
|
|
newWatcher.Renamed.Where(e => e.FullPath == FullPath)
|
|
.Merge(newWatcher.Changed.Where(e => e.FullPath == FullPath))
|
|
.Throttle(TimeSpan.FromMilliseconds(100))
|
|
.Select(_ => new StringLiteralValue() { Value = File.ReadAllText(FullPath) })
|
|
.StartWith(new StringLiteralValue() { Value = File.ReadAllText(FullPath) });
|
|
newWatcher.Start();
|
|
return result;
|
|
}
|
|
|
|
stringPreview.Value = string.Empty;
|
|
return Observable.Empty<StringLiteralValue>();
|
|
})
|
|
.Switch();
|
|
|
|
Outputs.Add(Contents);
|
|
}
|
|
|
|
public ObservableFileSystemWatcher FileWatcher => _fileWatcher.Value;
|
|
|
|
public string FullPath => _fullPath.Value;
|
|
|
|
public StringValueEditorViewModel PathEditor { get; } = new();
|
|
|
|
public ValueNodeInputViewModel<string?> Path { get; }
|
|
|
|
public ValueNodeOutputViewModel<ITypedExpression<string?>> Contents { get; }
|
|
|
|
public override NodeModelBase CreateModel()
|
|
{
|
|
return new StringFileModel();
|
|
}
|
|
|
|
public override void LoadModel(NodeModelBase model)
|
|
{
|
|
base.LoadModel(model);
|
|
var fileModel = (StringFileModel)model;
|
|
PathEditor.Value = fileModel.Value;
|
|
}
|
|
|
|
public override void SaveModel(NodeModelBase model)
|
|
{
|
|
base.SaveModel(model);
|
|
var fileModel = (StringFileModel)model;
|
|
fileModel.Value = PathEditor.Value;
|
|
}
|
|
}
|
|
} |