diff --git a/.idea/.idea.Flawless-Version-Control/.idea/avalonia.xml b/.idea/.idea.Flawless-Version-Control/.idea/avalonia.xml
index 1ab1d7f..88412e0 100644
--- a/.idea/.idea.Flawless-Version-Control/.idea/avalonia.xml
+++ b/.idea/.idea.Flawless-Version-Control/.idea/avalonia.xml
@@ -8,6 +8,7 @@
+
diff --git a/Flawless.Abstract/WorkPath.cs b/Flawless.Abstract/WorkPath.cs
index 786b54d..6747007 100644
--- a/Flawless.Abstract/WorkPath.cs
+++ b/Flawless.Abstract/WorkPath.cs
@@ -106,6 +106,12 @@ public static class WorkPath
return sb.ToString();
}
+ public static string FormatPathDirectorySeparator(string path)
+ {
+ return path.Replace(Path.DirectorySeparatorChar, DirectorySeparatorChar)
+ .Replace(Path.AltDirectorySeparatorChar, DirectorySeparatorChar);
+ }
+
///
/// Split work path into path vector.
///
diff --git a/Flawless.Client/ErrorGUIHandler.cs b/Flawless.Client/ErrorGUIHandler.cs
deleted file mode 100644
index 63125e6..0000000
--- a/Flawless.Client/ErrorGUIHandler.cs
+++ /dev/null
@@ -1,11 +0,0 @@
-using System;
-using Avalonia.Controls.Notifications;
-
-namespace Flawless.Client;
-
-public static class ErrorGUIHandler
-{
- public static void OnError(Exception ex)
- {
- }
-}
\ No newline at end of file
diff --git a/Flawless.Client/Service/Api.cs b/Flawless.Client/Service/Api.cs
index 65a0ecc..e096f92 100644
--- a/Flawless.Client/Service/Api.cs
+++ b/Flawless.Client/Service/Api.cs
@@ -99,7 +99,7 @@ public class Api : BaseService
public bool RequireRefreshToken()
{
if (_token.Value == null) return true;
- if (DateTime.UtcNow.AddMinutes(1) > _token.Value.Expiration) return true;
+ if (DateTime.UtcNow > _token.Value.Expiration!.Value.UtcDateTime.AddMinutes(-2)) return true;
return false;
}
diff --git a/Flawless.Client/Service/RepositoryService.cs b/Flawless.Client/Service/RepositoryService.cs
index 8d383bd..d3c7a42 100644
--- a/Flawless.Client/Service/RepositoryService.cs
+++ b/Flawless.Client/Service/RepositoryService.cs
@@ -115,6 +115,7 @@ public class RepositoryService : BaseService
}
catch (Exception e)
{
+ UIHelper.NotifyError(e);
Console.WriteLine(e);
return null;
}
@@ -164,6 +165,7 @@ public class RepositoryService : BaseService
}
catch (Exception e)
{
+ UIHelper.NotifyError(e);
Console.WriteLine(e);
return false;
}
@@ -226,6 +228,7 @@ public class RepositoryService : BaseService
}
catch (Exception e)
{
+ UIHelper.NotifyError(e);
Console.WriteLine(e);
return false;
}
@@ -328,6 +331,7 @@ public class RepositoryService : BaseService
}
catch (Exception e)
{
+ UIHelper.NotifyError(e);
Console.WriteLine(e);
await DeleteFromDiskAsync(repo);
return false;
@@ -361,6 +365,7 @@ public class RepositoryService : BaseService
}
catch (Exception e)
{
+ UIHelper.NotifyError(e);
Console.WriteLine(e);
return false;
}
@@ -417,6 +422,7 @@ public class RepositoryService : BaseService
}
catch (Exception e)
{
+ UIHelper.NotifyError(e);
Console.WriteLine(e);
return false;
}
@@ -435,7 +441,6 @@ public class RepositoryService : BaseService
if (manifest == null) return null;
// Prepare folders
- var path = PathUtility.GetWorkspacePath(repo.OwnerName, repo.Name);
var depotsRoot = PathUtility.GetWorkspaceDepotCachePath(repo.OwnerName, repo.Name);
Directory.CreateDirectory(depotsRoot);
@@ -464,18 +469,22 @@ public class RepositoryService : BaseService
}
// Create mapping dictionary
- var mappingDict = downloadedDepots.ToDictionary(i => i.Item1, i => i.Item2!);
+ var streamMap = downloadedDepots.ToDictionary(i => i.Item1, i => i.Item2!);
foreach (var dl in mainDepotLabel)
{
- if (mappingDict.ContainsKey(dl.Id)) continue;
- var dst = Path.Combine(depotsRoot, dl.Id.ToString());
- mappingDict.Add(dl.Id, new FileStream(dst, FileMode.Create));
+ // If this file is not being opened, open it from file system
+ if (!streamMap.ContainsKey(dl.Id))
+ {
+ var dst = Path.Combine(depotsRoot, dl.Id.ToString());
+ streamMap.Add(dl.Id, new FileStream(dst, FileMode.Open, FileAccess.Read, FileShare.Read));
+ }
}
- return new RepositoryFileTreeAccessor(mappingDict, manifest.Value);
+ return new RepositoryFileTreeAccessor(streamMap, manifest.Value);
}
catch (Exception e)
{
+ UIHelper.NotifyError(e);
if (downloadedDepots != null)
foreach (var t in downloadedDepots)
{
@@ -537,6 +546,7 @@ public class RepositoryService : BaseService
}
catch (Exception e)
{
+ UIHelper.NotifyError(e);
Console.WriteLine(e);
return null;
}
@@ -561,6 +571,7 @@ public class RepositoryService : BaseService
}
catch (Exception e)
{
+ UIHelper.NotifyError(e);
Console.WriteLine(e);
return null;
}
@@ -575,6 +586,7 @@ public class RepositoryService : BaseService
}
catch (Exception e)
{
+ UIHelper.NotifyError(e);
Console.WriteLine(e);
return false;
}
@@ -630,8 +642,15 @@ public class RepositoryService : BaseService
if (accessor == null) return null; //todo this is a really fatal issue...
if (localDb.RepoAccessor != null)
{
- try { await localDb.RepoAccessor.DisposeAsync(); }
- catch (Exception e) { Console.WriteLine(e); }
+ try
+ {
+ await localDb.RepoAccessor.DisposeAsync();
+ }
+ catch (Exception e)
+ {
+ UIHelper.NotifyError(e);
+ Console.WriteLine(e);
+ }
}
// Point to newest state.
@@ -644,6 +663,7 @@ public class RepositoryService : BaseService
}
catch (Exception e)
{
+ UIHelper.NotifyError(e);
Console.WriteLine(e);
return null;
}
@@ -735,6 +755,7 @@ public class RepositoryService : BaseService
}
catch (Exception e)
{
+ UIHelper.NotifyError(e);
Directory.Delete(repoWs, true);
Console.WriteLine(e);
return null;
diff --git a/Flawless.Client/Service/UserService.cs b/Flawless.Client/Service/UserService.cs
index 7ddaeb2..2bc5704 100644
--- a/Flawless.Client/Service/UserService.cs
+++ b/Flawless.Client/Service/UserService.cs
@@ -50,6 +50,7 @@ public partial class UserService : BaseService
}
catch (Exception e)
{
+ UIHelper.NotifyError(e);
Console.WriteLine(e);
return null;
}
@@ -80,6 +81,7 @@ public partial class UserService : BaseService
}
catch (Exception e)
{
+ UIHelper.NotifyError(e);
Console.WriteLine(e);
return false;
}
diff --git a/Flawless.Client/UIHelper.cs b/Flawless.Client/UIHelper.cs
new file mode 100644
index 0000000..f51cdd3
--- /dev/null
+++ b/Flawless.Client/UIHelper.cs
@@ -0,0 +1,96 @@
+using System;
+using System.Threading.Tasks;
+using Avalonia.Controls.ApplicationLifetimes;
+using Avalonia.Controls.Notifications;
+using Flawless.Client.ViewModels.ModalBox;
+using Flawless.Client.Views.ModalBox;
+using Ursa.Controls;
+using Notification = Ursa.Controls.Notification;
+using WindowNotificationManager = Ursa.Controls.WindowNotificationManager;
+
+namespace Flawless.Client;
+
+public static class UIHelper
+{
+
+ private static WindowNotificationManager _notificationManager = null!;
+
+ public static WindowNotificationManager Notify
+ {
+ get
+ {
+ if (_notificationManager != null) return _notificationManager!;
+
+ var lf = ((IClassicDesktopStyleApplicationLifetime)App.Current.ApplicationLifetime);
+ if (!WindowNotificationManager.TryGetNotificationManager(lf.MainWindow!, out _notificationManager))
+ throw new Exception("Can not get notification manager");
+
+ _notificationManager!.Position = NotificationPosition.TopCenter;
+ return _notificationManager!;
+ }
+ }
+
+
+ public static void NotifyError(Exception ex)
+ {
+ try
+ {
+ var content = ex.ToString();
+ if (content.Length > 100) content = content.Substring(0, 100) + "...";
+ var nf = new Notification(ex.GetType().Name, content, NotificationType.Error);
+ Notify.Show(nf);
+ }
+ catch (Exception e)
+ {
+ Console.WriteLine("Can not notify error to users: " + e);
+ }
+ }
+
+ public static void NotifyError(string title, string content)
+ {
+ try
+ {
+ var nf = new Notification(title, content, NotificationType.Error);
+ Notify.Show(nf);
+ }
+ catch (Exception e)
+ {
+ Console.WriteLine($"Can not notify error to users: {title} - {content}, {e}");
+ }
+ }
+
+
+ public static Task SimpleAskAsync(string content, DialogMode mode = DialogMode.None)
+ {
+ var opt = new OverlayDialogOptions
+ {
+ FullScreen = false,
+ Buttons = DialogButton.YesNo,
+ CanResize = false,
+ CanDragMove = false,
+ IsCloseButtonVisible = true,
+ CanLightDismiss = true,
+ Mode = mode
+ };
+
+ var vm = new SimpleMessageDialogViewModel(content);
+ return OverlayDialog.ShowModal(vm, AppDefaultValues.HostId, opt);
+ }
+
+ public static Task SimpleAlert(string content, DialogMode mode = DialogMode.Error)
+ {
+ var opt = new OverlayDialogOptions
+ {
+ FullScreen = false,
+ Buttons = DialogButton.YesNo,
+ CanResize = false,
+ CanDragMove = false,
+ IsCloseButtonVisible = true,
+ CanLightDismiss = true,
+ Mode = mode
+ };
+
+ var vm = new SimpleMessageDialogViewModel(content);
+ return OverlayDialog.ShowModal(vm, AppDefaultValues.HostId, opt);
+ }
+}
\ No newline at end of file
diff --git a/Flawless.Client/ViewModels/LoginPageViewModel.cs b/Flawless.Client/ViewModels/LoginPageViewModel.cs
index 87de465..be693ea 100644
--- a/Flawless.Client/ViewModels/LoginPageViewModel.cs
+++ b/Flawless.Client/ViewModels/LoginPageViewModel.cs
@@ -20,8 +20,6 @@ public partial class LoginPageViewModel : ViewModelBase, IRoutableViewModel
[Reactive] private string _username = "cardidi";
[Reactive] private string _password = "4453A2b33";
-
- [Reactive(SetModifier = AccessModifier.Protected)] private string _issue = String.Empty;
public IObservable CanLogin;
@@ -56,12 +54,12 @@ public partial class LoginPageViewModel : ViewModelBase, IRoutableViewModel
catch (ApiException ex)
{
await Console.Error.WriteLineAsync($"Login as '{Username}' Failed: {ex.Content}");
- Issue = ex.Content ?? String.Empty;
+ UIHelper.NotifyError(ex);
}
catch (Exception ex)
{
await Console.Error.WriteLineAsync($"Login as '{Username}' Failed: {ex}");
- Issue = ex.Message;
+ UIHelper.NotifyError(ex);
}
Console.WriteLine($"Login as '{Username}' success!");
diff --git a/Flawless.Client/ViewModels/RegisterPageViewModel.cs b/Flawless.Client/ViewModels/RegisterPageViewModel.cs
index d351ea9..bc1fa87 100644
--- a/Flawless.Client/ViewModels/RegisterPageViewModel.cs
+++ b/Flawless.Client/ViewModels/RegisterPageViewModel.cs
@@ -23,8 +23,6 @@ public partial class RegisterPageViewModel : ViewModelBase, IRoutableViewModel
[Reactive] private string _password;
- [Reactive(SetModifier = AccessModifier.Protected)] private string _issue;
-
public RegisterPageViewModel(IScreen hostScreen)
{
HostScreen = hostScreen;
@@ -49,12 +47,12 @@ public partial class RegisterPageViewModel : ViewModelBase, IRoutableViewModel
catch (ApiException ex)
{
await Console.Error.WriteLineAsync($"Register as '{Username}' Failed: {ex.Content}");
- Issue = ex.Content ?? String.Empty;
+ UIHelper.NotifyError(ex);
}
catch (Exception ex)
{
await Console.Error.WriteLineAsync($"Register as '{Username}' Failed: {ex}");
- Issue = ex.Message;
+ UIHelper.NotifyError(ex);
}
Console.WriteLine($"Register as '{Username}' success!");
diff --git a/Flawless.Client/ViewModels/RepositoryViewModel.cs b/Flawless.Client/ViewModels/RepositoryViewModel.cs
index a1b38cd..4b29758 100644
--- a/Flawless.Client/ViewModels/RepositoryViewModel.cs
+++ b/Flawless.Client/ViewModels/RepositoryViewModel.cs
@@ -10,6 +10,7 @@ using Avalonia.Controls;
using Avalonia.Controls.Models.TreeDataGrid;
using DynamicData;
using DynamicData.Binding;
+using Flawless.Abstraction;
using Flawless.Client.Models;
using Flawless.Client.Service;
using Flawless.Core.Modal;
@@ -106,13 +107,14 @@ public partial class RepositoryViewModel : RoutableViewModelBase
public HierarchicalTreeDataGridSource LocalChange { get; }
-
public HierarchicalTreeDataGridSource FileTree { get; }
public FlatTreeDataGridSource Commits { get; }
public ObservableCollection LocalChangeSetRaw { get; } = new();
+ public ObservableCollection CurrentCommitFileTreeRaw { get; } = new();
+
public UserModel User { get; }
[Reactive] private bool _autoDetectChanges = true;
@@ -181,10 +183,49 @@ public partial class RepositoryViewModel : RoutableViewModelBase
}
};
- DetectLocalChangesAsyncCommand.Execute();
+ FileTree = new HierarchicalTreeDataGridSource(CurrentCommitFileTreeRaw)
+ {
+ Columns =
+ {
+ new HierarchicalExpanderColumn(
+ new TextColumn(
+ "Name",
+ n => Path.GetFileName(n.FullPath)),
+ n => n.Contents),
+
+ new TextColumn(
+ "File Type",
+ n => n.Contents != null ? "Folder" : Path.GetExtension(n.FullPath)),
+
+ new TextColumn(
+ "Size",
+ n => 0),
+
+ new TextColumn(
+ "ModifiedTime", n => n.ModifiedTime.HasValue ? n.ModifiedTime.Value.ToLocalTime() : null),
+ }
+ };
+
+ _ = StartupTasksAsync();
}
+ private async Task StartupTasksAsync()
+ {
+ await DetectLocalChangesAsyncCommand.Execute();
+ await RendererFileTreeAsync();
+ }
+ private async ValueTask RendererFileTreeAsync()
+ {
+ if (LocalDatabase.RepoAccessor == null) return;
+ var accessor = LocalDatabase.RepoAccessor;
+ var nodes = await CalculateFileTreeOfChangesNodeAsync(accessor.Select(
+ f => new LocalFileTreeAccessor.ChangeRecord(ChangeType.Add, f)));
+
+ CurrentCommitFileTreeRaw.Clear();
+ CurrentCommitFileTreeRaw.AddRange(nodes);
+ }
+
private void CollectChanges(List store, IEnumerable changesNode)
{
foreach (var n in changesNode)
@@ -201,21 +242,72 @@ public partial class RepositoryViewModel : RoutableViewModelBase
}
}
+ private Task> CalculateFileTreeOfChangesNodeAsync(IEnumerable changesNode)
+ {
+ return Task.Run(() =>
+ {
+ // Generate a map of all folders
+ var folderMap = new Dictionary();
+ var nodes = new List();
+
+ foreach (var file in changesNode)
+ {
+ var n = LocalChangesNode.FromWorkspaceFile(file);
+ var parentNode = AddParentToMap(file.File.WorkPath);
+ if (parentNode == null) nodes.Add(n);
+ else parentNode.Contents!.Add(n);
+ }
+
+ return nodes;
+
+ LocalChangesNode? AddParentToMap(string path)
+ {
+ path = WorkPath.FormatPathDirectorySeparator(Path.GetDirectoryName(path) ?? string.Empty);
+
+ // 如果为空,则其直接文件夹就是根目录
+ if (string.IsNullOrEmpty(path)) return null;
+
+ // 如果直接文件夹已经存在,则不再生成,直接返回即可
+ if (folderMap.TryGetValue(path, out var node)) return node;
+
+ // 生成当前文件夹,并先找到这个文件夹的直接文件夹
+ node = LocalChangesNode.FromFolder(path);
+ var parent = AddParentToMap(path);
+ folderMap.Add(path, node);
+ if (parent != null) parent.Contents!.Add(node);
+ else nodes.Add(node);
+
+ // 将新建的文件夹告知调用方
+ return node;
+ }
+ });
+ }
+
[ReactiveCommand]
private async Task CommitSelectedChangesAsync()
{
var changes = new List();
CollectChanges(changes, LocalChangeSetRaw);
- if (changes.Count == 0) return;
- var manifest = await RepositoryService.C.CommitWorkspaceAsBaselineAsync(Repository, changes,
- LocalDatabase.CommitMessage ?? string.Empty);
+ if (changes.Count == 0)
+ {
+ await UIHelper.SimpleAlert("You haven't choose any changes yet!");
+ return;
+ }
+
+ if (string.IsNullOrWhiteSpace(LocalDatabase.CommitMessage))
+ {
+ await UIHelper.SimpleAlert("Commit message can not be empty!");
+ return;
+ }
+ var manifest = await RepositoryService.C.CommitWorkspaceAsBaselineAsync(Repository, changes, LocalDatabase.CommitMessage!);
if (manifest == null) return;
LocalDatabase.LocalAccessor.SetBaseline(manifest.Value.FilePaths);
LocalDatabase.CommitMessage = string.Empty;
await DetectLocalChangesAsyncCommand.Execute();
+ await RendererFileTreeAsync();
}
[ReactiveCommand]
@@ -242,37 +334,28 @@ public partial class RepositoryViewModel : RoutableViewModelBase
[ReactiveCommand]
private async ValueTask DetectLocalChangesAsync()
{
- var ns = await Task.Run(() =>
+ var ns = await Task.Run(async () =>
{
LocalDatabase.LocalAccessor.Refresh();
-
- // Generate a map of all folders
- var folderMap = new Dictionary();
- foreach (var k in LocalDatabase.LocalAccessor.Changes.Keys)
- AddParentToMap(k);
-
- var nodes = new List();
- foreach (var file in LocalDatabase.LocalAccessor.Changes.Values)
- {
- var directory = Path.GetDirectoryName(file.File.WorkPath);
- var n = LocalChangesNode.FromWorkspaceFile(file);
- if (string.IsNullOrEmpty(directory)) nodes.Add(n);
- else folderMap[directory].Contents!.Add(n);
- }
-
- nodes.AddRange(folderMap.Values);
- return nodes;
-
- void AddParentToMap(string path)
- {
- var parent = Path.GetDirectoryName(path);
- if (string.IsNullOrEmpty(parent) || folderMap.ContainsKey(parent)) return;
-
- folderMap.Add(parent, LocalChangesNode.FromFolder(parent));
- }
+ return await CalculateFileTreeOfChangesNodeAsync(LocalDatabase.LocalAccessor.Changes.Values);
});
LocalChangeSetRaw.Clear();
LocalChangeSetRaw.AddRange(ns);
}
+
+ [ReactiveCommand]
+ private void SelectAllChanges()
+ {
+ foreach (var n in LocalChangeSetRaw)
+ n.Included = true;
+ }
+
+
+ [ReactiveCommand]
+ private void DeselectAllChanges()
+ {
+ foreach (var n in LocalChangeSetRaw)
+ n.Included = false;
+ }
}
\ No newline at end of file
diff --git a/Flawless.Client/ViewModels/ServerSetupPageViewModel.cs b/Flawless.Client/ViewModels/ServerSetupPageViewModel.cs
index dad59b1..0759661 100644
--- a/Flawless.Client/ViewModels/ServerSetupPageViewModel.cs
+++ b/Flawless.Client/ViewModels/ServerSetupPageViewModel.cs
@@ -14,8 +14,6 @@ public partial class ServerSetupPageViewModel : RoutableViewModelBase
[Reactive] private string _host = "http://localhost:5256/";
- [Reactive(SetModifier = AccessModifier.Protected)] private string? _issue;
-
public IObservable CanSetHost { get; }
public ServerSetupPageViewModel(IScreen hostScreen) : base(hostScreen)
@@ -33,19 +31,18 @@ public partial class ServerSetupPageViewModel : RoutableViewModelBase
{
try
{
- Issue = string.Empty;
await Api.C.SetGatewayAsync(Host);
HostScreen.Router.Navigate.Execute(new LoginPageViewModel(HostScreen));
}
catch (ApiException ex)
{
await Console.Error.WriteLineAsync("Can not connect to server: " + ex.ToString());
- Issue = ex.Content;
+ UIHelper.NotifyError(ex);
}
catch (Exception ex)
{
await Console.Error.WriteLineAsync("Can not connect to server: " + ex.ToString());
- Issue = ex.Message;
+ UIHelper.NotifyError(ex);
}
}
diff --git a/Flawless.Client/Views/HelloSetup/LoginPageView.axaml b/Flawless.Client/Views/HelloSetup/LoginPageView.axaml
index a75a8a0..54f45f6 100644
--- a/Flawless.Client/Views/HelloSetup/LoginPageView.axaml
+++ b/Flawless.Client/Views/HelloSetup/LoginPageView.axaml
@@ -20,6 +20,5 @@
-
diff --git a/Flawless.Client/Views/HelloSetup/RegisterPageView.axaml b/Flawless.Client/Views/HelloSetup/RegisterPageView.axaml
index bd4e415..312b280 100644
--- a/Flawless.Client/Views/HelloSetup/RegisterPageView.axaml
+++ b/Flawless.Client/Views/HelloSetup/RegisterPageView.axaml
@@ -20,6 +20,5 @@
-
\ No newline at end of file
diff --git a/Flawless.Client/Views/HelloSetup/ServerSetupPageView.axaml b/Flawless.Client/Views/HelloSetup/ServerSetupPageView.axaml
index 8704d50..4f8e096 100644
--- a/Flawless.Client/Views/HelloSetup/ServerSetupPageView.axaml
+++ b/Flawless.Client/Views/HelloSetup/ServerSetupPageView.axaml
@@ -16,6 +16,5 @@
-
diff --git a/Flawless.Client/Views/MainWindowView.axaml b/Flawless.Client/Views/MainWindowView.axaml
index c0ab123..8877726 100644
--- a/Flawless.Client/Views/MainWindowView.axaml
+++ b/Flawless.Client/Views/MainWindowView.axaml
@@ -21,5 +21,6 @@
+
\ No newline at end of file
diff --git a/Flawless.Client/Views/RepositoryPage/RepoDashboardPageView.axaml b/Flawless.Client/Views/RepositoryPage/RepoDashboardPageView.axaml
index da30e13..fa7c9a9 100644
--- a/Flawless.Client/Views/RepositoryPage/RepoDashboardPageView.axaml
+++ b/Flawless.Client/Views/RepositoryPage/RepoDashboardPageView.axaml
@@ -10,15 +10,9 @@
-
-
-
-
-
-
-
-
+
+
+
diff --git a/Flawless.Client/Views/RepositoryPage/RepoFileTreePageView.axaml b/Flawless.Client/Views/RepositoryPage/RepoFileTreePageView.axaml
index abe3352..739061f 100644
--- a/Flawless.Client/Views/RepositoryPage/RepoFileTreePageView.axaml
+++ b/Flawless.Client/Views/RepositoryPage/RepoFileTreePageView.axaml
@@ -7,7 +7,7 @@
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
x:Class="Flawless.Client.Views.RepositoryPage.RepoFileTreePageView">
-
+
diff --git a/Flawless.Client/Views/RepositoryPage/RepoSettingPageView.axaml b/Flawless.Client/Views/RepositoryPage/RepoSettingPageView.axaml
index 1320df0..117538e 100644
--- a/Flawless.Client/Views/RepositoryPage/RepoSettingPageView.axaml
+++ b/Flawless.Client/Views/RepositoryPage/RepoSettingPageView.axaml
@@ -6,7 +6,26 @@
x:DataType="vm:RepositoryViewModel"
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
x:Class="Flawless.Client.Views.RepositoryPage.RepoSettingPageView">
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Flawless.Client/Views/RepositoryPage/RepoWorkspacePageView.axaml b/Flawless.Client/Views/RepositoryPage/RepoWorkspacePageView.axaml
index 2d2b108..ca955bb 100644
--- a/Flawless.Client/Views/RepositoryPage/RepoWorkspacePageView.axaml
+++ b/Flawless.Client/Views/RepositoryPage/RepoWorkspacePageView.axaml
@@ -12,6 +12,8 @@
+
+
diff --git a/Flawless.Client/Views/RepositoryView.axaml b/Flawless.Client/Views/RepositoryView.axaml
index 6e256a6..d14f52c 100644
--- a/Flawless.Client/Views/RepositoryView.axaml
+++ b/Flawless.Client/Views/RepositoryView.axaml
@@ -19,7 +19,7 @@
-
+
diff --git a/Flawless.Server/Controllers/RepositoryInnieController.cs b/Flawless.Server/Controllers/RepositoryInnieController.cs
index 5232ebf..87603c6 100644
--- a/Flawless.Server/Controllers/RepositoryInnieController.cs
+++ b/Flawless.Server/Controllers/RepositoryInnieController.cs
@@ -382,6 +382,7 @@ public class RepositoryInnieController(
}
[HttpPost("create_commit")]
+ [RequestSizeLimit(long.MaxValue)]
[ProducesResponseType(200)]
public async Task CommitAsync(string userName, string repositoryName, [FromForm] FormCommitRequest req)
{
diff --git a/Flawless.Server/Program.cs b/Flawless.Server/Program.cs
index fcf5ec5..09a7b20 100644
--- a/Flawless.Server/Program.cs
+++ b/Flawless.Server/Program.cs
@@ -8,6 +8,7 @@ using Flawless.Server.Services;
using Flawless.Server.Utility;
using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.AspNetCore.Authorization;
+using Microsoft.AspNetCore.Http.Features;
using Microsoft.AspNetCore.Identity;
using Microsoft.EntityFrameworkCore;
using Microsoft.IdentityModel.Tokens;
@@ -38,6 +39,14 @@ public static class Program
builder.WebHost.ConfigureKestrel(opt =>
{
opt.Limits.MaxRequestBodySize = long.MaxValue; // As big as possible...
+ opt.Limits.MaxRequestHeaderCount = int.MaxValue; // As big as possible...
+ });
+
+ builder.Services.Configure(opt =>
+ {
+ opt.MultipartBodyLengthLimit = long.MaxValue;
+ opt.ValueLengthLimit = int.MaxValue;
+ opt.MultipartHeadersLengthLimit = int.MaxValue;
});
// Api related