aboutsummaryrefslogtreecommitdiff
path: root/apps
diff options
context:
space:
mode:
authorDhravya <[email protected]>2024-04-13 11:40:01 -0700
committerDhravya <[email protected]>2024-04-13 11:40:01 -0700
commit6f4792cab8643dacd651c3cb1b069ad7aedd33fb (patch)
tree88f03e31212bbf8b3ebff55f0ca93d2dff4e190f /apps
parentadded browser rendering for getting clean page content (diff)
parentfix notes (diff)
downloadsupermemory-6f4792cab8643dacd651c3cb1b069ad7aedd33fb.tar.xz
supermemory-6f4792cab8643dacd651c3cb1b069ad7aedd33fb.zip
resolved conflicts
Diffstat (limited to 'apps')
-rw-r--r--apps/extension/src/SideBar.tsx2
-rw-r--r--apps/extension/src/background.ts44
-rw-r--r--apps/web/public/note.svg5
-rw-r--r--apps/web/public/web.svg2
-rw-r--r--apps/web/src/actions/db.ts48
-rw-r--r--apps/web/src/app/page.tsx2
-rw-r--r--apps/web/src/components/Sidebar/AddMemoryDialog.tsx12
-rw-r--r--apps/web/src/components/Sidebar/FilterCombobox.tsx7
-rw-r--r--apps/web/src/components/Sidebar/MemoriesBar.tsx22
-rw-r--r--apps/web/src/contexts/MemoryContext.tsx29
-rw-r--r--apps/web/src/server/db/schema.ts16
11 files changed, 137 insertions, 52 deletions
diff --git a/apps/extension/src/SideBar.tsx b/apps/extension/src/SideBar.tsx
index 9704511b..385c0f22 100644
--- a/apps/extension/src/SideBar.tsx
+++ b/apps/extension/src/SideBar.tsx
@@ -79,7 +79,7 @@ function SideBar({ jwt }: { jwt: string }) {
const fetchSpaces = async () => {
setLoading(true);
chrome.runtime.sendMessage({ type: "fetchSpaces" }, (resp) => {
- console.log(resp);
+ console.log("response", resp);
setSpaces(resp);
setLoading(false);
});
diff --git a/apps/extension/src/background.ts b/apps/extension/src/background.ts
index ec71810b..d2f8759e 100644
--- a/apps/extension/src/background.ts
+++ b/apps/extension/src/background.ts
@@ -52,12 +52,13 @@ chrome.runtime.onMessage.addListener((request, sender, sendResponse) => {
const spaces = request.spaces(
// eslint-disable-next-line no-unexpected-multiline
async () => {
- chrome.storage.local.get(["jwt"], async ({ jwt }) => {
+ chrome.storage.local.get(["jwt"], ({ jwt }) => {
if (!jwt) {
console.error("No JWT found");
return;
}
- await fetch(`${backendUrl}/api/spaces`, {
+ fetch(`${backendUrl}/api/store`, {
+ method: "POST",
headers: {
Authorization: `Bearer ${jwt}`,
},
@@ -67,29 +68,26 @@ chrome.runtime.onMessage.addListener((request, sender, sendResponse) => {
},
)();
} else if (request.type === "fetchSpaces") {
- const run = () =>
- chrome.storage.local.get(["jwt"], async ({ jwt }) => {
- if (!jwt) {
- console.error("No JWT found");
- return;
- }
- const resp = await fetch(`${backendUrl}/api/spaces`, {
- headers: {
- Authorization: `Bearer ${jwt}`,
- },
- });
-
- const data: {
- message: "OK" | string;
- data: Space[] | undefined;
- } = await resp.json();
-
- if (data.message === "OK" && data.data) {
- sendResponse(data.data);
- }
+ chrome.storage.local.get(["jwt"], async ({ jwt }) => {
+ if (!jwt) {
+ console.error("No JWT found");
+ return;
+ }
+ const resp = await fetch(`${backendUrl}/api/spaces`, {
+ headers: {
+ Authorization: `Bearer ${jwt}`,
+ },
});
- run();
+ const data: {
+ message: "OK" | string;
+ data: Space[] | undefined;
+ } = await resp.json();
+
+ if (data.message === "OK" && data.data) {
+ sendResponse(data.data);
+ }
+ });
return true;
} else if (request.type === "queryApi") {
diff --git a/apps/web/public/note.svg b/apps/web/public/note.svg
new file mode 100644
index 00000000..ffb4c795
--- /dev/null
+++ b/apps/web/public/note.svg
@@ -0,0 +1,5 @@
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="#6F6F6F" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-text w-10 h-10">
+ <path d="M17 6.1H3"></path>
+ <path d="M21 12.1H3">
+ </path><path d="M15.1 18H3"></path>
+</svg>
diff --git a/apps/web/public/web.svg b/apps/web/public/web.svg
index dffbed97..c59f016d 100644
--- a/apps/web/public/web.svg
+++ b/apps/web/public/web.svg
@@ -1,3 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="w-6 h-6">
<path stroke-linecap="round" stroke-linejoin="round" d="M12 21a9.004 9.004 0 0 0 8.716-6.747M12 21a9.004 9.004 0 0 1-8.716-6.747M12 21c2.485 0 4.5-4.03 4.5-9S14.485 3 12 3m0 18c-2.485 0-4.5-4.03-4.5-9S9.515 3 12 3m0 0a8.997 8.997 0 0 1 7.843 4.582M12 3a8.997 8.997 0 0 0-7.843 4.582m15.686 0A11.953 11.953 0 0 1 12 10.5c-2.998 0-5.74-1.1-7.843-2.918m15.686 0A8.959 8.959 0 0 1 21 12c0 .778-.099 1.533-.284 2.253m0 0A17.919 17.919 0 0 1 12 16.5c-3.162 0-6.133-.815-8.716-2.247m0 0A9.015 9.015 0 0 1 3 12c0-1.605.42-3.113 1.157-4.418" />
-</svg> \ No newline at end of file
+</svg>
diff --git a/apps/web/src/actions/db.ts b/apps/web/src/actions/db.ts
index e380d562..cd54c1bd 100644
--- a/apps/web/src/actions/db.ts
+++ b/apps/web/src/actions/db.ts
@@ -41,7 +41,8 @@ export async function searchMemoriesAndSpaces(
eq(storedContent.user, user.id),
like(storedContent.title, `%${query}%`),
),
- );
+ )
+ .orderBy(asc(storedContent.savedAt));
const searchSpacesQuery = db
.select({
@@ -50,10 +51,13 @@ export async function searchMemoriesAndSpaces(
memory: sql`NULL`,
})
.from(space)
- .where(and(eq(space.user, user.id), like(space.name, `%${query}%`)));
+ .where(and(eq(space.user, user.id), like(space.name, `%${query}%`)))
+ .orderBy(asc(space.name));
let queries = [];
+ console.log("adding");
+
[undefined, true].includes(opts?.filter?.memories) &&
queries.push(searchMemoriesQuery);
[undefined, true].includes(opts?.filter?.spaces) &&
@@ -69,6 +73,8 @@ export async function searchMemoriesAndSpaces(
const data = await Promise.all(queries);
+ console.log("resp", data);
+
return data.reduce((acc, i) => [...acc, ...i]) as SearchResult[];
} catch {
return [];
@@ -183,7 +189,7 @@ export async function fetchContentForSpace(
),
),
)
- .orderBy(asc(storedContent.title));
+ .orderBy(asc(storedContent.savedAt));
return range
? await query.limit(range.limit).offset(range.offset)
@@ -214,7 +220,7 @@ export async function fetchFreeMemories(range?: {
eq(storedContent.user, user.id),
),
)
- .orderBy(asc(storedContent.title));
+ .orderBy(asc(storedContent.savedAt));
return range
? await query.limit(range.limit).offset(range.offset)
@@ -257,3 +263,37 @@ export async function addMemory(
addedToSpaces,
};
}
+
+export async function deleteSpace(id: number) {
+ const user = await getUser();
+
+ if (!user) {
+ return null;
+ }
+
+ await db.delete(contentToSpace).where(eq(contentToSpace.spaceId, id));
+
+ const [deleted] = await db
+ .delete(space)
+ .where(and(eq(space.user, user.id), eq(space.id, id)))
+ .returning();
+
+ return deleted;
+}
+
+export async function deleteMemory(id: number) {
+ const user = await getUser();
+
+ if (!user) {
+ return null;
+ }
+
+ await db.delete(contentToSpace).where(eq(contentToSpace.contentId, id));
+
+ const [deleted] = await db
+ .delete(storedContent)
+ .where(and(eq(storedContent.user, user.id), eq(storedContent.id, id)))
+ .returning();
+
+ return deleted;
+}
diff --git a/apps/web/src/app/page.tsx b/apps/web/src/app/page.tsx
index 3112e71e..1cc21adf 100644
--- a/apps/web/src/app/page.tsx
+++ b/apps/web/src/app/page.tsx
@@ -18,8 +18,6 @@ import {
} from "../../types/memory";
import { MemoryProvider } from "@/contexts/MemoryContext";
import Content from "./content";
-import { searchMemoriesAndSpaces } from "@/actions/db";
-import { getMetaData } from "@/server/helpers";
export const runtime = "edge";
diff --git a/apps/web/src/components/Sidebar/AddMemoryDialog.tsx b/apps/web/src/components/Sidebar/AddMemoryDialog.tsx
index 3043c972..31628ab7 100644
--- a/apps/web/src/components/Sidebar/AddMemoryDialog.tsx
+++ b/apps/web/src/components/Sidebar/AddMemoryDialog.tsx
@@ -324,12 +324,18 @@ export function MemorySelectedItem({
id,
title,
url,
+ type,
image,
onRemove,
}: StoredContent & { onRemove: () => void }) {
return (
<div className="hover:bg-rgray-4 focus-within-bg-rgray-4 flex w-full items-center justify-start gap-2 rounded-md p-1 px-2 text-sm [&:hover>[data-icon]]:block [&:hover>img]:hidden">
- <img src={image ?? "/icons/logo_without_bg.png"} className="h-5 w-5" />
+ <img
+ src={
+ type === "note" ? "/note.svg" : image ?? "/icons/logo_without_bg.png"
+ }
+ className="h-5 w-5"
+ />
<button
onClick={onRemove}
data-icon
@@ -338,7 +344,9 @@ export function MemorySelectedItem({
<X className="h-5 w-5 scale-90" />
</button>
<span>{title}</span>
- <span className="ml-auto block opacity-50">{cleanUrl(url)}</span>
+ <span className="ml-auto block opacity-50">
+ {type === "note" ? "Note" : cleanUrl(url)}
+ </span>
</div>
);
}
diff --git a/apps/web/src/components/Sidebar/FilterCombobox.tsx b/apps/web/src/components/Sidebar/FilterCombobox.tsx
index 80319ab1..c2c68135 100644
--- a/apps/web/src/components/Sidebar/FilterCombobox.tsx
+++ b/apps/web/src/components/Sidebar/FilterCombobox.tsx
@@ -180,7 +180,6 @@ export function FilterMemories({
const [isSearching, setIsSearching] = React.useState(false);
const results = React.useMemo(() => {
- console.log("use memo");
return searchResults.map((r) => r.memory);
}, [searchResults]);
@@ -266,7 +265,11 @@ export function FilterMemories({
>
<div className="text-rgray-11">
<img
- src={m.image ?? "/icons/logo_without_bg.png"}
+ src={
+ m.type === "note"
+ ? "/note.svg"
+ : m.image ?? "/icons/logo_without_bg.png"
+ }
className="mr-2 h-4 w-4"
/>
{m.title}
diff --git a/apps/web/src/components/Sidebar/MemoriesBar.tsx b/apps/web/src/components/Sidebar/MemoriesBar.tsx
index 0c468475..052098db 100644
--- a/apps/web/src/components/Sidebar/MemoriesBar.tsx
+++ b/apps/web/src/components/Sidebar/MemoriesBar.tsx
@@ -46,7 +46,6 @@ import { ExpandedSpace } from "./ExpandedSpace";
import { StoredContent, StoredSpace } from "@/server/db/schema";
import Image from "next/image";
import { useDebounce } from "@/hooks/useDebounce";
-import { searchMemoriesAndSpaces } from "@/actions/db";
export function MemoriesBar() {
const [parent, enableAnimations] = useAutoAnimate();
@@ -169,7 +168,7 @@ export function MemoriesBar() {
<>
{spaces.map((space) => (
<SpaceItem
- onDelete={() => {}}
+ onDelete={() => deleteSpace(space.id)}
key={space.id}
//onClick={() => setExpandedSpace(space.id)}
{...space}
@@ -255,7 +254,6 @@ export function SpaceItem({
}, [cachedMemories]);
const _name = name.length > 10 ? name.slice(0, 10) + "..." : name;
-
return (
<motion.div
ref={itemRef}
@@ -355,19 +353,31 @@ export function SpaceItem({
<MemoryWithImages3
className="h-24 w-24"
id={id.toString()}
- images={spaceMemories.map((c) => c.image).reverse() as string[]}
+ images={
+ spaceMemories
+ .map((c) => (c.type === "note" ? "/note.svg" : c.image))
+ .reverse() as string[]
+ }
/>
) : spaceMemories.length > 1 ? (
<MemoryWithImages2
className="h-24 w-24"
id={id.toString()}
- images={spaceMemories.map((c) => c.image).reverse() as string[]}
+ images={
+ spaceMemories
+ .map((c) => (c.type === "note" ? "/note.svg" : c.image))
+ .reverse() as string[]
+ }
/>
) : spaceMemories.length === 1 ? (
<MemoryWithImage
className="h-24 w-24"
id={id.toString()}
- image={spaceMemories[0].image!}
+ image={
+ spaceMemories[0].type === "note"
+ ? "/note.svg"
+ : spaceMemories[0].image!
+ }
/>
) : (
<div className="bg-rgray-4 shadow- h-24 w-24 scale-50 rounded-full opacity-30"></div>
diff --git a/apps/web/src/contexts/MemoryContext.tsx b/apps/web/src/contexts/MemoryContext.tsx
index 881ba45e..548365f8 100644
--- a/apps/web/src/contexts/MemoryContext.tsx
+++ b/apps/web/src/contexts/MemoryContext.tsx
@@ -11,6 +11,8 @@ import {
searchMemoriesAndSpaces,
addSpace,
fetchContentForSpace,
+ deleteSpace,
+ deleteMemory,
} from "@/actions/db";
import { User } from "next-auth";
@@ -23,20 +25,22 @@ export type SearchResult = {
// temperory (will change)
export const MemoryContext = React.createContext<{
spaces: StoredSpace[];
- deleteSpace: (id: number) => Promise<void>;
freeMemories: StoredContent[];
addSpace: typeof addSpace;
addMemory: typeof addMemory;
cachedMemories: ChachedSpaceContent[];
search: typeof searchMemoriesAndSpaces;
+ deleteSpace: typeof deleteSpace;
+ deleteMemory: typeof deleteMemory;
}>({
spaces: [],
freeMemories: [],
addMemory: (() => {}) as unknown as typeof addMemory,
addSpace: (async () => {}) as unknown as typeof addSpace,
- deleteSpace: async () => {},
cachedMemories: [],
search: async () => [],
+ deleteMemory: (() => {}) as unknown as typeof deleteMemory,
+ deleteSpace: (() => {}) as unknown as typeof deleteSpace,
});
export const MemoryProvider: React.FC<
@@ -61,8 +65,22 @@ export const MemoryProvider: React.FC<
ChachedSpaceContent[]
>(initialCachedMemories);
- const deleteSpace = async (id: number) => {
- setSpaces((prev) => prev.filter((s) => s.id !== id));
+ const _deleteSpace: typeof deleteSpace = async (...params) => {
+ const deleted = (await deleteSpace(...params))!;
+
+ setSpaces((prev) => prev.filter((i) => i.id !== deleted.id));
+ setCachedMemories((prev) => prev.filter((i) => i.space !== deleted.id));
+
+ return deleted;
+ };
+
+ const _deleteMemory: typeof deleteMemory = async (...params) => {
+ const deleted = (await deleteMemory(...params))!;
+
+ setCachedMemories((prev) => prev.filter((i) => i.id !== deleted.id));
+ setFreeMemories((prev) => prev.filter((i) => i.id !== deleted.id));
+
+ return deleted;
};
// const fetchMemories = useCallback(async (query: string) => {
@@ -115,9 +133,10 @@ export const MemoryProvider: React.FC<
search: searchMemoriesAndSpaces,
spaces,
addSpace: _addSpace,
- deleteSpace,
+ deleteSpace: _deleteSpace,
freeMemories,
cachedMemories,
+ deleteMemory: _deleteMemory,
addMemory: _addMemory,
}}
>
diff --git a/apps/web/src/server/db/schema.ts b/apps/web/src/server/db/schema.ts
index 4ca4332f..cd2756f1 100644
--- a/apps/web/src/server/db/schema.ts
+++ b/apps/web/src/server/db/schema.ts
@@ -34,7 +34,7 @@ export const accounts = createTable(
id: integer("id").notNull().primaryKey({ autoIncrement: true }),
userId: text("userId", { length: 255 })
.notNull()
- .references(() => users.id),
+ .references(() => users.id, { onDelete: "cascade" }),
type: text("type", { length: 255 }).notNull(),
provider: text("provider", { length: 255 }).notNull(),
providerAccountId: text("providerAccountId", { length: 255 }).notNull(),
@@ -60,7 +60,7 @@ export const sessions = createTable(
sessionToken: text("sessionToken", { length: 255 }).notNull(),
userId: text("userId", { length: 255 })
.notNull()
- .references(() => users.id),
+ .references(() => users.id, { onDelete: "cascade" }),
expires: int("expires", { mode: "timestamp" }).notNull(),
},
(session) => ({
@@ -94,7 +94,9 @@ export const storedContent = createTable(
"page",
),
image: text("image", { length: 255 }),
- user: text("user", { length: 255 }).references(() => users.id),
+ user: text("user", { length: 255 }).references(() => users.id, {
+ onDelete: "cascade",
+ }),
},
(sc) => ({
urlIdx: index("storedContent_url_idx").on(sc.url),
@@ -109,10 +111,10 @@ export const contentToSpace = createTable(
{
contentId: integer("contentId")
.notNull()
- .references(() => storedContent.id),
+ .references(() => storedContent.id, { onDelete: "cascade" }),
spaceId: integer("spaceId")
.notNull()
- .references(() => space.id),
+ .references(() => space.id, { onDelete: "cascade" }),
},
(cts) => ({
compoundKey: primaryKey({ columns: [cts.contentId, cts.spaceId] }),
@@ -124,7 +126,9 @@ export const space = createTable(
{
id: integer("id").notNull().primaryKey({ autoIncrement: true }),
name: text("name").notNull().unique().default("none"),
- user: text("user", { length: 255 }).references(() => users.id),
+ user: text("user", { length: 255 }).references(() => users.id, {
+ onDelete: "cascade",
+ }),
},
(space) => ({
nameIdx: index("spaces_name_idx").on(space.name),