Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
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
41 changes: 41 additions & 0 deletions .github/workflows/fe-code-check.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
name: Frontend Lint Check

on:
pull_request:
branches: [dev/fe]
paths:
- "src/frontend/**"
push:
branches: [dev/fe]
paths:
- "src/frontend/**"

jobs:
lint:
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v4

- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: "20"
cache: "yarn"
cache-dependency-path: "./src/frontend/yarn.lock"

- name: Install Dependencies
working-directory: ./src/frontend
run: yarn install --frozen-lockfile

- name: Run ESLint
working-directory: ./src/frontend
run: yarn lint --max-warnings=0

- name: Run Type Check
working-directory: ./src/frontend
run: yarn typecheck

- name: Run Prettier Check
working-directory: ./src/frontend
run: yarn format
7 changes: 6 additions & 1 deletion src/frontend/eslint.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import reactHooks from 'eslint-plugin-react-hooks'
import simpleImportSort from 'eslint-plugin-simple-import-sort'
import tanstackPlugin from '@tanstack/eslint-plugin-query'
import unusedImports from 'eslint-plugin-unused-imports'
import reactPlugin from 'eslint-plugin-react'

export default tseslint.config(
{ ignores: ['dist', 'node_modules', '**/*.config.js', '!**/eslint.config.js'] },
Expand Down Expand Up @@ -37,10 +38,14 @@ export default tseslint.config(
'simple-import-sort': simpleImportSort,
'@typescript-eslint': tseslint.plugin,
onlyWarn,
tanstack: tanstackPlugin
tanstack: tanstackPlugin,
react: reactPlugin
},
rules: {
...reactHooks.configs.recommended.rules,
'no-console': ['error', { allow: ['warn', 'error'] }],
'react-hooks/rules-of-hooks': 'error',
'react-hooks/exhaustive-deps': 'warn',
'import/no-anonymous-default-export': 'off',
'prettier/prettier': 'error',
'unused-imports/no-unused-imports': 'error',
Expand Down
7 changes: 5 additions & 2 deletions src/frontend/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,10 @@
"start": "vite",
"typecheck": "tsc",
"check": "yarn formatter && yarn lint:fix",
"lint": "eslint \"src/**/*.{ts,tsx}\"",
"lint:fix": "eslint --fix \"src/**/*.{ts,tsx}\"",
"formatter": "prettier --write \"src/**/*.{ts,tsx}\"",
"format": "prettier --check \"src/**/*.{ts,tsx}\"",
"format:fix": "prettier --write \"src/**/*.{ts,tsx}\"",
"preview": "vite preview",
"storybook": "storybook dev -p 6006",
"build-storybook": "storybook build",
Expand Down Expand Up @@ -56,7 +58,8 @@
"eslint": "^9.17.0",
"eslint-plugin-only-warn": "^1.1.0",
"eslint-plugin-prettier": "^5.2.3",
"eslint-plugin-react-hooks": "^5.0.0",
"eslint-plugin-react": "^7.37.4",
"eslint-plugin-react-hooks": "^5.2.0",
"eslint-plugin-simple-import-sort": "^12.1.1",
"eslint-plugin-storybook": "^0.11.2",
"eslint-plugin-unused-imports": "^4.1.4",
Expand Down
2 changes: 1 addition & 1 deletion src/frontend/src/components/chat-area/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ function ChatArea({
if (historyMessages && chatKey) {
setMessages(Number(chatKey), historyMessages)
}
}, [historyMessages, chatKey])
}, [historyMessages, chatKey, setMessages])

useEffect(() => {
if (messagesRef.current) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import type { Meta, StoryObj } from '@storybook/react'
import { fn } from '@storybook/test'

import HeaderToolBar from '.'

Expand Down Expand Up @@ -27,11 +28,11 @@ export const PrimaryHeaderToolBar: Story = {
args: {
type: 'DEFAULT',
isStatusBarOpen: false,
onToggleStatusBar: () => console.log('Status bar toggled'),
onToggleStatusBar: () => fn(),
searchProps: {
value: '검색',
onChange: () => console.log('검색'),
handleClear: () => console.log('검색 초기화'),
onChange: () => fn(),
handleClear: () => fn(),
placeholder: '검색'
}
}
Expand All @@ -40,7 +41,7 @@ export const PrimaryHeaderToolBar: Story = {
export const VoiceChannelHeaderToolBar: Story = {
args: {
type: 'VOICE',
onClose: () => console.log('Voice channel closed')
onClose: () => fn()
}
}

Expand All @@ -49,8 +50,8 @@ export const DirectMessageHeaderToolBar: Story = {
type: 'DM',
searchProps: {
value: '검색',
onChange: () => console.log('검색'),
handleClear: () => console.log('검색 초기화'),
onChange: () => fn(),
handleClear: () => fn(),
placeholder: '검색'
}
}
Expand All @@ -60,11 +61,11 @@ export const StatusBarOpenHeaderToolBar: Story = {
args: {
type: 'DEFAULT',
isStatusBarOpen: true,
onToggleStatusBar: () => console.log('Status bar toggled'),
onToggleStatusBar: () => fn(),
searchProps: {
value: '검색',
onChange: () => console.log('검색'),
handleClear: () => console.log('검색 초기화'),
onChange: () => fn(),
handleClear: () => fn(),
placeholder: '검색'
}
}
Expand Down
25 changes: 15 additions & 10 deletions src/frontend/src/layouts/main-layout/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -35,23 +35,27 @@ const Inner = () => {

const navigate = useNavigate()

useEffect(function init() {
const initChatting = async () => {
if (!checkConnection()) {
await connectChatting()
await subscribeToPersonal()
}
}

/* Socket 연결 관련 함수들은 매번 새로 생성될 필요가 없고,
* 의존성 배열에 추가하면 불필요한 재연결이 발생할 수 있으므로
* exhaustive-deps 규칙을 비활성화합니다.
*/
useEffect(() => {
checkConnection()
connectChatting()
connectSignaling()
initChatting()
subscribeToPersonal()

return function cleanup() {
return () => {
disconnectChatting()
disconnectSignaling()
}
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [])

/* 서버 연결 관련 함수들은 매번 새로 생성될 필요가 없고,
* 의존성 배열에 추가하면 불필요한 재연결이 발생할 수 있으므로
* exhaustive-deps 규칙을 비활성화합니다.
*/
useEffect(() => {
const subscribeToServerIfConnected = async () => {
if (!serverId) return
Expand All @@ -77,6 +81,7 @@ const Inner = () => {
unsubscribe(`/topic/server/${previousServerId.current}`)
}
}
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [checkConnection])

const myChannelList = useGetServer()
Expand Down
5 changes: 5 additions & 0 deletions src/frontend/src/layouts/server-layout/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,10 @@ function ServerLayout() {

const { channelInfoList } = serverData

/*
* 채널 입장 및 퇴장 이벤트를 처리하는 함수
* 무한 루프 방지를 위해 exhaustive-deps 규칙을 비활성화합니다.
*/
useEffect(() => {
if (!channelInfoList || channelInfoList.length === 0) return

Expand All @@ -48,6 +52,7 @@ function ServerLayout() {
lastReadMessageId: getLastMessageId(Number(channelId))
})
}
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [channelId, channelInfoList, serverId])

return (
Expand Down
7 changes: 5 additions & 2 deletions src/frontend/src/stores/use-server-unread-store.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,11 @@ export const useServerUnreadStore = create<ServerUnreadStore>((set) => ({
resetUnreadCount: (serverId, channelId) =>
set((state) => {
if (!state.unreadCounts[serverId]) return state
const newCounts = { ...state.unreadCounts[serverId] }
delete newCounts[channelId]

const newCounts = Object.fromEntries(
Object.entries(state.unreadCounts[serverId]).filter(([key]) => key !== String(channelId))
)

return {
unreadCounts: { ...state.unreadCounts, [serverId]: newCounts }
}
Expand Down
1 change: 1 addition & 0 deletions src/frontend/src/utils/log.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { ENABLE_CONSOLE } from '@/constants/env'

export const log = (message: string, ...args: unknown[]) => {
if (!ENABLE_CONSOLE) return
// eslint-disable-next-line no-console
console.log(`%c${message}`, 'color: #4CAF50; font-weight: bold;', ...args)
}
export const errorLog = (message: string, ...args: unknown[]) => {
Expand Down
Loading