Add options

This commit is contained in:
ahjephson
2024-04-26 19:45:10 +01:00
parent f9847c60f5
commit d698370c45
34 changed files with 2542 additions and 195 deletions

View File

@@ -20,6 +20,10 @@
<PackageReference Include="System.Net.Http" Version="4.3.4" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Lantean.QBitTorrentClient\Lantean.QBitTorrentClient.csproj" />
</ItemGroup>
<ItemGroup>
<Using Include="Xunit" />
</ItemGroup>

View File

@@ -1,97 +1,99 @@
<div class="pl-6 pt-6"><MudText Typo="Typo.h6">Transfer</MudText></div>
<MudGrid Class="pl-6 pr-6 pb-6">
<MudItem xs="4">
<MudField Label="Time Active">@DisplayHelpers.Duration(Properties?.TimeElapsed)</MudField>
</MudItem>
<MudItem xs="4">
<MudField Label="ETA">@DisplayHelpers.Duration(Properties?.EstimatedTimeOfArrival)</MudField>
</MudItem>
<MudItem xs="4">
<MudField Label="Connections">@DisplayHelpers.Duration(Properties?.Connections) @DisplayHelpers.EmptyIfNull(Properties?.ConnectionsLimit, "(", " max)")</MudField>
</MudItem>
<MudContainer MaxWidth="MaxWidth.ExtraExtraLarge">
<MudText Typo="Typo.subtitle2" Class="pt-6">Transfer</MudText>
<MudGrid>
<MudItem xs="4">
<MudField Label="Time Active">@DisplayHelpers.Duration(Properties?.TimeElapsed)</MudField>
</MudItem>
<MudItem xs="4">
<MudField Label="ETA">@DisplayHelpers.Duration(Properties?.EstimatedTimeOfArrival)</MudField>
</MudItem>
<MudItem xs="4">
<MudField Label="Connections">@DisplayHelpers.Duration(Properties?.Connections) @DisplayHelpers.EmptyIfNull(Properties?.ConnectionsLimit, "(", " max)")</MudField>
</MudItem>
<MudItem xs="4">
<MudField Label="Downloaded">@DisplayHelpers.Size(Properties?.TotalDownloaded) @DisplayHelpers.Size(Properties?.TotalDownloadedSession, "(", " this session)")</MudField>
</MudItem>
<MudItem xs="4">
<MudField Label="Uploaded">@DisplayHelpers.Size(Properties?.TotalUploaded) @DisplayHelpers.Size(Properties?.TotalUploaded, "(", " this session)")</MudField>
</MudItem>
<MudItem xs="4">
<MudField Label="Seeds">@DisplayHelpers.Size(Properties?.Seeds) @DisplayHelpers.EmptyIfNull(Properties?.Seeds, "(", " total)")</MudField>
</MudItem>
<MudItem xs="4">
<MudField Label="Downloaded">@DisplayHelpers.Size(Properties?.TotalDownloaded) @DisplayHelpers.Size(Properties?.TotalDownloadedSession, "(", " this session)")</MudField>
</MudItem>
<MudItem xs="4">
<MudField Label="Uploaded">@DisplayHelpers.Size(Properties?.TotalUploaded) @DisplayHelpers.Size(Properties?.TotalUploaded, "(", " this session)")</MudField>
</MudItem>
<MudItem xs="4">
<MudField Label="Seeds">@DisplayHelpers.Size(Properties?.Seeds) @DisplayHelpers.EmptyIfNull(Properties?.Seeds, "(", " total)")</MudField>
</MudItem>
<MudItem xs="4">
<MudField Label="Download Speed">@DisplayHelpers.Speed(Properties?.DownloadSpeed) @DisplayHelpers.Speed(Properties?.DownloadSpeedAverage, "(", " avg.)")</MudField>
</MudItem>
<MudItem xs="4">
<MudField Label="Upload Speed">@DisplayHelpers.Speed(Properties?.UploadSpeed) @DisplayHelpers.Speed(Properties?.UploadSpeedAverage, "(", " avg.)")</MudField>
</MudItem>
<MudItem xs="4">
<MudField Label="Peers">@DisplayHelpers.Size(Properties?.Peers) @DisplayHelpers.EmptyIfNull(Properties?.Peers, "(", " total)")</MudField>
</MudItem>
<MudItem xs="4">
<MudField Label="Download Speed">@DisplayHelpers.Speed(Properties?.DownloadSpeed) @DisplayHelpers.Speed(Properties?.DownloadSpeedAverage, "(", " avg.)")</MudField>
</MudItem>
<MudItem xs="4">
<MudField Label="Upload Speed">@DisplayHelpers.Speed(Properties?.UploadSpeed) @DisplayHelpers.Speed(Properties?.UploadSpeedAverage, "(", " avg.)")</MudField>
</MudItem>
<MudItem xs="4">
<MudField Label="Peers">@DisplayHelpers.Size(Properties?.Peers) @DisplayHelpers.EmptyIfNull(Properties?.Peers, "(", " total)")</MudField>
</MudItem>
<MudItem xs="4">
<MudField Label="Download Limit">@DisplayHelpers.Speed(Properties?.DownloadLimit)</MudField>
</MudItem>
<MudItem xs="4">
<MudField Label="Upload Limit">@DisplayHelpers.Speed(Properties?.UploadLimit)</MudField>
</MudItem>
<MudItem xs="4">
<MudField Label="Wasted">@DisplayHelpers.Size(Properties?.TotalWasted)</MudField>
</MudItem>
<MudItem xs="4">
<MudField Label="Download Limit">@DisplayHelpers.Speed(Properties?.DownloadLimit)</MudField>
</MudItem>
<MudItem xs="4">
<MudField Label="Upload Limit">@DisplayHelpers.Speed(Properties?.UploadLimit)</MudField>
</MudItem>
<MudItem xs="4">
<MudField Label="Wasted">@DisplayHelpers.Size(Properties?.TotalWasted)</MudField>
</MudItem>
<MudItem xs="4">
<MudField Label="Share Ratio">@Properties?.ShareRatio.ToString("0.00")</MudField>
</MudItem>
<MudItem xs="4">
<MudField Label="Reannounce In">@DisplayHelpers.Duration(Properties?.Reannounce)</MudField>
</MudItem>
<MudItem xs="4">
<MudField Label="Last Seen Complete">@DisplayHelpers.DateTime(Properties?.LastSeen, "Never")</MudField>
</MudItem>
<MudItem xs="4">
<MudField Label="Share Ratio">@Properties?.ShareRatio.ToString("0.00")</MudField>
</MudItem>
<MudItem xs="4">
<MudField Label="Reannounce In">@DisplayHelpers.Duration(Properties?.Reannounce)</MudField>
</MudItem>
<MudItem xs="4">
<MudField Label="Last Seen Complete">@DisplayHelpers.DateTime(Properties?.LastSeen, "Never")</MudField>
</MudItem>
</MudGrid>
</MudGrid>
<div class="pl-6 pt-6"><MudText Typo="Typo.h6">Information</MudText></div>
<MudGrid Class="pl-6 pr-6 pb-6">
<MudItem xs="4">
<MudField Label="Total Size">@DisplayHelpers.Size(Properties?.TotalSize)</MudField>
</MudItem>
<MudItem xs="4">
<MudField Label="Pieces">
@if (Properties is not null)
{
<text>@Properties.PiecesNum x @DisplayHelpers.Size(Properties.PieceSize) (have @Properties.PiecesHave)</text>
}
</MudField>
</MudItem>
<MudItem xs="4">
<MudField Label="Created By">@Properties?.CreatedBy</MudField>
</MudItem>
<MudText Typo="Typo.subtitle1" Class="pt-6">Information</MudText>
<MudGrid>
<MudItem xs="4">
<MudField Label="Total Size">@DisplayHelpers.Size(Properties?.TotalSize)</MudField>
</MudItem>
<MudItem xs="4">
<MudField Label="Pieces">
@if (Properties is not null)
{
<text>@Properties.PiecesNum x @DisplayHelpers.Size(Properties.PieceSize) (have @Properties.PiecesHave)</text>
}
</MudField>
</MudItem>
<MudItem xs="4">
<MudField Label="Created By">@Properties?.CreatedBy</MudField>
</MudItem>
<MudItem xs="4">
<MudField Label="Added On">@DisplayHelpers.DateTime(Properties?.AdditionDate)</MudField>
</MudItem>
<MudItem xs="4">
<MudField Label="Completed On">@DisplayHelpers.DateTime(Properties?.CompletionDate)</MudField>
</MudItem>
<MudItem xs="4">
<MudField Label="Created On">@DisplayHelpers.DateTime(Properties?.CreationDate)</MudField>
</MudItem>
<MudItem xs="4">
<MudField Label="Added On">@DisplayHelpers.DateTime(Properties?.AdditionDate)</MudField>
</MudItem>
<MudItem xs="4">
<MudField Label="Completed On">@DisplayHelpers.DateTime(Properties?.CompletionDate)</MudField>
</MudItem>
<MudItem xs="4">
<MudField Label="Created On">@DisplayHelpers.DateTime(Properties?.CreationDate)</MudField>
</MudItem>
<MudItem xs="12">
<MudField Label="Info Hash v1">@Properties?.InfoHashV1</MudField>
</MudItem>
<MudItem xs="12">
<MudField Label="Info Hash v1">@Properties?.InfoHashV1</MudField>
</MudItem>
<MudItem xs="12">
<MudField Label="Info Hash v2">@Properties?.InfoHashV2</MudField>
</MudItem>
<MudItem xs="12">
<MudField Label="Info Hash v2">@Properties?.InfoHashV2</MudField>
</MudItem>
<MudItem xs="12">
<MudField Label="Save Path">@Properties?.SavePath</MudField>
</MudItem>
<MudItem xs="12">
<MudField Label="Save Path">@Properties?.SavePath</MudField>
</MudItem>
<MudItem xs="12">
<MudField Label="Commenet">@Properties?.Comment</MudField>
</MudItem>
</MudGrid>
<MudItem xs="12">
<MudField Label="Comment">@Properties?.Comment</MudField>
</MudItem>
</MudGrid>
</MudContainer>

View File

@@ -0,0 +1,3 @@
<MudField Variant="Variant.Outlined" InnerPadding="false" Label="@Label">
<MudSwitch T="bool" Value="@Value" ValueChanged="ValueChangedCallback" ThumbIcon="@(Value ? Icons.Material.Filled.Done : Icons.Material.Filled.Close)" ThumbIconColor="@(Value ? Color.Success : Color.Error)" Class="pt-1 pb-1" />
</MudField>

View File

@@ -0,0 +1,22 @@
using Microsoft.AspNetCore.Components;
namespace Lantean.QBTMudBlade.Components
{
public partial class MudFieldSwitch
{
[Parameter]
public bool Value { get; set; }
[Parameter]
public EventCallback<bool> ValueChanged { get; set; }
[Parameter]
public string? Label { get; set; }
protected async Task ValueChangedCallback(bool value)
{
Value = value;
await ValueChanged.InvokeAsync(value);
}
}
}

View File

@@ -3,12 +3,241 @@
<MudCard Elevation="1" Class="ml-4 mr-4 mb-4 mt-4">
<MudCardHeader>
<CardHeaderContent>
<MudText Typo="Typo.h6"></MudText>
<MudText Typo="Typo.subtitle2">qBittorrent Section</MudText>
</CardHeaderContent>
</MudCardHeader>
<MudCardContent Class="pt-0">
<MudGrid>
<MudItem xs="12">
<MudSelect T="string" Label="Resume data storage type (requires restart)" Value="ResumeDataStorageType" ValueChanged="ResumeDataStorageTypeChanged" ShrinkLabel Variant="Variant.Outlined">
<MudSelectItem T="string" Value="@("Legacy")">Fastresume files</MudSelectItem>
<MudSelectItem T="string" Value="@("SQLite")">SQLite database (experimental)</MudSelectItem>
</MudSelect>
</MudItem>
<MudItem xs="12">
<MudNumericField T="int" Label="Physical memory (RAM) usage limit (applied if libtorrent &gt;= 2.0)" Value="MemoryWorkingSetLimit" ValueChanged="MemoryWorkingSetLimitChanged" Min="0" title="This option is less effective on Linux" ShrinkLabel Variant="Variant.Outlined" /> <MudText Typo="Typo.caption">MiB</MudText>
</MudItem>
<MudItem xs="12">
<MudSelect T="string" Label="Network interface" Value="CurrentNetworkInterface" ValueChanged="CurrentNetworkInterfaceChanged" ShrinkLabel Variant="Variant.Outlined">
<MudSelectItem T="string" Value="@("")">Any interface</MudSelectItem>
@foreach (var networkInterface in NetworkInterfaces)
{
<MudSelectItem T="string" Value="networkInterface.Value">@networkInterface.Name</MudSelectItem>
}
</MudSelect>
</MudItem>
<MudItem xs="12">
<MudSelect T="string" Label="Optional IP address to bind to" Value="CurrentInterfaceAddress" ValueChanged="CurrentInterfaceAddressChanged" ShrinkLabel Variant="Variant.Outlined">
<MudSelectItem T="string" Value="@("")">All addresses</MudSelectItem>
<MudSelectItem T="string" Value="@("0.0.0.0")">All IPv4 addresses</MudSelectItem>
<MudSelectItem T="string" Value="@("::")">All IPv6 addresses</MudSelectItem>
@foreach (var address in NetworkInterfaceAddresses)
{
<MudSelectItem T="string" Value="address">@address</MudSelectItem>
}
</MudSelect>
</MudItem>
<MudItem xs="12">
<MudNumericField T="int" Label="Save resume data interval" Value="SaveResumeDataInterval" ValueChanged="SaveResumeDataIntervalChanged" Min="0" ShrinkLabel Variant="Variant.Outlined" /> <MudText Typo="Typo.caption">min</MudText>
</MudItem>
<MudItem xs="12">
<MudNumericField T="int" Label=".torrent file size limit" Value="TorrentFileSizeLimit" ValueChanged="TorrentFileSizeLimitChanged" Min="0" ShrinkLabel Variant="Variant.Outlined" /> <MudText Typo="Typo.caption">MiB</MudText>
</MudItem>
<MudItem xs="12">
<MudCheckBox T="bool" Label="Recheck torrents on completion" Value="RecheckCompletedTorrents" ValueChanged="RecheckCompletedTorrentsChanged" LabelPosition="LabelPosition.End" />
</MudItem>
<MudItem xs="12">
<MudNumericField T="int" Label="Refresh interval" Value="RefreshInterval" ValueChanged="RefreshIntervalChanged" Min="0" ShrinkLabel Variant="Variant.Outlined" /> <MudText Typo="Typo.caption">ms</MudText>
</MudItem>
<MudItem xs="12">
<MudCheckBox T="bool" Label="Resolve peer countries" Value="ResolvePeerCountries" ValueChanged="ResolvePeerCountriesChanged" LabelPosition="LabelPosition.End" />
</MudItem>
<MudItem xs="12">
<MudCheckBox T="bool" Label="Reannounce to all trackers when IP or port changed" Value="ReannounceWhenAddressChanged" ValueChanged="ReannounceWhenAddressChangedChanged" LabelPosition="LabelPosition.End" />
</MudItem>
<MudItem xs="12">
<MudCheckBox T="bool" Label="Enable embedded tracker" Value="EnableEmbeddedTracker" ValueChanged="EnableEmbeddedTrackerChanged" LabelPosition="LabelPosition.End" />
</MudItem>
<MudItem xs="12">
<MudNumericField T="int" Label="Embedded tracker port" Value="EmbeddedTrackerPort" ValueChanged="EmbeddedTrackerPortChanged" Min="@Options.MinPortValue" Max="@Options.MaxPortValue" ShrinkLabel Variant="Variant.Outlined" />
</MudItem>
<MudItem xs="12">
<MudCheckBox T="bool" Label="Enable port forwarding for embedded tracker" Value="EmbeddedTrackerPortForwarding" ValueChanged="EmbeddedTrackerPortForwardingChanged" LabelPosition="LabelPosition.End" />
</MudItem>
</MudGrid>
</MudCardContent>
</MudCard>
</MudCard>
<MudCard Elevation="1" Class="ml-4 mr-4 mb-4 mt-4">
<MudCardHeader>
<CardHeaderContent>
<MudText Typo="Typo.subtitle2">qBittorrent Section</MudText>
</CardHeaderContent>
</MudCardHeader>
<MudCardContent Class="pt-0">
<MudGrid>
<MudItem xs="12">
<MudNumericField T="int" Label="Bdecode depth limit" Value="BdecodeDepthLimit" ValueChanged="BdecodeDepthLimitChanged" Min="0" ShrinkLabel Variant="Variant.Outlined" />
</MudItem>
<MudItem xs="12">
<MudNumericField T="int" Label="Bdecode token limit" Value="BdecodeTokenLimit" ValueChanged="BdecodeTokenLimitChanged" Min="0" ShrinkLabel Variant="Variant.Outlined" />
</MudItem>
<MudItem xs="12">
<MudNumericField T="int" Label="Asynchronous I/O threads" Value="AsyncIoThreads" ValueChanged="AsyncIoThreadsChanged" Min="0" ShrinkLabel Variant="Variant.Outlined" />
</MudItem>
<MudItem xs="12">
<MudNumericField T="int" Label="Hashing threads (requires libtorrent &gt;= 2.0)" Value="HashingThreads" ValueChanged="HashingThreadsChanged" Min="0" ShrinkLabel Variant="Variant.Outlined" />
</MudItem>
<MudItem xs="12">
<MudNumericField T="int" Label="File pool size" Value="FilePoolSize" ValueChanged="FilePoolSizeChanged" Min="0" ShrinkLabel Variant="Variant.Outlined" />
</MudItem>
<MudItem xs="12">
<MudNumericField T="int" Label="Outstanding memory when checking torrents" Value="CheckingMemoryUse" ValueChanged="CheckingMemoryUseChanged" Min="0" ShrinkLabel Variant="Variant.Outlined" /> <MudText Typo="Typo.caption">MiB</MudText>
</MudItem>
<MudItem xs="12">
<MudNumericField T="int" Label="Disk cache (requires libtorrent &lt; 2.0)" Value="DiskCache" ValueChanged="DiskCacheChanged" Min="0" ShrinkLabel Variant="Variant.Outlined" /> <MudText Typo="Typo.caption">MiB</MudText>
</MudItem>
<MudItem xs="12">
<MudNumericField T="int" Label="Disk cache expiry interval (requires libtorrent &lt; 2.0)" Value="DiskCacheTtl" ValueChanged="DiskCacheTtlChanged" Min="0" ShrinkLabel Variant="Variant.Outlined" /> <MudText Typo="Typo.caption">s</MudText>
</MudItem>
<MudItem xs="12">
<MudNumericField T="int" Label="Disk queue size" Value="DiskQueueSize" ValueChanged="DiskQueueSizeChanged" Min="0" ShrinkLabel Variant="Variant.Outlined" /> <MudText Typo="Typo.caption">KiB</MudText>
</MudItem>
<MudItem xs="12">
<MudSelect T="int" Label="Disk IO type (libtorrent &gt;= 2.0; requires restart)" Value="DiskIoType" ValueChanged="DiskIoTypeChanged" ShrinkLabel Variant="Variant.Outlined">
<MudSelectItem T="int" Value="0">Default</MudSelectItem>
<MudSelectItem T="int" Value="1">Memory mapped files</MudSelectItem>
<MudSelectItem T="int" Value="2">POSIX-compliant</MudSelectItem>
</MudSelect>
</MudItem>
<MudItem xs="12">
<MudSelect T="int" Label="Disk IO read mode" Value="DiskIoReadMode" ValueChanged="DiskIoReadModeChanged" ShrinkLabel Variant="Variant.Outlined">
<MudSelectItem T="int" Value="0">Disable OS cache</MudSelectItem>
<MudSelectItem T="int" Value="1">Enable OS cache</MudSelectItem>
</MudSelect>
</MudItem>
<MudItem xs="12">
<MudSelect T="int" Label="Disk IO write mode" Value="DiskIoWriteMode" ValueChanged="DiskIoWriteModeChanged" ShrinkLabel Variant="Variant.Outlined">
<MudSelectItem T="int" Value="0">Disable OS cache</MudSelectItem>
<MudSelectItem T="int" Value="1">Enable OS cache</MudSelectItem>
<MudSelectItem T="int" Value="2">Write-through (requires libtorrent &gt;= 2.0.6)</MudSelectItem>
</MudSelect>
</MudItem>
<MudItem xs="12">
<MudCheckBox T="bool" Label="Coalesce reads &amp; writes (requires libtorrent &lt; 2.0)" Value="EnableCoalesceReadWrite" ValueChanged="EnableCoalesceReadWriteChanged" LabelPosition="LabelPosition.End" />
</MudItem>
<MudItem xs="12">
<MudCheckBox T="bool" Label="Use piece extent affinity" Value="EnablePieceExtentAffinity" ValueChanged="EnablePieceExtentAffinityChanged" LabelPosition="LabelPosition.End" />
</MudItem>
<MudItem xs="12">
<MudCheckBox T="bool" Label="Send upload piece suggestions" Value="EnableUploadSuggestions" ValueChanged="EnableUploadSuggestionsChanged" LabelPosition="LabelPosition.End" />
</MudItem>
<MudItem xs="12">
<MudNumericField T="int" Label="Send buffer watermark" Value="SendBufferWatermark" ValueChanged="SendBufferWatermarkChanged" Min="0" ShrinkLabel Variant="Variant.Outlined" /> <MudText Typo="Typo.caption">KiB</MudText>
</MudItem>
<MudItem xs="12">
<MudNumericField T="int" Label="Send buffer low watermark" Value="SendBufferLowWatermark" ValueChanged="SendBufferLowWatermarkChanged" Min="0" ShrinkLabel Variant="Variant.Outlined" /> <MudText Typo="Typo.caption">KiB</MudText>
</MudItem>
<MudItem xs="12">
<MudNumericField T="int" Label="Send buffer watermark factor" Value="SendBufferWatermarkFactor" ValueChanged="SendBufferWatermarkFactorChanged" Min="0" ShrinkLabel Variant="Variant.Outlined" /> <MudText Typo="Typo.caption">%</MudText>
</MudItem>
<MudItem xs="12">
<MudNumericField T="int" Label="Outgoing connections per second" Value="ConnectionSpeed" ValueChanged="ConnectionSpeedChanged" Min="0" ShrinkLabel Variant="Variant.Outlined" />
</MudItem>
<MudItem xs="12">
<MudNumericField T="int" Label="Socket send buffer size [0: system default]" Value="SocketSendBufferSize" ValueChanged="SocketSendBufferSizeChanged" Min="0" ShrinkLabel Variant="Variant.Outlined" /> <MudText Typo="Typo.caption">KiB</MudText>
</MudItem>
<MudItem xs="12">
<MudNumericField T="int" Label="Socket receive buffer size [0: system default]" Value="SocketReceiveBufferSize" ValueChanged="SocketReceiveBufferSizeChanged" Min="0" ShrinkLabel Variant="Variant.Outlined" /> <MudText Typo="Typo.caption">KiB</MudText>
</MudItem>
<MudItem xs="12">
<MudNumericField T="int" Label="Socket backlog size" Value="SocketBacklogSize" ValueChanged="SocketBacklogSizeChanged" Min="0" ShrinkLabel Variant="Variant.Outlined" />
</MudItem>
<MudItem xs="12">
<MudNumericField T="int" Label="Outgoing ports (Min) [0: disabled]" Value="OutgoingPortsMin" ValueChanged="OutgoingPortsMinChanged" Min="0" ShrinkLabel Variant="Variant.Outlined" />
</MudItem>
<MudItem xs="12">
<MudNumericField T="int" Label="Outgoing ports (Max) [0: disabled]" Value="OutgoingPortsMax" ValueChanged="OutgoingPortsMaxChanged" Min="0" ShrinkLabel Variant="Variant.Outlined" />
</MudItem>
<MudItem xs="12">
<MudNumericField T="int" Label="UPnP lease duration [0: permanent lease]" Value="UpnpLeaseDuration" ValueChanged="UpnpLeaseDurationChanged" Min="0" ShrinkLabel Variant="Variant.Outlined" />
</MudItem>
<MudItem xs="12">
<MudNumericField T="int" Label="Type of service (ToS) for connections to peers" Value="PeerTos" ValueChanged="PeerTosChanged" Min="0" ShrinkLabel Variant="Variant.Outlined" />
</MudItem>
<MudItem xs="12">
<MudSelect T="int" Label="μTP-TCP mixed mode algorithm" Value="UtpTcpMixedMode" ValueChanged="UtpTcpMixedModeChanged" ShrinkLabel Variant="Variant.Outlined">
<MudSelectItem T="int" Value="0">Prefer TCP</MudSelectItem>
<MudSelectItem T="int" Value="1">Peer proportional (throttles TCP)</MudSelectItem>
</MudSelect>
</MudItem>
<MudItem xs="12">
<MudCheckBox T="bool" Label="Support internationalized domain name (IDN)" Value="IdnSupportEnabled" ValueChanged="IdnSupportEnabledChanged" LabelPosition="LabelPosition.End" />
</MudItem>
<MudItem xs="12">
<MudCheckBox T="bool" Label="Allow multiple connections from the same IP address" Value="EnableMultiConnectionsFromSameIp" ValueChanged="EnableMultiConnectionsFromSameIpChanged" LabelPosition="LabelPosition.End" />
</MudItem>
<MudItem xs="12">
<MudCheckBox T="bool" Label="Validate HTTPS tracker certificate" Value="ValidateHttpsTrackerCertificate" ValueChanged="ValidateHttpsTrackerCertificateChanged" LabelPosition="LabelPosition.End" />
</MudItem>
<MudItem xs="12">
<MudCheckBox T="bool" Label="Server-side request forgery (SSRF) mitigation" Value="SsrfMitigation" ValueChanged="SsrfMitigationChanged" LabelPosition="LabelPosition.End" />
</MudItem>
<MudItem xs="12">
<MudCheckBox T="bool" Label="Disallow connection to peers on privileged ports" Value="BlockPeersOnPrivilegedPorts" ValueChanged="BlockPeersOnPrivilegedPortsChanged" LabelPosition="LabelPosition.End" />
</MudItem>
<MudItem xs="12">
<MudSelect T="int" Label="Upload slots behavior" Value="UploadSlotsBehavior" ValueChanged="UploadSlotsBehaviorChanged" ShrinkLabel Variant="Variant.Outlined">
<MudSelectItem T="int" Value="0">Fixed slots</MudSelectItem>
<MudSelectItem T="int" Value="1">Upload rate based</MudSelectItem>
</MudSelect>
</MudItem>
<MudItem xs="12">
<MudSelect T="int" Label="Upload choking algorithm" Value="UploadChokingAlgorithm" ValueChanged="UploadChokingAlgorithmChanged" ShrinkLabel Variant="Variant.Outlined">
<MudSelectItem T="int" Value="0">Round-robin</MudSelectItem>
<MudSelectItem T="int" Value="1">Fastest upload</MudSelectItem>
<MudSelectItem T="int" Value="2">Anti-leech</MudSelectItem>
</MudSelect>
</MudItem>
<MudItem xs="12">
<MudCheckBox T="bool" Label="Always announce to all trackers in a tier" Value="AnnounceToAllTrackers" ValueChanged="AnnounceToAllTrackersChanged" LabelPosition="LabelPosition.End" />
</MudItem>
<MudItem xs="12">
<MudCheckBox T="bool" Label="Always announce to all tiers" Value="AnnounceToAllTiers" ValueChanged="AnnounceToAllTiersChanged" LabelPosition="LabelPosition.End" />
</MudItem>
<MudItem xs="12">
<MudTextField T="string" Label="IP address reported to trackers (requires restart)" Value="AnnounceIp" ValueChanged="AnnounceIpChanged" ShrinkLabel Variant="Variant.Outlined" />
</MudItem>
<MudItem xs="12">
<MudNumericField T="int" Label="Max concurrent HTTP announces" Value="MaxConcurrentHttpAnnounces" ValueChanged="MaxConcurrentHttpAnnouncesChanged" Min="0" ShrinkLabel Variant="Variant.Outlined" />
</MudItem>
<MudItem xs="12">
<MudNumericField T="int" Label="Stop tracker timeout [0: disabled]" Value="StopTrackerTimeout" ValueChanged="StopTrackerTimeoutChanged" Min="0" ShrinkLabel Variant="Variant.Outlined" />
</MudItem>
<MudItem xs="12">
<MudNumericField T="int" Label="Peer turnover disconnect percentage:" Value="PeerTurnover" ValueChanged="PeerTurnoverChanged" Min="0" ShrinkLabel Variant="Variant.Outlined" /> <MudText Typo="Typo.caption">%</MudText>
</MudItem>
<MudItem xs="12">
<MudNumericField T="int" Label="Peer turnover threshold percentage" Value="PeerTurnoverCutoff" ValueChanged="PeerTurnoverCutoffChanged" Min="0" ShrinkLabel Variant="Variant.Outlined" /> <MudText Typo="Typo.caption">%</MudText>
</MudItem>
<MudItem xs="12">
<MudNumericField T="int" Label="Peer turnover disconnect interval" Value="PeerTurnoverInterval" ValueChanged="PeerTurnoverIntervalChanged" Min="0" ShrinkLabel Variant="Variant.Outlined" /> <MudText Typo="Typo.caption">s</MudText>
</MudItem>
<MudItem xs="12">
<MudNumericField T="int" Label="Maximum outstanding requests to a single peer" Value="RequestQueueSize" ValueChanged="RequestQueueSizeChanged" Min="0" ShrinkLabel Variant="Variant.Outlined" />
</MudItem>
<MudItem xs="12">
<MudNumericField T="int" Label="I2P inbound quantity (requires libtorrent &gt;= 2.0)" Value="I2pInboundQuantity" ValueChanged="I2pInboundQuantityChanged" Min="0" ShrinkLabel Variant="Variant.Outlined" />
</MudItem>
<MudItem xs="12">
<MudNumericField T="int" Label="I2P outbound quantity (requires libtorrent &gt;= 2.0)" Value="I2pOutboundQuantity" ValueChanged="I2pOutboundQuantityChanged" Min="0" ShrinkLabel Variant="Variant.Outlined" />
</MudItem>
<MudItem xs="12">
<MudNumericField T="int" Label="I2P inbound length (requires libtorrent &gt;= 2.0)" Value="I2pInboundLength" ValueChanged="I2pInboundLengthChanged" Min="0" ShrinkLabel Variant="Variant.Outlined" />
</MudItem>
<MudItem xs="12">
<MudNumericField T="int" Label="I2P outbound length (requires libtorrent &gt;= 2.0)" Value="I2pOutboundLength" ValueChanged="I2pOutboundLengthChanged" Min="0" ShrinkLabel Variant="Variant.Outlined" />
</MudItem>
</MudGrid>
</MudCardContent>
</MudCard>

View File

@@ -1,10 +1,613 @@
namespace Lantean.QBTMudBlade.Components.Options
using Lantean.QBitTorrentClient;
using Lantean.QBitTorrentClient.Models;
using Microsoft.AspNetCore.Components;
namespace Lantean.QBTMudBlade.Components.Options
{
public partial class AdvancedOptions : Options
{
[Inject]
public IApiClient ApiClient { get; set; } = default!;
protected string? ResumeDataStorageType { get; private set; }
protected int MemoryWorkingSetLimit { get; private set; }
protected string? CurrentNetworkInterface { get; private set; }
protected string? CurrentInterfaceAddress { get; private set; }
protected int SaveResumeDataInterval { get; private set; }
protected int TorrentFileSizeLimit { get; private set; }
protected bool RecheckCompletedTorrents { get; private set; }
protected string? AppInstanceName { get; private set; }
protected int RefreshInterval { get; private set; }
protected bool ResolvePeerCountries { get; private set; }
protected bool ReannounceWhenAddressChanged { get; private set; }
protected int BdecodeDepthLimit { get; private set; }
protected int BdecodeTokenLimit { get; private set; }
protected int AsyncIoThreads { get; private set; }
protected int HashingThreads { get; private set; }
protected int FilePoolSize { get; private set; }
protected int CheckingMemoryUse { get; private set; }
protected int DiskCache { get; private set; }
protected int DiskCacheTtl { get; private set; }
protected int DiskQueueSize { get; private set; }
protected int DiskIoType { get; private set; }
protected int DiskIoReadMode { get; private set; }
protected int DiskIoWriteMode { get; private set; }
protected bool EnableCoalesceReadWrite { get; private set; }
protected bool EnablePieceExtentAffinity { get; private set; }
protected bool EnableUploadSuggestions { get; private set; }
protected int SendBufferWatermark { get; private set; }
protected int SendBufferLowWatermark { get; private set; }
protected int SendBufferWatermarkFactor { get; private set; }
protected int ConnectionSpeed { get; private set; }
protected int SocketSendBufferSize { get; private set; }
protected int SocketReceiveBufferSize { get; private set; }
protected int SocketBacklogSize { get; private set; }
protected int OutgoingPortsMin { get; private set; }
protected int OutgoingPortsMax { get; private set; }
protected int UpnpLeaseDuration { get; private set; }
protected int PeerTos { get; private set; }
protected int UtpTcpMixedMode { get; private set; }
protected bool IdnSupportEnabled { get; private set; }
protected bool EnableMultiConnectionsFromSameIp { get; private set; }
protected bool ValidateHttpsTrackerCertificate { get; private set; }
protected bool SsrfMitigation { get; private set; }
protected bool BlockPeersOnPrivilegedPorts { get; private set; }
protected bool EnableEmbeddedTracker { get; private set; }
protected int EmbeddedTrackerPort { get; private set; }
protected bool EmbeddedTrackerPortForwarding { get; private set; }
protected bool MarkOfTheWeb { get; private set; }
protected string? PythonExecutablePath { get; private set; }
protected int UploadSlotsBehavior { get; private set; }
protected int UploadChokingAlgorithm { get; private set; }
protected bool AnnounceToAllTrackers { get; private set; }
protected bool AnnounceToAllTiers { get; private set; }
protected string? AnnounceIp { get; private set; }
protected int MaxConcurrentHttpAnnounces { get; private set; }
protected int StopTrackerTimeout { get; private set; }
protected int PeerTurnover { get; private set; }
protected int PeerTurnoverCutoff { get; private set; }
protected int PeerTurnoverInterval { get; private set; }
protected int RequestQueueSize { get; private set; }
protected string? DhtBootstrapNodes { get; private set; }
protected int I2pInboundQuantity { get; private set; }
protected int I2pOutboundQuantity { get; private set; }
protected int I2pInboundLength { get; private set; }
protected int I2pOutboundLength { get; private set; }
protected IReadOnlyList<NetworkInterface> NetworkInterfaces { get; private set; } = [];
protected IReadOnlyList<string> NetworkInterfaceAddresses { get; private set; } = [];
protected override async Task OnInitializedAsync()
{
NetworkInterfaces = await ApiClient.GetNetworkInterfaces();
}
protected override bool SetOptions()
{
if (Preferences is null)
{
return false;
}
ResumeDataStorageType = Preferences.ResumeDataStorageType;
MemoryWorkingSetLimit = Preferences.MemoryWorkingSetLimit;
CurrentNetworkInterface = Preferences.CurrentNetworkInterface;
CurrentInterfaceAddress = Preferences.CurrentInterfaceAddress;
SaveResumeDataInterval = Preferences.SaveResumeDataInterval;
TorrentFileSizeLimit = Preferences.TorrentFileSizeLimit;
RecheckCompletedTorrents = Preferences.RecheckCompletedTorrents;
AppInstanceName = Preferences.AppInstanceName;
RefreshInterval = Preferences.RefreshInterval;
ResolvePeerCountries = Preferences.ResolvePeerCountries;
ReannounceWhenAddressChanged = Preferences.ReannounceWhenAddressChanged;
BdecodeDepthLimit = Preferences.BdecodeDepthLimit;
BdecodeTokenLimit = Preferences.BdecodeTokenLimit;
AsyncIoThreads = Preferences.AsyncIoThreads;
HashingThreads = Preferences.HashingThreads;
FilePoolSize = Preferences.FilePoolSize;
CheckingMemoryUse = Preferences.CheckingMemoryUse;
DiskCache = Preferences.DiskCache;
DiskCacheTtl = Preferences.DiskCacheTtl;
DiskQueueSize = Preferences.DiskQueueSize;
DiskIoType = Preferences.DiskIoType;
DiskIoReadMode = Preferences.DiskIoReadMode;
DiskIoWriteMode = Preferences.DiskIoWriteMode;
EnableCoalesceReadWrite = Preferences.EnableCoalesceReadWrite;
EnablePieceExtentAffinity = Preferences.EnablePieceExtentAffinity;
EnableUploadSuggestions = Preferences.EnableUploadSuggestions;
SendBufferWatermark = Preferences.SendBufferWatermark;
SendBufferLowWatermark = Preferences.SendBufferLowWatermark;
SendBufferWatermarkFactor = Preferences.SendBufferWatermarkFactor;
ConnectionSpeed = Preferences.ConnectionSpeed;
SocketSendBufferSize = Preferences.SocketSendBufferSize;
SocketReceiveBufferSize = Preferences.SocketReceiveBufferSize;
SocketBacklogSize = Preferences.SocketBacklogSize;
OutgoingPortsMin = Preferences.OutgoingPortsMin;
OutgoingPortsMax = Preferences.OutgoingPortsMax;
UpnpLeaseDuration = Preferences.UpnpLeaseDuration;
PeerTos = Preferences.PeerTos;
UtpTcpMixedMode = Preferences.UtpTcpMixedMode;
IdnSupportEnabled = Preferences.IdnSupportEnabled;
EnableMultiConnectionsFromSameIp = Preferences.EnableMultiConnectionsFromSameIp;
ValidateHttpsTrackerCertificate = Preferences.ValidateHttpsTrackerCertificate;
SsrfMitigation = Preferences.SsrfMitigation;
BlockPeersOnPrivilegedPorts = Preferences.BlockPeersOnPrivilegedPorts;
EnableEmbeddedTracker = Preferences.EnableEmbeddedTracker;
EmbeddedTrackerPort = Preferences.EmbeddedTrackerPort;
EmbeddedTrackerPortForwarding = Preferences.EmbeddedTrackerPortForwarding;
MarkOfTheWeb = Preferences.MarkOfTheWeb;
PythonExecutablePath = Preferences.PythonExecutablePath;
UploadSlotsBehavior = Preferences.UploadSlotsBehavior;
UploadChokingAlgorithm = Preferences.UploadChokingAlgorithm;
AnnounceToAllTrackers = Preferences.AnnounceToAllTrackers;
AnnounceToAllTiers = Preferences.AnnounceToAllTiers;
AnnounceIp = Preferences.AnnounceIp;
MaxConcurrentHttpAnnounces = Preferences.MaxConcurrentHttpAnnounces;
StopTrackerTimeout = Preferences.StopTrackerTimeout;
PeerTurnover = Preferences.PeerTurnover;
PeerTurnoverCutoff = Preferences.PeerTurnoverCutoff;
PeerTurnoverInterval = Preferences.PeerTurnoverInterval;
RequestQueueSize = Preferences.RequestQueueSize;
DhtBootstrapNodes = Preferences.DhtBootstrapNodes;
I2pInboundQuantity = Preferences.I2pInboundQuantity;
I2pOutboundQuantity = Preferences.I2pOutboundQuantity;
I2pInboundLength = Preferences.I2pInboundLength;
I2pOutboundLength = Preferences.I2pOutboundLength;
return true;
}
protected async Task ResumeDataStorageTypeChanged(string value)
{
ResumeDataStorageType = value;
UpdatePreferences.ResumeDataStorageType = value;
await PreferencesChanged.InvokeAsync(UpdatePreferences);
}
protected async Task MemoryWorkingSetLimitChanged(int value)
{
MemoryWorkingSetLimit = value;
UpdatePreferences.MemoryWorkingSetLimit = value;
await PreferencesChanged.InvokeAsync(UpdatePreferences);
}
protected async Task CurrentNetworkInterfaceChanged(string value)
{
CurrentNetworkInterface = value;
UpdatePreferences.CurrentNetworkInterface = value;
await PreferencesChanged.InvokeAsync(UpdatePreferences);
NetworkInterfaceAddresses = await ApiClient.GetNetworkInterfaceAddressList(value);
}
protected async Task CurrentInterfaceAddressChanged(string value)
{
CurrentInterfaceAddress = value;
UpdatePreferences.CurrentInterfaceAddress = value;
await PreferencesChanged.InvokeAsync(UpdatePreferences);
}
protected async Task SaveResumeDataIntervalChanged(int value)
{
SaveResumeDataInterval = value;
UpdatePreferences.SaveResumeDataInterval = value;
await PreferencesChanged.InvokeAsync(UpdatePreferences);
}
protected async Task TorrentFileSizeLimitChanged(int value)
{
TorrentFileSizeLimit = value;
UpdatePreferences.TorrentFileSizeLimit = value;
await PreferencesChanged.InvokeAsync(UpdatePreferences);
}
protected async Task RecheckCompletedTorrentsChanged(bool value)
{
RecheckCompletedTorrents = value;
UpdatePreferences.RecheckCompletedTorrents = value;
await PreferencesChanged.InvokeAsync(UpdatePreferences);
}
protected async Task AppInstanceNameChanged(string value)
{
AppInstanceName = value;
UpdatePreferences.AppInstanceName = value;
await PreferencesChanged.InvokeAsync(UpdatePreferences);
}
protected async Task RefreshIntervalChanged(int value)
{
RefreshInterval = value;
UpdatePreferences.RefreshInterval = value;
await PreferencesChanged.InvokeAsync(UpdatePreferences);
}
protected async Task ResolvePeerCountriesChanged(bool value)
{
ResolvePeerCountries = value;
UpdatePreferences.ResolvePeerCountries = value;
await PreferencesChanged.InvokeAsync(UpdatePreferences);
}
protected async Task ReannounceWhenAddressChangedChanged(bool value)
{
ReannounceWhenAddressChanged = value;
UpdatePreferences.ReannounceWhenAddressChanged = value;
await PreferencesChanged.InvokeAsync(UpdatePreferences);
}
protected async Task BdecodeDepthLimitChanged(int value)
{
BdecodeDepthLimit = value;
UpdatePreferences.BdecodeDepthLimit = value;
await PreferencesChanged.InvokeAsync(UpdatePreferences);
}
protected async Task BdecodeTokenLimitChanged(int value)
{
BdecodeTokenLimit = value;
UpdatePreferences.BdecodeTokenLimit = value;
await PreferencesChanged.InvokeAsync(UpdatePreferences);
}
protected async Task AsyncIoThreadsChanged(int value)
{
AsyncIoThreads = value;
UpdatePreferences.AsyncIoThreads = value;
await PreferencesChanged.InvokeAsync(UpdatePreferences);
}
protected async Task HashingThreadsChanged(int value)
{
HashingThreads = value;
UpdatePreferences.HashingThreads = value;
await PreferencesChanged.InvokeAsync(UpdatePreferences);
}
protected async Task FilePoolSizeChanged(int value)
{
FilePoolSize = value;
UpdatePreferences.FilePoolSize = value;
await PreferencesChanged.InvokeAsync(UpdatePreferences);
}
protected async Task CheckingMemoryUseChanged(int value)
{
CheckingMemoryUse = value;
UpdatePreferences.CheckingMemoryUse = value;
await PreferencesChanged.InvokeAsync(UpdatePreferences);
}
protected async Task DiskCacheChanged(int value)
{
DiskCache = value;
UpdatePreferences.DiskCache = value;
await PreferencesChanged.InvokeAsync(UpdatePreferences);
}
protected async Task DiskCacheTtlChanged(int value)
{
DiskCacheTtl = value;
UpdatePreferences.DiskCacheTtl = value;
await PreferencesChanged.InvokeAsync(UpdatePreferences);
}
protected async Task DiskQueueSizeChanged(int value)
{
DiskQueueSize = value;
UpdatePreferences.DiskQueueSize = value;
await PreferencesChanged.InvokeAsync(UpdatePreferences);
}
protected async Task DiskIoTypeChanged(int value)
{
DiskIoType = value;
UpdatePreferences.DiskIoType = value;
await PreferencesChanged.InvokeAsync(UpdatePreferences);
}
protected async Task DiskIoReadModeChanged(int value)
{
DiskIoReadMode = value;
UpdatePreferences.DiskIoReadMode = value;
await PreferencesChanged.InvokeAsync(UpdatePreferences);
}
protected async Task DiskIoWriteModeChanged(int value)
{
DiskIoWriteMode = value;
UpdatePreferences.DiskIoWriteMode = value;
await PreferencesChanged.InvokeAsync(UpdatePreferences);
}
protected async Task EnableCoalesceReadWriteChanged(bool value)
{
EnableCoalesceReadWrite = value;
UpdatePreferences.EnableCoalesceReadWrite = value;
await PreferencesChanged.InvokeAsync(UpdatePreferences);
}
protected async Task EnablePieceExtentAffinityChanged(bool value)
{
EnablePieceExtentAffinity = value;
UpdatePreferences.EnablePieceExtentAffinity = value;
await PreferencesChanged.InvokeAsync(UpdatePreferences);
}
protected async Task EnableUploadSuggestionsChanged(bool value)
{
EnableUploadSuggestions = value;
UpdatePreferences.EnableUploadSuggestions = value;
await PreferencesChanged.InvokeAsync(UpdatePreferences);
}
protected async Task SendBufferWatermarkChanged(int value)
{
SendBufferWatermark = value;
UpdatePreferences.SendBufferWatermark = value;
await PreferencesChanged.InvokeAsync(UpdatePreferences);
}
protected async Task SendBufferLowWatermarkChanged(int value)
{
SendBufferLowWatermark = value;
UpdatePreferences.SendBufferLowWatermark = value;
await PreferencesChanged.InvokeAsync(UpdatePreferences);
}
protected async Task SendBufferWatermarkFactorChanged(int value)
{
SendBufferWatermarkFactor = value;
UpdatePreferences.SendBufferWatermarkFactor = value;
await PreferencesChanged.InvokeAsync(UpdatePreferences);
}
protected async Task ConnectionSpeedChanged(int value)
{
ConnectionSpeed = value;
UpdatePreferences.ConnectionSpeed = value;
await PreferencesChanged.InvokeAsync(UpdatePreferences);
}
protected async Task SocketSendBufferSizeChanged(int value)
{
SocketSendBufferSize = value;
UpdatePreferences.SocketSendBufferSize = value;
await PreferencesChanged.InvokeAsync(UpdatePreferences);
}
protected async Task SocketReceiveBufferSizeChanged(int value)
{
SocketReceiveBufferSize = value;
UpdatePreferences.SocketReceiveBufferSize = value;
await PreferencesChanged.InvokeAsync(UpdatePreferences);
}
protected async Task SocketBacklogSizeChanged(int value)
{
SocketBacklogSize = value;
UpdatePreferences.SocketBacklogSize = value;
await PreferencesChanged.InvokeAsync(UpdatePreferences);
}
protected async Task OutgoingPortsMinChanged(int value)
{
OutgoingPortsMin = value;
UpdatePreferences.OutgoingPortsMin = value;
await PreferencesChanged.InvokeAsync(UpdatePreferences);
}
protected async Task OutgoingPortsMaxChanged(int value)
{
OutgoingPortsMax = value;
UpdatePreferences.OutgoingPortsMax = value;
await PreferencesChanged.InvokeAsync(UpdatePreferences);
}
protected async Task UpnpLeaseDurationChanged(int value)
{
UpnpLeaseDuration = value;
UpdatePreferences.UpnpLeaseDuration = value;
await PreferencesChanged.InvokeAsync(UpdatePreferences);
}
protected async Task PeerTosChanged(int value)
{
PeerTos = value;
UpdatePreferences.PeerTos = value;
await PreferencesChanged.InvokeAsync(UpdatePreferences);
}
protected async Task UtpTcpMixedModeChanged(int value)
{
UtpTcpMixedMode = value;
UpdatePreferences.UtpTcpMixedMode = value;
await PreferencesChanged.InvokeAsync(UpdatePreferences);
}
protected async Task IdnSupportEnabledChanged(bool value)
{
IdnSupportEnabled = value;
UpdatePreferences.IdnSupportEnabled = value;
await PreferencesChanged.InvokeAsync(UpdatePreferences);
}
protected async Task EnableMultiConnectionsFromSameIpChanged(bool value)
{
EnableMultiConnectionsFromSameIp = value;
UpdatePreferences.EnableMultiConnectionsFromSameIp = value;
await PreferencesChanged.InvokeAsync(UpdatePreferences);
}
protected async Task ValidateHttpsTrackerCertificateChanged(bool value)
{
ValidateHttpsTrackerCertificate = value;
UpdatePreferences.ValidateHttpsTrackerCertificate = value;
await PreferencesChanged.InvokeAsync(UpdatePreferences);
}
protected async Task SsrfMitigationChanged(bool value)
{
SsrfMitigation = value;
UpdatePreferences.SsrfMitigation = value;
await PreferencesChanged.InvokeAsync(UpdatePreferences);
}
protected async Task BlockPeersOnPrivilegedPortsChanged(bool value)
{
BlockPeersOnPrivilegedPorts = value;
UpdatePreferences.BlockPeersOnPrivilegedPorts = value;
await PreferencesChanged.InvokeAsync(UpdatePreferences);
}
protected async Task EnableEmbeddedTrackerChanged(bool value)
{
EnableEmbeddedTracker = value;
UpdatePreferences.EnableEmbeddedTracker = value;
await PreferencesChanged.InvokeAsync(UpdatePreferences);
}
protected async Task EmbeddedTrackerPortChanged(int value)
{
EmbeddedTrackerPort = value;
UpdatePreferences.EmbeddedTrackerPort = value;
await PreferencesChanged.InvokeAsync(UpdatePreferences);
}
protected async Task EmbeddedTrackerPortForwardingChanged(bool value)
{
EmbeddedTrackerPortForwarding = value;
UpdatePreferences.EmbeddedTrackerPortForwarding = value;
await PreferencesChanged.InvokeAsync(UpdatePreferences);
}
protected async Task MarkOfTheWebChanged(bool value)
{
MarkOfTheWeb = value;
UpdatePreferences.MarkOfTheWeb = value;
await PreferencesChanged.InvokeAsync(UpdatePreferences);
}
protected async Task PythonExecutablePathChanged(string value)
{
PythonExecutablePath = value;
UpdatePreferences.PythonExecutablePath = value;
await PreferencesChanged.InvokeAsync(UpdatePreferences);
}
protected async Task UploadSlotsBehaviorChanged(int value)
{
UploadSlotsBehavior = value;
UpdatePreferences.UploadSlotsBehavior = value;
await PreferencesChanged.InvokeAsync(UpdatePreferences);
}
protected async Task UploadChokingAlgorithmChanged(int value)
{
UploadChokingAlgorithm = value;
UpdatePreferences.UploadChokingAlgorithm = value;
await PreferencesChanged.InvokeAsync(UpdatePreferences);
}
protected async Task AnnounceToAllTrackersChanged(bool value)
{
AnnounceToAllTrackers = value;
UpdatePreferences.AnnounceToAllTrackers = value;
await PreferencesChanged.InvokeAsync(UpdatePreferences);
}
protected async Task AnnounceToAllTiersChanged(bool value)
{
AnnounceToAllTiers = value;
UpdatePreferences.AnnounceToAllTiers = value;
await PreferencesChanged.InvokeAsync(UpdatePreferences);
}
protected async Task AnnounceIpChanged(string value)
{
AnnounceIp = value;
UpdatePreferences.AnnounceIp = value;
await PreferencesChanged.InvokeAsync(UpdatePreferences);
}
protected async Task MaxConcurrentHttpAnnouncesChanged(int value)
{
MaxConcurrentHttpAnnounces = value;
UpdatePreferences.MaxConcurrentHttpAnnounces = value;
await PreferencesChanged.InvokeAsync(UpdatePreferences);
}
protected async Task StopTrackerTimeoutChanged(int value)
{
StopTrackerTimeout = value;
UpdatePreferences.StopTrackerTimeout = value;
await PreferencesChanged.InvokeAsync(UpdatePreferences);
}
protected async Task PeerTurnoverChanged(int value)
{
PeerTurnover = value;
UpdatePreferences.PeerTurnover = value;
await PreferencesChanged.InvokeAsync(UpdatePreferences);
}
protected async Task PeerTurnoverCutoffChanged(int value)
{
PeerTurnoverCutoff = value;
UpdatePreferences.PeerTurnoverCutoff = value;
await PreferencesChanged.InvokeAsync(UpdatePreferences);
}
protected async Task PeerTurnoverIntervalChanged(int value)
{
PeerTurnoverInterval = value;
UpdatePreferences.PeerTurnoverInterval = value;
await PreferencesChanged.InvokeAsync(UpdatePreferences);
}
protected async Task RequestQueueSizeChanged(int value)
{
RequestQueueSize = value;
UpdatePreferences.RequestQueueSize = value;
await PreferencesChanged.InvokeAsync(UpdatePreferences);
}
protected async Task DhtBootstrapNodesChanged(string value)
{
DhtBootstrapNodes = value;
UpdatePreferences.DhtBootstrapNodes = value;
await PreferencesChanged.InvokeAsync(UpdatePreferences);
}
protected async Task I2pInboundQuantityChanged(int value)
{
I2pInboundQuantity = value;
UpdatePreferences.I2pInboundQuantity = value;
await PreferencesChanged.InvokeAsync(UpdatePreferences);
}
protected async Task I2pOutboundQuantityChanged(int value)
{
I2pOutboundQuantity = value;
UpdatePreferences.I2pOutboundQuantity = value;
await PreferencesChanged.InvokeAsync(UpdatePreferences);
}
protected async Task I2pInboundLengthChanged(int value)
{
I2pInboundLength = value;
UpdatePreferences.I2pInboundLength = value;
await PreferencesChanged.InvokeAsync(UpdatePreferences);
}
protected async Task I2pOutboundLengthChanged(int value)
{
I2pOutboundLength = value;
UpdatePreferences.I2pOutboundLength = value;
await PreferencesChanged.InvokeAsync(UpdatePreferences);
}
}
}

View File

@@ -3,13 +3,13 @@
<MudCard Elevation="1" Class="ml-4 mr-4 mb-4 mt-4">
<MudCardHeader>
<CardHeaderContent>
<MudText Typo="Typo.h6">Language</MudText>
<MudText Typo="Typo.subtitle2">Language</MudText>
</CardHeaderContent>
</MudCardHeader>
<MudCardContent Class="pt-0">
<MudGrid>
<MudItem xs="12">
<MudSelect T="string" Label="User Interface Language" Value="@("en-US")">
<MudSelect T="string" Label="User Interface Language" Value="@("en-US")" ShrinkLabel Variant="Variant.Outlined">
<MudSelectItem Value="@("en-US")">English</MudSelectItem>
</MudSelect>
</MudItem>
@@ -20,33 +20,33 @@
<MudCard Elevation="1" Class="ml-4 mr-4 mb-4">
<MudCardHeader>
<CardHeaderContent>
<MudText Typo="Typo.h6">Log File</MudText>
<MudText Typo="Typo.subtitle2">Log File</MudText>
</CardHeaderContent>
</MudCardHeader>
<MudCardContent Class="pt-0">
<MudGrid>
<MudItem xs="12">
<MudCheckBox T="bool" Label="Log file" Value="FileLogEnabled" ValueChanged="FileLogEnabledChanged" LabelPosition="LabelPosition.End" />
<MudSwitch T="bool" Label="Log file" Value="FileLogEnabled" ValueChanged="FileLogEnabledChanged" LabelPosition="LabelPosition.End" />
</MudItem>
<MudItem xs="12">
<MudTextField T="string" Label="Save Path" Value="FileLogPath" ValueChanged="FileLogPathChanged" Disabled="@(!FileLogEnabled)" />
<MudTextField T="string" Label="Save Path" Value="FileLogPath" ValueChanged="FileLogPathChanged" Disabled="@(!FileLogEnabled)" ShrinkLabel Variant="Variant.Outlined" />
</MudItem>
<MudItem xs="3">
<MudCheckBox T="bool" Label="Backup the log after" Value="FileLogBackupEnabled" ValueChanged="FileLogBackupEnabledChanged" Disabled="@(!FileLogEnabled)" LabelPosition="LabelPosition.End" />
<MudSwitch T="bool" Label="Backup the log after" Value="FileLogBackupEnabled" ValueChanged="FileLogBackupEnabledChanged" Disabled="@(!FileLogEnabled)" LabelPosition="LabelPosition.End" />
</MudItem>
<MudItem xs="9">
<MudNumericField T="int" Label="KiB" Value="FileLogMaxSize" ValueChanged="FileLogMaxSizeChanged" Disabled="@(!FileLogEnabled)" ShrinkLabel Min="1" />
<MudNumericField T="int" Label="KiB" Value="FileLogMaxSize" ValueChanged="FileLogMaxSizeChanged" Disabled="@(!FileLogEnabled)" Min="1" ShrinkLabel Variant="Variant.Outlined" HelperText="KiB" />
</MudItem>
<MudItem xs="3">
<MudCheckBox T="bool" Label="Delete backups older than" Value="FileLogDeleteOld" ValueChanged="FileLogDeleteOldChanged" Disabled="@(!FileLogEnabled)" LabelPosition="LabelPosition.End" />
<MudSwitch T="bool" Label="Delete backups older than" Value="FileLogDeleteOld" ValueChanged="FileLogDeleteOldChanged" Disabled="@(!FileLogEnabled)" LabelPosition="LabelPosition.End" />
</MudItem>
<MudItem xs="9">
<MudGrid>
<MudItem xs="9">
<MudNumericField T="int" Value="FileLogAge" ValueChanged="FileLogAgeChanged" Disabled="@(!FileLogEnabled)" ShrinkLabel Min="1" />
<MudNumericField T="int" Value="FileLogAge" ValueChanged="FileLogAgeChanged" Disabled="@(!FileLogEnabled)" Min="1" ShrinkLabel Variant="Variant.Outlined" />
</MudItem>
<MudItem xs="3">
<MudSelect T="int" Value="FileLogAgeType" ValueChanged="FileLogAgeTypeChanged" Disabled="@(!FileLogEnabled)" ShrinkLabel>
<MudSelect T="int" Value="FileLogAgeType" ValueChanged="FileLogAgeTypeChanged" Disabled="@(!FileLogEnabled)" ShrinkLabel Variant="Variant.Outlined">
<MudSelectItem Value="0">days</MudSelectItem>
<MudSelectItem Value="1">months</MudSelectItem>
<MudSelectItem Value="2">years</MudSelectItem>
@@ -59,10 +59,15 @@
</MudCard>
<MudCard Elevation="1" Class="ml-4 mr-4 mb-4">
<MudCardHeader>
<CardHeaderContent>
<MudText Typo="Typo.subtitle2">Performance</MudText>
</CardHeaderContent>
</MudCardHeader>
<MudCardContent>
<MudGrid>
<MudItem xs="12">
<MudCheckBox T="bool" Label="Log performance warnings" Value="PerformanceWarning" ValueChanged="PerformanceWarningChanged" LabelPosition="LabelPosition.End" />
<MudFieldSwitch Label="Log performance warnings" Value="PerformanceWarning" ValueChanged="PerformanceWarningChanged" />
</MudItem>
</MudGrid>
</MudCardContent>

View File

@@ -3,12 +3,133 @@
<MudCard Elevation="1" Class="ml-4 mr-4 mb-4 mt-4">
<MudCardHeader>
<CardHeaderContent>
<MudText Typo="Typo.h6"></MudText>
<MudText Typo="Typo.subtitle2">Privacy</MudText>
</CardHeaderContent>
</MudCardHeader>
<MudCardContent Class="pt-0">
<MudGrid>
<MudItem xs="12">
<MudCheckBox T="bool" Label="Enable DHT (decentralized network) to find more peers" Value="Dht" ValueChanged="DhtChanged" LabelPosition="LabelPosition.End" />
</MudItem>
<MudItem xs="12">
<MudCheckBox T="bool" Label="Enable Peer Exchange (PeX) to find more peers" Value="Pex" ValueChanged="PexChanged" LabelPosition="LabelPosition.End" />
</MudItem>
<MudItem xs="12">
<MudCheckBox T="bool" Label="Enable Local Peer Discovery to find more peers" Value="Lsd" ValueChanged="LsdChanged" LabelPosition="LabelPosition.End" />
</MudItem>
<MudItem xs="12">
<MudSelect T="int" Label="Encryption mode" Value="Encryption" ValueChanged="EncryptionChanged" ShrinkLabel Variant="Variant.Outlined">
<MudSelectItem Value="0">Allow encryption</MudSelectItem>
<MudSelectItem Value="1">Require encryption</MudSelectItem>
<MudSelectItem Value="2">Disable encryption</MudSelectItem>
</MudSelect>
</MudItem>
<MudItem xs="12">
<MudCheckBox T="bool" Label="Enable anonymous mode" Value="AnonymousMode" ValueChanged="AnonymousModeChanged" LabelPosition="LabelPosition.End" />
<MudLink Href="https://github.com/qbittorrent/qBittorrent/wiki/Anonymous-Mode" Underline="Underline.Always" Target="https://github.com/qbittorrent/qBittorrent/wiki/Anonymous-Mode">More information</MudLink>
</MudItem>
</MudGrid>
</MudCardContent>
</MudCard>
<MudCard Elevation="1" Class="ml-4 mr-4 mb-4 mt-4">
<MudCardContent Class="pt-0">
<MudGrid>
<MudItem xs="12">
<MudNumericField T="int" Label="Max active checking torrents" Value="MaxActiveCheckingTorrents" ValueChanged="MaxActiveCheckingTorrentsChanged" Min="0" ShrinkLabel Variant="Variant.Outlined" />
</MudItem>
</MudGrid>
</MudCardContent>
</MudCard>
<MudCard Elevation="1" Class="ml-4 mr-4 mb-4">
<MudCardHeader>
<CardHeaderContent>
<MudText Typo="Typo.subtitle2">Torrent Queueing</MudText>
</CardHeaderContent>
</MudCardHeader>
<MudCardContent Class="pt-0">
<MudGrid>
<MudItem xs="12">
<MudCheckBox T="bool" Label="Queueing enabled" Value="QueueingEnabled" ValueChanged="QueueingEnabledChanged" LabelPosition="LabelPosition.End" />
</MudItem>
<MudItem xs="12">
<MudNumericField T="int" Label="Maximum active downloads" Value="MaxActiveDownloads" ValueChanged="MaxActiveDownloadsChanged" Min="0" Disabled="@(!QueueingEnabled)" ShrinkLabel Variant="Variant.Outlined" />
</MudItem>
<MudItem xs="12">
<MudNumericField T="int" Label="Maximum active uploads" Value="MaxActiveUploads" ValueChanged="MaxActiveUploadsChanged" Min="0" Disabled="@(!QueueingEnabled)" ShrinkLabel Variant="Variant.Outlined" />
</MudItem>
<MudItem xs="12">
<MudNumericField T="int" Label="Maximum active torrents" Value="MaxActiveTorrents" ValueChanged="MaxActiveTorrentsChanged" Min="0" Disabled="@(!QueueingEnabled)" ShrinkLabel Variant="Variant.Outlined" />
</MudItem>
<MudItem xs="12">
<MudCheckBox T="bool" Label="Do not count slow torrents in these limits" Value="DontCountSlowTorrents" ValueChanged="DontCountSlowTorrentsChanged" LabelPosition="LabelPosition.End" Disabled="@(!QueueingEnabled)" />
</MudItem>
<MudItem xs="12">
<MudNumericField T="int" Label="Download rate threshold" Value="SlowTorrentDlRateThreshold" ValueChanged="SlowTorrentDlRateThresholdChanged" Min="0" ShrinkLabel Variant="Variant.Outlined" /> <MudText Typo="Typo.caption">KiB/s</MudText>
</MudItem>
<MudItem xs="12">
<MudNumericField T="int" Label="Upload rate threshold" Value="SlowTorrentUlRateThreshold" ValueChanged="SlowTorrentUlRateThresholdChanged" Min="0" ShrinkLabel Variant="Variant.Outlined" /> <MudText Typo="Typo.caption">KiB/s</MudText>
</MudItem>
<MudItem xs="12">
<MudNumericField T="int" Label="Torrent inactivity timer" Value="SlowTorrentInactiveTimer" ValueChanged="SlowTorrentInactiveTimerChanged" Min="0" ShrinkLabel Variant="Variant.Outlined" /> <MudText Typo="Typo.caption">seconds</MudText>
</MudItem>
</MudGrid>
</MudCardContent>
</MudCard>
<MudCard Elevation="1" Class="ml-4 mr-4 mb-4">
<MudCardHeader>
<CardHeaderContent>
<MudText Typo="Typo.subtitle2">Seeding Limits</MudText>
</CardHeaderContent>
</MudCardHeader>
<MudCardContent Class="pt-0">
<MudGrid>
<MudItem xs="3">
<MudCheckBox T="bool" Label="When ratio reaches" Value="MaxRatioEnabled" ValueChanged="MaxRatioEnabledChanged" LabelPosition="LabelPosition.End" />
</MudItem>
<MudItem xs="9">
<MudNumericField T="int" Label="" Value="MaxRatio" ValueChanged="MaxRatioChanged" Disabled="@(!MaxRatioEnabled)" Min="1" ShrinkLabel Variant="Variant.Outlined" />
</MudItem>
<MudItem xs="3">
<MudCheckBox T="bool" Label="When total seeding time reaches" Value="MaxSeedingTimeEnabled" ValueChanged="MaxSeedingTimeEnabledChanged" LabelPosition="LabelPosition.End" />
</MudItem>
<MudItem xs="9">
<MudNumericField T="int" Label="minutes" Value="MaxSeedingTime" ValueChanged="MaxSeedingTimeChanged" Disabled="@(!MaxSeedingTimeEnabled)" Min="1" ShrinkLabel Variant="Variant.Outlined" />
</MudItem>
<MudItem xs="3">
<MudCheckBox T="bool" Label="When inactive seeding time reaches" Value="MaxInactiveSeedingTimeEnabled" ValueChanged="MaxInactiveSeedingTimeEnabledChanged" LabelPosition="LabelPosition.End" />
</MudItem>
<MudItem xs="9">
<MudNumericField T="int" Label="minutes" Value="MaxInactiveSeedingTime" ValueChanged="MaxInactiveSeedingTimeChanged" Disabled="@(!MaxInactiveSeedingTimeEnabled)" Min="1" ShrinkLabel Variant="Variant.Outlined" />
</MudItem>
<MudItem xs="12">
<MudSelect T="int" Value="MaxRatioAct" ValueChanged="MaxRatioActChanged" Disabled="@(!MaxRatioEnabled && !MaxSeedingTimeEnabled && !MaxInactiveSeedingTimeEnabled)" ShrinkLabel Variant="Variant.Outlined">
<MudSelectItem Value="0">Stop torrent</MudSelectItem>
<MudSelectItem Value="1">Remove torrent</MudSelectItem>
<MudSelectItem Value="2">Remove torrent and its files</MudSelectItem>
<MudSelectItem Value="3">Enable super seeding for torrent</MudSelectItem>
</MudSelect>
</MudItem>
</MudGrid>
</MudCardContent>
</MudCard>
<MudCard Elevation="1" Class="ml-4 mr-4 mb-4">
<MudCardHeader>
<CardHeaderContent>
<MudText Typo="Typo.subtitle2">Seeding Limits</MudText>
</CardHeaderContent>
</MudCardHeader>
<MudCardContent Class="pt-0">
<MudGrid>
<MudItem xs="12">
<MudCheckBox T="bool" Label="Automatically add these trackers to new downloads" Value="AddTrackersEnabled" ValueChanged="AddTrackersEnabledChanged" LabelPosition="LabelPosition.End" />
</MudItem>
<MudItem xs="12">
<MudTextField T="string" Label="Trackers" Value="AddTrackers" ValueChanged="AddTrackersChanged" Lines="5" ShrinkLabel Variant="Variant.Outlined" />
</MudItem>
</MudGrid>
</MudCardContent>
</MudCard>

View File

@@ -2,9 +2,223 @@
{
public partial class BitTorrentOptions : Options
{
protected bool Dht { get; private set; }
protected bool Pex { get; private set; }
protected bool Lsd { get; private set; }
protected int Encryption { get; private set; }
protected bool AnonymousMode { get; private set; }
protected int MaxActiveCheckingTorrents { get; private set; }
protected bool QueueingEnabled { get; private set; }
protected int MaxActiveDownloads { get; private set; }
protected int MaxActiveUploads { get; private set; }
protected int MaxActiveTorrents { get; private set; }
protected bool DontCountSlowTorrents { get; private set; }
protected int SlowTorrentDlRateThreshold { get; private set; }
protected int SlowTorrentUlRateThreshold { get; private set; }
protected int SlowTorrentInactiveTimer { get; private set; }
protected bool MaxRatioEnabled { get; private set; }
protected int MaxRatio { get; private set; }
protected bool MaxSeedingTimeEnabled { get; private set; }
protected int MaxSeedingTime { get; private set; }
protected int MaxRatioAct { get; private set; }
protected bool MaxInactiveSeedingTimeEnabled { get; private set; }
protected int MaxInactiveSeedingTime { get; private set; }
protected bool AddTrackersEnabled { get; private set; }
protected string? AddTrackers { get; private set; }
protected override bool SetOptions()
{
if (Preferences is null)
{
return false;
}
Dht = Preferences.Dht;
Pex = Preferences.Pex;
Lsd = Preferences.Lsd;
Encryption = Preferences.Encryption;
AnonymousMode = Preferences.AnonymousMode;
MaxActiveCheckingTorrents = Preferences.MaxActiveCheckingTorrents;
QueueingEnabled = Preferences.QueueingEnabled;
MaxActiveDownloads = Preferences.MaxActiveDownloads;
MaxActiveUploads = Preferences.MaxActiveUploads;
MaxActiveTorrents = Preferences.MaxActiveTorrents;
DontCountSlowTorrents = Preferences.DontCountSlowTorrents;
SlowTorrentDlRateThreshold = Preferences.SlowTorrentDlRateThreshold;
SlowTorrentUlRateThreshold = Preferences.SlowTorrentUlRateThreshold;
SlowTorrentInactiveTimer = Preferences.SlowTorrentInactiveTimer;
MaxRatioEnabled = Preferences.MaxRatioEnabled;
MaxRatio = Preferences.MaxRatio;
MaxSeedingTimeEnabled = Preferences.MaxSeedingTimeEnabled;
MaxSeedingTime = Preferences.MaxSeedingTime;
MaxRatioAct = Preferences.MaxRatioAct;
MaxInactiveSeedingTimeEnabled = Preferences.MaxInactiveSeedingTimeEnabled;
MaxInactiveSeedingTime = Preferences.MaxInactiveSeedingTime;
AddTrackersEnabled = Preferences.AddTrackersEnabled;
AddTrackers = Preferences.AddTrackers;
return true;
}
protected async Task DhtChanged(bool value)
{
Dht = value;
UpdatePreferences.Dht = value;
await PreferencesChanged.InvokeAsync(UpdatePreferences);
}
protected async Task PexChanged(bool value)
{
Pex = value;
UpdatePreferences.Pex = value;
await PreferencesChanged.InvokeAsync(UpdatePreferences);
}
protected async Task LsdChanged(bool value)
{
Lsd = value;
UpdatePreferences.Lsd = value;
await PreferencesChanged.InvokeAsync(UpdatePreferences);
}
protected async Task EncryptionChanged(int value)
{
Encryption = value;
UpdatePreferences.Encryption = value;
await PreferencesChanged.InvokeAsync(UpdatePreferences);
}
protected async Task AnonymousModeChanged(bool value)
{
AnonymousMode = value;
UpdatePreferences.AnonymousMode = value;
await PreferencesChanged.InvokeAsync(UpdatePreferences);
}
protected async Task MaxActiveCheckingTorrentsChanged(int value)
{
MaxActiveCheckingTorrents = value;
UpdatePreferences.MaxActiveCheckingTorrents = value;
await PreferencesChanged.InvokeAsync(UpdatePreferences);
}
protected async Task QueueingEnabledChanged(bool value)
{
QueueingEnabled = value;
UpdatePreferences.QueueingEnabled = value;
await PreferencesChanged.InvokeAsync(UpdatePreferences);
}
protected async Task MaxActiveDownloadsChanged(int value)
{
MaxActiveDownloads = value;
UpdatePreferences.MaxActiveDownloads = value;
await PreferencesChanged.InvokeAsync(UpdatePreferences);
}
protected async Task MaxActiveUploadsChanged(int value)
{
MaxActiveUploads = value;
UpdatePreferences.MaxActiveUploads = value;
await PreferencesChanged.InvokeAsync(UpdatePreferences);
}
protected async Task MaxActiveTorrentsChanged(int value)
{
MaxActiveTorrents = value;
UpdatePreferences.MaxActiveTorrents = value;
await PreferencesChanged.InvokeAsync(UpdatePreferences);
}
protected async Task DontCountSlowTorrentsChanged(bool value)
{
DontCountSlowTorrents = value;
UpdatePreferences.DontCountSlowTorrents = value;
await PreferencesChanged.InvokeAsync(UpdatePreferences);
}
protected async Task SlowTorrentDlRateThresholdChanged(int value)
{
SlowTorrentDlRateThreshold = value;
UpdatePreferences.SlowTorrentDlRateThreshold = value;
await PreferencesChanged.InvokeAsync(UpdatePreferences);
}
protected async Task SlowTorrentUlRateThresholdChanged(int value)
{
SlowTorrentUlRateThreshold = value;
UpdatePreferences.SlowTorrentUlRateThreshold = value;
await PreferencesChanged.InvokeAsync(UpdatePreferences);
}
protected async Task SlowTorrentInactiveTimerChanged(int value)
{
SlowTorrentInactiveTimer = value;
UpdatePreferences.SlowTorrentInactiveTimer = value;
await PreferencesChanged.InvokeAsync(UpdatePreferences);
}
protected async Task MaxRatioEnabledChanged(bool value)
{
MaxRatioEnabled = value;
UpdatePreferences.MaxRatioEnabled = value;
await PreferencesChanged.InvokeAsync(UpdatePreferences);
}
protected async Task MaxRatioChanged(int value)
{
MaxRatio = value;
UpdatePreferences.MaxRatio = value;
await PreferencesChanged.InvokeAsync(UpdatePreferences);
}
protected async Task MaxSeedingTimeEnabledChanged(bool value)
{
MaxSeedingTimeEnabled = value;
UpdatePreferences.MaxSeedingTimeEnabled = value;
await PreferencesChanged.InvokeAsync(UpdatePreferences);
}
protected async Task MaxSeedingTimeChanged(int value)
{
MaxSeedingTime = value;
UpdatePreferences.MaxSeedingTime = value;
await PreferencesChanged.InvokeAsync(UpdatePreferences);
}
protected async Task MaxRatioActChanged(int value)
{
MaxRatioAct = value;
UpdatePreferences.MaxRatioAct = value;
await PreferencesChanged.InvokeAsync(UpdatePreferences);
}
protected async Task MaxInactiveSeedingTimeEnabledChanged(bool value)
{
MaxInactiveSeedingTimeEnabled = value;
UpdatePreferences.MaxInactiveSeedingTimeEnabled = value;
await PreferencesChanged.InvokeAsync(UpdatePreferences);
}
protected async Task MaxInactiveSeedingTimeChanged(int value)
{
MaxInactiveSeedingTime = value;
UpdatePreferences.MaxInactiveSeedingTime = value;
await PreferencesChanged.InvokeAsync(UpdatePreferences);
}
protected async Task AddTrackersEnabledChanged(bool value)
{
AddTrackersEnabled = value;
UpdatePreferences.AddTrackersEnabled = value;
await PreferencesChanged.InvokeAsync(UpdatePreferences);
}
protected async Task AddTrackersChanged(string value)
{
AddTrackers = value;
UpdatePreferences.AddTrackers = value;
await PreferencesChanged.InvokeAsync(UpdatePreferences);
}
}
}
}

View File

@@ -4,7 +4,7 @@
<MudCardContent>
<MudGrid>
<MudItem xs="12">
<MudSelect T="int" Label="Peer connection protocol" Value="BittorrentProtocol" ValueChanged="BittorrentProtocolChanged">
<MudSelect T="int" Label="Peer connection protocol" Value="BittorrentProtocol" ValueChanged="BittorrentProtocolChanged" ShrinkLabel Variant="Variant.Outlined">
<MudSelectItem T="int" Value="0">TCP and μTP</MudSelectItem>
<MudSelectItem T="int" Value="1">TCP</MudSelectItem>
<MudSelectItem T="int" Value="2">μTP</MudSelectItem>
@@ -17,16 +17,19 @@
<MudCard Elevation="1" Class="ml-4 mr-4 mb-4">
<MudCardHeader>
<CardHeaderContent>
<MudText Typo="Typo.h6">Listening Port</MudText>
<MudText Typo="Typo.subtitle2">Listening Port</MudText>
</CardHeaderContent>
</MudCardHeader>
<MudCardContent Class="pt-0">
<MudGrid>
<MudItem xs="11">
<MudNumericField T="int" Label="Port used for incoming connections" Value="ListenPort" ValueChanged="ListenPortChanged" Min="@MinPortValue" Max="@MaxPortValue" />
<MudItem xs="10">
<MudNumericField T="int" Label="Port used for incoming connections" Value="ListenPort" ValueChanged="ListenPortChanged" Min="@MinPortValue" Max="@MaxPortValue" ShrinkLabel Variant="Variant.Outlined" />
</MudItem>
<MudItem xs="1">
<MudButton OnClick="GenerateRandomPort">Random</MudButton>
<MudButton OnClick="GenerateRandomPort" Variant="Variant.Filled" FullWidth="true">Random</MudButton>
</MudItem>
<MudItem xs="1">
<MudButton OnClick="UseSystemPort" Variant="Variant.Filled" FullWidth="true">Let System Decide</MudButton>
</MudItem>
<MudItem xs="12">
<MudCheckBox T="bool" Label="Use UPnp / NAT-PMP port forwarding from my router" Value="Upnp" ValueChanged="UpnpChanged" LabelPosition="LabelPosition.End" />
@@ -38,7 +41,7 @@
<MudCard Elevation="1" Class="ml-4 mr-4 mb-4">
<MudCardHeader>
<CardHeaderContent>
<MudText Typo="Typo.h6">Connections Limits</MudText>
<MudText Typo="Typo.subtitle2">Connections Limits</MudText>
</CardHeaderContent>
</MudCardHeader>
<MudCardContent Class="pt-0">
@@ -47,25 +50,122 @@
<MudCheckBox T="bool" Label="Global maximum number of connections" Value="MaxConnecEnabled" ValueChanged="MaxConnecEnabledChanged" LabelPosition="LabelPosition.End" />
</MudItem>
<MudItem xs="12" md="6">
<MudNumericField T="int" Label="Connections" Value="MaxConnec" ValueChanged="MaxConnecChanged" ShrinkLabel Min="1" Disabled="@(!MaxConnecEnabled)" />
<MudNumericField T="int" Label="Connections" Value="MaxConnec" ValueChanged="MaxConnecChanged" Min="1" Disabled="@(!MaxConnecEnabled)" ShrinkLabel Variant="Variant.Outlined" />
</MudItem>
<MudItem xs="12" md="6">
<MudCheckBox T="bool" Label="Maximum number of connections per torrent" Value="MaxConnecPerTorrentEnabled" ValueChanged="MaxConnecPerTorrentEnabledChanged" LabelPosition="LabelPosition.End" />
</MudItem>
<MudItem xs="12" md="6">
<MudNumericField T="int" Label="Connections" Value="MaxConnecPerTorrent" ValueChanged="MaxConnecPerTorrentChanged" ShrinkLabel Min="1" Disabled="@(!MaxConnecPerTorrentEnabled)" />
<MudNumericField T="int" Label="Connections" Value="MaxConnecPerTorrent" ValueChanged="MaxConnecPerTorrentChanged" Min="1" Disabled="@(!MaxConnecPerTorrentEnabled)" ShrinkLabel Variant="Variant.Outlined" />
</MudItem>
<MudItem xs="12" md="6">
<MudCheckBox T="bool" Label="Global maximum number of upload slots" Value="MaxUploadsEnabled" ValueChanged="MaxUploadsEnabledChanged" LabelPosition="LabelPosition.End" />
</MudItem>
<MudItem xs="12" md="6">
<MudNumericField T="int" Label="Slots" Value="MaxUploads" ValueChanged="MaxUploadsChanged" ShrinkLabel Min="1" Disabled="@(!MaxUploadsEnabled)" />
<MudNumericField T="int" Label="Slots" Value="MaxUploads" ValueChanged="MaxUploadsChanged" Min="1" Disabled="@(!MaxUploadsEnabled)" ShrinkLabel Variant="Variant.Outlined" />
</MudItem>
<MudItem xs="12" md="6">
<MudCheckBox T="bool" Label="Maximum number of upload slots per torrent" Value="MaxUploadsPerTorrentEnabled" ValueChanged="MaxUploadsPerTorrentEnabledChanged" LabelPosition="LabelPosition.End" />
</MudItem>
<MudItem xs="12" md="6">
<MudNumericField T="int" Label="Slots" Value="MaxUploadsPerTorrent" ValueChanged="MaxUploadsPerTorrentChanged" ShrinkLabel Min="1" Disabled="@(!MaxUploadsPerTorrentEnabled)" />
<MudNumericField T="int" Label="Slots" Value="MaxUploadsPerTorrent" ValueChanged="MaxUploadsPerTorrentChanged" Disabled="@(!MaxUploadsPerTorrentEnabled)" ShrinkLabel Variant="Variant.Outlined" />
</MudItem>
</MudGrid>
</MudCardContent>
</MudCard>
<MudCard Elevation="1" Class="ml-4 mr-4 mb-4">
<MudCardContent Class="pt-0">
<MudGrid>
<MudItem xs="12">
<MudCheckBox T="bool" Label="I2P (Experimental)" Value="I2pEnabled" ValueChanged="I2pEnabledChanged" LabelPosition="LabelPosition.End" />
</MudItem>
<MudItem xs="12" md="6">
<MudTextField T="string" Label="Host" Value="I2pAddress" ValueChanged="I2pAddressChanged" Disabled="@(!I2pEnabled)" ShrinkLabel Variant="Variant.Outlined" />
</MudItem>
<MudItem xs="12" md="6">
<MudNumericField T="int" Label="Slots" Value="I2pPort" ValueChanged="I2pPortChanged" Min="0" Max="65535" Disabled="@(!I2pEnabled)" ShrinkLabel Variant="Variant.Outlined" />
</MudItem>
<MudItem xs="12">
<MudCheckBox T="bool" Label="Mixed mode" Value="I2pMixedMode" ValueChanged="I2pMixedModeChanged" Disabled="@(!I2pEnabled)" LabelPosition="LabelPosition.End" title="If &quot;mixed mode&quot; is enabled, I2P torrents are allowed to also get peers from other sources than the tracker, and connect to regular IPs, not providing any anonymization. This may be useful if the user is not interested in the anonymization of I2P, but still wants to be able to connect to I2P peers." />
</MudItem>
</MudGrid>
</MudCardContent>
</MudCard>
<MudCard Elevation="1" Class="ml-4 mr-4 mb-4">
<MudCardHeader>
<CardHeaderContent>
<MudText Typo="Typo.subtitle2">Proxy Server</MudText>
</CardHeaderContent>
</MudCardHeader>
<MudCardContent Class="pt-0">
<MudGrid>
<MudItem xs="12" md="4">
<MudSelect T="string" Label="Type" Value="ProxyType" ValueChanged="ProxyTypeChanged" ShrinkLabel Variant="Variant.Outlined">
<MudSelectItem T="string" Value="@("None")">None</MudSelectItem>
<MudSelectItem T="string" Value="@("SOCKS4")">SOCKS4</MudSelectItem>
<MudSelectItem T="string" Value="@("SOCKS5")">SOCKS5</MudSelectItem>
<MudSelectItem T="string" Value="@("HTTP")">HTTP</MudSelectItem>
</MudSelect>
</MudItem>
<MudItem xs="12" md="4">
<MudTextField T="string" Label="Host" Value="ProxyIp" ValueChanged="ProxyIpChanged" Disabled="ProxyDisabled" ShrinkLabel Variant="Variant.Outlined" />
</MudItem>
<MudItem xs="12" md="4">
<MudNumericField T="int" Label="Port" Value="ProxyPort" ValueChanged="ProxyPortChanged" Min="@ConnectionOptions.MinPortValue" Max="@ConnectionOptions.MaxPortValue" Disabled="ProxyDisabled" ShrinkLabel Variant="Variant.Outlined" />
</MudItem>
<MudItem xs="12">
<MudCheckBox T="bool" Label="Perform hostname lookup via proxy" Value="ProxyHostnameLookup" ValueChanged="ProxyHostnameLookupChanged" LabelPosition="LabelPosition.End" title="If checked, hostname lookups are done via the proxy." />
</MudItem>
<MudItem xs="12">
<MudCheckBox T="bool" Label="Authentication" Value="ProxyAuthEnabled" ValueChanged="ProxyAuthEnabledChanged" LabelPosition="LabelPosition.End" Disabled="@(ProxyDisabled || ProxySocks4)" />
</MudItem>
<MudItem xs="12" md="6">
<MudTextField T="string" Label="Username" Value="ProxyUsername" ValueChanged="ProxyUsernameChanged" Disabled="@(ProxyDisabled || ProxySocks4)" ShrinkLabel Variant="Variant.Outlined" />
</MudItem>
<MudItem xs="12" md="6">
<MudTextField T="string" Label="Password" Value="ProxyPassword" ValueChanged="ProxyPasswordChanged" Disabled="@(ProxyDisabled || ProxySocks4)" ShrinkLabel Variant="Variant.Outlined"/>
</MudItem>
<MudItem xs="12">
<MudAlert Severity="Severity.Info">Info: The password is saved unencrypted</MudAlert>
</MudItem>
<MudItem xs="12">
<MudCheckBox T="bool" Label="Use proxy for BitTorrent purposes" Value="ProxyBittorrent" ValueChanged="ProxyBittorrentChanged" LabelPosition="LabelPosition.End" Disabled="ProxyDisabled" />
</MudItem>
<MudItem xs="12">
<MudCheckBox T="bool" Label="Use proxy for peer connections" Value="ProxyPeerConnections" ValueChanged="ProxyPeerConnectionsChanged" LabelPosition="LabelPosition.End" Disabled="@(ProxyDisabled || ProxyAuthEnabled)" />
</MudItem>
<MudItem xs="12">
<MudCheckBox T="bool" Label="Use proxy for RSS purposes" Value="ProxyRss" ValueChanged="ProxyRssChanged" LabelPosition="LabelPosition.End" Disabled="@(ProxyDisabled || ProxySocks4)" />
</MudItem>
<MudItem xs="12">
<MudCheckBox T="bool" Label="Use proxy for general purposes" Value="ProxyMisc" ValueChanged="ProxyMiscChanged" LabelPosition="LabelPosition.End" Disabled="@(ProxyDisabled || ProxySocks4)" />
</MudItem>
</MudGrid>
</MudCardContent>
</MudCard>
<MudCard Elevation="1" Class="ml-4 mr-4 mb-4">
<MudCardHeader>
<CardHeaderContent>
<MudText Typo="Typo.subtitle2">IP Filtering</MudText>
</CardHeaderContent>
</MudCardHeader>
<MudCardContent Class="pt-0">
<MudGrid>
<MudItem xs="12">
<MudCheckBox T="bool" Label="IP Filter" Value="IpFilterEnabled" ValueChanged="IpFilterEnabledChanged" LabelPosition="LabelPosition.End" />
</MudItem>
<MudItem xs="12">
<MudTextField T="string" Label="Filter path (.dat, .p2p, .p2b)" Value="IpFilterPath" ValueChanged="IpFilterPathChanged" Disabled="@(!IpFilterEnabled)" ShrinkLabel Variant="Variant.Outlined" />
</MudItem>
<MudItem xs="12">
<MudCheckBox T="bool" Label="Apply to trackers" Value="IpFilterTrackers" ValueChanged="IpFilterTrackersChanged" LabelPosition="LabelPosition.End" />
</MudItem>
<MudItem xs="12">
<MudTextField T="string" Label="Manually banned IP addresses" Value="BannedIPs" ValueChanged="BannedIPsChanged" Lines="5" ShrinkLabel Variant="Variant.Outlined" />
</MudItem>
</MudGrid>
</MudCardContent>

View File

@@ -19,6 +19,8 @@ namespace Lantean.QBTMudBlade.Components.Options
protected string? I2pAddress { get; private set; }
protected int I2pPort { get; private set; }
protected bool I2pMixedMode { get; private set; }
protected bool ProxyDisabled { get; private set; }
protected bool ProxySocks4 { get; private set; }
protected string? ProxyType { get; private set; }
protected string? ProxyIp { get; private set; }
protected int ProxyPort { get; private set; }
@@ -215,6 +217,8 @@ namespace Lantean.QBTMudBlade.Components.Options
{
ProxyType = value;
UpdatePreferences.ProxyType = value;
ProxyDisabled = value == "None";
ProxySocks4 = value == "SOCKS4";
await PreferencesChanged.InvokeAsync(UpdatePreferences);
}
@@ -316,9 +320,6 @@ namespace Lantean.QBTMudBlade.Components.Options
await PreferencesChanged.InvokeAsync(UpdatePreferences);
}
protected const int MinPortValue = 1024;
protected const int MaxPortValue = 65535;
protected async Task GenerateRandomPort()
{
var random = new Random();
@@ -326,5 +327,10 @@ namespace Lantean.QBTMudBlade.Components.Options
await ListenPortChanged(port);
}
protected async Task UseSystemPort()
{
await ListenPortChanged(0);
}
}
}

View File

@@ -3,26 +3,26 @@
<MudCard Elevation="1" Class="ml-4 mr-4 mb-4 mt-4">
<MudCardHeader>
<CardHeaderContent>
<MudText Typo="Typo.h6">When adding a torrent</MudText>
<MudText Typo="Typo.subtitle2">When adding a torrent</MudText>
</CardHeaderContent>
</MudCardHeader>
<MudCardContent Class="pt-0">
<MudGrid>
<MudItem xs="12">
<MudSelect T="string" Label="Torrent content layout" Value="TorrentContentLayout" ValueChanged="TorrentContentLayoutChanged" ShrinkLabel>
<MudSelect T="string" Label="Torrent content layout" Value="TorrentContentLayout" ValueChanged="TorrentContentLayoutChanged" ShrinkLabel Variant="Variant.Outlined">
<MudSelectItem Value="@("Original")">Original</MudSelectItem>
<MudSelectItem Value="@("Subfolder")">Create subfolder</MudSelectItem>
<MudSelectItem Value="@("NoSubfolder")">Don't create subfolder</MudSelectItem>
</MudSelect>
</MudItem>
<MudItem xs="12">
<MudCheckBox T="bool" Label="Add to top of queue" Value="AddToTopOfQueue" ValueChanged="AddToTopOfQueueChanged" LabelPosition="LabelPosition.End" />
<MudFieldSwitch Label="Add to top of queue" Value="AddToTopOfQueue" ValueChanged="AddToTopOfQueueChanged" />
</MudItem>
<MudItem xs="12">
<MudCheckBox T="bool" Label="Do not start the download automatically" Value="StartPausedEnabled" ValueChanged="StartPausedEnabledChanged" LabelPosition="LabelPosition.End" />
</MudItem>
<MudItem xs="12">
<MudSelect T="string" Label="Torrent stop condition" Value="TorrentStopCondition" ValueChanged="TorrentStopConditionChanged" ShrinkLabel>
<MudSelect T="string" Label="Torrent stop condition" Value="TorrentStopCondition" ValueChanged="TorrentStopConditionChanged" ShrinkLabel Variant="Variant.Outlined">
<MudSelectItem Value="@("None")">None</MudSelectItem>
<MudSelectItem Value="@("MetadataReceived")">Metadata received</MudSelectItem>
<MudSelectItem Value="@("FilesChecked")">Files Checked</MudSelectItem>
@@ -36,6 +36,11 @@
</MudCard>
<MudCard Elevation="1" Class="ml-4 mr-4 mb-4">
<MudCardHeader>
<CardHeaderContent>
<MudText Typo="Typo.subtitle2">Files</MudText>
</CardHeaderContent>
</MudCardHeader>
<MudCardContent>
<MudGrid>
<MudItem xs="12">
@@ -51,31 +56,31 @@
<MudCard Elevation="1" Class="ml-4 mr-4 mb-4">
<MudCardHeader>
<CardHeaderContent>
<MudText Typo="Typo.h6">Saving Management</MudText>
<MudText Typo="Typo.subtitle2">Saving Management</MudText>
</CardHeaderContent>
</MudCardHeader>
<MudCardContent Class="pt-0">
<MudGrid>
<MudItem xs="12">
<MudSelect T="bool" Label="Default Torrent Management Mode" Value="AutoTmmEnabled" ValueChanged="AutoDeleteModeChanged" ShrinkLabel>
<MudSelect T="bool" Label="Default Torrent Management Mode" Value="AutoTmmEnabled" ValueChanged="AutoDeleteModeChanged" ShrinkLabel Variant="Variant.Outlined">
<MudSelectItem Value="false">Manual</MudSelectItem>
<MudSelectItem Value="true">Automatic</MudSelectItem>
</MudSelect>
</MudItem>
<MudItem xs="12">
<MudSelect T="bool" Label="When Torrent Category changed" Value="TorrentChangedTmmEnabled" ValueChanged="TorrentChangedTmmEnabledChanged" ShrinkLabel>
<MudSelect T="bool" Label="When Torrent Category changed" Value="TorrentChangedTmmEnabled" ValueChanged="TorrentChangedTmmEnabledChanged" ShrinkLabel Variant="Variant.Outlined">
<MudSelectItem Value="true">Relocate torrent</MudSelectItem>
<MudSelectItem Value="false">Switch torrent to Manual Mode</MudSelectItem>
</MudSelect>
</MudItem>
<MudItem xs="12">
<MudSelect T="bool" Label="When Default Save Path changed" Value="SavePathChangedTmmEnabled" ValueChanged="SavePathChangedTmmEnabledChanged" ShrinkLabel>
<MudSelect T="bool" Label="When Default Save Path changed" Value="SavePathChangedTmmEnabled" ValueChanged="SavePathChangedTmmEnabledChanged" ShrinkLabel Variant="Variant.Outlined">
<MudSelectItem Value="true">Relocate affected torrents</MudSelectItem>
<MudSelectItem Value="false">Switch affected torrents to Manual Mode</MudSelectItem>
</MudSelect>
</MudItem>
<MudItem xs="12">
<MudSelect T="bool" Label="When Category Save Path changed" Value="CategoryChangedTmmEnabled" ValueChanged="CategoryChangedTmmEnabledChanged" ShrinkLabel>
<MudSelect T="bool" Label="When Category Save Path changed" Value="CategoryChangedTmmEnabled" ValueChanged="CategoryChangedTmmEnabledChanged" ShrinkLabel Variant="Variant.Outlined">
<MudSelectItem Value="true">Relocate affected torrents</MudSelectItem>
<MudSelectItem Value="false">Switch affected torrents to Manual Mode</MudSelectItem>
</MudSelect>
@@ -84,7 +89,7 @@
<MudCheckBox T="bool" Label="Use Subcategories" Value="UseSubcategories" ValueChanged="UseSubcategoriesChanged" LabelPosition="LabelPosition.End" />
</MudItem>
<MudItem xs="12">
<MudTextField T="string" Label="Default Save Path" Value="SavePath" ValueChanged="SavePathChanged" ShrinkLabel />
<MudTextField T="string" Label="Default Save Path" Value="SavePath" ValueChanged="SavePathChanged" ShrinkLabel Variant="Variant.Outlined" />
</MudItem>
<MudItem xs="12">
<MudGrid>
@@ -92,7 +97,7 @@
<MudCheckBox T="bool" Label="Keep incomplete torrents in" Value="TempPathEnabled" ValueChanged="TempPathEnabledChanged" LabelPosition="LabelPosition.End" />
</MudItem>
<MudItem xs="12" sm="6" md="9">
<MudTextField T="string" Label="Path" Value="TempPath" ValueChanged="TempPathChanged" ShrinkLabel Disabled="@(!TempPathEnabled)" />
<MudTextField T="string" Label="Path" Value="TempPath" ValueChanged="TempPathChanged" Disabled="@(!TempPathEnabled)" ShrinkLabel Variant="Variant.Outlined" />
</MudItem>
</MudGrid>
</MudItem>
@@ -102,7 +107,7 @@
<MudCheckBox T="bool" Label="Copy .torrent files to" Value="ExportDirEnabled" ValueChanged="ExportDirEnabledChanged" LabelPosition="LabelPosition.End" />
</MudItem>
<MudItem xs="12" sm="6" md="9">
<MudTextField T="string" Label="Path" Value="ExportDir" ValueChanged="ExportDirChanged" ShrinkLabel Disabled="@(!TempPathEnabled)" />
<MudTextField T="string" Label="Path" Value="ExportDir" ValueChanged="ExportDirChanged" Disabled="@(!TempPathEnabled)" ShrinkLabel Variant="Variant.Outlined" />
</MudItem>
</MudGrid>
</MudItem>
@@ -112,7 +117,7 @@
<MudCheckBox T="bool" Label="Copy .torrent files for finished downloads to" Value="ExportDirFinEnabled" ValueChanged="ExportDirFinEnabledChanged" LabelPosition="LabelPosition.End" />
</MudItem>
<MudItem xs="12" sm="6" md="9">
<MudTextField T="string" Label="Path" Value="ExportDirFin" ValueChanged="ExportDirFinChanged" ShrinkLabel Disabled="@(!TempPathEnabled)" />
<MudTextField T="string" Label="Path" Value="ExportDirFin" ValueChanged="ExportDirFinChanged" Disabled="@(!TempPathEnabled)" ShrinkLabel Variant="Variant.Outlined" />
</MudItem>
</MudGrid>
</MudItem>
@@ -123,7 +128,7 @@
<MudCard Elevation="1" Class="ml-4 mr-4 mb-4">
<MudCardHeader>
<CardHeaderContent>
<MudText Typo="Typo.h6">Automatically add torrents from</MudText>
<MudText Typo="Typo.subtitle2">Automatically add torrents from</MudText>
</CardHeaderContent>
</MudCardHeader>
<MudCardContent Class="pt-0">
@@ -202,44 +207,18 @@
</MudCard>
<MudCard Elevation="1" Class="ml-4 mr-4 mb-4">
<MudCardHeader>
<CardHeaderContent>
<MudText Typo="Typo.subtitle2">Excluded Files</MudText>
</CardHeaderContent>
</MudCardHeader>
<MudCardContent>
<MudGrid>
<MudItem xs="12">
<MudCheckBox T="bool" Label="Excluded file names" Value="ExcludedFileNamesEnabled" ValueChanged="ExcludedFileNamesEnabledChanged" LabelPosition="LabelPosition.End" />
</MudItem>
<MudItem xs="12">
<MudTextField T="string" Label="Excluded files names" Value="ExcludedFileNames" ValueChanged="ExcludedFileNamesChanged" MudListItemnes="5" ShrinkLabel Disabled="@(!ExcludedFileNamesEnabled)" />
</MudItem>
</MudGrid>
</MudCardContent>
</MudCard>
<MudCard Elevation="1" Class="ml-4 mr-4 mb-4">
<MudCardContent>
<MudGrid>
<MudItem xs="12">
<MudCheckBox T="bool" Label="Email notification upon download completion" Value="MailNotificationEnabled" ValueChanged="MailNotificationEnabledChanged" LabelPosition="LabelPosition.End" />
</MudItem>
<MudItem xs="12">
<MudTextField T="string" Label="From" Value="MailNotificationSender" ValueChanged="MailNotificationSenderChanged" ShrinkLabel Disabled="@(!MailNotificationEnabled)" />
</MudItem>
<MudItem xs="12">
<MudTextField T="string" Label="To" Value="MailNotificationEmail" ValueChanged="MailNotificationEmailChanged" ShrinkLabel Disabled="@(!MailNotificationEnabled)" />
</MudItem>
<MudItem xs="12">
<MudTextField T="string" Label="SMTP server" Value="MailNotificationSmtp" ValueChanged="MailNotificationSmtpChanged" ShrinkLabel Disabled="@(!MailNotificationEnabled)" />
</MudItem>
<MudItem xs="12">
<MudCheckBox T="bool" Label="This server requires a secure connection (SSL)" Value="MailNotificationSslEnabled" ValueChanged="MailNotificationSslEnabledChanged" LabelPosition="LabelPosition.End" Disabled="@(!MailNotificationEnabled)" />
</MudItem>
<MudItem xs="12">
<MudCheckBox T="bool" Label="Authentication" Value="MailNotificationAuthEnabled" ValueChanged="MailNotificationAuthEnabledChanged" LabelPosition="LabelPosition.End" Disabled="@(!MailNotificationEnabled)" />
</MudItem>
<MudItem xs="12">
<MudTextField T="string" Label="Username" Value="MailNotificationUsername" ValueChanged="MailNotificationUsernameChanged" ShrinkLabel Disabled="@(!(MailNotificationEnabled && MailNotificationAuthEnabled))" />
</MudItem>
<MudItem xs="12">
<MudTextField T="string" Label="Password" Value="MailNotificationPassword" ValueChanged="MailNotificationPasswordChanged" ShrinkLabel Disabled="@(!(MailNotificationEnabled && MailNotificationAuthEnabled))" InputType="InputType.Password" />
<MudTextField T="string" Label="Excluded files names" Value="ExcludedFileNames" ValueChanged="ExcludedFileNamesChanged" Lines="5" Disabled="@(!ExcludedFileNamesEnabled)" ShrinkLabel Variant="Variant.Outlined" />
</MudItem>
</MudGrid>
</MudCardContent>
@@ -248,7 +227,43 @@
<MudCard Elevation="1" Class="ml-4 mr-4 mb-4">
<MudCardHeader>
<CardHeaderContent>
<MudText Typo="Typo.h6">Run exernal program</MudText>
<MudText Typo="Typo.subtitle2">Email Notifications</MudText>
</CardHeaderContent>
</MudCardHeader>
<MudCardContent>
<MudGrid>
<MudItem xs="12">
<MudCheckBox T="bool" Label="Email notification upon download completion" Value="MailNotificationEnabled" ValueChanged="MailNotificationEnabledChanged" LabelPosition="LabelPosition.End" />
</MudItem>
<MudItem xs="12">
<MudTextField T="string" Label="From" Value="MailNotificationSender" ValueChanged="MailNotificationSenderChanged" Disabled="@(!MailNotificationEnabled)" ShrinkLabel Variant="Variant.Outlined" />
</MudItem>
<MudItem xs="12">
<MudTextField T="string" Label="To" Value="MailNotificationEmail" ValueChanged="MailNotificationEmailChanged" Disabled="@(!MailNotificationEnabled)" ShrinkLabel Variant="Variant.Outlined" />
</MudItem>
<MudItem xs="12">
<MudTextField T="string" Label="SMTP server" Value="MailNotificationSmtp" ValueChanged="MailNotificationSmtpChanged" Disabled="@(!MailNotificationEnabled)" ShrinkLabel Variant="Variant.Outlined" />
</MudItem>
<MudItem xs="12">
<MudCheckBox T="bool" Label="This server requires a secure connection (SSL)" Value="MailNotificationSslEnabled" ValueChanged="MailNotificationSslEnabledChanged" LabelPosition="LabelPosition.End" Disabled="@(!MailNotificationEnabled)" />
</MudItem>
<MudItem xs="12">
<MudCheckBox T="bool" Label="Authentication" Value="MailNotificationAuthEnabled" ValueChanged="MailNotificationAuthEnabledChanged" LabelPosition="LabelPosition.End" Disabled="@(!MailNotificationEnabled)" />
</MudItem>
<MudItem xs="12">
<MudTextField T="string" Label="Username" Value="MailNotificationUsername" ValueChanged="MailNotificationUsernameChanged" Disabled="@(!(MailNotificationEnabled && MailNotificationAuthEnabled))" ShrinkLabel Variant="Variant.Outlined" />
</MudItem>
<MudItem xs="12">
<MudTextField T="string" Label="Password" Value="MailNotificationPassword" ValueChanged="MailNotificationPasswordChanged" Disabled="@(!(MailNotificationEnabled && MailNotificationAuthEnabled))" InputType="InputType.Password" ShrinkLabel Variant="Variant.Outlined" />
</MudItem>
</MudGrid>
</MudCardContent>
</MudCard>
<MudCard Elevation="1" Class="ml-4 mr-4 mb-4">
<MudCardHeader>
<CardHeaderContent>
<MudText Typo="Typo.subtitle2">Run exernal program</MudText>
</CardHeaderContent>
</MudCardHeader>
<MudCardContent Class="pt-0">
@@ -257,13 +272,13 @@
<MudCheckBox T="bool" Label="Run external program on torrent added" Value="AutorunOnTorrentAddedEnabled" ValueChanged="AutorunOnTorrentAddedEnabledChanged" LabelPosition="LabelPosition.End" />
</MudItem>
<MudItem xs="12">
<MudTextField T="string" Label="External program" Value="AutorunOnTorrentAddedProgram" ValueChanged="AutorunOnTorrentAddedProgramChanged" ShrinkLabel Disabled="@(!AutorunOnTorrentAddedEnabled)" />
<MudTextField T="string" Label="External program" Value="AutorunOnTorrentAddedProgram" ValueChanged="AutorunOnTorrentAddedProgramChanged" Disabled="@(!AutorunOnTorrentAddedEnabled)" ShrinkLabel Variant="Variant.Outlined" />
</MudItem>
<MudItem xs="12">
<MudCheckBox T="bool" Label="Run external program on torrent finished" Value="AutorunEnabled" ValueChanged="AutorunEnabledChanged" LabelPosition="LabelPosition.End" />
</MudItem>
<MudItem xs="12">
<MudTextField T="string" Label="External program" Value="AutorunProgram" ValueChanged="AutorunProgramChanged" ShrinkLabel Disabled="@(!AutorunEnabled)" />
<MudTextField T="string" Label="External program" Value="AutorunProgram" ValueChanged="AutorunProgramChanged" Disabled="@(!AutorunEnabled)" ShrinkLabel Variant="Variant.Outlined" />
</MudItem>
<MudItem xs="12">
<MudText>Supported parameters (case sensitive):</MudText>

View File

@@ -260,10 +260,12 @@ namespace Lantean.QBTMudBlade.Components.Options
UpdatePreferences.ScanDirs = ScanDirs;
await PreferencesChanged.InvokeAsync(UpdatePreferences);
#pragma warning disable S2583 // Conditionally executed code should be reachable
if (AddedScanDirs.Count == 0)
{
AddDefaultScanDir();
}
#pragma warning restore S2583 // Conditionally executed code should be reachable
}
protected void AddedScanDirsValueChanged(int index, string value)

View File

@@ -6,12 +6,18 @@ namespace Lantean.QBTMudBlade.Components.Options
public abstract class Options : ComponentBase
{
private bool _preferencesRead;
protected UpdatePreferences UpdatePreferences { get; set; } = new UpdatePreferences();
protected const int MinPortValue = 1024;
protected const int MaxPortValue = 65535;
[Parameter]
[EditorRequired]
public Preferences? Preferences { get; set; }
[Parameter]
[EditorRequired]
public UpdatePreferences UpdatePreferences { get; set; } = default!;
[Parameter]
[EditorRequired]
public EventCallback<UpdatePreferences> PreferencesChanged { get; set; }
@@ -25,6 +31,8 @@ namespace Lantean.QBTMudBlade.Components.Options
protected override void OnParametersSet()
{
UpdatePreferences ??= new UpdatePreferences();
if (_preferencesRead)
{
return;

View File

@@ -3,12 +3,56 @@
<MudCard Elevation="1" Class="ml-4 mr-4 mb-4 mt-4">
<MudCardHeader>
<CardHeaderContent>
<MudText Typo="Typo.h6"></MudText>
<MudText Typo="Typo.subtitle2">RSS Reader</MudText>
</CardHeaderContent>
</MudCardHeader>
<MudCardContent Class="pt-0">
<MudGrid>
<MudItem xs="12">
<MudCheckBox T="bool" Label="Enable fetching RSS feeds" Value="RssProcessingEnabled" ValueChanged="RssProcessingEnabledChanged" LabelPosition="LabelPosition.End" />
</MudItem>
<MudItem xs="12">
<MudNumericField T="int" Label="Feeds refresh interval" Value="RssRefreshInterval" ValueChanged="RssRefreshIntervalChanged" Min="0" ShrinkLabel Variant="Variant.Outlined" /> <MudText Typo="Typo.caption">min</MudText>
</MudItem>
<MudItem xs="12">
<MudNumericField T="int" Label="Maximum number of articles per feed" Value="RssMaxArticlesPerFeed" ValueChanged="RssMaxArticlesPerFeedChanged" Min="0" ShrinkLabel Variant="Variant.Outlined" />
</MudItem>
</MudGrid>
</MudCardContent>
</MudCard>
<MudCard Elevation="1" Class="ml-4 mr-4 mb-4">
<MudCardHeader>
<CardHeaderContent>
<MudText Typo="Typo.subtitle2">RSS Torrent Auto Downloader</MudText>
</CardHeaderContent>
</MudCardHeader>
<MudCardContent Class="pt-0">
<MudGrid>
<MudItem xs="12">
<MudCheckBox T="bool" Label="Enable auto downloading of RSS torrents" Value="RssAutoDownloadingEnabled" ValueChanged="RssAutoDownloadingEnabledChanged" LabelPosition="LabelPosition.End" />
</MudItem>
<MudItem xs="12">
<MudButton OnClick="OpenRssRulesDialog" Variant="Variant.Filled">Edit auto downloading rules</MudButton>
</MudItem>
</MudGrid>
</MudCardContent>
</MudCard>
<MudCard Elevation="1" Class="ml-4 mr-4 mb-4">
<MudCardHeader>
<CardHeaderContent>
<MudText Typo="Typo.subtitle2">RSS Smart Episode Filter</MudText>
</CardHeaderContent>
</MudCardHeader>
<MudCardContent Class="pt-0">
<MudGrid>
<MudItem xs="12">
<MudCheckBox T="bool" Label="Download REPACK/PROPER episodes" Value="RssDownloadRepackProperEpisodes" ValueChanged="RssDownloadRepackProperEpisodesChanged" LabelPosition="LabelPosition.End" />
</MudItem>
<MudItem xs="12">
<MudTextField T="string" Label="Filters" Value="RssSmartEpisodeFilters" ValueChanged="RssSmartEpisodeFiltersChanged" Lines="5" ShrinkLabel Variant="Variant.Outlined" />
</MudItem>
</MudGrid>
</MudCardContent>
</MudCard>

View File

@@ -2,9 +2,84 @@
{
public partial class RSSOptions : Options
{
protected bool RssProcessingEnabled { get; private set; }
protected int RssRefreshInterval { get; private set; }
protected long RssFetchDelay { get; private set; }
protected int RssMaxArticlesPerFeed { get; private set; }
protected bool RssAutoDownloadingEnabled { get; private set; }
protected bool RssDownloadRepackProperEpisodes { get; private set; }
protected string? RssSmartEpisodeFilters { get; private set; }
protected override bool SetOptions()
{
if (Preferences is null)
{
return false;
}
RssProcessingEnabled = Preferences.RssProcessingEnabled;
RssRefreshInterval = Preferences.RssRefreshInterval;
RssFetchDelay = Preferences.RssFetchDelay;
RssMaxArticlesPerFeed = Preferences.RssMaxArticlesPerFeed;
RssAutoDownloadingEnabled = Preferences.RssAutoDownloadingEnabled;
RssDownloadRepackProperEpisodes = Preferences.RssDownloadRepackProperEpisodes;
RssSmartEpisodeFilters = Preferences.RssSmartEpisodeFilters;
return true;
}
protected async Task RssProcessingEnabledChanged(bool value)
{
RssProcessingEnabled = value;
UpdatePreferences.RssProcessingEnabled = value;
await PreferencesChanged.InvokeAsync(UpdatePreferences);
}
protected async Task RssRefreshIntervalChanged(int value)
{
RssRefreshInterval = value;
UpdatePreferences.RssRefreshInterval = value;
await PreferencesChanged.InvokeAsync(UpdatePreferences);
}
protected async Task RssFetchDelayChanged(int value)
{
RssFetchDelay = value;
UpdatePreferences.RssFetchDelay = value;
await PreferencesChanged.InvokeAsync(UpdatePreferences);
}
protected async Task RssMaxArticlesPerFeedChanged(int value)
{
RssMaxArticlesPerFeed = value;
UpdatePreferences.RssMaxArticlesPerFeed = value;
await PreferencesChanged.InvokeAsync(UpdatePreferences);
}
protected async Task RssAutoDownloadingEnabledChanged(bool value)
{
RssAutoDownloadingEnabled = value;
UpdatePreferences.RssAutoDownloadingEnabled = value;
await PreferencesChanged.InvokeAsync(UpdatePreferences);
}
protected async Task RssDownloadRepackProperEpisodesChanged(bool value)
{
RssDownloadRepackProperEpisodes = value;
UpdatePreferences.RssDownloadRepackProperEpisodes = value;
await PreferencesChanged.InvokeAsync(UpdatePreferences);
}
protected async Task RssSmartEpisodeFiltersChanged(string value)
{
RssSmartEpisodeFilters = value;
UpdatePreferences.RssSmartEpisodeFilters = value;
await PreferencesChanged.InvokeAsync(UpdatePreferences);
}
protected async Task OpenRssRulesDialog()
{
await Task.Delay(0);
}
}
}
}

View File

@@ -3,12 +3,85 @@
<MudCard Elevation="1" Class="ml-4 mr-4 mb-4 mt-4">
<MudCardHeader>
<CardHeaderContent>
<MudText Typo="Typo.h6"></MudText>
<MudText Typo="Typo.subtitle2">Global Rate Limits</MudText>
</CardHeaderContent>
</MudCardHeader>
<MudCardContent Class="pt-0">
<MudGrid>
<MudItem xs="12">
<MudNumericField T="int" Label="Upload" Value="UpLimit" ValueChanged="UpLimitChanged" Min="0" ShrinkLabel Variant="Variant.Outlined" /> <MudText Typo="Typo.caption">KiB/s</MudText>
</MudItem>
<MudItem xs="12">
<MudNumericField T="int" Label="Download" Value="DlLimit" ValueChanged="DlLimitChanged" Min="0" ShrinkLabel Variant="Variant.Outlined" /> <MudText Typo="Typo.caption">KiB/s</MudText>
</MudItem>
<MudItem xs="12">
<MudText Typo="Typo.body2">0 means unlimited</MudText>
</MudItem>
</MudGrid>
</MudCardContent>
</MudCard>
<MudCard Elevation="1" Class="ml-4 mr-4 mb-4">
<MudCardHeader>
<CardHeaderContent>
<MudText Typo="Typo.subtitle2">Alternative Rate Limits</MudText>
</CardHeaderContent>
</MudCardHeader>
<MudCardContent Class="pt-0">
<MudGrid>
<MudItem xs="12">
<MudNumericField T="int" Label="Upload" Value="AltUpLimit" ValueChanged="AltUpLimitChanged" Min="0" ShrinkLabel Variant="Variant.Outlined" /> <MudText Typo="Typo.caption">KiB/s</MudText>
</MudItem>
<MudItem xs="12">
<MudNumericField T="int" Label="Download" Value="AltDlLimit" ValueChanged="AltDlLimitChanged" Min="0" ShrinkLabel Variant="Variant.Outlined" /> <MudText Typo="Typo.caption">KiB/s</MudText>
</MudItem>
<MudItem xs="12">
<MudText Typo="Typo.caption">0 means unlimited</MudText>
</MudItem>
<MudItem xs="12">
<MudCheckBox T="bool" Label="Schedule the use of alternative rate limits" Value="SchedulerEnabled" ValueChanged="SchedulerEnabledChanged" LabelPosition="LabelPosition.End" />
</MudItem>
<MudItem xs="12" md="6">
<MudTimePicker Label="From" Editable="true" Time="ScheduleFrom" TimeChanged="ScheduleFromChanged" Disabled="@(!SchedulerEnabled)" Variant="Variant.Outlined" />
</MudItem>
<MudItem xs="12" md="6">
<MudTimePicker Label="To" Editable="true" Time="ScheduleTo" TimeChanged="ScheduleToChanged" Disabled="@(!SchedulerEnabled)" Variant="Variant.Outlined" />
</MudItem>
<MudItem xs="12">
<MudSelect T="int" Value="SchedulerDays" ValueChanged="SchedulerDaysChanged" Disabled="@(!SchedulerEnabled)" ShrinkLabel Variant="Variant.Outlined">
<MudSelectItem Value="0">Every day</MudSelectItem>
<MudSelectItem Value="1">Weekdays</MudSelectItem>
<MudSelectItem Value="2">Weekends</MudSelectItem>
<MudSelectItem Value="3">Monday</MudSelectItem>
<MudSelectItem Value="4">Tuesday</MudSelectItem>
<MudSelectItem Value="5">Wednesday</MudSelectItem>
<MudSelectItem Value="6">Thursday</MudSelectItem>
<MudSelectItem Value="7">Friday</MudSelectItem>
<MudSelectItem Value="8">Saturday</MudSelectItem>
<MudSelectItem Value="9">Sunday</MudSelectItem>
</MudSelect>
</MudItem>
</MudGrid>
</MudCardContent>
</MudCard>
<MudCard Elevation="1" Class="ml-4 mr-4 mb-4">
<MudCardHeader>
<CardHeaderContent>
<MudText Typo="Typo.subtitle2">Rate Limits Settings</MudText>
</CardHeaderContent>
</MudCardHeader>
<MudCardContent Class="pt-0">
<MudGrid>
<MudItem xs="12">
<MudCheckBox T="bool" Label="Apply rate limit to µTP protocol" Value="LimitUtpRate" ValueChanged="LimitUtpRateChanged" LabelPosition="LabelPosition.End" />
</MudItem>
<MudItem xs="12">
<MudCheckBox T="bool" Label="Apply rate limit to transport overhead" Value="LimitTcpOverhead" ValueChanged="LimitTcpOverheadChanged" LabelPosition="LabelPosition.End" />
</MudItem>
<MudItem xs="12">
<MudCheckBox T="bool" Label="Apply rate limit to peers on LAN" Value="LimitLanPeers" ValueChanged="LimitLanPeersChanged" LabelPosition="LabelPosition.End" />
</MudItem>
</MudGrid>
</MudCardContent>
</MudCard>

View File

@@ -2,9 +2,160 @@
{
public partial class SpeedOptions : Options
{
protected int UpLimit { get; private set; }
protected int DlLimit { get; private set; }
protected int AltUpLimit { get; private set; }
protected int AltDlLimit { get; private set; }
protected int BittorrentProtocol { get; private set; }
protected bool LimitUtpRate { get; private set; }
protected bool LimitTcpOverhead { get; private set; }
protected bool LimitLanPeers { get; private set; }
protected bool SchedulerEnabled { get; private set; }
protected TimeSpan ScheduleFrom { get; private set; }
protected TimeSpan ScheduleTo { get; private set; }
protected int SchedulerDays { get; private set; }
protected override bool SetOptions()
{
if (Preferences is null)
{
return false;
}
UpLimit = Preferences.UpLimit;
DlLimit = Preferences.DlLimit;
AltUpLimit = Preferences.AltUpLimit;
AltDlLimit = Preferences.AltDlLimit;
BittorrentProtocol = Preferences.BittorrentProtocol;
LimitUtpRate = Preferences.LimitUtpRate;
LimitTcpOverhead = Preferences.LimitTcpOverhead;
LimitLanPeers = Preferences.LimitLanPeers;
SchedulerEnabled = Preferences.SchedulerEnabled;
ScheduleFrom = TimeSpan.FromMinutes((Preferences.ScheduleFromHour * 60) + Preferences.ScheduleFromMin);
ScheduleTo = TimeSpan.FromMinutes((Preferences.ScheduleToHour * 60) + Preferences.ScheduleToMin);
SchedulerDays = Preferences.SchedulerDays;
return true;
}
protected async Task UpLimitChanged(int value)
{
UpLimit = value;
UpdatePreferences.UpLimit = value;
await PreferencesChanged.InvokeAsync(UpdatePreferences);
}
protected async Task DlLimitChanged(int value)
{
DlLimit = value;
UpdatePreferences.DlLimit = value;
await PreferencesChanged.InvokeAsync(UpdatePreferences);
}
protected async Task AltUpLimitChanged(int value)
{
AltUpLimit = value;
UpdatePreferences.AltUpLimit = value;
await PreferencesChanged.InvokeAsync(UpdatePreferences);
}
protected async Task AltDlLimitChanged(int value)
{
AltDlLimit = value;
UpdatePreferences.AltDlLimit = value;
await PreferencesChanged.InvokeAsync(UpdatePreferences);
}
protected async Task BittorrentProtocolChanged(int value)
{
BittorrentProtocol = value;
UpdatePreferences.BittorrentProtocol = value;
await PreferencesChanged.InvokeAsync(UpdatePreferences);
}
protected async Task LimitUtpRateChanged(bool value)
{
LimitUtpRate = value;
UpdatePreferences.LimitUtpRate = value;
await PreferencesChanged.InvokeAsync(UpdatePreferences);
}
protected async Task LimitTcpOverheadChanged(bool value)
{
LimitTcpOverhead = value;
UpdatePreferences.LimitTcpOverhead = value;
await PreferencesChanged.InvokeAsync(UpdatePreferences);
}
protected async Task LimitLanPeersChanged(bool value)
{
LimitLanPeers = value;
UpdatePreferences.LimitLanPeers = value;
await PreferencesChanged.InvokeAsync(UpdatePreferences);
}
protected async Task SchedulerEnabledChanged(bool value)
{
SchedulerEnabled = value;
UpdatePreferences.SchedulerEnabled = value;
await PreferencesChanged.InvokeAsync(UpdatePreferences);
}
protected async Task ScheduleFromChanged(TimeSpan? value)
{
if (value is null)
{
return;
}
ScheduleFrom = value.Value;
bool hasChanged = false;
if (value.Value.Hours != Preferences?.ScheduleFromHour)
{
UpdatePreferences.ScheduleFromHour = value.Value.Hours;
hasChanged = true;
}
if (value.Value.Minutes != Preferences?.ScheduleFromMin)
{
UpdatePreferences.ScheduleFromMin = value.Value.Minutes;
hasChanged = true;
}
if (hasChanged)
{
await PreferencesChanged.InvokeAsync(UpdatePreferences);
}
}
protected async Task ScheduleToChanged(TimeSpan? value)
{
if (value is null)
{
return;
}
ScheduleTo = value.Value;
bool hasChanged = false;
if (value.Value.Hours != Preferences?.ScheduleToHour)
{
UpdatePreferences.ScheduleToHour = value.Value.Hours;
hasChanged = true;
}
if (value.Value.Minutes != Preferences?.ScheduleToMin)
{
UpdatePreferences.ScheduleToMin = value.Value.Minutes;
hasChanged = true;
}
if (hasChanged)
{
await PreferencesChanged.InvokeAsync(UpdatePreferences);
}
}
protected async Task SchedulerDaysChanged(int value)
{
SchedulerDays = value;
UpdatePreferences.SchedulerDays = value;
await PreferencesChanged.InvokeAsync(UpdatePreferences);
}
}
}
}

View File

@@ -3,12 +3,218 @@
<MudCard Elevation="1" Class="ml-4 mr-4 mb-4 mt-4">
<MudCardHeader>
<CardHeaderContent>
<MudText Typo="Typo.h6"></MudText>
<MudText Typo="Typo.subtitle2">Web User Interface (Remote control)</MudText>
</CardHeaderContent>
</MudCardHeader>
<MudCardContent Class="pt-0">
<MudGrid>
<MudItem xs="12" md="8">
<MudTextField T="string" Label="Host" Value="WebUiAddress" ValueChanged="WebUiAddressChanged" ShrinkLabel Variant="Variant.Outlined" />
</MudItem>
<MudItem xs="12" md="4">
<MudNumericField T="int" Label="Port" Value="WebUiPort" ValueChanged="WebUiPortChanged" Min="@Options.MinPortValue" Max="@Options.MaxPortValue" ShrinkLabel Variant="Variant.Outlined" />
</MudItem>
<MudItem xs="12">
<MudCheckBox T="bool" Label="Use UPnP / NAT-PMP to forward the port from my router" Value="WebUiUpnp" ValueChanged="WebUiUpnpChanged" LabelPosition="LabelPosition.End" />
</MudItem>
</MudGrid>
</MudCardContent>
</MudCard>
<MudCard Elevation="1" Class="ml-4 mr-4 mb-4">
<MudCardHeader>
<CardHeaderContent>
<MudText Typo="Typo.subtitle2">Certificate</MudText>
</CardHeaderContent>
</MudCardHeader>
<MudCardContent Class="pt-0">
<MudGrid>
<MudItem xs="12">
<MudCheckBox T="bool" Label="Use HTTPS instead of HTTP" Value="UseHttps" ValueChanged="UseHttpsChanged" LabelPosition="LabelPosition.End" />
</MudItem>
<MudItem xs="12">
<MudTextField T="string" Label="Certificate" Value="WebUiHttpsCertPath" ValueChanged="WebUiHttpsCertPathChanged" Disabled="@(!UseHttps)" ShrinkLabel Variant="Variant.Outlined" />
</MudItem>
<MudItem xs="12">
<MudTextField T="string" Label="Key" Value="WebUiHttpsKeyPath" ValueChanged="WebUiHttpsKeyPathChanged" Disabled="@(!UseHttps)" ShrinkLabel Variant="Variant.Outlined" />
</MudItem>
</MudGrid>
</MudCardContent>
</MudCard>
<MudCard Elevation="1" Class="ml-4 mr-4 mb-4">
<MudCardHeader>
<CardHeaderContent>
<MudText Typo="Typo.subtitle2">Authentication</MudText>
</CardHeaderContent>
</MudCardHeader>
<MudCardContent Class="pt-0">
<MudGrid>
<MudItem xs="12">
<MudTextField T="string" Label="Username" Value="WebUiUsername" ValueChanged="WebUiUsernameChanged" ShrinkLabel Variant="Variant.Outlined" />
</MudItem>
<MudItem xs="12">
<MudTextField T="string" Label="Password" Value="WebUiPassword" ValueChanged="WebUiPasswordChanged" InputType="InputType.Password" ShrinkLabel Variant="Variant.Outlined" />
</MudItem>
<MudItem xs="12">
<MudCheckBox T="bool" Label="Bypass authentication for clients on localhost" Value="BypassLocalAuth" ValueChanged="BypassLocalAuthChanged" LabelPosition="LabelPosition.End" />
</MudItem>
<MudItem xs="12">
<MudCheckBox T="bool" Label="Bypass authentication for clients in whitelisted IP subnets" Value="BypassAuthSubnetWhitelistEnabled" ValueChanged="BypassAuthSubnetWhitelistEnabledChanged" LabelPosition="LabelPosition.End" />
</MudItem>
<MudItem xs="12">
<MudTextField T="string" Label="Trackers" Value="BypassAuthSubnetWhitelist" ValueChanged="BypassAuthSubnetWhitelistChanged" Lines="5" Disabled="@(!BypassAuthSubnetWhitelistEnabled)" ShrinkLabel Variant="Variant.Outlined" />
</MudItem>
<MudItem xs="12">
<MudNumericField T="int" Label="Ban client after consecutive failures" Value="WebUiMaxAuthFailCount" ValueChanged="WebUiMaxAuthFailCountChanged" Min="0" ShrinkLabel Variant="Variant.Outlined" />
</MudItem>
<MudItem xs="12">
<MudNumericField T="int" Label="ban for" Value="WebUiBanDuration" ValueChanged="WebUiBanDurationChanged" Min="0" ShrinkLabel Variant="Variant.Outlined" /> <MudText Typo="Typo.caption">seconds</MudText>
</MudItem>
<MudItem xs="12">
<MudNumericField T="int" Label="Session timeout" Value="WebUiSessionTimeout" ValueChanged="WebUiSessionTimeoutChanged" Min="0" ShrinkLabel Variant="Variant.Outlined" /> <MudText Typo="Typo.caption">seconds</MudText>
</MudItem>
</MudGrid>
</MudCardContent>
</MudCard>
<MudCard Elevation="1" Class="ml-4 mr-4 mb-4">
<MudCardHeader>
<CardHeaderContent>
<MudText Typo="Typo.subtitle2">Alternative Web UI</MudText>
</CardHeaderContent>
</MudCardHeader>
<MudCardContent Class="pt-0">
<MudGrid>
<MudItem xs="12">
<MudCheckBox T="bool" Label="Use alternative Web UI" Value="AlternativeWebuiEnabled" ValueChanged="AlternativeWebuiEnabledChanged" LabelPosition="LabelPosition.End" />
</MudItem>
<MudItem xs="12">
<MudTextField T="string" Label="Files location" Value="AlternativeWebuiPath" ValueChanged="AlternativeWebuiPathChanged" ShrinkLabel Variant="Variant.Outlined" />
</MudItem>
</MudGrid>
</MudCardContent>
</MudCard>
<MudCard Elevation="1" Class="ml-4 mr-4 mb-4">
<MudCardHeader>
<CardHeaderContent>
<MudText Typo="Typo.subtitle2">Security</MudText>
</CardHeaderContent>
</MudCardHeader>
<MudCardContent Class="pt-0">
<MudGrid>
<MudItem xs="12">
<MudCheckBox T="bool" Label="Enable clickjacking protection" Value="WebUiClickjackingProtectionEnabled" ValueChanged="WebUiClickjackingProtectionEnabledChanged" LabelPosition="LabelPosition.End" />
</MudItem>
<MudItem xs="12">
<MudCheckBox T="bool" Label="Enable Cross-Site Request Forgery (CSRF) protection" Value="WebUiCsrfProtectionEnabled" ValueChanged="WebUiCsrfProtectionEnabledChanged" LabelPosition="LabelPosition.End" />
</MudItem>
<MudItem xs="12">
<MudCheckBox T="bool" Label="Enable cookie Secure flag (requires HTTPS)" Value="WebUiSecureCookieEnabled" ValueChanged="WebUiSecureCookieEnabledChanged" LabelPosition="LabelPosition.End" />
</MudItem>
<MudItem xs="12">
<MudCheckBox T="bool" Label="Enable Host header validation" Value="WebUiHostHeaderValidationEnabled" ValueChanged="WebUiHostHeaderValidationEnabledChanged" LabelPosition="LabelPosition.End" />
</MudItem>
<MudItem xs="12">
<MudTextField T="string" Label="Server domains" Value="WebUiDomainList" ValueChanged="WebUiDomainListChanged" Lines="5" Disabled="@(!WebUiHostHeaderValidationEnabled)" ShrinkLabel Variant="Variant.Outlined" />
</MudItem>
</MudGrid>
</MudCardContent>
</MudCard>
<MudCard Elevation="1" Class="ml-4 mr-4 mb-4">
<MudCardHeader>
<CardHeaderContent>
<MudText Typo="Typo.subtitle2">Security</MudText>
</CardHeaderContent>
</MudCardHeader>
<MudCardContent Class="pt-0">
<MudGrid>
<MudItem xs="12">
<MudCheckBox T="bool" Label="Enable clickjacking protection" Value="WebUiClickjackingProtectionEnabled" ValueChanged="WebUiClickjackingProtectionEnabledChanged" LabelPosition="LabelPosition.End" />
</MudItem>
<MudItem xs="12">
<MudCheckBox T="bool" Label="Enable Cross-Site Request Forgery (CSRF) protection" Value="WebUiCsrfProtectionEnabled" ValueChanged="WebUiCsrfProtectionEnabledChanged" LabelPosition="LabelPosition.End" />
</MudItem>
<MudItem xs="12">
<MudCheckBox T="bool" Label="Enable cookie Secure flag (requires HTTPS)" Value="WebUiSecureCookieEnabled" ValueChanged="WebUiSecureCookieEnabledChanged" LabelPosition="LabelPosition.End" />
</MudItem>
<MudItem xs="12">
<MudCheckBox T="bool" Label="Enable Host header validation" Value="WebUiHostHeaderValidationEnabled" ValueChanged="WebUiHostHeaderValidationEnabledChanged" LabelPosition="LabelPosition.End" />
</MudItem>
<MudItem xs="12">
<MudTextField T="string" Label="Server domains" Value="WebUiDomainList" ValueChanged="WebUiDomainListChanged" Lines="5" Disabled="@(!WebUiHostHeaderValidationEnabled)" ShrinkLabel Variant="Variant.Outlined" />
</MudItem>
</MudGrid>
</MudCardContent>
</MudCard>
<MudCard Elevation="1" Class="ml-4 mr-4 mb-4">
<MudCardHeader>
<CardHeaderContent>
<MudText Typo="Typo.subtitle2">Http Headers</MudText>
</CardHeaderContent>
</MudCardHeader>
<MudCardContent Class="pt-0">
<MudGrid>
<MudItem xs="12">
<MudCheckBox T="bool" Label="Add custom HTTP headers" Value="WebUiUseCustomHttpHeadersEnabled" ValueChanged="WebUiUseCustomHttpHeadersEnabledChanged" LabelPosition="LabelPosition.End" />
</MudItem>
<MudItem xs="12">
<MudTextField T="string" Label="Server domains" Value="WebUiCustomHttpHeaders" ValueChanged="WebUiCustomHttpHeadersChanged" Lines="5" Disabled="@(!WebUiUseCustomHttpHeadersEnabled)" ShrinkLabel Variant="Variant.Outlined" />
</MudItem>
</MudGrid>
</MudCardContent>
</MudCard>
<MudCard Elevation="1" Class="ml-4 mr-4 mb-4">
<MudCardHeader>
<CardHeaderContent>
<MudText Typo="Typo.subtitle2">Reverse Proxy</MudText>
</CardHeaderContent>
</MudCardHeader>
<MudCardContent Class="pt-0">
<MudGrid>
<MudItem xs="12">
<MudCheckBox T="bool" Label="Enable reverse proxy support" Value="WebUiReverseProxyEnabled" ValueChanged="WebUiReverseProxyEnabledChanged" LabelPosition="LabelPosition.End" />
</MudItem>
<MudItem xs="12">
<MudTextField T="string" Label="Trusted proxies list" Value="WebUiReverseProxiesList" ValueChanged="WebUiReverseProxiesListChanged" Lines="5" Disabled="@(!WebUiReverseProxyEnabled)" ShrinkLabel Variant="Variant.Outlined" />
</MudItem>
</MudGrid>
</MudCardContent>
</MudCard>
<MudCard Elevation="1" Class="ml-4 mr-4 mb-4">
<MudCardHeader>
<CardHeaderContent>
<MudText Typo="Typo.subtitle2">Dynamic Domain Name</MudText>
</CardHeaderContent>
</MudCardHeader>
<MudCardContent Class="pt-0">
<MudGrid>
<MudItem xs="12">
<MudCheckBox T="bool" Label="Update my dynamic domain name" Value="DyndnsEnabled" ValueChanged="DyndnsEnabledChanged" LabelPosition="LabelPosition.End" />
</MudItem>
<MudItem xs="8">
<MudSelect T="int" Value="DyndnsService" ValueChanged="DyndnsServiceChanged" Disabled="@(!DyndnsEnabled)" ShrinkLabel Variant="Variant.Outlined">
<MudSelectItem Value="0">DynDNS</MudSelectItem>
<MudSelectItem Value="1">NO-IP</MudSelectItem>
</MudSelect>
</MudItem>
<MudItem xs="4">
<MudButton OnClick="RegisterDyndnsService" Disabled="@(!DyndnsEnabled)" Variant="Variant.Filled">Register</MudButton>
</MudItem>
<MudItem xs="12">
<MudTextField T="string" Label="Domain name" Value="DyndnsDomain" ValueChanged="DyndnsDomainChanged" Disabled="@(!DyndnsEnabled)" ShrinkLabel Variant="Variant.Outlined" />
</MudItem>
<MudItem xs="12">
<MudTextField T="string" Label="Username" Value="DyndnsUsername" ValueChanged="DyndnsUsernameChanged" Disabled="@(!DyndnsEnabled)" ShrinkLabel Variant="Variant.Outlined" />
</MudItem>
<MudItem xs="12">
<MudTextField T="string" Label="Password" Value="DyndnsPassword" ValueChanged="DyndnsPasswordChanged" Disabled="@(!DyndnsEnabled)" InputType="InputType.Password" ShrinkLabel Variant="Variant.Outlined" />
</MudItem>
</MudGrid>
</MudCardContent>
</MudCard>

View File

@@ -2,9 +2,309 @@
{
public partial class WebUIOptions : Options
{
protected string? Locale { get; private set; }
protected bool PerformanceWarning { get; private set; }
protected string? WebUiDomainList { get; private set; }
protected string? WebUiAddress { get; private set; }
protected int WebUiPort { get; private set; }
protected bool WebUiUpnp { get; private set; }
protected bool UseHttps { get; private set; }
protected string? WebUiHttpsCertPath { get; private set; }
protected string? WebUiHttpsKeyPath { get; private set; }
protected string? WebUiUsername { get; private set; }
protected string? WebUiPassword { get; private set; }
protected bool BypassLocalAuth { get; private set; }
protected bool BypassAuthSubnetWhitelistEnabled { get; private set; }
protected string? BypassAuthSubnetWhitelist { get; private set; }
protected int WebUiMaxAuthFailCount { get; private set; }
protected int WebUiBanDuration { get; private set; }
protected int WebUiSessionTimeout { get; private set; }
protected bool AlternativeWebuiEnabled { get; private set; }
protected string? AlternativeWebuiPath { get; private set; }
protected bool WebUiClickjackingProtectionEnabled { get; private set; }
protected bool WebUiCsrfProtectionEnabled { get; private set; }
protected bool WebUiSecureCookieEnabled { get; private set; }
protected bool WebUiHostHeaderValidationEnabled { get; private set; }
protected bool WebUiUseCustomHttpHeadersEnabled { get; private set; }
protected string? WebUiCustomHttpHeaders { get; private set; }
protected bool WebUiReverseProxyEnabled { get; private set; }
protected string? WebUiReverseProxiesList { get; private set; }
protected bool DyndnsEnabled { get; private set; }
protected int DyndnsService { get; private set; }
protected string? DyndnsDomain { get; private set; }
protected string? DyndnsUsername { get; private set; }
protected string? DyndnsPassword { get; private set; }
protected override bool SetOptions()
{
if (Preferences is null)
{
return false;
}
Locale = Preferences.Locale;
PerformanceWarning = Preferences.PerformanceWarning;
WebUiDomainList = Preferences.WebUiDomainList;
WebUiAddress = Preferences.WebUiAddress;
WebUiPort = Preferences.WebUiPort;
WebUiUpnp = Preferences.WebUiUpnp;
UseHttps = Preferences.UseHttps;
WebUiHttpsCertPath = Preferences.WebUiHttpsCertPath;
WebUiHttpsKeyPath = Preferences.WebUiHttpsKeyPath;
WebUiUsername = Preferences.WebUiUsername;
WebUiPassword = Preferences.WebUiPassword;
BypassLocalAuth = Preferences.BypassLocalAuth;
BypassAuthSubnetWhitelistEnabled = Preferences.BypassAuthSubnetWhitelistEnabled;
BypassAuthSubnetWhitelist = Preferences.BypassAuthSubnetWhitelist;
WebUiMaxAuthFailCount = Preferences.WebUiMaxAuthFailCount;
WebUiBanDuration = Preferences.WebUiBanDuration;
WebUiSessionTimeout = Preferences.WebUiSessionTimeout;
AlternativeWebuiEnabled = Preferences.AlternativeWebuiEnabled;
AlternativeWebuiPath = Preferences.AlternativeWebuiPath;
WebUiClickjackingProtectionEnabled = Preferences.WebUiClickjackingProtectionEnabled;
WebUiCsrfProtectionEnabled = Preferences.WebUiCsrfProtectionEnabled;
WebUiSecureCookieEnabled = Preferences.WebUiSecureCookieEnabled;
WebUiHostHeaderValidationEnabled = Preferences.WebUiHostHeaderValidationEnabled;
WebUiUseCustomHttpHeadersEnabled = Preferences.WebUiUseCustomHttpHeadersEnabled;
WebUiCustomHttpHeaders = Preferences.WebUiCustomHttpHeaders;
WebUiReverseProxyEnabled = Preferences.WebUiReverseProxyEnabled;
WebUiReverseProxiesList = Preferences.WebUiReverseProxiesList;
DyndnsEnabled = Preferences.DyndnsEnabled;
DyndnsService = Preferences.DyndnsService;
DyndnsDomain = Preferences.DyndnsDomain;
DyndnsUsername = Preferences.DyndnsUsername;
DyndnsPassword = Preferences.DyndnsPassword;
return true;
}
protected async Task LocaleChanged(string value)
{
Locale = value;
UpdatePreferences.Locale = value;
await PreferencesChanged.InvokeAsync(UpdatePreferences);
}
protected async Task PerformanceWarningChanged(bool value)
{
PerformanceWarning = value;
UpdatePreferences.PerformanceWarning = value;
await PreferencesChanged.InvokeAsync(UpdatePreferences);
}
protected async Task WebUiDomainListChanged(string value)
{
WebUiDomainList = value;
UpdatePreferences.WebUiDomainList = value;
await PreferencesChanged.InvokeAsync(UpdatePreferences);
}
protected async Task WebUiAddressChanged(string value)
{
WebUiAddress = value;
UpdatePreferences.WebUiAddress = value;
await PreferencesChanged.InvokeAsync(UpdatePreferences);
}
protected async Task WebUiPortChanged(int value)
{
WebUiPort = value;
UpdatePreferences.WebUiPort = value;
await PreferencesChanged.InvokeAsync(UpdatePreferences);
}
protected async Task WebUiUpnpChanged(bool value)
{
WebUiUpnp = value;
UpdatePreferences.WebUiUpnp = value;
await PreferencesChanged.InvokeAsync(UpdatePreferences);
}
protected async Task UseHttpsChanged(bool value)
{
UseHttps = value;
UpdatePreferences.UseHttps = value;
await PreferencesChanged.InvokeAsync(UpdatePreferences);
}
protected async Task WebUiHttpsCertPathChanged(string value)
{
WebUiHttpsCertPath = value;
UpdatePreferences.WebUiHttpsCertPath = value;
await PreferencesChanged.InvokeAsync(UpdatePreferences);
}
protected async Task WebUiHttpsKeyPathChanged(string value)
{
WebUiHttpsKeyPath = value;
UpdatePreferences.WebUiHttpsKeyPath = value;
await PreferencesChanged.InvokeAsync(UpdatePreferences);
}
protected async Task WebUiUsernameChanged(string value)
{
WebUiUsername = value;
UpdatePreferences.WebUiUsername = value;
await PreferencesChanged.InvokeAsync(UpdatePreferences);
}
protected async Task WebUiPasswordChanged(string value)
{
WebUiPassword = value;
UpdatePreferences.WebUiPassword = value;
await PreferencesChanged.InvokeAsync(UpdatePreferences);
}
protected async Task BypassLocalAuthChanged(bool value)
{
BypassLocalAuth = value;
UpdatePreferences.BypassLocalAuth = value;
await PreferencesChanged.InvokeAsync(UpdatePreferences);
}
protected async Task BypassAuthSubnetWhitelistEnabledChanged(bool value)
{
BypassAuthSubnetWhitelistEnabled = value;
UpdatePreferences.BypassAuthSubnetWhitelistEnabled = value;
await PreferencesChanged.InvokeAsync(UpdatePreferences);
}
protected async Task BypassAuthSubnetWhitelistChanged(string value)
{
BypassAuthSubnetWhitelist = value;
UpdatePreferences.BypassAuthSubnetWhitelist = value;
await PreferencesChanged.InvokeAsync(UpdatePreferences);
}
protected async Task WebUiMaxAuthFailCountChanged(int value)
{
WebUiMaxAuthFailCount = value;
UpdatePreferences.WebUiMaxAuthFailCount = value;
await PreferencesChanged.InvokeAsync(UpdatePreferences);
}
protected async Task WebUiBanDurationChanged(int value)
{
WebUiBanDuration = value;
UpdatePreferences.WebUiBanDuration = value;
await PreferencesChanged.InvokeAsync(UpdatePreferences);
}
protected async Task WebUiSessionTimeoutChanged(int value)
{
WebUiSessionTimeout = value;
UpdatePreferences.WebUiSessionTimeout = value;
await PreferencesChanged.InvokeAsync(UpdatePreferences);
}
protected async Task AlternativeWebuiEnabledChanged(bool value)
{
AlternativeWebuiEnabled = value;
UpdatePreferences.AlternativeWebuiEnabled = value;
await PreferencesChanged.InvokeAsync(UpdatePreferences);
}
protected async Task AlternativeWebuiPathChanged(string value)
{
AlternativeWebuiPath = value;
UpdatePreferences.AlternativeWebuiPath = value;
await PreferencesChanged.InvokeAsync(UpdatePreferences);
}
protected async Task WebUiClickjackingProtectionEnabledChanged(bool value)
{
WebUiClickjackingProtectionEnabled = value;
UpdatePreferences.WebUiClickjackingProtectionEnabled = value;
await PreferencesChanged.InvokeAsync(UpdatePreferences);
}
protected async Task WebUiCsrfProtectionEnabledChanged(bool value)
{
WebUiCsrfProtectionEnabled = value;
UpdatePreferences.WebUiCsrfProtectionEnabled = value;
await PreferencesChanged.InvokeAsync(UpdatePreferences);
}
protected async Task WebUiSecureCookieEnabledChanged(bool value)
{
WebUiSecureCookieEnabled = value;
UpdatePreferences.WebUiSecureCookieEnabled = value;
await PreferencesChanged.InvokeAsync(UpdatePreferences);
}
protected async Task WebUiHostHeaderValidationEnabledChanged(bool value)
{
WebUiHostHeaderValidationEnabled = value;
UpdatePreferences.WebUiHostHeaderValidationEnabled = value;
await PreferencesChanged.InvokeAsync(UpdatePreferences);
}
protected async Task WebUiUseCustomHttpHeadersEnabledChanged(bool value)
{
WebUiUseCustomHttpHeadersEnabled = value;
UpdatePreferences.WebUiUseCustomHttpHeadersEnabled = value;
await PreferencesChanged.InvokeAsync(UpdatePreferences);
}
protected async Task WebUiCustomHttpHeadersChanged(string value)
{
WebUiCustomHttpHeaders = value;
UpdatePreferences.WebUiCustomHttpHeaders = value;
await PreferencesChanged.InvokeAsync(UpdatePreferences);
}
protected async Task WebUiReverseProxyEnabledChanged(bool value)
{
WebUiReverseProxyEnabled = value;
UpdatePreferences.WebUiReverseProxyEnabled = value;
await PreferencesChanged.InvokeAsync(UpdatePreferences);
}
protected async Task WebUiReverseProxiesListChanged(string value)
{
WebUiReverseProxiesList = value;
UpdatePreferences.WebUiReverseProxiesList = value;
await PreferencesChanged.InvokeAsync(UpdatePreferences);
}
protected async Task DyndnsEnabledChanged(bool value)
{
DyndnsEnabled = value;
UpdatePreferences.DyndnsEnabled = value;
await PreferencesChanged.InvokeAsync(UpdatePreferences);
}
protected async Task DyndnsServiceChanged(int value)
{
DyndnsService = value;
UpdatePreferences.DyndnsService = value;
await PreferencesChanged.InvokeAsync(UpdatePreferences);
}
protected async Task DyndnsDomainChanged(string value)
{
DyndnsDomain = value;
UpdatePreferences.DyndnsDomain = value;
await PreferencesChanged.InvokeAsync(UpdatePreferences);
}
protected async Task DyndnsUsernameChanged(string value)
{
DyndnsUsername = value;
UpdatePreferences.DyndnsUsername = value;
await PreferencesChanged.InvokeAsync(UpdatePreferences);
}
protected async Task DyndnsPasswordChanged(string value)
{
DyndnsPassword = value;
UpdatePreferences.DyndnsPassword = value;
await PreferencesChanged.InvokeAsync(UpdatePreferences);
}
protected async Task RegisterDyndnsService()
{
await Task.Delay(0);
}
}
}

View File

@@ -64,7 +64,7 @@ else
}
else
{
<MudMenu Icon="@option.Icon" IconColor="@option.Color" Label="@option.Name" AnchorOrigin="Origin.BottomLeft" TransformOrigin="Origin.TopLeft">
<MudMenu Icon="@option.Icon" IconColor="@option.Color" Class="icon-menu" Label="@option.Name" title="@option.Name" AnchorOrigin="Origin.BottomLeft" TransformOrigin="Origin.TopLeft">
@foreach (var childItem in option.Children)
{
@ChildItem(childItem)

View File

@@ -1,7 +1,9 @@
using Lantean.QBitTorrentClient;
using Lantean.QBTMudBlade.Interop;
using Lantean.QBTMudBlade.Models;
using Lantean.QBTMudBlade.Services;
using Microsoft.AspNetCore.Components;
using Microsoft.JSInterop;
using MudBlazor;
namespace Lantean.QBTMudBlade.Components
@@ -26,6 +28,9 @@ namespace Lantean.QBTMudBlade.Components
[Inject]
public IClipboardService ClipboardService { get; set; } = default!;
[Inject]
public IJSRuntime JSRuntime { get; set; } = default!;
[Parameter]
[EditorRequired]
public IEnumerable<string> Hashes { get; set; } = default!;
@@ -155,7 +160,7 @@ namespace Lantean.QBTMudBlade.Components
protected async Task ToggleSuperSeeding()
{
var torrents = GetTorrents();
await ApiClient.SetSuperSeeding(false, null, torrents.Where(t => t.SuperSeeding).Select(t => t.Hash).ToArray());
await ApiClient.SetSuperSeeding(true, null, torrents.Where(t => !t.SuperSeeding).Select(t => t.Hash).ToArray());
}
@@ -195,9 +200,19 @@ namespace Lantean.QBTMudBlade.Components
await ClipboardService.WriteToClipboard(value);
}
protected async Task Copy(Func<Torrent, object?> selector)
{
await Copy(string.Join(Environment.NewLine, GetTorrents().Select(selector)));
}
protected async Task Export()
{
await Task.Delay(5);
foreach (var torrent in GetTorrents())
{
var url = await ApiClient.GetExportUrl(torrent.Hash);
await JSRuntime.FileDownload(url, $"{torrent.Name}.torrent");
await Task.Delay(200);
}
}
private IEnumerable<Torrent> GetTorrents()
@@ -265,11 +280,11 @@ namespace Lantean.QBTMudBlade.Components
}),
new Action("Copy", Icons.Material.Filled.FolderCopy, Color.Info, new List<Action>
{
new Action("Name", Icons.Material.Filled.TextFields, Color.Info, EventCallback.Factory.Create(this, () => Copy(firstTorrent.Name))),
new Action("Info hash v1", Icons.Material.Filled.Tag, Color.Info, EventCallback.Factory.Create(this, () => Copy(firstTorrent.InfoHashV1))),
new Action("Info hash v2", Icons.Material.Filled.Tag, Color.Info, EventCallback.Factory.Create(this, () => Copy(firstTorrent.InfoHashV2))),
new Action("Magnet link", Icons.Material.Filled.TextFields, Color.Info, EventCallback.Factory.Create(this, () => Copy(firstTorrent.MagnetUri))),
new Action("Torrent ID", Icons.Material.Filled.TextFields, Color.Info, EventCallback.Factory.Create(this, () => Copy(firstTorrent.Hash))),
new Action("Name", Icons.Material.Filled.TextFields, Color.Info, EventCallback.Factory.Create(this, () => Copy(t => t.Name))),
new Action("Info hash v1", Icons.Material.Filled.Tag, Color.Info, EventCallback.Factory.Create(this, () => Copy(t => t.InfoHashV1))),
new Action("Info hash v2", Icons.Material.Filled.Tag, Color.Info, EventCallback.Factory.Create(this, () => Copy(t => t.InfoHashV2))),
new Action("Magnet link", Icons.Material.Filled.TextFields, Color.Info, EventCallback.Factory.Create(this, () => Copy(t => t.MagnetUri))),
new Action("Torrent ID", Icons.Material.Filled.TextFields, Color.Info, EventCallback.Factory.Create(this, () => Copy(t => t.Hash))),
}),
new Action("Export", Icons.Material.Filled.SaveAlt, Color.Info, EventCallback.Factory.Create(this, Export)),
};

View File

@@ -260,7 +260,7 @@ namespace Lantean.QBTMudBlade
var dateTimeOffset = DateTimeOffset.FromUnixTimeSeconds(value.Value);
return dateTimeOffset.ToLocalTime().ToString();
return dateTimeOffset.ToLocalTime().DateTime.ToString();
}
/// <summary>

View File

@@ -8,5 +8,10 @@ namespace Lantean.QBTMudBlade.Interop
{
return await runtime.InvokeAsync<BoundingClientRect?>("qbt.getBoundingClientRect", id);
}
public static async Task FileDownload(this IJSRuntime runtime, string url, string? filename = null)
{
await runtime.InvokeVoidAsync("qbt.triggerFileDownload", url, filename);
}
}
}

View File

@@ -49,7 +49,7 @@ namespace Lantean.QBTMudBlade.Pages
#if DEBUG
protected override async Task OnInitializedAsync()
{
await DoLogin("admin", "kL76z3W36");
await DoLogin("admin", "Pmw29AWNK");
}
#endif
}

View File

@@ -26,30 +26,30 @@
<MudIconButton Icon="@Icons.Material.Outlined.Undo" OnClick="Undo" Disabled="@(LostConnection || UpdatePreferences is null)" />
</MudToolBar>
<MudTabs Elevation="2" ApplyEffectsToContainer="true" @bind-ActivePanelIndex="ActiveTab" KeepPanelsAlive="true" Border="true">
<MudTabs Elevation="2" ApplyEffectsToContainer="true" @bind-ActivePanelIndex="ActiveTab" Border="true">
<MudTabPanel Text="Behaviour">
<BehaviourOptions @ref="BehaviourOptions" Preferences="Preferences" PreferencesChanged="PreferencesChanged" />
<BehaviourOptions @ref="BehaviourOptions" Preferences="Preferences" UpdatePreferences="@UpdatePreferences" PreferencesChanged="PreferencesChanged" />
</MudTabPanel>
<MudTabPanel Text="Downloads">
<DownloadsOptions @ref="DownloadsOptions" Preferences="Preferences" PreferencesChanged="PreferencesChanged" />
<DownloadsOptions @ref="DownloadsOptions" Preferences="Preferences" UpdatePreferences="@UpdatePreferences" PreferencesChanged="PreferencesChanged" />
</MudTabPanel>
<MudTabPanel Text="Connection">
<ConnectionOptions @ref="ConnectionOptions" Preferences="Preferences" PreferencesChanged="PreferencesChanged" />
<ConnectionOptions @ref="ConnectionOptions" Preferences="Preferences" UpdatePreferences="@UpdatePreferences" PreferencesChanged="PreferencesChanged" />
</MudTabPanel>
<MudTabPanel Text="Speed">
<SpeedOptions @ref="SpeedOptions" Preferences="Preferences" PreferencesChanged="PreferencesChanged" />
<SpeedOptions @ref="SpeedOptions" Preferences="Preferences" UpdatePreferences="@UpdatePreferences" PreferencesChanged="PreferencesChanged" />
</MudTabPanel>
<MudTabPanel Text="BitTorrent">
<BitTorrentOptions @ref="BitTorrentOptions" Preferences="Preferences" PreferencesChanged="PreferencesChanged" />
<BitTorrentOptions @ref="BitTorrentOptions" Preferences="Preferences" UpdatePreferences="@UpdatePreferences" PreferencesChanged="PreferencesChanged" />
</MudTabPanel>
<MudTabPanel Text="RSS">
<RSSOptions @ref="RSSOptions" Preferences="Preferences" PreferencesChanged="PreferencesChanged" />
<RSSOptions @ref="RSSOptions" Preferences="Preferences" UpdatePreferences="@UpdatePreferences" PreferencesChanged="PreferencesChanged" />
</MudTabPanel>
<MudTabPanel Text="Web UI">
<WebUIOptions @ref="WebUIOptions" Preferences="Preferences" PreferencesChanged="PreferencesChanged" />
<WebUIOptions @ref="WebUIOptions" Preferences="Preferences" UpdatePreferences="@UpdatePreferences" PreferencesChanged="PreferencesChanged" />
</MudTabPanel>
<MudTabPanel Text="Advanced">
<AdvancedOptions @ref="AdvancedOptions" Preferences="Preferences" PreferencesChanged="PreferencesChanged" />
<AdvancedOptions @ref="AdvancedOptions" Preferences="Preferences" UpdatePreferences="@UpdatePreferences" PreferencesChanged="PreferencesChanged" />
</MudTabPanel>
</MudTabs>
</MudMainContent>

View File

@@ -109,4 +109,17 @@ td.no-wrap {
.background-blur {
backdrop-filter: blur(10px);
}
.icon-menu::after {
content: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M0 0h24v24H0V0z' fill='none'/%3E%3Cpath d='M7.41 8.59L12 13.17l4.59-4.58L18 10l-6 6-6-6 1.41-1.41z'/%3E%3C/svg%3E");
width: 25px;
height: 25px;
position: absolute;
top: 10px;
right: -5px;
}
.field-switch {
}

View File

@@ -0,0 +1,17 @@
const qbt = {};
qbt.triggerFileDownload = (url, fileName) => {
const anchorElement = document.createElement('a');
anchorElement.href = url;
anchorElement.download = fileName ?? '';
anchorElement.click();
anchorElement.remove();
}
qbt.getBoundingClientRect = (id) => {
const element = document.getElementById(id);
return element.getBoundingClientRect();
}
window.qbt = qbt;

View File

@@ -126,6 +126,24 @@ namespace Lantean.QBitTorrentClient
return await response.Content.ReadAsStringAsync();
}
public async Task<IReadOnlyList<NetworkInterface>> GetNetworkInterfaces()
{
var response = await _httpClient.GetAsync("app/networkInterfaceList");
response.EnsureSuccessStatusCode();
return await GetJsonList<NetworkInterface>(response.Content);
}
public async Task<IReadOnlyList<string>> GetNetworkInterfaceAddressList(string @interface)
{
var response = await _httpClient.GetAsync($"app/networkInterfaceAddressList?iface={@interface}");
response.EnsureSuccessStatusCode();
return await GetJsonList<string>(response.Content);
}
#endregion Application
#region Log
@@ -915,6 +933,11 @@ namespace Lantean.QBitTorrentClient
response.EnsureSuccessStatusCode();
}
public Task<string> GetExportUrl(string hash)
{
return Task.FromResult($"{_httpClient.BaseAddress}torrents/export?hash={hash}");
}
#endregion Torrent management
#region RSS

View File

@@ -30,6 +30,10 @@ namespace Lantean.QBitTorrentClient
Task<string> GetDefaultSavePath();
Task<IReadOnlyList<NetworkInterface>> GetNetworkInterfaces();
Task<IReadOnlyList<string>> GetNetworkInterfaceAddressList(string @interface);
#endregion Application
#region Log
@@ -162,6 +166,8 @@ namespace Lantean.QBitTorrentClient
Task RenameFolder(string hash, string oldPath, string newPath);
Task<string> GetExportUrl(string hash);
#endregion Torrent management
#region RSS

View File

@@ -76,6 +76,11 @@ namespace Lantean.QBitTorrentClient
return _apiClient.EditTracker(hash, originalUrl, newUrl);
}
public Task<string> GetExportUrl(string hash)
{
return _apiClient.GetExportUrl(hash);
}
public Task<IReadOnlyDictionary<string, Category>> GetAllCategories()
{
return _apiClient.GetAllCategories();
@@ -116,6 +121,16 @@ namespace Lantean.QBitTorrentClient
return _apiClient.GetDefaultSavePath();
}
public Task<IReadOnlyList<NetworkInterface>> GetNetworkInterfaces()
{
return _apiClient.GetNetworkInterfaces();
}
public Task<IReadOnlyList<string>> GetNetworkInterfaceAddressList(string @interface)
{
return _apiClient.GetNetworkInterfaceAddressList(@interface);
}
public Task<long> GetGlobalDownloadLimit()
{
return _apiClient.GetGlobalDownloadLimit();

View File

@@ -0,0 +1,22 @@
using System.Text.Json.Serialization;
namespace Lantean.QBitTorrentClient.Models
{
public record NetworkInterface
{
[JsonConstructor]
public NetworkInterface(
string name,
string value)
{
Name = name;
Value = value;
}
[JsonPropertyName("name")]
public string Name { get; }
[JsonPropertyName("value")]
public string Value { get; }
}
}

View File

@@ -17,6 +17,7 @@ namespace Lantean.QBitTorrentClient.Models
bool announceToAllTiers,
bool announceToAllTrackers,
bool anonymousMode,
string appInstanceName,
int asyncIoThreads,
int autoDeleteMode,
bool autoTmmEnabled,
@@ -39,6 +40,7 @@ namespace Lantean.QBitTorrentClient.Models
string currentInterfaceName,
string currentNetworkInterface,
bool dht,
string dhtBootstrapNodes,
int diskCache,
int diskCacheTtl,
int diskIoReadMode,
@@ -100,6 +102,7 @@ namespace Lantean.QBitTorrentClient.Models
string mailNotificationSmtp,
bool mailNotificationSslEnabled,
string mailNotificationUsername,
bool markOfTheWeb,
int maxActiveCheckingTorrents,
int maxActiveDownloads,
int maxActiveTorrents,
@@ -138,6 +141,7 @@ namespace Lantean.QBitTorrentClient.Models
bool proxyRss,
string proxyType,
string proxyUsername,
string pythonExecutablePath,
bool queueingEnabled,
bool randomPort,
bool reannounceWhenAddressChanged,
@@ -147,6 +151,7 @@ namespace Lantean.QBitTorrentClient.Models
bool resolvePeerCountries,
string resumeDataStorageType,
bool rssAutoDownloadingEnabled,
long rssFetchDelay,
bool rssDownloadRepackProperEpisodes,
int rssMaxArticlesPerFeed,
bool rssProcessingEnabled,
@@ -207,7 +212,8 @@ namespace Lantean.QBitTorrentClient.Models
int webUiSessionTimeout,
bool webUiUpnp,
bool webUiUseCustomHttpHeadersEnabled,
string webUiUsername
string webUiUsername,
string webUiPassword
)
{
AddToTopOfQueue = addToTopOfQueue;
@@ -221,6 +227,7 @@ namespace Lantean.QBitTorrentClient.Models
AnnounceToAllTiers = announceToAllTiers;
AnnounceToAllTrackers = announceToAllTrackers;
AnonymousMode = anonymousMode;
AppInstanceName = appInstanceName;
AsyncIoThreads = asyncIoThreads;
AutoDeleteMode = autoDeleteMode;
AutoTmmEnabled = autoTmmEnabled;
@@ -243,6 +250,7 @@ namespace Lantean.QBitTorrentClient.Models
CurrentInterfaceName = currentInterfaceName;
CurrentNetworkInterface = currentNetworkInterface;
Dht = dht;
DhtBootstrapNodes = dhtBootstrapNodes;
DiskCache = diskCache;
DiskCacheTtl = diskCacheTtl;
DiskIoReadMode = diskIoReadMode;
@@ -304,6 +312,7 @@ namespace Lantean.QBitTorrentClient.Models
MailNotificationSmtp = mailNotificationSmtp;
MailNotificationSslEnabled = mailNotificationSslEnabled;
MailNotificationUsername = mailNotificationUsername;
MarkOfTheWeb = markOfTheWeb;
MaxActiveCheckingTorrents = maxActiveCheckingTorrents;
MaxActiveDownloads = maxActiveDownloads;
MaxActiveTorrents = maxActiveTorrents;
@@ -342,6 +351,7 @@ namespace Lantean.QBitTorrentClient.Models
ProxyRss = proxyRss;
ProxyType = proxyType;
ProxyUsername = proxyUsername;
PythonExecutablePath = pythonExecutablePath;
QueueingEnabled = queueingEnabled;
RandomPort = randomPort;
ReannounceWhenAddressChanged = reannounceWhenAddressChanged;
@@ -352,6 +362,7 @@ namespace Lantean.QBitTorrentClient.Models
ResumeDataStorageType = resumeDataStorageType;
RssAutoDownloadingEnabled = rssAutoDownloadingEnabled;
RssDownloadRepackProperEpisodes = rssDownloadRepackProperEpisodes;
RssFetchDelay = rssFetchDelay;
RssMaxArticlesPerFeed = rssMaxArticlesPerFeed;
RssProcessingEnabled = rssProcessingEnabled;
RssRefreshInterval = rssRefreshInterval;
@@ -412,6 +423,7 @@ namespace Lantean.QBitTorrentClient.Models
WebUiUpnp = webUiUpnp;
WebUiUseCustomHttpHeadersEnabled = webUiUseCustomHttpHeadersEnabled;
WebUiUsername = webUiUsername;
WebUiPassword = webUiPassword;
}
[JsonPropertyName("add_to_top_of_queue")]
@@ -447,6 +459,9 @@ namespace Lantean.QBitTorrentClient.Models
[JsonPropertyName("anonymous_mode")]
public bool AnonymousMode { get; }
[JsonPropertyName("app_instance_name")]
public string AppInstanceName { get; }
[JsonPropertyName("async_io_threads")]
public int AsyncIoThreads { get; }
@@ -513,6 +528,9 @@ namespace Lantean.QBitTorrentClient.Models
[JsonPropertyName("dht")]
public bool Dht { get; }
[JsonPropertyName("dht_bootstrap_nodes")]
public string DhtBootstrapNodes { get; }
[JsonPropertyName("disk_cache")]
public int DiskCache { get; }
@@ -696,6 +714,9 @@ namespace Lantean.QBitTorrentClient.Models
[JsonPropertyName("mail_notification_username")]
public string MailNotificationUsername { get; }
[JsonPropertyName("mark_of_the_web")]
public bool MarkOfTheWeb { get; }
[JsonPropertyName("max_active_checking_torrents")]
public int MaxActiveCheckingTorrents { get; }
@@ -810,6 +831,9 @@ namespace Lantean.QBitTorrentClient.Models
[JsonPropertyName("proxy_username")]
public string ProxyUsername { get; }
[JsonPropertyName("python_executable_path")]
public string PythonExecutablePath { get; }
[JsonPropertyName("queueing_enabled")]
public bool QueueingEnabled { get; }
@@ -840,6 +864,9 @@ namespace Lantean.QBitTorrentClient.Models
[JsonPropertyName("rss_download_repack_proper_episodes")]
public bool RssDownloadRepackProperEpisodes { get; }
[JsonPropertyName("rss_fetch_delay")]
public long RssFetchDelay { get; }
[JsonPropertyName("rss_max_articles_per_feed")]
public int RssMaxArticlesPerFeed { get; }
@@ -1019,5 +1046,8 @@ namespace Lantean.QBitTorrentClient.Models
[JsonPropertyName("web_ui_username")]
public string WebUiUsername { get; }
[JsonPropertyName("web_ui_password")]
public string WebUiPassword { get; }
}
}

View File

@@ -37,6 +37,9 @@ namespace Lantean.QBitTorrentClient.Models
[JsonPropertyName("anonymous_mode")]
public bool? AnonymousMode { get; set; }
[JsonPropertyName("app_instance_name")]
public string? AppInstanceName { get; set; }
[JsonPropertyName("async_io_threads")]
public int? AsyncIoThreads { get; set; }
@@ -103,6 +106,9 @@ namespace Lantean.QBitTorrentClient.Models
[JsonPropertyName("dht")]
public bool? Dht { get; set; }
[JsonPropertyName("dht_bootstrap_nodes")]
public string? DhtBootstrapNodes { get; set; }
[JsonPropertyName("disk_cache")]
public int? DiskCache { get; set; }
@@ -286,6 +292,9 @@ namespace Lantean.QBitTorrentClient.Models
[JsonPropertyName("mail_notification_username")]
public string? MailNotificationUsername { get; set; }
[JsonPropertyName("mark_of_the_web")]
public bool? MarkOfTheWeb { get; set; }
[JsonPropertyName("max_active_checking_torrents")]
public int? MaxActiveCheckingTorrents { get; set; }
@@ -400,6 +409,9 @@ namespace Lantean.QBitTorrentClient.Models
[JsonPropertyName("proxy_username")]
public string? ProxyUsername { get; set; }
[JsonPropertyName("python_executable_path")]
public string? PythonExecutablePath { get; set; }
[JsonPropertyName("queueing_enabled")]
public bool? QueueingEnabled { get; set; }
@@ -430,6 +442,9 @@ namespace Lantean.QBitTorrentClient.Models
[JsonPropertyName("rss_download_repack_proper_episodes")]
public bool? RssDownloadRepackProperEpisodes { get; set; }
[JsonPropertyName("rss_fetch_delay")]
public long? RssFetchDelay { get; set; }
[JsonPropertyName("rss_max_articles_per_feed")]
public int? RssMaxArticlesPerFeed { get; set; }
@@ -609,5 +624,8 @@ namespace Lantean.QBitTorrentClient.Models
[JsonPropertyName("web_ui_username")]
public string? WebUiUsername { get; set; }
[JsonPropertyName("web_ui_password")]
public string? WebUiPassword { get; set; }
}
}