mirror of
https://github.com/ckaczor/FeedCenter.git
synced 2026-01-29 09:35:39 -05:00
Start adding Miniflux support plus other cleanup
- Modernize old async code - Update to .NET 10 - Adjust namespace - Bypass update check when debugging
This commit is contained in:
@@ -3,6 +3,7 @@ using System;
|
||||
using System.Linq;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using FeedCenter.Feeds;
|
||||
|
||||
namespace FeedCenter;
|
||||
|
||||
|
||||
@@ -3,6 +3,7 @@ using System;
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
using System.Threading;
|
||||
using FeedCenter.Feeds;
|
||||
|
||||
namespace FeedCenter;
|
||||
|
||||
|
||||
@@ -38,7 +38,7 @@ public partial class MainWindow
|
||||
return;
|
||||
|
||||
// Get the feed item
|
||||
var feedItem = (FeedItem) ((ListBoxItem) sender).DataContext;
|
||||
var feedItem = (Feeds.FeedItem) ((ListBoxItem) sender).DataContext;
|
||||
|
||||
// Remove the item from the list
|
||||
LinkTextList.Items.Remove(feedItem);
|
||||
@@ -50,7 +50,7 @@ public partial class MainWindow
|
||||
private async void HandleItemMouseDoubleClick(object sender, MouseButtonEventArgs e)
|
||||
{
|
||||
// Get the feed item
|
||||
var feedItem = (FeedItem) ((ListBoxItem) sender).DataContext;
|
||||
var feedItem = (Feeds.FeedItem) ((ListBoxItem) sender).DataContext;
|
||||
|
||||
// Try to open the item link
|
||||
if (!InstalledBrowser.OpenLink(Settings.Default.Browser, feedItem.Link))
|
||||
@@ -104,7 +104,7 @@ public partial class MainWindow
|
||||
var menuItem = (MenuItem) sender;
|
||||
|
||||
// Get the feed from the menu item tab
|
||||
var feed = (Feed) menuItem.Tag;
|
||||
var feed = (Feeds.Feed) menuItem.Tag;
|
||||
|
||||
// Loop over all feeds and look for the index of the new one
|
||||
var feedIndex = 0;
|
||||
|
||||
@@ -1,38 +1,19 @@
|
||||
using ChrisKaczor.ApplicationUpdate;
|
||||
using FeedCenter.Feeds;
|
||||
using FeedCenter.Properties;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows;
|
||||
|
||||
namespace FeedCenter;
|
||||
|
||||
public partial class MainWindow
|
||||
{
|
||||
private BackgroundWorker _feedReadWorker;
|
||||
|
||||
private class FeedReadWorkerInput
|
||||
{
|
||||
public bool ForceRead { get; }
|
||||
public Guid? FeedId { get; }
|
||||
|
||||
public FeedReadWorkerInput()
|
||||
{
|
||||
}
|
||||
|
||||
public FeedReadWorkerInput(bool forceRead)
|
||||
{
|
||||
ForceRead = forceRead;
|
||||
}
|
||||
|
||||
public FeedReadWorkerInput(bool forceRead, Guid? feedId)
|
||||
{
|
||||
ForceRead = forceRead;
|
||||
FeedId = feedId;
|
||||
}
|
||||
}
|
||||
private bool _reading;
|
||||
|
||||
private void SetProgressMode(bool showProgress, int maximum)
|
||||
{
|
||||
@@ -49,55 +30,72 @@ public partial class MainWindow
|
||||
}
|
||||
}
|
||||
|
||||
private void ReadCurrentFeed(bool forceRead = false)
|
||||
private async void ReadCurrentFeed(bool forceRead = false)
|
||||
{
|
||||
// Don't read if we're already working
|
||||
if (_feedReadWorker.IsBusy)
|
||||
return;
|
||||
try
|
||||
{
|
||||
// Don't read if we're already working
|
||||
if (_reading)
|
||||
return;
|
||||
|
||||
// Don't read if there is nothing to read
|
||||
if (!_database.Feeds.Any())
|
||||
return;
|
||||
_reading = true;
|
||||
|
||||
// Switch to progress mode
|
||||
SetProgressMode(true, 1);
|
||||
// Don't read if there is nothing to read
|
||||
if (!_database.Feeds.Any())
|
||||
return;
|
||||
|
||||
// Create the input class
|
||||
var workerInput = new FeedReadWorkerInput(forceRead, _currentFeed.Id);
|
||||
var accountReadInput = new AccountReadInput(_database, _currentFeed.Id, forceRead, () => { });
|
||||
|
||||
// Start the worker
|
||||
_feedReadWorker.RunWorkerAsync(workerInput);
|
||||
// Switch to progress mode
|
||||
SetProgressMode(true, await _currentFeed.Account.GetProgressSteps(_currentFeed.Account, accountReadInput));
|
||||
|
||||
// Start reading
|
||||
await HandleFeedReadWorkerStart(forceRead, _currentFeed.Id);
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
HandleException(exception);
|
||||
}
|
||||
}
|
||||
|
||||
private void ReadFeeds(bool forceRead = false)
|
||||
private async Task ReadFeeds(bool forceRead = false)
|
||||
{
|
||||
// Don't read if we're already working
|
||||
if (_feedReadWorker.IsBusy)
|
||||
if (_reading)
|
||||
return;
|
||||
|
||||
_reading = true;
|
||||
|
||||
// Don't read if there is nothing to read
|
||||
if (!_database.Accounts.Any())
|
||||
return;
|
||||
|
||||
var progressSteps = _database.Accounts.Sum(a => a.GetProgressSteps(_database));
|
||||
var accountReadInput = new AccountReadInput(_database, null, forceRead, () => { });
|
||||
|
||||
// Calculate total progress steps
|
||||
var progressSteps = 0;
|
||||
|
||||
foreach (var account in _database.Accounts)
|
||||
{
|
||||
progressSteps += await account.GetProgressSteps(account, accountReadInput);
|
||||
}
|
||||
|
||||
// Switch to progress mode
|
||||
SetProgressMode(true, progressSteps);
|
||||
|
||||
// Create the input class
|
||||
var workerInput = new FeedReadWorkerInput(forceRead);
|
||||
|
||||
// Start the worker
|
||||
_feedReadWorker.RunWorkerAsync(workerInput);
|
||||
// Start reading
|
||||
await HandleFeedReadWorkerStart(forceRead, null);
|
||||
}
|
||||
|
||||
private void HandleFeedReadWorkerProgressChanged(object sender, ProgressChangedEventArgs e)
|
||||
private void IncrementProgress()
|
||||
{
|
||||
Debug.Assert(FeedReadProgress.Value + 1 <= FeedReadProgress.Maximum);
|
||||
|
||||
// Set progress
|
||||
FeedReadProgress.Value = e.ProgressPercentage;
|
||||
FeedReadProgress.Value++;
|
||||
}
|
||||
|
||||
private void HandleFeedReadWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
|
||||
private void CompleteRead()
|
||||
{
|
||||
// Refresh the database to current settings
|
||||
ResetDatabase();
|
||||
@@ -119,6 +117,8 @@ public partial class MainWindow
|
||||
NewVersionLink.Visibility = Visibility.Visible;
|
||||
|
||||
UpdateErrorLink();
|
||||
|
||||
_reading = false;
|
||||
}
|
||||
|
||||
private void UpdateErrorLink()
|
||||
@@ -134,98 +134,61 @@ public partial class MainWindow
|
||||
: string.Format(Properties.Resources.FeedErrorsLink, feedErrorCount);
|
||||
}
|
||||
|
||||
private static void HandleFeedReadWorkerStart(object sender, DoWorkEventArgs e)
|
||||
private async Task HandleFeedReadWorkerStart(bool forceRead, Guid? feedId)
|
||||
{
|
||||
// Create a new database instance for just this thread
|
||||
var database = new FeedCenterEntities();
|
||||
|
||||
// Get the worker
|
||||
var worker = (BackgroundWorker)sender;
|
||||
|
||||
// Get the input information
|
||||
var workerInput = (FeedReadWorkerInput)e.Argument ?? new FeedReadWorkerInput();
|
||||
|
||||
// Setup for progress
|
||||
var currentProgress = 0;
|
||||
|
||||
var accountsToRead = new List<Account>();
|
||||
|
||||
// If we have a single feed then get the account for that feed
|
||||
if (workerInput.FeedId != null)
|
||||
try
|
||||
{
|
||||
var feed = database.Feeds.FirstOrDefault(f => f.Id == workerInput.FeedId);
|
||||
// Create a new database instance for just this thread
|
||||
var database = new FeedCenterEntities();
|
||||
|
||||
if (feed != null)
|
||||
accountsToRead.Add(feed.Account);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Otherwise get all accounts
|
||||
accountsToRead.AddRange(database.Accounts);
|
||||
}
|
||||
var accountsToRead = new List<Account>();
|
||||
|
||||
var incrementProgress = () =>
|
||||
{
|
||||
// Increment progress
|
||||
currentProgress += 1;
|
||||
// If we have a single feed then get the account for that feed
|
||||
if (feedId != null)
|
||||
{
|
||||
var feed = database.Feeds.FirstOrDefault(f => f.Id == feedId);
|
||||
|
||||
if (feed != null)
|
||||
accountsToRead.Add(feed.Account);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Otherwise get all accounts
|
||||
accountsToRead.AddRange(database.Accounts);
|
||||
}
|
||||
|
||||
// Loop over each account and read it
|
||||
foreach (var account in accountsToRead)
|
||||
{
|
||||
var accountReadInput = new AccountReadInput(database, feedId, forceRead, IncrementProgress);
|
||||
|
||||
await account.Read(accountReadInput);
|
||||
}
|
||||
|
||||
// Report progress
|
||||
worker.ReportProgress(currentProgress);
|
||||
};
|
||||
IncrementProgress();
|
||||
|
||||
// Loop over each account and read it
|
||||
foreach (var account in accountsToRead)
|
||||
{
|
||||
var accountReadInput = new AccountReadInput(database, workerInput.FeedId, workerInput.ForceRead, incrementProgress);
|
||||
// See if we're due for a version check
|
||||
if (UpdateCheck.LocalVersion.Major > 0 && DateTime.Now - Settings.Default.LastVersionCheck >= Settings.Default.VersionCheckInterval)
|
||||
{
|
||||
// Get the update information
|
||||
await UpdateCheck.CheckForUpdate(Settings.Default.IncludePrerelease);
|
||||
|
||||
account.Read(accountReadInput);
|
||||
// Update the last check time
|
||||
Settings.Default.LastVersionCheck = DateTime.Now;
|
||||
}
|
||||
|
||||
// Report progress
|
||||
IncrementProgress();
|
||||
|
||||
// Sleep for a little bit so the user can see the update
|
||||
Thread.Sleep(Settings.Default.ProgressSleepInterval * 3);
|
||||
|
||||
CompleteRead();
|
||||
}
|
||||
|
||||
//// Create the list of feeds to read
|
||||
//var feedsToRead = new List<Feed>();
|
||||
|
||||
//// If we have a single feed then add it to the list - otherwise add them all
|
||||
//if (workerInput.FeedId != null)
|
||||
// feedsToRead.Add(database.Feeds.First(feed => feed.Id == workerInput.FeedId));
|
||||
//else
|
||||
// feedsToRead.AddRange(database.Feeds);
|
||||
|
||||
//// Loop over each feed and read it
|
||||
//foreach (var feed in feedsToRead)
|
||||
//{
|
||||
// // Read the feed
|
||||
// database.SaveChanges(() => feed.Read(workerInput.ForceRead));
|
||||
|
||||
// // Increment progress
|
||||
// currentProgress += 1;
|
||||
|
||||
// // Report progress
|
||||
// worker.ReportProgress(currentProgress);
|
||||
//}
|
||||
|
||||
// Increment progress
|
||||
currentProgress += 1;
|
||||
|
||||
// Report progress
|
||||
worker.ReportProgress(currentProgress);
|
||||
|
||||
// See if we're due for a version check
|
||||
if (DateTime.Now - Settings.Default.LastVersionCheck >= Settings.Default.VersionCheckInterval)
|
||||
catch (Exception exception)
|
||||
{
|
||||
// Get the update information
|
||||
UpdateCheck.CheckForUpdate(Settings.Default.IncludePrerelease).Wait();
|
||||
|
||||
// Update the last check time
|
||||
Settings.Default.LastVersionCheck = DateTime.Now;
|
||||
HandleException(exception);
|
||||
}
|
||||
|
||||
// Increment progress
|
||||
currentProgress += 1;
|
||||
|
||||
// Report progress
|
||||
worker.ReportProgress(currentProgress);
|
||||
|
||||
// Sleep for a little bit so the user can see the update
|
||||
Thread.Sleep(Settings.Default.ProgressSleepInterval * 3);
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,6 @@
|
||||
using ChrisKaczor.ApplicationUpdate;
|
||||
using ChrisKaczor.Wpf.Application;
|
||||
using FeedCenter.Feeds;
|
||||
using FeedCenter.Properties;
|
||||
using Serilog;
|
||||
using System;
|
||||
@@ -29,7 +30,6 @@ public partial class MainWindow : IDisposable
|
||||
public void Dispose()
|
||||
{
|
||||
_mainTimer?.Dispose();
|
||||
_feedReadWorker?.Dispose();
|
||||
|
||||
GC.SuppressFinalize(this);
|
||||
}
|
||||
@@ -66,12 +66,6 @@ public partial class MainWindow : IDisposable
|
||||
: Brushes.Black;
|
||||
HeaderLabel.Foreground = LinkTextList.Foreground;
|
||||
|
||||
// Create the background worker that does the actual reading
|
||||
_feedReadWorker = new BackgroundWorker { WorkerReportsProgress = true, WorkerSupportsCancellation = true };
|
||||
_feedReadWorker.DoWork += HandleFeedReadWorkerStart;
|
||||
_feedReadWorker.ProgressChanged += HandleFeedReadWorkerProgressChanged;
|
||||
_feedReadWorker.RunWorkerCompleted += HandleFeedReadWorkerCompleted;
|
||||
|
||||
// Set up the database
|
||||
_database = new FeedCenterEntities();
|
||||
|
||||
@@ -88,13 +82,16 @@ public partial class MainWindow : IDisposable
|
||||
// Initialize the feed display
|
||||
InitializeDisplay();
|
||||
|
||||
// Check for update
|
||||
if (Settings.Default.CheckVersionAtStartup)
|
||||
await UpdateCheck.CheckForUpdate(Settings.Default.IncludePrerelease);
|
||||
if (UpdateCheck.LocalVersion.Major > 0)
|
||||
{
|
||||
// Check for update
|
||||
if (Settings.Default.CheckVersionAtStartup)
|
||||
await UpdateCheck.CheckForUpdate(Settings.Default.IncludePrerelease);
|
||||
|
||||
// Show the link if updates are available
|
||||
if (UpdateCheck.UpdateAvailable)
|
||||
NewVersionLink.Visibility = Visibility.Visible;
|
||||
// Show the link if updates are available
|
||||
if (UpdateCheck.UpdateAvailable)
|
||||
NewVersionLink.Visibility = Visibility.Visible;
|
||||
}
|
||||
|
||||
Log.Logger.Information("MainForm creation finished");
|
||||
}
|
||||
|
||||
@@ -38,29 +38,36 @@ public partial class MainWindow
|
||||
_mainTimer?.Stop();
|
||||
}
|
||||
|
||||
private void HandleMainTimerElapsed(object sender, EventArgs e)
|
||||
private async void HandleMainTimerElapsed(object sender, EventArgs e)
|
||||
{
|
||||
_dispatcher.Invoke(() =>
|
||||
try
|
||||
{
|
||||
// If the background worker is busy then don't do anything
|
||||
if (_feedReadWorker.IsBusy)
|
||||
return;
|
||||
await _dispatcher.Invoke(async () =>
|
||||
{
|
||||
// If the background worker is busy then don't do anything
|
||||
if (_reading)
|
||||
return;
|
||||
|
||||
// Stop the timer for now
|
||||
StopTimer();
|
||||
// Stop the timer for now
|
||||
StopTimer();
|
||||
|
||||
// Move to the next feed if the scroll interval has expired and the mouse isn't hovering
|
||||
if (LinkTextList.IsMouseOver)
|
||||
_lastFeedDisplay = DateTime.Now;
|
||||
else if (DateTime.Now - _lastFeedDisplay >= Settings.Default.FeedScrollInterval)
|
||||
NextFeed();
|
||||
// Move to the next feed if the scroll interval has expired and the mouse isn't hovering
|
||||
if (LinkTextList.IsMouseOver)
|
||||
_lastFeedDisplay = DateTime.Now;
|
||||
else if (DateTime.Now - _lastFeedDisplay >= Settings.Default.FeedScrollInterval)
|
||||
NextFeed();
|
||||
|
||||
// Check to see if we should try to read the feeds
|
||||
if (DateTime.Now - _lastFeedRead >= Settings.Default.FeedCheckInterval)
|
||||
ReadFeeds();
|
||||
// Check to see if we should try to read the feeds
|
||||
if (DateTime.Now - _lastFeedRead >= Settings.Default.FeedCheckInterval)
|
||||
await ReadFeeds();
|
||||
|
||||
// Get the timer going again
|
||||
StartTimer();
|
||||
});
|
||||
// Get the timer going again
|
||||
StartTimer();
|
||||
});
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
HandleException(exception);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -9,6 +9,7 @@ using System.Threading.Tasks;
|
||||
using System.Web.UI;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using FeedCenter.Feeds;
|
||||
using Serilog;
|
||||
using Serilog.Events;
|
||||
|
||||
@@ -75,7 +76,7 @@ public partial class MainWindow
|
||||
UpdateErrorLink();
|
||||
}
|
||||
|
||||
private static void HandleException(Exception exception)
|
||||
internal static void HandleException(Exception exception)
|
||||
{
|
||||
Log.Logger.Write(LogEventLevel.Debug, exception, "");
|
||||
}
|
||||
@@ -109,19 +110,33 @@ public partial class MainWindow
|
||||
UpdateErrorLink();
|
||||
}
|
||||
|
||||
private void HandleRefreshMenuItemClick(object sender, RoutedEventArgs e)
|
||||
private async void HandleRefreshMenuItemClick(object sender, RoutedEventArgs e)
|
||||
{
|
||||
var menuItem = (MenuItem) e.Source;
|
||||
try
|
||||
{
|
||||
var menuItem = (MenuItem) e.Source;
|
||||
|
||||
if (Equals(menuItem, MenuRefresh))
|
||||
ReadCurrentFeed(true);
|
||||
else if (Equals(menuItem, MenuRefreshAll))
|
||||
ReadFeeds(true);
|
||||
if (Equals(menuItem, MenuRefresh))
|
||||
ReadCurrentFeed(true);
|
||||
else if (Equals(menuItem, MenuRefreshAll))
|
||||
await ReadFeeds(true);
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
HandleException(exception);
|
||||
}
|
||||
}
|
||||
|
||||
private void HandleRefreshToolbarButtonClick(object sender, RoutedEventArgs e)
|
||||
private async void HandleRefreshToolbarButtonClick(object sender, RoutedEventArgs e)
|
||||
{
|
||||
ReadFeeds(true);
|
||||
try
|
||||
{
|
||||
await ReadFeeds(true);
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
HandleException(exception);
|
||||
}
|
||||
}
|
||||
|
||||
private async void HandleOpenAllMenuItemClick(object sender, RoutedEventArgs e)
|
||||
|
||||
@@ -76,13 +76,6 @@ public partial class MainWindow
|
||||
{
|
||||
base.OnClosing(e);
|
||||
|
||||
// Ditch the worker
|
||||
if (_feedReadWorker != null)
|
||||
{
|
||||
_feedReadWorker.CancelAsync();
|
||||
_feedReadWorker.Dispose();
|
||||
}
|
||||
|
||||
// Get rid of the timer
|
||||
TerminateTimer();
|
||||
|
||||
|
||||
Reference in New Issue
Block a user