diff --git a/src/background.ts b/src/background.ts index 990a0e0b..c1462f3e 100644 --- a/src/background.ts +++ b/src/background.ts @@ -166,10 +166,6 @@ browser.runtime.onMessage.addListener((request: any, _sender: any, sendResponse: case 'DownloadTheme': DownloadTheme(request.body.theme); break; - - case 'StoreDownloadTheme': - StoreDownloadTheme(request.body); - break; case 'DeleteDownloadedTheme': DeleteDownloadedTheme(request.body); diff --git a/src/interface/components/LoadingSpinner.tsx b/src/interface/components/LoadingSpinner.tsx new file mode 100644 index 00000000..249415d8 --- /dev/null +++ b/src/interface/components/LoadingSpinner.tsx @@ -0,0 +1,8 @@ +const SpinnerIcon = ({ className }: { className: string }) => ( + + + + +); + +export default SpinnerIcon; \ No newline at end of file diff --git a/src/interface/pages/Store.tsx b/src/interface/pages/Store.tsx index e337e55a..cd786c02 100644 --- a/src/interface/pages/Store.tsx +++ b/src/interface/pages/Store.tsx @@ -9,6 +9,9 @@ import 'swiper/css'; import 'swiper/css/pagination'; import 'swiper/css/scrollbar'; import 'swiper/css/autoplay'; +import SpinnerIcon from '../components/LoadingSpinner'; +import localforage from 'localforage'; +import { StoreDownloadTheme } from '../../seqta/ui/themes/downloadTheme'; export type Theme = { name: string; @@ -22,12 +25,24 @@ type ThemesResponse = { themes: Theme[]; } +const DeleteDownloadedTheme = async (themeID: string) => { + console.log('DeleteDownloaded Theme:', themeID) + await localforage.removeItem(themeID); + + const availableThemesList = await localforage.getItem('availableThemes') as string[]; + const updatedThemesList = availableThemesList.filter(theme => theme !== themeID); + + await localforage.setItem('availableThemes', updatedThemesList); +} + const Store = () => { const [searchTerm, setSearchTerm] = useState(''); const swiperCover = useRef(null); const [gridThemes, setGridThemes] = useState([]); const [filteredThemes, setFilteredThemes] = useState([]); const [coverThemes, setCoverThemes] = useState([]); + const [installingThemes, setInstallingThemes] = useState([]); + const [currentThemes, setCurrentThemes] = useState([]); useEffect(() => { fetch(`https://raw.githubusercontent.com/BetterSEQTA/BetterSEQTA-Themes/main/store/themes.json?nocache=${(new Date()).getTime()}`, { cache: 'no-store' }) @@ -39,6 +54,11 @@ const Store = () => { setCoverThemes(shuffled.slice(0, 3)); }) .catch(error => console.error('Failed to fetch themes', error)); + + (async () => { + const availableThemes = await localforage.getItem('availableThemes') as string[]; + setCurrentThemes(availableThemes) + })(); }, []); useEffect(() => { @@ -54,9 +74,34 @@ const Store = () => { return }; - browser.runtime.sendMessage({ type: 'StoreDownloadTheme', body: { themeContent } }); + setInstallingThemes([...installingThemes, id]); + + StoreDownloadTheme({ themeContent }).then(() => { + setInstallingThemes(installingThemes.filter(theme => theme !== id)); + setCurrentThemes([...currentThemes, id]); + }); }; + const removeTheme = async (id: string) => { + const themeContent = gridThemes.find(theme => theme.id === id); + if (!themeContent) { + alert('There was an error, The theme was not found!') + return + }; + + setInstallingThemes([...installingThemes, id]); + + DeleteDownloadedTheme(id).then(() => { + setInstallingThemes(installingThemes.filter(theme => theme !== id)); + setCurrentThemes(currentThemes.filter(theme => theme !== id)); + }); + + /* browser.runtime.sendMessage({ type: 'StoreRemoveTheme', body: { themeContent } }).then(async () => { + await new Promise(resolve => setTimeout(resolve, 1000)); + setInstallingThemes(installingThemes.filter(theme => theme !== id)); + }); */ + } + return (
@@ -143,11 +188,31 @@ const Store = () => { Theme Preview
- + { + currentThemes.includes(theme.id) ? + : + + }