aboutsummaryrefslogtreecommitdiff
path: root/apps/web/app/(dash)
diff options
context:
space:
mode:
authorDhravya <[email protected]>2024-06-30 14:07:16 -0500
committerDhravya <[email protected]>2024-06-30 14:07:16 -0500
commit7676ed57065eb61d54d500e68c7a7faae16e558b (patch)
tree0d59a7dd9ee1772667abbc03158e268732ff5214 /apps/web/app/(dash)
parenttailwind shadow dom (diff)
downloadsupermemory-7676ed57065eb61d54d500e68c7a7faae16e558b.tar.xz
supermemory-7676ed57065eb61d54d500e68c7a7faae16e558b.zip
added things
Diffstat (limited to 'apps/web/app/(dash)')
-rw-r--r--apps/web/app/(dash)/home/homeVariants.ts2
-rw-r--r--apps/web/app/(dash)/home/page.tsx7
-rw-r--r--apps/web/app/(dash)/memories/page.tsx90
-rw-r--r--apps/web/app/(dash)/memories/render-tweet.tsx33
-rw-r--r--apps/web/app/(dash)/menu.tsx21
5 files changed, 111 insertions, 42 deletions
diff --git a/apps/web/app/(dash)/home/homeVariants.ts b/apps/web/app/(dash)/home/homeVariants.ts
index ec24e22b..cc533fc4 100644
--- a/apps/web/app/(dash)/home/homeVariants.ts
+++ b/apps/web/app/(dash)/home/homeVariants.ts
@@ -44,7 +44,7 @@ export const variants = [
},
{
type: "highlighted",
- content: " digital treasures.",
+ content: " digital treasure.",
},
],
];
diff --git a/apps/web/app/(dash)/home/page.tsx b/apps/web/app/(dash)/home/page.tsx
index 4f7e4af6..f648923c 100644
--- a/apps/web/app/(dash)/home/page.tsx
+++ b/apps/web/app/(dash)/home/page.tsx
@@ -3,7 +3,7 @@
import React, { useEffect, useState } from "react";
import QueryInput from "./queryinput";
import { homeSearchParamsCache } from "@/lib/searchParams";
-import { getSpaces } from "@/app/actions/fetchers";
+import { getSessionAuthToken, getSpaces } from "@/app/actions/fetchers";
import { useRouter } from "next/navigation";
import { createChatThread, linkTelegramToUser } from "@/app/actions/doers";
import { toast } from "sonner";
@@ -67,6 +67,11 @@ function Page({
});
setShowVariant(Math.floor(Math.random() * variants.length));
+
+ getSessionAuthToken().then((token) => {
+ if (typeof window === "undefined") return;
+ window.postMessage({ token: token.data }, "*");
+ });
}, []);
return (
diff --git a/apps/web/app/(dash)/memories/page.tsx b/apps/web/app/(dash)/memories/page.tsx
index cb3825e7..380a653e 100644
--- a/apps/web/app/(dash)/memories/page.tsx
+++ b/apps/web/app/(dash)/memories/page.tsx
@@ -1,18 +1,19 @@
"use client";
import { getAllUserMemoriesAndSpaces } from "@/app/actions/fetchers";
-import { Space } from "@/app/actions/types";
import { Content, StoredSpace } from "@/server/db/schema";
-import { NextIcon, SearchIcon, UrlIcon } from "@repo/ui/icons";
+import { MemoriesIcon, NextIcon, SearchIcon, UrlIcon } from "@repo/ui/icons";
+import { NotebookIcon, PaperclipIcon } from "lucide-react";
import Image from "next/image";
+import Link from "next/link";
import React, { useEffect, useMemo, useState } from "react";
import Masonry from "react-layout-masonry";
+import { getRawTweet } from "@repo/shared-types/utils";
+import { MyTweet } from "./render-tweet";
function Page() {
const [filter, setFilter] = useState("All");
- const [search, setSearch] = useState("");
-
const [memoriesAndSpaces, setMemoriesAndSpaces] = useState<{
memories: Content[];
spaces: StoredSpace[];
@@ -55,9 +56,13 @@ function Page() {
return (
item.item === "memory" && (item.data as Content).type === "note"
);
+ if (filter === "Tweet")
+ return (
+ item.item === "memory" && (item.data as Content).type === "tweet"
+ );
return false;
})
- .sort((a, b) => a.date - b.date);
+ .sort((a, b) => b.date - a.date);
}, [memoriesAndSpaces.memories, memoriesAndSpaces.spaces, filter]);
useEffect(() => {
@@ -69,7 +74,7 @@ function Page() {
}, []);
return (
- <div className="max-w-3xl min-w-3xl py-36 h-full flex mx-auto w-full flex-col gap-6">
+ <div className="px-2 md:px-32 py-36 h-full flex mx-auto w-full flex-col gap-6">
<h2 className="text-white w-full font-medium text-2xl text-left">
My Memories
</h2>
@@ -79,7 +84,7 @@ function Page() {
<Masonry
className="mt-6"
columns={{ 640: 1, 768: 2, 1024: 3, 1280: 4 }}
- gap={4}
+ gap={12}
>
{sortedItems.map((item) => {
if (item.item === "memory") {
@@ -88,12 +93,15 @@ function Page() {
type={(item.data as Content).type ?? "note"}
content={(item.data as Content).content}
title={(item.data as Content).title ?? "Untitled"}
- url={(item.data as Content).url}
+ url={
+ (item.data as Content).baseUrl ?? (item.data as Content).url
+ }
image={
(item.data as Content).ogImage ??
(item.data as Content).image ??
"/placeholder-image.svg" // TODO: add this placeholder
}
+ description={(item.data as Content).description ?? ""}
/>
);
}
@@ -123,47 +131,73 @@ function TabComponent({
}) {
// TODO: Display the space name and desription which is the number of elemenet in the space
return (
- <div className="flex items-center my-6">
- <div>
- <div className="h-12 w-12 bg-[#1F2428] flex justify-center items-center rounded-md">
- {title.slice(0, 2).toUpperCase()}
- </div>
- </div>
- <div className="grow px-4">
- <div className="text-lg text-[#fff]">{title}</div>
- <div>{description}</div>
+ <div className="flex flex-col gap-4 bg-[#161f2a]/30 backdrop-blur-md border-2 border-border w-full rounded-xl p-4 -z-10">
+ <div className="flex items-center gap-2 text-xs">
+ <Image alt="Spaces icon" src={MemoriesIcon} className="size-3" /> Space
</div>
- <div>
- <Image src={NextIcon} alt="Search icon" />
+ <div className="flex items-center">
+ <div>
+ <div className="h-12 w-12 flex justify-center items-center rounded-md">
+ {title.slice(0, 2).toUpperCase()}
+ </div>
+ </div>
+ <div className="grow px-4">
+ <div className="text-lg text-[#fff] line-clamp-2">{title}</div>
+ <div>{description}</div>
+ </div>
+ <div>
+ <Image src={NextIcon} alt="Search icon" />
+ </div>
</div>
</div>
);
}
-function LinkComponent({
+export function LinkComponent({
type,
content,
title,
url,
image,
+ description,
}: {
type: string;
content: string;
title: string;
url: string;
image?: string;
+ description: string;
}) {
// TODO: DISPLAY THE ITEM BASED ON `type` being note or page
return (
- <div className="w-full">
- <div className="text-lg text-[#fff]">{title}</div>
- <div>{content}</div>
- <div>{url}</div>
- </div>
+ <Link
+ href={url}
+ className={`bg-secondary border-2 border-border w-full rounded-xl ${type === "tweet" ? "" : "p-4"} hover:scale-105 transition duration-200`}
+ >
+ {type === "page" ? (
+ <>
+ <div className="flex items-center gap-2 text-xs">
+ <PaperclipIcon className="w-3 h-3" /> Page
+ </div>
+ <div className="text-lg text-[#fff] mt-4 line-clamp-2">{title}</div>
+ <div>{url}</div>
+ </>
+ ) : type === "note" ? (
+ <>
+ <div className="flex items-center gap-2 text-xs">
+ <NotebookIcon className="w-3 h-3" /> Note
+ </div>
+ <div className="text-lg text-[#fff] mt-4 line-clamp-2">{title}</div>
+ <div className="line-clamp-3">{content.replace(title, "")}</div>
+ </>
+ ) : type === "tweet" ? (
+ <MyTweet tweet={JSON.parse(getRawTweet(content) ?? "{}")} />
+ ) : null}
+ </Link>
);
}
-const FilterMethods = ["All", "Spaces", "Pages", "Notes"];
+const FilterMethods = ["All", "Spaces", "Pages", "Notes", "Tweet"];
function Filters({
setFilter,
filter,
@@ -175,12 +209,12 @@ function Filters({
<div className="flex gap-4">
{FilterMethods.map((i) => {
return (
- <div
+ <button
onClick={() => setFilter(i)}
className={`transition px-6 py-2 rounded-xl bg-border ${i === filter ? " text-[#369DFD]" : "text-[#B3BCC5] bg-secondary hover:bg-secondary hover:text-[#76a3cc]"}`}
>
{i}
- </div>
+ </button>
);
})}
</div>
diff --git a/apps/web/app/(dash)/memories/render-tweet.tsx b/apps/web/app/(dash)/memories/render-tweet.tsx
new file mode 100644
index 00000000..3e1e3746
--- /dev/null
+++ b/apps/web/app/(dash)/memories/render-tweet.tsx
@@ -0,0 +1,33 @@
+import type { Tweet } from "react-tweet/api";
+import {
+ type TwitterComponents,
+ TweetContainer,
+ TweetHeader,
+ TweetInReplyTo,
+ TweetBody,
+ TweetMedia,
+ TweetInfo,
+ QuotedTweet,
+ enrichTweet,
+} from "react-tweet";
+
+type Props = {
+ tweet: Tweet;
+ components?: TwitterComponents;
+};
+
+export const MyTweet = ({ tweet: t, components }: Props) => {
+ const tweet = enrichTweet(t);
+ return (
+ <TweetContainer className="bg-transparent !m-0 !p-0 !z-0">
+ <TweetHeader tweet={tweet} components={components} />
+ {tweet.in_reply_to_status_id_str && <TweetInReplyTo tweet={tweet} />}
+ <TweetBody tweet={tweet} />
+ {tweet.mediaDetails?.length ? (
+ <TweetMedia tweet={tweet} components={components} />
+ ) : null}
+ {tweet.quoted_tweet && <QuotedTweet tweet={tweet.quoted_tweet} />}
+ <TweetInfo tweet={tweet} />
+ </TweetContainer>
+ );
+};
diff --git a/apps/web/app/(dash)/menu.tsx b/apps/web/app/(dash)/menu.tsx
index 340c7e16..a8ba4172 100644
--- a/apps/web/app/(dash)/menu.tsx
+++ b/apps/web/app/(dash)/menu.tsx
@@ -65,12 +65,6 @@ function Menu() {
disabled: false,
},
{
- icon: ExploreIcon,
- text: "Explore",
- url: "/explore",
- disabled: true,
- },
- {
icon: CanvasIcon,
text: "Canvas",
url: "/canvas",
@@ -86,7 +80,9 @@ function Menu() {
return "none";
}
- if (content.match(/https?:\/\/[\w\.]+\/[\w]+\/[\w]+\/[\d]+/)) {
+ if (
+ content.match(/https?:\/\/(x\.com|twitter\.com)\/[\w]+\/[\w]+\/[\d]+/)
+ ) {
return "tweet";
} else if (content.match(/https?:\/\/[\w\.]+/)) {
return "page";
@@ -136,8 +132,8 @@ function Menu() {
<>
{/* Desktop Menu */}
<Dialog open={dialogOpen} onOpenChange={setDialogOpen}>
- <div className="hidden lg:flex fixed h-screen pb-20 w-full p-4 items-center justify-start top-0 left-0 pointer-events-none">
- <div className="pointer-events-auto group flex w-14 text-foreground-menu text-[15px] font-medium flex-col items-start gap-6 overflow-hidden rounded-[28px] border-2 border-border bg-secondary px-3 py-4 duration-200 hover:w-40">
+ <div className="hidden lg:flex fixed h-screen pb-20 w-full p-4 items-center justify-start top-0 left-0 pointer-events-none z-[39]">
+ <div className="pointer-events-auto group flex w-14 text-foreground-menu text-[15px] font-medium flex-col items-start gap-6 overflow-hidden rounded-[28px] border-2 border-border bg-secondary px-3 py-4 duration-200 hover:w-40 z-[99999]">
<div className="border-b border-border pb-4 w-full">
<DialogTrigger
className={`flex w-full text-white brightness-75 hover:brightness-125 focus:brightness-125 cursor-pointer items-center gap-3 px-1 duration-200 justify-start`}
@@ -180,7 +176,7 @@ function Menu() {
</div>
</div>
- <DialogContent className="sm:max-w-[425px] rounded-2xl bg-[#161f2a]/30 backdrop-blur-md">
+ <DialogContent className="sm:max-w-[425px] rounded-2xl bg-[#161f2a]/40 backdrop-blur-md">
<form
action={async (e: FormData) => {
const content = e.get("content")?.toString();
@@ -202,7 +198,7 @@ function Menu() {
Resource (URL or content)
</Label>
<Textarea
- className="bg-[#161f2a] focus-visible:ring-0 border-none focus-visible:ring-offset-0 mt-2"
+ className="bg-[#2F353C] focus-visible:ring-0 border-none focus-visible:ring-offset-0 mt-2"
id="content"
name="content"
placeholder="Start typing a note or paste a URL here. I'll remember it."
@@ -287,7 +283,7 @@ function Menu() {
}
}}
placeholder="Save or create space by typing."
- className="bg-[#161f2a] h-min rounded-md mt-2 mb-4"
+ className="bg-[#2F353C] h-min rounded-md mt-2 mb-4"
/>
<div>
@@ -296,6 +292,7 @@ function Menu() {
{selectedSpaces.map((x, idx) => (
<button
key={x}
+ type="button"
onClick={() =>
setSelectedSpaces((prev) =>
prev.filter((y) => y !== x),