2024-03-17 18:37:06 -07:00
|
|
|
|
using System;
|
2024-02-05 23:08:37 -08:00
|
|
|
|
using System.IO;
|
|
|
|
|
|
2024-03-17 18:37:06 -07:00
|
|
|
|
using Avalonia.Collections;
|
|
|
|
|
|
|
|
|
|
using CommunityToolkit.Mvvm.ComponentModel;
|
|
|
|
|
|
|
|
|
|
namespace SourceGit.ViewModels
|
|
|
|
|
{
|
|
|
|
|
public class Launcher : ObservableObject
|
|
|
|
|
{
|
|
|
|
|
public AvaloniaList<LauncherPage> Pages
|
|
|
|
|
{
|
2024-02-05 23:08:37 -08:00
|
|
|
|
get;
|
|
|
|
|
private set;
|
|
|
|
|
}
|
|
|
|
|
|
2024-03-17 18:37:06 -07:00
|
|
|
|
public LauncherPage ActivePage
|
|
|
|
|
{
|
2024-02-05 23:08:37 -08:00
|
|
|
|
get => _activePage;
|
2024-03-17 18:37:06 -07:00
|
|
|
|
set
|
|
|
|
|
{
|
|
|
|
|
if (SetProperty(ref _activePage, value))
|
|
|
|
|
{
|
2024-02-05 23:08:37 -08:00
|
|
|
|
PopupHost.Active = value;
|
2024-06-06 03:09:35 -07:00
|
|
|
|
UpdateTabSplitterVisible();
|
2024-02-05 23:08:37 -08:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2024-03-17 18:37:06 -07:00
|
|
|
|
public Launcher()
|
|
|
|
|
{
|
2024-02-05 23:08:37 -08:00
|
|
|
|
Pages = new AvaloniaList<LauncherPage>();
|
|
|
|
|
AddNewTab();
|
2024-02-19 03:54:53 -08:00
|
|
|
|
|
2024-05-19 23:39:05 -07:00
|
|
|
|
var commandlines = Environment.GetCommandLineArgs();
|
|
|
|
|
if (commandlines.Length == 2)
|
|
|
|
|
{
|
2024-05-20 00:15:08 -07:00
|
|
|
|
var path = commandlines[1];
|
2024-05-19 23:39:05 -07:00
|
|
|
|
var root = new Commands.QueryRepositoryRootPath(path).Result();
|
|
|
|
|
if (string.IsNullOrEmpty(root))
|
|
|
|
|
{
|
|
|
|
|
Pages[0].Notifications.Add(new Models.Notification
|
|
|
|
|
{
|
|
|
|
|
IsError = true,
|
2024-05-20 00:15:08 -07:00
|
|
|
|
Message = $"Given path: '{path}' is NOT a valid repository!"
|
2024-05-19 23:39:05 -07:00
|
|
|
|
});
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var gitDir = new Commands.QueryGitDir(root).Result();
|
|
|
|
|
var repo = Preference.AddRepository(root, gitDir);
|
2024-05-20 02:36:43 -07:00
|
|
|
|
var node = Preference.FindOrAddNodeByRepositoryPath(repo.FullPath, null, false);
|
2024-05-19 23:39:05 -07:00
|
|
|
|
OpenRepositoryInTab(node, null);
|
|
|
|
|
}
|
|
|
|
|
else if (Preference.Instance.RestoreTabs)
|
2024-03-17 18:37:06 -07:00
|
|
|
|
{
|
|
|
|
|
foreach (var id in Preference.Instance.OpenedTabs)
|
|
|
|
|
{
|
2024-02-19 03:54:53 -08:00
|
|
|
|
var node = Preference.FindNode(id);
|
2024-03-31 01:54:29 -07:00
|
|
|
|
if (node == null)
|
|
|
|
|
continue;
|
2024-02-19 03:54:53 -08:00
|
|
|
|
|
|
|
|
|
OpenRepositoryInTab(node, null);
|
|
|
|
|
}
|
2024-03-06 03:46:19 -08:00
|
|
|
|
|
|
|
|
|
var lastActiveIdx = Preference.Instance.LastActiveTabIdx;
|
2024-03-17 18:37:06 -07:00
|
|
|
|
if (lastActiveIdx >= 0 && lastActiveIdx < Pages.Count)
|
|
|
|
|
{
|
2024-03-06 03:46:19 -08:00
|
|
|
|
ActivePage = Pages[lastActiveIdx];
|
|
|
|
|
}
|
2024-02-19 03:54:53 -08:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2024-03-17 18:37:06 -07:00
|
|
|
|
public void Quit()
|
|
|
|
|
{
|
2024-02-19 03:54:53 -08:00
|
|
|
|
Preference.Instance.OpenedTabs.Clear();
|
|
|
|
|
|
2024-03-17 18:37:06 -07:00
|
|
|
|
if (Preference.Instance.RestoreTabs)
|
|
|
|
|
{
|
|
|
|
|
foreach (var page in Pages)
|
|
|
|
|
{
|
2024-03-31 01:54:29 -07:00
|
|
|
|
if (page.Node.IsRepository)
|
|
|
|
|
Preference.Instance.OpenedTabs.Add(page.Node.Id);
|
2024-02-19 03:54:53 -08:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2024-03-06 03:46:19 -08:00
|
|
|
|
Preference.Instance.LastActiveTabIdx = Pages.IndexOf(ActivePage);
|
2024-02-19 03:54:53 -08:00
|
|
|
|
Preference.Save();
|
2024-02-05 23:08:37 -08:00
|
|
|
|
}
|
|
|
|
|
|
2024-03-17 18:37:06 -07:00
|
|
|
|
public void AddNewTab()
|
|
|
|
|
{
|
2024-02-05 23:08:37 -08:00
|
|
|
|
var page = new LauncherPage();
|
|
|
|
|
Pages.Add(page);
|
|
|
|
|
ActivePage = page;
|
|
|
|
|
}
|
|
|
|
|
|
2024-03-17 18:37:06 -07:00
|
|
|
|
public void MoveTab(LauncherPage from, LauncherPage to)
|
|
|
|
|
{
|
2024-02-05 23:08:37 -08:00
|
|
|
|
var fromIdx = Pages.IndexOf(from);
|
|
|
|
|
var toIdx = Pages.IndexOf(to);
|
|
|
|
|
Pages.Move(fromIdx, toIdx);
|
|
|
|
|
ActivePage = from;
|
|
|
|
|
}
|
|
|
|
|
|
2024-03-17 18:37:06 -07:00
|
|
|
|
public void GotoNextTab()
|
|
|
|
|
{
|
2024-03-31 01:54:29 -07:00
|
|
|
|
if (Pages.Count == 1)
|
|
|
|
|
return;
|
2024-02-05 23:08:37 -08:00
|
|
|
|
|
|
|
|
|
var activeIdx = Pages.IndexOf(_activePage);
|
|
|
|
|
var nextIdx = (activeIdx + 1) % Pages.Count;
|
|
|
|
|
ActivePage = Pages[nextIdx];
|
|
|
|
|
}
|
|
|
|
|
|
2024-05-05 19:22:13 -07:00
|
|
|
|
public void GotoPrevTab()
|
|
|
|
|
{
|
|
|
|
|
if (Pages.Count == 1)
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
var activeIdx = Pages.IndexOf(_activePage);
|
|
|
|
|
var prevIdx = activeIdx == 0 ? Pages.Count - 1 : activeIdx - 1;
|
|
|
|
|
ActivePage = Pages[prevIdx];
|
|
|
|
|
}
|
|
|
|
|
|
2024-03-17 18:37:06 -07:00
|
|
|
|
public void CloseTab(object param)
|
|
|
|
|
{
|
|
|
|
|
if (Pages.Count == 1)
|
|
|
|
|
{
|
2024-05-06 19:34:04 -07:00
|
|
|
|
var last = Pages[0];
|
|
|
|
|
if (last.Data is Repository repo)
|
|
|
|
|
{
|
|
|
|
|
Commands.AutoFetch.RemoveRepository(repo.FullPath);
|
|
|
|
|
repo.Close();
|
|
|
|
|
|
|
|
|
|
last.Node = new RepositoryNode() { Id = Guid.NewGuid().ToString() };
|
2024-05-06 23:12:33 -07:00
|
|
|
|
last.Data = Welcome.Instance;
|
2024-05-06 19:34:04 -07:00
|
|
|
|
|
|
|
|
|
GC.Collect();
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
App.Quit();
|
|
|
|
|
}
|
|
|
|
|
|
2024-02-05 23:08:37 -08:00
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
LauncherPage page = param as LauncherPage;
|
2024-03-31 01:54:29 -07:00
|
|
|
|
if (page == null)
|
|
|
|
|
page = _activePage;
|
2024-02-05 23:08:37 -08:00
|
|
|
|
|
|
|
|
|
var removeIdx = Pages.IndexOf(page);
|
|
|
|
|
var activeIdx = Pages.IndexOf(_activePage);
|
2024-03-17 18:37:06 -07:00
|
|
|
|
if (removeIdx == activeIdx)
|
|
|
|
|
{
|
2024-05-06 23:28:34 -07:00
|
|
|
|
ActivePage = Pages[removeIdx == Pages.Count - 1 ? removeIdx - 1 : removeIdx + 1];
|
2024-02-20 02:27:59 -08:00
|
|
|
|
CloseRepositoryInTab(page);
|
2024-02-05 23:08:37 -08:00
|
|
|
|
Pages.RemoveAt(removeIdx);
|
2024-06-06 03:25:28 -07:00
|
|
|
|
UpdateTabSplitterVisible();
|
2024-03-17 18:37:06 -07:00
|
|
|
|
}
|
|
|
|
|
else if (removeIdx + 1 == activeIdx)
|
|
|
|
|
{
|
2024-02-20 02:27:59 -08:00
|
|
|
|
CloseRepositoryInTab(page);
|
2024-02-05 23:08:37 -08:00
|
|
|
|
Pages.RemoveAt(removeIdx);
|
2024-06-06 03:09:35 -07:00
|
|
|
|
UpdateTabSplitterVisible();
|
2024-03-17 18:37:06 -07:00
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
2024-02-20 02:27:59 -08:00
|
|
|
|
CloseRepositoryInTab(page);
|
2024-02-05 23:08:37 -08:00
|
|
|
|
Pages.RemoveAt(removeIdx);
|
|
|
|
|
}
|
2024-02-20 02:27:59 -08:00
|
|
|
|
|
|
|
|
|
GC.Collect();
|
2024-02-05 23:08:37 -08:00
|
|
|
|
}
|
|
|
|
|
|
2024-06-06 03:09:35 -07:00
|
|
|
|
public void CloseOtherTabs()
|
2024-03-17 18:37:06 -07:00
|
|
|
|
{
|
2024-03-31 01:54:29 -07:00
|
|
|
|
if (Pages.Count == 1)
|
|
|
|
|
return;
|
2024-02-05 23:08:37 -08:00
|
|
|
|
|
2024-06-06 03:09:35 -07:00
|
|
|
|
var id = ActivePage.Node.Id;
|
2024-03-17 18:37:06 -07:00
|
|
|
|
foreach (var one in Pages)
|
|
|
|
|
{
|
2024-06-06 03:09:35 -07:00
|
|
|
|
if (one.Node.Id != id)
|
2024-03-31 01:54:29 -07:00
|
|
|
|
CloseRepositoryInTab(one);
|
2024-02-05 23:08:37 -08:00
|
|
|
|
}
|
|
|
|
|
|
2024-06-06 03:09:35 -07:00
|
|
|
|
Pages = new AvaloniaList<LauncherPage> { ActivePage };
|
2024-02-20 02:27:59 -08:00
|
|
|
|
GC.Collect();
|
2024-02-05 23:08:37 -08:00
|
|
|
|
}
|
|
|
|
|
|
2024-06-06 03:09:35 -07:00
|
|
|
|
public void CloseRightTabs()
|
2024-03-17 18:37:06 -07:00
|
|
|
|
{
|
2024-06-06 03:09:35 -07:00
|
|
|
|
var endIdx = Pages.IndexOf(ActivePage);
|
2024-03-17 18:37:06 -07:00
|
|
|
|
for (var i = Pages.Count - 1; i > endIdx; i--)
|
|
|
|
|
{
|
2024-02-05 23:08:37 -08:00
|
|
|
|
CloseRepositoryInTab(Pages[i]);
|
|
|
|
|
Pages.Remove(Pages[i]);
|
|
|
|
|
}
|
2024-02-20 02:27:59 -08:00
|
|
|
|
|
|
|
|
|
GC.Collect();
|
2024-02-05 23:08:37 -08:00
|
|
|
|
}
|
|
|
|
|
|
2024-03-17 18:37:06 -07:00
|
|
|
|
public void OpenRepositoryInTab(RepositoryNode node, LauncherPage page)
|
|
|
|
|
{
|
|
|
|
|
foreach (var one in Pages)
|
|
|
|
|
{
|
|
|
|
|
if (one.Node.Id == node.Id)
|
|
|
|
|
{
|
2024-02-05 23:08:37 -08:00
|
|
|
|
ActivePage = one;
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var repo = Preference.FindRepository(node.Id);
|
2024-03-17 18:37:06 -07:00
|
|
|
|
if (repo == null || !Path.Exists(repo.FullPath))
|
|
|
|
|
{
|
2024-02-05 23:08:37 -08:00
|
|
|
|
var ctx = page == null ? ActivePage.Node.Id : page.Node.Id;
|
|
|
|
|
App.RaiseException(ctx, "Repository does NOT exists any more. Please remove it.");
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
repo.Open();
|
2024-02-18 00:26:07 -08:00
|
|
|
|
Commands.AutoFetch.AddRepository(repo.FullPath);
|
2024-02-05 23:08:37 -08:00
|
|
|
|
|
2024-03-17 18:37:06 -07:00
|
|
|
|
if (page == null)
|
|
|
|
|
{
|
|
|
|
|
if (ActivePage == null || ActivePage.Node.IsRepository)
|
|
|
|
|
{
|
2024-02-05 23:08:37 -08:00
|
|
|
|
page = new LauncherPage(node, repo);
|
|
|
|
|
Pages.Add(page);
|
2024-03-17 18:37:06 -07:00
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
2024-02-19 03:54:53 -08:00
|
|
|
|
page = ActivePage;
|
2024-02-05 23:08:37 -08:00
|
|
|
|
page.Node = node;
|
2024-03-02 06:45:14 -08:00
|
|
|
|
page.Data = repo;
|
2024-02-05 23:08:37 -08:00
|
|
|
|
}
|
2024-03-17 18:37:06 -07:00
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
2024-02-05 23:08:37 -08:00
|
|
|
|
page.Node = node;
|
2024-03-02 06:45:14 -08:00
|
|
|
|
page.Data = repo;
|
2024-02-05 23:08:37 -08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ActivePage = page;
|
|
|
|
|
}
|
|
|
|
|
|
2024-03-17 18:37:06 -07:00
|
|
|
|
private void CloseRepositoryInTab(LauncherPage page)
|
|
|
|
|
{
|
|
|
|
|
if (page.Data is Repository repo)
|
|
|
|
|
{
|
2024-03-02 06:45:14 -08:00
|
|
|
|
Commands.AutoFetch.RemoveRepository(repo.FullPath);
|
|
|
|
|
repo.Close();
|
2024-02-20 02:27:59 -08:00
|
|
|
|
}
|
2024-02-05 23:08:37 -08:00
|
|
|
|
|
2024-03-02 06:45:14 -08:00
|
|
|
|
page.Data = null;
|
2024-02-05 23:08:37 -08:00
|
|
|
|
}
|
|
|
|
|
|
2024-06-06 03:09:35 -07:00
|
|
|
|
private void UpdateTabSplitterVisible()
|
|
|
|
|
{
|
|
|
|
|
var activePageIdx = ActivePage == null ? -1 : Pages.IndexOf(ActivePage);
|
|
|
|
|
for (int i = 0; i < Pages.Count; i++)
|
|
|
|
|
Pages[i].IsTabSplitterVisible = (activePageIdx != i && activePageIdx != i + 1);
|
|
|
|
|
}
|
|
|
|
|
|
2024-02-05 23:08:37 -08:00
|
|
|
|
private LauncherPage _activePage = null;
|
|
|
|
|
}
|
2024-03-31 01:54:29 -07:00
|
|
|
|
}
|