mirror of
https://github.com/supermemoryai/supermemory.git
synced 2026-09-15 23:31:05 +00:00
feat(graph): add canvas-native document type icons for all supported types
- Add 10 new icon drawing functions: Notion, Google Docs, Slides, Cloud, X/Twitter, Play/Video, Image, Text/Note, and more - Extend drawDocIcon switch to handle all 19+ document types from web app: word, excel, google_sheet, google_slide, powerpoint, onedrive, google_drive, tweet, youtube, video, image, text, note, onenote, mcp - Update mock data with additional document types for better demo coverage - All icons are pure canvas vector drawings (no image assets needed)
This commit is contained in:
parent
2a18fb4df0
commit
c6ac3e0651
2 changed files with 231 additions and 4 deletions
|
|
@ -735,9 +735,14 @@ function drawDocIcon(
|
|||
break
|
||||
case "doc":
|
||||
case "docx":
|
||||
drawTextLabel(ctx, x, y, size, "DOC", 0.28)
|
||||
case "word":
|
||||
case "microsoft_word":
|
||||
drawTextLabel(ctx, x, y, size, "W", 0.4)
|
||||
break
|
||||
case "csv":
|
||||
case "excel":
|
||||
case "microsoft_excel":
|
||||
case "google_sheet":
|
||||
drawGridIcon(ctx, x, y, size)
|
||||
break
|
||||
case "json":
|
||||
|
|
@ -745,12 +750,40 @@ function drawDocIcon(
|
|||
break
|
||||
case "notion":
|
||||
case "notion_doc":
|
||||
drawTextLabel(ctx, x, y, size, "N", 0.4)
|
||||
drawNotionIcon(ctx, x, y, size)
|
||||
break
|
||||
case "google_doc":
|
||||
case "google_sheet":
|
||||
drawGoogleDocIcon(ctx, x, y, size)
|
||||
break
|
||||
case "google_slide":
|
||||
drawTextLabel(ctx, x, y, size, "G", 0.4)
|
||||
case "powerpoint":
|
||||
case "microsoft_powerpoint":
|
||||
drawSlidesIcon(ctx, x, y, size)
|
||||
break
|
||||
case "google_drive":
|
||||
case "onedrive":
|
||||
drawCloudIcon(ctx, x, y, size)
|
||||
break
|
||||
case "tweet":
|
||||
drawXIcon(ctx, x, y, size)
|
||||
break
|
||||
case "youtube":
|
||||
case "video":
|
||||
drawPlayIcon(ctx, x, y, size)
|
||||
break
|
||||
case "image":
|
||||
drawImageIcon(ctx, x, y, size)
|
||||
break
|
||||
case "text":
|
||||
case "note":
|
||||
drawTextNoteIcon(ctx, x, y, size)
|
||||
break
|
||||
case "onenote":
|
||||
case "microsoft_onenote":
|
||||
drawTextLabel(ctx, x, y, size, "N", 0.4)
|
||||
break
|
||||
case "mcp":
|
||||
drawTextLabel(ctx, x, y, size, "MCP", 0.25)
|
||||
break
|
||||
default:
|
||||
drawDocOutline(ctx, x, y, size)
|
||||
|
|
@ -859,6 +892,193 @@ function drawDocOutline(
|
|||
ctx.stroke()
|
||||
}
|
||||
|
||||
/** Draw a simplified Notion "N" logo mark */
|
||||
function drawNotionIcon(
|
||||
ctx: CanvasRenderingContext2D,
|
||||
x: number,
|
||||
y: number,
|
||||
size: number,
|
||||
): void {
|
||||
const w = size * 0.5
|
||||
const h = size * 0.6
|
||||
// Outer rounded rect outline
|
||||
const r = size * 0.08
|
||||
ctx.lineWidth = Math.max(1, size / 14)
|
||||
roundRect(ctx, x - w / 2, y - h / 2, w, h, r)
|
||||
ctx.stroke()
|
||||
// Inner "N" shape
|
||||
const inset = size * 0.12
|
||||
const left = x - w / 2 + inset
|
||||
const right = x + w / 2 - inset
|
||||
const top = y - h / 2 + inset
|
||||
const bottom = y + h / 2 - inset
|
||||
ctx.beginPath()
|
||||
ctx.moveTo(left, top)
|
||||
ctx.lineTo(left, bottom)
|
||||
ctx.moveTo(left, top)
|
||||
ctx.lineTo(right, bottom)
|
||||
ctx.moveTo(right, top)
|
||||
ctx.lineTo(right, bottom)
|
||||
ctx.stroke()
|
||||
}
|
||||
|
||||
/** Draw a Google Docs icon (document with lines) */
|
||||
function drawGoogleDocIcon(
|
||||
ctx: CanvasRenderingContext2D,
|
||||
x: number,
|
||||
y: number,
|
||||
size: number,
|
||||
): void {
|
||||
const w = size * 0.55
|
||||
const h = size * 0.7
|
||||
const fold = size * 0.15
|
||||
// Document body with corner fold
|
||||
ctx.beginPath()
|
||||
ctx.moveTo(x - w / 2, y - h / 2)
|
||||
ctx.lineTo(x + w / 2 - fold, y - h / 2)
|
||||
ctx.lineTo(x + w / 2, y - h / 2 + fold)
|
||||
ctx.lineTo(x + w / 2, y + h / 2)
|
||||
ctx.lineTo(x - w / 2, y + h / 2)
|
||||
ctx.closePath()
|
||||
ctx.stroke()
|
||||
// Text lines
|
||||
const lineW = w * 0.6
|
||||
const sp = size * 0.1
|
||||
ctx.beginPath()
|
||||
ctx.moveTo(x - lineW / 2, y - sp)
|
||||
ctx.lineTo(x + lineW / 2, y - sp)
|
||||
ctx.moveTo(x - lineW / 2, y + sp * 0.3)
|
||||
ctx.lineTo(x + lineW / 2, y + sp * 0.3)
|
||||
ctx.moveTo(x - lineW / 2, y + sp * 1.6)
|
||||
ctx.lineTo(x + lineW / 3, y + sp * 1.6)
|
||||
ctx.stroke()
|
||||
}
|
||||
|
||||
/** Draw a slides/presentation icon (rectangle with play triangle) */
|
||||
function drawSlidesIcon(
|
||||
ctx: CanvasRenderingContext2D,
|
||||
x: number,
|
||||
y: number,
|
||||
size: number,
|
||||
): void {
|
||||
const w = size * 0.7
|
||||
const h = size * 0.5
|
||||
ctx.strokeRect(x - w / 2, y - h / 2, w, h)
|
||||
// Small play triangle in center
|
||||
const triSize = size * 0.15
|
||||
ctx.beginPath()
|
||||
ctx.moveTo(x - triSize * 0.5, y - triSize * 0.7)
|
||||
ctx.lineTo(x - triSize * 0.5, y + triSize * 0.7)
|
||||
ctx.lineTo(x + triSize * 0.7, y)
|
||||
ctx.closePath()
|
||||
ctx.fill()
|
||||
}
|
||||
|
||||
/** Draw a cloud icon for drive/storage types */
|
||||
function drawCloudIcon(
|
||||
ctx: CanvasRenderingContext2D,
|
||||
x: number,
|
||||
y: number,
|
||||
size: number,
|
||||
): void {
|
||||
const s = size * 0.35
|
||||
ctx.beginPath()
|
||||
// Cloud shape using arcs
|
||||
ctx.arc(x - s * 0.3, y + s * 0.1, s * 0.5, Math.PI * 0.7, Math.PI * 1.9)
|
||||
ctx.arc(x + s * 0.1, y - s * 0.3, s * 0.55, Math.PI * 1.1, Math.PI * 0.3)
|
||||
ctx.arc(x + s * 0.5, y + s * 0.1, s * 0.4, Math.PI * 1.4, Math.PI * 0.6)
|
||||
ctx.lineTo(x - s * 0.7, y + s * 0.45)
|
||||
ctx.closePath()
|
||||
ctx.stroke()
|
||||
}
|
||||
|
||||
/** Draw an X (formerly Twitter) icon */
|
||||
function drawXIcon(
|
||||
ctx: CanvasRenderingContext2D,
|
||||
x: number,
|
||||
y: number,
|
||||
size: number,
|
||||
): void {
|
||||
const s = size * 0.3
|
||||
ctx.lineWidth = Math.max(1.5, size / 10)
|
||||
ctx.beginPath()
|
||||
// X shape (two crossing strokes)
|
||||
ctx.moveTo(x - s, y - s)
|
||||
ctx.lineTo(x + s, y + s)
|
||||
ctx.moveTo(x + s, y - s)
|
||||
ctx.lineTo(x - s, y + s)
|
||||
ctx.stroke()
|
||||
}
|
||||
|
||||
/** Draw a play button icon for video/youtube */
|
||||
function drawPlayIcon(
|
||||
ctx: CanvasRenderingContext2D,
|
||||
x: number,
|
||||
y: number,
|
||||
size: number,
|
||||
): void {
|
||||
const r = size * 0.38
|
||||
// Rounded rectangle background
|
||||
const w = r * 2.2
|
||||
const h = r * 1.5
|
||||
const cr = size * 0.08
|
||||
roundRect(ctx, x - w / 2, y - h / 2, w, h, cr)
|
||||
ctx.stroke()
|
||||
// Play triangle
|
||||
const triH = size * 0.22
|
||||
ctx.beginPath()
|
||||
ctx.moveTo(x - triH * 0.45, y - triH)
|
||||
ctx.lineTo(x - triH * 0.45, y + triH)
|
||||
ctx.lineTo(x + triH * 0.7, y)
|
||||
ctx.closePath()
|
||||
ctx.fill()
|
||||
}
|
||||
|
||||
/** Draw an image/photo icon (landscape with mountain) */
|
||||
function drawImageIcon(
|
||||
ctx: CanvasRenderingContext2D,
|
||||
x: number,
|
||||
y: number,
|
||||
size: number,
|
||||
): void {
|
||||
const w = size * 0.7
|
||||
const h = size * 0.55
|
||||
ctx.strokeRect(x - w / 2, y - h / 2, w, h)
|
||||
// Mountain shape
|
||||
ctx.beginPath()
|
||||
ctx.moveTo(x - w / 2 + w * 0.1, y + h / 2 - h * 0.1)
|
||||
ctx.lineTo(x - w * 0.05, y - h * 0.05)
|
||||
ctx.lineTo(x + w * 0.15, y + h * 0.15)
|
||||
ctx.lineTo(x + w * 0.25, y - h * 0.02)
|
||||
ctx.lineTo(x + w / 2 - w * 0.1, y + h / 2 - h * 0.1)
|
||||
ctx.stroke()
|
||||
// Sun circle
|
||||
const sunR = size * 0.06
|
||||
ctx.beginPath()
|
||||
ctx.arc(x - w * 0.15, y - h * 0.15, sunR, 0, Math.PI * 2)
|
||||
ctx.fill()
|
||||
}
|
||||
|
||||
/** Draw a text/note icon (lines of text) */
|
||||
function drawTextNoteIcon(
|
||||
ctx: CanvasRenderingContext2D,
|
||||
x: number,
|
||||
y: number,
|
||||
size: number,
|
||||
): void {
|
||||
const w = size * 0.55
|
||||
const h = size * 0.6
|
||||
const sp = h / 5
|
||||
ctx.beginPath()
|
||||
for (let i = 0; i < 4; i++) {
|
||||
const lineY = y - h / 2 + sp * (i + 0.5)
|
||||
const lineW = i === 3 ? w * 0.6 : w
|
||||
ctx.moveTo(x - w / 2, lineY)
|
||||
ctx.lineTo(x - w / 2 + lineW, lineY)
|
||||
}
|
||||
ctx.stroke()
|
||||
}
|
||||
|
||||
/** Lighten a 6-digit hex color by a fraction (0-1). Cached to avoid per-frame parsing. */
|
||||
export function lightenColor(hex: string, amount: number): string {
|
||||
if (
|
||||
|
|
|
|||
|
|
@ -29,6 +29,13 @@ const DOCUMENT_TYPES = [
|
|||
"json",
|
||||
"notion",
|
||||
"text",
|
||||
"google_doc",
|
||||
"google_sheet",
|
||||
"google_slide",
|
||||
"tweet",
|
||||
"youtube",
|
||||
"image",
|
||||
"note",
|
||||
] as const
|
||||
|
||||
const TITLE_PREFIXES = [
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue