diff --git a/.idea/.idea.Flawless-Version-Control/.idea/MarsCodeWorkspaceAppSettings.xml b/.idea/.idea.Flawless-Version-Control/.idea/MarsCodeWorkspaceAppSettings.xml
new file mode 100644
index 0000000..05ed8ba
--- /dev/null
+++ b/.idea/.idea.Flawless-Version-Control/.idea/MarsCodeWorkspaceAppSettings.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/.idea.Flawless-Version-Control/.idea/avalonia.xml b/.idea/.idea.Flawless-Version-Control/.idea/avalonia.xml
index 293ee92..ba59aa9 100644
--- a/.idea/.idea.Flawless-Version-Control/.idea/avalonia.xml
+++ b/.idea/.idea.Flawless-Version-Control/.idea/avalonia.xml
@@ -12,6 +12,7 @@
+
@@ -19,9 +20,11 @@
+
+
diff --git a/Flawless.Client/Service/RepositoryService.cs b/Flawless.Client/Service/RepositoryService.cs
index a570fe9..61adb88 100644
--- a/Flawless.Client/Service/RepositoryService.cs
+++ b/Flawless.Client/Service/RepositoryService.cs
@@ -473,7 +473,7 @@ public class RepositoryService : BaseService
}
}
- public async ValueTask CloseIssueAsync(RepositoryModel repo, long issueId)
+ public async ValueTask CloseIssueAsync(RepositoryModel repo, ulong issueId)
{
var api = Api.C;
try
@@ -484,7 +484,7 @@ public class RepositoryService : BaseService
return false;
}
- await api.Gateway.Close(repo.OwnerName, repo.Name, issueId);
+ await api.Gateway.Close(repo.OwnerName, repo.Name, (long) issueId);
return true;
}
catch (Exception e)
@@ -495,7 +495,7 @@ public class RepositoryService : BaseService
}
}
- public async ValueTask ReopenIssueAsync(RepositoryModel repo, long issueId)
+ public async ValueTask ReopenIssueAsync(RepositoryModel repo, ulong issueId)
{
var api = Api.C;
try
@@ -506,7 +506,7 @@ public class RepositoryService : BaseService
return false;
}
- await api.Gateway.Reopen(repo.OwnerName, repo.Name, issueId);
+ await api.Gateway.Reopen(repo.OwnerName, repo.Name, (long) issueId);
return true;
}
catch (Exception e)
diff --git a/Flawless.Client/ViewModels/IssueDetailViewModel.cs b/Flawless.Client/ViewModels/IssueDetailViewModel.cs
new file mode 100644
index 0000000..d4bfac6
--- /dev/null
+++ b/Flawless.Client/ViewModels/IssueDetailViewModel.cs
@@ -0,0 +1,91 @@
+using System.Linq;
+using System.Reactive.Threading.Tasks;
+using System.Threading.Tasks;
+using Flawless.Client;
+using Flawless.Client.Models;
+using ReactiveUI;
+using Flawless.Client.Service;
+using Flawless.Client.ViewModels;
+using ReactiveUI.SourceGenerators;
+
+public partial class IssueDetailViewModel : RoutableViewModelBase
+{
+ [Reactive] private RepositoryModel.Issue? _currentIssue;
+
+ [Reactive] private string _newComment;
+
+ [Reactive] private RepositoryModel.Comment? _replyTo;
+
+ private readonly RepositoryService _service;
+
+ private readonly RepositoryModel _repo;
+
+ public IssueDetailViewModel(IScreen screen, RepositoryModel repo, ulong issueId) : base(screen)
+ {
+ _repo = repo;
+ _service = RepositoryService.Current;
+ LoadDataAsync(repo, issueId);
+ }
+
+ private async Task LoadDataAsync(RepositoryModel repo, ulong issueId)
+ {
+ using var _ = UIHelper.MakeLoading("Fetching comments from server...");
+ if (!await _service.UpdateIssueDetailsFromServerAsync(repo, issueId))
+ {
+ await NavigateBackAsync();
+ UIHelper.NotifyError("Operation failed", "Can not open issue...");
+ return;
+ }
+
+ CurrentIssue = repo.Issues.First(x => x.Id == issueId);
+ }
+
+ [ReactiveCommand]
+ private Task RefreshIssueAsync() => LoadDataAsync(_repo, CurrentIssue!.Id);
+
+ [ReactiveCommand]
+ private async Task ToggleIssueStatusAsync()
+ {
+ if (CurrentIssue == null) return;
+
+ using var _ = UIHelper.MakeLoading("Update issue...");
+ if (CurrentIssue.Closed)
+ {
+ if (!await _service.ReopenIssueAsync(_repo, CurrentIssue.Id)) return;
+
+ }
+ else
+ {
+ if (!await _service.CloseIssueAsync(_repo, CurrentIssue.Id)) return;
+ }
+
+ CurrentIssue.Closed = !CurrentIssue.Closed;
+ }
+
+ [ReactiveCommand]
+ private async Task AddCommentAsync()
+ {
+ if (CurrentIssue == null) return;
+
+ using var _ = UIHelper.MakeLoading("Update issue...");
+ if (string.IsNullOrWhiteSpace(NewComment))
+ {
+ UIHelper.NotifyError("No input", "No comment has been written!");
+ }
+ else
+ {
+ if (!await _service.AddCommentAsync(_repo, CurrentIssue.Id, NewComment, _replyTo?.Id ?? null)) return;
+
+ _replyTo = null;
+ NewComment = string.Empty;
+ }
+ }
+
+ [ReactiveCommand]
+ private async Task EditIssueAsync()
+ {
+ }
+
+ [ReactiveCommand]
+ private Task NavigateBackAsync() => HostScreen.Router.NavigateBack.Execute().ToTask();
+}
\ No newline at end of file
diff --git a/Flawless.Client/ViewModels/ModalBox/IssueEditDialogViewModel.cs b/Flawless.Client/ViewModels/ModalBox/IssueEditDialogViewModel.cs
new file mode 100644
index 0000000..65ea355
--- /dev/null
+++ b/Flawless.Client/ViewModels/ModalBox/IssueEditDialogViewModel.cs
@@ -0,0 +1,29 @@
+using System.Collections.Generic;
+using System.Text;
+using Flawless.Client.Models;
+using ReactiveUI;
+using ReactiveUI.SourceGenerators;
+
+namespace Flawless.Client.ViewModels.ModalBox;
+
+public partial class IssueEditDialogViewModel : ReactiveObject
+{
+ [Reactive] public string Title { get; set; } = string.Empty;
+ [Reactive] public string Description { get; set; } = string.Empty;
+ [Reactive] public string? Tag { get; set; }
+
+ public bool IsEditMode { get; }
+
+ public List AvailableTags { get; } = new() { "bug", "feature", "question" };
+
+ public IssueEditDialogViewModel(RepositoryModel.Issue? existingIssue = null)
+ {
+ IsEditMode = existingIssue != null;
+ if (IsEditMode)
+ {
+ Title = existingIssue!.Title;
+ Description = existingIssue.Description ?? string.Empty;
+ Tag = new StringBuilder().AppendJoin(',', existingIssue.Tags).ToString();
+ }
+ }
+}
\ No newline at end of file
diff --git a/Flawless.Client/ViewModels/RepositoryViewModel.cs b/Flawless.Client/ViewModels/RepositoryViewModel.cs
index 4c31d8f..4b34584 100644
--- a/Flawless.Client/ViewModels/RepositoryViewModel.cs
+++ b/Flawless.Client/ViewModels/RepositoryViewModel.cs
@@ -400,8 +400,7 @@ public partial class RepositoryViewModel : RoutableViewModelBase
if (!await RepositoryService.C.UpdateCommitsHistoryFromServerAsync(Repository)) return;
var changes = new List();
CollectChanges(changes, LocalChangeSetRaw);
-
-
+
var result = await UIHelper.SimpleAskAsync(
"All files will being matched with this commit. Do you wish to execute it?",
DialogMode.Warning);
@@ -419,7 +418,30 @@ public partial class RepositoryViewModel : RoutableViewModelBase
SyncCommitsFromRepository();
}
}
+
+ [ReactiveCommand]
+ private async Task CreateIssueAsync()
+ {
+
+ }
+
+ [ReactiveCommand]
+ private async Task OpenIssueAsync()
+ {
+
+ }
+
+ [ReactiveCommand]
+ private async Task CloseIssueAsync()
+ {
+
+ }
+ [ReactiveCommand]
+ private async Task ReopenIssueAsync()
+ {
+
+ }
[ReactiveCommand]
private async Task PullLatestRepositoryAsync()
diff --git a/Flawless.Client/Views/IssueDetailView.axaml b/Flawless.Client/Views/IssueDetailView.axaml
new file mode 100644
index 0000000..0c098b1
--- /dev/null
+++ b/Flawless.Client/Views/IssueDetailView.axaml
@@ -0,0 +1,63 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Flawless.Client/Views/ModalBox/IssueEditDialogView.axaml b/Flawless.Client/Views/ModalBox/IssueEditDialogView.axaml
new file mode 100644
index 0000000..463bb25
--- /dev/null
+++ b/Flawless.Client/Views/ModalBox/IssueEditDialogView.axaml
@@ -0,0 +1,25 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Flawless.Client/Views/RepositoryPage/RepoIssuePageView.axaml b/Flawless.Client/Views/RepositoryPage/RepoIssuePageView.axaml
index adaa6be..de50354 100644
--- a/Flawless.Client/Views/RepositoryPage/RepoIssuePageView.axaml
+++ b/Flawless.Client/Views/RepositoryPage/RepoIssuePageView.axaml
@@ -3,10 +3,68 @@
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:vm="using:Flawless.Client.ViewModels"
+ xmlns:u="https://irihi.tech/ursa"
x:DataType="vm:RepositoryViewModel"
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
x:Class="Flawless.Client.Views.RepositoryPage.RepoIssuePageView">
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+