feat(publish): a release keeps its colour, and a description for Explore
Publishing takes a description for Explore (rich text, as its JSON), which Explore shows in place of the studyset's own: a studyset may introduce itself to strangers otherwise than in the library, where its author may leave it empty. Without one, as from older apps, the studyset's description as before; one that isn't rich text, or over 100,000 characters, counts as none. A release also keeps the studyset's colour, which Explore gives out with it; releases before have none. The publication's releases say their description, for the next publish to start from. Migration release-colour adds a nullable column: ALTER TABLE "studyset_release" ADD COLUMN "colorName" text; the server before it reads and writes the table as ever. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Signed-off-by: Tizian 「ティツィアーン」 <raisondetredev@pm.me>
This commit is contained in:
parent
d5fe51b296
commit
fe6b1f5ed1
3 changed files with 14958 additions and 15 deletions
|
|
@ -746,6 +746,11 @@ class EndpointPublish extends _isc.EndpointRef {
|
|||
/// Publishes your studyset [studysetId] with everything inside it as its
|
||||
/// next release, [notes] saying what changed; at the first, under the
|
||||
/// name [slug] in its location, which stays its name from then on.
|
||||
/// [description] (rich text, as its JSON) is what Explore shows of it,
|
||||
/// when given: a studyset may introduce itself to strangers otherwise
|
||||
/// than in the library (decided 2026-10-14); without, the studyset's
|
||||
/// own description. One that isn't rich text, or is larger than
|
||||
/// [maxExploreDescription], counts as not given.
|
||||
///
|
||||
/// Throws [PublishRefusedException] when it can't be published (see
|
||||
/// [PublishRefusal]), and [NotFoundException] for a studyset that isn't
|
||||
|
|
@ -753,14 +758,16 @@ class EndpointPublish extends _isc.EndpointRef {
|
|||
_ida.Future<_ij0cqo11.Publication> publish(
|
||||
_isc.UuidValue studysetId,
|
||||
String slug,
|
||||
String notes,
|
||||
) => caller.callServerEndpoint<_ij0cqo11.Publication>(
|
||||
String notes, {
|
||||
String? description,
|
||||
}) => caller.callServerEndpoint<_ij0cqo11.Publication>(
|
||||
'publish',
|
||||
'publish',
|
||||
{
|
||||
'studysetId': studysetId,
|
||||
'slug': slug,
|
||||
'notes': notes,
|
||||
'description': description,
|
||||
},
|
||||
);
|
||||
|
||||
|
|
|
|||
|
|
@ -31,6 +31,7 @@ abstract class ExploreEntry
|
|||
this.frontLanguage,
|
||||
this.backLanguage,
|
||||
this.basedOn,
|
||||
this.colorName,
|
||||
required this.license,
|
||||
this.licenseHolder,
|
||||
this.licenseYear,
|
||||
|
|
@ -57,6 +58,7 @@ abstract class ExploreEntry
|
|||
String? frontLanguage,
|
||||
String? backLanguage,
|
||||
String? basedOn,
|
||||
String? colorName,
|
||||
required String license,
|
||||
String? licenseHolder,
|
||||
int? licenseYear,
|
||||
|
|
@ -88,6 +90,7 @@ abstract class ExploreEntry
|
|||
frontLanguage: jsonSerialization['frontLanguage'] as String?,
|
||||
backLanguage: jsonSerialization['backLanguage'] as String?,
|
||||
basedOn: jsonSerialization['basedOn'] as String?,
|
||||
colorName: jsonSerialization['colorName'] as String?,
|
||||
license: jsonSerialization['license'] as String,
|
||||
licenseHolder: jsonSerialization['licenseHolder'] as String?,
|
||||
licenseYear: jsonSerialization['licenseYear'] as int?,
|
||||
|
|
@ -135,6 +138,9 @@ abstract class ExploreEntry
|
|||
/// Where the published studyset it is a copy of is, for a copy.
|
||||
String? basedOn;
|
||||
|
||||
/// Its colour, by the app palette's name for it; null for none.
|
||||
String? colorName;
|
||||
|
||||
/// Its licence and credits.
|
||||
String license;
|
||||
|
||||
|
|
@ -175,6 +181,7 @@ abstract class ExploreEntry
|
|||
String? frontLanguage,
|
||||
String? backLanguage,
|
||||
String? basedOn,
|
||||
String? colorName,
|
||||
String? license,
|
||||
String? licenseHolder,
|
||||
int? licenseYear,
|
||||
|
|
@ -203,6 +210,7 @@ abstract class ExploreEntry
|
|||
if (frontLanguage != null) 'frontLanguage': frontLanguage,
|
||||
if (backLanguage != null) 'backLanguage': backLanguage,
|
||||
if (basedOn != null) 'basedOn': basedOn,
|
||||
if (colorName != null) 'colorName': colorName,
|
||||
'license': license,
|
||||
if (licenseHolder != null) 'licenseHolder': licenseHolder,
|
||||
if (licenseYear != null) 'licenseYear': licenseYear,
|
||||
|
|
@ -233,6 +241,7 @@ abstract class ExploreEntry
|
|||
if (frontLanguage != null) 'frontLanguage': frontLanguage,
|
||||
if (backLanguage != null) 'backLanguage': backLanguage,
|
||||
if (basedOn != null) 'basedOn': basedOn,
|
||||
if (colorName != null) 'colorName': colorName,
|
||||
'license': license,
|
||||
if (licenseHolder != null) 'licenseHolder': licenseHolder,
|
||||
if (licenseYear != null) 'licenseYear': licenseYear,
|
||||
|
|
@ -269,6 +278,7 @@ class _ExploreEntryImpl extends ExploreEntry {
|
|||
String? frontLanguage,
|
||||
String? backLanguage,
|
||||
String? basedOn,
|
||||
String? colorName,
|
||||
required String license,
|
||||
String? licenseHolder,
|
||||
int? licenseYear,
|
||||
|
|
@ -293,6 +303,7 @@ class _ExploreEntryImpl extends ExploreEntry {
|
|||
frontLanguage: frontLanguage,
|
||||
backLanguage: backLanguage,
|
||||
basedOn: basedOn,
|
||||
colorName: colorName,
|
||||
license: license,
|
||||
licenseHolder: licenseHolder,
|
||||
licenseYear: licenseYear,
|
||||
|
|
@ -323,6 +334,7 @@ class _ExploreEntryImpl extends ExploreEntry {
|
|||
Object? frontLanguage = _Undefined,
|
||||
Object? backLanguage = _Undefined,
|
||||
Object? basedOn = _Undefined,
|
||||
Object? colorName = _Undefined,
|
||||
String? license,
|
||||
Object? licenseHolder = _Undefined,
|
||||
Object? licenseYear = _Undefined,
|
||||
|
|
@ -352,6 +364,7 @@ class _ExploreEntryImpl extends ExploreEntry {
|
|||
: this.frontLanguage,
|
||||
backLanguage: backLanguage is String? ? backLanguage : this.backLanguage,
|
||||
basedOn: basedOn is String? ? basedOn : this.basedOn,
|
||||
colorName: colorName is String? ? colorName : this.colorName,
|
||||
license: license ?? this.license,
|
||||
licenseHolder: licenseHolder is String?
|
||||
? licenseHolder
|
||||
|
|
|
|||
|
|
@ -25,6 +25,7 @@ abstract class ReleaseInfo
|
|||
required this.pathCount,
|
||||
required this.pdfCount,
|
||||
required this.releasedAt,
|
||||
this.description,
|
||||
});
|
||||
|
||||
factory ReleaseInfo({
|
||||
|
|
@ -37,6 +38,7 @@ abstract class ReleaseInfo
|
|||
required int pathCount,
|
||||
required int pdfCount,
|
||||
required DateTime releasedAt,
|
||||
String? description,
|
||||
}) = _ReleaseInfoImpl;
|
||||
|
||||
factory ReleaseInfo.fromJson(Map<String, dynamic> jsonSerialization) {
|
||||
|
|
@ -52,6 +54,7 @@ abstract class ReleaseInfo
|
|||
releasedAt: _isc.DateTimeJsonExtension.fromJson(
|
||||
jsonSerialization['releasedAt'],
|
||||
),
|
||||
description: jsonSerialization['description'] as String?,
|
||||
);
|
||||
}
|
||||
|
||||
|
|
@ -77,6 +80,10 @@ abstract class ReleaseInfo
|
|||
/// When it was released, in UTC.
|
||||
DateTime releasedAt;
|
||||
|
||||
/// What Explore shows of it as its description (rich text, as its JSON);
|
||||
/// null for none.
|
||||
String? description;
|
||||
|
||||
/// Returns a shallow copy of this [ReleaseInfo]
|
||||
/// with some or all fields replaced by the given arguments.
|
||||
@_isc.useResult
|
||||
|
|
@ -90,6 +97,7 @@ abstract class ReleaseInfo
|
|||
int? pathCount,
|
||||
int? pdfCount,
|
||||
DateTime? releasedAt,
|
||||
String? description,
|
||||
});
|
||||
@override
|
||||
Map<String, dynamic> toJson() {
|
||||
|
|
@ -104,6 +112,7 @@ abstract class ReleaseInfo
|
|||
'pathCount': pathCount,
|
||||
'pdfCount': pdfCount,
|
||||
'releasedAt': releasedAt.toJson(),
|
||||
if (description != null) 'description': description,
|
||||
};
|
||||
}
|
||||
|
||||
|
|
@ -120,6 +129,7 @@ abstract class ReleaseInfo
|
|||
'pathCount': pathCount,
|
||||
'pdfCount': pdfCount,
|
||||
'releasedAt': releasedAt.toJson(),
|
||||
if (description != null) 'description': description,
|
||||
};
|
||||
}
|
||||
|
||||
|
|
@ -129,6 +139,8 @@ abstract class ReleaseInfo
|
|||
}
|
||||
}
|
||||
|
||||
class _Undefined {}
|
||||
|
||||
class _ReleaseInfoImpl extends ReleaseInfo {
|
||||
_ReleaseInfoImpl({
|
||||
required int version,
|
||||
|
|
@ -140,6 +152,7 @@ class _ReleaseInfoImpl extends ReleaseInfo {
|
|||
required int pathCount,
|
||||
required int pdfCount,
|
||||
required DateTime releasedAt,
|
||||
String? description,
|
||||
}) : super._(
|
||||
version: version,
|
||||
notes: notes,
|
||||
|
|
@ -150,6 +163,7 @@ class _ReleaseInfoImpl extends ReleaseInfo {
|
|||
pathCount: pathCount,
|
||||
pdfCount: pdfCount,
|
||||
releasedAt: releasedAt,
|
||||
description: description,
|
||||
);
|
||||
|
||||
/// Returns a shallow copy of this [ReleaseInfo]
|
||||
|
|
@ -166,6 +180,7 @@ class _ReleaseInfoImpl extends ReleaseInfo {
|
|||
int? pathCount,
|
||||
int? pdfCount,
|
||||
DateTime? releasedAt,
|
||||
Object? description = _Undefined,
|
||||
}) {
|
||||
return ReleaseInfo(
|
||||
version: version ?? this.version,
|
||||
|
|
@ -177,6 +192,7 @@ class _ReleaseInfoImpl extends ReleaseInfo {
|
|||
pathCount: pathCount ?? this.pathCount,
|
||||
pdfCount: pdfCount ?? this.pdfCount,
|
||||
releasedAt: releasedAt ?? this.releasedAt,
|
||||
description: description is String? ? description : this.description,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue