mirror of
https://github.com/supermemoryai/supermemory.git
synced 2026-05-20 00:56:41 +00:00
Show own space as Your conversations (#956)
This commit is contained in:
parent
6df9c8f462
commit
ba8eb52b94
5 changed files with 73 additions and 17 deletions
|
|
@ -723,10 +723,16 @@ export function DashboardView({
|
|||
firstName,
|
||||
)
|
||||
|
||||
const [tipIndex, setTipIndex] = useState(0)
|
||||
|
||||
useEffect(() => {
|
||||
setTipIndex(Math.floor(Math.random() * TIPS[profession].length))
|
||||
}, [profession])
|
||||
|
||||
const tip = useMemo(() => {
|
||||
const tips = TIPS[profession]
|
||||
return tips[Math.floor(Math.random() * tips.length)]
|
||||
}, [profession])
|
||||
return tips[tipIndex % tips.length] ?? tips[0]
|
||||
}, [profession, tipIndex])
|
||||
|
||||
return (
|
||||
<div
|
||||
|
|
|
|||
|
|
@ -29,6 +29,7 @@ import { useAuth } from "@lib/auth-context"
|
|||
import type { ContainerTagListType } from "@lib/types"
|
||||
import {
|
||||
compareSpacesUserFirst,
|
||||
isOwnConversationSpace,
|
||||
spaceSelectorDisplayName,
|
||||
} from "@/lib/ingest-auto-space"
|
||||
import {
|
||||
|
|
@ -225,7 +226,7 @@ export function SelectSpacesModal({
|
|||
setLastBulkDeleteTag(null)
|
||||
}, [activeDiscoverId])
|
||||
|
||||
const { org } = useAuth()
|
||||
const { org, user } = useAuth()
|
||||
const queryClient = useQueryClient()
|
||||
const [connectingPluginId, setConnectingPluginId] = useState<string | null>(
|
||||
null,
|
||||
|
|
@ -455,15 +456,19 @@ export function SelectSpacesModal({
|
|||
return byCategory.filter((p) => {
|
||||
const plugin = detectPluginSpace(p.containerTag)
|
||||
const projectName = pluginMetaMap.get(p.containerTag)?.projectName
|
||||
const displayName = spaceSelectorDisplayName(p, p.containerTag, {
|
||||
currentUserId: user?.id,
|
||||
})
|
||||
return (
|
||||
p.containerTag.toLowerCase().includes(query) ||
|
||||
(p.name ?? "").toLowerCase().includes(query) ||
|
||||
displayName.toLowerCase().includes(query) ||
|
||||
(plugin?.label.toLowerCase().includes(query) ?? false) ||
|
||||
(plugin?.projectId?.toLowerCase().includes(query) ?? false) ||
|
||||
(projectName?.toLowerCase().includes(query) ?? false)
|
||||
)
|
||||
})
|
||||
}, [allSpaces, activeCategory, searchQuery, pluginMetaMap])
|
||||
}, [allSpaces, activeCategory, searchQuery, pluginMetaMap, user?.id])
|
||||
|
||||
const recentProjects = useMemo<ContainerTagListType[]>(() => {
|
||||
if (!recents?.length) return []
|
||||
|
|
@ -551,10 +556,12 @@ export function SelectSpacesModal({
|
|||
)
|
||||
.map((project) => ({
|
||||
id: project.id,
|
||||
name: project.name ?? project.containerTag,
|
||||
name: spaceSelectorDisplayName(project, project.containerTag, {
|
||||
currentUserId: user?.id,
|
||||
}),
|
||||
containerTag: project.containerTag,
|
||||
})),
|
||||
[allSpaces, bulkDeleteTags],
|
||||
[allSpaces, bulkDeleteTags, user?.id],
|
||||
)
|
||||
|
||||
const bulkDeleteCount = bulkDeleteProjects.length
|
||||
|
|
@ -567,8 +574,16 @@ export function SelectSpacesModal({
|
|||
project.containerTag,
|
||||
)?.projectName
|
||||
const pluginIdLabel = pluginProjectName || plugin?.projectId
|
||||
const displayName = spaceSelectorDisplayName(
|
||||
project,
|
||||
project.containerTag,
|
||||
{
|
||||
currentUserId: user?.id,
|
||||
},
|
||||
)
|
||||
const isDefault = project.containerTag === DEFAULT_PROJECT_ID
|
||||
const canEdit = !isDefault && !plugin
|
||||
const isOwnSpace = isOwnConversationSpace(project, user?.id)
|
||||
const canEdit = !isDefault && !plugin && !isOwnSpace
|
||||
const canBulkDelete = enableDelete && !isDefault
|
||||
const isEditing = editingProject?.containerTag === project.containerTag
|
||||
const isBulkDeleteSelected = bulkDeleteTags.has(project.containerTag)
|
||||
|
|
@ -697,7 +712,7 @@ export function SelectSpacesModal({
|
|||
)}
|
||||
<span
|
||||
className="min-w-0 flex-1 truncate text-[#fafafa] text-sm font-medium"
|
||||
title={project.containerTag}
|
||||
title={plugin ? project.containerTag : displayName}
|
||||
>
|
||||
{plugin ? (
|
||||
<>
|
||||
|
|
@ -709,7 +724,7 @@ export function SelectSpacesModal({
|
|||
)}
|
||||
</>
|
||||
) : (
|
||||
spaceSelectorDisplayName(project, project.containerTag)
|
||||
displayName
|
||||
)}
|
||||
</span>
|
||||
</button>
|
||||
|
|
@ -738,7 +753,7 @@ export function SelectSpacesModal({
|
|||
e.stopPropagation()
|
||||
onDeleteRequest({
|
||||
id: project.id,
|
||||
name: project.name ?? project.containerTag,
|
||||
name: displayName,
|
||||
containerTag: project.containerTag,
|
||||
})
|
||||
}}
|
||||
|
|
@ -766,6 +781,7 @@ export function SelectSpacesModal({
|
|||
startEditing,
|
||||
toggleBulkDeleteTag,
|
||||
updateProjectMutation.isPending,
|
||||
user?.id,
|
||||
],
|
||||
)
|
||||
|
||||
|
|
|
|||
|
|
@ -31,6 +31,7 @@ import {
|
|||
} from "@repo/ui/components/select"
|
||||
import { Button } from "@repo/ui/components/button"
|
||||
import { Tooltip, TooltipContent, TooltipTrigger } from "@ui/components/tooltip"
|
||||
import { useAuth } from "@lib/auth-context"
|
||||
import { analytics } from "@/lib/analytics"
|
||||
import {
|
||||
compareSpacesUserFirst,
|
||||
|
|
@ -135,6 +136,7 @@ export function SpaceSelector({
|
|||
const { deleteProjectMutation, deleteProjectsMutation } =
|
||||
useProjectMutations()
|
||||
const { allProjects, isLoading } = useContainerTags()
|
||||
const { user } = useAuth()
|
||||
|
||||
useEffect(() => {
|
||||
setRecents(readRecents())
|
||||
|
|
@ -199,12 +201,14 @@ export function SpaceSelector({
|
|||
? idForLabel
|
||||
? `${plugin.label} · ${idForLabel}`
|
||||
: plugin.label
|
||||
: spaceSelectorDisplayName(found, containerTag),
|
||||
: spaceSelectorDisplayName(found, containerTag, {
|
||||
currentUserId: user?.id,
|
||||
}),
|
||||
emoji: found?.emoji || "📁",
|
||||
plugin,
|
||||
isAuto: false,
|
||||
}
|
||||
}, [allProjects, selectedProjects, pluginMetaMap, includeAuto])
|
||||
}, [allProjects, selectedProjects, pluginMetaMap, includeAuto, user?.id])
|
||||
|
||||
const pushRecent = useCallback((tag: string) => {
|
||||
setRecents((prev) => {
|
||||
|
|
@ -615,7 +619,13 @@ export function SpaceSelector({
|
|||
)}
|
||||
</>
|
||||
) : (
|
||||
spaceSelectorDisplayName(p, p.containerTag)
|
||||
spaceSelectorDisplayName(
|
||||
p,
|
||||
p.containerTag,
|
||||
{
|
||||
currentUserId: user?.id,
|
||||
},
|
||||
)
|
||||
)}
|
||||
</span>
|
||||
</span>
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
import { useState, useEffect, useCallback } from "react"
|
||||
import { $fetch } from "@lib/api"
|
||||
import type { SearchResult } from "@repo/lib/api"
|
||||
import type { SearchResult } from "@repo/validation/api"
|
||||
|
||||
const CACHE_KEY = "sm_profession_v1"
|
||||
const CACHE_TTL_MS = 7 * 24 * 60 * 60 * 1000
|
||||
|
|
@ -235,6 +235,15 @@ function pickCopy(p: Profession): PersonalizedCopy {
|
|||
}
|
||||
}
|
||||
|
||||
function defaultCopy(p: Profession): PersonalizedCopy {
|
||||
const pool = COPY_POOLS[p]
|
||||
return {
|
||||
saveLink: pool.saveLink[0] ?? "",
|
||||
writeNote: pool.writeNote[0] ?? "",
|
||||
chatPlaceholder: pool.chatPlaceholder[0] ?? "",
|
||||
}
|
||||
}
|
||||
|
||||
const sessionCopyCache: Partial<Record<Profession, PersonalizedCopy>> = {}
|
||||
|
||||
function getSessionCopy(p: Profession): PersonalizedCopy {
|
||||
|
|
@ -398,7 +407,7 @@ export function usePersonalization(): {
|
|||
setProfession: (p: Profession) => void
|
||||
} {
|
||||
const [copy, setCopy] = useState<PersonalizedCopy>(() =>
|
||||
getSessionCopy("default"),
|
||||
defaultCopy("default"),
|
||||
)
|
||||
const [profession, setProfessionState] = useState<Profession>("default")
|
||||
|
||||
|
|
@ -410,8 +419,9 @@ export function usePersonalization(): {
|
|||
)
|
||||
} catch {}
|
||||
// Re-pick on explicit change so the user sees fresh copy for the new identity
|
||||
sessionCopyCache[p] = pickCopy(p)
|
||||
setCopy(sessionCopyCache[p]!)
|
||||
const freshCopy = pickCopy(p)
|
||||
sessionCopyCache[p] = freshCopy
|
||||
setCopy(freshCopy)
|
||||
setProfessionState(p)
|
||||
}, [])
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,8 @@
|
|||
import { DEFAULT_PROJECT_ID } from "@lib/constants"
|
||||
import type { ContainerTagListType } from "@lib/types"
|
||||
|
||||
export const OWN_CONVERSATIONS_SPACE_NAME = "Your conversations"
|
||||
|
||||
/**
|
||||
* Spaces auto-created on first ingest use `name === \`Space ${containerTag}\``
|
||||
* (mono `apps/api/src/routes/memories/handler-effect.ts`). Those are noisy in the
|
||||
|
|
@ -24,10 +26,22 @@ export function compareSpacesUserFirst(
|
|||
)
|
||||
}
|
||||
|
||||
export function isOwnConversationSpace(
|
||||
p: Pick<ContainerTagListType, "containerTag"> | undefined,
|
||||
currentUserId?: string | null,
|
||||
): boolean {
|
||||
return !!currentUserId && p?.containerTag === currentUserId
|
||||
}
|
||||
|
||||
export function spaceSelectorDisplayName(
|
||||
p: Pick<ContainerTagListType, "name" | "containerTag"> | undefined,
|
||||
fallback: string,
|
||||
options?: { currentUserId?: string | null },
|
||||
): string {
|
||||
const containerTag = p?.containerTag ?? fallback
|
||||
if (containerTag === options?.currentUserId) {
|
||||
return OWN_CONVERSATIONS_SPACE_NAME
|
||||
}
|
||||
if (!p) return fallback
|
||||
const name = p.name ?? p.containerTag
|
||||
const long = name.length > 44
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue