adds infinite scroll setting, prevents post rerendering on list updates, adds debounce to scroll event listener
This commit is contained in:
parent
cd57edbb32
commit
2620bb8282
|
@ -101,6 +101,11 @@ export class Post extends React.Component<any, IPostState> {
|
|||
});
|
||||
}
|
||||
|
||||
shouldComponentUpdate(nextProps: any, nextState: any) {
|
||||
if (nextState == this.state) return false
|
||||
return true
|
||||
}
|
||||
|
||||
togglePostMenu() {
|
||||
this.setState({ menuIsOpen: !this.state.menuIsOpen });
|
||||
}
|
||||
|
|
|
@ -65,6 +65,7 @@ import DomainDisabledIcon from "@material-ui/icons/DomainDisabled";
|
|||
import AccountSettingsIcon from "mdi-material-ui/AccountSettings";
|
||||
import AlphabeticalVariantOffIcon from "mdi-material-ui/AlphabeticalVariantOff";
|
||||
import DashboardIcon from "@material-ui/icons/Dashboard";
|
||||
import InfiniteIcon from "@material-ui/icons/AllInclusive";
|
||||
|
||||
import { Config } from "../types/Config";
|
||||
import { Account } from "../types/Account";
|
||||
|
@ -88,6 +89,7 @@ interface ISettingsState {
|
|||
currentUser?: Account;
|
||||
imposeCharacterLimit: boolean;
|
||||
masonryLayout?: boolean;
|
||||
infiniteScroll?: boolean;
|
||||
}
|
||||
|
||||
class SettingsPage extends Component<any, ISettingsState> {
|
||||
|
@ -120,7 +122,8 @@ class SettingsPage extends Component<any, ISettingsState> {
|
|||
brandName: "Hyperspace",
|
||||
federated: true,
|
||||
imposeCharacterLimit: getUserDefaultBool("imposeCharacterLimit"),
|
||||
masonryLayout: getUserDefaultBool("isMasonryLayout")
|
||||
masonryLayout: getUserDefaultBool("isMasonryLayout"),
|
||||
infiniteScroll: getUserDefaultBool("isInfiniteScroll")
|
||||
};
|
||||
|
||||
this.toggleDarkMode = this.toggleDarkMode.bind(this);
|
||||
|
@ -130,6 +133,7 @@ class SettingsPage extends Component<any, ISettingsState> {
|
|||
this.toggleThemeDialog = this.toggleThemeDialog.bind(this);
|
||||
this.toggleVisibilityDialog = this.toggleVisibilityDialog.bind(this);
|
||||
this.toggleMasonryLayout = this.toggleMasonryLayout.bind(this);
|
||||
this.toggleInfiniteScroll = this.toggleInfiniteScroll.bind(this);
|
||||
this.changeThemeName = this.changeThemeName.bind(this);
|
||||
this.changeTheme = this.changeTheme.bind(this);
|
||||
this.setVisibility = this.setVisibility.bind(this);
|
||||
|
@ -170,7 +174,6 @@ class SettingsPage extends Component<any, ISettingsState> {
|
|||
getConfig().then((result: any) => {
|
||||
if (result !== undefined) {
|
||||
let config: Config = result;
|
||||
console.log(!config.federation.allowPublicPosts);
|
||||
this.setState({
|
||||
federated: config.federation.allowPublicPosts
|
||||
});
|
||||
|
@ -250,6 +253,11 @@ class SettingsPage extends Component<any, ISettingsState> {
|
|||
setUserDefaultBool("isMasonryLayout", !this.state.masonryLayout);
|
||||
}
|
||||
|
||||
toggleInfiniteScroll() {
|
||||
this.setState({ infiniteScroll: !this.state.infiniteScroll });
|
||||
setUserDefaultBool("isInfiniteScroll", !this.state.infiniteScroll);
|
||||
}
|
||||
|
||||
changeTheme() {
|
||||
setUserDefaultTheme(this.state.selectThemeName);
|
||||
window.location.reload();
|
||||
|
@ -675,6 +683,22 @@ class SettingsPage extends Component<any, ISettingsState> {
|
|||
/>
|
||||
</ListItemSecondaryAction>
|
||||
</ListItem>
|
||||
|
||||
<ListItem>
|
||||
<ListItemAvatar>
|
||||
<InfiniteIcon color="action" />
|
||||
</ListItemAvatar>
|
||||
<ListItemText
|
||||
primary="Enable infinite scroll"
|
||||
secondary="Automatically load more posts when scrolling"
|
||||
/>
|
||||
<ListItemSecondaryAction>
|
||||
<Switch
|
||||
checked={this.state.infiniteScroll}
|
||||
onChange={this.toggleInfiniteScroll}
|
||||
/>
|
||||
</ListItemSecondaryAction>
|
||||
</ListItem>
|
||||
</List>
|
||||
</Paper>
|
||||
<br />
|
||||
|
|
|
@ -77,6 +77,11 @@ interface ITimelinePageState {
|
|||
* the user settings.
|
||||
*/
|
||||
isMasonryLayout?: boolean;
|
||||
|
||||
/**
|
||||
* Whether posts should automatically load when scrolling.
|
||||
*/
|
||||
isInfiniteScroll?: boolean;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -109,7 +114,8 @@ class TimelinePage extends Component<ITimelinePageProps, ITimelinePageState> {
|
|||
this.state = {
|
||||
viewIsLoading: true,
|
||||
backlogPosts: null,
|
||||
isMasonryLayout: getUserDefaultBool("isMasonryLayout")
|
||||
isMasonryLayout: getUserDefaultBool("isMasonryLayout"),
|
||||
isInfiniteScroll: getUserDefaultBool("isInfiniteScroll"),
|
||||
};
|
||||
|
||||
// Generate the client.
|
||||
|
@ -132,8 +138,7 @@ class TimelinePage extends Component<ITimelinePageProps, ITimelinePageState> {
|
|||
this.streamListener.on("connect", () => {
|
||||
// Get the latest posts from this timeline.
|
||||
this.client
|
||||
.get(this.props.timeline, { limit: 10 })
|
||||
|
||||
.get(this.props.timeline, { limit: 50 })
|
||||
// If we succeeded, update the state and turn off loading.
|
||||
.then((resp: any) => {
|
||||
let statuses: [Status] = resp.data;
|
||||
|
@ -200,11 +205,34 @@ class TimelinePage extends Component<ITimelinePageProps, ITimelinePageState> {
|
|||
this.streamListener.on("heartbeat", () => {});
|
||||
}
|
||||
|
||||
/**
|
||||
* Insert a delay between repeated function calls
|
||||
* codeburst.io/throttling-and-debouncing-in-javascript-646d076d0a44
|
||||
* @param delay How long to wait before calling function (ms)
|
||||
* @param fn The function to call
|
||||
*/
|
||||
debounced(delay: number, fn: Function) {
|
||||
let lastCall = 0
|
||||
return function(...args: any) {
|
||||
const now = (new Date).getTime();
|
||||
if (now - lastCall < delay) {
|
||||
return
|
||||
}
|
||||
lastCall = now;
|
||||
return fn(...args)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Listen for when scroll position changes
|
||||
*/
|
||||
componentDidMount() {
|
||||
window.addEventListener("scroll", this.shouldLoadMorePosts);
|
||||
if (this.state.isInfiniteScroll) {
|
||||
window.addEventListener(
|
||||
"scroll",
|
||||
this.debounced(200, this.shouldLoadMorePosts),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -212,7 +240,12 @@ class TimelinePage extends Component<ITimelinePageProps, ITimelinePageState> {
|
|||
*/
|
||||
componentWillUnmount() {
|
||||
this.streamListener.stop();
|
||||
window.removeEventListener("scroll", this.shouldLoadMorePosts);
|
||||
if (this.state.isInfiniteScroll) {
|
||||
window.removeEventListener(
|
||||
"scroll",
|
||||
this.shouldLoadMorePosts,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -241,7 +274,7 @@ class TimelinePage extends Component<ITimelinePageProps, ITimelinePageState> {
|
|||
this.client
|
||||
.get(this.props.timeline, {
|
||||
max_id: this.state.posts[this.state.posts.length - 1].id,
|
||||
limit: 20
|
||||
limit: 50
|
||||
})
|
||||
|
||||
// If we succeeded, append them to the end of the list of posts.
|
||||
|
|
Loading…
Reference in New Issue