ブログタイトル

目次

コメント機能アプデ

ユーザーが残したコメントが、ログとして残るようにする。さらにユーザー間で残したコメントが表示されるようにコメント機能を修正していく。

コメント更新ロジック


    type prevState = {
  reactionCount: number;
  hasReacted: boolean;
  comment?: string[];
};

export const updateReaction = async (
  prevState: prevState,
  
  reactiondata: ReactionData
) => {
  let userToken = await getUserToken();
 
  if (!userToken) {
    userToken = await setUserToken();
  }
 
  if (reactiondata.reactionType === "memo") {
    const targetId = GLOBAL_MEMO_CONTENT_ID;

    // 既存のコメントを取得
    const { data: currentData } = await supabaseAdmin
      .from("reactions")
      .select("comment")
      .eq("user_token", userToken)
      .eq("content_id", targetId)
      .eq("reaction_type", "memo")
      .single();

    const comments: string[] = currentData?.comment || [];

    if (reactiondata.comment) {
      comments.push(reactiondata.comment);
    }

    const { data, error } = await supabaseAdmin
      .from("reactions")
      .upsert(
        {
          user_token: userToken,
          content_id: targetId,
          reaction_type: reactiondata.reactionType,
          comment: comments,
          created_at: new Date().toISOString(),
        },
        
        { onConflict: "user_token, content_id, reaction_type" }
      )
      .select()
      .single();

    if (error) {
      console.error(error);
      return prevState;
    }

    return {
      reactionCount: prevState.reactionCount, 
      hasReacted: true,
      comment: comments,
    };
  }

前回から変わったのは、まずcommentのデータ型を配列にした点。何行目のコメントを格納する定数GLOBAL_MEMO_CONTENT_IDにコメントのログを格納する処理。DBの行(レコード)を増やさず、1つの行の中にある comment配列だけを更新し続けるupsert処理の三点を追加した。ほんとはコメントのみの新たなテーブルを作るべきだけど、リアクションボタンのテーブルとメモを一緒くたにしたため、このような実装になった。supabaseの無料枠を超えないための乞食的発想。

   const { data, error } = await supabaseAdmin
      .from("reactions")
      .upsert(
        {
          user_token: userToken,
          content_id: targetId,
          reaction_type: reactiondata.reactionType,
          comment: comments,
          created_at: new Date().toISOString(),
        },
        
        { onConflict: "user_token, content_id, reaction_type" }
      )
      .select()
      .single();

onConflict文でuser_token, content_id, reaction_type の3つがすべて一致するレコードが既にあるかチェックして、「同じユーザーが、同じ記事に、同じリアクション(メモ)を何度も送った場合」 に、DBの行(レコード)を増やさず、1つの行の中にある comment 配列だけを更新し続けるという挙動を実現している。

コメント機能をなんか暇だから作ったけど、一回始めちゃうと作りこんじゃう笑。