feat: update main chat and system chat UI
This commit is contained in:
155
src/app/main/isolatedChatRooms.ts
Normal file
155
src/app/main/isolatedChatRooms.ts
Normal file
@@ -0,0 +1,155 @@
|
||||
export const ISOLATED_CHAT_ROOM_SESSION_PREFIX = 'chat-room-menu-';
|
||||
export const MANAGED_CHAT_SHARE_SESSION_PREFIX = 'chat-share-room-';
|
||||
|
||||
export type IsolatedChatRoomScope = {
|
||||
topMenu: string;
|
||||
menuTitle: string;
|
||||
featureTitle: string;
|
||||
focusedComponentId: string | null;
|
||||
pageUrl: string;
|
||||
selectionSummary?: string | null;
|
||||
selectionIds?: string[];
|
||||
errorSummary?: string | null;
|
||||
sourceAppId?: string | null;
|
||||
launchedAt: string;
|
||||
};
|
||||
|
||||
export type MainChatPanelMode = 'live' | 'rooms';
|
||||
|
||||
export function isIsolatedChatRoomSessionId(sessionId: string | null | undefined) {
|
||||
return String(sessionId ?? '').trim().startsWith(ISOLATED_CHAT_ROOM_SESSION_PREFIX);
|
||||
}
|
||||
|
||||
export function isManagedChatShareSessionId(sessionId: string | null | undefined) {
|
||||
return String(sessionId ?? '').trim().startsWith(MANAGED_CHAT_SHARE_SESSION_PREFIX);
|
||||
}
|
||||
|
||||
export function createIsolatedChatRoomSessionId() {
|
||||
if (typeof crypto !== 'undefined' && typeof crypto.randomUUID === 'function') {
|
||||
return `${ISOLATED_CHAT_ROOM_SESSION_PREFIX}${crypto.randomUUID()}`;
|
||||
}
|
||||
|
||||
return `${ISOLATED_CHAT_ROOM_SESSION_PREFIX}${Date.now().toString(36)}-${Math.random().toString(36).slice(2, 10)}`;
|
||||
}
|
||||
|
||||
export function shouldShowConversationForMode(sessionId: string, mode: MainChatPanelMode) {
|
||||
const isIsolatedRoom = isIsolatedChatRoomSessionId(sessionId);
|
||||
const isManagedShareRoom = isManagedChatShareSessionId(sessionId);
|
||||
return mode === 'rooms' ? isIsolatedRoom || isManagedShareRoom : !isIsolatedRoom && !isManagedShareRoom;
|
||||
}
|
||||
|
||||
export function resolveChatPathForSession(sessionId: string) {
|
||||
return isIsolatedChatRoomSessionId(sessionId) || isManagedChatShareSessionId(sessionId) ? '/chat/rooms' : '/chat/live';
|
||||
}
|
||||
|
||||
export function normalizeIsolatedChatRoomScope(
|
||||
scope: Partial<IsolatedChatRoomScope> | null | undefined,
|
||||
): IsolatedChatRoomScope | null {
|
||||
if (!scope) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const menuTitle = String(scope.menuTitle ?? '').trim();
|
||||
const featureTitle = String(scope.featureTitle ?? '').trim();
|
||||
const pageUrl = String(scope.pageUrl ?? '').trim();
|
||||
|
||||
if (!menuTitle && !featureTitle && !pageUrl) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return {
|
||||
topMenu: String(scope.topMenu ?? '').trim() || 'unknown',
|
||||
menuTitle: menuTitle || '현재 메뉴',
|
||||
featureTitle: featureTitle || menuTitle || '현재 기능',
|
||||
focusedComponentId: String(scope.focusedComponentId ?? '').trim() || null,
|
||||
pageUrl,
|
||||
selectionSummary: String(scope.selectionSummary ?? '').trim() || null,
|
||||
selectionIds: Array.isArray(scope.selectionIds)
|
||||
? scope.selectionIds.map((item) => String(item).trim()).filter(Boolean)
|
||||
: [],
|
||||
errorSummary: String(scope.errorSummary ?? '').trim() || null,
|
||||
sourceAppId: String(scope.sourceAppId ?? '').trim() || null,
|
||||
launchedAt: String(scope.launchedAt ?? '').trim() || new Date().toISOString(),
|
||||
};
|
||||
}
|
||||
|
||||
export function buildIsolatedChatRoomTitle(scope: IsolatedChatRoomScope | null | undefined) {
|
||||
if (!scope) {
|
||||
return '격리 채팅방';
|
||||
}
|
||||
|
||||
return `${scope.menuTitle} · ${scope.featureTitle}`.trim();
|
||||
}
|
||||
|
||||
export function buildIsolatedChatRoomRequestBadgeLabel(scope: IsolatedChatRoomScope | null | undefined) {
|
||||
if (!scope) {
|
||||
return '격리 요청';
|
||||
}
|
||||
|
||||
return scope.focusedComponentId?.trim() || scope.featureTitle || scope.menuTitle || '격리 요청';
|
||||
}
|
||||
|
||||
export function buildIsolatedChatRoomContextSupplement(scope: IsolatedChatRoomScope | null | undefined) {
|
||||
if (!scope) {
|
||||
return '';
|
||||
}
|
||||
|
||||
const lines = [
|
||||
'## 격리 채팅방 범위',
|
||||
`- 현재 활성 메뉴: ${scope.menuTitle}`,
|
||||
`- 현재 기능: ${scope.featureTitle}`,
|
||||
`- topMenu: ${scope.topMenu || '없음'}`,
|
||||
`- focusedComponentId: ${scope.focusedComponentId || '없음'}`,
|
||||
`- pageUrl: ${scope.pageUrl || '없음'}`,
|
||||
];
|
||||
|
||||
if (scope.selectionSummary) {
|
||||
lines.push(`- 현재 선택: ${scope.selectionSummary}`);
|
||||
}
|
||||
|
||||
if (scope.selectionIds && scope.selectionIds.length > 0) {
|
||||
lines.push(`- 선택 ID: ${scope.selectionIds.join(', ')}`);
|
||||
}
|
||||
|
||||
if (scope.errorSummary) {
|
||||
lines.push('');
|
||||
lines.push('## 최근 참조 에러');
|
||||
lines.push(scope.errorSummary);
|
||||
}
|
||||
|
||||
return lines.join('\n').trim();
|
||||
}
|
||||
|
||||
function normalizeScopeCompareValue(value: string | null | undefined) {
|
||||
return String(value ?? '').trim();
|
||||
}
|
||||
|
||||
function normalizeScopeSelectionIds(value: string[] | null | undefined) {
|
||||
return (value ?? []).map((item) => String(item).trim()).filter(Boolean).sort();
|
||||
}
|
||||
|
||||
export function doesIsolatedChatRoomScopeMatch(
|
||||
left: IsolatedChatRoomScope | null | undefined,
|
||||
right: IsolatedChatRoomScope | null | undefined,
|
||||
) {
|
||||
const normalizedLeft = normalizeIsolatedChatRoomScope(left);
|
||||
const normalizedRight = normalizeIsolatedChatRoomScope(right);
|
||||
|
||||
if (!normalizedLeft || !normalizedRight) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const leftSelectionIds = normalizeScopeSelectionIds(normalizedLeft.selectionIds);
|
||||
const rightSelectionIds = normalizeScopeSelectionIds(normalizedRight.selectionIds);
|
||||
|
||||
return (
|
||||
normalizeScopeCompareValue(normalizedLeft.sourceAppId) === normalizeScopeCompareValue(normalizedRight.sourceAppId) &&
|
||||
normalizeScopeCompareValue(normalizedLeft.topMenu) === normalizeScopeCompareValue(normalizedRight.topMenu) &&
|
||||
normalizeScopeCompareValue(normalizedLeft.menuTitle) === normalizeScopeCompareValue(normalizedRight.menuTitle) &&
|
||||
normalizeScopeCompareValue(normalizedLeft.featureTitle) === normalizeScopeCompareValue(normalizedRight.featureTitle) &&
|
||||
normalizeScopeCompareValue(normalizedLeft.focusedComponentId) === normalizeScopeCompareValue(normalizedRight.focusedComponentId) &&
|
||||
normalizeScopeCompareValue(normalizedLeft.pageUrl) === normalizeScopeCompareValue(normalizedRight.pageUrl) &&
|
||||
leftSelectionIds.length === rightSelectionIds.length &&
|
||||
leftSelectionIds.every((item, index) => item === rightSelectionIds[index])
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user