major update
This commit is contained in:
@@ -10,7 +10,7 @@ class ArticleDao extends DatabaseAccessor<FeedDatabase> with _$ArticleDaoMixin {
|
||||
ArticleDao(super.attachedDatabase);
|
||||
|
||||
Selectable<FeedArticle> getFeedArticles(Uri? url) {
|
||||
final select = db.article.select();
|
||||
final select = db.articleView.select();
|
||||
|
||||
if (url != null) {
|
||||
select.where((article) => article.feedId.equalsValue(url));
|
||||
@@ -25,7 +25,7 @@ class ArticleDao extends DatabaseAccessor<FeedDatabase> with _$ArticleDaoMixin {
|
||||
}
|
||||
|
||||
SingleOrNullSelectable<FeedArticle> getArticleById(String articleId) {
|
||||
return db.article.select()..where((row) => row.id.equals(articleId));
|
||||
return db.articleView.select()..where((row) => row.id.equals(articleId));
|
||||
}
|
||||
|
||||
Future<void> upsertArticles(List<FeedArticle> articles) {
|
||||
@@ -111,8 +111,6 @@ class ArticleDao extends DatabaseAccessor<FeedDatabase> with _$ArticleDaoMixin {
|
||||
return db.queryArticlesBasic(
|
||||
feedId: feedId?.toString(),
|
||||
query: db.buildLikeQuery(searchString),
|
||||
beforeMatch: matchPrefix,
|
||||
afterMatch: matchSuffix,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,15 +11,19 @@ class FeedDao extends DatabaseAccessor<FeedDatabase> with _$FeedDaoMixin {
|
||||
return db.feed.select();
|
||||
}
|
||||
|
||||
Future<int> updateFeedFetched(Uri url, DateTime fetched) {
|
||||
SingleOrNullSelectable<FeedData> getFeed(Uri feedId) {
|
||||
return db.feed.select()..where((feed) => feed.url.equalsValue(feedId));
|
||||
}
|
||||
|
||||
Future<int> updateFeedFetched(Uri feedId, DateTime fetched) {
|
||||
final statement =
|
||||
db.feed.update()..where((feed) => feed.url.equalsValue(url));
|
||||
db.feed.update()..where((feed) => feed.url.equalsValue(feedId));
|
||||
|
||||
return statement.write(FeedCompanion(lastFetched: Value(fetched)));
|
||||
}
|
||||
|
||||
Future<int> deleteFeed(Uri url) {
|
||||
return db.feed.deleteWhere((feed) => feed.url.equals(url.toString()));
|
||||
Future<int> deleteFeed(Uri feedId) {
|
||||
return db.feed.deleteWhere((feed) => feed.url.equals(feedId.toString()));
|
||||
}
|
||||
|
||||
Future<int> upsertFeed(FeedData feedData) {
|
||||
|
||||
@@ -9,6 +9,8 @@ CREATE TABLE feed (
|
||||
url TEXT PRIMARY KEY NOT NULL MAPPED BY `const UriConverter()`,
|
||||
title TEXT,
|
||||
description TEXT,
|
||||
icon TEXT MAPPED BY `const UriConverter()`,
|
||||
site_link TEXT MAPPED BY `const UriConverter()`,
|
||||
authors TEXT MAPPED BY `const FeedAuthorsConverter()`,
|
||||
tags TEXT MAPPED BY `const FeedCategoriesConverter()`,
|
||||
last_fetched DATETIME
|
||||
@@ -31,6 +33,15 @@ CREATE TABLE article (
|
||||
contentPlain TEXT
|
||||
) WITH FeedArticle;
|
||||
|
||||
CREATE VIEW article_view WITH FeedArticle AS
|
||||
SELECT
|
||||
a.*,
|
||||
f.icon
|
||||
FROM
|
||||
article a
|
||||
INNER JOIN
|
||||
feed f on f.url = a.feed_id;
|
||||
|
||||
CREATE INDEX article_feed_id ON article (feed_id);
|
||||
|
||||
CREATE VIRTUAL TABLE article_fts
|
||||
@@ -73,17 +84,19 @@ queryArticlesBasic(:feed_id AS TEXT OR NULL) WITH FeedArticleQueryResult:
|
||||
)
|
||||
SELECT
|
||||
a.*,
|
||||
highlight(article_fts, 0, :beforeMatch, :afterMatch) AS title,
|
||||
f.icon,
|
||||
(
|
||||
bm25(article_fts, weights.title_weight)
|
||||
) AS weighted_rank
|
||||
FROM article_fts(:query) fts
|
||||
FROM article_fts fts
|
||||
INNER JOIN
|
||||
article a ON a.rowid = fts.rowid
|
||||
INNER JOIN
|
||||
feed f ON f.url = a.feed_id
|
||||
CROSS JOIN weights
|
||||
WHERE
|
||||
fts.title LIKE :query AND
|
||||
:feed_id IS NULL OR a.feed_id = :feed_id
|
||||
(:feed_id IS NULL OR a.feed_id = :feed_id)
|
||||
ORDER BY
|
||||
weighted_rank ASC,
|
||||
a.created DESC NULLS LAST;
|
||||
@@ -92,15 +105,16 @@ queryArticlesFullContent(:feed_id AS TEXT OR NULL) WITH FeedArticleQueryResult:
|
||||
WITH weights AS (
|
||||
SELECT
|
||||
-- Customize these weights (higher = more important)
|
||||
5.0 as title_weight, -- Title matches are most important
|
||||
2.0 as summary_weight, -- Summary matches are quite important
|
||||
10.0 as title_weight, -- Title matches are most important
|
||||
3.0 as summary_weight, -- Summary matches are quite important
|
||||
1.0 as content_weight -- Content matches are basic
|
||||
)
|
||||
SELECT
|
||||
a.*,
|
||||
highlight(article_fts, 0, :beforeMatch, :afterMatch) AS title,
|
||||
snippet(article_fts, 1, :beforeMatch, :afterMatch, :ellipsis, :snippetLength) AS summary,
|
||||
snippet(article_fts, 2, :beforeMatch, :afterMatch, :ellipsis, :snippetLength) AS content,
|
||||
f.icon,
|
||||
highlight(article_fts, 0, :beforeMatch, :afterMatch) AS title_highlight,
|
||||
snippet(article_fts, 1, :beforeMatch, :afterMatch, :ellipsis, :snippetLength) AS summary_snippet,
|
||||
snippet(article_fts, 2, :beforeMatch, :afterMatch, :ellipsis, :snippetLength) AS content_snippet,
|
||||
(
|
||||
bm25(article_fts, weights.title_weight, weights.summary_weight,
|
||||
weights.content_weight)
|
||||
@@ -108,6 +122,8 @@ queryArticlesFullContent(:feed_id AS TEXT OR NULL) WITH FeedArticleQueryResult:
|
||||
FROM article_fts(:query) fts
|
||||
INNER JOIN
|
||||
article a ON a.rowid = fts.rowid
|
||||
INNER JOIN
|
||||
feed f ON f.url = a.feed_id
|
||||
CROSS JOIN weights
|
||||
WHERE
|
||||
:feed_id IS NULL OR a.feed_id = :feed_id
|
||||
|
||||
@@ -33,6 +33,24 @@ class Feed extends Table with TableInfo<Feed, FeedData> {
|
||||
requiredDuringInsert: false,
|
||||
$customConstraints: '',
|
||||
);
|
||||
late final GeneratedColumnWithTypeConverter<Uri?, String> icon =
|
||||
GeneratedColumn<String>(
|
||||
'icon',
|
||||
aliasedName,
|
||||
true,
|
||||
type: DriftSqlType.string,
|
||||
requiredDuringInsert: false,
|
||||
$customConstraints: '',
|
||||
).withConverter<Uri?>(Feed.$convertericonn);
|
||||
late final GeneratedColumnWithTypeConverter<Uri?, String> siteLink =
|
||||
GeneratedColumn<String>(
|
||||
'site_link',
|
||||
aliasedName,
|
||||
true,
|
||||
type: DriftSqlType.string,
|
||||
requiredDuringInsert: false,
|
||||
$customConstraints: '',
|
||||
).withConverter<Uri?>(Feed.$convertersiteLinkn);
|
||||
late final GeneratedColumnWithTypeConverter<List<FeedAuthor>?, String>
|
||||
authors = GeneratedColumn<String>(
|
||||
'authors',
|
||||
@@ -64,6 +82,8 @@ class Feed extends Table with TableInfo<Feed, FeedData> {
|
||||
url,
|
||||
title,
|
||||
description,
|
||||
icon,
|
||||
siteLink,
|
||||
authors,
|
||||
tags,
|
||||
lastFetched,
|
||||
@@ -93,6 +113,18 @@ class Feed extends Table with TableInfo<Feed, FeedData> {
|
||||
DriftSqlType.string,
|
||||
data['${effectivePrefix}description'],
|
||||
),
|
||||
icon: Feed.$convertericonn.fromSql(
|
||||
attachedDatabase.typeMapping.read(
|
||||
DriftSqlType.string,
|
||||
data['${effectivePrefix}icon'],
|
||||
),
|
||||
),
|
||||
siteLink: Feed.$convertersiteLinkn.fromSql(
|
||||
attachedDatabase.typeMapping.read(
|
||||
DriftSqlType.string,
|
||||
data['${effectivePrefix}site_link'],
|
||||
),
|
||||
),
|
||||
authors: Feed.$converterauthorsn.fromSql(
|
||||
attachedDatabase.typeMapping.read(
|
||||
DriftSqlType.string,
|
||||
@@ -118,6 +150,12 @@ class Feed extends Table with TableInfo<Feed, FeedData> {
|
||||
}
|
||||
|
||||
static TypeConverter<Uri, String> $converterurl = const UriConverter();
|
||||
static TypeConverter<Uri, String> $convertericon = const UriConverter();
|
||||
static TypeConverter<Uri?, String?> $convertericonn =
|
||||
NullAwareTypeConverter.wrap($convertericon);
|
||||
static TypeConverter<Uri, String> $convertersiteLink = const UriConverter();
|
||||
static TypeConverter<Uri?, String?> $convertersiteLinkn =
|
||||
NullAwareTypeConverter.wrap($convertersiteLink);
|
||||
static TypeConverter<List<FeedAuthor>, String> $converterauthors =
|
||||
const FeedAuthorsConverter();
|
||||
static TypeConverter<List<FeedAuthor>?, String?> $converterauthorsn =
|
||||
@@ -134,6 +172,8 @@ class FeedData extends DataClass implements Insertable<FeedData> {
|
||||
final Uri url;
|
||||
final String? title;
|
||||
final String? description;
|
||||
final Uri? icon;
|
||||
final Uri? siteLink;
|
||||
final List<FeedAuthor>? authors;
|
||||
final List<FeedCategory>? tags;
|
||||
final DateTime? lastFetched;
|
||||
@@ -141,6 +181,8 @@ class FeedData extends DataClass implements Insertable<FeedData> {
|
||||
required this.url,
|
||||
this.title,
|
||||
this.description,
|
||||
this.icon,
|
||||
this.siteLink,
|
||||
this.authors,
|
||||
this.tags,
|
||||
this.lastFetched,
|
||||
@@ -157,6 +199,14 @@ class FeedData extends DataClass implements Insertable<FeedData> {
|
||||
if (!nullToAbsent || description != null) {
|
||||
map['description'] = Variable<String>(description);
|
||||
}
|
||||
if (!nullToAbsent || icon != null) {
|
||||
map['icon'] = Variable<String>(Feed.$convertericonn.toSql(icon));
|
||||
}
|
||||
if (!nullToAbsent || siteLink != null) {
|
||||
map['site_link'] = Variable<String>(
|
||||
Feed.$convertersiteLinkn.toSql(siteLink),
|
||||
);
|
||||
}
|
||||
if (!nullToAbsent || authors != null) {
|
||||
map['authors'] = Variable<String>(Feed.$converterauthorsn.toSql(authors));
|
||||
}
|
||||
@@ -178,6 +228,8 @@ class FeedData extends DataClass implements Insertable<FeedData> {
|
||||
url: serializer.fromJson<Uri>(json['url']),
|
||||
title: serializer.fromJson<String?>(json['title']),
|
||||
description: serializer.fromJson<String?>(json['description']),
|
||||
icon: serializer.fromJson<Uri?>(json['icon']),
|
||||
siteLink: serializer.fromJson<Uri?>(json['site_link']),
|
||||
authors: serializer.fromJson<List<FeedAuthor>?>(json['authors']),
|
||||
tags: serializer.fromJson<List<FeedCategory>?>(json['tags']),
|
||||
lastFetched: serializer.fromJson<DateTime?>(json['last_fetched']),
|
||||
@@ -190,6 +242,8 @@ class FeedData extends DataClass implements Insertable<FeedData> {
|
||||
'url': serializer.toJson<Uri>(url),
|
||||
'title': serializer.toJson<String?>(title),
|
||||
'description': serializer.toJson<String?>(description),
|
||||
'icon': serializer.toJson<Uri?>(icon),
|
||||
'site_link': serializer.toJson<Uri?>(siteLink),
|
||||
'authors': serializer.toJson<List<FeedAuthor>?>(authors),
|
||||
'tags': serializer.toJson<List<FeedCategory>?>(tags),
|
||||
'last_fetched': serializer.toJson<DateTime?>(lastFetched),
|
||||
@@ -200,6 +254,8 @@ class FeedData extends DataClass implements Insertable<FeedData> {
|
||||
Uri? url,
|
||||
Value<String?> title = const Value.absent(),
|
||||
Value<String?> description = const Value.absent(),
|
||||
Value<Uri?> icon = const Value.absent(),
|
||||
Value<Uri?> siteLink = const Value.absent(),
|
||||
Value<List<FeedAuthor>?> authors = const Value.absent(),
|
||||
Value<List<FeedCategory>?> tags = const Value.absent(),
|
||||
Value<DateTime?> lastFetched = const Value.absent(),
|
||||
@@ -207,6 +263,8 @@ class FeedData extends DataClass implements Insertable<FeedData> {
|
||||
url: url ?? this.url,
|
||||
title: title.present ? title.value : this.title,
|
||||
description: description.present ? description.value : this.description,
|
||||
icon: icon.present ? icon.value : this.icon,
|
||||
siteLink: siteLink.present ? siteLink.value : this.siteLink,
|
||||
authors: authors.present ? authors.value : this.authors,
|
||||
tags: tags.present ? tags.value : this.tags,
|
||||
lastFetched: lastFetched.present ? lastFetched.value : this.lastFetched,
|
||||
@@ -217,6 +275,8 @@ class FeedData extends DataClass implements Insertable<FeedData> {
|
||||
title: data.title.present ? data.title.value : this.title,
|
||||
description:
|
||||
data.description.present ? data.description.value : this.description,
|
||||
icon: data.icon.present ? data.icon.value : this.icon,
|
||||
siteLink: data.siteLink.present ? data.siteLink.value : this.siteLink,
|
||||
authors: data.authors.present ? data.authors.value : this.authors,
|
||||
tags: data.tags.present ? data.tags.value : this.tags,
|
||||
lastFetched:
|
||||
@@ -230,6 +290,8 @@ class FeedData extends DataClass implements Insertable<FeedData> {
|
||||
..write('url: $url, ')
|
||||
..write('title: $title, ')
|
||||
..write('description: $description, ')
|
||||
..write('icon: $icon, ')
|
||||
..write('siteLink: $siteLink, ')
|
||||
..write('authors: $authors, ')
|
||||
..write('tags: $tags, ')
|
||||
..write('lastFetched: $lastFetched')
|
||||
@@ -238,8 +300,16 @@ class FeedData extends DataClass implements Insertable<FeedData> {
|
||||
}
|
||||
|
||||
@override
|
||||
int get hashCode =>
|
||||
Object.hash(url, title, description, authors, tags, lastFetched);
|
||||
int get hashCode => Object.hash(
|
||||
url,
|
||||
title,
|
||||
description,
|
||||
icon,
|
||||
siteLink,
|
||||
authors,
|
||||
tags,
|
||||
lastFetched,
|
||||
);
|
||||
@override
|
||||
bool operator ==(Object other) =>
|
||||
identical(this, other) ||
|
||||
@@ -247,6 +317,8 @@ class FeedData extends DataClass implements Insertable<FeedData> {
|
||||
other.url == this.url &&
|
||||
other.title == this.title &&
|
||||
other.description == this.description &&
|
||||
other.icon == this.icon &&
|
||||
other.siteLink == this.siteLink &&
|
||||
other.authors == this.authors &&
|
||||
other.tags == this.tags &&
|
||||
other.lastFetched == this.lastFetched);
|
||||
@@ -256,6 +328,8 @@ class FeedCompanion extends UpdateCompanion<FeedData> {
|
||||
final Value<Uri> url;
|
||||
final Value<String?> title;
|
||||
final Value<String?> description;
|
||||
final Value<Uri?> icon;
|
||||
final Value<Uri?> siteLink;
|
||||
final Value<List<FeedAuthor>?> authors;
|
||||
final Value<List<FeedCategory>?> tags;
|
||||
final Value<DateTime?> lastFetched;
|
||||
@@ -264,6 +338,8 @@ class FeedCompanion extends UpdateCompanion<FeedData> {
|
||||
this.url = const Value.absent(),
|
||||
this.title = const Value.absent(),
|
||||
this.description = const Value.absent(),
|
||||
this.icon = const Value.absent(),
|
||||
this.siteLink = const Value.absent(),
|
||||
this.authors = const Value.absent(),
|
||||
this.tags = const Value.absent(),
|
||||
this.lastFetched = const Value.absent(),
|
||||
@@ -273,6 +349,8 @@ class FeedCompanion extends UpdateCompanion<FeedData> {
|
||||
required Uri url,
|
||||
this.title = const Value.absent(),
|
||||
this.description = const Value.absent(),
|
||||
this.icon = const Value.absent(),
|
||||
this.siteLink = const Value.absent(),
|
||||
this.authors = const Value.absent(),
|
||||
this.tags = const Value.absent(),
|
||||
this.lastFetched = const Value.absent(),
|
||||
@@ -282,6 +360,8 @@ class FeedCompanion extends UpdateCompanion<FeedData> {
|
||||
Expression<String>? url,
|
||||
Expression<String>? title,
|
||||
Expression<String>? description,
|
||||
Expression<String>? icon,
|
||||
Expression<String>? siteLink,
|
||||
Expression<String>? authors,
|
||||
Expression<String>? tags,
|
||||
Expression<DateTime>? lastFetched,
|
||||
@@ -291,6 +371,8 @@ class FeedCompanion extends UpdateCompanion<FeedData> {
|
||||
if (url != null) 'url': url,
|
||||
if (title != null) 'title': title,
|
||||
if (description != null) 'description': description,
|
||||
if (icon != null) 'icon': icon,
|
||||
if (siteLink != null) 'site_link': siteLink,
|
||||
if (authors != null) 'authors': authors,
|
||||
if (tags != null) 'tags': tags,
|
||||
if (lastFetched != null) 'last_fetched': lastFetched,
|
||||
@@ -302,6 +384,8 @@ class FeedCompanion extends UpdateCompanion<FeedData> {
|
||||
Value<Uri>? url,
|
||||
Value<String?>? title,
|
||||
Value<String?>? description,
|
||||
Value<Uri?>? icon,
|
||||
Value<Uri?>? siteLink,
|
||||
Value<List<FeedAuthor>?>? authors,
|
||||
Value<List<FeedCategory>?>? tags,
|
||||
Value<DateTime?>? lastFetched,
|
||||
@@ -311,6 +395,8 @@ class FeedCompanion extends UpdateCompanion<FeedData> {
|
||||
url: url ?? this.url,
|
||||
title: title ?? this.title,
|
||||
description: description ?? this.description,
|
||||
icon: icon ?? this.icon,
|
||||
siteLink: siteLink ?? this.siteLink,
|
||||
authors: authors ?? this.authors,
|
||||
tags: tags ?? this.tags,
|
||||
lastFetched: lastFetched ?? this.lastFetched,
|
||||
@@ -330,6 +416,14 @@ class FeedCompanion extends UpdateCompanion<FeedData> {
|
||||
if (description.present) {
|
||||
map['description'] = Variable<String>(description.value);
|
||||
}
|
||||
if (icon.present) {
|
||||
map['icon'] = Variable<String>(Feed.$convertericonn.toSql(icon.value));
|
||||
}
|
||||
if (siteLink.present) {
|
||||
map['site_link'] = Variable<String>(
|
||||
Feed.$convertersiteLinkn.toSql(siteLink.value),
|
||||
);
|
||||
}
|
||||
if (authors.present) {
|
||||
map['authors'] = Variable<String>(
|
||||
Feed.$converterauthorsn.toSql(authors.value),
|
||||
@@ -353,6 +447,8 @@ class FeedCompanion extends UpdateCompanion<FeedData> {
|
||||
..write('url: $url, ')
|
||||
..write('title: $title, ')
|
||||
..write('description: $description, ')
|
||||
..write('icon: $icon, ')
|
||||
..write('siteLink: $siteLink, ')
|
||||
..write('authors: $authors, ')
|
||||
..write('tags: $tags, ')
|
||||
..write('lastFetched: $lastFetched, ')
|
||||
@@ -806,6 +902,226 @@ class ArticleCompanion extends UpdateCompanion<FeedArticle> {
|
||||
}
|
||||
}
|
||||
|
||||
class ArticleView extends ViewInfo<ArticleView, FeedArticle>
|
||||
implements HasResultSet {
|
||||
final String? _alias;
|
||||
@override
|
||||
final _$FeedDatabase attachedDatabase;
|
||||
ArticleView(this.attachedDatabase, [this._alias]);
|
||||
@override
|
||||
List<GeneratedColumn> get $columns => [
|
||||
id,
|
||||
feedId,
|
||||
fetched,
|
||||
created,
|
||||
updated,
|
||||
lastRead,
|
||||
title,
|
||||
authors,
|
||||
tags,
|
||||
links,
|
||||
summaryMarkdown,
|
||||
summaryPlain,
|
||||
contentMarkdown,
|
||||
contentPlain,
|
||||
icon,
|
||||
];
|
||||
@override
|
||||
String get aliasedName => _alias ?? entityName;
|
||||
@override
|
||||
String get entityName => 'article_view';
|
||||
@override
|
||||
Map<SqlDialect, String> get createViewStatements => {
|
||||
SqlDialect.sqlite:
|
||||
'CREATE VIEW article_view AS SELECT a.*, f.icon FROM article AS a INNER JOIN feed AS f ON f.url = a.feed_id',
|
||||
};
|
||||
@override
|
||||
ArticleView get asDslTable => this;
|
||||
@override
|
||||
FeedArticle map(Map<String, dynamic> data, {String? tablePrefix}) {
|
||||
final effectivePrefix = tablePrefix != null ? '$tablePrefix.' : '';
|
||||
return FeedArticle(
|
||||
id:
|
||||
attachedDatabase.typeMapping.read(
|
||||
DriftSqlType.string,
|
||||
data['${effectivePrefix}id'],
|
||||
)!,
|
||||
feedId: Article.$converterfeedId.fromSql(
|
||||
attachedDatabase.typeMapping.read(
|
||||
DriftSqlType.string,
|
||||
data['${effectivePrefix}feed_id'],
|
||||
)!,
|
||||
),
|
||||
fetched:
|
||||
attachedDatabase.typeMapping.read(
|
||||
DriftSqlType.dateTime,
|
||||
data['${effectivePrefix}fetched'],
|
||||
)!,
|
||||
created: attachedDatabase.typeMapping.read(
|
||||
DriftSqlType.dateTime,
|
||||
data['${effectivePrefix}created'],
|
||||
),
|
||||
updated: attachedDatabase.typeMapping.read(
|
||||
DriftSqlType.dateTime,
|
||||
data['${effectivePrefix}updated'],
|
||||
),
|
||||
lastRead: attachedDatabase.typeMapping.read(
|
||||
DriftSqlType.dateTime,
|
||||
data['${effectivePrefix}last_read'],
|
||||
),
|
||||
title: attachedDatabase.typeMapping.read(
|
||||
DriftSqlType.string,
|
||||
data['${effectivePrefix}title'],
|
||||
),
|
||||
authors: Article.$converterauthorsn.fromSql(
|
||||
attachedDatabase.typeMapping.read(
|
||||
DriftSqlType.string,
|
||||
data['${effectivePrefix}authors'],
|
||||
),
|
||||
),
|
||||
tags: Article.$convertertagsn.fromSql(
|
||||
attachedDatabase.typeMapping.read(
|
||||
DriftSqlType.string,
|
||||
data['${effectivePrefix}tags'],
|
||||
),
|
||||
),
|
||||
links: Article.$converterlinksn.fromSql(
|
||||
attachedDatabase.typeMapping.read(
|
||||
DriftSqlType.string,
|
||||
data['${effectivePrefix}links'],
|
||||
),
|
||||
),
|
||||
summaryMarkdown: attachedDatabase.typeMapping.read(
|
||||
DriftSqlType.string,
|
||||
data['${effectivePrefix}summaryMarkdown'],
|
||||
),
|
||||
summaryPlain: attachedDatabase.typeMapping.read(
|
||||
DriftSqlType.string,
|
||||
data['${effectivePrefix}summaryPlain'],
|
||||
),
|
||||
contentMarkdown: attachedDatabase.typeMapping.read(
|
||||
DriftSqlType.string,
|
||||
data['${effectivePrefix}contentMarkdown'],
|
||||
),
|
||||
contentPlain: attachedDatabase.typeMapping.read(
|
||||
DriftSqlType.string,
|
||||
data['${effectivePrefix}contentPlain'],
|
||||
),
|
||||
icon: Feed.$convertericonn.fromSql(
|
||||
attachedDatabase.typeMapping.read(
|
||||
DriftSqlType.string,
|
||||
data['${effectivePrefix}icon'],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
late final GeneratedColumn<String> id = GeneratedColumn<String>(
|
||||
'id',
|
||||
aliasedName,
|
||||
false,
|
||||
type: DriftSqlType.string,
|
||||
);
|
||||
late final GeneratedColumnWithTypeConverter<Uri, String> feedId =
|
||||
GeneratedColumn<String>(
|
||||
'feed_id',
|
||||
aliasedName,
|
||||
false,
|
||||
type: DriftSqlType.string,
|
||||
).withConverter<Uri>(Article.$converterfeedId);
|
||||
late final GeneratedColumn<DateTime> fetched = GeneratedColumn<DateTime>(
|
||||
'fetched',
|
||||
aliasedName,
|
||||
false,
|
||||
type: DriftSqlType.dateTime,
|
||||
);
|
||||
late final GeneratedColumn<DateTime> created = GeneratedColumn<DateTime>(
|
||||
'created',
|
||||
aliasedName,
|
||||
true,
|
||||
type: DriftSqlType.dateTime,
|
||||
);
|
||||
late final GeneratedColumn<DateTime> updated = GeneratedColumn<DateTime>(
|
||||
'updated',
|
||||
aliasedName,
|
||||
true,
|
||||
type: DriftSqlType.dateTime,
|
||||
);
|
||||
late final GeneratedColumn<DateTime> lastRead = GeneratedColumn<DateTime>(
|
||||
'last_read',
|
||||
aliasedName,
|
||||
true,
|
||||
type: DriftSqlType.dateTime,
|
||||
);
|
||||
late final GeneratedColumn<String> title = GeneratedColumn<String>(
|
||||
'title',
|
||||
aliasedName,
|
||||
true,
|
||||
type: DriftSqlType.string,
|
||||
);
|
||||
late final GeneratedColumnWithTypeConverter<List<FeedAuthor>?, String>
|
||||
authors = GeneratedColumn<String>(
|
||||
'authors',
|
||||
aliasedName,
|
||||
true,
|
||||
type: DriftSqlType.string,
|
||||
).withConverter<List<FeedAuthor>?>(Article.$converterauthorsn);
|
||||
late final GeneratedColumnWithTypeConverter<List<FeedCategory>?, String>
|
||||
tags = GeneratedColumn<String>(
|
||||
'tags',
|
||||
aliasedName,
|
||||
true,
|
||||
type: DriftSqlType.string,
|
||||
).withConverter<List<FeedCategory>?>(Article.$convertertagsn);
|
||||
late final GeneratedColumnWithTypeConverter<List<FeedLink>?, String> links =
|
||||
GeneratedColumn<String>(
|
||||
'links',
|
||||
aliasedName,
|
||||
true,
|
||||
type: DriftSqlType.string,
|
||||
).withConverter<List<FeedLink>?>(Article.$converterlinksn);
|
||||
late final GeneratedColumn<String> summaryMarkdown = GeneratedColumn<String>(
|
||||
'summaryMarkdown',
|
||||
aliasedName,
|
||||
true,
|
||||
type: DriftSqlType.string,
|
||||
);
|
||||
late final GeneratedColumn<String> summaryPlain = GeneratedColumn<String>(
|
||||
'summaryPlain',
|
||||
aliasedName,
|
||||
true,
|
||||
type: DriftSqlType.string,
|
||||
);
|
||||
late final GeneratedColumn<String> contentMarkdown = GeneratedColumn<String>(
|
||||
'contentMarkdown',
|
||||
aliasedName,
|
||||
true,
|
||||
type: DriftSqlType.string,
|
||||
);
|
||||
late final GeneratedColumn<String> contentPlain = GeneratedColumn<String>(
|
||||
'contentPlain',
|
||||
aliasedName,
|
||||
true,
|
||||
type: DriftSqlType.string,
|
||||
);
|
||||
late final GeneratedColumnWithTypeConverter<Uri?, String> icon =
|
||||
GeneratedColumn<String>(
|
||||
'icon',
|
||||
aliasedName,
|
||||
true,
|
||||
type: DriftSqlType.string,
|
||||
).withConverter<Uri?>(Feed.$convertericonn);
|
||||
@override
|
||||
ArticleView createAlias(String alias) {
|
||||
return ArticleView(attachedDatabase, alias);
|
||||
}
|
||||
|
||||
@override
|
||||
Query? get query => null;
|
||||
@override
|
||||
Set<String> get readTables => const {'article', 'feed'};
|
||||
}
|
||||
|
||||
class ArticleFts extends Table
|
||||
with
|
||||
TableInfo<ArticleFts, ArticleFt>,
|
||||
@@ -1046,6 +1362,7 @@ abstract class _$FeedDatabase extends GeneratedDatabase {
|
||||
$FeedDatabaseManager get managers => $FeedDatabaseManager(this);
|
||||
late final Feed feed = Feed(this);
|
||||
late final Article article = Article(this);
|
||||
late final ArticleView articleView = ArticleView(this);
|
||||
late final Index articleFeedId = Index(
|
||||
'article_feed_id',
|
||||
'CREATE INDEX article_feed_id ON article (feed_id)',
|
||||
@@ -1074,20 +1391,13 @@ abstract class _$FeedDatabase extends GeneratedDatabase {
|
||||
}
|
||||
|
||||
Selectable<FeedArticleQueryResult> queryArticlesBasic({
|
||||
required String beforeMatch,
|
||||
required String afterMatch,
|
||||
required String query,
|
||||
String? feedId,
|
||||
}) {
|
||||
return customSelect(
|
||||
'WITH weights AS (SELECT 1.0 AS title_weight) SELECT a.*, highlight(article_fts, 0, ?1, ?2) AS title,(bm25(article_fts, weights.title_weight))AS weighted_rank FROM article_fts(?3)AS fts INNER JOIN article AS a ON a."rowid" = fts."rowid" CROSS JOIN weights WHERE fts.title LIKE ?3 AND ?4 IS NULL OR a.feed_id = ?4 ORDER BY weighted_rank ASC, a.created DESC NULLS LAST',
|
||||
variables: [
|
||||
Variable<String>(beforeMatch),
|
||||
Variable<String>(afterMatch),
|
||||
Variable<String>(query),
|
||||
Variable<String>(feedId),
|
||||
],
|
||||
readsFrom: {articleFts, article},
|
||||
'WITH weights AS (SELECT 1.0 AS title_weight) SELECT a.*, f.icon,(bm25(article_fts, weights.title_weight))AS weighted_rank FROM article_fts AS fts INNER JOIN article AS a ON a."rowid" = fts."rowid" INNER JOIN feed AS f ON f.url = a.feed_id CROSS JOIN weights WHERE fts.title LIKE ?1 AND(?2 IS NULL OR a.feed_id = ?2)ORDER BY weighted_rank ASC, a.created DESC NULLS LAST',
|
||||
variables: [Variable<String>(query), Variable<String>(feedId)],
|
||||
readsFrom: {feed, articleFts, article},
|
||||
).map(
|
||||
(QueryRow row) => FeedArticleQueryResult(
|
||||
id: row.read<String>('id'),
|
||||
@@ -1114,6 +1424,10 @@ abstract class _$FeedDatabase extends GeneratedDatabase {
|
||||
summaryPlain: row.readNullable<String>('summaryPlain'),
|
||||
contentMarkdown: row.readNullable<String>('contentMarkdown'),
|
||||
contentPlain: row.readNullable<String>('contentPlain'),
|
||||
icon: NullAwareTypeConverter.wrapFromSql(
|
||||
Feed.$convertericon,
|
||||
row.readNullable<String>('icon'),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
@@ -1127,7 +1441,7 @@ abstract class _$FeedDatabase extends GeneratedDatabase {
|
||||
String? feedId,
|
||||
}) {
|
||||
return customSelect(
|
||||
'WITH weights AS (SELECT 5.0 AS title_weight, 2.0 AS summary_weight, 1.0 AS content_weight) SELECT a.*, highlight(article_fts, 0, ?1, ?2) AS title, snippet(article_fts, 1, ?1, ?2, ?3, ?4) AS summary, snippet(article_fts, 2, ?1, ?2, ?3, ?4) AS content,(bm25(article_fts, weights.title_weight, weights.summary_weight, weights.content_weight))AS weighted_rank FROM article_fts(?5)AS fts INNER JOIN article AS a ON a."rowid" = fts."rowid" CROSS JOIN weights WHERE ?6 IS NULL OR a.feed_id = ?6 ORDER BY weighted_rank ASC, a.created DESC NULLS LAST',
|
||||
'WITH weights AS (SELECT 10.0 AS title_weight, 3.0 AS summary_weight, 1.0 AS content_weight) SELECT a.*, f.icon, highlight(article_fts, 0, ?1, ?2) AS title_highlight, snippet(article_fts, 1, ?1, ?2, ?3, ?4) AS summary_snippet, snippet(article_fts, 2, ?1, ?2, ?3, ?4) AS content_snippet,(bm25(article_fts, weights.title_weight, weights.summary_weight, weights.content_weight))AS weighted_rank FROM article_fts(?5)AS fts INNER JOIN article AS a ON a."rowid" = fts."rowid" INNER JOIN feed AS f ON f.url = a.feed_id CROSS JOIN weights WHERE ?6 IS NULL OR a.feed_id = ?6 ORDER BY weighted_rank ASC, a.created DESC NULLS LAST',
|
||||
variables: [
|
||||
Variable<String>(beforeMatch),
|
||||
Variable<String>(afterMatch),
|
||||
@@ -1136,7 +1450,7 @@ abstract class _$FeedDatabase extends GeneratedDatabase {
|
||||
Variable<String>(query),
|
||||
Variable<String>(feedId),
|
||||
],
|
||||
readsFrom: {articleFts, article},
|
||||
readsFrom: {feed, articleFts, article},
|
||||
).map(
|
||||
(QueryRow row) => FeedArticleQueryResult(
|
||||
id: row.read<String>('id'),
|
||||
@@ -1163,6 +1477,13 @@ abstract class _$FeedDatabase extends GeneratedDatabase {
|
||||
summaryPlain: row.readNullable<String>('summaryPlain'),
|
||||
contentMarkdown: row.readNullable<String>('contentMarkdown'),
|
||||
contentPlain: row.readNullable<String>('contentPlain'),
|
||||
icon: NullAwareTypeConverter.wrapFromSql(
|
||||
Feed.$convertericon,
|
||||
row.readNullable<String>('icon'),
|
||||
),
|
||||
titleHighlight: row.readNullable<String>('title_highlight'),
|
||||
summarySnippet: row.readNullable<String>('summary_snippet'),
|
||||
contentSnippet: row.readNullable<String>('content_snippet'),
|
||||
),
|
||||
);
|
||||
}
|
||||
@@ -1174,6 +1495,7 @@ abstract class _$FeedDatabase extends GeneratedDatabase {
|
||||
List<DatabaseSchemaEntity> get allSchemaEntities => [
|
||||
feed,
|
||||
article,
|
||||
articleView,
|
||||
articleFeedId,
|
||||
articleFts,
|
||||
articleAfterInsert,
|
||||
@@ -1218,6 +1540,8 @@ typedef $FeedCreateCompanionBuilder =
|
||||
required Uri url,
|
||||
Value<String?> title,
|
||||
Value<String?> description,
|
||||
Value<Uri?> icon,
|
||||
Value<Uri?> siteLink,
|
||||
Value<List<FeedAuthor>?> authors,
|
||||
Value<List<FeedCategory>?> tags,
|
||||
Value<DateTime?> lastFetched,
|
||||
@@ -1228,6 +1552,8 @@ typedef $FeedUpdateCompanionBuilder =
|
||||
Value<Uri> url,
|
||||
Value<String?> title,
|
||||
Value<String?> description,
|
||||
Value<Uri?> icon,
|
||||
Value<Uri?> siteLink,
|
||||
Value<List<FeedAuthor>?> authors,
|
||||
Value<List<FeedCategory>?> tags,
|
||||
Value<DateTime?> lastFetched,
|
||||
@@ -1282,6 +1608,18 @@ class $FeedFilterComposer extends Composer<_$FeedDatabase, Feed> {
|
||||
builder: (column) => ColumnFilters(column),
|
||||
);
|
||||
|
||||
ColumnWithTypeConverterFilters<Uri?, Uri, String> get icon =>
|
||||
$composableBuilder(
|
||||
column: $table.icon,
|
||||
builder: (column) => ColumnWithTypeConverterFilters(column),
|
||||
);
|
||||
|
||||
ColumnWithTypeConverterFilters<Uri?, Uri, String> get siteLink =>
|
||||
$composableBuilder(
|
||||
column: $table.siteLink,
|
||||
builder: (column) => ColumnWithTypeConverterFilters(column),
|
||||
);
|
||||
|
||||
ColumnWithTypeConverterFilters<List<FeedAuthor>?, List<FeedAuthor>, String>
|
||||
get authors => $composableBuilder(
|
||||
column: $table.authors,
|
||||
@@ -1352,6 +1690,16 @@ class $FeedOrderingComposer extends Composer<_$FeedDatabase, Feed> {
|
||||
builder: (column) => ColumnOrderings(column),
|
||||
);
|
||||
|
||||
ColumnOrderings<String> get icon => $composableBuilder(
|
||||
column: $table.icon,
|
||||
builder: (column) => ColumnOrderings(column),
|
||||
);
|
||||
|
||||
ColumnOrderings<String> get siteLink => $composableBuilder(
|
||||
column: $table.siteLink,
|
||||
builder: (column) => ColumnOrderings(column),
|
||||
);
|
||||
|
||||
ColumnOrderings<String> get authors => $composableBuilder(
|
||||
column: $table.authors,
|
||||
builder: (column) => ColumnOrderings(column),
|
||||
@@ -1387,6 +1735,12 @@ class $FeedAnnotationComposer extends Composer<_$FeedDatabase, Feed> {
|
||||
builder: (column) => column,
|
||||
);
|
||||
|
||||
GeneratedColumnWithTypeConverter<Uri?, String> get icon =>
|
||||
$composableBuilder(column: $table.icon, builder: (column) => column);
|
||||
|
||||
GeneratedColumnWithTypeConverter<Uri?, String> get siteLink =>
|
||||
$composableBuilder(column: $table.siteLink, builder: (column) => column);
|
||||
|
||||
GeneratedColumnWithTypeConverter<List<FeedAuthor>?, String> get authors =>
|
||||
$composableBuilder(column: $table.authors, builder: (column) => column);
|
||||
|
||||
@@ -1455,6 +1809,8 @@ class $FeedTableManager
|
||||
Value<Uri> url = const Value.absent(),
|
||||
Value<String?> title = const Value.absent(),
|
||||
Value<String?> description = const Value.absent(),
|
||||
Value<Uri?> icon = const Value.absent(),
|
||||
Value<Uri?> siteLink = const Value.absent(),
|
||||
Value<List<FeedAuthor>?> authors = const Value.absent(),
|
||||
Value<List<FeedCategory>?> tags = const Value.absent(),
|
||||
Value<DateTime?> lastFetched = const Value.absent(),
|
||||
@@ -1463,6 +1819,8 @@ class $FeedTableManager
|
||||
url: url,
|
||||
title: title,
|
||||
description: description,
|
||||
icon: icon,
|
||||
siteLink: siteLink,
|
||||
authors: authors,
|
||||
tags: tags,
|
||||
lastFetched: lastFetched,
|
||||
@@ -1473,6 +1831,8 @@ class $FeedTableManager
|
||||
required Uri url,
|
||||
Value<String?> title = const Value.absent(),
|
||||
Value<String?> description = const Value.absent(),
|
||||
Value<Uri?> icon = const Value.absent(),
|
||||
Value<Uri?> siteLink = const Value.absent(),
|
||||
Value<List<FeedAuthor>?> authors = const Value.absent(),
|
||||
Value<List<FeedCategory>?> tags = const Value.absent(),
|
||||
Value<DateTime?> lastFetched = const Value.absent(),
|
||||
@@ -1481,6 +1841,8 @@ class $FeedTableManager
|
||||
url: url,
|
||||
title: title,
|
||||
description: description,
|
||||
icon: icon,
|
||||
siteLink: siteLink,
|
||||
authors: authors,
|
||||
tags: tags,
|
||||
lastFetched: lastFetched,
|
||||
|
||||
@@ -25,6 +25,9 @@ class FeedArticle with FastEquatable implements Insertable<FeedArticle> {
|
||||
final String? contentMarkdown;
|
||||
final String? contentPlain;
|
||||
|
||||
//Derived by view from feed table, should not get inserted
|
||||
final Uri? icon;
|
||||
|
||||
FeedArticle({
|
||||
required this.id,
|
||||
required this.feedId,
|
||||
@@ -40,6 +43,7 @@ class FeedArticle with FastEquatable implements Insertable<FeedArticle> {
|
||||
this.summaryPlain,
|
||||
this.contentMarkdown,
|
||||
this.contentPlain,
|
||||
this.icon,
|
||||
});
|
||||
|
||||
factory FeedArticle.fromJson(Map<String, dynamic> json) =>
|
||||
@@ -109,5 +113,6 @@ class FeedArticle with FastEquatable implements Insertable<FeedArticle> {
|
||||
summaryPlain,
|
||||
contentMarkdown,
|
||||
contentPlain,
|
||||
icon,
|
||||
];
|
||||
}
|
||||
|
||||
@@ -39,6 +39,7 @@ FeedArticle _$FeedArticleFromJson(Map<String, dynamic> json) => FeedArticle(
|
||||
summaryPlain: json['summaryPlain'] as String?,
|
||||
contentMarkdown: json['contentMarkdown'] as String?,
|
||||
contentPlain: json['contentPlain'] as String?,
|
||||
icon: json['icon'] == null ? null : Uri.parse(json['icon'] as String),
|
||||
);
|
||||
|
||||
Map<String, dynamic> _$FeedArticleToJson(FeedArticle instance) =>
|
||||
@@ -57,4 +58,5 @@ Map<String, dynamic> _$FeedArticleToJson(FeedArticle instance) =>
|
||||
'summaryPlain': instance.summaryPlain,
|
||||
'contentMarkdown': instance.contentMarkdown,
|
||||
'contentPlain': instance.contentPlain,
|
||||
'icon': instance.icon?.toString(),
|
||||
};
|
||||
|
||||
@@ -1,6 +1,10 @@
|
||||
import 'package:lensai/features/web_feed/data/models/feed_article.dart';
|
||||
|
||||
class FeedArticleQueryResult extends FeedArticle {
|
||||
final String? titleHighlight;
|
||||
final String? summarySnippet;
|
||||
final String? contentSnippet;
|
||||
|
||||
final double weightedRank;
|
||||
|
||||
FeedArticleQueryResult({
|
||||
@@ -8,19 +12,29 @@ class FeedArticleQueryResult extends FeedArticle {
|
||||
required super.feedId,
|
||||
required super.fetched,
|
||||
required this.weightedRank,
|
||||
super.created,
|
||||
super.updated,
|
||||
super.lastRead,
|
||||
super.title,
|
||||
super.authors,
|
||||
super.tags,
|
||||
super.links,
|
||||
super.summaryMarkdown,
|
||||
super.summaryPlain,
|
||||
super.contentMarkdown,
|
||||
super.contentPlain,
|
||||
required super.created,
|
||||
required super.updated,
|
||||
required super.lastRead,
|
||||
required super.title,
|
||||
required super.authors,
|
||||
required super.tags,
|
||||
required super.links,
|
||||
required super.summaryMarkdown,
|
||||
required super.summaryPlain,
|
||||
required super.contentMarkdown,
|
||||
required super.contentPlain,
|
||||
required super.icon,
|
||||
this.titleHighlight,
|
||||
this.summarySnippet,
|
||||
this.contentSnippet,
|
||||
});
|
||||
|
||||
@override
|
||||
List<Object?> get hashParameters => [...super.hashParameters, weightedRank];
|
||||
List<Object?> get hashParameters => [
|
||||
...super.hashParameters,
|
||||
weightedRank,
|
||||
summarySnippet,
|
||||
contentSnippet,
|
||||
titleHighlight,
|
||||
];
|
||||
}
|
||||
|
||||
@@ -1,16 +0,0 @@
|
||||
import 'package:copy_with_extension/copy_with_extension.dart';
|
||||
import 'package:fast_equatable/fast_equatable.dart';
|
||||
|
||||
part 'feed_filter.g.dart';
|
||||
|
||||
@CopyWith()
|
||||
class FeedFilter with FastEquatable {
|
||||
final Uri? feedId;
|
||||
final String? query;
|
||||
final Set<String>? tags;
|
||||
|
||||
FeedFilter({this.feedId, this.query, this.tags});
|
||||
|
||||
@override
|
||||
List<Object?> get hashParameters => [feedId, query, tags];
|
||||
}
|
||||
@@ -1,76 +0,0 @@
|
||||
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||
|
||||
part of 'feed_filter.dart';
|
||||
|
||||
// **************************************************************************
|
||||
// CopyWithGenerator
|
||||
// **************************************************************************
|
||||
|
||||
abstract class _$FeedFilterCWProxy {
|
||||
FeedFilter feedId(Uri? feedId);
|
||||
|
||||
FeedFilter query(String? query);
|
||||
|
||||
FeedFilter tags(Set<String>? tags);
|
||||
|
||||
/// This function **does support** nullification of nullable fields. All `null` values passed to `non-nullable` fields will be ignored. You can also use `FeedFilter(...).copyWith.fieldName(...)` to override fields one at a time with nullification support.
|
||||
///
|
||||
/// Usage
|
||||
/// ```dart
|
||||
/// FeedFilter(...).copyWith(id: 12, name: "My name")
|
||||
/// ````
|
||||
FeedFilter call({Uri? feedId, String? query, Set<String>? tags});
|
||||
}
|
||||
|
||||
/// Proxy class for `copyWith` functionality. This is a callable class and can be used as follows: `instanceOfFeedFilter.copyWith(...)`. Additionally contains functions for specific fields e.g. `instanceOfFeedFilter.copyWith.fieldName(...)`
|
||||
class _$FeedFilterCWProxyImpl implements _$FeedFilterCWProxy {
|
||||
const _$FeedFilterCWProxyImpl(this._value);
|
||||
|
||||
final FeedFilter _value;
|
||||
|
||||
@override
|
||||
FeedFilter feedId(Uri? feedId) => this(feedId: feedId);
|
||||
|
||||
@override
|
||||
FeedFilter query(String? query) => this(query: query);
|
||||
|
||||
@override
|
||||
FeedFilter tags(Set<String>? tags) => this(tags: tags);
|
||||
|
||||
@override
|
||||
/// This function **does support** nullification of nullable fields. All `null` values passed to `non-nullable` fields will be ignored. You can also use `FeedFilter(...).copyWith.fieldName(...)` to override fields one at a time with nullification support.
|
||||
///
|
||||
/// Usage
|
||||
/// ```dart
|
||||
/// FeedFilter(...).copyWith(id: 12, name: "My name")
|
||||
/// ````
|
||||
FeedFilter call({
|
||||
Object? feedId = const $CopyWithPlaceholder(),
|
||||
Object? query = const $CopyWithPlaceholder(),
|
||||
Object? tags = const $CopyWithPlaceholder(),
|
||||
}) {
|
||||
return FeedFilter(
|
||||
feedId:
|
||||
feedId == const $CopyWithPlaceholder()
|
||||
? _value.feedId
|
||||
// ignore: cast_nullable_to_non_nullable
|
||||
: feedId as Uri?,
|
||||
query:
|
||||
query == const $CopyWithPlaceholder()
|
||||
? _value.query
|
||||
// ignore: cast_nullable_to_non_nullable
|
||||
: query as String?,
|
||||
tags:
|
||||
tags == const $CopyWithPlaceholder()
|
||||
? _value.tags
|
||||
// ignore: cast_nullable_to_non_nullable
|
||||
: tags as Set<String>?,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
extension $FeedFilterCopyWith on FeedFilter {
|
||||
/// Returns a callable class that can be used as follows: `instanceOfFeedFilter.copyWith(...)` or like so:`instanceOfFeedFilter.copyWith.fieldName(...)`.
|
||||
// ignore: library_private_types_in_public_api
|
||||
_$FeedFilterCWProxy get copyWith => _$FeedFilterCWProxyImpl(this);
|
||||
}
|
||||
Reference in New Issue
Block a user