Skip to content

Commit

Permalink
8 refresh articles (#9)
Browse files Browse the repository at this point in the history
* #8 : Change article view

* #8 : Add settings window

* #5 : Add settings for feeds

* #5 : Change edit feed
  • Loading branch information
oliver254 authored Jun 16, 2022
1 parent b4093f0 commit 988ef43
Show file tree
Hide file tree
Showing 17 changed files with 336 additions and 164 deletions.
22 changes: 21 additions & 1 deletion src/Monbsoft.Feeader.Avalonia/Models/Feed.cs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,27 @@ public Feed(string name, string link, DateTime creationDate)

public DateTime CreationDate { get; }
public string Link { get; set; }
public string Name { get; }
public string Name { get; set; }

public override bool Equals(object? obj)
{
Feed? other = obj as Feed;

if (ReferenceEquals(null, other))
return false;
if (ReferenceEquals(this, other))
return true;
return string.Equals(Name, other.Name) && string.Equals(Link, other.Link);

}
public override int GetHashCode()
{
return Name.GetHashCode() ^ Link.GetHashCode();
}
override public string ToString()
{
return Name;
}

}
}
23 changes: 23 additions & 0 deletions src/Monbsoft.Feeader.Avalonia/Models/SettingsContext.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Monbsoft.Feeader.Avalonia.Models
{
public class SettingsContext
{
public SettingsContext()
{
Feeds = new ObservableCollection<Feed>();
}
public SettingsContext(IEnumerable<Feed> feeds)
{
Feeds = new ObservableCollection<Feed>(feeds);
}

public ObservableCollection<Feed> Feeds { get; }
}
}
61 changes: 0 additions & 61 deletions src/Monbsoft.Feeader.Avalonia/ViewModels/AddFeedViewModel.cs

This file was deleted.

4 changes: 2 additions & 2 deletions src/Monbsoft.Feeader.Avalonia/ViewModels/ArticleViewModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@ namespace Monbsoft.Feeader.Avalonia.ViewModels
{
public class ArticleViewModel : ViewModelBase
{
private Uri? _pictureUri;
private Bitmap? _picture;
private Uri? _pictureUri;

public ArticleViewModel(Article article)
{
Expand Down Expand Up @@ -54,7 +54,7 @@ public async Task LoadPictureAsync(CancellationToken cancellationToken)
if (_pictureUri != null)
{
Picture = await PictureService.LoadPictureBitmapAsync(_pictureUri, cancellationToken);
}
}
}
}
}
92 changes: 92 additions & 0 deletions src/Monbsoft.Feeader.Avalonia/ViewModels/EditFeedViewModel.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
using Monbsoft.Feeader.Avalonia.Models;
using Monbsoft.Feeader.Avalonia.Services;
using NLog.Fluent;
using ReactiveUI;
using System;
using System.Collections.ObjectModel;
using System.Diagnostics;
using System.Linq;
using System.Reactive;
using System.Reactive.Linq;

namespace Monbsoft.Feeader.Avalonia.ViewModels
{
public class EditFeedViewModel : ViewModelBase
{
private string _name;
private Feed? _selected;
private string _url;
public EditFeedViewModel(SettingsContext context)
{
this.WhenAnyValue(x => x.Url)
.Where(x => !string.IsNullOrWhiteSpace(x))
.Throttle(TimeSpan.FromMilliseconds(400))
.ObserveOn(RxApp.MainThreadScheduler)
.Subscribe(DoSearch);

Feeds = new ObservableCollection<Feed>(context.Feeds);

AddCommand = ReactiveCommand.Create(() =>
{
Feeds.Add(new Feed("name", "https://feed.com"));
Debug.WriteLine($"Feed added");
});
RemoveCommand = ReactiveCommand.Create(() =>
{
if(_selected != null)
{
Feeds.Remove(_selected);
Debug.WriteLine($"Feed {_selected?.Name} removed");
}
});

}

/// <summary>
/// Gets the add command
/// </summary>
public ReactiveCommand<Unit, Unit> AddCommand { get; }
public ObservableCollection<Feed> Feeds { get; }
/// <summary>
/// Gets the name of the feed
/// </summary>
public string? Name
{
get => _name;
set => this.RaiseAndSetIfChanged(ref _name, value);
}
public ReactiveCommand<Unit, Unit> RemoveCommand { get; }
/// <summary>
/// Gets or sets the selected feed
/// </summary>
public Feed SelectedFeed
{
get => _selected;
set => this.RaiseAndSetIfChanged(ref _selected, value);
}
/// <summary>
/// Gets the url of the feed
/// </summary>
public string? Url
{
get => _url;
set => this.RaiseAndSetIfChanged(ref _url, value);
}

private async void DoSearch(string? url)
{
try
{
if (!string.IsNullOrEmpty(url))
{
var feed = await FeedService.GetFeedDataAsync(url);
Name = feed.Name;
}
}
catch(Exception ex)
{
Log.Error(ex.Message);
}
}
}
}
71 changes: 38 additions & 33 deletions src/Monbsoft.Feeader.Avalonia/ViewModels/MainWindowViewModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,12 @@
using Monbsoft.Feeader.Avalonia.Services;
using ReactiveUI;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Diagnostics;
using System.Linq;
using System.Reactive.Concurrency;
using System.Reactive.Linq;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Input;

namespace Monbsoft.Feeader.Avalonia.ViewModels;
Expand All @@ -22,71 +20,78 @@ public class MainWindowViewModel : ViewModelBase

public MainWindowViewModel()
{
ShowDialog = new Interaction<SettingsWindowViewModel, SettingsContext>();

ShowDialog = new Interaction<AddFeedViewModel, Feed?>();

AddFeedCommand = ReactiveCommand.CreateFromTask(async () =>
ShowSettingsCommand = ReactiveCommand.CreateFromTask(async () =>
{
var store = new AddFeedViewModel();
var feed = await ShowDialog.Handle(store);
AddFeed(feed);
var store = new SettingsWindowViewModel(new SettingsContext(Feeds));
var context = await ShowDialog.Handle(store);
await FeedService.SaveAsync(context.Feeds.ToList());
LoadFeedsAsync();
});

this.WhenAnyValue(x => x.SelectedFeed)
.WhereNotNull()
.Subscribe(LoadArticles);

FeedService.InitializeCache();
PictureService.InitializePictureCache();

RxApp.MainThreadScheduler.Schedule(LoadFeedsAsync);
}

public ICommand AddFeedCommand { get; }
public ObservableCollection<ArticleViewModel> Articles { get; } = new ();
public ICommand ShowSettingsCommand { get; }
public ObservableCollection<ArticleViewModel> Articles { get; } = new();
public ObservableCollection<Feed> Feeds { get; } = new();

public Feed? SelectedFeed
{
get => _selectedFeed;
set => this.RaiseAndSetIfChanged(ref _selectedFeed, value);
}

public ArticleViewModel? SelectedArticle
{
get => _selectedArticle;
set => this.RaiseAndSetIfChanged(ref _selectedArticle, value);
}
public Interaction<AddFeedViewModel, Feed?> ShowDialog { get; }

public Interaction<SettingsWindowViewModel, SettingsContext> ShowDialog { get; }

public async void LoadFeedsAsync()
{
FeedService.InitializeCache();
PictureService.InitializePictureCache();
var feeds = await FeedService.LoadAsync();
var feeds = await FeedService.LoadAsync();

SelectedFeed = null;
Feeds.Clear();

foreach(var feed in feeds)
foreach (var feed in feeds)
{
Feeds.Add(feed);
}
Trace.TraceInformation("{0} feeds loaded", Feeds.Count);
}
private async void AddFeed(Feed? feed)
{
if (feed == null)
return;
Feeds.Add(feed);
await FeedService.SaveAsync(Feeds.ToList());
}
private async void LoadArticles(Feed feed)

private async void LoadArticles(Feed? feed)
{
Articles.Clear();

_cancellationTokenSource?.Cancel();
_cancellationTokenSource = new CancellationTokenSource();
foreach(var article in await ArticleService.LoadAsync(feed, _cancellationTokenSource.Token))
{
Articles.Add(new ArticleViewModel(article));
}
if (!_cancellationTokenSource.IsCancellationRequested)
_cancellationTokenSource = new CancellationTokenSource();

if (feed != null)
{
LoadPictures(_cancellationTokenSource.Token);
foreach (var article in await ArticleService.LoadAsync(feed, _cancellationTokenSource.Token))
{
Articles.Add(new ArticleViewModel(article));
}
if (!_cancellationTokenSource.IsCancellationRequested)
{
LoadPictures(_cancellationTokenSource.Token);
}
}
Trace.TraceInformation("{0} articles loaded", Articles.Count);
}

private async void LoadPictures(CancellationToken cancellationToken)
{
foreach (var article in Articles)
Expand All @@ -96,8 +101,8 @@ private async void LoadPictures(CancellationToken cancellationToken)
if (cancellationToken.IsCancellationRequested)
{
return;
}
}
}
Trace.TraceInformation("Pictures loaded");
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
using Monbsoft.Feeader.Avalonia.Models;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Monbsoft.Feeader.Avalonia.ViewModels
{
public class SettingsWindowViewModel : ViewModelBase
{

public SettingsWindowViewModel(SettingsContext context)
{
EditFeedViewModel = new EditFeedViewModel(context);
}

public EditFeedViewModel EditFeedViewModel { get; }

public SettingsContext CreateContext()
{
return new SettingsContext(EditFeedViewModel.Feeds);
}
}
}
Loading

0 comments on commit 988ef43

Please sign in to comment.