From 356d3d4d3ece405b5318c04c0132b567fc96bb7f Mon Sep 17 00:00:00 2001
From: LittleSheep <littlesheep.code@hotmail.com>
Date: Tue, 26 Nov 2024 00:00:09 +0800
Subject: [PATCH] :refactor: Central post fetching logic

---
 lib/controllers/post_write_controller.dart |  39 ++-----
 lib/main.dart                              |   2 +
 lib/providers/post.dart                    | 119 +++++++++++++++++++++
 lib/screens/explore.dart                   |  34 +-----
 lib/screens/post/post_detail.dart          |  18 +---
 lib/screens/post/post_search.dart          |  39 ++-----
 lib/types/post.dart                        |   1 +
 lib/types/post.freezed.dart                |  53 +++++++--
 lib/types/post.g.dart                      |   4 +
 lib/widgets/post/post_comment_list.dart    |  37 +------
 10 files changed, 206 insertions(+), 140 deletions(-)
 create mode 100644 lib/providers/post.dart

diff --git a/lib/controllers/post_write_controller.dart b/lib/controllers/post_write_controller.dart
index 88fc89a..0c6b27c 100644
--- a/lib/controllers/post_write_controller.dart
+++ b/lib/controllers/post_write_controller.dart
@@ -6,6 +6,7 @@ import 'package:flutter/material.dart';
 import 'package:image_picker/image_picker.dart';
 import 'package:mime/mime.dart';
 import 'package:provider/provider.dart';
+import 'package:surface/providers/post.dart';
 import 'package:surface/providers/sn_attachment.dart';
 import 'package:surface/providers/sn_network.dart';
 import 'package:surface/types/attachment.dart';
@@ -180,53 +181,35 @@ class PostWriteController extends ChangeNotifier {
     int? reposting,
     int? replying,
   }) async {
-    final sn = context.read<SnNetworkProvider>();
-    final attach = context.read<SnAttachmentProvider>();
+    final pt = context.read<SnPostContentProvider>();
 
     isLoading = true;
     notifyListeners();
 
     try {
       if (editing != null) {
-        final resp = await sn.client.get('/cgi/co/posts/$editing');
-        final post = SnPost.fromJson(resp.data);
-        final alts = await attach
-            .getMultiple(post.body['attachments']?.cast<String>() ?? []);
+        final post = await pt.getPost(editing);
         publisher = post.publisher;
         titleController.text = post.body['title'] ?? '';
         descriptionController.text = post.body['description'] ?? '';
         contentController.text = post.body['content'] ?? '';
         publishedAt = post.publishedAt;
         publishedUntil = post.publishedUntil;
-        attachments.addAll(alts.map((ele) => PostWriteMedia(ele)));
-
-        editingPost = post.copyWith(
-          preload: SnPostPreload(
-            attachments: alts,
-          ),
+        attachments.addAll(
+          post.preload?.attachments?.map((ele) => PostWriteMedia(ele)) ?? [],
         );
+
+        editingPost = post;
       }
 
       if (replying != null) {
-        final resp = await sn.client.get('/cgi/co/posts/$replying');
-        final post = SnPost.fromJson(resp.data);
-        replyingPost = post.copyWith(
-          preload: SnPostPreload(
-            attachments: await attach
-                .getMultiple(post.body['attachments']?.cast<String>() ?? []),
-          ),
-        );
+        final post = await pt.getPost(replying);
+        replyingPost = post;
       }
 
       if (reposting != null) {
-        final resp = await sn.client.get('/cgi/co/posts/$reposting');
-        final post = SnPost.fromJson(resp.data);
-        repostingPost = post.copyWith(
-          preload: SnPostPreload(
-            attachments: await attach
-                .getMultiple(post.body['attachments']?.cast<String>() ?? []),
-          ),
-        );
+        final post = await pt.getPost(reposting);
+        replyingPost = post;
       }
     } catch (err) {
       if (!context.mounted) return;
diff --git a/lib/main.dart b/lib/main.dart
index 70238f5..bf62bd8 100644
--- a/lib/main.dart
+++ b/lib/main.dart
@@ -15,6 +15,7 @@ import 'package:surface/providers/channel.dart';
 import 'package:surface/providers/chat_call.dart';
 import 'package:surface/providers/navigation.dart';
 import 'package:surface/providers/notification.dart';
+import 'package:surface/providers/post.dart';
 import 'package:surface/providers/sn_attachment.dart';
 import 'package:surface/providers/sn_network.dart';
 import 'package:surface/providers/theme.dart';
@@ -82,6 +83,7 @@ class SolianApp extends StatelessWidget {
             // Data layer
             Provider(create: (_) => SnNetworkProvider()),
             Provider(create: (ctx) => SnAttachmentProvider(ctx)),
+            Provider(create: (ctx) => SnPostContentProvider(ctx)),
             Provider(create: (ctx) => UserDirectoryProvider(ctx)),
             ChangeNotifierProvider(create: (ctx) => UserProvider(ctx)),
             ChangeNotifierProvider(create: (ctx) => WebSocketProvider(ctx)),
diff --git a/lib/providers/post.dart b/lib/providers/post.dart
new file mode 100644
index 0000000..9c33499
--- /dev/null
+++ b/lib/providers/post.dart
@@ -0,0 +1,119 @@
+import 'package:flutter/material.dart';
+import 'package:provider/provider.dart';
+import 'package:surface/providers/sn_attachment.dart';
+import 'package:surface/providers/sn_network.dart';
+import 'package:surface/types/post.dart';
+
+class SnPostContentProvider {
+  late final SnNetworkProvider _sn;
+  late final SnAttachmentProvider _attach;
+
+  SnPostContentProvider(BuildContext context) {
+    _sn = context.read<SnNetworkProvider>();
+    _attach = context.read<SnAttachmentProvider>();
+  }
+
+  Future<List<SnPost>> _preloadRelatedDataInBatch(List<SnPost> out) async {
+    Set<String> rids = {};
+    for (var i = 0; i < out.length; i++) {
+      rids.addAll(out[i].body['attachments']?.cast<String>() ?? []);
+      if (out[i].body['thumbnail'] != null) {
+        rids.add(out[i].body['thumbnail']);
+      }
+    }
+
+    final attachments = await _attach.getMultiple(rids.toList());
+    for (var i = 0; i < out.length; i++) {
+      out[i] = out[i].copyWith(
+        preload: SnPostPreload(
+          thumbnail: attachments
+              .where((ele) => ele?.rid == out[i].body['thumbnail'])
+              .firstOrNull,
+          attachments: attachments
+              .where((ele) =>
+                  out[i].body['attachments']?.contains(ele?.rid) ?? false)
+              .toList(),
+        ),
+      );
+    }
+
+    return out;
+  }
+
+  Future<SnPost> _preloadRelatedDataSingle(SnPost out) async {
+    Set<String> rids = {};
+    rids.addAll(out.body['attachments']?.cast<String>() ?? []);
+    if (out.body['thumbnail'] != null) {
+      rids.add(out.body['thumbnail']);
+    }
+
+    final attachments = await _attach.getMultiple(rids.toList());
+    out = out.copyWith(
+      preload: SnPostPreload(
+        thumbnail: attachments
+            .where((ele) => ele?.rid == out.body['thumbnail'])
+            .firstOrNull,
+        attachments: attachments
+            .where(
+                (ele) => out.body['attachments']?.contains(ele?.rid) ?? false)
+            .toList(),
+      ),
+    );
+
+    return out;
+  }
+
+  Future<(List<SnPost>, int)> listPosts({int take = 10, int offset = 0}) async {
+    final resp = await _sn.client.get('/cgi/co/posts', queryParameters: {
+      'take': take,
+      'offset': offset,
+    });
+    final List<SnPost> out = await _preloadRelatedDataInBatch(
+      List.from(resp.data['data']?.map((e) => SnPost.fromJson(e)) ?? []),
+    );
+
+    return (out, resp.data['count'] as int);
+  }
+
+  Future<(List<SnPost>, int)> listPostReplies(
+    dynamic parentId, {
+    int take = 10,
+    int offset = 0,
+  }) async {
+    final resp = await _sn.client
+        .get('/cgi/co/posts/$parentId/replies', queryParameters: {
+      'take': take,
+      'offset': offset,
+    });
+    final List<SnPost> out = await _preloadRelatedDataInBatch(
+      List.from(resp.data['data']?.map((e) => SnPost.fromJson(e)) ?? []),
+    );
+
+    return (out, resp.data['count'] as int);
+  }
+
+  Future<(List<SnPost>, int)> searchPosts(
+    String searchTerm, {
+    int take = 10,
+    int offset = 0,
+  }) async {
+    final resp = await _sn.client.get('/cgi/co/posts/search', queryParameters: {
+      'take': take,
+      'offset': offset,
+      'probe': searchTerm,
+    });
+    final List<SnPost> out = await _preloadRelatedDataInBatch(
+      List.from(resp.data['data']?.map((e) => SnPost.fromJson(e)) ?? []),
+    );
+
+    return (out, resp.data['count'] as int);
+  }
+
+  Future<SnPost> getPost(dynamic id) async {
+    final resp = await _sn.client.get('/cgi/co/posts/$id');
+    final out = _preloadRelatedDataSingle(
+      SnPost.fromJson(resp.data['data']),
+    );
+    return out;
+  }
+}
diff --git a/lib/screens/explore.dart b/lib/screens/explore.dart
index e278b20..95b41b5 100644
--- a/lib/screens/explore.dart
+++ b/lib/screens/explore.dart
@@ -5,8 +5,7 @@ import 'package:gap/gap.dart';
 import 'package:go_router/go_router.dart';
 import 'package:material_symbols_icons/symbols.dart';
 import 'package:provider/provider.dart';
-import 'package:surface/providers/sn_attachment.dart';
-import 'package:surface/providers/sn_network.dart';
+import 'package:surface/providers/post.dart';
 import 'package:surface/types/post.dart';
 import 'package:surface/widgets/post/post_item.dart';
 import 'package:very_good_infinite_list/very_good_infinite_list.dart';
@@ -31,36 +30,13 @@ class _ExploreScreenState extends State<ExploreScreen> {
 
     setState(() => _isBusy = true);
 
-    final sn = context.read<SnNetworkProvider>();
-    final resp = await sn.client.get('/cgi/co/posts', queryParameters: {
-      'take': 10,
-      'offset': _posts.length,
-    });
-    final List<SnPost> out =
-        List.from(resp.data['data']?.map((e) => SnPost.fromJson(e)) ?? []);
-
-    Set<String> rids = {};
-    for (var i = 0; i < out.length; i++) {
-      rids.addAll(out[i].body['attachments']?.cast<String>() ?? []);
-    }
+    final pt = context.read<SnPostContentProvider>();
+    final result = await pt.listPosts(take: 10, offset: _posts.length);
+    final out = result.$1;
 
     if (!mounted) return;
-    final attach = context.read<SnAttachmentProvider>();
-    final attachments = await attach.getMultiple(rids.toList());
-    for (var i = 0; i < out.length; i++) {
-      out[i] = out[i].copyWith(
-        preload: SnPostPreload(
-          attachments: attachments
-              .where(
-                (ele) =>
-                    out[i].body['attachments']?.contains(ele?.rid) ?? false,
-              )
-              .toList(),
-        ),
-      );
-    }
 
-    _postCount = resp.data['count'];
+    _postCount = result.$2;
     _posts.addAll(out);
 
     if (mounted) setState(() => _isBusy = false);
diff --git a/lib/screens/post/post_detail.dart b/lib/screens/post/post_detail.dart
index 23c1d5c..5cf2729 100644
--- a/lib/screens/post/post_detail.dart
+++ b/lib/screens/post/post_detail.dart
@@ -7,8 +7,7 @@ import 'package:go_router/go_router.dart';
 import 'package:material_symbols_icons/symbols.dart';
 import 'package:provider/provider.dart';
 import 'package:styled_widget/styled_widget.dart';
-import 'package:surface/providers/sn_attachment.dart';
-import 'package:surface/providers/sn_network.dart';
+import 'package:surface/providers/post.dart';
 import 'package:surface/providers/userinfo.dart';
 import 'package:surface/types/post.dart';
 import 'package:surface/widgets/dialog.dart';
@@ -39,19 +38,10 @@ class _PostDetailScreenState extends State<PostDetailScreen> {
     setState(() => _isBusy = true);
 
     try {
-      final sn = context.read<SnNetworkProvider>();
-      final attach = context.read<SnAttachmentProvider>();
-      final resp = await sn.client.get('/cgi/co/posts/${widget.slug}');
+      final pt = context.read<SnPostContentProvider>();
+      final post = await pt.getPost(widget.slug);
       if (!mounted) return;
-      final attachments = await attach.getMultiple(
-        resp.data['body']['attachments']?.cast<String>() ?? [],
-      );
-      if (!mounted) return;
-      _data = SnPost.fromJson(resp.data).copyWith(
-        preload: SnPostPreload(
-          attachments: attachments,
-        ),
-      );
+      _data = post;
     } catch (err) {
       context.showErrorDialog(err);
     } finally {
diff --git a/lib/screens/post/post_search.dart b/lib/screens/post/post_search.dart
index 088c906..32686d7 100644
--- a/lib/screens/post/post_search.dart
+++ b/lib/screens/post/post_search.dart
@@ -5,8 +5,7 @@ import 'package:go_router/go_router.dart';
 import 'package:material_symbols_icons/symbols.dart';
 import 'package:provider/provider.dart';
 import 'package:styled_widget/styled_widget.dart';
-import 'package:surface/providers/sn_attachment.dart';
-import 'package:surface/providers/sn_network.dart';
+import 'package:surface/providers/post.dart';
 import 'package:surface/types/post.dart';
 import 'package:surface/widgets/post/post_item.dart';
 import 'package:very_good_infinite_list/very_good_infinite_list.dart';
@@ -35,40 +34,20 @@ class _PostSearchScreenState extends State<PostSearchScreen> {
 
     final stopwatch = Stopwatch()..start();
 
-    final sn = context.read<SnNetworkProvider>();
-    final resp = await sn.client.get('/cgi/co/posts/search', queryParameters: {
-      'take': 10,
-      'offset': _posts.length,
-      'probe': _searchTerm,
-    });
-    final List<SnPost> out =
-        List.from(resp.data['data']?.map((e) => SnPost.fromJson(e)) ?? []);
-
-    Set<String> rids = {};
-    for (var i = 0; i < out.length; i++) {
-      rids.addAll(out[i].body['attachments']?.cast<String>() ?? []);
-    }
+    final pt = context.read<SnPostContentProvider>();
+    final result = await pt.searchPosts(
+      _searchTerm,
+      take: 10,
+      offset: _posts.length,
+    );
+    final List<SnPost> out = result.$1;
 
     if (!mounted) return;
-    final attach = context.read<SnAttachmentProvider>();
-    final attachments = await attach.getMultiple(rids.toList());
-    for (var i = 0; i < out.length; i++) {
-      out[i] = out[i].copyWith(
-        preload: SnPostPreload(
-          attachments: attachments
-              .where(
-                (ele) =>
-                    out[i].body['attachments']?.contains(ele?.rid) ?? false,
-              )
-              .toList(),
-        ),
-      );
-    }
 
     stopwatch.stop();
 
     _lastTook = stopwatch.elapsed;
-    _postCount = resp.data['count'];
+    _postCount = result.$2;
     _posts.addAll(out);
 
     if (mounted) setState(() => _isBusy = false);
diff --git a/lib/types/post.dart b/lib/types/post.dart
index 4f9301c..c04604b 100644
--- a/lib/types/post.dart
+++ b/lib/types/post.dart
@@ -53,6 +53,7 @@ class SnPost with _$SnPost {
 @freezed
 class SnPostPreload with _$SnPostPreload {
   const factory SnPostPreload({
+    required SnAttachment? thumbnail,
     required List<SnAttachment?>? attachments,
   }) = _SnPostPreload;
 
diff --git a/lib/types/post.freezed.dart b/lib/types/post.freezed.dart
index 8b00e4e..cd21182 100644
--- a/lib/types/post.freezed.dart
+++ b/lib/types/post.freezed.dart
@@ -953,6 +953,7 @@ SnPostPreload _$SnPostPreloadFromJson(Map<String, dynamic> json) {
 
 /// @nodoc
 mixin _$SnPostPreload {
+  SnAttachment? get thumbnail => throw _privateConstructorUsedError;
   List<SnAttachment?>? get attachments => throw _privateConstructorUsedError;
 
   /// Serializes this SnPostPreload to a JSON map.
@@ -971,7 +972,9 @@ abstract class $SnPostPreloadCopyWith<$Res> {
           SnPostPreload value, $Res Function(SnPostPreload) then) =
       _$SnPostPreloadCopyWithImpl<$Res, SnPostPreload>;
   @useResult
-  $Res call({List<SnAttachment?>? attachments});
+  $Res call({SnAttachment? thumbnail, List<SnAttachment?>? attachments});
+
+  $SnAttachmentCopyWith<$Res>? get thumbnail;
 }
 
 /// @nodoc
@@ -989,15 +992,34 @@ class _$SnPostPreloadCopyWithImpl<$Res, $Val extends SnPostPreload>
   @pragma('vm:prefer-inline')
   @override
   $Res call({
+    Object? thumbnail = freezed,
     Object? attachments = freezed,
   }) {
     return _then(_value.copyWith(
+      thumbnail: freezed == thumbnail
+          ? _value.thumbnail
+          : thumbnail // ignore: cast_nullable_to_non_nullable
+              as SnAttachment?,
       attachments: freezed == attachments
           ? _value.attachments
           : attachments // ignore: cast_nullable_to_non_nullable
               as List<SnAttachment?>?,
     ) as $Val);
   }
+
+  /// Create a copy of SnPostPreload
+  /// with the given fields replaced by the non-null parameter values.
+  @override
+  @pragma('vm:prefer-inline')
+  $SnAttachmentCopyWith<$Res>? get thumbnail {
+    if (_value.thumbnail == null) {
+      return null;
+    }
+
+    return $SnAttachmentCopyWith<$Res>(_value.thumbnail!, (value) {
+      return _then(_value.copyWith(thumbnail: value) as $Val);
+    });
+  }
 }
 
 /// @nodoc
@@ -1008,7 +1030,10 @@ abstract class _$$SnPostPreloadImplCopyWith<$Res>
       __$$SnPostPreloadImplCopyWithImpl<$Res>;
   @override
   @useResult
-  $Res call({List<SnAttachment?>? attachments});
+  $Res call({SnAttachment? thumbnail, List<SnAttachment?>? attachments});
+
+  @override
+  $SnAttachmentCopyWith<$Res>? get thumbnail;
 }
 
 /// @nodoc
@@ -1024,9 +1049,14 @@ class __$$SnPostPreloadImplCopyWithImpl<$Res>
   @pragma('vm:prefer-inline')
   @override
   $Res call({
+    Object? thumbnail = freezed,
     Object? attachments = freezed,
   }) {
     return _then(_$SnPostPreloadImpl(
+      thumbnail: freezed == thumbnail
+          ? _value.thumbnail
+          : thumbnail // ignore: cast_nullable_to_non_nullable
+              as SnAttachment?,
       attachments: freezed == attachments
           ? _value._attachments
           : attachments // ignore: cast_nullable_to_non_nullable
@@ -1038,12 +1068,16 @@ class __$$SnPostPreloadImplCopyWithImpl<$Res>
 /// @nodoc
 @JsonSerializable()
 class _$SnPostPreloadImpl implements _SnPostPreload {
-  const _$SnPostPreloadImpl({required final List<SnAttachment?>? attachments})
+  const _$SnPostPreloadImpl(
+      {required this.thumbnail,
+      required final List<SnAttachment?>? attachments})
       : _attachments = attachments;
 
   factory _$SnPostPreloadImpl.fromJson(Map<String, dynamic> json) =>
       _$$SnPostPreloadImplFromJson(json);
 
+  @override
+  final SnAttachment? thumbnail;
   final List<SnAttachment?>? _attachments;
   @override
   List<SnAttachment?>? get attachments {
@@ -1056,7 +1090,7 @@ class _$SnPostPreloadImpl implements _SnPostPreload {
 
   @override
   String toString() {
-    return 'SnPostPreload(attachments: $attachments)';
+    return 'SnPostPreload(thumbnail: $thumbnail, attachments: $attachments)';
   }
 
   @override
@@ -1064,14 +1098,16 @@ class _$SnPostPreloadImpl implements _SnPostPreload {
     return identical(this, other) ||
         (other.runtimeType == runtimeType &&
             other is _$SnPostPreloadImpl &&
+            (identical(other.thumbnail, thumbnail) ||
+                other.thumbnail == thumbnail) &&
             const DeepCollectionEquality()
                 .equals(other._attachments, _attachments));
   }
 
   @JsonKey(includeFromJson: false, includeToJson: false)
   @override
-  int get hashCode => Object.hash(
-      runtimeType, const DeepCollectionEquality().hash(_attachments));
+  int get hashCode => Object.hash(runtimeType, thumbnail,
+      const DeepCollectionEquality().hash(_attachments));
 
   /// Create a copy of SnPostPreload
   /// with the given fields replaced by the non-null parameter values.
@@ -1091,11 +1127,14 @@ class _$SnPostPreloadImpl implements _SnPostPreload {
 
 abstract class _SnPostPreload implements SnPostPreload {
   const factory _SnPostPreload(
-      {required final List<SnAttachment?>? attachments}) = _$SnPostPreloadImpl;
+      {required final SnAttachment? thumbnail,
+      required final List<SnAttachment?>? attachments}) = _$SnPostPreloadImpl;
 
   factory _SnPostPreload.fromJson(Map<String, dynamic> json) =
       _$SnPostPreloadImpl.fromJson;
 
+  @override
+  SnAttachment? get thumbnail;
   @override
   List<SnAttachment?>? get attachments;
 
diff --git a/lib/types/post.g.dart b/lib/types/post.g.dart
index 83ba11f..addcb8e 100644
--- a/lib/types/post.g.dart
+++ b/lib/types/post.g.dart
@@ -102,6 +102,9 @@ Map<String, dynamic> _$$SnPostImplToJson(_$SnPostImpl instance) =>
 
 _$SnPostPreloadImpl _$$SnPostPreloadImplFromJson(Map<String, dynamic> json) =>
     _$SnPostPreloadImpl(
+      thumbnail: json['thumbnail'] == null
+          ? null
+          : SnAttachment.fromJson(json['thumbnail'] as Map<String, dynamic>),
       attachments: (json['attachments'] as List<dynamic>?)
           ?.map((e) => e == null
               ? null
@@ -111,6 +114,7 @@ _$SnPostPreloadImpl _$$SnPostPreloadImplFromJson(Map<String, dynamic> json) =>
 
 Map<String, dynamic> _$$SnPostPreloadImplToJson(_$SnPostPreloadImpl instance) =>
     <String, dynamic>{
+      'thumbnail': instance.thumbnail?.toJson(),
       'attachments': instance.attachments?.map((e) => e?.toJson()).toList(),
     };
 
diff --git a/lib/widgets/post/post_comment_list.dart b/lib/widgets/post/post_comment_list.dart
index f74c451..da4a148 100644
--- a/lib/widgets/post/post_comment_list.dart
+++ b/lib/widgets/post/post_comment_list.dart
@@ -5,8 +5,7 @@ import 'package:go_router/go_router.dart';
 import 'package:material_symbols_icons/symbols.dart';
 import 'package:provider/provider.dart';
 import 'package:styled_widget/styled_widget.dart';
-import 'package:surface/providers/sn_attachment.dart';
-import 'package:surface/providers/sn_network.dart';
+import 'package:surface/providers/post.dart';
 import 'package:surface/providers/userinfo.dart';
 import 'package:surface/types/post.dart';
 import 'package:surface/widgets/post/post_item.dart';
@@ -37,39 +36,13 @@ class PostCommentSliverListState extends State<PostCommentSliverList> {
 
     setState(() => _isBusy = true);
 
-    final sn = context.read<SnNetworkProvider>();
-    final resp = await sn.client.get(
-      '/cgi/co/posts/${widget.parentPostId}/replies',
-      queryParameters: {
-        'take': 10,
-        'offset': _posts.length,
-      },
-    );
-    final List<SnPost> out =
-        List.from(resp.data['data']?.map((e) => SnPost.fromJson(e)) ?? []);
-
-    Set<String> rids = {};
-    for (var i = 0; i < out.length; i++) {
-      rids.addAll(out[i].body['attachments']?.cast<String>() ?? []);
-    }
+    final pt = context.read<SnPostContentProvider>();
+    final result = await pt.listPostReplies(widget.parentPostId);
+    final List<SnPost> out = result.$1;
 
     if (!mounted) return;
-    final attach = context.read<SnAttachmentProvider>();
-    final attachments = await attach.getMultiple(rids.toList());
-    for (var i = 0; i < out.length; i++) {
-      out[i] = out[i].copyWith(
-        preload: SnPostPreload(
-          attachments: attachments
-              .where(
-                (ele) =>
-                    out[i].body['attachments']?.contains(ele?.rid) ?? false,
-              )
-              .toList(),
-        ),
-      );
-    }
 
-    _postCount = resp.data['count'];
+    _postCount = result.$2;
     _posts.addAll(out);
 
     if (mounted) setState(() => _isBusy = false);