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 @@
+
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 @@
\ No newline at end of file
+
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 (
-

+
{title}
-
{cleanUrl(url)}
+
+ {type === "note" ? "Note" : cleanUrl(url)}
+
);
}
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({
>

{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) => (
{}}
+ 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 (
c.image).reverse() as string[]}
+ images={
+ spaceMemories
+ .map((c) => (c.type === "note" ? "/note.svg" : c.image))
+ .reverse() as string[]
+ }
/>
) : spaceMemories.length > 1 ? (
c.image).reverse() as string[]}
+ images={
+ spaceMemories
+ .map((c) => (c.type === "note" ? "/note.svg" : c.image))
+ .reverse() as string[]
+ }
/>
) : spaceMemories.length === 1 ? (
) : (
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;
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),