Improve scroll handling and cache fetch results

This commit is contained in:
Tanner Collin 2020-02-17 00:19:44 +00:00
parent 2aff4e97b6
commit 8555fbfa0f
6 changed files with 76 additions and 19 deletions

View File

@ -38,8 +38,7 @@ export function Admin(props) {
</a>
</p>
<p>
Automate with wget (keep secret, that's <b>your</b> login token):
Automate with wget (keep secret, that's <b>your</b> login token): <br />
{reveal ?
<pre>
wget \
@ -48,9 +47,8 @@ export function Admin(props) {
<br /> {apiUrl}/backup/
</pre>
:
<div><Button onClick={() => setReveal(true)}>Show Secret</Button></div>
<Button onClick={() => setReveal(true)}>Show Secret</Button>
}
</p>
</div>
:
<p>Loading...</p>

View File

@ -4,6 +4,7 @@ import './semantic-ui/semantic.min.css';
import './light.css';
import { Container, Divider, Dropdown, Form, Grid, Header, Icon, Image, Menu, Message, Segment, Table } from 'semantic-ui-react';
import { isAdmin, requester } from './utils.js';
import { ManageScroll } from './ManageScroll.js';
import { Home } from './Home.js';
import { Account } from './Account.js';
import { Transactions, TransactionDetail } from './Transactions.js';
@ -71,6 +72,8 @@ function App() {
return (
<div>
<ManageScroll />
<div className='content-wrap'>
<div className='content-wrap-inside'>

View File

@ -48,14 +48,17 @@ function ClassTable(props) {
);
};
let classesCache = false;
export function Classes(props) {
const [classes, setClasses] = useState(false);
const [classes, setClasses] = useState(classesCache);
const { token } = props;
useEffect(() => {
requester('/sessions/', 'GET', token)
.then(res => {
setClasses(res.results);
classesCache = res.results;
})
.catch(err => {
console.log(err);

View File

@ -8,14 +8,17 @@ import { NotFound, PleaseLogin } from './Misc.js';
import { InstructorCourseList, InstructorCourseDetail } from './InstructorCourses.js';
import { InstructorClassList } from './InstructorClasses.js';
let courseCache = false;
export function Courses(props) {
const [courses, setCourses] = useState(false);
const [courses, setCourses] = useState(courseCache);
const { token, user } = props;
useEffect(() => {
requester('/courses/', 'GET', token)
.then(res => {
setCourses(res.results);
courseCache = res.results;
})
.catch(err => {
console.log(err);

View File

@ -0,0 +1,44 @@
import React, { useState, useEffect, useReducer, useContext } from 'react';
import { BrowserRouter as Router, Switch, Route, Link, useParams, useHistory } from 'react-router-dom';
let scrollPositions = {};
let timeout = null;
export function ManageScroll() {
const history = useHistory();
const scrollListener = () => {
if (timeout) {
window.cancelAnimationFrame(timeout);
}
timeout = window.requestAnimationFrame(() => {
const key = history.location.key;
if (key in scrollPositions) {
scrollPositions[key] = window.scrollY;
}
});
};
useEffect(() => {
window.addEventListener('scroll', scrollListener);
return () => {
window.removeEventListener('scroll', scrollListener);
}
}, []);
useEffect(() => {
const key = history.location.key;
if (key in scrollPositions) {
window.scrollTo(0, scrollPositions[key]);
} else {
window.scrollTo(0, 0);
scrollPositions[key] = 0;
}
}, [history.location]);
return (
null
);
};

View File

@ -49,13 +49,16 @@ export function MembersDropdown(props) {
);
};
let searchCache = '';
export function Members(props) {
const [response, setResponse] = useState(false);
const searchDefault = {seq: 0, q: ''};
const searchDefault = {seq: 0, q: searchCache};
const [search, setSearch] = useState(searchDefault);
const { token } = props;
useEffect(() => {
searchCache = search.q;
requester('/search/', 'POST', token, search)
.then(res => {
if (!search.seq || res.seq > response.seq) {
@ -82,7 +85,7 @@ export function Members(props) {
{search.q.length ?
<Button
content='Clear'
onClick={() => setSearch(searchDefault)}
onClick={() => setSearch({seq: 0, q: ''})}
/> : ''
}
@ -118,17 +121,20 @@ export function Members(props) {
);
};
let resultCache = {};
export function MemberDetail(props) {
const [result, setResult] = useState(false);
const { id } = useParams();
const [result, setResult] = useState(resultCache[id] || false);
const [refreshCount, refreshResult] = useReducer(x => x + 1, 0);
const [error, setError] = useState(false);
const { token, user } = props;
const { id } = useParams();
useEffect(() => {
requester('/search/'+id+'/', 'GET', token)
.then(res => {
setResult(res);
resultCache[id] = res;
})
.catch(err => {
console.log(err);