Skip to content

Commit 7b463ec

Browse files
Feature: Added support for pushing Git commits (#12633)
1 parent fd002b5 commit 7b463ec

20 files changed

+727
-72
lines changed

builds/azure-pipelines-preview.yml

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,17 @@ jobs:
6868
}
6969
failOnStderr: true
7070

71+
# Injects the GitHub token to the project
72+
- task: PowerShell@2
73+
displayName: 'Inject AppCenter token'
74+
inputs:
75+
targetType: 'inline'
76+
script: |
77+
gci $(Build.SourcesDirectory)\src -Include *.cs -recurse | ForEach -Process {
78+
(Get-Content $_ -Raw | ForEach -Process {$_ -replace "githubclientid.secret", "$(githubclientid.secret)"}) | Set-Content $_ -NoNewline
79+
}
80+
failOnStderr: true
81+
7182
- task: UseDotNet@2
7283
inputs:
7384
packageType: sdk

builds/azure-pipelines-release.yml

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,17 @@ jobs:
100100
}
101101
failOnStderr: true
102102

103+
# Injects the GitHub token to the project
104+
- task: PowerShell@2
105+
displayName: 'Inject AppCenter token'
106+
inputs:
107+
targetType: 'inline'
108+
script: |
109+
gci $(Build.SourcesDirectory)\src -Include *.cs -recurse | ForEach -Process {
110+
(Get-Content $_ -Raw | ForEach -Process {$_ -replace "githubclientid.secret", "$(githubclientid.secret)"}) | Set-Content $_ -NoNewline
111+
}
112+
failOnStderr: true
113+
103114
- task: UseDotNet@2
104115
inputs:
105116
packageType: sdk
@@ -215,6 +226,17 @@ jobs:
215226
}
216227
failOnStderr: true
217228

229+
# Injects the GitHub token to the project
230+
- task: PowerShell@2
231+
displayName: 'Inject AppCenter token'
232+
inputs:
233+
targetType: 'inline'
234+
script: |
235+
gci $(Build.SourcesDirectory)\src -Include *.cs -recurse | ForEach -Process {
236+
(Get-Content $_ -Raw | ForEach -Process {$_ -replace "githubclientid.secret", "$(githubclientid.secret)"}) | Set-Content $_ -NoNewline
237+
}
238+
failOnStderr: true
239+
218240
- task: UseDotNet@2
219241
inputs:
220242
packageType: sdk

src/Files.App/Actions/Git/GitPullAction.cs

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,9 +25,7 @@ public GitPullAction()
2525

2626
public Task ExecuteAsync()
2727
{
28-
GitHelpers.PullOrigin(_context.ShellPage!.InstanceViewModel.GitRepositoryPath);
29-
30-
return Task.CompletedTask;
28+
return GitHelpers.PullOrigin(_context.ShellPage!.InstanceViewModel.GitRepositoryPath);
3129
}
3230

3331
private void Context_PropertyChanged(object? sender, PropertyChangedEventArgs e)
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
using Files.App.Commands;
2+
using Files.App.Contexts;
3+
4+
namespace Files.App.Actions
5+
{
6+
internal class GitPushAction : ObservableObject, IAction
7+
{
8+
private readonly IContentPageContext _context;
9+
10+
public string Label { get; } = "Push".GetLocalizedResource();
11+
12+
public string Description { get; } = "GitPushDescription".GetLocalizedResource();
13+
14+
public RichGlyph Glyph { get; } = new("\uE74A");
15+
16+
public bool IsExecutable =>
17+
_context.CanExecuteGitAction;
18+
19+
public GitPushAction()
20+
{
21+
_context = Ioc.Default.GetRequiredService<IContentPageContext>();
22+
23+
_context.PropertyChanged += Context_PropertyChanged;
24+
}
25+
26+
public Task ExecuteAsync()
27+
{
28+
return GitHelpers.PushToOrigin(
29+
_context.ShellPage?.InstanceViewModel.GitRepositoryPath,
30+
_context.ShellPage?.InstanceViewModel.GitBranchName);
31+
}
32+
33+
private void Context_PropertyChanged(object? sender, PropertyChangedEventArgs e)
34+
{
35+
if (e.PropertyName is nameof(IContentPageContext.CanExecuteGitAction))
36+
OnPropertyChanged(nameof(IsExecutable));
37+
}
38+
}
39+
}
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
using Files.App.Commands;
2+
using Files.App.Contexts;
3+
4+
namespace Files.App.Actions
5+
{
6+
internal class GitSyncAction : ObservableObject, IAction
7+
{
8+
private readonly IContentPageContext _context;
9+
10+
public string Label { get; } = "GitSync".GetLocalizedResource();
11+
12+
public string Description { get; } = "GitSyncDescription".GetLocalizedResource();
13+
14+
public RichGlyph Glyph { get; } = new("\uEDAB");
15+
16+
public bool IsExecutable =>
17+
_context.CanExecuteGitAction;
18+
19+
public GitSyncAction()
20+
{
21+
_context = Ioc.Default.GetRequiredService<IContentPageContext>();
22+
23+
_context.PropertyChanged += Context_PropertyChanged;
24+
}
25+
26+
public Task ExecuteAsync()
27+
{
28+
var instance = _context.ShellPage?.InstanceViewModel;
29+
30+
return GitHelpers.PullOrigin(instance?.GitRepositoryPath)
31+
.ContinueWith(t => GitHelpers.PushToOrigin(
32+
instance?.GitRepositoryPath,
33+
instance?.GitBranchName));
34+
}
35+
36+
private void Context_PropertyChanged(object? sender, PropertyChangedEventArgs e)
37+
{
38+
if (e.PropertyName is nameof(IContentPageContext.CanExecuteGitAction))
39+
OnPropertyChanged(nameof(IsExecutable));
40+
}
41+
}
42+
}

src/Files.App/Commands/CommandCodes.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -183,5 +183,7 @@ public enum CommandCodes
183183
// Git
184184
GitFetch,
185185
GitPull,
186+
GitPush,
187+
GitSync,
186188
}
187189
}

src/Files.App/Commands/Manager/CommandManager.cs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -159,6 +159,8 @@ public IRichCommand this[HotKey hotKey]
159159
public IRichCommand PlayAll => commands[CommandCodes.PlayAll];
160160
public IRichCommand GitFetch => commands[CommandCodes.GitFetch];
161161
public IRichCommand GitPull => commands[CommandCodes.GitPull];
162+
public IRichCommand GitPush => commands[CommandCodes.GitPush];
163+
public IRichCommand GitSync => commands[CommandCodes.GitSync];
162164

163165
public CommandManager()
164166
{
@@ -312,6 +314,8 @@ public CommandManager()
312314
[CommandCodes.PlayAll] = new PlayAllAction(),
313315
[CommandCodes.GitFetch] = new GitFetchAction(),
314316
[CommandCodes.GitPull] = new GitPullAction(),
317+
[CommandCodes.GitPush] = new GitPushAction(),
318+
[CommandCodes.GitSync] = new GitSyncAction(),
315319
};
316320

317321
private void UpdateHotKeys()

src/Files.App/Commands/Manager/ICommandManager.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -162,5 +162,7 @@ public interface ICommandManager : IEnumerable<IRichCommand>
162162

163163
IRichCommand GitFetch { get; }
164164
IRichCommand GitPull { get; }
165+
IRichCommand GitPush { get; }
166+
IRichCommand GitSync { get; }
165167
}
166168
}

src/Files.App/Data/Models/DirectoryPropertiesViewModel.cs

Lines changed: 16 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -62,11 +62,18 @@ public bool ShowLocals
6262
}
6363
}
6464

65-
private string _PullInfo = "0";
66-
public string PullInfo
65+
private string _StatusInfo = "0 / 0";
66+
public string StatusInfo
6767
{
68-
get => _PullInfo;
69-
set => SetProperty(ref _PullInfo, value);
68+
get => _StatusInfo;
69+
set => SetProperty(ref _StatusInfo, value);
70+
}
71+
72+
private string _ExtendedStatusInfo = string.Format("CommitsNumber".GetLocalizedResource(), 0);
73+
public string ExtendedStatusInfo
74+
{
75+
get => _ExtendedStatusInfo;
76+
set => SetProperty(ref _ExtendedStatusInfo, value);
7077
}
7178

7279
public ObservableCollection<string> BranchesNames => _ShowLocals
@@ -92,9 +99,11 @@ public void UpdateGitInfo(bool isGitRepository, string? repositoryPath, BranchIt
9299
_gitRepositoryPath = repositoryPath;
93100
ShowLocals = true;
94101

95-
PullInfo = branches.Any()
96-
? branches[0].BehindBy.ToString() ?? "0"
97-
: "0";
102+
var behind = branches.Any() ? branches[0].BehindBy ?? 0 : 0;
103+
var ahead = branches.Any() ? branches[0].AheadBy ?? 0 : 0;
104+
105+
ExtendedStatusInfo = string.Format("GitSyncStatusExtendedInfo".GetLocalizedResource(), ahead, behind);
106+
StatusInfo = $"{ahead} / {behind}";
98107

99108
if (isGitRepository)
100109
{
Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
<!-- Copyright (c) 2023 Files Community. Licensed under the MIT License. See the LICENSE. -->
2+
<ContentDialog
3+
x:Class="Files.App.Dialogs.GitHubLoginDialog"
4+
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
5+
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
6+
xmlns:converters="using:CommunityToolkit.WinUI.UI.Converters"
7+
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
8+
xmlns:helpers="using:Files.App.Helpers"
9+
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
10+
Title="{helpers:ResourceString Name=ConnectGitHub}"
11+
CloseButtonCommand="{x:Bind ViewModel.CloseButtonCommand}"
12+
CloseButtonStyle="{StaticResource AccentButtonStyle}"
13+
CloseButtonText="{helpers:ResourceString Name=Close}"
14+
CornerRadius="{StaticResource OverlayCornerRadius}"
15+
PrimaryButtonClick="ContentDialog_PrimaryButtonClick"
16+
PrimaryButtonText="{helpers:ResourceString Name=OK}"
17+
RequestedTheme="{x:Bind helpers:ThemeHelper.RootTheme}"
18+
Style="{StaticResource DefaultContentDialogStyle}"
19+
mc:Ignorable="d">
20+
21+
<ContentDialog.PrimaryButtonStyle>
22+
<Style BasedOn="{StaticResource DefaultButtonStyle}" TargetType="Button">
23+
<Setter Property="ContentTemplate">
24+
<Setter.Value>
25+
<DataTemplate>
26+
<StackPanel
27+
HorizontalAlignment="Center"
28+
Orientation="Horizontal"
29+
Spacing="8">
30+
<FontIcon FontSize="14" Glyph="&#xE8C8;" />
31+
<TextBlock Text="{helpers:ResourceString Name=CopyCode}" />
32+
</StackPanel>
33+
</DataTemplate>
34+
</Setter.Value>
35+
</Setter>
36+
</Style>
37+
</ContentDialog.PrimaryButtonStyle>
38+
39+
<ContentDialog.Resources>
40+
<ResourceDictionary>
41+
<converters:BoolNegationConverter x:Key="BoolNegationConverter" />
42+
</ResourceDictionary>
43+
</ContentDialog.Resources>
44+
45+
<Grid RowSpacing="20">
46+
<Grid.RowDefinitions>
47+
<RowDefinition Height="Auto" />
48+
<RowDefinition />
49+
</Grid.RowDefinitions>
50+
51+
<StackPanel Width="360" Height="40">
52+
<!-- Subtitle -->
53+
<TextBlock
54+
x:Name="Subtitle"
55+
Grid.Row="0"
56+
HorizontalAlignment="Left"
57+
VerticalAlignment="Center"
58+
Text="{x:Bind ViewModel.Subtitle, Mode=OneWay}"
59+
TextWrapping="WrapWholeWords" />
60+
</StackPanel>
61+
62+
<StackPanel
63+
x:Name="UserCodeContainer"
64+
Grid.Row="1"
65+
HorizontalAlignment="Stretch"
66+
VerticalAlignment="Stretch"
67+
x:Load="{x:Bind ViewModel.LoginConfirmed, Converter={StaticResource BoolNegationConverter}, Mode=OneWay}">
68+
<HyperlinkButton
69+
x:Name="LoginUrl"
70+
Content="{x:Bind ViewModel.LoginUrl}"
71+
NavigateUri="{x:Bind ViewModel.NavigateUri}" />
72+
<TextBlock
73+
Margin="12,8"
74+
CharacterSpacing="150"
75+
FontFamily="Cascadia Mono,Consolas,Segoe UI Variable"
76+
FontSize="32"
77+
FontWeight="Normal"
78+
Text="{x:Bind ViewModel.UserCode}" />
79+
</StackPanel>
80+
<Border
81+
x:Name="LoginSuccessBadge"
82+
Grid.Row="1"
83+
Width="70"
84+
Height="70"
85+
Margin="8"
86+
x:Load="{x:Bind ViewModel.LoginConfirmed, Mode=OneWay}"
87+
Background="#6ccb5f"
88+
CornerRadius="35">
89+
<SymbolIcon
90+
Width="52"
91+
Height="52"
92+
Symbol="Accept" />
93+
</Border>
94+
</Grid>
95+
</ContentDialog>
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
// Copyright (c) 2023 Files Community
2+
// Licensed under the MIT License. See the LICENSE.
3+
4+
using Microsoft.UI.Xaml.Controls;
5+
using Windows.ApplicationModel.DataTransfer;
6+
7+
namespace Files.App.Dialogs
8+
{
9+
public sealed partial class GitHubLoginDialog : ContentDialog, IDialog<GitHubLoginDialogViewModel>
10+
{
11+
public GitHubLoginDialogViewModel ViewModel
12+
{
13+
get => (GitHubLoginDialogViewModel)DataContext;
14+
set
15+
{
16+
if (ViewModel is not null)
17+
ViewModel.PropertyChanged -= ViewModel_PropertyChanged;
18+
19+
DataContext = value;
20+
if (value is not null)
21+
value.PropertyChanged += ViewModel_PropertyChanged;
22+
}
23+
}
24+
25+
public GitHubLoginDialog()
26+
{
27+
InitializeComponent();
28+
}
29+
30+
public new async Task<DialogResult> ShowAsync() => (DialogResult)await base.ShowAsync();
31+
32+
private void ContentDialog_PrimaryButtonClick(ContentDialog sender, ContentDialogButtonClickEventArgs args)
33+
{
34+
args.Cancel = true;
35+
36+
var data = new DataPackage();
37+
data.SetText(ViewModel.UserCode);
38+
39+
Clipboard.SetContent(data);
40+
Clipboard.Flush();
41+
}
42+
43+
private void ViewModel_PropertyChanged(object? sender, PropertyChangedEventArgs e)
44+
{
45+
if (e.PropertyName == nameof(GitHubLoginDialogViewModel.LoginConfirmed) && ViewModel.LoginConfirmed)
46+
PrimaryButtonText = null;
47+
}
48+
}
49+
}

0 commit comments

Comments
 (0)