mirror of
https://github.com/hmaxnl/SharpRSS.git
synced 2025-01-18 21:04:21 +01:00
Reworking UI and simple dashboard implementation
This commit is contained in:
parent
3cc8838c23
commit
0b35c32fe1
|
@ -12,7 +12,6 @@ using SharpRss.Models;
|
|||
|
||||
namespace SharpRss
|
||||
{
|
||||
//TODO: Need rework to only get from db syndication service will handle extra data.
|
||||
internal static class DbAccess
|
||||
{
|
||||
private static readonly string ConnectionString = $"Data Source={Path.Combine(Environment.CurrentDirectory, "sharp_rss.sqlite")};";
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Argotic.Common;
|
||||
using Argotic.Syndication;
|
||||
|
@ -10,14 +9,14 @@ using SharpRss.Models;
|
|||
namespace SharpRss.Services
|
||||
{
|
||||
/// <summary>
|
||||
/// Managing feeds and categories.
|
||||
/// Managing syndication feeds and categories.
|
||||
/// </summary>
|
||||
public class SyndicationService
|
||||
{
|
||||
public SyndicationService()
|
||||
{
|
||||
Log.Information("Constructing SyndicationService...");
|
||||
SetupTestCategoriesAndFeedsAsync();
|
||||
Task.Run(async () => await SetupTestCategoriesAndFeedsAsync());
|
||||
}
|
||||
|
||||
public async Task<HashSet<object>> GetCategoriesAndSyndicationsAsync()
|
||||
|
@ -59,16 +58,16 @@ namespace SharpRss.Services
|
|||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Log.Error(e,"Error adding feed: {FeedUrl} to database!", url);
|
||||
Log.Error(e,"Error adding syndication: {FeedUrl} to database!", url);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
public async Task UpdateFeeds()
|
||||
{
|
||||
Log.Information("Fetching feeds...");
|
||||
var feeds = await GetFeedsAsync();
|
||||
Log.Information("Fetching...");
|
||||
var feeds = await GetSyndicationsAsync();
|
||||
}
|
||||
public async Task<HashSet<SyndicationModel>> GetFeedsAsync(string? categoryId = null) => await DbAccess.GetSyndicationsAsync(categoryId == null ? null : new[]{ categoryId });
|
||||
public async Task<HashSet<SyndicationModel>> GetSyndicationsAsync(string? categoryId = null) => await DbAccess.GetSyndicationsAsync(categoryId == null ? null : new[]{ categoryId });
|
||||
public async Task<HashSet<SyndicationModel>> GetUngroupedSyndicationsAsync() => await DbAccess.GetSyndicationsAsync(new []{""});
|
||||
public async Task<HashSet<SyndicationItemModel>> GetSyndicationItemsAsync(string feedId, string? groupId = null) => await GetSyndicationItemsFromSyndicationsAsync(new[] { feedId }, groupId);
|
||||
public async Task<HashSet<SyndicationItemModel>> GetSyndicationItemsFromSyndicationsAsync(string[] feedIds, string? categoryId = null)
|
||||
|
@ -98,24 +97,24 @@ namespace SharpRss.Services
|
|||
AtomFeed atomFeed = (AtomFeed)resource;
|
||||
break;
|
||||
default:
|
||||
Log.Information("Feed implementation missing!");
|
||||
Log.Information("Syndication implementation missing!");
|
||||
break;
|
||||
}
|
||||
return model;
|
||||
}
|
||||
private GenericSyndicationFeed? CreateFeed(string url)
|
||||
private GenericSyndicationFeed? CreateSyndication(string url)
|
||||
{
|
||||
Uri feedUri = new Uri(url);
|
||||
Log.Verbose("Checking feed: {FeedUrl}", feedUri.ToString());
|
||||
Log.Verbose("Checking syndication: {FeedUrl}", feedUri.ToString());
|
||||
if (!SyndicationDiscoveryUtility.UriExists(feedUri))
|
||||
{
|
||||
Log.Warning("Feed: {FeedUri} does not exists!", feedUri.ToString());
|
||||
Log.Warning("Syndication: {FeedUri} does not exists!", feedUri.ToString());
|
||||
return null;
|
||||
}
|
||||
Log.Verbose("Fetching feed: {FeedUrl}", feedUri.ToString());
|
||||
Log.Verbose("Fetching syndication: {FeedUrl}", feedUri.ToString());
|
||||
return GenericSyndicationFeed.Create(new Uri(url));
|
||||
}
|
||||
private async void SetupTestCategoriesAndFeedsAsync()
|
||||
private async Task SetupTestCategoriesAndFeedsAsync()
|
||||
{
|
||||
Log.Information("Setting up test data...");
|
||||
try
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
@using System.Drawing
|
||||
@using Color = MudBlazor.Color
|
||||
@inherits LayoutComponentBase
|
||||
|
||||
<MudThemeProvider @bind-IsDarkMode="@_darkTheme" Theme="_mainTheme"/>
|
||||
|
@ -27,6 +29,10 @@
|
|||
<MudIconButton Icon="@Icons.Custom.Brands.GitHub" Href="https://github.com/hmaxnl/SharpRSS" Target="_blank"></MudIconButton>
|
||||
</MudAppBar>
|
||||
<MudDrawer @bind-Open="@_drawerOpen" ClipMode="DrawerClipMode.Always">
|
||||
<MudNavMenu>
|
||||
<MudNavLink Href="/" Icon="@Icons.Material.Filled.Home">Home</MudNavLink>
|
||||
<MudNavLink Href="/list?cid=" Icon="@Icons.Material.Filled.Power">All</MudNavLink>
|
||||
</MudNavMenu>
|
||||
<SideGuide/>
|
||||
</MudDrawer>
|
||||
<MudMainContent>
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Configuration;
|
||||
using System.Linq;
|
||||
using MudBlazor;
|
||||
using SharpRss;
|
||||
|
|
|
@ -1,14 +1,38 @@
|
|||
@page "/"
|
||||
@page "/dashboard"
|
||||
@using WebSharpRSS.Models;
|
||||
@using SharpRss.Models
|
||||
@using SharpRss.Services
|
||||
|
||||
@inject FeedStateContainer _stateContainer;
|
||||
@inject SyndicationService _service;
|
||||
|
||||
<MudText>Dashboard!</MudText>
|
||||
<MudGrid Spacing="2" Class="ml-2 mr-2">
|
||||
|
||||
<MudGrid Spacing="2" Class="mx-2" Justify="Justify.FlexStart">
|
||||
@if (_loading)
|
||||
{
|
||||
<MudProgressCircular Indeterminate="true" Color="Color.Primary"/>
|
||||
}
|
||||
else
|
||||
{
|
||||
@foreach (CategoryModel category in _categories)
|
||||
{
|
||||
<MudItem>
|
||||
<DashboardCategoryItemView Category="category"/>
|
||||
</MudItem>
|
||||
}
|
||||
}
|
||||
</MudGrid>
|
||||
|
||||
@code {
|
||||
|
||||
bool _loading = true;
|
||||
HashSet<CategoryModel> _categories = new HashSet<CategoryModel>();
|
||||
|
||||
protected override async void OnInitialized()
|
||||
{
|
||||
await _service.GetCategoriesAsync().ContinueWith(task =>
|
||||
{
|
||||
_categories = task.Result;
|
||||
_loading = false;
|
||||
});
|
||||
}
|
||||
}
|
|
@ -8,9 +8,11 @@
|
|||
<div>
|
||||
@if (_isLoading)
|
||||
{
|
||||
<div class="justify-self: center">
|
||||
<MudProgressCircular Color="Color.Primary" Indeterminate="true" />
|
||||
<MudText>Loading...</MudText>
|
||||
<div class="d-flex justify-center">
|
||||
<div>
|
||||
<MudProgressCircular Class="d-block" Color="Color.Primary" Indeterminate="true" Size="Size.Large"/>
|
||||
<MudText Class="d-block">Loading...</MudText>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
else
|
||||
|
@ -28,7 +30,7 @@
|
|||
set
|
||||
{
|
||||
_fid = value;
|
||||
LoadItems();
|
||||
Task.Run(async () => await LoadItems());
|
||||
}
|
||||
}
|
||||
private string? _fid;
|
||||
|
@ -40,13 +42,13 @@
|
|||
set
|
||||
{
|
||||
_cid = value;
|
||||
LoadItems();
|
||||
Task.Run(async () => await LoadItems());
|
||||
}
|
||||
}
|
||||
private string? _cid;
|
||||
HashSet<SyndicationItemData> items = new HashSet<SyndicationItemData>();
|
||||
bool _isLoading = true;
|
||||
private async void LoadItems()
|
||||
private async Task LoadItems()
|
||||
{
|
||||
_isLoading = true;
|
||||
if (Fid != null)
|
||||
|
@ -56,16 +58,12 @@
|
|||
}
|
||||
else if (Cid != null)
|
||||
{
|
||||
var feeds = await _syndicationService.GetFeedsAsync(Cid == string.Empty ? null : Cid);
|
||||
var feeds = await _syndicationService.GetSyndicationsAsync(Cid == string.Empty ? null : Cid);
|
||||
var feedIds = feeds.Select(x => x.EncodedUrl);
|
||||
var feedItems = await _syndicationService.GetSyndicationItemsFromSyndicationsAsync(feedIds.ToArray());
|
||||
items = feedItems.Select(x => SyndicationItemData.FromModel(x)).OrderBy(x => x.PublishingDate).Reverse().ToHashSet();
|
||||
}
|
||||
_isLoading = false;
|
||||
StateHasChanged();
|
||||
}
|
||||
protected override void OnInitialized()
|
||||
{
|
||||
LoadItems();
|
||||
await InvokeAsync(StateHasChanged);
|
||||
}
|
||||
}
|
|
@ -14,7 +14,7 @@
|
|||
<component type="typeof(HeadOutlet)" render-mode="ServerPrerendered"/>
|
||||
</head>
|
||||
<body>
|
||||
<component type="typeof(App)" render-mode="ServerPrerendered"/>
|
||||
<component type="typeof(App)" render-mode="Server"/>
|
||||
|
||||
<div id="blazor-error-ui">
|
||||
<environment include="Staging,Production">
|
||||
|
|
62
WebSharpRSS/Shared/DashboardCategoryItemView.razor
Normal file
62
WebSharpRSS/Shared/DashboardCategoryItemView.razor
Normal file
|
@ -0,0 +1,62 @@
|
|||
@using SharpRss.Models
|
||||
@using SharpRss.Services
|
||||
@using WebSharpRSS.Models
|
||||
@using Serilog
|
||||
|
||||
@inject SyndicationService _service;
|
||||
|
||||
<MudPaper Height="100%" Width="80vh">
|
||||
@if (Category != null)
|
||||
{
|
||||
<div style="justify-self: start;" class="d-flex align-center my-2">
|
||||
<MudIcon Icon="@Category.Icon" Style="@($"color:{Category.HexColor}")" Class="mx-2"/>
|
||||
<MudText>@Category.Name</MudText>
|
||||
</div>
|
||||
<MudDivider/>
|
||||
@if (_isLoading)
|
||||
{
|
||||
<div class="d-flex justify-center">
|
||||
<div>
|
||||
<MudProgressCircular Class="d-block" Color="Color.Primary" Indeterminate="true"/>
|
||||
<MudText Class="d-block">Loading...</MudText>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
else
|
||||
{
|
||||
<div style="display: flex; height: 80vh; overflow-y: scroll">
|
||||
<SyndicationListItem Items="@items"/>
|
||||
</div>
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
<MudText>Could not load data!</MudText>
|
||||
}
|
||||
</MudPaper>
|
||||
|
||||
@code {
|
||||
[Parameter]
|
||||
public CategoryModel? Category { get; set; }
|
||||
|
||||
bool _isLoading = true;
|
||||
HashSet<SyndicationItemData> items = new HashSet<SyndicationItemData>();
|
||||
|
||||
async Task LoadDataAsync()
|
||||
{
|
||||
if (Category == null)
|
||||
{
|
||||
Log.Warning("Category is null!");
|
||||
return;
|
||||
}
|
||||
_isLoading = true;
|
||||
var syndicationIds = Category.Syndications.Select(x => x.EncodedUrl);
|
||||
var syndicationItems = await _service.GetSyndicationItemsFromSyndicationsAsync(syndicationIds.ToArray());
|
||||
items = syndicationItems.Select(x => SyndicationItemData.FromModel(x)).OrderBy(x => x.PublishingDate).Reverse().ToHashSet();
|
||||
_isLoading = false;
|
||||
}
|
||||
protected override void OnInitialized()
|
||||
{
|
||||
Task.Run(async () => await LoadDataAsync()).ContinueWith(async t => await InvokeAsync(StateHasChanged));
|
||||
}
|
||||
}
|
|
@ -15,7 +15,7 @@
|
|||
<Content>
|
||||
<div style="display: grid; grid-template-columns: 1fr auto; align-items: center; width: 100%">
|
||||
<div class="d-flex align-center">
|
||||
<MudTreeViewItemToggleButton ExpandedChanged="@(() => ExpandedChanged(context))" Loading="@context.Loading" Visible="@context.HasChildren" LoadingIconColor="Color.Info" />
|
||||
<MudTreeViewItemToggleButton ExpandedChanged="@(() => ExpandedChanged(context))" Loading="@context.Loading" Visible="@context.HasChildren" LoadingIconColor="Color.Info"/>
|
||||
@if (context.FaviconUrl == null && context.Icon != null)
|
||||
{
|
||||
<MudIcon Icon="@context.Icon" Style="@($"color:{context.CategoryModel?.HexColor ?? _theme.Palette.Primary.Value}")"/>
|
||||
|
@ -71,7 +71,6 @@
|
|||
protected override async void OnInitialized()
|
||||
{
|
||||
Log.Verbose("Loading guide data...");
|
||||
_guideItems.Add(new TreeItemData(new CategoryModel() { Name = "All", Icon = Icons.Material.Filled.Home, HexColor = Colors.Blue.Accent1, Id = string.Empty }));
|
||||
HashSet<object> items = await _syndicationService.GetCategoriesAndSyndicationsAsync();
|
||||
_guideItems.UnionWith(ModelToTreeItem(items));
|
||||
|
||||
|
|
Binary file not shown.
Loading…
Reference in New Issue
Block a user