From 15cea9bc3d832c55408f80d3344aa0287b437583 Mon Sep 17 00:00:00 2001 From: alexsparkes Date: Fri, 14 Jun 2024 23:50:47 +0100 Subject: [PATCH] feat: cross-modal tab navigation --- .../Elements/MainModal/backend/TabContext.jsx | 34 ++++++--- .../CollectionCarousel/CollectionCarousel.jsx | 75 +++++++++++++++++++ .../Elements/CollectionCarousel/index.jsx | 1 + src/features/marketplace/views/Browse.jsx | 28 +++++-- 4 files changed, 121 insertions(+), 17 deletions(-) create mode 100644 src/features/marketplace/components/Elements/CollectionCarousel/CollectionCarousel.jsx create mode 100644 src/features/marketplace/components/Elements/CollectionCarousel/index.jsx diff --git a/src/components/Elements/MainModal/backend/TabContext.jsx b/src/components/Elements/MainModal/backend/TabContext.jsx index f18193c0..b558e069 100644 --- a/src/components/Elements/MainModal/backend/TabContext.jsx +++ b/src/components/Elements/MainModal/backend/TabContext.jsx @@ -9,35 +9,49 @@ export const useTab = () => { export const TabProvider = ({ children }) => { const [activeTab, setActiveTab] = useState('settings'); - const [subTab, setSubTab] = useState(variables.getMessage('modals.main.marketplace.product.overview')); + const [subTab, setSubTab] = useState( + variables.getMessage('modals.main.marketplace.product.overview'), + ); const [subSection, setSubSection] = useState(''); const [direction, setDirection] = useState(1); - const changeTab = (type) => { + const changeTab = (tab, subtab = '', section = '') => { const tabs = [ { id: 'settings', label: 'Settings' }, { id: 'addons', label: 'Addons' }, { id: 'marketplace', label: 'Marketplace' }, ]; - const currentIndex = tabs.findIndex((tab) => tab.id === activeTab); - const newIndex = tabs.findIndex((tab) => tab.id === type); + const currentIndex = tabs.findIndex((t) => t.id === activeTab); + const newIndex = tabs.findIndex((t) => t.id === tab); setDirection(newIndex > currentIndex ? 1 : -1); - setActiveTab(type); - if(type === 'settings') { + setSubTab(subtab); + if (tab === 'settings' && subtab === '' && section === '') { setSubTab(variables.getMessage('modals.main.marketplace.product.overview')); - } else { - setSubTab(''); } + + setActiveTab(tab); + setSubSection(section); }; const setSection = (type) => { setSubTab(type); - } + }; return ( - + {children} ); diff --git a/src/features/marketplace/components/Elements/CollectionCarousel/CollectionCarousel.jsx b/src/features/marketplace/components/Elements/CollectionCarousel/CollectionCarousel.jsx new file mode 100644 index 00000000..c1a6eff1 --- /dev/null +++ b/src/features/marketplace/components/Elements/CollectionCarousel/CollectionCarousel.jsx @@ -0,0 +1,75 @@ +import React, { useState, useEffect } from 'react'; +import { motion, AnimatePresence } from 'framer-motion'; +import { Button } from 'components/Elements'; +import { MdOutlineOpenInNew, MdOutlineArrowForward } from 'react-icons/md'; +import variables from 'config/variables'; + +const CollectionCarousel = ({ collections, collectionFunction }) => { + const [currentIndex, setCurrentIndex] = useState(0); + const [selectedCollections, setSelectedCollections] = useState([]); + + const getRandomCollections = (collections, count) => { + let shuffled = collections.sort(() => 0.5 - Math.random()); + return shuffled.slice(0, count); + }; + + useEffect(() => { + setSelectedCollections(getRandomCollections(collections, 3)); + }, [collections]); + + useEffect(() => { + const interval = setInterval(() => { + setCurrentIndex((prevIndex) => (prevIndex + 1) % selectedCollections.length); + }, 5000); + return () => clearInterval(interval); + }, [selectedCollections]); + + return ( +
+ + {selectedCollections.length > 0 && ( + +
+ {selectedCollections[currentIndex]?.display_name} + {selectedCollections[currentIndex]?.description} +
+ {selectedCollections[currentIndex]?.news === true ? ( + + {variables.getMessage('modals.main.marketplace.learn_more')} + + ) : ( +
+ ); +}; + +export { CollectionCarousel as default, CollectionCarousel }; diff --git a/src/features/marketplace/components/Elements/CollectionCarousel/index.jsx b/src/features/marketplace/components/Elements/CollectionCarousel/index.jsx new file mode 100644 index 00000000..c9384bf4 --- /dev/null +++ b/src/features/marketplace/components/Elements/CollectionCarousel/index.jsx @@ -0,0 +1 @@ +export * from './CollectionCarousel'; diff --git a/src/features/marketplace/views/Browse.jsx b/src/features/marketplace/views/Browse.jsx index 4c2b7f45..0065681d 100644 --- a/src/features/marketplace/views/Browse.jsx +++ b/src/features/marketplace/views/Browse.jsx @@ -12,6 +12,8 @@ import { Button } from 'components/Elements'; import { install } from 'utils/marketplace'; import { sortItems } from '../api'; +import { useTab } from 'components/Elements/MainModal/backend/TabContext'; + function Marketplace() { const [items, setItems] = useState([]); const [done, setDone] = useState(false); @@ -21,7 +23,8 @@ function Marketplace() { const [type, setType] = useState('all'); const [busy, setBusy] = useState(false); const [collectionTitle, setCollectionTitle] = useState(''); - + const { changeTab } = useTab(); + const controller = new AbortController(); async function toggle(pageType, data) { @@ -129,7 +132,6 @@ function Marketplace() { setDone(true); } - function returnToMain() { setCollection(false); } @@ -208,6 +210,16 @@ function Marketplace() { return ( <> +

+ changeTab( + 'settings', + variables.getMessage('modals.main.settings.sections.changelog.title'), + ) + } + > + See changelog +

{collection === true ? ( <>
{variables.getMessage('modals.main.marketplace.collection')}
- {collectionTitle} -=
+ {collectionTitle}={' '} +