Show own space as Your conversations (#956)

This commit is contained in:
Dhravya Shah 2026-05-17 00:15:37 -07:00 committed by GitHub
parent 6df9c8f462
commit ba8eb52b94
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 73 additions and 17 deletions

View file

@ -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

View file

@ -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,
],
)

View file

@ -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>

View file

@ -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)
}, [])

View file

@ -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