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

Merge branch 'master' of https://github.com/naturalcrit/homebrewery into scroll-to-element

This commit is contained in:
Víctor Losada Hernández
2024-09-15 16:52:12 +02:00
15 changed files with 430 additions and 283 deletions

View File

@@ -1,7 +1,7 @@
/*eslint max-lines: ["warn", {"max": 300, "skipBlankLines": true, "skipComments": true}]*/
require('./brewRenderer.less');
const React = require('react');
const { useState, useRef, useEffect } = React;
const { useState, useRef, useEffect, useCallback } = React;
const _ = require('lodash');
const MarkdownLegacy = require('naturalcrit/markdownLegacy.js');
@@ -48,23 +48,25 @@ let rawPages = [];
const BrewRenderer = (props)=>{
props = {
text : '',
style : '',
renderer : 'legacy',
theme : '5ePHB',
lang : '',
errors : [],
currentEditorPage : 0,
themeBundle : {},
text : '',
style : '',
renderer : 'legacy',
theme : '5ePHB',
lang : '',
errors : [],
currentEditorCursorPageNum : 0,
currentEditorViewPageNum : 0,
currentBrewRendererPageNum : 0,
themeBundle : {},
onPageChange : ()=>{},
...props
};
const [state, setState] = useState({
height : PAGE_HEIGHT,
isMounted : false,
visibility : 'hidden',
zoom : 100,
currentPageNumber : 1,
height : PAGE_HEIGHT,
isMounted : false,
visibility : 'hidden',
zoom : 100
});
const mainRef = useRef(null);
@@ -157,25 +159,22 @@ const BrewRenderer = (props)=>{
}));
};
const getCurrentPage = (e)=>{
const updateCurrentPage = useCallback(_.throttle((e)=>{
const { scrollTop, clientHeight, scrollHeight } = e.target;
const totalScrollableHeight = scrollHeight - clientHeight;
const currentPageNumber = Math.ceil((scrollTop / totalScrollableHeight) * rawPages.length);
const currentPageNumber = Math.ceil(((scrollTop + 1) / totalScrollableHeight) * rawPages.length);
setState((prevState)=>({
...prevState,
currentPageNumber : currentPageNumber || 1
}));
};
props.onPageChange(currentPageNumber);
}, 200), []);
const isInView = (index)=>{
if(!state.isMounted)
return false;
if(index == props.currentEditorPage) //Already rendered before this step
if(index == props.currentEditorCursorPageNum - 1) //Already rendered before this step
return false;
if(Math.abs(index - state.currentPageNumber) <= 3)
if(Math.abs(index - props.currentBrewRendererPageNum - 1) <= 3)
return true;
return false;
@@ -212,7 +211,7 @@ const BrewRenderer = (props)=>{
renderedPages.length = 0;
// Render currently-edited page first so cross-page effects (variables, links) can propagate out first
renderedPages[props.currentEditorPage] = renderPage(rawPages[props.currentEditorPage], props.currentEditorPage);
renderedPages[props.currentEditorCursorPageNum - 1] = renderPage(rawPages[props.currentEditorCursorPageNum - 1], props.currentEditorCursorPageNum - 1);
_.forEach(rawPages, (page, index)=>{
if((isInView(index) || !renderedPages[index]) && typeof window !== 'undefined'){
@@ -262,7 +261,7 @@ const BrewRenderer = (props)=>{
<>
{/*render dummy page while iFrame is mounting.*/}
{!state.isMounted
? <div className='brewRenderer' onScroll={getCurrentPage}>
? <div className='brewRenderer' onScroll={updateCurrentPage}>
<div className='pages'>
{renderDummyPage(1)}
</div>
@@ -275,7 +274,7 @@ const BrewRenderer = (props)=>{
<NotificationPopup />
</div>
<ToolBar onZoomChange={handleZoom} currentPage={state.currentPageNumber} totalPages={rawPages.length}/>
<ToolBar onZoomChange={handleZoom} currentPage={props.currentBrewRendererPageNum} totalPages={rawPages.length}/>
{/*render in iFrame so broken code doesn't crash the site.*/}
<Frame id='BrewRenderer' initialContent={INITIAL_CONTENT}
@@ -284,7 +283,7 @@ const BrewRenderer = (props)=>{
onClick={()=>{emitClick();}}
>
<div className={'brewRenderer'}
onScroll={getCurrentPage}
onScroll={updateCurrentPage}
onKeyDown={handleControlKeys}
tabIndex={-1}
style={{ height: state.height }}>

View File

@@ -11,6 +11,7 @@ const ToolBar = ({ onZoomChange, currentPage, onPageChange, totalPages })=>{
const [zoomLevel, setZoomLevel] = useState(100);
const [pageNum, setPageNum] = useState(currentPage);
const [toolsVisible, setToolsVisible] = useState(true);
useEffect(()=>{
onZoomChange(zoomLevel);
@@ -66,8 +67,9 @@ const ToolBar = ({ onZoomChange, currentPage, onPageChange, totalPages })=>{
return deltaZoom;
};
return (
<div className='toolBar'>
return (
<div className={`toolBar ${toolsVisible ? 'visible' : 'hidden'}`}>
<button className='toggleButton' title={`${toolsVisible ? 'Hide' : 'Show'} Preview Toolbar`} onClick={()=>{setToolsVisible(!toolsVisible)}}><i className='fas fa-glasses' /></button>
{/*v=====----------------------< Zoom Controls >---------------------=====v*/}
<div className='group'>
<button

View File

@@ -15,6 +15,10 @@
font-family : 'Open Sans', sans-serif;
color : #CCCCCC;
background-color : #555555;
& > *:not(.toggleButton) {
opacity: 1;
transition: all .2s ease;
}
.group {
box-sizing : border-box;
@@ -100,4 +104,25 @@
font-size:1.2em;
}
}
&.hidden {
width: 32px;
transition: all .3s ease;
flex-wrap:nowrap;
overflow: hidden;
background-color: unset;
opacity: .5;
& > *:not(.toggleButton) {
opacity: 0;
transition: all .2s ease;
}
}
}
button.toggleButton {
z-index : 5;
position:absolute;
left: 0;
width: 32px;
min-width: unset;
}