Skip to content

Commit

Permalink
chore: Add API endpoints for sending messages with different types (t…
Browse files Browse the repository at this point in the history
…ext, image, audio, video) in group and friend chats
  • Loading branch information
tako0614 committed Jul 12, 2024
1 parent 8230a07 commit a21f327
Show file tree
Hide file tree
Showing 25 changed files with 303 additions and 111 deletions.
4 changes: 2 additions & 2 deletions components/chatmain.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,11 @@ function chatmain({ state }: { state: AppStateType }) {
return (
<>
<div class="p-talk-chat-main" id="chat-area">
<div class="p-talk-chat-title">
<div class="p-talk-chat-title hidden" id="chatHeader">
<div class="p-1 h-full">
<ChatTalkTitle state={state} />
</div>
<ChatTalkTitleContent>a</ChatTalkTitleContent>
<ChatTalkTitleContent state={state}></ChatTalkTitleContent>
</div>
<ChatTalkContent state={state} />
</div>
Expand Down
186 changes: 103 additions & 83 deletions fresh.gen.ts

Large diffs are not rendered by default.

18 changes: 16 additions & 2 deletions islands/ChatTalkContent.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -139,5 +139,19 @@ function ChatTalkMain({ state }: { state: AppStateType }) {
</>
);
}

export default ChatTalkMain;
function ChatTalk({ state }: { state: AppStateType }) {
if (state.isChoiceUser.value === true) {
return (
<ul class="c-talk-chat-list">
<ChatTalkMain state={state} />
</ul>
);
} else {
return (
<div class="flex w-full h-full">
<p class="m-auto">友達を選択してください</p>
</div>
);
}
}
export default ChatTalk;
5 changes: 3 additions & 2 deletions islands/ChatTalkTitleContent.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
export default function ChatTalkTitleContent(props: { children: string }) {
return <p>{props.children}</p>;
import { AppStateType } from "../util/types.ts";
export default function ChatTalkTitleContent(props: { state: AppStateType }) {
return <p>{props.state.roomName.value}</p>;
}
24 changes: 24 additions & 0 deletions islands/TalkListContent.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import User from "../components/User.tsx";
import { setIschoiseUser } from "../util/takosClient.ts";
import { AppStateType } from "../util/types.ts";
function TalkListContent({ state }: { state: AppStateType }) {
if (state.page.value === 0) {
Expand All @@ -15,6 +16,29 @@ function TalkListContent({ state }: { state: AppStateType }) {
userName2={talk.userName}
isNewMessage={talk.isNewMessage}
isSelected={talk.isSelect}
onClick={() => {
setIschoiseUser(true, state.isChoiceUser);
state.roomid.value = talk.roomID;
state.roomName.value = talk.roomName;
console.log(talk.roomName);
state.friendList.value.map((data: any) => {
if (data.roomID == talk.roomID) {
data.isNewMessage = false;
}
});
//urlの一番最後にroomidを追加
//どのようなurlにも対応できるようにする
const url = new URL(window.location.href);
url.searchParams.set("roomid", talk.roomID);
window.history.pushState({}, "", url.toString());
state.ws.value?.send(
JSON.stringify({
type: "join",
sessionid: state.sessionid.value,
roomid: talk.roomID,
}),
);
}}
/>
);
})}
Expand Down
10 changes: 10 additions & 0 deletions islands/setDefaultState.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -28,5 +28,15 @@ export default function setDefaultState({ state }: { state: AppStateType }) {
state.isValidInput.value = false;
}
}, [state.inputMessage.value]);
useEffect(() => {
state.ws.value = new WebSocket("/api/v2/client/main");
state.ws.value.onmessage = (event: any) => {
const data = JSON.parse(event.data);
console.log(data);
};
state.ws.value.onopen = () => {
console.log("connected");
};
}, []);
return <></>;
}
75 changes: 70 additions & 5 deletions routes/api/v2/client/main.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
import { getCookies } from "$std/http/cookie.ts";
import ssessionID from "../../../../models/sessionid.ts";
import users from "../../../../models/users.ts";
import rooms from "../../../../models/rooms.ts";
import redis from "redis";
import pubClient from "../../../../util/redisClient.ts";
import { WebSocketSessionObject } from "../../../../util/types.ts";
import { WebSocketJoiningFriend, WebSocketJoiningRoom, WebSocketSessionObject } from "../../../../util/types.ts";
import { load } from "$std/dotenv/mod.ts";
import friends from "../../../../models/friends.ts";
import takos from "../../../../util/takos.ts";
const env = await load();
const redisURL = env["REDIS_URL"];
const redisch = env["REDIS_CH"];
Expand Down Expand Up @@ -37,13 +40,15 @@ export const handler = {
//sessionidを取得
const cookies = getCookies(req.headers);
const sessionid = cookies.sessionid;
const isTrueSessionid = await ssessionID.findOne({ sessionid: sessionid });
const isTrueSessionid = await ssessionID.findOne({ sessionID: sessionid });
if (!isTrueSessionid) {
console.log("Invalid SessionID", sessionid);
socket.close(1000, "Invalid SessionID");
return;
}
const user = await users.findOne({ uuid: isTrueSessionid.userid });
if (!user) {
console.log("Invalid User");
socket.close(1000, "Invalid User");
return;
}
Expand All @@ -59,13 +64,73 @@ export const handler = {
const data = JSON.parse(event.data);
if (data.type === "ping") {
socket.send(JSON.stringify({ type: "pong" }));
UpdateLastActivityTime(value.sessionid);
return;
}
if (data.type === "joinFriend") {
const value = data as WebSocketJoiningFriend;
const session = sessions.get(value.sessionid);
if (!session) {
socket.close(1000, "Invalid SessionID");
return;
}
const friendId = value.friendid;
const friendList = await friends.findOne({ user: ctx.state.data.user.uuid});
if (!friendList) {
socket.close(1000, "you have no friends");
return;
}
const friend = friendList.friends.find((friend) => friend.userid === friendId);
if (!friend) {
socket.close(1000, "Invalid FriendID");
return;
}
const roomid = friend.room;
const room = await rooms.findOne({ uuid: roomid });
if (!room) {
socket.close(1000, "Invalid RoomID");
return;
}
session.roomid = room.uuid;
session.roomType = room.types;
sessions.set(value.sessionid, session);
//ルームに参加したことを通知
pubClient.publish(room.uuid, JSON.stringify({ type: "join", userid: session.userid }));
session.ws.send(JSON.stringify({ type: "joined", roomid: room.uuid }));
UpdateLastActivityTime(value.sessionid);
return;
}
if (data.type === "join") {
const session = sessions.get(data.sessionid);
if (data.type === "joinRoom") {
const value = data as WebSocketJoiningRoom;
const session = sessions.get(value.sessionid);
if (!session) {
socket.close(1000, "Invalid SessionID");
return;
}
const room = await rooms.findOne({ roomID: value.roomid });
if (!room) {
socket.close(1000, "Invalid RoomID");
return;
}
//個人ルームかどうかを確認
if (room.types === "friend" || room.types === "remotefriend") {
socket.close(1000, "Invalid RoomID");
return;
}
//ルームメンバーかどうかを確認
const isRoomMember = room.users.find((user) => user.userid === session.userid);
if (!isRoomMember) {
socket.close(1000, "Invalid RoomID");
return;
}
session.roomid = value.roomid;
session.roomType = room.types;
sessions.set(value.sessionid, session);
//ルームに参加したことを通知
pubClient.publish(value.roomid, JSON.stringify({ type: "join", userid: session.userid }));
session.ws.send(JSON.stringify({ type: "joined", roomid: value.roomid }));
UpdateLastActivityTime(value.sessionid);
return;
}
};
socket.onclose = () => {
Expand All @@ -78,7 +143,7 @@ export const handler = {
};

// セッションの最後の活動時間を更新する関数
function UpdateLastActivityTime(sessionId: string, Changes: Object) {
function UpdateLastActivityTime(sessionId: string) {
const session = sessions.get(sessionId);
if (!session) {
return;
Expand Down
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
4 changes: 4 additions & 0 deletions routes/api/v2/client/talks/friend/audio.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
//音声メッセージを送信
// POST /api/v2/client/talks/sending/audio
// { audio: file, csrftoken: string, roomid: string, channel: string }
// -> { status: boolean, message: string }
4 changes: 4 additions & 0 deletions routes/api/v2/client/talks/friend/image.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
//画像を送信
// POST /api/v2/client/talks/sending/image
// { image: file, csrftoken: string, roomid: string, channel: string }
// -> { status: boolean, message: string }
4 changes: 4 additions & 0 deletions routes/api/v2/client/talks/friend/text.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
//textメッセージを送信する
// POST /api/v2/client/talks/sending/text
// { text: string, csrftoken: string, roomid: string, channel: string }
// -> { status: boolean, message: string }
4 changes: 4 additions & 0 deletions routes/api/v2/client/talks/friend/update.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
//textメッセージを編集する
// POST /api/v2/client/talks/sending/update
// { text: string, csrftoken: string, roomid: string, channel: string, messageid: string }
// -> { status: boolean, message: string }
4 changes: 4 additions & 0 deletions routes/api/v2/client/talks/friend/video.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
//動画を送信するapi
// POST /api/v2/client/talks/sending/video
// { video: file, csrftoken: string, roomid: string, channel: string }
// -> { status: boolean, message: string }
4 changes: 4 additions & 0 deletions routes/api/v2/client/talks/group/audio.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
//音声メッセージを送信
// POST /api/v2/client/talks/sending/audio
// { audio: file, csrftoken: string, roomid: string, channel: string }
// -> { status: boolean, message: string }
4 changes: 4 additions & 0 deletions routes/api/v2/client/talks/group/image.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
//画像を送信
// POST /api/v2/client/talks/sending/image
// { image: file, csrftoken: string, roomid: string, channel: string }
// -> { status: boolean, message: string }
4 changes: 4 additions & 0 deletions routes/api/v2/client/talks/group/text.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
//textメッセージを送信する
// POST /api/v2/client/talks/sending/text
// { text: string, csrftoken: string, roomid: string, channel: string }
// -> { status: boolean, message: string }
4 changes: 4 additions & 0 deletions routes/api/v2/client/talks/group/update.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
//textメッセージを編集する
// POST /api/v2/client/talks/sending/update
// { text: string, csrftoken: string, roomid: string, channel: string, messageid: string }
// -> { status: boolean, message: string }
4 changes: 4 additions & 0 deletions routes/api/v2/client/talks/group/video.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
//動画を送信するapi
// POST /api/v2/client/talks/sending/video
// { video: file, csrftoken: string, roomid: string, channel: string }
// -> { status: boolean, message: string }
17 changes: 0 additions & 17 deletions util/takos.ts
Original file line number Diff line number Diff line change
Expand Up @@ -137,23 +137,6 @@ const takos = {
}
return true;
},
setIschoiseUser: (ischoiseUser: boolean, obj: any) => {
const headerElement = document.getElementById("header");
const chatmainElement = document.getElementById("chatmain");
if (chatmainElement === null || headerElement === null) {
return;
}
if (ischoiseUser) {
//"l-header is-inview" : "l-header"
//isChoiceUser ? "p-talk is-inview" : "p-talk"
headerElement.className = "l-header is-inview";
chatmainElement.className = "p-talk is-inview";
} else {
headerElement.className = "l-header";
chatmainElement.className = "p-talk";
}
obj.value = ischoiseUser;
},
};
export default takos;
async function importCryptoKey(keyData: string | undefined): Promise<CryptoKey> {
Expand Down
25 changes: 25 additions & 0 deletions util/takosClient.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
// Cache the elements outside the function if they are used multiple times throughout the app
let headerElement: HTMLElement | null;
let chatmainElement: HTMLElement | null;
let chatHeaderElement: HTMLElement | null;

export const setIschoiseUser = (ischoiseUser: boolean, obj: any) => {
if (!headerElement || !chatmainElement || !chatHeaderElement) {
headerElement = document.getElementById("header");
chatmainElement = document.getElementById("chatmain");
chatHeaderElement = document.getElementById("chatHeader");
}
if (ischoiseUser) {
headerElement?.classList.add("is-inview");
chatmainElement?.classList.add("is-inview");
chatHeaderElement?.classList.remove("hidden");
} else {
headerElement?.classList.remove("is-inview");
chatmainElement?.classList.remove("is-inview");
chatHeaderElement?.classList.add("hidden");
}
// Only update obj.value if necessary
if (obj.value !== ischoiseUser) {
obj.value = ischoiseUser;
}
};
10 changes: 10 additions & 0 deletions util/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -59,3 +59,13 @@ export interface WebSocketSessionObject {
roomType: string;
lastActivityTime: Date;
}
export interface WebSocketJoiningRoom {
type: string;
sessionid: string;
roomid: string;
}
export interface WebSocketJoiningFriend {
type: string;
sessionid: string;
friendid: string;
}

0 comments on commit a21f327

Please sign in to comment.