0
0
mirror of https://github.com/naturalcrit/homebrewery.git synced 2026-01-09 22:22:41 +00:00

Refactored the "Recent Items" navbar component. Greatly simplified the code to about 70% length and made it much easier to read. Results in the same thing.

Oh. And it works again. Recent brews should be showing up fine now.
This commit is contained in:
Trevor Buckner
2019-01-18 14:27:38 -05:00
parent 63a1ff454f
commit 71af97e489
7 changed files with 107 additions and 161 deletions

View File

@@ -1,51 +1,72 @@
const React = require('react'); const React = require('react');
const createClass = require('create-react-class'); const createClass = require('create-react-class');
const _ = require('lodash'); const _ = require('lodash');
const cx = require('classnames');
const Moment = require('moment'); const Moment = require('moment');
const Nav = require('naturalcrit/nav/nav.jsx'); const Nav = require('naturalcrit/nav/nav.jsx');
const VIEW_KEY = 'homebrewery-recently-viewed';
const EDIT_KEY = 'homebrewery-recently-edited'; const EDIT_KEY = 'homebrewery-recently-edited';
const VIEW_KEY = 'homebrewery-recently-viewed';
const RecentItems = createClass({
const BaseItem = createClass({
getDefaultProps : function() { getDefaultProps : function() {
return { return {
storageKey : '', storageKey : '',
text : '', showEdit : false,
currentBrew : { showView : false
title : '',
id : '',
url : ''
}
}; };
}, },
getInitialState : function() { getInitialState : function() {
return { return {
showDropdown : false, showDropdown : false,
brews : [] edit : [],
view : []
}; };
}, },
componentDidMount : function() { componentDidMount : function() {
let brews = JSON.parse(localStorage.getItem(this.props.storageKey) || '[]');
brews = _.filter(brews, (brew)=>{ //== Load recent items list ==//
return brew.id !== this.props.currentBrew.id; let edited = JSON.parse(localStorage.getItem(EDIT_KEY) || '[]');
}); let viewed = JSON.parse(localStorage.getItem(VIEW_KEY) || '[]');
if(this.props.currentBrew.id){
brews.unshift({ //== Add current brew to appropriate recent items list (depending on storageKey) ==//
id : this.props.currentBrew.id, if(this.props.storageKey == 'edit'){
url : this.props.currentBrew.url, edited = _.filter(edited, (brew)=>{
title : this.props.currentBrew.title, return brew.id !== this.props.brew.editId;
});
edited.unshift({
id : this.props.brew.editId,
title : this.props.brew.title,
url : `/edit/${this.props.brew.editId}`,
ts : Date.now() ts : Date.now()
}); });
} }
brews = _.slice(brews, 0, 8); if(this.props.storageKey == 'view'){
localStorage.setItem(this.props.storageKey, JSON.stringify(brews)); viewed = _.filter(viewed, (brew)=>{
return brew.id !== this.props.brew.shareId;
});
viewed.unshift({
id : this.props.brew.shareId,
title : this.props.brew.title,
url : `/share/${this.props.brew.shareId}`,
ts : Date.now()
});
}
//== Store the updated lists (up to 8 items each) ==//
edited = _.slice(edited, 0, 8);
viewed = _.slice(viewed, 0, 8);
localStorage.setItem(EDIT_KEY, JSON.stringify(edited));
localStorage.setItem(VIEW_KEY, JSON.stringify(viewed));
this.setState({ this.setState({
brews : brews edit : edited,
view : viewed
}); });
}, },
@@ -58,14 +79,25 @@ const BaseItem = createClass({
renderDropdown : function(){ renderDropdown : function(){
if(!this.state.showDropdown) return null; if(!this.state.showDropdown) return null;
const items = _.map(this.state.brews, (brew)=>{ const makeItems = (brews)=>{
return <a href={brew.url} className='item' key={brew.id} target='_blank' rel='noopener noreferrer'> return _.map(brews, (brew)=>{
<span className='title'>{brew.title}</span> return <a href={brew.url} className='item' key={brew.id} target='_blank' rel='noopener noreferrer'>
<span className='time'>{Moment(brew.ts).fromNow()}</span> <span className='title'>{brew.title || '[ no title ]'}</span>
</a>; <span className='time'>{Moment(brew.ts).fromNow()}</span>
}); </a>;
});
};
return <div className='dropdown'>{items}</div>; return <div className='dropdown'>
{(this.props.showEdit && this.props.showView) ?
<h4>edited</h4> : null }
{this.props.showEdit ?
makeItems(this.state.edit) : null }
{(this.props.showEdit && this.props.showView) ?
<h4>viewed</h4> : null }
{this.props.showView ?
makeItems(this.state.view) : null }
</div>;
}, },
render : function(){ render : function(){
@@ -75,126 +107,37 @@ const BaseItem = createClass({
{this.props.text} {this.props.text}
{this.renderDropdown()} {this.renderDropdown()}
</Nav.item>; </Nav.item>;
}, }
}); });
module.exports = { module.exports = {
viewed : createClass({
getDefaultProps : function() {
return {
brew : {
title : '',
shareId : ''
}
};
},
render : function(){
return <BaseItem text='recently viewed' storageKey={VIEW_KEY}
currentBrew={{
id : this.props.brew.shareId,
title : this.props.brew.title,
url : `/share/${this.props.brew.shareId}`
}}
/>;
},
}),
edited : createClass({ edited: (props) => {
getDefaultProps : function() { return <RecentItems
return { brew={props.brew}
brew : { storageKey={props.storageKey}
title : '', text='recently edited'
editId : '' showEdit={true}
} />;
}; },
},
render : function(){
return <BaseItem text='recently edited' storageKey={EDIT_KEY}
currentBrew={{
id : this.props.brew.editId,
title : this.props.brew.title,
url : `/edit/${this.props.brew.editId}`
}}
/>;
},
}),
both : createClass({ viewed: (props) => {
getDefaultProps : function() { return <RecentItems
return { brew={props.brew}
errorId : null storageKey={props.storageKey}
}; text='recently viewed'
}, showView={true}
/>;
},
getInitialState : function() { both: (props) => {
return { return <RecentItems
showDropdown : false, brew={props.brew}
edit : [], storageKey={props.storageKey}
view : [] text='recent brews'
}; showEdit={true}
}, showView={true}
/>;
componentDidMount : function() { }
let edited = JSON.parse(localStorage.getItem(EDIT_KEY) || '[]');
let viewed = JSON.parse(localStorage.getItem(VIEW_KEY) || '[]');
if(this.props.errorId){
edited = _.filter(edited, (edit)=>{
return edit.id !== this.props.errorId;
});
viewed = _.filter(viewed, (view)=>{
return view.id !== this.props.errorId;
});
localStorage.setItem(EDIT_KEY, JSON.stringify(edited));
localStorage.setItem(VIEW_KEY, JSON.stringify(viewed));
}
this.setState({
edit : edited,
view : viewed
});
},
handleDropdown : function(show){
this.setState({
showDropdown : show
});
},
renderDropdown : function(){
if(!this.state.showDropdown) return null;
const makeItems = (brews)=>{
return _.map(brews, (brew)=>{
return <a href={brew.url} className='item' key={brew.id} target='_blank' rel='noopener noreferrer'>
<span className='title'>{brew.title}</span>
<span className='time'>{Moment(brew.ts).fromNow()}</span>
</a>;
});
};
return <div className='dropdown'>
<h4>edited</h4>
{makeItems(this.state.edit)}
<h4>viewed</h4>
{makeItems(this.state.view)}
</div>;
},
render : function(){
return <Nav.item icon='fa-clock-o' color='grey' className='recent'
onMouseEnter={()=>this.handleDropdown(true)}
onMouseLeave={()=>this.handleDropdown(false)}>
Recent brews
{this.renderDropdown()}
</Nav.item>;
}
})
}; };

View File

@@ -10,7 +10,7 @@ const Navbar = require('../../navbar/navbar.jsx');
const ReportIssue = require('../../navbar/issue.navitem.jsx'); const ReportIssue = require('../../navbar/issue.navitem.jsx');
const PrintLink = require('../../navbar/print.navitem.jsx'); const PrintLink = require('../../navbar/print.navitem.jsx');
const Account = require('../../navbar/account.navitem.jsx'); const Account = require('../../navbar/account.navitem.jsx');
//const RecentlyEdited = require('../../navbar/recent.navitem.jsx').edited; const RecentNavItem = require('../../navbar/recent.navitem.jsx').both;
const SplitPane = require('naturalcrit/splitPane/splitPane.jsx'); const SplitPane = require('naturalcrit/splitPane/splitPane.jsx');
const Editor = require('../../editor/editor.jsx'); const Editor = require('../../editor/editor.jsx');
@@ -186,14 +186,15 @@ const EditPage = createClass({
<Nav.section> <Nav.section>
<Nav.item className='brewTitle'>{this.state.brew.title}</Nav.item> <Nav.item className='brewTitle'>{this.state.brew.title}</Nav.item>
</Nav.section> </Nav.section>
<Nav.section> <Nav.section>
{this.renderSaveButton()} {this.renderSaveButton()}
{/*<RecentlyEdited brew={this.props.brew} />*/}
<ReportIssue /> <ReportIssue />
<Nav.item newTab={true} href={`/share/${this.props.brew.shareId}`} color='teal' icon='fa-share-alt'> <Nav.item newTab={true} href={`/share/${this.props.brew.shareId}`} color='teal' icon='fa-share-alt'>
Share Share
</Nav.item> </Nav.item>
<PrintLink shareId={this.props.brew.shareId} /> <PrintLink shareId={this.props.brew.shareId} />
<RecentNavItem brew={this.props.brew} storageKey='edit' />
<Account /> <Account />
</Nav.section> </Nav.section>
</Navbar>; </Navbar>;

View File

@@ -7,7 +7,7 @@ const Nav = require('naturalcrit/nav/nav.jsx');
const Navbar = require('../../navbar/navbar.jsx'); const Navbar = require('../../navbar/navbar.jsx');
const PatreonNavItem = require('../../navbar/patreon.navitem.jsx'); const PatreonNavItem = require('../../navbar/patreon.navitem.jsx');
const IssueNavItem = require('../../navbar/issue.navitem.jsx'); const IssueNavItem = require('../../navbar/issue.navitem.jsx');
const RecentNavItem = require('../../navbar/recent.navitem.jsx'); const RecentNavItem = require('../../navbar/recent.navitem.jsx').both;
const BrewRenderer = require('../../brewRenderer/brewRenderer.jsx'); const BrewRenderer = require('../../brewRenderer/brewRenderer.jsx');
@@ -33,7 +33,7 @@ const ErrorPage = createClass({
<Nav.section> <Nav.section>
<PatreonNavItem /> <PatreonNavItem />
<IssueNavItem /> <IssueNavItem />
<RecentNavItem.both errorId={this.props.errorId} /> <RecentNavItem />
</Nav.section> </Nav.section>
</Navbar> </Navbar>

View File

@@ -8,7 +8,7 @@ const Nav = require('naturalcrit/nav/nav.jsx');
const Navbar = require('../../navbar/navbar.jsx'); const Navbar = require('../../navbar/navbar.jsx');
const PatreonNavItem = require('../../navbar/patreon.navitem.jsx'); const PatreonNavItem = require('../../navbar/patreon.navitem.jsx');
const IssueNavItem = require('../../navbar/issue.navitem.jsx'); const IssueNavItem = require('../../navbar/issue.navitem.jsx');
const RecentNavItem = require('../../navbar/recent.navitem.jsx'); const RecentNavItem = require('../../navbar/recent.navitem.jsx').both;
const AccountNavItem = require('../../navbar/account.navitem.jsx'); const AccountNavItem = require('../../navbar/account.navitem.jsx');
@@ -59,7 +59,7 @@ const HomePage = createClass({
<Nav.item newTab={true} href='/changelog' color='purple' icon='fa-file-text-o'> <Nav.item newTab={true} href='/changelog' color='purple' icon='fa-file-text-o'>
Changelog Changelog
</Nav.item> </Nav.item>
<RecentNavItem.both /> <RecentNavItem />
<AccountNavItem /> <AccountNavItem />
{/*} {/*}
<Nav.item href='/new' color='green' icon='fa-external-link'> <Nav.item href='/new' color='green' icon='fa-external-link'>

View File

@@ -9,6 +9,7 @@ const Markdown = require('naturalcrit/markdown.js');
const Nav = require('naturalcrit/nav/nav.jsx'); const Nav = require('naturalcrit/nav/nav.jsx');
const Navbar = require('../../navbar/navbar.jsx'); const Navbar = require('../../navbar/navbar.jsx');
const AccountNavItem = require('../../navbar/account.navitem.jsx'); const AccountNavItem = require('../../navbar/account.navitem.jsx');
const RecentNavItem = require('../../navbar/recent.navitem.jsx').both;
const IssueNavItem = require('../../navbar/issue.navitem.jsx'); const IssueNavItem = require('../../navbar/issue.navitem.jsx');
const SplitPane = require('naturalcrit/splitPane/splitPane.jsx'); const SplitPane = require('naturalcrit/splitPane/splitPane.jsx');
@@ -135,6 +136,7 @@ const NewPage = createClass({
{this.renderSaveButton()} {this.renderSaveButton()}
{this.renderLocalPrintButton()} {this.renderLocalPrintButton()}
<IssueNavItem /> <IssueNavItem />
<RecentNavItem />
<AccountNavItem /> <AccountNavItem />
</Nav.section> </Nav.section>
</Navbar>; </Navbar>;

View File

@@ -7,7 +7,7 @@ const Nav = require('naturalcrit/nav/nav.jsx');
const Navbar = require('../../navbar/navbar.jsx'); const Navbar = require('../../navbar/navbar.jsx');
const PrintLink = require('../../navbar/print.navitem.jsx'); const PrintLink = require('../../navbar/print.navitem.jsx');
const ReportIssue = require('../../navbar/issue.navitem.jsx'); const ReportIssue = require('../../navbar/issue.navitem.jsx');
//const RecentlyViewed = require('../../navbar/recent.navitem.jsx').viewed; const RecentNavItem = require('../../navbar/recent.navitem.jsx').both;
const Account = require('../../navbar/account.navitem.jsx'); const Account = require('../../navbar/account.navitem.jsx');
@@ -53,11 +53,11 @@ const SharePage = createClass({
<Nav.section> <Nav.section>
<ReportIssue /> <ReportIssue />
{/*<RecentlyViewed brew={this.props.brew} />*/}
<PrintLink shareId={this.props.brew.shareId} /> <PrintLink shareId={this.props.brew.shareId} />
<Nav.item href={`/source/${this.props.brew.shareId}`} color='teal' icon='fa-code'> <Nav.item href={`/source/${this.props.brew.shareId}`} color='teal' icon='fa-code'>
source source
</Nav.item> </Nav.item>
<RecentNavItem brew={this.props.brew} storageKey='view' />
<Account /> <Account />
</Nav.section> </Nav.section>
</Navbar> </Navbar>

View File

@@ -6,7 +6,7 @@ const cx = require('classnames');
const Nav = require('naturalcrit/nav/nav.jsx'); const Nav = require('naturalcrit/nav/nav.jsx');
const Navbar = require('../../navbar/navbar.jsx'); const Navbar = require('../../navbar/navbar.jsx');
const RecentNavItem = require('../../navbar/recent.navitem.jsx'); const RecentNavItem = require('../../navbar/recent.navitem.jsx').both;
const Account = require('../../navbar/account.navitem.jsx'); const Account = require('../../navbar/account.navitem.jsx');
const BrewItem = require('./brewItem/brewItem.jsx'); const BrewItem = require('./brewItem/brewItem.jsx');
@@ -57,7 +57,7 @@ const UserPage = createClass({
return <div className='userPage page'> return <div className='userPage page'>
<Navbar> <Navbar>
<Nav.section> <Nav.section>
<RecentNavItem.both /> <RecentNavItem />
<Account /> <Account />
</Nav.section> </Nav.section>
</Navbar> </Navbar>