mirror of
https://github.com/lantean-code/qbtmud.git
synced 2025-10-22 20:42:24 +00:00
Update field dialogs and share ratio
This commit is contained in:
@@ -0,0 +1,15 @@
|
||||
@typeparam T
|
||||
|
||||
<MudDialog>
|
||||
<DialogContent>
|
||||
<MudGrid>
|
||||
<MudItem xs="12">
|
||||
<MudNumericField T="string" Label="@Label" Value="@GetDisplayValue()" ValueChanged="ValueChanged" Min="@(Min.ToString())" Max="@(Max.ToString())" Disabled="Disabled" Variant="Variant.Outlined" />
|
||||
</MudItem>
|
||||
</MudGrid>
|
||||
</DialogContent>
|
||||
<DialogActions>
|
||||
<MudButton OnClick="Cancel">Cancel</MudButton>
|
||||
<MudButton Color="Color.Primary" OnClick="Submit">Save</MudButton>
|
||||
</DialogActions>
|
||||
</MudDialog>
|
@@ -0,0 +1,69 @@
|
||||
using Microsoft.AspNetCore.Components;
|
||||
using Microsoft.AspNetCore.Components.Web;
|
||||
using MudBlazor;
|
||||
using System.Numerics;
|
||||
|
||||
namespace Lantean.QBTMudBlade.Components.Dialogs
|
||||
{
|
||||
public partial class NumericFieldDialog<T> where T : struct, INumber<T>
|
||||
{
|
||||
[CascadingParameter]
|
||||
public MudDialogInstance MudDialog { get; set; } = default!;
|
||||
|
||||
[Parameter]
|
||||
public string? Label { get; set; }
|
||||
|
||||
[Parameter]
|
||||
public T Value { get; set; }
|
||||
|
||||
[Parameter]
|
||||
public T Min { get; set; } = T.Zero;
|
||||
|
||||
[Parameter]
|
||||
public T Max { get; set; } = T.One;
|
||||
|
||||
[Parameter]
|
||||
public bool Disabled { get; set; }
|
||||
|
||||
[Parameter]
|
||||
public Func<T, string>? ValueDisplayFunc { get; set; }
|
||||
|
||||
[Parameter]
|
||||
public Func<string, T>? ValueGetFunc { get; set; }
|
||||
|
||||
private string? GetDisplayValue()
|
||||
{
|
||||
var value = ValueDisplayFunc?.Invoke(Value);
|
||||
return value is null ? Value.ToString() : value;
|
||||
}
|
||||
|
||||
protected void ValueChanged(string value)
|
||||
{
|
||||
if (ValueGetFunc is not null)
|
||||
{
|
||||
Value = ValueGetFunc.Invoke(value);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (T.TryParse(value, null, out var result))
|
||||
{
|
||||
Value = result;
|
||||
}
|
||||
else
|
||||
{
|
||||
Value = Min;
|
||||
}
|
||||
}
|
||||
|
||||
protected void Cancel(MouseEventArgs args)
|
||||
{
|
||||
MudDialog.Cancel();
|
||||
}
|
||||
|
||||
protected void Submit(MouseEventArgs args)
|
||||
{
|
||||
MudDialog.Close(DialogResult.Ok(Value));
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,35 @@
|
||||
<MudDialog>
|
||||
<DialogContent>
|
||||
<MudGrid>
|
||||
<MudItem xs="12">
|
||||
<MudRadioGroup T="int" Value="ShareRatioType" ValueChanged="ShareRatioTypeChanged">
|
||||
<MudRadio T="int" Value="-2">Use global share limit</MudRadio>
|
||||
<MudRadio T="int" Value="-1">Set no share limit</MudRadio>
|
||||
<MudRadio T="int" Value="0">Set share limit to</MudRadio>
|
||||
</MudRadioGroup>
|
||||
</MudItem>
|
||||
<MudItem xs="3">
|
||||
<FieldSwitch Label="Ratio" Value="RatioEnabled" ValueChanged="RatioEnabledChanged" Disabled="@(!CustomEnabled)" />
|
||||
</MudItem>
|
||||
<MudItem xs="9">
|
||||
<MudNumericField T="float" Value="Ratio" ValueChanged="RatioChanged" Disabled="@(!CustomEnabled)" Min="1" Max="1024000" Variant="Variant.Outlined" Adornment="Adornment.End" AdornmentText="KiB" />
|
||||
</MudItem>
|
||||
<MudItem xs="3">
|
||||
<FieldSwitch Label="Total minutes" Value="TotalMinutesEnabled" ValueChanged="TotalMinutesEnabledChanged" Disabled="@(!CustomEnabled)" />
|
||||
</MudItem>
|
||||
<MudItem xs="9">
|
||||
<MudNumericField T="int" Value="TotalMinutes" ValueChanged="TotalMinutesChanged" Disabled="@(!CustomEnabled)" Min="1" Max="1024000" Variant="Variant.Outlined" Adornment="Adornment.End" AdornmentText="KiB" />
|
||||
</MudItem>
|
||||
<MudItem xs="3">
|
||||
<FieldSwitch Label="Inactive minutes" Value="InactiveMinutesEnabled" ValueChanged="InactiveMinutesEnabledChanged" Disabled="@(!CustomEnabled)" />
|
||||
</MudItem>
|
||||
<MudItem xs="9">
|
||||
<MudNumericField T="int" Value="InactiveMinutes" ValueChanged="InactiveMinutesChanged" Disabled="@(!CustomEnabled)" Min="1" Max="1024000" Variant="Variant.Outlined" Adornment="Adornment.End" AdornmentText="KiB" />
|
||||
</MudItem>
|
||||
</MudGrid>
|
||||
</DialogContent>
|
||||
<DialogActions>
|
||||
<MudButton OnClick="Cancel">Cancel</MudButton>
|
||||
<MudButton Color="Color.Primary" OnClick="Submit">Save</MudButton>
|
||||
</DialogActions>
|
||||
</MudDialog>
|
130
Lantean.QBTMudBlade/Components/Dialogs/ShareRatioDialog.razor.cs
Normal file
130
Lantean.QBTMudBlade/Components/Dialogs/ShareRatioDialog.razor.cs
Normal file
@@ -0,0 +1,130 @@
|
||||
using Lantean.QBitTorrentClient;
|
||||
using Lantean.QBTMudBlade.Models;
|
||||
using Microsoft.AspNetCore.Components;
|
||||
using Microsoft.AspNetCore.Components.Web;
|
||||
using MudBlazor;
|
||||
|
||||
namespace Lantean.QBTMudBlade.Components.Dialogs
|
||||
{
|
||||
public partial class ShareRatioDialog
|
||||
{
|
||||
[CascadingParameter]
|
||||
public MudDialogInstance MudDialog { get; set; } = default!;
|
||||
|
||||
[Parameter]
|
||||
public string? Label { get; set; }
|
||||
|
||||
[Parameter]
|
||||
public ShareRatioMax? Value { get; set; }
|
||||
|
||||
[Parameter]
|
||||
public bool Disabled { get; set; }
|
||||
|
||||
protected int ShareRatioType { get; set; }
|
||||
|
||||
protected bool RatioEnabled { get; set; }
|
||||
|
||||
protected float Ratio { get; set; }
|
||||
|
||||
protected bool TotalMinutesEnabled { get; set; }
|
||||
|
||||
protected int TotalMinutes { get; set; }
|
||||
|
||||
protected bool InactiveMinutesEnabled { get; set; }
|
||||
|
||||
protected int InactiveMinutes { get; set; }
|
||||
|
||||
protected bool CustomEnabled => ShareRatioType == 0;
|
||||
|
||||
protected void RatioEnabledChanged(bool value)
|
||||
{
|
||||
RatioEnabled = value;
|
||||
}
|
||||
|
||||
protected void RatioChanged(float value)
|
||||
{
|
||||
Ratio = value;
|
||||
}
|
||||
|
||||
protected void TotalMinutesEnabledChanged(bool value)
|
||||
{
|
||||
TotalMinutesEnabled = value;
|
||||
}
|
||||
|
||||
protected void TotalMinutesChanged(int value)
|
||||
{
|
||||
TotalMinutes = value;
|
||||
}
|
||||
|
||||
protected void InactiveMinutesEnabledChanged(bool value)
|
||||
{
|
||||
InactiveMinutesEnabled = value;
|
||||
}
|
||||
|
||||
protected void InactiveMinutesChanged(int value)
|
||||
{
|
||||
InactiveMinutes = value;
|
||||
}
|
||||
|
||||
protected override void OnParametersSet()
|
||||
{
|
||||
if (Value is null || (Value.RatioLimit == Limits.GlobalLimit && Value.SeedingTimeLimit == Limits.GlobalLimit && Value.InactiveSeedingTimeLimit == Limits.GlobalLimit))
|
||||
{
|
||||
ShareRatioType = Limits.GlobalLimit;
|
||||
}
|
||||
else if (Value.MaxRatio == Limits.NoLimit && Value.MaxSeedingTime == Limits.NoLimit && Value.MaxInactiveSeedingTime == Limits.NoLimit)
|
||||
{
|
||||
ShareRatioType = Limits.NoLimit;
|
||||
}
|
||||
else
|
||||
{
|
||||
ShareRatioType = 0;
|
||||
if (Value.RatioLimit >= 0)
|
||||
{
|
||||
RatioEnabled = true;
|
||||
Ratio = Value.RatioLimit;
|
||||
}
|
||||
if (Value.SeedingTimeLimit >= 0)
|
||||
{
|
||||
TotalMinutesEnabled = true;
|
||||
TotalMinutes = (int)Value.SeedingTimeLimit;
|
||||
}
|
||||
if (Value.InactiveSeedingTimeLimit >= 0)
|
||||
{
|
||||
InactiveMinutesEnabled = true;
|
||||
InactiveMinutes = (int)Value.InactiveSeedingTimeLimit;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected void ShareRatioTypeChanged(int value)
|
||||
{
|
||||
ShareRatioType = value;
|
||||
}
|
||||
|
||||
protected void Cancel(MouseEventArgs args)
|
||||
{
|
||||
MudDialog.Cancel();
|
||||
}
|
||||
|
||||
protected void Submit(MouseEventArgs args)
|
||||
{
|
||||
var result = new ShareRatio();
|
||||
if (ShareRatioType == Limits.GlobalLimit)
|
||||
{
|
||||
result.RatioLimit = result.SeedingTimeLimit = result.InactiveSeedingTimeLimit = Limits.GlobalLimit;
|
||||
}
|
||||
else if (ShareRatioType == Limits.NoLimit)
|
||||
{
|
||||
result.RatioLimit = result.SeedingTimeLimit = result.InactiveSeedingTimeLimit = Limits.NoLimit;
|
||||
}
|
||||
else
|
||||
{
|
||||
result.RatioLimit = RatioEnabled ? Ratio : Limits.NoLimit;
|
||||
result.SeedingTimeLimit = TotalMinutesEnabled ? TotalMinutes : Limits.NoLimit;
|
||||
result.InactiveSeedingTimeLimit = InactiveMinutesEnabled ? InactiveMinutes : Limits.NoLimit;
|
||||
}
|
||||
MudDialog.Close(DialogResult.Ok(result));
|
||||
}
|
||||
}
|
||||
}
|
@@ -4,10 +4,10 @@
|
||||
<DialogContent>
|
||||
<MudGrid>
|
||||
<MudItem xs="12">
|
||||
<MudNumericField T="T" Label="@GetLabel()" Value="@Value" Min="@Min" Max="@Max" Disabled="Disabled" Variant="Variant.Outlined" />
|
||||
<MudNumericField T="string" Label="@Label" Value="@GetDisplayValue()" ValueChanged="ValueChanged" Min="@(Min.ToString())" Max="@(Max.ToString())" Disabled="Disabled" Variant="Variant.Outlined" />
|
||||
</MudItem>
|
||||
<MudItem xs="12">
|
||||
<MudSlider T="T" ValueLabel="true" Value="@Value" Min="@Min" Max="@Max" Disabled="Disabled" />
|
||||
<MudSlider T="T" ValueLabel="true" Value="@Value" ValueChanged="ValueChanged" Min="@Min" Max="@Max" Disabled="Disabled" />
|
||||
</MudItem>
|
||||
</MudGrid>
|
||||
</DialogContent>
|
||||
|
@@ -1,6 +1,7 @@
|
||||
using Microsoft.AspNetCore.Components;
|
||||
using Microsoft.AspNetCore.Components.Web;
|
||||
using MudBlazor;
|
||||
using System.ComponentModel;
|
||||
using System.Numerics;
|
||||
|
||||
namespace Lantean.QBTMudBlade.Components.Dialogs
|
||||
@@ -26,12 +27,39 @@ namespace Lantean.QBTMudBlade.Components.Dialogs
|
||||
public bool Disabled { get; set; }
|
||||
|
||||
[Parameter]
|
||||
public Func<T, string?>? LabelFunc { get; set; }
|
||||
public Func<T, string?>? ValueDisplayFunc { get; set; }
|
||||
|
||||
private string? GetLabel()
|
||||
[Parameter]
|
||||
public Func<string, T>? ValueGetFunc { get; set; }
|
||||
|
||||
private string? GetDisplayValue()
|
||||
{
|
||||
var label = LabelFunc?.Invoke(Value);
|
||||
return label is null ? Label : label;
|
||||
var value = ValueDisplayFunc?.Invoke(Value);
|
||||
return value is null ? Value.ToString() : value;
|
||||
}
|
||||
|
||||
protected void ValueChanged(T value)
|
||||
{
|
||||
Value = value;
|
||||
}
|
||||
|
||||
protected void ValueChanged(string value)
|
||||
{
|
||||
if (ValueGetFunc is not null)
|
||||
{
|
||||
Value = ValueGetFunc.Invoke(value);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (T.TryParse(value, null, out var result))
|
||||
{
|
||||
Value = result;
|
||||
}
|
||||
else
|
||||
{
|
||||
Value = Min;
|
||||
}
|
||||
}
|
||||
|
||||
protected void Cancel(MouseEventArgs args)
|
||||
|
@@ -1,10 +1,8 @@
|
||||
@typeparam T
|
||||
|
||||
<MudDialog>
|
||||
<MudDialog>
|
||||
<DialogContent>
|
||||
<MudGrid>
|
||||
<MudItem xs="12">
|
||||
<MudTextField T="T" Label="@GetLabel()" Value="@Value" Disabled="Disabled" Variant="Variant.Outlined" />
|
||||
<MudTextField T="string" Label="@Label" Value="@Value" Disabled="Disabled" Variant="Variant.Outlined" />
|
||||
</MudItem>
|
||||
</MudGrid>
|
||||
</DialogContent>
|
@@ -4,7 +4,7 @@ using MudBlazor;
|
||||
|
||||
namespace Lantean.QBTMudBlade.Components.Dialogs
|
||||
{
|
||||
public partial class SingleFieldDialog<T>
|
||||
public partial class StringFieldDialog
|
||||
{
|
||||
[CascadingParameter]
|
||||
public MudDialogInstance MudDialog { get; set; } = default!;
|
||||
@@ -13,20 +13,11 @@ namespace Lantean.QBTMudBlade.Components.Dialogs
|
||||
public string? Label { get; set; }
|
||||
|
||||
[Parameter]
|
||||
public T? Value { get; set; }
|
||||
public string? Value { get; set; }
|
||||
|
||||
[Parameter]
|
||||
public bool Disabled { get; set; }
|
||||
|
||||
[Parameter]
|
||||
public Func<T?, string?>? LabelFunc { get; set; }
|
||||
|
||||
private string? GetLabel()
|
||||
{
|
||||
var label = LabelFunc?.Invoke(Value);
|
||||
return label is null ? Label : label;
|
||||
}
|
||||
|
||||
protected void Cancel(MouseEventArgs args)
|
||||
{
|
||||
MudDialog.Cancel();
|
@@ -308,7 +308,7 @@ namespace Lantean.QBTMudBlade.Components
|
||||
{
|
||||
var contentItem = contentItems[0];
|
||||
var name = contentItem.GetFileName();
|
||||
await DialogService.ShowSingleFieldDialog("Rename", "New name", name, async value => await ApiClient.RenameFile(Hash, contentItem.Name, contentItem.Path + value));
|
||||
await DialogService.ShowStringFieldDialog("Rename", "New name", name, async value => await ApiClient.RenameFile(Hash, contentItem.Name, contentItem.Path + value));
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@@ -41,7 +41,7 @@
|
||||
<MudCardContent Class="pt-0">
|
||||
<MudGrid>
|
||||
<MudItem xs="12" md="6">
|
||||
<FieldSwitch T="bool" Label="Global maximum number of connections" Value="MaxConnecEnabled" ValueChanged="MaxConnecEnabledChanged" />
|
||||
<FieldSwitch Label="Global maximum number of connections" Value="MaxConnecEnabled" ValueChanged="MaxConnecEnabledChanged" />
|
||||
</MudItem>
|
||||
<MudItem xs="12" md="6">
|
||||
<MudNumericField T="int" Label="Connections" Value="MaxConnec" ValueChanged="MaxConnecChanged" Min="0" Disabled="@(!MaxConnecEnabled)" Variant="Variant.Outlined" Validation="MaxConnectValidation" />
|
||||
|
@@ -173,7 +173,7 @@ namespace Lantean.QBTMudBlade.Components
|
||||
savePath = torrent.SavePath;
|
||||
}
|
||||
|
||||
await DialogService.ShowSingleFieldDialog("Set Location", "Location", savePath, v => ApiClient.SetTorrentLocation(v, null, Hashes.ToArray()));
|
||||
await DialogService.ShowStringFieldDialog("Set Location", "Location", savePath, v => ApiClient.SetTorrentLocation(v, null, Hashes.ToArray()));
|
||||
}
|
||||
|
||||
protected async Task Rename()
|
||||
@@ -184,7 +184,7 @@ namespace Lantean.QBTMudBlade.Components
|
||||
{
|
||||
name = torrent.Name;
|
||||
}
|
||||
await DialogService.ShowSingleFieldDialog("Rename", "Name", name, v => ApiClient.SetTorrentName(v, hash));
|
||||
await DialogService.ShowStringFieldDialog("Rename", "Name", name, v => ApiClient.SetTorrentName(v, hash));
|
||||
}
|
||||
|
||||
protected async Task RenameFiles()
|
||||
@@ -211,7 +211,7 @@ namespace Lantean.QBTMudBlade.Components
|
||||
string hash = Hashes.First();
|
||||
if (Hashes.Any() && Torrents.TryGetValue(hash, out var torrent))
|
||||
{
|
||||
downloadLimit = torrent.UploadLimit;
|
||||
downloadLimit = torrent.DownloadLimit;
|
||||
}
|
||||
|
||||
await DialogService.InvokeDownloadRateDialog(ApiClient, downloadLimit, Hashes);
|
||||
@@ -231,14 +231,16 @@ namespace Lantean.QBTMudBlade.Components
|
||||
|
||||
protected async Task LimitShareRatio()
|
||||
{
|
||||
float ratioLimit = -1;
|
||||
string hash = Hashes.First();
|
||||
if (Hashes.Any() && Torrents.TryGetValue(hash, out var torrent))
|
||||
var torrents = new List<Torrent>();
|
||||
foreach (var hash in Hashes)
|
||||
{
|
||||
ratioLimit = torrent.RatioLimit;
|
||||
if (Torrents.TryGetValue(hash, out var torrent))
|
||||
{
|
||||
torrents.Add(torrent);
|
||||
}
|
||||
}
|
||||
|
||||
await DialogService.InvokeShareRatioDialog(ApiClient, ratioLimit, Hashes);
|
||||
await DialogService.InvokeShareRatioDialog(ApiClient, torrents);
|
||||
}
|
||||
|
||||
protected async Task ToggleSuperSeeding()
|
||||
|
@@ -187,7 +187,7 @@ namespace Lantean.QBTMudBlade.Components
|
||||
return;
|
||||
}
|
||||
|
||||
await DialogService.ShowSingleFieldDialog("Edit Tracker", "Tracker URL", tracker.Url, async (value) => await ApiClient.EditTracker(Hash, tracker.Url, value));
|
||||
await DialogService.ShowStringFieldDialog("Edit Tracker", "Tracker URL", tracker.Url, async (value) => await ApiClient.EditTracker(Hash, tracker.Url, value));
|
||||
}
|
||||
|
||||
protected Task RemoveTrackerToolbar()
|
||||
|
@@ -246,14 +246,14 @@ namespace Lantean.QBTMudBlade
|
||||
});
|
||||
}
|
||||
|
||||
public static async Task ShowSingleFieldDialog<T>(this IDialogService dialogService, string title, string label, T? value, Func<T, Task> onSuccess)
|
||||
public static async Task ShowStringFieldDialog(this IDialogService dialogService, string title, string label, string? value, Func<string, Task> onSuccess)
|
||||
{
|
||||
var parameters = new DialogParameters
|
||||
{
|
||||
{ nameof(SingleFieldDialog<T>.Label), label },
|
||||
{ nameof(SingleFieldDialog<T>.Value), value }
|
||||
{ nameof(StringFieldDialog.Label), label },
|
||||
{ nameof(StringFieldDialog.Value), value }
|
||||
};
|
||||
var result = await dialogService.ShowAsync<SingleFieldDialog<T>>(title, parameters, FormDialogOptions);
|
||||
var result = await dialogService.ShowAsync<StringFieldDialog>(title, parameters, FormDialogOptions);
|
||||
|
||||
var dialogResult = await result.Result;
|
||||
if (dialogResult is null || dialogResult.Canceled || dialogResult.Data is null)
|
||||
@@ -261,19 +261,23 @@ namespace Lantean.QBTMudBlade
|
||||
return;
|
||||
}
|
||||
|
||||
await onSuccess((T)dialogResult.Data);
|
||||
await onSuccess((string)dialogResult.Data);
|
||||
}
|
||||
|
||||
public static async Task InvokeDownloadRateDialog(this IDialogService dialogService, IApiClient apiClient, long rate, IEnumerable<string> hashes)
|
||||
{
|
||||
Func<long, string> labelFunc = v => v == Limits.NoLimit ? "No limit" : v.ToString();
|
||||
Func<long, string> valueDisplayFunc = v => v == Limits.NoLimit ? "∞" : v.ToString();
|
||||
Func<string, long> valueGetFunc = v => v == "∞" ? Limits.NoLimit : long.Parse(v);
|
||||
|
||||
var parameters = new DialogParameters
|
||||
{
|
||||
{ nameof(SliderFieldDialog<long>.Value), rate },
|
||||
{ nameof(SliderFieldDialog<long>.Min), 0L },
|
||||
{ nameof(SliderFieldDialog<long>.Min), -1L },
|
||||
{ nameof(SliderFieldDialog<long>.Max), 100L },
|
||||
{ nameof(SingleFieldDialog<long>.LabelFunc), labelFunc }
|
||||
{ nameof(SliderFieldDialog<long>.Value), rate },
|
||||
{ nameof(SliderFieldDialog<long>.ValueDisplayFunc), valueDisplayFunc },
|
||||
{ nameof(SliderFieldDialog<long>.ValueGetFunc), valueGetFunc },
|
||||
{ nameof(SliderFieldDialog<long>.Label), "Download rate limit" }
|
||||
};
|
||||
var result = await dialogService.ShowAsync<SliderFieldDialog<long>>("Download Rate", parameters, FormDialogOptions);
|
||||
|
||||
@@ -288,12 +292,18 @@ namespace Lantean.QBTMudBlade
|
||||
|
||||
public static async Task InvokeUploadRateDialog(this IDialogService dialogService, IApiClient apiClient, long rate, IEnumerable<string> hashes)
|
||||
{
|
||||
Func<long, string> valueDisplayFunc = v => v == Limits.NoLimit ? "∞" : v.ToString();
|
||||
Func<string, long> valueGetFunc = v => v == "∞" ? Limits.NoLimit : long.Parse(v);
|
||||
|
||||
var parameters = new DialogParameters
|
||||
{
|
||||
{ nameof(SliderFieldDialog<long>.Value), rate },
|
||||
{ nameof(SliderFieldDialog<long>.Min), 0L },
|
||||
{ nameof(SliderFieldDialog<long>.Min), -1L },
|
||||
{ nameof(SliderFieldDialog<long>.Max), 100L },
|
||||
{ nameof(SliderFieldDialog<long>.Disabled), rate == Limits.GlobalLimit },
|
||||
{ nameof(SliderFieldDialog<long>.Value), rate },
|
||||
{ nameof(SliderFieldDialog<long>.ValueDisplayFunc), valueDisplayFunc },
|
||||
{ nameof(SliderFieldDialog<long>.ValueGetFunc), valueGetFunc },
|
||||
{ nameof(SliderFieldDialog<long>.Label), "Upload rate limit" }
|
||||
};
|
||||
var result = await dialogService.ShowAsync<SliderFieldDialog<long>>("Upload Rate", parameters, FormDialogOptions);
|
||||
|
||||
@@ -306,15 +316,25 @@ namespace Lantean.QBTMudBlade
|
||||
await apiClient.SetTorrentUploadLimit((long)dialogResult.Data, null, hashes.ToArray());
|
||||
}
|
||||
|
||||
public static async Task InvokeShareRatioDialog(this IDialogService dialogService, IApiClient apiClient, float ratio, IEnumerable<string> hashes)
|
||||
public static async Task InvokeShareRatioDialog(this IDialogService dialogService, IApiClient apiClient, IEnumerable<Torrent> torrents)
|
||||
{
|
||||
var torrentShareRatios = torrents.Select(t => new ShareRatioMax
|
||||
{
|
||||
InactiveSeedingTimeLimit = t.InactiveSeedingTimeLimit,
|
||||
MaxInactiveSeedingTime = t.InactiveSeedingTimeLimit,
|
||||
MaxRatio = t.MaxRatio,
|
||||
MaxSeedingTime = t.MaxSeedingTime,
|
||||
RatioLimit = t.RatioLimit,
|
||||
SeedingTimeLimit = t.SeedingTimeLimit,
|
||||
});
|
||||
|
||||
var torrentsHaveSameShareRatio = torrentShareRatios.Distinct().Count() == 1;
|
||||
|
||||
var parameters = new DialogParameters
|
||||
{
|
||||
{ nameof(SliderFieldDialog<float>.Value), ratio },
|
||||
{ nameof(SliderFieldDialog<float>.Min), 0F },
|
||||
{ nameof(SliderFieldDialog<float>.Max), 100F },
|
||||
{ nameof(ShareRatioDialog.Value), torrentsHaveSameShareRatio ? torrentShareRatios.FirstOrDefault() : null },
|
||||
};
|
||||
var result = await dialogService.ShowAsync<SliderFieldDialog<float>>("Share ratio", parameters, FormDialogOptions);
|
||||
var result = await dialogService.ShowAsync<ShareRatioDialog>("Share ratio", parameters, FormDialogOptions);
|
||||
|
||||
var dialogResult = await result.Result;
|
||||
if (dialogResult is null || dialogResult.Canceled || dialogResult.Data is null)
|
||||
@@ -322,7 +342,9 @@ namespace Lantean.QBTMudBlade
|
||||
return;
|
||||
}
|
||||
|
||||
await apiClient.SetTorrentShareLimit((float)dialogResult.Data, 0, null, hashes.ToArray());
|
||||
var shareRatio = (ShareRatio)dialogResult.Data;
|
||||
|
||||
await apiClient.SetTorrentShareLimit(shareRatio.RatioLimit, shareRatio.SeedingTimeLimit, shareRatio.InactiveSeedingTimeLimit, null, torrents.Select(t => t.Hash).ToArray());
|
||||
}
|
||||
|
||||
public static async Task<List<PropertyFilterDefinition<T>>?> ShowFilterOptionsDialog<T>(this IDialogService dialogService, List<PropertyFilterDefinition<T>>? propertyFilterDefinitions)
|
||||
|
@@ -26,6 +26,12 @@
|
||||
<Content Update="Components\Dialogs\ManageCategoriesDialog.razor">
|
||||
<ExcludeFromSingleFile>true</ExcludeFromSingleFile>
|
||||
</Content>
|
||||
<Content Update="Components\Dialogs\ShareRatioDialog.razor">
|
||||
<ExcludeFromSingleFile>true</ExcludeFromSingleFile>
|
||||
</Content>
|
||||
<Content Update="Components\Dialogs\NumericFieldDialog.razor">
|
||||
<ExcludeFromSingleFile>true</ExcludeFromSingleFile>
|
||||
</Content>
|
||||
<Content Update="Pages\TagManagement.razor">
|
||||
<ExcludeFromSingleFile>true</ExcludeFromSingleFile>
|
||||
</Content>
|
||||
|
@@ -3,7 +3,7 @@
|
||||
<CascadingValue Value="DrawerOpen" Name="DrawerOpen">
|
||||
<EnhancedErrorBoundary @ref="ErrorBoundary" OnClear="Cleared">
|
||||
<MudThemeProvider @ref="MudThemeProvider" @bind-IsDarkMode="IsDarkMode" Theme="Theme" />
|
||||
<MudDialogProvider CloseButton="true" CloseOnEscapeKey="true" />
|
||||
<MudDialogProvider CloseOnEscapeKey="true" />
|
||||
<MudSnackbarProvider />
|
||||
<MudPopoverProvider />
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
<MudSpacer />
|
||||
@if (ErrorBoundary?.Errors.Count > 0)
|
||||
{
|
||||
<MudBadge Content="@(ErrorBoundary?.Errors.Count ?? 0)" Color="Color.Error" Overlap="true">
|
||||
<MudBadge Content="@(ErrorBoundary?.Errors.Count ?? 0)" Color="Color.Error" Overlap="true" Class="mr-2">
|
||||
<MudIconButton Icon="@Icons.Material.Filled.Error" Color="Color.Default" OnClick="ToggleErrorDrawer" />
|
||||
</MudBadge>
|
||||
}
|
||||
|
17
Lantean.QBTMudBlade/Models/ShareRatio.cs
Normal file
17
Lantean.QBTMudBlade/Models/ShareRatio.cs
Normal file
@@ -0,0 +1,17 @@
|
||||
namespace Lantean.QBTMudBlade.Models
|
||||
{
|
||||
public record ShareRatio
|
||||
{
|
||||
public float RatioLimit { get; set; }
|
||||
public float SeedingTimeLimit { get; set; }
|
||||
public float InactiveSeedingTimeLimit { get; set; }
|
||||
|
||||
}
|
||||
|
||||
public record ShareRatioMax : ShareRatio
|
||||
{
|
||||
public float MaxRatio { get; set; }
|
||||
public float MaxSeedingTime { get; set; }
|
||||
public float MaxInactiveSeedingTime { get; set; }
|
||||
}
|
||||
}
|
@@ -50,7 +50,9 @@
|
||||
long uploaded,
|
||||
long uploadedSession,
|
||||
long uploadSpeed,
|
||||
long reannounce)
|
||||
long reannounce,
|
||||
float inactiveSeedingTimeLimit,
|
||||
float maxInactiveSeedingTime)
|
||||
{
|
||||
Hash = hash;
|
||||
AddedOn = addedOn;
|
||||
@@ -100,6 +102,8 @@
|
||||
UploadedSession = uploadedSession;
|
||||
UploadSpeed = uploadSpeed;
|
||||
Reannounce = reannounce;
|
||||
InactiveSeedingTimeLimit = inactiveSeedingTimeLimit;
|
||||
MaxInactiveSeedingTime = maxInactiveSeedingTime;
|
||||
}
|
||||
|
||||
protected Torrent()
|
||||
@@ -213,6 +217,10 @@
|
||||
|
||||
public long Reannounce { get; set; }
|
||||
|
||||
public float InactiveSeedingTimeLimit { get; set; }
|
||||
|
||||
public float MaxInactiveSeedingTime { get; set; }
|
||||
|
||||
public override bool Equals(object? obj)
|
||||
{
|
||||
if (obj is null) return false;
|
||||
|
@@ -48,7 +48,7 @@ namespace Lantean.QBTMudBlade.Pages
|
||||
#if DEBUG
|
||||
protected override Task OnInitializedAsync()
|
||||
{
|
||||
return DoLogin("admin", "ALKEVRPZP");
|
||||
return DoLogin("admin", "YZQC4Jhcw");
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
@@ -532,7 +532,9 @@ namespace Lantean.QBTMudBlade.Services
|
||||
torrent.Uploaded.GetValueOrDefault(),
|
||||
torrent.UploadedSession.GetValueOrDefault(),
|
||||
torrent.UploadSpeed.GetValueOrDefault(),
|
||||
torrent.Reannounce ?? 0);
|
||||
torrent.Reannounce ?? 0,
|
||||
torrent.InactiveSeedingTimeLimit.GetValueOrDefault(),
|
||||
torrent.MaxInactiveSeedingTime.GetValueOrDefault());
|
||||
}
|
||||
|
||||
private static void UpdateCategory(Category existingCategory, QBitTorrentClient.Models.Category category)
|
||||
@@ -593,6 +595,8 @@ namespace Lantean.QBTMudBlade.Services
|
||||
existingTorrent.UploadedSession = torrent.UploadedSession ?? existingTorrent.UploadedSession;
|
||||
existingTorrent.UploadSpeed = torrent.UploadSpeed ?? existingTorrent.UploadSpeed;
|
||||
existingTorrent.Reannounce = torrent.Reannounce ?? existingTorrent.Reannounce;
|
||||
existingTorrent.InactiveSeedingTimeLimit = torrent.InactiveSeedingTimeLimit ?? existingTorrent.InactiveSeedingTimeLimit;
|
||||
existingTorrent.MaxInactiveSeedingTime = torrent.MaxInactiveSeedingTime ?? existingTorrent.MaxInactiveSeedingTime;
|
||||
}
|
||||
|
||||
public Dictionary<string, ContentItem> CreateContentsList(IReadOnlyList<QBitTorrentClient.Models.FileData> files)
|
||||
|
@@ -675,12 +675,13 @@ namespace Lantean.QBitTorrentClient
|
||||
response.EnsureSuccessStatusCode();
|
||||
}
|
||||
|
||||
public async Task SetTorrentShareLimit(float ratioLimit, float seedingTimeLimit, bool? all = null, params string[] hashes)
|
||||
public async Task SetTorrentShareLimit(float ratioLimit, float seedingTimeLimit, float inactiveSeedingTimeLimit, bool? all = null, params string[] hashes)
|
||||
{
|
||||
var content = new FormUrlEncodedBuilder()
|
||||
.AddAllOrPipeSeparated("hashes", all, hashes)
|
||||
.Add("ratioLimit", ratioLimit)
|
||||
.Add("seedingTimeLimit", seedingTimeLimit)
|
||||
.Add("inactiveSeedingTimeLimit", inactiveSeedingTimeLimit)
|
||||
.ToFormUrlEncodedContent();
|
||||
|
||||
var response = await _httpClient.PostAsync("torrents/setShareLimits", content);
|
||||
|
@@ -122,7 +122,7 @@ namespace Lantean.QBitTorrentClient
|
||||
|
||||
Task SetTorrentDownloadLimit(long limit, bool? all = null, params string[] hashes);
|
||||
|
||||
Task SetTorrentShareLimit(float ratioLimit, float seedingTimeLimit, bool? all = null, params string[] hashes);
|
||||
Task SetTorrentShareLimit(float ratioLimit, float seedingTimeLimit, float inactiveSeedingTimeLimit, bool? all = null, params string[] hashes);
|
||||
|
||||
Task<IReadOnlyDictionary<string, long>> GetTorrentUploadLimit(bool? all = null, params string[] hashes);
|
||||
|
||||
|
@@ -2,8 +2,8 @@
|
||||
{
|
||||
public static class Limits
|
||||
{
|
||||
public const long GlobalLimit = -2;
|
||||
public const int GlobalLimit = -2;
|
||||
|
||||
public const long NoLimit = -1;
|
||||
public const int NoLimit = -1;
|
||||
}
|
||||
}
|
@@ -54,7 +54,9 @@ namespace Lantean.QBitTorrentClient.Models
|
||||
long? uploaded,
|
||||
long? uploadedSession,
|
||||
long? uploadSpeed,
|
||||
long? reannounce)
|
||||
long? reannounce,
|
||||
float? inactiveSeedingTimeLimit,
|
||||
float? maxInactiveSeedingTime)
|
||||
{
|
||||
AddedOn = addedOn;
|
||||
AmountLeft = amountLeft;
|
||||
@@ -104,6 +106,8 @@ namespace Lantean.QBitTorrentClient.Models
|
||||
UploadedSession = uploadedSession;
|
||||
UploadSpeed = uploadSpeed;
|
||||
Reannounce = reannounce;
|
||||
InactiveSeedingTimeLimit = inactiveSeedingTimeLimit;
|
||||
MaxInactiveSeedingTime = maxInactiveSeedingTime;
|
||||
}
|
||||
|
||||
[JsonPropertyName("added_on")]
|
||||
@@ -250,5 +254,11 @@ namespace Lantean.QBitTorrentClient.Models
|
||||
|
||||
[JsonPropertyName("reannounce")]
|
||||
public long? Reannounce { get; }
|
||||
|
||||
[JsonPropertyName("inactive_seeding_time_limit")]
|
||||
public float? InactiveSeedingTimeLimit { get; }
|
||||
|
||||
[JsonPropertyName("max_inactive_seeding_time")]
|
||||
public float? MaxInactiveSeedingTime { get; }
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user