0
0
mirror of https://github.com/naturalcrit/homebrewery.git synced 2026-01-02 17:12:45 +00:00

merge master into google-document-stubs

This commit is contained in:
Charlie Humphreys
2022-04-14 23:31:07 -05:00
20 changed files with 613 additions and 213 deletions

View File

@@ -7,6 +7,8 @@ const request = require('superagent');
const SYSTEMS = ['5e', '4e', '3.5e', 'Pathfinder'];
const homebreweryThumbnail = require('../../thumbnail.png');
const MetadataEditor = createClass({
displayName : 'MetadataEditor',
getDefaultProps : function() {
@@ -25,6 +27,23 @@ const MetadataEditor = createClass({
};
},
getInitialState : function(){
return {
showThumbnail : true
};
},
toggleThumbnailDisplay : function(){
this.setState({
showThumbnail : !this.state.showThumbnail
});
},
renderThumbnail : function(){
if(!this.state.showThumbnail) return;
return <img className='thumbnail-preview' src={this.props.metadata.thumbnail || homebreweryThumbnail}></img>;
},
handleFieldChange : function(name, e){
this.props.onChange(_.merge({}, this.props.metadata, {
[name] : e.target.value
@@ -59,7 +78,7 @@ const MetadataEditor = createClass({
if(!confirm('Are you REALLY sure? You will lose editor access to this document.')) return;
}
request.delete(`/api/${this.props.metadata.googleId}${this.props.metadata.editId}`)
request.delete(`/api/${this.props.metadata.googleId ?? ''}${this.props.metadata.editId}`)
.send()
.end(function(err, res){
window.location.href = '/';
@@ -162,6 +181,18 @@ const MetadataEditor = createClass({
<textarea value={this.props.metadata.description} className='value'
onChange={(e)=>this.handleFieldChange('description', e)} />
</div>
<div className='field thumbnail'>
<label>thumbnail</label>
<input type='text'
value={this.props.metadata.thumbnail}
placeholder='my.thumbnail.url'
className='value'
onChange={(e)=>this.handleFieldChange('thumbnail', e)} />
<button className='display' onClick={this.toggleThumbnailDisplay}>
<i className={`fas fa-caret-${this.state.showThumbnail ? 'right' : 'left'}`} />
</button>
{this.renderThumbnail()}
</div>
{/*}
<div className='field tags'>
<label>tags</label>

View File

@@ -24,6 +24,33 @@
flex : 1 1 auto;
min-width : 200px;
}
&.thumbnail{
height : 1.4em;
label{
line-height: 2.0em;
}
.value{
overflow: hidden;
text-overflow: ellipsis;
}
button{
border: 1px solid #999;
color: white;
padding: 0px 5px;
background-color: black;
&:hover{
background-color: #777;
}
}
.thumbnail-preview{
position : relative;
width : 80px;
height : min-content;
border : 2px solid white;
margin-left : 5px;
max-height : 115px;
}
}
}
.description.field textarea.value{
resize : none;

View File

@@ -33,10 +33,12 @@ const Homebrew = createClass({
};
},
getInitialState : function(){
global.version = this.props.version;
getInitialState : function() {
global.account = this.props.account;
global.version = this.props.version;
global.enable_v3 = this.props.enable_v3;
global.config = this.props.config;
return {};
},
@@ -49,7 +51,7 @@ const Homebrew = createClass({
<Route path='/share/:id' component={(routeProps)=><SharePage id={routeProps.match.params.id} brew={this.props.brew} />}/>
<Route path='/new/:id' component={(routeProps)=><NewPage id={routeProps.match.params.id} brew={this.props.brew} />}/>
<Route path='/new' exact component={(routeProps)=><NewPage />}/>
<Route path='/user/:username' component={(routeProps)=><UserPage username={routeProps.match.params.username} brews={this.props.brews} />}/>
<Route path='/user/:username' component={(routeProps)=><UserPage username={routeProps.match.params.username} brews={this.props.brews} query={queryString.parse(routeProps.location.search)}/>}/>
<Route path='/print/:id' component={(routeProps)=><PrintPage brew={this.props.brew} query={queryString.parse(routeProps.location.search)} />}/>
<Route path='/print' exact component={(routeProps)=><PrintPage query={queryString.parse(routeProps.location.search)} />}/>
<Route path='/changelog' exact component={()=><SharePage brew={this.props.brew} />}/>

View File

@@ -1,6 +1,7 @@
const React = require('react');
const createClass = require('create-react-class');
const Nav = require('naturalcrit/nav/nav.jsx');
const request = require('superagent');
const Account = createClass({
displayName : 'AccountNavItem',
@@ -36,7 +37,29 @@ const Account = createClass({
}
},
localLogin : async function(){
const username = prompt('Enter username:');
if(!username) {return;}
const expiry = new Date;
expiry.setFullYear(expiry.getFullYear() + 1);
const token = await request.post('/local/login')
.send({ username })
.then((response)=>{
return response.body;
})
.catch((err)=>{
console.warn(err);
});
if(!token) return;
document.cookie = `nc_session=${token};expires=${expiry};path=/;samesite=lax;${window.domain ? `domain=${window.domain}` : ''}`;
window.location.reload(true);
},
render : function(){
// Logged in
if(global.account){
return <Nav.dropdown>
<Nav.item
@@ -64,6 +87,16 @@ const Account = createClass({
</Nav.dropdown>;
}
// Logged out
// LOCAL ONLY
if(global.config.local) {
return <Nav.item color='teal' icon='fas fa-sign-in-alt' onClick={this.localLogin}>
login
</Nav.item>;
};
// Logged out
// Production site
return <Nav.item href={`https://www.naturalcrit.com/login?redirect=${this.state.url}`} color='teal' icon='fas fa-sign-in-alt'>
login
</Nav.item>;

View File

@@ -31,7 +31,7 @@ const BrewItem = createClass({
if(!confirm('Are you REALLY sure? You will lose editor access to this document.')) return;
}
request.delete(`/api/${this.props.brew.googleId}${this.props.brew.editId}`)
request.delete(`/api/${this.props.brew.googleId ?? ''}${this.props.brew.editId}`)
.send()
.end(function(err, res){
location.reload();

View File

@@ -24,7 +24,8 @@ const ListPage = createClass({
return {
sortType : 'alpha',
sortDir : 'asc',
filterString : ''
filterString : this.props.query?.filter || '',
query : this.props.query
};
},
@@ -74,19 +75,35 @@ const ListPage = createClass({
handleFilterTextChange : function(e){
this.setState({
filterString : e.target.value
filterString : e.target.value,
});
this.updateUrl(e.target.value);
return;
},
updateUrl : function(filterTerm){
const url = new URL(window.location.href);
const urlParams = new URLSearchParams(url.search);
if(urlParams.get('filter') == filterTerm)
return;
if(!filterTerm)
urlParams.delete('filter');
else
urlParams.set('filter', filterTerm);
url.search = urlParams;
window.history.replaceState(null, null, url);
},
renderFilterOption : function(){
return <td>
<label>
<i className='fas fa-search'></i>
<input
type='search'
placeholder='search title/description'
autoFocus={true}
placeholder='filter title/description'
onChange={this.handleFilterTextChange}
value={this.state.filterString}
/>
</label>
</td>;

View File

@@ -19,6 +19,7 @@ const UserPage = createClass({
return {
username : '',
brews : [],
query : ''
};
},
getInitialState : function() {
@@ -62,7 +63,7 @@ const UserPage = createClass({
},
render : function(){
return <ListPage brewCollection={this.state.brewCollection} navItems={this.navItems()}></ListPage>;
return <ListPage brewCollection={this.state.brewCollection} navItems={this.navItems()} query={this.props.query}></ListPage>;
}
});

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.9 KiB

View File

@@ -1,4 +1,6 @@
module.exports = async(name, title = '', props = {})=>{
const HOMEBREWERY_PUBLIC_URL=props.publicUrl;
return `
<!DOCTYPE html>
<html>
@@ -7,6 +9,13 @@ module.exports = async(name, title = '', props = {})=>{
<link href="//fonts.googleapis.com/css?family=Open+Sans:400,300,600,700" rel="stylesheet" type="text/css" />
<link href=${`/${name}/bundle.css`} rel='stylesheet' />
<link rel="icon" href="/assets/homebrew/favicon.ico" type="image/x-icon" />
<meta property="og:title" content="${props.brew?.title ?? 'Homebrewery - Untitled Brew'}">
<meta property="og:url" content="${HOMEBREWERY_PUBLIC_URL}/${props.brew?.shareId ? `share/${props.brew.shareId}` : ''}">
<meta property="og:image" content="${props.brew?.thumbnail ?? `${HOMEBREWERY_PUBLIC_URL}/thumbnail.png`}">
<meta property="og:description" content="${props.brew?.description ?? 'No description.'}">
<meta property="og:site_name" content="The Homebrewery - Make your Homebrew content look legit!">
<meta property="og:type" content="website">
<meta name="twitter:card" content="summary_large_image">
<title>${title.length ? `${title} - The Homebrewery`: 'The Homebrewery - NaturalCrit'}</title>
</head>
<body>