mirror of
https://github.com/supermemoryai/supermemory.git
synced 2026-10-06 02:47:54 +00:00
Merge branch 'codetorso' of https://github.com/Dhravya/supermemory into codetorso
This commit is contained in:
commit
0d069e8741
31 changed files with 411 additions and 183 deletions
37
apps/extension/README.md
Normal file
37
apps/extension/README.md
Normal file
|
|
@ -0,0 +1,37 @@
|
|||
# [projectName]
|
||||
|
||||
> This project was bootstrapped using the Extension.js React-TypeScript template.
|
||||
|
||||
## Scripts Available
|
||||
|
||||
In the project directory, you can run:
|
||||
|
||||
### [projectPackageManager] dev
|
||||
|
||||
```
|
||||
// Runs the app in the development mode.
|
||||
// Will open a new browser instance with your extension loaded.
|
||||
// The page will reload when you make changes.
|
||||
[projectPackageManager] dev
|
||||
```
|
||||
|
||||
### [projectPackageManager] start
|
||||
|
||||
```
|
||||
// Runs the app in the production mode.
|
||||
// Will open a new browser instance with your extension loaded.
|
||||
// This is how your browser extension will work once published.
|
||||
[projectPackageManager] start
|
||||
```
|
||||
|
||||
### [projectPackageManager] build
|
||||
|
||||
```
|
||||
// Builds the app for production.
|
||||
// Bundles your browser extension in production mode for the target browser.
|
||||
[projectPackageManager] run build
|
||||
```
|
||||
|
||||
## Learn More
|
||||
|
||||
You can learn more in the [Extension.js](https://extension.js.org) documentation.
|
||||
25
apps/extension/background.ts
Normal file
25
apps/extension/background.ts
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
chrome.runtime.onInstalled.addListener(function () {
|
||||
let context = 'selection';
|
||||
let title = "Supermemory - Save Highlight";
|
||||
chrome.contextMenus.create({
|
||||
title: title,
|
||||
contexts: ['selection'],
|
||||
id: context,
|
||||
});
|
||||
});
|
||||
|
||||
chrome.contextMenus.onClicked.addListener(function (info, tab) {
|
||||
if (info.menuItemId === 'selection') {
|
||||
// you can add a link to a cf worker or whatever u want
|
||||
// fetch("", {
|
||||
// method: "POST",
|
||||
// headers: { "Content-Type": "application/json" },
|
||||
// body: JSON.stringify({
|
||||
// data: info.selectionText,
|
||||
// }),
|
||||
// });
|
||||
|
||||
//so you first save it and then send the reponse to the screen
|
||||
chrome.tabs.sendMessage(tab?.id || 1, info.selectionText);
|
||||
}
|
||||
});
|
||||
45
apps/extension/content/ContentApp.tsx
Normal file
45
apps/extension/content/ContentApp.tsx
Normal file
|
|
@ -0,0 +1,45 @@
|
|||
import React, { useEffect } from "react";
|
||||
|
||||
export default function ContentApp() {
|
||||
const [text, setText] = React.useState("");
|
||||
const [hover, setHover] = React.useState(false);
|
||||
|
||||
useEffect(() => {
|
||||
const messageListener = (message: any) => {
|
||||
setText(message);
|
||||
setTimeout(() => setText(""), 2000);
|
||||
};
|
||||
chrome.runtime.onMessage.addListener(messageListener);
|
||||
|
||||
document.addEventListener('mousemove', (e)=> {
|
||||
const percentageX = (e.clientX / window.innerWidth) * 100;
|
||||
const percentageY = (e.clientY / window.innerHeight) * 100;
|
||||
|
||||
if (percentageX > 75 && percentageY > 75){
|
||||
setHover(true)
|
||||
} else {
|
||||
setHover(false)
|
||||
}
|
||||
})
|
||||
return () => {
|
||||
chrome.runtime.onMessage.removeListener(messageListener);
|
||||
};
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<div className="pointer-events-none flex justify-end items-end h-screen w-full absolute z-99999">
|
||||
<div className="h-[30vh] bg-red-500 absolute flex justify-end items-center">
|
||||
<div
|
||||
className={`${hover && "opacity-100 "} transition bg-red-600 opacity-0 h-12 w-12 `}
|
||||
></div>
|
||||
</div>
|
||||
|
||||
<div
|
||||
className={`mx-4 my-2 flex flex-col gap-3 rounded-3xl bg-gray-900 text-xl py-4 px-6 overflow-hidden min-w-[20vw] min-h-24 max-w-96 max-h-40 ${text ? "translate-y-0 opacity-100" : "translate-y-[15%] opacity-0"} transition`}
|
||||
>
|
||||
<h2 className="text-2xl font-extrabold text-white">Saved!</h2>
|
||||
<h2 className="text-lg font-medium text-white">{text}</h2>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
3
apps/extension/content/base.css
Normal file
3
apps/extension/content/base.css
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
@tailwind base;
|
||||
@tailwind components;
|
||||
@tailwind utilities;
|
||||
6
apps/extension/content/content.css
Normal file
6
apps/extension/content/content.css
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
#extension-root {
|
||||
position: fixed;
|
||||
bottom: 0;
|
||||
right: 0;
|
||||
z-index: 99999;
|
||||
}
|
||||
15
apps/extension/content/content.tsx
Normal file
15
apps/extension/content/content.tsx
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
import ReactDOM from 'react-dom/client'
|
||||
import ContentApp from './ContentApp'
|
||||
import('./base.css')
|
||||
import('./content.css')
|
||||
|
||||
setTimeout(initial, 4000)
|
||||
|
||||
function initial() {
|
||||
const rootDiv = document.createElement('div')
|
||||
rootDiv.id = 'extension-root'
|
||||
document.body.appendChild(rootDiv)
|
||||
|
||||
const root = ReactDOM.createRoot(rootDiv)
|
||||
root.render(<><ContentApp /></>)
|
||||
}
|
||||
9
apps/extension/extension-env.d.ts
vendored
Normal file
9
apps/extension/extension-env.d.ts
vendored
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
// Required Extension.js types for TypeScript projects.
|
||||
// This file is auto-generated and should not be excluded.
|
||||
// If you need extra types, consider creating a new *.d.ts and
|
||||
// referencing it in the "include" array in your tsconfig.json file.
|
||||
// See https://www.typescriptlang.org/tsconfig#include for info.
|
||||
/// <reference types="@extension-create/develop/dist/types/index.d.ts" />
|
||||
|
||||
// Polyfill types for browser.* APIs.
|
||||
/// <reference types="@extension-create/develop/dist/types/polyfill.d.ts" />
|
||||
11
apps/extension/index.html
Normal file
11
apps/extension/index.html
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>God Bless Vanilla JavaScript!!!</title>
|
||||
</head>
|
||||
<body>
|
||||
<h1>hello World! Follow <a href="https://x.com/supermemoryai">@supermemoryai</a></h1>
|
||||
</body>
|
||||
</html>
|
||||
30
apps/extension/manifest.json
Normal file
30
apps/extension/manifest.json
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
|
||||
{
|
||||
"name": "Supermemory.ai-Extension",
|
||||
"description": "Uses the chrome.contextMenus API to customize the context menu.",
|
||||
"version": "0.1",
|
||||
"permissions": [
|
||||
"contextMenus"
|
||||
],
|
||||
"manifest_version": 3,
|
||||
"action": {
|
||||
"default_popup": "index.html"
|
||||
},
|
||||
"background": {
|
||||
"service_worker": "./background.ts"
|
||||
},
|
||||
"content_scripts": [
|
||||
{
|
||||
"matches": [
|
||||
"<all_urls>"
|
||||
],
|
||||
"js": [
|
||||
"./content/content.tsx"
|
||||
]
|
||||
}
|
||||
],
|
||||
"icons": {
|
||||
"16": "public/icon/logo(16).png",
|
||||
"48": "public/icon/logo(48).png"
|
||||
}
|
||||
}
|
||||
20
apps/extension/package.json
Normal file
20
apps/extension/package.json
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
{
|
||||
"devDependencies": {
|
||||
"@types/react": "^18.0.9",
|
||||
"@types/react-dom": "^18.0.5",
|
||||
"react": "^18.1.0",
|
||||
"react-dom": "^18.1.0",
|
||||
"tailwindcss": "^3.4.1",
|
||||
"typescript": "5.3.3",
|
||||
"extension": "latest"
|
||||
},
|
||||
"scripts": {
|
||||
"dev": "extension dev",
|
||||
"start": "extension start",
|
||||
"build": "extension build"
|
||||
},
|
||||
"dependencies": {},
|
||||
"name": "extension",
|
||||
"private": true,
|
||||
"version": "0.0.0"
|
||||
}
|
||||
BIN
apps/extension/public/icon/logo(16).png
Normal file
BIN
apps/extension/public/icon/logo(16).png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 980 B |
BIN
apps/extension/public/icon/logo(48).png
Normal file
BIN
apps/extension/public/icon/logo(48).png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 2 KiB |
8
apps/extension/tailwind.config.js
Normal file
8
apps/extension/tailwind.config.js
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
module.exports = {
|
||||
content: ['**/*.html', '**/*.tsx'],
|
||||
theme: {
|
||||
extend: {}
|
||||
},
|
||||
plugins: []
|
||||
}
|
||||
module.exports = require("@repo/tailwind-config/tailwind.config");
|
||||
19
apps/extension/tsconfig.json
Normal file
19
apps/extension/tsconfig.json
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
{
|
||||
"extends": "@repo/typescript-config/nextjs.json",
|
||||
"compilerOptions": {
|
||||
"allowJs": true,
|
||||
"allowSyntheticDefaultImports": true,
|
||||
"esModuleInterop": true,
|
||||
"forceConsistentCasingInFileNames": true,
|
||||
"isolatedModules": false,
|
||||
"jsx": "react-jsx",
|
||||
"lib": ["dom", "dom.iterable", "esnext"],
|
||||
"moduleResolution": "node",
|
||||
"module": "esnext",
|
||||
"resolveJsonModule": true,
|
||||
"strict": true,
|
||||
"target": "esnext"
|
||||
},
|
||||
"include": ["./"],
|
||||
"exclude": ["node_modules", "dist"]
|
||||
}
|
||||
|
|
@ -1,3 +0,0 @@
|
|||
.tlui-dialog__overlay {
|
||||
position: fixed;
|
||||
}
|
||||
125
apps/web/app/(canvas)/canvas/[id]/page.tsx
Normal file
125
apps/web/app/(canvas)/canvas/[id]/page.tsx
Normal file
|
|
@ -0,0 +1,125 @@
|
|||
"use client";
|
||||
|
||||
import { Canvas } from "@repo/ui/components/canvas/components/canvas";
|
||||
import React, { useState } from "react";
|
||||
import { Panel, PanelGroup, PanelResizeHandle } from "react-resizable-panels";
|
||||
import { SettingsIcon, DragIcon } from "@repo/ui/icons";
|
||||
import DraggableComponentsContainer from "@repo/ui/components/canvas/components/draggableComponent";
|
||||
import { AutocompleteIcon, blockIcon } from "@repo/ui/icons";
|
||||
import Image from "next/image";
|
||||
import { Switch } from "@repo/ui/shadcn/switch";
|
||||
import { Label } from "@repo/ui/shadcn/label";
|
||||
|
||||
function page() {
|
||||
const [fullScreen, setFullScreen] = useState(false);
|
||||
const [visible, setVisible] = useState(true);
|
||||
|
||||
return (
|
||||
<div
|
||||
className={`h-screen w-full ${!fullScreen ? "px-4 py-6" : "bg-[#1F2428]"} transition-all`}
|
||||
>
|
||||
<div>
|
||||
<PanelGroup
|
||||
onLayout={(l) => {
|
||||
l[0]! < 20 ? setVisible(false) : setVisible(true);
|
||||
}}
|
||||
className={` ${fullScreen ? "w-[calc(100vw-2rem)]" : "w-screen"} transition-all`}
|
||||
direction="horizontal"
|
||||
>
|
||||
<Panel
|
||||
onExpand={() => {
|
||||
setTimeout(() => setFullScreen(false), 50);
|
||||
}}
|
||||
onCollapse={() => {
|
||||
setTimeout(() => setFullScreen(true), 50);
|
||||
}}
|
||||
defaultSize={30}
|
||||
collapsible={true}
|
||||
>
|
||||
<div
|
||||
className={`flex transition-all rounded-2xl ${fullScreen ? "h-screen" : "h-[calc(100vh-3rem)]"} w-full flex-col overflow-hidden bg-[#1F2428]`}
|
||||
>
|
||||
<div className="flex items-center justify-between bg-[#2C3439] px-4 py-2 text-lg font-medium text-[#989EA4]">
|
||||
Change Filters
|
||||
<Image src={SettingsIcon} alt="setting-icon" />
|
||||
</div>
|
||||
{visible ? (
|
||||
<SidePanel />
|
||||
) : (
|
||||
<h1 className="text-center py-10 text-xl">
|
||||
Need more space to show!
|
||||
</h1>
|
||||
)}
|
||||
</div>
|
||||
</Panel>
|
||||
<PanelResizeHandle
|
||||
className={`relative flex items-center transition-all justify-center ${!fullScreen && "px-1"}`}
|
||||
>
|
||||
<div
|
||||
className={`rounded-lg bg-[#2F363B] ${!fullScreen && "px-1"} transition-all py-2`}
|
||||
>
|
||||
<Image src={DragIcon} alt="drag-icon" />
|
||||
</div>
|
||||
</PanelResizeHandle>
|
||||
<Panel className="relative" defaultSize={70} minSize={60}>
|
||||
<div
|
||||
className={`absolute overflow-hidden transition-all inset-0 ${fullScreen ? "h-screen " : "h-[calc(100vh-3rem)] rounded-2xl"} w-full`}
|
||||
>
|
||||
<Canvas />
|
||||
</div>
|
||||
</Panel>
|
||||
</PanelGroup>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
function SidePanel() {
|
||||
const [value, setValue] = useState("");
|
||||
const [dragAsText, setDragAsText] = useState(false);
|
||||
return (
|
||||
<>
|
||||
<div className="px-3 py-5">
|
||||
<input
|
||||
placeholder="search..."
|
||||
onChange={(e) => {
|
||||
setValue(e.target.value);
|
||||
}}
|
||||
value={value}
|
||||
// rows={1}
|
||||
className="w-full resize-none rounded-xl bg-[#151515] px-3 py-4 text-xl text-[#989EA4] outline-none focus:outline-none sm:max-h-52"
|
||||
/>
|
||||
</div>
|
||||
<div className="flex items-center justify-end px-3 py-4">
|
||||
<Switch
|
||||
className="bg-[#151515] data-[state=unchecked]:bg-red-400 data-[state=checked]:bg-blue-400"
|
||||
onCheckedChange={(e) => setDragAsText(e)}
|
||||
id="drag-text-mode"
|
||||
/>
|
||||
<Label htmlFor="drag-text-mode">Drag as Text</Label>
|
||||
</div>
|
||||
<DraggableComponentsContainer content={content} />
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
export default page;
|
||||
|
||||
const content = [
|
||||
{
|
||||
content:
|
||||
"Regional growth patterns diverge, with strong performance in the United States and several emerging markets, contrasted by weaker prospects in many advanced economies, particularly in Europe (World Economic Forum) (OECD). The rapid adoption of artificial intelligence (AI) is expected to drive productivity growth, especially in advanced economies, potentially mitigating labor shortages and boosting income levels in emerging markets (World Economic Forum) (OECD). However, ongoing geopolitical tensions and economic fragmentation are likely to maintain a level of uncertainty and volatility in the global economy (World Economic Forum.",
|
||||
icon: AutocompleteIcon,
|
||||
iconAlt: "Autocomplete",
|
||||
extraInfo:
|
||||
"Page Url: https://chatgpt.com/c/762cd44e-1752-495b-967a-aa3c23c6024a",
|
||||
},
|
||||
{
|
||||
content:
|
||||
"As of mid-2024, the global economy is experiencing modest growth with significant regional disparities. Global GDP growth is projected to be around 3.1% in 2024, rising slightly to 3.2% in 2025. This performance, although below the pre-pandemic average, reflects resilience despite various economic pressures, including tight monetary conditions and geopolitical tensions (IMF)(OECD) Inflation is moderating faster than expected, with global headline inflation projected to fall to 5.8% in 2024 and 4.4% in 2025, contributing to improving real incomes and positive trade growth (IMF) (OECD)",
|
||||
icon: blockIcon,
|
||||
iconAlt: "Autocomplete",
|
||||
extraInfo:
|
||||
"Page Url: https://www.cnbc.com/2024/05/23/nvidia-keeps-hitting-records-can-investors-still-buy-the-stock.html?&qsearchterm=nvidia",
|
||||
},
|
||||
];
|
||||
|
|
@ -1,125 +1,9 @@
|
|||
"use client";
|
||||
|
||||
import { Canvas } from "../canvas";
|
||||
import React, { useState } from "react";
|
||||
import { Panel, PanelGroup, PanelResizeHandle } from "react-resizable-panels";
|
||||
import { SettingsIcon, DragIcon } from "@repo/ui/icons";
|
||||
import DraggableComponentsContainer from "@repo/ui/components/canvas/draggableComponent";
|
||||
import { AutocompleteIcon, blockIcon } from "@repo/ui/icons";
|
||||
import Image from "next/image";
|
||||
import { Switch } from "@repo/ui/shadcn/switch";
|
||||
import { Label } from "@repo/ui/shadcn/label";
|
||||
import React from 'react'
|
||||
|
||||
function page() {
|
||||
const [fullScreen, setFullScreen] = useState(false);
|
||||
const [visible, setVisible] = useState(true);
|
||||
|
||||
return (
|
||||
<div
|
||||
className={`h-screen w-full ${!fullScreen ? "px-4 py-6" : "bg-[#1F2428]"} transition-all`}
|
||||
>
|
||||
<div>
|
||||
<PanelGroup
|
||||
onLayout={(l) => {
|
||||
l[0]! < 20 ? setVisible(false) : setVisible(true);
|
||||
}}
|
||||
className={` ${fullScreen ? "w-[calc(100vw-2rem)]" : "w-screen"} transition-all`}
|
||||
direction="horizontal"
|
||||
>
|
||||
<Panel
|
||||
onExpand={() => {
|
||||
setTimeout(() => setFullScreen(false), 50);
|
||||
}}
|
||||
onCollapse={() => {
|
||||
setTimeout(() => setFullScreen(true), 50);
|
||||
}}
|
||||
defaultSize={30}
|
||||
collapsible={true}
|
||||
>
|
||||
<div
|
||||
className={`flex transition-all rounded-2xl ${fullScreen ? "h-screen" : "h-[calc(100vh-3rem)]"} w-full flex-col overflow-hidden bg-[#1F2428]`}
|
||||
>
|
||||
<div className="flex items-center justify-between bg-[#2C3439] px-4 py-2 text-lg font-medium text-[#989EA4]">
|
||||
Change Filters
|
||||
<Image src={SettingsIcon} alt="setting-icon" />
|
||||
</div>
|
||||
{visible ? (
|
||||
<SidePanel />
|
||||
) : (
|
||||
<h1 className="text-center py-10 text-xl">
|
||||
Need more space to show!
|
||||
</h1>
|
||||
)}
|
||||
</div>
|
||||
</Panel>
|
||||
<PanelResizeHandle
|
||||
className={`relative flex items-center transition-all justify-center ${!fullScreen && "px-1"}`}
|
||||
>
|
||||
<div
|
||||
className={`rounded-lg bg-[#2F363B] ${!fullScreen && "px-1"} transition-all py-2`}
|
||||
>
|
||||
<Image src={DragIcon} alt="drag-icon" />
|
||||
</div>
|
||||
</PanelResizeHandle>
|
||||
<Panel className="relative" defaultSize={70} minSize={60}>
|
||||
<div
|
||||
className={`absolute overflow-hidden transition-all inset-0 ${fullScreen ? "h-screen " : "h-[calc(100vh-3rem)] rounded-2xl"} w-full`}
|
||||
>
|
||||
<Canvas />
|
||||
</div>
|
||||
</Panel>
|
||||
</PanelGroup>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
<div>page</div>
|
||||
)
|
||||
}
|
||||
|
||||
function SidePanel() {
|
||||
const [value, setValue] = useState("");
|
||||
const [dragAsText, setDragAsText] = useState(false);
|
||||
return (
|
||||
<>
|
||||
<div className="px-3 py-5">
|
||||
<input
|
||||
placeholder="search..."
|
||||
onChange={(e) => {
|
||||
setValue(e.target.value);
|
||||
}}
|
||||
value={value}
|
||||
// rows={1}
|
||||
className="w-full resize-none rounded-xl bg-[#151515] px-3 py-4 text-xl text-[#989EA4] outline-none focus:outline-none sm:max-h-52"
|
||||
/>
|
||||
</div>
|
||||
<div className="flex items-center justify-end px-3 py-4">
|
||||
<Switch
|
||||
className="bg-[#151515] data-[state=unchecked]:bg-red-400 data-[state=checked]:bg-blue-400"
|
||||
onCheckedChange={(e) => setDragAsText(e)}
|
||||
id="drag-text-mode"
|
||||
/>
|
||||
<Label htmlFor="drag-text-mode">Drag as Text</Label>
|
||||
</div>
|
||||
<DraggableComponentsContainer content={content} />
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
export default page;
|
||||
|
||||
const content = [
|
||||
{
|
||||
content:
|
||||
"Regional growth patterns diverge, with strong performance in the United States and several emerging markets, contrasted by weaker prospects in many advanced economies, particularly in Europe (World Economic Forum) (OECD). The rapid adoption of artificial intelligence (AI) is expected to drive productivity growth, especially in advanced economies, potentially mitigating labor shortages and boosting income levels in emerging markets (World Economic Forum) (OECD). However, ongoing geopolitical tensions and economic fragmentation are likely to maintain a level of uncertainty and volatility in the global economy (World Economic Forum.",
|
||||
icon: AutocompleteIcon,
|
||||
iconAlt: "Autocomplete",
|
||||
extraInfo:
|
||||
"Page Url: https://chatgpt.com/c/762cd44e-1752-495b-967a-aa3c23c6024a",
|
||||
},
|
||||
{
|
||||
content:
|
||||
"As of mid-2024, the global economy is experiencing modest growth with significant regional disparities. Global GDP growth is projected to be around 3.1% in 2024, rising slightly to 3.2% in 2025. This performance, although below the pre-pandemic average, reflects resilience despite various economic pressures, including tight monetary conditions and geopolitical tensions (IMF)(OECD) Inflation is moderating faster than expected, with global headline inflation projected to fall to 5.8% in 2024 and 4.4% in 2025, contributing to improving real incomes and positive trade growth (IMF) (OECD)",
|
||||
icon: blockIcon,
|
||||
iconAlt: "Autocomplete",
|
||||
extraInfo:
|
||||
"Page Url: https://www.cnbc.com/2024/05/23/nvidia-keeps-hitting-records-can-investors-still-buy-the-stock.html?&qsearchterm=nvidia",
|
||||
},
|
||||
];
|
||||
export default page
|
||||
|
|
@ -21,4 +21,8 @@
|
|||
|
||||
.tlui-minimap__canvas {
|
||||
background: #1F2428 !important;
|
||||
}
|
||||
|
||||
.tlui-dialog__overlay {
|
||||
position: fixed;
|
||||
}
|
||||
|
|
@ -1,11 +0,0 @@
|
|||
import { createContext } from 'react';
|
||||
|
||||
export interface DragContextType {
|
||||
isDraggingOver: boolean;
|
||||
setIsDraggingOver: React.Dispatch<React.SetStateAction<boolean>>;
|
||||
}
|
||||
|
||||
|
||||
const DragContext = createContext<DragContextType | undefined>(undefined);
|
||||
|
||||
export default DragContext;
|
||||
|
|
@ -1,16 +1,16 @@
|
|||
import { useCallback, useEffect, useMemo, useRef, useState } from "react";
|
||||
import { useCallback, useEffect, useRef, useState } from "react";
|
||||
import { Editor, Tldraw, setUserPreferences, TLStoreWithStatus } from "tldraw";
|
||||
import { createAssetFromUrl } from "./lib/createAssetUrl";
|
||||
import { createAssetFromUrl } from "../lib/createAssetUrl";
|
||||
import "tldraw/tldraw.css";
|
||||
import { components } from "./enabledComp";
|
||||
import { twitterCardUtil } from "./twitterCard";
|
||||
import { textCardUtil } from "./textCard";
|
||||
import createEmbedsFromUrl from "./lib/createEmbeds";
|
||||
import { loadRemoteSnapshot } from "./lib/loadSnap";
|
||||
import createEmbedsFromUrl from "../lib/createEmbeds";
|
||||
import { loadRemoteSnapshot } from "../lib/loadSnap";
|
||||
import { SaveStatus } from "./savesnap";
|
||||
import { getAssetUrls } from "@tldraw/assets/selfHosted";
|
||||
import { memo } from "react";
|
||||
import DragContext from "./lib/context";
|
||||
import DragContext from "../lib/context";
|
||||
import DropZone from "./dropComponent";
|
||||
import "./canvas.css";
|
||||
|
||||
|
|
@ -1,7 +1,7 @@
|
|||
import React, { useRef, useCallback, useEffect, useContext } from "react";
|
||||
import { useEditor } from "tldraw";
|
||||
import DragContext, { DragContextType } from "./lib/context";
|
||||
import { handleExternalDroppedContent } from "./lib/createEmbeds";
|
||||
import DragContext, { DragContextType, useDragContext } from "../lib/context";
|
||||
import { handleExternalDroppedContent } from "../lib/createEmbeds";
|
||||
|
||||
const stripHtmlTags = (html: string): string => {
|
||||
const div = document.createElement("div");
|
||||
|
|
@ -33,17 +33,9 @@ function formatTextToRatio(text: string) {
|
|||
return lines.join("\n");
|
||||
}
|
||||
|
||||
const useDrag = (): DragContextType => {
|
||||
const context = useContext(DragContext);
|
||||
if (!context) {
|
||||
throw new Error("useCounter must be used within a CounterProvider");
|
||||
}
|
||||
return context;
|
||||
};
|
||||
|
||||
function DropZone() {
|
||||
const dropRef = useRef<HTMLDivElement | null>(null);
|
||||
const { isDraggingOver, setIsDraggingOver } = useDrag();
|
||||
const { isDraggingOver, setIsDraggingOver } = useDragContext();
|
||||
|
||||
const editor = useEditor();
|
||||
|
||||
22
packages/ui/components/canvas/components/enabledComp.tsx
Normal file
22
packages/ui/components/canvas/components/enabledComp.tsx
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
import { TLUiComponents } from "tldraw";
|
||||
|
||||
export const components: Partial<TLUiComponents> = {
|
||||
ActionsMenu: null,
|
||||
MainMenu: null,
|
||||
QuickActions: null,
|
||||
TopPanel: null,
|
||||
DebugPanel: null,
|
||||
DebugMenu: null,
|
||||
PageMenu: null,
|
||||
// Minimap: null,
|
||||
// ContextMenu: null,
|
||||
// HelpMenu: null,
|
||||
// ZoomMenu: null,
|
||||
// StylePanel: null,
|
||||
// NavigationPanel: null,
|
||||
// Toolbar: null,
|
||||
// KeyboardShortcutsDialog: null,
|
||||
// HelperButtons: null,
|
||||
// SharePanel: null,
|
||||
// MenuPanel: null,
|
||||
};
|
||||
|
|
@ -1,11 +1,4 @@
|
|||
import {
|
||||
BaseBoxShapeUtil,
|
||||
HTMLContainer,
|
||||
TLBaseBoxShape,
|
||||
TLBaseShape,
|
||||
useIsEditing,
|
||||
useValue,
|
||||
} from "tldraw";
|
||||
import { BaseBoxShapeUtil, HTMLContainer, TLBaseShape } from "tldraw";
|
||||
|
||||
type ITextCardShape = TLBaseShape<
|
||||
"Textcard",
|
||||
|
|
@ -25,37 +18,13 @@ export class textCardUtil extends BaseBoxShapeUtil<ITextCardShape> {
|
|||
}
|
||||
|
||||
component(s: ITextCardShape) {
|
||||
const isEditing = useIsEditing(s.id);
|
||||
const isHoveringWhileEditingSameShape = useValue(
|
||||
"is hovering",
|
||||
() => {
|
||||
const { editingShapeId, hoveredShapeId } =
|
||||
this.editor.getCurrentPageState();
|
||||
|
||||
if (editingShapeId && hoveredShapeId !== editingShapeId) {
|
||||
const editingShape = this.editor.getShape(editingShapeId);
|
||||
if (
|
||||
editingShape &&
|
||||
this.editor.isShapeOfType<TLBaseBoxShape>(editingShape, "embed")
|
||||
) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
},
|
||||
[],
|
||||
);
|
||||
|
||||
const isInteractive = isEditing || isHoveringWhileEditingSameShape;
|
||||
return (
|
||||
<HTMLContainer className="flex h-full w-full items-center justify-center">
|
||||
<div
|
||||
style={{
|
||||
height: s.props.h,
|
||||
width: s.props.w,
|
||||
pointerEvents: isInteractive ? "all" : "none",
|
||||
zIndex: isInteractive ? "" : "-1",
|
||||
pointerEvents: "all",
|
||||
background: "#2C3439",
|
||||
borderRadius: "16px",
|
||||
padding: "8px 14px",
|
||||
18
packages/ui/components/canvas/lib/context.ts
Normal file
18
packages/ui/components/canvas/lib/context.ts
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
import { createContext, useContext } from 'react';
|
||||
|
||||
export interface DragContextType {
|
||||
isDraggingOver: boolean;
|
||||
setIsDraggingOver: React.Dispatch<React.SetStateAction<boolean>>;
|
||||
}
|
||||
|
||||
const DragContext = createContext<DragContextType | undefined>(undefined);
|
||||
|
||||
export const useDragContext = () => {
|
||||
const context = useContext(DragContext);
|
||||
if (context === undefined) {
|
||||
throw new Error('useAppContext must be used within an AppProvider');
|
||||
}
|
||||
return context;
|
||||
};
|
||||
|
||||
export default DragContext;
|
||||
Loading…
Add table
Reference in a new issue