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