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
10 changes: 7 additions & 3 deletions src/assets/shared/lib/axios.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,13 @@ export class TokenRefreshError extends Error {
}
}

export const baseURL = import.meta.env.DEV
? ''
: 'https://port-0-gami-server-mj0rdvda8d11523e.sel3.cloudtype.app';
const DEFAULT_BACKEND =
'https://port-0-gami-server-mj0rdvda8d11523e.sel3.cloudtype.app';

// Allow override via Vite env var VITE_API_BASE for local testing.
// Fallback to DEFAULT_BACKEND to avoid dev-time proxying to vite origin.
export const baseURL: string =
(import.meta.env.VITE_API_BASE as string) || DEFAULT_BACKEND;

export const instance = axios.create({
baseURL,
Expand Down
40 changes: 16 additions & 24 deletions src/hooks/useStomp.ts
Original file line number Diff line number Diff line change
Expand Up @@ -210,41 +210,33 @@ export function useStomp<TRoomMessage = unknown>(
}

isConnectingRef.current = true;
const backendOriginRaw =
baseURL && baseURL !== '' ? baseURL : window.location.origin;
let backendOrigin = String(backendOriginRaw);

if (backendOrigin.startsWith('ws:')) {
backendOrigin = backendOrigin.replace(/^ws:/, 'http:');
} else if (backendOrigin.startsWith('wss:')) {
backendOrigin = backendOrigin.replace(/^wss:/, 'https:');
}

const wsUrl = `${baseURL}/ws`;
const sockjsUrl = backendOrigin.endsWith('/')
? backendOrigin + 'ws'
: backendOrigin + '/ws';

if (connectionTimeoutIdRef.current) {
clearTimeout(connectionTimeoutIdRef.current);
connectionTimeoutIdRef.current = null;
}

const socket = new SockJS(wsUrl, null, {
transports: ['websocket', 'xhr-streaming', 'xhr-polling'],
});

socket.onerror = (error: Event) => {
console.error('SockJS 였λ₯˜:', error);
isConnectingRef.current = false;
if (connectionTimeoutIdRef.current) {
clearTimeout(connectionTimeoutIdRef.current);
connectionTimeoutIdRef.current = null;
}
};

socket.onclose = () => {
isConnectingRef.current = false;
if (connectionTimeoutIdRef.current) {
clearTimeout(connectionTimeoutIdRef.current);
connectionTimeoutIdRef.current = null;
}
};

const client = new Client({
webSocketFactory: () => socket as WebSocket,
// SockJS μΈμŠ€ν„΄μŠ€λ₯Ό webSocketFactoryμ—μ„œ 직접 μƒμ„±ν•΄μ„œ λ°˜ν™˜ν•©λ‹ˆλ‹€.
webSocketFactory: () => new SockJS(sockjsUrl),
connectHeaders: {
Authorization: `Bearer ${token}`,
},
reconnectDelay: 0,
// μž¬μ ‘μ† 지연을 두어 반볡 μ—°κ²° μ‹œλ„λ₯Ό μ™„ν™”ν•©λ‹ˆλ‹€.
reconnectDelay: 2000,
heartbeatIncoming: 4000,
heartbeatOutgoing: 4000,
connectionTimeout: 10000,
Expand Down
1 change: 0 additions & 1 deletion src/pages/chat/ChatApplyPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,6 @@ export default function ChatApplyPage() {
return () => {
disconnectWebSocket();
};
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [connectWebSocket, disconnectWebSocket]);

useEffect(() => {
Expand Down
7 changes: 7 additions & 0 deletions src/pages/chat/ChatPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -406,6 +406,13 @@ export default function ChatPage() {
return;
}

if (message.length > 250) {
toast.error(
`λ©”μ‹œμ§€λŠ” 250자 μ΄ν•˜λ‘œ μž‘μ„±ν•΄μ£Όμ„Έμš”. (ν˜„μž¬ ${message.length}자)`
);
return;
Comment on lines +409 to +413
Copy link
Contributor

Choose a reason for hiding this comment

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

medium

λ©”μ‹œμ§€ μ΅œλŒ€ 길이λ₯Ό λ‚˜νƒ€λ‚΄λŠ” 숫자 250이 μ½”λ“œμ— 직접 μ‚¬μš©λ˜μ—ˆμŠ΅λ‹ˆλ‹€ (맀직 λ„˜λ²„). 이 값을 μƒμˆ˜λ‘œ μ •μ˜ν•˜λ©΄ μ½”λ“œμ˜ 가독성과 μœ μ§€λ³΄μˆ˜μ„±μ„ 높일 수 μžˆμŠ΅λ‹ˆλ‹€. 예λ₯Ό λ“€μ–΄, λ‚˜μ€‘μ— μ΅œλŒ€ 길이λ₯Ό λ³€κ²½ν•΄μ•Ό ν•  λ•Œ ν•œ 곳만 μˆ˜μ •ν•˜λ©΄ λ©λ‹ˆλ‹€. 이 μƒμˆ˜λŠ” handleSendMessage ν•¨μˆ˜ μ™ΈλΆ€(예: 파일 μ΅œμƒλ‹¨)에 μ„ μ–Έν•˜λŠ” 것이 더 μ’‹μŠ΅λ‹ˆλ‹€.

Suggested change
if (message.length > 250) {
toast.error(
`λ©”μ‹œμ§€λŠ” 250자 μ΄ν•˜λ‘œ μž‘μ„±ν•΄μ£Όμ„Έμš”. (ν˜„μž¬ ${message.length}자)`
);
return;
const MAX_MESSAGE_LENGTH = 250;
if (message.length > MAX_MESSAGE_LENGTH) {
toast.error(
`λ©”μ‹œμ§€λŠ” ${MAX_MESSAGE_LENGTH}자 μ΄ν•˜λ‘œ μž‘μ„±ν•΄μ£Όμ„Έμš”. (ν˜„μž¬ ${message.length}자)`
);
return;
}

}

if (!isConnected()) {
toast.error(
'WebSocket이 μ—°κ²°λ˜μ§€ μ•Šμ•˜μŠ΅λ‹ˆλ‹€. μž μ‹œ ν›„ λ‹€μ‹œ μ‹œλ„ν•΄μ£Όμ„Έμš”.'
Expand Down
45 changes: 31 additions & 14 deletions src/pages/mentoring/MentoringPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,12 @@ interface SentApply {
createdAt: string;
}

type MentorParams = {
page: number;
size: number;
generation?: number;
};

export default function MentoringPage() {
const [allMentors, setAllMentors] = useState<MentorData[]>([]);
const [searchQuery, setSearchQuery] = useState('');
Expand All @@ -62,22 +68,33 @@ export default function MentoringPage() {
const fetchData = async () => {
try {
setIsLoading(true);
const [mentorsResponse, memberResponse, sentAppliesResponse] =
await Promise.all([
instance.get<MentorListResponse>('/api/mentoring/mentor/all', {
params: {
page: 0,
size: 100,
},
}),
instance.get<MemberInfo>('/api/member'),
instance
.get<SentApply[]>(API_PATHS.MENTORING_APPLY_SENT)
.catch(() => ({ data: [] })),
]);

// λ¨Όμ € ν˜„μž¬ 멀버 정보λ₯Ό 가져와 generation을 ν™•λ³΄ν•©λ‹ˆλ‹€.
let memberResponse: { data: MemberInfo } | null = null;
try {
memberResponse = await instance.get<MemberInfo>('/api/member');
setCurrentMemberId(memberResponse.data.memberId);
} catch {
// 멀버 쑰회 μ‹€νŒ¨(예: 비인증) μ‹œμ—λ„ λ©˜ν†  λͺ©λ‘μ€ generation 없이 κ°€μ Έμ˜΅λ‹ˆλ‹€.
memberResponse = null;
setCurrentMemberId(null);
}

const mentorParams: MentorParams = { page: 0, size: 100 };
if (memberResponse && memberResponse.data.generation != null) {
mentorParams.generation = memberResponse.data.generation;
}

const [mentorsResponse, sentAppliesResponse] = await Promise.all([
instance.get<MentorListResponse>('/api/mentoring/mentor/all', {
params: mentorParams,
}),
instance
.get<SentApply[]>(API_PATHS.MENTORING_APPLY_SENT)
.catch(() => ({ data: [] })),
]);

setAllMentors(mentorsResponse.data.content);
setCurrentMemberId(memberResponse.data.memberId);
if (Array.isArray(sentAppliesResponse.data)) {
setSentApplies(sentAppliesResponse.data);
}
Expand Down
Loading