tangled
alpha
login
or
join now
margin.at
/
margin
87
fork
atom
Write on the margins of the internet. Powered by the AT Protocol.
margin.at
extension
web
atproto
comments
87
fork
atom
overview
issues
4
pulls
1
pipelines
add aturi.to to share dropdown (universal url)
scanash.com
1 month ago
30cc9e80
a8ece103
+44
-1
2 changed files
expand all
collapse all
unified
split
web
src
components
Icons.jsx
ShareMenu.jsx
+18
web/src/components/Icons.jsx
···
333
333
</svg>
334
334
);
335
335
}
336
336
+
337
337
+
export function AturiIcon({ size = 18 }) {
338
338
+
return (
339
339
+
<svg
340
340
+
width={size}
341
341
+
height={size}
342
342
+
viewBox="0 0 24 24"
343
343
+
fill="none"
344
344
+
stroke="currentColor"
345
345
+
strokeWidth="2"
346
346
+
strokeLinecap="round"
347
347
+
strokeLinejoin="round"
348
348
+
>
349
349
+
<path d="M11 20A7 7 0 0 1 9.8 6.1C15.5 5 17 4.48 19 2c1 2 2 4.18 2 8 0 5.5-4.78 10-10 10Z" />
350
350
+
<path d="M2 21c0-3 1.85-5.36 5.08-6C9.5 14.52 12 13 13 12" />
351
351
+
</svg>
352
352
+
);
353
353
+
}
+26
-1
web/src/components/ShareMenu.jsx
···
1
1
import { useState, useRef, useEffect } from "react";
2
2
import { Copy, ExternalLink, Check } from "lucide-react";
3
3
-
import { BlueskyIcon } from "./Icons";
3
3
+
import { BlueskyIcon, AturiIcon } from "./Icons";
4
4
5
5
const BLUESKY_COLOR = "#1185fe";
6
6
···
100
100
export default function ShareMenu({ uri, text, customUrl, handle, type }) {
101
101
const [isOpen, setIsOpen] = useState(false);
102
102
const [copied, setCopied] = useState(false);
103
103
+
const [copiedAturi, setCopiedAturi] = useState(false);
103
104
const menuRef = useRef(null);
104
105
105
106
const getShareUrl = () => {
···
163
164
}
164
165
};
165
166
167
167
+
const handleCopyAturi = async () => {
168
168
+
const aturiUrl = uri ? uri.replace("at://", "https://aturi.to/") : "";
169
169
+
if (!aturiUrl) return;
170
170
+
171
171
+
try {
172
172
+
await navigator.clipboard.writeText(aturiUrl);
173
173
+
setCopiedAturi(true);
174
174
+
setTimeout(() => {
175
175
+
setCopiedAturi(false);
176
176
+
setIsOpen(false);
177
177
+
}, 1500);
178
178
+
} catch {
179
179
+
prompt("Copy this link:", aturiUrl);
180
180
+
}
181
181
+
};
182
182
+
166
183
const handleSystemShare = async () => {
167
184
if (navigator.share) {
168
185
try {
···
224
241
<button className="share-menu-item" onClick={handleCopy}>
225
242
{copied ? <Check size={16} /> : <Copy size={16} />}
226
243
<span>{copied ? "Copied!" : "Copy Link"}</span>
244
244
+
</button>
245
245
+
<button
246
246
+
className="share-menu-item"
247
247
+
onClick={handleCopyAturi}
248
248
+
title="Copy a universal link atproto link (via aturi.to)"
249
249
+
>
250
250
+
{copiedAturi ? <Check size={16} /> : <AturiIcon size={16} />}
251
251
+
<span>{copiedAturi ? "Copied!" : "Copy Universal Link"}</span>
227
252
</button>
228
253
{navigator.share && (
229
254
<button className="share-menu-item" onClick={handleSystemShare}>