From 41fdf48ad357ab499986c498292c255525026253 Mon Sep 17 00:00:00 2001 From: Gazook89 Date: Mon, 21 Oct 2024 00:30:45 -0500 Subject: [PATCH 01/36] Setup Intersection Observers & more... Bad commit here with too much stuff. I apologize. This sets up two Intersection Observers: the first captures every page that is at least 30% visible inside the `.pages` container, and the second captures every page that has at least one pixel on the horizontal center line of `.pages`. Both can be arrays of integers (page index). The "visiblePages" array is duplicated and formatted into a "formattedPages" state, which gets displayed in the toolbar. The toolbar displays that, unless the user clicks into the page input and enters their own integer (only a single integer, no range), which can then jump the preview to that page on Enter or blur(). The Arrow 'change page' buttons jump the preview back and forth by a 'full set'. If one page is viewed at a time, this is moved on page a time, and if 10 pages are viewed at a time it jumps the pages by 10. Left to do: adapt the "jump editor to match preview" divider button to work with new "centerPage". --- client/homebrew/brewRenderer/brewRenderer.jsx | 133 ++++++++++++++---- .../homebrew/brewRenderer/toolBar/toolBar.jsx | 24 +++- .../brewRenderer/toolBar/toolBar.less | 2 +- 3 files changed, 126 insertions(+), 33 deletions(-) diff --git a/client/homebrew/brewRenderer/brewRenderer.jsx b/client/homebrew/brewRenderer/brewRenderer.jsx index 48f155820..1b30c0ae5 100644 --- a/client/homebrew/brewRenderer/brewRenderer.jsx +++ b/client/homebrew/brewRenderer/brewRenderer.jsx @@ -1,7 +1,7 @@ /*eslint max-lines: ["warn", {"max": 300, "skipBlankLines": true, "skipComments": true}]*/ require('./brewRenderer.less'); const React = require('react'); -const { useState, useRef, useCallback } = React; +const { useState, useRef, useCallback, useEffect } = React; const _ = require('lodash'); const MarkdownLegacy = require('naturalcrit/markdownLegacy.js'); @@ -30,14 +30,47 @@ const INITIAL_CONTENT = dedent`
`; //v=====----------------------< Brew Page Component >---------------------=====v// -const BrewPage = (props)=>{ - props = { - contents : '', - index : 0, - ...props - }; - const cleanText = props.contents; //DOMPurify.sanitize(props.contents, purifyConfig); - return
+const BrewPage = ({contents = '', index = 0, onVisibilityChange, onCenterPageChange, ...props})=>{ + const pageRef = useRef(null); + const cleanText = contents; //DOMPurify.sanitize(props.contents, purifyConfig); + + useEffect(()=>{ + if(!pageRef.current) return; + const observer = new IntersectionObserver( + (entries)=>{ + entries.forEach((entry)=>{ + if(entry.isIntersecting){ + onVisibilityChange(index + 1, true); + } else { + onVisibilityChange(index + 1, false); + } + }); + }, + { threshold: .3, rootMargin: '0px 0px 0px 0px' } + ); + + // Observer for tracking the page at the center of the iframe. + const centerObserver = new IntersectionObserver( + (entries) => { + entries.forEach((entry) => { + if (entry.isIntersecting) { + onCenterPageChange(index + 1); // Set this page as the center page + } + }); + }, + { threshold: 0, rootMargin: '-50% 0px -50% 0px' } // Detect when the page is at the center + ); + + observer.observe(pageRef.current); + centerObserver.observe(pageRef.current); + + return ()=>{ + observer.disconnect(); + centerObserver.disconnect(); + }; + }, [index, onVisibilityChange, onCenterPageChange]); + + return
; }; @@ -64,11 +97,14 @@ const BrewRenderer = (props)=>{ }; const [state, setState] = useState({ - isMounted : false, - visibility : 'hidden', - zoom : 100 + isMounted : false, + visibility : 'hidden', + zoom : 100, + visiblePages : [], + formattedPages : '', + centerPage : 1 }); - + const iframeRef = useRef(null); const mainRef = useRef(null); if(props.renderer == 'legacy') { @@ -77,13 +113,54 @@ const BrewRenderer = (props)=>{ rawPages = props.text.split(/^\\page$/gm); } - const updateCurrentPage = useCallback(_.throttle((e)=>{ - const { scrollTop, clientHeight, scrollHeight } = e.target; - const totalScrollableHeight = scrollHeight - clientHeight; - const currentPageNumber = Math.max(Math.ceil((scrollTop / totalScrollableHeight) * rawPages.length), 1); + useEffect(() => { + props.onPageChange(formatVisiblePages(state.visiblePages)); + }, [state.visiblePages]); - props.onPageChange(currentPageNumber); - }, 200), []); + const handlePageVisibilityChange = useCallback((pageNum, isVisible) => { + setState((prevState) => { + let updatedVisiblePages = new Set(prevState.visiblePages); + if(isVisible){ + updatedVisiblePages.add(pageNum) + } else { + updatedVisiblePages.delete(pageNum) + } + const pages = Array.from(updatedVisiblePages); + + return { ...prevState, + visiblePages : _.sortBy(pages), + formattedPages : formatVisiblePages(pages) + }; + }); + }, []); + + const formatVisiblePages = (pages) => { + if (pages.length === 0) return ''; + + const sortedPages = [...pages].sort((a, b) => a - b); // Copy and sort the array + let ranges = []; + let start = sortedPages[0]; + + for (let i = 1; i <= sortedPages.length; i++) { + // If the current page is not consecutive or it's the end of the list + if (i === sortedPages.length || sortedPages[i] !== sortedPages[i - 1] + 1) { + // Push the range to the list + ranges.push( + start === sortedPages[i - 1] ? `${start}` : `${start} - ${sortedPages[i - 1]}` + ); + start = sortedPages[i]; // Start a new range + } + } + + return ranges.join(', '); + }; + + const handleCenterPageChange = useCallback((pageNum) => { + setState((prevState) => ({ + ...prevState, + centerPage : pageNum, + })); + }, []); const isInView = (index)=>{ if(!state.isMounted) @@ -113,11 +190,11 @@ const BrewRenderer = (props)=>{ const renderPage = (pageText, index)=>{ if(props.renderer == 'legacy') { const html = MarkdownLegacy.render(pageText); - return ; + return ; } else { pageText += `\n\n \n\\column\n `; //Artificial column break at page end to emulate column-fill:auto (until `wide` is used, when column-fill:balance will reappear) const html = Markdown.render(pageText, index); - return ; + return ; } }; @@ -183,7 +260,9 @@ const BrewRenderer = (props)=>{ <> {/*render dummy page while iFrame is mounting.*/} {!state.isMounted - ?
+ ?
{renderDummyPage(1)}
@@ -196,7 +275,7 @@ const BrewRenderer = (props)=>{
- + {/*render in iFrame so broken code doesn't crash the site.*/} { onClick={()=>{emitClick();}} >
+ style={ styleObject } + > {/* Apply CSS from Style tab and render pages from Markdown tab */} {state.isMounted && <> {renderStyle()} -
+
{renderPages()}
diff --git a/client/homebrew/brewRenderer/toolBar/toolBar.jsx b/client/homebrew/brewRenderer/toolBar/toolBar.jsx index 73b48d778..f3ee3a11a 100644 --- a/client/homebrew/brewRenderer/toolBar/toolBar.jsx +++ b/client/homebrew/brewRenderer/toolBar/toolBar.jsx @@ -7,12 +7,20 @@ const _ = require('lodash'); const MAX_ZOOM = 300; const MIN_ZOOM = 10; -const ToolBar = ({ onZoomChange, currentPage, onPageChange, totalPages })=>{ +const ToolBar = ({ onZoomChange, currentPage, visiblePages, formattedPages, centerPage, totalPages })=>{ const [zoomLevel, setZoomLevel] = useState(100); - const [pageNum, setPageNum] = useState(currentPage); + const [pageNum, setPageNum] = useState(null); const [toolsVisible, setToolsVisible] = useState(true); + useEffect(()=>{ + setPageNum(visiblePages[0]); + }, []); + + useEffect(()=>{ + setPageNum(formattedPages); + }, [visiblePages]); + useEffect(()=>{ onZoomChange(zoomLevel); }, [zoomLevel]); @@ -26,17 +34,21 @@ const ToolBar = ({ onZoomChange, currentPage, onPageChange, totalPages })=>{ }; const handlePageInput = (pageInput)=>{ + console.log(pageInput); if(/[0-9]/.test(pageInput)) setPageNum(parseInt(pageInput)); // input type is 'text', so `page` comes in as a string, not number. }; const scrollToPage = (pageNumber)=>{ + console.log('visiblePages:', visiblePages); + console.log('centerPage:', centerPage); + console.log('pageNumber:', pageNumber); + if(typeof pageNumber !== 'number') return; pageNumber = _.clamp(pageNumber, 1, totalPages); const iframe = document.getElementById('BrewRenderer'); const brewRenderer = iframe?.contentWindow?.document.querySelector('.brewRenderer'); const page = brewRenderer?.querySelector(`#p${pageNumber}`); page?.scrollIntoView({ block: 'start' }); - setPageNum(pageNumber); }; @@ -125,7 +137,7 @@ const ToolBar = ({ onZoomChange, currentPage, onPageChange, totalPages })=>{ From 26050e21342b2371c748cf1c58dbff3843b3dbe7 Mon Sep 17 00:00:00 2001 From: Gazook89 Date: Mon, 21 Oct 2024 22:20:52 -0500 Subject: [PATCH 07/36] add comment --- client/homebrew/brewRenderer/toolBar/toolBar.jsx | 1 + 1 file changed, 1 insertion(+) diff --git a/client/homebrew/brewRenderer/toolBar/toolBar.jsx b/client/homebrew/brewRenderer/toolBar/toolBar.jsx index 61183a083..1fcdceecb 100644 --- a/client/homebrew/brewRenderer/toolBar/toolBar.jsx +++ b/client/homebrew/brewRenderer/toolBar/toolBar.jsx @@ -71,6 +71,7 @@ const ToolBar = ({ onZoomChange, visiblePages, totalPages })=>{ return deltaZoom; }; + // format the visible pages to work with ranges, including separate ranges ("2-7, 10-15") const formatVisiblePages = (pages)=>{ if(pages.length === 0) return ''; From 4126188df12b5c0d76fe8108927567c3f1309ee9 Mon Sep 17 00:00:00 2001 From: Gazook89 Date: Mon, 21 Oct 2024 22:29:58 -0500 Subject: [PATCH 08/36] linting --- client/homebrew/brewRenderer/brewRenderer.jsx | 10 +++--- .../brewRenderer/toolBar/toolBar.less | 34 +++++++++---------- 2 files changed, 21 insertions(+), 23 deletions(-) diff --git a/client/homebrew/brewRenderer/brewRenderer.jsx b/client/homebrew/brewRenderer/brewRenderer.jsx index c846d4d63..2177e224e 100644 --- a/client/homebrew/brewRenderer/brewRenderer.jsx +++ b/client/homebrew/brewRenderer/brewRenderer.jsx @@ -99,11 +99,11 @@ const BrewRenderer = (props)=>{ }; const [state, setState] = useState({ - isMounted : false, - visibility : 'hidden', - zoom : 100, - visiblePages : [], - centerPage : 1 + isMounted : false, + visibility : 'hidden', + zoom : 100, + visiblePages : [], + centerPage : 1 }); const iframeRef = useRef(null); const mainRef = useRef(null); diff --git a/client/homebrew/brewRenderer/toolBar/toolBar.less b/client/homebrew/brewRenderer/toolBar/toolBar.less index 4cc125aad..86ea769f6 100644 --- a/client/homebrew/brewRenderer/toolBar/toolBar.less +++ b/client/homebrew/brewRenderer/toolBar/toolBar.less @@ -16,8 +16,8 @@ color : #CCCCCC; background-color : #555555; & > *:not(.toggleButton) { - opacity: 1; - transition: all .2s ease; + opacity : 1; + transition : all 0.2s ease; } .group { @@ -100,29 +100,27 @@ color : #777777; background-color : unset !important; } - i { - font-size:1.2em; - } + i { font-size : 1.2em; } } &.hidden { - width: 32px; - transition: all .3s ease; - flex-wrap:nowrap; - overflow: hidden; - background-color: unset; - opacity: .5; + flex-wrap : nowrap; + width : 32px; + overflow : hidden; + background-color : unset; + opacity : 0.5; + transition : all 0.3s ease; & > *:not(.toggleButton) { - opacity: 0; - transition: all .2s ease; + opacity : 0; + transition : all 0.2s ease; } } } button.toggleButton { - z-index : 5; - position:absolute; - left: 0; - width: 32px; - min-width: unset; + position : absolute; + left : 0; + z-index : 5; + width : 32px; + min-width : unset; } \ No newline at end of file From 5ab867f21efd2ecd85e70b0ceabc97ade360c7c8 Mon Sep 17 00:00:00 2001 From: Gazook89 Date: Tue, 22 Oct 2024 22:36:13 -0500 Subject: [PATCH 09/36] adjust prev/next page buttons to meet expectations i hope --- client/homebrew/brewRenderer/toolBar/toolBar.jsx | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/client/homebrew/brewRenderer/toolBar/toolBar.jsx b/client/homebrew/brewRenderer/toolBar/toolBar.jsx index 1fcdceecb..291b33352 100644 --- a/client/homebrew/brewRenderer/toolBar/toolBar.jsx +++ b/client/homebrew/brewRenderer/toolBar/toolBar.jsx @@ -43,7 +43,6 @@ const ToolBar = ({ onZoomChange, visiblePages, totalPages })=>{ page?.scrollIntoView({ block: 'start' }); }; - const calculateChange = (mode)=>{ const iframe = document.getElementById('BrewRenderer'); const iframeWidth = iframe.getBoundingClientRect().width; @@ -151,7 +150,10 @@ const ToolBar = ({ onZoomChange, visiblePages, totalPages })=>{
- + 0 ? state.visiblePages : [state.centerPage]} totalPages={rawPages.length}/> {/*render in iFrame so broken code doesn't crash the site.*/} { - console.log(pageInput); if(/[0-9]/.test(pageInput)) setPageNum(parseInt(pageInput)); // input type is 'text', so `page` comes in as a string, not number. }; From 9ef11bca999ce9f7f102ac1132911f2650356851 Mon Sep 17 00:00:00 2001 From: Gazook89 Date: Thu, 7 Nov 2024 10:40:44 -0600 Subject: [PATCH 18/36] lint and refactor --- client/homebrew/brewRenderer/brewRenderer.jsx | 21 +++++++------------ .../homebrew/brewRenderer/toolBar/toolBar.jsx | 10 ++++----- 2 files changed, 12 insertions(+), 19 deletions(-) diff --git a/client/homebrew/brewRenderer/brewRenderer.jsx b/client/homebrew/brewRenderer/brewRenderer.jsx index e9e3da8a6..3108176b4 100644 --- a/client/homebrew/brewRenderer/brewRenderer.jsx +++ b/client/homebrew/brewRenderer/brewRenderer.jsx @@ -128,23 +128,14 @@ const BrewRenderer = (props)=>{ rawPages = props.text.split(/^\\page$/gm); } - // update centerPage (aka "current page") and pass it up to parent components - useEffect(()=>{ - props.onPageChange(state.centerPage); - }, [state.centerPage]); - const handlePageVisibilityChange = useCallback((pageNum, isVisible)=>{ setState((prevState)=>{ const updatedVisiblePages = new Set(prevState.visiblePages); - if(isVisible){ - updatedVisiblePages.add(pageNum); - } else { - updatedVisiblePages.delete(pageNum); - } - const pages = Array.from(updatedVisiblePages); + isVisible ? updatedVisiblePages.add(pageNum) : updatedVisiblePages.delete(pageNum); - return { ...prevState, - visiblePages : _.sortBy(pages) + return { + ...prevState, + visiblePages : [...updatedVisiblePages].sort((a, b)=>a - b) }; }); }, []); @@ -154,7 +145,9 @@ const BrewRenderer = (props)=>{ ...prevState, centerPage : pageNum, })); - }, []); + + props.onPageChange(pageNum); + }, [props.onPageChange]); const isInView = (index)=>{ if(!state.isMounted) diff --git a/client/homebrew/brewRenderer/toolBar/toolBar.jsx b/client/homebrew/brewRenderer/toolBar/toolBar.jsx index 89c341345..5fa9f0588 100644 --- a/client/homebrew/brewRenderer/toolBar/toolBar.jsx +++ b/client/homebrew/brewRenderer/toolBar/toolBar.jsx @@ -66,7 +66,7 @@ const ToolBar = ({ displayOptions, onDisplayOptionsChange, visiblePages, totalPa } else { minDimRatio = [...pages].reduce((minRatio, page)=>Math.min(minRatio, iframeWidth / page.offsetWidth, iframeHeight / page.offsetHeight), Infinity); } - console.log(minDimRatio) + console.log(minDimRatio); desiredZoom = minDimRatio * 100; } @@ -249,14 +249,14 @@ const ToolBar = ({ displayOptions, onDisplayOptionsChange, visiblePages, totalPa title='Next Page(s)' onClick={()=>{ // if there are multiple pages in a 'row' and they are in 'view', - // then the 'max'/last page in view will always be the same, and + // then the 'max'/last page in view will always be the same, and // the other pages will always be the same (since the viewport doesn't change). - // So this needs to scroll to the 'max', then see what is newly in view, + // So this needs to scroll to the 'max', then see what is newly in view, // and if the same pages are visible, do it again but +1. - const start = _.max(visiblePages); + const start = _.max(visiblePages); scrollToPage(start); if(start === _.max(visiblePages)){ - scrollToPage(start + 1) + scrollToPage(start + 1); }; }} disabled={pageNum >= totalPages} From 650ec0441761de46fcd9d6cbe9ca763780f875cf Mon Sep 17 00:00:00 2001 From: Gazook89 Date: Thu, 7 Nov 2024 18:56:19 -0600 Subject: [PATCH 19/36] fix 'disabled' attribute on min/max of page range --- client/homebrew/brewRenderer/toolBar/toolBar.jsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/client/homebrew/brewRenderer/toolBar/toolBar.jsx b/client/homebrew/brewRenderer/toolBar/toolBar.jsx index 5fa9f0588..c83ef59a6 100644 --- a/client/homebrew/brewRenderer/toolBar/toolBar.jsx +++ b/client/homebrew/brewRenderer/toolBar/toolBar.jsx @@ -219,7 +219,7 @@ const ToolBar = ({ displayOptions, onDisplayOptionsChange, visiblePages, totalPa const rangeOffset = visiblePages.length > 1 ? 1 : 0; scrollToPage(_.min(visiblePages) - visiblePages.length + rangeOffset); }} - disabled={pageNum <= 1} + disabled={visiblePages.includes(1)} > @@ -259,7 +259,7 @@ const ToolBar = ({ displayOptions, onDisplayOptionsChange, visiblePages, totalPa scrollToPage(start + 1); }; }} - disabled={pageNum >= totalPages} + disabled={visiblePages.includes(totalPages)} > From 28855d02a647e6ec55792ae0edd89276e97badfe Mon Sep 17 00:00:00 2001 From: Gazook89 Date: Thu, 7 Nov 2024 19:46:07 -0600 Subject: [PATCH 20/36] dynamic text input width to match characters --- client/homebrew/brewRenderer/toolBar/toolBar.jsx | 1 + client/homebrew/brewRenderer/toolBar/toolBar.less | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/client/homebrew/brewRenderer/toolBar/toolBar.jsx b/client/homebrew/brewRenderer/toolBar/toolBar.jsx index c83ef59a6..c2486c095 100644 --- a/client/homebrew/brewRenderer/toolBar/toolBar.jsx +++ b/client/homebrew/brewRenderer/toolBar/toolBar.jsx @@ -238,6 +238,7 @@ const ToolBar = ({ displayOptions, onDisplayOptionsChange, visiblePages, totalPa onChange={(e)=>handlePageInput(e.target.value)} onBlur={()=>scrollToPage(pageNum)} onKeyDown={(e)=>e.key == 'Enter' && scrollToPage(pageNum)} + style={{ width: `${pageNum.length}ch` }} /> / {totalPages}
diff --git a/client/homebrew/brewRenderer/toolBar/toolBar.less b/client/homebrew/brewRenderer/toolBar/toolBar.less index 27989cff6..dfbd7a20d 100644 --- a/client/homebrew/brewRenderer/toolBar/toolBar.less +++ b/client/homebrew/brewRenderer/toolBar/toolBar.less @@ -140,7 +140,7 @@ // `.text-input` if generic to all range inputs, or `#page-input` if only for current page input &#page-input { - width : 10ch; + min-width : 5ch; margin-right : 1ch; text-align : center; } From 28a7f249890053d616f3035b03ef954aa202eced Mon Sep 17 00:00:00 2001 From: Gazook89 Date: Thu, 7 Nov 2024 20:32:30 -0600 Subject: [PATCH 21/36] add scrollToHash method back in pretty much completely unchanged, was originally moved just to help with merging master in (ie it was erroneously removed) --- client/homebrew/brewRenderer/brewRenderer.jsx | 21 +++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/client/homebrew/brewRenderer/brewRenderer.jsx b/client/homebrew/brewRenderer/brewRenderer.jsx index 3108176b4..795095f71 100644 --- a/client/homebrew/brewRenderer/brewRenderer.jsx +++ b/client/homebrew/brewRenderer/brewRenderer.jsx @@ -221,7 +221,28 @@ const BrewRenderer = (props)=>{ } }; + const scrollToHash = (hash)=>{ + if(!hash) return; + + const iframeDoc = document.getElementById('BrewRenderer').contentDocument; + let anchor = iframeDoc.querySelector(hash); + + if(anchor) { + anchor.scrollIntoView({ behavior: 'smooth' }); + } else { + // Use MutationObserver to wait for the element if it's not immediately available + new MutationObserver((mutations, obs)=>{ + anchor = iframeDoc.querySelector(hash); + if(anchor) { + anchor.scrollIntoView({ behavior: 'smooth' }); + obs.disconnect(); + } + }).observe(iframeDoc, { childList: true, subtree: true }); + } + }; + const frameDidMount = ()=>{ //This triggers when iFrame finishes internal "componentDidMount" + scrollToHash(window.location.hash); setTimeout(()=>{ //We still see a flicker where the style isn't applied yet, so wait 100ms before showing iFrame renderPages(); //Make sure page is renderable before showing From aa951ff96cdcacc3f2845ba641f990799913929f Mon Sep 17 00:00:00 2001 From: Trevor Buckner Date: Mon, 9 Dec 2024 17:04:16 -0500 Subject: [PATCH 22/36] Small cleanups --- client/homebrew/brewRenderer/brewRenderer.jsx | 8 +++----- client/homebrew/brewRenderer/toolBar/toolBar.jsx | 13 +++++-------- 2 files changed, 8 insertions(+), 13 deletions(-) diff --git a/client/homebrew/brewRenderer/brewRenderer.jsx b/client/homebrew/brewRenderer/brewRenderer.jsx index 879af2a9a..7792742cd 100644 --- a/client/homebrew/brewRenderer/brewRenderer.jsx +++ b/client/homebrew/brewRenderer/brewRenderer.jsx @@ -32,10 +32,8 @@ const INITIAL_CONTENT = dedent` //v=====----------------------< Brew Page Component >---------------------=====v// const BrewPage = (props)=>{ props = { - contents : '', - index : 0, - onVisibilityChange : ()=>{}, - onCenterPageChange : ()=>{}, + contents : '', + index : 0, ...props }; const pageRef = useRef(null); @@ -77,7 +75,7 @@ const BrewPage = (props)=>{ visibleObserver.disconnect(); centerObserver.disconnect(); }; - }, [props.index, props.onVisibilityChange, props.onCenterPageChange]); + }, []); return
diff --git a/client/homebrew/brewRenderer/toolBar/toolBar.jsx b/client/homebrew/brewRenderer/toolBar/toolBar.jsx index c2486c095..9257660d1 100644 --- a/client/homebrew/brewRenderer/toolBar/toolBar.jsx +++ b/client/homebrew/brewRenderer/toolBar/toolBar.jsx @@ -25,7 +25,6 @@ const ToolBar = ({ displayOptions, onDisplayOptionsChange, visiblePages, totalPa }; const handleOptionChange = (optionKey, newValue)=>{ - //setDisplayOptions(prevOptions => ({ ...prevOptions, [optionKey]: newValue })); onDisplayOptionsChange({ ...displayOptions, [optionKey]: newValue }); }; @@ -61,12 +60,10 @@ const ToolBar = ({ displayOptions, onDisplayOptionsChange, visiblePages, totalPa } else if(mode == 'fit'){ let minDimRatio; // find the page with the largest single dim (height or width) so that zoom can be adapted to fit it. - if(displayOptions.spread === 'facing'){ + if(displayOptions.spread === 'facing') minDimRatio = [...pages].reduce((minRatio, page)=>Math.min(minRatio, iframeWidth / page.offsetWidth / 2), Infinity); // if 'facing' spread, fit two pages in view - } else { + else minDimRatio = [...pages].reduce((minRatio, page)=>Math.min(minRatio, iframeWidth / page.offsetWidth, iframeHeight / page.offsetHeight), Infinity); - } - console.log(minDimRatio); desiredZoom = minDimRatio * 100; } @@ -86,9 +83,8 @@ const ToolBar = ({ displayOptions, onDisplayOptionsChange, visiblePages, totalPa let start = sortedPages[0]; for (let i = 1; i <= sortedPages.length; i++) { - // If the current page is not consecutive or it's the end of the list + // If the current page is the end of the list or not consecutive if(i === sortedPages.length || sortedPages[i] !== sortedPages[i - 1] + 1) { - // Push the range to the list ranges.push( start === sortedPages[i - 1] ? `${start}` : `${start} - ${sortedPages[i - 1]}` ); @@ -233,7 +229,7 @@ const ToolBar = ({ displayOptions, onDisplayOptionsChange, visiblePages, totalPa title='Current page(s) in view' inputMode='numeric' pattern='[0-9]' - value={`${pageNum}`} + value={pageNum} onClick={(e)=>e.target.select()} onChange={(e)=>handlePageInput(e.target.value)} onBlur={()=>scrollToPage(pageNum)} @@ -257,6 +253,7 @@ const ToolBar = ({ displayOptions, onDisplayOptionsChange, visiblePages, totalPa const start = _.max(visiblePages); scrollToPage(start); if(start === _.max(visiblePages)){ + console.log("oh no") scrollToPage(start + 1); }; }} From 870a4c33637c248af1f59e6e386f48f4ade2d2e0 Mon Sep 17 00:00:00 2001 From: Trevor Buckner Date: Mon, 9 Dec 2024 17:06:26 -0500 Subject: [PATCH 23/36] small cleanups --- client/homebrew/brewRenderer/brewRenderer.jsx | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/client/homebrew/brewRenderer/brewRenderer.jsx b/client/homebrew/brewRenderer/brewRenderer.jsx index 7792742cd..4606529f0 100644 --- a/client/homebrew/brewRenderer/brewRenderer.jsx +++ b/client/homebrew/brewRenderer/brewRenderer.jsx @@ -46,11 +46,10 @@ const BrewPage = (props)=>{ const visibleObserver = new IntersectionObserver( (entries)=>{ entries.forEach((entry)=>{ - if(entry.isIntersecting){ + if(entry.isIntersecting) props.onVisibilityChange(props.index + 1, true); // add page to array of visible pages. - } else { + else props.onVisibilityChange(props.index + 1, false); - } }); }, { threshold: .3, rootMargin: '0px 0px 0px 0px' } // detect when >30% of page is within bounds. @@ -60,9 +59,8 @@ const BrewPage = (props)=>{ const centerObserver = new IntersectionObserver( (entries)=>{ entries.forEach((entry)=>{ - if(entry.isIntersecting) { + if(entry.isIntersecting) props.onCenterPageChange(props.index + 1); // Set this page as the center page - } }); }, { threshold: 0, rootMargin: '-50% 0px -50% 0px' } // Detect when the page is at the center From a53eacf05522427b9bff50cbf857c7d102d463b9 Mon Sep 17 00:00:00 2001 From: Trevor Buckner Date: Mon, 23 Dec 2024 17:17:13 -0500 Subject: [PATCH 24/36] remove CenterPage from ToolBar props centerPage is not used in the toolbar component. --- client/homebrew/brewRenderer/brewRenderer.jsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/homebrew/brewRenderer/brewRenderer.jsx b/client/homebrew/brewRenderer/brewRenderer.jsx index 4606529f0..453892b1b 100644 --- a/client/homebrew/brewRenderer/brewRenderer.jsx +++ b/client/homebrew/brewRenderer/brewRenderer.jsx @@ -292,7 +292,7 @@ const BrewRenderer = (props)=>{
- 0 ? state.visiblePages : [state.centerPage]} totalPages={rawPages.length}/> + 0 ? state.visiblePages : [state.centerPage]} totalPages={rawPages.length}/> {/*render in iFrame so broken code doesn't crash the site.*/} Date: Mon, 23 Dec 2024 17:22:50 -0500 Subject: [PATCH 25/36] useCallBack is not needed here. --- client/homebrew/brewRenderer/brewRenderer.jsx | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/client/homebrew/brewRenderer/brewRenderer.jsx b/client/homebrew/brewRenderer/brewRenderer.jsx index 453892b1b..e4c14e86c 100644 --- a/client/homebrew/brewRenderer/brewRenderer.jsx +++ b/client/homebrew/brewRenderer/brewRenderer.jsx @@ -1,7 +1,7 @@ /*eslint max-lines: ["warn", {"max": 300, "skipBlankLines": true, "skipComments": true}]*/ require('./brewRenderer.less'); const React = require('react'); -const { useState, useRef, useCallback, useMemo, useEffect } = React; +const { useState, useRef, useMemo, useEffect } = React; const _ = require('lodash'); const MarkdownLegacy = require('naturalcrit/markdownLegacy.js'); @@ -124,7 +124,7 @@ const BrewRenderer = (props)=>{ rawPages = props.text.split(/^\\page$/gm); } - const handlePageVisibilityChange = useCallback((pageNum, isVisible)=>{ + const handlePageVisibilityChange = (pageNum, isVisible)=>{ setState((prevState)=>{ const updatedVisiblePages = new Set(prevState.visiblePages); isVisible ? updatedVisiblePages.add(pageNum) : updatedVisiblePages.delete(pageNum); @@ -134,16 +134,17 @@ const BrewRenderer = (props)=>{ visiblePages : [...updatedVisiblePages].sort((a, b)=>a - b) }; }); - }, []); + }; - const handleCenterPageChange = useCallback((pageNum)=>{ + const handleCenterPageChange = (pageNum)=>{ setState((prevState)=>({ + //if(prevState.visiblePages.length == 0) ...prevState, centerPage : pageNum, })); props.onPageChange(pageNum); - }, [props.onPageChange]); + }; const isInView = (index)=>{ if(!state.isMounted) From 2b7a1e1cb20af73d915dcdebbfa6ea6d74b28c66 Mon Sep 17 00:00:00 2001 From: Trevor Buckner Date: Mon, 23 Dec 2024 18:35:36 -0500 Subject: [PATCH 26/36] Reduce overlapping observer handlers Combine handlePageVisibilityChange and handleCenterPageChange to reduce some of the infrastructure burden for handling centerPage. --- client/homebrew/brewRenderer/brewRenderer.jsx | 29 ++++++++----------- 1 file changed, 12 insertions(+), 17 deletions(-) diff --git a/client/homebrew/brewRenderer/brewRenderer.jsx b/client/homebrew/brewRenderer/brewRenderer.jsx index e4c14e86c..376151210 100644 --- a/client/homebrew/brewRenderer/brewRenderer.jsx +++ b/client/homebrew/brewRenderer/brewRenderer.jsx @@ -47,9 +47,9 @@ const BrewPage = (props)=>{ (entries)=>{ entries.forEach((entry)=>{ if(entry.isIntersecting) - props.onVisibilityChange(props.index + 1, true); // add page to array of visible pages. + props.onVisibilityChange(props.index + 1, true, false); // add page to array of visible pages. else - props.onVisibilityChange(props.index + 1, false); + props.onVisibilityChange(props.index + 1, false, false); }); }, { threshold: .3, rootMargin: '0px 0px 0px 0px' } // detect when >30% of page is within bounds. @@ -60,7 +60,7 @@ const BrewPage = (props)=>{ (entries)=>{ entries.forEach((entry)=>{ if(entry.isIntersecting) - props.onCenterPageChange(props.index + 1); // Set this page as the center page + props.onVisibilityChange(props.index + 1, true, true); // Set this page as the center page }); }, { threshold: 0, rootMargin: '-50% 0px -50% 0px' } // Detect when the page is at the center @@ -124,26 +124,21 @@ const BrewRenderer = (props)=>{ rawPages = props.text.split(/^\\page$/gm); } - const handlePageVisibilityChange = (pageNum, isVisible)=>{ + const handlePageVisibilityChange = (pageNum, isVisible, isCenter)=>{ setState((prevState)=>{ const updatedVisiblePages = new Set(prevState.visiblePages); - isVisible ? updatedVisiblePages.add(pageNum) : updatedVisiblePages.delete(pageNum); + if(!isCenter) + isVisible ? updatedVisiblePages.add(pageNum) : updatedVisiblePages.delete(pageNum); return { ...prevState, - visiblePages : [...updatedVisiblePages].sort((a, b)=>a - b) + visiblePages : [...updatedVisiblePages].sort((a, b)=>a - b), + centerPage : isCenter ? pageNum : prevState.centerPage }; }); - }; - const handleCenterPageChange = (pageNum)=>{ - setState((prevState)=>({ - //if(prevState.visiblePages.length == 0) - ...prevState, - centerPage : pageNum, - })); - - props.onPageChange(pageNum); + if(isCenter) + props.onPageChange(pageNum); }; const isInView = (index)=>{ @@ -181,12 +176,12 @@ const BrewRenderer = (props)=>{ if(props.renderer == 'legacy') { const html = MarkdownLegacy.render(pageText); - return ; + return ; } else { pageText += `\n\n \n\\column\n `; //Artificial column break at page end to emulate column-fill:auto (until `wide` is used, when column-fill:balance will reappear) const html = Markdown.render(pageText, index); - return ; + return ; } }; From d588a921474865649484e50a726cfbb7f21bbe3e Mon Sep 17 00:00:00 2001 From: Trevor Buckner Date: Mon, 23 Dec 2024 18:37:20 -0500 Subject: [PATCH 27/36] Change page range to only display a single range Having multiple page ranges visible is a weird edge case that only happens in two-page view. Simplifying logic to just group all page ranges together if a middle page is partly obscured. --- client/homebrew/brewRenderer/toolBar/toolBar.jsx | 15 +-------------- 1 file changed, 1 insertion(+), 14 deletions(-) diff --git a/client/homebrew/brewRenderer/toolBar/toolBar.jsx b/client/homebrew/brewRenderer/toolBar/toolBar.jsx index 9257660d1..61e7eee36 100644 --- a/client/homebrew/brewRenderer/toolBar/toolBar.jsx +++ b/client/homebrew/brewRenderer/toolBar/toolBar.jsx @@ -79,20 +79,7 @@ const ToolBar = ({ displayOptions, onDisplayOptionsChange, visiblePages, totalPa if(pages.length === 0) return ''; const sortedPages = [...pages].sort((a, b)=>a - b); // Copy and sort the array - const ranges = []; - let start = sortedPages[0]; - - for (let i = 1; i <= sortedPages.length; i++) { - // If the current page is the end of the list or not consecutive - if(i === sortedPages.length || sortedPages[i] !== sortedPages[i - 1] + 1) { - ranges.push( - start === sortedPages[i - 1] ? `${start}` : `${start} - ${sortedPages[i - 1]}` - ); - start = sortedPages[i]; // Start a new range - } - } - - return ranges.join(', '); + return sortedPages.length == 1 ? `${sortedPages[0]}` : `${sortedPages[0]} - ${sortedPages.at(-1)}`; }; return ( From f0e047e7cc7b1fee0e502de81847a58c26e610be Mon Sep 17 00:00:00 2001 From: Trevor Buckner Date: Mon, 23 Dec 2024 22:43:37 -0500 Subject: [PATCH 28/36] Remove loop on intersectionObserver entries Guaranteed to only be one entry each time, since we are attaching each page to its own observers. --- client/homebrew/brewRenderer/brewRenderer.jsx | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) diff --git a/client/homebrew/brewRenderer/brewRenderer.jsx b/client/homebrew/brewRenderer/brewRenderer.jsx index 376151210..c0ef848c5 100644 --- a/client/homebrew/brewRenderer/brewRenderer.jsx +++ b/client/homebrew/brewRenderer/brewRenderer.jsx @@ -45,12 +45,10 @@ const BrewPage = (props)=>{ // Observer for tracking pages within the `.pages` div const visibleObserver = new IntersectionObserver( (entries)=>{ - entries.forEach((entry)=>{ - if(entry.isIntersecting) - props.onVisibilityChange(props.index + 1, true, false); // add page to array of visible pages. - else - props.onVisibilityChange(props.index + 1, false, false); - }); + if(entries[0].isIntersecting) + props.onVisibilityChange(props.index + 1, true, false); // add page to array of visible pages. + else + props.onVisibilityChange(props.index + 1, false, false); }, { threshold: .3, rootMargin: '0px 0px 0px 0px' } // detect when >30% of page is within bounds. ); @@ -58,10 +56,8 @@ const BrewPage = (props)=>{ // Observer for tracking the page at the center of the iframe. const centerObserver = new IntersectionObserver( (entries)=>{ - entries.forEach((entry)=>{ - if(entry.isIntersecting) - props.onVisibilityChange(props.index + 1, true, true); // Set this page as the center page - }); + if(entries[0].isIntersecting) + props.onVisibilityChange(props.index + 1, true, true); // Set this page as the center page }, { threshold: 0, rootMargin: '-50% 0px -50% 0px' } // Detect when the page is at the center ); From 3909d5aef9a77ec4834ebebac41e852bbb57559e Mon Sep 17 00:00:00 2001 From: Trevor Buckner Date: Mon, 23 Dec 2024 22:48:57 -0500 Subject: [PATCH 29/36] remove unused iFrameRef iFrameRef is not used anywhere --- client/homebrew/brewRenderer/brewRenderer.jsx | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/client/homebrew/brewRenderer/brewRenderer.jsx b/client/homebrew/brewRenderer/brewRenderer.jsx index c0ef848c5..2d1e6c40b 100644 --- a/client/homebrew/brewRenderer/brewRenderer.jsx +++ b/client/homebrew/brewRenderer/brewRenderer.jsx @@ -111,7 +111,6 @@ const BrewRenderer = (props)=>{ pageShadows : true }); - const iframeRef = useRef(null); const mainRef = useRef(null); if(props.renderer == 'legacy') { @@ -303,7 +302,7 @@ const BrewRenderer = (props)=>{ && <> {renderedStyle} -
+
{renderedPages}
From 85f1da942facfa1c77d5406269f560aef8282394 Mon Sep 17 00:00:00 2001 From: Trevor Buckner Date: Mon, 23 Dec 2024 23:08:30 -0500 Subject: [PATCH 30/36] Restore looping over entries. Needed for very fast scrolling --- client/homebrew/brewRenderer/brewRenderer.jsx | 20 +++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/client/homebrew/brewRenderer/brewRenderer.jsx b/client/homebrew/brewRenderer/brewRenderer.jsx index 2d1e6c40b..5563c5e04 100644 --- a/client/homebrew/brewRenderer/brewRenderer.jsx +++ b/client/homebrew/brewRenderer/brewRenderer.jsx @@ -45,20 +45,24 @@ const BrewPage = (props)=>{ // Observer for tracking pages within the `.pages` div const visibleObserver = new IntersectionObserver( (entries)=>{ - if(entries[0].isIntersecting) - props.onVisibilityChange(props.index + 1, true, false); // add page to array of visible pages. - else - props.onVisibilityChange(props.index + 1, false, false); - }, + entries.forEach((entry)=>{ + if(entry.isIntersecting) + props.onVisibilityChange(props.index + 1, true, false); // add page to array of visible pages. + else + props.onVisibilityChange(props.index + 1, false, false); + } + )}, { threshold: .3, rootMargin: '0px 0px 0px 0px' } // detect when >30% of page is within bounds. ); // Observer for tracking the page at the center of the iframe. const centerObserver = new IntersectionObserver( (entries)=>{ - if(entries[0].isIntersecting) - props.onVisibilityChange(props.index + 1, true, true); // Set this page as the center page - }, + entries.forEach((entry)=>{ + if(entry.isIntersecting) + props.onVisibilityChange(props.index + 1, true, true); // Set this page as the center page + } + )}, { threshold: 0, rootMargin: '-50% 0px -50% 0px' } // Detect when the page is at the center ); From 628b2542a098828ef7a2ea96e56819a45760dd7a Mon Sep 17 00:00:00 2001 From: Trevor Buckner Date: Tue, 24 Dec 2024 00:02:55 -0500 Subject: [PATCH 31/36] Simplify logic for previous/next buttons --- client/homebrew/brewRenderer/toolBar/toolBar.jsx | 15 ++------------- 1 file changed, 2 insertions(+), 13 deletions(-) diff --git a/client/homebrew/brewRenderer/toolBar/toolBar.jsx b/client/homebrew/brewRenderer/toolBar/toolBar.jsx index 61e7eee36..86edf072a 100644 --- a/client/homebrew/brewRenderer/toolBar/toolBar.jsx +++ b/client/homebrew/brewRenderer/toolBar/toolBar.jsx @@ -199,8 +199,7 @@ const ToolBar = ({ displayOptions, onDisplayOptionsChange, visiblePages, totalPa type='button' title='Previous Page(s)' onClick={()=>{ - const rangeOffset = visiblePages.length > 1 ? 1 : 0; - scrollToPage(_.min(visiblePages) - visiblePages.length + rangeOffset); + scrollToPage(_.min(visiblePages) - visiblePages.length); }} disabled={visiblePages.includes(1)} > @@ -232,17 +231,7 @@ const ToolBar = ({ displayOptions, onDisplayOptionsChange, visiblePages, totalPa type='button' title='Next Page(s)' onClick={()=>{ - // if there are multiple pages in a 'row' and they are in 'view', - // then the 'max'/last page in view will always be the same, and - // the other pages will always be the same (since the viewport doesn't change). - // So this needs to scroll to the 'max', then see what is newly in view, - // and if the same pages are visible, do it again but +1. - const start = _.max(visiblePages); - scrollToPage(start); - if(start === _.max(visiblePages)){ - console.log("oh no") - scrollToPage(start + 1); - }; + scrollToPage(_.max(visiblePages) + 1); }} disabled={visiblePages.includes(totalPages)} > From c0155052ea2563f514f9e10da1b99940a3d88726 Mon Sep 17 00:00:00 2001 From: Trevor Buckner Date: Tue, 24 Dec 2024 00:06:30 -0500 Subject: [PATCH 32/36] Further simplifying --- client/homebrew/brewRenderer/toolBar/toolBar.jsx | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/client/homebrew/brewRenderer/toolBar/toolBar.jsx b/client/homebrew/brewRenderer/toolBar/toolBar.jsx index 86edf072a..b31ee9589 100644 --- a/client/homebrew/brewRenderer/toolBar/toolBar.jsx +++ b/client/homebrew/brewRenderer/toolBar/toolBar.jsx @@ -198,9 +198,7 @@ const ToolBar = ({ displayOptions, onDisplayOptionsChange, visiblePages, totalPa className='previousPage tool' type='button' title='Previous Page(s)' - onClick={()=>{ - scrollToPage(_.min(visiblePages) - visiblePages.length); - }} + onClick={()=>scrollToPage(_.min(visiblePages) - visiblePages.length)} disabled={visiblePages.includes(1)} > @@ -230,9 +228,7 @@ const ToolBar = ({ displayOptions, onDisplayOptionsChange, visiblePages, totalPa className='tool' type='button' title='Next Page(s)' - onClick={()=>{ - scrollToPage(_.max(visiblePages) + 1); - }} + onClick={()=>scrollToPage(_.max(visiblePages) + 1)} disabled={visiblePages.includes(totalPages)} > From 0632d78f717c3face615ffd41c26ffbc92542dab Mon Sep 17 00:00:00 2001 From: Trevor Buckner Date: Tue, 24 Dec 2024 00:18:37 -0500 Subject: [PATCH 33/36] Remove toolbar checks for empty visiblePages list With `centerPage`, ToolBar will never receive an empty visiblePages array. No need to check if visiblepages.length == 0 --- client/homebrew/brewRenderer/toolBar/toolBar.jsx | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/client/homebrew/brewRenderer/toolBar/toolBar.jsx b/client/homebrew/brewRenderer/toolBar/toolBar.jsx index b31ee9589..598981eaa 100644 --- a/client/homebrew/brewRenderer/toolBar/toolBar.jsx +++ b/client/homebrew/brewRenderer/toolBar/toolBar.jsx @@ -15,9 +15,7 @@ const ToolBar = ({ displayOptions, onDisplayOptionsChange, visiblePages, totalPa const [toolsVisible, setToolsVisible] = useState(true); useEffect(()=>{ - if(visiblePages.length !== 0){ // If zoomed in enough, it's possible that no page fits the intersection criteria, so don't update. - setPageNum(formatVisiblePages(visiblePages)); - } + setPageNum(formatVisiblePages(visiblePages)); }, [visiblePages]); const handleZoomButton = (zoom)=>{ @@ -74,12 +72,9 @@ const ToolBar = ({ displayOptions, onDisplayOptionsChange, visiblePages, totalPa return deltaZoom; }; - // format the visible pages to work with ranges, including separate ranges ("2-7, 10-15") + // format the visible pages into a range (e.g. "150-153") const formatVisiblePages = (pages)=>{ - if(pages.length === 0) return ''; - - const sortedPages = [...pages].sort((a, b)=>a - b); // Copy and sort the array - return sortedPages.length == 1 ? `${sortedPages[0]}` : `${sortedPages[0]} - ${sortedPages.at(-1)}`; + return pages.length === 1 ? `${pages[0]}` : `${pages[0]} - ${pages.at(-1)}`; }; return ( From 8159c408c8dfdda9c5398d197cf6e3c5a4d49aed Mon Sep 17 00:00:00 2001 From: Trevor Buckner Date: Tue, 24 Dec 2024 00:24:52 -0500 Subject: [PATCH 34/36] Move formatVisiblePages After simplifying, this has become a single-line function used in only one place. Can just be placed directly in the one place it is used. --- client/homebrew/brewRenderer/toolBar/toolBar.jsx | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/client/homebrew/brewRenderer/toolBar/toolBar.jsx b/client/homebrew/brewRenderer/toolBar/toolBar.jsx index 598981eaa..ce60971aa 100644 --- a/client/homebrew/brewRenderer/toolBar/toolBar.jsx +++ b/client/homebrew/brewRenderer/toolBar/toolBar.jsx @@ -15,7 +15,9 @@ const ToolBar = ({ displayOptions, onDisplayOptionsChange, visiblePages, totalPa const [toolsVisible, setToolsVisible] = useState(true); useEffect(()=>{ - setPageNum(formatVisiblePages(visiblePages)); + // format multiple visible pages as a range (e.g. "150-153") + const pageRange = visiblePages.length === 1 ? `${visiblePages[0]}` : `${visiblePages[0]} - ${visiblePages.at(-1)}`; + setPageNum(pageRange); }, [visiblePages]); const handleZoomButton = (zoom)=>{ @@ -72,11 +74,6 @@ const ToolBar = ({ displayOptions, onDisplayOptionsChange, visiblePages, totalPa return deltaZoom; }; - // format the visible pages into a range (e.g. "150-153") - const formatVisiblePages = (pages)=>{ - return pages.length === 1 ? `${pages[0]}` : `${pages[0]} - ${pages.at(-1)}`; - }; - return ( - 0 ? state.visiblePages : [state.centerPage]} totalPages={rawPages.length}/> + 0 ? state.visiblePages : [state.centerPage]} totalPages={rawPages.length}/> {/*render in iFrame so broken code doesn't crash the site.*/} Date: Tue, 24 Dec 2024 00:38:36 -0500 Subject: [PATCH 36/36] Undo --- client/homebrew/brewRenderer/brewRenderer.jsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/homebrew/brewRenderer/brewRenderer.jsx b/client/homebrew/brewRenderer/brewRenderer.jsx index ed73c8839..5563c5e04 100644 --- a/client/homebrew/brewRenderer/brewRenderer.jsx +++ b/client/homebrew/brewRenderer/brewRenderer.jsx @@ -287,7 +287,7 @@ const BrewRenderer = (props)=>{
- 0 ? state.visiblePages : [state.centerPage]} totalPages={rawPages.length}/> + 0 ? state.visiblePages : [state.centerPage]} totalPages={rawPages.length}/> {/*render in iFrame so broken code doesn't crash the site.*/}