- fix: path parsing
This commit is contained in:
@@ -37,6 +37,7 @@ public sealed partial class ContentBrowserViewModel : ViewModelBase
|
|||||||
|
|
||||||
[ObservableProperty] private string _message = "";
|
[ObservableProperty] private string _message = "";
|
||||||
[ObservableProperty] private string _searchText = "";
|
[ObservableProperty] private string _searchText = "";
|
||||||
|
[ObservableProperty] private string _serverText = "";
|
||||||
|
|
||||||
private ContentEntry? _selectedEntry;
|
private ContentEntry? _selectedEntry;
|
||||||
|
|
||||||
@@ -84,8 +85,8 @@ public sealed partial class ContentBrowserViewModel : ViewModelBase
|
|||||||
|
|
||||||
public ContentBrowserViewModel() : base()
|
public ContentBrowserViewModel() : base()
|
||||||
{
|
{
|
||||||
var a = new ContentEntry(this, "A:", "");
|
var a = new ContentEntry(this, "A:","A", "");
|
||||||
var b = new ContentEntry(this, "B", "");
|
var b = new ContentEntry(this, "B","B", "");
|
||||||
a.TryAddChild(b);
|
a.TryAddChild(b);
|
||||||
Entries.Add(a);
|
Entries.Add(a);
|
||||||
}
|
}
|
||||||
@@ -100,10 +101,7 @@ public sealed partial class ContentBrowserViewModel : ViewModelBase
|
|||||||
_debugService = debugService;
|
_debugService = debugService;
|
||||||
_popupService = popupService;
|
_popupService = popupService;
|
||||||
|
|
||||||
foreach (var info in hubService.ServerList)
|
FillRoot(hubService.ServerList);
|
||||||
{
|
|
||||||
_root.Add(new ContentEntry(this, ToContentUrl(info.Address.ToRobustUrl()),info.Address));
|
|
||||||
}
|
|
||||||
|
|
||||||
hubService.HubServerChangedEventArgs += HubServerChangedEventArgs;
|
hubService.HubServerChangedEventArgs += HubServerChangedEventArgs;
|
||||||
hubService.HubServerLoaded += GoHome;
|
hubService.HubServerLoaded += GoHome;
|
||||||
@@ -128,46 +126,43 @@ public sealed partial class ContentBrowserViewModel : ViewModelBase
|
|||||||
if(obj.Action == HubServerChangeAction.Clear) _root.Clear();
|
if(obj.Action == HubServerChangeAction.Clear) _root.Clear();
|
||||||
if (obj.Action == HubServerChangeAction.Add)
|
if (obj.Action == HubServerChangeAction.Add)
|
||||||
{
|
{
|
||||||
foreach (var info in obj.Items)
|
FillRoot(obj.Items);
|
||||||
{
|
|
||||||
_root.Add(new ContentEntry(this, ToContentUrl(info.Address.ToRobustUrl()),info.Address));
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void FillRoot(IEnumerable<ServerHubInfo> infos)
|
||||||
|
{
|
||||||
|
foreach (var info in infos)
|
||||||
|
{
|
||||||
|
_root.Add(new ContentEntry(this, info.StatusData.Name,info.Address,info.Address));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public async void Go(ContentPath path, bool appendHistory = true)
|
public async void Go(ContentPath path, bool appendHistory = true)
|
||||||
{
|
{
|
||||||
if (path.Pathes.Count <= 1)
|
if (path.Pathes.Count > 0 && (path.Pathes[0].StartsWith("ss14://") || path.Pathes[0].StartsWith("ss14s://")))
|
||||||
|
{
|
||||||
|
ServerText = path.Pathes[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (string.IsNullOrEmpty(ServerText))
|
||||||
{
|
{
|
||||||
SearchText = "";
|
SearchText = "";
|
||||||
GoHome();
|
GoHome();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (path.Pathes[0] != "content:" || path.Pathes.Count < 3)
|
if (ServerText != SelectedEntry?.ServerName)
|
||||||
{
|
{
|
||||||
return;
|
SelectedEntry = await CreateEntry(ServerText);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_debugService.Debug(path.Path);
|
||||||
|
|
||||||
var oriPath = path.Clone();
|
var oriPath = path.Clone();
|
||||||
|
|
||||||
path.Pathes.RemoveAt(0);
|
|
||||||
path.Pathes.RemoveAt(0);
|
|
||||||
|
|
||||||
var serverUrl = path.Pathes[0];
|
|
||||||
path.Pathes.RemoveAt(0);
|
|
||||||
|
|
||||||
_debugService.Debug(path.Path + " " + serverUrl +" "+ SelectedEntry?.ServerName);
|
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
ContentEntry entry;
|
if (SelectedEntry == null || !SelectedEntry.GetRoot().TryGetEntry(path, out var centry))
|
||||||
if (serverUrl == SelectedEntry?.ServerName)
|
|
||||||
entry = SelectedEntry.GetRoot();
|
|
||||||
else
|
|
||||||
entry = await CreateEntry(serverUrl);
|
|
||||||
|
|
||||||
if (!entry.TryGetEntry(path, out var centry))
|
|
||||||
{
|
{
|
||||||
throw new Exception("Not found!");
|
throw new Exception("Not found!");
|
||||||
}
|
}
|
||||||
@@ -209,7 +204,7 @@ public sealed partial class ContentBrowserViewModel : ViewModelBase
|
|||||||
var items = await _contentService.EnsureItems(info.RobustManifestInfo, loading,
|
var items = await _contentService.EnsureItems(info.RobustManifestInfo, loading,
|
||||||
_cancellationService.Token);
|
_cancellationService.Token);
|
||||||
|
|
||||||
var rootEntry = new ContentEntry(this,ToContentUrl(rurl), serverUrl);
|
var rootEntry = new ContentEntry(this,"","", serverUrl);
|
||||||
|
|
||||||
foreach (var item in items)
|
foreach (var item in items)
|
||||||
{
|
{
|
||||||
@@ -235,12 +230,6 @@ public sealed partial class ContentBrowserViewModel : ViewModelBase
|
|||||||
_history.RemoveAt(0);
|
_history.RemoveAt(0);
|
||||||
return h;
|
return h;
|
||||||
}
|
}
|
||||||
|
|
||||||
private string ToContentUrl(RobustUrl serverUrl)
|
|
||||||
{
|
|
||||||
var port = serverUrl.Uri.Port != -1 ? (":"+serverUrl.Uri.Port) : "";
|
|
||||||
return "content://" + serverUrl.Uri.Host + port;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public class ContentEntry
|
public class ContentEntry
|
||||||
@@ -254,6 +243,7 @@ public class ContentEntry
|
|||||||
public bool IsDirectory => Item == null;
|
public bool IsDirectory => Item == null;
|
||||||
|
|
||||||
public string Name { get; private set; }
|
public string Name { get; private set; }
|
||||||
|
public string PathName { get; private set; }
|
||||||
public string ServerName { get; private set; }
|
public string ServerName { get; private set; }
|
||||||
public IImage IconPath { get; set; } = DirImage;
|
public IImage IconPath { get; set; } = DirImage;
|
||||||
|
|
||||||
@@ -271,7 +261,7 @@ public class ContentEntry
|
|||||||
|
|
||||||
public bool TryAddChild(ContentEntry contentEntry)
|
public bool TryAddChild(ContentEntry contentEntry)
|
||||||
{
|
{
|
||||||
if(_childs.TryAdd(contentEntry.Name, contentEntry))
|
if(_childs.TryAdd(contentEntry.PathName, contentEntry))
|
||||||
{
|
{
|
||||||
contentEntry.Parent = this;
|
contentEntry.Parent = this;
|
||||||
return true;
|
return true;
|
||||||
@@ -280,10 +270,11 @@ public class ContentEntry
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
internal ContentEntry(ContentBrowserViewModel viewModel, string name, string serverName)
|
internal ContentEntry(ContentBrowserViewModel viewModel, string name, string pathName, string serverName)
|
||||||
{
|
{
|
||||||
Name = name;
|
Name = name;
|
||||||
ServerName = serverName;
|
ServerName = serverName;
|
||||||
|
PathName = pathName;
|
||||||
_viewModel = viewModel;
|
_viewModel = viewModel;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -292,22 +283,21 @@ public class ContentEntry
|
|||||||
if (Parent != null)
|
if (Parent != null)
|
||||||
{
|
{
|
||||||
var path = Parent.GetPath();
|
var path = Parent.GetPath();
|
||||||
path.Pathes.Add(Name);
|
path.Pathes.Add(PathName);
|
||||||
return path;
|
return path;
|
||||||
}
|
}
|
||||||
return new ContentPath(Name);
|
return new ContentPath([PathName]);
|
||||||
}
|
}
|
||||||
|
|
||||||
public ContentEntry GetOrCreateDirectory(ContentPath rootPath)
|
public ContentEntry GetOrCreateDirectory(ContentPath rootPath)
|
||||||
{
|
{
|
||||||
if (rootPath.Pathes.Count == 0) return this;
|
if (rootPath.Pathes.Count == 0) return this;
|
||||||
|
|
||||||
var fName = rootPath.Pathes[0];
|
var fName = rootPath.GetNext();
|
||||||
rootPath.Pathes.RemoveAt(0);
|
|
||||||
|
|
||||||
if(!TryGetChild(fName, out var child))
|
if(!TryGetChild(fName, out var child))
|
||||||
{
|
{
|
||||||
child = new ContentEntry(_viewModel, fName, ServerName);
|
child = new ContentEntry(_viewModel, fName, fName, ServerName);
|
||||||
TryAddChild(child);
|
TryAddChild(child);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -325,7 +315,8 @@ public class ContentEntry
|
|||||||
var dir = path.GetDirectory();
|
var dir = path.GetDirectory();
|
||||||
var dirEntry = GetOrCreateDirectory(dir);
|
var dirEntry = GetOrCreateDirectory(dir);
|
||||||
|
|
||||||
var entry = new ContentEntry(_viewModel, path.GetName(), ServerName)
|
var name = path.GetName();
|
||||||
|
var entry = new ContentEntry(_viewModel, name, name, ServerName)
|
||||||
{
|
{
|
||||||
Item = item
|
Item = item
|
||||||
};
|
};
|
||||||
@@ -344,9 +335,8 @@ public class ContentEntry
|
|||||||
entry = this;
|
entry = this;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
var fName = path.Pathes[0];
|
var fName = path.GetNext();
|
||||||
path.Pathes.RemoveAt(0);
|
|
||||||
|
|
||||||
if(!TryGetChild(fName, out var child))
|
if(!TryGetChild(fName, out var child))
|
||||||
{
|
{
|
||||||
@@ -362,36 +352,60 @@ public class ContentEntry
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public struct ContentPath
|
public struct ContentPath
|
||||||
{
|
{
|
||||||
public List<string> Pathes;
|
public List<string> Pathes { get; private set; }
|
||||||
|
|
||||||
public ContentPath(List<string> pathes)
|
public ContentPath(List<string> pathes)
|
||||||
{
|
{
|
||||||
Pathes = pathes;
|
Pathes = pathes ?? new List<string>();
|
||||||
}
|
}
|
||||||
|
|
||||||
public ContentPath(string path)
|
public ContentPath(string path)
|
||||||
{
|
{
|
||||||
Pathes = path.Split("/").ToList();
|
Pathes = string.IsNullOrEmpty(path)
|
||||||
|
? new List<string>()
|
||||||
|
: path.Split(new[] { '/' }, StringSplitOptions.RemoveEmptyEntries).ToList();
|
||||||
}
|
}
|
||||||
|
|
||||||
public ContentPath GetDirectory()
|
public ContentPath GetDirectory()
|
||||||
{
|
{
|
||||||
var p = Pathes.ToList();
|
if (Pathes.Count == 0)
|
||||||
p.RemoveAt(Pathes.Count - 1);
|
return this; // Root remains root when getting the directory.
|
||||||
return new ContentPath(p);
|
|
||||||
|
var directoryPathes = Pathes.Take(Pathes.Count - 1).ToList();
|
||||||
|
return new ContentPath(directoryPathes);
|
||||||
}
|
}
|
||||||
|
|
||||||
public string GetName()
|
public string GetName()
|
||||||
{
|
{
|
||||||
|
if (Pathes.Count == 0)
|
||||||
|
throw new InvalidOperationException("Cannot get the name of the root path.");
|
||||||
|
|
||||||
return Pathes.Last();
|
return Pathes.Last();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public string GetNext()
|
||||||
|
{
|
||||||
|
if (Pathes.Count == 0)
|
||||||
|
throw new InvalidOperationException("No elements left to retrieve from the root.");
|
||||||
|
|
||||||
|
var nextName = Pathes[0];
|
||||||
|
Pathes.RemoveAt(0);
|
||||||
|
|
||||||
|
return string.IsNullOrWhiteSpace(nextName) ? GetNext() : nextName;
|
||||||
|
}
|
||||||
|
|
||||||
public ContentPath Clone()
|
public ContentPath Clone()
|
||||||
{
|
{
|
||||||
return new ContentPath(Pathes.ToList());
|
return new ContentPath(new List<string>(Pathes));
|
||||||
}
|
}
|
||||||
|
|
||||||
public string Path => string.Join("/", Pathes);
|
public string Path => Pathes.Count == 0 ? "/" : string.Join("/", Pathes);
|
||||||
}
|
|
||||||
|
public override string ToString()
|
||||||
|
{
|
||||||
|
return Path;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -15,21 +15,27 @@
|
|||||||
|
|
||||||
<StackPanel Margin="5">
|
<StackPanel Margin="5">
|
||||||
<Border BorderThickness="2,0,0,0" CornerRadius="10">
|
<Border BorderThickness="2,0,0,0" CornerRadius="10">
|
||||||
<Grid ColumnDefinitions="*,40,40" RowDefinitions="*">
|
<Grid ColumnDefinitions="*,2*,40,40" RowDefinitions="*">
|
||||||
<TextBox
|
<TextBox
|
||||||
|
Margin="0"
|
||||||
|
Text="{Binding ServerText}"
|
||||||
|
VerticalAlignment="Center"
|
||||||
|
Watermark="Server Url..." />
|
||||||
|
<TextBox
|
||||||
|
Grid.Column="1"
|
||||||
Margin="0"
|
Margin="0"
|
||||||
Text="{Binding SearchText}"
|
Text="{Binding SearchText}"
|
||||||
VerticalAlignment="Center"
|
VerticalAlignment="Center"
|
||||||
Watermark="Path..." />
|
Watermark="Path..." />
|
||||||
<Button
|
<Button
|
||||||
Command="{Binding OnBackEnter}"
|
Command="{Binding OnBackEnter}"
|
||||||
Grid.Column="1"
|
Grid.Column="2"
|
||||||
Padding="10">
|
Padding="10">
|
||||||
<Image Source="/Assets/back.png" />
|
<Image Source="/Assets/back.png" />
|
||||||
</Button>
|
</Button>
|
||||||
<Button
|
<Button
|
||||||
Command="{Binding OnGoEnter}"
|
Command="{Binding OnGoEnter}"
|
||||||
Grid.Column="2"
|
Grid.Column="3"
|
||||||
Padding="10">
|
Padding="10">
|
||||||
<Image Source="/Assets/go.png" />
|
<Image Source="/Assets/go.png" />
|
||||||
</Button>
|
</Button>
|
||||||
|
|||||||
@@ -28,13 +28,10 @@ public class HubService
|
|||||||
{
|
{
|
||||||
if(_isUpdating) return;
|
if(_isUpdating) return;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
_serverList.Clear();
|
_serverList.Clear();
|
||||||
|
|
||||||
_isUpdating = true;
|
_isUpdating = true;
|
||||||
|
|
||||||
|
|
||||||
HubServerChangedEventArgs?.Invoke(new HubServerChangedEventArgs([], HubServerChangeAction.Clear));
|
HubServerChangedEventArgs?.Invoke(new HubServerChangedEventArgs([], HubServerChangeAction.Clear));
|
||||||
|
|
||||||
foreach (var urlStr in _configurationService.GetConfigValue(CurrentConVar.Hub)!)
|
foreach (var urlStr in _configurationService.GetConfigValue(CurrentConVar.Hub)!)
|
||||||
|
|||||||
Reference in New Issue
Block a user