Compare commits
32 Commits
Author | SHA1 | Date | |
---|---|---|---|
c9727e92b8
|
|||
9b8768061d
|
|||
0949f0da54
|
|||
215ca705ac
|
|||
03457af04a
|
|||
73c6a1febf
|
|||
ba8d30bcde
|
|||
8449658b47
|
|||
c7f417234e
|
|||
6c847ee1e1
|
|||
18ad4d376e
|
|||
c4d5ba5c9d
|
|||
1069669049
|
|||
aa648fec62
|
|||
541900673a
|
|||
265502ffd0
|
|||
3bd79350d1
|
|||
5294d1fb23
|
|||
ec1269dcf1
|
|||
edb0a25f34
|
|||
7cd10118cc
|
|||
fcddc8f345
|
|||
1cc34240da
|
|||
013f7f02bc
|
|||
4e79e4100f
|
|||
feda1f067f
|
|||
fe0e192a43
|
|||
93df294142
|
|||
78d65c39f3
|
|||
18b0dbd797
|
|||
80cc8cbb40
|
|||
646e95a9fc
|
@@ -24,6 +24,8 @@ android {
|
|||||||
ndkVersion = "29.0.13113456"
|
ndkVersion = "29.0.13113456"
|
||||||
|
|
||||||
compileOptions {
|
compileOptions {
|
||||||
|
isCoreLibraryDesugaringEnabled = true
|
||||||
|
|
||||||
sourceCompatibility = JavaVersion.VERSION_17
|
sourceCompatibility = JavaVersion.VERSION_17
|
||||||
targetCompatibility = JavaVersion.VERSION_17
|
targetCompatibility = JavaVersion.VERSION_17
|
||||||
}
|
}
|
||||||
@@ -63,6 +65,8 @@ android {
|
|||||||
}
|
}
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
|
coreLibraryDesugaring("com.android.tools:desugar_jdk_libs:2.1.4")
|
||||||
|
|
||||||
implementation("com.google.android.material:material:1.12.0")
|
implementation("com.google.android.material:material:1.12.0")
|
||||||
implementation("com.github.bumptech.glide:glide:4.16.0")
|
implementation("com.github.bumptech.glide:glide:4.16.0")
|
||||||
implementation("com.squareup.okhttp3:okhttp:5.1.0")
|
implementation("com.squareup.okhttp3:okhttp:5.1.0")
|
||||||
|
@@ -133,6 +133,25 @@
|
|||||||
"other": "{} replies"
|
"other": "{} replies"
|
||||||
},
|
},
|
||||||
"forward": "Forward",
|
"forward": "Forward",
|
||||||
|
"award": "Award",
|
||||||
|
"awardPost": "Award Post",
|
||||||
|
"awardMessage": "Message",
|
||||||
|
"awardMessageHint": "Enter your award message...",
|
||||||
|
"awardAttitude": "Attitude",
|
||||||
|
"awardAttitudePositive": "Positive",
|
||||||
|
"awardAttitudeNegative": "Negative",
|
||||||
|
"awardAmount": "Amount",
|
||||||
|
"awardAmountHint": "Enter amount...",
|
||||||
|
"awardAmountRequired": "Amount is required",
|
||||||
|
"awardAmountInvalid": "Please enter a valid amount",
|
||||||
|
"awardMessageTooLong": "Message is too long (max 4096 characters)",
|
||||||
|
"awardSuccess": "Award sent successfully!",
|
||||||
|
"awardSubmit": "Award",
|
||||||
|
"awardPostPreview": "Post Preview",
|
||||||
|
"awardNoContent": "No content available",
|
||||||
|
"awardByPublisher": "By {}",
|
||||||
|
"awardBenefits": "Award Benefits",
|
||||||
|
"awardBenefitsDescription": "Awarding this post increases its value and visibility. Higher valued posts have a better chance of being featured and highlighted in the community.",
|
||||||
"repliedTo": "Replied to",
|
"repliedTo": "Replied to",
|
||||||
"forwarded": "Forwarded",
|
"forwarded": "Forwarded",
|
||||||
"hasAttachments": {
|
"hasAttachments": {
|
||||||
@@ -452,6 +471,8 @@
|
|||||||
"close": "Close",
|
"close": "Close",
|
||||||
"drafts": "Drafts",
|
"drafts": "Drafts",
|
||||||
"noDrafts": "No drafts yet",
|
"noDrafts": "No drafts yet",
|
||||||
|
"searchDrafts": "Search drafts...",
|
||||||
|
"noSearchResults": "No search results",
|
||||||
"articleDrafts": "Article drafts",
|
"articleDrafts": "Article drafts",
|
||||||
"postDrafts": "Post drafts",
|
"postDrafts": "Post drafts",
|
||||||
"saveDraft": "Save draft",
|
"saveDraft": "Save draft",
|
||||||
@@ -498,6 +519,10 @@
|
|||||||
"contactMethodSetPrimary": "Set as Primary",
|
"contactMethodSetPrimary": "Set as Primary",
|
||||||
"contactMethodSetPrimaryHint": "Set this contact method as your primary contact method for account recovery and notifications",
|
"contactMethodSetPrimaryHint": "Set this contact method as your primary contact method for account recovery and notifications",
|
||||||
"contactMethodDeleteHint": "Are you sure to delete this contact method? This action cannot be undone.",
|
"contactMethodDeleteHint": "Are you sure to delete this contact method? This action cannot be undone.",
|
||||||
|
"contactMethodMakePublic": "Make Public",
|
||||||
|
"contactMethodMakePrivate": "Make Private",
|
||||||
|
"contactMethodPublic": "Public",
|
||||||
|
"contactMethodPrivate": "Private",
|
||||||
"chatNotifyLevel": "Notify Level",
|
"chatNotifyLevel": "Notify Level",
|
||||||
"chatNotifyLevelDescription": "Decide how many notifications you will receive.",
|
"chatNotifyLevelDescription": "Decide how many notifications you will receive.",
|
||||||
"chatNotifyLevelAll": "All",
|
"chatNotifyLevelAll": "All",
|
||||||
@@ -977,5 +1002,19 @@
|
|||||||
"pinned": "Pinned",
|
"pinned": "Pinned",
|
||||||
"noResultsFound": "No results found",
|
"noResultsFound": "No results found",
|
||||||
"toggleFilters": "Toggle filters",
|
"toggleFilters": "Toggle filters",
|
||||||
"notableDayNext": "{} is in"
|
"notableDayNext": "{} is in",
|
||||||
|
"expandPoll": "Expand Poll",
|
||||||
|
"collapsePoll": "Collapse Poll",
|
||||||
|
"embedView": "Embed View",
|
||||||
|
"embedUri": "Embed URI",
|
||||||
|
"aspectRatio": "Aspect Ratio",
|
||||||
|
"renderer": "Renderer",
|
||||||
|
"addEmbed": "Add Embed",
|
||||||
|
"editEmbed": "Edit Embed",
|
||||||
|
"deleteEmbed": "Delete Embed",
|
||||||
|
"deleteEmbedConfirm": "Are you sure you want to delete this embed?",
|
||||||
|
"currentEmbed": "Current Embed",
|
||||||
|
"noEmbed": "No embed yet",
|
||||||
|
"save": "Save",
|
||||||
|
"webView": "Web View"
|
||||||
}
|
}
|
||||||
|
@@ -2,8 +2,15 @@ import 'package:drift/drift.dart';
|
|||||||
|
|
||||||
class PostDrafts extends Table {
|
class PostDrafts extends Table {
|
||||||
TextColumn get id => text()();
|
TextColumn get id => text()();
|
||||||
TextColumn get post => text()(); // Store SnPost model as JSON string
|
// Searchable fields stored separately for performance
|
||||||
|
TextColumn get title => text().nullable()();
|
||||||
|
TextColumn get description => text().nullable()();
|
||||||
|
TextColumn get content => text().nullable()();
|
||||||
|
IntColumn get visibility => integer().withDefault(const Constant(0))();
|
||||||
|
IntColumn get type => integer().withDefault(const Constant(0))();
|
||||||
DateTimeColumn get lastModified => dateTime()();
|
DateTimeColumn get lastModified => dateTime()();
|
||||||
|
// Full post data stored as JSON for complete restoration
|
||||||
|
TextColumn get postData => text()();
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Set<Column> get primaryKey => {id};
|
Set<Column> get primaryKey => {id};
|
||||||
|
@@ -12,7 +12,7 @@ class AppDatabase extends _$AppDatabase {
|
|||||||
AppDatabase(super.e);
|
AppDatabase(super.e);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
int get schemaVersion => 4;
|
int get schemaVersion => 6;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
MigrationStrategy get migration => MigrationStrategy(
|
MigrationStrategy get migration => MigrationStrategy(
|
||||||
@@ -28,9 +28,67 @@ class AppDatabase extends _$AppDatabase {
|
|||||||
// Drop old draft tables if they exist
|
// Drop old draft tables if they exist
|
||||||
await m.createTable(postDrafts);
|
await m.createTable(postDrafts);
|
||||||
}
|
}
|
||||||
|
if (from < 6) {
|
||||||
|
// Migrate from old schema to new schema with separate searchable fields
|
||||||
|
await _migrateToVersion6(m);
|
||||||
|
}
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
|
Future<void> _migrateToVersion6(Migrator m) async {
|
||||||
|
// Rename existing table to old if it exists
|
||||||
|
try {
|
||||||
|
await customStatement(
|
||||||
|
'ALTER TABLE post_drafts RENAME TO post_drafts_old',
|
||||||
|
);
|
||||||
|
} catch (e) {
|
||||||
|
// Table might not exist
|
||||||
|
}
|
||||||
|
|
||||||
|
// Drop the table
|
||||||
|
await customStatement('DROP TABLE IF EXISTS post_drafts');
|
||||||
|
|
||||||
|
// Create new table
|
||||||
|
await m.createTable(postDrafts);
|
||||||
|
|
||||||
|
// Migrate existing data if any
|
||||||
|
try {
|
||||||
|
final oldDrafts =
|
||||||
|
await customSelect(
|
||||||
|
'SELECT id, post, lastModified FROM post_drafts_old',
|
||||||
|
readsFrom: {postDrafts},
|
||||||
|
).get();
|
||||||
|
|
||||||
|
for (final row in oldDrafts) {
|
||||||
|
final postJson = row.read<String>('post');
|
||||||
|
final id = row.read<String>('id');
|
||||||
|
final lastModified = row.read<DateTime>('lastModified');
|
||||||
|
|
||||||
|
if (postJson.isNotEmpty) {
|
||||||
|
final post = SnPost.fromJson(jsonDecode(postJson));
|
||||||
|
await into(postDrafts).insert(
|
||||||
|
PostDraftsCompanion(
|
||||||
|
id: Value(id),
|
||||||
|
title: Value(post.title),
|
||||||
|
description: Value(post.description),
|
||||||
|
content: Value(post.content),
|
||||||
|
visibility: Value(post.visibility),
|
||||||
|
type: Value(post.type),
|
||||||
|
lastModified: Value(lastModified),
|
||||||
|
postData: Value(postJson),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Drop old table
|
||||||
|
await customStatement('DROP TABLE IF EXISTS post_drafts_old');
|
||||||
|
} catch (e) {
|
||||||
|
// If migration fails, just recreate the table
|
||||||
|
await m.createTable(postDrafts);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Methods for chat messages
|
// Methods for chat messages
|
||||||
Future<List<ChatMessage>> getMessagesForRoom(
|
Future<List<ChatMessage>> getMessagesForRoom(
|
||||||
String roomId, {
|
String roomId, {
|
||||||
@@ -69,7 +127,9 @@ class AppDatabase extends _$AppDatabase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Future<int> getTotalMessagesForRoom(String roomId) {
|
Future<int> getTotalMessagesForRoom(String roomId) {
|
||||||
return (select(chatMessages)..where((m) => m.roomId.equals(roomId))).get().then((list) => list.length);
|
return (select(
|
||||||
|
chatMessages,
|
||||||
|
)..where((m) => m.roomId.equals(roomId))).get().then((list) => list.length);
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<List<LocalChatMessage>> searchMessages(
|
Future<List<LocalChatMessage>> searchMessages(
|
||||||
@@ -85,10 +145,6 @@ class AppDatabase extends _$AppDatabase {
|
|||||||
..where((m) => m.content.like('%${query.toLowerCase()}%'));
|
..where((m) => m.content.like('%${query.toLowerCase()}%'));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
final messages =
|
final messages =
|
||||||
await (selectStatement
|
await (selectStatement
|
||||||
..orderBy([(m) => OrderingTerm.desc(m.createdAt)]))
|
..orderBy([(m) => OrderingTerm.desc(m.createdAt)]))
|
||||||
@@ -129,10 +185,31 @@ class AppDatabase extends _$AppDatabase {
|
|||||||
Future<List<SnPost>> getAllPostDrafts() async {
|
Future<List<SnPost>> getAllPostDrafts() async {
|
||||||
final drafts = await select(postDrafts).get();
|
final drafts = await select(postDrafts).get();
|
||||||
return drafts
|
return drafts
|
||||||
.map((draft) => SnPost.fromJson(jsonDecode(draft.post)))
|
.map((draft) => SnPost.fromJson(jsonDecode(draft.postData)))
|
||||||
.toList();
|
.toList();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Future<List<PostDraft>> getAllPostDraftRecords() async {
|
||||||
|
return await select(postDrafts).get();
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<List<PostDraft>> searchPostDrafts(String query) async {
|
||||||
|
if (query.isEmpty) {
|
||||||
|
return await select(postDrafts).get();
|
||||||
|
}
|
||||||
|
|
||||||
|
final searchTerm = '%${query.toLowerCase()}%';
|
||||||
|
return await (select(postDrafts)
|
||||||
|
..where(
|
||||||
|
(draft) =>
|
||||||
|
draft.title.like(searchTerm) |
|
||||||
|
draft.description.like(searchTerm) |
|
||||||
|
draft.content.like(searchTerm),
|
||||||
|
)
|
||||||
|
..orderBy([(draft) => OrderingTerm.desc(draft.lastModified)]))
|
||||||
|
.get();
|
||||||
|
}
|
||||||
|
|
||||||
Future<void> addPostDraft(PostDraftsCompanion entry) async {
|
Future<void> addPostDraft(PostDraftsCompanion entry) async {
|
||||||
await into(postDrafts).insert(entry, mode: InsertMode.replace);
|
await into(postDrafts).insert(entry, mode: InsertMode.replace);
|
||||||
}
|
}
|
||||||
@@ -144,4 +221,9 @@ class AppDatabase extends _$AppDatabase {
|
|||||||
Future<void> clearAllPostDrafts() async {
|
Future<void> clearAllPostDrafts() async {
|
||||||
await delete(postDrafts).go();
|
await delete(postDrafts).go();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Future<PostDraft?> getPostDraftById(String id) async {
|
||||||
|
return await (select(postDrafts)
|
||||||
|
..where((tbl) => tbl.id.equals(id))).getSingleOrNull();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -584,14 +584,58 @@ class $PostDraftsTable extends PostDrafts
|
|||||||
type: DriftSqlType.string,
|
type: DriftSqlType.string,
|
||||||
requiredDuringInsert: true,
|
requiredDuringInsert: true,
|
||||||
);
|
);
|
||||||
static const VerificationMeta _postMeta = const VerificationMeta('post');
|
static const VerificationMeta _titleMeta = const VerificationMeta('title');
|
||||||
@override
|
@override
|
||||||
late final GeneratedColumn<String> post = GeneratedColumn<String>(
|
late final GeneratedColumn<String> title = GeneratedColumn<String>(
|
||||||
'post',
|
'title',
|
||||||
|
aliasedName,
|
||||||
|
true,
|
||||||
|
type: DriftSqlType.string,
|
||||||
|
requiredDuringInsert: false,
|
||||||
|
);
|
||||||
|
static const VerificationMeta _descriptionMeta = const VerificationMeta(
|
||||||
|
'description',
|
||||||
|
);
|
||||||
|
@override
|
||||||
|
late final GeneratedColumn<String> description = GeneratedColumn<String>(
|
||||||
|
'description',
|
||||||
|
aliasedName,
|
||||||
|
true,
|
||||||
|
type: DriftSqlType.string,
|
||||||
|
requiredDuringInsert: false,
|
||||||
|
);
|
||||||
|
static const VerificationMeta _contentMeta = const VerificationMeta(
|
||||||
|
'content',
|
||||||
|
);
|
||||||
|
@override
|
||||||
|
late final GeneratedColumn<String> content = GeneratedColumn<String>(
|
||||||
|
'content',
|
||||||
|
aliasedName,
|
||||||
|
true,
|
||||||
|
type: DriftSqlType.string,
|
||||||
|
requiredDuringInsert: false,
|
||||||
|
);
|
||||||
|
static const VerificationMeta _visibilityMeta = const VerificationMeta(
|
||||||
|
'visibility',
|
||||||
|
);
|
||||||
|
@override
|
||||||
|
late final GeneratedColumn<int> visibility = GeneratedColumn<int>(
|
||||||
|
'visibility',
|
||||||
aliasedName,
|
aliasedName,
|
||||||
false,
|
false,
|
||||||
type: DriftSqlType.string,
|
type: DriftSqlType.int,
|
||||||
requiredDuringInsert: true,
|
requiredDuringInsert: false,
|
||||||
|
defaultValue: const Constant(0),
|
||||||
|
);
|
||||||
|
static const VerificationMeta _typeMeta = const VerificationMeta('type');
|
||||||
|
@override
|
||||||
|
late final GeneratedColumn<int> type = GeneratedColumn<int>(
|
||||||
|
'type',
|
||||||
|
aliasedName,
|
||||||
|
false,
|
||||||
|
type: DriftSqlType.int,
|
||||||
|
requiredDuringInsert: false,
|
||||||
|
defaultValue: const Constant(0),
|
||||||
);
|
);
|
||||||
static const VerificationMeta _lastModifiedMeta = const VerificationMeta(
|
static const VerificationMeta _lastModifiedMeta = const VerificationMeta(
|
||||||
'lastModified',
|
'lastModified',
|
||||||
@@ -604,8 +648,28 @@ class $PostDraftsTable extends PostDrafts
|
|||||||
type: DriftSqlType.dateTime,
|
type: DriftSqlType.dateTime,
|
||||||
requiredDuringInsert: true,
|
requiredDuringInsert: true,
|
||||||
);
|
);
|
||||||
|
static const VerificationMeta _postDataMeta = const VerificationMeta(
|
||||||
|
'postData',
|
||||||
|
);
|
||||||
@override
|
@override
|
||||||
List<GeneratedColumn> get $columns => [id, post, lastModified];
|
late final GeneratedColumn<String> postData = GeneratedColumn<String>(
|
||||||
|
'post_data',
|
||||||
|
aliasedName,
|
||||||
|
false,
|
||||||
|
type: DriftSqlType.string,
|
||||||
|
requiredDuringInsert: true,
|
||||||
|
);
|
||||||
|
@override
|
||||||
|
List<GeneratedColumn> get $columns => [
|
||||||
|
id,
|
||||||
|
title,
|
||||||
|
description,
|
||||||
|
content,
|
||||||
|
visibility,
|
||||||
|
type,
|
||||||
|
lastModified,
|
||||||
|
postData,
|
||||||
|
];
|
||||||
@override
|
@override
|
||||||
String get aliasedName => _alias ?? actualTableName;
|
String get aliasedName => _alias ?? actualTableName;
|
||||||
@override
|
@override
|
||||||
@@ -623,13 +687,38 @@ class $PostDraftsTable extends PostDrafts
|
|||||||
} else if (isInserting) {
|
} else if (isInserting) {
|
||||||
context.missing(_idMeta);
|
context.missing(_idMeta);
|
||||||
}
|
}
|
||||||
if (data.containsKey('post')) {
|
if (data.containsKey('title')) {
|
||||||
context.handle(
|
context.handle(
|
||||||
_postMeta,
|
_titleMeta,
|
||||||
post.isAcceptableOrUnknown(data['post']!, _postMeta),
|
title.isAcceptableOrUnknown(data['title']!, _titleMeta),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
if (data.containsKey('description')) {
|
||||||
|
context.handle(
|
||||||
|
_descriptionMeta,
|
||||||
|
description.isAcceptableOrUnknown(
|
||||||
|
data['description']!,
|
||||||
|
_descriptionMeta,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
if (data.containsKey('content')) {
|
||||||
|
context.handle(
|
||||||
|
_contentMeta,
|
||||||
|
content.isAcceptableOrUnknown(data['content']!, _contentMeta),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
if (data.containsKey('visibility')) {
|
||||||
|
context.handle(
|
||||||
|
_visibilityMeta,
|
||||||
|
visibility.isAcceptableOrUnknown(data['visibility']!, _visibilityMeta),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
if (data.containsKey('type')) {
|
||||||
|
context.handle(
|
||||||
|
_typeMeta,
|
||||||
|
type.isAcceptableOrUnknown(data['type']!, _typeMeta),
|
||||||
);
|
);
|
||||||
} else if (isInserting) {
|
|
||||||
context.missing(_postMeta);
|
|
||||||
}
|
}
|
||||||
if (data.containsKey('last_modified')) {
|
if (data.containsKey('last_modified')) {
|
||||||
context.handle(
|
context.handle(
|
||||||
@@ -642,6 +731,14 @@ class $PostDraftsTable extends PostDrafts
|
|||||||
} else if (isInserting) {
|
} else if (isInserting) {
|
||||||
context.missing(_lastModifiedMeta);
|
context.missing(_lastModifiedMeta);
|
||||||
}
|
}
|
||||||
|
if (data.containsKey('post_data')) {
|
||||||
|
context.handle(
|
||||||
|
_postDataMeta,
|
||||||
|
postData.isAcceptableOrUnknown(data['post_data']!, _postDataMeta),
|
||||||
|
);
|
||||||
|
} else if (isInserting) {
|
||||||
|
context.missing(_postDataMeta);
|
||||||
|
}
|
||||||
return context;
|
return context;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -656,16 +753,38 @@ class $PostDraftsTable extends PostDrafts
|
|||||||
DriftSqlType.string,
|
DriftSqlType.string,
|
||||||
data['${effectivePrefix}id'],
|
data['${effectivePrefix}id'],
|
||||||
)!,
|
)!,
|
||||||
post:
|
title: attachedDatabase.typeMapping.read(
|
||||||
|
DriftSqlType.string,
|
||||||
|
data['${effectivePrefix}title'],
|
||||||
|
),
|
||||||
|
description: attachedDatabase.typeMapping.read(
|
||||||
|
DriftSqlType.string,
|
||||||
|
data['${effectivePrefix}description'],
|
||||||
|
),
|
||||||
|
content: attachedDatabase.typeMapping.read(
|
||||||
|
DriftSqlType.string,
|
||||||
|
data['${effectivePrefix}content'],
|
||||||
|
),
|
||||||
|
visibility:
|
||||||
attachedDatabase.typeMapping.read(
|
attachedDatabase.typeMapping.read(
|
||||||
DriftSqlType.string,
|
DriftSqlType.int,
|
||||||
data['${effectivePrefix}post'],
|
data['${effectivePrefix}visibility'],
|
||||||
|
)!,
|
||||||
|
type:
|
||||||
|
attachedDatabase.typeMapping.read(
|
||||||
|
DriftSqlType.int,
|
||||||
|
data['${effectivePrefix}type'],
|
||||||
)!,
|
)!,
|
||||||
lastModified:
|
lastModified:
|
||||||
attachedDatabase.typeMapping.read(
|
attachedDatabase.typeMapping.read(
|
||||||
DriftSqlType.dateTime,
|
DriftSqlType.dateTime,
|
||||||
data['${effectivePrefix}last_modified'],
|
data['${effectivePrefix}last_modified'],
|
||||||
)!,
|
)!,
|
||||||
|
postData:
|
||||||
|
attachedDatabase.typeMapping.read(
|
||||||
|
DriftSqlType.string,
|
||||||
|
data['${effectivePrefix}post_data'],
|
||||||
|
)!,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -677,27 +796,60 @@ class $PostDraftsTable extends PostDrafts
|
|||||||
|
|
||||||
class PostDraft extends DataClass implements Insertable<PostDraft> {
|
class PostDraft extends DataClass implements Insertable<PostDraft> {
|
||||||
final String id;
|
final String id;
|
||||||
final String post;
|
final String? title;
|
||||||
|
final String? description;
|
||||||
|
final String? content;
|
||||||
|
final int visibility;
|
||||||
|
final int type;
|
||||||
final DateTime lastModified;
|
final DateTime lastModified;
|
||||||
|
final String postData;
|
||||||
const PostDraft({
|
const PostDraft({
|
||||||
required this.id,
|
required this.id,
|
||||||
required this.post,
|
this.title,
|
||||||
|
this.description,
|
||||||
|
this.content,
|
||||||
|
required this.visibility,
|
||||||
|
required this.type,
|
||||||
required this.lastModified,
|
required this.lastModified,
|
||||||
|
required this.postData,
|
||||||
});
|
});
|
||||||
@override
|
@override
|
||||||
Map<String, Expression> toColumns(bool nullToAbsent) {
|
Map<String, Expression> toColumns(bool nullToAbsent) {
|
||||||
final map = <String, Expression>{};
|
final map = <String, Expression>{};
|
||||||
map['id'] = Variable<String>(id);
|
map['id'] = Variable<String>(id);
|
||||||
map['post'] = Variable<String>(post);
|
if (!nullToAbsent || title != null) {
|
||||||
|
map['title'] = Variable<String>(title);
|
||||||
|
}
|
||||||
|
if (!nullToAbsent || description != null) {
|
||||||
|
map['description'] = Variable<String>(description);
|
||||||
|
}
|
||||||
|
if (!nullToAbsent || content != null) {
|
||||||
|
map['content'] = Variable<String>(content);
|
||||||
|
}
|
||||||
|
map['visibility'] = Variable<int>(visibility);
|
||||||
|
map['type'] = Variable<int>(type);
|
||||||
map['last_modified'] = Variable<DateTime>(lastModified);
|
map['last_modified'] = Variable<DateTime>(lastModified);
|
||||||
|
map['post_data'] = Variable<String>(postData);
|
||||||
return map;
|
return map;
|
||||||
}
|
}
|
||||||
|
|
||||||
PostDraftsCompanion toCompanion(bool nullToAbsent) {
|
PostDraftsCompanion toCompanion(bool nullToAbsent) {
|
||||||
return PostDraftsCompanion(
|
return PostDraftsCompanion(
|
||||||
id: Value(id),
|
id: Value(id),
|
||||||
post: Value(post),
|
title:
|
||||||
|
title == null && nullToAbsent ? const Value.absent() : Value(title),
|
||||||
|
description:
|
||||||
|
description == null && nullToAbsent
|
||||||
|
? const Value.absent()
|
||||||
|
: Value(description),
|
||||||
|
content:
|
||||||
|
content == null && nullToAbsent
|
||||||
|
? const Value.absent()
|
||||||
|
: Value(content),
|
||||||
|
visibility: Value(visibility),
|
||||||
|
type: Value(type),
|
||||||
lastModified: Value(lastModified),
|
lastModified: Value(lastModified),
|
||||||
|
postData: Value(postData),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -708,8 +860,13 @@ class PostDraft extends DataClass implements Insertable<PostDraft> {
|
|||||||
serializer ??= driftRuntimeOptions.defaultSerializer;
|
serializer ??= driftRuntimeOptions.defaultSerializer;
|
||||||
return PostDraft(
|
return PostDraft(
|
||||||
id: serializer.fromJson<String>(json['id']),
|
id: serializer.fromJson<String>(json['id']),
|
||||||
post: serializer.fromJson<String>(json['post']),
|
title: serializer.fromJson<String?>(json['title']),
|
||||||
|
description: serializer.fromJson<String?>(json['description']),
|
||||||
|
content: serializer.fromJson<String?>(json['content']),
|
||||||
|
visibility: serializer.fromJson<int>(json['visibility']),
|
||||||
|
type: serializer.fromJson<int>(json['type']),
|
||||||
lastModified: serializer.fromJson<DateTime>(json['lastModified']),
|
lastModified: serializer.fromJson<DateTime>(json['lastModified']),
|
||||||
|
postData: serializer.fromJson<String>(json['postData']),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@override
|
@override
|
||||||
@@ -717,25 +874,50 @@ class PostDraft extends DataClass implements Insertable<PostDraft> {
|
|||||||
serializer ??= driftRuntimeOptions.defaultSerializer;
|
serializer ??= driftRuntimeOptions.defaultSerializer;
|
||||||
return <String, dynamic>{
|
return <String, dynamic>{
|
||||||
'id': serializer.toJson<String>(id),
|
'id': serializer.toJson<String>(id),
|
||||||
'post': serializer.toJson<String>(post),
|
'title': serializer.toJson<String?>(title),
|
||||||
|
'description': serializer.toJson<String?>(description),
|
||||||
|
'content': serializer.toJson<String?>(content),
|
||||||
|
'visibility': serializer.toJson<int>(visibility),
|
||||||
|
'type': serializer.toJson<int>(type),
|
||||||
'lastModified': serializer.toJson<DateTime>(lastModified),
|
'lastModified': serializer.toJson<DateTime>(lastModified),
|
||||||
|
'postData': serializer.toJson<String>(postData),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
PostDraft copyWith({String? id, String? post, DateTime? lastModified}) =>
|
PostDraft copyWith({
|
||||||
PostDraft(
|
String? id,
|
||||||
id: id ?? this.id,
|
Value<String?> title = const Value.absent(),
|
||||||
post: post ?? this.post,
|
Value<String?> description = const Value.absent(),
|
||||||
lastModified: lastModified ?? this.lastModified,
|
Value<String?> content = const Value.absent(),
|
||||||
);
|
int? visibility,
|
||||||
|
int? type,
|
||||||
|
DateTime? lastModified,
|
||||||
|
String? postData,
|
||||||
|
}) => PostDraft(
|
||||||
|
id: id ?? this.id,
|
||||||
|
title: title.present ? title.value : this.title,
|
||||||
|
description: description.present ? description.value : this.description,
|
||||||
|
content: content.present ? content.value : this.content,
|
||||||
|
visibility: visibility ?? this.visibility,
|
||||||
|
type: type ?? this.type,
|
||||||
|
lastModified: lastModified ?? this.lastModified,
|
||||||
|
postData: postData ?? this.postData,
|
||||||
|
);
|
||||||
PostDraft copyWithCompanion(PostDraftsCompanion data) {
|
PostDraft copyWithCompanion(PostDraftsCompanion data) {
|
||||||
return PostDraft(
|
return PostDraft(
|
||||||
id: data.id.present ? data.id.value : this.id,
|
id: data.id.present ? data.id.value : this.id,
|
||||||
post: data.post.present ? data.post.value : this.post,
|
title: data.title.present ? data.title.value : this.title,
|
||||||
|
description:
|
||||||
|
data.description.present ? data.description.value : this.description,
|
||||||
|
content: data.content.present ? data.content.value : this.content,
|
||||||
|
visibility:
|
||||||
|
data.visibility.present ? data.visibility.value : this.visibility,
|
||||||
|
type: data.type.present ? data.type.value : this.type,
|
||||||
lastModified:
|
lastModified:
|
||||||
data.lastModified.present
|
data.lastModified.present
|
||||||
? data.lastModified.value
|
? data.lastModified.value
|
||||||
: this.lastModified,
|
: this.lastModified,
|
||||||
|
postData: data.postData.present ? data.postData.value : this.postData,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -743,66 +925,120 @@ class PostDraft extends DataClass implements Insertable<PostDraft> {
|
|||||||
String toString() {
|
String toString() {
|
||||||
return (StringBuffer('PostDraft(')
|
return (StringBuffer('PostDraft(')
|
||||||
..write('id: $id, ')
|
..write('id: $id, ')
|
||||||
..write('post: $post, ')
|
..write('title: $title, ')
|
||||||
..write('lastModified: $lastModified')
|
..write('description: $description, ')
|
||||||
|
..write('content: $content, ')
|
||||||
|
..write('visibility: $visibility, ')
|
||||||
|
..write('type: $type, ')
|
||||||
|
..write('lastModified: $lastModified, ')
|
||||||
|
..write('postData: $postData')
|
||||||
..write(')'))
|
..write(')'))
|
||||||
.toString();
|
.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
int get hashCode => Object.hash(id, post, lastModified);
|
int get hashCode => Object.hash(
|
||||||
|
id,
|
||||||
|
title,
|
||||||
|
description,
|
||||||
|
content,
|
||||||
|
visibility,
|
||||||
|
type,
|
||||||
|
lastModified,
|
||||||
|
postData,
|
||||||
|
);
|
||||||
@override
|
@override
|
||||||
bool operator ==(Object other) =>
|
bool operator ==(Object other) =>
|
||||||
identical(this, other) ||
|
identical(this, other) ||
|
||||||
(other is PostDraft &&
|
(other is PostDraft &&
|
||||||
other.id == this.id &&
|
other.id == this.id &&
|
||||||
other.post == this.post &&
|
other.title == this.title &&
|
||||||
other.lastModified == this.lastModified);
|
other.description == this.description &&
|
||||||
|
other.content == this.content &&
|
||||||
|
other.visibility == this.visibility &&
|
||||||
|
other.type == this.type &&
|
||||||
|
other.lastModified == this.lastModified &&
|
||||||
|
other.postData == this.postData);
|
||||||
}
|
}
|
||||||
|
|
||||||
class PostDraftsCompanion extends UpdateCompanion<PostDraft> {
|
class PostDraftsCompanion extends UpdateCompanion<PostDraft> {
|
||||||
final Value<String> id;
|
final Value<String> id;
|
||||||
final Value<String> post;
|
final Value<String?> title;
|
||||||
|
final Value<String?> description;
|
||||||
|
final Value<String?> content;
|
||||||
|
final Value<int> visibility;
|
||||||
|
final Value<int> type;
|
||||||
final Value<DateTime> lastModified;
|
final Value<DateTime> lastModified;
|
||||||
|
final Value<String> postData;
|
||||||
final Value<int> rowid;
|
final Value<int> rowid;
|
||||||
const PostDraftsCompanion({
|
const PostDraftsCompanion({
|
||||||
this.id = const Value.absent(),
|
this.id = const Value.absent(),
|
||||||
this.post = const Value.absent(),
|
this.title = const Value.absent(),
|
||||||
|
this.description = const Value.absent(),
|
||||||
|
this.content = const Value.absent(),
|
||||||
|
this.visibility = const Value.absent(),
|
||||||
|
this.type = const Value.absent(),
|
||||||
this.lastModified = const Value.absent(),
|
this.lastModified = const Value.absent(),
|
||||||
|
this.postData = const Value.absent(),
|
||||||
this.rowid = const Value.absent(),
|
this.rowid = const Value.absent(),
|
||||||
});
|
});
|
||||||
PostDraftsCompanion.insert({
|
PostDraftsCompanion.insert({
|
||||||
required String id,
|
required String id,
|
||||||
required String post,
|
this.title = const Value.absent(),
|
||||||
|
this.description = const Value.absent(),
|
||||||
|
this.content = const Value.absent(),
|
||||||
|
this.visibility = const Value.absent(),
|
||||||
|
this.type = const Value.absent(),
|
||||||
required DateTime lastModified,
|
required DateTime lastModified,
|
||||||
|
required String postData,
|
||||||
this.rowid = const Value.absent(),
|
this.rowid = const Value.absent(),
|
||||||
}) : id = Value(id),
|
}) : id = Value(id),
|
||||||
post = Value(post),
|
lastModified = Value(lastModified),
|
||||||
lastModified = Value(lastModified);
|
postData = Value(postData);
|
||||||
static Insertable<PostDraft> custom({
|
static Insertable<PostDraft> custom({
|
||||||
Expression<String>? id,
|
Expression<String>? id,
|
||||||
Expression<String>? post,
|
Expression<String>? title,
|
||||||
|
Expression<String>? description,
|
||||||
|
Expression<String>? content,
|
||||||
|
Expression<int>? visibility,
|
||||||
|
Expression<int>? type,
|
||||||
Expression<DateTime>? lastModified,
|
Expression<DateTime>? lastModified,
|
||||||
|
Expression<String>? postData,
|
||||||
Expression<int>? rowid,
|
Expression<int>? rowid,
|
||||||
}) {
|
}) {
|
||||||
return RawValuesInsertable({
|
return RawValuesInsertable({
|
||||||
if (id != null) 'id': id,
|
if (id != null) 'id': id,
|
||||||
if (post != null) 'post': post,
|
if (title != null) 'title': title,
|
||||||
|
if (description != null) 'description': description,
|
||||||
|
if (content != null) 'content': content,
|
||||||
|
if (visibility != null) 'visibility': visibility,
|
||||||
|
if (type != null) 'type': type,
|
||||||
if (lastModified != null) 'last_modified': lastModified,
|
if (lastModified != null) 'last_modified': lastModified,
|
||||||
|
if (postData != null) 'post_data': postData,
|
||||||
if (rowid != null) 'rowid': rowid,
|
if (rowid != null) 'rowid': rowid,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
PostDraftsCompanion copyWith({
|
PostDraftsCompanion copyWith({
|
||||||
Value<String>? id,
|
Value<String>? id,
|
||||||
Value<String>? post,
|
Value<String?>? title,
|
||||||
|
Value<String?>? description,
|
||||||
|
Value<String?>? content,
|
||||||
|
Value<int>? visibility,
|
||||||
|
Value<int>? type,
|
||||||
Value<DateTime>? lastModified,
|
Value<DateTime>? lastModified,
|
||||||
|
Value<String>? postData,
|
||||||
Value<int>? rowid,
|
Value<int>? rowid,
|
||||||
}) {
|
}) {
|
||||||
return PostDraftsCompanion(
|
return PostDraftsCompanion(
|
||||||
id: id ?? this.id,
|
id: id ?? this.id,
|
||||||
post: post ?? this.post,
|
title: title ?? this.title,
|
||||||
|
description: description ?? this.description,
|
||||||
|
content: content ?? this.content,
|
||||||
|
visibility: visibility ?? this.visibility,
|
||||||
|
type: type ?? this.type,
|
||||||
lastModified: lastModified ?? this.lastModified,
|
lastModified: lastModified ?? this.lastModified,
|
||||||
|
postData: postData ?? this.postData,
|
||||||
rowid: rowid ?? this.rowid,
|
rowid: rowid ?? this.rowid,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -813,12 +1049,27 @@ class PostDraftsCompanion extends UpdateCompanion<PostDraft> {
|
|||||||
if (id.present) {
|
if (id.present) {
|
||||||
map['id'] = Variable<String>(id.value);
|
map['id'] = Variable<String>(id.value);
|
||||||
}
|
}
|
||||||
if (post.present) {
|
if (title.present) {
|
||||||
map['post'] = Variable<String>(post.value);
|
map['title'] = Variable<String>(title.value);
|
||||||
|
}
|
||||||
|
if (description.present) {
|
||||||
|
map['description'] = Variable<String>(description.value);
|
||||||
|
}
|
||||||
|
if (content.present) {
|
||||||
|
map['content'] = Variable<String>(content.value);
|
||||||
|
}
|
||||||
|
if (visibility.present) {
|
||||||
|
map['visibility'] = Variable<int>(visibility.value);
|
||||||
|
}
|
||||||
|
if (type.present) {
|
||||||
|
map['type'] = Variable<int>(type.value);
|
||||||
}
|
}
|
||||||
if (lastModified.present) {
|
if (lastModified.present) {
|
||||||
map['last_modified'] = Variable<DateTime>(lastModified.value);
|
map['last_modified'] = Variable<DateTime>(lastModified.value);
|
||||||
}
|
}
|
||||||
|
if (postData.present) {
|
||||||
|
map['post_data'] = Variable<String>(postData.value);
|
||||||
|
}
|
||||||
if (rowid.present) {
|
if (rowid.present) {
|
||||||
map['rowid'] = Variable<int>(rowid.value);
|
map['rowid'] = Variable<int>(rowid.value);
|
||||||
}
|
}
|
||||||
@@ -829,8 +1080,13 @@ class PostDraftsCompanion extends UpdateCompanion<PostDraft> {
|
|||||||
String toString() {
|
String toString() {
|
||||||
return (StringBuffer('PostDraftsCompanion(')
|
return (StringBuffer('PostDraftsCompanion(')
|
||||||
..write('id: $id, ')
|
..write('id: $id, ')
|
||||||
..write('post: $post, ')
|
..write('title: $title, ')
|
||||||
|
..write('description: $description, ')
|
||||||
|
..write('content: $content, ')
|
||||||
|
..write('visibility: $visibility, ')
|
||||||
|
..write('type: $type, ')
|
||||||
..write('lastModified: $lastModified, ')
|
..write('lastModified: $lastModified, ')
|
||||||
|
..write('postData: $postData, ')
|
||||||
..write('rowid: $rowid')
|
..write('rowid: $rowid')
|
||||||
..write(')'))
|
..write(')'))
|
||||||
.toString();
|
.toString();
|
||||||
@@ -1140,15 +1396,25 @@ typedef $$ChatMessagesTableProcessedTableManager =
|
|||||||
typedef $$PostDraftsTableCreateCompanionBuilder =
|
typedef $$PostDraftsTableCreateCompanionBuilder =
|
||||||
PostDraftsCompanion Function({
|
PostDraftsCompanion Function({
|
||||||
required String id,
|
required String id,
|
||||||
required String post,
|
Value<String?> title,
|
||||||
|
Value<String?> description,
|
||||||
|
Value<String?> content,
|
||||||
|
Value<int> visibility,
|
||||||
|
Value<int> type,
|
||||||
required DateTime lastModified,
|
required DateTime lastModified,
|
||||||
|
required String postData,
|
||||||
Value<int> rowid,
|
Value<int> rowid,
|
||||||
});
|
});
|
||||||
typedef $$PostDraftsTableUpdateCompanionBuilder =
|
typedef $$PostDraftsTableUpdateCompanionBuilder =
|
||||||
PostDraftsCompanion Function({
|
PostDraftsCompanion Function({
|
||||||
Value<String> id,
|
Value<String> id,
|
||||||
Value<String> post,
|
Value<String?> title,
|
||||||
|
Value<String?> description,
|
||||||
|
Value<String?> content,
|
||||||
|
Value<int> visibility,
|
||||||
|
Value<int> type,
|
||||||
Value<DateTime> lastModified,
|
Value<DateTime> lastModified,
|
||||||
|
Value<String> postData,
|
||||||
Value<int> rowid,
|
Value<int> rowid,
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -1166,8 +1432,28 @@ class $$PostDraftsTableFilterComposer
|
|||||||
builder: (column) => ColumnFilters(column),
|
builder: (column) => ColumnFilters(column),
|
||||||
);
|
);
|
||||||
|
|
||||||
ColumnFilters<String> get post => $composableBuilder(
|
ColumnFilters<String> get title => $composableBuilder(
|
||||||
column: $table.post,
|
column: $table.title,
|
||||||
|
builder: (column) => ColumnFilters(column),
|
||||||
|
);
|
||||||
|
|
||||||
|
ColumnFilters<String> get description => $composableBuilder(
|
||||||
|
column: $table.description,
|
||||||
|
builder: (column) => ColumnFilters(column),
|
||||||
|
);
|
||||||
|
|
||||||
|
ColumnFilters<String> get content => $composableBuilder(
|
||||||
|
column: $table.content,
|
||||||
|
builder: (column) => ColumnFilters(column),
|
||||||
|
);
|
||||||
|
|
||||||
|
ColumnFilters<int> get visibility => $composableBuilder(
|
||||||
|
column: $table.visibility,
|
||||||
|
builder: (column) => ColumnFilters(column),
|
||||||
|
);
|
||||||
|
|
||||||
|
ColumnFilters<int> get type => $composableBuilder(
|
||||||
|
column: $table.type,
|
||||||
builder: (column) => ColumnFilters(column),
|
builder: (column) => ColumnFilters(column),
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -1175,6 +1461,11 @@ class $$PostDraftsTableFilterComposer
|
|||||||
column: $table.lastModified,
|
column: $table.lastModified,
|
||||||
builder: (column) => ColumnFilters(column),
|
builder: (column) => ColumnFilters(column),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
ColumnFilters<String> get postData => $composableBuilder(
|
||||||
|
column: $table.postData,
|
||||||
|
builder: (column) => ColumnFilters(column),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
class $$PostDraftsTableOrderingComposer
|
class $$PostDraftsTableOrderingComposer
|
||||||
@@ -1191,8 +1482,28 @@ class $$PostDraftsTableOrderingComposer
|
|||||||
builder: (column) => ColumnOrderings(column),
|
builder: (column) => ColumnOrderings(column),
|
||||||
);
|
);
|
||||||
|
|
||||||
ColumnOrderings<String> get post => $composableBuilder(
|
ColumnOrderings<String> get title => $composableBuilder(
|
||||||
column: $table.post,
|
column: $table.title,
|
||||||
|
builder: (column) => ColumnOrderings(column),
|
||||||
|
);
|
||||||
|
|
||||||
|
ColumnOrderings<String> get description => $composableBuilder(
|
||||||
|
column: $table.description,
|
||||||
|
builder: (column) => ColumnOrderings(column),
|
||||||
|
);
|
||||||
|
|
||||||
|
ColumnOrderings<String> get content => $composableBuilder(
|
||||||
|
column: $table.content,
|
||||||
|
builder: (column) => ColumnOrderings(column),
|
||||||
|
);
|
||||||
|
|
||||||
|
ColumnOrderings<int> get visibility => $composableBuilder(
|
||||||
|
column: $table.visibility,
|
||||||
|
builder: (column) => ColumnOrderings(column),
|
||||||
|
);
|
||||||
|
|
||||||
|
ColumnOrderings<int> get type => $composableBuilder(
|
||||||
|
column: $table.type,
|
||||||
builder: (column) => ColumnOrderings(column),
|
builder: (column) => ColumnOrderings(column),
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -1200,6 +1511,11 @@ class $$PostDraftsTableOrderingComposer
|
|||||||
column: $table.lastModified,
|
column: $table.lastModified,
|
||||||
builder: (column) => ColumnOrderings(column),
|
builder: (column) => ColumnOrderings(column),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
ColumnOrderings<String> get postData => $composableBuilder(
|
||||||
|
column: $table.postData,
|
||||||
|
builder: (column) => ColumnOrderings(column),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
class $$PostDraftsTableAnnotationComposer
|
class $$PostDraftsTableAnnotationComposer
|
||||||
@@ -1214,13 +1530,32 @@ class $$PostDraftsTableAnnotationComposer
|
|||||||
GeneratedColumn<String> get id =>
|
GeneratedColumn<String> get id =>
|
||||||
$composableBuilder(column: $table.id, builder: (column) => column);
|
$composableBuilder(column: $table.id, builder: (column) => column);
|
||||||
|
|
||||||
GeneratedColumn<String> get post =>
|
GeneratedColumn<String> get title =>
|
||||||
$composableBuilder(column: $table.post, builder: (column) => column);
|
$composableBuilder(column: $table.title, builder: (column) => column);
|
||||||
|
|
||||||
|
GeneratedColumn<String> get description => $composableBuilder(
|
||||||
|
column: $table.description,
|
||||||
|
builder: (column) => column,
|
||||||
|
);
|
||||||
|
|
||||||
|
GeneratedColumn<String> get content =>
|
||||||
|
$composableBuilder(column: $table.content, builder: (column) => column);
|
||||||
|
|
||||||
|
GeneratedColumn<int> get visibility => $composableBuilder(
|
||||||
|
column: $table.visibility,
|
||||||
|
builder: (column) => column,
|
||||||
|
);
|
||||||
|
|
||||||
|
GeneratedColumn<int> get type =>
|
||||||
|
$composableBuilder(column: $table.type, builder: (column) => column);
|
||||||
|
|
||||||
GeneratedColumn<DateTime> get lastModified => $composableBuilder(
|
GeneratedColumn<DateTime> get lastModified => $composableBuilder(
|
||||||
column: $table.lastModified,
|
column: $table.lastModified,
|
||||||
builder: (column) => column,
|
builder: (column) => column,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
GeneratedColumn<String> get postData =>
|
||||||
|
$composableBuilder(column: $table.postData, builder: (column) => column);
|
||||||
}
|
}
|
||||||
|
|
||||||
class $$PostDraftsTableTableManager
|
class $$PostDraftsTableTableManager
|
||||||
@@ -1255,25 +1590,45 @@ class $$PostDraftsTableTableManager
|
|||||||
updateCompanionCallback:
|
updateCompanionCallback:
|
||||||
({
|
({
|
||||||
Value<String> id = const Value.absent(),
|
Value<String> id = const Value.absent(),
|
||||||
Value<String> post = const Value.absent(),
|
Value<String?> title = const Value.absent(),
|
||||||
|
Value<String?> description = const Value.absent(),
|
||||||
|
Value<String?> content = const Value.absent(),
|
||||||
|
Value<int> visibility = const Value.absent(),
|
||||||
|
Value<int> type = const Value.absent(),
|
||||||
Value<DateTime> lastModified = const Value.absent(),
|
Value<DateTime> lastModified = const Value.absent(),
|
||||||
|
Value<String> postData = const Value.absent(),
|
||||||
Value<int> rowid = const Value.absent(),
|
Value<int> rowid = const Value.absent(),
|
||||||
}) => PostDraftsCompanion(
|
}) => PostDraftsCompanion(
|
||||||
id: id,
|
id: id,
|
||||||
post: post,
|
title: title,
|
||||||
|
description: description,
|
||||||
|
content: content,
|
||||||
|
visibility: visibility,
|
||||||
|
type: type,
|
||||||
lastModified: lastModified,
|
lastModified: lastModified,
|
||||||
|
postData: postData,
|
||||||
rowid: rowid,
|
rowid: rowid,
|
||||||
),
|
),
|
||||||
createCompanionCallback:
|
createCompanionCallback:
|
||||||
({
|
({
|
||||||
required String id,
|
required String id,
|
||||||
required String post,
|
Value<String?> title = const Value.absent(),
|
||||||
|
Value<String?> description = const Value.absent(),
|
||||||
|
Value<String?> content = const Value.absent(),
|
||||||
|
Value<int> visibility = const Value.absent(),
|
||||||
|
Value<int> type = const Value.absent(),
|
||||||
required DateTime lastModified,
|
required DateTime lastModified,
|
||||||
|
required String postData,
|
||||||
Value<int> rowid = const Value.absent(),
|
Value<int> rowid = const Value.absent(),
|
||||||
}) => PostDraftsCompanion.insert(
|
}) => PostDraftsCompanion.insert(
|
||||||
id: id,
|
id: id,
|
||||||
post: post,
|
title: title,
|
||||||
|
description: description,
|
||||||
|
content: content,
|
||||||
|
visibility: visibility,
|
||||||
|
type: type,
|
||||||
lastModified: lastModified,
|
lastModified: lastModified,
|
||||||
|
postData: postData,
|
||||||
rowid: rowid,
|
rowid: rowid,
|
||||||
),
|
),
|
||||||
withReferenceMapper:
|
withReferenceMapper:
|
||||||
|
@@ -19,6 +19,7 @@ sealed class SnAccount with _$SnAccount {
|
|||||||
required SnAccountProfile profile,
|
required SnAccountProfile profile,
|
||||||
required SnWalletSubscriptionRef? perkSubscription,
|
required SnWalletSubscriptionRef? perkSubscription,
|
||||||
@Default([]) List<SnAccountBadge> badges,
|
@Default([]) List<SnAccountBadge> badges,
|
||||||
|
@Default([]) List<SnContactMethod> contacts,
|
||||||
required DateTime createdAt,
|
required DateTime createdAt,
|
||||||
required DateTime updatedAt,
|
required DateTime updatedAt,
|
||||||
required DateTime? deletedAt,
|
required DateTime? deletedAt,
|
||||||
@@ -135,6 +136,7 @@ sealed class SnContactMethod with _$SnContactMethod {
|
|||||||
required int type,
|
required int type,
|
||||||
required DateTime? verifiedAt,
|
required DateTime? verifiedAt,
|
||||||
required bool isPrimary,
|
required bool isPrimary,
|
||||||
|
required bool isPublic,
|
||||||
required String content,
|
required String content,
|
||||||
required String accountId,
|
required String accountId,
|
||||||
required DateTime createdAt,
|
required DateTime createdAt,
|
||||||
|
@@ -15,7 +15,7 @@ T _$identity<T>(T value) => value;
|
|||||||
/// @nodoc
|
/// @nodoc
|
||||||
mixin _$SnAccount {
|
mixin _$SnAccount {
|
||||||
|
|
||||||
String get id; String get name; String get nick; String get language; String get region; bool get isSuperuser; String? get automatedId; SnAccountProfile get profile; SnWalletSubscriptionRef? get perkSubscription; List<SnAccountBadge> get badges; DateTime get createdAt; DateTime get updatedAt; DateTime? get deletedAt;
|
String get id; String get name; String get nick; String get language; String get region; bool get isSuperuser; String? get automatedId; SnAccountProfile get profile; SnWalletSubscriptionRef? get perkSubscription; List<SnAccountBadge> get badges; List<SnContactMethod> get contacts; DateTime get createdAt; DateTime get updatedAt; DateTime? get deletedAt;
|
||||||
/// Create a copy of SnAccount
|
/// Create a copy of SnAccount
|
||||||
/// with the given fields replaced by the non-null parameter values.
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||||
@@ -28,16 +28,16 @@ $SnAccountCopyWith<SnAccount> get copyWith => _$SnAccountCopyWithImpl<SnAccount>
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
bool operator ==(Object other) {
|
bool operator ==(Object other) {
|
||||||
return identical(this, other) || (other.runtimeType == runtimeType&&other is SnAccount&&(identical(other.id, id) || other.id == id)&&(identical(other.name, name) || other.name == name)&&(identical(other.nick, nick) || other.nick == nick)&&(identical(other.language, language) || other.language == language)&&(identical(other.region, region) || other.region == region)&&(identical(other.isSuperuser, isSuperuser) || other.isSuperuser == isSuperuser)&&(identical(other.automatedId, automatedId) || other.automatedId == automatedId)&&(identical(other.profile, profile) || other.profile == profile)&&(identical(other.perkSubscription, perkSubscription) || other.perkSubscription == perkSubscription)&&const DeepCollectionEquality().equals(other.badges, badges)&&(identical(other.createdAt, createdAt) || other.createdAt == createdAt)&&(identical(other.updatedAt, updatedAt) || other.updatedAt == updatedAt)&&(identical(other.deletedAt, deletedAt) || other.deletedAt == deletedAt));
|
return identical(this, other) || (other.runtimeType == runtimeType&&other is SnAccount&&(identical(other.id, id) || other.id == id)&&(identical(other.name, name) || other.name == name)&&(identical(other.nick, nick) || other.nick == nick)&&(identical(other.language, language) || other.language == language)&&(identical(other.region, region) || other.region == region)&&(identical(other.isSuperuser, isSuperuser) || other.isSuperuser == isSuperuser)&&(identical(other.automatedId, automatedId) || other.automatedId == automatedId)&&(identical(other.profile, profile) || other.profile == profile)&&(identical(other.perkSubscription, perkSubscription) || other.perkSubscription == perkSubscription)&&const DeepCollectionEquality().equals(other.badges, badges)&&const DeepCollectionEquality().equals(other.contacts, contacts)&&(identical(other.createdAt, createdAt) || other.createdAt == createdAt)&&(identical(other.updatedAt, updatedAt) || other.updatedAt == updatedAt)&&(identical(other.deletedAt, deletedAt) || other.deletedAt == deletedAt));
|
||||||
}
|
}
|
||||||
|
|
||||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||||
@override
|
@override
|
||||||
int get hashCode => Object.hash(runtimeType,id,name,nick,language,region,isSuperuser,automatedId,profile,perkSubscription,const DeepCollectionEquality().hash(badges),createdAt,updatedAt,deletedAt);
|
int get hashCode => Object.hash(runtimeType,id,name,nick,language,region,isSuperuser,automatedId,profile,perkSubscription,const DeepCollectionEquality().hash(badges),const DeepCollectionEquality().hash(contacts),createdAt,updatedAt,deletedAt);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String toString() {
|
String toString() {
|
||||||
return 'SnAccount(id: $id, name: $name, nick: $nick, language: $language, region: $region, isSuperuser: $isSuperuser, automatedId: $automatedId, profile: $profile, perkSubscription: $perkSubscription, badges: $badges, createdAt: $createdAt, updatedAt: $updatedAt, deletedAt: $deletedAt)';
|
return 'SnAccount(id: $id, name: $name, nick: $nick, language: $language, region: $region, isSuperuser: $isSuperuser, automatedId: $automatedId, profile: $profile, perkSubscription: $perkSubscription, badges: $badges, contacts: $contacts, createdAt: $createdAt, updatedAt: $updatedAt, deletedAt: $deletedAt)';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -48,7 +48,7 @@ abstract mixin class $SnAccountCopyWith<$Res> {
|
|||||||
factory $SnAccountCopyWith(SnAccount value, $Res Function(SnAccount) _then) = _$SnAccountCopyWithImpl;
|
factory $SnAccountCopyWith(SnAccount value, $Res Function(SnAccount) _then) = _$SnAccountCopyWithImpl;
|
||||||
@useResult
|
@useResult
|
||||||
$Res call({
|
$Res call({
|
||||||
String id, String name, String nick, String language, String region, bool isSuperuser, String? automatedId, SnAccountProfile profile, SnWalletSubscriptionRef? perkSubscription, List<SnAccountBadge> badges, DateTime createdAt, DateTime updatedAt, DateTime? deletedAt
|
String id, String name, String nick, String language, String region, bool isSuperuser, String? automatedId, SnAccountProfile profile, SnWalletSubscriptionRef? perkSubscription, List<SnAccountBadge> badges, List<SnContactMethod> contacts, DateTime createdAt, DateTime updatedAt, DateTime? deletedAt
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
@@ -65,7 +65,7 @@ class _$SnAccountCopyWithImpl<$Res>
|
|||||||
|
|
||||||
/// Create a copy of SnAccount
|
/// Create a copy of SnAccount
|
||||||
/// with the given fields replaced by the non-null parameter values.
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
@pragma('vm:prefer-inline') @override $Res call({Object? id = null,Object? name = null,Object? nick = null,Object? language = null,Object? region = null,Object? isSuperuser = null,Object? automatedId = freezed,Object? profile = null,Object? perkSubscription = freezed,Object? badges = null,Object? createdAt = null,Object? updatedAt = null,Object? deletedAt = freezed,}) {
|
@pragma('vm:prefer-inline') @override $Res call({Object? id = null,Object? name = null,Object? nick = null,Object? language = null,Object? region = null,Object? isSuperuser = null,Object? automatedId = freezed,Object? profile = null,Object? perkSubscription = freezed,Object? badges = null,Object? contacts = null,Object? createdAt = null,Object? updatedAt = null,Object? deletedAt = freezed,}) {
|
||||||
return _then(_self.copyWith(
|
return _then(_self.copyWith(
|
||||||
id: null == id ? _self.id : id // ignore: cast_nullable_to_non_nullable
|
id: null == id ? _self.id : id // ignore: cast_nullable_to_non_nullable
|
||||||
as String,name: null == name ? _self.name : name // ignore: cast_nullable_to_non_nullable
|
as String,name: null == name ? _self.name : name // ignore: cast_nullable_to_non_nullable
|
||||||
@@ -77,7 +77,8 @@ as bool,automatedId: freezed == automatedId ? _self.automatedId : automatedId //
|
|||||||
as String?,profile: null == profile ? _self.profile : profile // ignore: cast_nullable_to_non_nullable
|
as String?,profile: null == profile ? _self.profile : profile // ignore: cast_nullable_to_non_nullable
|
||||||
as SnAccountProfile,perkSubscription: freezed == perkSubscription ? _self.perkSubscription : perkSubscription // ignore: cast_nullable_to_non_nullable
|
as SnAccountProfile,perkSubscription: freezed == perkSubscription ? _self.perkSubscription : perkSubscription // ignore: cast_nullable_to_non_nullable
|
||||||
as SnWalletSubscriptionRef?,badges: null == badges ? _self.badges : badges // ignore: cast_nullable_to_non_nullable
|
as SnWalletSubscriptionRef?,badges: null == badges ? _self.badges : badges // ignore: cast_nullable_to_non_nullable
|
||||||
as List<SnAccountBadge>,createdAt: null == createdAt ? _self.createdAt : createdAt // ignore: cast_nullable_to_non_nullable
|
as List<SnAccountBadge>,contacts: null == contacts ? _self.contacts : contacts // ignore: cast_nullable_to_non_nullable
|
||||||
|
as List<SnContactMethod>,createdAt: null == createdAt ? _self.createdAt : createdAt // ignore: cast_nullable_to_non_nullable
|
||||||
as DateTime,updatedAt: null == updatedAt ? _self.updatedAt : updatedAt // ignore: cast_nullable_to_non_nullable
|
as DateTime,updatedAt: null == updatedAt ? _self.updatedAt : updatedAt // ignore: cast_nullable_to_non_nullable
|
||||||
as DateTime,deletedAt: freezed == deletedAt ? _self.deletedAt : deletedAt // ignore: cast_nullable_to_non_nullable
|
as DateTime,deletedAt: freezed == deletedAt ? _self.deletedAt : deletedAt // ignore: cast_nullable_to_non_nullable
|
||||||
as DateTime?,
|
as DateTime?,
|
||||||
@@ -183,10 +184,10 @@ return $default(_that);case _:
|
|||||||
/// }
|
/// }
|
||||||
/// ```
|
/// ```
|
||||||
|
|
||||||
@optionalTypeArgs TResult maybeWhen<TResult extends Object?>(TResult Function( String id, String name, String nick, String language, String region, bool isSuperuser, String? automatedId, SnAccountProfile profile, SnWalletSubscriptionRef? perkSubscription, List<SnAccountBadge> badges, DateTime createdAt, DateTime updatedAt, DateTime? deletedAt)? $default,{required TResult orElse(),}) {final _that = this;
|
@optionalTypeArgs TResult maybeWhen<TResult extends Object?>(TResult Function( String id, String name, String nick, String language, String region, bool isSuperuser, String? automatedId, SnAccountProfile profile, SnWalletSubscriptionRef? perkSubscription, List<SnAccountBadge> badges, List<SnContactMethod> contacts, DateTime createdAt, DateTime updatedAt, DateTime? deletedAt)? $default,{required TResult orElse(),}) {final _that = this;
|
||||||
switch (_that) {
|
switch (_that) {
|
||||||
case _SnAccount() when $default != null:
|
case _SnAccount() when $default != null:
|
||||||
return $default(_that.id,_that.name,_that.nick,_that.language,_that.region,_that.isSuperuser,_that.automatedId,_that.profile,_that.perkSubscription,_that.badges,_that.createdAt,_that.updatedAt,_that.deletedAt);case _:
|
return $default(_that.id,_that.name,_that.nick,_that.language,_that.region,_that.isSuperuser,_that.automatedId,_that.profile,_that.perkSubscription,_that.badges,_that.contacts,_that.createdAt,_that.updatedAt,_that.deletedAt);case _:
|
||||||
return orElse();
|
return orElse();
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -204,10 +205,10 @@ return $default(_that.id,_that.name,_that.nick,_that.language,_that.region,_that
|
|||||||
/// }
|
/// }
|
||||||
/// ```
|
/// ```
|
||||||
|
|
||||||
@optionalTypeArgs TResult when<TResult extends Object?>(TResult Function( String id, String name, String nick, String language, String region, bool isSuperuser, String? automatedId, SnAccountProfile profile, SnWalletSubscriptionRef? perkSubscription, List<SnAccountBadge> badges, DateTime createdAt, DateTime updatedAt, DateTime? deletedAt) $default,) {final _that = this;
|
@optionalTypeArgs TResult when<TResult extends Object?>(TResult Function( String id, String name, String nick, String language, String region, bool isSuperuser, String? automatedId, SnAccountProfile profile, SnWalletSubscriptionRef? perkSubscription, List<SnAccountBadge> badges, List<SnContactMethod> contacts, DateTime createdAt, DateTime updatedAt, DateTime? deletedAt) $default,) {final _that = this;
|
||||||
switch (_that) {
|
switch (_that) {
|
||||||
case _SnAccount():
|
case _SnAccount():
|
||||||
return $default(_that.id,_that.name,_that.nick,_that.language,_that.region,_that.isSuperuser,_that.automatedId,_that.profile,_that.perkSubscription,_that.badges,_that.createdAt,_that.updatedAt,_that.deletedAt);}
|
return $default(_that.id,_that.name,_that.nick,_that.language,_that.region,_that.isSuperuser,_that.automatedId,_that.profile,_that.perkSubscription,_that.badges,_that.contacts,_that.createdAt,_that.updatedAt,_that.deletedAt);}
|
||||||
}
|
}
|
||||||
/// A variant of `when` that fallback to returning `null`
|
/// A variant of `when` that fallback to returning `null`
|
||||||
///
|
///
|
||||||
@@ -221,10 +222,10 @@ return $default(_that.id,_that.name,_that.nick,_that.language,_that.region,_that
|
|||||||
/// }
|
/// }
|
||||||
/// ```
|
/// ```
|
||||||
|
|
||||||
@optionalTypeArgs TResult? whenOrNull<TResult extends Object?>(TResult? Function( String id, String name, String nick, String language, String region, bool isSuperuser, String? automatedId, SnAccountProfile profile, SnWalletSubscriptionRef? perkSubscription, List<SnAccountBadge> badges, DateTime createdAt, DateTime updatedAt, DateTime? deletedAt)? $default,) {final _that = this;
|
@optionalTypeArgs TResult? whenOrNull<TResult extends Object?>(TResult? Function( String id, String name, String nick, String language, String region, bool isSuperuser, String? automatedId, SnAccountProfile profile, SnWalletSubscriptionRef? perkSubscription, List<SnAccountBadge> badges, List<SnContactMethod> contacts, DateTime createdAt, DateTime updatedAt, DateTime? deletedAt)? $default,) {final _that = this;
|
||||||
switch (_that) {
|
switch (_that) {
|
||||||
case _SnAccount() when $default != null:
|
case _SnAccount() when $default != null:
|
||||||
return $default(_that.id,_that.name,_that.nick,_that.language,_that.region,_that.isSuperuser,_that.automatedId,_that.profile,_that.perkSubscription,_that.badges,_that.createdAt,_that.updatedAt,_that.deletedAt);case _:
|
return $default(_that.id,_that.name,_that.nick,_that.language,_that.region,_that.isSuperuser,_that.automatedId,_that.profile,_that.perkSubscription,_that.badges,_that.contacts,_that.createdAt,_that.updatedAt,_that.deletedAt);case _:
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -236,7 +237,7 @@ return $default(_that.id,_that.name,_that.nick,_that.language,_that.region,_that
|
|||||||
@JsonSerializable()
|
@JsonSerializable()
|
||||||
|
|
||||||
class _SnAccount implements SnAccount {
|
class _SnAccount implements SnAccount {
|
||||||
const _SnAccount({required this.id, required this.name, required this.nick, required this.language, this.region = "", required this.isSuperuser, required this.automatedId, required this.profile, required this.perkSubscription, final List<SnAccountBadge> badges = const [], required this.createdAt, required this.updatedAt, required this.deletedAt}): _badges = badges;
|
const _SnAccount({required this.id, required this.name, required this.nick, required this.language, this.region = "", required this.isSuperuser, required this.automatedId, required this.profile, required this.perkSubscription, final List<SnAccountBadge> badges = const [], final List<SnContactMethod> contacts = const [], required this.createdAt, required this.updatedAt, required this.deletedAt}): _badges = badges,_contacts = contacts;
|
||||||
factory _SnAccount.fromJson(Map<String, dynamic> json) => _$SnAccountFromJson(json);
|
factory _SnAccount.fromJson(Map<String, dynamic> json) => _$SnAccountFromJson(json);
|
||||||
|
|
||||||
@override final String id;
|
@override final String id;
|
||||||
@@ -255,6 +256,13 @@ class _SnAccount implements SnAccount {
|
|||||||
return EqualUnmodifiableListView(_badges);
|
return EqualUnmodifiableListView(_badges);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
final List<SnContactMethod> _contacts;
|
||||||
|
@override@JsonKey() List<SnContactMethod> get contacts {
|
||||||
|
if (_contacts is EqualUnmodifiableListView) return _contacts;
|
||||||
|
// ignore: implicit_dynamic_type
|
||||||
|
return EqualUnmodifiableListView(_contacts);
|
||||||
|
}
|
||||||
|
|
||||||
@override final DateTime createdAt;
|
@override final DateTime createdAt;
|
||||||
@override final DateTime updatedAt;
|
@override final DateTime updatedAt;
|
||||||
@override final DateTime? deletedAt;
|
@override final DateTime? deletedAt;
|
||||||
@@ -272,16 +280,16 @@ Map<String, dynamic> toJson() {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
bool operator ==(Object other) {
|
bool operator ==(Object other) {
|
||||||
return identical(this, other) || (other.runtimeType == runtimeType&&other is _SnAccount&&(identical(other.id, id) || other.id == id)&&(identical(other.name, name) || other.name == name)&&(identical(other.nick, nick) || other.nick == nick)&&(identical(other.language, language) || other.language == language)&&(identical(other.region, region) || other.region == region)&&(identical(other.isSuperuser, isSuperuser) || other.isSuperuser == isSuperuser)&&(identical(other.automatedId, automatedId) || other.automatedId == automatedId)&&(identical(other.profile, profile) || other.profile == profile)&&(identical(other.perkSubscription, perkSubscription) || other.perkSubscription == perkSubscription)&&const DeepCollectionEquality().equals(other._badges, _badges)&&(identical(other.createdAt, createdAt) || other.createdAt == createdAt)&&(identical(other.updatedAt, updatedAt) || other.updatedAt == updatedAt)&&(identical(other.deletedAt, deletedAt) || other.deletedAt == deletedAt));
|
return identical(this, other) || (other.runtimeType == runtimeType&&other is _SnAccount&&(identical(other.id, id) || other.id == id)&&(identical(other.name, name) || other.name == name)&&(identical(other.nick, nick) || other.nick == nick)&&(identical(other.language, language) || other.language == language)&&(identical(other.region, region) || other.region == region)&&(identical(other.isSuperuser, isSuperuser) || other.isSuperuser == isSuperuser)&&(identical(other.automatedId, automatedId) || other.automatedId == automatedId)&&(identical(other.profile, profile) || other.profile == profile)&&(identical(other.perkSubscription, perkSubscription) || other.perkSubscription == perkSubscription)&&const DeepCollectionEquality().equals(other._badges, _badges)&&const DeepCollectionEquality().equals(other._contacts, _contacts)&&(identical(other.createdAt, createdAt) || other.createdAt == createdAt)&&(identical(other.updatedAt, updatedAt) || other.updatedAt == updatedAt)&&(identical(other.deletedAt, deletedAt) || other.deletedAt == deletedAt));
|
||||||
}
|
}
|
||||||
|
|
||||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||||
@override
|
@override
|
||||||
int get hashCode => Object.hash(runtimeType,id,name,nick,language,region,isSuperuser,automatedId,profile,perkSubscription,const DeepCollectionEquality().hash(_badges),createdAt,updatedAt,deletedAt);
|
int get hashCode => Object.hash(runtimeType,id,name,nick,language,region,isSuperuser,automatedId,profile,perkSubscription,const DeepCollectionEquality().hash(_badges),const DeepCollectionEquality().hash(_contacts),createdAt,updatedAt,deletedAt);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String toString() {
|
String toString() {
|
||||||
return 'SnAccount(id: $id, name: $name, nick: $nick, language: $language, region: $region, isSuperuser: $isSuperuser, automatedId: $automatedId, profile: $profile, perkSubscription: $perkSubscription, badges: $badges, createdAt: $createdAt, updatedAt: $updatedAt, deletedAt: $deletedAt)';
|
return 'SnAccount(id: $id, name: $name, nick: $nick, language: $language, region: $region, isSuperuser: $isSuperuser, automatedId: $automatedId, profile: $profile, perkSubscription: $perkSubscription, badges: $badges, contacts: $contacts, createdAt: $createdAt, updatedAt: $updatedAt, deletedAt: $deletedAt)';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -292,7 +300,7 @@ abstract mixin class _$SnAccountCopyWith<$Res> implements $SnAccountCopyWith<$Re
|
|||||||
factory _$SnAccountCopyWith(_SnAccount value, $Res Function(_SnAccount) _then) = __$SnAccountCopyWithImpl;
|
factory _$SnAccountCopyWith(_SnAccount value, $Res Function(_SnAccount) _then) = __$SnAccountCopyWithImpl;
|
||||||
@override @useResult
|
@override @useResult
|
||||||
$Res call({
|
$Res call({
|
||||||
String id, String name, String nick, String language, String region, bool isSuperuser, String? automatedId, SnAccountProfile profile, SnWalletSubscriptionRef? perkSubscription, List<SnAccountBadge> badges, DateTime createdAt, DateTime updatedAt, DateTime? deletedAt
|
String id, String name, String nick, String language, String region, bool isSuperuser, String? automatedId, SnAccountProfile profile, SnWalletSubscriptionRef? perkSubscription, List<SnAccountBadge> badges, List<SnContactMethod> contacts, DateTime createdAt, DateTime updatedAt, DateTime? deletedAt
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
@@ -309,7 +317,7 @@ class __$SnAccountCopyWithImpl<$Res>
|
|||||||
|
|
||||||
/// Create a copy of SnAccount
|
/// Create a copy of SnAccount
|
||||||
/// with the given fields replaced by the non-null parameter values.
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
@override @pragma('vm:prefer-inline') $Res call({Object? id = null,Object? name = null,Object? nick = null,Object? language = null,Object? region = null,Object? isSuperuser = null,Object? automatedId = freezed,Object? profile = null,Object? perkSubscription = freezed,Object? badges = null,Object? createdAt = null,Object? updatedAt = null,Object? deletedAt = freezed,}) {
|
@override @pragma('vm:prefer-inline') $Res call({Object? id = null,Object? name = null,Object? nick = null,Object? language = null,Object? region = null,Object? isSuperuser = null,Object? automatedId = freezed,Object? profile = null,Object? perkSubscription = freezed,Object? badges = null,Object? contacts = null,Object? createdAt = null,Object? updatedAt = null,Object? deletedAt = freezed,}) {
|
||||||
return _then(_SnAccount(
|
return _then(_SnAccount(
|
||||||
id: null == id ? _self.id : id // ignore: cast_nullable_to_non_nullable
|
id: null == id ? _self.id : id // ignore: cast_nullable_to_non_nullable
|
||||||
as String,name: null == name ? _self.name : name // ignore: cast_nullable_to_non_nullable
|
as String,name: null == name ? _self.name : name // ignore: cast_nullable_to_non_nullable
|
||||||
@@ -321,7 +329,8 @@ as bool,automatedId: freezed == automatedId ? _self.automatedId : automatedId //
|
|||||||
as String?,profile: null == profile ? _self.profile : profile // ignore: cast_nullable_to_non_nullable
|
as String?,profile: null == profile ? _self.profile : profile // ignore: cast_nullable_to_non_nullable
|
||||||
as SnAccountProfile,perkSubscription: freezed == perkSubscription ? _self.perkSubscription : perkSubscription // ignore: cast_nullable_to_non_nullable
|
as SnAccountProfile,perkSubscription: freezed == perkSubscription ? _self.perkSubscription : perkSubscription // ignore: cast_nullable_to_non_nullable
|
||||||
as SnWalletSubscriptionRef?,badges: null == badges ? _self._badges : badges // ignore: cast_nullable_to_non_nullable
|
as SnWalletSubscriptionRef?,badges: null == badges ? _self._badges : badges // ignore: cast_nullable_to_non_nullable
|
||||||
as List<SnAccountBadge>,createdAt: null == createdAt ? _self.createdAt : createdAt // ignore: cast_nullable_to_non_nullable
|
as List<SnAccountBadge>,contacts: null == contacts ? _self._contacts : contacts // ignore: cast_nullable_to_non_nullable
|
||||||
|
as List<SnContactMethod>,createdAt: null == createdAt ? _self.createdAt : createdAt // ignore: cast_nullable_to_non_nullable
|
||||||
as DateTime,updatedAt: null == updatedAt ? _self.updatedAt : updatedAt // ignore: cast_nullable_to_non_nullable
|
as DateTime,updatedAt: null == updatedAt ? _self.updatedAt : updatedAt // ignore: cast_nullable_to_non_nullable
|
||||||
as DateTime,deletedAt: freezed == deletedAt ? _self.deletedAt : deletedAt // ignore: cast_nullable_to_non_nullable
|
as DateTime,deletedAt: freezed == deletedAt ? _self.deletedAt : deletedAt // ignore: cast_nullable_to_non_nullable
|
||||||
as DateTime?,
|
as DateTime?,
|
||||||
@@ -1627,7 +1636,7 @@ as DateTime?,
|
|||||||
/// @nodoc
|
/// @nodoc
|
||||||
mixin _$SnContactMethod {
|
mixin _$SnContactMethod {
|
||||||
|
|
||||||
String get id; int get type; DateTime? get verifiedAt; bool get isPrimary; String get content; String get accountId; DateTime get createdAt; DateTime get updatedAt; DateTime? get deletedAt;
|
String get id; int get type; DateTime? get verifiedAt; bool get isPrimary; bool get isPublic; String get content; String get accountId; DateTime get createdAt; DateTime get updatedAt; DateTime? get deletedAt;
|
||||||
/// Create a copy of SnContactMethod
|
/// Create a copy of SnContactMethod
|
||||||
/// with the given fields replaced by the non-null parameter values.
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||||
@@ -1640,16 +1649,16 @@ $SnContactMethodCopyWith<SnContactMethod> get copyWith => _$SnContactMethodCopyW
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
bool operator ==(Object other) {
|
bool operator ==(Object other) {
|
||||||
return identical(this, other) || (other.runtimeType == runtimeType&&other is SnContactMethod&&(identical(other.id, id) || other.id == id)&&(identical(other.type, type) || other.type == type)&&(identical(other.verifiedAt, verifiedAt) || other.verifiedAt == verifiedAt)&&(identical(other.isPrimary, isPrimary) || other.isPrimary == isPrimary)&&(identical(other.content, content) || other.content == content)&&(identical(other.accountId, accountId) || other.accountId == accountId)&&(identical(other.createdAt, createdAt) || other.createdAt == createdAt)&&(identical(other.updatedAt, updatedAt) || other.updatedAt == updatedAt)&&(identical(other.deletedAt, deletedAt) || other.deletedAt == deletedAt));
|
return identical(this, other) || (other.runtimeType == runtimeType&&other is SnContactMethod&&(identical(other.id, id) || other.id == id)&&(identical(other.type, type) || other.type == type)&&(identical(other.verifiedAt, verifiedAt) || other.verifiedAt == verifiedAt)&&(identical(other.isPrimary, isPrimary) || other.isPrimary == isPrimary)&&(identical(other.isPublic, isPublic) || other.isPublic == isPublic)&&(identical(other.content, content) || other.content == content)&&(identical(other.accountId, accountId) || other.accountId == accountId)&&(identical(other.createdAt, createdAt) || other.createdAt == createdAt)&&(identical(other.updatedAt, updatedAt) || other.updatedAt == updatedAt)&&(identical(other.deletedAt, deletedAt) || other.deletedAt == deletedAt));
|
||||||
}
|
}
|
||||||
|
|
||||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||||
@override
|
@override
|
||||||
int get hashCode => Object.hash(runtimeType,id,type,verifiedAt,isPrimary,content,accountId,createdAt,updatedAt,deletedAt);
|
int get hashCode => Object.hash(runtimeType,id,type,verifiedAt,isPrimary,isPublic,content,accountId,createdAt,updatedAt,deletedAt);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String toString() {
|
String toString() {
|
||||||
return 'SnContactMethod(id: $id, type: $type, verifiedAt: $verifiedAt, isPrimary: $isPrimary, content: $content, accountId: $accountId, createdAt: $createdAt, updatedAt: $updatedAt, deletedAt: $deletedAt)';
|
return 'SnContactMethod(id: $id, type: $type, verifiedAt: $verifiedAt, isPrimary: $isPrimary, isPublic: $isPublic, content: $content, accountId: $accountId, createdAt: $createdAt, updatedAt: $updatedAt, deletedAt: $deletedAt)';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -1660,7 +1669,7 @@ abstract mixin class $SnContactMethodCopyWith<$Res> {
|
|||||||
factory $SnContactMethodCopyWith(SnContactMethod value, $Res Function(SnContactMethod) _then) = _$SnContactMethodCopyWithImpl;
|
factory $SnContactMethodCopyWith(SnContactMethod value, $Res Function(SnContactMethod) _then) = _$SnContactMethodCopyWithImpl;
|
||||||
@useResult
|
@useResult
|
||||||
$Res call({
|
$Res call({
|
||||||
String id, int type, DateTime? verifiedAt, bool isPrimary, String content, String accountId, DateTime createdAt, DateTime updatedAt, DateTime? deletedAt
|
String id, int type, DateTime? verifiedAt, bool isPrimary, bool isPublic, String content, String accountId, DateTime createdAt, DateTime updatedAt, DateTime? deletedAt
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
@@ -1677,12 +1686,13 @@ class _$SnContactMethodCopyWithImpl<$Res>
|
|||||||
|
|
||||||
/// Create a copy of SnContactMethod
|
/// Create a copy of SnContactMethod
|
||||||
/// with the given fields replaced by the non-null parameter values.
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
@pragma('vm:prefer-inline') @override $Res call({Object? id = null,Object? type = null,Object? verifiedAt = freezed,Object? isPrimary = null,Object? content = null,Object? accountId = null,Object? createdAt = null,Object? updatedAt = null,Object? deletedAt = freezed,}) {
|
@pragma('vm:prefer-inline') @override $Res call({Object? id = null,Object? type = null,Object? verifiedAt = freezed,Object? isPrimary = null,Object? isPublic = null,Object? content = null,Object? accountId = null,Object? createdAt = null,Object? updatedAt = null,Object? deletedAt = freezed,}) {
|
||||||
return _then(_self.copyWith(
|
return _then(_self.copyWith(
|
||||||
id: null == id ? _self.id : id // ignore: cast_nullable_to_non_nullable
|
id: null == id ? _self.id : id // ignore: cast_nullable_to_non_nullable
|
||||||
as String,type: null == type ? _self.type : type // ignore: cast_nullable_to_non_nullable
|
as String,type: null == type ? _self.type : type // ignore: cast_nullable_to_non_nullable
|
||||||
as int,verifiedAt: freezed == verifiedAt ? _self.verifiedAt : verifiedAt // ignore: cast_nullable_to_non_nullable
|
as int,verifiedAt: freezed == verifiedAt ? _self.verifiedAt : verifiedAt // ignore: cast_nullable_to_non_nullable
|
||||||
as DateTime?,isPrimary: null == isPrimary ? _self.isPrimary : isPrimary // ignore: cast_nullable_to_non_nullable
|
as DateTime?,isPrimary: null == isPrimary ? _self.isPrimary : isPrimary // ignore: cast_nullable_to_non_nullable
|
||||||
|
as bool,isPublic: null == isPublic ? _self.isPublic : isPublic // ignore: cast_nullable_to_non_nullable
|
||||||
as bool,content: null == content ? _self.content : content // ignore: cast_nullable_to_non_nullable
|
as bool,content: null == content ? _self.content : content // ignore: cast_nullable_to_non_nullable
|
||||||
as String,accountId: null == accountId ? _self.accountId : accountId // ignore: cast_nullable_to_non_nullable
|
as String,accountId: null == accountId ? _self.accountId : accountId // ignore: cast_nullable_to_non_nullable
|
||||||
as String,createdAt: null == createdAt ? _self.createdAt : createdAt // ignore: cast_nullable_to_non_nullable
|
as String,createdAt: null == createdAt ? _self.createdAt : createdAt // ignore: cast_nullable_to_non_nullable
|
||||||
@@ -1770,10 +1780,10 @@ return $default(_that);case _:
|
|||||||
/// }
|
/// }
|
||||||
/// ```
|
/// ```
|
||||||
|
|
||||||
@optionalTypeArgs TResult maybeWhen<TResult extends Object?>(TResult Function( String id, int type, DateTime? verifiedAt, bool isPrimary, String content, String accountId, DateTime createdAt, DateTime updatedAt, DateTime? deletedAt)? $default,{required TResult orElse(),}) {final _that = this;
|
@optionalTypeArgs TResult maybeWhen<TResult extends Object?>(TResult Function( String id, int type, DateTime? verifiedAt, bool isPrimary, bool isPublic, String content, String accountId, DateTime createdAt, DateTime updatedAt, DateTime? deletedAt)? $default,{required TResult orElse(),}) {final _that = this;
|
||||||
switch (_that) {
|
switch (_that) {
|
||||||
case _SnContactMethod() when $default != null:
|
case _SnContactMethod() when $default != null:
|
||||||
return $default(_that.id,_that.type,_that.verifiedAt,_that.isPrimary,_that.content,_that.accountId,_that.createdAt,_that.updatedAt,_that.deletedAt);case _:
|
return $default(_that.id,_that.type,_that.verifiedAt,_that.isPrimary,_that.isPublic,_that.content,_that.accountId,_that.createdAt,_that.updatedAt,_that.deletedAt);case _:
|
||||||
return orElse();
|
return orElse();
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -1791,10 +1801,10 @@ return $default(_that.id,_that.type,_that.verifiedAt,_that.isPrimary,_that.conte
|
|||||||
/// }
|
/// }
|
||||||
/// ```
|
/// ```
|
||||||
|
|
||||||
@optionalTypeArgs TResult when<TResult extends Object?>(TResult Function( String id, int type, DateTime? verifiedAt, bool isPrimary, String content, String accountId, DateTime createdAt, DateTime updatedAt, DateTime? deletedAt) $default,) {final _that = this;
|
@optionalTypeArgs TResult when<TResult extends Object?>(TResult Function( String id, int type, DateTime? verifiedAt, bool isPrimary, bool isPublic, String content, String accountId, DateTime createdAt, DateTime updatedAt, DateTime? deletedAt) $default,) {final _that = this;
|
||||||
switch (_that) {
|
switch (_that) {
|
||||||
case _SnContactMethod():
|
case _SnContactMethod():
|
||||||
return $default(_that.id,_that.type,_that.verifiedAt,_that.isPrimary,_that.content,_that.accountId,_that.createdAt,_that.updatedAt,_that.deletedAt);}
|
return $default(_that.id,_that.type,_that.verifiedAt,_that.isPrimary,_that.isPublic,_that.content,_that.accountId,_that.createdAt,_that.updatedAt,_that.deletedAt);}
|
||||||
}
|
}
|
||||||
/// A variant of `when` that fallback to returning `null`
|
/// A variant of `when` that fallback to returning `null`
|
||||||
///
|
///
|
||||||
@@ -1808,10 +1818,10 @@ return $default(_that.id,_that.type,_that.verifiedAt,_that.isPrimary,_that.conte
|
|||||||
/// }
|
/// }
|
||||||
/// ```
|
/// ```
|
||||||
|
|
||||||
@optionalTypeArgs TResult? whenOrNull<TResult extends Object?>(TResult? Function( String id, int type, DateTime? verifiedAt, bool isPrimary, String content, String accountId, DateTime createdAt, DateTime updatedAt, DateTime? deletedAt)? $default,) {final _that = this;
|
@optionalTypeArgs TResult? whenOrNull<TResult extends Object?>(TResult? Function( String id, int type, DateTime? verifiedAt, bool isPrimary, bool isPublic, String content, String accountId, DateTime createdAt, DateTime updatedAt, DateTime? deletedAt)? $default,) {final _that = this;
|
||||||
switch (_that) {
|
switch (_that) {
|
||||||
case _SnContactMethod() when $default != null:
|
case _SnContactMethod() when $default != null:
|
||||||
return $default(_that.id,_that.type,_that.verifiedAt,_that.isPrimary,_that.content,_that.accountId,_that.createdAt,_that.updatedAt,_that.deletedAt);case _:
|
return $default(_that.id,_that.type,_that.verifiedAt,_that.isPrimary,_that.isPublic,_that.content,_that.accountId,_that.createdAt,_that.updatedAt,_that.deletedAt);case _:
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -1823,13 +1833,14 @@ return $default(_that.id,_that.type,_that.verifiedAt,_that.isPrimary,_that.conte
|
|||||||
@JsonSerializable()
|
@JsonSerializable()
|
||||||
|
|
||||||
class _SnContactMethod implements SnContactMethod {
|
class _SnContactMethod implements SnContactMethod {
|
||||||
const _SnContactMethod({required this.id, required this.type, required this.verifiedAt, required this.isPrimary, required this.content, required this.accountId, required this.createdAt, required this.updatedAt, required this.deletedAt});
|
const _SnContactMethod({required this.id, required this.type, required this.verifiedAt, required this.isPrimary, required this.isPublic, required this.content, required this.accountId, required this.createdAt, required this.updatedAt, required this.deletedAt});
|
||||||
factory _SnContactMethod.fromJson(Map<String, dynamic> json) => _$SnContactMethodFromJson(json);
|
factory _SnContactMethod.fromJson(Map<String, dynamic> json) => _$SnContactMethodFromJson(json);
|
||||||
|
|
||||||
@override final String id;
|
@override final String id;
|
||||||
@override final int type;
|
@override final int type;
|
||||||
@override final DateTime? verifiedAt;
|
@override final DateTime? verifiedAt;
|
||||||
@override final bool isPrimary;
|
@override final bool isPrimary;
|
||||||
|
@override final bool isPublic;
|
||||||
@override final String content;
|
@override final String content;
|
||||||
@override final String accountId;
|
@override final String accountId;
|
||||||
@override final DateTime createdAt;
|
@override final DateTime createdAt;
|
||||||
@@ -1849,16 +1860,16 @@ Map<String, dynamic> toJson() {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
bool operator ==(Object other) {
|
bool operator ==(Object other) {
|
||||||
return identical(this, other) || (other.runtimeType == runtimeType&&other is _SnContactMethod&&(identical(other.id, id) || other.id == id)&&(identical(other.type, type) || other.type == type)&&(identical(other.verifiedAt, verifiedAt) || other.verifiedAt == verifiedAt)&&(identical(other.isPrimary, isPrimary) || other.isPrimary == isPrimary)&&(identical(other.content, content) || other.content == content)&&(identical(other.accountId, accountId) || other.accountId == accountId)&&(identical(other.createdAt, createdAt) || other.createdAt == createdAt)&&(identical(other.updatedAt, updatedAt) || other.updatedAt == updatedAt)&&(identical(other.deletedAt, deletedAt) || other.deletedAt == deletedAt));
|
return identical(this, other) || (other.runtimeType == runtimeType&&other is _SnContactMethod&&(identical(other.id, id) || other.id == id)&&(identical(other.type, type) || other.type == type)&&(identical(other.verifiedAt, verifiedAt) || other.verifiedAt == verifiedAt)&&(identical(other.isPrimary, isPrimary) || other.isPrimary == isPrimary)&&(identical(other.isPublic, isPublic) || other.isPublic == isPublic)&&(identical(other.content, content) || other.content == content)&&(identical(other.accountId, accountId) || other.accountId == accountId)&&(identical(other.createdAt, createdAt) || other.createdAt == createdAt)&&(identical(other.updatedAt, updatedAt) || other.updatedAt == updatedAt)&&(identical(other.deletedAt, deletedAt) || other.deletedAt == deletedAt));
|
||||||
}
|
}
|
||||||
|
|
||||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||||
@override
|
@override
|
||||||
int get hashCode => Object.hash(runtimeType,id,type,verifiedAt,isPrimary,content,accountId,createdAt,updatedAt,deletedAt);
|
int get hashCode => Object.hash(runtimeType,id,type,verifiedAt,isPrimary,isPublic,content,accountId,createdAt,updatedAt,deletedAt);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String toString() {
|
String toString() {
|
||||||
return 'SnContactMethod(id: $id, type: $type, verifiedAt: $verifiedAt, isPrimary: $isPrimary, content: $content, accountId: $accountId, createdAt: $createdAt, updatedAt: $updatedAt, deletedAt: $deletedAt)';
|
return 'SnContactMethod(id: $id, type: $type, verifiedAt: $verifiedAt, isPrimary: $isPrimary, isPublic: $isPublic, content: $content, accountId: $accountId, createdAt: $createdAt, updatedAt: $updatedAt, deletedAt: $deletedAt)';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -1869,7 +1880,7 @@ abstract mixin class _$SnContactMethodCopyWith<$Res> implements $SnContactMethod
|
|||||||
factory _$SnContactMethodCopyWith(_SnContactMethod value, $Res Function(_SnContactMethod) _then) = __$SnContactMethodCopyWithImpl;
|
factory _$SnContactMethodCopyWith(_SnContactMethod value, $Res Function(_SnContactMethod) _then) = __$SnContactMethodCopyWithImpl;
|
||||||
@override @useResult
|
@override @useResult
|
||||||
$Res call({
|
$Res call({
|
||||||
String id, int type, DateTime? verifiedAt, bool isPrimary, String content, String accountId, DateTime createdAt, DateTime updatedAt, DateTime? deletedAt
|
String id, int type, DateTime? verifiedAt, bool isPrimary, bool isPublic, String content, String accountId, DateTime createdAt, DateTime updatedAt, DateTime? deletedAt
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
@@ -1886,12 +1897,13 @@ class __$SnContactMethodCopyWithImpl<$Res>
|
|||||||
|
|
||||||
/// Create a copy of SnContactMethod
|
/// Create a copy of SnContactMethod
|
||||||
/// with the given fields replaced by the non-null parameter values.
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
@override @pragma('vm:prefer-inline') $Res call({Object? id = null,Object? type = null,Object? verifiedAt = freezed,Object? isPrimary = null,Object? content = null,Object? accountId = null,Object? createdAt = null,Object? updatedAt = null,Object? deletedAt = freezed,}) {
|
@override @pragma('vm:prefer-inline') $Res call({Object? id = null,Object? type = null,Object? verifiedAt = freezed,Object? isPrimary = null,Object? isPublic = null,Object? content = null,Object? accountId = null,Object? createdAt = null,Object? updatedAt = null,Object? deletedAt = freezed,}) {
|
||||||
return _then(_SnContactMethod(
|
return _then(_SnContactMethod(
|
||||||
id: null == id ? _self.id : id // ignore: cast_nullable_to_non_nullable
|
id: null == id ? _self.id : id // ignore: cast_nullable_to_non_nullable
|
||||||
as String,type: null == type ? _self.type : type // ignore: cast_nullable_to_non_nullable
|
as String,type: null == type ? _self.type : type // ignore: cast_nullable_to_non_nullable
|
||||||
as int,verifiedAt: freezed == verifiedAt ? _self.verifiedAt : verifiedAt // ignore: cast_nullable_to_non_nullable
|
as int,verifiedAt: freezed == verifiedAt ? _self.verifiedAt : verifiedAt // ignore: cast_nullable_to_non_nullable
|
||||||
as DateTime?,isPrimary: null == isPrimary ? _self.isPrimary : isPrimary // ignore: cast_nullable_to_non_nullable
|
as DateTime?,isPrimary: null == isPrimary ? _self.isPrimary : isPrimary // ignore: cast_nullable_to_non_nullable
|
||||||
|
as bool,isPublic: null == isPublic ? _self.isPublic : isPublic // ignore: cast_nullable_to_non_nullable
|
||||||
as bool,content: null == content ? _self.content : content // ignore: cast_nullable_to_non_nullable
|
as bool,content: null == content ? _self.content : content // ignore: cast_nullable_to_non_nullable
|
||||||
as String,accountId: null == accountId ? _self.accountId : accountId // ignore: cast_nullable_to_non_nullable
|
as String,accountId: null == accountId ? _self.accountId : accountId // ignore: cast_nullable_to_non_nullable
|
||||||
as String,createdAt: null == createdAt ? _self.createdAt : createdAt // ignore: cast_nullable_to_non_nullable
|
as String,createdAt: null == createdAt ? _self.createdAt : createdAt // ignore: cast_nullable_to_non_nullable
|
||||||
|
@@ -26,6 +26,11 @@ _SnAccount _$SnAccountFromJson(Map<String, dynamic> json) => _SnAccount(
|
|||||||
?.map((e) => SnAccountBadge.fromJson(e as Map<String, dynamic>))
|
?.map((e) => SnAccountBadge.fromJson(e as Map<String, dynamic>))
|
||||||
.toList() ??
|
.toList() ??
|
||||||
const [],
|
const [],
|
||||||
|
contacts:
|
||||||
|
(json['contacts'] as List<dynamic>?)
|
||||||
|
?.map((e) => SnContactMethod.fromJson(e as Map<String, dynamic>))
|
||||||
|
.toList() ??
|
||||||
|
const [],
|
||||||
createdAt: DateTime.parse(json['created_at'] as String),
|
createdAt: DateTime.parse(json['created_at'] as String),
|
||||||
updatedAt: DateTime.parse(json['updated_at'] as String),
|
updatedAt: DateTime.parse(json['updated_at'] as String),
|
||||||
deletedAt:
|
deletedAt:
|
||||||
@@ -46,6 +51,7 @@ Map<String, dynamic> _$SnAccountToJson(_SnAccount instance) =>
|
|||||||
'profile': instance.profile.toJson(),
|
'profile': instance.profile.toJson(),
|
||||||
'perk_subscription': instance.perkSubscription?.toJson(),
|
'perk_subscription': instance.perkSubscription?.toJson(),
|
||||||
'badges': instance.badges.map((e) => e.toJson()).toList(),
|
'badges': instance.badges.map((e) => e.toJson()).toList(),
|
||||||
|
'contacts': instance.contacts.map((e) => e.toJson()).toList(),
|
||||||
'created_at': instance.createdAt.toIso8601String(),
|
'created_at': instance.createdAt.toIso8601String(),
|
||||||
'updated_at': instance.updatedAt.toIso8601String(),
|
'updated_at': instance.updatedAt.toIso8601String(),
|
||||||
'deleted_at': instance.deletedAt?.toIso8601String(),
|
'deleted_at': instance.deletedAt?.toIso8601String(),
|
||||||
@@ -229,6 +235,7 @@ _SnContactMethod _$SnContactMethodFromJson(Map<String, dynamic> json) =>
|
|||||||
? null
|
? null
|
||||||
: DateTime.parse(json['verified_at'] as String),
|
: DateTime.parse(json['verified_at'] as String),
|
||||||
isPrimary: json['is_primary'] as bool,
|
isPrimary: json['is_primary'] as bool,
|
||||||
|
isPublic: json['is_public'] as bool,
|
||||||
content: json['content'] as String,
|
content: json['content'] as String,
|
||||||
accountId: json['account_id'] as String,
|
accountId: json['account_id'] as String,
|
||||||
createdAt: DateTime.parse(json['created_at'] as String),
|
createdAt: DateTime.parse(json['created_at'] as String),
|
||||||
@@ -245,6 +252,7 @@ Map<String, dynamic> _$SnContactMethodToJson(_SnContactMethod instance) =>
|
|||||||
'type': instance.type,
|
'type': instance.type,
|
||||||
'verified_at': instance.verifiedAt?.toIso8601String(),
|
'verified_at': instance.verifiedAt?.toIso8601String(),
|
||||||
'is_primary': instance.isPrimary,
|
'is_primary': instance.isPrimary,
|
||||||
|
'is_public': instance.isPublic,
|
||||||
'content': instance.content,
|
'content': instance.content,
|
||||||
'account_id': instance.accountId,
|
'account_id': instance.accountId,
|
||||||
'created_at': instance.createdAt.toIso8601String(),
|
'created_at': instance.createdAt.toIso8601String(),
|
||||||
|
@@ -1,4 +1,5 @@
|
|||||||
import 'package:freezed_annotation/freezed_annotation.dart';
|
import 'package:freezed_annotation/freezed_annotation.dart';
|
||||||
|
import 'package:island/models/account.dart';
|
||||||
import 'package:island/models/publisher.dart';
|
import 'package:island/models/publisher.dart';
|
||||||
|
|
||||||
part 'poll.freezed.dart';
|
part 'poll.freezed.dart';
|
||||||
@@ -101,6 +102,7 @@ sealed class SnPollAnswer with _$SnPollAnswer {
|
|||||||
required DateTime createdAt,
|
required DateTime createdAt,
|
||||||
required DateTime updatedAt,
|
required DateTime updatedAt,
|
||||||
required DateTime? deletedAt,
|
required DateTime? deletedAt,
|
||||||
|
SnAccount? account,
|
||||||
}) = _SnPollAnswer;
|
}) = _SnPollAnswer;
|
||||||
|
|
||||||
factory SnPollAnswer.fromJson(Map<String, dynamic> json) =>
|
factory SnPollAnswer.fromJson(Map<String, dynamic> json) =>
|
||||||
|
@@ -1187,7 +1187,7 @@ as int,
|
|||||||
/// @nodoc
|
/// @nodoc
|
||||||
mixin _$SnPollAnswer {
|
mixin _$SnPollAnswer {
|
||||||
|
|
||||||
String get id; Map<String, dynamic> get answer; String get accountId; String get pollId; DateTime get createdAt; DateTime get updatedAt; DateTime? get deletedAt;
|
String get id; Map<String, dynamic> get answer; String get accountId; String get pollId; DateTime get createdAt; DateTime get updatedAt; DateTime? get deletedAt; SnAccount? get account;
|
||||||
/// Create a copy of SnPollAnswer
|
/// Create a copy of SnPollAnswer
|
||||||
/// with the given fields replaced by the non-null parameter values.
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||||
@@ -1200,16 +1200,16 @@ $SnPollAnswerCopyWith<SnPollAnswer> get copyWith => _$SnPollAnswerCopyWithImpl<S
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
bool operator ==(Object other) {
|
bool operator ==(Object other) {
|
||||||
return identical(this, other) || (other.runtimeType == runtimeType&&other is SnPollAnswer&&(identical(other.id, id) || other.id == id)&&const DeepCollectionEquality().equals(other.answer, answer)&&(identical(other.accountId, accountId) || other.accountId == accountId)&&(identical(other.pollId, pollId) || other.pollId == pollId)&&(identical(other.createdAt, createdAt) || other.createdAt == createdAt)&&(identical(other.updatedAt, updatedAt) || other.updatedAt == updatedAt)&&(identical(other.deletedAt, deletedAt) || other.deletedAt == deletedAt));
|
return identical(this, other) || (other.runtimeType == runtimeType&&other is SnPollAnswer&&(identical(other.id, id) || other.id == id)&&const DeepCollectionEquality().equals(other.answer, answer)&&(identical(other.accountId, accountId) || other.accountId == accountId)&&(identical(other.pollId, pollId) || other.pollId == pollId)&&(identical(other.createdAt, createdAt) || other.createdAt == createdAt)&&(identical(other.updatedAt, updatedAt) || other.updatedAt == updatedAt)&&(identical(other.deletedAt, deletedAt) || other.deletedAt == deletedAt)&&(identical(other.account, account) || other.account == account));
|
||||||
}
|
}
|
||||||
|
|
||||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||||
@override
|
@override
|
||||||
int get hashCode => Object.hash(runtimeType,id,const DeepCollectionEquality().hash(answer),accountId,pollId,createdAt,updatedAt,deletedAt);
|
int get hashCode => Object.hash(runtimeType,id,const DeepCollectionEquality().hash(answer),accountId,pollId,createdAt,updatedAt,deletedAt,account);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String toString() {
|
String toString() {
|
||||||
return 'SnPollAnswer(id: $id, answer: $answer, accountId: $accountId, pollId: $pollId, createdAt: $createdAt, updatedAt: $updatedAt, deletedAt: $deletedAt)';
|
return 'SnPollAnswer(id: $id, answer: $answer, accountId: $accountId, pollId: $pollId, createdAt: $createdAt, updatedAt: $updatedAt, deletedAt: $deletedAt, account: $account)';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -1220,11 +1220,11 @@ abstract mixin class $SnPollAnswerCopyWith<$Res> {
|
|||||||
factory $SnPollAnswerCopyWith(SnPollAnswer value, $Res Function(SnPollAnswer) _then) = _$SnPollAnswerCopyWithImpl;
|
factory $SnPollAnswerCopyWith(SnPollAnswer value, $Res Function(SnPollAnswer) _then) = _$SnPollAnswerCopyWithImpl;
|
||||||
@useResult
|
@useResult
|
||||||
$Res call({
|
$Res call({
|
||||||
String id, Map<String, dynamic> answer, String accountId, String pollId, DateTime createdAt, DateTime updatedAt, DateTime? deletedAt
|
String id, Map<String, dynamic> answer, String accountId, String pollId, DateTime createdAt, DateTime updatedAt, DateTime? deletedAt, SnAccount? account
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
|
$SnAccountCopyWith<$Res>? get account;
|
||||||
|
|
||||||
}
|
}
|
||||||
/// @nodoc
|
/// @nodoc
|
||||||
@@ -1237,7 +1237,7 @@ class _$SnPollAnswerCopyWithImpl<$Res>
|
|||||||
|
|
||||||
/// Create a copy of SnPollAnswer
|
/// Create a copy of SnPollAnswer
|
||||||
/// with the given fields replaced by the non-null parameter values.
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
@pragma('vm:prefer-inline') @override $Res call({Object? id = null,Object? answer = null,Object? accountId = null,Object? pollId = null,Object? createdAt = null,Object? updatedAt = null,Object? deletedAt = freezed,}) {
|
@pragma('vm:prefer-inline') @override $Res call({Object? id = null,Object? answer = null,Object? accountId = null,Object? pollId = null,Object? createdAt = null,Object? updatedAt = null,Object? deletedAt = freezed,Object? account = freezed,}) {
|
||||||
return _then(_self.copyWith(
|
return _then(_self.copyWith(
|
||||||
id: null == id ? _self.id : id // ignore: cast_nullable_to_non_nullable
|
id: null == id ? _self.id : id // ignore: cast_nullable_to_non_nullable
|
||||||
as String,answer: null == answer ? _self.answer : answer // ignore: cast_nullable_to_non_nullable
|
as String,answer: null == answer ? _self.answer : answer // ignore: cast_nullable_to_non_nullable
|
||||||
@@ -1246,10 +1246,23 @@ as String,pollId: null == pollId ? _self.pollId : pollId // ignore: cast_nullabl
|
|||||||
as String,createdAt: null == createdAt ? _self.createdAt : createdAt // ignore: cast_nullable_to_non_nullable
|
as String,createdAt: null == createdAt ? _self.createdAt : createdAt // ignore: cast_nullable_to_non_nullable
|
||||||
as DateTime,updatedAt: null == updatedAt ? _self.updatedAt : updatedAt // ignore: cast_nullable_to_non_nullable
|
as DateTime,updatedAt: null == updatedAt ? _self.updatedAt : updatedAt // ignore: cast_nullable_to_non_nullable
|
||||||
as DateTime,deletedAt: freezed == deletedAt ? _self.deletedAt : deletedAt // ignore: cast_nullable_to_non_nullable
|
as DateTime,deletedAt: freezed == deletedAt ? _self.deletedAt : deletedAt // ignore: cast_nullable_to_non_nullable
|
||||||
as DateTime?,
|
as DateTime?,account: freezed == account ? _self.account : account // ignore: cast_nullable_to_non_nullable
|
||||||
|
as SnAccount?,
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
/// Create a copy of SnPollAnswer
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
|
@override
|
||||||
|
@pragma('vm:prefer-inline')
|
||||||
|
$SnAccountCopyWith<$Res>? get account {
|
||||||
|
if (_self.account == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $SnAccountCopyWith<$Res>(_self.account!, (value) {
|
||||||
|
return _then(_self.copyWith(account: value));
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -1328,10 +1341,10 @@ return $default(_that);case _:
|
|||||||
/// }
|
/// }
|
||||||
/// ```
|
/// ```
|
||||||
|
|
||||||
@optionalTypeArgs TResult maybeWhen<TResult extends Object?>(TResult Function( String id, Map<String, dynamic> answer, String accountId, String pollId, DateTime createdAt, DateTime updatedAt, DateTime? deletedAt)? $default,{required TResult orElse(),}) {final _that = this;
|
@optionalTypeArgs TResult maybeWhen<TResult extends Object?>(TResult Function( String id, Map<String, dynamic> answer, String accountId, String pollId, DateTime createdAt, DateTime updatedAt, DateTime? deletedAt, SnAccount? account)? $default,{required TResult orElse(),}) {final _that = this;
|
||||||
switch (_that) {
|
switch (_that) {
|
||||||
case _SnPollAnswer() when $default != null:
|
case _SnPollAnswer() when $default != null:
|
||||||
return $default(_that.id,_that.answer,_that.accountId,_that.pollId,_that.createdAt,_that.updatedAt,_that.deletedAt);case _:
|
return $default(_that.id,_that.answer,_that.accountId,_that.pollId,_that.createdAt,_that.updatedAt,_that.deletedAt,_that.account);case _:
|
||||||
return orElse();
|
return orElse();
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -1349,10 +1362,10 @@ return $default(_that.id,_that.answer,_that.accountId,_that.pollId,_that.created
|
|||||||
/// }
|
/// }
|
||||||
/// ```
|
/// ```
|
||||||
|
|
||||||
@optionalTypeArgs TResult when<TResult extends Object?>(TResult Function( String id, Map<String, dynamic> answer, String accountId, String pollId, DateTime createdAt, DateTime updatedAt, DateTime? deletedAt) $default,) {final _that = this;
|
@optionalTypeArgs TResult when<TResult extends Object?>(TResult Function( String id, Map<String, dynamic> answer, String accountId, String pollId, DateTime createdAt, DateTime updatedAt, DateTime? deletedAt, SnAccount? account) $default,) {final _that = this;
|
||||||
switch (_that) {
|
switch (_that) {
|
||||||
case _SnPollAnswer():
|
case _SnPollAnswer():
|
||||||
return $default(_that.id,_that.answer,_that.accountId,_that.pollId,_that.createdAt,_that.updatedAt,_that.deletedAt);}
|
return $default(_that.id,_that.answer,_that.accountId,_that.pollId,_that.createdAt,_that.updatedAt,_that.deletedAt,_that.account);}
|
||||||
}
|
}
|
||||||
/// A variant of `when` that fallback to returning `null`
|
/// A variant of `when` that fallback to returning `null`
|
||||||
///
|
///
|
||||||
@@ -1366,10 +1379,10 @@ return $default(_that.id,_that.answer,_that.accountId,_that.pollId,_that.created
|
|||||||
/// }
|
/// }
|
||||||
/// ```
|
/// ```
|
||||||
|
|
||||||
@optionalTypeArgs TResult? whenOrNull<TResult extends Object?>(TResult? Function( String id, Map<String, dynamic> answer, String accountId, String pollId, DateTime createdAt, DateTime updatedAt, DateTime? deletedAt)? $default,) {final _that = this;
|
@optionalTypeArgs TResult? whenOrNull<TResult extends Object?>(TResult? Function( String id, Map<String, dynamic> answer, String accountId, String pollId, DateTime createdAt, DateTime updatedAt, DateTime? deletedAt, SnAccount? account)? $default,) {final _that = this;
|
||||||
switch (_that) {
|
switch (_that) {
|
||||||
case _SnPollAnswer() when $default != null:
|
case _SnPollAnswer() when $default != null:
|
||||||
return $default(_that.id,_that.answer,_that.accountId,_that.pollId,_that.createdAt,_that.updatedAt,_that.deletedAt);case _:
|
return $default(_that.id,_that.answer,_that.accountId,_that.pollId,_that.createdAt,_that.updatedAt,_that.deletedAt,_that.account);case _:
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -1381,7 +1394,7 @@ return $default(_that.id,_that.answer,_that.accountId,_that.pollId,_that.created
|
|||||||
@JsonSerializable()
|
@JsonSerializable()
|
||||||
|
|
||||||
class _SnPollAnswer implements SnPollAnswer {
|
class _SnPollAnswer implements SnPollAnswer {
|
||||||
const _SnPollAnswer({required this.id, required final Map<String, dynamic> answer, required this.accountId, required this.pollId, required this.createdAt, required this.updatedAt, required this.deletedAt}): _answer = answer;
|
const _SnPollAnswer({required this.id, required final Map<String, dynamic> answer, required this.accountId, required this.pollId, required this.createdAt, required this.updatedAt, required this.deletedAt, this.account}): _answer = answer;
|
||||||
factory _SnPollAnswer.fromJson(Map<String, dynamic> json) => _$SnPollAnswerFromJson(json);
|
factory _SnPollAnswer.fromJson(Map<String, dynamic> json) => _$SnPollAnswerFromJson(json);
|
||||||
|
|
||||||
@override final String id;
|
@override final String id;
|
||||||
@@ -1397,6 +1410,7 @@ class _SnPollAnswer implements SnPollAnswer {
|
|||||||
@override final DateTime createdAt;
|
@override final DateTime createdAt;
|
||||||
@override final DateTime updatedAt;
|
@override final DateTime updatedAt;
|
||||||
@override final DateTime? deletedAt;
|
@override final DateTime? deletedAt;
|
||||||
|
@override final SnAccount? account;
|
||||||
|
|
||||||
/// Create a copy of SnPollAnswer
|
/// Create a copy of SnPollAnswer
|
||||||
/// with the given fields replaced by the non-null parameter values.
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
@@ -1411,16 +1425,16 @@ Map<String, dynamic> toJson() {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
bool operator ==(Object other) {
|
bool operator ==(Object other) {
|
||||||
return identical(this, other) || (other.runtimeType == runtimeType&&other is _SnPollAnswer&&(identical(other.id, id) || other.id == id)&&const DeepCollectionEquality().equals(other._answer, _answer)&&(identical(other.accountId, accountId) || other.accountId == accountId)&&(identical(other.pollId, pollId) || other.pollId == pollId)&&(identical(other.createdAt, createdAt) || other.createdAt == createdAt)&&(identical(other.updatedAt, updatedAt) || other.updatedAt == updatedAt)&&(identical(other.deletedAt, deletedAt) || other.deletedAt == deletedAt));
|
return identical(this, other) || (other.runtimeType == runtimeType&&other is _SnPollAnswer&&(identical(other.id, id) || other.id == id)&&const DeepCollectionEquality().equals(other._answer, _answer)&&(identical(other.accountId, accountId) || other.accountId == accountId)&&(identical(other.pollId, pollId) || other.pollId == pollId)&&(identical(other.createdAt, createdAt) || other.createdAt == createdAt)&&(identical(other.updatedAt, updatedAt) || other.updatedAt == updatedAt)&&(identical(other.deletedAt, deletedAt) || other.deletedAt == deletedAt)&&(identical(other.account, account) || other.account == account));
|
||||||
}
|
}
|
||||||
|
|
||||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||||
@override
|
@override
|
||||||
int get hashCode => Object.hash(runtimeType,id,const DeepCollectionEquality().hash(_answer),accountId,pollId,createdAt,updatedAt,deletedAt);
|
int get hashCode => Object.hash(runtimeType,id,const DeepCollectionEquality().hash(_answer),accountId,pollId,createdAt,updatedAt,deletedAt,account);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String toString() {
|
String toString() {
|
||||||
return 'SnPollAnswer(id: $id, answer: $answer, accountId: $accountId, pollId: $pollId, createdAt: $createdAt, updatedAt: $updatedAt, deletedAt: $deletedAt)';
|
return 'SnPollAnswer(id: $id, answer: $answer, accountId: $accountId, pollId: $pollId, createdAt: $createdAt, updatedAt: $updatedAt, deletedAt: $deletedAt, account: $account)';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -1431,11 +1445,11 @@ abstract mixin class _$SnPollAnswerCopyWith<$Res> implements $SnPollAnswerCopyWi
|
|||||||
factory _$SnPollAnswerCopyWith(_SnPollAnswer value, $Res Function(_SnPollAnswer) _then) = __$SnPollAnswerCopyWithImpl;
|
factory _$SnPollAnswerCopyWith(_SnPollAnswer value, $Res Function(_SnPollAnswer) _then) = __$SnPollAnswerCopyWithImpl;
|
||||||
@override @useResult
|
@override @useResult
|
||||||
$Res call({
|
$Res call({
|
||||||
String id, Map<String, dynamic> answer, String accountId, String pollId, DateTime createdAt, DateTime updatedAt, DateTime? deletedAt
|
String id, Map<String, dynamic> answer, String accountId, String pollId, DateTime createdAt, DateTime updatedAt, DateTime? deletedAt, SnAccount? account
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
|
@override $SnAccountCopyWith<$Res>? get account;
|
||||||
|
|
||||||
}
|
}
|
||||||
/// @nodoc
|
/// @nodoc
|
||||||
@@ -1448,7 +1462,7 @@ class __$SnPollAnswerCopyWithImpl<$Res>
|
|||||||
|
|
||||||
/// Create a copy of SnPollAnswer
|
/// Create a copy of SnPollAnswer
|
||||||
/// with the given fields replaced by the non-null parameter values.
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
@override @pragma('vm:prefer-inline') $Res call({Object? id = null,Object? answer = null,Object? accountId = null,Object? pollId = null,Object? createdAt = null,Object? updatedAt = null,Object? deletedAt = freezed,}) {
|
@override @pragma('vm:prefer-inline') $Res call({Object? id = null,Object? answer = null,Object? accountId = null,Object? pollId = null,Object? createdAt = null,Object? updatedAt = null,Object? deletedAt = freezed,Object? account = freezed,}) {
|
||||||
return _then(_SnPollAnswer(
|
return _then(_SnPollAnswer(
|
||||||
id: null == id ? _self.id : id // ignore: cast_nullable_to_non_nullable
|
id: null == id ? _self.id : id // ignore: cast_nullable_to_non_nullable
|
||||||
as String,answer: null == answer ? _self._answer : answer // ignore: cast_nullable_to_non_nullable
|
as String,answer: null == answer ? _self._answer : answer // ignore: cast_nullable_to_non_nullable
|
||||||
@@ -1457,11 +1471,24 @@ as String,pollId: null == pollId ? _self.pollId : pollId // ignore: cast_nullabl
|
|||||||
as String,createdAt: null == createdAt ? _self.createdAt : createdAt // ignore: cast_nullable_to_non_nullable
|
as String,createdAt: null == createdAt ? _self.createdAt : createdAt // ignore: cast_nullable_to_non_nullable
|
||||||
as DateTime,updatedAt: null == updatedAt ? _self.updatedAt : updatedAt // ignore: cast_nullable_to_non_nullable
|
as DateTime,updatedAt: null == updatedAt ? _self.updatedAt : updatedAt // ignore: cast_nullable_to_non_nullable
|
||||||
as DateTime,deletedAt: freezed == deletedAt ? _self.deletedAt : deletedAt // ignore: cast_nullable_to_non_nullable
|
as DateTime,deletedAt: freezed == deletedAt ? _self.deletedAt : deletedAt // ignore: cast_nullable_to_non_nullable
|
||||||
as DateTime?,
|
as DateTime?,account: freezed == account ? _self.account : account // ignore: cast_nullable_to_non_nullable
|
||||||
|
as SnAccount?,
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Create a copy of SnPollAnswer
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
|
@override
|
||||||
|
@pragma('vm:prefer-inline')
|
||||||
|
$SnAccountCopyWith<$Res>? get account {
|
||||||
|
if (_self.account == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $SnAccountCopyWith<$Res>(_self.account!, (value) {
|
||||||
|
return _then(_self.copyWith(account: value));
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// dart format on
|
// dart format on
|
||||||
|
@@ -144,6 +144,10 @@ _SnPollAnswer _$SnPollAnswerFromJson(Map<String, dynamic> json) =>
|
|||||||
json['deleted_at'] == null
|
json['deleted_at'] == null
|
||||||
? null
|
? null
|
||||||
: DateTime.parse(json['deleted_at'] as String),
|
: DateTime.parse(json['deleted_at'] as String),
|
||||||
|
account:
|
||||||
|
json['account'] == null
|
||||||
|
? null
|
||||||
|
: SnAccount.fromJson(json['account'] as Map<String, dynamic>),
|
||||||
);
|
);
|
||||||
|
|
||||||
Map<String, dynamic> _$SnPollAnswerToJson(_SnPollAnswer instance) =>
|
Map<String, dynamic> _$SnPollAnswerToJson(_SnPollAnswer instance) =>
|
||||||
@@ -155,4 +159,5 @@ Map<String, dynamic> _$SnPollAnswerToJson(_SnPollAnswer instance) =>
|
|||||||
'created_at': instance.createdAt.toIso8601String(),
|
'created_at': instance.createdAt.toIso8601String(),
|
||||||
'updated_at': instance.updatedAt.toIso8601String(),
|
'updated_at': instance.updatedAt.toIso8601String(),
|
||||||
'deleted_at': instance.deletedAt?.toIso8601String(),
|
'deleted_at': instance.deletedAt?.toIso8601String(),
|
||||||
|
'account': instance.account?.toJson(),
|
||||||
};
|
};
|
||||||
|
@@ -22,11 +22,13 @@ sealed class SnPost with _$SnPost {
|
|||||||
String? slug,
|
String? slug,
|
||||||
@Default(0) int type,
|
@Default(0) int type,
|
||||||
Map<String, dynamic>? meta,
|
Map<String, dynamic>? meta,
|
||||||
|
SnPostEmbedView? embedView,
|
||||||
@Default(0) int viewsUnique,
|
@Default(0) int viewsUnique,
|
||||||
@Default(0) int viewsTotal,
|
@Default(0) int viewsTotal,
|
||||||
@Default(0) int upvotes,
|
@Default(0) int upvotes,
|
||||||
@Default(0) int downvotes,
|
@Default(0) int downvotes,
|
||||||
@Default(0) int repliesCount,
|
@Default(0) int repliesCount,
|
||||||
|
@Default(0) int awardedScore,
|
||||||
int? pinMode,
|
int? pinMode,
|
||||||
String? threadedPostId,
|
String? threadedPostId,
|
||||||
SnPost? threadedPost,
|
SnPost? threadedPost,
|
||||||
@@ -105,3 +107,38 @@ const Map<String, ReactInfo> kReactionTemplates = {
|
|||||||
'pray': ReactInfo(icon: '🙏', attitude: 0),
|
'pray': ReactInfo(icon: '🙏', attitude: 0),
|
||||||
'heart': ReactInfo(icon: '❤️', attitude: 0),
|
'heart': ReactInfo(icon: '❤️', attitude: 0),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum PostEmbedViewRenderer {
|
||||||
|
@JsonValue(0)
|
||||||
|
webView,
|
||||||
|
}
|
||||||
|
|
||||||
|
@freezed
|
||||||
|
sealed class SnPostEmbedView with _$SnPostEmbedView {
|
||||||
|
const factory SnPostEmbedView({
|
||||||
|
required String uri,
|
||||||
|
double? aspectRatio,
|
||||||
|
@Default(PostEmbedViewRenderer.webView) PostEmbedViewRenderer renderer,
|
||||||
|
}) = _SnPostEmbedView;
|
||||||
|
|
||||||
|
factory SnPostEmbedView.fromJson(Map<String, dynamic> json) =>
|
||||||
|
_$SnPostEmbedViewFromJson(json);
|
||||||
|
}
|
||||||
|
|
||||||
|
@freezed
|
||||||
|
sealed class SnPostAward with _$SnPostAward {
|
||||||
|
const factory SnPostAward({
|
||||||
|
required String id,
|
||||||
|
required double amount,
|
||||||
|
required int attitude,
|
||||||
|
String? message,
|
||||||
|
required String postId,
|
||||||
|
required String accountId,
|
||||||
|
@Default(null) DateTime? createdAt,
|
||||||
|
@Default(null) DateTime? updatedAt,
|
||||||
|
DateTime? deletedAt,
|
||||||
|
}) = _SnPostAward;
|
||||||
|
|
||||||
|
factory SnPostAward.fromJson(Map<String, dynamic> json) =>
|
||||||
|
_$SnPostAwardFromJson(json);
|
||||||
|
}
|
||||||
|
@@ -15,7 +15,7 @@ T _$identity<T>(T value) => value;
|
|||||||
/// @nodoc
|
/// @nodoc
|
||||||
mixin _$SnPost {
|
mixin _$SnPost {
|
||||||
|
|
||||||
String get id; String? get title; String? get description; String? get language; DateTime? get editedAt; DateTime? get publishedAt; int get visibility; String? get content; String? get slug; int get type; Map<String, dynamic>? get meta; int get viewsUnique; int get viewsTotal; int get upvotes; int get downvotes; int get repliesCount; int? get pinMode; String? get threadedPostId; SnPost? get threadedPost; String? get repliedPostId; SnPost? get repliedPost; String? get forwardedPostId; SnPost? get forwardedPost; String? get realmId; SnRealm? get realm; List<SnCloudFile> get attachments; SnPublisher get publisher; Map<String, int> get reactionsCount; Map<String, bool> get reactionsMade; List<dynamic> get reactions; List<SnPostTag> get tags; List<SnPostCategory> get categories; List<dynamic> get collections; DateTime? get createdAt; DateTime? get updatedAt; DateTime? get deletedAt; bool get isTruncated;
|
String get id; String? get title; String? get description; String? get language; DateTime? get editedAt; DateTime? get publishedAt; int get visibility; String? get content; String? get slug; int get type; Map<String, dynamic>? get meta; SnPostEmbedView? get embedView; int get viewsUnique; int get viewsTotal; int get upvotes; int get downvotes; int get repliesCount; int get awardedScore; int? get pinMode; String? get threadedPostId; SnPost? get threadedPost; String? get repliedPostId; SnPost? get repliedPost; String? get forwardedPostId; SnPost? get forwardedPost; String? get realmId; SnRealm? get realm; List<SnCloudFile> get attachments; SnPublisher get publisher; Map<String, int> get reactionsCount; Map<String, bool> get reactionsMade; List<dynamic> get reactions; List<SnPostTag> get tags; List<SnPostCategory> get categories; List<dynamic> get collections; DateTime? get createdAt; DateTime? get updatedAt; DateTime? get deletedAt; bool get isTruncated;
|
||||||
/// Create a copy of SnPost
|
/// Create a copy of SnPost
|
||||||
/// with the given fields replaced by the non-null parameter values.
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||||
@@ -28,16 +28,16 @@ $SnPostCopyWith<SnPost> get copyWith => _$SnPostCopyWithImpl<SnPost>(this as SnP
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
bool operator ==(Object other) {
|
bool operator ==(Object other) {
|
||||||
return identical(this, other) || (other.runtimeType == runtimeType&&other is SnPost&&(identical(other.id, id) || other.id == id)&&(identical(other.title, title) || other.title == title)&&(identical(other.description, description) || other.description == description)&&(identical(other.language, language) || other.language == language)&&(identical(other.editedAt, editedAt) || other.editedAt == editedAt)&&(identical(other.publishedAt, publishedAt) || other.publishedAt == publishedAt)&&(identical(other.visibility, visibility) || other.visibility == visibility)&&(identical(other.content, content) || other.content == content)&&(identical(other.slug, slug) || other.slug == slug)&&(identical(other.type, type) || other.type == type)&&const DeepCollectionEquality().equals(other.meta, meta)&&(identical(other.viewsUnique, viewsUnique) || other.viewsUnique == viewsUnique)&&(identical(other.viewsTotal, viewsTotal) || other.viewsTotal == viewsTotal)&&(identical(other.upvotes, upvotes) || other.upvotes == upvotes)&&(identical(other.downvotes, downvotes) || other.downvotes == downvotes)&&(identical(other.repliesCount, repliesCount) || other.repliesCount == repliesCount)&&(identical(other.pinMode, pinMode) || other.pinMode == pinMode)&&(identical(other.threadedPostId, threadedPostId) || other.threadedPostId == threadedPostId)&&(identical(other.threadedPost, threadedPost) || other.threadedPost == threadedPost)&&(identical(other.repliedPostId, repliedPostId) || other.repliedPostId == repliedPostId)&&(identical(other.repliedPost, repliedPost) || other.repliedPost == repliedPost)&&(identical(other.forwardedPostId, forwardedPostId) || other.forwardedPostId == forwardedPostId)&&(identical(other.forwardedPost, forwardedPost) || other.forwardedPost == forwardedPost)&&(identical(other.realmId, realmId) || other.realmId == realmId)&&(identical(other.realm, realm) || other.realm == realm)&&const DeepCollectionEquality().equals(other.attachments, attachments)&&(identical(other.publisher, publisher) || other.publisher == publisher)&&const DeepCollectionEquality().equals(other.reactionsCount, reactionsCount)&&const DeepCollectionEquality().equals(other.reactionsMade, reactionsMade)&&const DeepCollectionEquality().equals(other.reactions, reactions)&&const DeepCollectionEquality().equals(other.tags, tags)&&const DeepCollectionEquality().equals(other.categories, categories)&&const DeepCollectionEquality().equals(other.collections, collections)&&(identical(other.createdAt, createdAt) || other.createdAt == createdAt)&&(identical(other.updatedAt, updatedAt) || other.updatedAt == updatedAt)&&(identical(other.deletedAt, deletedAt) || other.deletedAt == deletedAt)&&(identical(other.isTruncated, isTruncated) || other.isTruncated == isTruncated));
|
return identical(this, other) || (other.runtimeType == runtimeType&&other is SnPost&&(identical(other.id, id) || other.id == id)&&(identical(other.title, title) || other.title == title)&&(identical(other.description, description) || other.description == description)&&(identical(other.language, language) || other.language == language)&&(identical(other.editedAt, editedAt) || other.editedAt == editedAt)&&(identical(other.publishedAt, publishedAt) || other.publishedAt == publishedAt)&&(identical(other.visibility, visibility) || other.visibility == visibility)&&(identical(other.content, content) || other.content == content)&&(identical(other.slug, slug) || other.slug == slug)&&(identical(other.type, type) || other.type == type)&&const DeepCollectionEquality().equals(other.meta, meta)&&(identical(other.embedView, embedView) || other.embedView == embedView)&&(identical(other.viewsUnique, viewsUnique) || other.viewsUnique == viewsUnique)&&(identical(other.viewsTotal, viewsTotal) || other.viewsTotal == viewsTotal)&&(identical(other.upvotes, upvotes) || other.upvotes == upvotes)&&(identical(other.downvotes, downvotes) || other.downvotes == downvotes)&&(identical(other.repliesCount, repliesCount) || other.repliesCount == repliesCount)&&(identical(other.awardedScore, awardedScore) || other.awardedScore == awardedScore)&&(identical(other.pinMode, pinMode) || other.pinMode == pinMode)&&(identical(other.threadedPostId, threadedPostId) || other.threadedPostId == threadedPostId)&&(identical(other.threadedPost, threadedPost) || other.threadedPost == threadedPost)&&(identical(other.repliedPostId, repliedPostId) || other.repliedPostId == repliedPostId)&&(identical(other.repliedPost, repliedPost) || other.repliedPost == repliedPost)&&(identical(other.forwardedPostId, forwardedPostId) || other.forwardedPostId == forwardedPostId)&&(identical(other.forwardedPost, forwardedPost) || other.forwardedPost == forwardedPost)&&(identical(other.realmId, realmId) || other.realmId == realmId)&&(identical(other.realm, realm) || other.realm == realm)&&const DeepCollectionEquality().equals(other.attachments, attachments)&&(identical(other.publisher, publisher) || other.publisher == publisher)&&const DeepCollectionEquality().equals(other.reactionsCount, reactionsCount)&&const DeepCollectionEquality().equals(other.reactionsMade, reactionsMade)&&const DeepCollectionEquality().equals(other.reactions, reactions)&&const DeepCollectionEquality().equals(other.tags, tags)&&const DeepCollectionEquality().equals(other.categories, categories)&&const DeepCollectionEquality().equals(other.collections, collections)&&(identical(other.createdAt, createdAt) || other.createdAt == createdAt)&&(identical(other.updatedAt, updatedAt) || other.updatedAt == updatedAt)&&(identical(other.deletedAt, deletedAt) || other.deletedAt == deletedAt)&&(identical(other.isTruncated, isTruncated) || other.isTruncated == isTruncated));
|
||||||
}
|
}
|
||||||
|
|
||||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||||
@override
|
@override
|
||||||
int get hashCode => Object.hashAll([runtimeType,id,title,description,language,editedAt,publishedAt,visibility,content,slug,type,const DeepCollectionEquality().hash(meta),viewsUnique,viewsTotal,upvotes,downvotes,repliesCount,pinMode,threadedPostId,threadedPost,repliedPostId,repliedPost,forwardedPostId,forwardedPost,realmId,realm,const DeepCollectionEquality().hash(attachments),publisher,const DeepCollectionEquality().hash(reactionsCount),const DeepCollectionEquality().hash(reactionsMade),const DeepCollectionEquality().hash(reactions),const DeepCollectionEquality().hash(tags),const DeepCollectionEquality().hash(categories),const DeepCollectionEquality().hash(collections),createdAt,updatedAt,deletedAt,isTruncated]);
|
int get hashCode => Object.hashAll([runtimeType,id,title,description,language,editedAt,publishedAt,visibility,content,slug,type,const DeepCollectionEquality().hash(meta),embedView,viewsUnique,viewsTotal,upvotes,downvotes,repliesCount,awardedScore,pinMode,threadedPostId,threadedPost,repliedPostId,repliedPost,forwardedPostId,forwardedPost,realmId,realm,const DeepCollectionEquality().hash(attachments),publisher,const DeepCollectionEquality().hash(reactionsCount),const DeepCollectionEquality().hash(reactionsMade),const DeepCollectionEquality().hash(reactions),const DeepCollectionEquality().hash(tags),const DeepCollectionEquality().hash(categories),const DeepCollectionEquality().hash(collections),createdAt,updatedAt,deletedAt,isTruncated]);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String toString() {
|
String toString() {
|
||||||
return 'SnPost(id: $id, title: $title, description: $description, language: $language, editedAt: $editedAt, publishedAt: $publishedAt, visibility: $visibility, content: $content, slug: $slug, type: $type, meta: $meta, viewsUnique: $viewsUnique, viewsTotal: $viewsTotal, upvotes: $upvotes, downvotes: $downvotes, repliesCount: $repliesCount, pinMode: $pinMode, threadedPostId: $threadedPostId, threadedPost: $threadedPost, repliedPostId: $repliedPostId, repliedPost: $repliedPost, forwardedPostId: $forwardedPostId, forwardedPost: $forwardedPost, realmId: $realmId, realm: $realm, attachments: $attachments, publisher: $publisher, reactionsCount: $reactionsCount, reactionsMade: $reactionsMade, reactions: $reactions, tags: $tags, categories: $categories, collections: $collections, createdAt: $createdAt, updatedAt: $updatedAt, deletedAt: $deletedAt, isTruncated: $isTruncated)';
|
return 'SnPost(id: $id, title: $title, description: $description, language: $language, editedAt: $editedAt, publishedAt: $publishedAt, visibility: $visibility, content: $content, slug: $slug, type: $type, meta: $meta, embedView: $embedView, viewsUnique: $viewsUnique, viewsTotal: $viewsTotal, upvotes: $upvotes, downvotes: $downvotes, repliesCount: $repliesCount, awardedScore: $awardedScore, pinMode: $pinMode, threadedPostId: $threadedPostId, threadedPost: $threadedPost, repliedPostId: $repliedPostId, repliedPost: $repliedPost, forwardedPostId: $forwardedPostId, forwardedPost: $forwardedPost, realmId: $realmId, realm: $realm, attachments: $attachments, publisher: $publisher, reactionsCount: $reactionsCount, reactionsMade: $reactionsMade, reactions: $reactions, tags: $tags, categories: $categories, collections: $collections, createdAt: $createdAt, updatedAt: $updatedAt, deletedAt: $deletedAt, isTruncated: $isTruncated)';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -48,11 +48,11 @@ abstract mixin class $SnPostCopyWith<$Res> {
|
|||||||
factory $SnPostCopyWith(SnPost value, $Res Function(SnPost) _then) = _$SnPostCopyWithImpl;
|
factory $SnPostCopyWith(SnPost value, $Res Function(SnPost) _then) = _$SnPostCopyWithImpl;
|
||||||
@useResult
|
@useResult
|
||||||
$Res call({
|
$Res call({
|
||||||
String id, String? title, String? description, String? language, DateTime? editedAt, DateTime? publishedAt, int visibility, String? content, String? slug, int type, Map<String, dynamic>? meta, int viewsUnique, int viewsTotal, int upvotes, int downvotes, int repliesCount, int? pinMode, String? threadedPostId, SnPost? threadedPost, String? repliedPostId, SnPost? repliedPost, String? forwardedPostId, SnPost? forwardedPost, String? realmId, SnRealm? realm, List<SnCloudFile> attachments, SnPublisher publisher, Map<String, int> reactionsCount, Map<String, bool> reactionsMade, List<dynamic> reactions, List<SnPostTag> tags, List<SnPostCategory> categories, List<dynamic> collections, DateTime? createdAt, DateTime? updatedAt, DateTime? deletedAt, bool isTruncated
|
String id, String? title, String? description, String? language, DateTime? editedAt, DateTime? publishedAt, int visibility, String? content, String? slug, int type, Map<String, dynamic>? meta, SnPostEmbedView? embedView, int viewsUnique, int viewsTotal, int upvotes, int downvotes, int repliesCount, int awardedScore, int? pinMode, String? threadedPostId, SnPost? threadedPost, String? repliedPostId, SnPost? repliedPost, String? forwardedPostId, SnPost? forwardedPost, String? realmId, SnRealm? realm, List<SnCloudFile> attachments, SnPublisher publisher, Map<String, int> reactionsCount, Map<String, bool> reactionsMade, List<dynamic> reactions, List<SnPostTag> tags, List<SnPostCategory> categories, List<dynamic> collections, DateTime? createdAt, DateTime? updatedAt, DateTime? deletedAt, bool isTruncated
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
$SnPostCopyWith<$Res>? get threadedPost;$SnPostCopyWith<$Res>? get repliedPost;$SnPostCopyWith<$Res>? get forwardedPost;$SnRealmCopyWith<$Res>? get realm;$SnPublisherCopyWith<$Res> get publisher;
|
$SnPostEmbedViewCopyWith<$Res>? get embedView;$SnPostCopyWith<$Res>? get threadedPost;$SnPostCopyWith<$Res>? get repliedPost;$SnPostCopyWith<$Res>? get forwardedPost;$SnRealmCopyWith<$Res>? get realm;$SnPublisherCopyWith<$Res> get publisher;
|
||||||
|
|
||||||
}
|
}
|
||||||
/// @nodoc
|
/// @nodoc
|
||||||
@@ -65,7 +65,7 @@ class _$SnPostCopyWithImpl<$Res>
|
|||||||
|
|
||||||
/// Create a copy of SnPost
|
/// Create a copy of SnPost
|
||||||
/// with the given fields replaced by the non-null parameter values.
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
@pragma('vm:prefer-inline') @override $Res call({Object? id = null,Object? title = freezed,Object? description = freezed,Object? language = freezed,Object? editedAt = freezed,Object? publishedAt = freezed,Object? visibility = null,Object? content = freezed,Object? slug = freezed,Object? type = null,Object? meta = freezed,Object? viewsUnique = null,Object? viewsTotal = null,Object? upvotes = null,Object? downvotes = null,Object? repliesCount = null,Object? pinMode = freezed,Object? threadedPostId = freezed,Object? threadedPost = freezed,Object? repliedPostId = freezed,Object? repliedPost = freezed,Object? forwardedPostId = freezed,Object? forwardedPost = freezed,Object? realmId = freezed,Object? realm = freezed,Object? attachments = null,Object? publisher = null,Object? reactionsCount = null,Object? reactionsMade = null,Object? reactions = null,Object? tags = null,Object? categories = null,Object? collections = null,Object? createdAt = freezed,Object? updatedAt = freezed,Object? deletedAt = freezed,Object? isTruncated = null,}) {
|
@pragma('vm:prefer-inline') @override $Res call({Object? id = null,Object? title = freezed,Object? description = freezed,Object? language = freezed,Object? editedAt = freezed,Object? publishedAt = freezed,Object? visibility = null,Object? content = freezed,Object? slug = freezed,Object? type = null,Object? meta = freezed,Object? embedView = freezed,Object? viewsUnique = null,Object? viewsTotal = null,Object? upvotes = null,Object? downvotes = null,Object? repliesCount = null,Object? awardedScore = null,Object? pinMode = freezed,Object? threadedPostId = freezed,Object? threadedPost = freezed,Object? repliedPostId = freezed,Object? repliedPost = freezed,Object? forwardedPostId = freezed,Object? forwardedPost = freezed,Object? realmId = freezed,Object? realm = freezed,Object? attachments = null,Object? publisher = null,Object? reactionsCount = null,Object? reactionsMade = null,Object? reactions = null,Object? tags = null,Object? categories = null,Object? collections = null,Object? createdAt = freezed,Object? updatedAt = freezed,Object? deletedAt = freezed,Object? isTruncated = null,}) {
|
||||||
return _then(_self.copyWith(
|
return _then(_self.copyWith(
|
||||||
id: null == id ? _self.id : id // ignore: cast_nullable_to_non_nullable
|
id: null == id ? _self.id : id // ignore: cast_nullable_to_non_nullable
|
||||||
as String,title: freezed == title ? _self.title : title // ignore: cast_nullable_to_non_nullable
|
as String,title: freezed == title ? _self.title : title // ignore: cast_nullable_to_non_nullable
|
||||||
@@ -78,11 +78,13 @@ as int,content: freezed == content ? _self.content : content // ignore: cast_nul
|
|||||||
as String?,slug: freezed == slug ? _self.slug : slug // ignore: cast_nullable_to_non_nullable
|
as String?,slug: freezed == slug ? _self.slug : slug // ignore: cast_nullable_to_non_nullable
|
||||||
as String?,type: null == type ? _self.type : type // ignore: cast_nullable_to_non_nullable
|
as String?,type: null == type ? _self.type : type // ignore: cast_nullable_to_non_nullable
|
||||||
as int,meta: freezed == meta ? _self.meta : meta // ignore: cast_nullable_to_non_nullable
|
as int,meta: freezed == meta ? _self.meta : meta // ignore: cast_nullable_to_non_nullable
|
||||||
as Map<String, dynamic>?,viewsUnique: null == viewsUnique ? _self.viewsUnique : viewsUnique // ignore: cast_nullable_to_non_nullable
|
as Map<String, dynamic>?,embedView: freezed == embedView ? _self.embedView : embedView // ignore: cast_nullable_to_non_nullable
|
||||||
|
as SnPostEmbedView?,viewsUnique: null == viewsUnique ? _self.viewsUnique : viewsUnique // ignore: cast_nullable_to_non_nullable
|
||||||
as int,viewsTotal: null == viewsTotal ? _self.viewsTotal : viewsTotal // ignore: cast_nullable_to_non_nullable
|
as int,viewsTotal: null == viewsTotal ? _self.viewsTotal : viewsTotal // ignore: cast_nullable_to_non_nullable
|
||||||
as int,upvotes: null == upvotes ? _self.upvotes : upvotes // ignore: cast_nullable_to_non_nullable
|
as int,upvotes: null == upvotes ? _self.upvotes : upvotes // ignore: cast_nullable_to_non_nullable
|
||||||
as int,downvotes: null == downvotes ? _self.downvotes : downvotes // ignore: cast_nullable_to_non_nullable
|
as int,downvotes: null == downvotes ? _self.downvotes : downvotes // ignore: cast_nullable_to_non_nullable
|
||||||
as int,repliesCount: null == repliesCount ? _self.repliesCount : repliesCount // ignore: cast_nullable_to_non_nullable
|
as int,repliesCount: null == repliesCount ? _self.repliesCount : repliesCount // ignore: cast_nullable_to_non_nullable
|
||||||
|
as int,awardedScore: null == awardedScore ? _self.awardedScore : awardedScore // ignore: cast_nullable_to_non_nullable
|
||||||
as int,pinMode: freezed == pinMode ? _self.pinMode : pinMode // ignore: cast_nullable_to_non_nullable
|
as int,pinMode: freezed == pinMode ? _self.pinMode : pinMode // ignore: cast_nullable_to_non_nullable
|
||||||
as int?,threadedPostId: freezed == threadedPostId ? _self.threadedPostId : threadedPostId // ignore: cast_nullable_to_non_nullable
|
as int?,threadedPostId: freezed == threadedPostId ? _self.threadedPostId : threadedPostId // ignore: cast_nullable_to_non_nullable
|
||||||
as String?,threadedPost: freezed == threadedPost ? _self.threadedPost : threadedPost // ignore: cast_nullable_to_non_nullable
|
as String?,threadedPost: freezed == threadedPost ? _self.threadedPost : threadedPost // ignore: cast_nullable_to_non_nullable
|
||||||
@@ -111,6 +113,18 @@ as bool,
|
|||||||
/// with the given fields replaced by the non-null parameter values.
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
@override
|
@override
|
||||||
@pragma('vm:prefer-inline')
|
@pragma('vm:prefer-inline')
|
||||||
|
$SnPostEmbedViewCopyWith<$Res>? get embedView {
|
||||||
|
if (_self.embedView == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $SnPostEmbedViewCopyWith<$Res>(_self.embedView!, (value) {
|
||||||
|
return _then(_self.copyWith(embedView: value));
|
||||||
|
});
|
||||||
|
}/// Create a copy of SnPost
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
|
@override
|
||||||
|
@pragma('vm:prefer-inline')
|
||||||
$SnPostCopyWith<$Res>? get threadedPost {
|
$SnPostCopyWith<$Res>? get threadedPost {
|
||||||
if (_self.threadedPost == null) {
|
if (_self.threadedPost == null) {
|
||||||
return null;
|
return null;
|
||||||
@@ -243,10 +257,10 @@ return $default(_that);case _:
|
|||||||
/// }
|
/// }
|
||||||
/// ```
|
/// ```
|
||||||
|
|
||||||
@optionalTypeArgs TResult maybeWhen<TResult extends Object?>(TResult Function( String id, String? title, String? description, String? language, DateTime? editedAt, DateTime? publishedAt, int visibility, String? content, String? slug, int type, Map<String, dynamic>? meta, int viewsUnique, int viewsTotal, int upvotes, int downvotes, int repliesCount, int? pinMode, String? threadedPostId, SnPost? threadedPost, String? repliedPostId, SnPost? repliedPost, String? forwardedPostId, SnPost? forwardedPost, String? realmId, SnRealm? realm, List<SnCloudFile> attachments, SnPublisher publisher, Map<String, int> reactionsCount, Map<String, bool> reactionsMade, List<dynamic> reactions, List<SnPostTag> tags, List<SnPostCategory> categories, List<dynamic> collections, DateTime? createdAt, DateTime? updatedAt, DateTime? deletedAt, bool isTruncated)? $default,{required TResult orElse(),}) {final _that = this;
|
@optionalTypeArgs TResult maybeWhen<TResult extends Object?>(TResult Function( String id, String? title, String? description, String? language, DateTime? editedAt, DateTime? publishedAt, int visibility, String? content, String? slug, int type, Map<String, dynamic>? meta, SnPostEmbedView? embedView, int viewsUnique, int viewsTotal, int upvotes, int downvotes, int repliesCount, int awardedScore, int? pinMode, String? threadedPostId, SnPost? threadedPost, String? repliedPostId, SnPost? repliedPost, String? forwardedPostId, SnPost? forwardedPost, String? realmId, SnRealm? realm, List<SnCloudFile> attachments, SnPublisher publisher, Map<String, int> reactionsCount, Map<String, bool> reactionsMade, List<dynamic> reactions, List<SnPostTag> tags, List<SnPostCategory> categories, List<dynamic> collections, DateTime? createdAt, DateTime? updatedAt, DateTime? deletedAt, bool isTruncated)? $default,{required TResult orElse(),}) {final _that = this;
|
||||||
switch (_that) {
|
switch (_that) {
|
||||||
case _SnPost() when $default != null:
|
case _SnPost() when $default != null:
|
||||||
return $default(_that.id,_that.title,_that.description,_that.language,_that.editedAt,_that.publishedAt,_that.visibility,_that.content,_that.slug,_that.type,_that.meta,_that.viewsUnique,_that.viewsTotal,_that.upvotes,_that.downvotes,_that.repliesCount,_that.pinMode,_that.threadedPostId,_that.threadedPost,_that.repliedPostId,_that.repliedPost,_that.forwardedPostId,_that.forwardedPost,_that.realmId,_that.realm,_that.attachments,_that.publisher,_that.reactionsCount,_that.reactionsMade,_that.reactions,_that.tags,_that.categories,_that.collections,_that.createdAt,_that.updatedAt,_that.deletedAt,_that.isTruncated);case _:
|
return $default(_that.id,_that.title,_that.description,_that.language,_that.editedAt,_that.publishedAt,_that.visibility,_that.content,_that.slug,_that.type,_that.meta,_that.embedView,_that.viewsUnique,_that.viewsTotal,_that.upvotes,_that.downvotes,_that.repliesCount,_that.awardedScore,_that.pinMode,_that.threadedPostId,_that.threadedPost,_that.repliedPostId,_that.repliedPost,_that.forwardedPostId,_that.forwardedPost,_that.realmId,_that.realm,_that.attachments,_that.publisher,_that.reactionsCount,_that.reactionsMade,_that.reactions,_that.tags,_that.categories,_that.collections,_that.createdAt,_that.updatedAt,_that.deletedAt,_that.isTruncated);case _:
|
||||||
return orElse();
|
return orElse();
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -264,10 +278,10 @@ return $default(_that.id,_that.title,_that.description,_that.language,_that.edit
|
|||||||
/// }
|
/// }
|
||||||
/// ```
|
/// ```
|
||||||
|
|
||||||
@optionalTypeArgs TResult when<TResult extends Object?>(TResult Function( String id, String? title, String? description, String? language, DateTime? editedAt, DateTime? publishedAt, int visibility, String? content, String? slug, int type, Map<String, dynamic>? meta, int viewsUnique, int viewsTotal, int upvotes, int downvotes, int repliesCount, int? pinMode, String? threadedPostId, SnPost? threadedPost, String? repliedPostId, SnPost? repliedPost, String? forwardedPostId, SnPost? forwardedPost, String? realmId, SnRealm? realm, List<SnCloudFile> attachments, SnPublisher publisher, Map<String, int> reactionsCount, Map<String, bool> reactionsMade, List<dynamic> reactions, List<SnPostTag> tags, List<SnPostCategory> categories, List<dynamic> collections, DateTime? createdAt, DateTime? updatedAt, DateTime? deletedAt, bool isTruncated) $default,) {final _that = this;
|
@optionalTypeArgs TResult when<TResult extends Object?>(TResult Function( String id, String? title, String? description, String? language, DateTime? editedAt, DateTime? publishedAt, int visibility, String? content, String? slug, int type, Map<String, dynamic>? meta, SnPostEmbedView? embedView, int viewsUnique, int viewsTotal, int upvotes, int downvotes, int repliesCount, int awardedScore, int? pinMode, String? threadedPostId, SnPost? threadedPost, String? repliedPostId, SnPost? repliedPost, String? forwardedPostId, SnPost? forwardedPost, String? realmId, SnRealm? realm, List<SnCloudFile> attachments, SnPublisher publisher, Map<String, int> reactionsCount, Map<String, bool> reactionsMade, List<dynamic> reactions, List<SnPostTag> tags, List<SnPostCategory> categories, List<dynamic> collections, DateTime? createdAt, DateTime? updatedAt, DateTime? deletedAt, bool isTruncated) $default,) {final _that = this;
|
||||||
switch (_that) {
|
switch (_that) {
|
||||||
case _SnPost():
|
case _SnPost():
|
||||||
return $default(_that.id,_that.title,_that.description,_that.language,_that.editedAt,_that.publishedAt,_that.visibility,_that.content,_that.slug,_that.type,_that.meta,_that.viewsUnique,_that.viewsTotal,_that.upvotes,_that.downvotes,_that.repliesCount,_that.pinMode,_that.threadedPostId,_that.threadedPost,_that.repliedPostId,_that.repliedPost,_that.forwardedPostId,_that.forwardedPost,_that.realmId,_that.realm,_that.attachments,_that.publisher,_that.reactionsCount,_that.reactionsMade,_that.reactions,_that.tags,_that.categories,_that.collections,_that.createdAt,_that.updatedAt,_that.deletedAt,_that.isTruncated);}
|
return $default(_that.id,_that.title,_that.description,_that.language,_that.editedAt,_that.publishedAt,_that.visibility,_that.content,_that.slug,_that.type,_that.meta,_that.embedView,_that.viewsUnique,_that.viewsTotal,_that.upvotes,_that.downvotes,_that.repliesCount,_that.awardedScore,_that.pinMode,_that.threadedPostId,_that.threadedPost,_that.repliedPostId,_that.repliedPost,_that.forwardedPostId,_that.forwardedPost,_that.realmId,_that.realm,_that.attachments,_that.publisher,_that.reactionsCount,_that.reactionsMade,_that.reactions,_that.tags,_that.categories,_that.collections,_that.createdAt,_that.updatedAt,_that.deletedAt,_that.isTruncated);}
|
||||||
}
|
}
|
||||||
/// A variant of `when` that fallback to returning `null`
|
/// A variant of `when` that fallback to returning `null`
|
||||||
///
|
///
|
||||||
@@ -281,10 +295,10 @@ return $default(_that.id,_that.title,_that.description,_that.language,_that.edit
|
|||||||
/// }
|
/// }
|
||||||
/// ```
|
/// ```
|
||||||
|
|
||||||
@optionalTypeArgs TResult? whenOrNull<TResult extends Object?>(TResult? Function( String id, String? title, String? description, String? language, DateTime? editedAt, DateTime? publishedAt, int visibility, String? content, String? slug, int type, Map<String, dynamic>? meta, int viewsUnique, int viewsTotal, int upvotes, int downvotes, int repliesCount, int? pinMode, String? threadedPostId, SnPost? threadedPost, String? repliedPostId, SnPost? repliedPost, String? forwardedPostId, SnPost? forwardedPost, String? realmId, SnRealm? realm, List<SnCloudFile> attachments, SnPublisher publisher, Map<String, int> reactionsCount, Map<String, bool> reactionsMade, List<dynamic> reactions, List<SnPostTag> tags, List<SnPostCategory> categories, List<dynamic> collections, DateTime? createdAt, DateTime? updatedAt, DateTime? deletedAt, bool isTruncated)? $default,) {final _that = this;
|
@optionalTypeArgs TResult? whenOrNull<TResult extends Object?>(TResult? Function( String id, String? title, String? description, String? language, DateTime? editedAt, DateTime? publishedAt, int visibility, String? content, String? slug, int type, Map<String, dynamic>? meta, SnPostEmbedView? embedView, int viewsUnique, int viewsTotal, int upvotes, int downvotes, int repliesCount, int awardedScore, int? pinMode, String? threadedPostId, SnPost? threadedPost, String? repliedPostId, SnPost? repliedPost, String? forwardedPostId, SnPost? forwardedPost, String? realmId, SnRealm? realm, List<SnCloudFile> attachments, SnPublisher publisher, Map<String, int> reactionsCount, Map<String, bool> reactionsMade, List<dynamic> reactions, List<SnPostTag> tags, List<SnPostCategory> categories, List<dynamic> collections, DateTime? createdAt, DateTime? updatedAt, DateTime? deletedAt, bool isTruncated)? $default,) {final _that = this;
|
||||||
switch (_that) {
|
switch (_that) {
|
||||||
case _SnPost() when $default != null:
|
case _SnPost() when $default != null:
|
||||||
return $default(_that.id,_that.title,_that.description,_that.language,_that.editedAt,_that.publishedAt,_that.visibility,_that.content,_that.slug,_that.type,_that.meta,_that.viewsUnique,_that.viewsTotal,_that.upvotes,_that.downvotes,_that.repliesCount,_that.pinMode,_that.threadedPostId,_that.threadedPost,_that.repliedPostId,_that.repliedPost,_that.forwardedPostId,_that.forwardedPost,_that.realmId,_that.realm,_that.attachments,_that.publisher,_that.reactionsCount,_that.reactionsMade,_that.reactions,_that.tags,_that.categories,_that.collections,_that.createdAt,_that.updatedAt,_that.deletedAt,_that.isTruncated);case _:
|
return $default(_that.id,_that.title,_that.description,_that.language,_that.editedAt,_that.publishedAt,_that.visibility,_that.content,_that.slug,_that.type,_that.meta,_that.embedView,_that.viewsUnique,_that.viewsTotal,_that.upvotes,_that.downvotes,_that.repliesCount,_that.awardedScore,_that.pinMode,_that.threadedPostId,_that.threadedPost,_that.repliedPostId,_that.repliedPost,_that.forwardedPostId,_that.forwardedPost,_that.realmId,_that.realm,_that.attachments,_that.publisher,_that.reactionsCount,_that.reactionsMade,_that.reactions,_that.tags,_that.categories,_that.collections,_that.createdAt,_that.updatedAt,_that.deletedAt,_that.isTruncated);case _:
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -296,7 +310,7 @@ return $default(_that.id,_that.title,_that.description,_that.language,_that.edit
|
|||||||
@JsonSerializable()
|
@JsonSerializable()
|
||||||
|
|
||||||
class _SnPost implements SnPost {
|
class _SnPost implements SnPost {
|
||||||
const _SnPost({required this.id, this.title, this.description, this.language, this.editedAt, this.publishedAt = null, this.visibility = 0, this.content, this.slug, this.type = 0, final Map<String, dynamic>? meta, this.viewsUnique = 0, this.viewsTotal = 0, this.upvotes = 0, this.downvotes = 0, this.repliesCount = 0, this.pinMode, this.threadedPostId, this.threadedPost, this.repliedPostId, this.repliedPost, this.forwardedPostId, this.forwardedPost, this.realmId, this.realm, final List<SnCloudFile> attachments = const [], required this.publisher, final Map<String, int> reactionsCount = const {}, final Map<String, bool> reactionsMade = const {}, final List<dynamic> reactions = const [], final List<SnPostTag> tags = const [], final List<SnPostCategory> categories = const [], final List<dynamic> collections = const [], this.createdAt = null, this.updatedAt = null, this.deletedAt, this.isTruncated = false}): _meta = meta,_attachments = attachments,_reactionsCount = reactionsCount,_reactionsMade = reactionsMade,_reactions = reactions,_tags = tags,_categories = categories,_collections = collections;
|
const _SnPost({required this.id, this.title, this.description, this.language, this.editedAt, this.publishedAt = null, this.visibility = 0, this.content, this.slug, this.type = 0, final Map<String, dynamic>? meta, this.embedView, this.viewsUnique = 0, this.viewsTotal = 0, this.upvotes = 0, this.downvotes = 0, this.repliesCount = 0, this.awardedScore = 0, this.pinMode, this.threadedPostId, this.threadedPost, this.repliedPostId, this.repliedPost, this.forwardedPostId, this.forwardedPost, this.realmId, this.realm, final List<SnCloudFile> attachments = const [], required this.publisher, final Map<String, int> reactionsCount = const {}, final Map<String, bool> reactionsMade = const {}, final List<dynamic> reactions = const [], final List<SnPostTag> tags = const [], final List<SnPostCategory> categories = const [], final List<dynamic> collections = const [], this.createdAt = null, this.updatedAt = null, this.deletedAt, this.isTruncated = false}): _meta = meta,_attachments = attachments,_reactionsCount = reactionsCount,_reactionsMade = reactionsMade,_reactions = reactions,_tags = tags,_categories = categories,_collections = collections;
|
||||||
factory _SnPost.fromJson(Map<String, dynamic> json) => _$SnPostFromJson(json);
|
factory _SnPost.fromJson(Map<String, dynamic> json) => _$SnPostFromJson(json);
|
||||||
|
|
||||||
@override final String id;
|
@override final String id;
|
||||||
@@ -318,11 +332,13 @@ class _SnPost implements SnPost {
|
|||||||
return EqualUnmodifiableMapView(value);
|
return EqualUnmodifiableMapView(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@override final SnPostEmbedView? embedView;
|
||||||
@override@JsonKey() final int viewsUnique;
|
@override@JsonKey() final int viewsUnique;
|
||||||
@override@JsonKey() final int viewsTotal;
|
@override@JsonKey() final int viewsTotal;
|
||||||
@override@JsonKey() final int upvotes;
|
@override@JsonKey() final int upvotes;
|
||||||
@override@JsonKey() final int downvotes;
|
@override@JsonKey() final int downvotes;
|
||||||
@override@JsonKey() final int repliesCount;
|
@override@JsonKey() final int repliesCount;
|
||||||
|
@override@JsonKey() final int awardedScore;
|
||||||
@override final int? pinMode;
|
@override final int? pinMode;
|
||||||
@override final String? threadedPostId;
|
@override final String? threadedPostId;
|
||||||
@override final SnPost? threadedPost;
|
@override final SnPost? threadedPost;
|
||||||
@@ -400,16 +416,16 @@ Map<String, dynamic> toJson() {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
bool operator ==(Object other) {
|
bool operator ==(Object other) {
|
||||||
return identical(this, other) || (other.runtimeType == runtimeType&&other is _SnPost&&(identical(other.id, id) || other.id == id)&&(identical(other.title, title) || other.title == title)&&(identical(other.description, description) || other.description == description)&&(identical(other.language, language) || other.language == language)&&(identical(other.editedAt, editedAt) || other.editedAt == editedAt)&&(identical(other.publishedAt, publishedAt) || other.publishedAt == publishedAt)&&(identical(other.visibility, visibility) || other.visibility == visibility)&&(identical(other.content, content) || other.content == content)&&(identical(other.slug, slug) || other.slug == slug)&&(identical(other.type, type) || other.type == type)&&const DeepCollectionEquality().equals(other._meta, _meta)&&(identical(other.viewsUnique, viewsUnique) || other.viewsUnique == viewsUnique)&&(identical(other.viewsTotal, viewsTotal) || other.viewsTotal == viewsTotal)&&(identical(other.upvotes, upvotes) || other.upvotes == upvotes)&&(identical(other.downvotes, downvotes) || other.downvotes == downvotes)&&(identical(other.repliesCount, repliesCount) || other.repliesCount == repliesCount)&&(identical(other.pinMode, pinMode) || other.pinMode == pinMode)&&(identical(other.threadedPostId, threadedPostId) || other.threadedPostId == threadedPostId)&&(identical(other.threadedPost, threadedPost) || other.threadedPost == threadedPost)&&(identical(other.repliedPostId, repliedPostId) || other.repliedPostId == repliedPostId)&&(identical(other.repliedPost, repliedPost) || other.repliedPost == repliedPost)&&(identical(other.forwardedPostId, forwardedPostId) || other.forwardedPostId == forwardedPostId)&&(identical(other.forwardedPost, forwardedPost) || other.forwardedPost == forwardedPost)&&(identical(other.realmId, realmId) || other.realmId == realmId)&&(identical(other.realm, realm) || other.realm == realm)&&const DeepCollectionEquality().equals(other._attachments, _attachments)&&(identical(other.publisher, publisher) || other.publisher == publisher)&&const DeepCollectionEquality().equals(other._reactionsCount, _reactionsCount)&&const DeepCollectionEquality().equals(other._reactionsMade, _reactionsMade)&&const DeepCollectionEquality().equals(other._reactions, _reactions)&&const DeepCollectionEquality().equals(other._tags, _tags)&&const DeepCollectionEquality().equals(other._categories, _categories)&&const DeepCollectionEquality().equals(other._collections, _collections)&&(identical(other.createdAt, createdAt) || other.createdAt == createdAt)&&(identical(other.updatedAt, updatedAt) || other.updatedAt == updatedAt)&&(identical(other.deletedAt, deletedAt) || other.deletedAt == deletedAt)&&(identical(other.isTruncated, isTruncated) || other.isTruncated == isTruncated));
|
return identical(this, other) || (other.runtimeType == runtimeType&&other is _SnPost&&(identical(other.id, id) || other.id == id)&&(identical(other.title, title) || other.title == title)&&(identical(other.description, description) || other.description == description)&&(identical(other.language, language) || other.language == language)&&(identical(other.editedAt, editedAt) || other.editedAt == editedAt)&&(identical(other.publishedAt, publishedAt) || other.publishedAt == publishedAt)&&(identical(other.visibility, visibility) || other.visibility == visibility)&&(identical(other.content, content) || other.content == content)&&(identical(other.slug, slug) || other.slug == slug)&&(identical(other.type, type) || other.type == type)&&const DeepCollectionEquality().equals(other._meta, _meta)&&(identical(other.embedView, embedView) || other.embedView == embedView)&&(identical(other.viewsUnique, viewsUnique) || other.viewsUnique == viewsUnique)&&(identical(other.viewsTotal, viewsTotal) || other.viewsTotal == viewsTotal)&&(identical(other.upvotes, upvotes) || other.upvotes == upvotes)&&(identical(other.downvotes, downvotes) || other.downvotes == downvotes)&&(identical(other.repliesCount, repliesCount) || other.repliesCount == repliesCount)&&(identical(other.awardedScore, awardedScore) || other.awardedScore == awardedScore)&&(identical(other.pinMode, pinMode) || other.pinMode == pinMode)&&(identical(other.threadedPostId, threadedPostId) || other.threadedPostId == threadedPostId)&&(identical(other.threadedPost, threadedPost) || other.threadedPost == threadedPost)&&(identical(other.repliedPostId, repliedPostId) || other.repliedPostId == repliedPostId)&&(identical(other.repliedPost, repliedPost) || other.repliedPost == repliedPost)&&(identical(other.forwardedPostId, forwardedPostId) || other.forwardedPostId == forwardedPostId)&&(identical(other.forwardedPost, forwardedPost) || other.forwardedPost == forwardedPost)&&(identical(other.realmId, realmId) || other.realmId == realmId)&&(identical(other.realm, realm) || other.realm == realm)&&const DeepCollectionEquality().equals(other._attachments, _attachments)&&(identical(other.publisher, publisher) || other.publisher == publisher)&&const DeepCollectionEquality().equals(other._reactionsCount, _reactionsCount)&&const DeepCollectionEquality().equals(other._reactionsMade, _reactionsMade)&&const DeepCollectionEquality().equals(other._reactions, _reactions)&&const DeepCollectionEquality().equals(other._tags, _tags)&&const DeepCollectionEquality().equals(other._categories, _categories)&&const DeepCollectionEquality().equals(other._collections, _collections)&&(identical(other.createdAt, createdAt) || other.createdAt == createdAt)&&(identical(other.updatedAt, updatedAt) || other.updatedAt == updatedAt)&&(identical(other.deletedAt, deletedAt) || other.deletedAt == deletedAt)&&(identical(other.isTruncated, isTruncated) || other.isTruncated == isTruncated));
|
||||||
}
|
}
|
||||||
|
|
||||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||||
@override
|
@override
|
||||||
int get hashCode => Object.hashAll([runtimeType,id,title,description,language,editedAt,publishedAt,visibility,content,slug,type,const DeepCollectionEquality().hash(_meta),viewsUnique,viewsTotal,upvotes,downvotes,repliesCount,pinMode,threadedPostId,threadedPost,repliedPostId,repliedPost,forwardedPostId,forwardedPost,realmId,realm,const DeepCollectionEquality().hash(_attachments),publisher,const DeepCollectionEquality().hash(_reactionsCount),const DeepCollectionEquality().hash(_reactionsMade),const DeepCollectionEquality().hash(_reactions),const DeepCollectionEquality().hash(_tags),const DeepCollectionEquality().hash(_categories),const DeepCollectionEquality().hash(_collections),createdAt,updatedAt,deletedAt,isTruncated]);
|
int get hashCode => Object.hashAll([runtimeType,id,title,description,language,editedAt,publishedAt,visibility,content,slug,type,const DeepCollectionEquality().hash(_meta),embedView,viewsUnique,viewsTotal,upvotes,downvotes,repliesCount,awardedScore,pinMode,threadedPostId,threadedPost,repliedPostId,repliedPost,forwardedPostId,forwardedPost,realmId,realm,const DeepCollectionEquality().hash(_attachments),publisher,const DeepCollectionEquality().hash(_reactionsCount),const DeepCollectionEquality().hash(_reactionsMade),const DeepCollectionEquality().hash(_reactions),const DeepCollectionEquality().hash(_tags),const DeepCollectionEquality().hash(_categories),const DeepCollectionEquality().hash(_collections),createdAt,updatedAt,deletedAt,isTruncated]);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String toString() {
|
String toString() {
|
||||||
return 'SnPost(id: $id, title: $title, description: $description, language: $language, editedAt: $editedAt, publishedAt: $publishedAt, visibility: $visibility, content: $content, slug: $slug, type: $type, meta: $meta, viewsUnique: $viewsUnique, viewsTotal: $viewsTotal, upvotes: $upvotes, downvotes: $downvotes, repliesCount: $repliesCount, pinMode: $pinMode, threadedPostId: $threadedPostId, threadedPost: $threadedPost, repliedPostId: $repliedPostId, repliedPost: $repliedPost, forwardedPostId: $forwardedPostId, forwardedPost: $forwardedPost, realmId: $realmId, realm: $realm, attachments: $attachments, publisher: $publisher, reactionsCount: $reactionsCount, reactionsMade: $reactionsMade, reactions: $reactions, tags: $tags, categories: $categories, collections: $collections, createdAt: $createdAt, updatedAt: $updatedAt, deletedAt: $deletedAt, isTruncated: $isTruncated)';
|
return 'SnPost(id: $id, title: $title, description: $description, language: $language, editedAt: $editedAt, publishedAt: $publishedAt, visibility: $visibility, content: $content, slug: $slug, type: $type, meta: $meta, embedView: $embedView, viewsUnique: $viewsUnique, viewsTotal: $viewsTotal, upvotes: $upvotes, downvotes: $downvotes, repliesCount: $repliesCount, awardedScore: $awardedScore, pinMode: $pinMode, threadedPostId: $threadedPostId, threadedPost: $threadedPost, repliedPostId: $repliedPostId, repliedPost: $repliedPost, forwardedPostId: $forwardedPostId, forwardedPost: $forwardedPost, realmId: $realmId, realm: $realm, attachments: $attachments, publisher: $publisher, reactionsCount: $reactionsCount, reactionsMade: $reactionsMade, reactions: $reactions, tags: $tags, categories: $categories, collections: $collections, createdAt: $createdAt, updatedAt: $updatedAt, deletedAt: $deletedAt, isTruncated: $isTruncated)';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -420,11 +436,11 @@ abstract mixin class _$SnPostCopyWith<$Res> implements $SnPostCopyWith<$Res> {
|
|||||||
factory _$SnPostCopyWith(_SnPost value, $Res Function(_SnPost) _then) = __$SnPostCopyWithImpl;
|
factory _$SnPostCopyWith(_SnPost value, $Res Function(_SnPost) _then) = __$SnPostCopyWithImpl;
|
||||||
@override @useResult
|
@override @useResult
|
||||||
$Res call({
|
$Res call({
|
||||||
String id, String? title, String? description, String? language, DateTime? editedAt, DateTime? publishedAt, int visibility, String? content, String? slug, int type, Map<String, dynamic>? meta, int viewsUnique, int viewsTotal, int upvotes, int downvotes, int repliesCount, int? pinMode, String? threadedPostId, SnPost? threadedPost, String? repliedPostId, SnPost? repliedPost, String? forwardedPostId, SnPost? forwardedPost, String? realmId, SnRealm? realm, List<SnCloudFile> attachments, SnPublisher publisher, Map<String, int> reactionsCount, Map<String, bool> reactionsMade, List<dynamic> reactions, List<SnPostTag> tags, List<SnPostCategory> categories, List<dynamic> collections, DateTime? createdAt, DateTime? updatedAt, DateTime? deletedAt, bool isTruncated
|
String id, String? title, String? description, String? language, DateTime? editedAt, DateTime? publishedAt, int visibility, String? content, String? slug, int type, Map<String, dynamic>? meta, SnPostEmbedView? embedView, int viewsUnique, int viewsTotal, int upvotes, int downvotes, int repliesCount, int awardedScore, int? pinMode, String? threadedPostId, SnPost? threadedPost, String? repliedPostId, SnPost? repliedPost, String? forwardedPostId, SnPost? forwardedPost, String? realmId, SnRealm? realm, List<SnCloudFile> attachments, SnPublisher publisher, Map<String, int> reactionsCount, Map<String, bool> reactionsMade, List<dynamic> reactions, List<SnPostTag> tags, List<SnPostCategory> categories, List<dynamic> collections, DateTime? createdAt, DateTime? updatedAt, DateTime? deletedAt, bool isTruncated
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
@override $SnPostCopyWith<$Res>? get threadedPost;@override $SnPostCopyWith<$Res>? get repliedPost;@override $SnPostCopyWith<$Res>? get forwardedPost;@override $SnRealmCopyWith<$Res>? get realm;@override $SnPublisherCopyWith<$Res> get publisher;
|
@override $SnPostEmbedViewCopyWith<$Res>? get embedView;@override $SnPostCopyWith<$Res>? get threadedPost;@override $SnPostCopyWith<$Res>? get repliedPost;@override $SnPostCopyWith<$Res>? get forwardedPost;@override $SnRealmCopyWith<$Res>? get realm;@override $SnPublisherCopyWith<$Res> get publisher;
|
||||||
|
|
||||||
}
|
}
|
||||||
/// @nodoc
|
/// @nodoc
|
||||||
@@ -437,7 +453,7 @@ class __$SnPostCopyWithImpl<$Res>
|
|||||||
|
|
||||||
/// Create a copy of SnPost
|
/// Create a copy of SnPost
|
||||||
/// with the given fields replaced by the non-null parameter values.
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
@override @pragma('vm:prefer-inline') $Res call({Object? id = null,Object? title = freezed,Object? description = freezed,Object? language = freezed,Object? editedAt = freezed,Object? publishedAt = freezed,Object? visibility = null,Object? content = freezed,Object? slug = freezed,Object? type = null,Object? meta = freezed,Object? viewsUnique = null,Object? viewsTotal = null,Object? upvotes = null,Object? downvotes = null,Object? repliesCount = null,Object? pinMode = freezed,Object? threadedPostId = freezed,Object? threadedPost = freezed,Object? repliedPostId = freezed,Object? repliedPost = freezed,Object? forwardedPostId = freezed,Object? forwardedPost = freezed,Object? realmId = freezed,Object? realm = freezed,Object? attachments = null,Object? publisher = null,Object? reactionsCount = null,Object? reactionsMade = null,Object? reactions = null,Object? tags = null,Object? categories = null,Object? collections = null,Object? createdAt = freezed,Object? updatedAt = freezed,Object? deletedAt = freezed,Object? isTruncated = null,}) {
|
@override @pragma('vm:prefer-inline') $Res call({Object? id = null,Object? title = freezed,Object? description = freezed,Object? language = freezed,Object? editedAt = freezed,Object? publishedAt = freezed,Object? visibility = null,Object? content = freezed,Object? slug = freezed,Object? type = null,Object? meta = freezed,Object? embedView = freezed,Object? viewsUnique = null,Object? viewsTotal = null,Object? upvotes = null,Object? downvotes = null,Object? repliesCount = null,Object? awardedScore = null,Object? pinMode = freezed,Object? threadedPostId = freezed,Object? threadedPost = freezed,Object? repliedPostId = freezed,Object? repliedPost = freezed,Object? forwardedPostId = freezed,Object? forwardedPost = freezed,Object? realmId = freezed,Object? realm = freezed,Object? attachments = null,Object? publisher = null,Object? reactionsCount = null,Object? reactionsMade = null,Object? reactions = null,Object? tags = null,Object? categories = null,Object? collections = null,Object? createdAt = freezed,Object? updatedAt = freezed,Object? deletedAt = freezed,Object? isTruncated = null,}) {
|
||||||
return _then(_SnPost(
|
return _then(_SnPost(
|
||||||
id: null == id ? _self.id : id // ignore: cast_nullable_to_non_nullable
|
id: null == id ? _self.id : id // ignore: cast_nullable_to_non_nullable
|
||||||
as String,title: freezed == title ? _self.title : title // ignore: cast_nullable_to_non_nullable
|
as String,title: freezed == title ? _self.title : title // ignore: cast_nullable_to_non_nullable
|
||||||
@@ -450,11 +466,13 @@ as int,content: freezed == content ? _self.content : content // ignore: cast_nul
|
|||||||
as String?,slug: freezed == slug ? _self.slug : slug // ignore: cast_nullable_to_non_nullable
|
as String?,slug: freezed == slug ? _self.slug : slug // ignore: cast_nullable_to_non_nullable
|
||||||
as String?,type: null == type ? _self.type : type // ignore: cast_nullable_to_non_nullable
|
as String?,type: null == type ? _self.type : type // ignore: cast_nullable_to_non_nullable
|
||||||
as int,meta: freezed == meta ? _self._meta : meta // ignore: cast_nullable_to_non_nullable
|
as int,meta: freezed == meta ? _self._meta : meta // ignore: cast_nullable_to_non_nullable
|
||||||
as Map<String, dynamic>?,viewsUnique: null == viewsUnique ? _self.viewsUnique : viewsUnique // ignore: cast_nullable_to_non_nullable
|
as Map<String, dynamic>?,embedView: freezed == embedView ? _self.embedView : embedView // ignore: cast_nullable_to_non_nullable
|
||||||
|
as SnPostEmbedView?,viewsUnique: null == viewsUnique ? _self.viewsUnique : viewsUnique // ignore: cast_nullable_to_non_nullable
|
||||||
as int,viewsTotal: null == viewsTotal ? _self.viewsTotal : viewsTotal // ignore: cast_nullable_to_non_nullable
|
as int,viewsTotal: null == viewsTotal ? _self.viewsTotal : viewsTotal // ignore: cast_nullable_to_non_nullable
|
||||||
as int,upvotes: null == upvotes ? _self.upvotes : upvotes // ignore: cast_nullable_to_non_nullable
|
as int,upvotes: null == upvotes ? _self.upvotes : upvotes // ignore: cast_nullable_to_non_nullable
|
||||||
as int,downvotes: null == downvotes ? _self.downvotes : downvotes // ignore: cast_nullable_to_non_nullable
|
as int,downvotes: null == downvotes ? _self.downvotes : downvotes // ignore: cast_nullable_to_non_nullable
|
||||||
as int,repliesCount: null == repliesCount ? _self.repliesCount : repliesCount // ignore: cast_nullable_to_non_nullable
|
as int,repliesCount: null == repliesCount ? _self.repliesCount : repliesCount // ignore: cast_nullable_to_non_nullable
|
||||||
|
as int,awardedScore: null == awardedScore ? _self.awardedScore : awardedScore // ignore: cast_nullable_to_non_nullable
|
||||||
as int,pinMode: freezed == pinMode ? _self.pinMode : pinMode // ignore: cast_nullable_to_non_nullable
|
as int,pinMode: freezed == pinMode ? _self.pinMode : pinMode // ignore: cast_nullable_to_non_nullable
|
||||||
as int?,threadedPostId: freezed == threadedPostId ? _self.threadedPostId : threadedPostId // ignore: cast_nullable_to_non_nullable
|
as int?,threadedPostId: freezed == threadedPostId ? _self.threadedPostId : threadedPostId // ignore: cast_nullable_to_non_nullable
|
||||||
as String?,threadedPost: freezed == threadedPost ? _self.threadedPost : threadedPost // ignore: cast_nullable_to_non_nullable
|
as String?,threadedPost: freezed == threadedPost ? _self.threadedPost : threadedPost // ignore: cast_nullable_to_non_nullable
|
||||||
@@ -484,6 +502,18 @@ as bool,
|
|||||||
/// with the given fields replaced by the non-null parameter values.
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
@override
|
@override
|
||||||
@pragma('vm:prefer-inline')
|
@pragma('vm:prefer-inline')
|
||||||
|
$SnPostEmbedViewCopyWith<$Res>? get embedView {
|
||||||
|
if (_self.embedView == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $SnPostEmbedViewCopyWith<$Res>(_self.embedView!, (value) {
|
||||||
|
return _then(_self.copyWith(embedView: value));
|
||||||
|
});
|
||||||
|
}/// Create a copy of SnPost
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
|
@override
|
||||||
|
@pragma('vm:prefer-inline')
|
||||||
$SnPostCopyWith<$Res>? get threadedPost {
|
$SnPostCopyWith<$Res>? get threadedPost {
|
||||||
if (_self.threadedPost == null) {
|
if (_self.threadedPost == null) {
|
||||||
return null;
|
return null;
|
||||||
@@ -1324,6 +1354,550 @@ as int,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
mixin _$SnPostEmbedView {
|
||||||
|
|
||||||
|
String get uri; double? get aspectRatio; PostEmbedViewRenderer get renderer;
|
||||||
|
/// Create a copy of SnPostEmbedView
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
|
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||||
|
@pragma('vm:prefer-inline')
|
||||||
|
$SnPostEmbedViewCopyWith<SnPostEmbedView> get copyWith => _$SnPostEmbedViewCopyWithImpl<SnPostEmbedView>(this as SnPostEmbedView, _$identity);
|
||||||
|
|
||||||
|
/// Serializes this SnPostEmbedView to a JSON map.
|
||||||
|
Map<String, dynamic> toJson();
|
||||||
|
|
||||||
|
|
||||||
|
@override
|
||||||
|
bool operator ==(Object other) {
|
||||||
|
return identical(this, other) || (other.runtimeType == runtimeType&&other is SnPostEmbedView&&(identical(other.uri, uri) || other.uri == uri)&&(identical(other.aspectRatio, aspectRatio) || other.aspectRatio == aspectRatio)&&(identical(other.renderer, renderer) || other.renderer == renderer));
|
||||||
|
}
|
||||||
|
|
||||||
|
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||||
|
@override
|
||||||
|
int get hashCode => Object.hash(runtimeType,uri,aspectRatio,renderer);
|
||||||
|
|
||||||
|
@override
|
||||||
|
String toString() {
|
||||||
|
return 'SnPostEmbedView(uri: $uri, aspectRatio: $aspectRatio, renderer: $renderer)';
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
abstract mixin class $SnPostEmbedViewCopyWith<$Res> {
|
||||||
|
factory $SnPostEmbedViewCopyWith(SnPostEmbedView value, $Res Function(SnPostEmbedView) _then) = _$SnPostEmbedViewCopyWithImpl;
|
||||||
|
@useResult
|
||||||
|
$Res call({
|
||||||
|
String uri, double? aspectRatio, PostEmbedViewRenderer renderer
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
/// @nodoc
|
||||||
|
class _$SnPostEmbedViewCopyWithImpl<$Res>
|
||||||
|
implements $SnPostEmbedViewCopyWith<$Res> {
|
||||||
|
_$SnPostEmbedViewCopyWithImpl(this._self, this._then);
|
||||||
|
|
||||||
|
final SnPostEmbedView _self;
|
||||||
|
final $Res Function(SnPostEmbedView) _then;
|
||||||
|
|
||||||
|
/// Create a copy of SnPostEmbedView
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
|
@pragma('vm:prefer-inline') @override $Res call({Object? uri = null,Object? aspectRatio = freezed,Object? renderer = null,}) {
|
||||||
|
return _then(_self.copyWith(
|
||||||
|
uri: null == uri ? _self.uri : uri // ignore: cast_nullable_to_non_nullable
|
||||||
|
as String,aspectRatio: freezed == aspectRatio ? _self.aspectRatio : aspectRatio // ignore: cast_nullable_to_non_nullable
|
||||||
|
as double?,renderer: null == renderer ? _self.renderer : renderer // ignore: cast_nullable_to_non_nullable
|
||||||
|
as PostEmbedViewRenderer,
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// Adds pattern-matching-related methods to [SnPostEmbedView].
|
||||||
|
extension SnPostEmbedViewPatterns on SnPostEmbedView {
|
||||||
|
/// A variant of `map` that fallback to returning `orElse`.
|
||||||
|
///
|
||||||
|
/// It is equivalent to doing:
|
||||||
|
/// ```dart
|
||||||
|
/// switch (sealedClass) {
|
||||||
|
/// case final Subclass value:
|
||||||
|
/// return ...;
|
||||||
|
/// case _:
|
||||||
|
/// return orElse();
|
||||||
|
/// }
|
||||||
|
/// ```
|
||||||
|
|
||||||
|
@optionalTypeArgs TResult maybeMap<TResult extends Object?>(TResult Function( _SnPostEmbedView value)? $default,{required TResult orElse(),}){
|
||||||
|
final _that = this;
|
||||||
|
switch (_that) {
|
||||||
|
case _SnPostEmbedView() when $default != null:
|
||||||
|
return $default(_that);case _:
|
||||||
|
return orElse();
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/// A `switch`-like method, using callbacks.
|
||||||
|
///
|
||||||
|
/// Callbacks receives the raw object, upcasted.
|
||||||
|
/// It is equivalent to doing:
|
||||||
|
/// ```dart
|
||||||
|
/// switch (sealedClass) {
|
||||||
|
/// case final Subclass value:
|
||||||
|
/// return ...;
|
||||||
|
/// case final Subclass2 value:
|
||||||
|
/// return ...;
|
||||||
|
/// }
|
||||||
|
/// ```
|
||||||
|
|
||||||
|
@optionalTypeArgs TResult map<TResult extends Object?>(TResult Function( _SnPostEmbedView value) $default,){
|
||||||
|
final _that = this;
|
||||||
|
switch (_that) {
|
||||||
|
case _SnPostEmbedView():
|
||||||
|
return $default(_that);}
|
||||||
|
}
|
||||||
|
/// A variant of `map` that fallback to returning `null`.
|
||||||
|
///
|
||||||
|
/// It is equivalent to doing:
|
||||||
|
/// ```dart
|
||||||
|
/// switch (sealedClass) {
|
||||||
|
/// case final Subclass value:
|
||||||
|
/// return ...;
|
||||||
|
/// case _:
|
||||||
|
/// return null;
|
||||||
|
/// }
|
||||||
|
/// ```
|
||||||
|
|
||||||
|
@optionalTypeArgs TResult? mapOrNull<TResult extends Object?>(TResult? Function( _SnPostEmbedView value)? $default,){
|
||||||
|
final _that = this;
|
||||||
|
switch (_that) {
|
||||||
|
case _SnPostEmbedView() when $default != null:
|
||||||
|
return $default(_that);case _:
|
||||||
|
return null;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/// A variant of `when` that fallback to an `orElse` callback.
|
||||||
|
///
|
||||||
|
/// It is equivalent to doing:
|
||||||
|
/// ```dart
|
||||||
|
/// switch (sealedClass) {
|
||||||
|
/// case Subclass(:final field):
|
||||||
|
/// return ...;
|
||||||
|
/// case _:
|
||||||
|
/// return orElse();
|
||||||
|
/// }
|
||||||
|
/// ```
|
||||||
|
|
||||||
|
@optionalTypeArgs TResult maybeWhen<TResult extends Object?>(TResult Function( String uri, double? aspectRatio, PostEmbedViewRenderer renderer)? $default,{required TResult orElse(),}) {final _that = this;
|
||||||
|
switch (_that) {
|
||||||
|
case _SnPostEmbedView() when $default != null:
|
||||||
|
return $default(_that.uri,_that.aspectRatio,_that.renderer);case _:
|
||||||
|
return orElse();
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/// A `switch`-like method, using callbacks.
|
||||||
|
///
|
||||||
|
/// As opposed to `map`, this offers destructuring.
|
||||||
|
/// It is equivalent to doing:
|
||||||
|
/// ```dart
|
||||||
|
/// switch (sealedClass) {
|
||||||
|
/// case Subclass(:final field):
|
||||||
|
/// return ...;
|
||||||
|
/// case Subclass2(:final field2):
|
||||||
|
/// return ...;
|
||||||
|
/// }
|
||||||
|
/// ```
|
||||||
|
|
||||||
|
@optionalTypeArgs TResult when<TResult extends Object?>(TResult Function( String uri, double? aspectRatio, PostEmbedViewRenderer renderer) $default,) {final _that = this;
|
||||||
|
switch (_that) {
|
||||||
|
case _SnPostEmbedView():
|
||||||
|
return $default(_that.uri,_that.aspectRatio,_that.renderer);}
|
||||||
|
}
|
||||||
|
/// A variant of `when` that fallback to returning `null`
|
||||||
|
///
|
||||||
|
/// It is equivalent to doing:
|
||||||
|
/// ```dart
|
||||||
|
/// switch (sealedClass) {
|
||||||
|
/// case Subclass(:final field):
|
||||||
|
/// return ...;
|
||||||
|
/// case _:
|
||||||
|
/// return null;
|
||||||
|
/// }
|
||||||
|
/// ```
|
||||||
|
|
||||||
|
@optionalTypeArgs TResult? whenOrNull<TResult extends Object?>(TResult? Function( String uri, double? aspectRatio, PostEmbedViewRenderer renderer)? $default,) {final _that = this;
|
||||||
|
switch (_that) {
|
||||||
|
case _SnPostEmbedView() when $default != null:
|
||||||
|
return $default(_that.uri,_that.aspectRatio,_that.renderer);case _:
|
||||||
|
return null;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
@JsonSerializable()
|
||||||
|
|
||||||
|
class _SnPostEmbedView implements SnPostEmbedView {
|
||||||
|
const _SnPostEmbedView({required this.uri, this.aspectRatio, this.renderer = PostEmbedViewRenderer.webView});
|
||||||
|
factory _SnPostEmbedView.fromJson(Map<String, dynamic> json) => _$SnPostEmbedViewFromJson(json);
|
||||||
|
|
||||||
|
@override final String uri;
|
||||||
|
@override final double? aspectRatio;
|
||||||
|
@override@JsonKey() final PostEmbedViewRenderer renderer;
|
||||||
|
|
||||||
|
/// Create a copy of SnPostEmbedView
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
|
@override @JsonKey(includeFromJson: false, includeToJson: false)
|
||||||
|
@pragma('vm:prefer-inline')
|
||||||
|
_$SnPostEmbedViewCopyWith<_SnPostEmbedView> get copyWith => __$SnPostEmbedViewCopyWithImpl<_SnPostEmbedView>(this, _$identity);
|
||||||
|
|
||||||
|
@override
|
||||||
|
Map<String, dynamic> toJson() {
|
||||||
|
return _$SnPostEmbedViewToJson(this, );
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
bool operator ==(Object other) {
|
||||||
|
return identical(this, other) || (other.runtimeType == runtimeType&&other is _SnPostEmbedView&&(identical(other.uri, uri) || other.uri == uri)&&(identical(other.aspectRatio, aspectRatio) || other.aspectRatio == aspectRatio)&&(identical(other.renderer, renderer) || other.renderer == renderer));
|
||||||
|
}
|
||||||
|
|
||||||
|
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||||
|
@override
|
||||||
|
int get hashCode => Object.hash(runtimeType,uri,aspectRatio,renderer);
|
||||||
|
|
||||||
|
@override
|
||||||
|
String toString() {
|
||||||
|
return 'SnPostEmbedView(uri: $uri, aspectRatio: $aspectRatio, renderer: $renderer)';
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
abstract mixin class _$SnPostEmbedViewCopyWith<$Res> implements $SnPostEmbedViewCopyWith<$Res> {
|
||||||
|
factory _$SnPostEmbedViewCopyWith(_SnPostEmbedView value, $Res Function(_SnPostEmbedView) _then) = __$SnPostEmbedViewCopyWithImpl;
|
||||||
|
@override @useResult
|
||||||
|
$Res call({
|
||||||
|
String uri, double? aspectRatio, PostEmbedViewRenderer renderer
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
/// @nodoc
|
||||||
|
class __$SnPostEmbedViewCopyWithImpl<$Res>
|
||||||
|
implements _$SnPostEmbedViewCopyWith<$Res> {
|
||||||
|
__$SnPostEmbedViewCopyWithImpl(this._self, this._then);
|
||||||
|
|
||||||
|
final _SnPostEmbedView _self;
|
||||||
|
final $Res Function(_SnPostEmbedView) _then;
|
||||||
|
|
||||||
|
/// Create a copy of SnPostEmbedView
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
|
@override @pragma('vm:prefer-inline') $Res call({Object? uri = null,Object? aspectRatio = freezed,Object? renderer = null,}) {
|
||||||
|
return _then(_SnPostEmbedView(
|
||||||
|
uri: null == uri ? _self.uri : uri // ignore: cast_nullable_to_non_nullable
|
||||||
|
as String,aspectRatio: freezed == aspectRatio ? _self.aspectRatio : aspectRatio // ignore: cast_nullable_to_non_nullable
|
||||||
|
as double?,renderer: null == renderer ? _self.renderer : renderer // ignore: cast_nullable_to_non_nullable
|
||||||
|
as PostEmbedViewRenderer,
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
mixin _$SnPostAward {
|
||||||
|
|
||||||
|
String get id; double get amount; int get attitude; String? get message; String get postId; String get accountId; DateTime? get createdAt; DateTime? get updatedAt; DateTime? get deletedAt;
|
||||||
|
/// Create a copy of SnPostAward
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
|
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||||
|
@pragma('vm:prefer-inline')
|
||||||
|
$SnPostAwardCopyWith<SnPostAward> get copyWith => _$SnPostAwardCopyWithImpl<SnPostAward>(this as SnPostAward, _$identity);
|
||||||
|
|
||||||
|
/// Serializes this SnPostAward to a JSON map.
|
||||||
|
Map<String, dynamic> toJson();
|
||||||
|
|
||||||
|
|
||||||
|
@override
|
||||||
|
bool operator ==(Object other) {
|
||||||
|
return identical(this, other) || (other.runtimeType == runtimeType&&other is SnPostAward&&(identical(other.id, id) || other.id == id)&&(identical(other.amount, amount) || other.amount == amount)&&(identical(other.attitude, attitude) || other.attitude == attitude)&&(identical(other.message, message) || other.message == message)&&(identical(other.postId, postId) || other.postId == postId)&&(identical(other.accountId, accountId) || other.accountId == accountId)&&(identical(other.createdAt, createdAt) || other.createdAt == createdAt)&&(identical(other.updatedAt, updatedAt) || other.updatedAt == updatedAt)&&(identical(other.deletedAt, deletedAt) || other.deletedAt == deletedAt));
|
||||||
|
}
|
||||||
|
|
||||||
|
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||||
|
@override
|
||||||
|
int get hashCode => Object.hash(runtimeType,id,amount,attitude,message,postId,accountId,createdAt,updatedAt,deletedAt);
|
||||||
|
|
||||||
|
@override
|
||||||
|
String toString() {
|
||||||
|
return 'SnPostAward(id: $id, amount: $amount, attitude: $attitude, message: $message, postId: $postId, accountId: $accountId, createdAt: $createdAt, updatedAt: $updatedAt, deletedAt: $deletedAt)';
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
abstract mixin class $SnPostAwardCopyWith<$Res> {
|
||||||
|
factory $SnPostAwardCopyWith(SnPostAward value, $Res Function(SnPostAward) _then) = _$SnPostAwardCopyWithImpl;
|
||||||
|
@useResult
|
||||||
|
$Res call({
|
||||||
|
String id, double amount, int attitude, String? message, String postId, String accountId, DateTime? createdAt, DateTime? updatedAt, DateTime? deletedAt
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
/// @nodoc
|
||||||
|
class _$SnPostAwardCopyWithImpl<$Res>
|
||||||
|
implements $SnPostAwardCopyWith<$Res> {
|
||||||
|
_$SnPostAwardCopyWithImpl(this._self, this._then);
|
||||||
|
|
||||||
|
final SnPostAward _self;
|
||||||
|
final $Res Function(SnPostAward) _then;
|
||||||
|
|
||||||
|
/// Create a copy of SnPostAward
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
|
@pragma('vm:prefer-inline') @override $Res call({Object? id = null,Object? amount = null,Object? attitude = null,Object? message = freezed,Object? postId = null,Object? accountId = null,Object? createdAt = freezed,Object? updatedAt = freezed,Object? deletedAt = freezed,}) {
|
||||||
|
return _then(_self.copyWith(
|
||||||
|
id: null == id ? _self.id : id // ignore: cast_nullable_to_non_nullable
|
||||||
|
as String,amount: null == amount ? _self.amount : amount // ignore: cast_nullable_to_non_nullable
|
||||||
|
as double,attitude: null == attitude ? _self.attitude : attitude // ignore: cast_nullable_to_non_nullable
|
||||||
|
as int,message: freezed == message ? _self.message : message // ignore: cast_nullable_to_non_nullable
|
||||||
|
as String?,postId: null == postId ? _self.postId : postId // ignore: cast_nullable_to_non_nullable
|
||||||
|
as String,accountId: null == accountId ? _self.accountId : accountId // ignore: cast_nullable_to_non_nullable
|
||||||
|
as String,createdAt: freezed == createdAt ? _self.createdAt : createdAt // ignore: cast_nullable_to_non_nullable
|
||||||
|
as DateTime?,updatedAt: freezed == updatedAt ? _self.updatedAt : updatedAt // ignore: cast_nullable_to_non_nullable
|
||||||
|
as DateTime?,deletedAt: freezed == deletedAt ? _self.deletedAt : deletedAt // ignore: cast_nullable_to_non_nullable
|
||||||
|
as DateTime?,
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// Adds pattern-matching-related methods to [SnPostAward].
|
||||||
|
extension SnPostAwardPatterns on SnPostAward {
|
||||||
|
/// A variant of `map` that fallback to returning `orElse`.
|
||||||
|
///
|
||||||
|
/// It is equivalent to doing:
|
||||||
|
/// ```dart
|
||||||
|
/// switch (sealedClass) {
|
||||||
|
/// case final Subclass value:
|
||||||
|
/// return ...;
|
||||||
|
/// case _:
|
||||||
|
/// return orElse();
|
||||||
|
/// }
|
||||||
|
/// ```
|
||||||
|
|
||||||
|
@optionalTypeArgs TResult maybeMap<TResult extends Object?>(TResult Function( _SnPostAward value)? $default,{required TResult orElse(),}){
|
||||||
|
final _that = this;
|
||||||
|
switch (_that) {
|
||||||
|
case _SnPostAward() when $default != null:
|
||||||
|
return $default(_that);case _:
|
||||||
|
return orElse();
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/// A `switch`-like method, using callbacks.
|
||||||
|
///
|
||||||
|
/// Callbacks receives the raw object, upcasted.
|
||||||
|
/// It is equivalent to doing:
|
||||||
|
/// ```dart
|
||||||
|
/// switch (sealedClass) {
|
||||||
|
/// case final Subclass value:
|
||||||
|
/// return ...;
|
||||||
|
/// case final Subclass2 value:
|
||||||
|
/// return ...;
|
||||||
|
/// }
|
||||||
|
/// ```
|
||||||
|
|
||||||
|
@optionalTypeArgs TResult map<TResult extends Object?>(TResult Function( _SnPostAward value) $default,){
|
||||||
|
final _that = this;
|
||||||
|
switch (_that) {
|
||||||
|
case _SnPostAward():
|
||||||
|
return $default(_that);}
|
||||||
|
}
|
||||||
|
/// A variant of `map` that fallback to returning `null`.
|
||||||
|
///
|
||||||
|
/// It is equivalent to doing:
|
||||||
|
/// ```dart
|
||||||
|
/// switch (sealedClass) {
|
||||||
|
/// case final Subclass value:
|
||||||
|
/// return ...;
|
||||||
|
/// case _:
|
||||||
|
/// return null;
|
||||||
|
/// }
|
||||||
|
/// ```
|
||||||
|
|
||||||
|
@optionalTypeArgs TResult? mapOrNull<TResult extends Object?>(TResult? Function( _SnPostAward value)? $default,){
|
||||||
|
final _that = this;
|
||||||
|
switch (_that) {
|
||||||
|
case _SnPostAward() when $default != null:
|
||||||
|
return $default(_that);case _:
|
||||||
|
return null;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/// A variant of `when` that fallback to an `orElse` callback.
|
||||||
|
///
|
||||||
|
/// It is equivalent to doing:
|
||||||
|
/// ```dart
|
||||||
|
/// switch (sealedClass) {
|
||||||
|
/// case Subclass(:final field):
|
||||||
|
/// return ...;
|
||||||
|
/// case _:
|
||||||
|
/// return orElse();
|
||||||
|
/// }
|
||||||
|
/// ```
|
||||||
|
|
||||||
|
@optionalTypeArgs TResult maybeWhen<TResult extends Object?>(TResult Function( String id, double amount, int attitude, String? message, String postId, String accountId, DateTime? createdAt, DateTime? updatedAt, DateTime? deletedAt)? $default,{required TResult orElse(),}) {final _that = this;
|
||||||
|
switch (_that) {
|
||||||
|
case _SnPostAward() when $default != null:
|
||||||
|
return $default(_that.id,_that.amount,_that.attitude,_that.message,_that.postId,_that.accountId,_that.createdAt,_that.updatedAt,_that.deletedAt);case _:
|
||||||
|
return orElse();
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/// A `switch`-like method, using callbacks.
|
||||||
|
///
|
||||||
|
/// As opposed to `map`, this offers destructuring.
|
||||||
|
/// It is equivalent to doing:
|
||||||
|
/// ```dart
|
||||||
|
/// switch (sealedClass) {
|
||||||
|
/// case Subclass(:final field):
|
||||||
|
/// return ...;
|
||||||
|
/// case Subclass2(:final field2):
|
||||||
|
/// return ...;
|
||||||
|
/// }
|
||||||
|
/// ```
|
||||||
|
|
||||||
|
@optionalTypeArgs TResult when<TResult extends Object?>(TResult Function( String id, double amount, int attitude, String? message, String postId, String accountId, DateTime? createdAt, DateTime? updatedAt, DateTime? deletedAt) $default,) {final _that = this;
|
||||||
|
switch (_that) {
|
||||||
|
case _SnPostAward():
|
||||||
|
return $default(_that.id,_that.amount,_that.attitude,_that.message,_that.postId,_that.accountId,_that.createdAt,_that.updatedAt,_that.deletedAt);}
|
||||||
|
}
|
||||||
|
/// A variant of `when` that fallback to returning `null`
|
||||||
|
///
|
||||||
|
/// It is equivalent to doing:
|
||||||
|
/// ```dart
|
||||||
|
/// switch (sealedClass) {
|
||||||
|
/// case Subclass(:final field):
|
||||||
|
/// return ...;
|
||||||
|
/// case _:
|
||||||
|
/// return null;
|
||||||
|
/// }
|
||||||
|
/// ```
|
||||||
|
|
||||||
|
@optionalTypeArgs TResult? whenOrNull<TResult extends Object?>(TResult? Function( String id, double amount, int attitude, String? message, String postId, String accountId, DateTime? createdAt, DateTime? updatedAt, DateTime? deletedAt)? $default,) {final _that = this;
|
||||||
|
switch (_that) {
|
||||||
|
case _SnPostAward() when $default != null:
|
||||||
|
return $default(_that.id,_that.amount,_that.attitude,_that.message,_that.postId,_that.accountId,_that.createdAt,_that.updatedAt,_that.deletedAt);case _:
|
||||||
|
return null;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
@JsonSerializable()
|
||||||
|
|
||||||
|
class _SnPostAward implements SnPostAward {
|
||||||
|
const _SnPostAward({required this.id, required this.amount, required this.attitude, this.message, required this.postId, required this.accountId, this.createdAt = null, this.updatedAt = null, this.deletedAt});
|
||||||
|
factory _SnPostAward.fromJson(Map<String, dynamic> json) => _$SnPostAwardFromJson(json);
|
||||||
|
|
||||||
|
@override final String id;
|
||||||
|
@override final double amount;
|
||||||
|
@override final int attitude;
|
||||||
|
@override final String? message;
|
||||||
|
@override final String postId;
|
||||||
|
@override final String accountId;
|
||||||
|
@override@JsonKey() final DateTime? createdAt;
|
||||||
|
@override@JsonKey() final DateTime? updatedAt;
|
||||||
|
@override final DateTime? deletedAt;
|
||||||
|
|
||||||
|
/// Create a copy of SnPostAward
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
|
@override @JsonKey(includeFromJson: false, includeToJson: false)
|
||||||
|
@pragma('vm:prefer-inline')
|
||||||
|
_$SnPostAwardCopyWith<_SnPostAward> get copyWith => __$SnPostAwardCopyWithImpl<_SnPostAward>(this, _$identity);
|
||||||
|
|
||||||
|
@override
|
||||||
|
Map<String, dynamic> toJson() {
|
||||||
|
return _$SnPostAwardToJson(this, );
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
bool operator ==(Object other) {
|
||||||
|
return identical(this, other) || (other.runtimeType == runtimeType&&other is _SnPostAward&&(identical(other.id, id) || other.id == id)&&(identical(other.amount, amount) || other.amount == amount)&&(identical(other.attitude, attitude) || other.attitude == attitude)&&(identical(other.message, message) || other.message == message)&&(identical(other.postId, postId) || other.postId == postId)&&(identical(other.accountId, accountId) || other.accountId == accountId)&&(identical(other.createdAt, createdAt) || other.createdAt == createdAt)&&(identical(other.updatedAt, updatedAt) || other.updatedAt == updatedAt)&&(identical(other.deletedAt, deletedAt) || other.deletedAt == deletedAt));
|
||||||
|
}
|
||||||
|
|
||||||
|
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||||
|
@override
|
||||||
|
int get hashCode => Object.hash(runtimeType,id,amount,attitude,message,postId,accountId,createdAt,updatedAt,deletedAt);
|
||||||
|
|
||||||
|
@override
|
||||||
|
String toString() {
|
||||||
|
return 'SnPostAward(id: $id, amount: $amount, attitude: $attitude, message: $message, postId: $postId, accountId: $accountId, createdAt: $createdAt, updatedAt: $updatedAt, deletedAt: $deletedAt)';
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
abstract mixin class _$SnPostAwardCopyWith<$Res> implements $SnPostAwardCopyWith<$Res> {
|
||||||
|
factory _$SnPostAwardCopyWith(_SnPostAward value, $Res Function(_SnPostAward) _then) = __$SnPostAwardCopyWithImpl;
|
||||||
|
@override @useResult
|
||||||
|
$Res call({
|
||||||
|
String id, double amount, int attitude, String? message, String postId, String accountId, DateTime? createdAt, DateTime? updatedAt, DateTime? deletedAt
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
/// @nodoc
|
||||||
|
class __$SnPostAwardCopyWithImpl<$Res>
|
||||||
|
implements _$SnPostAwardCopyWith<$Res> {
|
||||||
|
__$SnPostAwardCopyWithImpl(this._self, this._then);
|
||||||
|
|
||||||
|
final _SnPostAward _self;
|
||||||
|
final $Res Function(_SnPostAward) _then;
|
||||||
|
|
||||||
|
/// Create a copy of SnPostAward
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
|
@override @pragma('vm:prefer-inline') $Res call({Object? id = null,Object? amount = null,Object? attitude = null,Object? message = freezed,Object? postId = null,Object? accountId = null,Object? createdAt = freezed,Object? updatedAt = freezed,Object? deletedAt = freezed,}) {
|
||||||
|
return _then(_SnPostAward(
|
||||||
|
id: null == id ? _self.id : id // ignore: cast_nullable_to_non_nullable
|
||||||
|
as String,amount: null == amount ? _self.amount : amount // ignore: cast_nullable_to_non_nullable
|
||||||
|
as double,attitude: null == attitude ? _self.attitude : attitude // ignore: cast_nullable_to_non_nullable
|
||||||
|
as int,message: freezed == message ? _self.message : message // ignore: cast_nullable_to_non_nullable
|
||||||
|
as String?,postId: null == postId ? _self.postId : postId // ignore: cast_nullable_to_non_nullable
|
||||||
|
as String,accountId: null == accountId ? _self.accountId : accountId // ignore: cast_nullable_to_non_nullable
|
||||||
|
as String,createdAt: freezed == createdAt ? _self.createdAt : createdAt // ignore: cast_nullable_to_non_nullable
|
||||||
|
as DateTime?,updatedAt: freezed == updatedAt ? _self.updatedAt : updatedAt // ignore: cast_nullable_to_non_nullable
|
||||||
|
as DateTime?,deletedAt: freezed == deletedAt ? _self.deletedAt : deletedAt // ignore: cast_nullable_to_non_nullable
|
||||||
|
as DateTime?,
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// dart format on
|
// dart format on
|
||||||
|
@@ -24,11 +24,18 @@ _SnPost _$SnPostFromJson(Map<String, dynamic> json) => _SnPost(
|
|||||||
slug: json['slug'] as String?,
|
slug: json['slug'] as String?,
|
||||||
type: (json['type'] as num?)?.toInt() ?? 0,
|
type: (json['type'] as num?)?.toInt() ?? 0,
|
||||||
meta: json['meta'] as Map<String, dynamic>?,
|
meta: json['meta'] as Map<String, dynamic>?,
|
||||||
|
embedView:
|
||||||
|
json['embed_view'] == null
|
||||||
|
? null
|
||||||
|
: SnPostEmbedView.fromJson(
|
||||||
|
json['embed_view'] as Map<String, dynamic>,
|
||||||
|
),
|
||||||
viewsUnique: (json['views_unique'] as num?)?.toInt() ?? 0,
|
viewsUnique: (json['views_unique'] as num?)?.toInt() ?? 0,
|
||||||
viewsTotal: (json['views_total'] as num?)?.toInt() ?? 0,
|
viewsTotal: (json['views_total'] as num?)?.toInt() ?? 0,
|
||||||
upvotes: (json['upvotes'] as num?)?.toInt() ?? 0,
|
upvotes: (json['upvotes'] as num?)?.toInt() ?? 0,
|
||||||
downvotes: (json['downvotes'] as num?)?.toInt() ?? 0,
|
downvotes: (json['downvotes'] as num?)?.toInt() ?? 0,
|
||||||
repliesCount: (json['replies_count'] as num?)?.toInt() ?? 0,
|
repliesCount: (json['replies_count'] as num?)?.toInt() ?? 0,
|
||||||
|
awardedScore: (json['awarded_score'] as num?)?.toInt() ?? 0,
|
||||||
pinMode: (json['pin_mode'] as num?)?.toInt(),
|
pinMode: (json['pin_mode'] as num?)?.toInt(),
|
||||||
threadedPostId: json['threaded_post_id'] as String?,
|
threadedPostId: json['threaded_post_id'] as String?,
|
||||||
threadedPost:
|
threadedPost:
|
||||||
@@ -105,11 +112,13 @@ Map<String, dynamic> _$SnPostToJson(_SnPost instance) => <String, dynamic>{
|
|||||||
'slug': instance.slug,
|
'slug': instance.slug,
|
||||||
'type': instance.type,
|
'type': instance.type,
|
||||||
'meta': instance.meta,
|
'meta': instance.meta,
|
||||||
|
'embed_view': instance.embedView?.toJson(),
|
||||||
'views_unique': instance.viewsUnique,
|
'views_unique': instance.viewsUnique,
|
||||||
'views_total': instance.viewsTotal,
|
'views_total': instance.viewsTotal,
|
||||||
'upvotes': instance.upvotes,
|
'upvotes': instance.upvotes,
|
||||||
'downvotes': instance.downvotes,
|
'downvotes': instance.downvotes,
|
||||||
'replies_count': instance.repliesCount,
|
'replies_count': instance.repliesCount,
|
||||||
|
'awarded_score': instance.awardedScore,
|
||||||
'pin_mode': instance.pinMode,
|
'pin_mode': instance.pinMode,
|
||||||
'threaded_post_id': instance.threadedPostId,
|
'threaded_post_id': instance.threadedPostId,
|
||||||
'threaded_post': instance.threadedPost?.toJson(),
|
'threaded_post': instance.threadedPost?.toJson(),
|
||||||
@@ -166,3 +175,58 @@ Map<String, dynamic> _$SnSubscriptionStatusToJson(
|
|||||||
'publisher_id': instance.publisherId,
|
'publisher_id': instance.publisherId,
|
||||||
'publisher_name': instance.publisherName,
|
'publisher_name': instance.publisherName,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
_SnPostEmbedView _$SnPostEmbedViewFromJson(Map<String, dynamic> json) =>
|
||||||
|
_SnPostEmbedView(
|
||||||
|
uri: json['uri'] as String,
|
||||||
|
aspectRatio: (json['aspect_ratio'] as num?)?.toDouble(),
|
||||||
|
renderer:
|
||||||
|
$enumDecodeNullable(
|
||||||
|
_$PostEmbedViewRendererEnumMap,
|
||||||
|
json['renderer'],
|
||||||
|
) ??
|
||||||
|
PostEmbedViewRenderer.webView,
|
||||||
|
);
|
||||||
|
|
||||||
|
Map<String, dynamic> _$SnPostEmbedViewToJson(_SnPostEmbedView instance) =>
|
||||||
|
<String, dynamic>{
|
||||||
|
'uri': instance.uri,
|
||||||
|
'aspect_ratio': instance.aspectRatio,
|
||||||
|
'renderer': _$PostEmbedViewRendererEnumMap[instance.renderer]!,
|
||||||
|
};
|
||||||
|
|
||||||
|
const _$PostEmbedViewRendererEnumMap = {PostEmbedViewRenderer.webView: 0};
|
||||||
|
|
||||||
|
_SnPostAward _$SnPostAwardFromJson(Map<String, dynamic> json) => _SnPostAward(
|
||||||
|
id: json['id'] as String,
|
||||||
|
amount: (json['amount'] as num).toDouble(),
|
||||||
|
attitude: (json['attitude'] as num).toInt(),
|
||||||
|
message: json['message'] as String?,
|
||||||
|
postId: json['post_id'] as String,
|
||||||
|
accountId: json['account_id'] as String,
|
||||||
|
createdAt:
|
||||||
|
json['created_at'] == null
|
||||||
|
? null
|
||||||
|
: DateTime.parse(json['created_at'] as String),
|
||||||
|
updatedAt:
|
||||||
|
json['updated_at'] == null
|
||||||
|
? null
|
||||||
|
: DateTime.parse(json['updated_at'] as String),
|
||||||
|
deletedAt:
|
||||||
|
json['deleted_at'] == null
|
||||||
|
? null
|
||||||
|
: DateTime.parse(json['deleted_at'] as String),
|
||||||
|
);
|
||||||
|
|
||||||
|
Map<String, dynamic> _$SnPostAwardToJson(_SnPostAward instance) =>
|
||||||
|
<String, dynamic>{
|
||||||
|
'id': instance.id,
|
||||||
|
'amount': instance.amount,
|
||||||
|
'attitude': instance.attitude,
|
||||||
|
'message': instance.message,
|
||||||
|
'post_id': instance.postId,
|
||||||
|
'account_id': instance.accountId,
|
||||||
|
'created_at': instance.createdAt?.toIso8601String(),
|
||||||
|
'updated_at': instance.updatedAt?.toIso8601String(),
|
||||||
|
'deleted_at': instance.deletedAt?.toIso8601String(),
|
||||||
|
};
|
||||||
|
@@ -108,17 +108,14 @@ sealed class SnWalletOrder with _$SnWalletOrder {
|
|||||||
required String id,
|
required String id,
|
||||||
required int status,
|
required int status,
|
||||||
required String currency,
|
required String currency,
|
||||||
required dynamic remarks,
|
required String? remarks,
|
||||||
required String appIdentifier,
|
required String appIdentifier,
|
||||||
@Default({}) Map<String, dynamic> meta,
|
@Default({}) Map<String, dynamic> meta,
|
||||||
required int amount,
|
required int amount,
|
||||||
required DateTime expiredAt,
|
required DateTime expiredAt,
|
||||||
required String? payeeWalletId,
|
required String? payeeWalletId,
|
||||||
required SnWallet? payeeWallet,
|
|
||||||
required String? transactionId,
|
required String? transactionId,
|
||||||
required SnTransaction? transaction,
|
|
||||||
required String? issuerAppId,
|
required String? issuerAppId,
|
||||||
required dynamic issuerApp,
|
|
||||||
required DateTime createdAt,
|
required DateTime createdAt,
|
||||||
required DateTime updatedAt,
|
required DateTime updatedAt,
|
||||||
required DateTime? deletedAt,
|
required DateTime? deletedAt,
|
||||||
|
@@ -1554,7 +1554,7 @@ as String,
|
|||||||
/// @nodoc
|
/// @nodoc
|
||||||
mixin _$SnWalletOrder {
|
mixin _$SnWalletOrder {
|
||||||
|
|
||||||
String get id; int get status; String get currency; dynamic get remarks; String get appIdentifier; Map<String, dynamic> get meta; int get amount; DateTime get expiredAt; String? get payeeWalletId; SnWallet? get payeeWallet; String? get transactionId; SnTransaction? get transaction; String? get issuerAppId; dynamic get issuerApp; DateTime get createdAt; DateTime get updatedAt; DateTime? get deletedAt;
|
String get id; int get status; String get currency; String? get remarks; String get appIdentifier; Map<String, dynamic> get meta; int get amount; DateTime get expiredAt; String? get payeeWalletId; String? get transactionId; String? get issuerAppId; DateTime get createdAt; DateTime get updatedAt; DateTime? get deletedAt;
|
||||||
/// Create a copy of SnWalletOrder
|
/// Create a copy of SnWalletOrder
|
||||||
/// with the given fields replaced by the non-null parameter values.
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||||
@@ -1567,16 +1567,16 @@ $SnWalletOrderCopyWith<SnWalletOrder> get copyWith => _$SnWalletOrderCopyWithImp
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
bool operator ==(Object other) {
|
bool operator ==(Object other) {
|
||||||
return identical(this, other) || (other.runtimeType == runtimeType&&other is SnWalletOrder&&(identical(other.id, id) || other.id == id)&&(identical(other.status, status) || other.status == status)&&(identical(other.currency, currency) || other.currency == currency)&&const DeepCollectionEquality().equals(other.remarks, remarks)&&(identical(other.appIdentifier, appIdentifier) || other.appIdentifier == appIdentifier)&&const DeepCollectionEquality().equals(other.meta, meta)&&(identical(other.amount, amount) || other.amount == amount)&&(identical(other.expiredAt, expiredAt) || other.expiredAt == expiredAt)&&(identical(other.payeeWalletId, payeeWalletId) || other.payeeWalletId == payeeWalletId)&&(identical(other.payeeWallet, payeeWallet) || other.payeeWallet == payeeWallet)&&(identical(other.transactionId, transactionId) || other.transactionId == transactionId)&&(identical(other.transaction, transaction) || other.transaction == transaction)&&(identical(other.issuerAppId, issuerAppId) || other.issuerAppId == issuerAppId)&&const DeepCollectionEquality().equals(other.issuerApp, issuerApp)&&(identical(other.createdAt, createdAt) || other.createdAt == createdAt)&&(identical(other.updatedAt, updatedAt) || other.updatedAt == updatedAt)&&(identical(other.deletedAt, deletedAt) || other.deletedAt == deletedAt));
|
return identical(this, other) || (other.runtimeType == runtimeType&&other is SnWalletOrder&&(identical(other.id, id) || other.id == id)&&(identical(other.status, status) || other.status == status)&&(identical(other.currency, currency) || other.currency == currency)&&(identical(other.remarks, remarks) || other.remarks == remarks)&&(identical(other.appIdentifier, appIdentifier) || other.appIdentifier == appIdentifier)&&const DeepCollectionEquality().equals(other.meta, meta)&&(identical(other.amount, amount) || other.amount == amount)&&(identical(other.expiredAt, expiredAt) || other.expiredAt == expiredAt)&&(identical(other.payeeWalletId, payeeWalletId) || other.payeeWalletId == payeeWalletId)&&(identical(other.transactionId, transactionId) || other.transactionId == transactionId)&&(identical(other.issuerAppId, issuerAppId) || other.issuerAppId == issuerAppId)&&(identical(other.createdAt, createdAt) || other.createdAt == createdAt)&&(identical(other.updatedAt, updatedAt) || other.updatedAt == updatedAt)&&(identical(other.deletedAt, deletedAt) || other.deletedAt == deletedAt));
|
||||||
}
|
}
|
||||||
|
|
||||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||||
@override
|
@override
|
||||||
int get hashCode => Object.hash(runtimeType,id,status,currency,const DeepCollectionEquality().hash(remarks),appIdentifier,const DeepCollectionEquality().hash(meta),amount,expiredAt,payeeWalletId,payeeWallet,transactionId,transaction,issuerAppId,const DeepCollectionEquality().hash(issuerApp),createdAt,updatedAt,deletedAt);
|
int get hashCode => Object.hash(runtimeType,id,status,currency,remarks,appIdentifier,const DeepCollectionEquality().hash(meta),amount,expiredAt,payeeWalletId,transactionId,issuerAppId,createdAt,updatedAt,deletedAt);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String toString() {
|
String toString() {
|
||||||
return 'SnWalletOrder(id: $id, status: $status, currency: $currency, remarks: $remarks, appIdentifier: $appIdentifier, meta: $meta, amount: $amount, expiredAt: $expiredAt, payeeWalletId: $payeeWalletId, payeeWallet: $payeeWallet, transactionId: $transactionId, transaction: $transaction, issuerAppId: $issuerAppId, issuerApp: $issuerApp, createdAt: $createdAt, updatedAt: $updatedAt, deletedAt: $deletedAt)';
|
return 'SnWalletOrder(id: $id, status: $status, currency: $currency, remarks: $remarks, appIdentifier: $appIdentifier, meta: $meta, amount: $amount, expiredAt: $expiredAt, payeeWalletId: $payeeWalletId, transactionId: $transactionId, issuerAppId: $issuerAppId, createdAt: $createdAt, updatedAt: $updatedAt, deletedAt: $deletedAt)';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -1587,11 +1587,11 @@ abstract mixin class $SnWalletOrderCopyWith<$Res> {
|
|||||||
factory $SnWalletOrderCopyWith(SnWalletOrder value, $Res Function(SnWalletOrder) _then) = _$SnWalletOrderCopyWithImpl;
|
factory $SnWalletOrderCopyWith(SnWalletOrder value, $Res Function(SnWalletOrder) _then) = _$SnWalletOrderCopyWithImpl;
|
||||||
@useResult
|
@useResult
|
||||||
$Res call({
|
$Res call({
|
||||||
String id, int status, String currency, dynamic remarks, String appIdentifier, Map<String, dynamic> meta, int amount, DateTime expiredAt, String? payeeWalletId, SnWallet? payeeWallet, String? transactionId, SnTransaction? transaction, String? issuerAppId, dynamic issuerApp, DateTime createdAt, DateTime updatedAt, DateTime? deletedAt
|
String id, int status, String currency, String? remarks, String appIdentifier, Map<String, dynamic> meta, int amount, DateTime expiredAt, String? payeeWalletId, String? transactionId, String? issuerAppId, DateTime createdAt, DateTime updatedAt, DateTime? deletedAt
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
$SnWalletCopyWith<$Res>? get payeeWallet;$SnTransactionCopyWith<$Res>? get transaction;
|
|
||||||
|
|
||||||
}
|
}
|
||||||
/// @nodoc
|
/// @nodoc
|
||||||
@@ -1604,53 +1604,26 @@ class _$SnWalletOrderCopyWithImpl<$Res>
|
|||||||
|
|
||||||
/// Create a copy of SnWalletOrder
|
/// Create a copy of SnWalletOrder
|
||||||
/// with the given fields replaced by the non-null parameter values.
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
@pragma('vm:prefer-inline') @override $Res call({Object? id = null,Object? status = null,Object? currency = null,Object? remarks = freezed,Object? appIdentifier = null,Object? meta = null,Object? amount = null,Object? expiredAt = null,Object? payeeWalletId = freezed,Object? payeeWallet = freezed,Object? transactionId = freezed,Object? transaction = freezed,Object? issuerAppId = freezed,Object? issuerApp = freezed,Object? createdAt = null,Object? updatedAt = null,Object? deletedAt = freezed,}) {
|
@pragma('vm:prefer-inline') @override $Res call({Object? id = null,Object? status = null,Object? currency = null,Object? remarks = freezed,Object? appIdentifier = null,Object? meta = null,Object? amount = null,Object? expiredAt = null,Object? payeeWalletId = freezed,Object? transactionId = freezed,Object? issuerAppId = freezed,Object? createdAt = null,Object? updatedAt = null,Object? deletedAt = freezed,}) {
|
||||||
return _then(_self.copyWith(
|
return _then(_self.copyWith(
|
||||||
id: null == id ? _self.id : id // ignore: cast_nullable_to_non_nullable
|
id: null == id ? _self.id : id // ignore: cast_nullable_to_non_nullable
|
||||||
as String,status: null == status ? _self.status : status // ignore: cast_nullable_to_non_nullable
|
as String,status: null == status ? _self.status : status // ignore: cast_nullable_to_non_nullable
|
||||||
as int,currency: null == currency ? _self.currency : currency // ignore: cast_nullable_to_non_nullable
|
as int,currency: null == currency ? _self.currency : currency // ignore: cast_nullable_to_non_nullable
|
||||||
as String,remarks: freezed == remarks ? _self.remarks : remarks // ignore: cast_nullable_to_non_nullable
|
as String,remarks: freezed == remarks ? _self.remarks : remarks // ignore: cast_nullable_to_non_nullable
|
||||||
as dynamic,appIdentifier: null == appIdentifier ? _self.appIdentifier : appIdentifier // ignore: cast_nullable_to_non_nullable
|
as String?,appIdentifier: null == appIdentifier ? _self.appIdentifier : appIdentifier // ignore: cast_nullable_to_non_nullable
|
||||||
as String,meta: null == meta ? _self.meta : meta // ignore: cast_nullable_to_non_nullable
|
as String,meta: null == meta ? _self.meta : meta // ignore: cast_nullable_to_non_nullable
|
||||||
as Map<String, dynamic>,amount: null == amount ? _self.amount : amount // ignore: cast_nullable_to_non_nullable
|
as Map<String, dynamic>,amount: null == amount ? _self.amount : amount // ignore: cast_nullable_to_non_nullable
|
||||||
as int,expiredAt: null == expiredAt ? _self.expiredAt : expiredAt // ignore: cast_nullable_to_non_nullable
|
as int,expiredAt: null == expiredAt ? _self.expiredAt : expiredAt // ignore: cast_nullable_to_non_nullable
|
||||||
as DateTime,payeeWalletId: freezed == payeeWalletId ? _self.payeeWalletId : payeeWalletId // ignore: cast_nullable_to_non_nullable
|
as DateTime,payeeWalletId: freezed == payeeWalletId ? _self.payeeWalletId : payeeWalletId // ignore: cast_nullable_to_non_nullable
|
||||||
as String?,payeeWallet: freezed == payeeWallet ? _self.payeeWallet : payeeWallet // ignore: cast_nullable_to_non_nullable
|
as String?,transactionId: freezed == transactionId ? _self.transactionId : transactionId // ignore: cast_nullable_to_non_nullable
|
||||||
as SnWallet?,transactionId: freezed == transactionId ? _self.transactionId : transactionId // ignore: cast_nullable_to_non_nullable
|
as String?,issuerAppId: freezed == issuerAppId ? _self.issuerAppId : issuerAppId // ignore: cast_nullable_to_non_nullable
|
||||||
as String?,transaction: freezed == transaction ? _self.transaction : transaction // ignore: cast_nullable_to_non_nullable
|
as String?,createdAt: null == createdAt ? _self.createdAt : createdAt // ignore: cast_nullable_to_non_nullable
|
||||||
as SnTransaction?,issuerAppId: freezed == issuerAppId ? _self.issuerAppId : issuerAppId // ignore: cast_nullable_to_non_nullable
|
|
||||||
as String?,issuerApp: freezed == issuerApp ? _self.issuerApp : issuerApp // ignore: cast_nullable_to_non_nullable
|
|
||||||
as dynamic,createdAt: null == createdAt ? _self.createdAt : createdAt // ignore: cast_nullable_to_non_nullable
|
|
||||||
as DateTime,updatedAt: null == updatedAt ? _self.updatedAt : updatedAt // ignore: cast_nullable_to_non_nullable
|
as DateTime,updatedAt: null == updatedAt ? _self.updatedAt : updatedAt // ignore: cast_nullable_to_non_nullable
|
||||||
as DateTime,deletedAt: freezed == deletedAt ? _self.deletedAt : deletedAt // ignore: cast_nullable_to_non_nullable
|
as DateTime,deletedAt: freezed == deletedAt ? _self.deletedAt : deletedAt // ignore: cast_nullable_to_non_nullable
|
||||||
as DateTime?,
|
as DateTime?,
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
/// Create a copy of SnWalletOrder
|
|
||||||
/// with the given fields replaced by the non-null parameter values.
|
|
||||||
@override
|
|
||||||
@pragma('vm:prefer-inline')
|
|
||||||
$SnWalletCopyWith<$Res>? get payeeWallet {
|
|
||||||
if (_self.payeeWallet == null) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
return $SnWalletCopyWith<$Res>(_self.payeeWallet!, (value) {
|
|
||||||
return _then(_self.copyWith(payeeWallet: value));
|
|
||||||
});
|
|
||||||
}/// Create a copy of SnWalletOrder
|
|
||||||
/// with the given fields replaced by the non-null parameter values.
|
|
||||||
@override
|
|
||||||
@pragma('vm:prefer-inline')
|
|
||||||
$SnTransactionCopyWith<$Res>? get transaction {
|
|
||||||
if (_self.transaction == null) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
return $SnTransactionCopyWith<$Res>(_self.transaction!, (value) {
|
|
||||||
return _then(_self.copyWith(transaction: value));
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -1729,10 +1702,10 @@ return $default(_that);case _:
|
|||||||
/// }
|
/// }
|
||||||
/// ```
|
/// ```
|
||||||
|
|
||||||
@optionalTypeArgs TResult maybeWhen<TResult extends Object?>(TResult Function( String id, int status, String currency, dynamic remarks, String appIdentifier, Map<String, dynamic> meta, int amount, DateTime expiredAt, String? payeeWalletId, SnWallet? payeeWallet, String? transactionId, SnTransaction? transaction, String? issuerAppId, dynamic issuerApp, DateTime createdAt, DateTime updatedAt, DateTime? deletedAt)? $default,{required TResult orElse(),}) {final _that = this;
|
@optionalTypeArgs TResult maybeWhen<TResult extends Object?>(TResult Function( String id, int status, String currency, String? remarks, String appIdentifier, Map<String, dynamic> meta, int amount, DateTime expiredAt, String? payeeWalletId, String? transactionId, String? issuerAppId, DateTime createdAt, DateTime updatedAt, DateTime? deletedAt)? $default,{required TResult orElse(),}) {final _that = this;
|
||||||
switch (_that) {
|
switch (_that) {
|
||||||
case _SnWalletOrder() when $default != null:
|
case _SnWalletOrder() when $default != null:
|
||||||
return $default(_that.id,_that.status,_that.currency,_that.remarks,_that.appIdentifier,_that.meta,_that.amount,_that.expiredAt,_that.payeeWalletId,_that.payeeWallet,_that.transactionId,_that.transaction,_that.issuerAppId,_that.issuerApp,_that.createdAt,_that.updatedAt,_that.deletedAt);case _:
|
return $default(_that.id,_that.status,_that.currency,_that.remarks,_that.appIdentifier,_that.meta,_that.amount,_that.expiredAt,_that.payeeWalletId,_that.transactionId,_that.issuerAppId,_that.createdAt,_that.updatedAt,_that.deletedAt);case _:
|
||||||
return orElse();
|
return orElse();
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -1750,10 +1723,10 @@ return $default(_that.id,_that.status,_that.currency,_that.remarks,_that.appIden
|
|||||||
/// }
|
/// }
|
||||||
/// ```
|
/// ```
|
||||||
|
|
||||||
@optionalTypeArgs TResult when<TResult extends Object?>(TResult Function( String id, int status, String currency, dynamic remarks, String appIdentifier, Map<String, dynamic> meta, int amount, DateTime expiredAt, String? payeeWalletId, SnWallet? payeeWallet, String? transactionId, SnTransaction? transaction, String? issuerAppId, dynamic issuerApp, DateTime createdAt, DateTime updatedAt, DateTime? deletedAt) $default,) {final _that = this;
|
@optionalTypeArgs TResult when<TResult extends Object?>(TResult Function( String id, int status, String currency, String? remarks, String appIdentifier, Map<String, dynamic> meta, int amount, DateTime expiredAt, String? payeeWalletId, String? transactionId, String? issuerAppId, DateTime createdAt, DateTime updatedAt, DateTime? deletedAt) $default,) {final _that = this;
|
||||||
switch (_that) {
|
switch (_that) {
|
||||||
case _SnWalletOrder():
|
case _SnWalletOrder():
|
||||||
return $default(_that.id,_that.status,_that.currency,_that.remarks,_that.appIdentifier,_that.meta,_that.amount,_that.expiredAt,_that.payeeWalletId,_that.payeeWallet,_that.transactionId,_that.transaction,_that.issuerAppId,_that.issuerApp,_that.createdAt,_that.updatedAt,_that.deletedAt);}
|
return $default(_that.id,_that.status,_that.currency,_that.remarks,_that.appIdentifier,_that.meta,_that.amount,_that.expiredAt,_that.payeeWalletId,_that.transactionId,_that.issuerAppId,_that.createdAt,_that.updatedAt,_that.deletedAt);}
|
||||||
}
|
}
|
||||||
/// A variant of `when` that fallback to returning `null`
|
/// A variant of `when` that fallback to returning `null`
|
||||||
///
|
///
|
||||||
@@ -1767,10 +1740,10 @@ return $default(_that.id,_that.status,_that.currency,_that.remarks,_that.appIden
|
|||||||
/// }
|
/// }
|
||||||
/// ```
|
/// ```
|
||||||
|
|
||||||
@optionalTypeArgs TResult? whenOrNull<TResult extends Object?>(TResult? Function( String id, int status, String currency, dynamic remarks, String appIdentifier, Map<String, dynamic> meta, int amount, DateTime expiredAt, String? payeeWalletId, SnWallet? payeeWallet, String? transactionId, SnTransaction? transaction, String? issuerAppId, dynamic issuerApp, DateTime createdAt, DateTime updatedAt, DateTime? deletedAt)? $default,) {final _that = this;
|
@optionalTypeArgs TResult? whenOrNull<TResult extends Object?>(TResult? Function( String id, int status, String currency, String? remarks, String appIdentifier, Map<String, dynamic> meta, int amount, DateTime expiredAt, String? payeeWalletId, String? transactionId, String? issuerAppId, DateTime createdAt, DateTime updatedAt, DateTime? deletedAt)? $default,) {final _that = this;
|
||||||
switch (_that) {
|
switch (_that) {
|
||||||
case _SnWalletOrder() when $default != null:
|
case _SnWalletOrder() when $default != null:
|
||||||
return $default(_that.id,_that.status,_that.currency,_that.remarks,_that.appIdentifier,_that.meta,_that.amount,_that.expiredAt,_that.payeeWalletId,_that.payeeWallet,_that.transactionId,_that.transaction,_that.issuerAppId,_that.issuerApp,_that.createdAt,_that.updatedAt,_that.deletedAt);case _:
|
return $default(_that.id,_that.status,_that.currency,_that.remarks,_that.appIdentifier,_that.meta,_that.amount,_that.expiredAt,_that.payeeWalletId,_that.transactionId,_that.issuerAppId,_that.createdAt,_that.updatedAt,_that.deletedAt);case _:
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -1782,13 +1755,13 @@ return $default(_that.id,_that.status,_that.currency,_that.remarks,_that.appIden
|
|||||||
@JsonSerializable()
|
@JsonSerializable()
|
||||||
|
|
||||||
class _SnWalletOrder implements SnWalletOrder {
|
class _SnWalletOrder implements SnWalletOrder {
|
||||||
const _SnWalletOrder({required this.id, required this.status, required this.currency, required this.remarks, required this.appIdentifier, final Map<String, dynamic> meta = const {}, required this.amount, required this.expiredAt, required this.payeeWalletId, required this.payeeWallet, required this.transactionId, required this.transaction, required this.issuerAppId, required this.issuerApp, required this.createdAt, required this.updatedAt, required this.deletedAt}): _meta = meta;
|
const _SnWalletOrder({required this.id, required this.status, required this.currency, required this.remarks, required this.appIdentifier, final Map<String, dynamic> meta = const {}, required this.amount, required this.expiredAt, required this.payeeWalletId, required this.transactionId, required this.issuerAppId, required this.createdAt, required this.updatedAt, required this.deletedAt}): _meta = meta;
|
||||||
factory _SnWalletOrder.fromJson(Map<String, dynamic> json) => _$SnWalletOrderFromJson(json);
|
factory _SnWalletOrder.fromJson(Map<String, dynamic> json) => _$SnWalletOrderFromJson(json);
|
||||||
|
|
||||||
@override final String id;
|
@override final String id;
|
||||||
@override final int status;
|
@override final int status;
|
||||||
@override final String currency;
|
@override final String currency;
|
||||||
@override final dynamic remarks;
|
@override final String? remarks;
|
||||||
@override final String appIdentifier;
|
@override final String appIdentifier;
|
||||||
final Map<String, dynamic> _meta;
|
final Map<String, dynamic> _meta;
|
||||||
@override@JsonKey() Map<String, dynamic> get meta {
|
@override@JsonKey() Map<String, dynamic> get meta {
|
||||||
@@ -1800,11 +1773,8 @@ class _SnWalletOrder implements SnWalletOrder {
|
|||||||
@override final int amount;
|
@override final int amount;
|
||||||
@override final DateTime expiredAt;
|
@override final DateTime expiredAt;
|
||||||
@override final String? payeeWalletId;
|
@override final String? payeeWalletId;
|
||||||
@override final SnWallet? payeeWallet;
|
|
||||||
@override final String? transactionId;
|
@override final String? transactionId;
|
||||||
@override final SnTransaction? transaction;
|
|
||||||
@override final String? issuerAppId;
|
@override final String? issuerAppId;
|
||||||
@override final dynamic issuerApp;
|
|
||||||
@override final DateTime createdAt;
|
@override final DateTime createdAt;
|
||||||
@override final DateTime updatedAt;
|
@override final DateTime updatedAt;
|
||||||
@override final DateTime? deletedAt;
|
@override final DateTime? deletedAt;
|
||||||
@@ -1822,16 +1792,16 @@ Map<String, dynamic> toJson() {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
bool operator ==(Object other) {
|
bool operator ==(Object other) {
|
||||||
return identical(this, other) || (other.runtimeType == runtimeType&&other is _SnWalletOrder&&(identical(other.id, id) || other.id == id)&&(identical(other.status, status) || other.status == status)&&(identical(other.currency, currency) || other.currency == currency)&&const DeepCollectionEquality().equals(other.remarks, remarks)&&(identical(other.appIdentifier, appIdentifier) || other.appIdentifier == appIdentifier)&&const DeepCollectionEquality().equals(other._meta, _meta)&&(identical(other.amount, amount) || other.amount == amount)&&(identical(other.expiredAt, expiredAt) || other.expiredAt == expiredAt)&&(identical(other.payeeWalletId, payeeWalletId) || other.payeeWalletId == payeeWalletId)&&(identical(other.payeeWallet, payeeWallet) || other.payeeWallet == payeeWallet)&&(identical(other.transactionId, transactionId) || other.transactionId == transactionId)&&(identical(other.transaction, transaction) || other.transaction == transaction)&&(identical(other.issuerAppId, issuerAppId) || other.issuerAppId == issuerAppId)&&const DeepCollectionEquality().equals(other.issuerApp, issuerApp)&&(identical(other.createdAt, createdAt) || other.createdAt == createdAt)&&(identical(other.updatedAt, updatedAt) || other.updatedAt == updatedAt)&&(identical(other.deletedAt, deletedAt) || other.deletedAt == deletedAt));
|
return identical(this, other) || (other.runtimeType == runtimeType&&other is _SnWalletOrder&&(identical(other.id, id) || other.id == id)&&(identical(other.status, status) || other.status == status)&&(identical(other.currency, currency) || other.currency == currency)&&(identical(other.remarks, remarks) || other.remarks == remarks)&&(identical(other.appIdentifier, appIdentifier) || other.appIdentifier == appIdentifier)&&const DeepCollectionEquality().equals(other._meta, _meta)&&(identical(other.amount, amount) || other.amount == amount)&&(identical(other.expiredAt, expiredAt) || other.expiredAt == expiredAt)&&(identical(other.payeeWalletId, payeeWalletId) || other.payeeWalletId == payeeWalletId)&&(identical(other.transactionId, transactionId) || other.transactionId == transactionId)&&(identical(other.issuerAppId, issuerAppId) || other.issuerAppId == issuerAppId)&&(identical(other.createdAt, createdAt) || other.createdAt == createdAt)&&(identical(other.updatedAt, updatedAt) || other.updatedAt == updatedAt)&&(identical(other.deletedAt, deletedAt) || other.deletedAt == deletedAt));
|
||||||
}
|
}
|
||||||
|
|
||||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||||
@override
|
@override
|
||||||
int get hashCode => Object.hash(runtimeType,id,status,currency,const DeepCollectionEquality().hash(remarks),appIdentifier,const DeepCollectionEquality().hash(_meta),amount,expiredAt,payeeWalletId,payeeWallet,transactionId,transaction,issuerAppId,const DeepCollectionEquality().hash(issuerApp),createdAt,updatedAt,deletedAt);
|
int get hashCode => Object.hash(runtimeType,id,status,currency,remarks,appIdentifier,const DeepCollectionEquality().hash(_meta),amount,expiredAt,payeeWalletId,transactionId,issuerAppId,createdAt,updatedAt,deletedAt);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String toString() {
|
String toString() {
|
||||||
return 'SnWalletOrder(id: $id, status: $status, currency: $currency, remarks: $remarks, appIdentifier: $appIdentifier, meta: $meta, amount: $amount, expiredAt: $expiredAt, payeeWalletId: $payeeWalletId, payeeWallet: $payeeWallet, transactionId: $transactionId, transaction: $transaction, issuerAppId: $issuerAppId, issuerApp: $issuerApp, createdAt: $createdAt, updatedAt: $updatedAt, deletedAt: $deletedAt)';
|
return 'SnWalletOrder(id: $id, status: $status, currency: $currency, remarks: $remarks, appIdentifier: $appIdentifier, meta: $meta, amount: $amount, expiredAt: $expiredAt, payeeWalletId: $payeeWalletId, transactionId: $transactionId, issuerAppId: $issuerAppId, createdAt: $createdAt, updatedAt: $updatedAt, deletedAt: $deletedAt)';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -1842,11 +1812,11 @@ abstract mixin class _$SnWalletOrderCopyWith<$Res> implements $SnWalletOrderCopy
|
|||||||
factory _$SnWalletOrderCopyWith(_SnWalletOrder value, $Res Function(_SnWalletOrder) _then) = __$SnWalletOrderCopyWithImpl;
|
factory _$SnWalletOrderCopyWith(_SnWalletOrder value, $Res Function(_SnWalletOrder) _then) = __$SnWalletOrderCopyWithImpl;
|
||||||
@override @useResult
|
@override @useResult
|
||||||
$Res call({
|
$Res call({
|
||||||
String id, int status, String currency, dynamic remarks, String appIdentifier, Map<String, dynamic> meta, int amount, DateTime expiredAt, String? payeeWalletId, SnWallet? payeeWallet, String? transactionId, SnTransaction? transaction, String? issuerAppId, dynamic issuerApp, DateTime createdAt, DateTime updatedAt, DateTime? deletedAt
|
String id, int status, String currency, String? remarks, String appIdentifier, Map<String, dynamic> meta, int amount, DateTime expiredAt, String? payeeWalletId, String? transactionId, String? issuerAppId, DateTime createdAt, DateTime updatedAt, DateTime? deletedAt
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
@override $SnWalletCopyWith<$Res>? get payeeWallet;@override $SnTransactionCopyWith<$Res>? get transaction;
|
|
||||||
|
|
||||||
}
|
}
|
||||||
/// @nodoc
|
/// @nodoc
|
||||||
@@ -1859,54 +1829,27 @@ class __$SnWalletOrderCopyWithImpl<$Res>
|
|||||||
|
|
||||||
/// Create a copy of SnWalletOrder
|
/// Create a copy of SnWalletOrder
|
||||||
/// with the given fields replaced by the non-null parameter values.
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
@override @pragma('vm:prefer-inline') $Res call({Object? id = null,Object? status = null,Object? currency = null,Object? remarks = freezed,Object? appIdentifier = null,Object? meta = null,Object? amount = null,Object? expiredAt = null,Object? payeeWalletId = freezed,Object? payeeWallet = freezed,Object? transactionId = freezed,Object? transaction = freezed,Object? issuerAppId = freezed,Object? issuerApp = freezed,Object? createdAt = null,Object? updatedAt = null,Object? deletedAt = freezed,}) {
|
@override @pragma('vm:prefer-inline') $Res call({Object? id = null,Object? status = null,Object? currency = null,Object? remarks = freezed,Object? appIdentifier = null,Object? meta = null,Object? amount = null,Object? expiredAt = null,Object? payeeWalletId = freezed,Object? transactionId = freezed,Object? issuerAppId = freezed,Object? createdAt = null,Object? updatedAt = null,Object? deletedAt = freezed,}) {
|
||||||
return _then(_SnWalletOrder(
|
return _then(_SnWalletOrder(
|
||||||
id: null == id ? _self.id : id // ignore: cast_nullable_to_non_nullable
|
id: null == id ? _self.id : id // ignore: cast_nullable_to_non_nullable
|
||||||
as String,status: null == status ? _self.status : status // ignore: cast_nullable_to_non_nullable
|
as String,status: null == status ? _self.status : status // ignore: cast_nullable_to_non_nullable
|
||||||
as int,currency: null == currency ? _self.currency : currency // ignore: cast_nullable_to_non_nullable
|
as int,currency: null == currency ? _self.currency : currency // ignore: cast_nullable_to_non_nullable
|
||||||
as String,remarks: freezed == remarks ? _self.remarks : remarks // ignore: cast_nullable_to_non_nullable
|
as String,remarks: freezed == remarks ? _self.remarks : remarks // ignore: cast_nullable_to_non_nullable
|
||||||
as dynamic,appIdentifier: null == appIdentifier ? _self.appIdentifier : appIdentifier // ignore: cast_nullable_to_non_nullable
|
as String?,appIdentifier: null == appIdentifier ? _self.appIdentifier : appIdentifier // ignore: cast_nullable_to_non_nullable
|
||||||
as String,meta: null == meta ? _self._meta : meta // ignore: cast_nullable_to_non_nullable
|
as String,meta: null == meta ? _self._meta : meta // ignore: cast_nullable_to_non_nullable
|
||||||
as Map<String, dynamic>,amount: null == amount ? _self.amount : amount // ignore: cast_nullable_to_non_nullable
|
as Map<String, dynamic>,amount: null == amount ? _self.amount : amount // ignore: cast_nullable_to_non_nullable
|
||||||
as int,expiredAt: null == expiredAt ? _self.expiredAt : expiredAt // ignore: cast_nullable_to_non_nullable
|
as int,expiredAt: null == expiredAt ? _self.expiredAt : expiredAt // ignore: cast_nullable_to_non_nullable
|
||||||
as DateTime,payeeWalletId: freezed == payeeWalletId ? _self.payeeWalletId : payeeWalletId // ignore: cast_nullable_to_non_nullable
|
as DateTime,payeeWalletId: freezed == payeeWalletId ? _self.payeeWalletId : payeeWalletId // ignore: cast_nullable_to_non_nullable
|
||||||
as String?,payeeWallet: freezed == payeeWallet ? _self.payeeWallet : payeeWallet // ignore: cast_nullable_to_non_nullable
|
as String?,transactionId: freezed == transactionId ? _self.transactionId : transactionId // ignore: cast_nullable_to_non_nullable
|
||||||
as SnWallet?,transactionId: freezed == transactionId ? _self.transactionId : transactionId // ignore: cast_nullable_to_non_nullable
|
as String?,issuerAppId: freezed == issuerAppId ? _self.issuerAppId : issuerAppId // ignore: cast_nullable_to_non_nullable
|
||||||
as String?,transaction: freezed == transaction ? _self.transaction : transaction // ignore: cast_nullable_to_non_nullable
|
as String?,createdAt: null == createdAt ? _self.createdAt : createdAt // ignore: cast_nullable_to_non_nullable
|
||||||
as SnTransaction?,issuerAppId: freezed == issuerAppId ? _self.issuerAppId : issuerAppId // ignore: cast_nullable_to_non_nullable
|
|
||||||
as String?,issuerApp: freezed == issuerApp ? _self.issuerApp : issuerApp // ignore: cast_nullable_to_non_nullable
|
|
||||||
as dynamic,createdAt: null == createdAt ? _self.createdAt : createdAt // ignore: cast_nullable_to_non_nullable
|
|
||||||
as DateTime,updatedAt: null == updatedAt ? _self.updatedAt : updatedAt // ignore: cast_nullable_to_non_nullable
|
as DateTime,updatedAt: null == updatedAt ? _self.updatedAt : updatedAt // ignore: cast_nullable_to_non_nullable
|
||||||
as DateTime,deletedAt: freezed == deletedAt ? _self.deletedAt : deletedAt // ignore: cast_nullable_to_non_nullable
|
as DateTime,deletedAt: freezed == deletedAt ? _self.deletedAt : deletedAt // ignore: cast_nullable_to_non_nullable
|
||||||
as DateTime?,
|
as DateTime?,
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Create a copy of SnWalletOrder
|
|
||||||
/// with the given fields replaced by the non-null parameter values.
|
|
||||||
@override
|
|
||||||
@pragma('vm:prefer-inline')
|
|
||||||
$SnWalletCopyWith<$Res>? get payeeWallet {
|
|
||||||
if (_self.payeeWallet == null) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
return $SnWalletCopyWith<$Res>(_self.payeeWallet!, (value) {
|
|
||||||
return _then(_self.copyWith(payeeWallet: value));
|
|
||||||
});
|
|
||||||
}/// Create a copy of SnWalletOrder
|
|
||||||
/// with the given fields replaced by the non-null parameter values.
|
|
||||||
@override
|
|
||||||
@pragma('vm:prefer-inline')
|
|
||||||
$SnTransactionCopyWith<$Res>? get transaction {
|
|
||||||
if (_self.transaction == null) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
return $SnTransactionCopyWith<$Res>(_self.transaction!, (value) {
|
|
||||||
return _then(_self.copyWith(transaction: value));
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// dart format on
|
// dart format on
|
||||||
|
@@ -195,25 +195,14 @@ _SnWalletOrder _$SnWalletOrderFromJson(Map<String, dynamic> json) =>
|
|||||||
id: json['id'] as String,
|
id: json['id'] as String,
|
||||||
status: (json['status'] as num).toInt(),
|
status: (json['status'] as num).toInt(),
|
||||||
currency: json['currency'] as String,
|
currency: json['currency'] as String,
|
||||||
remarks: json['remarks'],
|
remarks: json['remarks'] as String?,
|
||||||
appIdentifier: json['app_identifier'] as String,
|
appIdentifier: json['app_identifier'] as String,
|
||||||
meta: json['meta'] as Map<String, dynamic>? ?? const {},
|
meta: json['meta'] as Map<String, dynamic>? ?? const {},
|
||||||
amount: (json['amount'] as num).toInt(),
|
amount: (json['amount'] as num).toInt(),
|
||||||
expiredAt: DateTime.parse(json['expired_at'] as String),
|
expiredAt: DateTime.parse(json['expired_at'] as String),
|
||||||
payeeWalletId: json['payee_wallet_id'] as String?,
|
payeeWalletId: json['payee_wallet_id'] as String?,
|
||||||
payeeWallet:
|
|
||||||
json['payee_wallet'] == null
|
|
||||||
? null
|
|
||||||
: SnWallet.fromJson(json['payee_wallet'] as Map<String, dynamic>),
|
|
||||||
transactionId: json['transaction_id'] as String?,
|
transactionId: json['transaction_id'] as String?,
|
||||||
transaction:
|
|
||||||
json['transaction'] == null
|
|
||||||
? null
|
|
||||||
: SnTransaction.fromJson(
|
|
||||||
json['transaction'] as Map<String, dynamic>,
|
|
||||||
),
|
|
||||||
issuerAppId: json['issuer_app_id'] as String?,
|
issuerAppId: json['issuer_app_id'] as String?,
|
||||||
issuerApp: json['issuer_app'],
|
|
||||||
createdAt: DateTime.parse(json['created_at'] as String),
|
createdAt: DateTime.parse(json['created_at'] as String),
|
||||||
updatedAt: DateTime.parse(json['updated_at'] as String),
|
updatedAt: DateTime.parse(json['updated_at'] as String),
|
||||||
deletedAt:
|
deletedAt:
|
||||||
@@ -233,11 +222,8 @@ Map<String, dynamic> _$SnWalletOrderToJson(_SnWalletOrder instance) =>
|
|||||||
'amount': instance.amount,
|
'amount': instance.amount,
|
||||||
'expired_at': instance.expiredAt.toIso8601String(),
|
'expired_at': instance.expiredAt.toIso8601String(),
|
||||||
'payee_wallet_id': instance.payeeWalletId,
|
'payee_wallet_id': instance.payeeWalletId,
|
||||||
'payee_wallet': instance.payeeWallet?.toJson(),
|
|
||||||
'transaction_id': instance.transactionId,
|
'transaction_id': instance.transactionId,
|
||||||
'transaction': instance.transaction?.toJson(),
|
|
||||||
'issuer_app_id': instance.issuerAppId,
|
'issuer_app_id': instance.issuerAppId,
|
||||||
'issuer_app': instance.issuerApp,
|
|
||||||
'created_at': instance.createdAt.toIso8601String(),
|
'created_at': instance.createdAt.toIso8601String(),
|
||||||
'updated_at': instance.updatedAt.toIso8601String(),
|
'updated_at': instance.updatedAt.toIso8601String(),
|
||||||
'deleted_at': instance.deletedAt?.toIso8601String(),
|
'deleted_at': instance.deletedAt?.toIso8601String(),
|
||||||
|
651
lib/pods/activity_rpc.dart
Normal file
651
lib/pods/activity_rpc.dart
Normal file
@@ -0,0 +1,651 @@
|
|||||||
|
import 'dart:async';
|
||||||
|
import 'dart:convert';
|
||||||
|
import 'dart:developer' as developer;
|
||||||
|
import 'dart:io';
|
||||||
|
import 'package:flutter/foundation.dart';
|
||||||
|
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||||
|
import 'package:island/pods/network.dart';
|
||||||
|
import 'package:shelf/shelf.dart';
|
||||||
|
import 'package:shelf/shelf_io.dart' as shelf_io;
|
||||||
|
import 'package:shelf_web_socket/shelf_web_socket.dart';
|
||||||
|
import 'package:web_socket_channel/web_socket_channel.dart';
|
||||||
|
import 'package:path/path.dart' as path;
|
||||||
|
|
||||||
|
const String kRpcLogPrefix = 'arRPC.websocket';
|
||||||
|
const String kRpcIpcLogPrefix = 'arRPC.ipc';
|
||||||
|
|
||||||
|
// IPC Constants
|
||||||
|
const String kIpcBasePath = 'discord-ipc';
|
||||||
|
|
||||||
|
// IPC Packet Types
|
||||||
|
class IpcTypes {
|
||||||
|
static const int handshake = 0;
|
||||||
|
static const int frame = 1;
|
||||||
|
static const int close = 2;
|
||||||
|
static const int ping = 3;
|
||||||
|
static const int pong = 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
// IPC Close Codes
|
||||||
|
class IpcCloseCodes {
|
||||||
|
static const int closeNormal = 1000;
|
||||||
|
static const int closeUnsupported = 1003;
|
||||||
|
static const int closeAbnormal = 1006;
|
||||||
|
}
|
||||||
|
|
||||||
|
// IPC Error Codes
|
||||||
|
class IpcErrorCodes {
|
||||||
|
static const int invalidClientId = 4000;
|
||||||
|
static const int invalidOrigin = 4001;
|
||||||
|
static const int rateLimited = 4002;
|
||||||
|
static const int tokenRevoked = 4003;
|
||||||
|
static const int invalidVersion = 4004;
|
||||||
|
static const int invalidEncoding = 4005;
|
||||||
|
}
|
||||||
|
|
||||||
|
class ActivityRpcServer {
|
||||||
|
static const List<int> portRange = [6463, 6472]; // Ports 6463–6472
|
||||||
|
Map<String, Function>
|
||||||
|
handlers; // {connection: (socket), message: (socket, data), close: (socket)}
|
||||||
|
HttpServer? _httpServer;
|
||||||
|
ServerSocket? _ipcServer;
|
||||||
|
final List<WebSocketChannel> _wsSockets = [];
|
||||||
|
final List<_IpcSocketWrapper> _ipcSockets = [];
|
||||||
|
|
||||||
|
ActivityRpcServer(this.handlers);
|
||||||
|
|
||||||
|
void updateHandlers(Map<String, Function> newHandlers) {
|
||||||
|
handlers = newHandlers;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Encode IPC packet
|
||||||
|
static Uint8List encodeIpcPacket(int type, Map<String, dynamic> data) {
|
||||||
|
final jsonData = jsonEncode(data);
|
||||||
|
final dataBytes = utf8.encode(jsonData);
|
||||||
|
final dataSize = dataBytes.length;
|
||||||
|
|
||||||
|
final buffer = ByteData(8 + dataSize);
|
||||||
|
buffer.setInt32(0, type, Endian.little);
|
||||||
|
buffer.setInt32(4, dataSize, Endian.little);
|
||||||
|
buffer.buffer.asUint8List().setRange(8, 8 + dataSize, dataBytes);
|
||||||
|
|
||||||
|
return buffer.buffer.asUint8List();
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<String> _getMacOsSystemTmpDir() async {
|
||||||
|
final result = await Process.run('getconf', ['DARWIN_USER_TEMP_DIR']);
|
||||||
|
return (result.stdout as String).trim();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Find available IPC socket path
|
||||||
|
Future<String> _findAvailableIpcPath() async {
|
||||||
|
// Build list of directories to try, with macOS-specific handling
|
||||||
|
final baseDirs = <String>[];
|
||||||
|
|
||||||
|
if (Platform.isMacOS) {
|
||||||
|
try {
|
||||||
|
final macTempDir = await _getMacOsSystemTmpDir();
|
||||||
|
if (macTempDir.isNotEmpty) {
|
||||||
|
baseDirs.add(macTempDir);
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
developer.log(
|
||||||
|
'Failed to get macOS system temp dir: $e',
|
||||||
|
name: kRpcIpcLogPrefix,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add other standard directories
|
||||||
|
final otherDirs = [
|
||||||
|
Platform.environment['XDG_RUNTIME_DIR'], // User runtime directory
|
||||||
|
Platform.environment['TMPDIR'], // App container temp (fallback)
|
||||||
|
Platform.environment['TMP'],
|
||||||
|
Platform.environment['TEMP'],
|
||||||
|
'/tmp', // System temp directory - most compatible
|
||||||
|
];
|
||||||
|
|
||||||
|
baseDirs.addAll(
|
||||||
|
otherDirs.where((dir) => dir != null && dir.isNotEmpty).cast<String>(),
|
||||||
|
);
|
||||||
|
|
||||||
|
for (final baseDir in baseDirs) {
|
||||||
|
for (int i = 0; i < 10; i++) {
|
||||||
|
final socketPath = path.join(baseDir, '$kIpcBasePath-$i');
|
||||||
|
try {
|
||||||
|
final socket = await ServerSocket.bind(
|
||||||
|
InternetAddress(socketPath, type: InternetAddressType.unix),
|
||||||
|
0,
|
||||||
|
);
|
||||||
|
socket.close();
|
||||||
|
// Clean up the test socket
|
||||||
|
try {
|
||||||
|
await File(socketPath).delete();
|
||||||
|
} catch (_) {}
|
||||||
|
developer.log(
|
||||||
|
'IPC socket will be created at: $socketPath',
|
||||||
|
name: kRpcIpcLogPrefix,
|
||||||
|
);
|
||||||
|
return socketPath;
|
||||||
|
} catch (e) {
|
||||||
|
// Path not available, try next
|
||||||
|
if (i == 0) {
|
||||||
|
// Log only for the first attempt per directory
|
||||||
|
developer.log(
|
||||||
|
'IPC path $socketPath not available: $e',
|
||||||
|
name: kRpcIpcLogPrefix,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
throw Exception(
|
||||||
|
'No available IPC socket paths found in any temp directory',
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Start the WebSocket server
|
||||||
|
Future<void> start() async {
|
||||||
|
int port = portRange[0];
|
||||||
|
bool wsSuccess = false;
|
||||||
|
|
||||||
|
// Start WebSocket server
|
||||||
|
while (port <= portRange[1]) {
|
||||||
|
developer.log('trying port $port', name: kRpcLogPrefix);
|
||||||
|
try {
|
||||||
|
// Start HTTP server
|
||||||
|
_httpServer = await HttpServer.bind(InternetAddress.loopbackIPv4, port);
|
||||||
|
developer.log('listening on $port', name: kRpcLogPrefix);
|
||||||
|
|
||||||
|
// Handle WebSocket upgrades
|
||||||
|
shelf_io.serveRequests(_httpServer!, (Request request) async {
|
||||||
|
developer.log('new request', name: kRpcLogPrefix);
|
||||||
|
if (request.headers['upgrade']?.toLowerCase() == 'websocket') {
|
||||||
|
final handler = webSocketHandler((WebSocketChannel channel, _) {
|
||||||
|
_wsSockets.add(channel);
|
||||||
|
_onWsConnection(channel, request);
|
||||||
|
});
|
||||||
|
return handler(request);
|
||||||
|
}
|
||||||
|
developer.log(
|
||||||
|
'new request disposed due to not websocket',
|
||||||
|
name: kRpcLogPrefix,
|
||||||
|
);
|
||||||
|
return Response.notFound('Not a WebSocket request');
|
||||||
|
});
|
||||||
|
wsSuccess = true;
|
||||||
|
break;
|
||||||
|
} catch (e) {
|
||||||
|
if (e is SocketException && e.osError?.errorCode == 98) {
|
||||||
|
// EADDRINUSE
|
||||||
|
developer.log('$port in use!', name: kRpcLogPrefix);
|
||||||
|
} else {
|
||||||
|
developer.log('http error: $e', name: kRpcLogPrefix);
|
||||||
|
}
|
||||||
|
port++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!wsSuccess) {
|
||||||
|
throw Exception(
|
||||||
|
'Failed to bind to any port in range ${portRange[0]}–${portRange[1]}',
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Start IPC server (skip on macOS due to sandboxing)
|
||||||
|
final shouldStartIpc = !Platform.isMacOS;
|
||||||
|
if (shouldStartIpc) {
|
||||||
|
try {
|
||||||
|
final ipcPath = await _findAvailableIpcPath();
|
||||||
|
_ipcServer = await ServerSocket.bind(
|
||||||
|
InternetAddress(ipcPath, type: InternetAddressType.unix),
|
||||||
|
0,
|
||||||
|
);
|
||||||
|
developer.log('IPC listening at $ipcPath', name: kRpcIpcLogPrefix);
|
||||||
|
|
||||||
|
_ipcServer!.listen((Socket socket) {
|
||||||
|
_onIpcConnection(socket);
|
||||||
|
});
|
||||||
|
} catch (e) {
|
||||||
|
developer.log('IPC server error: $e', name: kRpcIpcLogPrefix);
|
||||||
|
// Continue without IPC if it fails
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
developer.log(
|
||||||
|
'IPC server disabled on macOS in production mode due to sandboxing',
|
||||||
|
name: kRpcIpcLogPrefix,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Stop the server
|
||||||
|
Future<void> stop() async {
|
||||||
|
// Stop WebSocket server
|
||||||
|
for (var socket in _wsSockets) {
|
||||||
|
await socket.sink.close();
|
||||||
|
}
|
||||||
|
_wsSockets.clear();
|
||||||
|
await _httpServer?.close();
|
||||||
|
|
||||||
|
// Stop IPC server
|
||||||
|
for (var socket in _ipcSockets) {
|
||||||
|
socket.close();
|
||||||
|
}
|
||||||
|
_ipcSockets.clear();
|
||||||
|
await _ipcServer?.close();
|
||||||
|
|
||||||
|
developer.log('servers stopped', name: kRpcLogPrefix);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Handle new WebSocket connection
|
||||||
|
void _onWsConnection(WebSocketChannel socket, Request request) {
|
||||||
|
// Parse query parameters
|
||||||
|
final uri = request.url;
|
||||||
|
final params = uri.queryParameters;
|
||||||
|
final ver = int.tryParse(params['v'] ?? '1') ?? 1;
|
||||||
|
final encoding = params['encoding'] ?? 'json';
|
||||||
|
final clientId = params['client_id'] ?? '';
|
||||||
|
final origin = request.headers['origin'] ?? '';
|
||||||
|
|
||||||
|
developer.log(
|
||||||
|
'new WS connection! origin: $origin, params: $params',
|
||||||
|
name: kRpcLogPrefix,
|
||||||
|
);
|
||||||
|
|
||||||
|
// Validate origin
|
||||||
|
if (origin.isNotEmpty &&
|
||||||
|
![
|
||||||
|
'https://discord.com',
|
||||||
|
'https://ptb.discord.com',
|
||||||
|
'https://canary.discord.com',
|
||||||
|
].contains(origin)) {
|
||||||
|
developer.log('disallowed origin: $origin', name: kRpcLogPrefix);
|
||||||
|
socket.sink.close();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Validate encoding
|
||||||
|
if (encoding != 'json') {
|
||||||
|
developer.log(
|
||||||
|
'unsupported encoding requested: $encoding',
|
||||||
|
name: kRpcLogPrefix,
|
||||||
|
);
|
||||||
|
socket.sink.close();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Validate version
|
||||||
|
if (ver != 1) {
|
||||||
|
developer.log('unsupported version requested: $ver', name: kRpcLogPrefix);
|
||||||
|
socket.sink.close();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Store client info on socket
|
||||||
|
final socketWithMeta = _WsSocketWrapper(socket, clientId, encoding);
|
||||||
|
|
||||||
|
// Set up event listeners
|
||||||
|
socket.stream.listen(
|
||||||
|
(data) => _onWsMessage(socketWithMeta, data),
|
||||||
|
onError: (e) {
|
||||||
|
developer.log('WS socket error: $e', name: kRpcLogPrefix);
|
||||||
|
},
|
||||||
|
onDone: () {
|
||||||
|
developer.log('WS socket closed', name: kRpcLogPrefix);
|
||||||
|
handlers['close']?.call(socketWithMeta);
|
||||||
|
_wsSockets.remove(socket);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
// Notify handler of new connection
|
||||||
|
handlers['connection']?.call(socketWithMeta);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Handle new IPC connection
|
||||||
|
void _onIpcConnection(Socket socket) {
|
||||||
|
developer.log('new IPC connection!', name: kRpcIpcLogPrefix);
|
||||||
|
|
||||||
|
final socketWrapper = _IpcSocketWrapper(socket);
|
||||||
|
_ipcSockets.add(socketWrapper);
|
||||||
|
|
||||||
|
// Set up event listeners
|
||||||
|
socket.listen(
|
||||||
|
(data) => _onIpcData(socketWrapper, data),
|
||||||
|
onError: (e) {
|
||||||
|
developer.log('IPC socket error: $e', name: kRpcIpcLogPrefix);
|
||||||
|
socket.close();
|
||||||
|
},
|
||||||
|
onDone: () {
|
||||||
|
developer.log('IPC socket closed', name: kRpcIpcLogPrefix);
|
||||||
|
handlers['close']?.call(socketWrapper);
|
||||||
|
_ipcSockets.remove(socketWrapper);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Handle incoming WebSocket message
|
||||||
|
void _onWsMessage(_WsSocketWrapper socket, dynamic data) {
|
||||||
|
try {
|
||||||
|
final jsonData = jsonDecode(data as String);
|
||||||
|
developer.log('WS message: $jsonData', name: kRpcLogPrefix);
|
||||||
|
handlers['message']?.call(socket, jsonData);
|
||||||
|
} catch (e) {
|
||||||
|
developer.log('WS message parse error: $e', name: kRpcLogPrefix);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Handle incoming IPC data
|
||||||
|
void _onIpcData(_IpcSocketWrapper socket, List<int> data) {
|
||||||
|
try {
|
||||||
|
socket.addData(data);
|
||||||
|
final packets = socket.readPackets();
|
||||||
|
for (final packet in packets) {
|
||||||
|
_handleIpcPacket(socket, packet);
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
developer.log('IPC data error: $e', name: kRpcIpcLogPrefix);
|
||||||
|
socket.closeWithCode(IpcCloseCodes.closeUnsupported, e.toString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Handle IPC packet
|
||||||
|
void _handleIpcPacket(_IpcSocketWrapper socket, _IpcPacket packet) {
|
||||||
|
switch (packet.type) {
|
||||||
|
case IpcTypes.ping:
|
||||||
|
developer.log('IPC ping received', name: kRpcIpcLogPrefix);
|
||||||
|
socket.sendPong(packet.data);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case IpcTypes.pong:
|
||||||
|
developer.log('IPC pong received', name: kRpcIpcLogPrefix);
|
||||||
|
// Handle pong if needed
|
||||||
|
break;
|
||||||
|
|
||||||
|
case IpcTypes.handshake:
|
||||||
|
if (socket.handshook) {
|
||||||
|
throw Exception('Already handshook');
|
||||||
|
}
|
||||||
|
socket.handshook = true;
|
||||||
|
_onIpcHandshake(socket, packet.data);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case IpcTypes.frame:
|
||||||
|
if (!socket.handshook) {
|
||||||
|
throw Exception('Need to handshake first');
|
||||||
|
}
|
||||||
|
developer.log('IPC frame: ${packet.data}', name: kRpcIpcLogPrefix);
|
||||||
|
handlers['message']?.call(socket, packet.data);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case IpcTypes.close:
|
||||||
|
socket.close();
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
throw Exception('Invalid packet type: ${packet.type}');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Handle IPC handshake
|
||||||
|
void _onIpcHandshake(_IpcSocketWrapper socket, Map<String, dynamic> params) {
|
||||||
|
developer.log('IPC handshake: $params', name: kRpcIpcLogPrefix);
|
||||||
|
|
||||||
|
final ver = int.tryParse(params['v']?.toString() ?? '1') ?? 1;
|
||||||
|
final clientId = params['client_id']?.toString() ?? '';
|
||||||
|
|
||||||
|
// Validate version
|
||||||
|
if (ver != 1) {
|
||||||
|
developer.log(
|
||||||
|
'IPC unsupported version requested: $ver',
|
||||||
|
name: kRpcIpcLogPrefix,
|
||||||
|
);
|
||||||
|
socket.closeWithCode(IpcErrorCodes.invalidVersion);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Validate client ID
|
||||||
|
if (clientId.isEmpty) {
|
||||||
|
developer.log('IPC client ID required', name: kRpcIpcLogPrefix);
|
||||||
|
socket.closeWithCode(IpcErrorCodes.invalidClientId);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
socket.clientId = clientId;
|
||||||
|
|
||||||
|
// Notify handler of new connection
|
||||||
|
handlers['connection']?.call(socket);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// WebSocket wrapper
|
||||||
|
class _WsSocketWrapper {
|
||||||
|
final WebSocketChannel channel;
|
||||||
|
final String clientId;
|
||||||
|
final String encoding;
|
||||||
|
|
||||||
|
_WsSocketWrapper(this.channel, this.clientId, this.encoding);
|
||||||
|
|
||||||
|
void send(Map<String, dynamic> msg) {
|
||||||
|
developer.log('WS sending: $msg', name: kRpcLogPrefix);
|
||||||
|
channel.sink.add(jsonEncode(msg));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// IPC wrapper
|
||||||
|
class _IpcSocketWrapper {
|
||||||
|
final Socket socket;
|
||||||
|
String clientId = '';
|
||||||
|
bool handshook = false;
|
||||||
|
final List<int> _buffer = [];
|
||||||
|
|
||||||
|
_IpcSocketWrapper(this.socket);
|
||||||
|
|
||||||
|
void addData(List<int> data) {
|
||||||
|
_buffer.addAll(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
void send(Map<String, dynamic> msg) {
|
||||||
|
developer.log('IPC sending: $msg', name: kRpcIpcLogPrefix);
|
||||||
|
final packet = ActivityRpcServer.encodeIpcPacket(IpcTypes.frame, msg);
|
||||||
|
socket.add(packet);
|
||||||
|
}
|
||||||
|
|
||||||
|
void sendPong(dynamic data) {
|
||||||
|
final packet = ActivityRpcServer.encodeIpcPacket(IpcTypes.pong, data ?? {});
|
||||||
|
socket.add(packet);
|
||||||
|
}
|
||||||
|
|
||||||
|
void close() {
|
||||||
|
socket.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
void closeWithCode(int code, [String message = '']) {
|
||||||
|
final closeData = {'code': code, 'message': message};
|
||||||
|
final packet = ActivityRpcServer.encodeIpcPacket(IpcTypes.close, closeData);
|
||||||
|
socket.add(packet);
|
||||||
|
socket.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
List<_IpcPacket> readPackets() {
|
||||||
|
final packets = <_IpcPacket>[];
|
||||||
|
|
||||||
|
while (_buffer.length >= 8) {
|
||||||
|
final buffer = Uint8List.fromList(_buffer);
|
||||||
|
final byteData = ByteData.view(buffer.buffer);
|
||||||
|
|
||||||
|
final type = byteData.getInt32(0, Endian.little);
|
||||||
|
final dataSize = byteData.getInt32(4, Endian.little);
|
||||||
|
|
||||||
|
if (_buffer.length < 8 + dataSize) break;
|
||||||
|
|
||||||
|
final dataBytes = _buffer.sublist(8, 8 + dataSize);
|
||||||
|
final jsonStr = utf8.decode(dataBytes);
|
||||||
|
final jsonData = jsonDecode(jsonStr);
|
||||||
|
|
||||||
|
packets.add(_IpcPacket(type, jsonData));
|
||||||
|
|
||||||
|
_buffer.removeRange(0, 8 + dataSize);
|
||||||
|
}
|
||||||
|
|
||||||
|
return packets;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// IPC Packet structure
|
||||||
|
class _IpcPacket {
|
||||||
|
final int type;
|
||||||
|
final Map<String, dynamic> data;
|
||||||
|
|
||||||
|
_IpcPacket(this.type, this.data);
|
||||||
|
}
|
||||||
|
|
||||||
|
// State management for server status and activities
|
||||||
|
class ServerState {
|
||||||
|
final String status;
|
||||||
|
final List<String> activities;
|
||||||
|
|
||||||
|
ServerState({required this.status, this.activities = const []});
|
||||||
|
|
||||||
|
ServerState copyWith({String? status, List<String>? activities}) {
|
||||||
|
return ServerState(
|
||||||
|
status: status ?? this.status,
|
||||||
|
activities: activities ?? this.activities,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class ServerStateNotifier extends StateNotifier<ServerState> {
|
||||||
|
final ActivityRpcServer server;
|
||||||
|
|
||||||
|
ServerStateNotifier(this.server)
|
||||||
|
: super(ServerState(status: 'Server not started'));
|
||||||
|
|
||||||
|
Future<void> start() async {
|
||||||
|
// Only start server on desktop platforms
|
||||||
|
if (!Platform.isAndroid && !Platform.isIOS && !kIsWeb) {
|
||||||
|
try {
|
||||||
|
await server.start();
|
||||||
|
state = state.copyWith(status: 'Server running');
|
||||||
|
} catch (e) {
|
||||||
|
state = state.copyWith(status: 'Server failed: $e');
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
state = state.copyWith(status: 'Server disabled on mobile/web');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void updateStatus(String status) {
|
||||||
|
state = state.copyWith(status: status);
|
||||||
|
}
|
||||||
|
|
||||||
|
void addActivity(String activity) {
|
||||||
|
state = state.copyWith(activities: [...state.activities, activity]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Providers
|
||||||
|
final rpcServerStateProvider =
|
||||||
|
StateNotifierProvider<ServerStateNotifier, ServerState>((ref) {
|
||||||
|
final server = ActivityRpcServer({});
|
||||||
|
final notifier = ServerStateNotifier(server);
|
||||||
|
server.updateHandlers({
|
||||||
|
'connection': (socket) {
|
||||||
|
final clientId =
|
||||||
|
socket is _WsSocketWrapper
|
||||||
|
? socket.clientId
|
||||||
|
: (socket as _IpcSocketWrapper).clientId;
|
||||||
|
notifier.updateStatus('Client connected (ID: $clientId)');
|
||||||
|
// Send READY event
|
||||||
|
socket.send({
|
||||||
|
'cmd': 'DISPATCH',
|
||||||
|
'data': {
|
||||||
|
'v': 1,
|
||||||
|
'config': {
|
||||||
|
'cdn_host': 'fake.cdn',
|
||||||
|
'api_endpoint': '//fake.api',
|
||||||
|
'environment': 'dev',
|
||||||
|
},
|
||||||
|
'user': {
|
||||||
|
'id': 'fake_user_id',
|
||||||
|
'username': 'FakeUser',
|
||||||
|
'discriminator': '0001',
|
||||||
|
'avatar': null,
|
||||||
|
'bot': false,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
'evt': 'READY',
|
||||||
|
'nonce': '12345', // Should be dynamic
|
||||||
|
});
|
||||||
|
},
|
||||||
|
'message': (socket, dynamic data) async {
|
||||||
|
if (data['cmd'] == 'SET_ACTIVITY') {
|
||||||
|
notifier.addActivity(
|
||||||
|
'Activity: ${data['args']['activity']['details'] ?? 'Unknown'}',
|
||||||
|
);
|
||||||
|
// Call setRemoteActivityStatus
|
||||||
|
final label = data['args']['activity']['details'] ?? 'Unknown';
|
||||||
|
final appId = socket.clientId;
|
||||||
|
try {
|
||||||
|
await setRemoteActivityStatus(ref, label, appId);
|
||||||
|
} catch (e) {
|
||||||
|
developer.log(
|
||||||
|
'Failed to set remote activity status: $e',
|
||||||
|
name: kRpcLogPrefix,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
// Echo back success
|
||||||
|
socket.send({
|
||||||
|
'cmd': 'SET_ACTIVITY',
|
||||||
|
'data': data['args']['activity'],
|
||||||
|
'evt': null,
|
||||||
|
'nonce': data['nonce'],
|
||||||
|
});
|
||||||
|
}
|
||||||
|
},
|
||||||
|
'close': (socket) async {
|
||||||
|
notifier.updateStatus('Client disconnected');
|
||||||
|
final appId = socket.clientId;
|
||||||
|
try {
|
||||||
|
await unsetRemoteActivityStatus(ref, appId);
|
||||||
|
} catch (e) {
|
||||||
|
developer.log(
|
||||||
|
'Failed to unset remote activity status: $e',
|
||||||
|
name: kRpcLogPrefix,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
});
|
||||||
|
return notifier;
|
||||||
|
});
|
||||||
|
|
||||||
|
final rpcServerProvider = Provider<ActivityRpcServer>((ref) {
|
||||||
|
final notifier = ref.watch(rpcServerStateProvider.notifier);
|
||||||
|
return notifier.server;
|
||||||
|
});
|
||||||
|
|
||||||
|
Future<void> setRemoteActivityStatus(
|
||||||
|
Ref ref,
|
||||||
|
String label,
|
||||||
|
String appId,
|
||||||
|
) async {
|
||||||
|
final apiClient = ref.read(apiClientProvider);
|
||||||
|
await apiClient.post(
|
||||||
|
'/id/accounts/me/statuses',
|
||||||
|
data: {
|
||||||
|
'is_invisible': false,
|
||||||
|
'is_not_disturb': false,
|
||||||
|
'is_automated': true,
|
||||||
|
'label': label,
|
||||||
|
'app_identifier': appId,
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> unsetRemoteActivityStatus(Ref ref, String appId) async {
|
||||||
|
final apiClient = ref.read(apiClientProvider);
|
||||||
|
await apiClient.delete(
|
||||||
|
'/id/accounts/me/statuses',
|
||||||
|
queryParameters: {'app': appId},
|
||||||
|
);
|
||||||
|
}
|
@@ -789,11 +789,8 @@ class LevelingScreen extends HookConsumerWidget {
|
|||||||
if (context.mounted) showLoadingModal(context);
|
if (context.mounted) showLoadingModal(context);
|
||||||
|
|
||||||
if (paidOrder != null) {
|
if (paidOrder != null) {
|
||||||
await client.post(
|
// Wait for server to handle order
|
||||||
'/id/subscriptions/order/handle',
|
await Future.delayed(const Duration(seconds: 1));
|
||||||
data: {'order_id': paidOrder.id},
|
|
||||||
);
|
|
||||||
|
|
||||||
ref.invalidate(accountStellarSubscriptionProvider);
|
ref.invalidate(accountStellarSubscriptionProvider);
|
||||||
ref.read(userInfoProvider.notifier).fetchUser();
|
ref.read(userInfoProvider.notifier).fetchUser();
|
||||||
if (context.mounted) {
|
if (context.mounted) {
|
||||||
|
@@ -4,6 +4,7 @@ import 'package:easy_localization/easy_localization.dart';
|
|||||||
import 'package:flutter/foundation.dart';
|
import 'package:flutter/foundation.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter/services.dart';
|
import 'package:flutter/services.dart';
|
||||||
|
import 'package:gap/gap.dart';
|
||||||
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||||
import 'package:island/models/auth.dart';
|
import 'package:island/models/auth.dart';
|
||||||
import 'package:island/models/account.dart';
|
import 'package:island/models/account.dart';
|
||||||
@@ -479,6 +480,7 @@ class AccountSettingsScreen extends HookConsumerWidget {
|
|||||||
);
|
);
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
|
const Gap(8),
|
||||||
]
|
]
|
||||||
: null,
|
: null,
|
||||||
),
|
),
|
||||||
|
@@ -62,6 +62,32 @@ class ContactMethodSheet extends HookConsumerWidget {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Future<void> makeContactMethodPublic() async {
|
||||||
|
try {
|
||||||
|
showLoadingModal(context);
|
||||||
|
final client = ref.read(apiClientProvider);
|
||||||
|
await client.post('/id/accounts/me/contacts/${contact.id}/public');
|
||||||
|
if (context.mounted) Navigator.pop(context, true);
|
||||||
|
} catch (err) {
|
||||||
|
showErrorAlert(err);
|
||||||
|
} finally {
|
||||||
|
if (context.mounted) hideLoadingModal(context);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> makeContactMethodPrivate() async {
|
||||||
|
try {
|
||||||
|
showLoadingModal(context);
|
||||||
|
final client = ref.read(apiClientProvider);
|
||||||
|
await client.delete('/id/accounts/me/contacts/${contact.id}/public');
|
||||||
|
if (context.mounted) Navigator.pop(context, true);
|
||||||
|
} catch (err) {
|
||||||
|
showErrorAlert(err);
|
||||||
|
} finally {
|
||||||
|
if (context.mounted) hideLoadingModal(context);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return SheetScaffold(
|
return SheetScaffold(
|
||||||
titleText: 'contactMethod'.tr(),
|
titleText: 'contactMethod'.tr(),
|
||||||
child: Column(
|
child: Column(
|
||||||
@@ -111,6 +137,27 @@ class ContactMethodSheet extends HookConsumerWidget {
|
|||||||
backgroundColor: Theme.of(context).colorScheme.tertiary,
|
backgroundColor: Theme.of(context).colorScheme.tertiary,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
if (contact.isPublic)
|
||||||
|
Padding(
|
||||||
|
padding: const EdgeInsets.only(left: 8.0),
|
||||||
|
child: Badge(
|
||||||
|
label: Text('contactMethodPublic'.tr()),
|
||||||
|
textColor: Theme.of(context).colorScheme.onPrimary,
|
||||||
|
backgroundColor: Theme.of(context).colorScheme.primary,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
if (!contact.isPublic)
|
||||||
|
Padding(
|
||||||
|
padding: const EdgeInsets.only(left: 8.0),
|
||||||
|
child: Badge(
|
||||||
|
label: Text('contactMethodPrivate'.tr()),
|
||||||
|
textColor: Theme.of(context).colorScheme.onSurface,
|
||||||
|
backgroundColor:
|
||||||
|
Theme.of(
|
||||||
|
context,
|
||||||
|
).colorScheme.surfaceContainerHighest,
|
||||||
|
),
|
||||||
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
@@ -130,6 +177,20 @@ class ContactMethodSheet extends HookConsumerWidget {
|
|||||||
onTap: setContactMethodAsPrimary,
|
onTap: setContactMethodAsPrimary,
|
||||||
contentPadding: EdgeInsets.symmetric(horizontal: 20),
|
contentPadding: EdgeInsets.symmetric(horizontal: 20),
|
||||||
),
|
),
|
||||||
|
if (contact.verifiedAt != null && !contact.isPublic)
|
||||||
|
ListTile(
|
||||||
|
leading: const Icon(Symbols.public),
|
||||||
|
title: Text('contactMethodMakePublic').tr(),
|
||||||
|
onTap: makeContactMethodPublic,
|
||||||
|
contentPadding: EdgeInsets.symmetric(horizontal: 20),
|
||||||
|
),
|
||||||
|
if (contact.verifiedAt != null && contact.isPublic)
|
||||||
|
ListTile(
|
||||||
|
leading: const Icon(Symbols.visibility_off),
|
||||||
|
title: Text('contactMethodMakePrivate').tr(),
|
||||||
|
onTap: makeContactMethodPrivate,
|
||||||
|
contentPadding: EdgeInsets.symmetric(horizontal: 20),
|
||||||
|
),
|
||||||
ListTile(
|
ListTile(
|
||||||
leading: const Icon(Symbols.delete),
|
leading: const Icon(Symbols.delete),
|
||||||
title: Text('contactMethodDelete').tr(),
|
title: Text('contactMethodDelete').tr(),
|
||||||
|
@@ -321,6 +321,59 @@ class _AccountProfileLinks extends StatelessWidget {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class _AccountProfileContacts extends StatelessWidget {
|
||||||
|
final SnAccount data;
|
||||||
|
|
||||||
|
const _AccountProfileContacts({required this.data});
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
final publicContacts = data.contacts.where((c) => c.isPublic).toList();
|
||||||
|
if (publicContacts.isEmpty) return const SizedBox.shrink();
|
||||||
|
|
||||||
|
return Card(
|
||||||
|
child: Column(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
Text(
|
||||||
|
'contactMethod',
|
||||||
|
).tr().bold().padding(horizontal: 24, top: 12, bottom: 4),
|
||||||
|
for (final contact in publicContacts)
|
||||||
|
ListTile(
|
||||||
|
title: Text(contact.content),
|
||||||
|
subtitle: Text(switch (contact.type) {
|
||||||
|
0 => 'contactMethodTypeEmail'.tr(),
|
||||||
|
1 => 'contactMethodTypePhone'.tr(),
|
||||||
|
_ => 'contactMethodTypeAddress'.tr(),
|
||||||
|
}),
|
||||||
|
leading: Icon(switch (contact.type) {
|
||||||
|
0 => Symbols.mail,
|
||||||
|
1 => Symbols.phone,
|
||||||
|
_ => Symbols.home,
|
||||||
|
}),
|
||||||
|
contentPadding: EdgeInsets.symmetric(horizontal: 24),
|
||||||
|
trailing: const Icon(Symbols.chevron_right),
|
||||||
|
shape: RoundedRectangleBorder(
|
||||||
|
borderRadius: const BorderRadius.all(Radius.circular(8)),
|
||||||
|
),
|
||||||
|
onTap: () {
|
||||||
|
switch (contact.type) {
|
||||||
|
case 0:
|
||||||
|
launchUrlString('mailto:${contact.content}');
|
||||||
|
case 1:
|
||||||
|
launchUrlString('tel:${contact.content}');
|
||||||
|
default:
|
||||||
|
// For address, maybe copy to clipboard or do nothing
|
||||||
|
Clipboard.setData(ClipboardData(text: contact.content));
|
||||||
|
}
|
||||||
|
},
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
class _AccountPublisherList extends StatelessWidget {
|
class _AccountPublisherList extends StatelessWidget {
|
||||||
final List<SnPublisher> publishers;
|
final List<SnPublisher> publishers;
|
||||||
|
|
||||||
@@ -792,6 +845,10 @@ class AccountProfileScreen extends HookConsumerWidget {
|
|||||||
SliverToBoxAdapter(
|
SliverToBoxAdapter(
|
||||||
child: _AccountProfileLinks(data: data),
|
child: _AccountProfileLinks(data: data),
|
||||||
),
|
),
|
||||||
|
if (data.contacts.any((c) => c.isPublic))
|
||||||
|
SliverToBoxAdapter(
|
||||||
|
child: _AccountProfileContacts(data: data),
|
||||||
|
),
|
||||||
SliverToBoxAdapter(
|
SliverToBoxAdapter(
|
||||||
child: _AccountProfileDetail(data: data),
|
child: _AccountProfileDetail(data: data),
|
||||||
),
|
),
|
||||||
@@ -916,6 +973,12 @@ class AccountProfileScreen extends HookConsumerWidget {
|
|||||||
data: data,
|
data: data,
|
||||||
).padding(horizontal: 4),
|
).padding(horizontal: 4),
|
||||||
),
|
),
|
||||||
|
if (data.contacts.any((c) => c.isPublic))
|
||||||
|
SliverToBoxAdapter(
|
||||||
|
child: _AccountProfileContacts(
|
||||||
|
data: data,
|
||||||
|
).padding(horizontal: 4),
|
||||||
|
),
|
||||||
SliverToBoxAdapter(
|
SliverToBoxAdapter(
|
||||||
child: _AccountPublisherList(
|
child: _AccountPublisherList(
|
||||||
publishers: accountPublishers.value ?? [],
|
publishers: accountPublishers.value ?? [],
|
||||||
|
@@ -727,7 +727,11 @@ class _ChatMemberListSheet extends HookConsumerWidget {
|
|||||||
children: [
|
children: [
|
||||||
Flexible(child: Text(member.account.nick)),
|
Flexible(child: Text(member.account.nick)),
|
||||||
if (member.status != null)
|
if (member.status != null)
|
||||||
AccountStatusLabel(status: member.status!),
|
AccountStatusLabel(
|
||||||
|
status: member.status!,
|
||||||
|
maxLines: 1,
|
||||||
|
overflow: TextOverflow.ellipsis,
|
||||||
|
),
|
||||||
if (member.joinedAt == null)
|
if (member.joinedAt == null)
|
||||||
const Icon(Symbols.pending_actions, size: 20),
|
const Icon(Symbols.pending_actions, size: 20),
|
||||||
],
|
],
|
||||||
|
@@ -1,3 +1,4 @@
|
|||||||
|
import 'package:easy_localization/easy_localization.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:gap/gap.dart';
|
import 'package:gap/gap.dart';
|
||||||
import 'package:go_router/go_router.dart';
|
import 'package:go_router/go_router.dart';
|
||||||
@@ -10,6 +11,7 @@ import 'package:material_symbols_icons/symbols.dart';
|
|||||||
import 'package:riverpod_annotation/riverpod_annotation.dart';
|
import 'package:riverpod_annotation/riverpod_annotation.dart';
|
||||||
import 'package:riverpod_paging_utils/riverpod_paging_utils.dart';
|
import 'package:riverpod_paging_utils/riverpod_paging_utils.dart';
|
||||||
import 'package:island/widgets/extended_refresh_indicator.dart';
|
import 'package:island/widgets/extended_refresh_indicator.dart';
|
||||||
|
import 'package:styled_widget/styled_widget.dart';
|
||||||
|
|
||||||
part 'poll_list.g.dart';
|
part 'poll_list.g.dart';
|
||||||
|
|
||||||
@@ -117,14 +119,14 @@ class CreatorPollListScreen extends HookConsumerWidget {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class _CreatorPollItem extends StatelessWidget {
|
class _CreatorPollItem extends HookConsumerWidget {
|
||||||
final String pubName;
|
final String pubName;
|
||||||
const _CreatorPollItem({required this.pollWithStats, required this.pubName});
|
const _CreatorPollItem({required this.pollWithStats, required this.pubName});
|
||||||
|
|
||||||
final SnPollWithStats pollWithStats;
|
final SnPollWithStats pollWithStats;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context, WidgetRef ref) {
|
||||||
final theme = Theme.of(context);
|
final theme = Theme.of(context);
|
||||||
final ended = pollWithStats.endedAt;
|
final ended = pollWithStats.endedAt;
|
||||||
final endedText =
|
final endedText =
|
||||||
@@ -167,7 +169,7 @@ class _CreatorPollItem extends StatelessWidget {
|
|||||||
children: [
|
children: [
|
||||||
const Icon(Symbols.edit),
|
const Icon(Symbols.edit),
|
||||||
const Gap(16),
|
const Gap(16),
|
||||||
Text('Edit'),
|
Text('edit').tr(),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
onTap: () {
|
onTap: () {
|
||||||
@@ -177,6 +179,61 @@ class _CreatorPollItem extends StatelessWidget {
|
|||||||
);
|
);
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
|
PopupMenuItem(
|
||||||
|
child: Row(
|
||||||
|
children: [
|
||||||
|
const Icon(Symbols.delete, color: Colors.red),
|
||||||
|
const Gap(16),
|
||||||
|
Text('delete').tr().textColor(Colors.red),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
onTap: () async {
|
||||||
|
final confirmed = await showDialog<bool>(
|
||||||
|
context: context,
|
||||||
|
builder:
|
||||||
|
(context) => AlertDialog(
|
||||||
|
title: Text('Delete Poll'),
|
||||||
|
content: Text(
|
||||||
|
'Are you sure you want to delete this poll?',
|
||||||
|
),
|
||||||
|
actions: [
|
||||||
|
TextButton(
|
||||||
|
onPressed:
|
||||||
|
() => Navigator.of(context).pop(false),
|
||||||
|
child: Text('Cancel'),
|
||||||
|
),
|
||||||
|
TextButton(
|
||||||
|
onPressed:
|
||||||
|
() => Navigator.of(context).pop(true),
|
||||||
|
child: Text('Delete'),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
if (confirmed == true) {
|
||||||
|
try {
|
||||||
|
final client = ref.read(apiClientProvider);
|
||||||
|
await client.delete(
|
||||||
|
'/sphere/polls/${pollWithStats.id}',
|
||||||
|
);
|
||||||
|
ref.invalidate(pollListNotifierProvider(pubName));
|
||||||
|
if (context.mounted) {
|
||||||
|
ScaffoldMessenger.of(context).showSnackBar(
|
||||||
|
SnackBar(
|
||||||
|
content: Text('Poll deleted successfully'),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
if (context.mounted) {
|
||||||
|
ScaffoldMessenger.of(context).showSnackBar(
|
||||||
|
SnackBar(content: Text('Failed to delete poll')),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
onTap: () {
|
onTap: () {
|
||||||
|
@@ -10,6 +10,7 @@ import 'package:island/pods/network.dart';
|
|||||||
import 'package:island/widgets/alert.dart';
|
import 'package:island/widgets/alert.dart';
|
||||||
import 'package:island/models/poll.dart';
|
import 'package:island/models/poll.dart';
|
||||||
import 'package:island/widgets/app_scaffold.dart';
|
import 'package:island/widgets/app_scaffold.dart';
|
||||||
|
import 'package:styled_widget/styled_widget.dart';
|
||||||
import 'package:uuid/uuid.dart';
|
import 'package:uuid/uuid.dart';
|
||||||
import 'package:easy_localization/easy_localization.dart';
|
import 'package:easy_localization/easy_localization.dart';
|
||||||
|
|
||||||
@@ -516,8 +517,7 @@ class PollEditorScreen extends ConsumerWidget {
|
|||||||
if (model.questions.isEmpty)
|
if (model.questions.isEmpty)
|
||||||
_EmptyState(
|
_EmptyState(
|
||||||
title: 'pollNoQuestionsYet'.tr(),
|
title: 'pollNoQuestionsYet'.tr(),
|
||||||
subtitle:
|
subtitle: 'pollNoQuestionsHint'.tr(),
|
||||||
'pollNoQuestionsHint'.tr(),
|
|
||||||
)
|
)
|
||||||
else
|
else
|
||||||
ReorderableListView.builder(
|
ReorderableListView.builder(
|
||||||
@@ -579,24 +579,32 @@ class PollEditorScreen extends ConsumerWidget {
|
|||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
Row(
|
Material(
|
||||||
children: [
|
elevation: 2,
|
||||||
OutlinedButton.icon(
|
color: Theme.of(context).colorScheme.surfaceContainer,
|
||||||
onPressed: () {
|
child: Row(
|
||||||
Navigator.of(context).maybePop();
|
children: [
|
||||||
},
|
OutlinedButton.icon(
|
||||||
icon: const Icon(Icons.close),
|
onPressed: () {
|
||||||
label: Text('cancel'.tr()),
|
Navigator.of(context).maybePop();
|
||||||
),
|
},
|
||||||
const Spacer(),
|
icon: const Icon(Icons.close),
|
||||||
FilledButton.icon(
|
label: Text('cancel'.tr()),
|
||||||
onPressed: () {
|
),
|
||||||
_submitPoll(context, ref);
|
const Spacer(),
|
||||||
},
|
FilledButton.icon(
|
||||||
icon: const Icon(Icons.cloud_upload_outlined),
|
onPressed: () {
|
||||||
label: Text(model.id == null ? 'create'.tr() : 'update'.tr()),
|
_submitPoll(context, ref);
|
||||||
),
|
},
|
||||||
],
|
icon: const Icon(Icons.cloud_upload_outlined),
|
||||||
|
label: Text(model.id == null ? 'create'.tr() : 'update'.tr()),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
).padding(
|
||||||
|
horizontal: 24,
|
||||||
|
top: 16,
|
||||||
|
bottom: MediaQuery.of(context).padding.bottom + 16,
|
||||||
|
),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
@@ -1049,7 +1057,9 @@ class _TextAnswerPreview extends StatelessWidget {
|
|||||||
maxLines: long ? 4 : 1,
|
maxLines: long ? 4 : 1,
|
||||||
decoration: InputDecoration(
|
decoration: InputDecoration(
|
||||||
labelText:
|
labelText:
|
||||||
long ? 'pollLongTextAnswerPreview'.tr() : 'pollShortTextAnswerPreview'.tr(),
|
long
|
||||||
|
? 'pollLongTextAnswerPreview'.tr()
|
||||||
|
: 'pollShortTextAnswerPreview'.tr(),
|
||||||
border: const OutlineInputBorder(
|
border: const OutlineInputBorder(
|
||||||
borderRadius: BorderRadius.all(Radius.circular(16)),
|
borderRadius: BorderRadius.all(Radius.circular(16)),
|
||||||
),
|
),
|
||||||
@@ -1083,9 +1093,15 @@ class _EmptyState extends StatelessWidget {
|
|||||||
child: Column(
|
child: Column(
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
children: [
|
children: [
|
||||||
Text('pollNoQuestionsYet'.tr(), style: Theme.of(context).textTheme.titleMedium),
|
Text(
|
||||||
|
'pollNoQuestionsYet'.tr(),
|
||||||
|
style: Theme.of(context).textTheme.titleMedium,
|
||||||
|
),
|
||||||
const Gap(4),
|
const Gap(4),
|
||||||
Text('pollNoQuestionsHint'.tr(), style: Theme.of(context).textTheme.bodyMedium),
|
Text(
|
||||||
|
'pollNoQuestionsHint'.tr(),
|
||||||
|
style: Theme.of(context).textTheme.bodyMedium,
|
||||||
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
@@ -128,14 +128,6 @@ class ArticleComposeScreen extends HookConsumerWidget {
|
|||||||
return null;
|
return null;
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
// Auto-save cleanup
|
|
||||||
useEffect(() {
|
|
||||||
return () {
|
|
||||||
state.stopAutoSave();
|
|
||||||
ComposeLogic.dispose(state);
|
|
||||||
};
|
|
||||||
}, [state]);
|
|
||||||
|
|
||||||
// Helper methods
|
// Helper methods
|
||||||
void showSettingsSheet() {
|
void showSettingsSheet() {
|
||||||
showModalBottomSheet(
|
showModalBottomSheet(
|
||||||
@@ -182,6 +174,12 @@ class ArticleComposeScreen extends HookConsumerWidget {
|
|||||||
MarkdownTextContent(
|
MarkdownTextContent(
|
||||||
content: contentValue.text,
|
content: contentValue.text,
|
||||||
textStyle: theme.textTheme.bodyMedium,
|
textStyle: theme.textTheme.bodyMedium,
|
||||||
|
attachments:
|
||||||
|
state.attachments.value
|
||||||
|
.where((e) => e.isOnCloud)
|
||||||
|
.map((e) => e.data)
|
||||||
|
.cast<SnCloudFile>()
|
||||||
|
.toList(),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
@@ -268,7 +266,7 @@ class ArticleComposeScreen extends HookConsumerWidget {
|
|||||||
child: KeyboardListener(
|
child: KeyboardListener(
|
||||||
focusNode: FocusNode(),
|
focusNode: FocusNode(),
|
||||||
onKeyEvent:
|
onKeyEvent:
|
||||||
(event) => _handleKeyPress(
|
(event) => ComposeLogic.handleKeyPress(
|
||||||
event,
|
event,
|
||||||
state,
|
state,
|
||||||
ref,
|
ref,
|
||||||
@@ -511,38 +509,4 @@ class ArticleComposeScreen extends HookConsumerWidget {
|
|||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Helper method to handle keyboard shortcuts
|
|
||||||
void _handleKeyPress(
|
|
||||||
KeyEvent event,
|
|
||||||
ComposeState state,
|
|
||||||
WidgetRef ref,
|
|
||||||
BuildContext context, {
|
|
||||||
SnPost? originalPost,
|
|
||||||
}) {
|
|
||||||
if (event is! RawKeyDownEvent) return;
|
|
||||||
|
|
||||||
final isPaste = event.logicalKey == LogicalKeyboardKey.keyV;
|
|
||||||
final isSave = event.logicalKey == LogicalKeyboardKey.keyS;
|
|
||||||
final isModifierPressed =
|
|
||||||
HardwareKeyboard.instance.isMetaPressed ||
|
|
||||||
HardwareKeyboard.instance.isControlPressed;
|
|
||||||
final isSubmit = event.logicalKey == LogicalKeyboardKey.enter;
|
|
||||||
|
|
||||||
if (isPaste && isModifierPressed) {
|
|
||||||
ComposeLogic.handlePaste(state);
|
|
||||||
} else if (isSave && isModifierPressed) {
|
|
||||||
ComposeLogic.saveDraft(ref, state);
|
|
||||||
ComposeLogic.saveDraft(ref, state);
|
|
||||||
} else if (isSubmit && isModifierPressed && !state.submitting.value) {
|
|
||||||
ComposeLogic.performAction(
|
|
||||||
ref,
|
|
||||||
state,
|
|
||||||
context,
|
|
||||||
originalPost: originalPost,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Helper method to save article draft
|
|
||||||
}
|
}
|
||||||
|
@@ -13,6 +13,7 @@ import 'package:island/widgets/alert.dart';
|
|||||||
import 'package:island/widgets/app_scaffold.dart';
|
import 'package:island/widgets/app_scaffold.dart';
|
||||||
import 'package:island/widgets/extended_refresh_indicator.dart';
|
import 'package:island/widgets/extended_refresh_indicator.dart';
|
||||||
import 'package:island/widgets/post/post_item.dart';
|
import 'package:island/widgets/post/post_item.dart';
|
||||||
|
import 'package:island/widgets/post/post_award_history_sheet.dart';
|
||||||
import 'package:island/widgets/post/post_pin_sheet.dart';
|
import 'package:island/widgets/post/post_pin_sheet.dart';
|
||||||
import 'package:island/widgets/post/post_quick_reply.dart';
|
import 'package:island/widgets/post/post_quick_reply.dart';
|
||||||
import 'package:island/widgets/post/post_replies.dart';
|
import 'package:island/widgets/post/post_replies.dart';
|
||||||
@@ -77,6 +78,22 @@ class PostActionButtons extends HookConsumerWidget {
|
|||||||
final isAuthor =
|
final isAuthor =
|
||||||
user.value != null && user.value?.id == post.publisher.accountId;
|
user.value != null && user.value?.id == post.publisher.accountId;
|
||||||
|
|
||||||
|
String formatScore(int score) {
|
||||||
|
if (score >= 1000000) {
|
||||||
|
double value = score / 1000000;
|
||||||
|
return value % 1 == 0
|
||||||
|
? '${value.toInt()}m'
|
||||||
|
: '${value.toStringAsFixed(1)}m';
|
||||||
|
} else if (score >= 1000) {
|
||||||
|
double value = score / 1000;
|
||||||
|
return value % 1 == 0
|
||||||
|
? '${value.toInt()}k'
|
||||||
|
: '${value.toStringAsFixed(1)}k';
|
||||||
|
} else {
|
||||||
|
return score.toString();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
final actions = <Widget>[];
|
final actions = <Widget>[];
|
||||||
|
|
||||||
const kButtonHeight = 40.0;
|
const kButtonHeight = 40.0;
|
||||||
@@ -254,6 +271,24 @@ class PostActionButtons extends HookConsumerWidget {
|
|||||||
),
|
),
|
||||||
];
|
];
|
||||||
|
|
||||||
|
actions.add(
|
||||||
|
FilledButton.tonalIcon(
|
||||||
|
onPressed: () {},
|
||||||
|
onLongPress: () {
|
||||||
|
showModalBottomSheet(
|
||||||
|
context: context,
|
||||||
|
isScrollControlled: true,
|
||||||
|
builder: (context) => PostAwardHistorySheet(postId: post.id),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
icon: const Icon(Symbols.star),
|
||||||
|
label:
|
||||||
|
post.awardedScore > 0
|
||||||
|
? Text('${formatScore(post.awardedScore)} pts')
|
||||||
|
: Text('award').tr(),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
actions.add(
|
actions.add(
|
||||||
Row(
|
Row(
|
||||||
mainAxisSize: MainAxisSize.min,
|
mainAxisSize: MainAxisSize.min,
|
||||||
|
@@ -277,8 +277,6 @@ class PostSearchScreen extends HookConsumerWidget {
|
|||||||
Text('pinned'.tr()),
|
Text('pinned'.tr()),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
// TODO: Add dropdown for type selection
|
|
||||||
// TODO: Add multi-select for categories and tags
|
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
@@ -668,7 +668,13 @@ class _RealmMemberListSheet extends HookConsumerWidget {
|
|||||||
title: Row(
|
title: Row(
|
||||||
spacing: 6,
|
spacing: 6,
|
||||||
children: [
|
children: [
|
||||||
Flexible(child: Text(member.account!.nick)),
|
Flexible(
|
||||||
|
child: Text(
|
||||||
|
member.account!.nick,
|
||||||
|
maxLines: 1,
|
||||||
|
overflow: TextOverflow.ellipsis,
|
||||||
|
),
|
||||||
|
),
|
||||||
if (member.status != null)
|
if (member.status != null)
|
||||||
AccountStatusLabel(status: member.status!),
|
AccountStatusLabel(status: member.status!),
|
||||||
if (member.joinedAt == null)
|
if (member.joinedAt == null)
|
||||||
|
@@ -39,8 +39,13 @@ class ComposeStorageNotifier extends _$ComposeStorageNotifier {
|
|||||||
await database.addPostDraft(
|
await database.addPostDraft(
|
||||||
PostDraftsCompanion(
|
PostDraftsCompanion(
|
||||||
id: Value(updatedDraft.id),
|
id: Value(updatedDraft.id),
|
||||||
post: Value(jsonEncode(updatedDraft.toJson())),
|
title: Value(updatedDraft.title),
|
||||||
|
description: Value(updatedDraft.description),
|
||||||
|
content: Value(updatedDraft.content),
|
||||||
|
visibility: Value(updatedDraft.visibility),
|
||||||
|
type: Value(updatedDraft.type),
|
||||||
lastModified: Value(updatedDraft.updatedAt ?? DateTime.now()),
|
lastModified: Value(updatedDraft.updatedAt ?? DateTime.now()),
|
||||||
|
postData: Value(jsonEncode(updatedDraft.toJson())),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
|
@@ -7,7 +7,7 @@ part of 'compose_storage_db.dart';
|
|||||||
// **************************************************************************
|
// **************************************************************************
|
||||||
|
|
||||||
String _$composeStorageNotifierHash() =>
|
String _$composeStorageNotifierHash() =>
|
||||||
r'4ab4dce85d0a961f096dc3b11505f8f0964dee9d';
|
r'8baf17aa06b6f69641c20645ba8a3dfe01c97f8c';
|
||||||
|
|
||||||
/// See also [ComposeStorageNotifier].
|
/// See also [ComposeStorageNotifier].
|
||||||
@ProviderFor(ComposeStorageNotifier)
|
@ProviderFor(ComposeStorageNotifier)
|
||||||
|
@@ -3,6 +3,7 @@ import 'package:bitsdojo_window/bitsdojo_window.dart';
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_hooks/flutter_hooks.dart';
|
import 'package:flutter_hooks/flutter_hooks.dart';
|
||||||
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||||
|
import 'package:island/pods/activity_rpc.dart';
|
||||||
import 'package:island/pods/websocket.dart';
|
import 'package:island/pods/websocket.dart';
|
||||||
import 'package:island/screens/tray_manager.dart';
|
import 'package:island/screens/tray_manager.dart';
|
||||||
import 'package:island/services/notify.dart';
|
import 'package:island/services/notify.dart';
|
||||||
@@ -31,7 +32,10 @@ class AppWrapper extends HookConsumerWidget with TrayListener {
|
|||||||
|
|
||||||
TrayService.instance.initialize(this);
|
TrayService.instance.initialize(this);
|
||||||
|
|
||||||
|
ref.read(rpcServerStateProvider.notifier).start();
|
||||||
|
|
||||||
return () {
|
return () {
|
||||||
|
ref.read(rpcServerProvider).stop();
|
||||||
TrayService.instance.dispose(this);
|
TrayService.instance.dispose(this);
|
||||||
sharingService.dispose();
|
sharingService.dispose();
|
||||||
ntySubs?.cancel();
|
ntySubs?.cancel();
|
||||||
|
@@ -1,3 +1,4 @@
|
|||||||
|
import 'dart:async';
|
||||||
import 'dart:convert';
|
import 'dart:convert';
|
||||||
|
|
||||||
import 'package:dio/dio.dart';
|
import 'package:dio/dio.dart';
|
||||||
@@ -57,11 +58,21 @@ class CheckInWidget extends HookConsumerWidget {
|
|||||||
final todayResult = ref.watch(checkInResultTodayProvider);
|
final todayResult = ref.watch(checkInResultTodayProvider);
|
||||||
final nextNotableDay = ref.watch(nextNotableDayProvider);
|
final nextNotableDay = ref.watch(nextNotableDayProvider);
|
||||||
|
|
||||||
|
// Update time every second for live progress
|
||||||
|
final currentTime = useState(DateTime.now());
|
||||||
|
useEffect(() {
|
||||||
|
final timer = Timer.periodic(const Duration(seconds: 1), (_) {
|
||||||
|
currentTime.value = DateTime.now();
|
||||||
|
});
|
||||||
|
return timer.cancel;
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
final now = currentTime.value;
|
||||||
|
|
||||||
final userinfo = ref.watch(userInfoProvider);
|
final userinfo = ref.watch(userInfoProvider);
|
||||||
final isAdult = useMemoized(() {
|
final isAdult = useMemoized(() {
|
||||||
final birthday = userinfo.value?.profile.birthday;
|
final birthday = userinfo.value?.profile.birthday;
|
||||||
if (birthday == null) return false;
|
if (birthday == null) return false;
|
||||||
final now = DateTime.now();
|
|
||||||
final age =
|
final age =
|
||||||
now.year -
|
now.year -
|
||||||
birthday.year -
|
birthday.year -
|
||||||
@@ -72,6 +83,12 @@ class CheckInWidget extends HookConsumerWidget {
|
|||||||
return age >= 18;
|
return age >= 18;
|
||||||
}, [userinfo]);
|
}, [userinfo]);
|
||||||
|
|
||||||
|
final progress = (now.hour * 60.0 + now.minute) / (24 * 60);
|
||||||
|
final endOfDay = DateTime(now.year, now.month, now.day, 23, 59, 59);
|
||||||
|
final timeLeft = endOfDay.difference(now);
|
||||||
|
final timeLeftFormatted =
|
||||||
|
'${timeLeft.inHours.toString().padLeft(2, '0')}:${(timeLeft.inMinutes % 60).toString().padLeft(2, '0')}:${(timeLeft.inSeconds % 60).toString().padLeft(2, '0')}';
|
||||||
|
|
||||||
Future<void> checkIn({String? captchatTk}) async {
|
Future<void> checkIn({String? captchatTk}) async {
|
||||||
final client = ref.read(apiClientProvider);
|
final client = ref.read(apiClientProvider);
|
||||||
try {
|
try {
|
||||||
@@ -100,106 +117,102 @@ class CheckInWidget extends HookConsumerWidget {
|
|||||||
return Card(
|
return Card(
|
||||||
margin:
|
margin:
|
||||||
margin ?? EdgeInsets.only(left: 16, right: 16, top: 16, bottom: 8),
|
margin ?? EdgeInsets.only(left: 16, right: 16, top: 16, bottom: 8),
|
||||||
child: Column(
|
child: Row(
|
||||||
crossAxisAlignment: CrossAxisAlignment.center,
|
|
||||||
spacing: 8,
|
|
||||||
children: [
|
children: [
|
||||||
Column(
|
Expanded(
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
child: Column(
|
||||||
children: [
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
Row(
|
children: [
|
||||||
spacing: 8,
|
Row(
|
||||||
mainAxisSize: MainAxisSize.min,
|
spacing: 6,
|
||||||
crossAxisAlignment: CrossAxisAlignment.center,
|
mainAxisSize: MainAxisSize.min,
|
||||||
children: [
|
crossAxisAlignment: CrossAxisAlignment.center,
|
||||||
Icon(
|
children: [
|
||||||
switch (DateTime.now().weekday) {
|
Icon(
|
||||||
6 || 7 => Symbols.weekend,
|
switch (DateTime.now().weekday) {
|
||||||
_ => isAdult ? Symbols.work : Symbols.school,
|
6 || 7 => Symbols.weekend,
|
||||||
},
|
_ => isAdult ? Symbols.work : Symbols.school,
|
||||||
fill: 1,
|
},
|
||||||
size: 16,
|
fill: 1,
|
||||||
).padding(right: 2),
|
size: 16,
|
||||||
Text(DateFormat('EEE').format(DateTime.now()))
|
).padding(right: 2),
|
||||||
.fontSize(16)
|
Text(
|
||||||
.bold()
|
DateFormat('EEE').format(DateTime.now()),
|
||||||
.textColor(
|
).fontSize(16).bold(),
|
||||||
Theme.of(context).colorScheme.onSecondaryContainer,
|
Text(
|
||||||
|
DateFormat('MM/dd').format(DateTime.now()),
|
||||||
|
).fontSize(16),
|
||||||
|
Tooltip(
|
||||||
|
message: timeLeftFormatted,
|
||||||
|
child: SizedBox(
|
||||||
|
width: 20,
|
||||||
|
height: 20,
|
||||||
|
child: CircularProgressIndicator(
|
||||||
|
value: progress,
|
||||||
|
strokeWidth: 2,
|
||||||
|
),
|
||||||
),
|
),
|
||||||
Text(DateFormat('MM/dd').format(DateTime.now()))
|
|
||||||
.fontSize(12)
|
|
||||||
.textColor(
|
|
||||||
Theme.of(context).colorScheme.onSecondaryContainer,
|
|
||||||
)
|
|
||||||
.padding(top: 2),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
Row(
|
|
||||||
spacing: 5,
|
|
||||||
children: [
|
|
||||||
Text('notableDayNext')
|
|
||||||
.tr(args: [nextNotableDay.value?.localName ?? 'idk'])
|
|
||||||
.fontSize(12),
|
|
||||||
SlideCountdown(
|
|
||||||
decoration: const BoxDecoration(),
|
|
||||||
style: const TextStyle(fontSize: 12),
|
|
||||||
separatorStyle: const TextStyle(fontSize: 12),
|
|
||||||
padding: EdgeInsets.zero,
|
|
||||||
duration: nextNotableDay.value?.date.difference(
|
|
||||||
DateTime.now(),
|
|
||||||
),
|
),
|
||||||
),
|
],
|
||||||
],
|
),
|
||||||
),
|
Row(
|
||||||
],
|
spacing: 5,
|
||||||
).padding(horizontal: 16, top: 8),
|
children: [
|
||||||
const Divider(height: 1),
|
Text('notableDayNext')
|
||||||
Row(
|
.tr(args: [nextNotableDay.value?.localName ?? 'idk'])
|
||||||
children: [
|
.fontSize(12),
|
||||||
Expanded(
|
if (nextNotableDay.value != null)
|
||||||
child: AnimatedSwitcher(
|
SlideCountdown(
|
||||||
|
decoration: const BoxDecoration(),
|
||||||
|
style: const TextStyle(fontSize: 12),
|
||||||
|
separatorStyle: const TextStyle(fontSize: 12),
|
||||||
|
padding: EdgeInsets.zero,
|
||||||
|
duration: nextNotableDay.value?.date.difference(
|
||||||
|
DateTime.now(),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
const Gap(2),
|
||||||
|
AnimatedSwitcher(
|
||||||
duration: const Duration(milliseconds: 300),
|
duration: const Duration(milliseconds: 300),
|
||||||
child: todayResult.when(
|
child: todayResult.when(
|
||||||
data: (result) {
|
data: (result) {
|
||||||
if (result == null) return _CheckInNoneWidget();
|
if (result == null) {
|
||||||
return Column(
|
return Text('checkInNoneHint').tr().fontSize(11);
|
||||||
crossAxisAlignment: CrossAxisAlignment.stretch,
|
}
|
||||||
children: [
|
return Wrap(
|
||||||
Text(
|
alignment: WrapAlignment.start,
|
||||||
'checkInResultLevel${result.level}',
|
runAlignment: WrapAlignment.start,
|
||||||
).tr().fontSize(15).bold(),
|
children:
|
||||||
Wrap(
|
result.tips
|
||||||
children:
|
.map((e) {
|
||||||
result.tips
|
return Row(
|
||||||
.map((e) {
|
mainAxisSize: MainAxisSize.min,
|
||||||
return Row(
|
children: [
|
||||||
mainAxisSize: MainAxisSize.min,
|
Icon(
|
||||||
children: [
|
e.isPositive
|
||||||
Icon(
|
? Symbols.thumb_up
|
||||||
e.isPositive
|
: Symbols.thumb_down,
|
||||||
? Symbols.thumb_up
|
size: 12,
|
||||||
: Symbols.thumb_down,
|
),
|
||||||
size: 12,
|
const Gap(4),
|
||||||
),
|
Text(e.title).fontSize(11),
|
||||||
const Gap(4),
|
],
|
||||||
Text(e.title).fontSize(11),
|
);
|
||||||
],
|
})
|
||||||
);
|
.toList()
|
||||||
})
|
.expand(
|
||||||
.toList()
|
(widget) => [
|
||||||
.expand(
|
widget,
|
||||||
(widget) => [
|
Text(' · ').fontSize(11),
|
||||||
widget,
|
],
|
||||||
Text(' · ').fontSize(11),
|
)
|
||||||
],
|
.toList()
|
||||||
)
|
..removeLast(),
|
||||||
.toList()
|
|
||||||
..removeLast(),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
loading: () => _CheckInNoneWidget(),
|
loading: () => Text('checkInNoneHint').tr().fontSize(11),
|
||||||
error:
|
error:
|
||||||
(err, stack) => Column(
|
(err, stack) => Column(
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
@@ -209,9 +222,35 @@ class CheckInWidget extends HookConsumerWidget {
|
|||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
).alignment(Alignment.centerLeft),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Column(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||||
|
spacing: 3,
|
||||||
|
children: [
|
||||||
|
AnimatedSwitcher(
|
||||||
|
duration: const Duration(milliseconds: 300),
|
||||||
|
child: todayResult.when(
|
||||||
|
data: (result) {
|
||||||
|
return Text(
|
||||||
|
result == null
|
||||||
|
? 'checkInNone'
|
||||||
|
: 'checkInResultLevel${result.level}',
|
||||||
|
textAlign: TextAlign.start,
|
||||||
|
).tr().fontSize(15).bold();
|
||||||
|
},
|
||||||
|
loading: () => Text('checkInNone').tr().fontSize(15).bold(),
|
||||||
|
error: (err, stack) => Text('error').tr().fontSize(15).bold(),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
IconButton.outlined(
|
IconButton.outlined(
|
||||||
|
iconSize: 16,
|
||||||
|
visualDensity: const VisualDensity(
|
||||||
|
horizontal: -3,
|
||||||
|
vertical: -2,
|
||||||
|
),
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
if (todayResult.valueOrNull == null) {
|
if (todayResult.valueOrNull == null) {
|
||||||
checkIn();
|
checkIn();
|
||||||
@@ -238,24 +277,9 @@ class CheckInWidget extends HookConsumerWidget {
|
|||||||
),
|
),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
).padding(horizontal: 16, bottom: 12, top: 4),
|
),
|
||||||
],
|
],
|
||||||
),
|
).padding(horizontal: 16, vertical: 12),
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class _CheckInNoneWidget extends StatelessWidget {
|
|
||||||
const _CheckInNoneWidget();
|
|
||||||
|
|
||||||
@override
|
|
||||||
Widget build(BuildContext context) {
|
|
||||||
return Column(
|
|
||||||
crossAxisAlignment: CrossAxisAlignment.stretch,
|
|
||||||
children: [
|
|
||||||
Text('checkInNone').tr().fontSize(15).bold(),
|
|
||||||
Text('checkInNoneHint').tr().fontSize(11),
|
|
||||||
],
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -6,17 +6,21 @@ import 'package:flutter_platform_alert/flutter_platform_alert.dart';
|
|||||||
|
|
||||||
String _parseRemoteError(DioException err) {
|
String _parseRemoteError(DioException err) {
|
||||||
log('${err.requestOptions.method} ${err.requestOptions.uri} ${err.message}');
|
log('${err.requestOptions.method} ${err.requestOptions.uri} ${err.message}');
|
||||||
if (err.response?.data is String) return err.response?.data;
|
String? message;
|
||||||
if (err.response?.data?['errors'] != null) {
|
if (err.response?.data is String) {
|
||||||
|
message = err.response?.data;
|
||||||
|
} else if (err.response?.data?['errors'] != null) {
|
||||||
final errors = err.response?.data['errors'] as Map<String, dynamic>;
|
final errors = err.response?.data['errors'] as Map<String, dynamic>;
|
||||||
return errors.values
|
message = errors.values
|
||||||
.map(
|
.map(
|
||||||
(ele) =>
|
(ele) =>
|
||||||
(ele as List<dynamic>).map((ele) => ele.toString()).join('\n'),
|
(ele as List<dynamic>).map((ele) => ele.toString()).join('\n'),
|
||||||
)
|
)
|
||||||
.join('\n');
|
.join('\n');
|
||||||
}
|
}
|
||||||
return err.message ?? err.toString();
|
if (message == null || message.isEmpty) message = err.response?.statusMessage;
|
||||||
|
message ??= err.message;
|
||||||
|
return message ?? err.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
void showErrorAlert(dynamic err) async {
|
void showErrorAlert(dynamic err) async {
|
||||||
|
@@ -830,7 +830,7 @@ class _CloudFileListEntry extends HookConsumerWidget {
|
|||||||
bg = ImageFiltered(
|
bg = ImageFiltered(
|
||||||
imageFilter: ImageFilter.blur(sigmaX: 10, sigmaY: 10),
|
imageFilter: ImageFilter.blur(sigmaX: 10, sigmaY: 10),
|
||||||
child: CloudFileWidget(
|
child: CloudFileWidget(
|
||||||
fit: fit,
|
fit: BoxFit.cover,
|
||||||
item: file,
|
item: file,
|
||||||
noBlurhash: true,
|
noBlurhash: true,
|
||||||
useInternalGate: false,
|
useInternalGate: false,
|
||||||
|
@@ -142,10 +142,6 @@ class _PaymentContentState extends ConsumerState<_PaymentContent> {
|
|||||||
// Set initial mode based on stored PIN and biometric support
|
// Set initial mode based on stored PIN and biometric support
|
||||||
if (_hasStoredPin && _hasBiometricSupport && widget.enableBiometric) {
|
if (_hasStoredPin && _hasBiometricSupport && widget.enableBiometric) {
|
||||||
_isPinMode = false;
|
_isPinMode = false;
|
||||||
// Automatically trigger biometric authentication
|
|
||||||
WidgetsBinding.instance.addPostFrameCallback((_) {
|
|
||||||
_authenticateWithBiometric();
|
|
||||||
});
|
|
||||||
} else {
|
} else {
|
||||||
_isPinMode = true;
|
_isPinMode = true;
|
||||||
}
|
}
|
||||||
@@ -270,6 +266,8 @@ class _PaymentContentState extends ConsumerState<_PaymentContent> {
|
|||||||
}
|
}
|
||||||
} else if (err.response?.statusCode == 400) {
|
} else if (err.response?.statusCode == 400) {
|
||||||
errorMessage = err.response?.data?['error'] ?? errorMessage;
|
errorMessage = err.response?.data?['error'] ?? errorMessage;
|
||||||
|
} else {
|
||||||
|
rethrow;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
throw errorMessage;
|
throw errorMessage;
|
||||||
@@ -419,42 +417,48 @@ class _PaymentContentState extends ConsumerState<_PaymentContent> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Widget _buildBiometricAuth() {
|
Widget _buildBiometricAuth() {
|
||||||
return Column(
|
return SingleChildScrollView(
|
||||||
mainAxisAlignment: MainAxisAlignment.center,
|
child:
|
||||||
crossAxisAlignment: CrossAxisAlignment.center,
|
Column(
|
||||||
children: [
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
Icon(Symbols.fingerprint, size: 48),
|
crossAxisAlignment: CrossAxisAlignment.center,
|
||||||
const Gap(16),
|
children: [
|
||||||
Text(
|
Icon(Symbols.fingerprint, size: 48),
|
||||||
'useBiometricToConfirm'.tr(),
|
const Gap(16),
|
||||||
style: Theme.of(
|
Text(
|
||||||
context,
|
'useBiometricToConfirm'.tr(),
|
||||||
).textTheme.titleMedium?.copyWith(fontWeight: FontWeight.w500),
|
style: Theme.of(
|
||||||
textAlign: TextAlign.center,
|
context,
|
||||||
),
|
).textTheme.titleMedium?.copyWith(fontWeight: FontWeight.w500),
|
||||||
Text(
|
textAlign: TextAlign.center,
|
||||||
'The biometric data will only be processed on your device',
|
),
|
||||||
style: Theme.of(context).textTheme.bodyMedium?.copyWith(
|
Text(
|
||||||
color: Theme.of(context).colorScheme.onSurfaceVariant,
|
'The biometric data will only be processed on your device',
|
||||||
fontSize: 11,
|
style: Theme.of(context).textTheme.bodyMedium?.copyWith(
|
||||||
),
|
color: Theme.of(context).colorScheme.onSurfaceVariant,
|
||||||
textAlign: TextAlign.center,
|
fontSize: 11,
|
||||||
).opacity(0.75),
|
),
|
||||||
const Gap(28),
|
textAlign: TextAlign.center,
|
||||||
ElevatedButton.icon(
|
).opacity(0.75),
|
||||||
onPressed: _authenticateWithBiometric,
|
const Gap(28),
|
||||||
icon: const Icon(Symbols.fingerprint),
|
ElevatedButton.icon(
|
||||||
label: Text('authenticateNow'.tr()),
|
onPressed: _authenticateWithBiometric,
|
||||||
style: ElevatedButton.styleFrom(
|
icon: const Icon(Symbols.fingerprint),
|
||||||
padding: const EdgeInsets.symmetric(horizontal: 24, vertical: 12),
|
label: Text('authenticateNow'.tr()),
|
||||||
),
|
style: ElevatedButton.styleFrom(
|
||||||
),
|
padding: const EdgeInsets.symmetric(
|
||||||
TextButton(
|
horizontal: 24,
|
||||||
onPressed: () => _fallbackToPinMode(null),
|
vertical: 12,
|
||||||
child: Text('usePinInstead'.tr()),
|
),
|
||||||
),
|
),
|
||||||
],
|
),
|
||||||
).center();
|
TextButton(
|
||||||
|
onPressed: () => _fallbackToPinMode(null),
|
||||||
|
child: Text('usePinInstead'.tr()),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
).center(),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
Widget _buildActionButtons() {
|
Widget _buildActionButtons() {
|
||||||
|
@@ -6,6 +6,8 @@ import 'package:island/models/poll.dart';
|
|||||||
import 'package:island/pods/network.dart';
|
import 'package:island/pods/network.dart';
|
||||||
import 'package:island/screens/creators/poll/poll_list.dart';
|
import 'package:island/screens/creators/poll/poll_list.dart';
|
||||||
import 'package:island/services/time.dart';
|
import 'package:island/services/time.dart';
|
||||||
|
import 'package:island/widgets/account/account_pfc.dart';
|
||||||
|
import 'package:island/widgets/content/cloud_files.dart';
|
||||||
import 'package:island/widgets/content/sheet.dart';
|
import 'package:island/widgets/content/sheet.dart';
|
||||||
import 'package:island/widgets/poll/poll_stats_widget.dart';
|
import 'package:island/widgets/poll/poll_stats_widget.dart';
|
||||||
import 'package:island/widgets/response.dart';
|
import 'package:island/widgets/response.dart';
|
||||||
@@ -134,19 +136,27 @@ class _PollHeader extends StatelessWidget {
|
|||||||
),
|
),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
).padding(horizontal: 20, top: 16),
|
||||||
Text('pollQuestions').tr().fontSize(17).bold(),
|
ExpansionTile(
|
||||||
for (final q in poll.questions)
|
title: Text('pollQuestions').tr().fontSize(17).bold(),
|
||||||
Column(
|
tilePadding: EdgeInsets.symmetric(horizontal: 20),
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
children:
|
||||||
children: [
|
poll.questions
|
||||||
if (q.title.isNotEmpty) Text(q.title).bold(),
|
.map(
|
||||||
if (q.description?.isNotEmpty ?? false) Text(q.description!),
|
(q) => Column(
|
||||||
PollStatsWidget(question: q, stats: poll.stats),
|
crossAxisAlignment: CrossAxisAlignment.stretch,
|
||||||
],
|
children: [
|
||||||
),
|
if (q.title.isNotEmpty) Text(q.title).bold(),
|
||||||
|
if (q.description?.isNotEmpty ?? false)
|
||||||
|
Text(q.description!),
|
||||||
|
PollStatsWidget(question: q, stats: poll.stats),
|
||||||
|
],
|
||||||
|
).padding(horizontal: 20, top: 8, bottom: 16),
|
||||||
|
)
|
||||||
|
.toList(),
|
||||||
|
),
|
||||||
],
|
],
|
||||||
).padding(horizontal: 20, vertical: 16);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -207,7 +217,10 @@ class _PollAnswerTile extends StatelessWidget {
|
|||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
// Submit date/time (title)
|
// Submit date/time (title)
|
||||||
final submitText = answer.createdAt.formatSystem();
|
final submitText =
|
||||||
|
answer.account == null
|
||||||
|
? answer.createdAt.formatSystem()
|
||||||
|
: '${answer.account!.nick} · ${answer.createdAt.formatSystem()}';
|
||||||
|
|
||||||
// Compose content from poll questions if provided, otherwise fallback to joined key-values
|
// Compose content from poll questions if provided, otherwise fallback to joined key-values
|
||||||
String content;
|
String content;
|
||||||
@@ -244,10 +257,18 @@ class _PollAnswerTile extends StatelessWidget {
|
|||||||
return ListTile(
|
return ListTile(
|
||||||
contentPadding: const EdgeInsets.symmetric(horizontal: 20),
|
contentPadding: const EdgeInsets.symmetric(horizontal: 20),
|
||||||
isThreeLine: true,
|
isThreeLine: true,
|
||||||
leading: const CircleAvatar(
|
leading:
|
||||||
radius: 16,
|
answer.account == null
|
||||||
child: Icon(Icons.how_to_vote, size: 16),
|
? const CircleAvatar(
|
||||||
),
|
radius: 16,
|
||||||
|
child: Icon(Icons.how_to_vote, size: 16),
|
||||||
|
)
|
||||||
|
: AccountPfcGestureDetector(
|
||||||
|
uname: answer.account!.name,
|
||||||
|
child: ProfilePictureWidget(
|
||||||
|
file: answer.account!.profile.picture,
|
||||||
|
),
|
||||||
|
),
|
||||||
title: Text(submitText),
|
title: Text(submitText),
|
||||||
subtitle: Text(content),
|
subtitle: Text(content),
|
||||||
trailing: null,
|
trailing: null,
|
||||||
|
@@ -44,13 +44,13 @@ class PollStatsWidget extends StatelessWidget {
|
|||||||
// yes/no: map {true: count, false: count}
|
// yes/no: map {true: count, false: count}
|
||||||
if (raw is Map) {
|
if (raw is Map) {
|
||||||
final int yes =
|
final int yes =
|
||||||
(raw[true] is int)
|
(raw['true'] is int)
|
||||||
? raw[true] as int
|
? raw['true'] as int
|
||||||
: int.tryParse('${raw[true]}') ?? 0;
|
: int.tryParse('${raw['true']}') ?? 0;
|
||||||
final int no =
|
final int no =
|
||||||
(raw[false] is int)
|
(raw['false'] is int)
|
||||||
? raw[false] as int
|
? raw['false'] as int
|
||||||
: int.tryParse('${raw[false]}') ?? 0;
|
: int.tryParse('${raw['false']}') ?? 0;
|
||||||
final total = (yes + no).clamp(0, 1 << 31);
|
final total = (yes + no).clamp(0, 1 << 31);
|
||||||
final yesPct = total == 0 ? 0.0 : yes / total;
|
final yesPct = total == 0 ? 0.0 : yes / total;
|
||||||
final noPct = total == 0 ? 0.0 : no / total;
|
final noPct = total == 0 ? 0.0 : no / total;
|
||||||
|
@@ -17,6 +17,7 @@ class PollSubmit extends ConsumerStatefulWidget {
|
|||||||
this.onCancel,
|
this.onCancel,
|
||||||
this.showProgress = true,
|
this.showProgress = true,
|
||||||
this.isReadonly = false,
|
this.isReadonly = false,
|
||||||
|
this.isInitiallyExpanded = false,
|
||||||
});
|
});
|
||||||
|
|
||||||
final SnPollWithStats poll;
|
final SnPollWithStats poll;
|
||||||
@@ -36,6 +37,9 @@ class PollSubmit extends ConsumerStatefulWidget {
|
|||||||
|
|
||||||
final bool isReadonly;
|
final bool isReadonly;
|
||||||
|
|
||||||
|
/// Whether the poll should start expanded instead of collapsed.
|
||||||
|
final bool isInitiallyExpanded;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
ConsumerState<PollSubmit> createState() => _PollSubmitState();
|
ConsumerState<PollSubmit> createState() => _PollSubmitState();
|
||||||
}
|
}
|
||||||
@@ -45,6 +49,7 @@ class _PollSubmitState extends ConsumerState<PollSubmit> {
|
|||||||
int _index = 0;
|
int _index = 0;
|
||||||
bool _submitting = false;
|
bool _submitting = false;
|
||||||
bool _isModifying = false; // New state to track if user is modifying answers
|
bool _isModifying = false; // New state to track if user is modifying answers
|
||||||
|
bool _isCollapsed = true; // New state to track collapse/expand
|
||||||
|
|
||||||
/// Collected answers, keyed by questionId
|
/// Collected answers, keyed by questionId
|
||||||
late Map<String, dynamic> _answers;
|
late Map<String, dynamic> _answers;
|
||||||
@@ -65,6 +70,8 @@ class _PollSubmitState extends ConsumerState<PollSubmit> {
|
|||||||
_questions = [...widget.poll.questions]
|
_questions = [...widget.poll.questions]
|
||||||
..sort((a, b) => a.order.compareTo(b.order));
|
..sort((a, b) => a.order.compareTo(b.order));
|
||||||
_answers = Map<String, dynamic>.from(widget.initialAnswers ?? {});
|
_answers = Map<String, dynamic>.from(widget.initialAnswers ?? {});
|
||||||
|
// Set initial collapse state based on the parameter
|
||||||
|
_isCollapsed = !widget.isInitiallyExpanded;
|
||||||
if (!widget.isReadonly) {
|
if (!widget.isReadonly) {
|
||||||
_loadCurrentIntoLocalState();
|
_loadCurrentIntoLocalState();
|
||||||
// If initial answers are provided, set _isModifying to false initially
|
// If initial answers are provided, set _isModifying to false initially
|
||||||
@@ -405,6 +412,7 @@ class _PollSubmitState extends ConsumerState<PollSubmit> {
|
|||||||
});
|
});
|
||||||
},
|
},
|
||||||
multiSelectionEnabled: false,
|
multiSelectionEnabled: false,
|
||||||
|
emptySelectionAllowed: true,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
@@ -652,39 +660,179 @@ class _PollSubmitState extends ConsumerState<PollSubmit> {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Widget _buildCollapsedView(BuildContext context) {
|
||||||
|
return Column(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
Row(
|
||||||
|
children: [
|
||||||
|
Expanded(
|
||||||
|
child: Column(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
if (widget.poll.title != null)
|
||||||
|
Text(
|
||||||
|
widget.poll.title!,
|
||||||
|
style: Theme.of(context).textTheme.titleMedium?.copyWith(
|
||||||
|
fontWeight: FontWeight.w600,
|
||||||
|
),
|
||||||
|
maxLines: 1,
|
||||||
|
overflow: TextOverflow.ellipsis,
|
||||||
|
),
|
||||||
|
if (widget.poll.description != null)
|
||||||
|
Padding(
|
||||||
|
padding: const EdgeInsets.only(top: 2),
|
||||||
|
child: Text(
|
||||||
|
widget.poll.description!,
|
||||||
|
style: Theme.of(context).textTheme.bodySmall?.copyWith(
|
||||||
|
color: Theme.of(
|
||||||
|
context,
|
||||||
|
).textTheme.bodySmall?.color?.withOpacity(0.7),
|
||||||
|
),
|
||||||
|
maxLines: 2,
|
||||||
|
overflow: TextOverflow.ellipsis,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
else
|
||||||
|
Padding(
|
||||||
|
padding: const EdgeInsets.only(top: 2),
|
||||||
|
child: Text(
|
||||||
|
'${_questions.length} question${_questions.length == 1 ? '' : 's'}',
|
||||||
|
style: Theme.of(context).textTheme.bodySmall?.copyWith(
|
||||||
|
color: Theme.of(
|
||||||
|
context,
|
||||||
|
).textTheme.bodySmall?.color?.withOpacity(0.7),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
IconButton(
|
||||||
|
icon: Icon(
|
||||||
|
_isCollapsed ? Icons.expand_more : Icons.expand_less,
|
||||||
|
size: 20,
|
||||||
|
),
|
||||||
|
onPressed: () {
|
||||||
|
setState(() {
|
||||||
|
_isCollapsed = !_isCollapsed;
|
||||||
|
});
|
||||||
|
},
|
||||||
|
visualDensity: VisualDensity.compact,
|
||||||
|
tooltip: _isCollapsed ? 'expandPoll'.tr() : 'collapsePoll'.tr(),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
if (_questions.isEmpty) {
|
if (_questions.isEmpty) {
|
||||||
return const SizedBox.shrink();
|
return const SizedBox.shrink();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// If collapsed, show collapsed view for all states
|
||||||
|
if (_isCollapsed) {
|
||||||
|
return _buildCollapsedView(context);
|
||||||
|
}
|
||||||
|
|
||||||
// If poll is already submitted and not in readonly mode, and not in modification mode, show submitted view
|
// If poll is already submitted and not in readonly mode, and not in modification mode, show submitted view
|
||||||
if (widget.initialAnswers != null && !widget.isReadonly && !_isModifying) {
|
if (widget.initialAnswers != null && !widget.isReadonly && !_isModifying) {
|
||||||
return Column(
|
return Column(
|
||||||
crossAxisAlignment: CrossAxisAlignment.stretch,
|
crossAxisAlignment: CrossAxisAlignment.stretch,
|
||||||
children: [_buildSubmittedView(context), _buildNavBar(context)],
|
children: [
|
||||||
|
_buildCollapsedView(context),
|
||||||
|
const SizedBox(height: 8),
|
||||||
|
AnimatedSwitcher(
|
||||||
|
duration: const Duration(milliseconds: 300),
|
||||||
|
transitionBuilder: (child, anim) {
|
||||||
|
final offset = Tween<Offset>(
|
||||||
|
begin: const Offset(0, -0.1),
|
||||||
|
end: Offset.zero,
|
||||||
|
).animate(CurvedAnimation(parent: anim, curve: Curves.easeOut));
|
||||||
|
final fade = CurvedAnimation(parent: anim, curve: Curves.easeOut);
|
||||||
|
return FadeTransition(
|
||||||
|
opacity: fade,
|
||||||
|
child: SlideTransition(position: offset, child: child),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
child: Column(
|
||||||
|
key: const ValueKey('submitted_expanded'),
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.stretch,
|
||||||
|
children: [_buildSubmittedView(context), _buildNavBar(context)],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// If poll is in readonly mode, show readonly view
|
// If poll is in readonly mode, show readonly view
|
||||||
if (widget.isReadonly) {
|
if (widget.isReadonly) {
|
||||||
return _buildReadonlyView(context);
|
return Column(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.stretch,
|
||||||
|
children: [
|
||||||
|
_buildCollapsedView(context),
|
||||||
|
const SizedBox(height: 8),
|
||||||
|
AnimatedSwitcher(
|
||||||
|
duration: const Duration(milliseconds: 300),
|
||||||
|
transitionBuilder: (child, anim) {
|
||||||
|
final offset = Tween<Offset>(
|
||||||
|
begin: const Offset(0, -0.1),
|
||||||
|
end: Offset.zero,
|
||||||
|
).animate(CurvedAnimation(parent: anim, curve: Curves.easeOut));
|
||||||
|
final fade = CurvedAnimation(parent: anim, curve: Curves.easeOut);
|
||||||
|
return FadeTransition(
|
||||||
|
opacity: fade,
|
||||||
|
child: SlideTransition(position: offset, child: child),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
child: _buildReadonlyView(context),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
return Column(
|
return Column(
|
||||||
crossAxisAlignment: CrossAxisAlignment.stretch,
|
crossAxisAlignment: CrossAxisAlignment.stretch,
|
||||||
children: [
|
children: [
|
||||||
_buildHeader(context),
|
_buildCollapsedView(context),
|
||||||
const SizedBox(height: 12),
|
const SizedBox(height: 8),
|
||||||
_AnimatedStep(
|
AnimatedSwitcher(
|
||||||
key: ValueKey(_current.id),
|
duration: const Duration(milliseconds: 300),
|
||||||
|
transitionBuilder: (child, anim) {
|
||||||
|
final offset = Tween<Offset>(
|
||||||
|
begin: const Offset(0, -0.1),
|
||||||
|
end: Offset.zero,
|
||||||
|
).animate(CurvedAnimation(parent: anim, curve: Curves.easeOut));
|
||||||
|
final fade = CurvedAnimation(parent: anim, curve: Curves.easeOut);
|
||||||
|
return FadeTransition(
|
||||||
|
opacity: fade,
|
||||||
|
child: SlideTransition(position: offset, child: child),
|
||||||
|
);
|
||||||
|
},
|
||||||
child: Column(
|
child: Column(
|
||||||
|
key: const ValueKey('normal_expanded'),
|
||||||
crossAxisAlignment: CrossAxisAlignment.stretch,
|
crossAxisAlignment: CrossAxisAlignment.stretch,
|
||||||
children: [_buildBody(context), _buildStats(context, _current)],
|
children: [
|
||||||
|
_buildHeader(context),
|
||||||
|
const SizedBox(height: 12),
|
||||||
|
_AnimatedStep(
|
||||||
|
key: ValueKey(_current.id),
|
||||||
|
child: Column(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.stretch,
|
||||||
|
children: [
|
||||||
|
_buildBody(context),
|
||||||
|
_buildStats(context, _current),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
const SizedBox(height: 16),
|
||||||
|
_buildNavBar(context),
|
||||||
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
const SizedBox(height: 16),
|
|
||||||
_buildNavBar(context),
|
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
287
lib/widgets/post/compose_embed_sheet.dart
Normal file
287
lib/widgets/post/compose_embed_sheet.dart
Normal file
@@ -0,0 +1,287 @@
|
|||||||
|
import 'package:dropdown_button2/dropdown_button2.dart';
|
||||||
|
import 'package:easy_localization/easy_localization.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter/services.dart';
|
||||||
|
import 'package:flutter_hooks/flutter_hooks.dart';
|
||||||
|
import 'package:gap/gap.dart';
|
||||||
|
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||||
|
import 'package:island/models/post.dart';
|
||||||
|
import 'package:island/widgets/content/sheet.dart';
|
||||||
|
import 'package:island/widgets/post/compose_shared.dart';
|
||||||
|
import 'package:material_symbols_icons/symbols.dart';
|
||||||
|
import 'package:styled_widget/styled_widget.dart';
|
||||||
|
|
||||||
|
class ComposeEmbedSheet extends HookConsumerWidget {
|
||||||
|
final ComposeState state;
|
||||||
|
|
||||||
|
const ComposeEmbedSheet({super.key, required this.state});
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context, WidgetRef ref) {
|
||||||
|
final theme = Theme.of(context);
|
||||||
|
final colorScheme = theme.colorScheme;
|
||||||
|
|
||||||
|
// Listen to embed view changes
|
||||||
|
final currentEmbedView = useValueListenable(state.embedView);
|
||||||
|
|
||||||
|
// Form state
|
||||||
|
final uriController = useTextEditingController();
|
||||||
|
final aspectRatioController = useTextEditingController();
|
||||||
|
final selectedRenderer = useState<PostEmbedViewRenderer>(
|
||||||
|
PostEmbedViewRenderer.webView,
|
||||||
|
);
|
||||||
|
|
||||||
|
void clearForm() {
|
||||||
|
uriController.clear();
|
||||||
|
aspectRatioController.clear();
|
||||||
|
selectedRenderer.value = PostEmbedViewRenderer.webView;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Populate form when embed view changes
|
||||||
|
useEffect(() {
|
||||||
|
if (currentEmbedView != null) {
|
||||||
|
uriController.text = currentEmbedView.uri;
|
||||||
|
aspectRatioController.text =
|
||||||
|
currentEmbedView.aspectRatio?.toString() ?? '';
|
||||||
|
selectedRenderer.value = currentEmbedView.renderer;
|
||||||
|
} else {
|
||||||
|
clearForm();
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}, [currentEmbedView]);
|
||||||
|
|
||||||
|
void saveEmbedView() {
|
||||||
|
final uri = uriController.text.trim();
|
||||||
|
if (uri.isEmpty) {
|
||||||
|
ScaffoldMessenger.of(
|
||||||
|
context,
|
||||||
|
).showSnackBar(SnackBar(content: Text('embedUriRequired'.tr())));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
final aspectRatio =
|
||||||
|
aspectRatioController.text.trim().isNotEmpty
|
||||||
|
? double.tryParse(aspectRatioController.text.trim())
|
||||||
|
: null;
|
||||||
|
|
||||||
|
final embedView = SnPostEmbedView(
|
||||||
|
uri: uri,
|
||||||
|
aspectRatio: aspectRatio,
|
||||||
|
renderer: selectedRenderer.value,
|
||||||
|
);
|
||||||
|
|
||||||
|
if (currentEmbedView != null) {
|
||||||
|
ComposeLogic.updateEmbedView(state, embedView);
|
||||||
|
} else {
|
||||||
|
ComposeLogic.setEmbedView(state, embedView);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return SheetScaffold(
|
||||||
|
titleText: 'embedView'.tr(),
|
||||||
|
heightFactor: 0.7,
|
||||||
|
child: Column(
|
||||||
|
children: [
|
||||||
|
// Header with save button when editing
|
||||||
|
if (currentEmbedView != null)
|
||||||
|
Container(
|
||||||
|
padding: const EdgeInsets.symmetric(horizontal: 20, vertical: 8),
|
||||||
|
color: Theme.of(context).colorScheme.surfaceContainerHigh,
|
||||||
|
child: Row(
|
||||||
|
children: [
|
||||||
|
Expanded(
|
||||||
|
child: Text(
|
||||||
|
'editEmbed'.tr(),
|
||||||
|
style: theme.textTheme.titleMedium,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
TextButton(
|
||||||
|
onPressed: saveEmbedView,
|
||||||
|
child: Text('save'.tr()),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
|
||||||
|
// Content area
|
||||||
|
Expanded(
|
||||||
|
child: SingleChildScrollView(
|
||||||
|
padding: const EdgeInsets.all(16),
|
||||||
|
child: Column(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
// Form fields
|
||||||
|
TextField(
|
||||||
|
controller: uriController,
|
||||||
|
decoration: InputDecoration(
|
||||||
|
labelText: 'embedUri'.tr(),
|
||||||
|
hintText: 'https://example.com',
|
||||||
|
border: OutlineInputBorder(
|
||||||
|
borderRadius: BorderRadius.circular(8),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
keyboardType: TextInputType.url,
|
||||||
|
),
|
||||||
|
const Gap(16),
|
||||||
|
TextField(
|
||||||
|
controller: aspectRatioController,
|
||||||
|
decoration: InputDecoration(
|
||||||
|
labelText: 'aspectRatio'.tr(),
|
||||||
|
hintText: '16/9 = 1.777',
|
||||||
|
border: OutlineInputBorder(
|
||||||
|
borderRadius: BorderRadius.circular(8),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
keyboardType: TextInputType.numberWithOptions(
|
||||||
|
decimal: true,
|
||||||
|
),
|
||||||
|
inputFormatters: [
|
||||||
|
FilteringTextInputFormatter.allow(RegExp(r'^\d*\.?\d*$')),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
const Gap(16),
|
||||||
|
DropdownButtonFormField2<PostEmbedViewRenderer>(
|
||||||
|
value: selectedRenderer.value,
|
||||||
|
decoration: InputDecoration(
|
||||||
|
labelText: 'renderer'.tr(),
|
||||||
|
border: OutlineInputBorder(
|
||||||
|
borderRadius: BorderRadius.circular(8),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
items:
|
||||||
|
PostEmbedViewRenderer.values.map((renderer) {
|
||||||
|
return DropdownMenuItem(
|
||||||
|
value: renderer,
|
||||||
|
child: Text(renderer.name).tr(),
|
||||||
|
);
|
||||||
|
}).toList(),
|
||||||
|
onChanged: (value) {
|
||||||
|
if (value != null) {
|
||||||
|
selectedRenderer.value = value;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
),
|
||||||
|
|
||||||
|
// Current embed view display (when exists)
|
||||||
|
if (currentEmbedView != null) ...[
|
||||||
|
const Gap(32),
|
||||||
|
Text(
|
||||||
|
'currentEmbed'.tr(),
|
||||||
|
style: theme.textTheme.titleMedium,
|
||||||
|
).padding(horizontal: 4),
|
||||||
|
const Gap(8),
|
||||||
|
Card(
|
||||||
|
margin: EdgeInsets.zero,
|
||||||
|
color: Theme.of(context).colorScheme.surfaceContainerHigh,
|
||||||
|
child: Padding(
|
||||||
|
padding: const EdgeInsets.only(
|
||||||
|
left: 16,
|
||||||
|
right: 16,
|
||||||
|
bottom: 12,
|
||||||
|
top: 4,
|
||||||
|
),
|
||||||
|
child: Column(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
Row(
|
||||||
|
children: [
|
||||||
|
Icon(
|
||||||
|
currentEmbedView.renderer ==
|
||||||
|
PostEmbedViewRenderer.webView
|
||||||
|
? Symbols.web
|
||||||
|
: Symbols.web,
|
||||||
|
color: colorScheme.primary,
|
||||||
|
),
|
||||||
|
const Gap(12),
|
||||||
|
Expanded(
|
||||||
|
child: Text(
|
||||||
|
currentEmbedView.uri,
|
||||||
|
style: theme.textTheme.bodyMedium,
|
||||||
|
maxLines: 1,
|
||||||
|
overflow: TextOverflow.ellipsis,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
IconButton(
|
||||||
|
icon: const Icon(Symbols.delete),
|
||||||
|
onPressed: () {
|
||||||
|
showDialog(
|
||||||
|
context: context,
|
||||||
|
builder:
|
||||||
|
(dialogContext) => AlertDialog(
|
||||||
|
title: Text('deleteEmbed').tr(),
|
||||||
|
content:
|
||||||
|
Text('deleteEmbedConfirm').tr(),
|
||||||
|
actions: [
|
||||||
|
TextButton(
|
||||||
|
onPressed:
|
||||||
|
() =>
|
||||||
|
Navigator.of(
|
||||||
|
dialogContext,
|
||||||
|
).pop(),
|
||||||
|
child: Text('cancel'.tr()),
|
||||||
|
),
|
||||||
|
TextButton(
|
||||||
|
onPressed: () {
|
||||||
|
ComposeLogic.deleteEmbedView(
|
||||||
|
state,
|
||||||
|
);
|
||||||
|
clearForm();
|
||||||
|
Navigator.of(
|
||||||
|
dialogContext,
|
||||||
|
).pop();
|
||||||
|
},
|
||||||
|
style: TextButton.styleFrom(
|
||||||
|
foregroundColor:
|
||||||
|
colorScheme.error,
|
||||||
|
),
|
||||||
|
child: Text('delete').tr(),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
tooltip: 'delete'.tr(),
|
||||||
|
color: colorScheme.error,
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
const Gap(12),
|
||||||
|
Text(
|
||||||
|
'aspectRatio'.tr(),
|
||||||
|
style: theme.textTheme.labelMedium?.copyWith(
|
||||||
|
color: colorScheme.onSurfaceVariant,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
const Gap(4),
|
||||||
|
Text(
|
||||||
|
currentEmbedView.aspectRatio != null
|
||||||
|
? currentEmbedView.aspectRatio!
|
||||||
|
.toStringAsFixed(2)
|
||||||
|
: 'notSet'.tr(),
|
||||||
|
style: theme.textTheme.bodyMedium,
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
] else ...[
|
||||||
|
// Save button for new embed
|
||||||
|
const Gap(16),
|
||||||
|
SizedBox(
|
||||||
|
width: double.infinity,
|
||||||
|
child: FilledButton.icon(
|
||||||
|
onPressed: saveEmbedView,
|
||||||
|
icon: const Icon(Symbols.add),
|
||||||
|
label: Text('addEmbed'.tr()),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
@@ -37,6 +37,7 @@ class ComposeState {
|
|||||||
final ValueNotifier<List<SnPostCategory>> categories;
|
final ValueNotifier<List<SnPostCategory>> categories;
|
||||||
StringTagController tagsController;
|
StringTagController tagsController;
|
||||||
final ValueNotifier<SnRealm?> realm;
|
final ValueNotifier<SnRealm?> realm;
|
||||||
|
final ValueNotifier<SnPostEmbedView?> embedView;
|
||||||
final String draftId;
|
final String draftId;
|
||||||
int postType;
|
int postType;
|
||||||
// Linked poll id for this compose session (nullable)
|
// Linked poll id for this compose session (nullable)
|
||||||
@@ -56,6 +57,7 @@ class ComposeState {
|
|||||||
required this.tagsController,
|
required this.tagsController,
|
||||||
required this.categories,
|
required this.categories,
|
||||||
required this.realm,
|
required this.realm,
|
||||||
|
required this.embedView,
|
||||||
required this.draftId,
|
required this.draftId,
|
||||||
this.postType = 0,
|
this.postType = 0,
|
||||||
String? pollId,
|
String? pollId,
|
||||||
@@ -120,6 +122,7 @@ class ComposeLogic {
|
|||||||
originalPost?.categories ?? [],
|
originalPost?.categories ?? [],
|
||||||
),
|
),
|
||||||
realm: ValueNotifier(originalPost?.realm),
|
realm: ValueNotifier(originalPost?.realm),
|
||||||
|
embedView: ValueNotifier<SnPostEmbedView?>(originalPost?.embedView),
|
||||||
draftId: id,
|
draftId: id,
|
||||||
postType: postType,
|
postType: postType,
|
||||||
// initialize without poll by default
|
// initialize without poll by default
|
||||||
@@ -151,6 +154,7 @@ class ComposeLogic {
|
|||||||
tagsController: tagsController,
|
tagsController: tagsController,
|
||||||
categories: ValueNotifier<List<SnPostCategory>>([]),
|
categories: ValueNotifier<List<SnPostCategory>>([]),
|
||||||
realm: ValueNotifier(null),
|
realm: ValueNotifier(null),
|
||||||
|
embedView: ValueNotifier<SnPostEmbedView?>(draft.embedView),
|
||||||
draftId: draft.id,
|
draftId: draft.id,
|
||||||
postType: postType,
|
postType: postType,
|
||||||
pollId: null,
|
pollId: null,
|
||||||
@@ -169,10 +173,6 @@ class ComposeLogic {
|
|||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
if (state._autoSaveTimer == null) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Upload any local attachments first
|
// Upload any local attachments first
|
||||||
final baseUrl = ref.watch(serverUrlProvider);
|
final baseUrl = ref.watch(serverUrlProvider);
|
||||||
final token = await getToken(ref.watch(tokenProvider));
|
final token = await getToken(ref.watch(tokenProvider));
|
||||||
@@ -253,6 +253,7 @@ class ComposeLogic {
|
|||||||
tags: [],
|
tags: [],
|
||||||
categories: [],
|
categories: [],
|
||||||
collections: [],
|
collections: [],
|
||||||
|
embedView: state.embedView.value,
|
||||||
createdAt: DateTime.now(),
|
createdAt: DateTime.now(),
|
||||||
updatedAt: DateTime.now(),
|
updatedAt: DateTime.now(),
|
||||||
deletedAt: null,
|
deletedAt: null,
|
||||||
@@ -279,10 +280,6 @@ class ComposeLogic {
|
|||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
if (state._autoSaveTimer == null) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
final draft = SnPost(
|
final draft = SnPost(
|
||||||
id: state.draftId,
|
id: state.draftId,
|
||||||
title: state.titleController.text,
|
title: state.titleController.text,
|
||||||
@@ -329,6 +326,7 @@ class ComposeLogic {
|
|||||||
tags: [],
|
tags: [],
|
||||||
categories: [],
|
categories: [],
|
||||||
collections: [],
|
collections: [],
|
||||||
|
embedView: state.embedView.value,
|
||||||
createdAt: DateTime.now(),
|
createdAt: DateTime.now(),
|
||||||
updatedAt: DateTime.now(),
|
updatedAt: DateTime.now(),
|
||||||
deletedAt: null,
|
deletedAt: null,
|
||||||
@@ -577,6 +575,18 @@ class ComposeLogic {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void setEmbedView(ComposeState state, SnPostEmbedView embedView) {
|
||||||
|
state.embedView.value = embedView;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void updateEmbedView(ComposeState state, SnPostEmbedView embedView) {
|
||||||
|
state.embedView.value = embedView;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void deleteEmbedView(ComposeState state) {
|
||||||
|
state.embedView.value = null;
|
||||||
|
}
|
||||||
|
|
||||||
static Future<void> pickPoll(
|
static Future<void> pickPoll(
|
||||||
WidgetRef ref,
|
WidgetRef ref,
|
||||||
ComposeState state,
|
ComposeState state,
|
||||||
@@ -660,6 +670,8 @@ class ComposeLogic {
|
|||||||
'categories': state.categories.value.map((e) => e.slug).toList(),
|
'categories': state.categories.value.map((e) => e.slug).toList(),
|
||||||
if (state.realm.value != null) 'realm_id': state.realm.value?.id,
|
if (state.realm.value != null) 'realm_id': state.realm.value?.id,
|
||||||
if (state.pollId.value != null) 'poll_id': state.pollId.value,
|
if (state.pollId.value != null) 'poll_id': state.pollId.value,
|
||||||
|
if (state.embedView.value != null)
|
||||||
|
'embed_view': state.embedView.value!.toJson(),
|
||||||
};
|
};
|
||||||
|
|
||||||
// Send request
|
// Send request
|
||||||
@@ -753,6 +765,7 @@ class ComposeLogic {
|
|||||||
state.tagsController.dispose();
|
state.tagsController.dispose();
|
||||||
state.categories.dispose();
|
state.categories.dispose();
|
||||||
state.realm.dispose();
|
state.realm.dispose();
|
||||||
|
state.embedView.dispose();
|
||||||
state.pollId.dispose();
|
state.pollId.dispose();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -3,6 +3,7 @@ import 'package:flutter/material.dart';
|
|||||||
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||||
import 'package:island/models/post.dart';
|
import 'package:island/models/post.dart';
|
||||||
import 'package:island/services/compose_storage_db.dart';
|
import 'package:island/services/compose_storage_db.dart';
|
||||||
|
import 'package:island/widgets/post/compose_embed_sheet.dart';
|
||||||
import 'package:island/widgets/post/compose_shared.dart';
|
import 'package:island/widgets/post/compose_shared.dart';
|
||||||
import 'package:island/widgets/post/draft_manager.dart';
|
import 'package:island/widgets/post/draft_manager.dart';
|
||||||
import 'package:material_symbols_icons/symbols.dart';
|
import 'package:material_symbols_icons/symbols.dart';
|
||||||
@@ -33,13 +34,21 @@ class ComposeToolbar extends HookConsumerWidget {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void saveDraft() {
|
void saveDraft() {
|
||||||
ComposeLogic.saveDraft(ref, state);
|
ComposeLogic.saveDraftManually(ref, state, context);
|
||||||
}
|
}
|
||||||
|
|
||||||
void pickPoll() {
|
void pickPoll() {
|
||||||
ComposeLogic.pickPoll(ref, state, context);
|
ComposeLogic.pickPoll(ref, state, context);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void showEmbedSheet() {
|
||||||
|
showModalBottomSheet(
|
||||||
|
context: context,
|
||||||
|
isScrollControlled: true,
|
||||||
|
builder: (context) => ComposeEmbedSheet(state: state),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
void showDraftManager() {
|
void showDraftManager() {
|
||||||
showModalBottomSheet(
|
showModalBottomSheet(
|
||||||
context: context,
|
context: context,
|
||||||
@@ -112,6 +121,25 @@ class ComposeToolbar extends HookConsumerWidget {
|
|||||||
);
|
);
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
|
// Embed button with visual state when embed is present
|
||||||
|
ListenableBuilder(
|
||||||
|
listenable: state.embedView,
|
||||||
|
builder: (context, _) {
|
||||||
|
return IconButton(
|
||||||
|
onPressed: showEmbedSheet,
|
||||||
|
icon: const Icon(Symbols.web),
|
||||||
|
tooltip: 'embedView'.tr(),
|
||||||
|
color: colorScheme.primary,
|
||||||
|
style: ButtonStyle(
|
||||||
|
backgroundColor: WidgetStatePropertyAll(
|
||||||
|
state.embedView.value != null
|
||||||
|
? colorScheme.primary.withOpacity(0.15)
|
||||||
|
: null,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
),
|
||||||
const Spacer(),
|
const Spacer(),
|
||||||
if (originalPost == null && state.isEmpty)
|
if (originalPost == null && state.isEmpty)
|
||||||
IconButton(
|
IconButton(
|
||||||
|
@@ -16,138 +16,145 @@ class DraftManagerSheet extends HookConsumerWidget {
|
|||||||
Widget build(BuildContext context, WidgetRef ref) {
|
Widget build(BuildContext context, WidgetRef ref) {
|
||||||
final theme = Theme.of(context);
|
final theme = Theme.of(context);
|
||||||
final colorScheme = theme.colorScheme;
|
final colorScheme = theme.colorScheme;
|
||||||
final isLoading = useState(true);
|
final searchController = useTextEditingController();
|
||||||
|
final searchQuery = useState('');
|
||||||
|
|
||||||
final drafts = ref.watch(composeStorageNotifierProvider);
|
final drafts = ref.watch(composeStorageNotifierProvider);
|
||||||
|
|
||||||
// Track loading state based on drafts being loaded
|
// Search functionality
|
||||||
useEffect(() {
|
final filteredDrafts = useMemoized(() {
|
||||||
// Set loading to false after drafts are loaded
|
if (searchQuery.value.isEmpty) {
|
||||||
// We consider drafts loaded when the provider has been initialized
|
return drafts.values.toList()
|
||||||
Future.microtask(() {
|
..sort((a, b) => b.updatedAt!.compareTo(a.updatedAt!));
|
||||||
if (isLoading.value) {
|
}
|
||||||
isLoading.value = false;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
return null;
|
|
||||||
}, [drafts]);
|
|
||||||
|
|
||||||
final sortedDrafts = useMemoized(
|
final query = searchQuery.value.toLowerCase();
|
||||||
() {
|
return drafts.values.where((draft) {
|
||||||
final draftList = drafts.values.toList();
|
return (draft.title?.toLowerCase().contains(query) ?? false) ||
|
||||||
draftList.sort((a, b) => b.updatedAt!.compareTo(a.updatedAt!));
|
(draft.description?.toLowerCase().contains(query) ?? false) ||
|
||||||
return draftList;
|
(draft.content?.toLowerCase().contains(query) ?? false);
|
||||||
},
|
}).toList()
|
||||||
[
|
..sort((a, b) => b.updatedAt!.compareTo(a.updatedAt!));
|
||||||
drafts.length,
|
}, [drafts, searchQuery.value]);
|
||||||
drafts.values.map((e) => e.updatedAt!.millisecondsSinceEpoch).join(),
|
|
||||||
],
|
|
||||||
);
|
|
||||||
|
|
||||||
return SheetScaffold(
|
return SheetScaffold(
|
||||||
titleText: 'drafts'.tr(),
|
titleText: 'drafts'.tr(),
|
||||||
child:
|
child: Column(
|
||||||
isLoading.value
|
children: [
|
||||||
? const Center(child: CircularProgressIndicator())
|
// Search bar
|
||||||
: Column(
|
Padding(
|
||||||
children: [
|
padding: const EdgeInsets.all(16),
|
||||||
if (sortedDrafts.isEmpty)
|
child: TextField(
|
||||||
Expanded(
|
controller: searchController,
|
||||||
child: Center(
|
decoration: InputDecoration(
|
||||||
child: Column(
|
hintText: 'searchDrafts'.tr(),
|
||||||
mainAxisAlignment: MainAxisAlignment.center,
|
prefixIcon: const Icon(Symbols.search),
|
||||||
children: [
|
border: OutlineInputBorder(
|
||||||
Icon(
|
borderRadius: BorderRadius.circular(12),
|
||||||
Symbols.draft,
|
),
|
||||||
size: 64,
|
contentPadding: const EdgeInsets.symmetric(
|
||||||
color: colorScheme.onSurface.withOpacity(0.3),
|
horizontal: 16,
|
||||||
),
|
vertical: 12,
|
||||||
const Gap(16),
|
),
|
||||||
Text(
|
),
|
||||||
'noDrafts'.tr(),
|
onChanged: (value) => searchQuery.value = value,
|
||||||
style: theme.textTheme.bodyLarge?.copyWith(
|
),
|
||||||
color: colorScheme.onSurface.withOpacity(0.6),
|
),
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
)
|
|
||||||
else
|
|
||||||
Expanded(
|
|
||||||
child: ListView.builder(
|
|
||||||
itemCount: sortedDrafts.length,
|
|
||||||
itemBuilder: (context, index) {
|
|
||||||
final draft = sortedDrafts[index];
|
|
||||||
return _DraftItem(
|
|
||||||
draft: draft,
|
|
||||||
onTap: () {
|
|
||||||
Navigator.of(context).pop();
|
|
||||||
onDraftSelected?.call(draft.id);
|
|
||||||
},
|
|
||||||
onDelete: () async {
|
|
||||||
await ref
|
|
||||||
.read(composeStorageNotifierProvider.notifier)
|
|
||||||
.deleteDraft(draft.id);
|
|
||||||
},
|
|
||||||
);
|
|
||||||
},
|
|
||||||
),
|
|
||||||
),
|
|
||||||
if (sortedDrafts.isNotEmpty) ...[
|
|
||||||
const Divider(),
|
|
||||||
Padding(
|
|
||||||
padding: const EdgeInsets.all(16),
|
|
||||||
child: Row(
|
|
||||||
children: [
|
|
||||||
Expanded(
|
|
||||||
child: OutlinedButton.icon(
|
|
||||||
onPressed: () async {
|
|
||||||
final confirmed = await showDialog<bool>(
|
|
||||||
context: context,
|
|
||||||
builder:
|
|
||||||
(context) => AlertDialog(
|
|
||||||
title: Text('clearAllDrafts'.tr()),
|
|
||||||
content: Text(
|
|
||||||
'clearAllDraftsConfirm'.tr(),
|
|
||||||
),
|
|
||||||
actions: [
|
|
||||||
TextButton(
|
|
||||||
onPressed:
|
|
||||||
() => Navigator.of(
|
|
||||||
context,
|
|
||||||
).pop(false),
|
|
||||||
child: Text('cancel'.tr()),
|
|
||||||
),
|
|
||||||
TextButton(
|
|
||||||
onPressed:
|
|
||||||
() => Navigator.of(
|
|
||||||
context,
|
|
||||||
).pop(true),
|
|
||||||
child: Text('confirm'.tr()),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
);
|
|
||||||
|
|
||||||
if (confirmed == true) {
|
// Drafts list
|
||||||
await ref
|
if (filteredDrafts.isEmpty)
|
||||||
.read(
|
Expanded(
|
||||||
composeStorageNotifierProvider.notifier,
|
child: Center(
|
||||||
)
|
child: Column(
|
||||||
.clearAllDrafts();
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
}
|
children: [
|
||||||
},
|
Icon(
|
||||||
icon: const Icon(Symbols.delete_sweep),
|
Symbols.draft,
|
||||||
label: Text('clearAll'.tr()),
|
size: 64,
|
||||||
),
|
color: colorScheme.onSurface.withOpacity(0.3),
|
||||||
),
|
),
|
||||||
],
|
const Gap(16),
|
||||||
|
Text(
|
||||||
|
searchQuery.value.isEmpty
|
||||||
|
? 'noDrafts'.tr()
|
||||||
|
: 'noSearchResults'.tr(),
|
||||||
|
style: theme.textTheme.bodyLarge?.copyWith(
|
||||||
|
color: colorScheme.onSurface.withOpacity(0.6),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
else
|
||||||
|
Expanded(
|
||||||
|
child: ListView.builder(
|
||||||
|
itemCount: filteredDrafts.length,
|
||||||
|
itemBuilder: (context, index) {
|
||||||
|
final draft = filteredDrafts[index];
|
||||||
|
return _DraftItem(
|
||||||
|
draft: draft,
|
||||||
|
onTap: () {
|
||||||
|
Navigator.of(context).pop();
|
||||||
|
onDraftSelected?.call(draft.id);
|
||||||
|
},
|
||||||
|
onDelete: () async {
|
||||||
|
await ref
|
||||||
|
.read(composeStorageNotifierProvider.notifier)
|
||||||
|
.deleteDraft(draft.id);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
|
||||||
|
// Clear all button
|
||||||
|
if (filteredDrafts.isNotEmpty) ...[
|
||||||
|
const Divider(),
|
||||||
|
Padding(
|
||||||
|
padding: const EdgeInsets.all(16),
|
||||||
|
child: Row(
|
||||||
|
children: [
|
||||||
|
Expanded(
|
||||||
|
child: OutlinedButton.icon(
|
||||||
|
onPressed: () async {
|
||||||
|
final confirmed = await showDialog<bool>(
|
||||||
|
context: context,
|
||||||
|
builder:
|
||||||
|
(context) => AlertDialog(
|
||||||
|
title: Text('clearAllDrafts'.tr()),
|
||||||
|
content: Text('clearAllDraftsConfirm'.tr()),
|
||||||
|
actions: [
|
||||||
|
TextButton(
|
||||||
|
onPressed:
|
||||||
|
() => Navigator.of(context).pop(false),
|
||||||
|
child: Text('cancel'.tr()),
|
||||||
|
),
|
||||||
|
TextButton(
|
||||||
|
onPressed:
|
||||||
|
() => Navigator.of(context).pop(true),
|
||||||
|
child: Text('confirm'.tr()),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
if (confirmed == true) {
|
||||||
|
await ref
|
||||||
|
.read(composeStorageNotifierProvider.notifier)
|
||||||
|
.clearAllDrafts();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
icon: const Icon(Symbols.delete_sweep),
|
||||||
|
label: Text('clearAll'.tr()),
|
||||||
|
),
|
||||||
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
],
|
||||||
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -169,7 +176,7 @@ class _DraftItem extends StatelessWidget {
|
|||||||
final preview =
|
final preview =
|
||||||
content.length > 100 ? '${content.substring(0, 100)}...' : content;
|
content.length > 100 ? '${content.substring(0, 100)}...' : content;
|
||||||
final timeAgo = _formatTimeAgo(draft.updatedAt!);
|
final timeAgo = _formatTimeAgo(draft.updatedAt!);
|
||||||
final visibility = _parseVisibility(draft.visibility);
|
final visibility = _parseVisibility(draft.visibility).tr();
|
||||||
|
|
||||||
return Card(
|
return Card(
|
||||||
margin: const EdgeInsets.symmetric(horizontal: 16, vertical: 4),
|
margin: const EdgeInsets.symmetric(horizontal: 16, vertical: 4),
|
||||||
|
291
lib/widgets/post/embed_view_renderer.dart
Normal file
291
lib/widgets/post/embed_view_renderer.dart
Normal file
@@ -0,0 +1,291 @@
|
|||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter_hooks/flutter_hooks.dart';
|
||||||
|
import 'package:flutter_inappwebview/flutter_inappwebview.dart';
|
||||||
|
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||||
|
import 'package:island/models/post.dart';
|
||||||
|
import 'package:material_symbols_icons/symbols.dart';
|
||||||
|
import 'package:url_launcher/url_launcher.dart';
|
||||||
|
|
||||||
|
class EmbedViewRenderer extends HookConsumerWidget {
|
||||||
|
final SnPostEmbedView embedView;
|
||||||
|
final double? maxHeight;
|
||||||
|
final BorderRadius? borderRadius;
|
||||||
|
|
||||||
|
const EmbedViewRenderer({
|
||||||
|
super.key,
|
||||||
|
required this.embedView,
|
||||||
|
this.maxHeight = 400,
|
||||||
|
this.borderRadius,
|
||||||
|
});
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context, WidgetRef ref) {
|
||||||
|
final theme = Theme.of(context);
|
||||||
|
final colorScheme = theme.colorScheme;
|
||||||
|
|
||||||
|
// State management for lazy loading
|
||||||
|
final shouldLoad = useState(false);
|
||||||
|
final isLoading = useState(false);
|
||||||
|
|
||||||
|
return Container(
|
||||||
|
constraints: BoxConstraints(maxHeight: maxHeight ?? 400),
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
borderRadius: borderRadius ?? BorderRadius.circular(12),
|
||||||
|
border: Border.all(
|
||||||
|
color: colorScheme.outline.withOpacity(0.3),
|
||||||
|
width: 1,
|
||||||
|
),
|
||||||
|
color: colorScheme.surfaceContainerLowest,
|
||||||
|
),
|
||||||
|
child: ClipRRect(
|
||||||
|
borderRadius: borderRadius ?? BorderRadius.circular(12),
|
||||||
|
child: Column(
|
||||||
|
mainAxisSize: MainAxisSize.min,
|
||||||
|
children: [
|
||||||
|
// Header with embed info
|
||||||
|
Container(
|
||||||
|
padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 8),
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: colorScheme.surfaceContainerHigh,
|
||||||
|
border: Border(
|
||||||
|
bottom: BorderSide(
|
||||||
|
color: colorScheme.outline.withOpacity(0.2),
|
||||||
|
width: 1,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
child: Row(
|
||||||
|
children: [
|
||||||
|
Icon(
|
||||||
|
embedView.renderer == PostEmbedViewRenderer.webView
|
||||||
|
? Symbols.web
|
||||||
|
: Symbols.web,
|
||||||
|
size: 16,
|
||||||
|
color: colorScheme.primary,
|
||||||
|
),
|
||||||
|
const SizedBox(width: 8),
|
||||||
|
Expanded(
|
||||||
|
child: Text(
|
||||||
|
_getUriDisplay(embedView.uri),
|
||||||
|
style: theme.textTheme.bodySmall?.copyWith(
|
||||||
|
color: colorScheme.onSurfaceVariant,
|
||||||
|
),
|
||||||
|
maxLines: 1,
|
||||||
|
overflow: TextOverflow.ellipsis,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
IconButton(
|
||||||
|
icon: Icon(
|
||||||
|
Symbols.open_in_new,
|
||||||
|
size: 16,
|
||||||
|
color: colorScheme.onSurfaceVariant,
|
||||||
|
),
|
||||||
|
onPressed: () async {
|
||||||
|
final uri = Uri.parse(embedView.uri);
|
||||||
|
if (await canLaunchUrl(uri)) {
|
||||||
|
await launchUrl(
|
||||||
|
uri,
|
||||||
|
mode: LaunchMode.externalApplication,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
padding: EdgeInsets.zero,
|
||||||
|
constraints: const BoxConstraints(),
|
||||||
|
visualDensity: VisualDensity.compact,
|
||||||
|
tooltip: 'Open in browser',
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
|
||||||
|
// WebView content with lazy loading
|
||||||
|
AspectRatio(
|
||||||
|
aspectRatio: embedView.aspectRatio ?? 1,
|
||||||
|
child:
|
||||||
|
shouldLoad.value
|
||||||
|
? Stack(
|
||||||
|
children: [
|
||||||
|
InAppWebView(
|
||||||
|
initialUrlRequest: URLRequest(
|
||||||
|
url: WebUri(embedView.uri),
|
||||||
|
),
|
||||||
|
initialSettings: InAppWebViewSettings(
|
||||||
|
javaScriptEnabled: true,
|
||||||
|
mediaPlaybackRequiresUserGesture: false,
|
||||||
|
allowsInlineMediaPlayback: true,
|
||||||
|
useShouldOverrideUrlLoading: true,
|
||||||
|
useOnLoadResource: true,
|
||||||
|
supportZoom: false,
|
||||||
|
useWideViewPort: false,
|
||||||
|
loadWithOverviewMode: true,
|
||||||
|
builtInZoomControls: false,
|
||||||
|
displayZoomControls: false,
|
||||||
|
minimumFontSize: 12,
|
||||||
|
preferredContentMode:
|
||||||
|
UserPreferredContentMode.RECOMMENDED,
|
||||||
|
allowsBackForwardNavigationGestures: false,
|
||||||
|
allowsLinkPreview: false,
|
||||||
|
isInspectable: false,
|
||||||
|
),
|
||||||
|
onWebViewCreated: (controller) {
|
||||||
|
// Configure webview settings
|
||||||
|
controller.addJavaScriptHandler(
|
||||||
|
handlerName: 'onHeightChanged',
|
||||||
|
callback: (args) {
|
||||||
|
// Handle dynamic height changes if needed
|
||||||
|
},
|
||||||
|
);
|
||||||
|
},
|
||||||
|
onLoadStart: (controller, url) {
|
||||||
|
isLoading.value = true;
|
||||||
|
},
|
||||||
|
onLoadStop: (controller, url) async {
|
||||||
|
isLoading.value = false;
|
||||||
|
// Inject CSS to improve mobile display and remove borders
|
||||||
|
await controller.evaluateJavascript(
|
||||||
|
source: '''
|
||||||
|
// Remove unwanted elements
|
||||||
|
var elements = document.querySelectorAll('nav, header, footer, .ads, .advertisement, .sidebar');
|
||||||
|
for (var i = 0; i < elements.length; i++) {
|
||||||
|
elements[i].style.display = 'none';
|
||||||
|
}
|
||||||
|
|
||||||
|
// Remove borders from embedded content (YouTube, Vimeo, etc.)
|
||||||
|
var iframes = document.querySelectorAll('iframe');
|
||||||
|
for (var i = 0; i < iframes.length; i++) {
|
||||||
|
iframes[i].style.border = 'none';
|
||||||
|
iframes[i].style.borderRadius = '0';
|
||||||
|
}
|
||||||
|
|
||||||
|
// Remove borders from video elements
|
||||||
|
var videos = document.querySelectorAll('video');
|
||||||
|
for (var i = 0; i < videos.length; i++) {
|
||||||
|
videos[i].style.border = 'none';
|
||||||
|
videos[i].style.borderRadius = '0';
|
||||||
|
}
|
||||||
|
|
||||||
|
// Remove borders from any element that might have them
|
||||||
|
var allElements = document.querySelectorAll('*');
|
||||||
|
for (var i = 0; i < allElements.length; i++) {
|
||||||
|
if (allElements[i].style.border) {
|
||||||
|
allElements[i].style.border = 'none';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Improve readability
|
||||||
|
var body = document.body;
|
||||||
|
body.style.fontSize = '14px';
|
||||||
|
body.style.lineHeight = '1.4';
|
||||||
|
body.style.margin = '0';
|
||||||
|
body.style.padding = '0';
|
||||||
|
|
||||||
|
// Handle dynamic content
|
||||||
|
var observer = new MutationObserver(function(mutations) {
|
||||||
|
// Remove borders from newly added elements
|
||||||
|
var newIframes = document.querySelectorAll('iframe');
|
||||||
|
for (var i = 0; i < newIframes.length; i++) {
|
||||||
|
if (!newIframes[i].style.border || newIframes[i].style.border !== 'none') {
|
||||||
|
newIframes[i].style.border = 'none';
|
||||||
|
newIframes[i].style.borderRadius = '0';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
var newVideos = document.querySelectorAll('video');
|
||||||
|
for (var i = 0; i < newVideos.length; i++) {
|
||||||
|
if (!newVideos[i].style.border || newVideos[i].style.border !== 'none') {
|
||||||
|
newVideos[i].style.border = 'none';
|
||||||
|
newVideos[i].style.borderRadius = '0';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
window.flutter_inappwebview.callHandler('onHeightChanged', document.body.scrollHeight);
|
||||||
|
});
|
||||||
|
observer.observe(document.body, { childList: true, subtree: true });
|
||||||
|
''',
|
||||||
|
);
|
||||||
|
},
|
||||||
|
onLoadError: (controller, url, code, message) {
|
||||||
|
isLoading.value = false;
|
||||||
|
},
|
||||||
|
onLoadHttpError: (
|
||||||
|
controller,
|
||||||
|
url,
|
||||||
|
statusCode,
|
||||||
|
description,
|
||||||
|
) {
|
||||||
|
isLoading.value = false;
|
||||||
|
},
|
||||||
|
shouldOverrideUrlLoading: (
|
||||||
|
controller,
|
||||||
|
navigationAction,
|
||||||
|
) async {
|
||||||
|
final uri = navigationAction.request.url;
|
||||||
|
if (uri != null &&
|
||||||
|
uri.toString() != embedView.uri) {
|
||||||
|
// Open external links in browser
|
||||||
|
// You might want to use url_launcher here
|
||||||
|
return NavigationActionPolicy.CANCEL;
|
||||||
|
}
|
||||||
|
return NavigationActionPolicy.ALLOW;
|
||||||
|
},
|
||||||
|
onProgressChanged: (controller, progress) {
|
||||||
|
// Handle progress changes if needed
|
||||||
|
},
|
||||||
|
onConsoleMessage: (controller, consoleMessage) {
|
||||||
|
// Handle console messages for debugging
|
||||||
|
debugPrint(
|
||||||
|
'WebView Console: ${consoleMessage.message}',
|
||||||
|
);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
if (isLoading.value)
|
||||||
|
Container(
|
||||||
|
color: colorScheme.surfaceContainerLowest,
|
||||||
|
child: const Center(
|
||||||
|
child: CircularProgressIndicator(),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
)
|
||||||
|
: GestureDetector(
|
||||||
|
onTap: () {
|
||||||
|
shouldLoad.value = true;
|
||||||
|
},
|
||||||
|
child: Container(
|
||||||
|
color: colorScheme.surfaceContainerLowest,
|
||||||
|
child: Column(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
|
children: [
|
||||||
|
Icon(
|
||||||
|
Symbols.play_arrow,
|
||||||
|
size: 48,
|
||||||
|
color: colorScheme.onSurfaceVariant.withOpacity(
|
||||||
|
0.6,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
const SizedBox(height: 8),
|
||||||
|
Text(
|
||||||
|
'Tap to load content',
|
||||||
|
style: theme.textTheme.bodyMedium?.copyWith(
|
||||||
|
color: colorScheme.onSurfaceVariant
|
||||||
|
.withOpacity(0.6),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
String _getUriDisplay(String uri) {
|
||||||
|
try {
|
||||||
|
final parsedUri = Uri.parse(uri);
|
||||||
|
return parsedUri.host.isNotEmpty ? parsedUri.host : uri;
|
||||||
|
} catch (e) {
|
||||||
|
return uri;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
164
lib/widgets/post/post_award_history_sheet.dart
Normal file
164
lib/widgets/post/post_award_history_sheet.dart
Normal file
@@ -0,0 +1,164 @@
|
|||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||||
|
import 'package:island/models/post.dart';
|
||||||
|
import 'package:island/pods/network.dart';
|
||||||
|
import 'package:island/widgets/content/sheet.dart';
|
||||||
|
import 'package:riverpod_annotation/riverpod_annotation.dart';
|
||||||
|
import 'package:riverpod_paging_utils/riverpod_paging_utils.dart';
|
||||||
|
|
||||||
|
part 'post_award_history_sheet.g.dart';
|
||||||
|
|
||||||
|
@riverpod
|
||||||
|
class PostAwardListNotifier extends _$PostAwardListNotifier
|
||||||
|
with CursorPagingNotifierMixin<SnPostAward> {
|
||||||
|
static const int _pageSize = 20;
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future<CursorPagingData<SnPostAward>> build({required String postId}) {
|
||||||
|
return fetch(cursor: null);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future<CursorPagingData<SnPostAward>> fetch({required String? cursor}) async {
|
||||||
|
final client = ref.read(apiClientProvider);
|
||||||
|
final offset = cursor == null ? 0 : int.parse(cursor);
|
||||||
|
|
||||||
|
final queryParams = {'offset': offset, 'take': _pageSize};
|
||||||
|
|
||||||
|
final response = await client.get(
|
||||||
|
'/sphere/posts/$postId/awards',
|
||||||
|
queryParameters: queryParams,
|
||||||
|
);
|
||||||
|
final total = int.parse(response.headers.value('X-Total') ?? '0');
|
||||||
|
final List<dynamic> data = response.data;
|
||||||
|
final awards = data.map((json) => SnPostAward.fromJson(json)).toList();
|
||||||
|
|
||||||
|
final hasMore = offset + awards.length < total;
|
||||||
|
final nextCursor = hasMore ? (offset + awards.length).toString() : null;
|
||||||
|
|
||||||
|
return CursorPagingData(
|
||||||
|
items: awards,
|
||||||
|
hasMore: hasMore,
|
||||||
|
nextCursor: nextCursor,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class PostAwardHistorySheet extends HookConsumerWidget {
|
||||||
|
final String postId;
|
||||||
|
|
||||||
|
const PostAwardHistorySheet({super.key, required this.postId});
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context, WidgetRef ref) {
|
||||||
|
final provider = postAwardListNotifierProvider(postId: postId);
|
||||||
|
|
||||||
|
return SheetScaffold(
|
||||||
|
titleText: 'Award History',
|
||||||
|
child: PagingHelperView(
|
||||||
|
provider: provider,
|
||||||
|
futureRefreshable: provider.future,
|
||||||
|
notifierRefreshable: provider.notifier,
|
||||||
|
contentBuilder:
|
||||||
|
(data, widgetCount, endItemView) => ListView.builder(
|
||||||
|
itemCount: widgetCount,
|
||||||
|
itemBuilder: (context, index) {
|
||||||
|
if (index == widgetCount - 1) {
|
||||||
|
return endItemView;
|
||||||
|
}
|
||||||
|
|
||||||
|
final award = data.items[index];
|
||||||
|
return Column(
|
||||||
|
children: [
|
||||||
|
PostAwardItem(award: award),
|
||||||
|
const Divider(height: 1),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class PostAwardItem extends StatelessWidget {
|
||||||
|
final SnPostAward award;
|
||||||
|
|
||||||
|
const PostAwardItem({super.key, required this.award});
|
||||||
|
|
||||||
|
String _getAttitudeText(int attitude) {
|
||||||
|
switch (attitude) {
|
||||||
|
case 0:
|
||||||
|
return 'Positive';
|
||||||
|
case 2:
|
||||||
|
return 'Negative';
|
||||||
|
default:
|
||||||
|
return 'Neutral';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Color _getAttitudeColor(int attitude, BuildContext context) {
|
||||||
|
switch (attitude) {
|
||||||
|
case 0:
|
||||||
|
return Colors.green;
|
||||||
|
case 2:
|
||||||
|
return Colors.red;
|
||||||
|
default:
|
||||||
|
return Theme.of(context).colorScheme.onSurfaceVariant;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return ListTile(
|
||||||
|
leading: CircleAvatar(
|
||||||
|
backgroundColor: _getAttitudeColor(
|
||||||
|
award.attitude,
|
||||||
|
context,
|
||||||
|
).withOpacity(0.1),
|
||||||
|
child: Icon(
|
||||||
|
award.attitude == 0
|
||||||
|
? Icons.thumb_up
|
||||||
|
: award.attitude == 2
|
||||||
|
? Icons.thumb_down
|
||||||
|
: Icons.thumbs_up_down,
|
||||||
|
color: _getAttitudeColor(award.attitude, context),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
title: Text(
|
||||||
|
'${award.amount} pts',
|
||||||
|
style: Theme.of(
|
||||||
|
context,
|
||||||
|
).textTheme.titleMedium?.copyWith(fontWeight: FontWeight.w600),
|
||||||
|
),
|
||||||
|
subtitle: Column(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
Text(
|
||||||
|
_getAttitudeText(award.attitude),
|
||||||
|
style: TextStyle(
|
||||||
|
color: _getAttitudeColor(award.attitude, context),
|
||||||
|
fontWeight: FontWeight.w500,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
if (award.message != null && award.message!.isNotEmpty) ...[
|
||||||
|
const SizedBox(height: 4),
|
||||||
|
Text(award.message!, style: Theme.of(context).textTheme.bodyMedium),
|
||||||
|
],
|
||||||
|
const SizedBox(height: 2),
|
||||||
|
if (award.createdAt != null) ...[
|
||||||
|
const SizedBox(height: 2),
|
||||||
|
Text(
|
||||||
|
award.createdAt!.toLocal().toString().split('.')[0],
|
||||||
|
style: Theme.of(context).textTheme.bodySmall?.copyWith(
|
||||||
|
color: Theme.of(context).colorScheme.onSurfaceVariant,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
],
|
||||||
|
),
|
||||||
|
isThreeLine: award.message != null && award.message!.isNotEmpty,
|
||||||
|
contentPadding: const EdgeInsets.symmetric(horizontal: 16, vertical: 8),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
180
lib/widgets/post/post_award_history_sheet.g.dart
Normal file
180
lib/widgets/post/post_award_history_sheet.g.dart
Normal file
@@ -0,0 +1,180 @@
|
|||||||
|
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||||
|
|
||||||
|
part of 'post_award_history_sheet.dart';
|
||||||
|
|
||||||
|
// **************************************************************************
|
||||||
|
// RiverpodGenerator
|
||||||
|
// **************************************************************************
|
||||||
|
|
||||||
|
String _$postAwardListNotifierHash() =>
|
||||||
|
r'492ae59a5dbbfb5c98f863f036023193b6e08668';
|
||||||
|
|
||||||
|
/// Copied from Dart SDK
|
||||||
|
class _SystemHash {
|
||||||
|
_SystemHash._();
|
||||||
|
|
||||||
|
static int combine(int hash, int value) {
|
||||||
|
// ignore: parameter_assignments
|
||||||
|
hash = 0x1fffffff & (hash + value);
|
||||||
|
// ignore: parameter_assignments
|
||||||
|
hash = 0x1fffffff & (hash + ((0x0007ffff & hash) << 10));
|
||||||
|
return hash ^ (hash >> 6);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int finish(int hash) {
|
||||||
|
// ignore: parameter_assignments
|
||||||
|
hash = 0x1fffffff & (hash + ((0x03ffffff & hash) << 3));
|
||||||
|
// ignore: parameter_assignments
|
||||||
|
hash = hash ^ (hash >> 11);
|
||||||
|
return 0x1fffffff & (hash + ((0x00003fff & hash) << 15));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
abstract class _$PostAwardListNotifier
|
||||||
|
extends BuildlessAutoDisposeAsyncNotifier<CursorPagingData<SnPostAward>> {
|
||||||
|
late final String postId;
|
||||||
|
|
||||||
|
FutureOr<CursorPagingData<SnPostAward>> build({required String postId});
|
||||||
|
}
|
||||||
|
|
||||||
|
/// See also [PostAwardListNotifier].
|
||||||
|
@ProviderFor(PostAwardListNotifier)
|
||||||
|
const postAwardListNotifierProvider = PostAwardListNotifierFamily();
|
||||||
|
|
||||||
|
/// See also [PostAwardListNotifier].
|
||||||
|
class PostAwardListNotifierFamily
|
||||||
|
extends Family<AsyncValue<CursorPagingData<SnPostAward>>> {
|
||||||
|
/// See also [PostAwardListNotifier].
|
||||||
|
const PostAwardListNotifierFamily();
|
||||||
|
|
||||||
|
/// See also [PostAwardListNotifier].
|
||||||
|
PostAwardListNotifierProvider call({required String postId}) {
|
||||||
|
return PostAwardListNotifierProvider(postId: postId);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
PostAwardListNotifierProvider getProviderOverride(
|
||||||
|
covariant PostAwardListNotifierProvider provider,
|
||||||
|
) {
|
||||||
|
return call(postId: provider.postId);
|
||||||
|
}
|
||||||
|
|
||||||
|
static const Iterable<ProviderOrFamily>? _dependencies = null;
|
||||||
|
|
||||||
|
@override
|
||||||
|
Iterable<ProviderOrFamily>? get dependencies => _dependencies;
|
||||||
|
|
||||||
|
static const Iterable<ProviderOrFamily>? _allTransitiveDependencies = null;
|
||||||
|
|
||||||
|
@override
|
||||||
|
Iterable<ProviderOrFamily>? get allTransitiveDependencies =>
|
||||||
|
_allTransitiveDependencies;
|
||||||
|
|
||||||
|
@override
|
||||||
|
String? get name => r'postAwardListNotifierProvider';
|
||||||
|
}
|
||||||
|
|
||||||
|
/// See also [PostAwardListNotifier].
|
||||||
|
class PostAwardListNotifierProvider
|
||||||
|
extends
|
||||||
|
AutoDisposeAsyncNotifierProviderImpl<
|
||||||
|
PostAwardListNotifier,
|
||||||
|
CursorPagingData<SnPostAward>
|
||||||
|
> {
|
||||||
|
/// See also [PostAwardListNotifier].
|
||||||
|
PostAwardListNotifierProvider({required String postId})
|
||||||
|
: this._internal(
|
||||||
|
() => PostAwardListNotifier()..postId = postId,
|
||||||
|
from: postAwardListNotifierProvider,
|
||||||
|
name: r'postAwardListNotifierProvider',
|
||||||
|
debugGetCreateSourceHash:
|
||||||
|
const bool.fromEnvironment('dart.vm.product')
|
||||||
|
? null
|
||||||
|
: _$postAwardListNotifierHash,
|
||||||
|
dependencies: PostAwardListNotifierFamily._dependencies,
|
||||||
|
allTransitiveDependencies:
|
||||||
|
PostAwardListNotifierFamily._allTransitiveDependencies,
|
||||||
|
postId: postId,
|
||||||
|
);
|
||||||
|
|
||||||
|
PostAwardListNotifierProvider._internal(
|
||||||
|
super._createNotifier, {
|
||||||
|
required super.name,
|
||||||
|
required super.dependencies,
|
||||||
|
required super.allTransitiveDependencies,
|
||||||
|
required super.debugGetCreateSourceHash,
|
||||||
|
required super.from,
|
||||||
|
required this.postId,
|
||||||
|
}) : super.internal();
|
||||||
|
|
||||||
|
final String postId;
|
||||||
|
|
||||||
|
@override
|
||||||
|
FutureOr<CursorPagingData<SnPostAward>> runNotifierBuild(
|
||||||
|
covariant PostAwardListNotifier notifier,
|
||||||
|
) {
|
||||||
|
return notifier.build(postId: postId);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Override overrideWith(PostAwardListNotifier Function() create) {
|
||||||
|
return ProviderOverride(
|
||||||
|
origin: this,
|
||||||
|
override: PostAwardListNotifierProvider._internal(
|
||||||
|
() => create()..postId = postId,
|
||||||
|
from: from,
|
||||||
|
name: null,
|
||||||
|
dependencies: null,
|
||||||
|
allTransitiveDependencies: null,
|
||||||
|
debugGetCreateSourceHash: null,
|
||||||
|
postId: postId,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
AutoDisposeAsyncNotifierProviderElement<
|
||||||
|
PostAwardListNotifier,
|
||||||
|
CursorPagingData<SnPostAward>
|
||||||
|
>
|
||||||
|
createElement() {
|
||||||
|
return _PostAwardListNotifierProviderElement(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
bool operator ==(Object other) {
|
||||||
|
return other is PostAwardListNotifierProvider && other.postId == postId;
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
int get hashCode {
|
||||||
|
var hash = _SystemHash.combine(0, runtimeType.hashCode);
|
||||||
|
hash = _SystemHash.combine(hash, postId.hashCode);
|
||||||
|
|
||||||
|
return _SystemHash.finish(hash);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Deprecated('Will be removed in 3.0. Use Ref instead')
|
||||||
|
// ignore: unused_element
|
||||||
|
mixin PostAwardListNotifierRef
|
||||||
|
on AutoDisposeAsyncNotifierProviderRef<CursorPagingData<SnPostAward>> {
|
||||||
|
/// The parameter `postId` of this provider.
|
||||||
|
String get postId;
|
||||||
|
}
|
||||||
|
|
||||||
|
class _PostAwardListNotifierProviderElement
|
||||||
|
extends
|
||||||
|
AutoDisposeAsyncNotifierProviderElement<
|
||||||
|
PostAwardListNotifier,
|
||||||
|
CursorPagingData<SnPostAward>
|
||||||
|
>
|
||||||
|
with PostAwardListNotifierRef {
|
||||||
|
_PostAwardListNotifierProviderElement(super.provider);
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get postId => (origin as PostAwardListNotifierProvider).postId;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ignore_for_file: type=lint
|
||||||
|
// ignore_for_file: subtype_of_sealed_class, invalid_use_of_internal_member, invalid_use_of_visible_for_testing_member, deprecated_member_use_from_same_package
|
287
lib/widgets/post/post_award_sheet.dart
Normal file
287
lib/widgets/post/post_award_sheet.dart
Normal file
@@ -0,0 +1,287 @@
|
|||||||
|
import 'package:easy_localization/easy_localization.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter_hooks/flutter_hooks.dart';
|
||||||
|
import 'package:gap/gap.dart';
|
||||||
|
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||||
|
import 'package:island/models/post.dart';
|
||||||
|
import 'package:island/models/wallet.dart';
|
||||||
|
import 'package:island/pods/network.dart';
|
||||||
|
import 'package:island/widgets/alert.dart';
|
||||||
|
import 'package:island/widgets/content/cloud_files.dart';
|
||||||
|
import 'package:island/widgets/content/sheet.dart';
|
||||||
|
import 'package:island/widgets/payment/payment_overlay.dart';
|
||||||
|
import 'package:material_symbols_icons/symbols.dart';
|
||||||
|
|
||||||
|
class PostAwardSheet extends HookConsumerWidget {
|
||||||
|
final SnPost post;
|
||||||
|
const PostAwardSheet({super.key, required this.post});
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context, WidgetRef ref) {
|
||||||
|
final messageController = useTextEditingController();
|
||||||
|
final amountController = useTextEditingController();
|
||||||
|
final selectedAttitude = useState<int>(0); // 0 for positive, 2 for negative
|
||||||
|
|
||||||
|
return SheetScaffold(
|
||||||
|
titleText: 'awardPost'.tr(),
|
||||||
|
child: SingleChildScrollView(
|
||||||
|
padding: const EdgeInsets.all(16.0),
|
||||||
|
child: Column(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.stretch,
|
||||||
|
children: [
|
||||||
|
// Post Preview Section
|
||||||
|
_buildPostPreview(context),
|
||||||
|
const Gap(20),
|
||||||
|
|
||||||
|
// Award Result Explanation
|
||||||
|
_buildAwardResultExplanation(context),
|
||||||
|
const Gap(20),
|
||||||
|
|
||||||
|
Text(
|
||||||
|
'awardMessage'.tr(),
|
||||||
|
style: Theme.of(context).textTheme.titleMedium,
|
||||||
|
),
|
||||||
|
const Gap(8),
|
||||||
|
TextField(
|
||||||
|
controller: messageController,
|
||||||
|
maxLines: 3,
|
||||||
|
decoration: InputDecoration(
|
||||||
|
hintText: 'awardMessageHint'.tr(),
|
||||||
|
border: const OutlineInputBorder(
|
||||||
|
borderRadius: BorderRadius.all(Radius.circular(16)),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
const Gap(16),
|
||||||
|
Text(
|
||||||
|
'awardAttitude'.tr(),
|
||||||
|
style: Theme.of(context).textTheme.titleMedium,
|
||||||
|
),
|
||||||
|
const Gap(8),
|
||||||
|
SegmentedButton<int>(
|
||||||
|
segments: [
|
||||||
|
ButtonSegment<int>(
|
||||||
|
value: 0,
|
||||||
|
label: Text('awardAttitudePositive'.tr()),
|
||||||
|
icon: const Icon(Symbols.thumb_up),
|
||||||
|
),
|
||||||
|
ButtonSegment<int>(
|
||||||
|
value: 2,
|
||||||
|
label: Text('awardAttitudeNegative'.tr()),
|
||||||
|
icon: const Icon(Symbols.thumb_down),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
selected: {selectedAttitude.value},
|
||||||
|
onSelectionChanged: (Set<int> selection) {
|
||||||
|
selectedAttitude.value = selection.first;
|
||||||
|
},
|
||||||
|
),
|
||||||
|
const Gap(16),
|
||||||
|
Text(
|
||||||
|
'awardAmount'.tr(),
|
||||||
|
style: Theme.of(context).textTheme.titleMedium,
|
||||||
|
),
|
||||||
|
const Gap(8),
|
||||||
|
TextField(
|
||||||
|
controller: amountController,
|
||||||
|
keyboardType: TextInputType.number,
|
||||||
|
decoration: InputDecoration(
|
||||||
|
hintText: 'awardAmountHint'.tr(),
|
||||||
|
border: const OutlineInputBorder(
|
||||||
|
borderRadius: BorderRadius.all(Radius.circular(16)),
|
||||||
|
),
|
||||||
|
suffixText: 'NSP',
|
||||||
|
),
|
||||||
|
),
|
||||||
|
const Gap(24),
|
||||||
|
SizedBox(
|
||||||
|
width: double.infinity,
|
||||||
|
child: FilledButton.icon(
|
||||||
|
onPressed:
|
||||||
|
() => _submitAward(
|
||||||
|
context,
|
||||||
|
ref,
|
||||||
|
messageController,
|
||||||
|
amountController,
|
||||||
|
selectedAttitude.value,
|
||||||
|
),
|
||||||
|
icon: const Icon(Symbols.star),
|
||||||
|
label: Text('awardSubmit'.tr()),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget _buildPostPreview(BuildContext context) {
|
||||||
|
return Container(
|
||||||
|
padding: const EdgeInsets.all(12),
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: Theme.of(context).colorScheme.surfaceContainerHighest,
|
||||||
|
borderRadius: BorderRadius.circular(12),
|
||||||
|
border: Border.all(
|
||||||
|
color: Theme.of(context).colorScheme.outline.withOpacity(0.2),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
child: Column(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
Row(
|
||||||
|
children: [
|
||||||
|
Icon(
|
||||||
|
Symbols.article,
|
||||||
|
size: 20,
|
||||||
|
color: Theme.of(context).colorScheme.primary,
|
||||||
|
),
|
||||||
|
const Gap(8),
|
||||||
|
Text(
|
||||||
|
'awardPostPreview'.tr(),
|
||||||
|
style: Theme.of(
|
||||||
|
context,
|
||||||
|
).textTheme.titleSmall?.copyWith(fontWeight: FontWeight.w600),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
const Gap(8),
|
||||||
|
Text(
|
||||||
|
post.content ?? 'awardNoContent'.tr(),
|
||||||
|
maxLines: 2,
|
||||||
|
overflow: TextOverflow.ellipsis,
|
||||||
|
style: Theme.of(context).textTheme.bodyMedium,
|
||||||
|
),
|
||||||
|
...[
|
||||||
|
const Gap(4),
|
||||||
|
Row(
|
||||||
|
spacing: 6,
|
||||||
|
children: [
|
||||||
|
Text(
|
||||||
|
'awardByPublisher'.tr(args: ['@${post.publisher.name}']),
|
||||||
|
style: Theme.of(context).textTheme.bodySmall?.copyWith(
|
||||||
|
color: Theme.of(context).colorScheme.onSurfaceVariant,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
ProfilePictureWidget(file: post.publisher.picture, radius: 8),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
],
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget _buildAwardResultExplanation(BuildContext context) {
|
||||||
|
return Container(
|
||||||
|
padding: const EdgeInsets.all(12),
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: Theme.of(context).colorScheme.primaryContainer.withOpacity(0.3),
|
||||||
|
borderRadius: BorderRadius.circular(12),
|
||||||
|
border: Border.all(
|
||||||
|
color: Theme.of(context).colorScheme.primary.withOpacity(0.2),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
child: Column(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
Row(
|
||||||
|
children: [
|
||||||
|
Icon(
|
||||||
|
Symbols.info,
|
||||||
|
size: 20,
|
||||||
|
color: Theme.of(context).colorScheme.primary,
|
||||||
|
),
|
||||||
|
const Gap(8),
|
||||||
|
Text(
|
||||||
|
'awardBenefits'.tr(),
|
||||||
|
style: Theme.of(context).textTheme.titleSmall?.copyWith(
|
||||||
|
fontWeight: FontWeight.w600,
|
||||||
|
color: Theme.of(context).colorScheme.primary,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
const Gap(8),
|
||||||
|
Text(
|
||||||
|
'awardBenefitsDescription'.tr(),
|
||||||
|
style: Theme.of(context).textTheme.bodySmall?.copyWith(
|
||||||
|
color: Theme.of(context).colorScheme.onSurfaceVariant,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> _submitAward(
|
||||||
|
BuildContext context,
|
||||||
|
WidgetRef ref,
|
||||||
|
TextEditingController messageController,
|
||||||
|
TextEditingController amountController,
|
||||||
|
int selectedAttitude,
|
||||||
|
) async {
|
||||||
|
// Get values from controllers
|
||||||
|
final message = messageController.text.trim();
|
||||||
|
final amountText = amountController.text.trim();
|
||||||
|
|
||||||
|
// Validate inputs
|
||||||
|
if (amountText.isEmpty) {
|
||||||
|
showSnackBar('awardAmountRequired'.tr());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
final amount = double.tryParse(amountText);
|
||||||
|
if (amount == null || amount <= 0) {
|
||||||
|
showSnackBar('awardAmountInvalid'.tr());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (message.length > 4096) {
|
||||||
|
showSnackBar('awardMessageTooLong'.tr());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
showLoadingModal(context);
|
||||||
|
|
||||||
|
final client = ref.read(apiClientProvider);
|
||||||
|
|
||||||
|
// Send award request
|
||||||
|
final awardResponse = await client.post(
|
||||||
|
'/sphere/posts/${post.id}/awards',
|
||||||
|
data: {
|
||||||
|
'amount': amount,
|
||||||
|
'attitude': selectedAttitude,
|
||||||
|
if (message.isNotEmpty) 'message': message,
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
final orderId = awardResponse.data['order_id'] as String;
|
||||||
|
|
||||||
|
// Fetch order details
|
||||||
|
final orderResponse = await client.get('/id/orders/$orderId');
|
||||||
|
final order = SnWalletOrder.fromJson(orderResponse.data);
|
||||||
|
|
||||||
|
if (context.mounted) {
|
||||||
|
hideLoadingModal(context);
|
||||||
|
|
||||||
|
// Show payment overlay
|
||||||
|
final paidOrder = await PaymentOverlay.show(
|
||||||
|
context: context,
|
||||||
|
order: order,
|
||||||
|
enableBiometric: true,
|
||||||
|
);
|
||||||
|
|
||||||
|
if (paidOrder != null && context.mounted) {
|
||||||
|
showSnackBar('awardSuccess'.tr());
|
||||||
|
Navigator.of(context).pop();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
if (context.mounted) {
|
||||||
|
hideLoadingModal(context);
|
||||||
|
showErrorAlert(err);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@@ -18,8 +18,10 @@ import 'package:island/screens/posts/compose.dart';
|
|||||||
import 'package:island/widgets/alert.dart';
|
import 'package:island/widgets/alert.dart';
|
||||||
import 'package:island/widgets/content/markdown.dart';
|
import 'package:island/widgets/content/markdown.dart';
|
||||||
import 'package:island/widgets/post/post_item_screenshot.dart';
|
import 'package:island/widgets/post/post_item_screenshot.dart';
|
||||||
|
import 'package:island/widgets/post/post_award_sheet.dart';
|
||||||
import 'package:island/widgets/post/post_pin_sheet.dart';
|
import 'package:island/widgets/post/post_pin_sheet.dart';
|
||||||
import 'package:island/widgets/post/post_shared.dart';
|
import 'package:island/widgets/post/post_shared.dart';
|
||||||
|
import 'package:island/widgets/post/embed_view_renderer.dart';
|
||||||
import 'package:island/widgets/safety/abuse_report_helper.dart';
|
import 'package:island/widgets/safety/abuse_report_helper.dart';
|
||||||
import 'package:island/widgets/share/share_sheet.dart';
|
import 'package:island/widgets/share/share_sheet.dart';
|
||||||
import 'package:material_symbols_icons/symbols.dart';
|
import 'package:material_symbols_icons/symbols.dart';
|
||||||
@@ -245,6 +247,18 @@ class PostActionableItem extends HookConsumerWidget {
|
|||||||
);
|
);
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
|
MenuAction(
|
||||||
|
title: 'award'.tr(),
|
||||||
|
image: MenuImage.icon(Symbols.star),
|
||||||
|
callback: () {
|
||||||
|
showModalBottomSheet(
|
||||||
|
context: context,
|
||||||
|
isScrollControlled: true,
|
||||||
|
useRootNavigator: true,
|
||||||
|
builder: (context) => PostAwardSheet(post: item),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
),
|
||||||
MenuSeparator(),
|
MenuSeparator(),
|
||||||
MenuAction(
|
MenuAction(
|
||||||
title: 'share'.tr(),
|
title: 'share'.tr(),
|
||||||
@@ -422,6 +436,7 @@ class PostItem extends HookConsumerWidget {
|
|||||||
MarkdownTextContent(
|
MarkdownTextContent(
|
||||||
content: translatedText.value!,
|
content: translatedText.value!,
|
||||||
isSelectable: isTextSelectable,
|
isSelectable: isTextSelectable,
|
||||||
|
attachments: item.attachments,
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
@@ -536,6 +551,12 @@ class PostItem extends HookConsumerWidget {
|
|||||||
translationSection: translationSection,
|
translationSection: translationSection,
|
||||||
renderingPadding: renderingPadding,
|
renderingPadding: renderingPadding,
|
||||||
),
|
),
|
||||||
|
if (item.embedView != null)
|
||||||
|
EmbedViewRenderer(
|
||||||
|
embedView: item.embedView!,
|
||||||
|
maxHeight: 400,
|
||||||
|
borderRadius: BorderRadius.circular(12),
|
||||||
|
).padding(horizontal: renderingPadding.horizontal, vertical: 8),
|
||||||
if (isShowReference)
|
if (isShowReference)
|
||||||
ReferencedPostWidget(item: item, renderingPadding: renderingPadding),
|
ReferencedPostWidget(item: item, renderingPadding: renderingPadding),
|
||||||
if (item.repliesCount > 0 && isEmbedReply)
|
if (item.repliesCount > 0 && isEmbedReply)
|
||||||
|
@@ -141,6 +141,7 @@ class PostReplyPreview extends HookConsumerWidget {
|
|||||||
Expanded(
|
Expanded(
|
||||||
child: MarkdownTextContent(
|
child: MarkdownTextContent(
|
||||||
content: post.content!,
|
content: post.content!,
|
||||||
|
attachments: post.attachments,
|
||||||
).padding(top: 2),
|
).padding(top: 2),
|
||||||
)
|
)
|
||||||
else
|
else
|
||||||
@@ -210,6 +211,7 @@ class PostReplyPreview extends HookConsumerWidget {
|
|||||||
Expanded(
|
Expanded(
|
||||||
child: MarkdownTextContent(
|
child: MarkdownTextContent(
|
||||||
content: data.value!.content!,
|
content: data.value!.content!,
|
||||||
|
attachments: data.value!.attachments,
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
else
|
else
|
||||||
@@ -745,7 +747,10 @@ class PostBody extends ConsumerWidget {
|
|||||||
style: Theme.of(context).textTheme.bodyMedium,
|
style: Theme.of(context).textTheme.bodyMedium,
|
||||||
)
|
)
|
||||||
else
|
else
|
||||||
MarkdownTextContent(content: '${item.content!}...'),
|
MarkdownTextContent(
|
||||||
|
content: '${item.content!}...',
|
||||||
|
attachments: item.attachments,
|
||||||
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
@@ -784,6 +789,7 @@ class PostBody extends ConsumerWidget {
|
|||||||
? '${item.content!}...'
|
? '${item.content!}...'
|
||||||
: item.content ?? '',
|
: item.content ?? '',
|
||||||
isSelectable: isTextSelectable,
|
isSelectable: isTextSelectable,
|
||||||
|
attachments: item.attachments,
|
||||||
),
|
),
|
||||||
if (translationSection != null) translationSection!,
|
if (translationSection != null) translationSection!,
|
||||||
],
|
],
|
||||||
@@ -900,6 +906,7 @@ class PostBody extends ConsumerWidget {
|
|||||||
poll: SnPollWithStats.fromJson(embedData['poll']),
|
poll: SnPollWithStats.fromJson(embedData['poll']),
|
||||||
onSubmit: (_) {},
|
onSubmit: (_) {},
|
||||||
isReadonly: !isInteractive,
|
isReadonly: !isInteractive,
|
||||||
|
isInitiallyExpanded: isFullPost,
|
||||||
).padding(horizontal: 16, vertical: 12),
|
).padding(horizontal: 16, vertical: 12),
|
||||||
),
|
),
|
||||||
_ => Text('Unable show embed: ${embedData['type']}'),
|
_ => Text('Unable show embed: ${embedData['type']}'),
|
||||||
|
12
pubspec.lock
12
pubspec.lock
@@ -485,10 +485,10 @@ packages:
|
|||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
name: drift_flutter
|
name: drift_flutter
|
||||||
sha256: ccfb42bc942e59f81500b16228df59cf8eb40d2fbd96637ff677df923350af7b
|
sha256: b52bd710f809db11e25259d429d799d034ba1c5224ce6a73fe8419feb980d44c
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.2.5"
|
version: "0.2.6"
|
||||||
dropdown_button2:
|
dropdown_button2:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
@@ -2206,7 +2206,7 @@ packages:
|
|||||||
source: hosted
|
source: hosted
|
||||||
version: "2.4.1"
|
version: "2.4.1"
|
||||||
shelf:
|
shelf:
|
||||||
dependency: transitive
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
name: shelf
|
name: shelf
|
||||||
sha256: e7dd780a7ffb623c57850b33f43309312fc863fb6aa3d276a754bb299839ef12
|
sha256: e7dd780a7ffb623c57850b33f43309312fc863fb6aa3d276a754bb299839ef12
|
||||||
@@ -2214,7 +2214,7 @@ packages:
|
|||||||
source: hosted
|
source: hosted
|
||||||
version: "1.4.2"
|
version: "1.4.2"
|
||||||
shelf_web_socket:
|
shelf_web_socket:
|
||||||
dependency: transitive
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
name: shelf_web_socket
|
name: shelf_web_socket
|
||||||
sha256: "3632775c8e90d6c9712f883e633716432a27758216dfb61bd86a8321c0580925"
|
sha256: "3632775c8e90d6c9712f883e633716432a27758216dfb61bd86a8321c0580925"
|
||||||
@@ -2760,10 +2760,10 @@ packages:
|
|||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: webrtc_interface
|
name: webrtc_interface
|
||||||
sha256: "86fe3afc81a08481dfb25cf14a5a94e27062ecef25544783f352c914e0bbc1ca"
|
sha256: "2e604a31703ad26781782fb14fa8a4ee621154ee2c513d2b9938e486fa695233"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.2.2+hotfix.2"
|
version: "1.3.0"
|
||||||
win32:
|
win32:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
@@ -16,7 +16,7 @@ publish_to: "none" # Remove this line if you wish to publish to pub.dev
|
|||||||
# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html
|
# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html
|
||||||
# In Windows, build-name is used as the major, minor, and patch parts
|
# In Windows, build-name is used as the major, minor, and patch parts
|
||||||
# of the product and file versions while build-number is used as the build suffix.
|
# of the product and file versions while build-number is used as the build suffix.
|
||||||
version: 3.2.0+131
|
version: 3.2.0+132
|
||||||
|
|
||||||
environment:
|
environment:
|
||||||
sdk: ^3.7.2
|
sdk: ^3.7.2
|
||||||
@@ -85,7 +85,7 @@ dependencies:
|
|||||||
web_socket_channel: ^3.0.3
|
web_socket_channel: ^3.0.3
|
||||||
material_symbols_icons: ^4.2872.0
|
material_symbols_icons: ^4.2872.0
|
||||||
drift: ^2.28.1
|
drift: ^2.28.1
|
||||||
drift_flutter: ^0.2.5
|
drift_flutter: ^0.2.6
|
||||||
path: ^1.9.1
|
path: ^1.9.1
|
||||||
collection: ^1.19.1
|
collection: ^1.19.1
|
||||||
markdown_editor_plus: ^0.2.15
|
markdown_editor_plus: ^0.2.15
|
||||||
@@ -133,7 +133,7 @@ dependencies:
|
|||||||
waveform_flutter: ^1.2.0
|
waveform_flutter: ^1.2.0
|
||||||
flutter_app_update: ^3.2.2
|
flutter_app_update: ^3.2.2
|
||||||
archive: ^4.0.7
|
archive: ^4.0.7
|
||||||
process_run: ^1.2.0
|
process_run: ^1.2.4
|
||||||
firebase_crashlytics: ^5.0.1
|
firebase_crashlytics: ^5.0.1
|
||||||
firebase_analytics: ^12.0.1
|
firebase_analytics: ^12.0.1
|
||||||
material_color_utilities: ^0.11.1
|
material_color_utilities: ^0.11.1
|
||||||
@@ -145,6 +145,8 @@ dependencies:
|
|||||||
flutter_local_notifications: ^19.4.1
|
flutter_local_notifications: ^19.4.1
|
||||||
wakelock_plus: ^1.3.2
|
wakelock_plus: ^1.3.2
|
||||||
slide_countdown: ^2.0.2
|
slide_countdown: ^2.0.2
|
||||||
|
shelf: ^1.4.2
|
||||||
|
shelf_web_socket: ^3.0.0
|
||||||
|
|
||||||
dev_dependencies:
|
dev_dependencies:
|
||||||
flutter_test:
|
flutter_test:
|
||||||
|
Reference in New Issue
Block a user