From 11c152de293e68e278e63d13aa8c9595e4ba7aa0 Mon Sep 17 00:00:00 2001 From: P-man2976 Date: Thu, 26 Oct 2023 17:23:30 +0900 Subject: [PATCH] Settings page 5/5 (there is still something to do) --- .../src/components/topic/TopicPicker.tsx | 87 ++++++++++ packages/react/src/locales/en/ui.yml | 14 +- packages/react/src/routes/router.tsx | 10 ++ .../react/src/routes/settings/blocked.tsx | 8 + .../react/src/routes/settings/homepage.tsx | 160 ++++++++++++++++++ packages/react/src/routes/settings/lang.tsx | 4 +- packages/react/src/services/search.service.ts | 2 +- packages/react/src/store/settings.ts | 2 +- packages/react/src/types/search.d.ts | 7 + 9 files changed, 287 insertions(+), 7 deletions(-) create mode 100644 packages/react/src/components/topic/TopicPicker.tsx create mode 100644 packages/react/src/routes/settings/blocked.tsx create mode 100644 packages/react/src/routes/settings/homepage.tsx diff --git a/packages/react/src/components/topic/TopicPicker.tsx b/packages/react/src/components/topic/TopicPicker.tsx new file mode 100644 index 000000000..89a574ec1 --- /dev/null +++ b/packages/react/src/components/topic/TopicPicker.tsx @@ -0,0 +1,87 @@ +import { useState, useEffect } from "react"; +import { ChevronsUpDown } from "lucide-react"; +import { Button } from "@/shadcn/ui/button"; +import { + Command, + CommandEmpty, + CommandGroup, + CommandInput, + CommandItem, + CommandList, +} from "@/shadcn/ui/command"; +import { Popover, PopoverTrigger, PopoverContent } from "@/shadcn/ui/popover"; +import { useTranslation } from "react-i18next"; +import { useAtom, useAtomValue } from "jotai/react"; +import { useSearchAutoCompleteMutation } from "@/services/search.service"; +import atomWithDebounce from "@/lib/atomWithDebounce"; + +const { debouncedValueAtom, currentValueAtom } = atomWithDebounce("", 300); + +interface TopicPickerProps { + onSelect: (topicId: string) => void; +} + +export function TopicPicker({ onSelect }: TopicPickerProps) { + const [deboundcedValue, setDebouncedValue] = useAtom(debouncedValueAtom); + const currentValue = useAtomValue(currentValueAtom); + const { t } = useTranslation(); + const [open, setOpen] = useState(false); + + const { data, isPending, mutate } = useSearchAutoCompleteMutation(); + + useEffect(() => { + mutate({ + q: deboundcedValue, + t: "topic", + n: 10, + }); + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [deboundcedValue]); + + return ( + + + + + + + + + {t("component.topicPicker.notFound")} + + {data?.topic?.map(({ id }) => ( + { + onSelect(topicId); + setOpen(false); + }} + > + {id} + + ))} + {isPending && ( + +
+ + )} + + + + + + ); +} diff --git a/packages/react/src/locales/en/ui.yml b/packages/react/src/locales/en/ui.yml index a7980ca31..64a473121 100644 --- a/packages/react/src/locales/en/ui.yml +++ b/packages/react/src/locales/en/ui.yml @@ -212,6 +212,10 @@ component: pickDate: Pick a date... toast: copiedToClipboard: Copied to clipboard + topicPicker: + searchLabel: Search topics... + notFound: No topic found + pickLabel: Pick topics... views: channel: video: Videos @@ -323,9 +327,9 @@ views: gridSizeLabel: Thumbnail/Grid Size gridSizeMsg: Change thumbnail/video grid size on Home/Favorites page gridSize: - - Large - - Medium - - Small + - Grid + - List + - Dense List hideCollabStreamsLabel: Hide Collab Streams hideCollabStreamsMsg: Hide collab streams from your favorites feed hidePlaceholderStreams: Hide Placeholder Streams @@ -339,6 +343,10 @@ views: languageSearch: Search language... languageNotfound: No language found userNotLinked: Not linked + defaultHomepage: + lastVisitedOrgHome: Last Visited Org Home + favoritesWhenLoggedIn: Favorites (When Logged In) + hideFeaturesLabel: Hide Features app: update_available: An update is available update_btn: Update diff --git a/packages/react/src/routes/router.tsx b/packages/react/src/routes/router.tsx index 474167cee..3a975fca1 100644 --- a/packages/react/src/routes/router.tsx +++ b/packages/react/src/routes/router.tsx @@ -11,6 +11,8 @@ const Settings = React.lazy(() => import("./settings")); const SettingsLang = React.lazy(() => import("./settings/lang")); const SettingsTheme = React.lazy(() => import("./settings/theme")); const SettingsUser = React.lazy(() => import("./settings/user")); +const SettingsHomepage = React.lazy(() => import("./settings/homepage")); +const SettingsBlocked = React.lazy(() => import("./settings/blocked")); const About = React.lazy(() => import("./about")); const AboutGeneral = React.lazy(() => import("./about/general")); const AboutChangelog = React.lazy(() => import("./about/changelog")); @@ -97,6 +99,14 @@ const router = createBrowserRouter([ path: "user", element: , }, + { + path: "homepage", + element: , + }, + { + path: "blocked", + element: , + }, // Add children routes similar to above pattern ], }, diff --git a/packages/react/src/routes/settings/blocked.tsx b/packages/react/src/routes/settings/blocked.tsx new file mode 100644 index 000000000..c320ade9b --- /dev/null +++ b/packages/react/src/routes/settings/blocked.tsx @@ -0,0 +1,8 @@ +import { blockedChannelsAtom } from "@/store/settings"; +import { useAtom } from "jotai"; + +export default function SettingsBlocked() { + const [blockedChannels, setBlockedChannels] = useAtom(blockedChannelsAtom); + + return
; +} diff --git a/packages/react/src/routes/settings/homepage.tsx b/packages/react/src/routes/settings/homepage.tsx new file mode 100644 index 000000000..ddd883d8a --- /dev/null +++ b/packages/react/src/routes/settings/homepage.tsx @@ -0,0 +1,160 @@ +import { SettingsItem } from "@/components/settings/SettingsItem"; +import { TopicPicker } from "@/components/topic/TopicPicker"; +import { cn } from "@/lib/utils"; +import { Badge } from "@/shadcn/ui/badge"; +import { Label } from "@/shadcn/ui/label"; +import { RadioGroup, RadioGroupItem } from "@/shadcn/ui/radio-group"; +import { Switch } from "@/shadcn/ui/switch"; +import { + defaultOpenAtom, + hideCollabStreamsAtom, + hidePlaceholderAtom, + hideThumbnailAtom, + homeViewModeAtom, + ignoredTopicsAtom, +} from "@/store/settings"; +import { useAtom } from "jotai"; +import { useTranslation } from "react-i18next"; + +export default function SettingsHomepage() { + const { t } = useTranslation(); + const [defaultOpen, setDefaultOpen] = useAtom(defaultOpenAtom); + const [homeViewMode, setHomeViewMode] = useAtom(homeViewModeAtom); + const [ignoredTopics, setIgnoredTopics] = useAtom(ignoredTopicsAtom); + const [hideThumbnail, setHideThumbnail] = useAtom(hideThumbnailAtom); + const [hideCollab, setHideCollab] = useAtom(hideCollabStreamsAtom); + const [hidePlaceholder, setHidePlaceholder] = useAtom(hidePlaceholderAtom); + + const defaultPages = [ + { + value: "Home", + label: t("views.settings.defaultHomepage.lastVisitedOrgHome"), + }, + { + value: "Favorites", + label: t("views.settings.defaultHomepage.favoritesWhenLoggedIn"), + }, + ]; + + const gridSizes = [ + { + value: "grid", + label: t("views.settings.gridSize.0"), + }, + { + value: "list", + label: t("views.settings.gridSize.1"), + }, + { + value: "denseList", + label: t("views.settings.gridSize.2"), + }, + ]; + + const hideFeatures = [ + { + label: t("views.settings.hideVideoThumbnailsLabel"), + value: hideThumbnail, + onChange: () => setHideThumbnail(!hideThumbnail), + }, + { + label: t("views.settings.hideCollabStreamsLabel"), + value: hideCollab, + onChange: () => setHideCollab(!hideCollab), + }, + { + label: t("views.settings.hidePlaceholderStreams"), + value: hidePlaceholder, + onChange: () => setHidePlaceholder(!hidePlaceholder), + }, + ]; + + return ( +
+ + setDefaultOpen(val)} + > + {defaultPages.map(({ label, value }, index) => ( + + ))} + + + + + setHomeViewMode(val) + } + > + {gridSizes.map(({ label, value }) => ( + + ))} + + + +
+ + setIgnoredTopics((currentTopics) => [...currentTopics, topic]) + } + /> +
+ {ignoredTopics.map((topic) => ( + + setIgnoredTopics((currentTopics) => + currentTopics.filter((t) => t !== topic), + ) + } + > + {topic} +
+ + ))} +
+
+ + +
+ {hideFeatures.map(({ label, value, onChange }, index) => ( + + ))} +
+
+
+ ); +} diff --git a/packages/react/src/routes/settings/lang.tsx b/packages/react/src/routes/settings/lang.tsx index f1d2246f6..985ef232b 100644 --- a/packages/react/src/routes/settings/lang.tsx +++ b/packages/react/src/routes/settings/lang.tsx @@ -92,11 +92,11 @@ export default function SettingsLang() {
-
+
{TL_LANGS.map(({ text, value }, index) => (