mirror of
https://github.com/wwiinnddyy/LanMountainDesktop.git
synced 2026-06-24 02:14:26 +08:00
0.7.4
首先我加了CI课程表json的读取,然后把天气时钟这个老问题也修了。
This commit is contained in:
@@ -12,7 +12,7 @@ namespace LanMountainDesktop.Services;
|
||||
|
||||
public interface IClassIslandScheduleDataService
|
||||
{
|
||||
ClassIslandScheduleReadResult Load(string? inputPath = null, string? profileFileName = null);
|
||||
ClassIslandScheduleReadResult Load(string? inputPath = null, string? profileFileName = null, DateOnly? semesterStartDate = null, int semesterWeekCycle = 1);
|
||||
|
||||
bool TryResolveClassPlanForDate(
|
||||
ClassIslandScheduleSnapshot snapshot,
|
||||
@@ -43,7 +43,7 @@ public sealed class ClassIslandScheduleDataService : IClassIslandScheduleDataSer
|
||||
.IgnoreUnmatchedProperties()
|
||||
.Build();
|
||||
|
||||
public ClassIslandScheduleReadResult Load(string? inputPath = null, string? profileFileName = null)
|
||||
public ClassIslandScheduleReadResult Load(string? inputPath = null, string? profileFileName = null, DateOnly? semesterStartDate = null, int semesterWeekCycle = 1)
|
||||
{
|
||||
var warnings = new List<string>();
|
||||
try
|
||||
@@ -73,11 +73,11 @@ public sealed class ClassIslandScheduleDataService : IClassIslandScheduleDataSer
|
||||
ClassIslandScheduleSnapshot snapshot;
|
||||
if (source.SourceKind == ScheduleSourceKind.Cses)
|
||||
{
|
||||
snapshot = ParseCsesSnapshot(source);
|
||||
snapshot = ParseCsesSnapshot(source, semesterStartDate, semesterWeekCycle);
|
||||
}
|
||||
else
|
||||
{
|
||||
var cycleRule = ParseCycleRule(source.SettingsPath, warnings);
|
||||
var cycleRule = ParseCycleRule(source.SettingsPath, warnings, semesterStartDate, semesterWeekCycle);
|
||||
var profileJson = ReadJson(source.ProfilePath);
|
||||
snapshot = ParseProfileSnapshot(profileJson.RootElement, source, cycleRule);
|
||||
}
|
||||
@@ -412,22 +412,50 @@ public sealed class ClassIslandScheduleDataService : IClassIslandScheduleDataSer
|
||||
return null;
|
||||
}
|
||||
|
||||
private static ClassIslandScheduleCycleRule ParseCycleRule(string? settingsPath, List<string> warnings)
|
||||
private static ClassIslandScheduleCycleRule ParseCycleRule(
|
||||
string? settingsPath,
|
||||
List<string> warnings,
|
||||
DateOnly? semesterStartDate = null,
|
||||
int semesterWeekCycle = 1)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(settingsPath) || !File.Exists(settingsPath))
|
||||
DateOnly? singleWeekStartDate = semesterStartDate;
|
||||
int maxCycle = semesterWeekCycle > 1 ? semesterWeekCycle : 4;
|
||||
var offsetList = new List<int> { -1, -1, 0, 0, 0, 0, 0, 0 };
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(settingsPath) && File.Exists(settingsPath))
|
||||
{
|
||||
warnings.Add("ClassIsland Settings.json not found, using default cycle rule.");
|
||||
return new ClassIslandScheduleCycleRule(null, 4, new List<int> { -1, -1, 0, 0, 0 });
|
||||
using var json = ReadJson(settingsPath);
|
||||
var root = json.RootElement;
|
||||
|
||||
if (!singleWeekStartDate.HasValue)
|
||||
{
|
||||
singleWeekStartDate = TryReadDateOnly(root, "SingleWeekStartTime");
|
||||
}
|
||||
|
||||
if (semesterWeekCycle <= 1)
|
||||
{
|
||||
maxCycle = TryReadInt(root, "MultiWeekRotationMaxCycle", 4);
|
||||
}
|
||||
|
||||
var settingsOffsetList = ReadIntList(root, "MultiWeekRotationOffset");
|
||||
if (settingsOffsetList.Count >= 2)
|
||||
{
|
||||
offsetList = settingsOffsetList;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
warnings.Add("ClassIsland Settings.json not found, using semester settings from component.");
|
||||
}
|
||||
|
||||
using var json = ReadJson(settingsPath);
|
||||
var root = json.RootElement;
|
||||
var singleWeekStartDate = TryReadDateOnly(root, "SingleWeekStartTime");
|
||||
var maxCycle = TryReadInt(root, "MultiWeekRotationMaxCycle", 4);
|
||||
var offsetList = ReadIntList(root, "MultiWeekRotationOffset");
|
||||
if (offsetList.Count < 2)
|
||||
if (maxCycle < 2)
|
||||
{
|
||||
offsetList = new List<int> { -1, -1, 0, 0, 0 };
|
||||
maxCycle = 2;
|
||||
}
|
||||
|
||||
while (offsetList.Count <= maxCycle)
|
||||
{
|
||||
offsetList.Add(0);
|
||||
}
|
||||
|
||||
return new ClassIslandScheduleCycleRule(
|
||||
@@ -469,7 +497,10 @@ public sealed class ClassIslandScheduleDataService : IClassIslandScheduleDataSer
|
||||
ClassPlanGroups: groups);
|
||||
}
|
||||
|
||||
private static ClassIslandScheduleSnapshot ParseCsesSnapshot(ResolvedSource source)
|
||||
private static ClassIslandScheduleSnapshot ParseCsesSnapshot(
|
||||
ResolvedSource source,
|
||||
DateOnly? semesterStartDate = null,
|
||||
int semesterWeekCycle = 1)
|
||||
{
|
||||
var yaml = File.ReadAllText(source.ProfilePath);
|
||||
var csesProfile = CsesDeserializer.Deserialize<CsesProfileDto>(yaml) ?? new CsesProfileDto();
|
||||
@@ -600,12 +631,19 @@ public sealed class ClassIslandScheduleDataService : IClassIslandScheduleDataSer
|
||||
[GlobalClassPlanGroupId] = new ClassIslandClassPlanGroup(GlobalClassPlanGroupId, "Global", IsGlobal: true)
|
||||
};
|
||||
|
||||
var maxCycle = semesterWeekCycle > 1 ? semesterWeekCycle : 4;
|
||||
var offsetList = new List<int> { -1, -1, 0, 0, 0, 0, 0, 0 };
|
||||
while (offsetList.Count <= maxCycle)
|
||||
{
|
||||
offsetList.Add(0);
|
||||
}
|
||||
|
||||
return new ClassIslandScheduleSnapshot(
|
||||
SourceRootPath: source.SourceRootPath,
|
||||
ProfilePath: source.ProfilePath,
|
||||
ProfileFileName: source.ProfileFileName,
|
||||
LoadedAt: DateTimeOffset.Now,
|
||||
CycleRule: new ClassIslandScheduleCycleRule(null, 4, new List<int> { -1, -1, 0, 0, 0 }),
|
||||
CycleRule: new ClassIslandScheduleCycleRule(semesterStartDate, Math.Clamp(maxCycle, 2, 32), offsetList),
|
||||
SelectedClassPlanGroupId: DefaultClassPlanGroupId,
|
||||
TempClassPlanGroupId: null,
|
||||
IsTempClassPlanGroupEnabled: false,
|
||||
|
||||
@@ -16,7 +16,13 @@ public enum WallpaperMediaType
|
||||
}
|
||||
|
||||
public sealed record GridSettingsState(int ShortSideCells, string SpacingPreset, int EdgeInsetPercent);
|
||||
public sealed record WallpaperSettingsState(string? WallpaperPath, string Type, string? Color, string Placement, string? CustomColor = null);
|
||||
public sealed record WallpaperSettingsState(
|
||||
string? WallpaperPath,
|
||||
string Type,
|
||||
string? Color,
|
||||
string Placement,
|
||||
string? CustomColor = null,
|
||||
int SystemWallpaperRefreshIntervalSeconds = 300);
|
||||
public sealed record ThemeAppearanceSettingsState(
|
||||
bool IsNightMode,
|
||||
string? ThemeColor,
|
||||
|
||||
@@ -101,7 +101,9 @@ internal sealed class WallpaperSettingsService : IWallpaperSettingsService
|
||||
: snapshot.WallpaperPath,
|
||||
normalizedType,
|
||||
snapshot.WallpaperColor,
|
||||
snapshot.WallpaperPlacement);
|
||||
snapshot.WallpaperPlacement,
|
||||
CustomColor: null,
|
||||
SystemWallpaperRefreshIntervalSeconds: NormalizeRefreshInterval(snapshot.SystemWallpaperRefreshIntervalSeconds));
|
||||
}
|
||||
|
||||
public void Save(WallpaperSettingsState state)
|
||||
@@ -128,6 +130,7 @@ internal sealed class WallpaperSettingsService : IWallpaperSettingsService
|
||||
snapshot.WallpaperPlacement = string.IsNullOrWhiteSpace(state.Placement)
|
||||
? "Fill"
|
||||
: state.Placement.Trim();
|
||||
snapshot.SystemWallpaperRefreshIntervalSeconds = NormalizeRefreshInterval(state.SystemWallpaperRefreshIntervalSeconds);
|
||||
_settingsService.SaveSnapshot(
|
||||
SettingsScope.App,
|
||||
snapshot,
|
||||
@@ -136,9 +139,21 @@ internal sealed class WallpaperSettingsService : IWallpaperSettingsService
|
||||
nameof(AppSettingsSnapshot.WallpaperPath),
|
||||
nameof(AppSettingsSnapshot.WallpaperType),
|
||||
nameof(AppSettingsSnapshot.WallpaperColor),
|
||||
nameof(AppSettingsSnapshot.WallpaperPlacement)
|
||||
nameof(AppSettingsSnapshot.WallpaperPlacement),
|
||||
nameof(AppSettingsSnapshot.SystemWallpaperRefreshIntervalSeconds)
|
||||
]);
|
||||
}
|
||||
|
||||
private static int NormalizeRefreshInterval(int seconds)
|
||||
{
|
||||
return seconds switch
|
||||
{
|
||||
<= 0 => 300,
|
||||
< 30 => 30,
|
||||
> 86400 => 86400,
|
||||
_ => seconds
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
internal sealed class WallpaperMediaService : IWallpaperMediaService
|
||||
|
||||
65
LanMountainDesktop/Services/SystemWallpaperProvider.cs
Normal file
65
LanMountainDesktop/Services/SystemWallpaperProvider.cs
Normal file
@@ -0,0 +1,65 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Runtime.InteropServices;
|
||||
using Avalonia.Media.Imaging;
|
||||
using Microsoft.Win32;
|
||||
|
||||
namespace LanMountainDesktop.Services;
|
||||
|
||||
public interface ISystemWallpaperProvider
|
||||
{
|
||||
bool IsSupported { get; }
|
||||
string? GetWallpaperPath();
|
||||
event EventHandler? WallpaperChanged;
|
||||
}
|
||||
|
||||
internal sealed class SystemWallpaperProvider : ISystemWallpaperProvider, IDisposable
|
||||
{
|
||||
public bool IsSupported => RuntimeInformation.IsOSPlatform(OSPlatform.Windows);
|
||||
|
||||
public event EventHandler? WallpaperChanged;
|
||||
|
||||
public string? GetWallpaperPath()
|
||||
{
|
||||
if (!IsSupported)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
using var key = Registry.CurrentUser.OpenSubKey(@"Control Panel\Desktop");
|
||||
var wallpaperPath = key?.GetValue("Wallpaper") as string;
|
||||
|
||||
if (string.IsNullOrWhiteSpace(wallpaperPath))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
if (!File.Exists(wallpaperPath))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
return wallpaperPath;
|
||||
}
|
||||
catch
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
public static class HostSystemWallpaperProvider
|
||||
{
|
||||
private static ISystemWallpaperProvider? _instance;
|
||||
|
||||
public static ISystemWallpaperProvider GetOrCreate()
|
||||
{
|
||||
return _instance ??= new SystemWallpaperProvider();
|
||||
}
|
||||
}
|
||||
@@ -5,13 +5,13 @@ using Avalonia.Media.Imaging;
|
||||
|
||||
namespace LanMountainDesktop.Services;
|
||||
|
||||
internal static class WallpaperImageBrushFactory
|
||||
public static class WallpaperImageBrushFactory
|
||||
{
|
||||
internal const string Fill = "Fill";
|
||||
internal const string Fit = "Fit";
|
||||
internal const string StretchMode = "Stretch";
|
||||
internal const string Center = "Center";
|
||||
internal const string Tile = "Tile";
|
||||
public const string Fill = "Fill";
|
||||
public const string Fit = "Fit";
|
||||
public const string StretchMode = "Stretch";
|
||||
public const string Center = "Center";
|
||||
public const string Tile = "Tile";
|
||||
|
||||
public static string NormalizePlacement(string? placement)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user