feat: add url shortner
This commit is contained in:
@@ -1,9 +1,10 @@
|
||||
"use client";
|
||||
|
||||
import { useEffect, useRef } from "react";
|
||||
import { useEffect, useRef, useState } from "react";
|
||||
import { createPortal } from "react-dom";
|
||||
import { useCopyFeedback, type Position } from "./shared";
|
||||
import { Bookmark, FolderPlus, AtSign } from "lucide-react";
|
||||
import { buildShortHighlightUrl } from "@/lib/text-highlight";
|
||||
import { Bookmark, FolderPlus, AtSign, Link2, Check } from "lucide-react";
|
||||
import {
|
||||
Drawer,
|
||||
DrawerClose,
|
||||
@@ -33,6 +34,18 @@ export function MorePopover({
|
||||
}) {
|
||||
const ref = useRef<HTMLDivElement>(null);
|
||||
const { copied, copy } = useCopyFeedback();
|
||||
const [generatingLink, setGeneratingLink] = useState(false);
|
||||
|
||||
async function handleCopyLink() {
|
||||
if (generatingLink) return;
|
||||
setGeneratingLink(true);
|
||||
try {
|
||||
const url = await buildShortHighlightUrl(selectedText);
|
||||
await copy(url);
|
||||
} finally {
|
||||
setGeneratingLink(false);
|
||||
}
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
if (!open || isMobile) return;
|
||||
@@ -67,6 +80,17 @@ export function MorePopover({
|
||||
icon: <FolderPlus className="size-5" />,
|
||||
onClick: onSaveToCollection,
|
||||
},
|
||||
{
|
||||
key: "copy-link",
|
||||
label: copied
|
||||
? "Link Copied!"
|
||||
: generatingLink
|
||||
? "Generating link…"
|
||||
: "Copy Link",
|
||||
description: "Copy a shareable link to this quote",
|
||||
icon: copied ? <Check className="size-5" /> : <Link2 className="size-5" />,
|
||||
onClick: handleCopyLink,
|
||||
},
|
||||
{
|
||||
key: "mention",
|
||||
label: "Mention",
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
"use client";
|
||||
|
||||
import { useState } from "react";
|
||||
import { useCopyFeedback } from "./shared";
|
||||
import { buildHighlightUrl } from "@/lib/text-highlight";
|
||||
import { buildShortHighlightUrl } from "@/lib/text-highlight";
|
||||
import { createPortal } from "react-dom";
|
||||
import { X, MessageSquare, ExternalLink } from "lucide-react";
|
||||
import {
|
||||
@@ -24,6 +25,18 @@ export function ShareModal({
|
||||
isMobile: boolean;
|
||||
}) {
|
||||
const { copied, copy } = useCopyFeedback();
|
||||
const [generating, setGenerating] = useState(false);
|
||||
|
||||
async function handleCopyShareLink() {
|
||||
if (generating) return;
|
||||
setGenerating(true);
|
||||
try {
|
||||
const url = await buildShortHighlightUrl(selectedText);
|
||||
await copy(url);
|
||||
} finally {
|
||||
setGenerating(false);
|
||||
}
|
||||
}
|
||||
|
||||
const shareOptions = [
|
||||
{
|
||||
@@ -41,12 +54,17 @@ export function ShareModal({
|
||||
label: "Share Link",
|
||||
icon: <ExternalLink className="size-4" />,
|
||||
description: "Copy a shareable link",
|
||||
onClick: () => {
|
||||
copy(buildHighlightUrl(selectedText));
|
||||
},
|
||||
onClick: handleCopyShareLink,
|
||||
},
|
||||
];
|
||||
|
||||
function linkLabel(optKey: string, optLabel: string) {
|
||||
if (optKey !== "link") return optLabel;
|
||||
if (copied) return "Link Copied!";
|
||||
if (generating) return "Generating link…";
|
||||
return optLabel;
|
||||
}
|
||||
|
||||
if (isMobile) {
|
||||
return (
|
||||
<Drawer open={open} onOpenChange={(o) => !o && onClose()}>
|
||||
@@ -72,7 +90,7 @@ export function ShareModal({
|
||||
</div>
|
||||
<div>
|
||||
<p className="text-sm font-medium text-white/90">
|
||||
{opt.key === "link" && copied ? "Link Copied!" : opt.label}
|
||||
{linkLabel(opt.key, opt.label)}
|
||||
</p>
|
||||
<p className="text-xs text-white/50">{opt.description}</p>
|
||||
</div>
|
||||
@@ -130,7 +148,7 @@ export function ShareModal({
|
||||
</div>
|
||||
<div>
|
||||
<p className="text-sm font-medium text-white/90">
|
||||
{opt.key === "link" && copied ? "Link Copied!" : opt.label}
|
||||
{linkLabel(opt.key, opt.label)}
|
||||
</p>
|
||||
<p className="text-xs text-white/50">{opt.description}</p>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user