stan44 7562cf6fad Add gateway root adoption and mobile polish
- Add Tauri commands to inspect and adopt the gateway repo root
- Retry locked vault commands by prompting for unlock
- Improve mobile layout, editor mode toggles, and settings UI
2026-03-30 00:00:25 -05:00

76 lines
3.1 KiB
C#

namespace Journal.WebGateway.Infrastructure;
public sealed record RepoRootResolution(string Root, bool IsCustom, string Source);
public static class PathResolver
{
public static RepoRootResolution ResolveRepoRoot(IConfiguration config)
{
var fromConfig = config.GetValue<string>("GatewaySettings:RepoRoot");
if (!string.IsNullOrWhiteSpace(fromConfig) && Directory.Exists(fromConfig))
return new RepoRootResolution(Path.GetFullPath(fromConfig), true, "config");
var fromEnv = Environment.GetEnvironmentVariable("JOURNAL_PROJECT_ROOT");
if (!string.IsNullOrWhiteSpace(fromEnv) && Directory.Exists(fromEnv))
return new RepoRootResolution(Path.GetFullPath(fromEnv), true, "env");
if (IsPublishedLayout())
{
throw new InvalidOperationException(
"Published WebGateway requires an explicit root. Set GatewaySettings:RepoRoot or JOURNAL_PROJECT_ROOT before launch.");
}
foreach (var start in new[] { Directory.GetCurrentDirectory(), AppContext.BaseDirectory })
{
var resolved = FindRepoRoot(start);
if (resolved is not null)
return new RepoRootResolution(resolved, false, "auto");
}
return new RepoRootResolution(Path.GetFullPath(Directory.GetCurrentDirectory()), false, "cwd");
}
private static string? FindRepoRoot(string start)
{
var cursor = Path.GetFullPath(start);
while (!string.IsNullOrWhiteSpace(cursor))
{
if (File.Exists(Path.Combine(cursor, "Journal.slnx")) ||
Directory.Exists(Path.Combine(cursor, "Journal.Sidecar")) ||
File.Exists(Path.Combine(cursor, "Journal.Sidecar.exe")) ||
File.Exists(Path.Combine(cursor, "Journal.Sidecar")) ||
Directory.Exists(Path.Combine(cursor, "Journal.Core")))
return cursor;
var parent = Directory.GetParent(cursor);
if (parent is null || string.Equals(parent.FullName, cursor, StringComparison.OrdinalIgnoreCase))
return null;
cursor = parent.FullName;
}
return null;
}
public static string ResolveWebDist(string repoRootPath, IConfiguration config)
{
var fromConfig = config.GetValue<string>("GatewaySettings:WebDist");
if (!string.IsNullOrWhiteSpace(fromConfig)) return Path.GetFullPath(fromConfig);
var fromEnv = Environment.GetEnvironmentVariable("JOURNAL_WEB_DIST");
if (!string.IsNullOrWhiteSpace(fromEnv)) return Path.GetFullPath(fromEnv);
var packagedWwwRoot = Path.Combine(AppContext.BaseDirectory, "wwwroot");
if (Directory.Exists(packagedWwwRoot)) return packagedWwwRoot;
return Path.Combine(repoRootPath, "Journal.App", "build");
}
private static bool IsPublishedLayout()
{
var baseDir = Path.GetFullPath(AppContext.BaseDirectory);
return Directory.Exists(Path.Combine(baseDir, "wwwroot")) &&
!File.Exists(Path.Combine(baseDir, "Journal.slnx")) &&
!Directory.Exists(Path.Combine(baseDir, "Journal.WebGateway"));
}
}