2026-10-11 13:20:00 +03:00
|
|
|
import '../../database/database.dart';
|
|
|
|
|
import '../../l10n/strings.dart';
|
|
|
|
|
import '../../mews/document.dart';
|
|
|
|
|
import 'mews_urls.dart';
|
|
|
|
|
import 'page_blocks.dart';
|
|
|
|
|
|
|
|
|
|
/// Every post from every subscribed site in one list (spec 6.1), newest first
|
|
|
|
|
/// unless the reader orders it otherwise. Unread posts stand out, and opening
|
|
|
|
|
/// one marks it read.
|
|
|
|
|
Future<MewsPage> buildPostsPage(
|
|
|
|
|
Uri url, {
|
|
|
|
|
required MewsDatabase db,
|
|
|
|
|
required Strings strings,
|
|
|
|
|
required bool refreshing,
|
|
|
|
|
}) async {
|
|
|
|
|
final sort = EntrySort.parse(url.queryParameters['sort']);
|
|
|
|
|
final unreadOnly = url.queryParameters['show'] == 'unread';
|
|
|
|
|
final entries =
|
|
|
|
|
await db.riverEntries(sort: sort, unreadOnly: unreadOnly);
|
|
|
|
|
final unread = await db.unreadCount();
|
|
|
|
|
final title = strings.t('posts-title');
|
|
|
|
|
|
|
|
|
|
return internalPage(
|
|
|
|
|
url: url,
|
|
|
|
|
title: title,
|
2026-10-11 14:54:43 +03:00
|
|
|
strings: strings,
|
2026-10-11 13:20:00 +03:00
|
|
|
body: [
|
|
|
|
|
...chrome(title: title, current: url, strings: strings),
|
|
|
|
|
ParagraphBlock([
|
|
|
|
|
MewsEmphasis(EmphasisStyle.emphasis, [
|
|
|
|
|
MewsText(countText(strings, unread,
|
|
|
|
|
none: 'count-unread-none',
|
|
|
|
|
one: 'count-unread-one',
|
|
|
|
|
many: 'count-unread-many')),
|
|
|
|
|
]),
|
|
|
|
|
const MewsText(actionSeparator),
|
|
|
|
|
if (refreshing)
|
|
|
|
|
MewsEmphasis(EmphasisStyle.emphasis,
|
|
|
|
|
[MewsText(strings.t('posts-checking'))])
|
|
|
|
|
else
|
|
|
|
|
MewsLink(MewsUrls.action('refresh-subscriptions'),
|
|
|
|
|
[MewsText(strings.t('action-refresh'))]),
|
|
|
|
|
]),
|
|
|
|
|
...choiceLine(
|
|
|
|
|
label: strings.t('posts-sort-label'),
|
|
|
|
|
options: [
|
|
|
|
|
for (final option in const [
|
|
|
|
|
(EntrySort.date, 'posts-sort-date'),
|
|
|
|
|
(EntrySort.source, 'posts-sort-source'),
|
|
|
|
|
(EntrySort.unread, 'posts-sort-unread'),
|
|
|
|
|
])
|
|
|
|
|
(
|
|
|
|
|
href: MewsUrls.page(url, {'sort': option.$1.name}),
|
|
|
|
|
label: strings.t(option.$2),
|
|
|
|
|
current: option.$1 == sort,
|
|
|
|
|
),
|
|
|
|
|
],
|
|
|
|
|
),
|
|
|
|
|
...choiceLine(
|
|
|
|
|
label: strings.t('posts-show-label'),
|
|
|
|
|
options: [
|
|
|
|
|
(
|
|
|
|
|
href: MewsUrls.page(url, {'show': null}),
|
|
|
|
|
label: strings.t('posts-show-all'),
|
|
|
|
|
current: !unreadOnly,
|
|
|
|
|
),
|
|
|
|
|
(
|
|
|
|
|
href: MewsUrls.page(url, {'show': 'unread'}),
|
|
|
|
|
label: strings.t('posts-show-unread'),
|
|
|
|
|
current: unreadOnly,
|
|
|
|
|
),
|
|
|
|
|
],
|
|
|
|
|
),
|
|
|
|
|
const RuleBlock(),
|
|
|
|
|
if (entries.isEmpty)
|
|
|
|
|
ParagraphBlock([
|
|
|
|
|
MewsText(strings
|
|
|
|
|
.t(unreadOnly ? 'posts-none-unread' : 'posts-empty')),
|
|
|
|
|
])
|
|
|
|
|
else
|
|
|
|
|
itemList([
|
|
|
|
|
for (final entry in entries)
|
|
|
|
|
itemRow(
|
|
|
|
|
href: entry.url,
|
|
|
|
|
label: entry.title,
|
|
|
|
|
date: dayText(entry.date),
|
|
|
|
|
note: entry.siteName,
|
|
|
|
|
strong: entry.unread,
|
|
|
|
|
actions: [
|
|
|
|
|
if (entry.unread)
|
|
|
|
|
action(
|
|
|
|
|
MewsUrls.action('mark-read',
|
|
|
|
|
{'site': entry.siteUrl, 'url': entry.url}),
|
|
|
|
|
strings.t('posts-mark-read'))
|
|
|
|
|
else
|
|
|
|
|
action(
|
|
|
|
|
MewsUrls.action('mark-unread',
|
|
|
|
|
{'site': entry.siteUrl, 'url': entry.url}),
|
|
|
|
|
strings.t('posts-mark-unread')),
|
|
|
|
|
],
|
|
|
|
|
),
|
|
|
|
|
]),
|
|
|
|
|
],
|
|
|
|
|
);
|
|
|
|
|
}
|