Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 28 additions & 0 deletions src/Commands/InitGit.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
using System.Text;

namespace SourceGit.Commands
{
public class InitGit : Command
{
public InitGit(string ctx, string path, string localName, string branchName, bool bareRepo)
{
Context = ctx;
WorkingDirectory = path;

var builder = new StringBuilder(1024);
builder.Append("init ");

if (bareRepo)
builder.Append("--bare ");
else
{
if (!string.IsNullOrEmpty(branchName))
builder.Append("-b " + branchName + " ");
}

builder.Append(localName.Quoted());

Args = builder.ToString();
}
}
}
10 changes: 10 additions & 0 deletions src/Resources/Locales/en_US.axaml
Original file line number Diff line number Diff line change
Expand Up @@ -540,6 +540,15 @@
<x:String x:Key="Text.Init.CommandTip" xml:space="preserve">Do you want to run `git init` command under this path?</x:String>
<x:String x:Key="Text.Init.ErrorMessageTip" xml:space="preserve">Open repository failed. Reason: </x:String>
<x:String x:Key="Text.Init.Path" xml:space="preserve">Path:</x:String>
<x:String x:Key="Text.InitGit" xml:space="preserve">Initialize Git Repository</x:String>
<x:String x:Key="Text.InitGit.BareRepo" xml:space="preserve">Create Bare Repository</x:String>
<x:String x:Key="Text.InitGit.Bookmark" xml:space="preserve">Bookmark:</x:String>
<x:String x:Key="Text.InitGit.Group" xml:space="preserve">Group:</x:String>
<x:String x:Key="Text.InitGit.InitialBranch" xml:space="preserve">Initial Branch Name</x:String>
<x:String x:Key="Text.InitGit.InitialBranch.Placeholder" xml:space="preserve">main</x:String>
<x:String x:Key="Text.InitGit.ParentFolder" xml:space="preserve">Parent Folder</x:String>
<x:String x:Key="Text.InitGit.ProjectName" xml:space="preserve">Project Name</x:String>
<x:String x:Key="Text.InitGit.ProjectName.Placeholder" xml:space="preserve">new_git_project</x:String>
<x:String x:Key="Text.InProgress.CherryPick" xml:space="preserve">Cherry-Pick in progress.</x:String>
<x:String x:Key="Text.InProgress.CherryPick.Head" xml:space="preserve">Processing commit</x:String>
<x:String x:Key="Text.InProgress.Merge" xml:space="preserve">Merge in progress.</x:String>
Expand Down Expand Up @@ -945,6 +954,7 @@
<x:String x:Key="Text.Welcome.Delete" xml:space="preserve">Delete</x:String>
<x:String x:Key="Text.Welcome.DragDropTip" xml:space="preserve">DRAG &amp; DROP FOLDER SUPPORTED. CUSTOM GROUPING SUPPORTED.</x:String>
<x:String x:Key="Text.Welcome.Edit" xml:space="preserve">Edit</x:String>
<x:String x:Key="Text.Welcome.InitGit" xml:space="preserve">Initialize Git Repository</x:String>
<x:String x:Key="Text.Welcome.Move" xml:space="preserve">Move to Another Group</x:String>
<x:String x:Key="Text.Welcome.OpenAllInNode" xml:space="preserve">Open All Repositories</x:String>
<x:String x:Key="Text.Welcome.OpenOrInit" xml:space="preserve">Open Repository</x:String>
Expand Down
157 changes: 157 additions & 0 deletions src/ViewModels/InitGit.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,157 @@
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.IO;
using System.Threading.Tasks;
using System.Globalization;

namespace SourceGit.ViewModels
{
public class InitGit : Popup
{
[Required(ErrorMessage = "Parent folder is required")]
[CustomValidation(typeof(InitGit), nameof(ValidateParentFolder))]
public string ParentFolder
{
get => _parentFolder;
set => SetProperty(ref _parentFolder, value, true);
}

public string ProjectName
{
get => null;
set => SetProperty(ref _projectName, value);
}

public List<RepositoryNode> Groups
{
get;
}

public RepositoryNode SelectedGroup
{
get => _selectedGroup;
set => SetProperty(ref _selectedGroup, value);
}

public List<int> Bookmarks
{
get;
}

public int Bookmark
{
get => _bookmark;
set => SetProperty(ref _bookmark, value);
}

public string InitialBranch
{
get => null;
set => SetProperty(ref _initialBranch, value);
}

public bool BareRepo
{
get;
set;
} = false;

public InitGit(string pageId)
{
_pageId = pageId;

Groups = new List<RepositoryNode>();
Groups.Add(new RepositoryNode { Name = "No Group (Uncategorized)", Id = string.Empty });
SelectedGroup = Groups[0];
CollectGroups(Groups, Preferences.Instance.RepositoryNodes);

Bookmarks = new List<int>();
for (var i = 0; i < Models.Bookmarks.Brushes.Length; i++)
Bookmarks.Add(i);

var activeWorkspace = Preferences.Instance.GetActiveWorkspace();
_parentFolder = activeWorkspace?.DefaultCloneDir;
if (string.IsNullOrEmpty(ParentFolder))
_parentFolder = Preferences.Instance.GitDefaultCloneDir;
}

public static ValidationResult ValidateParentFolder(string folder, ValidationContext _)
{
if (!Directory.Exists(folder))
return new ValidationResult("Given path can NOT be found");
return ValidationResult.Success;
}

public override async Task<bool> Sure()
{
ProgressDescription = "Init ...";

var log = new CommandLog("Init");
Use(log);

var succ = await new Commands.InitGit(_pageId, _parentFolder, _projectName, _initialBranch, BareRepo)
.Use(log)
.ExecAsync();
if (!succ)
return false;

var path = _parentFolder;
if (!string.IsNullOrEmpty(_projectName))
{
path = Path.GetFullPath(Path.Combine(path, _projectName));
}
else
{
path = Path.GetFullPath(Path.Combine(path, "new_git_project"));
}

if (!Directory.Exists(path))
{
Models.Notification.Send(_pageId, $"Folder '{path}' can NOT be found", true);
return false;
}

log.Complete();

var parent = _selectedGroup is { Id: not "" } ? _selectedGroup : null;
var node = Preferences.Instance.FindOrAddNodeByRepositoryPath(path, parent, true);
node.Bookmark = _bookmark;
await node.UpdateStatusAsync(false, null);

var launcher = App.GetLauncher();
LauncherPage page = null;
foreach (var one in launcher.Pages)
{
if (one.Node.Id == _pageId)
{
page = one;
break;
}
}

Welcome.Instance.Refresh();
launcher.OpenRepositoryInTab(node, page);
return true;
}

private void CollectGroups(List<RepositoryNode> outs, List<RepositoryNode> collections)
{
foreach (var node in collections)
{
if (!node.IsRepository)
{
outs.Add(node);
CollectGroups(outs, node.SubNodes);
}
}
}

private string _pageId = string.Empty;
private string _parentFolder = string.Empty;
private string _projectName = App.Text("InitGit.ProjectName.Placeholder");
private string _initialBranch = App.Text("InitGit.InitialBranch.Placeholder");
private RepositoryNode _selectedGroup = null;
private int _bookmark = 0;
}
}
13 changes: 13 additions & 0 deletions src/ViewModels/Welcome.cs
Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,19 @@ public void OpenTerminal()
Native.OS.OpenTerminal(null);
}

public void InitGit()
{
if (!Preferences.Instance.IsGitConfigured())
{
Models.Notification.Send(null, App.Text("NotConfigured"), true);
return;
}

var activePage = App.GetLauncher().ActivePage;
if (activePage != null && activePage.CanCreatePopup())
activePage.Popup = new InitGit(activePage.Node.Id);
}

public void ScanDefaultCloneDir()
{
if (!Preferences.Instance.IsGitConfigured())
Expand Down
103 changes: 103 additions & 0 deletions src/Views/InitGit.axaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
<UserControl xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:vm="using:SourceGit.ViewModels"
xmlns:v="using:SourceGit.Views"
xmlns:c="using:SourceGit.Converters"
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
x:Class="SourceGit.Views.InitGit"
x:DataType="vm:InitGit">
<StackPanel Orientation="Vertical" Margin="8,0,0,0">
<StackPanel Orientation="Horizontal">
<Path Width="16" Height="16"
Margin="0,4,0,0"
Data="{StaticResource Icons.Clone}"/>

<TextBlock FontSize="18"
Margin="8,0,0,0"
Classes="bold"
Text="{DynamicResource Text.InitGit}"/>
</StackPanel>

<Grid Margin="8,16,0,0" RowDefinitions="32,Auto,32,32,32,32" ColumnDefinitions="Auto,*">
<TextBlock Grid.Row="0" Grid.Column="0"
HorizontalAlignment="Right"
Margin="0,0,8,0"
Text="{DynamicResource Text.InitGit.ParentFolder}"/>
<TextBox Grid.Row="0" Grid.Column="1"
x:Name="TxtParentFolder"
Height="28"
CornerRadius="3"
Text="{Binding ParentFolder, Mode=TwoWay}">
<TextBox.InnerRightContent>
<Button Classes="icon_button" Width="28" Height="28" Margin="4,0,0,0" Click="SelectParentFolder">
<Path Data="{StaticResource Icons.Folder.Open}" Fill="{DynamicResource Brush.FG1}"/>
</Button>
</TextBox.InnerRightContent>
</TextBox>

<TextBlock Grid.Row="1" Grid.Column="0"
HorizontalAlignment="Right"
Margin="0,0,8,0"
Text="{DynamicResource Text.InitGit.ProjectName}"/>
<TextBox Grid.Row="1" Grid.Column="1"
Height="28"
CornerRadius="3"
Watermark="{DynamicResource Text.InitGit.ProjectName.Placeholder}"
Text="{Binding ProjectName, Mode=TwoWay}"/>

<TextBlock Grid.Row="2" Grid.Column="0"
HorizontalAlignment="Right"
Margin="0,0,8,0"
Text="{DynamicResource Text.InitGit.InitialBranch}"/>
<TextBox Grid.Row="2" Grid.Column="1"
Height="28"
CornerRadius="3"
Watermark="{DynamicResource Text.InitGit.InitialBranch.Placeholder}"
Text="{Binding InitialBranch, Mode=TwoWay}"/>

<TextBlock Grid.Row="3" Grid.Column="0"
HorizontalAlignment="Right"
Margin="0,0,8,0"
Text="{DynamicResource Text.InitGit.Group}"/>
<ComboBox Grid.Row="3" Grid.Column="1"
Height="28" Padding="8,0"
VerticalAlignment="Center" HorizontalAlignment="Stretch"
ItemsSource="{Binding Groups}"
SelectedItem="{Binding SelectedGroup, Mode=TwoWay}">
<ComboBox.ItemTemplate>
<DataTemplate DataType="vm:RepositoryNode">
<TextBlock Text="{Binding Name, Mode=OneWay}"/>
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>

<TextBlock Grid.Row="4" Grid.Column="0"
HorizontalAlignment="Right"
Margin="0,0,8,0"
Text="{DynamicResource Text.InitGit.Bookmark}"/>
<ComboBox Grid.Row="4" Grid.Column="1"
Height="28" Padding="8,0"
VerticalAlignment="Center"
ItemsSource="{Binding Bookmarks}"
SelectedItem="{Binding Bookmark, Mode=TwoWay}">
<ComboBox.ItemTemplate>
<DataTemplate>
<Grid Height="20">
<Path Width="12" Height="12"
Fill="{Binding Converter={x:Static c:IntConverters.ToBookmarkBrush}}"
HorizontalAlignment="Center" VerticalAlignment="Center"
Data="{StaticResource Icons.Bookmark}"/>
</Grid>
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>

<CheckBox Grid.Row="5" Grid.Column="1"
Content="{DynamicResource Text.InitGit.BareRepo}"
IsChecked="{Binding BareRepo, Mode=TwoWay}"
ToolTip.Tip="--bare"/>
</Grid>
</StackPanel>
</UserControl>
46 changes: 46 additions & 0 deletions src/Views/InitGit.axaml.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
using System;
using Avalonia.Controls;
using Avalonia.Input.Platform;
using Avalonia.Interactivity;
using Avalonia.Platform.Storage;

namespace SourceGit.Views
{
public partial class InitGit : UserControl
{
public InitGit()
{
InitializeComponent();
}

protected override async void OnLoaded(RoutedEventArgs e)
{
base.OnLoaded(e);
}

private async void SelectParentFolder(object _, RoutedEventArgs e)
{
var options = new FolderPickerOpenOptions() { AllowMultiple = false };
var toplevel = TopLevel.GetTopLevel(this);
if (toplevel == null)
return;

try
{
var selected = await toplevel.StorageProvider.OpenFolderPickerAsync(options);
if (selected.Count == 1)
{
var folder = selected[0];
var folderPath = folder is { Path: { IsAbsoluteUri: true } path } ? path.LocalPath : folder?.Path.ToString();
TxtParentFolder.Text = folderPath;
}
}
catch (Exception exception)
{
Models.Notification.Send(null, $"Failed to select parent folder: {exception.Message}", true);
}

e.Handled = true;
}
}
}
4 changes: 4 additions & 0 deletions src/Views/WelcomeToolbar.axaml
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,10 @@
<Button Classes="icon_button" Width="32" Command="{Binding OpenTerminal}" ToolTip.Tip="{DynamicResource Text.Welcome.OpenTerminal}">
<Path Width="13" Height="13" Data="{StaticResource Icons.Terminal}"/>
</Button>

<Button Classes="icon_button" Width="32" Command="{Binding InitGit}" ToolTip.Tip="{DynamicResource Text.Welcome.InitGit}">
<Path Width="13" Height="13" Data="{StaticResource Icons.OpenWith}" Margin="0,2,0,0"/>
</Button>
</StackPanel>

<StackPanel Grid.Column="2" Orientation="Horizontal">
Expand Down