探索 Tiptap V3 的最新功能

在你的编辑器中管理线程

使用本指南将评论直接集成到你的编辑器中。有关所有评论编辑器命令的完整列表,请参见 编辑器命令 页面。

你还可以通过我们的 评论 REST API 从编辑器外部与评论进行交互。

了解线程

Tiptap 的评论功能将讨论组织成线程,通过区分线程和单个评论,使协作变得清晰且相关。

线程作为与特定文档部分相关的讨论容器,而评论表示在这些线程中的个体贡献。

创建新线程

假设你有一个按钮用于创建新线程。你可以使用 setThread 命令在当前选中位置创建一个新线程。

const createThread = () => {
  editor
    .chain()
    .setThread({
      content: '这是一个新线程', // 线程初始评论的内容
    })
    .run()
}

这将会在当前选中位置创建一个新线程,并添加一个带有给定内容的评论。默认情况下,评论和线程没有分配用户或任何其他元数据。假设你想将作者添加到线程 评论中。你可以通过将 datacommentData 属性传递给 setThread 命令来实现。

const createThread = () => {
  const user = {
    id: '123', // 作者的用户 ID
    name: 'John Doe', // 作者的名字
    avatarUrl: 'https://example.com/avatar.jpg', // 作者的头像
  }

  editor
    .chain()
    .setThread({
      content: '这是一个新线程', // 线程初始评论的内容
      data: {
        user,
      },
      commentData: {
        user,
      },
    })
    .run()
}

现在线程和评论将会被分配给用户。

接收和监视线程及评论

接收和监视当前文档上的线程可以通过使用 subscribeToThreads 函数轻松完成。该函数将注册一个监视器,获取初始线程列表并保持列表的最新状态。

要取消订阅线程,可以调用 subscribeToThreads 函数返回的回调函数。

// 订阅线程
const unsubscribe = subscribeToThreads({
  provider: yourTiptapCollabProvider,
  callback: (threads) => {
    // 处理线程,可以将其存储在状态或变量中
  },
  // 可选选项
  getThreadsOptions: {
    // 只有具有特定类型的线程会被获取/监视,可能的值为 'archived' 和 'unarchived',
    // 如果未设置,仅处理未归档的线程
    // 归档和未归档的线程表示软删除的线程
    types: ['archived', 'unarchived'],
  },
})

手动接收和渲染线程

要手动接收当前文档上的线程列表,你只需调用 provider.getThreads()。这将返回一个与您的提供者连接的文档中的线程数组。

这是一个静态数组,不会自动更新。如果你想保持线程列表的最新状态,你可以通过 provider.watchThreadsprovider.unwatchThreads 函数监听更改。

// 将线程保存到一个变量中
let threads = []

// 每当线程发生变化时调用此函数
const getThreads = () => {
  threads = provider.getThreads()
}

// 初始调用以获取线程
getThreads()

// 监视更改
provider.watchThreads(getThreads)

要取消监视线程,你可以调用 provider.unwatchThreads(getThreads)

provider.unwatchThreads(getThreads)

假设你想编写一个 React 钩子以获取线程并保持其最新状态,可以这样编写钩子。

const useThreads = (provider) => {
  const [threads, setThreads] = useState([])

  useEffect(() => {
    if (!provider) {
      return () => null
    }

    const getThreads = () => {
      setThreads(provider.getThreads())
    }

    getThreads()

    provider.watchThreads(getThreads)

    return () => {
      provider.unwatchThreads(getThreads)
    }
  }, [provider])

  return threads
}

现在这些线程将是响应式的,可以用来在你的 UI 中渲染线程。

更新线程

要更新线程,你可以使用 updateThread 命令。该命令将使用给定 ID 更新线程并更新线程内容。

editor.commands.updateThread({
  id: '123',
  data: {
    seen: true,
  }
})

这将更新 ID 为 123 的线程,并将 seen 属性设置为 true

删除线程

要删除线程,你可以使用 removeThread 命令。该命令将删除具有给定 ID 的线程。

如何删除线程

默认情况下,已删除的线程不会从 yjs 文档中删除。要做到这一点,可以将 deleteThread 选项传递给 removeThread 命令。

editor.commands.removeThread({
  id: '123',
  deleteThread: true,
})

创建、更新和删除评论

评论可以在线程内添加、编辑和删除,但不能标记为已解决,因为它们被视为线程讨论的一部分。

要在线程上创建评论,你可以使用 createComment 命令。该命令将在具有给定 ID 的线程上创建一条新评论。

editor.commands.createComment({
  threadId: '123',
  content: '这是一个新评论', // 这也可以是 tiptap JSON 或任何其他类型的内容
  data: {
    user, // 传递任何你想要的元数据 - 在这种情况下是用户
  },
})

这将在 ID 为 123 的线程上创建一条新评论,并将内容设置为 这是一个新评论。你还可以将任何元数据传递给评论。

要更新评论,你可以使用 updateComment 命令。该命令将更新具有给定 ID 的评论并更新评论内容。

editor.commands.updateComment({
  threadId: '123', // 线程 ID
  id: '456', // 评论 ID
  content: '现在这是新内容', // 评论的新内容
  data: {
    edited: true, // 将 edited 属性设置为 true
  },
})

这将更新 ID 为 456 的评论,并将其内容设置为 现在这是新内容。你也可以传递任何你想要的元数据。

最后,你可以通过使用 deleteComment 命令删除评论。该命令将删除具有给定 ID 的评论。

editor.commands.deleteComment({
  threadId: '123',
  id: '456',
})

解决和取消解决线程

要解决线程,你可以使用 resolveThread 命令。该命令将解决具有给定 ID 的线程。

editor.commands.resolveThread({
  id: '123',
})

这将解决 ID 为 123 的线程。要取消解决线程,你可以使用 unresolveThread 命令。该命令将取消解决具有给定 ID 的线程。

如果你想解决一个线程并添加有关解决该线程的用户的信息,可以设置线程数据以包含解决该线程的用户。在取消解决线程时,请务必清除数据。

editor.commands.unresolveThread({
  id: '123',
})

选择线程

要选择线程,你可以使用 selectThread 命令。该命令选择具有指定 ID 的线程。

editor.commands.selectThread({
  id: '123',
})

这将光标移动到 ID 为 123 的线程。

要取消选择线程,你可以使用 unselectThread 命令。该命令取消选择具有指定 ID 的线程。

editor.commands.unselectThread({
  id: '123',
})

你还可以选择或取消选择没有 ID 的线程。在这种情况下,编辑器将选择或取消选择当前选中的线程。