diff --git a/app/Http/Controllers/LinkController.php b/app/Http/Controllers/LinkController.php index e5095d866..1468da7e0 100644 --- a/app/Http/Controllers/LinkController.php +++ b/app/Http/Controllers/LinkController.php @@ -11,6 +11,8 @@ use App\Queries\LinkCommitsQuery; use App\Queries\TopLinksQuery; use Illuminate\Container\Attributes\CurrentUser; +use Illuminate\Http\RedirectResponse; +use Illuminate\Support\Str; use Illuminate\Pagination\CursorPaginator; use Inertia\Inertia; use Inertia\Response; @@ -20,10 +22,32 @@ */ final readonly class LinkController { + public function lookup(ListLinksRequest $request): RedirectResponse + { + $url = $request->link(); + + if ($url === null) { + return to_route('link.index'); + } + + $token = Str::random(24); + $lookups = $request->session()->get('link_lookups', []); + $lookups[$token] = $url; + $request->session()->put('link_lookups', array_slice($lookups, -10, null, true)); + + return to_route('link.index', ['lookup' => $token]); + } + public function index(ListLinksRequest $request, #[CurrentUser] User $user, LinkCommitsQuery $commits, TopLinksQuery $topLinks): Response { $url = $request->link(); + if ($url === null && $request->filled('lookup')) { + $token = $request->string('lookup')->value(); + $url = $request->session()->get('link_lookups.'.$token); + abort_unless(is_string($url), 404); + } + if ($url === null) { return Inertia::render('links/index', [ 'url' => null, diff --git a/app/Http/Requests/ListLinksRequest.php b/app/Http/Requests/ListLinksRequest.php index df2b2cfd6..7a9e3ad0c 100644 --- a/app/Http/Requests/ListLinksRequest.php +++ b/app/Http/Requests/ListLinksRequest.php @@ -21,6 +21,7 @@ public function rules(): array { return [ 'url' => ['nullable', 'string', 'max:'.Urls::MAX_LENGTH], + 'lookup' => ['sometimes', 'string', 'regex:/^[A-Za-z0-9]{24}$/'], ]; } diff --git a/resources/js/pages/links/index.tsx b/resources/js/pages/links/index.tsx index a5f5f17c5..617074619 100644 --- a/resources/js/pages/links/index.tsx +++ b/resources/js/pages/links/index.tsx @@ -42,13 +42,35 @@ function peopleCount(count: number) { return count === 1 ? '1 person' : `${count} people`; } +function linkVisit(url: string) { + const destination = LinkController.index({ + query: url === '' ? {} : { url }, + }).url; + + if (destination.length > 1_800) { + return { + href: LinkController.lookup().url, + method: 'post' as const, + data: { url }, + preserveState: false, + }; + } + + return { href: destination, method: 'get' as const, data: {} }; +} + export default function Index(props: Props) { const [draft, setDraft] = useState(props.url ?? ''); const submit = (event: FormEvent) => { event.preventDefault(); - const url = draft.trim(); - router.get(LinkController.index({ query: url === '' ? {} : { url } })); + const visit = linkVisit(draft.trim()); + + if (visit.method === 'post') { + router.post(visit.href, visit.data, { preserveState: false }); + } else { + router.get(visit.href); + } }; return ( @@ -109,10 +131,8 @@ function TopLinks({ links }: { links: TopLink[] }) { {links.map((link, index) => (