import React, { Component } from "react"; import { List, ListItem, ListItemAvatar, ListItemText, ListSubheader, ListItemSecondaryAction, Paper, IconButton, withStyles, Button, Switch, Dialog, DialogTitle, DialogContent, RadioGroup, FormControlLabel, Radio, DialogActions, DialogContentText, Grid, Theme, Typography, Avatar, Toolbar, Tooltip } from "@material-ui/core"; import { styles } from "./PageLayout.styles"; import { setUserDefaultBool, getUserDefaultBool, getUserDefaultTheme, setUserDefaultTheme, getUserDefaultVisibility, setUserDefaultVisibility, getConfig } from "../utilities/settings"; import { canSendNotifications, browserSupportsNotificationRequests } from "../utilities/notifications"; import { themes, defaultTheme } from "../types/HyperspaceTheme"; import ThemePreview from "../components/ThemePreview"; import { setHyperspaceTheme, getHyperspaceTheme, getDarkModeFromSystem } from "../utilities/themes"; import { Visibility } from "../types/Visibility"; import { LinkableButton, LinkableIconButton } from "../interfaces/overrides"; import OpenInNewIcon from "@material-ui/icons/OpenInNew"; import DevicesIcon from "@material-ui/icons/Devices"; import Brightness3Icon from "@material-ui/icons/Brightness3"; import PaletteIcon from "@material-ui/icons/Palette"; import AccountEditIcon from "mdi-material-ui/AccountEdit"; import MastodonIcon from "mdi-material-ui/Mastodon"; import VisibilityIcon from "@material-ui/icons/Visibility"; import NotificationsIcon from "@material-ui/icons/Notifications"; import BellAlertIcon from "mdi-material-ui/BellAlert"; import RefreshIcon from "@material-ui/icons/Refresh"; import UndoIcon from "@material-ui/icons/Undo"; import DomainDisabledIcon from "@material-ui/icons/DomainDisabled"; import { Config } from "../types/Config"; import { Account } from "../types/Account"; import Mastodon from "megalodon"; import { isDarwinApp } from "../utilities/desktop"; interface ISettingsState { darkModeEnabled: boolean; systemDecidesDarkMode: boolean; pushNotificationsEnabled: boolean; badgeDisplaysAllNotifs: boolean; selectThemeName: string; themeDialogOpen: boolean; visibilityDialogOpen: boolean; resetHyperspaceDialog: boolean; resetSettingsDialog: boolean; previewTheme: Theme; defaultVisibility: Visibility; brandName: string; federated: boolean; currentUser?: Account; } class SettingsPage extends Component { client: Mastodon; constructor(props: any) { super(props); this.client = new Mastodon( localStorage.getItem("access_token") as string, (localStorage.getItem("baseurl") as string) + "/api/v1" ); this.state = { darkModeEnabled: getUserDefaultBool("darkModeEnabled"), systemDecidesDarkMode: getUserDefaultBool("systemDecidesDarkMode"), pushNotificationsEnabled: canSendNotifications(), badgeDisplaysAllNotifs: getUserDefaultBool( "displayAllOnNotificationBadge" ), selectThemeName: getUserDefaultTheme().key, themeDialogOpen: false, visibilityDialogOpen: false, resetHyperspaceDialog: false, resetSettingsDialog: false, previewTheme: setHyperspaceTheme(getUserDefaultTheme()) || setHyperspaceTheme(defaultTheme), defaultVisibility: getUserDefaultVisibility() || "public", brandName: "Hyperspace", federated: true }; this.toggleDarkMode = this.toggleDarkMode.bind(this); this.toggleSystemDarkMode = this.toggleSystemDarkMode.bind(this); this.togglePushNotifications = this.togglePushNotifications.bind(this); this.toggleBadgeCount = this.toggleBadgeCount.bind(this); this.toggleThemeDialog = this.toggleThemeDialog.bind(this); this.toggleVisibilityDialog = this.toggleVisibilityDialog.bind(this); this.changeThemeName = this.changeThemeName.bind(this); this.changeTheme = this.changeTheme.bind(this); this.setVisibility = this.setVisibility.bind(this); } componentDidMount() { getConfig() .then((config: any) => { this.setState({ brandName: config.branding.name }); }) .catch((err: Error) => { console.error(err.message); }); this.getFederatedStatus(); this.client .get("/accounts/verify_credentials") .then((resp: any) => { let data: Account = resp.data; this.setState({ currentUser: data }); }) .catch((err: Error) => { let acct = localStorage.getItem("account"); if (acct) { this.setState({ currentUser: JSON.parse(acct) }); } else { this.props.enqueueSnackbar( "Couldn't find profile info: " + err.name ); console.error(err.message); } }); } getFederatedStatus() { getConfig().then((result: any) => { if (result !== undefined) { let config: Config = result; console.log(!config.federation.allowPublicPosts); this.setState({ federated: config.federation.allowPublicPosts }); } }); } toggleDarkMode() { this.setState({ darkModeEnabled: !this.state.darkModeEnabled }); setUserDefaultBool("darkModeEnabled", !this.state.darkModeEnabled); window.location.reload(); } toggleSystemDarkMode() { this.setState({ systemDecidesDarkMode: !this.state.systemDecidesDarkMode }); setUserDefaultBool( "systemDecidesDarkMode", !this.state.systemDecidesDarkMode ); window.location.reload(); } togglePushNotifications() { this.setState({ pushNotificationsEnabled: !this.state.pushNotificationsEnabled }); setUserDefaultBool( "enablePushNotifications", !this.state.pushNotificationsEnabled ); } toggleBadgeCount() { this.setState({ badgeDisplaysAllNotifs: !this.state.badgeDisplaysAllNotifs }); setUserDefaultBool( "displayAllOnNotificationBadge", !this.state.badgeDisplaysAllNotifs ); } toggleThemeDialog() { this.setState({ themeDialogOpen: !this.state.themeDialogOpen }); } toggleVisibilityDialog() { this.setState({ visibilityDialogOpen: !this.state.visibilityDialogOpen }); } toggleResetDialog() { this.setState({ resetHyperspaceDialog: !this.state.resetHyperspaceDialog }); } toggleResetSettingsDialog() { this.setState({ resetSettingsDialog: !this.state.resetSettingsDialog }); } changeTheme() { setUserDefaultTheme(this.state.selectThemeName); window.location.reload(); } changeThemeName(theme: string) { let previewTheme = setHyperspaceTheme(getHyperspaceTheme(theme)); this.setState({ selectThemeName: theme, previewTheme }); } changeVisibility(to: Visibility) { this.setState({ defaultVisibility: to }); } setVisibility() { setUserDefaultVisibility(this.state.defaultVisibility); this.toggleVisibilityDialog(); } reset() { localStorage.clear(); window.location.reload(); } refresh() { let settings = [ "darkModeEnabled", "enablePushNotifications", "clearNotificationsOnRead", "theme", "displayAllOnNotificationBadge", "defaultVisibility" ]; settings.forEach(setting => { localStorage.removeItem(setting); }); window.location.reload(); } showThemeDialog() { const { classes } = this.props; return ( Choose a theme this.changeThemeName(value) } > {themes.map(theme => ( } label={theme.name} /> ))} ))} Theme preview ); } showVisibilityDialog() { return ( Set your default visibility this.changeVisibility(value as Visibility) } > } label={`Public ${ this.state.federated ? "" : "(disabled by provider)" }`} disabled={!this.state.federated} /> } label={"Unlisted"} /> } label={"Private (followers only)"} /> } label={"Direct"} /> ); } showResetSettingsDialog() { return ( this.toggleResetSettingsDialog()} > Are you sure you want to refresh settings? ); } showResetDialog() { return ( this.toggleResetDialog()} > Reset {this.state.brandName}? Are you sure you want to reset {this.state.brandName}? You'll need to re-authorize {this.state.brandName}{" "} access again. ); } render() { const { classes } = this.props; return (
{this.state.currentUser ? (

{this.state.currentUser.display_name || this.state.currentUser.username} @{this.state.currentUser.acct}
) : null}
Appearance {!isDarwinApp() || (isDarwinApp() && !this.state.systemDecidesDarkMode) ? ( ) : null}
Composer
Notifications
Advanced {this.showThemeDialog()} {this.showVisibilityDialog()} {this.showResetDialog()} {this.showResetSettingsDialog()}
); } } export default withStyles(styles)(SettingsPage);