Merge branch 'production'

This commit is contained in:
HF 2021-05-02 01:50:36 +02:00
commit c39bbbfa7b
12 changed files with 206 additions and 249 deletions

View File

@ -4,39 +4,20 @@
*/ */
import React from 'react'; import React from 'react';
import { connect } from 'react-redux';
import { t } from 'ttag'; import { t } from 'ttag';
import { THREE_CANVAS_HEIGHT } from '../core/constants'; import { THREE_CANVAS_HEIGHT } from '../core/constants';
import { selectCanvas } from '../actions';
const buttonStyle = { const CanvasItem = ({ canvasId, canvas, selCanvas }) => (
marginTop: 8,
marginBottom: 8,
border: '#c5c5c5',
borderStyle: 'solid',
borderRadius: 8,
cursor: 'pointer',
};
const imageStyle = {
maxWidth: '20%',
opacity: 0.3,
padding: 2,
display: 'inline-block',
verticalAlign: 'middle',
};
const CanvasItem = ({ canvasId, canvas, changeCanvas }) => (
<div <div
style={buttonStyle} className="cvbtn"
onClick={() => { changeCanvas(canvasId); }} onClick={() => selCanvas(canvasId)}
role="button" role="button"
tabIndex={0} tabIndex={0}
> >
<img <img
style={imageStyle} className="cvimg"
alt="preview" alt="preview"
src={`/preview${canvasId}.png`} src={`/preview${canvasId}.png`}
/> />
@ -71,12 +52,4 @@ const CanvasItem = ({ canvasId, canvas, changeCanvas }) => (
</div> </div>
); );
function mapDispatchToProps(dispatch) { export default React.memo(CanvasItem);
return {
changeCanvas(canvasId) {
dispatch(selectCanvas(canvasId));
},
};
}
export default connect(null, mapDispatchToProps)(CanvasItem);

View File

@ -4,38 +4,37 @@
*/ */
import React from 'react'; import React from 'react';
import { connect } from 'react-redux'; import { useSelector } from 'react-redux';
import type { State } from '../reducers'; const DailyRankings = () => {
const totalDailyRanking = useSelector(
(state) => state.ranks.totalDailyRanking,
);
const DailyRankings = ({ totalDailyRanking }) => ( return (
<div style={{ overflowY: 'auto', display: 'inline-block' }}> <div style={{ overflowY: 'auto', display: 'inline-block' }}>
<table> <table>
<tr> <tr>
<th>#</th> <th>#</th>
<th>user</th> <th>user</th>
<th>Pixels</th> <th>Pixels</th>
<th># Total</th> <th># Total</th>
<th>Total Pixels</th> <th>Total Pixels</th>
</tr> </tr>
{ {
totalDailyRanking.map((rank) => ( totalDailyRanking.map((rank) => (
<tr> <tr>
<td>{rank.dailyRanking}</td> <td>{rank.dailyRanking}</td>
<td>{rank.name}</td> <td>{rank.name}</td>
<td>{rank.dailyTotalPixels}</td> <td>{rank.dailyTotalPixels}</td>
<td>{rank.ranking}</td> <td>{rank.ranking}</td>
<td>{rank.totalPixels}</td> <td>{rank.totalPixels}</td>
</tr> </tr>
)) ))
} }
</table> </table>
</div> </div>
); );
};
function mapStateToProps(state: State) { export default React.memo(DailyRankings);
const { totalDailyRanking } = state.ranks;
return { totalDailyRanking };
}
export default connect(mapStateToProps)(DailyRankings);

View File

@ -5,17 +5,16 @@
*/ */
import React, { useState, useEffect } from 'react'; import React, { useState, useEffect } from 'react';
import { connect } from 'react-redux'; import { useSelector } from 'react-redux';
import HelpButton from './buttons/HelpButton'; import HelpButton from './buttons/HelpButton';
import SettingsButton from './buttons/SettingsButton'; import SettingsButton from './buttons/SettingsButton';
import LogInButton from './buttons/LogInButton'; import LogInButton from './buttons/LogInButton';
import DownloadButton from './buttons/DownloadButton'; import DownloadButton from './buttons/DownloadButton';
function Menu({ const Menu = () => {
menuOpen,
}) {
const [render, setRender] = useState(false); const [render, setRender] = useState(false);
const menuOpen = useSelector((state) => state.gui.menuOpen);
useEffect(() => { useEffect(() => {
window.setTimeout(() => { window.setTimeout(() => {
@ -40,11 +39,6 @@ function Menu({
</div> </div>
) )
); );
} };
function mapStateToProps(state: State) { export default React.memo(Menu);
const { menuOpen } = state.gui;
return { menuOpen };
}
export default connect(mapStateToProps)(Menu);

View File

@ -3,42 +3,34 @@
* @flow * @flow
*/ */
import React, { useState } from 'react'; import React, { useState, useEffect } from 'react';
import { connect } from 'react-redux'; import { useSelector } from 'react-redux';
import type { State } from '../reducers';
const NotifyBox = ({ notification }) => { const NotifyBox = () => {
const [className, setClassName] = useState('notifybox'); const [className, setClassName] = useState('notifybox');
const [value, setValue] = useState(notification); const notification = useSelector((state) => state.user.notification);
if (notification) { useEffect(() => {
let newClassName = 'notifybox'; if (notification) {
if (notification && typeof notification !== 'string') { let newClassName = 'notifybox';
if (notification > 0) newClassName += ' green'; if (notification && typeof notification !== 'string') {
else newClassName += ' red'; if (notification > 0) newClassName += ' green';
else newClassName += ' red';
}
if (newClassName !== className) {
setClassName(newClassName);
}
} }
if (newClassName !== className) { }, [notification]);
setClassName(newClassName);
}
if (notification !== value) {
setValue(notification);
}
}
return ( return (
<div <div
className={(notification) ? `${className} show` : className} className={(notification) ? `${className} show` : className}
> >
{value} {notification}
</div> </div>
); );
}; };
function mapStateToProps(state: State) { export default React.memo(NotifyBox);
const { notification } = state.user;
return { notification };
}
export default connect(mapStateToProps)(NotifyBox);

View File

@ -4,38 +4,35 @@
*/ */
import React from 'react'; import React from 'react';
import { connect } from 'react-redux'; import { useSelector } from 'react-redux';
import type { State } from '../reducers'; const TotalRankings = () => {
const totalRanking = useSelector((state) => state.ranks.totalRanking);
const TotalRankings = ({ totalRanking }) => ( return (
<div style={{ overflowY: 'auto', display: 'inline-block' }}> <div style={{ overflowY: 'auto', display: 'inline-block' }}>
<table> <table>
<tr> <tr>
<th>#</th> <th>#</th>
<th>user</th> <th>user</th>
<th>Pixels</th> <th>Pixels</th>
<th># Today</th> <th># Today</th>
<th>Pixels Today</th> <th>Pixels Today</th>
</tr> </tr>
{ {
totalRanking.map((rank) => ( totalRanking.map((rank) => (
<tr> <tr>
<td>{rank.ranking}</td> <td>{rank.ranking}</td>
<td>{rank.name}</td> <td>{rank.name}</td>
<td>{rank.totalPixels}</td> <td>{rank.totalPixels}</td>
<td>{rank.dailyRanking}</td> <td>{rank.dailyRanking}</td>
<td>{rank.dailyTotalPixels}</td> <td>{rank.dailyTotalPixels}</td>
</tr> </tr>
)) ))
} }
</table> </table>
</div> </div>
); );
};
function mapStateToProps(state: State) { export default React.memo(TotalRankings);
const { totalRanking } = state.ranks;
return { totalRanking };
}
export default connect(mapStateToProps)(TotalRankings);

View File

@ -4,33 +4,28 @@
*/ */
import React from 'react'; import React from 'react';
import { connect } from 'react-redux'; import { useDispatch } from 'react-redux';
import { FaGlobe } from 'react-icons/fa'; import { FaGlobe } from 'react-icons/fa';
import { t } from 'ttag'; import { t } from 'ttag';
import { showCanvasSelectionModal } from '../../actions'; import { showCanvasSelectionModal } from '../../actions';
const CanvasSwitchButton = ({ open }) => ( const CanvasSwitchButton = () => {
<div const dispatch = useDispatch();
id="canvasbutton"
className="actionbuttons"
onClick={open}
role="button"
title={t`Canvas Selection`}
tabIndex={-1}
>
<FaGlobe />
</div>
);
function mapDispatchToProps(dispatch) { return (
return { <div
open() { id="canvasbutton"
dispatch(showCanvasSelectionModal()); className="actionbuttons"
}, onClick={() => dispatch(showCanvasSelectionModal())}
}; role="button"
} title={t`Canvas Selection`}
tabIndex={-1}
>
<FaGlobe />
</div>
);
};
export default connect(null, export default React.memo(CanvasSwitchButton);
mapDispatchToProps)(CanvasSwitchButton);

View File

@ -5,36 +5,28 @@
*/ */
import React from 'react'; import React from 'react';
import { connect } from 'react-redux'; import { useSelector, useDispatch } from 'react-redux';
import { MdExpandMore, MdExpandLess } from 'react-icons/md'; import { MdExpandMore, MdExpandLess } from 'react-icons/md';
import { t } from 'ttag'; import { t } from 'ttag';
import { toggleOpenMenu } from '../../actions'; import { toggleOpenMenu } from '../../actions';
const ExpandMenuButton = ({ menuOpen, expand }) => ( const ExpandMenuButton = () => {
<div const menuOpen = useSelector((state) => state.gui.menuOpen);
id="menubutton" const dispatch = useDispatch();
className="actionbuttons"
role="button"
title={(menuOpen) ? t`Close Menu` : t`Open Menu`}
tabIndex={-1}
onClick={expand}
>
{(menuOpen) ? <MdExpandLess /> : <MdExpandMore /> }
</div>
);
function mapStateToProps(state: State) { return (
const { menuOpen } = state.gui; <div
return { menuOpen }; id="menubutton"
} className="actionbuttons"
role="button"
title={(menuOpen) ? t`Close Menu` : t`Open Menu`}
tabIndex={-1}
onClick={() => dispatch(toggleOpenMenu())}
>
{(menuOpen) ? <MdExpandLess /> : <MdExpandMore /> }
</div>
);
};
function mapDispatchToProps(dispatch) { export default React.memo(ExpandMenuButton);
return {
expand() {
dispatch(toggleOpenMenu());
},
};
}
export default connect(mapStateToProps, mapDispatchToProps)(ExpandMenuButton);

View File

@ -4,33 +4,28 @@
*/ */
import React from 'react'; import React from 'react';
import { connect } from 'react-redux'; import { useDispatch } from 'react-redux';
import { FaQuestion } from 'react-icons/fa'; import { FaQuestion } from 'react-icons/fa';
import { t } from 'ttag'; import { t } from 'ttag';
import { showHelpModal } from '../../actions'; import { showHelpModal } from '../../actions';
const HelpButton = ({ open }) => ( const HelpButton = () => {
<div const dispatch = useDispatch();
id="helpbutton"
className="actionbuttons"
onClick={open}
role="button"
title={t`Help`}
tabIndex={-1}
>
<FaQuestion />
</div>
);
return (
<div
id="helpbutton"
className="actionbuttons"
onClick={() => dispatch(showHelpModal())}
role="button"
title={t`Help`}
tabIndex={-1}
>
<FaQuestion />
</div>
);
};
function mapDispatchToProps(dispatch) { export default React.memo(HelpButton);
return {
open() {
dispatch(showHelpModal());
},
};
}
export default connect(null, mapDispatchToProps)(HelpButton);

View File

@ -4,32 +4,28 @@
*/ */
import React from 'react'; import React from 'react';
import { connect } from 'react-redux'; import { useDispatch } from 'react-redux';
import { MdPerson } from 'react-icons/md'; import { MdPerson } from 'react-icons/md';
import { t } from 'ttag'; import { t } from 'ttag';
import { showUserAreaModal } from '../../actions'; import { showUserAreaModal } from '../../actions';
const LogInButton = ({ open }) => ( const LogInButton = () => {
<div const dispatch = useDispatch();
id="loginbutton"
className="actionbuttons"
onClick={open}
role="button"
title={t`User Area`}
tabIndex={-1}
>
<MdPerson />
</div>
);
function mapDispatchToProps(dispatch) { return (
return { <div
open() { id="loginbutton"
dispatch(showUserAreaModal()); className="actionbuttons"
}, onClick={() => dispatch(showUserAreaModal())}
}; role="button"
} title={t`User Area`}
tabIndex={-1}
>
<MdPerson />
</div>
);
};
export default connect(null, mapDispatchToProps)(LogInButton); export default React.memo(LogInButton);

View File

@ -4,32 +4,28 @@
*/ */
import React from 'react'; import React from 'react';
import { connect } from 'react-redux'; import { useDispatch } from 'react-redux';
import { FaCog } from 'react-icons/fa'; import { FaCog } from 'react-icons/fa';
import { t } from 'ttag'; import { t } from 'ttag';
import { showSettingsModal } from '../../actions'; import { showSettingsModal } from '../../actions';
const SettingsButton = ({ open }) => ( const SettingsButton = () => {
<div const dispatch = useDispatch();
id="settingsbutton"
className="actionbuttons"
onClick={open}
role="button"
title={t`Settings`}
tabIndex={-1}
>
<FaCog />
</div>
);
function mapDispatchToProps(dispatch) { return (
return { <div
open() { id="settingsbutton"
dispatch(showSettingsModal()); className="actionbuttons"
}, onClick={() => dispatch(showSettingsModal())}
}; role="button"
} title={t`Settings`}
tabIndex={-1}
>
<FaCog />
</div>
);
};
export default connect(null, mapDispatchToProps)(SettingsButton); export default React.memo(SettingsButton);

View File

@ -3,12 +3,12 @@
* @flow * @flow
*/ */
import React from 'react'; import React, { useCallback } from 'react';
import { useDispatch, useSelector, shallowEqual } from 'react-redux'; import { useDispatch, useSelector, shallowEqual } from 'react-redux';
import { t } from 'ttag'; import { t } from 'ttag';
import CanvasItem from '../CanvasItem'; import CanvasItem from '../CanvasItem';
import { changeWindowType } from '../../actions'; import { changeWindowType, selectCanvas } from '../../actions';
const CanvasSelect = ({ windowId }) => { const CanvasSelect = ({ windowId }) => {
@ -17,6 +17,8 @@ const CanvasSelect = ({ windowId }) => {
state.canvas.showHiddenCanvases, state.canvas.showHiddenCanvases,
], shallowEqual); ], shallowEqual);
const dispatch = useDispatch(); const dispatch = useDispatch();
const selCanvas = useCallback((canvasId) => dispatch(selectCanvas(canvasId)),
[dispatch]);
return ( return (
<p style={{ <p style={{
@ -39,9 +41,14 @@ const CanvasSelect = ({ windowId }) => {
</p> </p>
{ {
Object.keys(canvases).map((canvasId) => ( Object.keys(canvases).map((canvasId) => (
(canvases[canvasId].hid && !showHiddenCanvases) (!canvases[canvasId].hid || showHiddenCanvases)
? null && (
: <CanvasItem canvasId={canvasId} canvas={canvases[canvasId]} /> <CanvasItem
canvasId={canvasId}
canvas={canvases[canvasId]}
selCanvas={selCanvas}
/>
)
)) ))
} }
</p> </p>

View File

@ -246,6 +246,27 @@ tr:nth-child(even) {
color: #212121; color: #212121;
} }
.cvbtn {
margin-top: 8px;
margin-bottom: 8px;
border: #c5c5c5;
border-style: solid;
border-radius: 8px;
cursor: pointer;
}
.cvbtn:hover {
background: #c2bebc26;
}
.cvimg {
max-width: 20%;
opacity: 0.3;
padding: 2;
display: inline-block;
vertical-align: middle;
}
.channeldd { .channeldd {
background-color: rgba(226, 226, 226); background-color: rgba(226, 226, 226);
color: #212121; color: #212121;