Skip to content
Merged
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
18 changes: 18 additions & 0 deletions src/Commands/LFS.cs
Original file line number Diff line number Diff line change
Expand Up @@ -93,5 +93,23 @@ public async Task<bool> UnlockAsync(string remote, string file, bool force)
Args = builder.ToString();
return await ExecAsync().ConfigureAwait(false);
}

public async Task<bool> UnlockAsync(string remote, List<string> files, bool force)
{
var builder = new StringBuilder();
builder
.Append("lfs unlock --remote=")
.Append(remote)
.Append(force ? " -f " : " ");

foreach (string file in files)
{
builder.Append(file.Quoted());
builder.Append(" ");
}

Args = builder.ToString();
return await ExecAsync().ConfigureAwait(false);
}
}
}
2 changes: 2 additions & 0 deletions src/Resources/Locales/en_US.axaml
Original file line number Diff line number Diff line change
Expand Up @@ -441,6 +441,8 @@
<x:String x:Key="Text.GitLFS.Locks.Empty" xml:space="preserve">No Locked Files</x:String>
<x:String x:Key="Text.GitLFS.Locks.Lock" xml:space="preserve">Lock</x:String>
<x:String x:Key="Text.GitLFS.Locks.OnlyMine" xml:space="preserve">Show only my locks</x:String>
<x:String x:Key="Text.GitLFS.Locks.UnlockAll.Confirm" xml:space="preserve">Are you sure you want to unlock all your locked files?</x:String>
<x:String x:Key="Text.GitLFS.Locks.UnlockAllMyLocks" xml:space="preserve">Unlock all of my locks</x:String>
<x:String x:Key="Text.GitLFS.Locks.Title" xml:space="preserve">LFS Locks</x:String>
<x:String x:Key="Text.GitLFS.Locks.Unlock" xml:space="preserve">Unlock</x:String>
<x:String x:Key="Text.GitLFS.Locks.UnlockForce" xml:space="preserve">Force Unlock</x:String>
Expand Down
27 changes: 27 additions & 0 deletions src/ViewModels/LFSLocks.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
using System.Threading.Tasks;
using Avalonia.Threading;
using CommunityToolkit.Mvvm.ComponentModel;
using SourceGit.Models;

namespace SourceGit.ViewModels
{
Expand Down Expand Up @@ -72,6 +73,32 @@ public async Task UnlockAsync(Models.LFSLock lfsLock, bool force)
IsLoading = false;
}

public async Task UnlockAllMyLocksAsync(bool force = false)
{
if (_isLoading)
return;

IsLoading = true;

List<string> myLocks = [];
foreach (LFSLock lfsLock in _cachedLocks)
{
if (lfsLock.Owner.Name.Equals(_userName, StringComparison.Ordinal))
{
myLocks.Add(lfsLock.Path);
}
}

bool succ = await _repo.UnlockLFSFilesAsync(_remote, myLocks, force, false);
if (succ)
{
_cachedLocks.RemoveAll(lfsLock => lfsLock.Owner.Name.Equals(_userName, StringComparison.Ordinal));
UpdateVisibleLocks();
}

IsLoading = false;
}

private void UpdateVisibleLocks()
{
var visible = new List<Models.LFSLock>();
Expand Down
14 changes: 14 additions & 0 deletions src/ViewModels/Repository.cs
Original file line number Diff line number Diff line change
Expand Up @@ -738,6 +738,20 @@ public async Task<bool> UnlockLFSFileAsync(string remote, string path, bool forc
return succ;
}

public async Task<bool> UnlockLFSFilesAsync(string remote, List<string> paths, bool force, bool notify)
{
CommandLog log = CreateLog("Unlock LFS File");
bool succ = await new Commands.LFS(FullPath)
.Use(log)
.UnlockAsync(remote, paths, force);

if (succ && notify)
App.SendNotification(FullPath, $"Unlocked {paths.Count} files successfully!");

log.Complete();
return succ;
}

public CommandLog CreateLog(string name)
{
var log = new CommandLog(name);
Expand Down
40 changes: 28 additions & 12 deletions src/Views/LFSLocks.axaml
Original file line number Diff line number Diff line change
Expand Up @@ -38,18 +38,34 @@
</Grid>

<!-- Filter and Unlock All -->
<CheckBox Grid.Row="1"
Margin="8,0,0,0"
Content="{DynamicResource Text.GitLFS.Locks.OnlyMine}"
IsChecked="{Binding ShowOnlyMyLocks, Mode=TwoWay}"
VerticalAlignment="Center">
<CheckBox.IsEnabled>
<MultiBinding Converter="{x:Static BoolConverters.And}">
<Binding Path="HasValidUserName"/>
<Binding Path="!IsLoading"/>
</MultiBinding>
</CheckBox.IsEnabled>
</CheckBox>
<StackPanel Grid.Row="1"
HorizontalAlignment="Left"
Orientation="Horizontal">

<CheckBox Margin="8,0,4,0"
Content="{DynamicResource Text.GitLFS.Locks.OnlyMine}"
IsChecked="{Binding ShowOnlyMyLocks, Mode=TwoWay}"
VerticalAlignment="Center">
<CheckBox.IsEnabled>
<MultiBinding Converter="{x:Static BoolConverters.And}">
<Binding Path="HasValidUserName" />
<Binding Path="!IsLoading" />
</MultiBinding>
</CheckBox.IsEnabled>
</CheckBox>

<Button Margin="4,0,4,0"
Content="{DynamicResource Text.GitLFS.Locks.UnlockAllMyLocks}"
Click="OnUnlockAllMyLocksButtonClicked">
<Button.IsEnabled>
<MultiBinding Converter="{x:Static BoolConverters.And}">
<Binding Path="HasValidUserName" />
<Binding Path="!IsLoading" />
</MultiBinding>
</Button.IsEnabled>
</Button>

</StackPanel>

<!-- Locked Files -->
<Grid Grid.Row="2">
Expand Down
22 changes: 22 additions & 0 deletions src/Views/LFSLocks.axaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -26,5 +26,27 @@ private async void OnForceUnlockButtonClicked(object sender, RoutedEventArgs e)

e.Handled = true;
}

private async void OnUnlockAllMyLocksButtonClicked(object sender, RoutedEventArgs e)
{
if (DataContext is ViewModels.LFSLocks vm)
{
Confirm dialog = new()
{
Message =
{
Text = App.Text("GitLFS.Locks.UnlockAll.Confirm")
}
};

bool result = await dialog.ShowDialog<bool>(this);
if (result)
{
await vm.UnlockAllMyLocksAsync(true);
}
}

e.Handled = true;
}
}
}
Loading