web feed intermediate

This commit is contained in:
Fabian Freund
2025-02-28 14:31:07 +01:00
parent 3c4d479bd9
commit 2a2311253b
51 changed files with 5503 additions and 0 deletions
@@ -0,0 +1,117 @@
import 'package:lensai/extensions/nullable.dart';
import 'package:lensai/features/web_feed/data/database/database.dart';
import 'package:lensai/features/web_feed/data/models/feed_filter.dart';
import 'package:lensai/features/web_feed/data/models/feed_article.dart';
import 'package:lensai/features/web_feed/data/providers.dart';
import 'package:riverpod_annotation/riverpod_annotation.dart';
part 'feed_repository.g.dart';
@Riverpod(keepAlive: true)
class FeedRepository extends _$FeedRepository {
Future<List<FeedData>> getAllFeeds() {
return ref.read(feedDatabaseProvider).feedDao.getFeeds().get();
}
Future<void> touchFeedFetched(Uri url) {
return ref
.read(feedDatabaseProvider)
.feedDao
.updateFeedFetched(url, DateTime.now());
}
Future<void> upsertFeed(FeedData feedData) {
return ref.read(feedDatabaseProvider).feedDao.upsertFeed(feedData);
}
Future<void> upsertArticles(List<FeedArticle> articles) {
return ref.read(feedDatabaseProvider).articleDao.upsertArticles(articles);
}
Future<int> deleteFeed(Uri url) {
return ref.read(feedDatabaseProvider).feedDao.deleteFeed(url);
}
Future<void> touchArticleRead(String articleId) {
return ref
.read(feedDatabaseProvider)
.articleDao
.updateArticleRead(articleId, DateTime.now());
}
Future<void> unsetArticleRead(String articleId) {
return ref
.read(feedDatabaseProvider)
.articleDao
.updateArticleRead(articleId, null);
}
Stream<List<FeedData>> watchFeeds() {
return ref.read(feedDatabaseProvider).feedDao.getFeeds().watch();
}
Stream<List<FeedArticle>> watchFeedArticles(
FeedFilter filter, {
int snippetLength = 120,
String matchPrefix = '***',
String matchSuffix = '***',
String ellipsis = '',
}) {
final stream =
filter.query.isNotEmpty
? ref
.read(feedDatabaseProvider)
.articleDao
.queryArticles(
matchPrefix: matchPrefix,
matchSuffix: matchSuffix,
ellipsis: ellipsis,
snippetLength: snippetLength,
searchString: filter.query!,
feedId: filter.feedId,
)
.watch()
: ref
.read(feedDatabaseProvider)
.articleDao
.getFeedArticles(filter.feedId)
.watch();
if (filter.tags.isNotEmpty) {
return stream.map(
(articles) =>
articles
.where(
(article) =>
article.tags?.toSet().containsAll(filter.tags!) ?? false,
)
.toList(),
);
} else {
return stream;
}
}
Stream<FeedArticle?> watchArticle(String articleId) {
return ref
.read(feedDatabaseProvider)
.articleDao
.getArticleById(articleId)
.watchSingleOrNull();
}
Stream<Map<String, int>> watchUnreadFeedArticleCount() {
return ref
.read(feedDatabaseProvider)
.articleDao
.getUnreadArticleCount()
.watch()
.map(
(results) =>
Map.fromEntries(results.map((e) => MapEntry(e.$1, e.$2))),
);
}
@override
void build() {}
}
@@ -0,0 +1,26 @@
// GENERATED CODE - DO NOT MODIFY BY HAND
part of 'feed_repository.dart';
// **************************************************************************
// RiverpodGenerator
// **************************************************************************
String _$feedRepositoryHash() => r'6a050933a6a4eafbe76a66262e1b64bd838a1078';
/// See also [FeedRepository].
@ProviderFor(FeedRepository)
final feedRepositoryProvider = NotifierProvider<FeedRepository, void>.internal(
FeedRepository.new,
name: r'feedRepositoryProvider',
debugGetCreateSourceHash:
const bool.fromEnvironment('dart.vm.product')
? null
: _$feedRepositoryHash,
dependencies: null,
allTransitiveDependencies: null,
);
typedef _$FeedRepository = Notifier<void>;
// ignore_for_file: type=lint
// ignore_for_file: subtype_of_sealed_class, invalid_use_of_internal_member, invalid_use_of_visible_for_testing_member, deprecated_member_use_from_same_package