mirror of
https://github.com/naturalcrit/homebrewery.git
synced 2026-11-04 20:29:01 +00:00
Merge branch 'master' of https://github.com/naturalcrit/homebrewery into search-by-tags
This commit is contained in:
+94
-104
@@ -1,143 +1,133 @@
|
||||
import React from 'react';
|
||||
import createReactClass from 'create-react-class';
|
||||
import React, { useState, useEffect, useRef, useCallback } from 'react';
|
||||
import _ from 'lodash';
|
||||
import './combobox.less';
|
||||
|
||||
const Combobox = createReactClass({
|
||||
displayName : 'Combobox',
|
||||
getDefaultProps : function() {
|
||||
return {
|
||||
id : '',
|
||||
className : '',
|
||||
trigger : 'hover',
|
||||
default : '',
|
||||
placeholder : '',
|
||||
tooltip : '',
|
||||
autoSuggest : {
|
||||
clearAutoSuggestOnClick : true,
|
||||
suggestMethod : 'includes',
|
||||
filterOn : [] // should allow as array to filter on multiple attributes, or even custom filter
|
||||
},
|
||||
valuePatterns : /.+/
|
||||
};
|
||||
const Combobox = ({
|
||||
id = '',
|
||||
className = '',
|
||||
trigger = 'hover',
|
||||
defaultValue = '',
|
||||
placeholder = '',
|
||||
tooltip = '',
|
||||
autoSuggest = {
|
||||
clearAutoSuggestOnClick : true,
|
||||
suggestMethod : 'includes',
|
||||
filterOn : [] // should allow as array to filter on multiple attributes, or even custom filter
|
||||
},
|
||||
getInitialState : function() {
|
||||
this.dropdownRef = React.createRef();
|
||||
return {
|
||||
showDropdown : false,
|
||||
value : '',
|
||||
options : [...this.props.options],
|
||||
inputFocused : false
|
||||
};
|
||||
},
|
||||
componentDidMount : function() {
|
||||
if(this.props.trigger == 'click')
|
||||
document.addEventListener('click', this.handleClickOutside);
|
||||
this.setState({
|
||||
value : this.props.default
|
||||
});
|
||||
},
|
||||
componentWillUnmount : function() {
|
||||
if(this.props.trigger == 'click')
|
||||
document.removeEventListener('click', this.handleClickOutside);
|
||||
},
|
||||
handleClickOutside : function(e){
|
||||
// Close dropdown when clicked outside
|
||||
if(this.dropdownRef.current && !this.dropdownRef.current.contains(e.target)) {
|
||||
this.handleDropdown(false);
|
||||
valuePatterns = '.+',
|
||||
options = [],
|
||||
keepValueOnClose = false,
|
||||
...props
|
||||
})=>{
|
||||
const dropdownRef = useRef(null);
|
||||
const [showDropdown, setShowDropdown] = useState(false);
|
||||
const [inputFocused, setInputFocused] = useState(false);
|
||||
const [value, setValue] = useState(defaultValue);
|
||||
|
||||
useEffect(()=>{
|
||||
if(trigger === 'click') {
|
||||
document.addEventListener('click', handleClickOutside);
|
||||
return ()=>document.removeEventListener('click', handleClickOutside);
|
||||
}
|
||||
},
|
||||
handleDropdown : function(show){
|
||||
this.setState({
|
||||
value : show ? '' : this.props.default,
|
||||
showDropdown : show,
|
||||
inputFocused : this.props.autoSuggest.clearAutoSuggestOnClick ? show : false
|
||||
});
|
||||
},
|
||||
handleInput : function(e){
|
||||
e.persist();
|
||||
this.setState({
|
||||
value : e.target.value,
|
||||
inputFocused : false
|
||||
}, ()=>{
|
||||
this.props.onEntry(e);
|
||||
});
|
||||
},
|
||||
handleSelect : function(value, data=value){
|
||||
this.setState({
|
||||
value : value
|
||||
}, ()=>{this.props.onSelect(data);});
|
||||
;
|
||||
},
|
||||
renderTextInput : function(){
|
||||
}, []);
|
||||
|
||||
const handleClickOutside = useCallback((e)=>{
|
||||
// Close dropdown when clicked outside
|
||||
if(!dropdownRef.current?.contains(e.target)) {
|
||||
handleDropdown(false);
|
||||
}
|
||||
}, []);
|
||||
|
||||
const handleDropdown = (show)=>{
|
||||
if(show) {
|
||||
if(autoSuggest.clearAutoSuggestOnClick) {
|
||||
setValue('');
|
||||
}
|
||||
} else if(!keepValueOnClose) {
|
||||
setValue(defaultValue);
|
||||
}
|
||||
setShowDropdown(show);
|
||||
setInputFocused(autoSuggest.clearAutoSuggestOnClick && show);
|
||||
};
|
||||
|
||||
const handleInput = (e)=>{
|
||||
setValue(e.target.value);
|
||||
setInputFocused(false);
|
||||
props.onEntry(e);
|
||||
};
|
||||
|
||||
const handleSelect = (value, data=value)=>{
|
||||
setValue(value);
|
||||
props.onSelect(data);
|
||||
};
|
||||
|
||||
const renderTextInput = ()=>{
|
||||
return (
|
||||
<div className='dropdown-input item'
|
||||
onMouseEnter={this.props.trigger == 'hover' ? ()=>{this.handleDropdown(true);} : undefined}
|
||||
onClick= {this.props.trigger == 'click' ? ()=>{this.handleDropdown(true);} : undefined}
|
||||
{...(this.props.tooltip ? { 'data-tooltip-right': this.props.tooltip } : {})}>
|
||||
onMouseEnter={trigger == 'hover' ? ()=>{handleDropdown(true);} : undefined}
|
||||
onClick= {trigger == 'click' ? ()=>{handleDropdown(true);} : undefined}
|
||||
{...(tooltip ? { 'data-tooltip-right': tooltip } : {})}>
|
||||
<input
|
||||
id={this.props.id}
|
||||
id={id}
|
||||
type='text'
|
||||
onChange={(e)=>this.handleInput(e)}
|
||||
value={this.state.value || ''}
|
||||
onChange={(e)=>handleInput(e)}
|
||||
value={value || ''}
|
||||
title=''
|
||||
pattern={this.props.valuePatterns}
|
||||
placeholder={this.props.placeholder}
|
||||
pattern={valuePatterns}
|
||||
placeholder={placeholder}
|
||||
onBlur={(e)=>{
|
||||
if(!e.target.checkValidity()){
|
||||
this.setState({
|
||||
value : this.props.default
|
||||
});
|
||||
setValue(defaultValue);
|
||||
}
|
||||
}}
|
||||
onKeyDown={(e)=>{
|
||||
if(e.key === 'Enter') {
|
||||
e.preventDefault();
|
||||
this.props.onEntry(e);
|
||||
props.onEntry(e);
|
||||
}
|
||||
}}
|
||||
/>
|
||||
<i className='fas fa-caret-down'/>
|
||||
</div>
|
||||
);
|
||||
},
|
||||
renderDropdown : function(dropdownChildren){
|
||||
if(!this.state.showDropdown) return null;
|
||||
if(this.props.autoSuggest && !this.state.inputFocused){
|
||||
const suggestMethod = this.props.autoSuggest.suggestMethod;
|
||||
const filterOn = _.isString(this.props.autoSuggest.filterOn) ? [this.props.autoSuggest.filterOn] : this.props.autoSuggest.filterOn;
|
||||
};
|
||||
|
||||
const renderDropdown = ()=>{
|
||||
if(!showDropdown) return null;
|
||||
let dropdownChildren = options.map((child, i)=>{
|
||||
const clone = React.cloneElement(child, { onClick: ()=>handleSelect(child.props.value, child.props.data) });
|
||||
return clone;
|
||||
});
|
||||
if(autoSuggest && !inputFocused){
|
||||
const suggestMethod = autoSuggest.suggestMethod;
|
||||
const filterOn = _.isString(autoSuggest.filterOn) ? [autoSuggest.filterOn] : autoSuggest.filterOn;
|
||||
const filteredArrays = filterOn.map((attr)=>{
|
||||
const children = dropdownChildren.filter((item)=>{
|
||||
if(suggestMethod === 'includes')
|
||||
return item.props[attr]?.toLowerCase().includes(this.state.value.toLowerCase());
|
||||
return item.props[attr]?.toLowerCase().includes(value.toLowerCase());
|
||||
if(suggestMethod === 'startsWith')
|
||||
return item.props[attr]?.toLowerCase().startsWith(this.state.value.toLowerCase());
|
||||
return item.props[attr]?.toLowerCase().startsWith(value.toLowerCase());
|
||||
});
|
||||
return children;
|
||||
});
|
||||
dropdownChildren = _.uniq(filteredArrays.flat(1));
|
||||
}
|
||||
|
||||
return (
|
||||
<div className='dropdown-options'>
|
||||
{dropdownChildren}
|
||||
</div>
|
||||
);
|
||||
},
|
||||
render : function () {
|
||||
const dropdownChildren = this.state.options.map((child, i)=>{
|
||||
const clone = React.cloneElement(child, { onClick: ()=>this.handleSelect(child.props.value, child.props.data) });
|
||||
return clone;
|
||||
});
|
||||
return (
|
||||
<div className={`dropdown-container ${this.props.className}`}
|
||||
ref={this.dropdownRef}
|
||||
onMouseLeave={this.props.trigger == 'hover' ? ()=>{this.handleDropdown(false);} : undefined}>
|
||||
{this.renderTextInput()}
|
||||
{this.renderDropdown(dropdownChildren)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
return (
|
||||
<div className={`dropdown-container ${className}`}
|
||||
ref={dropdownRef}
|
||||
onMouseLeave={trigger == 'hover' ? ()=>{handleDropdown(false);} : undefined}>
|
||||
{renderTextInput()}
|
||||
{renderDropdown()}
|
||||
</div>
|
||||
);
|
||||
|
||||
};
|
||||
|
||||
export default Combobox;
|
||||
|
||||
@@ -219,7 +219,7 @@ const MetadataEditor = ({
|
||||
<Combobox trigger='click'
|
||||
id='combobox-themes'
|
||||
className='themes-dropdown'
|
||||
default={currentThemeDisplay}
|
||||
defaultValue={currentThemeDisplay}
|
||||
placeholder='Select from below, or enter the Share URL or ID of a brew with the meta:theme tag'
|
||||
onSelect={(value)=>handleTheme(value)}
|
||||
onEntry={(e)=>{
|
||||
@@ -261,8 +261,10 @@ const MetadataEditor = ({
|
||||
<Combobox trigger='click'
|
||||
id='combobox-language'
|
||||
className='language-dropdown'
|
||||
default={metadata.lang || ''}
|
||||
defaultValue={metadata.lang || ''}
|
||||
keepValueOnClose={true}
|
||||
placeholder='en'
|
||||
valuePatterns="^[a-z]{2,3}(-[A-Z][a-z]{3})?(-[A-Z]{2})?$"
|
||||
onSelect={(value)=>handleLanguage(value)}
|
||||
onEntry={(e)=>{
|
||||
e.target.setCustomValidity(''); //Clear the validation popup while typing
|
||||
|
||||
@@ -131,7 +131,7 @@ const TagInput = ({ id, tooltip, label, valuePatterns, values = [], unique = tru
|
||||
id={id}
|
||||
trigger='click'
|
||||
className='tagInput-dropdown'
|
||||
default=''
|
||||
defaultValue=''
|
||||
placeholder={placeholder}
|
||||
options={label === 'tags' ? suggestionOptions : []}
|
||||
tooltip={tooltip}
|
||||
|
||||
@@ -145,8 +145,8 @@
|
||||
box-shadow : 0 4px 5px 0 #333333;
|
||||
.text {
|
||||
min-height : 54px;
|
||||
padding-left : 5px;
|
||||
h2 { margin-bottom : 5px; }
|
||||
.description { padding-left : 5px; }
|
||||
}
|
||||
.info { padding-left : 5px; }
|
||||
.links {
|
||||
@@ -398,7 +398,7 @@
|
||||
}
|
||||
.storage { display : none; }
|
||||
}
|
||||
.brewItem {
|
||||
.brewItem {
|
||||
h2 {
|
||||
width : 200px;
|
||||
font-size : 1em;
|
||||
@@ -426,7 +426,7 @@
|
||||
}
|
||||
.info {
|
||||
display : grid;
|
||||
grid-template-areas :
|
||||
grid-template-areas :
|
||||
'tags pages views views'
|
||||
'authors update update storage';
|
||||
grid-template-columns : 2fr 1fr 1fr 20px;
|
||||
@@ -440,7 +440,7 @@
|
||||
a,
|
||||
button { margin : 0; }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@container (max-width : 650px) {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*eslint max-lines: ["warn", {"max": 300, "skipBlankLines": true, "skipComments": true}]*/
|
||||
import './listPage.less';
|
||||
import React, { useEffect, useState, useRef, useMemo } from 'react';
|
||||
import React, { useEffect, useState, useMemo } from 'react';
|
||||
import moment from 'moment';
|
||||
import _ from 'lodash';
|
||||
|
||||
@@ -26,24 +26,7 @@ const ListPage = ({ brewCollection = [{ title: '', class: '', brews: [] }], navI
|
||||
const [layoutMode, setLayoutMode] = useState(DEFAULT_LAYOUT_MODE);
|
||||
const [themeMode, setThemeMode] = useState(DEFAULT_THEME_MODE);
|
||||
|
||||
const groupVisibilityRef = useRef(groupVisibility);
|
||||
const sortTypeRef = useRef(sortType);
|
||||
const sortDirRef = useRef(sortDir);
|
||||
|
||||
useEffect(()=>{
|
||||
groupVisibilityRef.current = groupVisibility;
|
||||
}, [groupVisibility]);
|
||||
|
||||
useEffect(()=>{
|
||||
sortTypeRef.current = sortType;
|
||||
}, [sortType]);
|
||||
|
||||
useEffect(()=>{
|
||||
sortDirRef.current = sortDir;
|
||||
}, [sortDir]);
|
||||
|
||||
useEffect(()=>{
|
||||
window.onbeforeunload = saveToLocalStorage;
|
||||
if(typeof window === 'undefined') return;
|
||||
|
||||
const newSortType = sortType ?? (localStorage.getItem(USERPAGE_SORT_TYPE) || DEFAULT_SORT_TYPE);
|
||||
@@ -63,20 +46,8 @@ const ListPage = ({ brewCollection = [{ title: '', class: '', brews: [] }], navI
|
||||
setSortDir(newSortDir);
|
||||
setLayoutMode(newLayoutMode);
|
||||
setThemeMode(newThemeMode);
|
||||
|
||||
return ()=>{
|
||||
window.onbeforeunload = null;
|
||||
};
|
||||
}, []);
|
||||
|
||||
const saveToLocalStorage = ()=>{
|
||||
brewCollection.forEach((brewGroup)=>{
|
||||
localStorage.setItem(`${USERPAGE_GROUP_VISIBILITY_PREFIX}_${brewGroup.class}`, `${groupVisibilityRef.current[brewGroup.class]}`);
|
||||
});
|
||||
localStorage.setItem(USERPAGE_SORT_TYPE, sortTypeRef.current);
|
||||
localStorage.setItem(USERPAGE_SORT_DIR, sortDirRef.current);
|
||||
};
|
||||
|
||||
const renderBrews = (brews)=>{
|
||||
if(!brews || !brews.length) return <div className='noBrews'>No Brews.</div>;
|
||||
|
||||
@@ -108,6 +79,8 @@ const ListPage = ({ brewCollection = [{ title: '', class: '', brews: [] }], navI
|
||||
const handleSortOptionChange = (event)=>{
|
||||
updateUrl(filterString, event.target.value, sortDir);
|
||||
setSortType(event.target.value);
|
||||
localStorage.setItem(USERPAGE_SORT_TYPE, event.target.value);
|
||||
return;
|
||||
};
|
||||
|
||||
const handleSortDirChange = (event)=>{
|
||||
@@ -115,6 +88,8 @@ const ListPage = ({ brewCollection = [{ title: '', class: '', brews: [] }], navI
|
||||
|
||||
updateUrl(filterString, sortType, newDir);
|
||||
setSortDir(newDir);
|
||||
localStorage.setItem(USERPAGE_SORT_DIR, newDir);
|
||||
return;
|
||||
};
|
||||
|
||||
const renderSortOption = (sortTitle, sortValue)=>{
|
||||
@@ -187,7 +162,7 @@ const ListPage = ({ brewCollection = [{ title: '', class: '', brews: [] }], navI
|
||||
if(filterTags?.length == 0) return;
|
||||
return (
|
||||
<div className='tags-container'>
|
||||
Tags:
|
||||
Tags:
|
||||
{_.map(filterTags, (tag, idx)=>{
|
||||
const matches = tag.match(/^(?:([^:]+):)?([^:]+)$/);
|
||||
return (
|
||||
@@ -198,7 +173,7 @@ const ListPage = ({ brewCollection = [{ title: '', class: '', brews: [] }], navI
|
||||
updateUrl(filterString, sortType, sortDir, tag);
|
||||
}}>
|
||||
{matches[2]}
|
||||
</span>
|
||||
</span>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
@@ -257,7 +232,13 @@ const ListPage = ({ brewCollection = [{ title: '', class: '', brews: [] }], navI
|
||||
}, [brewCollection, filterString, filterTags, sortType, sortDir]);
|
||||
|
||||
const toggleBrewCollectionState = (brewGroupClass)=>{
|
||||
setGroupVisibility((prevVisibility)=>({ ...prevVisibility, [brewGroupClass]: !prevVisibility[brewGroupClass] }));
|
||||
setGroupVisibility((prevVisibility)=>{
|
||||
const visible = !prevVisibility[brewGroupClass];
|
||||
|
||||
localStorage.setItem(`${USERPAGE_GROUP_VISIBILITY_PREFIX}_${brewGroupClass}`, visible);
|
||||
|
||||
return {...prevVisibility, [brewGroupClass]: visible};
|
||||
});
|
||||
};
|
||||
|
||||
const renderBrewCollection = (brewCollection)=>{
|
||||
@@ -298,8 +279,8 @@ const ListPage = ({ brewCollection = [{ title: '', class: '', brews: [] }], navI
|
||||
<div className='radio-toggle layout-container'>
|
||||
<h6>View:</h6>
|
||||
<label className='option' title='grid'>
|
||||
<input name='layout-mode' type='radio' onChange={(e)=>handleLayoutChange(e, 'grid')} checked={layoutMode === 'grid'} />
|
||||
<i className='fac compressed-grid'></i>
|
||||
<input name='layout-mode' type='radio' onChange={(e)=>handleLayoutChange(e, 'grid')} checked={layoutMode === 'grid'} />
|
||||
<i className='fac compressed-grid'></i>
|
||||
</label>
|
||||
<label className='option' title='list'>
|
||||
<input name='layout-mode' type='radio' onChange={(e)=>handleLayoutChange(e, 'list')} checked={layoutMode === 'list'} />
|
||||
@@ -320,24 +301,24 @@ const ListPage = ({ brewCollection = [{ title: '', class: '', brews: [] }], navI
|
||||
};
|
||||
const renderThemePicker = ()=>{
|
||||
return (
|
||||
<div className="radio-toggle theme-container">
|
||||
<div className='radio-toggle theme-container'>
|
||||
<h6>Theme:</h6>
|
||||
<label className="option">
|
||||
<input type="radio" name="theme" onChange={(e)=>handleThemeChange(e, 'light')} checked={themeMode === 'light'}/>
|
||||
<i className="fas fa-sun"/>
|
||||
<label className='option'>
|
||||
<input type='radio' name='theme' onChange={(e)=>handleThemeChange(e, 'light')} checked={themeMode === 'light'}/>
|
||||
<i className='fas fa-sun'/>
|
||||
</label>
|
||||
<label className="option">
|
||||
<input type="radio" name="theme" onChange={(e)=>handleThemeChange(e, 'dark')} checked={themeMode === 'dark'}/>
|
||||
<i className="fas fa-moon"/>
|
||||
<label className='option'>
|
||||
<input type='radio' name='theme' onChange={(e)=>handleThemeChange(e, 'dark')} checked={themeMode === 'dark'}/>
|
||||
<i className='fas fa-moon'/>
|
||||
</label>
|
||||
</div>
|
||||
)
|
||||
);
|
||||
};
|
||||
|
||||
const renderNav = () =>{
|
||||
const renderNav = ()=>{
|
||||
|
||||
return (
|
||||
<div className="listPageNav">
|
||||
<div className='listPageNav'>
|
||||
{renderLayoutModeOptions()}
|
||||
{renderThemePicker()}
|
||||
{renderSortOptions()}
|
||||
@@ -345,8 +326,8 @@ const ListPage = ({ brewCollection = [{ title: '', class: '', brews: [] }], navI
|
||||
{renderTagsOptions()}
|
||||
</div>
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
return (
|
||||
<div className='sitePage listPage'>
|
||||
@@ -354,7 +335,7 @@ const ListPage = ({ brewCollection = [{ title: '', class: '', brews: [] }], navI
|
||||
|
||||
{renderNav()}
|
||||
|
||||
<div className={`content V3 ${themeMode + 'Mode'}`}>
|
||||
<div className={`content V3 ${`${themeMode}Mode`}`}>
|
||||
<div className='brewCollection'>{renderBrewCollection(brewCollection)}</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
Generated
+7
-7
@@ -25,7 +25,7 @@
|
||||
"@codemirror/search": "^6.6.0",
|
||||
"@codemirror/state": "^6.7.6",
|
||||
"@codemirror/view": "^6.43.15",
|
||||
"@googleapis/drive": "^26.0.2",
|
||||
"@googleapis/drive": "^27.0.0",
|
||||
"@lezer/highlight": "^1.2.4",
|
||||
"@oddbird/css-anchor-positioning": "^0.10.2",
|
||||
"@sanity/diff-match-patch": "^3.2.1",
|
||||
@@ -2559,9 +2559,9 @@
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@googleapis/drive": {
|
||||
"version": "26.0.2",
|
||||
"resolved": "https://registry.npmjs.org/@googleapis/drive/-/drive-26.0.2.tgz",
|
||||
"integrity": "sha512-VeKVZvzgH4ioczJZrZ5sy73RJbHrYLI1XZIZ3ZqGKQhC4U03XsOOOiBHKqvH4F9vbXrxR2LawmktoIJuTJhzYg==",
|
||||
"version": "27.0.0",
|
||||
"resolved": "https://registry.npmjs.org/@googleapis/drive/-/drive-27.0.0.tgz",
|
||||
"integrity": "sha512-q+K1+T4Kbz3VUOww15lhV+jq+/IzuxzkfiASIXzxVG6X894QUPdhBgU9hKFNSKh+e58o0g6mX/06XoLsS1JE6Q==",
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"googleapis-common": "^9.0.0"
|
||||
@@ -7660,9 +7660,9 @@
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/fast-uri": {
|
||||
"version": "3.1.8",
|
||||
"resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.1.8.tgz",
|
||||
"integrity": "sha512-GZMtZUTNRpOVIECoXwLNZS5xUGE+mVNbTB8h/7Rwh2TFWcBQiPzTgyZi05BF9UMZKkLJv8XBRJTlU7zg8+ZfMg==",
|
||||
"version": "3.1.9",
|
||||
"resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.1.9.tgz",
|
||||
"integrity": "sha512-hS/0Wt3Ya043oKXs0sIxrMpKQITXhMLIrVAKKXi4gozGC9v7YRWVnXIZzjNPTO02M9BdxLCWqK1yRXgNziVyJQ==",
|
||||
"dev": true,
|
||||
"funding": [
|
||||
{
|
||||
|
||||
+1
-1
@@ -104,7 +104,7 @@
|
||||
"@codemirror/search": "^6.6.0",
|
||||
"@codemirror/state": "^6.7.6",
|
||||
"@codemirror/view": "^6.43.15",
|
||||
"@googleapis/drive": "^26.0.2",
|
||||
"@googleapis/drive": "^27.0.0",
|
||||
"@lezer/highlight": "^1.2.4",
|
||||
"@oddbird/css-anchor-positioning": "^0.10.2",
|
||||
"@sanity/diff-match-patch": "^3.2.1",
|
||||
|
||||
@@ -28,8 +28,10 @@ export function generateAssetsPlugin(isDev = false) {
|
||||
|
||||
// Compile Legacy themes
|
||||
const themes = { Legacy: {}, V3: {} };
|
||||
const legacyDirs = fs.readdirSync('./themes/Legacy');
|
||||
for (const dir of legacyDirs) {
|
||||
const legacyDirs = fs.readdirSync('./themes/Legacy', { withFileTypes: true })
|
||||
.filter(entry => entry.isDirectory())
|
||||
.map(entry => entry.name);
|
||||
for (const dir of legacyDirs) {
|
||||
const themeData = JSON.parse(fs.readFileSync(`./themes/Legacy/${dir}/settings.json`, 'utf-8'));
|
||||
themeData.path = dir;
|
||||
themes.Legacy[dir] = themeData;
|
||||
@@ -41,7 +43,9 @@ export function generateAssetsPlugin(isDev = false) {
|
||||
}
|
||||
|
||||
// Compile V3 themes
|
||||
const v3Dirs = fs.readdirSync('./themes/V3');
|
||||
const v3Dirs = fs.readdirSync('./themes/V3', { withFileTypes: true })
|
||||
.filter(entry => entry.isDirectory())
|
||||
.map(entry => entry.name);
|
||||
for (const dir of v3Dirs) {
|
||||
const themeData = JSON.parse(fs.readFileSync(`./themes/V3/${dir}/settings.json`, 'utf-8'));
|
||||
themeData.path = dir;
|
||||
|
||||
Reference in New Issue
Block a user