mirror of
https://github.com/hmaxnl/SharpRSS.git
synced 2024-11-09 23:44:20 +01:00
Finishing models
This commit is contained in:
parent
13fd44bc72
commit
18e4135130
|
@ -43,9 +43,9 @@ namespace SharpRss
|
||||||
Id = reader["id"].ToString(),
|
Id = reader["id"].ToString(),
|
||||||
Name = reader["name"].ToString(),
|
Name = reader["name"].ToString(),
|
||||||
HexColor = reader["hex_color"].ToString(),
|
HexColor = reader["hex_color"].ToString(),
|
||||||
FeedCount = 0, // Not implemented.
|
|
||||||
Icon = reader["icon"].ToString()
|
Icon = reader["icon"].ToString()
|
||||||
};
|
};
|
||||||
|
categoryModel.FeedCount = await dbc.ExecuteScalarAsync<int>($"SELECT COUNT(*) FROM feed WHERE category_id=@CatId", new { CatId = categoryModel.Id });
|
||||||
categories.Add(categoryModel);
|
categories.Add(categoryModel);
|
||||||
}
|
}
|
||||||
return categories;
|
return categories;
|
||||||
|
@ -125,7 +125,7 @@ namespace SharpRss
|
||||||
await using SqliteConnection dbc = new SqliteConnection(ConnectionString);
|
await using SqliteConnection dbc = new SqliteConnection(ConnectionString);
|
||||||
dbc.Open();
|
dbc.Open();
|
||||||
HashSet<FeedModel> feeds = new HashSet<FeedModel>();
|
HashSet<FeedModel> feeds = new HashSet<FeedModel>();
|
||||||
await using DbDataReader reader = await dbc.ExecuteReaderAsync(categoryIds == null ? "SELECT * FROM feed WHERE category_id == ''" : "SELECT * FROM feed WHERE category_id IN(@CatIds)", new { CatIds = categoryIds });
|
await using DbDataReader reader = await dbc.ExecuteReaderAsync(categoryIds == null ? "SELECT * FROM feed" : "SELECT * FROM feed WHERE category_id IN(@CatIds)", new { CatIds = categoryIds });
|
||||||
while (await reader.ReadAsync())
|
while (await reader.ReadAsync())
|
||||||
{
|
{
|
||||||
FeedModel feedModel = new FeedModel()
|
FeedModel feedModel = new FeedModel()
|
||||||
|
|
|
@ -6,17 +6,12 @@ namespace SharpRss.Models
|
||||||
{
|
{
|
||||||
public class CategoryModel
|
public class CategoryModel
|
||||||
{
|
{
|
||||||
private string _id = string.Empty;
|
public CategoryModel()
|
||||||
public string Id
|
|
||||||
{
|
{
|
||||||
get
|
Id = Guid.NewGuid().ToString();
|
||||||
{
|
|
||||||
if (_id.IsNullEmptyWhiteSpace())
|
|
||||||
_id = Guid.NewGuid().ToString();
|
|
||||||
return _id;
|
|
||||||
}
|
|
||||||
set => _id = value;
|
|
||||||
}
|
}
|
||||||
|
/*private string _id = string.Empty;*/
|
||||||
|
public string Id { get; set; }
|
||||||
public string Name { get; set; } = string.Empty;
|
public string Name { get; set; } = string.Empty;
|
||||||
private string _hexColor = string.Empty;
|
private string _hexColor = string.Empty;
|
||||||
public string HexColor
|
public string HexColor
|
||||||
|
|
|
@ -70,8 +70,8 @@ namespace SharpRss.Services
|
||||||
var feeds = await GetFeedsAsync();
|
var feeds = await GetFeedsAsync();
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<HashSet<FeedModel>> GetFeedsAsync(string? groupId = null) => await DbAccess.GetFeedsAsync();
|
public async Task<HashSet<FeedModel>> GetFeedsAsync(string? categoryId = null) => await DbAccess.GetFeedsAsync(categoryId == null ? null : new[]{ categoryId });
|
||||||
public async Task<HashSet<FeedModel>> GetUngroupedFeedsAsync() => await DbAccess.GetFeedsAsync();
|
public async Task<HashSet<FeedModel>> GetUngroupedFeedsAsync() => await DbAccess.GetFeedsAsync(new []{""});
|
||||||
|
|
||||||
public async Task<HashSet<FeedItemModel>> GetFeedItemsAsync(string feedId, string? groupId = null) => await GetFeedItemsFromFeedsAsync(new[] { feedId }, groupId);
|
public async Task<HashSet<FeedItemModel>> GetFeedItemsAsync(string feedId, string? groupId = null) => await GetFeedItemsFromFeedsAsync(new[] { feedId }, groupId);
|
||||||
public async Task<HashSet<FeedItemModel>> GetFeedItemsFromFeedsAsync(string[] feedIds, string? groupId = null)
|
public async Task<HashSet<FeedItemModel>> GetFeedItemsFromFeedsAsync(string[] feedIds, string? groupId = null)
|
||||||
|
@ -94,7 +94,11 @@ namespace SharpRss.Services
|
||||||
}
|
}
|
||||||
private async void SetupTestGroupsAndFeedsAsync()
|
private async void SetupTestGroupsAndFeedsAsync()
|
||||||
{
|
{
|
||||||
/*await AddSubscriptionAsync("https://www.nu.nl/rss/Algemeen");*/
|
CategoryModel NewsCat = new CategoryModel() { Name = "News" };
|
||||||
|
await AddSubscriptionAsync("https://www.nu.nl/rss/Algemeen", NewsCat);
|
||||||
|
await AddSubscriptionAsync("https://www.nu.nl/rss/Economie", NewsCat);
|
||||||
|
await AddSubscriptionAsync("http://fedoramagazine.org/feed/");
|
||||||
|
await AddSubscriptionAsync("https://itsfoss.com/feed");
|
||||||
//TODO: Make multiple adding of feed to a transaction, now throws an exception.
|
//TODO: Make multiple adding of feed to a transaction, now throws an exception.
|
||||||
/*var groupRes = await CreateGroupAsync(new GroupModel() { Name = "Test" });
|
/*var groupRes = await CreateGroupAsync(new GroupModel() { Name = "Test" });
|
||||||
groupRes = await CreateGroupAsync(new GroupModel() { Name = "News" });
|
groupRes = await CreateGroupAsync(new GroupModel() { Name = "News" });
|
||||||
|
|
|
@ -69,7 +69,7 @@ namespace SharpRss
|
||||||
container.FeedModel.Description = rssFeed.Channel.Description ?? string.Empty;
|
container.FeedModel.Description = rssFeed.Channel.Description ?? string.Empty;
|
||||||
container.FeedModel.Language = rssFeed.Channel.Language?.ToString() ?? string.Empty;
|
container.FeedModel.Language = rssFeed.Channel.Language?.ToString() ?? string.Empty;
|
||||||
container.FeedModel.Copyright = rssFeed.Channel.Copyright ?? string.Empty;
|
container.FeedModel.Copyright = rssFeed.Channel.Copyright ?? string.Empty;
|
||||||
container.FeedModel.PublicationDate = rssFeed.Channel.LastBuildDate is not { Ticks: > 0 } ? DateTimeOffset.MinValue : new DateTimeOffset(rssFeed.Channel.LastBuildDate);
|
container.FeedModel.PublicationDate = rssFeed.Channel.LastBuildDate is not { Ticks: > 0 } ? new DateTimeOffset(rssFeed.Channel.LastBuildDate) : DateTimeOffset.MinValue;
|
||||||
container.FeedModel.Categories = rssFeed.Channel.Categories?.Select(x => x.Value).ToArray() ?? Array.Empty<string>();
|
container.FeedModel.Categories = rssFeed.Channel.Categories?.Select(x => x.Value).ToArray() ?? Array.Empty<string>();
|
||||||
container.FeedModel.ImageUrl = rssFeed.Channel.Image?.Url.ToString() ?? string.Empty;
|
container.FeedModel.ImageUrl = rssFeed.Channel.Image?.Url.ToString() ?? string.Empty;
|
||||||
foreach (var rssItem in rssFeed.Channel.Items)
|
foreach (var rssItem in rssFeed.Channel.Items)
|
||||||
|
@ -82,7 +82,7 @@ namespace SharpRss
|
||||||
Title = rssItem.Title ?? string.Empty,
|
Title = rssItem.Title ?? string.Empty,
|
||||||
Description = rssItem.Description ?? string.Empty,
|
Description = rssItem.Description ?? string.Empty,
|
||||||
Link = rssItem.Link?.ToString() ?? string.Empty,
|
Link = rssItem.Link?.ToString() ?? string.Empty,
|
||||||
PublishingDate = rssItem.PublicationDate is not { Ticks: <= 0 } ? DateTimeOffset.MinValue : new DateTimeOffset(rssItem.PublicationDate),
|
PublishingDate = rssItem.PublicationDate is not { Ticks: <= 0 } ? new DateTimeOffset(rssItem.PublicationDate) : DateTimeOffset.MinValue,
|
||||||
Authors = rssItem.Author != null ? new []{ rssItem.Author } : Array.Empty<string>(),
|
Authors = rssItem.Author != null ? new []{ rssItem.Author } : Array.Empty<string>(),
|
||||||
Categories = rssItem.Categories?.Select(x => x.Value).ToArray() ?? Array.Empty<string>(),
|
Categories = rssItem.Categories?.Select(x => x.Value).ToArray() ?? Array.Empty<string>(),
|
||||||
Content = rssItem.Extensions?.Where(x => x is SiteSummaryContentSyndicationExtension).Select(x => (x as SiteSummaryContentSyndicationExtension)?.Context.Encoded).FirstOrDefault() ?? string.Empty,
|
Content = rssItem.Extensions?.Where(x => x is SiteSummaryContentSyndicationExtension).Select(x => (x as SiteSummaryContentSyndicationExtension)?.Context.Encoded).FirstOrDefault() ?? string.Empty,
|
||||||
|
@ -113,8 +113,8 @@ namespace SharpRss
|
||||||
Title = entry.Title?.Content ?? string.Empty,
|
Title = entry.Title?.Content ?? string.Empty,
|
||||||
Description = entry.Summary?.Content ?? string.Empty,
|
Description = entry.Summary?.Content ?? string.Empty,
|
||||||
Link = entry.Id?.Uri.ToString() ?? string.Empty,
|
Link = entry.Id?.Uri.ToString() ?? string.Empty,
|
||||||
LastUpdated = entry.UpdatedOn is not { Ticks: <= 0 } ? DateTimeOffset.MinValue : new DateTimeOffset(entry.UpdatedOn),
|
LastUpdated = entry.UpdatedOn is not { Ticks: <= 0 } ? new DateTimeOffset(entry.UpdatedOn) : DateTimeOffset.MinValue,
|
||||||
PublishingDate = entry.PublishedOn is not { Ticks: <= 0 } ? DateTimeOffset.MinValue : new DateTimeOffset(entry.PublishedOn),
|
PublishingDate = entry.PublishedOn is not { Ticks: <= 0 } ? new DateTimeOffset(entry.PublishedOn) : DateTimeOffset.MinValue,
|
||||||
Authors = entry.Authors?.Select(auth => auth.Name).ToArray() ?? Array.Empty<string>(),
|
Authors = entry.Authors?.Select(auth => auth.Name).ToArray() ?? Array.Empty<string>(),
|
||||||
Categories = entry.Categories?.Select(cat => cat.Label).ToArray() ?? Array.Empty<string>(),
|
Categories = entry.Categories?.Select(cat => cat.Label).ToArray() ?? Array.Empty<string>(),
|
||||||
Content = entry.Content?.Content ?? string.Empty
|
Content = entry.Content?.Content ?? string.Empty
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Configuration;
|
||||||
|
using System.Linq;
|
||||||
using MudBlazor;
|
using MudBlazor;
|
||||||
using SharpRss.Models;
|
using SharpRss.Models;
|
||||||
using ToolQit;
|
using ToolQit;
|
||||||
|
@ -8,12 +10,12 @@ namespace WebSharpRSS.Models
|
||||||
{
|
{
|
||||||
public class TreeItemData
|
public class TreeItemData
|
||||||
{
|
{
|
||||||
public TreeItemData(CategoryModel groupModel)
|
public TreeItemData(CategoryModel categoryModel)
|
||||||
{
|
{
|
||||||
GroupModel = groupModel;
|
CategoryModel = categoryModel;
|
||||||
Title = groupModel.Name;
|
Title = categoryModel.Name;
|
||||||
Icon = groupModel.Icon == string.Empty ? Icons.Material.Filled.RssFeed : groupModel.Icon;
|
Icon = categoryModel.Icon == string.Empty ? Icons.Material.Filled.RssFeed : categoryModel.Icon;
|
||||||
HasChild = groupModel.FeedCount > 0;
|
HasChildren = CategoryModel.FeedCount > 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
public TreeItemData(FeedModel feedModel)
|
public TreeItemData(FeedModel feedModel)
|
||||||
|
@ -23,7 +25,7 @@ namespace WebSharpRSS.Models
|
||||||
if (FeedModel.OriginalUrl == null) return;
|
if (FeedModel.OriginalUrl == null) return;
|
||||||
FaviconUrl = string.Format(Caretaker.Settings["Paths"].GetString("FaviconResolveUrl"), new Uri(FeedModel.OriginalUrl).Host);
|
FaviconUrl = string.Format(Caretaker.Settings["Paths"].GetString("FaviconResolveUrl"), new Uri(FeedModel.OriginalUrl).Host);
|
||||||
}
|
}
|
||||||
public readonly CategoryModel? GroupModel;
|
public readonly CategoryModel? CategoryModel;
|
||||||
public readonly FeedModel? FeedModel;
|
public readonly FeedModel? FeedModel;
|
||||||
|
|
||||||
public HashSet<TreeItemData>? Children { get; set; }
|
public HashSet<TreeItemData>? Children { get; set; }
|
||||||
|
@ -31,7 +33,7 @@ namespace WebSharpRSS.Models
|
||||||
public bool IsSelected { get; set; }
|
public bool IsSelected { get; set; }
|
||||||
public string? Icon { get; set; }
|
public string? Icon { get; set; }
|
||||||
public string? FaviconUrl { get; set; }
|
public string? FaviconUrl { get; set; }
|
||||||
public bool HasChild { get; set; }
|
public bool HasChildren { get; set; }
|
||||||
public bool Loading { get; set; }
|
public bool Loading { get; set; }
|
||||||
public bool IsExpanded { get; set; }
|
public bool IsExpanded { get; set; }
|
||||||
}
|
}
|
||||||
|
|
|
@ -33,17 +33,17 @@
|
||||||
}
|
}
|
||||||
private string? _fid;
|
private string? _fid;
|
||||||
[Parameter]
|
[Parameter]
|
||||||
[SupplyParameterFromQuery(Name = "gid")]
|
[SupplyParameterFromQuery(Name = "cid")]
|
||||||
public string? Gid
|
public string? Cid
|
||||||
{
|
{
|
||||||
get => _gid;
|
get => _cid;
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
_gid = value;
|
_cid = value;
|
||||||
LoadItems();
|
LoadItems();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
private string? _gid;
|
private string? _cid;
|
||||||
HashSet<FeedItemData> items = new HashSet<FeedItemData>();
|
HashSet<FeedItemData> items = new HashSet<FeedItemData>();
|
||||||
bool _isLoading = true;
|
bool _isLoading = true;
|
||||||
private async void LoadItems()
|
private async void LoadItems()
|
||||||
|
@ -54,9 +54,9 @@
|
||||||
var fItems = await _rssService.GetFeedItemsAsync(Fid);
|
var fItems = await _rssService.GetFeedItemsAsync(Fid);
|
||||||
items = fItems.Select(x => FeedItemData.FromModel(x)).OrderBy(x => x.PublishingDate).Reverse().ToHashSet();
|
items = fItems.Select(x => FeedItemData.FromModel(x)).OrderBy(x => x.PublishingDate).Reverse().ToHashSet();
|
||||||
}
|
}
|
||||||
else if (Gid != null)
|
else if (Cid != null)
|
||||||
{
|
{
|
||||||
var feeds = await _rssService.GetFeedsAsync(Gid);
|
var feeds = await _rssService.GetFeedsAsync(Cid == string.Empty ? null : Cid);
|
||||||
var feedIds = feeds.Select(x => x.OriginalUrl);
|
var feedIds = feeds.Select(x => x.OriginalUrl);
|
||||||
var feedItems = await _rssService.GetFeedItemsFromFeedsAsync(feedIds.ToArray());
|
var feedItems = await _rssService.GetFeedItemsFromFeedsAsync(feedIds.ToArray());
|
||||||
items = feedItems.Select(x => FeedItemData.FromModel(x)).OrderBy(x => x.PublishingDate).Reverse().ToHashSet();
|
items = feedItems.Select(x => FeedItemData.FromModel(x)).OrderBy(x => x.PublishingDate).Reverse().ToHashSet();
|
||||||
|
|
|
@ -11,14 +11,14 @@
|
||||||
<MudStack Spacing="2">
|
<MudStack Spacing="2">
|
||||||
<MudTreeView Color="Color.Success" Items="_guideItems" @bind-SelectedValue="SelectedItem" Hover="true">
|
<MudTreeView Color="Color.Success" Items="_guideItems" @bind-SelectedValue="SelectedItem" Hover="true">
|
||||||
<ItemTemplate>
|
<ItemTemplate>
|
||||||
<MudTreeViewItem @bind-Expanded="@context.IsExpanded" Value="@context" Items="@context.Children" CanExpand="@context.HasChild" @onclick="ItemClicked">
|
<MudTreeViewItem @bind-Expanded="@context.IsExpanded" Value="@context" Items="@context.Children" CanExpand="@context.HasChildren" @onclick="ItemClicked">
|
||||||
<Content>
|
<Content>
|
||||||
<div style="display: grid; grid-template-columns: 1fr auto; align-items: center; width: 100%">
|
<div style="display: grid; grid-template-columns: 1fr auto; align-items: center; width: 100%">
|
||||||
<div style="justify-self: start;" class="d-flex align-center">
|
<div style="justify-self: start;" class="d-flex align-center">
|
||||||
<MudTreeViewItemToggleButton ExpandedChanged="@(() => ExpandedChanged(context))" Loading="@context.Loading" Visible="@context.HasChild" LoadingIconColor="Color.Info" />
|
<MudTreeViewItemToggleButton ExpandedChanged="@(() => ExpandedChanged(context))" Loading="@context.Loading" Visible="@context.HasChildren" LoadingIconColor="Color.Info" />
|
||||||
@if (context.FaviconUrl == null && context.Icon != null)
|
@if (context.FaviconUrl == null && context.Icon != null)
|
||||||
{
|
{
|
||||||
<MudIcon Icon="@context.Icon" Style="@($"color:{context.GroupModel?.HexColor ?? _theme.Palette.Primary.Value}")"/>
|
<MudIcon Icon="@context.Icon" Style="@($"color:{context.CategoryModel?.HexColor ?? _theme.Palette.Primary.Value}")"/>
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -53,15 +53,15 @@
|
||||||
{
|
{
|
||||||
_navigation.NavigateTo($"/list?fid={_selectedItem.FeedModel.OriginalUrl}");
|
_navigation.NavigateTo($"/list?fid={_selectedItem.FeedModel.OriginalUrl}");
|
||||||
}
|
}
|
||||||
else if (_selectedItem.GroupModel != null)
|
else if (_selectedItem.CategoryModel != null)
|
||||||
{
|
{
|
||||||
_navigation.NavigateTo($"/list?gid={_selectedItem.GroupModel.Id}");
|
_navigation.NavigateTo($"/list?cid={_selectedItem.CategoryModel.Id}");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
private async void ExpandedChanged(TreeItemData treeItemData)
|
private async void ExpandedChanged(TreeItemData treeItemData)
|
||||||
{
|
{
|
||||||
treeItemData.Loading = true;
|
treeItemData.Loading = true;
|
||||||
var groupedItems = await _rssService.GetFeedsAsync(treeItemData.GroupModel?.Id);
|
var groupedItems = await _rssService.GetFeedsAsync(treeItemData.CategoryModel?.Id);
|
||||||
treeItemData.Children = ModelToTreeItem(groupedItems);
|
treeItemData.Children = ModelToTreeItem(groupedItems);
|
||||||
treeItemData.IsExpanded = !treeItemData.IsExpanded;
|
treeItemData.IsExpanded = !treeItemData.IsExpanded;
|
||||||
treeItemData.Loading = false;
|
treeItemData.Loading = false;
|
||||||
|
@ -70,6 +70,7 @@
|
||||||
protected override async void OnInitialized()
|
protected override async void OnInitialized()
|
||||||
{
|
{
|
||||||
Log.Verbose("Loading guide data...");
|
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 _rssService.GetCategoriesFeedsAsync();
|
HashSet<object> items = await _rssService.GetCategoriesFeedsAsync();
|
||||||
_guideItems.UnionWith(ModelToTreeItem(items));
|
_guideItems.UnionWith(ModelToTreeItem(items));
|
||||||
|
|
||||||
|
|
Binary file not shown.
Loading…
Reference in New Issue
Block a user