From 18daf036d610852b8e315ed130b116ec7ad23b9a Mon Sep 17 00:00:00 2001 From: Micah Morrison Date: Fri, 13 Dec 2024 12:30:53 -0500 Subject: [PATCH 1/2] Add the ability to specify alt text for image posts --- drift_schemas/drift_schema_v6.json | 1 + lib/account/models/account.dart | 4 +- lib/account/models/draft.dart | 11 +- lib/community/pages/create_post_page.dart | 36 +- lib/core/database/database.dart | 6 +- lib/core/database/database.g.dart | 790 +++++++++++++++++++++- lib/core/database/migrations.dart | 2 +- lib/core/database/schema_versions.dart | 118 ++++ lib/core/database/tables.dart | 1 + lib/core/singletons/lemmy_client.dart | 1 + lib/feed/utils/post.dart | 5 + lib/l10n/app_en.arb | 4 + lib/post/cubit/create_post_cubit.dart | 2 + 13 files changed, 966 insertions(+), 15 deletions(-) create mode 100644 drift_schemas/drift_schema_v6.json diff --git a/drift_schemas/drift_schema_v6.json b/drift_schemas/drift_schema_v6.json new file mode 100644 index 000000000..01f8542cf --- /dev/null +++ b/drift_schemas/drift_schema_v6.json @@ -0,0 +1 @@ +{"_meta":{"description":"This file contains a serialized version of schema entities for drift.","version":"1.2.0"},"options":{"store_date_time_values_as_text":false},"entities":[{"id":0,"references":[],"type":"table","data":{"name":"accounts","was_declared_in_moor":false,"columns":[{"name":"id","getter_name":"id","moor_type":"int","nullable":false,"customConstraints":null,"defaultConstraints":"PRIMARY KEY AUTOINCREMENT","dialectAwareDefaultConstraints":{"sqlite":"PRIMARY KEY AUTOINCREMENT"},"default_dart":null,"default_client_dart":null,"dsl_features":["auto-increment"]},{"name":"username","getter_name":"username","moor_type":"string","nullable":true,"customConstraints":null,"default_dart":null,"default_client_dart":null,"dsl_features":[]},{"name":"jwt","getter_name":"jwt","moor_type":"string","nullable":true,"customConstraints":null,"default_dart":null,"default_client_dart":null,"dsl_features":[]},{"name":"instance","getter_name":"instance","moor_type":"string","nullable":true,"customConstraints":null,"default_dart":null,"default_client_dart":null,"dsl_features":[]},{"name":"anonymous","getter_name":"anonymous","moor_type":"bool","nullable":false,"customConstraints":null,"defaultConstraints":"CHECK (\"anonymous\" IN (0, 1))","dialectAwareDefaultConstraints":{"sqlite":"CHECK (\"anonymous\" IN (0, 1))"},"default_dart":"const Constant(false)","default_client_dart":null,"dsl_features":[]},{"name":"user_id","getter_name":"userId","moor_type":"int","nullable":true,"customConstraints":null,"default_dart":null,"default_client_dart":null,"dsl_features":[]},{"name":"list_index","getter_name":"listIndex","moor_type":"int","nullable":false,"customConstraints":null,"default_dart":"const Constant(-1)","default_client_dart":null,"dsl_features":[]}],"is_virtual":false,"without_rowid":false,"constraints":[]}},{"id":1,"references":[],"type":"table","data":{"name":"favorites","was_declared_in_moor":false,"columns":[{"name":"id","getter_name":"id","moor_type":"int","nullable":false,"customConstraints":null,"defaultConstraints":"PRIMARY KEY AUTOINCREMENT","dialectAwareDefaultConstraints":{"sqlite":"PRIMARY KEY AUTOINCREMENT"},"default_dart":null,"default_client_dart":null,"dsl_features":["auto-increment"]},{"name":"account_id","getter_name":"accountId","moor_type":"int","nullable":false,"customConstraints":null,"default_dart":null,"default_client_dart":null,"dsl_features":[]},{"name":"community_id","getter_name":"communityId","moor_type":"int","nullable":false,"customConstraints":null,"default_dart":null,"default_client_dart":null,"dsl_features":[]}],"is_virtual":false,"without_rowid":false,"constraints":[]}},{"id":2,"references":[],"type":"table","data":{"name":"local_subscriptions","was_declared_in_moor":false,"columns":[{"name":"id","getter_name":"id","moor_type":"int","nullable":false,"customConstraints":null,"defaultConstraints":"PRIMARY KEY AUTOINCREMENT","dialectAwareDefaultConstraints":{"sqlite":"PRIMARY KEY AUTOINCREMENT"},"default_dart":null,"default_client_dart":null,"dsl_features":["auto-increment"]},{"name":"name","getter_name":"name","moor_type":"string","nullable":false,"customConstraints":null,"default_dart":null,"default_client_dart":null,"dsl_features":[]},{"name":"title","getter_name":"title","moor_type":"string","nullable":false,"customConstraints":null,"default_dart":null,"default_client_dart":null,"dsl_features":[]},{"name":"actor_id","getter_name":"actorId","moor_type":"string","nullable":false,"customConstraints":null,"default_dart":null,"default_client_dart":null,"dsl_features":[]},{"name":"icon","getter_name":"icon","moor_type":"string","nullable":true,"customConstraints":null,"default_dart":null,"default_client_dart":null,"dsl_features":[]}],"is_virtual":false,"without_rowid":false,"constraints":[]}},{"id":3,"references":[],"type":"table","data":{"name":"user_labels","was_declared_in_moor":false,"columns":[{"name":"id","getter_name":"id","moor_type":"int","nullable":false,"customConstraints":null,"defaultConstraints":"PRIMARY KEY AUTOINCREMENT","dialectAwareDefaultConstraints":{"sqlite":"PRIMARY KEY AUTOINCREMENT"},"default_dart":null,"default_client_dart":null,"dsl_features":["auto-increment"]},{"name":"username","getter_name":"username","moor_type":"string","nullable":false,"customConstraints":null,"default_dart":null,"default_client_dart":null,"dsl_features":[]},{"name":"label","getter_name":"label","moor_type":"string","nullable":false,"customConstraints":null,"default_dart":null,"default_client_dart":null,"dsl_features":[]}],"is_virtual":false,"without_rowid":false,"constraints":[]}},{"id":4,"references":[],"type":"table","data":{"name":"drafts","was_declared_in_moor":false,"columns":[{"name":"id","getter_name":"id","moor_type":"int","nullable":false,"customConstraints":null,"defaultConstraints":"PRIMARY KEY AUTOINCREMENT","dialectAwareDefaultConstraints":{"sqlite":"PRIMARY KEY AUTOINCREMENT"},"default_dart":null,"default_client_dart":null,"dsl_features":["auto-increment"]},{"name":"draft_type","getter_name":"draftType","moor_type":"string","nullable":false,"customConstraints":null,"default_dart":null,"default_client_dart":null,"dsl_features":[],"type_converter":{"dart_expr":"const DraftTypeConverter()","dart_type_name":"DraftType"}},{"name":"existing_id","getter_name":"existingId","moor_type":"int","nullable":true,"customConstraints":null,"default_dart":null,"default_client_dart":null,"dsl_features":[]},{"name":"reply_id","getter_name":"replyId","moor_type":"int","nullable":true,"customConstraints":null,"default_dart":null,"default_client_dart":null,"dsl_features":[]},{"name":"title","getter_name":"title","moor_type":"string","nullable":true,"customConstraints":null,"default_dart":null,"default_client_dart":null,"dsl_features":[]},{"name":"url","getter_name":"url","moor_type":"string","nullable":true,"customConstraints":null,"default_dart":null,"default_client_dart":null,"dsl_features":[]},{"name":"custom_thumbnail","getter_name":"customThumbnail","moor_type":"string","nullable":true,"customConstraints":null,"default_dart":null,"default_client_dart":null,"dsl_features":[]},{"name":"alt_text","getter_name":"altText","moor_type":"string","nullable":true,"customConstraints":null,"default_dart":null,"default_client_dart":null,"dsl_features":[]},{"name":"body","getter_name":"body","moor_type":"string","nullable":true,"customConstraints":null,"default_dart":null,"default_client_dart":null,"dsl_features":[]}],"is_virtual":false,"without_rowid":false,"constraints":[]}}]} \ No newline at end of file diff --git a/lib/account/models/account.dart b/lib/account/models/account.dart index 10e6aa7ba..10fcf6201 100644 --- a/lib/account/models/account.dart +++ b/lib/account/models/account.dart @@ -56,7 +56,7 @@ class Account { instance: Value(account.instance), anonymous: Value(account.anonymous), userId: Value(account.userId), - listIndex: newIndex, + listIndex: Value(newIndex), ), ); @@ -85,7 +85,7 @@ class Account { instance: Value(anonymousInstance.instance), anonymous: Value(anonymousInstance.anonymous), userId: Value(anonymousInstance.userId), - listIndex: newIndex, + listIndex: Value(newIndex), ), ); diff --git a/lib/account/models/draft.dart b/lib/account/models/draft.dart index 4cdacd44e..dcf8a36cf 100644 --- a/lib/account/models/draft.dart +++ b/lib/account/models/draft.dart @@ -27,6 +27,9 @@ class Draft { /// The custom thumbnail of the post final String? customThumbnail; + /// Alternative text for the image + final String? altText; + /// The body of the post/comment final String? body; @@ -38,6 +41,7 @@ class Draft { this.title, this.url, this.customThumbnail, + this.altText, this.body, }); @@ -49,6 +53,7 @@ class Draft { String? title, String? url, String? customThumbnail, + String? altText, String? body, }) => Draft( @@ -59,11 +64,12 @@ class Draft { title: title ?? this.title, url: url ?? this.url, customThumbnail: customThumbnail ?? this.customThumbnail, + altText: altText ?? this.altText, body: body ?? this.body, ); /// See whether this draft contains enough info to save for a post - bool get isPostNotEmpty => title?.isNotEmpty == true || url?.isNotEmpty == true || customThumbnail?.isNotEmpty == true || body?.isNotEmpty == true; + bool get isPostNotEmpty => title?.isNotEmpty == true || url?.isNotEmpty == true || customThumbnail?.isNotEmpty == true || altText?.isNotEmpty == true || body?.isNotEmpty == true; /// See whether this draft contains enough info to save for a comment bool get isCommentNotEmpty => body?.isNotEmpty == true; @@ -86,6 +92,7 @@ class Draft { title: Value(draft.title), url: Value(draft.url), customThumbnail: Value(draft.customThumbnail), + altText: Value(draft.altText), body: Value(draft.body), ), ); @@ -100,6 +107,7 @@ class Draft { title: Value(draft.title), url: Value(draft.url), customThumbnail: Value(draft.customThumbnail), + altText: Value(draft.altText), body: Value(draft.body), ), ); @@ -130,6 +138,7 @@ class Draft { title: draft.title, url: draft.url, customThumbnail: draft.customThumbnail, + altText: draft.altText, body: draft.body, ); } catch (e) { diff --git a/lib/community/pages/create_post_page.dart b/lib/community/pages/create_post_page.dart index bce8af19f..0370ee0af 100644 --- a/lib/community/pages/create_post_page.dart +++ b/lib/community/pages/create_post_page.dart @@ -45,7 +45,7 @@ class CreatePostPage extends StatefulWidget { final int? communityId; final CommunityView? communityView; - /// Whether or not to pre-populate the post with the [title], [text], [image], [url], and/or [customThumbnail] + /// Whether or not to pre-populate the post with the [title], [text], [image], [url], [customThumbnail], and/or [altText] final bool? prePopulated; /// Used to pre-populate the post title @@ -63,6 +63,9 @@ class CreatePostPage extends StatefulWidget { /// Used to pre-populate the custom thumbnail for the post final String? customThumbnail; + /// Alternative text for the image + final String? altText; + /// [postView] is passed in when editing an existing post final PostView? postView; @@ -78,6 +81,7 @@ class CreatePostPage extends StatefulWidget { this.text, this.url, this.customThumbnail, + this.altText, this.prePopulated = false, this.postView, this.onPostSuccess, @@ -124,6 +128,9 @@ class _CreatePostPageState extends State { /// The custom thumbnail for this post. String? customThumbnail; + /// Alternative text for the image + String? altText; + /// The error message for the shared link if available String? urlError; @@ -146,6 +153,7 @@ class _CreatePostPageState extends State { final TextEditingController _titleTextController = TextEditingController(); final TextEditingController _urlTextController = TextEditingController(); final TextEditingController _customThumbnailTextController = TextEditingController(); + final TextEditingController _altTextTextController = TextEditingController(); /// The focus node for the body. This is used to keep track of the position of the cursor when toggling preview final FocusNode _bodyFocusNode = FocusNode(); @@ -182,12 +190,19 @@ class _CreatePostPageState extends State { debounce(const Duration(milliseconds: 1000), _updatePreview, [customThumbnail]); }); + _altTextTextController.addListener(() { + altText = _altTextTextController.text; + _validateSubmission(); + debounce(const Duration(milliseconds: 1000), _updatePreview, [altText]); + }); + // Logic for pre-populating the post with the given fields if (widget.prePopulated == true) { _titleTextController.text = widget.title ?? ''; _bodyTextController.text = widget.text ?? ''; _urlTextController.text = widget.url ?? ''; _customThumbnailTextController.text = widget.customThumbnail ?? ''; + _altTextTextController.text = widget.altText ?? ''; _getDataFromLink(updateTitleField: _titleTextController.text.isEmpty); if (widget.image != null) { @@ -204,6 +219,7 @@ class _CreatePostPageState extends State { _titleTextController.text = widget.postView!.post.name; _urlTextController.text = widget.postView!.post.url ?? ''; _customThumbnailTextController.text = widget.postView!.post.thumbnailUrl ?? ''; + _altTextTextController.text = widget.postView!.post.altText ?? ''; _bodyTextController.text = widget.postView!.post.body ?? ''; isNSFW = widget.postView!.post.nsfw; languageId = widget.postView!.post.languageId; @@ -221,6 +237,7 @@ class _CreatePostPageState extends State { _titleTextController.dispose(); _urlTextController.dispose(); _customThumbnailTextController.dispose(); + _altTextTextController.dispose(); _bodyFocusNode.dispose(); FocusManager.instance.primaryFocus?.unfocus(); @@ -260,6 +277,7 @@ class _CreatePostPageState extends State { _titleTextController.text = draft.title ?? ''; _urlTextController.text = draft.url ?? ''; _customThumbnailTextController.text = draft.customThumbnail ?? ''; + _altTextTextController.text = draft.altText ?? ''; _bodyTextController.text = draft.body ?? ''; } @@ -282,6 +300,7 @@ class _CreatePostPageState extends State { _titleTextController.text = widget.postView?.post.name ?? ''; _urlTextController.text = widget.postView?.post.url ?? ''; _customThumbnailTextController.text = widget.postView?.post.thumbnailUrl ?? ''; + _altTextTextController.text = widget.postView?.post.altText ?? ''; _bodyTextController.text = widget.postView?.post.body ?? ''; }, ); @@ -297,6 +316,7 @@ class _CreatePostPageState extends State { title: _titleTextController.text, url: _urlTextController.text, customThumbnail: _customThumbnailTextController.text, + altText: _altTextTextController.text, body: _bodyTextController.text, ); } @@ -311,6 +331,7 @@ class _CreatePostPageState extends State { return draft.title != widget.postView!.post.name || draft.url != (widget.postView!.post.url ?? '') || draft.customThumbnail != (widget.postView!.post.thumbnailUrl ?? '') || + draft.altText != (widget.postView!.post.altText ?? '') || draft.body != (widget.postView!.post.body ?? ''); } @@ -501,6 +522,18 @@ class _CreatePostPageState extends State { ), ), ], + if (LemmyClient.instance.supportsFeature(LemmyFeature.altText) && isImageUrl(_urlTextController.text)) ...[ + const SizedBox(height: 10), + TextFormField( + controller: _altTextTextController, + decoration: InputDecoration( + labelText: l10n.altText, + isDense: true, + border: const OutlineInputBorder(), + contentPadding: const EdgeInsets.all(13), + ), + ), + ], SizedBox(height: url.isNotEmpty ? 10 : 5), Visibility( visible: url.isNotEmpty, @@ -752,6 +785,7 @@ class _CreatePostPageState extends State { nsfw: isNSFW, url: url, customThumbnail: customThumbnail, + altText: altText, postIdBeingEdited: widget.postView?.post.id, languageId: languageId, ); diff --git a/lib/core/database/database.dart b/lib/core/database/database.dart index aa377d0d8..639cd0e5b 100644 --- a/lib/core/database/database.dart +++ b/lib/core/database/database.dart @@ -36,7 +36,7 @@ class AppDatabase extends _$AppDatabase { ); @override - int get schemaVersion => 5; + int get schemaVersion => 6; @override MigrationStrategy get migration => MigrationStrategy( @@ -67,6 +67,10 @@ class AppDatabase extends _$AppDatabase { await m.addColumn(schema.accounts, schema.accounts.listIndex); await customStatement('UPDATE accounts SET list_index = id'); }, + from5To6: (m, schema) async { + // Create the alt_text column on the drafts table + await m.addColumn(schema.drafts, schema.drafts.altText); + }, ), ); diff --git a/lib/core/database/database.g.dart b/lib/core/database/database.g.dart index 0592ca077..0335b0181 100644 --- a/lib/core/database/database.g.dart +++ b/lib/core/database/database.g.dart @@ -30,7 +30,7 @@ class $AccountsTable extends Accounts with TableInfo<$AccountsTable, Account> { late final GeneratedColumn userId = GeneratedColumn('user_id', aliasedName, true, type: DriftSqlType.int, requiredDuringInsert: false); static const VerificationMeta _listIndexMeta = const VerificationMeta('listIndex'); @override - late final GeneratedColumn listIndex = GeneratedColumn('list_index', aliasedName, false, type: DriftSqlType.int, requiredDuringInsert: true); + late final GeneratedColumn listIndex = GeneratedColumn('list_index', aliasedName, false, type: DriftSqlType.int, requiredDuringInsert: false, defaultValue: const Constant(-1)); @override List get $columns => [id, username, jwt, instance, anonymous, userId, listIndex]; @override @@ -62,8 +62,6 @@ class $AccountsTable extends Accounts with TableInfo<$AccountsTable, Account> { } if (data.containsKey('list_index')) { context.handle(_listIndexMeta, listIndex.isAcceptableOrUnknown(data['list_index']!, _listIndexMeta)); - } else if (isInserting) { - context.missing(_listIndexMeta); } return context; } @@ -175,6 +173,18 @@ class Account extends DataClass implements Insertable { userId: userId.present ? userId.value : this.userId, listIndex: listIndex ?? this.listIndex, ); + Account copyWithCompanion(AccountsCompanion data) { + return Account( + id: data.id.present ? data.id.value : this.id, + username: data.username.present ? data.username.value : this.username, + jwt: data.jwt.present ? data.jwt.value : this.jwt, + instance: data.instance.present ? data.instance.value : this.instance, + anonymous: data.anonymous.present ? data.anonymous.value : this.anonymous, + userId: data.userId.present ? data.userId.value : this.userId, + listIndex: data.listIndex.present ? data.listIndex.value : this.listIndex, + ); + } + @override String toString() { return (StringBuffer('Account(') @@ -228,8 +238,8 @@ class AccountsCompanion extends UpdateCompanion { this.instance = const Value.absent(), this.anonymous = const Value.absent(), this.userId = const Value.absent(), - required int listIndex, - }) : listIndex = Value(listIndex); + this.listIndex = const Value.absent(), + }); static Insertable custom({ Expression? id, Expression? username, @@ -409,6 +419,14 @@ class Favorite extends DataClass implements Insertable { accountId: accountId ?? this.accountId, communityId: communityId ?? this.communityId, ); + Favorite copyWithCompanion(FavoritesCompanion data) { + return Favorite( + id: data.id.present ? data.id.value : this.id, + accountId: data.accountId.present ? data.accountId.value : this.accountId, + communityId: data.communityId.present ? data.communityId.value : this.communityId, + ); + } + @override String toString() { return (StringBuffer('Favorite(') @@ -621,6 +639,16 @@ class LocalSubscription extends DataClass implements Insertable { username: username ?? this.username, label: label ?? this.label, ); + UserLabel copyWithCompanion(UserLabelsCompanion data) { + return UserLabel( + id: data.id.present ? data.id.value : this.id, + username: data.username.present ? data.username.value : this.username, + label: data.label.present ? data.label.value : this.label, + ); + } + @override String toString() { return (StringBuffer('UserLabel(') @@ -932,11 +968,14 @@ class $DraftsTable extends Drafts with TableInfo<$DraftsTable, Draft> { static const VerificationMeta _customThumbnailMeta = const VerificationMeta('customThumbnail'); @override late final GeneratedColumn customThumbnail = GeneratedColumn('custom_thumbnail', aliasedName, true, type: DriftSqlType.string, requiredDuringInsert: false); + static const VerificationMeta _altTextMeta = const VerificationMeta('altText'); + @override + late final GeneratedColumn altText = GeneratedColumn('alt_text', aliasedName, true, type: DriftSqlType.string, requiredDuringInsert: false); static const VerificationMeta _bodyMeta = const VerificationMeta('body'); @override late final GeneratedColumn body = GeneratedColumn('body', aliasedName, true, type: DriftSqlType.string, requiredDuringInsert: false); @override - List get $columns => [id, draftType, existingId, replyId, title, url, customThumbnail, body]; + List get $columns => [id, draftType, existingId, replyId, title, url, customThumbnail, altText, body]; @override String get aliasedName => _alias ?? actualTableName; @override @@ -965,6 +1004,9 @@ class $DraftsTable extends Drafts with TableInfo<$DraftsTable, Draft> { if (data.containsKey('custom_thumbnail')) { context.handle(_customThumbnailMeta, customThumbnail.isAcceptableOrUnknown(data['custom_thumbnail']!, _customThumbnailMeta)); } + if (data.containsKey('alt_text')) { + context.handle(_altTextMeta, altText.isAcceptableOrUnknown(data['alt_text']!, _altTextMeta)); + } if (data.containsKey('body')) { context.handle(_bodyMeta, body.isAcceptableOrUnknown(data['body']!, _bodyMeta)); } @@ -984,6 +1026,7 @@ class $DraftsTable extends Drafts with TableInfo<$DraftsTable, Draft> { title: attachedDatabase.typeMapping.read(DriftSqlType.string, data['${effectivePrefix}title']), url: attachedDatabase.typeMapping.read(DriftSqlType.string, data['${effectivePrefix}url']), customThumbnail: attachedDatabase.typeMapping.read(DriftSqlType.string, data['${effectivePrefix}custom_thumbnail']), + altText: attachedDatabase.typeMapping.read(DriftSqlType.string, data['${effectivePrefix}alt_text']), body: attachedDatabase.typeMapping.read(DriftSqlType.string, data['${effectivePrefix}body']), ); } @@ -1004,8 +1047,9 @@ class Draft extends DataClass implements Insertable { final String? title; final String? url; final String? customThumbnail; + final String? altText; final String? body; - const Draft({required this.id, required this.draftType, this.existingId, this.replyId, this.title, this.url, this.customThumbnail, this.body}); + const Draft({required this.id, required this.draftType, this.existingId, this.replyId, this.title, this.url, this.customThumbnail, this.altText, this.body}); @override Map toColumns(bool nullToAbsent) { final map = {}; @@ -1028,6 +1072,9 @@ class Draft extends DataClass implements Insertable { if (!nullToAbsent || customThumbnail != null) { map['custom_thumbnail'] = Variable(customThumbnail); } + if (!nullToAbsent || altText != null) { + map['alt_text'] = Variable(altText); + } if (!nullToAbsent || body != null) { map['body'] = Variable(body); } @@ -1043,6 +1090,7 @@ class Draft extends DataClass implements Insertable { title: title == null && nullToAbsent ? const Value.absent() : Value(title), url: url == null && nullToAbsent ? const Value.absent() : Value(url), customThumbnail: customThumbnail == null && nullToAbsent ? const Value.absent() : Value(customThumbnail), + altText: altText == null && nullToAbsent ? const Value.absent() : Value(altText), body: body == null && nullToAbsent ? const Value.absent() : Value(body), ); } @@ -1057,6 +1105,7 @@ class Draft extends DataClass implements Insertable { title: serializer.fromJson(json['title']), url: serializer.fromJson(json['url']), customThumbnail: serializer.fromJson(json['customThumbnail']), + altText: serializer.fromJson(json['altText']), body: serializer.fromJson(json['body']), ); } @@ -1071,6 +1120,7 @@ class Draft extends DataClass implements Insertable { 'title': serializer.toJson(title), 'url': serializer.toJson(url), 'customThumbnail': serializer.toJson(customThumbnail), + 'altText': serializer.toJson(altText), 'body': serializer.toJson(body), }; } @@ -1083,6 +1133,7 @@ class Draft extends DataClass implements Insertable { Value title = const Value.absent(), Value url = const Value.absent(), Value customThumbnail = const Value.absent(), + Value altText = const Value.absent(), Value body = const Value.absent()}) => Draft( id: id ?? this.id, @@ -1092,8 +1143,23 @@ class Draft extends DataClass implements Insertable { title: title.present ? title.value : this.title, url: url.present ? url.value : this.url, customThumbnail: customThumbnail.present ? customThumbnail.value : this.customThumbnail, + altText: altText.present ? altText.value : this.altText, body: body.present ? body.value : this.body, ); + Draft copyWithCompanion(DraftsCompanion data) { + return Draft( + id: data.id.present ? data.id.value : this.id, + draftType: data.draftType.present ? data.draftType.value : this.draftType, + existingId: data.existingId.present ? data.existingId.value : this.existingId, + replyId: data.replyId.present ? data.replyId.value : this.replyId, + title: data.title.present ? data.title.value : this.title, + url: data.url.present ? data.url.value : this.url, + customThumbnail: data.customThumbnail.present ? data.customThumbnail.value : this.customThumbnail, + altText: data.altText.present ? data.altText.value : this.altText, + body: data.body.present ? data.body.value : this.body, + ); + } + @override String toString() { return (StringBuffer('Draft(') @@ -1104,13 +1170,14 @@ class Draft extends DataClass implements Insertable { ..write('title: $title, ') ..write('url: $url, ') ..write('customThumbnail: $customThumbnail, ') + ..write('altText: $altText, ') ..write('body: $body') ..write(')')) .toString(); } @override - int get hashCode => Object.hash(id, draftType, existingId, replyId, title, url, customThumbnail, body); + int get hashCode => Object.hash(id, draftType, existingId, replyId, title, url, customThumbnail, altText, body); @override bool operator ==(Object other) => identical(this, other) || @@ -1122,6 +1189,7 @@ class Draft extends DataClass implements Insertable { other.title == this.title && other.url == this.url && other.customThumbnail == this.customThumbnail && + other.altText == this.altText && other.body == this.body); } @@ -1133,6 +1201,7 @@ class DraftsCompanion extends UpdateCompanion { final Value title; final Value url; final Value customThumbnail; + final Value altText; final Value body; const DraftsCompanion({ this.id = const Value.absent(), @@ -1142,6 +1211,7 @@ class DraftsCompanion extends UpdateCompanion { this.title = const Value.absent(), this.url = const Value.absent(), this.customThumbnail = const Value.absent(), + this.altText = const Value.absent(), this.body = const Value.absent(), }); DraftsCompanion.insert({ @@ -1152,6 +1222,7 @@ class DraftsCompanion extends UpdateCompanion { this.title = const Value.absent(), this.url = const Value.absent(), this.customThumbnail = const Value.absent(), + this.altText = const Value.absent(), this.body = const Value.absent(), }) : draftType = Value(draftType); static Insertable custom({ @@ -1162,6 +1233,7 @@ class DraftsCompanion extends UpdateCompanion { Expression? title, Expression? url, Expression? customThumbnail, + Expression? altText, Expression? body, }) { return RawValuesInsertable({ @@ -1172,12 +1244,21 @@ class DraftsCompanion extends UpdateCompanion { if (title != null) 'title': title, if (url != null) 'url': url, if (customThumbnail != null) 'custom_thumbnail': customThumbnail, + if (altText != null) 'alt_text': altText, if (body != null) 'body': body, }); } DraftsCompanion copyWith( - {Value? id, Value? draftType, Value? existingId, Value? replyId, Value? title, Value? url, Value? customThumbnail, Value? body}) { + {Value? id, + Value? draftType, + Value? existingId, + Value? replyId, + Value? title, + Value? url, + Value? customThumbnail, + Value? altText, + Value? body}) { return DraftsCompanion( id: id ?? this.id, draftType: draftType ?? this.draftType, @@ -1186,6 +1267,7 @@ class DraftsCompanion extends UpdateCompanion { title: title ?? this.title, url: url ?? this.url, customThumbnail: customThumbnail ?? this.customThumbnail, + altText: altText ?? this.altText, body: body ?? this.body, ); } @@ -1214,6 +1296,9 @@ class DraftsCompanion extends UpdateCompanion { if (customThumbnail.present) { map['custom_thumbnail'] = Variable(customThumbnail.value); } + if (altText.present) { + map['alt_text'] = Variable(altText.value); + } if (body.present) { map['body'] = Variable(body.value); } @@ -1230,6 +1315,7 @@ class DraftsCompanion extends UpdateCompanion { ..write('title: $title, ') ..write('url: $url, ') ..write('customThumbnail: $customThumbnail, ') + ..write('altText: $altText, ') ..write('body: $body') ..write(')')) .toString(); @@ -1238,6 +1324,7 @@ class DraftsCompanion extends UpdateCompanion { abstract class _$AppDatabase extends GeneratedDatabase { _$AppDatabase(QueryExecutor e) : super(e); + $AppDatabaseManager get managers => $AppDatabaseManager(this); late final $AccountsTable accounts = $AccountsTable(this); late final $FavoritesTable favorites = $FavoritesTable(this); late final $LocalSubscriptionsTable localSubscriptions = $LocalSubscriptionsTable(this); @@ -1248,3 +1335,688 @@ abstract class _$AppDatabase extends GeneratedDatabase { @override List get allSchemaEntities => [accounts, favorites, localSubscriptions, userLabels, drafts]; } + +typedef $$AccountsTableCreateCompanionBuilder = AccountsCompanion Function({ + Value id, + Value username, + Value jwt, + Value instance, + Value anonymous, + Value userId, + Value listIndex, +}); +typedef $$AccountsTableUpdateCompanionBuilder = AccountsCompanion Function({ + Value id, + Value username, + Value jwt, + Value instance, + Value anonymous, + Value userId, + Value listIndex, +}); + +class $$AccountsTableFilterComposer extends Composer<_$AppDatabase, $AccountsTable> { + $$AccountsTableFilterComposer({ + required super.$db, + required super.$table, + super.joinBuilder, + super.$addJoinBuilderToRootComposer, + super.$removeJoinBuilderFromRootComposer, + }); + ColumnFilters get id => $composableBuilder(column: $table.id, builder: (column) => ColumnFilters(column)); + + ColumnFilters get username => $composableBuilder(column: $table.username, builder: (column) => ColumnFilters(column)); + + ColumnFilters get jwt => $composableBuilder(column: $table.jwt, builder: (column) => ColumnFilters(column)); + + ColumnFilters get instance => $composableBuilder(column: $table.instance, builder: (column) => ColumnFilters(column)); + + ColumnFilters get anonymous => $composableBuilder(column: $table.anonymous, builder: (column) => ColumnFilters(column)); + + ColumnFilters get userId => $composableBuilder(column: $table.userId, builder: (column) => ColumnFilters(column)); + + ColumnFilters get listIndex => $composableBuilder(column: $table.listIndex, builder: (column) => ColumnFilters(column)); +} + +class $$AccountsTableOrderingComposer extends Composer<_$AppDatabase, $AccountsTable> { + $$AccountsTableOrderingComposer({ + required super.$db, + required super.$table, + super.joinBuilder, + super.$addJoinBuilderToRootComposer, + super.$removeJoinBuilderFromRootComposer, + }); + ColumnOrderings get id => $composableBuilder(column: $table.id, builder: (column) => ColumnOrderings(column)); + + ColumnOrderings get username => $composableBuilder(column: $table.username, builder: (column) => ColumnOrderings(column)); + + ColumnOrderings get jwt => $composableBuilder(column: $table.jwt, builder: (column) => ColumnOrderings(column)); + + ColumnOrderings get instance => $composableBuilder(column: $table.instance, builder: (column) => ColumnOrderings(column)); + + ColumnOrderings get anonymous => $composableBuilder(column: $table.anonymous, builder: (column) => ColumnOrderings(column)); + + ColumnOrderings get userId => $composableBuilder(column: $table.userId, builder: (column) => ColumnOrderings(column)); + + ColumnOrderings get listIndex => $composableBuilder(column: $table.listIndex, builder: (column) => ColumnOrderings(column)); +} + +class $$AccountsTableAnnotationComposer extends Composer<_$AppDatabase, $AccountsTable> { + $$AccountsTableAnnotationComposer({ + required super.$db, + required super.$table, + super.joinBuilder, + super.$addJoinBuilderToRootComposer, + super.$removeJoinBuilderFromRootComposer, + }); + GeneratedColumn get id => $composableBuilder(column: $table.id, builder: (column) => column); + + GeneratedColumn get username => $composableBuilder(column: $table.username, builder: (column) => column); + + GeneratedColumn get jwt => $composableBuilder(column: $table.jwt, builder: (column) => column); + + GeneratedColumn get instance => $composableBuilder(column: $table.instance, builder: (column) => column); + + GeneratedColumn get anonymous => $composableBuilder(column: $table.anonymous, builder: (column) => column); + + GeneratedColumn get userId => $composableBuilder(column: $table.userId, builder: (column) => column); + + GeneratedColumn get listIndex => $composableBuilder(column: $table.listIndex, builder: (column) => column); +} + +class $$AccountsTableTableManager extends RootTableManager<_$AppDatabase, $AccountsTable, Account, $$AccountsTableFilterComposer, $$AccountsTableOrderingComposer, $$AccountsTableAnnotationComposer, + $$AccountsTableCreateCompanionBuilder, $$AccountsTableUpdateCompanionBuilder, (Account, BaseReferences<_$AppDatabase, $AccountsTable, Account>), Account, PrefetchHooks Function()> { + $$AccountsTableTableManager(_$AppDatabase db, $AccountsTable table) + : super(TableManagerState( + db: db, + table: table, + createFilteringComposer: () => $$AccountsTableFilterComposer($db: db, $table: table), + createOrderingComposer: () => $$AccountsTableOrderingComposer($db: db, $table: table), + createComputedFieldComposer: () => $$AccountsTableAnnotationComposer($db: db, $table: table), + updateCompanionCallback: ({ + Value id = const Value.absent(), + Value username = const Value.absent(), + Value jwt = const Value.absent(), + Value instance = const Value.absent(), + Value anonymous = const Value.absent(), + Value userId = const Value.absent(), + Value listIndex = const Value.absent(), + }) => + AccountsCompanion( + id: id, + username: username, + jwt: jwt, + instance: instance, + anonymous: anonymous, + userId: userId, + listIndex: listIndex, + ), + createCompanionCallback: ({ + Value id = const Value.absent(), + Value username = const Value.absent(), + Value jwt = const Value.absent(), + Value instance = const Value.absent(), + Value anonymous = const Value.absent(), + Value userId = const Value.absent(), + Value listIndex = const Value.absent(), + }) => + AccountsCompanion.insert( + id: id, + username: username, + jwt: jwt, + instance: instance, + anonymous: anonymous, + userId: userId, + listIndex: listIndex, + ), + withReferenceMapper: (p0) => p0.map((e) => (e.readTable(table), BaseReferences(db, table, e))).toList(), + prefetchHooksCallback: null, + )); +} + +typedef $$AccountsTableProcessedTableManager = ProcessedTableManager< + _$AppDatabase, + $AccountsTable, + Account, + $$AccountsTableFilterComposer, + $$AccountsTableOrderingComposer, + $$AccountsTableAnnotationComposer, + $$AccountsTableCreateCompanionBuilder, + $$AccountsTableUpdateCompanionBuilder, + (Account, BaseReferences<_$AppDatabase, $AccountsTable, Account>), + Account, + PrefetchHooks Function()>; +typedef $$FavoritesTableCreateCompanionBuilder = FavoritesCompanion Function({ + Value id, + required int accountId, + required int communityId, +}); +typedef $$FavoritesTableUpdateCompanionBuilder = FavoritesCompanion Function({ + Value id, + Value accountId, + Value communityId, +}); + +class $$FavoritesTableFilterComposer extends Composer<_$AppDatabase, $FavoritesTable> { + $$FavoritesTableFilterComposer({ + required super.$db, + required super.$table, + super.joinBuilder, + super.$addJoinBuilderToRootComposer, + super.$removeJoinBuilderFromRootComposer, + }); + ColumnFilters get id => $composableBuilder(column: $table.id, builder: (column) => ColumnFilters(column)); + + ColumnFilters get accountId => $composableBuilder(column: $table.accountId, builder: (column) => ColumnFilters(column)); + + ColumnFilters get communityId => $composableBuilder(column: $table.communityId, builder: (column) => ColumnFilters(column)); +} + +class $$FavoritesTableOrderingComposer extends Composer<_$AppDatabase, $FavoritesTable> { + $$FavoritesTableOrderingComposer({ + required super.$db, + required super.$table, + super.joinBuilder, + super.$addJoinBuilderToRootComposer, + super.$removeJoinBuilderFromRootComposer, + }); + ColumnOrderings get id => $composableBuilder(column: $table.id, builder: (column) => ColumnOrderings(column)); + + ColumnOrderings get accountId => $composableBuilder(column: $table.accountId, builder: (column) => ColumnOrderings(column)); + + ColumnOrderings get communityId => $composableBuilder(column: $table.communityId, builder: (column) => ColumnOrderings(column)); +} + +class $$FavoritesTableAnnotationComposer extends Composer<_$AppDatabase, $FavoritesTable> { + $$FavoritesTableAnnotationComposer({ + required super.$db, + required super.$table, + super.joinBuilder, + super.$addJoinBuilderToRootComposer, + super.$removeJoinBuilderFromRootComposer, + }); + GeneratedColumn get id => $composableBuilder(column: $table.id, builder: (column) => column); + + GeneratedColumn get accountId => $composableBuilder(column: $table.accountId, builder: (column) => column); + + GeneratedColumn get communityId => $composableBuilder(column: $table.communityId, builder: (column) => column); +} + +class $$FavoritesTableTableManager extends RootTableManager< + _$AppDatabase, + $FavoritesTable, + Favorite, + $$FavoritesTableFilterComposer, + $$FavoritesTableOrderingComposer, + $$FavoritesTableAnnotationComposer, + $$FavoritesTableCreateCompanionBuilder, + $$FavoritesTableUpdateCompanionBuilder, + (Favorite, BaseReferences<_$AppDatabase, $FavoritesTable, Favorite>), + Favorite, + PrefetchHooks Function()> { + $$FavoritesTableTableManager(_$AppDatabase db, $FavoritesTable table) + : super(TableManagerState( + db: db, + table: table, + createFilteringComposer: () => $$FavoritesTableFilterComposer($db: db, $table: table), + createOrderingComposer: () => $$FavoritesTableOrderingComposer($db: db, $table: table), + createComputedFieldComposer: () => $$FavoritesTableAnnotationComposer($db: db, $table: table), + updateCompanionCallback: ({ + Value id = const Value.absent(), + Value accountId = const Value.absent(), + Value communityId = const Value.absent(), + }) => + FavoritesCompanion( + id: id, + accountId: accountId, + communityId: communityId, + ), + createCompanionCallback: ({ + Value id = const Value.absent(), + required int accountId, + required int communityId, + }) => + FavoritesCompanion.insert( + id: id, + accountId: accountId, + communityId: communityId, + ), + withReferenceMapper: (p0) => p0.map((e) => (e.readTable(table), BaseReferences(db, table, e))).toList(), + prefetchHooksCallback: null, + )); +} + +typedef $$FavoritesTableProcessedTableManager = ProcessedTableManager< + _$AppDatabase, + $FavoritesTable, + Favorite, + $$FavoritesTableFilterComposer, + $$FavoritesTableOrderingComposer, + $$FavoritesTableAnnotationComposer, + $$FavoritesTableCreateCompanionBuilder, + $$FavoritesTableUpdateCompanionBuilder, + (Favorite, BaseReferences<_$AppDatabase, $FavoritesTable, Favorite>), + Favorite, + PrefetchHooks Function()>; +typedef $$LocalSubscriptionsTableCreateCompanionBuilder = LocalSubscriptionsCompanion Function({ + Value id, + required String name, + required String title, + required String actorId, + Value icon, +}); +typedef $$LocalSubscriptionsTableUpdateCompanionBuilder = LocalSubscriptionsCompanion Function({ + Value id, + Value name, + Value title, + Value actorId, + Value icon, +}); + +class $$LocalSubscriptionsTableFilterComposer extends Composer<_$AppDatabase, $LocalSubscriptionsTable> { + $$LocalSubscriptionsTableFilterComposer({ + required super.$db, + required super.$table, + super.joinBuilder, + super.$addJoinBuilderToRootComposer, + super.$removeJoinBuilderFromRootComposer, + }); + ColumnFilters get id => $composableBuilder(column: $table.id, builder: (column) => ColumnFilters(column)); + + ColumnFilters get name => $composableBuilder(column: $table.name, builder: (column) => ColumnFilters(column)); + + ColumnFilters get title => $composableBuilder(column: $table.title, builder: (column) => ColumnFilters(column)); + + ColumnFilters get actorId => $composableBuilder(column: $table.actorId, builder: (column) => ColumnFilters(column)); + + ColumnFilters get icon => $composableBuilder(column: $table.icon, builder: (column) => ColumnFilters(column)); +} + +class $$LocalSubscriptionsTableOrderingComposer extends Composer<_$AppDatabase, $LocalSubscriptionsTable> { + $$LocalSubscriptionsTableOrderingComposer({ + required super.$db, + required super.$table, + super.joinBuilder, + super.$addJoinBuilderToRootComposer, + super.$removeJoinBuilderFromRootComposer, + }); + ColumnOrderings get id => $composableBuilder(column: $table.id, builder: (column) => ColumnOrderings(column)); + + ColumnOrderings get name => $composableBuilder(column: $table.name, builder: (column) => ColumnOrderings(column)); + + ColumnOrderings get title => $composableBuilder(column: $table.title, builder: (column) => ColumnOrderings(column)); + + ColumnOrderings get actorId => $composableBuilder(column: $table.actorId, builder: (column) => ColumnOrderings(column)); + + ColumnOrderings get icon => $composableBuilder(column: $table.icon, builder: (column) => ColumnOrderings(column)); +} + +class $$LocalSubscriptionsTableAnnotationComposer extends Composer<_$AppDatabase, $LocalSubscriptionsTable> { + $$LocalSubscriptionsTableAnnotationComposer({ + required super.$db, + required super.$table, + super.joinBuilder, + super.$addJoinBuilderToRootComposer, + super.$removeJoinBuilderFromRootComposer, + }); + GeneratedColumn get id => $composableBuilder(column: $table.id, builder: (column) => column); + + GeneratedColumn get name => $composableBuilder(column: $table.name, builder: (column) => column); + + GeneratedColumn get title => $composableBuilder(column: $table.title, builder: (column) => column); + + GeneratedColumn get actorId => $composableBuilder(column: $table.actorId, builder: (column) => column); + + GeneratedColumn get icon => $composableBuilder(column: $table.icon, builder: (column) => column); +} + +class $$LocalSubscriptionsTableTableManager extends RootTableManager< + _$AppDatabase, + $LocalSubscriptionsTable, + LocalSubscription, + $$LocalSubscriptionsTableFilterComposer, + $$LocalSubscriptionsTableOrderingComposer, + $$LocalSubscriptionsTableAnnotationComposer, + $$LocalSubscriptionsTableCreateCompanionBuilder, + $$LocalSubscriptionsTableUpdateCompanionBuilder, + (LocalSubscription, BaseReferences<_$AppDatabase, $LocalSubscriptionsTable, LocalSubscription>), + LocalSubscription, + PrefetchHooks Function()> { + $$LocalSubscriptionsTableTableManager(_$AppDatabase db, $LocalSubscriptionsTable table) + : super(TableManagerState( + db: db, + table: table, + createFilteringComposer: () => $$LocalSubscriptionsTableFilterComposer($db: db, $table: table), + createOrderingComposer: () => $$LocalSubscriptionsTableOrderingComposer($db: db, $table: table), + createComputedFieldComposer: () => $$LocalSubscriptionsTableAnnotationComposer($db: db, $table: table), + updateCompanionCallback: ({ + Value id = const Value.absent(), + Value name = const Value.absent(), + Value title = const Value.absent(), + Value actorId = const Value.absent(), + Value icon = const Value.absent(), + }) => + LocalSubscriptionsCompanion( + id: id, + name: name, + title: title, + actorId: actorId, + icon: icon, + ), + createCompanionCallback: ({ + Value id = const Value.absent(), + required String name, + required String title, + required String actorId, + Value icon = const Value.absent(), + }) => + LocalSubscriptionsCompanion.insert( + id: id, + name: name, + title: title, + actorId: actorId, + icon: icon, + ), + withReferenceMapper: (p0) => p0.map((e) => (e.readTable(table), BaseReferences(db, table, e))).toList(), + prefetchHooksCallback: null, + )); +} + +typedef $$LocalSubscriptionsTableProcessedTableManager = ProcessedTableManager< + _$AppDatabase, + $LocalSubscriptionsTable, + LocalSubscription, + $$LocalSubscriptionsTableFilterComposer, + $$LocalSubscriptionsTableOrderingComposer, + $$LocalSubscriptionsTableAnnotationComposer, + $$LocalSubscriptionsTableCreateCompanionBuilder, + $$LocalSubscriptionsTableUpdateCompanionBuilder, + (LocalSubscription, BaseReferences<_$AppDatabase, $LocalSubscriptionsTable, LocalSubscription>), + LocalSubscription, + PrefetchHooks Function()>; +typedef $$UserLabelsTableCreateCompanionBuilder = UserLabelsCompanion Function({ + Value id, + required String username, + required String label, +}); +typedef $$UserLabelsTableUpdateCompanionBuilder = UserLabelsCompanion Function({ + Value id, + Value username, + Value label, +}); + +class $$UserLabelsTableFilterComposer extends Composer<_$AppDatabase, $UserLabelsTable> { + $$UserLabelsTableFilterComposer({ + required super.$db, + required super.$table, + super.joinBuilder, + super.$addJoinBuilderToRootComposer, + super.$removeJoinBuilderFromRootComposer, + }); + ColumnFilters get id => $composableBuilder(column: $table.id, builder: (column) => ColumnFilters(column)); + + ColumnFilters get username => $composableBuilder(column: $table.username, builder: (column) => ColumnFilters(column)); + + ColumnFilters get label => $composableBuilder(column: $table.label, builder: (column) => ColumnFilters(column)); +} + +class $$UserLabelsTableOrderingComposer extends Composer<_$AppDatabase, $UserLabelsTable> { + $$UserLabelsTableOrderingComposer({ + required super.$db, + required super.$table, + super.joinBuilder, + super.$addJoinBuilderToRootComposer, + super.$removeJoinBuilderFromRootComposer, + }); + ColumnOrderings get id => $composableBuilder(column: $table.id, builder: (column) => ColumnOrderings(column)); + + ColumnOrderings get username => $composableBuilder(column: $table.username, builder: (column) => ColumnOrderings(column)); + + ColumnOrderings get label => $composableBuilder(column: $table.label, builder: (column) => ColumnOrderings(column)); +} + +class $$UserLabelsTableAnnotationComposer extends Composer<_$AppDatabase, $UserLabelsTable> { + $$UserLabelsTableAnnotationComposer({ + required super.$db, + required super.$table, + super.joinBuilder, + super.$addJoinBuilderToRootComposer, + super.$removeJoinBuilderFromRootComposer, + }); + GeneratedColumn get id => $composableBuilder(column: $table.id, builder: (column) => column); + + GeneratedColumn get username => $composableBuilder(column: $table.username, builder: (column) => column); + + GeneratedColumn get label => $composableBuilder(column: $table.label, builder: (column) => column); +} + +class $$UserLabelsTableTableManager extends RootTableManager< + _$AppDatabase, + $UserLabelsTable, + UserLabel, + $$UserLabelsTableFilterComposer, + $$UserLabelsTableOrderingComposer, + $$UserLabelsTableAnnotationComposer, + $$UserLabelsTableCreateCompanionBuilder, + $$UserLabelsTableUpdateCompanionBuilder, + (UserLabel, BaseReferences<_$AppDatabase, $UserLabelsTable, UserLabel>), + UserLabel, + PrefetchHooks Function()> { + $$UserLabelsTableTableManager(_$AppDatabase db, $UserLabelsTable table) + : super(TableManagerState( + db: db, + table: table, + createFilteringComposer: () => $$UserLabelsTableFilterComposer($db: db, $table: table), + createOrderingComposer: () => $$UserLabelsTableOrderingComposer($db: db, $table: table), + createComputedFieldComposer: () => $$UserLabelsTableAnnotationComposer($db: db, $table: table), + updateCompanionCallback: ({ + Value id = const Value.absent(), + Value username = const Value.absent(), + Value label = const Value.absent(), + }) => + UserLabelsCompanion( + id: id, + username: username, + label: label, + ), + createCompanionCallback: ({ + Value id = const Value.absent(), + required String username, + required String label, + }) => + UserLabelsCompanion.insert( + id: id, + username: username, + label: label, + ), + withReferenceMapper: (p0) => p0.map((e) => (e.readTable(table), BaseReferences(db, table, e))).toList(), + prefetchHooksCallback: null, + )); +} + +typedef $$UserLabelsTableProcessedTableManager = ProcessedTableManager< + _$AppDatabase, + $UserLabelsTable, + UserLabel, + $$UserLabelsTableFilterComposer, + $$UserLabelsTableOrderingComposer, + $$UserLabelsTableAnnotationComposer, + $$UserLabelsTableCreateCompanionBuilder, + $$UserLabelsTableUpdateCompanionBuilder, + (UserLabel, BaseReferences<_$AppDatabase, $UserLabelsTable, UserLabel>), + UserLabel, + PrefetchHooks Function()>; +typedef $$DraftsTableCreateCompanionBuilder = DraftsCompanion Function({ + Value id, + required DraftType draftType, + Value existingId, + Value replyId, + Value title, + Value url, + Value customThumbnail, + Value altText, + Value body, +}); +typedef $$DraftsTableUpdateCompanionBuilder = DraftsCompanion Function({ + Value id, + Value draftType, + Value existingId, + Value replyId, + Value title, + Value url, + Value customThumbnail, + Value altText, + Value body, +}); + +class $$DraftsTableFilterComposer extends Composer<_$AppDatabase, $DraftsTable> { + $$DraftsTableFilterComposer({ + required super.$db, + required super.$table, + super.joinBuilder, + super.$addJoinBuilderToRootComposer, + super.$removeJoinBuilderFromRootComposer, + }); + ColumnFilters get id => $composableBuilder(column: $table.id, builder: (column) => ColumnFilters(column)); + + ColumnWithTypeConverterFilters get draftType => $composableBuilder(column: $table.draftType, builder: (column) => ColumnWithTypeConverterFilters(column)); + + ColumnFilters get existingId => $composableBuilder(column: $table.existingId, builder: (column) => ColumnFilters(column)); + + ColumnFilters get replyId => $composableBuilder(column: $table.replyId, builder: (column) => ColumnFilters(column)); + + ColumnFilters get title => $composableBuilder(column: $table.title, builder: (column) => ColumnFilters(column)); + + ColumnFilters get url => $composableBuilder(column: $table.url, builder: (column) => ColumnFilters(column)); + + ColumnFilters get customThumbnail => $composableBuilder(column: $table.customThumbnail, builder: (column) => ColumnFilters(column)); + + ColumnFilters get altText => $composableBuilder(column: $table.altText, builder: (column) => ColumnFilters(column)); + + ColumnFilters get body => $composableBuilder(column: $table.body, builder: (column) => ColumnFilters(column)); +} + +class $$DraftsTableOrderingComposer extends Composer<_$AppDatabase, $DraftsTable> { + $$DraftsTableOrderingComposer({ + required super.$db, + required super.$table, + super.joinBuilder, + super.$addJoinBuilderToRootComposer, + super.$removeJoinBuilderFromRootComposer, + }); + ColumnOrderings get id => $composableBuilder(column: $table.id, builder: (column) => ColumnOrderings(column)); + + ColumnOrderings get draftType => $composableBuilder(column: $table.draftType, builder: (column) => ColumnOrderings(column)); + + ColumnOrderings get existingId => $composableBuilder(column: $table.existingId, builder: (column) => ColumnOrderings(column)); + + ColumnOrderings get replyId => $composableBuilder(column: $table.replyId, builder: (column) => ColumnOrderings(column)); + + ColumnOrderings get title => $composableBuilder(column: $table.title, builder: (column) => ColumnOrderings(column)); + + ColumnOrderings get url => $composableBuilder(column: $table.url, builder: (column) => ColumnOrderings(column)); + + ColumnOrderings get customThumbnail => $composableBuilder(column: $table.customThumbnail, builder: (column) => ColumnOrderings(column)); + + ColumnOrderings get altText => $composableBuilder(column: $table.altText, builder: (column) => ColumnOrderings(column)); + + ColumnOrderings get body => $composableBuilder(column: $table.body, builder: (column) => ColumnOrderings(column)); +} + +class $$DraftsTableAnnotationComposer extends Composer<_$AppDatabase, $DraftsTable> { + $$DraftsTableAnnotationComposer({ + required super.$db, + required super.$table, + super.joinBuilder, + super.$addJoinBuilderToRootComposer, + super.$removeJoinBuilderFromRootComposer, + }); + GeneratedColumn get id => $composableBuilder(column: $table.id, builder: (column) => column); + + GeneratedColumnWithTypeConverter get draftType => $composableBuilder(column: $table.draftType, builder: (column) => column); + + GeneratedColumn get existingId => $composableBuilder(column: $table.existingId, builder: (column) => column); + + GeneratedColumn get replyId => $composableBuilder(column: $table.replyId, builder: (column) => column); + + GeneratedColumn get title => $composableBuilder(column: $table.title, builder: (column) => column); + + GeneratedColumn get url => $composableBuilder(column: $table.url, builder: (column) => column); + + GeneratedColumn get customThumbnail => $composableBuilder(column: $table.customThumbnail, builder: (column) => column); + + GeneratedColumn get altText => $composableBuilder(column: $table.altText, builder: (column) => column); + + GeneratedColumn get body => $composableBuilder(column: $table.body, builder: (column) => column); +} + +class $$DraftsTableTableManager extends RootTableManager<_$AppDatabase, $DraftsTable, Draft, $$DraftsTableFilterComposer, $$DraftsTableOrderingComposer, $$DraftsTableAnnotationComposer, + $$DraftsTableCreateCompanionBuilder, $$DraftsTableUpdateCompanionBuilder, (Draft, BaseReferences<_$AppDatabase, $DraftsTable, Draft>), Draft, PrefetchHooks Function()> { + $$DraftsTableTableManager(_$AppDatabase db, $DraftsTable table) + : super(TableManagerState( + db: db, + table: table, + createFilteringComposer: () => $$DraftsTableFilterComposer($db: db, $table: table), + createOrderingComposer: () => $$DraftsTableOrderingComposer($db: db, $table: table), + createComputedFieldComposer: () => $$DraftsTableAnnotationComposer($db: db, $table: table), + updateCompanionCallback: ({ + Value id = const Value.absent(), + Value draftType = const Value.absent(), + Value existingId = const Value.absent(), + Value replyId = const Value.absent(), + Value title = const Value.absent(), + Value url = const Value.absent(), + Value customThumbnail = const Value.absent(), + Value altText = const Value.absent(), + Value body = const Value.absent(), + }) => + DraftsCompanion( + id: id, + draftType: draftType, + existingId: existingId, + replyId: replyId, + title: title, + url: url, + customThumbnail: customThumbnail, + altText: altText, + body: body, + ), + createCompanionCallback: ({ + Value id = const Value.absent(), + required DraftType draftType, + Value existingId = const Value.absent(), + Value replyId = const Value.absent(), + Value title = const Value.absent(), + Value url = const Value.absent(), + Value customThumbnail = const Value.absent(), + Value altText = const Value.absent(), + Value body = const Value.absent(), + }) => + DraftsCompanion.insert( + id: id, + draftType: draftType, + existingId: existingId, + replyId: replyId, + title: title, + url: url, + customThumbnail: customThumbnail, + altText: altText, + body: body, + ), + withReferenceMapper: (p0) => p0.map((e) => (e.readTable(table), BaseReferences(db, table, e))).toList(), + prefetchHooksCallback: null, + )); +} + +typedef $$DraftsTableProcessedTableManager = ProcessedTableManager<_$AppDatabase, $DraftsTable, Draft, $$DraftsTableFilterComposer, $$DraftsTableOrderingComposer, $$DraftsTableAnnotationComposer, + $$DraftsTableCreateCompanionBuilder, $$DraftsTableUpdateCompanionBuilder, (Draft, BaseReferences<_$AppDatabase, $DraftsTable, Draft>), Draft, PrefetchHooks Function()>; + +class $AppDatabaseManager { + final _$AppDatabase _db; + $AppDatabaseManager(this._db); + $$AccountsTableTableManager get accounts => $$AccountsTableTableManager(_db, _db.accounts); + $$FavoritesTableTableManager get favorites => $$FavoritesTableTableManager(_db, _db.favorites); + $$LocalSubscriptionsTableTableManager get localSubscriptions => $$LocalSubscriptionsTableTableManager(_db, _db.localSubscriptions); + $$UserLabelsTableTableManager get userLabels => $$UserLabelsTableTableManager(_db, _db.userLabels); + $$DraftsTableTableManager get drafts => $$DraftsTableTableManager(_db, _db.drafts); +} diff --git a/lib/core/database/migrations.dart b/lib/core/database/migrations.dart index 59bad7604..268ef34e3 100644 --- a/lib/core/database/migrations.dart +++ b/lib/core/database/migrations.dart @@ -49,7 +49,7 @@ Future migrateToSQLite(AppDatabase database, {Database? originalDB, bool d jwt: Value(record['jwt']), instance: Value(record['instance']), userId: Value(record['userId']), - listIndex: -1, + listIndex: Value(-1), )); String? activeProfileId = prefs?.getString('active_profile_id'); diff --git a/lib/core/database/schema_versions.dart b/lib/core/database/schema_versions.dart index 128f283d2..763b0d401 100644 --- a/lib/core/database/schema_versions.dart +++ b/lib/core/database/schema_versions.dart @@ -1,3 +1,4 @@ +// dart format width=80 import 'package:drift/internal/versioned_schema.dart' as i0; import 'package:drift/drift.dart' as i1; import 'package:drift/drift.dart'; // ignore_for_file: type=lint,unused_import @@ -448,11 +449,121 @@ class Shape6 extends i0.VersionedTable { } i1.GeneratedColumn _column_21(String aliasedName) => i1.GeneratedColumn('list_index', aliasedName, false, type: i1.DriftSqlType.int, defaultValue: const Constant(-1)); + +final class Schema6 extends i0.VersionedSchema { + Schema6({required super.database}) : super(version: 6); + @override + late final List entities = [ + accounts, + favorites, + localSubscriptions, + userLabels, + drafts, + ]; + late final Shape6 accounts = Shape6( + source: i0.VersionedTable( + entityName: 'accounts', + withoutRowId: false, + isStrict: false, + tableConstraints: [], + columns: [ + _column_0, + _column_1, + _column_2, + _column_3, + _column_4, + _column_5, + _column_21, + ], + attachedDatabase: database, + ), + alias: null); + late final Shape1 favorites = Shape1( + source: i0.VersionedTable( + entityName: 'favorites', + withoutRowId: false, + isStrict: false, + tableConstraints: [], + columns: [ + _column_0, + _column_6, + _column_7, + ], + attachedDatabase: database, + ), + alias: null); + late final Shape2 localSubscriptions = Shape2( + source: i0.VersionedTable( + entityName: 'local_subscriptions', + withoutRowId: false, + isStrict: false, + tableConstraints: [], + columns: [ + _column_0, + _column_8, + _column_9, + _column_10, + _column_11, + ], + attachedDatabase: database, + ), + alias: null); + late final Shape3 userLabels = Shape3( + source: i0.VersionedTable( + entityName: 'user_labels', + withoutRowId: false, + isStrict: false, + tableConstraints: [], + columns: [ + _column_0, + _column_12, + _column_13, + ], + attachedDatabase: database, + ), + alias: null); + late final Shape7 drafts = Shape7( + source: i0.VersionedTable( + entityName: 'drafts', + withoutRowId: false, + isStrict: false, + tableConstraints: [], + columns: [ + _column_0, + _column_14, + _column_15, + _column_16, + _column_17, + _column_18, + _column_20, + _column_22, + _column_19, + ], + attachedDatabase: database, + ), + alias: null); +} + +class Shape7 extends i0.VersionedTable { + Shape7({required super.source, required super.alias}) : super.aliased(); + i1.GeneratedColumn get id => columnsByName['id']! as i1.GeneratedColumn; + i1.GeneratedColumn get draftType => columnsByName['draft_type']! as i1.GeneratedColumn; + i1.GeneratedColumn get existingId => columnsByName['existing_id']! as i1.GeneratedColumn; + i1.GeneratedColumn get replyId => columnsByName['reply_id']! as i1.GeneratedColumn; + i1.GeneratedColumn get title => columnsByName['title']! as i1.GeneratedColumn; + i1.GeneratedColumn get url => columnsByName['url']! as i1.GeneratedColumn; + i1.GeneratedColumn get customThumbnail => columnsByName['custom_thumbnail']! as i1.GeneratedColumn; + i1.GeneratedColumn get altText => columnsByName['alt_text']! as i1.GeneratedColumn; + i1.GeneratedColumn get body => columnsByName['body']! as i1.GeneratedColumn; +} + +i1.GeneratedColumn _column_22(String aliasedName) => i1.GeneratedColumn('alt_text', aliasedName, true, type: i1.DriftSqlType.string); i0.MigrationStepWithVersion migrationSteps({ required Future Function(i1.Migrator m, Schema2 schema) from1To2, required Future Function(i1.Migrator m, Schema3 schema) from2To3, required Future Function(i1.Migrator m, Schema4 schema) from3To4, required Future Function(i1.Migrator m, Schema5 schema) from4To5, + required Future Function(i1.Migrator m, Schema6 schema) from5To6, }) { return (currentVersion, database) async { switch (currentVersion) { @@ -476,6 +587,11 @@ i0.MigrationStepWithVersion migrationSteps({ final migrator = i1.Migrator(database, schema); await from4To5(migrator, schema); return 5; + case 5: + final schema = Schema6(database: database); + final migrator = i1.Migrator(database, schema); + await from5To6(migrator, schema); + return 6; default: throw ArgumentError.value('Unknown migration from $currentVersion'); } @@ -487,6 +603,7 @@ i1.OnUpgrade stepByStep({ required Future Function(i1.Migrator m, Schema3 schema) from2To3, required Future Function(i1.Migrator m, Schema4 schema) from3To4, required Future Function(i1.Migrator m, Schema5 schema) from4To5, + required Future Function(i1.Migrator m, Schema6 schema) from5To6, }) => i0.VersionedSchema.stepByStepHelper( step: migrationSteps( @@ -494,4 +611,5 @@ i1.OnUpgrade stepByStep({ from2To3: from2To3, from3To4: from3To4, from4To5: from4To5, + from5To6: from5To6, )); diff --git a/lib/core/database/tables.dart b/lib/core/database/tables.dart index ca5abfdf0..89dc679ec 100644 --- a/lib/core/database/tables.dart +++ b/lib/core/database/tables.dart @@ -39,5 +39,6 @@ class Drafts extends Table { TextColumn get title => text().nullable()(); TextColumn get url => text().nullable()(); TextColumn get customThumbnail => text().nullable()(); + TextColumn get altText => text().nullable()(); TextColumn get body => text().nullable()(); } diff --git a/lib/core/singletons/lemmy_client.dart b/lib/core/singletons/lemmy_client.dart index 7ea65c1c7..3d6a9b83e 100644 --- a/lib/core/singletons/lemmy_client.dart +++ b/lib/core/singletons/lemmy_client.dart @@ -95,6 +95,7 @@ enum LemmyFeature { multiRead(0, 19, 0, preRelease: ["rc", "1"]), hidePosts(0, 19, 4), customThumbnail(0, 19, 4), + altText(0, 19, 4), commentModLog(0, 19, 4), imageDimension(0, 19, 6), ; diff --git a/lib/feed/utils/post.dart b/lib/feed/utils/post.dart index 0a9dc61fc..633ab607a 100644 --- a/lib/feed/utils/post.dart +++ b/lib/feed/utils/post.dart @@ -135,6 +135,7 @@ Future createPost({ String? body, String? url, String? customThumbnail, + String? altText, bool? nsfw, int? postIdBeingEdited, int? languageId, @@ -152,6 +153,7 @@ Future createPost({ body: body, url: url?.isEmpty == true ? null : url, customThumbnail: customThumbnail?.isEmpty == true ? null : customThumbnail, + altText: altText?.isEmpty == true ? null : altText, nsfw: nsfw, postId: postIdBeingEdited, languageId: languageId, @@ -164,6 +166,7 @@ Future createPost({ body: body, url: url?.isEmpty == true ? null : url, customThumbnail: customThumbnail?.isEmpty == true ? null : customThumbnail, + altText: altText?.isEmpty == true ? null : altText, nsfw: nsfw, languageId: languageId, )); @@ -179,6 +182,7 @@ Future createExamplePost({ String? postUrl, String? postBody, String? postThumbnailUrl, + String? postAltText, bool? locked, bool? nsfw, bool? pinned, @@ -199,6 +203,7 @@ Future createExamplePost({ url: postUrl, body: postBody, thumbnailUrl: postThumbnailUrl, + altText: postAltText, creatorId: 1, communityId: 1, removed: false, diff --git a/lib/l10n/app_en.arb b/lib/l10n/app_en.arb index 5cb2bf6c8..e9ec5b5fe 100644 --- a/lib/l10n/app_en.arb +++ b/lib/l10n/app_en.arb @@ -105,6 +105,10 @@ }, "alreadyPostedTo": "Already posted to", "@alreadyPostedTo": {}, + "altText": "Alt Text", + "@altText": { + "description": "Create/edit post field for adding alt text to an image post" + }, "alternateSources": "Alternate Sources", "@alternateSources": { "description": "Action for viewing a link from alternate sources" diff --git a/lib/post/cubit/create_post_cubit.dart b/lib/post/cubit/create_post_cubit.dart index 61672e3e1..cfb292835 100644 --- a/lib/post/cubit/create_post_cubit.dart +++ b/lib/post/cubit/create_post_cubit.dart @@ -55,6 +55,7 @@ class CreatePostCubit extends Cubit { String? body, String? url, String? customThumbnail, + String? altText, bool? nsfw, int? postIdBeingEdited, int? languageId, @@ -68,6 +69,7 @@ class CreatePostCubit extends Cubit { body: body, url: url, customThumbnail: customThumbnail, + altText: altText, nsfw: nsfw, postIdBeingEdited: postIdBeingEdited, languageId: languageId, From f85a85f3a6e9739ec65ce8f775d0dfdec68ac7fc Mon Sep 17 00:00:00 2001 From: Micah Morrison Date: Tue, 17 Dec 2024 11:16:34 -0500 Subject: [PATCH 2/2] Handle db migration downgrade for alt_text --- lib/core/database/database.dart | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/lib/core/database/database.dart b/lib/core/database/database.dart index 639cd0e5b..33b1450ba 100644 --- a/lib/core/database/database.dart +++ b/lib/core/database/database.dart @@ -82,9 +82,34 @@ class AppDatabase extends _$AppDatabase { await impl.validateDatabaseSchema(this); await customStatement('PRAGMA foreign_keys = ON;'); }, + beforeOpen: (details) async { + if (details.versionBefore != null && details.versionBefore! > details.versionNow) { + await _onDowngrade(this, details.versionBefore!, details.versionNow); + } + }, ); } +Future _onDowngrade(AppDatabase database, int fromVersion, int toVersion) async { + await database.customStatement('PRAGMA foreign_keys = OFF'); + + int current = fromVersion; + while (current > toVersion) { + int target = current - 1; + await _onDownGradeOneStep(database, current, target); + current = target; + } + + await database.customStatement('PRAGMA foreign_keys=ON;'); +} + +Future _onDownGradeOneStep(AppDatabase database, int fromVersion, int toVersion) async { + if (fromVersion == 6 && toVersion == 5) { + // Drop the alt_text column on the drafts table + await database.customStatement('ALTER TABLE drafts DROP COLUMN alt_text'); + } +} + Future exportDatabase() async { final Directory dbFolder = await getApplicationDocumentsDirectory(); final File file = File(join(dbFolder.path, 'thunder.sqlite'));