Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion .env.development
Original file line number Diff line number Diff line change
@@ -1 +1,3 @@
VITE_SOCKET_SERVER_URL=http://localhost:3050
VITE_SOCKET_SERVER_URL=http://localhost:4000
VITE_SERVER_URL=http://localhost:4000
VITE_AUTH_KEY=_PLUG_AUTH_
15 changes: 15 additions & 0 deletions codegen.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import type { CodegenConfig } from '@graphql-codegen/cli'

const config: CodegenConfig = {
overwrite: true,
schema: 'http://localhost:4000/graphql',
documents: ['src/**/*.tsx'],
ignoreNoDocuments: true,
generates: {
'./src/__api__/types.ts': {
plugins: ['typescript', 'typescript-operations'],
},
},
}

export default config
12 changes: 9 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,13 @@
"name": "react-typescript-vite",
"private": true,
"version": "0.0.0",
"type": "module",
"scripts": {
"start": "vite serve ./dist",
"dev": "vite",
"build": "tsc && vite build",
"preview": "vite preview",
"prepare": "husky install"
"prepare": "husky install",
"codegen": "graphql-codegen --config codegen.ts"
},
"dependencies": {
"@apollo/client": "^3.7.7",
Expand All @@ -19,11 +19,17 @@
"react-dom": "^18.2.0",
"react-hook-form": "^7.43.0",
"react-router-dom": "^6.8.0",
"socket.io-client": "^4.5.4"
"socket.io-client": "^4.5.4",
"zustand": "^4.3.2"
},
"devDependencies": {
"@commitlint/cli": "^17.4.2",
"@commitlint/config-conventional": "^17.4.2",
"@graphql-codegen/cli": "3.0.0",
"@graphql-codegen/client-preset": "2.0.0",
"@graphql-codegen/introspection": "3.0.0",
"@graphql-codegen/typescript": "^3.0.0",
"@graphql-codegen/typescript-operations": "^3.0.0",
"@types/react": "^18.0.26",
"@types/react-dom": "^18.0.9",
"@vitejs/plugin-react": "^3.0.0",
Expand Down
74 changes: 74 additions & 0 deletions src/__api__/types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
export type Maybe<T> = T | null;
export type InputMaybe<T> = Maybe<T>;
export type Exact<T extends { [key: string]: unknown }> = { [K in keyof T]: T[K] };
export type MakeOptional<T, K extends keyof T> = Omit<T, K> & { [SubKey in K]?: Maybe<T[SubKey]> };
export type MakeMaybe<T, K extends keyof T> = Omit<T, K> & { [SubKey in K]: Maybe<T[SubKey]> };
/** All built-in and custom scalars, mapped to their actual values */
export type Scalars = {
ID: string;
String: string;
Boolean: boolean;
Int: number;
Float: number;
DateTime: any;
};

export type LoginInput = {
nickname: Scalars['String'];
};

export type LoginOutput = {
__typename?: 'LoginOutput';
error?: Maybe<Scalars['String']>;
ok: Scalars['Boolean'];
token?: Maybe<Scalars['String']>;
user?: Maybe<User>;
};

export type Mutation = {
__typename?: 'Mutation';
login: LoginOutput;
};


export type MutationLoginArgs = {
input: LoginInput;
};

export type Query = {
__typename?: 'Query';
getMe: UserProfileOutput;
};

export type User = {
__typename?: 'User';
createdAt: Scalars['DateTime'];
id: Scalars['Float'];
nickname: Scalars['String'];
role?: Maybe<UserRole>;
updatedAt: Scalars['DateTime'];
};

export type UserProfileOutput = {
__typename?: 'UserProfileOutput';
error?: Maybe<Scalars['String']>;
ok: Scalars['Boolean'];
user?: Maybe<User>;
};

export enum UserRole {
Admin = 'Admin',
Client = 'Client'
}

export type GetMeQueryVariables = Exact<{ [key: string]: never; }>;


export type GetMeQuery = { __typename?: 'Query', getMe: { __typename?: 'UserProfileOutput', ok: boolean, error?: string | null, user?: { __typename?: 'User', id: number, nickname: string, createdAt: any, updatedAt: any, role?: UserRole | null } | null } };

export type LoginMutationVariables = Exact<{
LoginInput: LoginInput;
}>;


export type LoginMutation = { __typename?: 'Mutation', login: { __typename?: 'LoginOutput', ok: boolean, token?: string | null, error?: string | null, user?: { __typename?: 'User', id: number, nickname: string, updatedAt: any, createdAt: any, role?: UserRole | null } | null } };
1 change: 1 addition & 0 deletions src/env.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ declare namespace NodeJS {
readonly VITE_SERVER_URL: string
readonly VITE_SOCKET_SERVER_URL: string
readonly VITE_SOCKET_SERVER_PORT: string
readonly VITE_AUTH_KEY: string
readonly [key: string]: string
}
}
22 changes: 20 additions & 2 deletions src/hooks/useSocket.ts
Original file line number Diff line number Diff line change
@@ -1,24 +1,42 @@
import { useEffect, useRef, useState } from 'react'
import { useContext } from 'react'
import { SocketContext } from 'context/socketManager'
import { Socket } from 'socket.io-client'

interface useSocketProps {
nsp: string
}

const useSocket = ({ nsp }: useSocketProps) => {
const { manager } = useContext(SocketContext)
const [isError, setIsError] = useState<string | null>(null)

const socket = useRef(
manager.create_socket(nsp, {
auth: {
token: '123',
token: localStorage.getItem('_PLUG_AUTH_') || '',
},
}),
)
useEffect(() => {
if (socket.current) {
socket.current.listen('connect_error', ({ message }: Error) => {
if (!isError) {
setIsError(message)
}
})
socket.current.listen('connect', () => {
if (isError) {
setIsError(null)
}
})
}
}, [socket.current, isError])
return {
manager,
socket: socket.current,
isError,
isConnected: socket.current.connected,
isLoading: !socket.current,
}
}

Expand Down
67 changes: 46 additions & 21 deletions src/layout/SocketLayout.tsx
Original file line number Diff line number Diff line change
@@ -1,27 +1,52 @@
import { SocketContext } from 'context/socketManager'
import useSocket from 'hooks/useSocket'
import { useContext, useLayoutEffect, useState } from 'react'
import { gql, useQuery } from '@apollo/client'
import { Outlet, useNavigate } from 'react-router-dom'
import Cookie from 'js-cookie'
import { useClearUser } from 'store/action'
import store from 'store/index'
import { GetMeQuery } from '__api__/types'

const GET_ME = gql`

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

graphQl ๋ฅผ ๋„์ž… ํ•˜์…จ๋„ค์š”.

query getMe {
getMe {
ok
user {
id
nickname
createdAt
updatedAt
role
}
error
}
}
`

const SocketLayout = () => {
const cookie = Cookie.get('_PLUG_AUTH_')
const { socket } = useSocket({ nsp: '/' })
const key = import.meta.env.VITE_AUTH_KEY
const token = localStorage.getItem(key) || ''

const { setUser, clear } = store((state) => ({
setUser: state.setUser,
clear: state.clear,
}))
const { data, loading, client } = useQuery<GetMeQuery>(GET_ME, {
context: {
headers: {
[key]: token,
},
},
onCompleted({ getMe: { ok, error, user } }) {
if (ok && user) {
setUser({ user, token })
} else {
clear()
navigate('/login')
}
},
fetchPolicy: 'no-cache',
})

const navigate = useNavigate()
const [loading, setLoading] = useState(true)
useLayoutEffect(() => {
if (socket && cookie) {
// socket.emit('set_nickname', nickname, (nickname: string) => {
// if (nickname) {
// localStorage.setItem('plug_nickname', nickname)
// } else {
// // todo
// }
// })
setLoading(false)
} else {
navigate('/login')
}
}, [])

return <div>{loading ? 'loading...' : <Outlet />}</div>
}

Expand Down
2 changes: 1 addition & 1 deletion src/main.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { ApolloProvider } from '@apollo/client/react'
import { client } from 'apollo'
import { client } from './apollo'
import React from 'react'
import ReactDOM from 'react-dom/client'
import './index.css'
Expand Down
4 changes: 3 additions & 1 deletion src/screen/Home.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import useSocket from 'hooks/useSocket'
import { useCallback, useEffect, useState } from 'react'
import { useForm } from 'react-hook-form'
import { useNavigate } from 'react-router-dom'
import store from 'store/index'

interface JoinRoomInput {
roomName: string
Expand All @@ -14,10 +15,11 @@ const Home = () => {
const { socket } = useSocket({ nsp: '/' })
const navigate = useNavigate()
const [rooms, setRooms] = useState<string[] | []>([])
const user = store((state) => state.user)
const { register: roomRegister, handleSubmit: roomSubmit } = useForm<JoinRoomInput>()
const { register: nicknameRegister, handleSubmit: nicknameSubmit } = useForm<NicknameInput>({
defaultValues: {
nickname: localStorage.getItem('plug_nickname') || '',
nickname: user?.nickname,
},
})

Expand Down
49 changes: 47 additions & 2 deletions src/screen/Login.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,58 @@
import React from 'react'
import { gql, useMutation } from '@apollo/client'
import React, { useCallback } from 'react'
import { useForm } from 'react-hook-form'
import { useNavigate } from 'react-router-dom'
import store from 'store'
import { LoginMutation, LoginMutationVariables } from '__api__/types'

interface LoginInput {
nickname: string
}

const LOGIN_MUTATION = gql`
mutation login($LoginInput: LoginInput!) {
login(input: $LoginInput) {
ok
token
error
user {
id
nickname
updatedAt
createdAt
role
}
}
}
`

const Login = () => {
const [setUser] = store((state) => [state.setUser])
const { register, handleSubmit } = useForm<LoginInput>()
const onSetNickname = ({ nickname }: LoginInput) => {}
const navigate = useNavigate()
const onCompleted = (data: LoginMutation) => {
console.log(data)
const {
login: { error, ok, token, user },
} = data
if (ok && user && token) {
setUser({ user, token })
localStorage.setItem(import.meta.env.VITE_AUTH_KEY, token)
navigate('/')
}
}
const [login] = useMutation<LoginMutation, LoginMutationVariables>(LOGIN_MUTATION, {
onCompleted,
})
const onSetNickname = useCallback(({ nickname }: LoginInput) => {
login({
variables: {
LoginInput: {
nickname,
},
},
})
}, [])
return (
<div>
<form onSubmit={handleSubmit(onSetNickname)}>
Expand Down
10 changes: 5 additions & 5 deletions src/screen/Room.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -105,10 +105,10 @@ const Room = () => {
setUserList(users)
})
socket.emit('join_room', roomName, ({ nickname, userList: users, ok }: Welcome) => {
if (!ok) {
navigate('/')
return
}
// if (!ok) {
// navigate('/')
// return
// }
!loading && setUserList(users)
})

Expand Down Expand Up @@ -143,7 +143,7 @@ const Room = () => {
<div>
<video ref={myVideo}></video>
<video autoPlay ref={peerVideo}></video>
{userList.map((user, index) => (
{userList?.map((user, index) => (
<div key={user + '' + index}>
<span>User : {user}</span>
</div>
Expand Down
3 changes: 3 additions & 0 deletions src/store/action.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import store from 'store'

export const useClearUser = () => store.getState().clear
Loading