Skip to content

Commit

Permalink
Merge branch 'next' of github:HolodexNet/Holodex into next
Browse files Browse the repository at this point in the history
  • Loading branch information
P-man2976 committed Oct 23, 2023
2 parents 57e1edb + fb8baee commit 371651e
Show file tree
Hide file tree
Showing 22 changed files with 1,602 additions and 796 deletions.
3 changes: 2 additions & 1 deletion packages/react/.eslintrc.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ module.exports = {
"plugin:tailwindcss/recommended",
"prettier",
],
plugins: ["react-refresh"],
plugins: ["react-refresh", "prettier"],
settings: {
tailwindcss: {
whitelist: [
Expand All @@ -29,6 +29,7 @@ module.exports = {
},

rules: {
"prettier/prettier": 2, // Means error
"react-refresh/only-export-components": [
"warn",
{ allowConstantExport: true },
Expand Down
1,251 changes: 578 additions & 673 deletions packages/react/package-lock.json

Large diffs are not rendered by default.

30 changes: 15 additions & 15 deletions packages/react/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,8 @@
"@radix-ui/react-tabs": "^1.0.4",
"@radix-ui/react-toast": "^1.1.5",
"@react-oauth/google": "^0.11.1",
"@tanstack/react-query": "^4.36.1",
"@tanstack/react-query-devtools": "^4.36.1",
"@tanstack/react-query": "^5.0.0",
"@tanstack/react-query-devtools": "^5.0.3",
"axios": "^1.5.1",
"class-variance-authority": "^0.7.0",
"classnames": "^2.3.2",
Expand All @@ -43,7 +43,7 @@
"css-vars-hook": "^0.6.18",
"date-fns": "^2.30.0",
"dayjs": "^1.11.10",
"i18next": "^23.5.1",
"i18next": "^23.6.0",
"i18next-browser-languagedetector": "^7.1.0",
"i18next-chained-backend": "^4.5.0",
"i18next-http-backend": "^2.2.2",
Expand All @@ -58,35 +58,35 @@
"react-error-boundary": "^4.0.11",
"react-grid-layout": "^1.4.2",
"react-helmet-async": "^1.3.0",
"react-hook-form": "^7.47.0",
"react-i18next": "^13.2.2",
"react-player": "^2.13.0",
"react-router-dom": "^6.16.0",
"react-router-dom": "^6.17.0",
"react-use": "^17.4.0",
"react-virtuoso": "^4.6.1",
"react-virtuoso": "^4.6.2",
"tailwind-merge": "^1.14.0",
"tailwindcss-animate": "^1.0.7",
"use-seconds": "^1.7.0",
"usehooks-ts": "^2.9.1",
"zod": "^3.22.4"
},
"devDependencies": {
"@iconify/json": "^2.2.126",
"@iconify/json": "^2.2.131",
"@rollup/plugin-dynamic-import-vars": "^2.0.7",
"@rollup/plugin-yaml": "^4.1.2",
"@swc-jotai/debug-label": "^0.1.0",
"@types/react": "^18.2.24",
"@types/react-dom": "^18.2.8",
"@typescript-eslint/eslint-plugin": "^6.7.3",
"@typescript-eslint/parser": "^6.7.3",
"@types/react": "^18.2.31",
"@types/react-dom": "^18.2.14",
"@typescript-eslint/eslint-plugin": "^6.8.0",
"@typescript-eslint/parser": "^6.8.0",
"@unocss/eslint-config": "^0.56.5",
"@vitejs/plugin-react": "^4.1.0",
"@vitejs/plugin-react-swc": "^3.4.0",
"autoprefixer": "^10.4.16",
"browserslist": "^4.22.1",
"cross-env": "^7.0.3",
"eslint": "^8.51.0",
"eslint": "^8.52.0",
"eslint-config-prettier": "^9.0.0",
"eslint-plugin-prettier": "^5.0.1",
"eslint-plugin-react-hooks": "^4.6.0",
"eslint-plugin-react-refresh": "^0.4.3",
"eslint-plugin-tailwindcss": "3.13.0",
Expand All @@ -97,12 +97,12 @@
"prettier": "^3.0.3",
"react-git-info": "^2.0.1",
"rollup-plugin-bundle-analyzer": "^1.6.6",
"sass": "^1.69.1",
"sass": "^1.69.4",
"tailwindcss": "^3.3.3",
"typescript": "^5.2.2",
"typescript-plugin-css-modules": "^5.0.1",
"typescript-plugin-css-modules": "^5.0.2",
"unocss": "^0.56.5",
"unocss-preset-autoprefixer": "^0.0.6",
"vite": "^4.4.9"
"vite": "^4.5.0"
}
}
15 changes: 11 additions & 4 deletions packages/react/src/components/channel/ChannelCard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,20 +18,27 @@ export function ChannelCard({
top_topics,
twitter,
twitch,
inactive,
}: ChannelCardProps) {
const { t } = useTranslation();
const { mutate, isLoading: mutateLoading } = useFavoriteMutation();
const { mutate, isPending: mutateLoading } = useFavoriteMutation();
const { data } = useFavorites();
const isInFavorite = useMemo(
() => data?.some((channel) => id === channel.id),
[data],
[data, id],
);

return (
// Set min-height because react-virtuoso will break if the height is not fixed
<div className="flex h-full min-h-[24rem] w-full flex-col items-center gap-2 rounded-md bg-base-3 p-4">
<img className="h-24 w-24 rounded-full" src={photo ?? ""} />
<div className="line-clamp-2 text-center text-lg font-bold">{name}</div>
<img
className="-z-0 -mb-36 mt-4 h-32 w-32 rounded-full opacity-20 blur-2xl saturate-150"
src={photo ?? ""}
/>
<img className="z-10 h-24 w-24 rounded-full" src={photo ?? ""} />
<div className="z-10 line-clamp-2 text-center text-lg font-bold">
{name}
</div>
<div className="flex flex-col items-center">
<div className="whitespace-nowrap text-sm text-base-11">
{t("component.channelInfo.subscriberCount", {
Expand Down
6 changes: 5 additions & 1 deletion packages/react/src/components/common/Loading.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { cn } from "@/lib/utils";
import { Loader2 } from "lucide-react";
import { DetailedHTMLProps, HTMLAttributes } from "react";

interface LoadingProps {
Expand All @@ -16,6 +17,9 @@ export function Loading(
"text-4xl": props.size === "xl",
});

// I can't use a UNOCSS icon here because it doesn't work in Firefox...
// shows a weird white border around the icon
// https://bugzilla.mozilla.org/show_bug.cgi?id=1671784 wow it's fixed on firefox NEXT version...
return (
<div
{...props}
Expand All @@ -24,7 +28,7 @@ export function Loading(
props.className,
)}
>
<div className={cn("i-lucide:loader-2 animate-spin", sizeCN)} />
<Loader2 className="animate-spin" />
</div>
);
}
Expand Down
4 changes: 2 additions & 2 deletions packages/react/src/components/header/header.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import { toggleSidebarAtom } from "@/hooks/useFrame";
import { darkAtom } from "@/hooks/useTheme";
import { Button } from "@/shadcn/ui/button";
import { Input } from "@/shadcn/ui/input";
import { userAtom } from "@/store/auth";
import { useAtom, useAtomValue } from "jotai";
import { useSetAtom } from "jotai/react";
import { useTranslation } from "react-i18next";
import { Link } from "react-router-dom";
import { SearchBar } from "./searchbar/SearchBar";

interface HeaderProps
extends React.DetailedHTMLProps<
Expand All @@ -33,7 +33,7 @@ export function Header({ id }: HeaderProps) {
<div className="i-heroicons:bars-3 rounded-md p-3" />
</Button>
<div className="flex grow" />
<Input type="search" placeholder="Search" className="max-w-lg" />
<SearchBar className="max-w-lg" />
<Button
size="icon"
variant="ghost"
Expand Down
118 changes: 118 additions & 0 deletions packages/react/src/components/header/searchbar/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
## search bar design doc:

Basically it's a multi-select with validation and autocomplete given typed information.

```js
watch(search, (newValue) => {
// reflect value back to input
for (const _key of ["has_song", "type", "lang", "other"] as const)
ac_opts[_key] = [];
// clear ^
const [search_class, search_term] = splitSearchClassTerms(
newValue,
langCategoryReversemapClass.value
);
console.log(search_class, search_term);

if (search_class === "org" || search_class === undefined) {
const lower_search_term = search_term.toLowerCase();
ac_opts.org =
orgs.data.value
?.filter(
(x) =>
x.name.toLowerCase().includes(lower_search_term) ||
x.name_jp?.toLowerCase().includes(lower_search_term)
)
?.slice(0, search_class === "org" ? 20 : 5) // only give 5 suggestions when searching broadly.
?.map((x) => ({
type: "org",
value: x.name,
text: langPrefs.preferredLocaleFn(x.name, x.name_jp) || x.name,
})) || [];
} else {
ac_opts.org = []; // clear
}

if (search_class === undefined) {
const categoryAutofill = FIRST_SEARCH.filter((x) =>
t(`search.class.${x.type}`, x.type).startsWith(search_term)
);

const ok = JSON_SCHEMA.search.suggestionOK?.(query.value);
ac_opts.other = ok
? [
{
type: "search",
value: search_term,
text: "?",
replace: ok === "replace",
},
...categoryAutofill,
]
: categoryAutofill;
return;
}

// everything else only gets autocompleted when needed:
switch (search_class) {
case "has_song":
const ok = JSON_SCHEMA.has_song.suggestionOK?.(query.value);
if (ok) {
ac_opts.has_song = [
{
type: "has_song",
value: "none",
text: "$t",
replace: ok === "replace",
},
{
type: "has_song",
value: "non-zero",
text: "$t",
replace: ok === "replace",
},
{
type: "has_song",
value: "one",
text: "$t",
replace: ok === "replace",
},
{
type: "has_song",
value: "many",
text: "$t",
replace: ok === "replace",
},
];
}
return;
case "lang":
ac_opts.lang = CLIPPER_LANGS.map((x) => ({ ...x, type: "lang" }));
return;
case "type":
ac_opts.type = [
{ type: "type", value: "clip", text: "$t" },
{ type: "type", value: "stream", text: "$t" },
{ type: "type", value: "placeholder", text: "$t" },
];
return;
case "org":
case "topic":
case "vtuber":
return;
default:
const ok2 = JSON_SCHEMA[search_class].suggestionOK?.(query.value);
if (ok2 ?? true) {
ac_opts.other = [
{
type: search_class,
value: search_term,
text: "?",
replace: ok2 === "replace",
},
];
}
}
})

```
Loading

0 comments on commit 371651e

Please sign in to comment.