fix(explore): the summary in blocks: what it is, what it holds, its release
The summary sheet ran its parts together, each aligned its own way. Now it groups them in cards, as the Profile tab does its parts: what the studyset is (its colour along the top, its secondary title, author and description), what it holds (languages, contents, learners), and its latest release with its notes and Reports and suggestions; its credits centred beneath them, as at the foot of a studyset. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Signed-off-by: Tizian 「ティツィアーン」 <raisondetredev@pm.me>
This commit is contained in:
parent
11b0935728
commit
500ce1a25b
6 changed files with 106 additions and 59 deletions
|
|
@ -1623,6 +1623,7 @@
|
|||
"exploreNothingMatches": "Nichts Veröffentlichtes passt dazu.",
|
||||
"exploreBy": "von {author}",
|
||||
"exploreRelease": "v{version} · {date}",
|
||||
"exploreHolds": "Inhalt",
|
||||
"exploreLatestRelease": "Neueste Veröffentlichung: v{version} · {date}",
|
||||
"exploreAddToLibrary": "Zur Bibliothek hinzufügen",
|
||||
"exploreAdd": "Hinzufügen",
|
||||
|
|
|
|||
|
|
@ -1904,6 +1904,7 @@
|
|||
"@exploreBy": {"placeholders": {"author": {"type": "String"}}},
|
||||
"exploreRelease": "v{version} · {date}",
|
||||
"@exploreRelease": {"placeholders": {"version": {"type": "int"}, "date": {"type": "String"}}},
|
||||
"exploreHolds": "What it holds",
|
||||
"exploreLatestRelease": "Latest release: v{version} · {date}",
|
||||
"@exploreLatestRelease": {"placeholders": {"version": {"type": "int"}, "date": {"type": "String"}}},
|
||||
"exploreAddToLibrary": "Add to library",
|
||||
|
|
|
|||
|
|
@ -9603,6 +9603,12 @@ abstract class AppLocalizations {
|
|||
/// **'v{version} · {date}'**
|
||||
String exploreRelease(int version, String date);
|
||||
|
||||
/// No description provided for @exploreHolds.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'What it holds'**
|
||||
String get exploreHolds;
|
||||
|
||||
/// No description provided for @exploreLatestRelease.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
|
|
|
|||
|
|
@ -6044,6 +6044,9 @@ class AppLocalizationsDe extends AppLocalizations {
|
|||
return 'v$version · $date';
|
||||
}
|
||||
|
||||
@override
|
||||
String get exploreHolds => 'Inhalt';
|
||||
|
||||
@override
|
||||
String exploreLatestRelease(int version, String date) {
|
||||
return 'Neueste Veröffentlichung: v$version · $date';
|
||||
|
|
|
|||
|
|
@ -5991,6 +5991,9 @@ class AppLocalizationsEn extends AppLocalizations {
|
|||
return 'v$version · $date';
|
||||
}
|
||||
|
||||
@override
|
||||
String get exploreHolds => 'What it holds';
|
||||
|
||||
@override
|
||||
String exploreLatestRelease(int version, String date) {
|
||||
return 'Latest release: v$version · $date';
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ import 'package:halkyon_learn_flutter/l10n/app_localizations.dart';
|
|||
import 'package:halkyon_learn_flutter/src/core/editor/rich_content_view.dart';
|
||||
import 'package:halkyon_learn_flutter/src/core/l10n/content_languages.dart';
|
||||
import 'package:halkyon_learn_flutter/src/core/widget/adaptive_sheet.dart';
|
||||
import 'package:halkyon_learn_flutter/src/core/widget/section_card.dart';
|
||||
import 'package:halkyon_learn_flutter/src/feature/explore/bloc/explore_bloc.dart';
|
||||
import 'package:halkyon_learn_flutter/src/feature/explore/model/explore_studyset.dart';
|
||||
import 'package:halkyon_learn_flutter/src/feature/explore/widget/explore_screen.dart';
|
||||
|
|
@ -51,74 +52,106 @@ class const _Summary({required final ExploreStudyset studyset})
|
|||
body: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.stretch,
|
||||
children: [
|
||||
// Its colour, as along the top of its card.
|
||||
Container(
|
||||
height: 4,
|
||||
margin: const EdgeInsets.only(bottom: 12),
|
||||
decoration: BoxDecoration(
|
||||
color: exploreColor(context, studyset),
|
||||
borderRadius: BorderRadius.circular(2),
|
||||
// What it is, in its colour along the top as on its card.
|
||||
SectionCard(
|
||||
padding: EdgeInsets.zero,
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.stretch,
|
||||
children: [
|
||||
Container(height: 4, color: exploreColor(context, studyset)),
|
||||
Padding(
|
||||
padding: const EdgeInsets.all(16),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
if (studyset.secondaryTitle case final secondary?)
|
||||
Text(
|
||||
secondary,
|
||||
style: theme.textTheme.labelLarge?.copyWith(
|
||||
color: theme.colorScheme.primary,
|
||||
),
|
||||
),
|
||||
Text(
|
||||
l10n.exploreBy(authorLine(studyset)),
|
||||
style: muted,
|
||||
),
|
||||
if (studyset.basedOn case final original?)
|
||||
Text(l10n.exploreBasedOn(original), style: muted),
|
||||
const SizedBox(height: 12),
|
||||
if (studyset.description.isBlank)
|
||||
Text(
|
||||
l10n.exploreNoDescription,
|
||||
style: theme.textTheme.bodyMedium?.copyWith(
|
||||
color: theme.colorScheme.onSurfaceVariant,
|
||||
fontStyle: FontStyle.italic,
|
||||
),
|
||||
)
|
||||
else
|
||||
RichContentView(content: studyset.description),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
if (studyset.secondaryTitle case final secondary?)
|
||||
Text(secondary, style: theme.textTheme.titleSmall),
|
||||
Text(l10n.exploreBy(authorLine(studyset)), style: muted),
|
||||
if (studyset.basedOn case final original?)
|
||||
Text(l10n.exploreBasedOn(original), style: muted),
|
||||
const SizedBox(height: 12),
|
||||
if (studyset.description.isBlank)
|
||||
Text(
|
||||
l10n.exploreNoDescription,
|
||||
style: theme.textTheme.bodyMedium?.copyWith(
|
||||
color: theme.colorScheme.onSurfaceVariant,
|
||||
fontStyle: FontStyle.italic,
|
||||
),
|
||||
)
|
||||
else
|
||||
RichContentView(content: studyset.description),
|
||||
const SizedBox(height: 16),
|
||||
if (languages.isNotEmpty)
|
||||
Text(
|
||||
languages.length == 2
|
||||
? l10n.exploreLanguagePair(languages[0], languages[1])
|
||||
: languages.single,
|
||||
style: muted,
|
||||
// What it holds.
|
||||
SectionCard(
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(l10n.exploreHolds, style: theme.textTheme.titleSmall),
|
||||
const SizedBox(height: 8),
|
||||
if (languages.isNotEmpty)
|
||||
Text(
|
||||
languages.length == 2
|
||||
? l10n.exploreLanguagePair(languages[0], languages[1])
|
||||
: languages.single,
|
||||
style: muted,
|
||||
),
|
||||
ExploreCounts(studyset: studyset),
|
||||
if (studyset.learners case final learners?)
|
||||
Text(l10n.exploreLearners(learners), style: muted),
|
||||
],
|
||||
),
|
||||
ExploreCounts(studyset: studyset),
|
||||
if (studyset.learners case final learners?)
|
||||
Text(l10n.exploreLearners(learners), style: muted),
|
||||
const SizedBox(height: 12),
|
||||
Text(
|
||||
l10n.exploreLatestRelease(
|
||||
studyset.version,
|
||||
releaseDate(context, studyset.releasedAt),
|
||||
),
|
||||
style: theme.textTheme.labelLarge,
|
||||
),
|
||||
if (studyset.notes.isNotEmpty) ...[
|
||||
const SizedBox(height: 4),
|
||||
Text(studyset.notes),
|
||||
],
|
||||
const SizedBox(height: 4),
|
||||
Align(
|
||||
alignment: AlignmentDirectional.centerStart,
|
||||
child: TextButton.icon(
|
||||
// Its icon on the edge the lines above start at.
|
||||
style: TextButton.styleFrom(
|
||||
padding: const EdgeInsetsDirectional.only(end: 8),
|
||||
),
|
||||
icon: const Icon(LucideIcons.messagesSquare, size: 18),
|
||||
label: Text(l10n.studysetFeedback),
|
||||
onPressed: () => showStudysetFeedback(
|
||||
context,
|
||||
publicId: studyset.publicId,
|
||||
title: studyset.title,
|
||||
),
|
||||
const SizedBox(height: 12),
|
||||
// Its latest release, and what people say about it.
|
||||
SectionCard(
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
l10n.exploreLatestRelease(
|
||||
studyset.version,
|
||||
releaseDate(context, studyset.releasedAt),
|
||||
),
|
||||
style: theme.textTheme.titleSmall,
|
||||
),
|
||||
if (studyset.notes.isNotEmpty) ...[
|
||||
const SizedBox(height: 4),
|
||||
Text(studyset.notes, style: muted),
|
||||
],
|
||||
const SizedBox(height: 4),
|
||||
TextButton.icon(
|
||||
// Its icon on the edge the lines above start at.
|
||||
style: TextButton.styleFrom(
|
||||
padding: const EdgeInsetsDirectional.only(end: 8),
|
||||
),
|
||||
icon: const Icon(LucideIcons.messagesSquare, size: 18),
|
||||
label: Text(l10n.studysetFeedback),
|
||||
onPressed: () => showStudysetFeedback(
|
||||
context,
|
||||
publicId: studyset.publicId,
|
||||
title: studyset.title,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 8),
|
||||
// Its credits beneath the blocks, as at the foot of a studyset.
|
||||
LicenseFooter(
|
||||
centred: false,
|
||||
content: StudysetContent(
|
||||
title: studyset.title,
|
||||
description: studyset.description,
|
||||
|
|
|
|||
Loading…
Reference in a new issue