mirror of
https://github.com/sourcegit-scm/sourcegit.git
synced 2024-12-24 20:57:19 -08:00
refactor: delay starting background tasks
* start background task only it is needed * solve the problem that we can not use `ViewModels.Preference.Instance` until resource ready * remove avatar sever settings
This commit is contained in:
parent
e7921db339
commit
7fe1df20cc
13 changed files with 178 additions and 190 deletions
|
@ -528,6 +528,8 @@ namespace SourceGit
|
||||||
private void TryLaunchedAsNormal(IClassicDesktopStyleApplicationLifetime desktop)
|
private void TryLaunchedAsNormal(IClassicDesktopStyleApplicationLifetime desktop)
|
||||||
{
|
{
|
||||||
Native.OS.SetupEnternalTools();
|
Native.OS.SetupEnternalTools();
|
||||||
|
Models.AvatarManager.Instance.Start();
|
||||||
|
Models.AutoFetchManager.Instance.Start();
|
||||||
|
|
||||||
string startupRepo = null;
|
string startupRepo = null;
|
||||||
if (desktop.Args != null && desktop.Args.Length == 1 && Directory.Exists(desktop.Args[0]))
|
if (desktop.Args != null && desktop.Args.Length == 1 && Directory.Exists(desktop.Args[0]))
|
||||||
|
|
|
@ -26,7 +26,7 @@ namespace SourceGit.Commands
|
||||||
|
|
||||||
Args += remote;
|
Args += remote;
|
||||||
|
|
||||||
AutoFetch.MarkFetched(repo);
|
Models.AutoFetchManager.Instance.MarkFetched(repo);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Fetch(string repo, string remote, string localBranch, string remoteBranch, Action<string> outputHandler)
|
public Fetch(string repo, string remote, string localBranch, string remoteBranch, Action<string> outputHandler)
|
||||||
|
@ -46,110 +46,4 @@ namespace SourceGit.Commands
|
||||||
|
|
||||||
private readonly Action<string> _outputHandler;
|
private readonly Action<string> _outputHandler;
|
||||||
}
|
}
|
||||||
|
|
||||||
public class AutoFetch
|
|
||||||
{
|
|
||||||
public static bool IsEnabled
|
|
||||||
{
|
|
||||||
get;
|
|
||||||
set;
|
|
||||||
} = false;
|
|
||||||
|
|
||||||
public static int Interval
|
|
||||||
{
|
|
||||||
get => _interval;
|
|
||||||
set
|
|
||||||
{
|
|
||||||
if (value < 1)
|
|
||||||
return;
|
|
||||||
_interval = value;
|
|
||||||
lock (_lock)
|
|
||||||
{
|
|
||||||
foreach (var job in _jobs)
|
|
||||||
{
|
|
||||||
job.Value.NextRunTimepoint = DateTime.Now.AddMinutes(Convert.ToDouble(_interval));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class Job
|
|
||||||
{
|
|
||||||
public Fetch Cmd = null;
|
|
||||||
public DateTime NextRunTimepoint = DateTime.MinValue;
|
|
||||||
}
|
|
||||||
|
|
||||||
static AutoFetch()
|
|
||||||
{
|
|
||||||
Task.Run(() =>
|
|
||||||
{
|
|
||||||
while (true)
|
|
||||||
{
|
|
||||||
if (!IsEnabled)
|
|
||||||
{
|
|
||||||
Thread.Sleep(10000);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
var now = DateTime.Now;
|
|
||||||
var uptodate = new List<Job>();
|
|
||||||
lock (_lock)
|
|
||||||
{
|
|
||||||
foreach (var job in _jobs)
|
|
||||||
{
|
|
||||||
if (job.Value.NextRunTimepoint.Subtract(now).TotalSeconds <= 0)
|
|
||||||
{
|
|
||||||
uptodate.Add(job.Value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
foreach (var job in uptodate)
|
|
||||||
{
|
|
||||||
job.Cmd.Exec();
|
|
||||||
job.NextRunTimepoint = DateTime.Now.AddMinutes(Convert.ToDouble(Interval));
|
|
||||||
}
|
|
||||||
|
|
||||||
Thread.Sleep(2000);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void AddRepository(string repo)
|
|
||||||
{
|
|
||||||
var job = new Job
|
|
||||||
{
|
|
||||||
Cmd = new Fetch(repo, "--all", true, false, null) { RaiseError = false },
|
|
||||||
NextRunTimepoint = DateTime.Now.AddMinutes(Convert.ToDouble(Interval)),
|
|
||||||
};
|
|
||||||
|
|
||||||
lock (_lock)
|
|
||||||
{
|
|
||||||
_jobs[repo] = job;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void RemoveRepository(string repo)
|
|
||||||
{
|
|
||||||
lock (_lock)
|
|
||||||
{
|
|
||||||
_jobs.Remove(repo);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void MarkFetched(string repo)
|
|
||||||
{
|
|
||||||
lock (_lock)
|
|
||||||
{
|
|
||||||
if (_jobs.TryGetValue(repo, out var value))
|
|
||||||
{
|
|
||||||
value.NextRunTimepoint = DateTime.Now.AddMinutes(Convert.ToDouble(Interval));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static readonly Dictionary<string, Job> _jobs = new Dictionary<string, Job>();
|
|
||||||
private static readonly object _lock = new object();
|
|
||||||
private static int _interval = 10;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
120
src/Models/AutoFetchManager.cs
Normal file
120
src/Models/AutoFetchManager.cs
Normal file
|
@ -0,0 +1,120 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Threading;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace SourceGit.Models
|
||||||
|
{
|
||||||
|
public class AutoFetchManager
|
||||||
|
{
|
||||||
|
public static AutoFetchManager Instance
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
if (_instance == null)
|
||||||
|
_instance = new AutoFetchManager();
|
||||||
|
|
||||||
|
return _instance;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public class Job
|
||||||
|
{
|
||||||
|
public Commands.Fetch Cmd = null;
|
||||||
|
public DateTime NextRunTimepoint = DateTime.MinValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool IsEnabled
|
||||||
|
{
|
||||||
|
get;
|
||||||
|
set;
|
||||||
|
} = false;
|
||||||
|
|
||||||
|
public int Interval
|
||||||
|
{
|
||||||
|
get => _interval;
|
||||||
|
set
|
||||||
|
{
|
||||||
|
_interval = Math.Max(1, value);
|
||||||
|
|
||||||
|
lock (_lock)
|
||||||
|
{
|
||||||
|
foreach (var job in _jobs)
|
||||||
|
job.Value.NextRunTimepoint = DateTime.Now.AddMinutes(_interval * 1.0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static AutoFetchManager _instance = null;
|
||||||
|
private Dictionary<string, Job> _jobs = new Dictionary<string, Job>();
|
||||||
|
private object _lock = new object();
|
||||||
|
private int _interval = 10;
|
||||||
|
|
||||||
|
public void Start()
|
||||||
|
{
|
||||||
|
Task.Run(() =>
|
||||||
|
{
|
||||||
|
while (true)
|
||||||
|
{
|
||||||
|
if (!IsEnabled)
|
||||||
|
{
|
||||||
|
Thread.Sleep(10000);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
var now = DateTime.Now;
|
||||||
|
var uptodate = new List<Job>();
|
||||||
|
lock (_lock)
|
||||||
|
{
|
||||||
|
foreach (var job in _jobs)
|
||||||
|
{
|
||||||
|
if (job.Value.NextRunTimepoint.Subtract(now).TotalSeconds <= 0)
|
||||||
|
uptodate.Add(job.Value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (var job in uptodate)
|
||||||
|
{
|
||||||
|
job.Cmd.Exec();
|
||||||
|
job.NextRunTimepoint = DateTime.Now.AddMinutes(Convert.ToDouble(Interval));
|
||||||
|
}
|
||||||
|
|
||||||
|
Thread.Sleep(2000);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ReSharper disable once FunctionNeverReturns
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public void AddRepository(string repo)
|
||||||
|
{
|
||||||
|
var job = new Job
|
||||||
|
{
|
||||||
|
Cmd = new Commands.Fetch(repo, "--all", true, false, null) { RaiseError = false },
|
||||||
|
NextRunTimepoint = DateTime.Now.AddMinutes(Convert.ToDouble(Interval)),
|
||||||
|
};
|
||||||
|
|
||||||
|
lock (_lock)
|
||||||
|
{
|
||||||
|
_jobs[repo] = job;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void RemoveRepository(string repo)
|
||||||
|
{
|
||||||
|
lock (_lock)
|
||||||
|
{
|
||||||
|
_jobs.Remove(repo);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void MarkFetched(string repo)
|
||||||
|
{
|
||||||
|
lock (_lock)
|
||||||
|
{
|
||||||
|
if (_jobs.TryGetValue(repo, out var value))
|
||||||
|
value.NextRunTimepoint = DateTime.Now.AddMinutes(Interval * 1.0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -20,15 +20,31 @@ namespace SourceGit.Models
|
||||||
void OnAvatarResourceChanged(string email);
|
void OnAvatarResourceChanged(string email);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static partial class AvatarManager
|
public partial class AvatarManager
|
||||||
{
|
{
|
||||||
public static string SelectedServer
|
public static AvatarManager Instance
|
||||||
{
|
{
|
||||||
get;
|
get
|
||||||
set;
|
{
|
||||||
} = "https://www.gravatar.com/avatar/";
|
if (_instance == null)
|
||||||
|
_instance = new AvatarManager();
|
||||||
|
|
||||||
static AvatarManager()
|
return _instance;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static AvatarManager _instance = null;
|
||||||
|
|
||||||
|
[GeneratedRegex(@"^(?:(\d+)\+)?(.+?)@users\.noreply\.github\.com$")]
|
||||||
|
private static partial Regex REG_GITHUB_USER_EMAIL();
|
||||||
|
|
||||||
|
private object _synclock = new object();
|
||||||
|
private string _storePath;
|
||||||
|
private List<IAvatarHost> _avatars = new List<IAvatarHost>();
|
||||||
|
private Dictionary<string, Bitmap> _resources = new Dictionary<string, Bitmap>();
|
||||||
|
private HashSet<string> _requesting = new HashSet<string>();
|
||||||
|
|
||||||
|
public void Start()
|
||||||
{
|
{
|
||||||
_storePath = Path.Combine(Native.OS.DataDir, "avatars");
|
_storePath = Path.Combine(Native.OS.DataDir, "avatars");
|
||||||
if (!Directory.Exists(_storePath))
|
if (!Directory.Exists(_storePath))
|
||||||
|
@ -62,7 +78,7 @@ namespace SourceGit.Models
|
||||||
var matchGithubUser = REG_GITHUB_USER_EMAIL().Match(email);
|
var matchGithubUser = REG_GITHUB_USER_EMAIL().Match(email);
|
||||||
var url = matchGithubUser.Success ?
|
var url = matchGithubUser.Success ?
|
||||||
$"https://avatars.githubusercontent.com/{matchGithubUser.Groups[2].Value}" :
|
$"https://avatars.githubusercontent.com/{matchGithubUser.Groups[2].Value}" :
|
||||||
$"{SelectedServer}{md5}?d=404";
|
$"https://www.gravatar.com/avatar/{md5}?d=404";
|
||||||
|
|
||||||
var localFile = Path.Combine(_storePath, md5);
|
var localFile = Path.Combine(_storePath, md5);
|
||||||
var img = null as Bitmap;
|
var img = null as Bitmap;
|
||||||
|
@ -105,20 +121,22 @@ namespace SourceGit.Models
|
||||||
NotifyResourceChanged(email);
|
NotifyResourceChanged(email);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ReSharper disable once FunctionNeverReturns
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void Subscribe(IAvatarHost host)
|
public void Subscribe(IAvatarHost host)
|
||||||
{
|
{
|
||||||
_avatars.Add(host);
|
_avatars.Add(host);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void Unsubscribe(IAvatarHost host)
|
public void Unsubscribe(IAvatarHost host)
|
||||||
{
|
{
|
||||||
_avatars.Remove(host);
|
_avatars.Remove(host);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Bitmap Request(string email, bool forceRefetch)
|
public Bitmap Request(string email, bool forceRefetch)
|
||||||
{
|
{
|
||||||
if (forceRefetch)
|
if (forceRefetch)
|
||||||
{
|
{
|
||||||
|
@ -167,7 +185,7 @@ namespace SourceGit.Models
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static string GetEmailHash(string email)
|
private string GetEmailHash(string email)
|
||||||
{
|
{
|
||||||
var lowered = email.ToLower(CultureInfo.CurrentCulture).Trim();
|
var lowered = email.ToLower(CultureInfo.CurrentCulture).Trim();
|
||||||
var hash = MD5.Create().ComputeHash(Encoding.Default.GetBytes(lowered));
|
var hash = MD5.Create().ComputeHash(Encoding.Default.GetBytes(lowered));
|
||||||
|
@ -177,21 +195,12 @@ namespace SourceGit.Models
|
||||||
return builder.ToString();
|
return builder.ToString();
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void NotifyResourceChanged(string email)
|
private void NotifyResourceChanged(string email)
|
||||||
{
|
{
|
||||||
foreach (var avatar in _avatars)
|
foreach (var avatar in _avatars)
|
||||||
{
|
{
|
||||||
avatar.OnAvatarResourceChanged(email);
|
avatar.OnAvatarResourceChanged(email);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static readonly object _synclock = new object();
|
|
||||||
private static readonly string _storePath;
|
|
||||||
private static readonly List<IAvatarHost> _avatars = new List<IAvatarHost>();
|
|
||||||
private static readonly Dictionary<string, Bitmap> _resources = new Dictionary<string, Bitmap>();
|
|
||||||
private static readonly HashSet<string> _requesting = new HashSet<string>();
|
|
||||||
|
|
||||||
[GeneratedRegex(@"^(?:(\d+)\+)?(.+?)@users\.noreply\.github\.com$")]
|
|
||||||
private static partial Regex REG_GITHUB_USER_EMAIL();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -378,7 +378,6 @@
|
||||||
<x:String x:Key="Text.Preference.Appearance.Theme" xml:space="preserve">Design</x:String>
|
<x:String x:Key="Text.Preference.Appearance.Theme" xml:space="preserve">Design</x:String>
|
||||||
<x:String x:Key="Text.Preference.Appearance.ThemeOverrides" xml:space="preserve">Design-Anpassungen</x:String>
|
<x:String x:Key="Text.Preference.Appearance.ThemeOverrides" xml:space="preserve">Design-Anpassungen</x:String>
|
||||||
<x:String x:Key="Text.Preference.General" xml:space="preserve">ALLGEMEIN</x:String>
|
<x:String x:Key="Text.Preference.General" xml:space="preserve">ALLGEMEIN</x:String>
|
||||||
<x:String x:Key="Text.Preference.General.AvatarServer" xml:space="preserve">Avatar Server</x:String>
|
|
||||||
<x:String x:Key="Text.Preference.General.Check4UpdatesOnStartup" xml:space="preserve">Beim Starten nach Updates suchen</x:String>
|
<x:String x:Key="Text.Preference.General.Check4UpdatesOnStartup" xml:space="preserve">Beim Starten nach Updates suchen</x:String>
|
||||||
<x:String x:Key="Text.Preference.General.Locale" xml:space="preserve">Sprache</x:String>
|
<x:String x:Key="Text.Preference.General.Locale" xml:space="preserve">Sprache</x:String>
|
||||||
<x:String x:Key="Text.Preference.General.MaxHistoryCommits" xml:space="preserve">Commit-Historie</x:String>
|
<x:String x:Key="Text.Preference.General.MaxHistoryCommits" xml:space="preserve">Commit-Historie</x:String>
|
||||||
|
|
|
@ -380,7 +380,6 @@
|
||||||
<x:String x:Key="Text.Preference.Appearance.Theme" xml:space="preserve">Theme</x:String>
|
<x:String x:Key="Text.Preference.Appearance.Theme" xml:space="preserve">Theme</x:String>
|
||||||
<x:String x:Key="Text.Preference.Appearance.ThemeOverrides" xml:space="preserve">Theme Overrides</x:String>
|
<x:String x:Key="Text.Preference.Appearance.ThemeOverrides" xml:space="preserve">Theme Overrides</x:String>
|
||||||
<x:String x:Key="Text.Preference.General" xml:space="preserve">GENERAL</x:String>
|
<x:String x:Key="Text.Preference.General" xml:space="preserve">GENERAL</x:String>
|
||||||
<x:String x:Key="Text.Preference.General.AvatarServer" xml:space="preserve">Avatar Server</x:String>
|
|
||||||
<x:String x:Key="Text.Preference.General.Check4UpdatesOnStartup" xml:space="preserve">Check for updates on startup</x:String>
|
<x:String x:Key="Text.Preference.General.Check4UpdatesOnStartup" xml:space="preserve">Check for updates on startup</x:String>
|
||||||
<x:String x:Key="Text.Preference.General.Locale" xml:space="preserve">Language</x:String>
|
<x:String x:Key="Text.Preference.General.Locale" xml:space="preserve">Language</x:String>
|
||||||
<x:String x:Key="Text.Preference.General.MaxHistoryCommits" xml:space="preserve">History Commits</x:String>
|
<x:String x:Key="Text.Preference.General.MaxHistoryCommits" xml:space="preserve">History Commits</x:String>
|
||||||
|
|
|
@ -383,7 +383,6 @@
|
||||||
<x:String x:Key="Text.Preference.Appearance.Theme" xml:space="preserve">Tema</x:String>
|
<x:String x:Key="Text.Preference.Appearance.Theme" xml:space="preserve">Tema</x:String>
|
||||||
<x:String x:Key="Text.Preference.Appearance.ThemeOverrides" xml:space="preserve">Sobrescrever Tema</x:String>
|
<x:String x:Key="Text.Preference.Appearance.ThemeOverrides" xml:space="preserve">Sobrescrever Tema</x:String>
|
||||||
<x:String x:Key="Text.Preference.General" xml:space="preserve">GERAL</x:String>
|
<x:String x:Key="Text.Preference.General" xml:space="preserve">GERAL</x:String>
|
||||||
<x:String x:Key="Text.Preference.General.AvatarServer" xml:space="preserve">Servidor de Avatar</x:String>
|
|
||||||
<x:String x:Key="Text.Preference.General.Check4UpdatesOnStartup" xml:space="preserve">Verificar atualizações na inicialização</x:String>
|
<x:String x:Key="Text.Preference.General.Check4UpdatesOnStartup" xml:space="preserve">Verificar atualizações na inicialização</x:String>
|
||||||
<x:String x:Key="Text.Preference.General.Locale" xml:space="preserve">Idioma</x:String>
|
<x:String x:Key="Text.Preference.General.Locale" xml:space="preserve">Idioma</x:String>
|
||||||
<x:String x:Key="Text.Preference.General.MaxHistoryCommits" xml:space="preserve">Commits do Histórico</x:String>
|
<x:String x:Key="Text.Preference.General.MaxHistoryCommits" xml:space="preserve">Commits do Histórico</x:String>
|
||||||
|
|
|
@ -383,7 +383,6 @@
|
||||||
<x:String x:Key="Text.Preference.Appearance.Theme" xml:space="preserve">主题</x:String>
|
<x:String x:Key="Text.Preference.Appearance.Theme" xml:space="preserve">主题</x:String>
|
||||||
<x:String x:Key="Text.Preference.Appearance.ThemeOverrides" xml:space="preserve">主题自定义</x:String>
|
<x:String x:Key="Text.Preference.Appearance.ThemeOverrides" xml:space="preserve">主题自定义</x:String>
|
||||||
<x:String x:Key="Text.Preference.General" xml:space="preserve">通用配置</x:String>
|
<x:String x:Key="Text.Preference.General" xml:space="preserve">通用配置</x:String>
|
||||||
<x:String x:Key="Text.Preference.General.AvatarServer" xml:space="preserve">头像服务</x:String>
|
|
||||||
<x:String x:Key="Text.Preference.General.Check4UpdatesOnStartup" xml:space="preserve">启动时检测软件更新</x:String>
|
<x:String x:Key="Text.Preference.General.Check4UpdatesOnStartup" xml:space="preserve">启动时检测软件更新</x:String>
|
||||||
<x:String x:Key="Text.Preference.General.Locale" xml:space="preserve">显示语言</x:String>
|
<x:String x:Key="Text.Preference.General.Locale" xml:space="preserve">显示语言</x:String>
|
||||||
<x:String x:Key="Text.Preference.General.MaxHistoryCommits" xml:space="preserve">最大历史提交数</x:String>
|
<x:String x:Key="Text.Preference.General.MaxHistoryCommits" xml:space="preserve">最大历史提交数</x:String>
|
||||||
|
|
|
@ -383,7 +383,6 @@
|
||||||
<x:String x:Key="Text.Preference.Appearance.Theme" xml:space="preserve">主題</x:String>
|
<x:String x:Key="Text.Preference.Appearance.Theme" xml:space="preserve">主題</x:String>
|
||||||
<x:String x:Key="Text.Preference.Appearance.ThemeOverrides" xml:space="preserve">主題自訂</x:String>
|
<x:String x:Key="Text.Preference.Appearance.ThemeOverrides" xml:space="preserve">主題自訂</x:String>
|
||||||
<x:String x:Key="Text.Preference.General" xml:space="preserve">通用配置</x:String>
|
<x:String x:Key="Text.Preference.General" xml:space="preserve">通用配置</x:String>
|
||||||
<x:String x:Key="Text.Preference.General.AvatarServer" xml:space="preserve">頭像服務</x:String>
|
|
||||||
<x:String x:Key="Text.Preference.General.Check4UpdatesOnStartup" xml:space="preserve">啟動時檢測軟體更新</x:String>
|
<x:String x:Key="Text.Preference.General.Check4UpdatesOnStartup" xml:space="preserve">啟動時檢測軟體更新</x:String>
|
||||||
<x:String x:Key="Text.Preference.General.Locale" xml:space="preserve">顯示語言</x:String>
|
<x:String x:Key="Text.Preference.General.Locale" xml:space="preserve">顯示語言</x:String>
|
||||||
<x:String x:Key="Text.Preference.General.MaxHistoryCommits" xml:space="preserve">最大歷史提交數</x:String>
|
<x:String x:Key="Text.Preference.General.MaxHistoryCommits" xml:space="preserve">最大歷史提交數</x:String>
|
||||||
|
|
|
@ -141,7 +141,7 @@ namespace SourceGit.ViewModels
|
||||||
var last = Pages[0];
|
var last = Pages[0];
|
||||||
if (last.Data is Repository repo)
|
if (last.Data is Repository repo)
|
||||||
{
|
{
|
||||||
Commands.AutoFetch.RemoveRepository(repo.FullPath);
|
Models.AutoFetchManager.Instance.RemoveRepository(repo.FullPath);
|
||||||
repo.Close();
|
repo.Close();
|
||||||
|
|
||||||
last.Node = new RepositoryNode() { Id = Guid.NewGuid().ToString() };
|
last.Node = new RepositoryNode() { Id = Guid.NewGuid().ToString() };
|
||||||
|
@ -245,7 +245,7 @@ namespace SourceGit.ViewModels
|
||||||
};
|
};
|
||||||
|
|
||||||
repo.Open();
|
repo.Open();
|
||||||
Commands.AutoFetch.AddRepository(repo.FullPath);
|
Models.AutoFetchManager.Instance.AddRepository(repo.FullPath);
|
||||||
|
|
||||||
if (page == null)
|
if (page == null)
|
||||||
{
|
{
|
||||||
|
@ -371,7 +371,7 @@ namespace SourceGit.ViewModels
|
||||||
{
|
{
|
||||||
if (page.Data is Repository repo)
|
if (page.Data is Repository repo)
|
||||||
{
|
{
|
||||||
Commands.AutoFetch.RemoveRepository(repo.FullPath);
|
Models.AutoFetchManager.Instance.RemoveRepository(repo.FullPath);
|
||||||
repo.Close();
|
repo.Close();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -128,19 +128,6 @@ namespace SourceGit.ViewModels
|
||||||
set => SetProperty(ref _layout, value);
|
set => SetProperty(ref _layout, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
public string AvatarServer
|
|
||||||
{
|
|
||||||
get => Models.AvatarManager.SelectedServer;
|
|
||||||
set
|
|
||||||
{
|
|
||||||
if (Models.AvatarManager.SelectedServer != value)
|
|
||||||
{
|
|
||||||
Models.AvatarManager.SelectedServer = value;
|
|
||||||
OnPropertyChanged();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public int MaxHistoryCommits
|
public int MaxHistoryCommits
|
||||||
{
|
{
|
||||||
get => _maxHistoryCommits;
|
get => _maxHistoryCommits;
|
||||||
|
@ -262,9 +249,7 @@ namespace SourceGit.ViewModels
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
if (Native.OS.SetShell(value))
|
if (Native.OS.SetShell(value))
|
||||||
{
|
|
||||||
OnPropertyChanged();
|
OnPropertyChanged();
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -276,12 +261,12 @@ namespace SourceGit.ViewModels
|
||||||
|
|
||||||
public bool GitAutoFetch
|
public bool GitAutoFetch
|
||||||
{
|
{
|
||||||
get => Commands.AutoFetch.IsEnabled;
|
get => Models.AutoFetchManager.Instance.IsEnabled;
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
if (Commands.AutoFetch.IsEnabled != value)
|
if (Models.AutoFetchManager.Instance.IsEnabled != value)
|
||||||
{
|
{
|
||||||
Commands.AutoFetch.IsEnabled = value;
|
Models.AutoFetchManager.Instance.IsEnabled = value;
|
||||||
OnPropertyChanged();
|
OnPropertyChanged();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -289,15 +274,15 @@ namespace SourceGit.ViewModels
|
||||||
|
|
||||||
public int? GitAutoFetchInterval
|
public int? GitAutoFetchInterval
|
||||||
{
|
{
|
||||||
get => Commands.AutoFetch.Interval;
|
get => Models.AutoFetchManager.Instance.Interval;
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
if (value is null or < 1)
|
if (value is null || value < 1)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (Commands.AutoFetch.Interval != value)
|
if (Models.AutoFetchManager.Instance.Interval != value)
|
||||||
{
|
{
|
||||||
Commands.AutoFetch.Interval = (int)value;
|
Models.AutoFetchManager.Instance.Interval = (int)value;
|
||||||
OnPropertyChanged();
|
OnPropertyChanged();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -336,7 +321,7 @@ namespace SourceGit.ViewModels
|
||||||
{
|
{
|
||||||
get;
|
get;
|
||||||
set;
|
set;
|
||||||
} = new List<string>();
|
} = [];
|
||||||
|
|
||||||
public int LastActiveTabIdx
|
public int LastActiveTabIdx
|
||||||
{
|
{
|
||||||
|
|
|
@ -39,7 +39,7 @@ namespace SourceGit.Views
|
||||||
refetch.Click += (_, _) =>
|
refetch.Click += (_, _) =>
|
||||||
{
|
{
|
||||||
if (User != null)
|
if (User != null)
|
||||||
Models.AvatarManager.Request(User.Email, true);
|
Models.AvatarManager.Instance.Request(User.Email, true);
|
||||||
};
|
};
|
||||||
|
|
||||||
ContextMenu = new ContextMenu();
|
ContextMenu = new ContextMenu();
|
||||||
|
@ -54,7 +54,7 @@ namespace SourceGit.Views
|
||||||
return;
|
return;
|
||||||
|
|
||||||
var corner = (float)Math.Max(2, Bounds.Width / 16);
|
var corner = (float)Math.Max(2, Bounds.Width / 16);
|
||||||
var img = Models.AvatarManager.Request(User.Email, false);
|
var img = Models.AvatarManager.Instance.Request(User.Email, false);
|
||||||
if (img != null)
|
if (img != null)
|
||||||
{
|
{
|
||||||
var rect = new Rect(0, 0, Bounds.Width, Bounds.Height);
|
var rect = new Rect(0, 0, Bounds.Width, Bounds.Height);
|
||||||
|
@ -72,21 +72,19 @@ namespace SourceGit.Views
|
||||||
public void OnAvatarResourceChanged(string email)
|
public void OnAvatarResourceChanged(string email)
|
||||||
{
|
{
|
||||||
if (User.Email.Equals(email, StringComparison.Ordinal))
|
if (User.Email.Equals(email, StringComparison.Ordinal))
|
||||||
{
|
|
||||||
InvalidateVisual();
|
InvalidateVisual();
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void OnLoaded(RoutedEventArgs e)
|
protected override void OnLoaded(RoutedEventArgs e)
|
||||||
{
|
{
|
||||||
base.OnLoaded(e);
|
base.OnLoaded(e);
|
||||||
Models.AvatarManager.Subscribe(this);
|
Models.AvatarManager.Instance.Subscribe(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void OnUnloaded(RoutedEventArgs e)
|
protected override void OnUnloaded(RoutedEventArgs e)
|
||||||
{
|
{
|
||||||
base.OnUnloaded(e);
|
base.OnUnloaded(e);
|
||||||
Models.AvatarManager.Unsubscribe(this);
|
Models.AvatarManager.Instance.Unsubscribe(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void OnUserPropertyChanged(Avatar avatar, AvaloniaPropertyChangedEventArgs e)
|
private static void OnUserPropertyChanged(Avatar avatar, AvaloniaPropertyChangedEventArgs e)
|
||||||
|
|
|
@ -57,7 +57,7 @@
|
||||||
<TabItem.Header>
|
<TabItem.Header>
|
||||||
<TextBlock Classes="tab_header" Text="{DynamicResource Text.Preference.General}"/>
|
<TextBlock Classes="tab_header" Text="{DynamicResource Text.Preference.General}"/>
|
||||||
</TabItem.Header>
|
</TabItem.Header>
|
||||||
<Grid Margin="8" RowDefinitions="32,32,32,32,32,32,32,32" ColumnDefinitions="Auto,*">
|
<Grid Margin="8" RowDefinitions="32,32,32,32,32,32,32" ColumnDefinitions="Auto,*">
|
||||||
<TextBlock Grid.Row="0" Grid.Column="0"
|
<TextBlock Grid.Row="0" Grid.Column="0"
|
||||||
Text="{DynamicResource Text.Preference.General.Locale}"
|
Text="{DynamicResource Text.Preference.General.Locale}"
|
||||||
HorizontalAlignment="Right"
|
HorizontalAlignment="Right"
|
||||||
|
@ -71,25 +71,10 @@
|
||||||
SelectedItem="{Binding Locale, Mode=TwoWay, Converter={x:Static c:StringConverters.ToLocale}}"/>
|
SelectedItem="{Binding Locale, Mode=TwoWay, Converter={x:Static c:StringConverters.ToLocale}}"/>
|
||||||
|
|
||||||
<TextBlock Grid.Row="1" Grid.Column="0"
|
<TextBlock Grid.Row="1" Grid.Column="0"
|
||||||
Text="{DynamicResource Text.Preference.General.AvatarServer}"
|
|
||||||
HorizontalAlignment="Right"
|
|
||||||
Margin="0,0,16,0"/>
|
|
||||||
<ComboBox Grid.Row="1" Grid.Column="1"
|
|
||||||
MinHeight="28"
|
|
||||||
Padding="8,0"
|
|
||||||
HorizontalAlignment="Stretch"
|
|
||||||
SelectedItem="{Binding AvatarServer, Mode=TwoWay}">
|
|
||||||
<ComboBox.Items>
|
|
||||||
<sys:String>https://www.gravatar.com/avatar/</sys:String>
|
|
||||||
<sys:String>https://cravatar.cn/avatar/</sys:String>
|
|
||||||
</ComboBox.Items>
|
|
||||||
</ComboBox>
|
|
||||||
|
|
||||||
<TextBlock Grid.Row="2" Grid.Column="0"
|
|
||||||
Text="{DynamicResource Text.Preference.General.VisibleDiffContextLines}"
|
Text="{DynamicResource Text.Preference.General.VisibleDiffContextLines}"
|
||||||
HorizontalAlignment="Right"
|
HorizontalAlignment="Right"
|
||||||
Margin="0,0,16,0"/>
|
Margin="0,0,16,0"/>
|
||||||
<NumericUpDown Grid.Row="2" Grid.Column="1"
|
<NumericUpDown Grid.Row="1" Grid.Column="1"
|
||||||
Minimum="4" Maximum="10000" Increment="1"
|
Minimum="4" Maximum="10000" Increment="1"
|
||||||
Height="28"
|
Height="28"
|
||||||
Padding="4"
|
Padding="4"
|
||||||
|
@ -98,11 +83,11 @@
|
||||||
CornerRadius="3"
|
CornerRadius="3"
|
||||||
Value="{Binding DiffViewVisualLineNumbers, Mode=TwoWay}"/>
|
Value="{Binding DiffViewVisualLineNumbers, Mode=TwoWay}"/>
|
||||||
|
|
||||||
<TextBlock Grid.Row="3" Grid.Column="0"
|
<TextBlock Grid.Row="2" Grid.Column="0"
|
||||||
Text="{DynamicResource Text.Preference.General.SubjectGuideLength}"
|
Text="{DynamicResource Text.Preference.General.SubjectGuideLength}"
|
||||||
HorizontalAlignment="Right"
|
HorizontalAlignment="Right"
|
||||||
Margin="0,0,16,0"/>
|
Margin="0,0,16,0"/>
|
||||||
<NumericUpDown Grid.Row="3" Grid.Column="1"
|
<NumericUpDown Grid.Row="2" Grid.Column="1"
|
||||||
Minimum="50" Maximum="1000" Increment="1"
|
Minimum="50" Maximum="1000" Increment="1"
|
||||||
Height="28"
|
Height="28"
|
||||||
Padding="4"
|
Padding="4"
|
||||||
|
@ -111,11 +96,11 @@
|
||||||
CornerRadius="3"
|
CornerRadius="3"
|
||||||
Value="{Binding SubjectGuideLength, Mode=TwoWay}"/>
|
Value="{Binding SubjectGuideLength, Mode=TwoWay}"/>
|
||||||
|
|
||||||
<TextBlock Grid.Row="4" Grid.Column="0"
|
<TextBlock Grid.Row="3" Grid.Column="0"
|
||||||
Text="{DynamicResource Text.Preference.General.MaxHistoryCommits}"
|
Text="{DynamicResource Text.Preference.General.MaxHistoryCommits}"
|
||||||
HorizontalAlignment="Right"
|
HorizontalAlignment="Right"
|
||||||
Margin="0,0,16,0"/>
|
Margin="0,0,16,0"/>
|
||||||
<Grid Grid.Row="4" Grid.Column="1" ColumnDefinitions="*,64">
|
<Grid Grid.Row="3" Grid.Column="1" ColumnDefinitions="*,64">
|
||||||
<Slider Grid.Column="0"
|
<Slider Grid.Column="0"
|
||||||
Minimum="20000" Maximum="100000"
|
Minimum="20000" Maximum="100000"
|
||||||
TickPlacement="BottomRight" TickFrequency="5000"
|
TickPlacement="BottomRight" TickFrequency="5000"
|
||||||
|
@ -130,16 +115,16 @@
|
||||||
Text="{Binding MaxHistoryCommits}"/>
|
Text="{Binding MaxHistoryCommits}"/>
|
||||||
</Grid>
|
</Grid>
|
||||||
|
|
||||||
<CheckBox Grid.Row="5" Grid.Column="1"
|
<CheckBox Grid.Row="4" Grid.Column="1"
|
||||||
Content="{DynamicResource Text.Preference.General.RestoreTabs}"
|
Content="{DynamicResource Text.Preference.General.RestoreTabs}"
|
||||||
IsChecked="{Binding RestoreTabs, Mode=TwoWay}"/>
|
IsChecked="{Binding RestoreTabs, Mode=TwoWay}"/>
|
||||||
|
|
||||||
<CheckBox Grid.Row="6" Grid.Column="1"
|
<CheckBox Grid.Row="5" Grid.Column="1"
|
||||||
Height="32"
|
Height="32"
|
||||||
Content="{DynamicResource Text.Preference.General.UseFixedTabWidth}"
|
Content="{DynamicResource Text.Preference.General.UseFixedTabWidth}"
|
||||||
IsChecked="{Binding Source={x:Static vm:Preference.Instance}, Path=UseFixedTabWidth, Mode=TwoWay}"/>
|
IsChecked="{Binding Source={x:Static vm:Preference.Instance}, Path=UseFixedTabWidth, Mode=TwoWay}"/>
|
||||||
|
|
||||||
<CheckBox Grid.Row="7" Grid.Column="1"
|
<CheckBox Grid.Row="6" Grid.Column="1"
|
||||||
Height="32"
|
Height="32"
|
||||||
Content="{DynamicResource Text.Preference.General.Check4UpdatesOnStartup}"
|
Content="{DynamicResource Text.Preference.General.Check4UpdatesOnStartup}"
|
||||||
IsChecked="{Binding Source={x:Static vm:Preference.Instance}, Path=Check4UpdatesOnStartup, Mode=TwoWay}"/>
|
IsChecked="{Binding Source={x:Static vm:Preference.Instance}, Path=Check4UpdatesOnStartup, Mode=TwoWay}"/>
|
||||||
|
|
Loading…
Reference in a new issue