Flutter评论管理插件easy_comment的使用

Flutter评论管理插件easy_comment的使用

本插件提供了强大的且简单的方式来为您的应用添加评论功能。它非常灵活,适用于文章评论、产品评价或照片反馈等场景。

该插件提供了完整的UI/UX组件和逻辑来管理评论。这包括用于创建、更新、删除和列出评论的组件,以及上传、点赞等功能。

术语

  • 一级评论:直接在文章下的评论。

待办事项

  • 使用实时数据库进行评论列表。
    • 将评论的内容、uid、第一张照片和创建时间镜像到实时数据库。
    • 这是为了降低成本。
    • Firestore将保留原始数据并用于过滤目的。

评论数据库结构

最初,我们考虑使用实时数据库来存储评论。然而,由于评论不仅仅应用于文章,还可能应用于应用的其他部分,因此我们选择了一个更灵活的选择——Firestore。

  • /comments/{commentId} 是存储评论的集合和文档。
  • 要获取一级评论,可以使用以下条件之一:
    • 条件:如果parentId为空,则是一级评论。
    • 条件:如果depth=0
  • documentReference 是评论所属的文档。
    • 如果它是用户文档的引用,则具有相同documentReference的评论属于该用户。您可以将其设置为用户公开资料的评论功能。
    • 这个documentReference可以是任何文档引用。它可以是一个在线商城的产品项文档,或者其他任何东西。
  • hasChild 字段在评论有子评论时变为true。
    • 它不保存在数据库中,在客户端侧设置。
    • 只有当评论被CommentService.instance.fromQuerySnapshot方法转换后才可用。
    • hasChild用于排序和显示目的。
  • deleted 字段如果评论被删除,则设为true。默认为false。因此,您可以过滤未被删除的评论。

组件

创建评论输入框

这是一个简单的评论创建组件。

CommentInputBox(
  parent: comment,
),

显示评论

easy_comment 提供了两个列表视图组件来显示评论。

您可以复制easy_comment 中的代码并构建自己的评论列表视图组件以适应不同的UI/UX。

CommentListView

这是类似于ListView 的第一个组件。

您可以使用CommentListView 如下所示来显示评论:

CommentListView(
  documentReference: ref,
  shrinkWrap: true,
  physics: const NeverScrollableScrollPhysics(),
  itemBuilder: (comment, index) => 
      CommentListDetail(comment: comment),
),

对于itemBuilder,您可以使用CommentDetailCommentListDetailCommentListArrowDetailCommentListVerticalLineDetail 中的一个。或者您可以复制代码并构建自己的组件。

示例:以下是使用可用组件的示例:

CommentListView(
  documentReference: ref,
  itemBuilder: (comment, index) {
    return CommentListDetail(comment: comment); // 默认
    return CommentListArrowDetail(comment: comment); // 箭头样式评论
    return CommentListVerticalLineDetail(comment: comment); // 垂直线评论
  },
),

CommentListTreeView

CommentListTreeView 提供了一个美观的树形风格垂直线,用于嵌套评论列表。它设计为在滑动视图中工作。因此,您应该在屏幕上使用CustomScrollView

SliverToBoxAdapter(
  child: CommentFakeInputBox(
    onTap: () => CommentService.instance.showCommentEditDialog(
      context: context,
      documentReference: task.ref,
      focusOnContent: true,
    ),
  ),
),
CommentListTreeView(documentReference: task.ref),

onCreate 回调

onCreate 是在评论创建后调用的回调。

您可以使用此回调在评论发布时执行某些操作。

使用示例:(例如,向祖先uid发送推送通知)

在下面的示例中,我们可以在评论创建后向祖先uid发送推送通知。它包含新创建的comment信息。

首先,我们在评论创建后获取祖先uid,然后向这些祖先uid发送推送通知。

CommentService.instance.init(
  onCreate: (Comment comment) async {
    /// 获取祖先uid
    List<String> ancestorUids = 
        await CommentService.instance.getAncestorsUid(comment.id);
    /// 获取文章信息
    Post post = await Post.get(comment.documentReference.id);
    if (myUid != null && post.uid != myUid) {
      ancestorUids.add(post.uid);
    }

    if (ancestorUids.isEmpty) return;

    /// 设置推送通知到剩余的uid
    /// 可以获取评论或文章来发送更多信息丰富的推送通知
    MessagingService.instance.sendMessageToUids(
      uids: ancestorUids,
      title: '标题 ${DateTime.now()}',
      body: '祖先评论测试 ${comment.content}',
      data: {
        "action": 'comment',
        'commentId': comment.id,
        'postId': comment.documentReference.id,
      },
    );
  },
);

开发技巧

测试

import 'package:easy_comment/easy_comment.dart';
import 'package:easy_post_v2/easy_post_v2.dart';
import 'package:easyuser/easyuser.dart';
import 'package:flutter/material.dart';

class CommentTestScreen extends StatefulWidget {
  static const String routeName = '/CommentTest';
  const CommentTestScreen({super.key});

  [@override](/user/override)
  State<CommentTestScreen> createState() => _CommentTestScreenState();
}

class _CommentTestScreenState extends State<CommentTestScreen> {
  [@override](/user/override)
  Widget build(BuildContext context) {
    // final ref = my.ref;
    // final ref = Post.col.doc('1zsZ2YMplgZN6D6bdZIn');
    // final ref = Post.col.doc('0-console');
    // final ref = Post.col.doc('0-console-2');
    // final ref = Post.col.doc('0-con-3');
    // final ref = Post.col.doc('0-a');
    // final ref = Post.col.doc('0-b');
    // final ref = Post.col.doc('0-c');
    final ref = Post.col.doc('0-4');
    return Scaffold(
      appBar: AppBar(
        title: const Text('评论测试'),
      ),
      body: Padding(
        padding: const EdgeInsets.fromLTRB(24.0, 24, 24, 0),
        child: MyDocReady(
          builder: () => ListView(
            padding: const EdgeInsets.all(0),
            children: [
              Text('引用: ${ref.path}'),
              const SizedBox(height: 24),
              CommentFakeInputBox(
                onTap: () => CommentService.instance.showCommentEditDialog(
                  context: context,
                  documentReference: ref,
                  focusOnContent: true,
                ),
              ),
              CommentInputBox(
                documentReference: ref,
              ),
              CommentListView(
                documentReference: ref,
                shrinkWrap: true,
                physics: const NeverScrollableScrollPhysics(),
                itemBuilder: (comment, index) => 
                    CommentListArrowDetail(comment: comment),
              ),
            ],
          ),
        ),
      ),
      bottomNavigationBar: SafeArea(
        top: false,
        child: CommentFakeInputBox(
          onTap: () => CommentService.instance.showCommentEditDialog(
            context: context,
            documentReference: ref,
            focusOnContent: true,
          ),
        ),
      ),
    );
  }
}

更多关于Flutter评论管理插件easy_comment的使用的实战教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter评论管理插件easy_comment的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


当然,下面是一个关于如何在Flutter项目中使用easy_comment插件来进行评论管理的示例代码。请注意,easy_comment是一个假定的插件名称,实际使用时你需要确保该插件在pub.dev上是存在的,或者这是一个你自定义的插件。以下代码将展示如何集成和使用一个假设的评论管理插件。

1. 添加依赖

首先,在你的pubspec.yaml文件中添加easy_comment插件的依赖:

dependencies:
  flutter:
    sdk: flutter
  easy_comment: ^1.0.0  # 假设的版本号

然后运行flutter pub get来安装依赖。

2. 导入插件

在你需要使用评论管理功能的Dart文件中导入插件:

import 'package:easy_comment/easy_comment.dart';

3. 初始化插件

通常,插件需要在应用启动时进行初始化。你可以在main.dart中或者其他合适的地方进行初始化:

void main() {
  WidgetsFlutterBinding.ensureInitialized();
  
  // 假设easy_comment有一个初始化方法
  EasyComment.instance.init(apiKey: 'your_api_key');  // 替换为你的API密钥

  runApp(MyApp());
}

4. 使用插件功能

下面是一个简单的示例,展示如何加载评论、提交评论和删除评论。

import 'package:flutter/material.dart';
import 'package:easy_comment/easy_comment.dart';

class CommentScreen extends StatefulWidget {
  @override
  _CommentScreenState createState() => _CommentScreenState();
}

class _CommentScreenState extends State<CommentScreen> {
  List<Comment> comments = [];
  TextEditingController commentController = TextEditingController();

  @override
  void initState() {
    super.initState();
    // 加载评论
    loadComments();
  }

  void loadComments() async {
    try {
      comments = await EasyComment.instance.getComments(postId: 'post_id_here');  // 替换为你的帖子ID
      setState(() {});
    } catch (e) {
      print('Error loading comments: $e');
    }
  }

  void submitComment() async {
    String commentText = commentController.text;
    if (commentText.isNotEmpty) {
      try {
        await EasyComment.instance.postComment(postId: 'post_id_here', content: commentText);  // 替换为你的帖子ID
        commentController.clear();
        loadComments();  // 重新加载评论以显示新提交的评论
      } catch (e) {
        print('Error posting comment: $e');
      }
    }
  }

  void deleteComment(String commentId) async {
    try {
      await EasyComment.instance.deleteComment(commentId: commentId);
      loadComments();  // 重新加载评论以反映删除操作
    } catch (e) {
      print('Error deleting comment: $e');
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Comments'),
      ),
      body: Padding(
        padding: const EdgeInsets.all(8.0),
        child: Column(
          children: [
            Expanded(
              child: ListView.builder(
                itemCount: comments.length,
                itemBuilder: (context, index) {
                  Comment comment = comments[index];
                  return Card(
                    child: ListTile(
                      leading: IconButton(
                        icon: Icon(Icons.delete),
                        onPressed: () => deleteComment(comment.id),
                      ),
                      title: Text(comment.content),
                      subtitle: Text('By ${comment.author}'),
                    ),
                  );
                },
              ),
            ),
            TextField(
              controller: commentController,
              decoration: InputDecoration(
                border: OutlineInputBorder(),
                labelText: 'Add a comment',
              ),
            ),
            ElevatedButton(
              onPressed: submitComment,
              child: Text('Submit'),
            ),
          ],
        ),
      ),
    );
  }
}

class Comment {
  String id;
  String content;
  String author;

  Comment({required this.id, required this.content, required this.author});
}

注意事项

  1. API密钥:确保你有正确的API密钥,并且已经配置好后端服务来处理评论的CRUD操作。
  2. 错误处理:示例代码中包含了基本的错误处理,但你可能需要根据实际需求进行更详细的错误处理。
  3. UI优化:示例代码中的UI可能需要根据实际设计进行调整和优化。
  4. 插件功能:确保easy_comment插件提供了上述功能,并且API接口与示例代码中的调用方式一致。

由于easy_comment是一个假设的插件名称,实际使用时你需要参考该插件的官方文档来进行集成和使用。

回到顶部