BASE changed interface
This commit is contained in:
commit
fd6bc3459f
33 files changed
+3047
No files matched your search
@@ -0,0 +1,96 @@
|
||||
using System.IO;
|
||||
using System.Text.Json;
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace FoxBrowser.Core;
|
||||
|
||||
/// <summary>
|
||||
/// Snapshot of a single tab persisted to disk.
|
||||
/// All properties are nullable so old session files remain forward-compatible.
|
||||
/// </summary>
|
||||
public sealed class TabSnapshot
|
||||
{
|
||||
public string Address { get; init; } = "https://www.google.com";
|
||||
public string Title { get; init; } = "Нова вкладка";
|
||||
public bool IsAudioOnly { get; init; }
|
||||
public double ScrollY { get; init; }
|
||||
public double MediaPosition { get; init; }
|
||||
public bool WasPlaying { get; init; }
|
||||
}
|
||||
|
||||
public sealed class Session
|
||||
{
|
||||
public List<TabSnapshot> Tabs { get; init; } = new();
|
||||
public int ActiveTabIndex { get; init; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Saves and loads the browser session (open tabs + per-tab state) to a JSON
|
||||
/// file in LocalApplicationData\FoxBrowser\session.json.
|
||||
///
|
||||
/// Crash-recovery strategy: the file is re-written after every successful
|
||||
/// NavigationCompleted so a hard crash never loses more than one page load.
|
||||
/// </summary>
|
||||
public static class SessionStore
|
||||
{
|
||||
private static readonly string SessionPath = Path.Combine(
|
||||
Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData),
|
||||
"FoxBrowser", "session.json");
|
||||
|
||||
private static readonly JsonSerializerOptions JsonOptions = new()
|
||||
{
|
||||
WriteIndented = true,
|
||||
DefaultIgnoreCondition = JsonIgnoreCondition.Never,
|
||||
};
|
||||
|
||||
public static async Task SaveAsync(IEnumerable<BrowserTab> tabs, int activeIndex)
|
||||
{
|
||||
try
|
||||
{
|
||||
var snapshots = tabs.Select(t => new TabSnapshot
|
||||
{
|
||||
Address = t.Address,
|
||||
Title = t.Title,
|
||||
IsAudioOnly = t.IsAudioOnly,
|
||||
ScrollY = t.ScrollY,
|
||||
MediaPosition = t.MediaPosition,
|
||||
WasPlaying = t.WasPlaying,
|
||||
}).ToList();
|
||||
|
||||
if (snapshots.Count == 0) return;
|
||||
|
||||
var session = new Session
|
||||
{
|
||||
Tabs = snapshots,
|
||||
ActiveTabIndex = Math.Clamp(activeIndex, 0, snapshots.Count - 1),
|
||||
};
|
||||
|
||||
Directory.CreateDirectory(Path.GetDirectoryName(SessionPath)!);
|
||||
var json = JsonSerializer.Serialize(session, JsonOptions);
|
||||
// Write to a temp file first, then replace atomically — avoids
|
||||
// truncating the real file if the process is killed mid-write.
|
||||
var tmp = SessionPath + ".tmp";
|
||||
await File.WriteAllTextAsync(tmp, json);
|
||||
File.Move(tmp, SessionPath, overwrite: true);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
System.Diagnostics.Debug.WriteLine($"[SessionStore] Save failed: {ex.Message}");
|
||||
}
|
||||
}
|
||||
|
||||
public static async Task<Session?> LoadAsync()
|
||||
{
|
||||
if (!File.Exists(SessionPath)) return null;
|
||||
try
|
||||
{
|
||||
var json = await File.ReadAllTextAsync(SessionPath);
|
||||
return JsonSerializer.Deserialize<Session>(json);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
System.Diagnostics.Debug.WriteLine($"[SessionStore] Load failed: {ex.Message}");
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user