mirror of
https://github.com/hmaxnl/SharpRSS.git
synced 2025-01-18 21:04:21 +01:00
Simplified UI & Started database backend implementations
This commit is contained in:
parent
24d62d79dc
commit
43cb208910
32
SharpRss/Models/FeedItemModel.cs
Normal file
32
SharpRss/Models/FeedItemModel.cs
Normal file
|
@ -0,0 +1,32 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace SharpRss.Models
|
||||
{
|
||||
public class FeedItemModel
|
||||
{
|
||||
/// <summary>
|
||||
/// Last time the item is fetched.
|
||||
/// </summary>
|
||||
public DateTime LastUpdated { get; set; }
|
||||
/// <summary>
|
||||
/// The feed in which the item is part.
|
||||
/// </summary>
|
||||
public string FeedId { get; set; }
|
||||
/// <summary>
|
||||
/// If the item is read.
|
||||
/// </summary>
|
||||
public string Read { get; set; }
|
||||
|
||||
public string Type { get; set; }
|
||||
public string Title { get; set; }
|
||||
public string Description { get; set; }
|
||||
public string Link { get; set; }
|
||||
public DateTime? PublishingDate { get; set; }
|
||||
public string Author { get; set; }
|
||||
public string Id { get; set; }
|
||||
public string[] Categories { get; set; }
|
||||
public string Content { get; set; }
|
||||
}
|
||||
}
|
|
@ -16,11 +16,17 @@ namespace SharpRss.Models
|
|||
FeedId = Guid.NewGuid().ToString();
|
||||
FeedUrl = rssFeedUrl;
|
||||
}
|
||||
|
||||
public string FeedUrl { get; set; }
|
||||
public string FeedId { get; private set; }
|
||||
public string CategoryId { get; set; } = "";
|
||||
|
||||
public string FeedType { get; set; }
|
||||
public string FeedUrl { get; set; }
|
||||
public string Description { get; set; }
|
||||
public string Language { get; set; }
|
||||
public string Copyright { get; set; }
|
||||
public DateTime LastUpdated { get; set; }
|
||||
public string ImageUrl { get; set; }
|
||||
|
||||
public static FeedModel Create(string url, string feedId, string categoryId)
|
||||
{
|
||||
FeedModel feedModel = new FeedModel()
|
||||
|
|
|
@ -2,6 +2,7 @@ using System;
|
|||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Dapper;
|
||||
using Microsoft.Data.Sqlite;
|
||||
|
@ -78,22 +79,23 @@ namespace SharpRss.Services
|
|||
private async void InitializeDb()
|
||||
{
|
||||
Log.Verbose("Checking database...");
|
||||
HashSet<string> failed = new HashSet<string>();
|
||||
_sqlConn.Open();
|
||||
// Check category_data table
|
||||
var queryResponse = await _sqlConn.QueryAsync("CREATE TABLE IF NOT EXISTS category_data (name STRING NOT NULL, hex_color STRING NOT NULL, path_icon STRING, category_id STRING PRIMARY KEY, CONSTRAINT name UNIQUE (name))");
|
||||
if (queryResponse.Any())
|
||||
{
|
||||
_sqlConn.Close();
|
||||
_sqlConn.Dispose();
|
||||
throw new SqliteException("Error initializing database!", 0);
|
||||
}
|
||||
if (queryResponse.Any()) failed.Add("category_data");
|
||||
|
||||
// Check feed_data table
|
||||
queryResponse = await _sqlConn.QueryAsync("CREATE TABLE IF NOT EXISTS feed_data (url STRING NOT NULL, feed_id STRING PRIMARY KEY, category_id STRING NOT NULL DEFAULT '', CONSTRAINT url, UNIQUE (url))");
|
||||
if (queryResponse.Any())
|
||||
if (queryResponse.Any()) failed.Add("feed_data");
|
||||
|
||||
_sqlConn.Close();
|
||||
if (failed.Any())
|
||||
{
|
||||
_sqlConn.Close();
|
||||
_sqlConn.Dispose();
|
||||
throw new SqliteException("Error initializing database!", 0);
|
||||
var joined = string.Join(',', failed);
|
||||
Log.Error("Failed to initialize table(s): {TableNames}", joined);
|
||||
}
|
||||
_sqlConn.Close();
|
||||
else
|
||||
Log.Verbose("Checking database done!");
|
||||
}
|
||||
|
||||
|
|
|
@ -10,7 +10,7 @@ namespace SharpRss.Services
|
|||
/// <summary>
|
||||
/// Managing RSS feeds and categories.
|
||||
/// </summary>
|
||||
public class RssService
|
||||
public class RssService : IDisposable
|
||||
{
|
||||
public RssService()
|
||||
{
|
||||
|
@ -85,5 +85,10 @@ namespace SharpRss.Services
|
|||
FeedModel feedModel = new FeedModel(rssUrl, category);
|
||||
await _dbService.AddFeedsAsync(new HashSet<FeedModel>() { feedModel });
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
_dbService.Dispose();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -2,6 +2,7 @@ using System;
|
|||
using System.IO;
|
||||
using Serilog;
|
||||
using Serilog.Formatting.Json;
|
||||
using Serilog.Sinks.SystemConsole.Themes;
|
||||
using ToolQit;
|
||||
using ToolQit.Containers;
|
||||
|
||||
|
|
19
WebSharpRSS/Models/FeedItemData.cs
Normal file
19
WebSharpRSS/Models/FeedItemData.cs
Normal file
|
@ -0,0 +1,19 @@
|
|||
using CodeHollow.FeedReader;
|
||||
using SharpRss.Models;
|
||||
|
||||
namespace WebSharpRSS.Models
|
||||
{
|
||||
public class FeedItemData
|
||||
{
|
||||
public FeedItemData(FeedItem feedItem)
|
||||
{
|
||||
FeedItem = feedItem;
|
||||
}
|
||||
public FeedModel FeedModel { get; set; }
|
||||
public FeedItem FeedItem { get; set; }
|
||||
public string? Icon {get; set; }
|
||||
public string? FaviconUrl { get; set; }
|
||||
public string? CategoryColorHex { get; set; }
|
||||
public bool Read { get; set; }
|
||||
}
|
||||
}
|
|
@ -23,6 +23,7 @@ namespace WebSharpRSS.Models
|
|||
{
|
||||
_service = rssService;
|
||||
FeedModel = feedModel;
|
||||
|
||||
Initialize();
|
||||
}
|
||||
|
||||
|
|
|
@ -4,27 +4,34 @@
|
|||
@using WebSharpRSS.Models;
|
||||
@using SharpRss.Services
|
||||
|
||||
@*@inject RssService _rssService;*@
|
||||
@inject FeedStateContainer _stateContainer;
|
||||
|
||||
<MudGrid Spacing="3" Justify="Justify.FlexStart">
|
||||
@foreach (var feedItem in _items)
|
||||
<MudStack Spacing="2" Class="ml-2 mr-2">
|
||||
@foreach (var feedItemData in _itemDatas)
|
||||
{
|
||||
<MudItem xs="6">
|
||||
<MudItem>
|
||||
<MudCard>
|
||||
<MudCardContent>
|
||||
<MudText>@feedItem.Title</MudText>
|
||||
<MudText Typo="Typo.body2">@feedItem.Description</MudText>
|
||||
<MudText Typo="Typo.overline">@feedItem.PublishingDate.ToString()</MudText>
|
||||
<div style="justify-self: start;" class="d-flex align-center">
|
||||
@if (feedItemData.Icon != null)
|
||||
{
|
||||
<MudIcon Icon="@feedItemData.Icon" Style="@($"color:{feedItemData.CategoryColorHex}")" />
|
||||
}
|
||||
@if (feedItemData.FaviconUrl != null)
|
||||
{
|
||||
<MudImage Src="@feedItemData.FaviconUrl" ObjectFit="ObjectFit.Contain" />
|
||||
}
|
||||
<MudText Class="d-inline pa-2 align-center">@feedItemData.FeedItem.Title</MudText>
|
||||
</div>
|
||||
<MudText Typo="Typo.body2">@feedItemData.FeedItem.Description</MudText>
|
||||
<MudText Typo="Typo.overline">@feedItemData.FeedItem.PublishingDate.ToString()</MudText>
|
||||
</MudCardContent>
|
||||
</MudCard>
|
||||
</MudItem>
|
||||
}
|
||||
</MudGrid>
|
||||
</MudStack>
|
||||
|
||||
@code {
|
||||
|
||||
private HashSet<FeedItem> _items = new HashSet<FeedItem>();
|
||||
protected override void OnInitialized()
|
||||
{
|
||||
UpdateFeeds();
|
||||
|
@ -35,19 +42,25 @@
|
|||
UpdateFeeds();
|
||||
InvokeAsync(StateHasChanged);
|
||||
}
|
||||
|
||||
private HashSet<FeedItemData> _itemDatas = new HashSet<FeedItemData>();
|
||||
private TreeItemData? _treeItemData;
|
||||
private void UpdateFeeds()
|
||||
{
|
||||
if (_stateContainer.TreeItem == null) return;
|
||||
if (_stateContainer.TreeItem.Feed != null)
|
||||
_items = _stateContainer.TreeItem.Feed.Items.ToHashSet();
|
||||
if (_stateContainer.TreeItem.Feeds != null)
|
||||
_treeItemData = _stateContainer.TreeItem;
|
||||
if (_treeItemData.Feed != null)
|
||||
{
|
||||
_items = new HashSet<FeedItem>();
|
||||
foreach (var itemData in _stateContainer.TreeItem.Feeds)
|
||||
Feed feed = _treeItemData.Feed;
|
||||
_itemDatas = feed.Items.Select(x => new FeedItemData(x) { Icon = _treeItemData.Icon, FaviconUrl = _treeItemData.FaviconUrl, CategoryColorHex = _treeItemData.CategoryModel?.HexColor }).ToHashSet();
|
||||
}
|
||||
else if (_treeItemData.Feeds != null)
|
||||
{
|
||||
if (itemData.Feed == null) continue;
|
||||
_items.UnionWith(itemData.Feed.Items);
|
||||
HashSet<FeedItemData> items = new HashSet<FeedItemData>();
|
||||
foreach (var treeItem in _treeItemData.Feeds)
|
||||
{
|
||||
if (treeItem.Feed == null) continue;
|
||||
items.UnionWith(treeItem.Feed.Items.Select(x => new FeedItemData(x) { Icon = treeItem.Icon, FaviconUrl = treeItem.FaviconUrl, CategoryColorHex = _treeItemData.CategoryModel?.HexColor }));
|
||||
_itemDatas = items.OrderBy(x => x.FeedItem.PublishingDate).Reverse().ToHashSet();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -63,6 +63,6 @@
|
|||
_guideItems.UnionWith(items.Select(x => x is CategoryModel model ? new TreeItemData(model, _rssService) : x is FeedModel feedModel ? new TreeItemData(feedModel, _rssService) : throw new ArgumentException("Arg x is invalid!")));
|
||||
|
||||
StateHasChanged();
|
||||
Log.Verbose(" Guide initialized!");
|
||||
Log.Verbose("Guide initialized!");
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user