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
2 changes: 1 addition & 1 deletion src/features/map/collaboration/CollabCursorsOverlay.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
'use client';

import { useEffect, useRef } from 'react';
import { useMyPresence, useOthers } from './liveblocks.config';
import { useMyPresence, useOthers } from '@liveblocks/react';
import { useMapStore } from '../hooks/useMapStore';
import { escapeHtml } from '../utils/formatters';
import { mapIconSvg } from '../utils/mapIconSvg';
Expand Down
2 changes: 1 addition & 1 deletion src/features/map/collaboration/CollabParticipants.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
'use client';

import styled from '@emotion/styled';
import { useSelf, useOthers } from './liveblocks.config';
import { useSelf, useOthers } from '@liveblocks/react';
import { palette, meok, ringShadow } from '@/design-system/tokens';

const USER_COLORS = [
Expand Down
16 changes: 15 additions & 1 deletion src/features/map/collaboration/MapCollabProvider.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,21 @@

import { Component, createContext, useContext, useRef, type ReactNode } from 'react';
import { LiveList } from '@liveblocks/client';
import { RoomProvider } from './liveblocks.config';
import { LiveblocksProvider, RoomProvider } from '@liveblocks/react';
import { useAuth } from '@/features/auth';

async function liveblocksAuthEndpoint(roomId?: string): Promise<{ token: string }> {
const room = (roomId ?? '').replace(/^map-collab-/, '');
const res = await fetch('/api/liveblocks-auth', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ room }),
credentials: 'include',
});
if (!res.ok) throw new Error(`Liveblocks auth failed: ${res.status}`);
return res.json();
}

// true = inside a live RoomProvider; false = error fallback path (no RoomProvider)
export const CollabActiveContext = createContext(false);
export const useCollabActive = () => useContext(CollabActiveContext);
Expand Down Expand Up @@ -33,6 +45,7 @@ export function MapCollabProvider({ roomId, children }: Props) {

return (
<CollabErrorBoundary fallback={children}>
<LiveblocksProvider authEndpoint={liveblocksAuthEndpoint}>
<CollabActiveContext.Provider value={true}>
<RoomProvider
id={`map-collab-${roomId}`}
Expand All @@ -49,6 +62,7 @@ export function MapCollabProvider({ roomId, children }: Props) {
{children}
</RoomProvider>
</CollabActiveContext.Provider>
</LiveblocksProvider>
</CollabErrorBoundary>
);
}
49 changes: 14 additions & 35 deletions src/features/map/collaboration/liveblocks.config.ts
Original file line number Diff line number Diff line change
@@ -1,22 +1,5 @@
import { createClient } from '@liveblocks/client';
import { createRoomContext } from '@liveblocks/react';
import type { LiveList } from '@liveblocks/client';

export const client = createClient({
authEndpoint: async (roomId) => {
// roomId = "map-collab-<uuid>", 뒤의 UUID만 추출해서 서버에 전송
const room = (roomId ?? '').replace(/^map-collab-/, '');
const res = await fetch('/api/liveblocks-auth', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ room }),
credentials: 'include',
});
if (!res.ok) throw new Error(`Liveblocks auth failed: ${res.status}`);
return res.json();
},
});

export type CollabPin = {
placeId: string;
placeName: string;
Expand All @@ -25,22 +8,18 @@ export type CollabPin = {
userId: string;
};

export type Presence = {
cursor: { lat: number; lng: number } | null;
userId: string;
nickname: string;
profileImage: string | null;
};

export type Storage = {
pins: LiveList<CollabPin>;
};
declare global {
interface Liveblocks {
Presence: {
cursor: { lat: number; lng: number } | null;
userId: string;
nickname: string;
profileImage: string | null;
};
Storage: {
pins: LiveList<CollabPin>;
};
}
}

export const {
RoomProvider,
useOthers,
useMyPresence,
useStorage,
useMutation,
useSelf,
} = createRoomContext<Presence, Storage>(client);
export {};
2 changes: 1 addition & 1 deletion src/features/map/collaboration/useCollabPins.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
'use client';

import { useStorage, useMutation } from './liveblocks.config';
import { useStorage, useMutation } from '@liveblocks/react';
import type { CollabPin } from './liveblocks.config';

export function useCollabPins() {
Expand Down
Loading