2019-03-27 22:39:25 +01:00
|
|
|
import React, { Component } from 'react';
|
|
|
|
import {
|
|
|
|
List,
|
|
|
|
ListItem,
|
|
|
|
ListItemText,
|
|
|
|
ListSubheader,
|
|
|
|
ListItemSecondaryAction,
|
|
|
|
Paper,
|
|
|
|
IconButton,
|
|
|
|
withStyles,
|
|
|
|
Button,
|
|
|
|
Switch,
|
|
|
|
Dialog,
|
|
|
|
DialogTitle,
|
|
|
|
DialogContent,
|
|
|
|
RadioGroup,
|
|
|
|
FormControlLabel,
|
|
|
|
Radio,
|
2019-04-08 20:31:20 +02:00
|
|
|
DialogActions,
|
|
|
|
DialogContentText
|
2019-03-27 22:39:25 +01:00
|
|
|
} from '@material-ui/core';
|
|
|
|
import OpenInNewIcon from '@material-ui/icons/OpenInNew';
|
|
|
|
import {styles} from './PageLayout.styles';
|
|
|
|
import {setUserDefaultBool, getUserDefaultBool, getUserDefaultTheme, setUserDefaultTheme} from '../utilities/settings';
|
2019-03-28 14:24:38 +01:00
|
|
|
import {canSendNotifications, browserSupportsNotificationRequests} from '../utilities/notifications';
|
2019-03-27 22:39:25 +01:00
|
|
|
import {themes} from '../types/HyperspaceTheme';
|
|
|
|
|
|
|
|
interface ISettingsState {
|
|
|
|
darkModeEnabled: boolean;
|
|
|
|
pushNotificationsEnabled: boolean;
|
2019-04-19 20:57:35 +02:00
|
|
|
badgeDisplaysAllNotifs: boolean;
|
2019-03-27 22:39:25 +01:00
|
|
|
selectThemeName: string;
|
|
|
|
themeDialogOpen: boolean;
|
2019-04-08 20:31:20 +02:00
|
|
|
resetHyperspaceDialog: boolean;
|
2019-04-12 19:39:24 +02:00
|
|
|
resetSettingsDialog: boolean;
|
2019-03-27 22:39:25 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
class SettingsPage extends Component<any, ISettingsState> {
|
|
|
|
|
|
|
|
constructor(props: any) {
|
|
|
|
super(props);
|
|
|
|
|
|
|
|
this.state = {
|
|
|
|
darkModeEnabled: getUserDefaultBool('darkModeEnabled'),
|
2019-03-28 14:24:38 +01:00
|
|
|
pushNotificationsEnabled: canSendNotifications(),
|
2019-04-19 20:57:35 +02:00
|
|
|
badgeDisplaysAllNotifs: getUserDefaultBool('displayAllOnNotificationBadge'),
|
2019-03-27 22:39:25 +01:00
|
|
|
selectThemeName: getUserDefaultTheme().key,
|
2019-04-08 20:31:20 +02:00
|
|
|
themeDialogOpen: false,
|
2019-04-12 19:39:24 +02:00
|
|
|
resetHyperspaceDialog: false,
|
|
|
|
resetSettingsDialog: false
|
2019-03-27 22:39:25 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
this.toggleDarkMode = this.toggleDarkMode.bind(this);
|
|
|
|
this.togglePushNotifications = this.togglePushNotifications.bind(this);
|
2019-04-19 20:57:35 +02:00
|
|
|
this.toggleBadgeCount = this.toggleBadgeCount.bind(this);
|
2019-03-27 22:39:25 +01:00
|
|
|
this.toggleThemeDialog = this.toggleThemeDialog.bind(this);
|
|
|
|
this.changeThemeName = this.changeThemeName.bind(this);
|
|
|
|
this.changeTheme = this.changeTheme.bind(this);
|
|
|
|
}
|
|
|
|
|
|
|
|
toggleDarkMode() {
|
|
|
|
this.setState({ darkModeEnabled: !this.state.darkModeEnabled });
|
|
|
|
setUserDefaultBool('darkModeEnabled', !this.state.darkModeEnabled);
|
|
|
|
window.location.reload();
|
|
|
|
}
|
|
|
|
|
|
|
|
togglePushNotifications() {
|
|
|
|
this.setState({ pushNotificationsEnabled: !this.state.pushNotificationsEnabled });
|
|
|
|
setUserDefaultBool('enablePushNotifications', !this.state.pushNotificationsEnabled);
|
|
|
|
}
|
|
|
|
|
2019-04-19 20:57:35 +02:00
|
|
|
toggleBadgeCount() {
|
|
|
|
this.setState({ badgeDisplaysAllNotifs: !this.state.badgeDisplaysAllNotifs });
|
|
|
|
setUserDefaultBool('displayAllOnNotificationBadge', !this.state.badgeDisplaysAllNotifs);
|
|
|
|
}
|
|
|
|
|
2019-03-27 22:39:25 +01:00
|
|
|
toggleThemeDialog() {
|
|
|
|
this.setState({ themeDialogOpen: !this.state.themeDialogOpen });
|
|
|
|
}
|
|
|
|
|
2019-04-08 20:31:20 +02:00
|
|
|
toggleResetDialog() {
|
|
|
|
this.setState({ resetHyperspaceDialog: !this.state.resetHyperspaceDialog });
|
|
|
|
}
|
|
|
|
|
2019-04-12 19:39:24 +02:00
|
|
|
toggleResetSettingsDialog() {
|
|
|
|
this.setState({ resetSettingsDialog: !this.state.resetSettingsDialog });
|
|
|
|
}
|
|
|
|
|
2019-03-27 22:39:25 +01:00
|
|
|
changeTheme() {
|
|
|
|
setUserDefaultTheme(this.state.selectThemeName);
|
|
|
|
window.location.reload();
|
|
|
|
}
|
|
|
|
|
|
|
|
changeThemeName(theme: string) {
|
|
|
|
this.setState({ selectThemeName: theme});
|
|
|
|
}
|
|
|
|
|
2019-04-08 20:31:20 +02:00
|
|
|
reset() {
|
|
|
|
localStorage.clear();
|
|
|
|
window.location.reload();
|
|
|
|
}
|
|
|
|
|
2019-04-12 19:39:24 +02:00
|
|
|
refresh() {
|
|
|
|
let settings = ['darkModeEnabled', 'enablePushNotifications', 'clearNotificationsOnRead', 'theme'];
|
|
|
|
settings.forEach(setting => {
|
|
|
|
localStorage.removeItem(setting);
|
|
|
|
})
|
|
|
|
window.location.reload();
|
|
|
|
}
|
|
|
|
|
2019-03-27 22:39:25 +01:00
|
|
|
showThemeDialog() {
|
|
|
|
return (
|
|
|
|
<Dialog
|
|
|
|
open={this.state.themeDialogOpen}
|
|
|
|
disableBackdropClick
|
|
|
|
disableEscapeKeyDown
|
|
|
|
maxWidth="sm"
|
|
|
|
fullWidth={true}
|
|
|
|
aria-labelledby="confirmation-dialog-title"
|
|
|
|
>
|
|
|
|
<DialogTitle id="confirmation-dialog-title">Choose a color scheme</DialogTitle>
|
|
|
|
<DialogContent>
|
|
|
|
<RadioGroup
|
|
|
|
aria-label="Color Scheme"
|
|
|
|
name="ringtone"
|
|
|
|
value={this.state.selectThemeName}
|
|
|
|
onChange={(e, value) => this.changeThemeName(value)}
|
|
|
|
>
|
|
|
|
{themes.map(theme => (
|
|
|
|
<FormControlLabel value={theme.key} key={theme.key} control={<Radio />} label={theme.name} />
|
|
|
|
))}
|
|
|
|
))}
|
|
|
|
</RadioGroup>
|
|
|
|
</DialogContent>
|
|
|
|
<DialogActions>
|
2019-03-28 00:24:52 +01:00
|
|
|
<Button onClick={this.toggleThemeDialog} color="default">
|
2019-03-27 22:39:25 +01:00
|
|
|
Cancel
|
|
|
|
</Button>
|
2019-03-28 00:24:52 +01:00
|
|
|
<Button onClick={this.changeTheme} color="secondary">
|
2019-03-27 22:39:25 +01:00
|
|
|
Ok
|
|
|
|
</Button>
|
|
|
|
</DialogActions>
|
|
|
|
</Dialog>
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
2019-04-12 19:39:24 +02:00
|
|
|
showResetSettingsDialog() {
|
|
|
|
return (
|
|
|
|
<Dialog
|
|
|
|
open={this.state.resetSettingsDialog}
|
|
|
|
onClose={() => this.toggleResetSettingsDialog()}
|
|
|
|
>
|
|
|
|
<DialogTitle id="alert-dialog-title">Are you sure you want to refresh settings?</DialogTitle>
|
|
|
|
<DialogActions>
|
|
|
|
<Button onClick={() => this.toggleResetSettingsDialog()} color="primary" autoFocus>
|
|
|
|
Cancel
|
|
|
|
</Button>
|
|
|
|
<Button onClick={() => {
|
|
|
|
this.refresh();
|
|
|
|
}} color="primary">
|
|
|
|
Refresh
|
|
|
|
</Button>
|
|
|
|
</DialogActions>
|
|
|
|
</Dialog>
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
2019-04-08 20:31:20 +02:00
|
|
|
showResetDialog() {
|
|
|
|
return (
|
|
|
|
<Dialog
|
|
|
|
open={this.state.resetHyperspaceDialog}
|
|
|
|
onClose={() => this.toggleResetDialog()}
|
|
|
|
>
|
|
|
|
<DialogTitle id="alert-dialog-title">Reset Hyperspace?</DialogTitle>
|
|
|
|
<DialogContent>
|
|
|
|
<DialogContentText id="alert-dialog-description">
|
|
|
|
Are you sure you want to reset Hyperspace? You'll need to sign in again and grant Hyperspace access to use it again.
|
|
|
|
</DialogContentText>
|
|
|
|
</DialogContent>
|
|
|
|
<DialogActions>
|
|
|
|
<Button onClick={() => this.toggleResetDialog()} color="primary" autoFocus>
|
|
|
|
Cancel
|
|
|
|
</Button>
|
|
|
|
<Button onClick={() => {
|
|
|
|
this.reset();
|
|
|
|
}} color="primary">
|
|
|
|
Reset
|
|
|
|
</Button>
|
|
|
|
</DialogActions>
|
|
|
|
</Dialog>
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
2019-03-27 22:39:25 +01:00
|
|
|
render() {
|
|
|
|
const { classes } = this.props;
|
|
|
|
return (
|
|
|
|
<div className={classes.pageLayoutConstraints}>
|
|
|
|
<ListSubheader>Appearance</ListSubheader>
|
|
|
|
<Paper className={classes.pageListConstraints}>
|
|
|
|
<List>
|
|
|
|
<ListItem>
|
|
|
|
<ListItemText primary="Dark mode"/>
|
|
|
|
<ListItemSecondaryAction>
|
|
|
|
<Switch checked={this.state.darkModeEnabled} onChange={this.toggleDarkMode}/>
|
|
|
|
</ListItemSecondaryAction>
|
|
|
|
</ListItem>
|
|
|
|
<ListItem>
|
|
|
|
<ListItemText primary="Color scheme"/>
|
|
|
|
<ListItemSecondaryAction>
|
|
|
|
<Button onClick={this.toggleThemeDialog}>
|
|
|
|
Set theme
|
|
|
|
</Button>
|
|
|
|
</ListItemSecondaryAction>
|
|
|
|
</ListItem>
|
|
|
|
</List>
|
|
|
|
</Paper>
|
|
|
|
<br/>
|
|
|
|
<ListSubheader>Notifications</ListSubheader>
|
|
|
|
<Paper className={classes.pageListConstraints}>
|
|
|
|
<List>
|
|
|
|
<ListItem>
|
2019-03-28 14:24:38 +01:00
|
|
|
<ListItemText
|
|
|
|
primary="Enable push notifications"
|
|
|
|
secondary={
|
2019-04-19 20:43:06 +02:00
|
|
|
getUserDefaultBool('userDeniedNotification')?
|
|
|
|
"Check your browser's notification permissions.":
|
|
|
|
browserSupportsNotificationRequests()?
|
2019-04-19 20:57:35 +02:00
|
|
|
"Send a push notification when not focused.":
|
2019-04-19 20:45:27 +02:00
|
|
|
"Notifications aren't supported."
|
2019-03-28 14:24:38 +01:00
|
|
|
}
|
|
|
|
/>
|
2019-03-27 22:39:25 +01:00
|
|
|
<ListItemSecondaryAction>
|
2019-03-28 14:24:38 +01:00
|
|
|
<Switch
|
|
|
|
checked={this.state.pushNotificationsEnabled}
|
|
|
|
onChange={this.togglePushNotifications}
|
2019-04-19 20:43:06 +02:00
|
|
|
disabled={!browserSupportsNotificationRequests() || getUserDefaultBool('userDeniedNotification')}
|
2019-03-28 14:24:38 +01:00
|
|
|
/>
|
2019-03-27 22:39:25 +01:00
|
|
|
</ListItemSecondaryAction>
|
|
|
|
</ListItem>
|
2019-04-19 20:57:35 +02:00
|
|
|
{
|
|
|
|
browserSupportsNotificationRequests()?
|
|
|
|
<ListItem>
|
|
|
|
<ListItemText
|
|
|
|
primary="Notification badge counts all notifications"
|
|
|
|
secondary={
|
|
|
|
"Counts all notifications, read or unread."
|
|
|
|
}
|
|
|
|
/>
|
|
|
|
<ListItemSecondaryAction>
|
|
|
|
<Switch
|
|
|
|
checked={this.state.badgeDisplaysAllNotifs}
|
|
|
|
onChange={this.toggleBadgeCount}
|
|
|
|
/>
|
|
|
|
</ListItemSecondaryAction>
|
|
|
|
</ListItem>: null
|
|
|
|
}
|
2019-03-27 22:39:25 +01:00
|
|
|
</List>
|
|
|
|
</Paper>
|
|
|
|
<br/>
|
|
|
|
<ListSubheader>Accounts</ListSubheader>
|
|
|
|
<Paper className={classes.pageListConstraints}>
|
|
|
|
<List>
|
|
|
|
<ListItem>
|
2019-04-19 20:43:06 +02:00
|
|
|
<ListItemText primary="Configure on Mastodon"/>
|
2019-03-27 22:39:25 +01:00
|
|
|
<ListItemSecondaryAction>
|
2019-03-28 14:24:38 +01:00
|
|
|
<IconButton href={(localStorage.getItem("baseurl") as string) + "/settings/preferences"} target="_blank" rel="noreferrer">
|
2019-03-27 22:39:25 +01:00
|
|
|
<OpenInNewIcon/>
|
|
|
|
</IconButton>
|
|
|
|
</ListItemSecondaryAction>
|
|
|
|
</ListItem>
|
|
|
|
</List>
|
|
|
|
</Paper>
|
|
|
|
<br/>
|
|
|
|
<ListSubheader>Advanced</ListSubheader>
|
|
|
|
<Paper className={classes.pageListConstraints}>
|
|
|
|
<List>
|
2019-04-12 19:39:24 +02:00
|
|
|
<ListItem>
|
|
|
|
<ListItemText primary="Refresh settings" secondary="Reset Hyperspace to its default settings."/>
|
|
|
|
<ListItemSecondaryAction>
|
|
|
|
<Button onClick={() => this.toggleResetSettingsDialog()}>
|
|
|
|
Refresh
|
|
|
|
</Button>
|
|
|
|
</ListItemSecondaryAction>
|
|
|
|
</ListItem>
|
2019-03-27 22:39:25 +01:00
|
|
|
<ListItem>
|
|
|
|
<ListItemText primary="Reset Hyperspace" secondary="Deletes all data and resets the app"/>
|
|
|
|
<ListItemSecondaryAction>
|
2019-04-08 20:31:20 +02:00
|
|
|
<Button onClick={() => this.toggleResetDialog()}>
|
2019-03-27 22:39:25 +01:00
|
|
|
Reset
|
|
|
|
</Button>
|
|
|
|
</ListItemSecondaryAction>
|
|
|
|
</ListItem>
|
|
|
|
</List>
|
|
|
|
</Paper>
|
|
|
|
{this.showThemeDialog()}
|
2019-04-08 20:31:20 +02:00
|
|
|
{this.showResetDialog()}
|
2019-04-12 19:39:24 +02:00
|
|
|
{this.showResetSettingsDialog()}
|
2019-03-27 22:39:25 +01:00
|
|
|
</div>
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
export default withStyles(styles)(SettingsPage);
|