mirror of
https://github.com/supermemoryai/supermemory.git
synced 2026-09-14 23:21:20 +00:00
fix favicons
This commit is contained in:
parent
0d4e91068f
commit
68ee684a1a
7 changed files with 107 additions and 59 deletions
|
|
@ -21,6 +21,7 @@
|
|||
"@radix-ui/react-icons": "^1.3.0",
|
||||
"@radix-ui/react-popover": "^1.0.7",
|
||||
"@radix-ui/react-slot": "^1.0.2",
|
||||
"cheerio": "^1.0.0-rc.12",
|
||||
"class-variance-authority": "^0.7.0",
|
||||
"clsx": "^2.1.0",
|
||||
"cmdk": "latest",
|
||||
|
|
|
|||
|
|
@ -115,28 +115,6 @@ export async function getMemory(title: string) {
|
|||
);
|
||||
}
|
||||
|
||||
export async function addMemory(
|
||||
content: typeof storedContent.$inferInsert,
|
||||
spaces: number[],
|
||||
) {
|
||||
|
||||
const user = await getUser();
|
||||
|
||||
if (!user) {
|
||||
return null
|
||||
}
|
||||
content.user = user.id;
|
||||
|
||||
const _content = (
|
||||
await db.insert(storedContent).values(content).returning()
|
||||
)[0];
|
||||
await Promise.all(
|
||||
spaces.map((spaceId) =>
|
||||
db.insert(contentToSpace).values({ contentId: _content.id, spaceId }),
|
||||
),
|
||||
);
|
||||
return _content;
|
||||
}
|
||||
|
||||
export async function addSpace(name: string, memories: number[]) {
|
||||
|
||||
|
|
@ -215,3 +193,32 @@ export async function fetchFreeMemories(
|
|||
return range ? await query.limit(range.limit).offset(range.offset) : await query.all()
|
||||
|
||||
}
|
||||
|
||||
export async function addMemory(content: typeof storedContent.$inferInsert, spaces: number[]) {
|
||||
|
||||
const user = await getUser()
|
||||
|
||||
if (!user) {
|
||||
return null
|
||||
}
|
||||
|
||||
const [addedMemory] = await db.insert(storedContent)
|
||||
.values({
|
||||
user: user.id,
|
||||
...content
|
||||
})
|
||||
.returning();
|
||||
|
||||
const addedToSpaces = spaces.length > 0 ? await db.insert(contentToSpace)
|
||||
.values(spaces.map(s => ({
|
||||
contentId: addedMemory.id,
|
||||
spaceId: s,
|
||||
})))
|
||||
.returning() : [];
|
||||
|
||||
return {
|
||||
memory: addedMemory,
|
||||
addedToSpaces
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
0
apps/web/src/assets/Note.tsx
Normal file
0
apps/web/src/assets/Note.tsx
Normal file
|
|
@ -77,6 +77,9 @@ export function AddMemoryPage() {
|
|||
}
|
||||
|
||||
export function NoteAddPage({ closeDialog }: { closeDialog: () => void }) {
|
||||
|
||||
const { addMemory } = useMemory()
|
||||
|
||||
const [selectedSpacesId, setSelectedSpacesId] = useState<number[]>([]);
|
||||
|
||||
const inputRef = useRef<HTMLInputElement>(null);
|
||||
|
|
@ -116,6 +119,7 @@ export function NoteAddPage({ closeDialog }: { closeDialog: () => void }) {
|
|||
placeholder="Title of the note"
|
||||
data-modal-autofocus
|
||||
value={name}
|
||||
disabled={loading}
|
||||
onChange={(e) => setName(e.target.value)}
|
||||
/>
|
||||
<Editor
|
||||
|
|
@ -138,16 +142,39 @@ export function NoteAddPage({ closeDialog }: { closeDialog: () => void }) {
|
|||
<button
|
||||
onClick={() => {
|
||||
if (check()) {
|
||||
closeDialog();
|
||||
setLoading(true)
|
||||
addMemory({
|
||||
content,
|
||||
title: name,
|
||||
type: "note",
|
||||
url: "https://notes.supermemory.dhr.wtf/",
|
||||
image: '',
|
||||
savedAt: new Date()
|
||||
}, selectedSpacesId).then(closeDialog)
|
||||
}
|
||||
}}
|
||||
className="bg-rgray-4 hover:bg-rgray-5 focus-visible:bg-rgray-5 focus-visible:ring-rgray-7 rounded-md px-4 py-2 ring-transparent transition focus-visible:outline-none focus-visible:ring-2"
|
||||
disabled={loading}
|
||||
className="relative disabled:opacity-70 disabled:cursor-not-allowed bg-rgray-4 hover:bg-rgray-5 focus-visible:bg-rgray-5 focus-visible:ring-rgray-7 rounded-md px-4 py-2 ring-transparent transition focus-visible:outline-none focus-visible:ring-2"
|
||||
>
|
||||
Add
|
||||
|
||||
<motion.div
|
||||
initial={{ x: '-50%', y: '-100%' }}
|
||||
animate={loading && { y: '-50%', x: '-50%', opacity: 1 }}
|
||||
className="opacity-0 absolute top-1/2 left-1/2 translate-y-[-100%] -translate-x-1/2"
|
||||
>
|
||||
<Loader className="w-5 h-5 animate-spin text-rgray-11" />
|
||||
</motion.div>
|
||||
<motion.div
|
||||
initial={{ y: '0%' }}
|
||||
animate={loading && { opacity: 0, y: '30%' }}
|
||||
>
|
||||
Add
|
||||
</motion.div>
|
||||
</button>
|
||||
<DialogClose
|
||||
type={undefined}
|
||||
className="hover:bg-rgray-4 focus-visible:bg-rgray-4 focus-visible:ring-rgray-7 rounded-md px-3 py-2 ring-transparent transition focus-visible:outline-none focus-visible:ring-2"
|
||||
disabled={loading}
|
||||
className="disabled:opacity-70 disabled:cursor-not-allowed hover:bg-rgray-4 focus-visible:bg-rgray-4 focus-visible:ring-rgray-7 rounded-md px-3 py-2 ring-transparent transition focus-visible:outline-none focus-visible:ring-2"
|
||||
>
|
||||
Cancel
|
||||
</DialogClose>
|
||||
|
|
|
|||
|
|
@ -194,7 +194,8 @@ const SpaceExitVariant: Variant = {
|
|||
export function MemoryItem({
|
||||
id,
|
||||
title,
|
||||
image
|
||||
image,
|
||||
type
|
||||
}: StoredContent) {
|
||||
|
||||
const name = title ? title.length > 10 ? title.slice(0, 10) + "..." : title : '<no title>';
|
||||
|
|
@ -209,11 +210,19 @@ export function MemoryItem({
|
|||
</button>
|
||||
|
||||
<div className="w-24 h-24 flex justify-center items-center">
|
||||
<img
|
||||
className="h-16 w-16"
|
||||
id={id.toString()}
|
||||
src={image!}
|
||||
/>
|
||||
{type === "page" ? (
|
||||
<img
|
||||
className="h-16 w-16"
|
||||
id={id.toString()}
|
||||
src={image!}
|
||||
/>
|
||||
): type === "note" ? (
|
||||
<div className="shadow-md rounded-md bg-rgray-4 p-2 flex justify-center items-center">
|
||||
<Text className="w-10 h-10" />
|
||||
</div>
|
||||
) : (
|
||||
<></>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
|
|
|
|||
|
|
@ -16,16 +16,13 @@ export const MemoryContext = React.createContext<{
|
|||
deleteSpace: (id: number) => Promise<void>;
|
||||
freeMemories: StoredContent[];
|
||||
addSpace: typeof addSpace;
|
||||
addMemory: (
|
||||
memory: typeof storedContent.$inferInsert,
|
||||
spaces?: number[],
|
||||
) => Promise<void>;
|
||||
addMemory: typeof addMemory;
|
||||
cachedMemories: ChachedSpaceContent[];
|
||||
search: typeof searchMemoriesAndSpaces;
|
||||
}>({
|
||||
spaces: [],
|
||||
freeMemories: [],
|
||||
addMemory: async () => {},
|
||||
addMemory: (() => {}) as unknown as (typeof addMemory),
|
||||
addSpace: (async () => {}) as unknown as (typeof addSpace),
|
||||
deleteSpace: async () => {},
|
||||
cachedMemories: [],
|
||||
|
|
@ -57,12 +54,6 @@ export const MemoryProvider: React.FC<
|
|||
// const response = await fetch(`/api/memories?${query}`);
|
||||
// }, []);
|
||||
|
||||
const _addMemory = async (
|
||||
memory: typeof storedContent.$inferInsert,
|
||||
spaces: number[] = [],
|
||||
) => {
|
||||
const content = await addMemory(memory, spaces);
|
||||
}
|
||||
|
||||
const _addSpace: typeof addSpace = async (...params) => {
|
||||
const { space: addedSpace, addedMemories } = (await addSpace(...params))!;
|
||||
|
|
@ -80,6 +71,23 @@ export const MemoryProvider: React.FC<
|
|||
}
|
||||
}
|
||||
|
||||
const _addMemory: typeof addMemory = async (...params) => {
|
||||
const { memory: addedMemory, addedToSpaces } = (await addMemory(...params))!;
|
||||
|
||||
addedToSpaces.length > 0 ? setCachedMemories(prev => [
|
||||
...prev,
|
||||
...addedToSpaces.map(s => ({
|
||||
...addedMemory,
|
||||
space: s.spaceId
|
||||
}))
|
||||
]) : setFreeMemories(prev => [...prev, addedMemory])
|
||||
|
||||
return {
|
||||
memory: addedMemory,
|
||||
addedToSpaces
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
<MemoryContext.Provider
|
||||
value={{
|
||||
|
|
|
|||
|
|
@ -1,29 +1,25 @@
|
|||
import * as cheerio from "cheerio"
|
||||
|
||||
export async function getMetaData(url: string) {
|
||||
const response = await fetch(url);
|
||||
const html = await response.text();
|
||||
|
||||
const $ = cheerio.load(html)
|
||||
|
||||
// Extract the base URL
|
||||
const baseUrl = new URL(url).origin;
|
||||
|
||||
// Extract title
|
||||
const titleMatch = html.match(/<title>(.*?)<\/title>/);
|
||||
const title = titleMatch ? titleMatch[1] : "Title not found";
|
||||
const title = $('title').text().trim()
|
||||
|
||||
// Extract meta description
|
||||
const descriptionMatch = html.match(
|
||||
/<meta name="description" content="(.*?)"\s*\/?>/,
|
||||
);
|
||||
const description = descriptionMatch
|
||||
? descriptionMatch[1]
|
||||
: "Description not found";
|
||||
const description = $('meta[name=description]').attr('content') ?? ''
|
||||
|
||||
// Extract favicon
|
||||
const faviconMatch = html.match(
|
||||
/<link rel="(?:icon|shortcut icon)" href="(.*?)"\s*\/?>/,
|
||||
);
|
||||
const favicon = faviconMatch
|
||||
? faviconMatch[1]
|
||||
: "https://supermemory.dhr.wtf/web.svg";
|
||||
const _favicon = $('link[rel=icon]').attr('href') ?? 'https://supermemory.dhr.wtf/web.svg';
|
||||
|
||||
let favicon = _favicon.trim().length > 0 ? _favicon.trim() : 'https://supermemory.dhr.wtf/web.svg'
|
||||
if (favicon.startsWith("/")) {
|
||||
favicon = baseUrl + favicon
|
||||
}
|
||||
|
||||
// Prepare the metadata object
|
||||
const metadata = {
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue