Update layout to remove hacks and rely only on flexbox

This commit is contained in:
ahjephson
2025-10-20 16:39:20 +01:00
parent 7db4f2f78d
commit 3d0d211d10
21 changed files with 777 additions and 566 deletions

View File

@@ -2,45 +2,48 @@
<MudMenuItem Icon="@Icons.Material.Filled.DriveFileRenameOutline" OnClick="RenameFileContextMenu">Rename</MudMenuItem> <MudMenuItem Icon="@Icons.Material.Filled.DriveFileRenameOutline" OnClick="RenameFileContextMenu">Rename</MudMenuItem>
</MudMenu> </MudMenu>
<div style="overflow-x: auto; white-space: nowrap; width: 100%;"> <div class="content-panel">
<MudToolBar Gutters="false" Dense="true"> <div class="content-panel__toolbar content-panel__toolbar--scroll">
<MudIconButton Icon="@Icons.Material.Filled.DriveFileRenameOutline" OnClick="RenameFileToolbar" title="Rename" /> <MudToolBar Gutters="false" Dense="true">
<MudDivider Vertical="true" /> <MudIconButton Icon="@Icons.Material.Filled.DriveFileRenameOutline" OnClick="RenameFileToolbar" title="Rename" />
<MudIconButton Icon="@Icons.Material.Outlined.ViewColumn" Color="Color.Inherit" OnClick="ColumnOptions" title="Choose Columns" /> <MudDivider Vertical="true" />
<MudDivider Vertical="true" /> <MudIconButton Icon="@Icons.Material.Outlined.ViewColumn" Color="Color.Inherit" OnClick="ColumnOptions" title="Choose Columns" />
<MudMenu Icon="@Icons.Material.Outlined.FileDownloadOff" Label="Do Not Download" AnchorOrigin="Origin.BottomLeft" TransformOrigin="Origin.TopLeft" title="Do Not Download"> <MudDivider Vertical="true" />
<MudMenuItem OnClick="DoNotDownloadLessThan100PercentAvailability">Less Than 100% Availability</MudMenuItem> <MudMenu Icon="@Icons.Material.Outlined.FileDownloadOff" Label="Do Not Download" AnchorOrigin="Origin.BottomLeft" TransformOrigin="Origin.TopLeft" title="Do Not Download">
<MudMenuItem OnClick="DoNotDownloadLessThan80PercentAvailability">Less than 80% Availability</MudMenuItem> <MudMenuItem OnClick="DoNotDownloadLessThan100PercentAvailability">Less Than 100% Availability</MudMenuItem>
<MudMenuItem OnClick="DoNotDownloadCurrentlyFilteredFiles">Currently Filtered Files</MudMenuItem> <MudMenuItem OnClick="DoNotDownloadLessThan80PercentAvailability">Less than 80% Availability</MudMenuItem>
</MudMenu> <MudMenuItem OnClick="DoNotDownloadCurrentlyFilteredFiles">Currently Filtered Files</MudMenuItem>
<MudMenu Icon="@Icons.Material.Outlined.FileDownload" Label="Normal Priority" AnchorOrigin="Origin.BottomLeft" TransformOrigin="Origin.TopLeft" title="Download"> </MudMenu>
<MudMenuItem OnClick="NormalPriorityLessThan100PercentAvailability">Less Than 100% Availability</MudMenuItem> <MudMenu Icon="@Icons.Material.Outlined.FileDownload" Label="Normal Priority" AnchorOrigin="Origin.BottomLeft" TransformOrigin="Origin.TopLeft" title="Download">
<MudMenuItem OnClick="NormalPriorityLessThan80PercentAvailability">Less than 80% Availability</MudMenuItem> <MudMenuItem OnClick="NormalPriorityLessThan100PercentAvailability">Less Than 100% Availability</MudMenuItem>
<MudMenuItem OnClick="NormalPriorityCurrentlyFilteredFiles">Currently Filtered Files</MudMenuItem> <MudMenuItem OnClick="NormalPriorityLessThan80PercentAvailability">Less than 80% Availability</MudMenuItem>
</MudMenu> <MudMenuItem OnClick="NormalPriorityCurrentlyFilteredFiles">Currently Filtered Files</MudMenuItem>
<MudIconButton Icon="@Icons.Material.Outlined.FilterList" OnClick="ShowFilterDialog" title="Filter" /> </MudMenu>
<MudIconButton Icon="@Icons.Material.Outlined.FilterListOff" OnClick="RemoveFilter" title="Remove Filter" /> <MudIconButton Icon="@Icons.Material.Outlined.FilterList" OnClick="ShowFilterDialog" title="Filter" />
<MudSpacer /> <MudIconButton Icon="@Icons.Material.Outlined.FilterListOff" OnClick="RemoveFilter" title="Remove Filter" />
<MudTextField T="string" Value="SearchText" ValueChanged="SearchTextChanged" Immediate="true" DebounceInterval="500" Placeholder="Filter file list" Adornment="Adornment.Start" AdornmentIcon="@Icons.Material.Filled.Search" IconSize="Size.Medium" Class="mt-0"></MudTextField> <MudSpacer />
</MudToolBar> <MudTextField T="string" Value="SearchText" ValueChanged="SearchTextChanged" Immediate="true" DebounceInterval="500" Placeholder="Filter file list" Adornment="Adornment.Start" AdornmentIcon="@Icons.Material.Filled.Search" IconSize="Size.Medium" Class="mt-0"></MudTextField>
</MudToolBar>
</div>
<div class="content-panel__body">
<DynamicTable
@ref="Table"
T="ContentItem"
ColumnDefinitions="Columns"
Items="Files"
MultiSelection="false"
SelectOnRowClick="true"
PreSorted="true"
SelectedItemChanged="SelectedItemChanged"
SortColumnChanged="SortColumnChanged"
SortDirectionChanged="SortDirectionChanged"
OnTableDataContextMenu="TableDataContextMenu"
OnTableDataLongPress="TableDataLongPress"
Class="file-list content-panel__table"
/>
</div>
</div> </div>
<DynamicTable
@ref="Table"
T="ContentItem"
ColumnDefinitions="Columns"
Items="Files"
MultiSelection="false"
SelectOnRowClick="true"
PreSorted="true"
SelectedItemChanged="SelectedItemChanged"
SortColumnChanged="SortColumnChanged"
SortDirectionChanged="SortDirectionChanged"
OnTableDataContextMenu="TableDataContextMenu"
OnTableDataLongPress="TableDataLongPress"
Class="file-list"
/>
@code { @code {
private RenderFragment<RowContext<ContentItem>> NameColumn private RenderFragment<RowContext<ContentItem>> NameColumn
{ {

View File

@@ -6,19 +6,25 @@
} }
</MudMenu> </MudMenu>
<MudToolBar Gutters="false" Dense="true"> <div class="content-panel">
<MudIconButton Icon="@Icons.Material.Filled.AddCircle" Color="Color.Info" OnClick="AddPeer">Add peer</MudIconButton> <div class="content-panel__toolbar">
<MudIconButton Icon="@Icons.Material.Filled.DisabledByDefault" Color="Color.Error" OnClick="BanPeerToolbar" Disabled="@(SelectedItem is null)">Ban peer</MudIconButton> <MudToolBar Gutters="false" Dense="true">
<MudDivider Vertical="true" /> <MudIconButton Icon="@Icons.Material.Filled.AddCircle" Color="Color.Info" OnClick="AddPeer">Add peer</MudIconButton>
<MudIconButton Icon="@Icons.Material.Outlined.ViewColumn" Color="Color.Inherit" OnClick="ColumnOptions" title="Choose Columns" /> <MudIconButton Icon="@Icons.Material.Filled.DisabledByDefault" Color="Color.Error" OnClick="BanPeerToolbar" Disabled="@(SelectedItem is null)">Ban peer</MudIconButton>
</MudToolBar> <MudDivider Vertical="true" />
<MudIconButton Icon="@Icons.Material.Outlined.ViewColumn" Color="Color.Inherit" OnClick="ColumnOptions" title="Choose Columns" />
</MudToolBar>
</div>
<DynamicTable T="Peer" <div class="content-panel__body">
ColumnDefinitions="Columns" <DynamicTable T="Peer"
Items="Peers" ColumnDefinitions="Columns"
MultiSelection="false" Items="Peers"
SelectOnRowClick="true" MultiSelection="false"
OnTableDataLongPress="TableDataLongPress" SelectOnRowClick="true"
OnTableDataContextMenu="TableDataContextMenu" OnTableDataLongPress="TableDataLongPress"
SelectedItemChanged="SelectedItemChanged" OnTableDataContextMenu="TableDataContextMenu"
Class="details-list" /> SelectedItemChanged="SelectedItemChanged"
Class="details-list content-panel__table" />
</div>
</div>

View File

@@ -8,25 +8,31 @@
} }
</MudMenu> </MudMenu>
<MudToolBar Gutters="false" Dense="true"> <div class="content-panel">
<MudIconButton Icon="@Icons.Material.Filled.AddCircle" Color="Color.Info" OnClick="AddTracker">Add trackers</MudIconButton> <div class="content-panel__toolbar">
<MudIconButton Icon="@Icons.Material.Filled.Edit" Color="Color.Info" OnClick="EditTrackerToolbar" Disabled="@(SelectedItem is null)">Edit tracker URL</MudIconButton> <MudToolBar Gutters="false" Dense="true">
<MudIconButton Icon="@Icons.Material.Filled.Delete" Color="Color.Error" OnClick="RemoveTrackerToolbar" Disabled="@(SelectedItem is null)">Remove tracker</MudIconButton> <MudIconButton Icon="@Icons.Material.Filled.AddCircle" Color="Color.Info" OnClick="AddTracker">Add trackers</MudIconButton>
<MudIconButton Icon="@Icons.Material.Filled.FolderCopy" Color="Color.Info" OnClick="CopyTrackerUrlToolbar" Disabled="@(SelectedItem is null)">Copy tracker url</MudIconButton> <MudIconButton Icon="@Icons.Material.Filled.Edit" Color="Color.Info" OnClick="EditTrackerToolbar" Disabled="@(SelectedItem is null)">Edit tracker URL</MudIconButton>
<MudDivider Vertical="true" /> <MudIconButton Icon="@Icons.Material.Filled.Delete" Color="Color.Error" OnClick="RemoveTrackerToolbar" Disabled="@(SelectedItem is null)">Remove tracker</MudIconButton>
<MudIconButton Icon="@Icons.Material.Outlined.ViewColumn" Color="Color.Inherit" OnClick="ColumnOptions" title="Choose Columns" /> <MudIconButton Icon="@Icons.Material.Filled.FolderCopy" Color="Color.Info" OnClick="CopyTrackerUrlToolbar" Disabled="@(SelectedItem is null)">Copy tracker url</MudIconButton>
</MudToolBar> <MudDivider Vertical="true" />
<MudIconButton Icon="@Icons.Material.Outlined.ViewColumn" Color="Color.Inherit" OnClick="ColumnOptions" title="Choose Columns" />
</MudToolBar>
</div>
<DynamicTable @ref="Table" <div class="content-panel__body">
T="Lantean.QBitTorrentClient.Models.TorrentTracker" <DynamicTable @ref="Table"
ColumnDefinitions="Columns" T="Lantean.QBitTorrentClient.Models.TorrentTracker"
Items="Trackers" ColumnDefinitions="Columns"
MultiSelection="false" Items="Trackers"
SelectOnRowClick="false" MultiSelection="false"
PreSorted="true" SelectOnRowClick="false"
SortDirectionChanged="SortDirectionChanged" PreSorted="true"
SortColumnChanged="SortColumnChanged" SortDirectionChanged="SortDirectionChanged"
OnTableDataLongPress="TableDataLongPress" SortColumnChanged="SortColumnChanged"
OnTableDataContextMenu="TableDataContextMenu" OnTableDataLongPress="TableDataLongPress"
SelectedItemChanged="SelectedItemChanged" OnTableDataContextMenu="TableDataContextMenu"
Class="file-list" /> SelectedItemChanged="SelectedItemChanged"
Class="file-list content-panel__table" />
</div>
</div>

View File

@@ -1,6 +1,10 @@
<DynamicTable T="Lantean.QBitTorrentClient.Models.WebSeed" <div class="content-panel">
ColumnDefinitions="Columns" <div class="content-panel__body">
Items="WebSeeds" <DynamicTable T="Lantean.QBitTorrentClient.Models.WebSeed"
MultiSelection="false" ColumnDefinitions="Columns"
SelectOnRowClick="false" Items="WebSeeds"
Class="details-list" /> MultiSelection="false"
SelectOnRowClick="false"
Class="details-list content-panel__table" />
</div>
</div>

View File

@@ -1,9 +1,11 @@
@inherits LayoutComponentBase @inherits LayoutComponentBase
@layout LoggedInLayout @layout LoggedInLayout
<MudDrawer Open="DrawerOpen" ClipMode="DrawerClipMode.Always" Elevation="2" Overlay="false"> <div class="app-shell__body">
<TorrentsListNav Torrents="Torrents" SelectedTorrent="@SelectedTorrent" SortDirection="SortDirection" SortColumn="@SortColumn" /> <MudDrawer Open="DrawerOpen" ClipMode="DrawerClipMode.Always" Elevation="2" Overlay="false" Class="app-shell__sidebar">
</MudDrawer> <TorrentsListNav Torrents="Torrents" SelectedTorrent="@SelectedTorrent" SortDirection="SortDirection" SortColumn="@SortColumn" />
<MudMainContent> </MudDrawer>
@Body <MudMainContent Class="app-shell__main">
</MudMainContent> @Body
</MudMainContent>
</div>

View File

@@ -1,11 +1,13 @@
@inherits LayoutComponentBase @inherits LayoutComponentBase
@layout LoggedInLayout @layout LoggedInLayout
<MudDrawer Open="DrawerOpen" ClipMode="DrawerClipMode.Always" Elevation="2" Overlay="false"> <div class="app-shell__body">
<FiltersNav CategoryChanged="CategoryChanged" StatusChanged="StatusChanged" TagChanged="TagChanged" TrackerChanged="TrackerChanged" /> <MudDrawer Open="DrawerOpen" ClipMode="DrawerClipMode.Always" Elevation="2" Overlay="false" Class="app-shell__sidebar">
</MudDrawer> <FiltersNav CategoryChanged="CategoryChanged" StatusChanged="StatusChanged" TagChanged="TagChanged" TrackerChanged="TrackerChanged" />
<MudMainContent> </MudDrawer>
<CascadingValue Value="SearchTermChanged" Name="SearchTermChanged"> <MudMainContent Class="app-shell__main">
@Body <CascadingValue Value="SearchTermChanged" Name="SearchTermChanged">
</CascadingValue> @Body
</MudMainContent> </CascadingValue>
</MudMainContent>
</div>

View File

@@ -12,19 +12,51 @@
<CascadingValue Value="Torrents"> <CascadingValue Value="Torrents">
<CascadingValue Value="_torrentsVersion" Name="TorrentsVersion"> <CascadingValue Value="_torrentsVersion" Name="TorrentsVersion">
<CascadingValue Value="MainData"> <CascadingValue Value="MainData">
<CascadingValue Value="Preferences"> <CascadingValue Value="Preferences">
<CascadingValue Value="SortColumnChanged" Name="SortColumnChanged"> <CascadingValue Value="SortColumnChanged" Name="SortColumnChanged">
<CascadingValue Value="SortColumn" Name="SortColumn"> <CascadingValue Value="SortColumn" Name="SortColumn">
<CascadingValue Value="SortDirectionChanged" Name="SortDirectionChanged"> <CascadingValue Value="SortDirectionChanged" Name="SortDirectionChanged">
<CascadingValue Value="SortDirection" Name="SortDirection"> <CascadingValue Value="SortDirection" Name="SortDirection">
<CascadingValue Value="CategoryChanged" Name="CategoryChanged"> <CascadingValue Value="CategoryChanged" Name="CategoryChanged">
<CascadingValue Value="StatusChanged" Name="StatusChanged"> <CascadingValue Value="StatusChanged" Name="StatusChanged">
<CascadingValue Value="TagChanged" Name="TagChanged"> <CascadingValue Value="TagChanged" Name="TagChanged">
<CascadingValue Value="TrackerChanged" Name="TrackerChanged"> <CascadingValue Value="TrackerChanged" Name="TrackerChanged">
<CascadingValue Value="SearchTermChanged" Name="SearchTermChanged"> <CascadingValue Value="SearchTermChanged" Name="SearchTermChanged">
<CascadingValue Value="@(MainData?.LostConnection ?? false)" Name="LostConnection"> <CascadingValue Value="@(MainData?.LostConnection ?? false)" Name="LostConnection">
<CascadingValue Value="Version" Name="Version"> <CascadingValue Value="Version" Name="Version">
@Body <div class="app-shell">
@Body
<MudAppBar Bottom="true" Elevation="0" Dense="true" Class="app-shell__status-bar">
@if (MainData?.LostConnection == true)
{
<MudText Class="mx-2 mb-1 d-none d-sm-flex" Color="Color.Error">qBittorrent client is not reachable</MudText>
}
<MudSpacer />
<MudText Class="mx-2 mb-1 d-none d-sm-flex">@DisplayHelpers.Size(MainData?.ServerState.FreeSpaceOnDisk, "Free space: ")</MudText>
<MudDivider Vertical="true" Class="d-none d-sm-flex" />
<MudText Class="mx-2 mb-1 d-none d-sm-flex">DHT @(MainData?.ServerState.DHTNodes ?? 0) nodes</MudText>
<MudDivider Vertical="true" Class="d-none d-sm-flex" />
@{
var (icon, colour) = GetConnectionIcon(MainData?.ServerState.ConnectionStatus);
}
<MudIcon Class="mx-1 mb-1" Icon="@icon" Color="@colour" Title="@MainData?.ServerState.ConnectionStatus" />
<MudDivider Vertical="true" Class="" />
<MudIcon Class="mx-1 mb-1" Icon="@Icons.Material.Outlined.Speed" Color="@((MainData?.ServerState.UseAltSpeedLimits ?? false) ? Color.Error : Color.Success)" />
<MudDivider Vertical="true" Class="" />
<MudIcon Class="ml-1 mb-1" Icon="@Icons.Material.Filled.KeyboardDoubleArrowDown" Color="Color.Success" />
<MudText Class="mr-1 mb-1">
@DisplayHelpers.Size(MainData?.ServerState.DownloadInfoSpeed, null, "/s")
@DisplayHelpers.Size(MainData?.ServerState.DownloadInfoData, "(", ")")
</MudText>
<MudDivider Vertical="true" />
<MudIcon Class="ml-1 mb-1" Icon="@Icons.Material.Filled.KeyboardDoubleArrowUp" Color="Color.Info" />
<MudText Class="mr-1 mb-1">
@DisplayHelpers.Size(MainData?.ServerState.UploadInfoSpeed, null, "/s")
@DisplayHelpers.Size(MainData?.ServerState.UploadInfoData, "(", ")")
</MudText>
</MudAppBar>
</div>
</CascadingValue>
</CascadingValue> </CascadingValue>
</CascadingValue> </CascadingValue>
</CascadingValue> </CascadingValue>
@@ -37,35 +69,5 @@
</CascadingValue> </CascadingValue>
</CascadingValue> </CascadingValue>
</CascadingValue> </CascadingValue>
<MudAppBar Bottom="true" Fixed="true" Elevation="0" Dense="true" Style="background-color: var(--mud-palette-dark-lighten); z-index: 900">
@if (MainData?.LostConnection == true)
{
<MudText Class="mx-2 mb-1 d-none d-sm-flex" Color="Color.Error">qBittorrent client is not reachable</MudText>
}
<MudSpacer />
<MudText Class="mx-2 mb-1 d-none d-sm-flex">@DisplayHelpers.Size(MainData?.ServerState.FreeSpaceOnDisk, "Free space: ")</MudText>
<MudDivider Vertical="true" Class="d-none d-sm-flex" />
<MudText Class="mx-2 mb-1 d-none d-sm-flex">DHT @(MainData?.ServerState.DHTNodes ?? 0) nodes</MudText>
<MudDivider Vertical="true" Class="d-none d-sm-flex" />
@{
var (icon, colour) = GetConnectionIcon(MainData?.ServerState.ConnectionStatus);
}
<MudIcon Class="mx-1 mb-1" Icon="@icon" Color="@colour" Title="@MainData?.ServerState.ConnectionStatus" />
<MudDivider Vertical="true" Class="" />
<MudIcon Class="mx-1 mb-1" Icon="@Icons.Material.Outlined.Speed" Color="@((MainData?.ServerState.UseAltSpeedLimits ?? false) ? Color.Error : Color.Success)" />
<MudDivider Vertical="true" Class="" />
<MudIcon Class="ml-1 mb-1" Icon="@Icons.Material.Filled.KeyboardDoubleArrowDown" Color="Color.Success" />
<MudText Class="mr-1 mb-1">
@DisplayHelpers.Size(MainData?.ServerState.DownloadInfoSpeed, null, "/s")
@DisplayHelpers.Size(MainData?.ServerState.DownloadInfoData, "(", ")")
</MudText>
<MudDivider Vertical="true" />
<MudIcon Class="ml-1 mb-1" Icon="@Icons.Material.Filled.KeyboardDoubleArrowUp" Color="Color.Info" />
<MudText Class="mr-1 mb-1">
@DisplayHelpers.Size(MainData?.ServerState.UploadInfoSpeed, null, "/s")
@DisplayHelpers.Size(MainData?.ServerState.UploadInfoData, "(", ")")
</MudText>
</MudAppBar>
</CascadingValue>
</CascadingValue> </CascadingValue>
</CascadingValue> </CascadingValue>

View File

@@ -1,11 +1,13 @@
@inherits LayoutComponentBase @inherits LayoutComponentBase
@layout LoggedInLayout @layout LoggedInLayout
<MudDrawer Open="DrawerOpen" ClipMode="DrawerClipMode.Always" Elevation="2" Overlay="false"> <div class="app-shell__body">
<MudNavMenu> <MudDrawer Open="DrawerOpen" ClipMode="DrawerClipMode.Always" Elevation="2" Overlay="false" Class="app-shell__sidebar">
<ApplicationActions IsMenu="false" Preferences="Preferences" /> <MudNavMenu>
</MudNavMenu> <ApplicationActions IsMenu="false" Preferences="Preferences" />
</MudDrawer> </MudNavMenu>
<MudMainContent> </MudDrawer>
@Body <MudMainContent Class="app-shell__main">
</MudMainContent> @Body
</MudMainContent>
</div>

View File

@@ -2,14 +2,14 @@
{ {
public class FileRow public class FileRow
{ {
public string OriginalName { get; set; } public required string OriginalName { get; set; }
public string? NewName { get; set; } public string? NewName { get; set; }
public bool IsFolder { get; set; } public bool IsFolder { get; set; }
public string Name { get; set; } public required string Name { get; set; }
public int Level { get; set; } public int Level { get; set; }
public bool Renamed { get; set; } public bool Renamed { get; set; }
public string? ErrorMessage { get; set; } public string? ErrorMessage { get; set; }
public string Path { get; set; } public required string Path { get; set; }
public override bool Equals(object? obj) public override bool Equals(object? obj)
{ {

View File

@@ -1,18 +1,22 @@
@page "/about" @page "/about"
@layout OtherLayout @layout OtherLayout
<MudToolBar Gutters="false" Dense="true"> <div class="content-panel">
@if (!DrawerOpen) <div class="content-panel__toolbar">
{ <MudToolBar Gutters="false" Dense="true">
<MudIconButton Icon="@Icons.Material.Outlined.NavigateBefore" OnClick="NavigateBack" title="Back to torrent list" /> @if (!DrawerOpen)
<MudDivider Vertical="true" /> {
} <MudIconButton Icon="@Icons.Material.Outlined.NavigateBefore" OnClick="NavigateBack" title="Back to torrent list" />
<MudText Class="px-5 no-wrap">About</MudText> <MudDivider Vertical="true" />
</MudToolBar> }
<MudText Class="px-5 no-wrap">About</MudText>
</MudToolBar>
</div>
<MudTabs Elevation="2" ApplyEffectsToContainer="true"> <div class="content-panel__body">
<MudTabPanel Text="About"> <MudTabs Elevation="2" ApplyEffectsToContainer="true">
<MudContainer MaxWidth="MaxWidth.ExtraExtraLarge" Class="mt-3"> <MudTabPanel Text="About">
<MudContainer MaxWidth="MaxWidth.ExtraExtraLarge" Class="mt-3 content-panel__container">
<MudGrid Class="mt-0 mb-4"> <MudGrid Class="mt-0 mb-4">
<MudItem xs="12" sm="3" md="2" lg="2" xl="1" Class="d-flex justify-center"> <MudItem xs="12" sm="3" md="2" lg="2" xl="1" Class="d-flex justify-center">
<MudImage Src="images/mascot.png" Alt="Mascot" Class="ma-6" <MudImage Src="images/mascot.png" Alt="Mascot" Class="ma-6"
@@ -1104,4 +1108,6 @@
<MudText Typo="Typo.body1" Class="py-1">The free IP to Country Lite database by DB-IP is used for resolving the countries of peers. The database is licensed under the Creative Commons Attribution 4.0 International License (<MudLink Target="https://db-ip.com/" Href="https://db-ip.com/" rel="noopener ">https://db-ip.com/</MudLink>)</MudText> <MudText Typo="Typo.body1" Class="py-1">The free IP to Country Lite database by DB-IP is used for resolving the countries of peers. The database is licensed under the Creative Commons Attribution 4.0 International License (<MudLink Target="https://db-ip.com/" Href="https://db-ip.com/" rel="noopener ">https://db-ip.com/</MudLink>)</MudText>
</MudContainer> </MudContainer>
</MudTabPanel> </MudTabPanel>
</MudTabs> </MudTabs>
</div>
</div>

View File

@@ -1,36 +1,41 @@
@page "/blocks" @page "/blocks"
@layout OtherLayout @layout OtherLayout
<MudToolBar Gutters="false" Dense="true"> <div class="content-panel">
@if (!DrawerOpen) <div class="content-panel__toolbar">
{ <MudToolBar Gutters="false" Dense="true">
<MudIconButton Icon="@Icons.Material.Outlined.NavigateBefore" OnClick="NavigateBack" title="Back to torrent list" /> @if (!DrawerOpen)
<MudDivider Vertical="true" /> {
} <MudIconButton Icon="@Icons.Material.Outlined.NavigateBefore" OnClick="NavigateBack" title="Back to torrent list" />
<MudDivider Vertical="true" /> <MudDivider Vertical="true" />
<MudText Class="pl-5 no-wrap">Blocked IPs</MudText> }
</MudToolBar> <MudDivider Vertical="true" />
<MudText Class="pl-5 no-wrap">Blocked IPs</MudText>
</MudToolBar>
</div>
<div class="content-panel__body">
<MudCard Elevation="1" Class="ml-4 mr-4 mb-4">
<MudCardContent>
<EditForm Model="Model" OnSubmit="Submit">
<MudGrid>
<MudItem md="10">
<MudTextField T="string" Label="Criteria" @bind-Value="Model.Criteria" Variant="Variant.Outlined" />
</MudItem>
<MudItem md="2">
<MudButton ButtonType="ButtonType.Submit" FullWidth="true" Color="Color.Primary" EndIcon="@Icons.Material.Filled.Search" Variant="Variant.Filled" Class="mt-6">Filter</MudButton>
</MudItem>
</MudGrid>
</EditForm>
</MudCardContent>
</MudCard>
<MudCard Elevation="1" Class="ml-4 mr-4 mb-4"> <DynamicTable @ref="Table"
<MudCardContent> T="Lantean.QBitTorrentClient.Models.PeerLog"
<EditForm Model="Model" OnSubmit="Submit"> ColumnDefinitions="Columns"
<MudGrid> Items="Results"
<MudItem md="10"> MultiSelection="false"
<MudTextField T="string" Label="Criteria" @bind-Value="Model.Criteria" Variant="Variant.Outlined" /> SelectOnRowClick="false"
</MudItem> RowClassFunc="RowClass"
<MudItem md="2"> Class="search-list content-panel__table" />
<MudButton ButtonType="ButtonType.Submit" FullWidth="true" Color="Color.Primary" EndIcon="@Icons.Material.Filled.Search" Variant="Variant.Filled" Class="mt-6">Filter</MudButton> </div>
</MudItem> </div>
</MudGrid>
</EditForm>
</MudCardContent>
</MudCard>
<DynamicTable @ref="Table"
T="Lantean.QBitTorrentClient.Models.PeerLog"
ColumnDefinitions="Columns"
Items="Results"
MultiSelection="false"
SelectOnRowClick="false"
RowClassFunc="RowClass"
Class="search-list" />

View File

@@ -1,24 +1,30 @@
@page "/categories" @page "/categories"
@layout OtherLayout @layout OtherLayout
<MudToolBar Gutters="false" Dense="true"> <div class="content-panel">
@if (!DrawerOpen) <div class="content-panel__toolbar">
{ <MudToolBar Gutters="false" Dense="true">
<MudIconButton Icon="@Icons.Material.Outlined.NavigateBefore" OnClick="NavigateBack" title="Back to torrent list" /> @if (!DrawerOpen)
<MudDivider Vertical="true" /> {
} <MudIconButton Icon="@Icons.Material.Outlined.NavigateBefore" OnClick="NavigateBack" title="Back to torrent list" />
<MudText Class="px-5 no-wrap">Categories</MudText> <MudDivider Vertical="true" />
<MudDivider Vertical="true" /> }
<MudIconButton Icon="@Icons.Material.Filled.PlaylistAdd" OnClick="AddCategory" title="Add Category" /> <MudText Class="px-5 no-wrap">Categories</MudText>
</MudToolBar> <MudDivider Vertical="true" />
<MudIconButton Icon="@Icons.Material.Filled.PlaylistAdd" OnClick="AddCategory" title="Add Category" />
</MudToolBar>
</div>
<DynamicTable @ref="Table" <div class="content-panel__body">
T="Category" <DynamicTable @ref="Table"
ColumnDefinitions="Columns" T="Category"
Items="Results" ColumnDefinitions="Columns"
MultiSelection="false" Items="Results"
SelectOnRowClick="false" MultiSelection="false"
Class="details-list" /> SelectOnRowClick="false"
Class="details-list content-panel__table" />
</div>
</div>
@code { @code {
private RenderFragment<RowContext<Category>> ActionsColumn private RenderFragment<RowContext<Category>> ActionsColumn

View File

@@ -1,41 +1,45 @@
@page "/details/{hash}" @page "/details/{hash}"
@layout DetailsLayout @layout DetailsLayout
<div style="overflow-x: auto; white-space: nowrap; width: 100%;"> <div class="content-panel">
<MudToolBar Gutters="false" Dense="true"> <div class="content-panel__toolbar content-panel__toolbar--scroll">
@if (!DrawerOpen) <MudToolBar Gutters="false" Dense="true">
{ @if (!DrawerOpen)
<MudIconButton Icon="@Icons.Material.Outlined.NavigateBefore" OnClick="NavigateBack" title="Back to torrent list" /> {
<MudDivider Vertical="true" /> <MudIconButton Icon="@Icons.Material.Outlined.NavigateBefore" OnClick="NavigateBack" title="Back to torrent list" />
} <MudDivider Vertical="true" />
@if (Hash is not null) }
{ @if (Hash is not null)
<TorrentActions RenderType="RenderType.InitialIconsOnly" Hashes="@([Hash])" Torrents="MainData.Torrents" Preferences="Preferences" /> {
} <TorrentActions RenderType="RenderType.InitialIconsOnly" Hashes="@([Hash])" Torrents="MainData.Torrents" Preferences="Preferences" />
<MudDivider Vertical="true" /> }
<MudText Class="pl-5 no-wrap">@Name</MudText> <MudDivider Vertical="true" />
</MudToolBar> <MudText Class="pl-5 no-wrap">@Name</MudText>
</div> </MudToolBar>
</div>
@if (ShowTabs) <div class="content-panel__body">
{ @if (ShowTabs)
<CascadingValue Value="RefreshInterval" Name="RefreshInterval"> {
<MudTabs Elevation="2" ApplyEffectsToContainer="true" @bind-ActivePanelIndex="ActiveTab" KeepPanelsAlive="true" Border="true"> <CascadingValue Value="RefreshInterval" Name="RefreshInterval">
<MudTabPanel Text="General"> <MudTabs Elevation="2" ApplyEffectsToContainer="true" @bind-ActivePanelIndex="ActiveTab" KeepPanelsAlive="true" Border="true">
<GeneralTab Hash="@Hash" Active="@(ActiveTab == 0)" /> <MudTabPanel Text="General">
</MudTabPanel> <GeneralTab Hash="@Hash" Active="@(ActiveTab == 0)" />
<MudTabPanel Text="Trackers"> </MudTabPanel>
<TrackersTab Hash="@Hash" Active="@(ActiveTab == 1)" /> <MudTabPanel Text="Trackers">
</MudTabPanel> <TrackersTab Hash="@Hash" Active="@(ActiveTab == 1)" />
<MudTabPanel Text="Peers"> </MudTabPanel>
<PeersTab Hash="@Hash" Active="@(ActiveTab == 2)" /> <MudTabPanel Text="Peers">
</MudTabPanel> <PeersTab Hash="@Hash" Active="@(ActiveTab == 2)" />
<MudTabPanel Text="HTTP Sources"> </MudTabPanel>
<WebSeedsTab Hash="@Hash" Active="@(ActiveTab == 3)" /> <MudTabPanel Text="HTTP Sources">
</MudTabPanel> <WebSeedsTab Hash="@Hash" Active="@(ActiveTab == 3)" />
<MudTabPanel Text="Content"> </MudTabPanel>
<FilesTab Hash="@Hash" Active="@(ActiveTab == 4)" /> <MudTabPanel Text="Content">
</MudTabPanel> <FilesTab Hash="@Hash" Active="@(ActiveTab == 4)" />
</MudTabs> </MudTabPanel>
</CascadingValue> </MudTabs>
} </CascadingValue>
}
</div>
</div>

View File

@@ -1,44 +1,49 @@
@page "/log" @page "/log"
@layout OtherLayout @layout OtherLayout
<MudToolBar Gutters="false" Dense="true"> <div class="content-panel">
@if (!DrawerOpen) <div class="content-panel__toolbar">
{ <MudToolBar Gutters="false" Dense="true">
<MudIconButton Icon="@Icons.Material.Outlined.NavigateBefore" OnClick="NavigateBack" title="Back to torrent list" /> @if (!DrawerOpen)
<MudDivider Vertical="true" /> {
} <MudIconButton Icon="@Icons.Material.Outlined.NavigateBefore" OnClick="NavigateBack" title="Back to torrent list" />
<MudDivider Vertical="true" /> <MudDivider Vertical="true" />
<MudText Class="pl-5 no-wrap">Execution Log</MudText> }
</MudToolBar> <MudDivider Vertical="true" />
<MudText Class="pl-5 no-wrap">Execution Log</MudText>
</MudToolBar>
</div>
<div class="content-panel__body">
<MudCard Elevation="1" Class="ml-4 mr-4 mb-4">
<MudCardContent>
<EditForm Model="Model" OnSubmit="Submit">
<MudGrid>
<MudItem md="7">
<MudTextField T="string" Label="Criteria" @bind-Value="Model.Criteria" Variant="Variant.Outlined" />
</MudItem>
<MudItem md="3">
<MudSelect @ref="CategoryMudSelect" T="string" Label="Categories" SelectedValues="Model.SelectedTypes" SelectedValuesChanged="SelectedValuesChanged" Variant="Variant.Outlined" MultiSelection="true" MultiSelectionTextFunc="GenerateSelectedText" SelectAll="true">
<MudSelectItem Value="@("Normal")">Normal</MudSelectItem>
<MudSelectItem Value="@("Info")">Info</MudSelectItem>
<MudSelectItem Value="@("Warning")">Warning</MudSelectItem>
<MudSelectItem Value="@("Critical")">Critical</MudSelectItem>
</MudSelect>
</MudItem>
<MudItem md="2">
<MudButton ButtonType="ButtonType.Submit" FullWidth="true" Color="Color.Primary" EndIcon="@Icons.Material.Filled.Search" Variant="Variant.Filled" Class="mt-6">Filter</MudButton>
</MudItem>
</MudGrid>
</EditForm>
</MudCardContent>
</MudCard>
<MudCard Elevation="1" Class="ml-4 mr-4 mb-4"> <DynamicTable @ref="Table"
<MudCardContent> T="Lantean.QBitTorrentClient.Models.Log"
<EditForm Model="Model" OnSubmit="Submit"> ColumnDefinitions="Columns"
<MudGrid> Items="Results"
<MudItem md="7"> MultiSelection="false"
<MudTextField T="string" Label="Criteria" @bind-Value="Model.Criteria" Variant="Variant.Outlined" /> SelectOnRowClick="false"
</MudItem> RowClassFunc="RowClass"
<MudItem md="3"> Class="search-list content-panel__table" />
<MudSelect @ref="CategoryMudSelect" T="string" Label="Categories" SelectedValues="Model.SelectedTypes" SelectedValuesChanged="SelectedValuesChanged" Variant="Variant.Outlined" MultiSelection="true" MultiSelectionTextFunc="GenerateSelectedText" SelectAll="true"> </div>
<MudSelectItem Value="@("Normal")">Normal</MudSelectItem> </div>
<MudSelectItem Value="@("Info")">Info</MudSelectItem>
<MudSelectItem Value="@("Warning")">Warning</MudSelectItem>
<MudSelectItem Value="@("Critical")">Critical</MudSelectItem>
</MudSelect>
</MudItem>
<MudItem md="2">
<MudButton ButtonType="ButtonType.Submit" FullWidth="true" Color="Color.Primary" EndIcon="@Icons.Material.Filled.Search" Variant="Variant.Filled" Class="mt-6">Filter</MudButton>
</MudItem>
</MudGrid>
</EditForm>
</MudCardContent>
</MudCard>
<DynamicTable @ref="Table"
T="Lantean.QBitTorrentClient.Models.Log"
ColumnDefinitions="Columns"
Items="Results"
MultiSelection="false"
SelectOnRowClick="false"
RowClassFunc="RowClass"
Class="search-list" />

View File

@@ -3,41 +3,63 @@
<NavigationLock ConfirmExternalNavigation="@(UpdatePreferences is not null)" OnBeforeInternalNavigation="ValidateExit" /> <NavigationLock ConfirmExternalNavigation="@(UpdatePreferences is not null)" OnBeforeInternalNavigation="ValidateExit" />
<MudToolBar Gutters="false" Dense="true"> <div class="content-panel">
@if (!DrawerOpen) <div class="content-panel__toolbar">
{ <MudToolBar Gutters="false" Dense="true">
<MudIconButton Icon="@Icons.Material.Outlined.NavigateBefore" OnClick="NavigateBack" /> @if (!DrawerOpen)
<MudDivider Vertical="true" /> {
} <MudIconButton Icon="@Icons.Material.Outlined.NavigateBefore" OnClick="NavigateBack" />
<MudText Class="px-5 no-wrap">Settings</MudText> <MudDivider Vertical="true" />
<MudDivider Vertical="true" /> }
<MudIconButton Icon="@Icons.Material.Outlined.Save" OnClick="Save" Disabled="@(LostConnection || UpdatePreferences is null)" /> <MudText Class="px-5 no-wrap">Settings</MudText>
<MudIconButton Icon="@Icons.Material.Outlined.Undo" OnClick="Undo" Disabled="@(LostConnection || UpdatePreferences is null)" /> <MudDivider Vertical="true" />
</MudToolBar> <MudIconButton Icon="@Icons.Material.Outlined.Save" OnClick="Save" Disabled="@(LostConnection || UpdatePreferences is null)" />
<MudIconButton Icon="@Icons.Material.Outlined.Undo" OnClick="Undo" Disabled="@(LostConnection || UpdatePreferences is null)" />
</MudToolBar>
</div>
<MudTabs Elevation="2" ApplyEffectsToContainer="true" @bind-ActivePanelIndex="ActiveTab" Border="true"> <div class="content-panel__body">
<MudTabPanel Text="Behaviour"> <MudTabs Elevation="2" ApplyEffectsToContainer="true" @bind-ActivePanelIndex="ActiveTab" Border="true">
<BehaviourOptions @ref="BehaviourOptions" Preferences="Preferences" UpdatePreferences="@UpdatePreferences" PreferencesChanged="PreferencesChanged" /> <MudTabPanel Text="Behaviour">
</MudTabPanel> <div class="options-tab-contents">
<MudTabPanel Text="Downloads"> <BehaviourOptions @ref="BehaviourOptions" Preferences="Preferences" UpdatePreferences="@UpdatePreferences" PreferencesChanged="PreferencesChanged" />
<DownloadsOptions @ref="DownloadsOptions" Preferences="Preferences" UpdatePreferences="@UpdatePreferences" PreferencesChanged="PreferencesChanged" /> </div>
</MudTabPanel> </MudTabPanel>
<MudTabPanel Text="Connection"> <MudTabPanel Text="Downloads">
<ConnectionOptions @ref="ConnectionOptions" Preferences="Preferences" UpdatePreferences="@UpdatePreferences" PreferencesChanged="PreferencesChanged" /> <div class="options-tab-contents">
</MudTabPanel> <DownloadsOptions @ref="DownloadsOptions" Preferences="Preferences" UpdatePreferences="@UpdatePreferences" PreferencesChanged="PreferencesChanged" />
<MudTabPanel Text="Speed"> </div>
<SpeedOptions @ref="SpeedOptions" Preferences="Preferences" UpdatePreferences="@UpdatePreferences" PreferencesChanged="PreferencesChanged" /> </MudTabPanel>
</MudTabPanel> <MudTabPanel Text="Connection">
<MudTabPanel Text="BitTorrent"> <div class="options-tab-contents">
<BitTorrentOptions @ref="BitTorrentOptions" Preferences="Preferences" UpdatePreferences="@UpdatePreferences" PreferencesChanged="PreferencesChanged" /> <ConnectionOptions @ref="ConnectionOptions" Preferences="Preferences" UpdatePreferences="@UpdatePreferences" PreferencesChanged="PreferencesChanged" />
</MudTabPanel> </div>
<MudTabPanel Text="RSS"> </MudTabPanel>
<RSSOptions @ref="RSSOptions" Preferences="Preferences" UpdatePreferences="@UpdatePreferences" PreferencesChanged="PreferencesChanged" /> <MudTabPanel Text="Speed">
</MudTabPanel> <div class="options-tab-contents">
<MudTabPanel Text="Web UI"> <SpeedOptions @ref="SpeedOptions" Preferences="Preferences" UpdatePreferences="@UpdatePreferences" PreferencesChanged="PreferencesChanged" />
<WebUIOptions @ref="WebUIOptions" Preferences="Preferences" UpdatePreferences="@UpdatePreferences" PreferencesChanged="PreferencesChanged" /> </div>
</MudTabPanel> </MudTabPanel>
<MudTabPanel Text="Advanced"> <MudTabPanel Text="BitTorrent">
<AdvancedOptions @ref="AdvancedOptions" Preferences="Preferences" UpdatePreferences="@UpdatePreferences" PreferencesChanged="PreferencesChanged" /> <div class="options-tab-contents">
</MudTabPanel> <BitTorrentOptions @ref="BitTorrentOptions" Preferences="Preferences" UpdatePreferences="@UpdatePreferences" PreferencesChanged="PreferencesChanged" />
</MudTabs> </div>
</MudTabPanel>
<MudTabPanel Text="RSS">
<div class="options-tab-contents">
<RSSOptions @ref="RSSOptions" Preferences="Preferences" UpdatePreferences="@UpdatePreferences" PreferencesChanged="PreferencesChanged" />
</div>
</MudTabPanel>
<MudTabPanel Text="Web UI">
<div class="options-tab-contents">
<WebUIOptions @ref="WebUIOptions" Preferences="Preferences" UpdatePreferences="@UpdatePreferences" PreferencesChanged="PreferencesChanged" />
</div>
</MudTabPanel>
<MudTabPanel Text="Advanced">
<div class="options-tab-contents">
<AdvancedOptions @ref="AdvancedOptions" Preferences="Preferences" UpdatePreferences="@UpdatePreferences" PreferencesChanged="PreferencesChanged" />
</div>
</MudTabPanel>
</MudTabs>
</div>
</div>

View File

@@ -1,73 +1,79 @@
@page "/rss" @page "/rss"
@layout OtherLayout @layout OtherLayout
<MudToolBar Gutters="false" Dense="true"> <div class="content-panel">
@if (!DrawerOpen) <div class="content-panel__toolbar">
{ <MudToolBar Gutters="false" Dense="true">
<MudIconButton Icon="@Icons.Material.Outlined.NavigateBefore" OnClick="NavigateBack" title="Back to torrent list" /> @if (!DrawerOpen)
<MudDivider Vertical="true" />
}
<MudText Class="px-5 no-wrap">RSS</MudText>
<MudDivider Vertical="true" />
<MudIconButton Icon="@Icons.Material.Outlined.Subscriptions" OnClick="NewSubscription" title="New subscription" />
<MudIconButton Icon="@Icons.Material.Outlined.MarkEmailRead" OnClick="MarkAsRead" Disabled="@(SelectedFeed is null)" title="Mark items read" />
<MudIconButton Icon="@Icons.Material.Outlined.Update" OnClick="UpdateAll" title="Update all" />
<MudDivider Vertical="true" />
<MudIconButton Icon="@Icons.Material.Outlined.DownloadForOffline" OnClick="EditDownloadRules" title="Edit auto downloading rules" />
</MudToolBar>
<MudContainer MaxWidth="MaxWidth.ExtraExtraLarge">
<MudGrid Class="rss-contents">
<MudItem xs="4" Style="height: 100%">
<MudList T="string" SelectionMode="SelectionMode.SingleSelection" SelectedValue="SelectedFeed" SelectedValueChanged="SelectedFeedChanged" Dense>
<MudListItem Icon="@Icons.Material.Filled.MarkEmailUnread" Text="@($"Unread ({UnreadCount})")" Value="@("unread")" />
@foreach (var (key, feed) in Feeds)
{
<MudListItem Icon="@(feed.IsLoading ? Icons.Material.Filled.Sync : Icons.Material.Filled.Wifi)" Class="@(feed.IsLoading ? "spin-animation" : "")" Text="@($"{feed.Title} ({feed.UnreadCount})")" Value="@key" />
}
</MudList>
</MudItem>
<MudItem xs="4" Style="height: 100%; overflow: auto">
@if (Articles.Count > 0)
{ {
<MudList T="string" SelectionMode="SelectionMode.SingleSelection" SelectedValue="SelectedArticle" SelectedValueChanged="SelectedArticleChanged" Dense> <MudIconButton Icon="@Icons.Material.Outlined.NavigateBefore" OnClick="NavigateBack" title="Back to torrent list" />
@foreach (var article in Articles) <MudDivider Vertical="true" />
}
<MudText Class="px-5 no-wrap">RSS</MudText>
<MudDivider Vertical="true" />
<MudIconButton Icon="@Icons.Material.Outlined.Subscriptions" OnClick="NewSubscription" title="New subscription" />
<MudIconButton Icon="@Icons.Material.Outlined.MarkEmailRead" OnClick="MarkAsRead" Disabled="@(SelectedFeed is null)" title="Mark items read" />
<MudIconButton Icon="@Icons.Material.Outlined.Update" OnClick="UpdateAll" title="Update all" />
<MudDivider Vertical="true" />
<MudIconButton Icon="@Icons.Material.Outlined.DownloadForOffline" OnClick="EditDownloadRules" title="Edit auto downloading rules" />
</MudToolBar>
</div>
<div class="content-panel__body">
<MudContainer MaxWidth="MaxWidth.ExtraExtraLarge" Class="content-panel__container">
<MudGrid Class="rss-contents">
<MudItem xs="4" Style="height: 100%">
<MudList T="string" SelectionMode="SelectionMode.SingleSelection" SelectedValue="SelectedFeed" SelectedValueChanged="SelectedFeedChanged" Dense>
<MudListItem Icon="@Icons.Material.Filled.MarkEmailUnread" Text="@($"Unread ({UnreadCount})")" Value="@("unread")" />
@foreach (var (key, feed) in Feeds)
{
<MudListItem Icon="@(feed.IsLoading ? Icons.Material.Filled.Sync : Icons.Material.Filled.Wifi)" Class="@(feed.IsLoading ? "spin-animation" : "")" Text="@($"{feed.Title} ({feed.UnreadCount})")" Value="@key" />
}
</MudList>
</MudItem>
<MudItem xs="4" Style="height: 100%; overflow: auto">
@if (Articles.Count > 0)
{ {
<MudListItem Text="@article.Title" Value="article.Id" Icon="@Icons.Material.Filled.Check" IconColor="@(article.IsRead ? Color.Success : Color.Transparent)" /> <MudList T="string" SelectionMode="SelectionMode.SingleSelection" SelectedValue="SelectedArticle" SelectedValueChanged="SelectedArticleChanged" Dense>
@foreach (var article in Articles)
{
<MudListItem Text="@article.Title" Value="article.Id" Icon="@Icons.Material.Filled.Check" IconColor="@(article.IsRead ? Color.Success : Color.Transparent)" />
}
</MudList>
} }
</MudList> else
} {
else <MudSkeleton SkeletonType="SkeletonType.Rectangle" Height="100%" Animation="Animation.False" Width="100%" />
{ }
<MudSkeleton SkeletonType="SkeletonType.Rectangle" Height="100%" Animation="Animation.False" Width="100%" /> </MudItem>
} <MudItem xs="4" Style="height: 100%">
</MudItem> @if (Article is not null)
<MudItem xs="4" Style="height: 100%"> {
@if (Article is not null) <MudCard>
{ <MudCardHeader>
<MudCard> <CardHeaderContent>
<MudCardHeader> <MudText Typo="Typo.h6" Style="overflow-wrap: anywhere">@Article.Title</MudText>
<CardHeaderContent> </CardHeaderContent>
<MudText Typo="Typo.h6" Style="overflow-wrap: anywhere">@Article.Title</MudText> <CardHeaderActions>
</CardHeaderContent> <MudMenu Icon="@Icons.Material.Filled.MoreVert" Dense>
<CardHeaderActions> <MudMenuItem Icon="@Icons.Material.Filled.Download" OnClick="c => DownloadItem(Article.TorrentURL)" title="Download">Download</MudMenuItem>
<MudMenu Icon="@Icons.Material.Filled.MoreVert" Dense> <MudMenuItem Icon="@Icons.Material.Filled.Link" Href="@Article.TorrentURL" Target="@Article.TorrentURL" title="Download">Open torrent URL</MudMenuItem>
<MudMenuItem Icon="@Icons.Material.Filled.Download" OnClick="c => DownloadItem(Article.TorrentURL)" title="Download">Download</MudMenuItem> </MudMenu>
<MudMenuItem Icon="@Icons.Material.Filled.Link" Href="@Article.TorrentURL" Target="@Article.TorrentURL" title="Download">Open torrent URL</MudMenuItem> </CardHeaderActions>
</MudMenu> </MudCardHeader>
</CardHeaderActions>
</MudCardHeader>
<MudCardContent> <MudCardContent>
<MudText Typo="Typo.subtitle2">@Article.Date</MudText> <MudText Typo="Typo.subtitle2">@Article.Date</MudText>
<MudText Typo="Typo.body1">@Article.Description</MudText> <MudText Typo="Typo.body1">@Article.Description</MudText>
</MudCardContent> </MudCardContent>
</MudCard> </MudCard>
} }
else else
{ {
<MudSkeleton SkeletonType="SkeletonType.Rectangle" Height="100%" Animation="Animation.False" Width="100%" /> <MudSkeleton SkeletonType="SkeletonType.Rectangle" Height="100%" Animation="Animation.False" Width="100%" />
} }
</MudItem> </MudItem>
</MudGrid> </MudGrid>
</MudContainer> </MudContainer>
</div>
</div>

View File

@@ -1,62 +1,67 @@
@page "/search" @page "/search"
@layout OtherLayout @layout OtherLayout
<MudToolBar Gutters="false" Dense="true"> <div class="content-panel">
@if (!DrawerOpen) <div class="content-panel__toolbar">
{ <MudToolBar Gutters="false" Dense="true">
<MudIconButton Icon="@Icons.Material.Outlined.NavigateBefore" OnClick="NavigateBack" title="Back to torrent list" /> @if (!DrawerOpen)
<MudDivider Vertical="true" /> {
} <MudIconButton Icon="@Icons.Material.Outlined.NavigateBefore" OnClick="NavigateBack" title="Back to torrent list" />
<MudDivider Vertical="true" /> <MudDivider Vertical="true" />
<MudText Class="pl-5 no-wrap">Search</MudText> }
</MudToolBar> <MudDivider Vertical="true" />
<MudText Class="pl-5 no-wrap">Search</MudText>
</MudToolBar>
</div>
<div class="content-panel__body">
<MudCard Elevation="1" Class="ml-4 mr-4 mb-4">
<MudCardContent>
<EditForm Model="Model" OnValidSubmit="DoSearch">
<MudGrid>
<MudItem xs="12" md="4">
<MudTextField T="string" Label="Criteria" @bind-Value="Model.SearchText" Variant="Variant.Outlined" />
</MudItem>
<MudItem xs="12" md="3">
<MudSelect T="string" Label="Categories" @bind-Value="Model.SelectedCategory" Variant="Variant.Outlined">
@foreach (var (value, name) in Categories)
{
<MudSelectItem Value="value">@name</MudSelectItem>
if (value == "all")
{
<MudDivider />
}
}
</MudSelect>
</MudItem>
<MudItem xs="12" md="3">
<MudSelect T="string" Label="Plugins" @bind-Value="Model.SelectedPlugin" Variant="Variant.Outlined">
<MudSelectItem Value="@("all")">All</MudSelectItem>
@if (Plugins.Count > 0)
{
<MudDivider />
<MudCard Elevation="1" Class="ml-4 mr-4 mb-4"> }
<MudCardContent> @foreach (var (value, name) in Plugins)
<EditForm Model="Model" OnValidSubmit="DoSearch"> {
<MudGrid> <MudSelectItem Value="value">@name</MudSelectItem>
<MudItem xs="12" md="4"> }
<MudTextField T="string" Label="Criteria" @bind-Value="Model.SearchText" Variant="Variant.Outlined" /> </MudSelect>
</MudItem> </MudItem>
<MudItem xs="12" md="3"> <MudItem xs="12" md="2">
<MudSelect T="string" Label="Categories" @bind-Value="Model.SelectedCategory" Variant="Variant.Outlined"> <MudButton ButtonType="ButtonType.Submit" FullWidth="true" Color="Color.Primary" EndIcon="@Icons.Material.Filled.Search" Variant="Variant.Filled" Class="mt-6">@(_searchId is null ? "Search" : "Stop")</MudButton>
@foreach (var (value, name) in Categories) </MudItem>
{
<MudSelectItem Value="value">@name</MudSelectItem> </MudGrid>
if (value == "all") </EditForm>
{ </MudCardContent>
<MudDivider /> </MudCard>
}
}
</MudSelect>
</MudItem>
<MudItem xs="12" md="3">
<MudSelect T="string" Label="Plugins" @bind-Value="Model.SelectedPlugin" Variant="Variant.Outlined">
<MudSelectItem Value="@("all")">All</MudSelectItem>
@if (Plugins.Count > 0)
{
<MudDivider />
} <DynamicTable @ref="Table"
@foreach (var (value, name) in Plugins) T="Lantean.QBitTorrentClient.Models.SearchResult"
{ ColumnDefinitions="Columns"
<MudSelectItem Value="value">@name</MudSelectItem> Items="Results"
} MultiSelection="false"
</MudSelect> SelectOnRowClick="false"
</MudItem> Class="search-list content-panel__table" />
<MudItem xs="12" md="2"> </div>
<MudButton ButtonType="ButtonType.Submit" FullWidth="true" Color="Color.Primary" EndIcon="@Icons.Material.Filled.Search" Variant="Variant.Filled" Class="mt-6">@(_searchId is null ? "Search" : "Stop")</MudButton> </div>
</MudItem>
</MudGrid>
</EditForm>
</MudCardContent>
</MudCard>
<DynamicTable @ref="Table"
T="Lantean.QBitTorrentClient.Models.SearchResult"
ColumnDefinitions="Columns"
Items="Results"
MultiSelection="false"
SelectOnRowClick="false"
Class="search-list" />

View File

@@ -1,62 +1,68 @@
@page "/statistics" @page "/statistics"
@layout OtherLayout @layout OtherLayout
<MudToolBar Gutters="false" Dense="true"> <div class="content-panel">
@if (!DrawerOpen) <div class="content-panel__toolbar">
{ <MudToolBar Gutters="false" Dense="true">
<MudIconButton Icon="@Icons.Material.Outlined.NavigateBefore" OnClick="NavigateBack" title="Back to torrent list" /> @if (!DrawerOpen)
<MudDivider Vertical="true" /> {
} <MudIconButton Icon="@Icons.Material.Outlined.NavigateBefore" OnClick="NavigateBack" title="Back to torrent list" />
<MudDivider Vertical="true" /> <MudDivider Vertical="true" />
<MudText Class="pl-5 no-wrap">Statistics</MudText> }
</MudToolBar> <MudDivider Vertical="true" />
<MudText Class="pl-5 no-wrap">Statistics</MudText>
</MudToolBar>
</div>
<MudContainer MaxWidth="MaxWidth.ExtraExtraLarge" Class="details-tab-contents"> <div class="content-panel__body">
<MudText Typo="Typo.subtitle2" Class="pt-6">User statistics</MudText> <MudContainer MaxWidth="MaxWidth.ExtraExtraLarge" Class="details-tab-contents content-panel__container">
<MudGrid> <MudText Typo="Typo.subtitle2" Class="pt-6">User statistics</MudText>
<MudItem xs="12"> <MudGrid>
<MudField Label="All-time uploaded">@DisplayHelpers.Size(ServerState?.AllTimeUploaded)</MudField> <MudItem xs="12">
</MudItem> <MudField Label="All-time uploaded">@DisplayHelpers.Size(ServerState?.AllTimeUploaded)</MudField>
<MudItem xs="12"> </MudItem>
<MudField Label="All-time downloaded">@DisplayHelpers.Size(ServerState?.AllTimeDownloaded)</MudField> <MudItem xs="12">
</MudItem> <MudField Label="All-time downloaded">@DisplayHelpers.Size(ServerState?.AllTimeDownloaded)</MudField>
<MudItem xs="12"> </MudItem>
<MudField Label="All-time share ratio">@DisplayHelpers.EmptyIfNull(ServerState?.GlobalRatio, format: "0.00")</MudField> <MudItem xs="12">
</MudItem> <MudField Label="All-time share ratio">@DisplayHelpers.EmptyIfNull(ServerState?.GlobalRatio, format: "0.00")</MudField>
<MudItem xs="12"> </MudItem>
<MudField Label="Session waste">@DisplayHelpers.Size(ServerState?.TotalWastedSession)</MudField> <MudItem xs="12">
</MudItem> <MudField Label="Session waste">@DisplayHelpers.Size(ServerState?.TotalWastedSession)</MudField>
<MudItem xs="12"> </MudItem>
<MudField Label="Connected peers">@DisplayHelpers.EmptyIfNull(ServerState?.TotalPeerConnections)</MudField> <MudItem xs="12">
</MudItem> <MudField Label="Connected peers">@DisplayHelpers.EmptyIfNull(ServerState?.TotalPeerConnections)</MudField>
</MudGrid> </MudItem>
</MudGrid>
<MudText Typo="Typo.subtitle2" Class="pt-6">Cache statistics</MudText> <MudText Typo="Typo.subtitle2" Class="pt-6">Cache statistics</MudText>
<MudGrid> <MudGrid>
<MudItem xs="12"> <MudItem xs="12">
<MudField Label="Read cache hits">@DisplayHelpers.Percentage(ServerState?.ReadCacheHits)</MudField> <MudField Label="Read cache hits">@DisplayHelpers.Percentage(ServerState?.ReadCacheHits)</MudField>
</MudItem> </MudItem>
<MudItem xs="12"> <MudItem xs="12">
<MudField Label="Total buffer size">@DisplayHelpers.Size(ServerState?.TotalBuffersSize)</MudField> <MudField Label="Total buffer size">@DisplayHelpers.Size(ServerState?.TotalBuffersSize)</MudField>
</MudItem> </MudItem>
</MudGrid> </MudGrid>
<MudText Typo="Typo.subtitle2" Class="pt-6">Performance statistics</MudText> <MudText Typo="Typo.subtitle2" Class="pt-6">Performance statistics</MudText>
<MudGrid> <MudGrid>
<MudItem xs="12"> <MudItem xs="12">
<MudField Label="Write cache overload">@DisplayHelpers.Percentage(ServerState?.WriteCacheOverload)</MudField> <MudField Label="Write cache overload">@DisplayHelpers.Percentage(ServerState?.WriteCacheOverload)</MudField>
</MudItem> </MudItem>
<MudItem xs="12"> <MudItem xs="12">
<MudField Label="Read cache overload">@DisplayHelpers.Percentage(ServerState?.ReadCacheOverload)</MudField> <MudField Label="Read cache overload">@DisplayHelpers.Percentage(ServerState?.ReadCacheOverload)</MudField>
</MudItem> </MudItem>
<MudItem xs="12"> <MudItem xs="12">
<MudField Label="Queued I/O jobs">@DisplayHelpers.EmptyIfNull(ServerState?.QueuedIOJobs)</MudField> <MudField Label="Queued I/O jobs">@DisplayHelpers.EmptyIfNull(ServerState?.QueuedIOJobs)</MudField>
</MudItem> </MudItem>
<MudItem xs="12"> <MudItem xs="12">
<MudField Label="Average time in queue">@DisplayHelpers.EmptyIfNull(ServerState?.AverageTimeQueue, suffix: "ms")</MudField> <MudField Label="Average time in queue">@DisplayHelpers.EmptyIfNull(ServerState?.AverageTimeQueue, suffix: "ms")</MudField>
</MudItem> </MudItem>
<MudItem xs="12"> <MudItem xs="12">
<MudField Label="Total queued size">@DisplayHelpers.Size(ServerState?.TotalQueuedSize)</MudField> <MudField Label="Total queued size">@DisplayHelpers.Size(ServerState?.TotalQueuedSize)</MudField>
</MudItem> </MudItem>
</MudGrid> </MudGrid>
</MudContainer> </MudContainer>
</div>
</div>

View File

@@ -1,24 +1,30 @@
@page "/tags" @page "/tags"
@layout OtherLayout @layout OtherLayout
<MudToolBar Gutters="false" Dense="true"> <div class="content-panel">
@if (!DrawerOpen) <div class="content-panel__toolbar">
{ <MudToolBar Gutters="false" Dense="true">
<MudIconButton Icon="@Icons.Material.Outlined.NavigateBefore" OnClick="NavigateBack" title="Back to torrent list" /> @if (!DrawerOpen)
<MudDivider Vertical="true" /> {
} <MudIconButton Icon="@Icons.Material.Outlined.NavigateBefore" OnClick="NavigateBack" title="Back to torrent list" />
<MudText Class="px-5 no-wrap">Tags</MudText> <MudDivider Vertical="true" />
<MudDivider Vertical="true" /> }
<MudIconButton Icon="@Icons.Material.Filled.NewLabel" OnClick="AddTag" title="Add Tag" /> <MudText Class="px-5 no-wrap">Tags</MudText>
</MudToolBar> <MudDivider Vertical="true" />
<MudIconButton Icon="@Icons.Material.Filled.NewLabel" OnClick="AddTag" title="Add Tag" />
</MudToolBar>
</div>
<DynamicTable @ref="Table" <div class="content-panel__body">
T="string" <DynamicTable @ref="Table"
ColumnDefinitions="Columns" T="string"
Items="Results" ColumnDefinitions="Columns"
MultiSelection="false" Items="Results"
SelectOnRowClick="false" MultiSelection="false"
Class="details-list" /> SelectOnRowClick="false"
Class="details-list content-panel__table" />
</div>
</div>
@code { @code {
private RenderFragment<RowContext<string>> ActionsColumn private RenderFragment<RowContext<string>> ActionsColumn

View File

@@ -7,38 +7,41 @@
<TorrentActions RenderType="RenderType.MenuItems" Hashes="GetContextMenuTargetHashes()" PrimaryHash="@(ContextMenuItem?.Hash)" Torrents="MainData.Torrents" Preferences="Preferences" /> <TorrentActions RenderType="RenderType.MenuItems" Hashes="GetContextMenuTargetHashes()" PrimaryHash="@(ContextMenuItem?.Hash)" Torrents="MainData.Torrents" Preferences="Preferences" />
</MudMenu> </MudMenu>
<div style="overflow-x: auto; white-space: nowrap; width: 100%;"> <div class="content-panel">
<MudToolBar Gutters="false" Dense="true"> <div class="content-panel__toolbar content-panel__toolbar--scroll">
<MudIconButton Icon="@Icons.Material.Outlined.AddLink" OnClick="AddTorrentLink" title="Add torrent link" /> <MudToolBar Gutters="false" Dense="true">
<MudIconButton Icon="@Icons.Material.Outlined.AddCircle" OnClick="AddTorrentFile" title="Add torrent file" /> <MudIconButton Icon="@Icons.Material.Outlined.AddLink" OnClick="AddTorrentLink" title="Add torrent link" />
<MudDivider Vertical="true" /> <MudIconButton Icon="@Icons.Material.Outlined.AddCircle" OnClick="AddTorrentFile" title="Add torrent file" />
<TorrentActions RenderType="RenderType.InitialIconsOnly" Hashes="GetSelectedTorrentsHashes()" Torrents="MainData.Torrents" Preferences="Preferences" /> <MudDivider Vertical="true" />
<MudDivider Vertical="true" /> <TorrentActions RenderType="RenderType.InitialIconsOnly" Hashes="GetSelectedTorrentsHashes()" Torrents="MainData.Torrents" Preferences="Preferences" />
<MudIconButton Icon="@Icons.Material.Outlined.Info" Color="Color.Inherit" Disabled="@(!ToolbarButtonsEnabled)" OnClick="ShowTorrentToolbar" title="View torrent details" /> <MudDivider Vertical="true" />
<MudIconButton Icon="@Icons.Material.Outlined.ViewColumn" Color="Color.Inherit" OnClick="ColumnOptions" title="Choose Columns" /> <MudIconButton Icon="@Icons.Material.Outlined.Info" Color="Color.Inherit" Disabled="@(!ToolbarButtonsEnabled)" OnClick="ShowTorrentToolbar" title="View torrent details" />
<MudSpacer /> <MudIconButton Icon="@Icons.Material.Outlined.ViewColumn" Color="Color.Inherit" OnClick="ColumnOptions" title="Choose Columns" />
<MudTextField Value="SearchText" TextChanged="SearchTextChanged" Immediate="true" DebounceInterval="1000" Placeholder="Filter torrent list" Adornment="Adornment.Start" AdornmentIcon="@Icons.Material.Filled.Search" IconSize="Size.Medium" Class="mt-0"></MudTextField> <MudSpacer />
</MudToolBar> <MudTextField Value="SearchText" TextChanged="SearchTextChanged" Immediate="true" DebounceInterval="1000" Placeholder="Filter torrent list" Adornment="Adornment.Start" AdornmentIcon="@Icons.Material.Filled.Search" IconSize="Size.Medium" Class="mt-0"></MudTextField>
</MudToolBar>
</div>
<div class="content-panel__body">
<MudContainer MaxWidth="MaxWidth.ExtraExtraLarge" Class="ma-0 pa-0 content-panel__container">
<DynamicTable
@ref="Table"
T="Torrent"
Class="torrent-list content-panel__table"
ColumnDefinitions="Columns"
Items="Torrents"
OnRowClick="RowClick"
MultiSelection="true"
SelectOnRowClick="true"
SelectedItemsChanged="SelectedItemsChanged"
SortColumnChanged="SortColumnChangedHandler"
SortDirectionChanged="SortDirectionChangedHandler"
OnTableDataContextMenu="TableDataContextMenu"
OnTableDataLongPress="TableDataLongPress"
/>
</MudContainer>
</div>
</div> </div>
<MudContainer MaxWidth="MaxWidth.ExtraExtraLarge" Class="ma-0 pa-0">
<DynamicTable
@ref="Table"
T="Torrent"
Class="torrent-list"
ColumnDefinitions="Columns"
Items="Torrents"
OnRowClick="RowClick"
MultiSelection="true"
SelectOnRowClick="true"
SelectedItemsChanged="SelectedItemsChanged"
SortColumnChanged="SortColumnChangedHandler"
SortDirectionChanged="SortDirectionChangedHandler"
OnTableDataContextMenu="TableDataContextMenu"
OnTableDataLongPress="TableDataLongPress"
/>
</MudContainer>
@code { @code {
private static RenderFragment<RowContext<Torrent>> ProgressBarColumn private static RenderFragment<RowContext<Torrent>> ProgressBarColumn
{ {

View File

@@ -1,4 +1,4 @@
#blazor-error-ui { #blazor-error-ui {
background: lightyellow; background: lightyellow;
bottom: 0; bottom: 0;
box-shadow: 0 -1px 2px rgba(0, 0, 0, 0.2); box-shadow: 0 -1px 2px rgba(0, 0, 0, 0.2);
@@ -65,15 +65,16 @@ code {
} }
.mud-appbar.mud-appbar-fixed-bottom { .mud-appbar.mud-appbar-fixed-bottom {
height: 35px; height: var(--app-status-bar-height);
} }
.mud-main-content { .mud-main-content {
padding-bottom: 35px; padding: var(--mud-appbar-height) 0 var(--app-status-bar-height);
box-sizing: border-box;
} }
.mud-drawer-fixed.mud-drawer-mini.mud-drawer-clipped-always, .mud-drawer-fixed.mud-drawer-persistent:not(.mud-drawer-clipped-never), .mud-drawer-fixed.mud-drawer-responsive.mud-drawer-clipped-always, .mud-drawer-fixed.mud-drawer-temporary.mud-drawer-clipped-always { .mud-drawer-fixed.mud-drawer-mini.mud-drawer-clipped-always, .mud-drawer-fixed.mud-drawer-persistent:not(.mud-drawer-clipped-never), .mud-drawer-fixed.mud-drawer-responsive.mud-drawer-clipped-always, .mud-drawer-fixed.mud-drawer-temporary.mud-drawer-clipped-always {
height: calc(100% - var(--mud-appbar-height) - 35px); height: calc(100% - var(--mud-appbar-height) - var(--app-status-bar-height));
} }
.w-100 { .w-100 {
@@ -154,25 +155,68 @@ code {
margin-right: 5px; margin-right: 5px;
} }
.torrent-list .mud-table-container { /*. Layout helpers */
height: calc(100vh - 160px); .content-panel {
display: flex;
flex-direction: column;
height: 100%;
min-height: 0;
} }
.file-list .mud-table-container { .content-panel__toolbar {
height: calc(100vh - 245px); flex: 0 0 auto;
} }
.details-list .mud-table-container { .content-panel__toolbar--scroll {
height: calc(100vh - 200px); overflow-x: auto;
white-space: nowrap;
} }
.details-tab-contents { .content-panel__body {
height: calc(100vh - 200px); flex: 1 1 auto;
overflow: auto; min-height: 0;
display: flex;
flex-direction: column;
overflow: hidden;
} }
.content-panel__container {
flex: 1 1 auto;
display: flex;
flex-direction: column;
min-height: 0;
}
.content-panel__table {
flex: 1 1 auto;
display: flex;
flex-direction: column;
min-height: 0;
}
.content-panel__table .mud-table-container {
flex: 1 1 auto;
height: 100%;
}
.content-panel__body > .mud-tabs { flex: 1 1 auto; min-height: 0; display: flex; flex-direction: column; }
.content-panel__body > .mud-tabs .mud-tabs-panels { flex: 1 1 auto; min-height: 0; display: flex; flex-direction: column; overflow: hidden; }
.content-panel__body > .mud-tabs .mud-tab-panel { flex: 1 1 auto; min-height: 0; display: flex; flex-direction: column; overflow: hidden; }
.content-panel__body > .mud-tabs .mud-tab-panel > .mud-tab-panel-content { flex: 1 1 auto; min-height: 0; overflow: auto; }
.torrent-list .mud-table-container,
.file-list .mud-table-container,
.details-list .mud-table-container,
.search-list .mud-table-container { .search-list .mud-table-container {
height: calc(100vh - 260px); height: 100%;
}
.details-tab-contents,
.options-tab-contents,
.rss-contents {
flex: 1 1 auto;
min-height: 0;
overflow: auto;
} }
tr.log-normal td { tr.log-normal td {
@@ -220,10 +264,6 @@ td .folder-button {
padding: 6px 16px 6px 16px !important; padding: 6px 16px 6px 16px !important;
} }
.rss-contents {
height: calc(100vh - 149px);
}
@keyframes spin { @keyframes spin {
0% { 0% {
transform: rotate(0deg); transform: rotate(0deg);
@@ -255,4 +295,74 @@ td .folder-button {
.mud-popover .mud-divider:last-child { .mud-popover .mud-divider:last-child {
display: none; display: none;
}
:root {
--app-viewport-height: 100vh;
--app-status-bar-height: 35px;
}
@supports (height: 100dvh) {
:root {
--app-viewport-height: 100dvh;
}
}
html,
body {
height: var(--app-viewport-height);
min-height: var(--app-viewport-height);
}
body {
margin: 0;
overflow: hidden;
overscroll-behavior: none;
}
#app,
.mud-layout {
height: 100%;
min-height: 100%;
}
.app-shell {
display: flex;
flex-direction: column;
height: 100%;
min-height: 0;
overflow: hidden;
}
.app-shell__body {
display: flex;
flex: 1 1 auto;
min-height: 0;
overflow: hidden;
}
.app-shell__sidebar {
flex: 0 0 auto;
}
.app-shell__main {
display: flex;
flex-direction: column;
flex: 1 1 auto;
min-height: 0;
overflow: hidden;
padding: var(--mud-appbar-height) 0 var(--app-status-bar-height);
box-sizing: border-box;
}
.app-shell__status-bar.mud-appbar {
flex: 0 0 var(--app-status-bar-height);
height: var(--app-status-bar-height);
width: 100%;
background-color: var(--mud-palette-dark-lighten);
align-items: center;
justify-content: flex-start;
}
.app-shell__status-bar .mud-toolbar {
width: 100%;
} }