mirror of
https://github.com/farion1231/cc-switch.git
synced 2026-07-30 02:14:43 +08:00
feat: session manger (#867)
* feat: init session manger * feat: persist selected app to localStorage - Save app selection when switching providers - Restore last selected app on page load * feat: persist current view to localStorage - Save view selection when switching tabs - Restore last selected view on page load * styles: update ui * feat: Improve macOS Terminal activation and refactor Kitty launch to use command with user's default shell. * fix: session view * feat: toc * feat: Implement FlexSearch for improved session search functionality. * feat: Redesign session manager search and filter UI for a more compact and dynamic experience. * refactor: modularize session manager by extracting components and utility functions into dedicated files. * feat: Enhance session terminal launching with support for iTerm2, Ghostty, WezTerm, and Alacritty, including UI and custom configuration options. * feat: Conditionally render terminal selection and resume session buttons only on macOS.
This commit is contained in:
@@ -0,0 +1,75 @@
|
||||
import { SessionMeta } from "@/types";
|
||||
|
||||
export const getSessionKey = (session: SessionMeta) =>
|
||||
`${session.providerId}:${session.sessionId}:${session.sourcePath ?? ""}`;
|
||||
|
||||
export const getBaseName = (value?: string | null) => {
|
||||
if (!value) return "";
|
||||
const trimmed = value.trim();
|
||||
if (!trimmed) return "";
|
||||
const normalized = trimmed.replace(/[\\/]+$/, "");
|
||||
const parts = normalized.split(/[\\/]/).filter(Boolean);
|
||||
return parts[parts.length - 1] || trimmed;
|
||||
};
|
||||
|
||||
export const formatTimestamp = (value?: number) => {
|
||||
if (!value) return "";
|
||||
return new Date(value).toLocaleString();
|
||||
};
|
||||
|
||||
export const formatRelativeTime = (value?: number) => {
|
||||
if (!value) return "";
|
||||
const now = Date.now();
|
||||
const diff = now - value;
|
||||
const minutes = Math.floor(diff / 60000);
|
||||
const hours = Math.floor(diff / 3600000);
|
||||
const days = Math.floor(diff / 86400000);
|
||||
|
||||
if (minutes < 1) return "刚刚";
|
||||
if (minutes < 60) return `${minutes} 分钟前`;
|
||||
if (hours < 24) return `${hours} 小时前`;
|
||||
if (days < 7) return `${days} 天前`;
|
||||
return new Date(value).toLocaleDateString();
|
||||
};
|
||||
|
||||
export const getProviderLabel = (
|
||||
providerId: string,
|
||||
t: (key: string) => string
|
||||
) => {
|
||||
const key = `apps.${providerId}`;
|
||||
const translated = t(key);
|
||||
return translated === key ? providerId : translated;
|
||||
};
|
||||
|
||||
// 根据 providerId 获取对应的图标名称
|
||||
export const getProviderIconName = (providerId: string) => {
|
||||
if (providerId === "codex") return "openai";
|
||||
if (providerId === "claude") return "claude";
|
||||
return providerId;
|
||||
};
|
||||
|
||||
export const getRoleTone = (role: string) => {
|
||||
const normalized = role.toLowerCase();
|
||||
if (normalized === "assistant") return "text-blue-500";
|
||||
if (normalized === "user") return "text-emerald-500";
|
||||
if (normalized === "system") return "text-amber-500";
|
||||
if (normalized === "tool") return "text-purple-500";
|
||||
return "text-muted-foreground";
|
||||
};
|
||||
|
||||
export const getRoleLabel = (role: string) => {
|
||||
const normalized = role.toLowerCase();
|
||||
if (normalized === "assistant") return "AI";
|
||||
if (normalized === "user") return "用户";
|
||||
if (normalized === "system") return "系统";
|
||||
if (normalized === "tool") return "工具";
|
||||
return role;
|
||||
};
|
||||
|
||||
export const formatSessionTitle = (session: SessionMeta) => {
|
||||
return (
|
||||
session.title ||
|
||||
getBaseName(session.projectDir) ||
|
||||
session.sessionId.slice(0, 8)
|
||||
);
|
||||
};
|
||||
Reference in New Issue
Block a user