Update field dialogs and share ratio

This commit is contained in:
ahjephson
2024-08-17 09:48:24 +01:00
parent cf12078de9
commit 566fab8f05
23 changed files with 394 additions and 58 deletions

View File

@@ -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>

View File

@@ -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));
}
}
}

View File

@@ -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>

View 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));
}
}
}

View File

@@ -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>

View File

@@ -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)

View File

@@ -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>

View File

@@ -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();

View File

@@ -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
{

View File

@@ -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" />

View File

@@ -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()

View File

@@ -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()

View File

@@ -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)

View File

@@ -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>

View File

@@ -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>
}

View 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; }
}
}

View File

@@ -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;

View File

@@ -48,7 +48,7 @@ namespace Lantean.QBTMudBlade.Pages
#if DEBUG
protected override Task OnInitializedAsync()
{
return DoLogin("admin", "ALKEVRPZP");
return DoLogin("admin", "YZQC4Jhcw");
}
#endif
}

View File

@@ -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)

View File

@@ -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);

View File

@@ -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);

View File

@@ -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;
}
}

View File

@@ -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; }
}
}