Skip to content

Commit

Permalink
feat: use forms for resource tags to allow wget -r to not run forever (
Browse files Browse the repository at this point in the history
  • Loading branch information
jacob-ebey authored Apr 4, 2024
1 parent 107b271 commit 2870467
Show file tree
Hide file tree
Showing 4 changed files with 57 additions and 60 deletions.
5 changes: 2 additions & 3 deletions app/routes/_extras.resources.$slug.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import {
import { useLoaderData } from "@remix-run/react";
import invariant from "tiny-invariant";
import { getResource } from "~/lib/resources.server";
import { InitCodeblock, ResourceTag, useCreateTagUrl } from "~/ui/resources";
import { InitCodeblock, ResourceTag } from "~/ui/resources";
import { octokit } from "~/lib/github.server";
import "~/styles/docs.css";
import iconsHref from "~/icons.svg";
Expand Down Expand Up @@ -80,7 +80,6 @@ export default function ResourcePage() {
tags,
readmeHtml,
} = resource;
let createTagUrl = useCreateTagUrl();

return (
<main className="flex flex-1 flex-col items-center px-8 lg:container">
Expand Down Expand Up @@ -136,7 +135,7 @@ export default function ResourcePage() {
<InitCodeblock initCommand={initCommand} />
<div className="flex w-full max-w-full flex-wrap gap-x-2 gap-y-2">
{tags.map((tag) => (
<ResourceTag key={tag} to={createTagUrl({ add: tag })}>
<ResourceTag key={tag} value={tag}>
{tag}
</ResourceTag>
))}
Expand Down
9 changes: 2 additions & 7 deletions app/routes/_extras.resources._index/route.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import {
type MetaFunction,
} from "@remix-run/node";
import { useLoaderData } from "@remix-run/react";
import { ResourceTag, useCreateTagUrl } from "~/ui/resources";
import { ResourceTag } from "~/ui/resources";
import { getResourcesForRequest } from "./data.server";
import { CACHE_CONTROL } from "~/lib/http.server";
import {
Expand Down Expand Up @@ -54,7 +54,6 @@ export const meta: MetaFunction<typeof loader> = (args) => {
export default function Resources() {
let { featuredResource, selectedCategory, selectedTags, resources } =
useLoaderData<typeof loader>();
let createTagUrl = useCreateTagUrl();

return (
<main className="container flex flex-1 flex-col items-center md:mt-8">
Expand All @@ -74,11 +73,7 @@ export default function Resources() {
</h1>
<div className="mt-2 flex w-full max-w-full flex-wrap gap-x-2 gap-y-2 lg:mt-2">
{selectedTags.map((tag) => (
<ResourceTag
key={tag}
to={createTagUrl({ remove: tag })}
selected
>
<ResourceTag key={tag} value={tag} selected>
{tag}
</ResourceTag>
))}
Expand Down
12 changes: 3 additions & 9 deletions app/routes/_extras.resources._index/ui.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import type { Category, Resource } from "~/lib/resources.server";
import { InitCodeblock, ResourceTag, useCreateTagUrl } from "~/ui/resources";
import { InitCodeblock, ResourceTag } from "~/ui/resources";
import { Link, useSearchParams } from "@remix-run/react";
import cx from "clsx";
import iconsHref from "~/icons.svg";
Expand All @@ -22,7 +22,6 @@ export function FeaturedResourcePoster({
sponsorUrl,
tags,
} = featuredResource;
let createTagUrl = useCreateTagUrl();

return (
<>
Expand All @@ -47,7 +46,7 @@ export function FeaturedResourcePoster({
</p>
<div className="mt-4 flex w-full max-w-full flex-wrap gap-x-2 gap-y-2">
{tags.map((tag) => (
<ResourceTag key={tag} to={createTagUrl({ add: tag })}>
<ResourceTag key={tag} value={tag}>
{tag}
</ResourceTag>
))}
Expand Down Expand Up @@ -113,7 +112,6 @@ export function ResourceCards({
selectedCategory,
selectedTags,
}: ResourceCardsProps) {
let createTagUrl = useCreateTagUrl();
let selectedTagsSet = new Set(selectedTags);

if (resources.length > 0) {
Expand All @@ -132,11 +130,7 @@ export function ResourceCards({
{tags.map((tag) => (
<ResourceTag
key={tag}
to={
selectedTagsSet.has(tag)
? createTagUrl({ remove: tag })
: createTagUrl({ add: tag })
}
value={tag}
selected={selectedTagsSet.has(tag)}
>
{tag}
Expand Down
91 changes: 50 additions & 41 deletions app/ui/resources.tsx
Original file line number Diff line number Diff line change
@@ -1,58 +1,67 @@
import { useEffect, useState } from "react";
import { Fragment, useEffect, useMemo, useState } from "react";
import { type Resource } from "~/lib/resources.server";
import { Link, useSearchParams } from "@remix-run/react";
import { Form, useSearchParams } from "@remix-run/react";
import cx from "clsx";
import iconsHref from "~/icons.svg";

import "~/styles/resources.css";

export function useCreateTagUrl() {
let [searchParams] = useSearchParams();

return ({ add, remove }: { add?: string; remove?: string }) => {
let newSearchParams = new URLSearchParams(searchParams);

if (add) {
newSearchParams.append("tag", add);
}
if (remove) {
newSearchParams.delete("tag", remove);
}

return `/resources?${newSearchParams}`;
};
}

type ResourceTagProps = {
to: string;
selected?: boolean;
value: string;
children: React.ReactNode;
selected?: boolean;
};

export function ResourceTag({
to,
selected = false,
value,
children,
selected: _selected,
}: ResourceTagProps) {
let [searchParams] = useSearchParams();

let selected = _selected ?? searchParams.has("tag", value);

let hiddenInputs = useMemo(() => {
const seenTags = new Set<string>([value]);
return [
...[...searchParams.entries()].map(([param, paramValue], key) => {
let seen =
param === "tag" && (seenTags.has(paramValue) || paramValue === value);
seenTags.add(paramValue);
if (seen) {
return <Fragment key={key} />;
}
return (
<input key={key} type="hidden" name={param} value={paramValue} />
);
}),
];
}, [searchParams, value]);

return (
<Link
to={to}
className={cx(
"inline-flex items-center rounded-md px-2 py-1 text-xs font-medium leading-none ring-1 ring-inset",
selected
? "bg-blue-100 ring-blue-500/10 hover:bg-blue-200 dark:bg-gray-300 dark:text-gray-900 dark:ring-gray-900/50 dark:hover:bg-gray-400 dark:hover:text-gray-900"
: "bg-gray-50 text-gray-600 ring-gray-500/10 hover:bg-blue-100 dark:bg-gray-900 dark:text-gray-300 dark:ring-gray-200/50 dark:hover:bg-gray-400 dark:hover:text-gray-900",
)}
>
<span className="sr-only">{selected ? "remove" : "add"}</span>
{children}
<span className="sr-only">tag</span>
{selected ? (
<svg aria-hidden className="-mr-1 h-3.5 w-3.5" viewBox="0 0 14 14">
<use href={`${iconsHref}#x-mark`} />
</svg>
) : null}
</Link>
<Form action="/resources" className="inline-flex">
{hiddenInputs}
<button
type="submit"
className={cx(
"inline-flex items-center rounded-md px-2 py-1 text-xs font-medium leading-none ring-1 ring-inset",
selected
? "bg-blue-100 ring-blue-500/10 hover:bg-blue-200 dark:bg-gray-300 dark:text-gray-900 dark:ring-gray-900/50 dark:hover:bg-gray-400 dark:hover:text-gray-900"
: "bg-gray-50 text-gray-600 ring-gray-500/10 hover:bg-blue-100 dark:bg-gray-900 dark:text-gray-300 dark:ring-gray-200/50 dark:hover:bg-gray-400 dark:hover:text-gray-900",
)}
name={selected ? undefined : "tag"}
value={selected ? undefined : value}
>
<span className="sr-only">{selected ? "remove" : "add"}</span>
{children}
<span className="sr-only">tag</span>
{selected ? (
<svg aria-hidden className="-mr-1 h-3.5 w-3.5" viewBox="0 0 14 14">
<use href={`${iconsHref}#x-mark`} />
</svg>
) : null}
</button>
</Form>
);
}

Expand Down

0 comments on commit 2870467

Please sign in to comment.