- Looks like there was a problem saving.
- Report the issue
- here
- .
+
+ {message ?? 'Conflict: please refresh to get latest changes'}
;
}
-});
+
+ if(status === 412) {
+ return
+ Oops!
+
+ {message ?? 'Your client is out of date. Please save your changes elsewhere and refresh.'}
+
+ ;
+ }
+
+ if(HBErrorCode === '04') {
+ return
+ Oops!
+
+ You are no longer signed in as an author of
+ this brew! Were you signed out from a different
+ window? Visit our log in page, then try again!
+
+
+
+ Sign In
+
+
+
+ Not Now
+
+
+ ;
+ }
+
+ if(response?.body?.errors?.[0].reason == 'storageQuotaExceeded') {
+ return
+ Oops!
+
+ Can't save because your Google Drive seems to be full!
+
+ ;
+ }
+
+ if(response?.req.url.match(/^\/api.*Google.*$/m)){
+ return
+ Oops!
+
+ Looks like your Google credentials have
+ expired! Visit our log in page to sign out
+ and sign back in with Google,
+ then try saving again!
+
+
+
+ Sign In
+
+
+
+ Not Now
+
+
+ ;
+ }
+
+ if(HBErrorCode === '09') {
+ return
+ Oops!
+
+ Looks like there was a problem retreiving
+ the theme, or a theme that it inherits,
+ for this brew. Verify that brew
+ {response.body.brewId} still exists!
+
+ ;
+ }
+
+ if(HBErrorCode === '10') {
+ return
+ Oops!
+
+ Looks like the brew you have selected
+ as a theme is not tagged for use as a
+ theme. Verify that
+ brew
+ {response.body.brewId} has the
meta:theme tag!
+
+ ;
+ }
+
+ if(errorCode === 'ECONNABORTED') {
+ return
+ Oops!
+
+ The request to the server was interrupted or timed out.
+ This can happen due to a network issue, or if
+ trying to save a particularly large brew.
+ Please check your internet connection and try again.
+
+ ;
+ }
+
+ return
+ Oops!
+
+ Looks like there was a problem saving.
+ Report the issue
+ here
+ .
+
+ ;
+};
module.exports = ErrorNavItem;
diff --git a/client/homebrew/navbar/newbrew.navitem.jsx b/client/homebrew/navbar/newbrew.navitem.jsx
index 30d53c675..ccade4e8b 100644
--- a/client/homebrew/navbar/newbrew.navitem.jsx
+++ b/client/homebrew/navbar/newbrew.navitem.jsx
@@ -5,33 +5,45 @@ const { splitTextStyleAndMetadata } = require('../../../shared/helpers.js'); //
const BREWKEY = 'homebrewery-new';
const STYLEKEY = 'homebrewery-new-style';
-const METAKEY = 'homebrewery-new-meta';
+const METAKEY = 'homebrewery-new-meta';
const NewBrew = ()=>{
const handleFileChange = (e)=>{
const file = e.target.files[0];
- if(file) {
- const reader = new FileReader();
- reader.onload = (e)=>{
- const fileContent = e.target.result;
- const newBrew = {
- text : fileContent,
- style : ''
- };
- if(fileContent.startsWith('```metadata')) {
- splitTextStyleAndMetadata(newBrew); // Modify newBrew directly
- localStorage.setItem(BREWKEY, newBrew.text);
- localStorage.setItem(STYLEKEY, newBrew.style);
- localStorage.setItem(METAKEY, JSON.stringify(_.pick(newBrew, ['title', 'description', 'tags', 'systems', 'renderer', 'theme', 'lang'])));
- window.location.href = '/new';
- } else {
- alert('This file is invalid, please, enter a valid file');
- }
- };
- reader.readAsText(file);
- }
+ if(!file) return;
+
+ const currentNew = localStorage.getItem(BREWKEY);
+ if(currentNew && !confirm(
+ `You have some text in the new brew space, if you load a file that text will be lost, are you sure you want to load the file?`
+ )) return;
+
+ const reader = new FileReader();
+ reader.onload = (e)=>{
+ const fileContent = e.target.result;
+ const newBrew = { text: fileContent, style: '' };
+
+ if(fileContent.startsWith('```metadata')) {
+ splitTextStyleAndMetadata(newBrew);
+ localStorage.setItem(BREWKEY, newBrew.text);
+ localStorage.setItem(STYLEKEY, newBrew.style);
+ localStorage.setItem(METAKEY, JSON.stringify(
+ _.pick(newBrew, ['title', 'description', 'tags', 'systems', 'renderer', 'theme', 'lang'])
+ ));
+ window.location.href = '/new';
+ return;
+ }
+
+ const type = file.name.split('.').pop().toLowerCase();
+
+ alert(`This file is invalid: ${!type ? "Missing file extension" :`.${type} files are not supported`}. Only .txt files exported from the Homebrewery are allowed.`);
+
+
+ console.log(file);
+ };
+ reader.readAsText(file);
};
+
return (
{this.setState({ error: err })}, (theme)=>{this.setState({ themeBundle: theme })}, this.props.brew.renderer, this.props.brew.theme);
document.addEventListener('keydown', this.handleControlKeys);
},
@@ -173,7 +173,7 @@ const EditPage = createClass({
handleMetaChange : function(metadata, field=undefined){
if(field == 'theme' || field == 'renderer') // Fetch theme bundle only if theme or renderer was changed
- fetchThemeBundle(this, metadata.renderer, metadata.theme);
+ fetchThemeBundle((err)=>{this.setState({ error: err })}, (theme)=>{this.setState({ themeBundle: theme })}, metadata.renderer, metadata.theme);
this.setState((prevState)=>({
brew : {
@@ -438,6 +438,13 @@ const EditPage = createClass({
return `https://www.reddit.com/r/UnearthedArcana/submit?title=${encodeURIComponent(title.toWellFormed())}&text=${encodeURIComponent(text)}`;
},
+ clearError : function(){
+ setState({
+ error : null,
+ isSaving : false
+ })
+ },
+
renderNavbar : function(){
const shareLink = this.processShareId();
@@ -449,7 +456,7 @@ const EditPage = createClass({
{this.renderGoogleDriveIcon()}
{this.state.error ?
- :
+ :
{this.renderSaveButton()}
{this.renderAutoSaveButton()}
diff --git a/client/homebrew/pages/homePage/homePage.jsx b/client/homebrew/pages/homePage/homePage.jsx
index d03e30c91..84967b1ff 100644
--- a/client/homebrew/pages/homePage/homePage.jsx
+++ b/client/homebrew/pages/homePage/homePage.jsx
@@ -1,90 +1,91 @@
-require('./homePage.less');
-const React = require('react');
-const createClass = require('create-react-class');
-const cx = require('classnames');
-import request from '../../utils/request-middleware.js';
-const { Meta } = require('vitreum/headtags');
+import './homePage.less';
-const Nav = require('naturalcrit/nav/nav.jsx');
-const Navbar = require('../../navbar/navbar.jsx');
-const NewBrewItem = require('../../navbar/newbrew.navitem.jsx');
-const HelpNavItem = require('../../navbar/help.navitem.jsx');
-const VaultNavItem = require('../../navbar/vault.navitem.jsx');
-const RecentNavItem = require('../../navbar/recent.navitem.jsx').both;
-const AccountNavItem = require('../../navbar/account.navitem.jsx');
-const ErrorNavItem = require('../../navbar/error-navitem.jsx');
-const { fetchThemeBundle } = require('../../../../shared/helpers.js');
+import React from 'react';
+import { useEffect, useState, useRef } from 'react';
+import request from '../../utils/request-middleware.js';
+import { Meta } from 'vitreum/headtags';
-const SplitPane = require('naturalcrit/splitPane/splitPane.jsx');
-const Editor = require('../../editor/editor.jsx');
-const BrewRenderer = require('../../brewRenderer/brewRenderer.jsx');
+import Nav from 'naturalcrit/nav/nav.jsx';
+import Navbar from '../../navbar/navbar.jsx';
+import NewBrewItem from '../../navbar/newbrew.navitem.jsx';
+import HelpNavItem from '../../navbar/help.navitem.jsx';
+import VaultNavItem from '../../navbar/vault.navitem.jsx';
+import { both as RecentNavItem } from '../../navbar/recent.navitem.jsx';
+import AccountNavItem from '../../navbar/account.navitem.jsx';
+import ErrorNavItem from '../../navbar/error-navitem.jsx';
+import { fetchThemeBundle } from '../../../../shared/helpers.js';
-const { DEFAULT_BREW } = require('../../../../server/brewDefaults.js');
+import SplitPane from 'client/components/splitPane/splitPane.jsx';
+import Editor from '../../editor/editor.jsx';
+import BrewRenderer from '../../brewRenderer/brewRenderer.jsx';
-const HomePage = createClass({
- displayName : 'HomePage',
- getDefaultProps : function() {
- return {
- brew : DEFAULT_BREW,
- ver : '0.0.0'
- };
- },
- getInitialState : function() {
- return {
- brew : this.props.brew,
- welcomeText : this.props.brew.text,
- error : undefined,
- currentEditorViewPageNum : 1,
- currentEditorCursorPageNum : 1,
- currentBrewRendererPageNum : 1,
- themeBundle : {}
- };
- },
+import { DEFAULT_BREW } from '../../../../server/brewDefaults.js';
- editor : React.createRef(null),
+const HomePage =(props)=>{
+ props = {
+ brew : DEFAULT_BREW,
+ ver : '0.0.0',
+ ...props
+ };
- componentDidMount : function() {
- fetchThemeBundle(this, this.props.brew.renderer, this.props.brew.theme);
- },
+ const [brew , setBrew] = useState(props.brew);
+ const [welcomeText , setWelcomeText] = useState(props.brew.text);
+ const [error , setError] = useState(undefined);
+ const [currentEditorViewPageNum , setCurrentEditorViewPageNum] = useState(1);
+ const [currentEditorCursorPageNum, setCurrentEditorCursorPageNum] = useState(1);
+ const [currentBrewRendererPageNum, setCurrentBrewRendererPageNum] = useState(1);
+ const [themeBundle , setThemeBundle] = useState({});
+ const [isSaving , setIsSaving] = useState(false);
- handleSave : function(){
+ const editorRef = useRef(null);
+
+ useEffect(()=>{
+ fetchThemeBundle(setError, setThemeBundle, brew.renderer, brew.theme);
+ }, []);
+
+ const save = ()=>{
request.post('/api')
- .send(this.state.brew)
+ .send(brew)
.end((err, res)=>{
if(err) {
- this.setState({ error: err });
+ setError(err);
return;
}
- const brew = res.body;
- window.location = `/edit/${brew.editId}`;
+ const saved = res.body;
+ window.location = `/edit/${saved.editId}`;
});
- },
- handleSplitMove : function(){
- this.editor.current.update();
- },
+ };
- handleEditorViewPageChange : function(pageNumber){
- this.setState({ currentEditorViewPageNum: pageNumber });
- },
+ const handleSplitMove = ()=>{
+ editorRef.current.update();
+ };
- handleEditorCursorPageChange : function(pageNumber){
- this.setState({ currentEditorCursorPageNum: pageNumber });
- },
+ const handleEditorViewPageChange = (pageNumber)=>{
+ setCurrentEditorViewPageNum(pageNumber);
+ };
+
+ const handleEditorCursorPageChange = (pageNumber)=>{
+ setCurrentEditorCursorPageNum(pageNumber);
+ };
+
+ const handleBrewRendererPageChange = (pageNumber)=>{
+ setCurrentBrewRendererPageNum(pageNumber);
+ };
- handleBrewRendererPageChange : function(pageNumber){
- this.setState({ currentBrewRendererPageNum: pageNumber });
- },
+ const handleTextChange = (text)=>{
+ setBrew((prevBrew) => ({ ...prevBrew, text }));
+ };
- handleTextChange : function(text){
- this.setState((prevState)=>({
- brew : { ...prevState.brew, text: text },
- }));
- },
- renderNavbar : function(){
- return
+ const clearError = ()=>{
+ setError(null);
+ setIsSaving(false);
+ };
+
+ const renderNavbar = ()=>{
+ return
- {this.state.error ?
- :
+ {error ?
+ :
null
}
@@ -94,48 +95,48 @@ const HomePage = createClass({
;
- },
+ };
- render : function(){
- return
+ return (
+
- {this.renderNavbar()}
+ {renderNavbar()}
-
+
-
;
- }
-});
+
+ )
+};
module.exports = HomePage;
diff --git a/client/homebrew/pages/newPage/newPage.jsx b/client/homebrew/pages/newPage/newPage.jsx
index 64fac86c0..c24128a93 100644
--- a/client/homebrew/pages/newPage/newPage.jsx
+++ b/client/homebrew/pages/newPage/newPage.jsx
@@ -14,7 +14,7 @@ const ErrorNavItem = require('../../navbar/error-navitem.jsx');
const RecentNavItem = require('../../navbar/recent.navitem.jsx').both;
const HelpNavItem = require('../../navbar/help.navitem.jsx');
-const SplitPane = require('naturalcrit/splitPane/splitPane.jsx');
+const SplitPane = require('client/components/splitPane/splitPane.jsx');
const Editor = require('../../editor/editor.jsx');
const BrewRenderer = require('../../brewRenderer/brewRenderer.jsx');
@@ -80,7 +80,7 @@ const NewPage = createClass({
saveGoogle : (saveStorage == 'GOOGLE-DRIVE' && this.state.saveGoogle)
});
- fetchThemeBundle(this, this.props.brew.renderer, this.props.brew.theme);
+ fetchThemeBundle((err)=>{this.setState({ error: err })}, (theme)=>{this.setState({ themeBundle: theme })}, this.props.brew.renderer, this.props.brew.theme);
localStorage.setItem(BREWKEY, brew.text);
if(brew.style)
@@ -154,7 +154,7 @@ const NewPage = createClass({
handleMetaChange : function(metadata, field=undefined){
if(field == 'theme' || field == 'renderer') // Fetch theme bundle only if theme or renderer was changed
- fetchThemeBundle(this, metadata.renderer, metadata.theme);
+ fetchThemeBundle((err)=>{this.setState({ error: err })}, (theme)=>{this.setState({ themeBundle: theme })}, metadata.renderer, metadata.theme);
this.setState((prevState)=>({
brew : { ...prevState.brew, ...metadata },
@@ -211,6 +211,13 @@ const NewPage = createClass({
}
},
+ clearError : function(){
+ setState({
+ error : null,
+ isSaving : false
+ })
+ },
+
renderNavbar : function(){
return
@@ -220,7 +227,7 @@ const NewPage = createClass({
{this.state.error ?
- :
+ :
this.renderSaveButton()
}
diff --git a/client/homebrew/pages/sharePage/sharePage.jsx b/client/homebrew/pages/sharePage/sharePage.jsx
index e9c5540a2..50104a665 100644
--- a/client/homebrew/pages/sharePage/sharePage.jsx
+++ b/client/homebrew/pages/sharePage/sharePage.jsx
@@ -17,15 +17,11 @@ const { printCurrentBrew, fetchThemeBundle } = require('../../../../shared/helpe
const SharePage = (props)=>{
const { brew = DEFAULT_BREW_LOAD, disableMeta = false } = props;
- const [state, setState] = useState({
- themeBundle : {},
- currentBrewRendererPageNum : 1,
- });
+ const [themeBundle, setThemeBundle] = useState({});
+ const [currentBrewRendererPageNum, setCurrentBrewRendererPageNum] = useState(1);
const handleBrewRendererPageChange = useCallback((pageNumber)=>{
- setState((prevState)=>({
- currentBrewRendererPageNum : pageNumber,
- ...prevState }));
+ setCurrentBrewRendererPageNum(pageNumber);
}, []);
const handleControlKeys = (e)=>{
@@ -40,11 +36,7 @@ const SharePage = (props)=>{
useEffect(()=>{
document.addEventListener('keydown', handleControlKeys);
- fetchThemeBundle(
- { setState },
- brew.renderer,
- brew.theme
- );
+ fetchThemeBundle(undefined, setThemeBundle, brew.renderer, brew.theme);
return ()=>{
document.removeEventListener('keydown', handleControlKeys);
@@ -114,9 +106,9 @@ const SharePage = (props)=>{
lang={brew.lang}
renderer={brew.renderer}
theme={brew.theme}
- themeBundle={state.themeBundle}
+ themeBundle={themeBundle}
onPageChange={handleBrewRendererPageChange}
- currentBrewRendererPageNum={state.currentBrewRendererPageNum}
+ currentBrewRendererPageNum={currentBrewRendererPageNum}
allowPrint={true}
/>
diff --git a/client/homebrew/pages/userPage/userPage.jsx b/client/homebrew/pages/userPage/userPage.jsx
index f6fae639d..e4a8b0b4e 100644
--- a/client/homebrew/pages/userPage/userPage.jsx
+++ b/client/homebrew/pages/userPage/userPage.jsx
@@ -39,10 +39,14 @@ const UserPage = (props)=>{
}] : [])
];
+ const clearError = ()=>{
+ setError(null);
+ };
+
const navItems = (
- {error && ()}
+ {error && ()}
diff --git a/client/homebrew/pages/vaultPage/vaultPage.jsx b/client/homebrew/pages/vaultPage/vaultPage.jsx
index f979aa4f7..e098bb1a2 100644
--- a/client/homebrew/pages/vaultPage/vaultPage.jsx
+++ b/client/homebrew/pages/vaultPage/vaultPage.jsx
@@ -12,7 +12,7 @@ const Account = require('../../navbar/account.navitem.jsx');
const NewBrew = require('../../navbar/newbrew.navitem.jsx');
const HelpNavItem = require('../../navbar/help.navitem.jsx');
const BrewItem = require('../basePages/listPage/brewItem/brewItem.jsx');
-const SplitPane = require('../../../../shared/naturalcrit/splitPane/splitPane.jsx');
+const SplitPane = require('client/components/splitPane/splitPane.jsx');
const ErrorIndex = require('../errorPage/errors/errorIndex.js');
import request from '../../utils/request-middleware.js';
diff --git a/client/homebrew/utils/request-middleware.spec.js b/client/homebrew/utils/request-middleware.spec.js
new file mode 100644
index 000000000..d7c198394
--- /dev/null
+++ b/client/homebrew/utils/request-middleware.spec.js
@@ -0,0 +1,74 @@
+import requestMiddleware from './request-middleware';
+
+jest.mock('superagent');
+import request from 'superagent';
+
+describe('request-middleware', ()=>{
+ let version;
+
+ let setFn;
+ let testFn;
+
+ beforeEach(()=>{
+ jest.resetAllMocks();
+ version = global.version;
+
+ global.version = '999';
+
+ setFn = jest.fn();
+ testFn = jest.fn(()=>{ return { set: setFn }; });
+ });
+
+ afterEach(()=>{
+ global.version = version;
+ });
+
+ it('should add header to get', ()=>{
+ // Ensure tests functions have been reset
+ expect(testFn).not.toHaveBeenCalled();
+ expect(setFn).not.toHaveBeenCalled();
+
+ request.get = testFn;
+
+ requestMiddleware.get('path');
+
+ expect(testFn).toHaveBeenCalledWith('path');
+ expect(setFn).toHaveBeenCalledWith('Homebrewery-Version', '999');
+ });
+
+ it('should add header to put', ()=>{
+ expect(testFn).not.toHaveBeenCalled();
+ expect(setFn).not.toHaveBeenCalled();
+
+ request.put = testFn;
+
+ requestMiddleware.put('path');
+
+ expect(testFn).toHaveBeenCalledWith('path');
+ expect(setFn).toHaveBeenCalledWith('Homebrewery-Version', '999');
+ });
+
+ it('should add header to post', ()=>{
+ expect(testFn).not.toHaveBeenCalled();
+ expect(setFn).not.toHaveBeenCalled();
+
+ request.post = testFn;
+
+ requestMiddleware.post('path');
+
+ expect(testFn).toHaveBeenCalledWith('path');
+ expect(setFn).toHaveBeenCalledWith('Homebrewery-Version', '999');
+ });
+
+ it('should add header to delete', ()=>{
+ expect(testFn).not.toHaveBeenCalled();
+ expect(setFn).not.toHaveBeenCalled();
+
+ request.delete = testFn;
+
+ requestMiddleware.delete('path');
+
+ expect(testFn).toHaveBeenCalledWith('path');
+ expect(setFn).toHaveBeenCalledWith('Homebrewery-Version', '999');
+ });
+});
diff --git a/package-lock.json b/package-lock.json
index eb82b0f40..430fb6778 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -63,9 +63,9 @@
"written-number": "^0.11.1"
},
"devDependencies": {
- "@stylistic/stylelint-plugin": "^3.1.3",
+ "@stylistic/stylelint-plugin": "^4.0.0",
"babel-plugin-transform-import-meta": "^2.3.3",
- "eslint": "^9.31.0",
+ "eslint": "^9.34.0",
"eslint-plugin-jest": "^29.0.1",
"eslint-plugin-react": "^7.37.5",
"globals": "^16.3.0",
@@ -73,9 +73,9 @@
"jest-expect-message": "^1.1.3",
"jsdom-global": "^3.0.2",
"postcss-less": "^6.0.0",
- "stylelint": "^16.22.0",
- "stylelint-config-recess-order": "^7.1.0",
- "stylelint-config-recommended": "^16.0.0",
+ "stylelint": "^16.23.1",
+ "stylelint-config-recess-order": "^7.2.0",
+ "stylelint-config-recommended": "^17.0.0",
"supertest": "^7.1.4"
},
"engines": {
@@ -1884,9 +1884,9 @@
}
},
"node_modules/@csstools/media-query-list-parser": {
- "version": "3.0.1",
- "resolved": "https://registry.npmjs.org/@csstools/media-query-list-parser/-/media-query-list-parser-3.0.1.tgz",
- "integrity": "sha512-HNo8gGD02kHmcbX6PvCoUuOQvn4szyB9ca63vZHKX5A81QytgDG4oxG4IaEfHTlEZSZ6MjPEMWIVU+zF2PZcgw==",
+ "version": "4.0.3",
+ "resolved": "https://registry.npmjs.org/@csstools/media-query-list-parser/-/media-query-list-parser-4.0.3.tgz",
+ "integrity": "sha512-HAYH7d3TLRHDOUQK4mZKf9k9Ph/m8Akstg66ywKR4SFAigjs3yBiUeZtFxywiTm5moZMAp/5W/ZuFnNXXYLuuQ==",
"dev": true,
"funding": [
{
@@ -1898,12 +1898,13 @@
"url": "https://opencollective.com/csstools"
}
],
+ "license": "MIT",
"engines": {
"node": ">=18"
},
"peerDependencies": {
- "@csstools/css-parser-algorithms": "^3.0.1",
- "@csstools/css-tokenizer": "^3.0.1"
+ "@csstools/css-parser-algorithms": "^3.0.5",
+ "@csstools/css-tokenizer": "^3.0.4"
}
},
"node_modules/@dmsnell/diff-match-patch": {
@@ -2021,18 +2022,19 @@
}
},
"node_modules/@eslint/config-helpers": {
- "version": "0.3.0",
- "resolved": "https://registry.npmjs.org/@eslint/config-helpers/-/config-helpers-0.3.0.tgz",
- "integrity": "sha512-ViuymvFmcJi04qdZeDc2whTHryouGcDlaxPqarTD0ZE10ISpxGUVZGZDx4w01upyIynL3iu6IXH2bS1NhclQMw==",
+ "version": "0.3.1",
+ "resolved": "https://registry.npmjs.org/@eslint/config-helpers/-/config-helpers-0.3.1.tgz",
+ "integrity": "sha512-xR93k9WhrDYpXHORXpxVL5oHj3Era7wo6k/Wd8/IsQNnZUTzkGS29lyn3nAT05v6ltUuTFVCCYDEGfy2Or/sPA==",
"dev": true,
+ "license": "Apache-2.0",
"engines": {
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
}
},
"node_modules/@eslint/core": {
- "version": "0.14.0",
- "resolved": "https://registry.npmjs.org/@eslint/core/-/core-0.14.0.tgz",
- "integrity": "sha512-qIbV0/JZr7iSDjqAc60IqbLdsj9GDt16xQtWD+B78d/HAlvysGdZZ6rpJHGAc2T0FQx1X6thsSPdnoiGKdNtdg==",
+ "version": "0.15.2",
+ "resolved": "https://registry.npmjs.org/@eslint/core/-/core-0.15.2.tgz",
+ "integrity": "sha512-78Md3/Rrxh83gCxoUc0EiciuOHsIITzLy53m3d9UyiW8y9Dj2D29FeETqyKA+BRK76tnTp6RXWb3pCay8Oyomg==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
@@ -2080,9 +2082,9 @@
}
},
"node_modules/@eslint/js": {
- "version": "9.31.0",
- "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.31.0.tgz",
- "integrity": "sha512-LOm5OVt7D4qiKCqoiPbA7LWmI+tbw1VbTUowBcUMgQSuM6poJufkFkYDcQpo5KfgD39TnNySV26QjOh7VFpSyw==",
+ "version": "9.34.0",
+ "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.34.0.tgz",
+ "integrity": "sha512-EoyvqQnBNsV1CWaEJ559rxXL4c8V92gxirbawSmVUOWXlsRxxQXl6LmCpdUblgxgSkDIqKnhzba2SjRTI/A5Rw==",
"dev": true,
"license": "MIT",
"engines": {
@@ -2102,13 +2104,13 @@
}
},
"node_modules/@eslint/plugin-kit": {
- "version": "0.3.1",
- "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.3.1.tgz",
- "integrity": "sha512-0J+zgWxHN+xXONWIyPWKFMgVuJoZuGiIFu8yxk7RJjxkzpGmyja5wRFqZIVtjDVOQpV+Rw0iOAjYPE2eQyjr0w==",
+ "version": "0.3.5",
+ "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.3.5.tgz",
+ "integrity": "sha512-Z5kJ+wU3oA7MMIqVR9tyZRtjYPr4OC004Q4Rw7pgOKUOKkJfZ3O24nz3WYfGRpMDNmcOi3TwQOmgm7B7Tpii0w==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
- "@eslint/core": "^0.14.0",
+ "@eslint/core": "^0.15.2",
"levn": "^0.4.1"
},
"engines": {
@@ -2832,37 +2834,11 @@
}
},
"node_modules/@keyv/serialize": {
- "version": "1.0.3",
- "resolved": "https://registry.npmjs.org/@keyv/serialize/-/serialize-1.0.3.tgz",
- "integrity": "sha512-qnEovoOp5Np2JDGonIDL6Ayihw0RhnRh6vxPuHo4RDn1UOzwEo4AeIfpL6UGIrsceWrCMiVPgwRjbHu4vYFc3g==",
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/@keyv/serialize/-/serialize-1.1.0.tgz",
+ "integrity": "sha512-RlDgexML7Z63Q8BSaqhXdCYNBy/JQnqYIwxofUrNLGCblOMHp+xux2Q8nLMLlPpgHQPoU0Do8Z6btCpRBEqZ8g==",
"dev": true,
- "dependencies": {
- "buffer": "^6.0.3"
- }
- },
- "node_modules/@keyv/serialize/node_modules/buffer": {
- "version": "6.0.3",
- "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz",
- "integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==",
- "dev": true,
- "funding": [
- {
- "type": "github",
- "url": "https://github.com/sponsors/feross"
- },
- {
- "type": "patreon",
- "url": "https://www.patreon.com/feross"
- },
- {
- "type": "consulting",
- "url": "https://feross.org/support"
- }
- ],
- "dependencies": {
- "base64-js": "^1.3.1",
- "ieee754": "^1.2.1"
- }
+ "license": "MIT"
},
"node_modules/@mongodb-js/saslprep": {
"version": "1.3.0",
@@ -3005,17 +2981,17 @@
}
},
"node_modules/@stylistic/stylelint-plugin": {
- "version": "3.1.3",
- "resolved": "https://registry.npmjs.org/@stylistic/stylelint-plugin/-/stylelint-plugin-3.1.3.tgz",
- "integrity": "sha512-85fsmzgsIVmyG3/GFrjuYj6Cz8rAM7IZiPiXCMiSMfoDOC1lOrzrXPDk24WqviAghnPqGpx8b0caK2PuewWGFg==",
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/@stylistic/stylelint-plugin/-/stylelint-plugin-4.0.0.tgz",
+ "integrity": "sha512-CFwt3K4Y/7bygNCLCQ8Sy4Hzgbhxq3BsNW0FIuYxl17HD3ywptm54ocyeiLVRrk5jtz1Zwks7Xr9eiZt8SWHAw==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "@csstools/css-parser-algorithms": "^3.0.1",
- "@csstools/css-tokenizer": "^3.0.1",
- "@csstools/media-query-list-parser": "^3.0.1",
- "is-plain-object": "^5.0.0",
- "postcss": "^8.4.41",
- "postcss-selector-parser": "^6.1.2",
+ "@csstools/css-parser-algorithms": "^3.0.5",
+ "@csstools/css-tokenizer": "^3.0.4",
+ "@csstools/media-query-list-parser": "^4.0.3",
+ "postcss": "^8.5.6",
+ "postcss-selector-parser": "^7.1.0",
"postcss-value-parser": "^4.2.0",
"style-search": "^0.1.0"
},
@@ -3023,7 +2999,7 @@
"node": "^18.12 || >=20.9"
},
"peerDependencies": {
- "stylelint": "^16.8.0"
+ "stylelint": "^16.22.0"
}
},
"node_modules/@tybys/wasm-util": {
@@ -4675,22 +4651,24 @@
}
},
"node_modules/cacheable": {
- "version": "1.10.1",
- "resolved": "https://registry.npmjs.org/cacheable/-/cacheable-1.10.1.tgz",
- "integrity": "sha512-Fa2BZY0CS9F0PFc/6aVA6tgpOdw+hmv9dkZOlHXII5v5Hw+meJBIWDcPrG9q/dXxGcNbym5t77fzmawrBQfTmQ==",
+ "version": "1.10.3",
+ "resolved": "https://registry.npmjs.org/cacheable/-/cacheable-1.10.3.tgz",
+ "integrity": "sha512-M6p10iJ/VT0wT7TLIGUnm958oVrU2cUK8pQAVU21Zu7h8rbk/PeRtRWrvHJBql97Bhzk3g1N6+2VKC+Rjxna9Q==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"hookified": "^1.10.0",
- "keyv": "^5.3.4"
+ "keyv": "^5.4.0"
}
},
"node_modules/cacheable/node_modules/keyv": {
- "version": "5.3.4",
- "resolved": "https://registry.npmjs.org/keyv/-/keyv-5.3.4.tgz",
- "integrity": "sha512-ypEvQvInNpUe+u+w8BIcPkQvEqXquyyibWE/1NB5T2BTzIpS5cGEV1LZskDzPSTvNAaT4+5FutvzlvnkxOSKlw==",
+ "version": "5.5.0",
+ "resolved": "https://registry.npmjs.org/keyv/-/keyv-5.5.0.tgz",
+ "integrity": "sha512-QG7qR2tijh1ftOvClut4YKKg1iW6cx3GZsKoGyJPxHkGWK9oJhG9P3j5deP0QQOGDowBMVQFaP+Vm4NpGYvmIQ==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "@keyv/serialize": "^1.0.3"
+ "@keyv/serialize": "^1.1.0"
}
},
"node_modules/cached-path-relative": {
@@ -4885,13 +4863,16 @@
}
},
"node_modules/cipher-base": {
- "version": "1.0.4",
- "resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.4.tgz",
- "integrity": "sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q==",
+ "version": "1.0.6",
+ "resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.6.tgz",
+ "integrity": "sha512-3Ek9H3X6pj5TgenXYtNWdaBon1tgYCaebd+XPg0keyjEbEfkD4KkmAxkQ/i1vYvxdcT5nscLBfq9VJRmCBcFSw==",
"license": "MIT",
"dependencies": {
- "inherits": "^2.0.1",
- "safe-buffer": "^5.0.1"
+ "inherits": "^2.0.4",
+ "safe-buffer": "^5.2.1"
+ },
+ "engines": {
+ "node": ">= 0.10"
}
},
"node_modules/cjs-module-lexer": {
@@ -6080,20 +6061,20 @@
}
},
"node_modules/eslint": {
- "version": "9.31.0",
- "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.31.0.tgz",
- "integrity": "sha512-QldCVh/ztyKJJZLr4jXNUByx3gR+TDYZCRXEktiZoUR3PGy4qCmSbkxcIle8GEwGpb5JBZazlaJ/CxLidXdEbQ==",
+ "version": "9.34.0",
+ "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.34.0.tgz",
+ "integrity": "sha512-RNCHRX5EwdrESy3Jc9o8ie8Bog+PeYvvSR8sDGoZxNFTvZ4dlxUB3WzQ3bQMztFrSRODGrLLj8g6OFuGY/aiQg==",
"dev": true,
"license": "MIT",
"dependencies": {
"@eslint-community/eslint-utils": "^4.2.0",
"@eslint-community/regexpp": "^4.12.1",
"@eslint/config-array": "^0.21.0",
- "@eslint/config-helpers": "^0.3.0",
- "@eslint/core": "^0.15.0",
+ "@eslint/config-helpers": "^0.3.1",
+ "@eslint/core": "^0.15.2",
"@eslint/eslintrc": "^3.3.1",
- "@eslint/js": "9.31.0",
- "@eslint/plugin-kit": "^0.3.1",
+ "@eslint/js": "9.34.0",
+ "@eslint/plugin-kit": "^0.3.5",
"@humanfs/node": "^0.16.6",
"@humanwhocodes/module-importer": "^1.0.1",
"@humanwhocodes/retry": "^0.4.2",
@@ -6258,19 +6239,6 @@
"url": "https://opencollective.com/eslint"
}
},
- "node_modules/eslint/node_modules/@eslint/core": {
- "version": "0.15.1",
- "resolved": "https://registry.npmjs.org/@eslint/core/-/core-0.15.1.tgz",
- "integrity": "sha512-bkOp+iumZCCbt1K1CmWf0R9pM5yKpDv+ZXtvSyQpudrI9kuFLp+bM2WOPXImuD/ceQuaa8f5pj93Y7zyECIGNA==",
- "dev": true,
- "license": "Apache-2.0",
- "dependencies": {
- "@types/json-schema": "^7.0.15"
- },
- "engines": {
- "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
- }
- },
"node_modules/eslint/node_modules/escape-string-regexp": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz",
@@ -7648,10 +7616,11 @@
}
},
"node_modules/hookified": {
- "version": "1.10.0",
- "resolved": "https://registry.npmjs.org/hookified/-/hookified-1.10.0.tgz",
- "integrity": "sha512-dJw0492Iddsj56U1JsSTm9E/0B/29a1AuoSLRAte8vQg/kaTGF3IgjEWT8c8yG4cC10+HisE1x5QAwR0Xwc+DA==",
- "dev": true
+ "version": "1.11.0",
+ "resolved": "https://registry.npmjs.org/hookified/-/hookified-1.11.0.tgz",
+ "integrity": "sha512-aDdIN3GyU5I6wextPplYdfmWCo+aLmjjVbntmX6HLD5RCi/xKsivYEBhnRD+d9224zFf008ZpLMPlWF0ZodYZw==",
+ "dev": true,
+ "license": "MIT"
},
"node_modules/html-encoding-sniffer": {
"version": "4.0.0",
@@ -11573,10 +11542,11 @@
}
},
"node_modules/postcss-selector-parser": {
- "version": "6.1.2",
- "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.1.2.tgz",
- "integrity": "sha512-Q8qQfPiZ+THO/3ZrOrO0cJJKfpYCagtMUkXbnEfmgUjwXg6z/WBeOyS9APBBPCTSiDV+s4SwQGu8yFsiMRIudg==",
+ "version": "7.1.0",
+ "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-7.1.0.tgz",
+ "integrity": "sha512-8sLjZwK0R+JlxlYcTuVnyT2v+htpdrjDOKuMcOVdYjt52Lh8hWRYpxBPoKx/Zg+bcjc3wx6fmQevMmUztS/ccA==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"cssesc": "^3.0.0",
"util-deprecate": "^1.0.2"
@@ -12560,16 +12530,23 @@
"license": "ISC"
},
"node_modules/sha.js": {
- "version": "2.4.11",
- "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz",
- "integrity": "sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==",
+ "version": "2.4.12",
+ "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.12.tgz",
+ "integrity": "sha512-8LzC5+bvI45BjpfXU8V5fdU2mfeKiQe1D1gIMn7XUlF3OTUrpdJpPPH4EMAnF0DsHHdSZqCdSss5qCmJKuiO3w==",
"license": "(MIT AND BSD-3-Clause)",
"dependencies": {
- "inherits": "^2.0.1",
- "safe-buffer": "^5.0.1"
+ "inherits": "^2.0.4",
+ "safe-buffer": "^5.2.1",
+ "to-buffer": "^1.2.0"
},
"bin": {
"sha.js": "bin.js"
+ },
+ "engines": {
+ "node": ">= 0.10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/shasum": {
@@ -13306,9 +13283,9 @@
"license": "ISC"
},
"node_modules/stylelint": {
- "version": "16.22.0",
- "resolved": "https://registry.npmjs.org/stylelint/-/stylelint-16.22.0.tgz",
- "integrity": "sha512-SVEMTdjKNV4ollUrIY9ordZ36zHv2/PHzPjfPMau370MlL2VYXeLgSNMMiEbLGRO8RmD2R8/BVUeF2DfnfkC0w==",
+ "version": "16.23.1",
+ "resolved": "https://registry.npmjs.org/stylelint/-/stylelint-16.23.1.tgz",
+ "integrity": "sha512-dNvDTsKV1U2YtiUDfe9d2gp902veFeo3ecCWdGlmLm2WFrAV0+L5LoOj/qHSBABQwMsZPJwfC4bf39mQm1S5zw==",
"dev": true,
"funding": [
{
@@ -13335,7 +13312,7 @@
"debug": "^4.4.1",
"fast-glob": "^3.3.3",
"fastest-levenshtein": "^1.0.16",
- "file-entry-cache": "^10.1.1",
+ "file-entry-cache": "^10.1.3",
"global-modules": "^2.0.0",
"globby": "^11.1.0",
"globjoin": "^0.1.4",
@@ -13369,19 +13346,20 @@
}
},
"node_modules/stylelint-config-recess-order": {
- "version": "7.1.0",
- "resolved": "https://registry.npmjs.org/stylelint-config-recess-order/-/stylelint-config-recess-order-7.1.0.tgz",
- "integrity": "sha512-rFc4Z6SCGgEohr1khsmAZ83X56Tdi2dHY/GB7VT3qJkpKU1V2w+mYlK+b7Za5gpsxEng3jnb4FzWyIl/KTH0AQ==",
+ "version": "7.2.0",
+ "resolved": "https://registry.npmjs.org/stylelint-config-recess-order/-/stylelint-config-recess-order-7.2.0.tgz",
+ "integrity": "sha512-3Y97dhsWkUHFKRLGNLF6LE5JuNB2EVAZKYJ41wBRK4gplYdk7eHhSIwE24hanu0AoNmv5534Djip70pE+y5qkA==",
"dev": true,
+ "license": "ISC",
"peerDependencies": {
"stylelint": ">=16.18",
"stylelint-order": ">=7"
}
},
"node_modules/stylelint-config-recommended": {
- "version": "16.0.0",
- "resolved": "https://registry.npmjs.org/stylelint-config-recommended/-/stylelint-config-recommended-16.0.0.tgz",
- "integrity": "sha512-4RSmPjQegF34wNcK1e1O3Uz91HN8P1aFdFzio90wNK9mjgAI19u5vsU868cVZboKzCaa5XbpvtTzAAGQAxpcXA==",
+ "version": "17.0.0",
+ "resolved": "https://registry.npmjs.org/stylelint-config-recommended/-/stylelint-config-recommended-17.0.0.tgz",
+ "integrity": "sha512-WaMSdEiPfZTSFVoYmJbxorJfA610O0tlYuU2aEwY33UQhSPgFbClrVJYWvy3jGJx+XW37O+LyNLiZOEXhKhJmA==",
"dev": true,
"funding": [
{
@@ -13398,7 +13376,7 @@
"node": ">=18.12.0"
},
"peerDependencies": {
- "stylelint": "^16.16.0"
+ "stylelint": "^16.23.0"
}
},
"node_modules/stylelint-order": {
@@ -13418,29 +13396,6 @@
"stylelint": "^16.18.0"
}
},
- "node_modules/stylelint/node_modules/@csstools/media-query-list-parser": {
- "version": "4.0.3",
- "resolved": "https://registry.npmjs.org/@csstools/media-query-list-parser/-/media-query-list-parser-4.0.3.tgz",
- "integrity": "sha512-HAYH7d3TLRHDOUQK4mZKf9k9Ph/m8Akstg66ywKR4SFAigjs3yBiUeZtFxywiTm5moZMAp/5W/ZuFnNXXYLuuQ==",
- "dev": true,
- "funding": [
- {
- "type": "github",
- "url": "https://github.com/sponsors/csstools"
- },
- {
- "type": "opencollective",
- "url": "https://opencollective.com/csstools"
- }
- ],
- "engines": {
- "node": ">=18"
- },
- "peerDependencies": {
- "@csstools/css-parser-algorithms": "^3.0.5",
- "@csstools/css-tokenizer": "^3.0.4"
- }
- },
"node_modules/stylelint/node_modules/@csstools/selector-specificity": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/@csstools/selector-specificity/-/selector-specificity-5.0.0.tgz",
@@ -13472,21 +13427,23 @@
"license": "MIT"
},
"node_modules/stylelint/node_modules/file-entry-cache": {
- "version": "10.1.1",
- "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-10.1.1.tgz",
- "integrity": "sha512-zcmsHjg2B2zjuBgjdnB+9q0+cWcgWfykIcsDkWDB4GTPtl1eXUA+gTI6sO0u01AqK3cliHryTU55/b2Ow1hfZg==",
+ "version": "10.1.3",
+ "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-10.1.3.tgz",
+ "integrity": "sha512-D+w75Ub8T55yor7fPgN06rkCAUbAYw2vpxJmmjv/GDAcvCnv9g7IvHhIZoxzRZThrXPFI2maeY24pPbtyYU7Lg==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "flat-cache": "^6.1.10"
+ "flat-cache": "^6.1.12"
}
},
"node_modules/stylelint/node_modules/flat-cache": {
- "version": "6.1.11",
- "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-6.1.11.tgz",
- "integrity": "sha512-zfOAns94mp7bHG/vCn9Ru2eDCmIxVQ5dELUHKjHfDEOJmHNzE+uGa6208kfkgmtym4a0FFjEuFksCXFacbVhSg==",
+ "version": "6.1.12",
+ "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-6.1.12.tgz",
+ "integrity": "sha512-U+HqqpZPPXP5d24bWuRzjGqVqUcw64k4nZAbruniDwdRg0H10tvN7H6ku1tjhA4rg5B9GS3siEvwO2qjJJ6f8Q==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "cacheable": "^1.10.1",
+ "cacheable": "^1.10.3",
"flatted": "^3.3.3",
"hookified": "^1.10.0"
}
@@ -13500,20 +13457,6 @@
"node": ">= 4"
}
},
- "node_modules/stylelint/node_modules/postcss-selector-parser": {
- "version": "7.1.0",
- "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-7.1.0.tgz",
- "integrity": "sha512-8sLjZwK0R+JlxlYcTuVnyT2v+htpdrjDOKuMcOVdYjt52Lh8hWRYpxBPoKx/Zg+bcjc3wx6fmQevMmUztS/ccA==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "cssesc": "^3.0.0",
- "util-deprecate": "^1.0.2"
- },
- "engines": {
- "node": ">=4"
- }
- },
"node_modules/stylelint/node_modules/resolve-from": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz",
diff --git a/package.json b/package.json
index e32f5a05c..5c6fb4efc 100644
--- a/package.json
+++ b/package.json
@@ -136,9 +136,9 @@
"written-number": "^0.11.1"
},
"devDependencies": {
- "@stylistic/stylelint-plugin": "^3.1.3",
+ "@stylistic/stylelint-plugin": "^4.0.0",
"babel-plugin-transform-import-meta": "^2.3.3",
- "eslint": "^9.31.0",
+ "eslint": "^9.34.0",
"eslint-plugin-jest": "^29.0.1",
"eslint-plugin-react": "^7.37.5",
"globals": "^16.3.0",
@@ -146,9 +146,9 @@
"jest-expect-message": "^1.1.3",
"jsdom-global": "^3.0.2",
"postcss-less": "^6.0.0",
- "stylelint": "^16.22.0",
- "stylelint-config-recess-order": "^7.1.0",
- "stylelint-config-recommended": "^16.0.0",
+ "stylelint": "^16.23.1",
+ "stylelint-config-recess-order": "^7.2.0",
+ "stylelint-config-recommended": "^17.0.0",
"supertest": "^7.1.4"
}
}
diff --git a/server/app.js b/server/app.js
index 113f4c37d..162b34df3 100644
--- a/server/app.js
+++ b/server/app.js
@@ -489,8 +489,8 @@ app.get('/account', asyncHandler(async (req, res, next)=>{
const query = { authors: req.account.username, googleId: { $exists: false } };
const mongoCount = await HomebrewModel.countDocuments(query)
.catch((err)=>{
- mongoCount = 0;
console.log(err);
+ return 0;
});
data.accountDetails = {
diff --git a/shared/helpers.js b/shared/helpers.js
index e09b0bdc4..3f91583d6 100644
--- a/shared/helpers.js
+++ b/shared/helpers.js
@@ -116,27 +116,21 @@ const printCurrentBrew = ()=>{
}
};
-const fetchThemeBundle = async (obj, renderer, theme)=>{
+const fetchThemeBundle = async (setError, setThemeBundle, renderer, theme)=>{
if(!renderer || !theme) return;
const res = await request
.get(`/api/theme/${renderer}/${theme}`)
.catch((err)=>{
- obj.setState({ error: err });
+ setError(err)
});
if(!res) {
- obj.setState((prevState)=>({
- ...prevState,
- themeBundle : {}
- }));
+ setThemeBundle({});
return;
}
const themeBundle = res.body;
themeBundle.joinedStyles = themeBundle.styles.map((style)=>``).join('\n\n');
- obj.setState((prevState)=>({
- ...prevState,
- themeBundle : themeBundle,
- error : null
- }));
+ setThemeBundle(themeBundle);
+ setError(null);
};
const debugTextMismatch = (clientTextRaw, serverTextRaw, label) => {