Skip to content
Open
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
8 changes: 4 additions & 4 deletions apps/desktop/src/services/event-listeners.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import { getCurrentWebviewWindowLabel } from "@hypr/plugin-windows";

import * as main from "~/store/tinybase/store/main";
import {
createSession,
createAdHocSession,
getOrCreateSessionForEventId,
} from "~/store/tinybase/store/sessions";
import { useTabs } from "~/store/zustand/tabs";
Expand Down Expand Up @@ -61,7 +61,7 @@ function useNotificationEvents() {
pendingAutoStart.current = null;
const sessionId = eventId
? getOrCreateSessionForEventId(store, eventId)
: createSession(store);
: createAdHocSession(store);
openNew({
type: "sessions",
id: sessionId,
Expand Down Expand Up @@ -95,7 +95,7 @@ function useNotificationEvents() {
}
const sessionId = eventId
? getOrCreateSessionForEventId(currentStore, eventId)
: createSession(currentStore);
: createAdHocSession(currentStore);
openNewRef.current({
type: "sessions",
id: sessionId,
Expand All @@ -117,7 +117,7 @@ function useNotificationEvents() {
currentStore,
eventIds[selectedIndex],
)
: createSession(currentStore);
: createAdHocSession(currentStore);

openNewRef.current({
type: "sessions",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,12 @@ import { parseTranscriptHints, updateTranscriptHints } from "~/stt/utils";

export function ParticipantChip({ mappingId }: { mappingId: string }) {
const details = useParticipantDetails(mappingId);
const currentUserId = main.UI.useValue("user_id", main.STORE_ID);

const assignedHumanId = details?.humanId;
const sessionId = details?.sessionId;
const source = details?.source;
const isCurrentUser = assignedHumanId === currentUserId;

const handleRemove = useRemoveParticipant({
mappingId,
Expand All @@ -35,15 +37,21 @@ export function ParticipantChip({ mappingId }: { mappingId: string }) {
return null;
}

const { humanName } = details;
const { humanEmail, humanName } = details;
const baseLabel =
humanName || humanEmail || (isCurrentUser ? "You" : "Unknown");
const label =
isCurrentUser && baseLabel !== "You" && !baseLabel.endsWith(" (You)")
? `${baseLabel} (You)`
: baseLabel;

return (
<Badge
variant="secondary"
className="bg-muted hover:bg-muted/80 flex cursor-pointer items-center gap-1 px-2 py-0.5 text-xs"
onClick={handleClick}
>
{humanName || "Unknown"}
{label}
<Button
type="button"
variant="ghost"
Expand Down
29 changes: 6 additions & 23 deletions apps/desktop/src/shared/main/useNewNote.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { useShallow } from "zustand/shallow";
import { commands as analyticsCommands } from "@hypr/plugin-analytics";

import { id } from "~/shared/utils";
import { createAdHocSession } from "~/store/tinybase/store/sessions";
import { useTabs } from "~/store/zustand/tabs";
import { useListener } from "~/stt/contexts";
import { setPendingUpload } from "~/stt/pending-upload";
Expand Down Expand Up @@ -53,7 +54,7 @@ export function useNewNoteAndListen({
}: {
behavior?: "new" | "current";
} = {}) {
const { persistedStore, internalStore } = useRouteContext({
const { persistedStore } = useRouteContext({
from: "__root__",
});
const { openNew, openCurrent } = useTabs(
Expand All @@ -74,35 +75,17 @@ export function useNewNoteAndListen({
return;
}

const user_id = internalStore?.getValue("user_id");
const sessionId = id();

persistedStore?.setRow("sessions", sessionId, {
user_id,
created_at: new Date().toISOString(),
title: "",
});

void analyticsCommands.event({
event: "note_created",
has_event_id: false,
});
const sessionId = persistedStore
? createAdHocSession(persistedStore)
: id();

const ff = behavior === "new" ? openNew : openCurrent;
ff({
type: "sessions",
id: sessionId,
state: { view: null, autoStart: true },
});
}, [
status,
liveSessionId,
persistedStore,
internalStore,
openNew,
openCurrent,
behavior,
]);
}, [status, liveSessionId, persistedStore, openNew, openCurrent, behavior]);

return handler;
}
Expand Down
70 changes: 70 additions & 0 deletions apps/desktop/src/store/tinybase/store/sessions.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
import { createMergeableStore } from "tinybase/with-schemas";
import { beforeEach, describe, expect, test, vi } from "vitest";

import { SCHEMA } from "@hypr/store";

import type { Store } from "./main";
import { createAdHocSession } from "./sessions";

const { analyticsEventMock } = vi.hoisted(() => ({
analyticsEventMock: vi.fn(),
}));

vi.mock("@hypr/plugin-analytics", () => ({
commands: {
event: analyticsEventMock,
},
}));

function createTestStore(): Store {
return createMergeableStore()
.setTablesSchema(SCHEMA.table)
.setValuesSchema(SCHEMA.value) as Store;
}

describe("createAdHocSession", () => {
let store: Store;

beforeEach(() => {
vi.clearAllMocks();
store = createTestStore();
});

test("adds the current user as a participant", () => {
store.setValue("user_id", "user-1");
store.setRow("humans", "user-1", {
user_id: "user-1",
name: "John",
email: "john@example.com",
org_id: "",
pinned: false,
});

const sessionId = createAdHocSession(store);
const mappingIds = store.getRowIds("mapping_session_participant");

expect(mappingIds).toHaveLength(1);
expect(
store.getRow("mapping_session_participant", mappingIds[0]),
).toMatchObject({
user_id: "user-1",
session_id: sessionId,
human_id: "user-1",
source: "manual",
});
});

test("creates the current user's human row when missing", () => {
store.setValue("user_id", "user-1");

createAdHocSession(store);

expect(store.getRow("humans", "user-1")).toMatchObject({
user_id: "user-1",
name: "",
email: "",
org_id: "",
pinned: false,
});
});
});
46 changes: 46 additions & 0 deletions apps/desktop/src/store/tinybase/store/sessions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,52 @@ export function createSession(store: Store, title?: string): string {
return sessionId;
}

export function createAdHocSession(store: Store, title?: string): string {
const sessionId = createSession(store, title);
const userId = store.getValue("user_id");
if (typeof userId !== "string" || !userId) {
return sessionId;
}

if (!store.hasRow("humans", userId)) {
store.setRow("humans", userId, {
user_id: userId,
name: "",
email: "",
org_id: "",
job_title: "",
linkedin_username: "",
memo: "",
pinned: false,
} satisfies HumanStorage);
}

let hasParticipant = false;
store.forEachRow("mapping_session_participant", (mappingId, _forEachCell) => {
const mapping = store.getRow("mapping_session_participant", mappingId);
if (
mapping?.session_id === sessionId &&
mapping.human_id === userId &&
mapping.source !== "excluded"
) {
hasParticipant = true;
}
});

if (hasParticipant) {
return sessionId;
}

store.setRow("mapping_session_participant", id(), {
user_id: userId,
session_id: sessionId,
human_id: userId,
source: "manual",
} satisfies MappingSessionParticipantStorage);

return sessionId;
}

export function getOrCreateSessionForEventId(
store: Store,
eventId: string,
Expand Down
Loading