ともビデ

友達だけの動画共有サイト
title.textContent=item.caption||""; const author=document.createElement("div"); author.className="small"; author.textContent=owner?.display_name||"メンバー"; post.append(video,title,author); const comments=document.createElement("div"); comments.className="small"; const {data:rows}=await client.from("comments") .select("body,user_id,created_at") .eq("video_id",item.id).order("created_at"); for(const row of rows||[]){ const line=document.createElement("p"); line.textContent=row.body; comments.append(line); } post.append(comments); const input=document.createElement("input"); input.placeholder="コメントを書く"; const send=document.createElement("button"); send.textContent="コメントする"; send.onclick=async()=>{ const body=input.value.trim(); if(!body)return; const {error}=await client.from("comments").insert({ video_id:item.id,user_id:currentUser.id,body }); if(error)alert("コメントできませんでした。"); else loadFeed(); }; post.append(input,send); if(item.user_id===currentUser.id){ const del=document.createElement("button"); del.textContent="自分の動画を削除"; del.onclick=async()=>{ if(!confirm("この動画を削除しますか?"))return; await client.from("videos").delete().eq("id",item.id); await client.storage.from("tomobide-videos").remove([item.storage_path]); loadFeed(); }; post.append(del); } $("feed").append(post); } } $("uploadBtn").onclick=async()=>{ const file=$("videoFile").files[0]; if(!file){message("uploadMsg","動画を選んでね。");return;} if(!file.type.startsWith("video/")){message("uploadMsg","動画ファイルを選んでね。");return;} $("uploadBtn").disabled=true; message("uploadMsg","アップロード中..."); try{ const ext=file.name.split(".").pop().replace(/[^a-zA-Z0-9]/g,"")||"mp4"; const path=currentUser.id+"/"+crypto.randomUUID()+"."+ext; const {error:uploadError}=await client.storage.from("tomobide-videos").upload(path,file); if(uploadError)throw uploadError; const {error:dbError}=await client.from("videos").insert({ user_id:currentUser.id,storage_path:path,caption:$("caption").value.trim() }); if(dbError)throw dbError; $("videoFile").value=""; $("caption").value=""; message("uploadMsg","投稿できたよ!"); await loadFeed(); }catch(e){message("uploadMsg","投稿できませんでした。容量や設定を確認してね。");} $("uploadBtn").disabled=false; }; $("inviteBtn").onclick=async()=>{ const {data:{session}}=await client.auth.getSession(); const response=await fetch(SUPABASE_URL+"/functions/v1/create-invitation",{ method:"POST", headers:{ "Authorization":"Bearer "+session.access_token, "apikey":SUPABASE_KEY } }); const result=await response.json(); if(!response.ok){alert("招待URLを作れませんでした。");return;} $("inviteUrl").value=location.origin+location.pathname+"?invite="+encodeURIComponent(result.token); }; $("copyInvite").onclick=async()=>{ if(!$("inviteUrl").value)return; await navigator.clipboard.writeText($("inviteUrl").value); alert("招待URLをコピーしたよ!"); }; start();