2019-03-26 02:37:02 +01:00
|
|
|
import React, { Component } from 'react';
|
2019-04-12 19:53:48 +02:00
|
|
|
import { Typography, AppBar, Toolbar, IconButton, InputBase, Avatar, ListItemText, Divider, List, ListItemIcon, Hidden, Drawer, ListSubheader, ListItemAvatar, withStyles, Menu, MenuItem, ClickAwayListener, Badge, Dialog, DialogTitle, DialogContent, DialogContentText, DialogActions, Button, ListItem, Tooltip } from '@material-ui/core';
|
2019-03-26 02:37:02 +01:00
|
|
|
import MenuIcon from '@material-ui/icons/Menu';
|
|
|
|
import SearchIcon from '@material-ui/icons/Search';
|
|
|
|
import NotificationsIcon from '@material-ui/icons/Notifications';
|
|
|
|
import MailIcon from '@material-ui/icons/Mail';
|
|
|
|
import HomeIcon from '@material-ui/icons/Home';
|
|
|
|
import DomainIcon from '@material-ui/icons/Domain';
|
|
|
|
import PublicIcon from '@material-ui/icons/Public';
|
|
|
|
import GroupIcon from '@material-ui/icons/Group';
|
|
|
|
import SettingsIcon from '@material-ui/icons/Settings';
|
|
|
|
import InfoIcon from '@material-ui/icons/Info';
|
2019-04-04 02:01:54 +02:00
|
|
|
import EditIcon from '@material-ui/icons/Edit';
|
2019-04-20 21:12:48 +02:00
|
|
|
//import SupervisedUserCircleIcon from '@material-ui/icons/SupervisedUserCircle';
|
2019-03-26 02:37:02 +01:00
|
|
|
import ExitToAppIcon from '@material-ui/icons/ExitToApp';
|
|
|
|
import {styles} from './AppLayout.styles';
|
2019-03-28 00:24:52 +01:00
|
|
|
import { UAccount } from '../../types/Account';
|
2019-04-04 02:01:54 +02:00
|
|
|
import {LinkableListItem, LinkableIconButton, LinkableFab} from '../../interfaces/overrides';
|
2019-04-01 19:48:00 +02:00
|
|
|
import Mastodon from 'megalodon';
|
|
|
|
import { Notification } from '../../types/Notification';
|
|
|
|
import {sendNotificationRequest} from '../../utilities/notifications';
|
2019-04-07 23:25:39 +02:00
|
|
|
import {withSnackbar} from 'notistack';
|
2019-04-19 20:57:35 +02:00
|
|
|
import { getConfig, getUserDefaultBool } from '../../utilities/settings';
|
2019-03-26 02:37:02 +01:00
|
|
|
|
|
|
|
interface IAppLayoutState {
|
2019-03-28 03:01:55 +01:00
|
|
|
acctMenuOpen: boolean;
|
2019-03-26 02:37:02 +01:00
|
|
|
drawerOpenOnMobile: boolean;
|
2019-04-07 23:25:39 +02:00
|
|
|
currentUser?: UAccount;
|
2019-04-01 19:48:00 +02:00
|
|
|
notificationCount: number;
|
2019-04-07 23:25:39 +02:00
|
|
|
logOutOpen: boolean;
|
2019-04-08 20:31:20 +02:00
|
|
|
enableFederation?: boolean;
|
|
|
|
brandName?: string;
|
|
|
|
developerMode?: boolean;
|
2019-03-26 02:37:02 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
export class AppLayout extends Component<any, IAppLayoutState> {
|
2019-04-01 19:48:00 +02:00
|
|
|
|
|
|
|
client: Mastodon;
|
|
|
|
streamListener: any;
|
|
|
|
|
2019-03-26 02:37:02 +01:00
|
|
|
constructor(props: any) {
|
|
|
|
super(props);
|
2019-03-28 03:01:55 +01:00
|
|
|
|
2019-04-01 19:48:00 +02:00
|
|
|
this.client = new Mastodon(localStorage.getItem('access_token') as string, localStorage.getItem('baseurl') as string + "/api/v1");
|
2019-03-26 02:37:02 +01:00
|
|
|
|
|
|
|
this.state = {
|
2019-03-28 00:24:52 +01:00
|
|
|
drawerOpenOnMobile: false,
|
2019-03-28 03:01:55 +01:00
|
|
|
acctMenuOpen: false,
|
2019-04-07 23:25:39 +02:00
|
|
|
notificationCount: 0,
|
|
|
|
logOutOpen: false
|
2019-03-26 02:37:02 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
this.toggleDrawerOnMobile = this.toggleDrawerOnMobile.bind(this);
|
2019-03-28 03:01:55 +01:00
|
|
|
this.toggleAcctMenu = this.toggleAcctMenu.bind(this);
|
2019-04-20 21:12:48 +02:00
|
|
|
this.clearBadge = this.clearBadge.bind(this);
|
2019-03-28 03:01:55 +01:00
|
|
|
}
|
|
|
|
|
2019-04-01 19:48:00 +02:00
|
|
|
componentDidMount() {
|
2019-04-07 23:25:39 +02:00
|
|
|
|
|
|
|
let acct = localStorage.getItem('account');
|
|
|
|
if (acct) {
|
|
|
|
this.setState({ currentUser: JSON.parse(acct) });
|
|
|
|
} else {
|
|
|
|
this.client.get('/accounts/verify_credentials').then((resp: any) => {
|
|
|
|
let data: UAccount = resp.data;
|
|
|
|
this.setState({ currentUser: data });
|
|
|
|
}).catch((err: Error) => {
|
|
|
|
this.props.enqueueSnackbar("Couldn't find profile info: " + err.name);
|
|
|
|
console.error(err.message);
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
2019-04-08 20:31:20 +02:00
|
|
|
getConfig().then((config: any) => {
|
|
|
|
this.setState({
|
|
|
|
enableFederation: config.federated === "true",
|
|
|
|
brandName: config.branding? config.branding.name: "Hyperspace",
|
|
|
|
developerMode: config.developer === "true"
|
|
|
|
});
|
|
|
|
})
|
|
|
|
|
|
|
|
this.streamNotifications()
|
|
|
|
}
|
|
|
|
|
|
|
|
streamNotifications() {
|
2019-04-01 19:48:00 +02:00
|
|
|
this.streamListener = this.client.stream('/streaming/user');
|
|
|
|
|
2019-04-19 20:57:35 +02:00
|
|
|
if (getUserDefaultBool('displayAllOnNotificationBadge')) {
|
|
|
|
this.client.get('/notifications').then((resp: any) => {
|
|
|
|
let notifArray = resp.data;
|
|
|
|
this.setState({ notificationCount: notifArray.length });
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
2019-04-01 19:48:00 +02:00
|
|
|
this.streamListener.on('notification', (notif: Notification) => {
|
|
|
|
const notificationCount = this.state.notificationCount + 1;
|
|
|
|
this.setState({ notificationCount });
|
|
|
|
if (!document.hasFocus()) {
|
|
|
|
let primaryMessage = "";
|
|
|
|
let secondaryMessage = "";
|
|
|
|
|
|
|
|
switch(notif.type) {
|
|
|
|
case "favourite":
|
|
|
|
primaryMessage = (notif.account.display_name || "@" + notif.account.username) + " favorited your post.";
|
|
|
|
if (notif.status) {
|
|
|
|
const div = document.createElement('div');
|
|
|
|
div.innerHTML = notif.status.content;
|
|
|
|
secondaryMessage = (div.textContent || div.innerText || "").slice(0, 100) + "..."
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case "follow":
|
|
|
|
primaryMessage = (notif.account.display_name || "@" + notif.account.username) + " is now following you.";
|
|
|
|
break;
|
|
|
|
case "mention":
|
|
|
|
primaryMessage = (notif.account.display_name || "@" + notif.account.username) + " mentioned you in a post.";
|
|
|
|
if (notif.status) {
|
|
|
|
const div = document.createElement('div');
|
|
|
|
div.innerHTML = notif.status.content;
|
|
|
|
secondaryMessage = (div.textContent || div.innerText || "").slice(0, 100) + "..."
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case "reblog":
|
|
|
|
primaryMessage = (notif.account.display_name || "@" + notif.account.username) + " reblogged your post.";
|
|
|
|
if (notif.status) {
|
|
|
|
const div = document.createElement('div');
|
|
|
|
div.innerHTML = notif.status.content;
|
|
|
|
secondaryMessage = (div.textContent || div.innerText || "").slice(0, 100) + "..."
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
sendNotificationRequest(primaryMessage, secondaryMessage);
|
|
|
|
}
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2019-03-28 03:01:55 +01:00
|
|
|
toggleAcctMenu() {
|
|
|
|
this.setState({ acctMenuOpen: !this.state.acctMenuOpen });
|
2019-03-26 02:37:02 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
toggleDrawerOnMobile() {
|
|
|
|
this.setState({
|
|
|
|
drawerOpenOnMobile: !this.state.drawerOpenOnMobile
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
2019-04-07 23:25:39 +02:00
|
|
|
toggleLogOutDialog() {
|
|
|
|
this.setState({ logOutOpen: !this.state.logOutOpen });
|
|
|
|
}
|
|
|
|
|
2019-04-02 23:28:04 +02:00
|
|
|
searchForQuery(what: string) {
|
|
|
|
window.location.href = "/#/search?query=" + what;
|
|
|
|
window.location.reload;
|
|
|
|
}
|
|
|
|
|
2019-04-07 23:25:39 +02:00
|
|
|
logOutAndRestart() {
|
|
|
|
let loginData = localStorage.getItem("login");
|
|
|
|
if (loginData) {
|
2019-04-08 20:31:20 +02:00
|
|
|
let items = ["login", "account", "baseurl", "access_token"];
|
|
|
|
items.forEach((entry) => {
|
|
|
|
localStorage.removeItem(entry);
|
|
|
|
})
|
2019-04-07 23:25:39 +02:00
|
|
|
window.location.reload();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-04-20 21:12:48 +02:00
|
|
|
clearBadge() {
|
|
|
|
if (!getUserDefaultBool('displayAllOnNotificationBadge')) {
|
|
|
|
this.setState({ notificationCount: 0 });
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-03-26 02:37:02 +01:00
|
|
|
titlebar() {
|
|
|
|
const { classes } = this.props;
|
2019-04-08 20:31:20 +02:00
|
|
|
if (this.state.developerMode || process.env.NODE_ENV === "development") {
|
2019-03-26 02:37:02 +01:00
|
|
|
return (
|
|
|
|
<div className={classes.titleBarRoot}>
|
2019-03-28 21:46:19 +01:00
|
|
|
<Typography className={classes.titleBarText}>Careful: you're running in developer mode.</Typography>
|
2019-03-26 02:37:02 +01:00
|
|
|
</div>
|
|
|
|
);
|
|
|
|
} else if ((navigator.userAgent.includes("Hyperspace") || navigator.userAgent.includes("Electron")) && navigator.userAgent.includes("Macintosh")) {
|
|
|
|
return (
|
|
|
|
<div className={classes.titleBarRoot}>
|
|
|
|
<Typography className={classes.titleBarText}>Hyperspace</Typography>
|
|
|
|
</div>
|
|
|
|
);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
appDrawer() {
|
|
|
|
const { classes } = this.props;
|
|
|
|
return (
|
|
|
|
<div>
|
|
|
|
<List>
|
|
|
|
<div className={classes.drawerDisplayMobile}>
|
2019-04-07 23:25:39 +02:00
|
|
|
<LinkableListItem button key="profile-mobile" to={`/profile/${this.state.currentUser? this.state.currentUser.id: "1"}`}>
|
2019-03-26 02:37:02 +01:00
|
|
|
<ListItemAvatar>
|
2019-04-07 23:25:39 +02:00
|
|
|
<Avatar alt="You" src={this.state.currentUser? this.state.currentUser.avatar_static: ""}/>
|
2019-03-26 02:37:02 +01:00
|
|
|
</ListItemAvatar>
|
2019-04-07 23:25:39 +02:00
|
|
|
<ListItemText primary={this.state.currentUser? (this.state.currentUser.display_name || this.state.currentUser.acct): "Loading..."} secondary={this.state.currentUser? this.state.currentUser.acct: "Loading..."}/>
|
2019-03-27 01:35:30 +01:00
|
|
|
</LinkableListItem>
|
|
|
|
<LinkableListItem button key="notifications-mobile" to="/notifications">
|
2019-04-21 19:56:18 +02:00
|
|
|
<ListItemIcon>
|
|
|
|
<Badge badgeContent={this.state.notificationCount > 0? this.state.notificationCount: ""} color="secondary">
|
|
|
|
<NotificationsIcon />
|
|
|
|
</Badge>
|
|
|
|
</ListItemIcon>
|
2019-03-26 02:37:02 +01:00
|
|
|
<ListItemText primary="Notifications"/>
|
2019-03-27 01:35:30 +01:00
|
|
|
</LinkableListItem>
|
|
|
|
<LinkableListItem button key="messages-mobile" to="/messages">
|
2019-03-26 02:37:02 +01:00
|
|
|
<ListItemIcon><MailIcon/></ListItemIcon>
|
|
|
|
<ListItemText primary="Messages"/>
|
2019-03-27 01:35:30 +01:00
|
|
|
</LinkableListItem>
|
2019-04-19 21:26:22 +02:00
|
|
|
{/* <LinkableListItem button key="acctSwitch-module" to="/switchacct">
|
2019-03-26 02:37:02 +01:00
|
|
|
<ListItemIcon><SupervisedUserCircleIcon/></ListItemIcon>
|
|
|
|
<ListItemText primary="Switch account"/>
|
2019-04-19 21:26:22 +02:00
|
|
|
</LinkableListItem> */}
|
2019-04-07 23:33:19 +02:00
|
|
|
<ListItem button key="acctLogout-mobile" onClick={() => this.toggleLogOutDialog()}>
|
2019-03-26 02:37:02 +01:00
|
|
|
<ListItemIcon><ExitToAppIcon/></ListItemIcon>
|
|
|
|
<ListItemText primary="Log out"/>
|
2019-04-07 23:33:19 +02:00
|
|
|
</ListItem>
|
2019-03-26 02:37:02 +01:00
|
|
|
<Divider/>
|
|
|
|
</div>
|
|
|
|
<ListSubheader>Timelines</ListSubheader>
|
2019-03-27 01:35:30 +01:00
|
|
|
<LinkableListItem button key="home" to="/home">
|
2019-03-26 02:37:02 +01:00
|
|
|
<ListItemIcon><HomeIcon/></ListItemIcon>
|
|
|
|
<ListItemText primary="Home"/>
|
2019-03-27 01:35:30 +01:00
|
|
|
</LinkableListItem>
|
|
|
|
<LinkableListItem button key="local" to="/local">
|
2019-03-26 02:37:02 +01:00
|
|
|
<ListItemIcon><DomainIcon/></ListItemIcon>
|
|
|
|
<ListItemText primary="Local"/>
|
2019-03-27 01:35:30 +01:00
|
|
|
</LinkableListItem>
|
2019-04-08 20:31:20 +02:00
|
|
|
{
|
|
|
|
this.state.enableFederation?
|
|
|
|
<LinkableListItem button key="public" to="/public">
|
|
|
|
<ListItemIcon><PublicIcon/></ListItemIcon>
|
|
|
|
<ListItemText primary="Public"/>
|
|
|
|
</LinkableListItem>:
|
|
|
|
<ListItem disabled>
|
|
|
|
<ListItemIcon><PublicIcon/></ListItemIcon>
|
|
|
|
<ListItemText primary="Public" secondary="Disabled by admin"/>
|
|
|
|
</ListItem>
|
|
|
|
}
|
2019-03-26 02:37:02 +01:00
|
|
|
<Divider/>
|
|
|
|
<ListSubheader>More</ListSubheader>
|
2019-04-21 19:45:47 +02:00
|
|
|
<LinkableListItem button key="recommended" to="/recommended">
|
2019-03-26 02:37:02 +01:00
|
|
|
<ListItemIcon><GroupIcon/></ListItemIcon>
|
2019-04-21 19:45:47 +02:00
|
|
|
<ListItemText primary="Who to follow"/>
|
2019-03-27 01:35:30 +01:00
|
|
|
</LinkableListItem>
|
|
|
|
<LinkableListItem button key="settings" to="/settings">
|
2019-03-26 02:37:02 +01:00
|
|
|
<ListItemIcon><SettingsIcon/></ListItemIcon>
|
|
|
|
<ListItemText primary="Settings"/>
|
2019-03-27 01:35:30 +01:00
|
|
|
</LinkableListItem>
|
|
|
|
<LinkableListItem button key="info" to="/about">
|
2019-03-26 02:37:02 +01:00
|
|
|
<ListItemIcon><InfoIcon/></ListItemIcon>
|
|
|
|
<ListItemText primary="About"/>
|
2019-03-27 01:35:30 +01:00
|
|
|
</LinkableListItem>
|
2019-03-26 02:37:02 +01:00
|
|
|
</List>
|
|
|
|
</div>
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
2019-04-01 19:48:00 +02:00
|
|
|
render() {
|
2019-03-26 02:37:02 +01:00
|
|
|
const { classes } = this.props;
|
|
|
|
return (
|
|
|
|
<div className={classes.root}>
|
|
|
|
<div className={classes.stickyArea}>
|
|
|
|
{this.titlebar()}
|
|
|
|
<AppBar className={classes.appBar} position="static">
|
|
|
|
<Toolbar>
|
|
|
|
<IconButton
|
|
|
|
className={classes.appBarMenuButton}
|
|
|
|
color="inherit"
|
|
|
|
aria-label="Open drawer"
|
|
|
|
onClick={this.toggleDrawerOnMobile}
|
|
|
|
>
|
|
|
|
<MenuIcon/>
|
|
|
|
</IconButton>
|
|
|
|
<Typography className={classes.appBarTitle} variant="h6" color="inherit" noWrap>
|
2019-04-08 20:31:20 +02:00
|
|
|
{this.state.brandName? this.state.brandName: "Hyperspace"}
|
2019-03-26 02:37:02 +01:00
|
|
|
</Typography>
|
|
|
|
<div className={classes.appBarFlexGrow}/>
|
|
|
|
<div className={classes.appBarSearch}>
|
|
|
|
<div className={classes.appBarSearchIcon}>
|
|
|
|
<SearchIcon/>
|
|
|
|
</div>
|
|
|
|
<InputBase
|
|
|
|
placeholder="Search..."
|
|
|
|
classes={{
|
|
|
|
root: classes.appBarSearchInputRoot,
|
|
|
|
input: classes.appBarSearchInputInput
|
|
|
|
}}
|
2019-04-02 23:28:04 +02:00
|
|
|
onKeyUp={(event) => {
|
|
|
|
if (event.keyCode === 13) {
|
|
|
|
this.searchForQuery(event.currentTarget.value);
|
|
|
|
}
|
|
|
|
}}
|
2019-03-26 02:37:02 +01:00
|
|
|
/>
|
|
|
|
</div>
|
|
|
|
<div className={classes.appBarFlexGrow}/>
|
|
|
|
<div className={classes.appBarActionButtons}>
|
2019-04-12 19:53:48 +02:00
|
|
|
<Tooltip title="Notifications">
|
2019-04-20 21:12:48 +02:00
|
|
|
<LinkableIconButton color="inherit" to="/notifications" onClick={this.clearBadge}>
|
2019-04-12 19:53:48 +02:00
|
|
|
<Badge badgeContent={this.state.notificationCount > 0? this.state.notificationCount: ""} color="secondary">
|
|
|
|
<NotificationsIcon />
|
|
|
|
</Badge>
|
|
|
|
</LinkableIconButton>
|
|
|
|
</Tooltip>
|
|
|
|
<Tooltip title="Direct messages">
|
|
|
|
<LinkableIconButton color="inherit" to="/messages">
|
|
|
|
<MailIcon/>
|
|
|
|
</LinkableIconButton>
|
|
|
|
</Tooltip>
|
|
|
|
<Tooltip title="Your account">
|
|
|
|
<IconButton id="acctMenuBtn" onClick={this.toggleAcctMenu}>
|
|
|
|
<Avatar className={classes.appBarAcctMenuIcon} alt="You" src={this.state.currentUser? this.state.currentUser.avatar_static: ""}/>
|
|
|
|
</IconButton>
|
|
|
|
</Tooltip>
|
|
|
|
|
2019-03-28 03:01:55 +01:00
|
|
|
<Menu
|
|
|
|
id="acct-menu"
|
|
|
|
anchorEl={document.getElementById("acctMenuBtn")}
|
|
|
|
open={this.state.acctMenuOpen}
|
|
|
|
className={classes.acctMenu}
|
|
|
|
>
|
|
|
|
<ClickAwayListener onClickAway={this.toggleAcctMenu}>
|
2019-03-30 22:13:49 +01:00
|
|
|
<div>
|
2019-04-07 23:25:39 +02:00
|
|
|
<LinkableListItem to={`/profile/${this.state.currentUser? this.state.currentUser.id: "1"}`}>
|
2019-03-30 22:13:49 +01:00
|
|
|
<ListItemAvatar>
|
2019-04-07 23:25:39 +02:00
|
|
|
<Avatar alt="You" src={this.state.currentUser? this.state.currentUser.avatar_static: ""}/>
|
2019-03-30 22:13:49 +01:00
|
|
|
</ListItemAvatar>
|
2019-04-07 23:25:39 +02:00
|
|
|
<ListItemText
|
|
|
|
primary={this.state.currentUser? (this.state.currentUser.display_name || this.state.currentUser.acct): "Loading..."}
|
|
|
|
secondary={'@' + (this.state.currentUser? this.state.currentUser.acct: "Loading...")}
|
|
|
|
/>
|
2019-03-30 22:13:49 +01:00
|
|
|
</LinkableListItem>
|
|
|
|
<Divider/>
|
2019-04-06 19:41:43 +02:00
|
|
|
{/* <MenuItem>Switch account</MenuItem> */}
|
2019-04-07 23:25:39 +02:00
|
|
|
<MenuItem onClick={() => this.toggleLogOutDialog()}>Log out</MenuItem>
|
2019-03-30 22:13:49 +01:00
|
|
|
</div>
|
2019-03-28 03:01:55 +01:00
|
|
|
</ClickAwayListener>
|
|
|
|
</Menu>
|
2019-03-26 02:37:02 +01:00
|
|
|
</div>
|
|
|
|
</Toolbar>
|
|
|
|
</AppBar>
|
|
|
|
<nav className={classes.drawer}>
|
|
|
|
<Hidden mdUp implementation="css">
|
|
|
|
<Drawer
|
|
|
|
container={this.props.container}
|
|
|
|
variant="temporary"
|
|
|
|
anchor={'left'}
|
|
|
|
open={this.state.drawerOpenOnMobile}
|
|
|
|
onClose={this.toggleDrawerOnMobile}
|
|
|
|
classes={{ paper: classes.drawerPaper }}
|
|
|
|
>
|
|
|
|
{this.appDrawer()}
|
|
|
|
</Drawer>
|
|
|
|
</Hidden>
|
|
|
|
<Hidden smDown implementation="css">
|
|
|
|
<Drawer
|
|
|
|
classes={{
|
|
|
|
paper: this.titlebar()? classes.drawerPaperWithTitleAndAppBar: classes.drawerPaperWithAppBar
|
|
|
|
}}
|
|
|
|
variant="permanent"
|
|
|
|
open
|
|
|
|
>
|
|
|
|
{this.appDrawer()}
|
|
|
|
</Drawer>
|
|
|
|
</Hidden>
|
|
|
|
</nav>
|
|
|
|
</div>
|
2019-04-07 23:25:39 +02:00
|
|
|
<Dialog
|
|
|
|
open={this.state.logOutOpen}
|
|
|
|
onClose={() => this.toggleLogOutDialog()}
|
|
|
|
>
|
|
|
|
<DialogTitle id="alert-dialog-title">Log out of Hyperspace?</DialogTitle>
|
|
|
|
<DialogContent>
|
|
|
|
<DialogContentText id="alert-dialog-description">
|
|
|
|
You'll need to remove Hyperspace from your list of authorized apps and log in again if you want to use Hyperspace.
|
|
|
|
</DialogContentText>
|
|
|
|
</DialogContent>
|
|
|
|
<DialogActions>
|
|
|
|
<Button onClick={() => this.toggleLogOutDialog()} color="primary" autoFocus>
|
|
|
|
Cancel
|
|
|
|
</Button>
|
|
|
|
<Button onClick={() => {
|
|
|
|
this.logOutAndRestart();
|
|
|
|
}} color="primary">
|
|
|
|
Log out
|
|
|
|
</Button>
|
|
|
|
</DialogActions>
|
|
|
|
</Dialog>
|
2019-04-12 19:53:48 +02:00
|
|
|
<Tooltip title="Create a new post">
|
|
|
|
<LinkableFab to="/compose" className={classes.composeButton} color="secondary" aria-label="Compose">
|
|
|
|
<EditIcon/>
|
|
|
|
</LinkableFab>
|
|
|
|
</Tooltip>
|
2019-03-26 02:37:02 +01:00
|
|
|
</div>
|
|
|
|
);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-04-07 23:25:39 +02:00
|
|
|
export default withStyles(styles)(withSnackbar(AppLayout));
|