A social knowledge tool for researchers built on ATProto

Merge branch 'development' of https://github.com/cosmik-network/semble into development

+120 -1
-1
.gitignore
··· 9 9 build 10 10 *storybook.log 11 11 storybook-static 12 - .vscode/settings.json
+3
.vscode/settings.json
··· 1 + { 2 + "jest.runMode": "on-demand" 3 + }
+117
src/webapp/app/bookmarklet/page.tsx
··· 1 + 'use client'; 2 + 3 + import { 4 + Container, 5 + Title, 6 + Text, 7 + Stack, 8 + Button, 9 + Code, 10 + Alert, 11 + Box, 12 + Group, 13 + } from '@mantine/core'; 14 + import { useState } from 'react'; 15 + import { BiInfoCircle } from 'react-icons/bi'; 16 + 17 + export default function BookmarkletPage() { 18 + const [copied, setCopied] = useState(false); 19 + 20 + const appUrl = process.env.NEXT_PUBLIC_APP_URL || 'http://127.0.0.1:4000'; 21 + 22 + const bookmarkletCode = `javascript:(function(){ 23 + const currentUrl = window.location.href; 24 + const sembleUrl = '${appUrl}/url?id=' + currentUrl; 25 + window.open(sembleUrl, '_blank'); 26 + })();`; 27 + 28 + const handleCopy = async () => { 29 + try { 30 + await navigator.clipboard.writeText(bookmarkletCode); 31 + setCopied(true); 32 + setTimeout(() => setCopied(false), 2000); 33 + } catch (err) { 34 + console.error('Failed to copy bookmarklet:', err); 35 + } 36 + }; 37 + 38 + // Create the bookmarklet link using dangerouslySetInnerHTML to bypass React's security check 39 + const createBookmarkletLink = () => { 40 + return { 41 + __html: `<a href="${bookmarkletCode}" style="text-decoration: none; padding: 8px 16px; background-color: var(--mantine-color-orange-6); color: white; border-radius: 4px; display: inline-flex; align-items: center; gap: 8px;"><svg width="16" height="16" viewBox="0 0 24 24" fill="currentColor"><path d="M17 3H7c-1.1 0-1.99.9-1.99 2L5 21l7-3 7 3V5c0-1.1-.9-2-2-2z"/></svg>Open in Semble</a>`, 42 + }; 43 + }; 44 + 45 + return ( 46 + <Container size="md" py="xl"> 47 + <Stack gap="xl"> 48 + <Stack gap="md"> 49 + <Title order={1}>Semble Bookmarklet</Title> 50 + <Text size="lg" c="dimmed"> 51 + Add this bookmarklet to your browser to quickly open any webpage in 52 + Semble. 53 + </Text> 54 + </Stack> 55 + 56 + <Alert icon={<BiInfoCircle />} title="How to install" color="orange"> 57 + <Stack gap="sm"> 58 + <Text> 59 + 1. Copy the bookmarklet code below or drag the button to your 60 + bookmarks bar 61 + </Text> 62 + <Text> 63 + 2. When you're on any webpage, click the bookmarklet to open it in 64 + Semble 65 + </Text> 66 + </Stack> 67 + </Alert> 68 + 69 + <Stack gap="md"> 70 + <Title order={2} size="h3"> 71 + Method 1: Drag to Bookmarks Bar 72 + </Title> 73 + <Text c="dimmed"> 74 + Drag this button directly to your browser's bookmarks bar: 75 + </Text> 76 + <Group> 77 + <Box dangerouslySetInnerHTML={createBookmarkletLink()} /> 78 + </Group> 79 + </Stack> 80 + 81 + <Stack gap="md"> 82 + <Title order={2} size="h3"> 83 + Method 2: Copy Code 84 + </Title> 85 + <Text c="dimmed"> 86 + Copy this code and create a new bookmark with it as the URL: 87 + </Text> 88 + <Box pos="relative"> 89 + <Code 90 + block 91 + p="md" 92 + style={{ 93 + wordBreak: 'break-all', 94 + whiteSpace: 'pre-wrap', 95 + fontSize: '12px', 96 + }} 97 + > 98 + {bookmarkletCode} 99 + </Code> 100 + <Button 101 + size="xs" 102 + variant="light" 103 + onClick={handleCopy} 104 + style={{ 105 + position: 'absolute', 106 + top: '8px', 107 + right: '8px', 108 + }} 109 + > 110 + {copied ? 'Copied!' : 'Copy'} 111 + </Button> 112 + </Box> 113 + </Stack> 114 + </Stack> 115 + </Container> 116 + ); 117 + }