2019-09-18 19:44:10 +02:00
|
|
|
import React, { Component } from "react";
|
|
|
|
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-10-27 20:34:55 +01:00
|
|
|
|
2019-09-18 19:44:10 +02: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";
|
|
|
|
import CreateIcon from "@material-ui/icons/Create";
|
2019-10-03 17:16:21 +02:00
|
|
|
import SupervisedUserCircleIcon from "@material-ui/icons/SupervisedUserCircle";
|
2019-09-18 19:44:10 +02:00
|
|
|
import ExitToAppIcon from "@material-ui/icons/ExitToApp";
|
2019-10-27 20:34:55 +01:00
|
|
|
|
2019-09-18 19:44:10 +02:00
|
|
|
import { styles } from "./AppLayout.styles";
|
2019-10-03 19:03:42 +02:00
|
|
|
import { MultiAccount, UAccount } from "../../types/Account";
|
2019-09-18 19:44:10 +02:00
|
|
|
import {
|
|
|
|
LinkableListItem,
|
|
|
|
LinkableIconButton,
|
|
|
|
LinkableFab
|
|
|
|
} from "../../interfaces/overrides";
|
|
|
|
import Mastodon from "megalodon";
|
|
|
|
import { Notification } from "../../types/Notification";
|
|
|
|
import { sendNotificationRequest } from "../../utilities/notifications";
|
|
|
|
import { withSnackbar } from "notistack";
|
|
|
|
import { getConfig, getUserDefaultBool } from "../../utilities/settings";
|
2019-10-01 22:56:57 +02:00
|
|
|
import {
|
|
|
|
isDesktopApp,
|
|
|
|
isDarwinApp,
|
|
|
|
getElectronApp
|
|
|
|
} from "../../utilities/desktop";
|
2019-09-18 19:44:10 +02:00
|
|
|
import { Config } from "../../types/Config";
|
2019-10-03 19:03:42 +02:00
|
|
|
import {
|
|
|
|
getAccountRegistry,
|
|
|
|
removeAccountFromRegistry
|
|
|
|
} from "../../utilities/accounts";
|
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-09-18 19:44:10 +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-09-18 19:44:10 +02:00
|
|
|
drawerOpenOnMobile: false,
|
|
|
|
acctMenuOpen: false,
|
|
|
|
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-09-18 19:44:10 +02:00
|
|
|
}
|
2019-03-28 03:01:55 +01:00
|
|
|
|
2019-09-18 19:44:10 +02:00
|
|
|
componentDidMount() {
|
2019-10-03 17:16:21 +02:00
|
|
|
this.getAccountData();
|
2019-04-07 23:25:39 +02:00
|
|
|
|
2019-05-08 21:24:36 +02:00
|
|
|
getConfig().then((result: any) => {
|
2019-09-18 19:44:10 +02:00
|
|
|
if (result !== undefined) {
|
|
|
|
let config: Config = result;
|
|
|
|
this.setState({
|
|
|
|
enableFederation: config.federation.enablePublicTimeline,
|
|
|
|
brandName: config.branding
|
|
|
|
? config.branding.name
|
|
|
|
: "Hyperspace",
|
|
|
|
developerMode: config.developer
|
|
|
|
});
|
|
|
|
}
|
|
|
|
});
|
2019-04-08 20:31:20 +02:00
|
|
|
|
2019-09-18 19:44:10 +02:00
|
|
|
this.streamNotifications();
|
|
|
|
}
|
2019-04-08 20:31:20 +02:00
|
|
|
|
2019-10-03 22:35:26 +02:00
|
|
|
getAccountData() {
|
2019-10-03 17:16:21 +02:00
|
|
|
this.client
|
|
|
|
.get("/accounts/verify_credentials")
|
|
|
|
.then((resp: any) => {
|
|
|
|
let data: UAccount = resp.data;
|
|
|
|
this.setState({ currentUser: data });
|
2019-10-03 22:48:11 +02:00
|
|
|
sessionStorage.setItem("id", data.id);
|
2019-10-03 17:16:21 +02:00
|
|
|
})
|
|
|
|
.catch((err: Error) => {
|
|
|
|
this.props.enqueueSnackbar(
|
|
|
|
"Couldn't find profile info: " + err.name
|
|
|
|
);
|
|
|
|
console.error(err.message);
|
|
|
|
let acct = localStorage.getItem("account") as string;
|
|
|
|
this.setState({ currentUser: JSON.parse(acct) });
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2019-09-18 19:44:10 +02:00
|
|
|
streamNotifications() {
|
|
|
|
this.streamListener = this.client.stream("/streaming/user");
|
2019-04-01 19:48:00 +02:00
|
|
|
|
2019-09-18 19:44:10 +02:00
|
|
|
if (getUserDefaultBool("displayAllOnNotificationBadge")) {
|
|
|
|
this.client.get("/notifications").then((resp: any) => {
|
|
|
|
let notifArray = resp.data;
|
|
|
|
this.setState({ notificationCount: notifArray.length });
|
|
|
|
});
|
2019-04-19 20:57:35 +02:00
|
|
|
}
|
|
|
|
|
2019-09-18 19:44:10 +02:00
|
|
|
this.streamListener.on("notification", (notif: Notification) => {
|
|
|
|
const notificationCount = this.state.notificationCount + 1;
|
|
|
|
this.setState({ notificationCount });
|
2019-10-01 22:56:57 +02:00
|
|
|
|
|
|
|
if (isDesktopApp()) {
|
|
|
|
getElectronApp().setBadgeCount(notificationCount);
|
|
|
|
}
|
|
|
|
|
2019-09-18 19:44:10 +02:00
|
|
|
if (!document.hasFocus()) {
|
|
|
|
let primaryMessage = "";
|
|
|
|
let secondaryMessage = "";
|
2019-04-01 19:48:00 +02:00
|
|
|
|
2019-09-18 19:44:10 +02:00
|
|
|
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;
|
2019-04-01 19:48:00 +02:00
|
|
|
}
|
|
|
|
|
2019-09-18 19:44:10 +02:00
|
|
|
sendNotificationRequest(primaryMessage, secondaryMessage);
|
|
|
|
}
|
2019-04-01 19:48:00 +02:00
|
|
|
});
|
2019-09-18 19:44:10 +02:00
|
|
|
}
|
2019-04-01 19:48:00 +02:00
|
|
|
|
2019-09-18 19:44:10 +02:00
|
|
|
toggleAcctMenu() {
|
2019-03-28 03:01:55 +01:00
|
|
|
this.setState({ acctMenuOpen: !this.state.acctMenuOpen });
|
2019-09-18 19:44:10 +02:00
|
|
|
}
|
2019-03-26 02:37:02 +01:00
|
|
|
|
2019-09-18 19:44:10 +02:00
|
|
|
toggleDrawerOnMobile() {
|
2019-03-26 02:37:02 +01:00
|
|
|
this.setState({
|
2019-09-18 19:44:10 +02:00
|
|
|
drawerOpenOnMobile: !this.state.drawerOpenOnMobile
|
|
|
|
});
|
|
|
|
}
|
2019-03-26 02:37:02 +01:00
|
|
|
|
2019-09-18 19:44:10 +02:00
|
|
|
toggleLogOutDialog() {
|
2019-04-07 23:25:39 +02:00
|
|
|
this.setState({ logOutOpen: !this.state.logOutOpen });
|
2019-09-18 19:44:10 +02:00
|
|
|
}
|
2019-04-07 23:25:39 +02:00
|
|
|
|
2019-09-18 19:44:10 +02:00
|
|
|
searchForQuery(what: string) {
|
2019-10-27 20:34:55 +01:00
|
|
|
what = what.replace(/^#/g, "tag:");
|
|
|
|
console.log(what);
|
2019-09-18 19:44:10 +02:00
|
|
|
window.location.href = isDesktopApp()
|
|
|
|
? "hyperspace://hyperspace/app/index.html#/search?query=" + what
|
|
|
|
: "/#/search?query=" + what;
|
|
|
|
}
|
2019-04-02 23:28:04 +02:00
|
|
|
|
2019-09-18 19:44:10 +02:00
|
|
|
logOutAndRestart() {
|
2019-04-07 23:25:39 +02:00
|
|
|
let loginData = localStorage.getItem("login");
|
|
|
|
if (loginData) {
|
2019-10-03 19:03:42 +02:00
|
|
|
let registry = getAccountRegistry();
|
|
|
|
|
|
|
|
registry.forEach((registryItem: MultiAccount, index: number) => {
|
|
|
|
if (
|
|
|
|
registryItem.access_token ===
|
|
|
|
localStorage.getItem("access_token")
|
|
|
|
) {
|
|
|
|
removeAccountFromRegistry(index);
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
2019-09-18 19:44:10 +02:00
|
|
|
let items = ["login", "account", "baseurl", "access_token"];
|
|
|
|
items.forEach(entry => {
|
|
|
|
localStorage.removeItem(entry);
|
|
|
|
});
|
2019-10-03 19:03:42 +02:00
|
|
|
|
2019-09-18 19:44:10 +02:00
|
|
|
window.location.reload();
|
2019-04-07 23:25:39 +02:00
|
|
|
}
|
2019-09-18 19:44:10 +02:00
|
|
|
}
|
2019-04-07 23:25:39 +02:00
|
|
|
|
2019-09-18 19:44:10 +02:00
|
|
|
clearBadge() {
|
|
|
|
if (!getUserDefaultBool("displayAllOnNotificationBadge")) {
|
|
|
|
this.setState({ notificationCount: 0 });
|
2019-04-20 21:12:48 +02:00
|
|
|
}
|
2019-10-01 22:56:57 +02:00
|
|
|
|
|
|
|
if (isDesktopApp() && getElectronApp().getBadgeCount() > 0) {
|
|
|
|
getElectronApp().setBadgeCount(0);
|
|
|
|
}
|
2019-09-18 19:44:10 +02:00
|
|
|
}
|
2019-04-20 21:12:48 +02:00
|
|
|
|
2019-09-18 19:44:10 +02:00
|
|
|
titlebar() {
|
2019-03-26 02:37:02 +01:00
|
|
|
const { classes } = this.props;
|
2019-05-16 17:00:37 +02:00
|
|
|
if (isDarwinApp()) {
|
2019-09-18 19:44:10 +02:00
|
|
|
return (
|
|
|
|
<div className={classes.titleBarRoot}>
|
2019-10-01 00:18:38 +02:00
|
|
|
<Typography
|
|
|
|
className={classes.titleBarText}
|
|
|
|
color="inherit"
|
|
|
|
>
|
2019-09-18 19:44:10 +02:00
|
|
|
{this.state.brandName
|
|
|
|
? this.state.brandName
|
|
|
|
: "Hyperspace"}{" "}
|
2019-09-19 00:12:18 +02:00
|
|
|
{this.state.developerMode ? "(Beta)" : null}
|
2019-09-18 19:44:10 +02:00
|
|
|
</Typography>
|
|
|
|
</div>
|
|
|
|
);
|
2019-09-19 00:12:18 +02:00
|
|
|
} else if (process.env.NODE_ENV === "development") {
|
2019-09-18 19:44:10 +02:00
|
|
|
return (
|
|
|
|
<div className={classes.titleBarRoot}>
|
|
|
|
<Typography className={classes.titleBarText}>
|
|
|
|
Careful: you're running in developer mode.
|
|
|
|
</Typography>
|
|
|
|
</div>
|
|
|
|
);
|
|
|
|
}
|
|
|
|
}
|
2019-03-26 02:37:02 +01:00
|
|
|
|
2019-09-18 19:44:10 +02:00
|
|
|
appDrawer() {
|
2019-03-26 02:37:02 +01:00
|
|
|
const { classes } = this.props;
|
|
|
|
return (
|
2019-09-18 19:44:10 +02:00
|
|
|
<div>
|
|
|
|
<List>
|
|
|
|
<div className={classes.drawerDisplayMobile}>
|
|
|
|
<LinkableListItem
|
|
|
|
button
|
|
|
|
key="profile-mobile"
|
|
|
|
to={`/profile/${
|
|
|
|
this.state.currentUser
|
|
|
|
? this.state.currentUser.id
|
|
|
|
: "1"
|
|
|
|
}`}
|
|
|
|
>
|
|
|
|
<ListItemAvatar>
|
|
|
|
<Avatar
|
|
|
|
alt="You"
|
|
|
|
src={
|
|
|
|
this.state.currentUser
|
|
|
|
? this.state.currentUser
|
|
|
|
.avatar_static
|
|
|
|
: ""
|
|
|
|
}
|
|
|
|
/>
|
|
|
|
</ListItemAvatar>
|
|
|
|
<ListItemText
|
|
|
|
primary={
|
|
|
|
this.state.currentUser
|
|
|
|
? this.state.currentUser.display_name ||
|
|
|
|
this.state.currentUser.acct
|
|
|
|
: "Loading..."
|
|
|
|
}
|
|
|
|
secondary={
|
|
|
|
this.state.currentUser
|
|
|
|
? this.state.currentUser.acct
|
|
|
|
: "Loading..."
|
|
|
|
}
|
|
|
|
/>
|
|
|
|
</LinkableListItem>
|
2019-10-03 17:16:21 +02:00
|
|
|
<LinkableListItem
|
|
|
|
button
|
|
|
|
key="acctSwitch-module"
|
|
|
|
to="/welcome"
|
|
|
|
>
|
|
|
|
<ListItemIcon>
|
|
|
|
<SupervisedUserCircleIcon />
|
|
|
|
</ListItemIcon>
|
|
|
|
<ListItemText
|
|
|
|
primary={
|
|
|
|
getAccountRegistry().length > 1
|
|
|
|
? "Switch account"
|
|
|
|
: "Add account"
|
|
|
|
}
|
|
|
|
/>
|
|
|
|
</LinkableListItem>
|
2019-09-18 19:44:10 +02:00
|
|
|
<ListItem
|
|
|
|
button
|
|
|
|
key="acctLogout-mobile"
|
|
|
|
onClick={() => this.toggleLogOutDialog()}
|
|
|
|
>
|
|
|
|
<ListItemIcon>
|
|
|
|
<ExitToAppIcon />
|
|
|
|
</ListItemIcon>
|
|
|
|
<ListItemText primary="Log out" />
|
|
|
|
</ListItem>
|
|
|
|
<Divider />
|
|
|
|
</div>
|
|
|
|
<ListSubheader>Timelines</ListSubheader>
|
|
|
|
<LinkableListItem button key="home" to="/home">
|
|
|
|
<ListItemIcon>
|
|
|
|
<HomeIcon />
|
|
|
|
</ListItemIcon>
|
|
|
|
<ListItemText primary="Home" />
|
|
|
|
</LinkableListItem>
|
|
|
|
<LinkableListItem button key="local" to="/local">
|
|
|
|
<ListItemIcon>
|
|
|
|
<DomainIcon />
|
|
|
|
</ListItemIcon>
|
|
|
|
<ListItemText primary="Local" />
|
|
|
|
</LinkableListItem>
|
|
|
|
{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>
|
|
|
|
)}
|
|
|
|
<Divider />
|
|
|
|
<div className={classes.drawerDisplayMobile}>
|
|
|
|
<ListSubheader>Account</ListSubheader>
|
|
|
|
<LinkableListItem
|
|
|
|
button
|
|
|
|
key="notifications-mobile"
|
|
|
|
to="/notifications"
|
|
|
|
>
|
|
|
|
<ListItemIcon>
|
|
|
|
<Badge
|
|
|
|
badgeContent={
|
|
|
|
this.state.notificationCount > 0
|
|
|
|
? this.state.notificationCount
|
|
|
|
: ""
|
|
|
|
}
|
|
|
|
color="secondary"
|
|
|
|
>
|
|
|
|
<NotificationsIcon />
|
|
|
|
</Badge>
|
|
|
|
</ListItemIcon>
|
|
|
|
<ListItemText primary="Notifications" />
|
|
|
|
</LinkableListItem>
|
|
|
|
<LinkableListItem
|
|
|
|
button
|
|
|
|
key="messages-mobile"
|
|
|
|
to="/messages"
|
|
|
|
>
|
|
|
|
<ListItemIcon>
|
|
|
|
<MailIcon />
|
|
|
|
</ListItemIcon>
|
|
|
|
<ListItemText primary="Messages" />
|
|
|
|
</LinkableListItem>
|
|
|
|
<Divider />
|
|
|
|
</div>
|
|
|
|
<ListSubheader>More</ListSubheader>
|
|
|
|
<LinkableListItem
|
|
|
|
button
|
|
|
|
key="recommended"
|
|
|
|
to="/recommended"
|
|
|
|
>
|
|
|
|
<ListItemIcon>
|
|
|
|
<GroupIcon />
|
|
|
|
</ListItemIcon>
|
|
|
|
<ListItemText primary="Who to follow" />
|
|
|
|
</LinkableListItem>
|
|
|
|
<LinkableListItem button key="settings" to="/settings">
|
|
|
|
<ListItemIcon>
|
|
|
|
<SettingsIcon />
|
|
|
|
</ListItemIcon>
|
|
|
|
<ListItemText primary="Settings" />
|
|
|
|
</LinkableListItem>
|
|
|
|
<LinkableListItem button key="info" to="/about">
|
|
|
|
<ListItemIcon>
|
|
|
|
<InfoIcon />
|
|
|
|
</ListItemIcon>
|
|
|
|
<ListItemText primary="About" />
|
|
|
|
</LinkableListItem>
|
|
|
|
</List>
|
|
|
|
</div>
|
|
|
|
);
|
2019-03-26 02:37:02 +01:00
|
|
|
}
|
|
|
|
|
2019-09-18 19:44:10 +02:00
|
|
|
render() {
|
|
|
|
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
|
|
|
|
>
|
|
|
|
{this.state.brandName
|
|
|
|
? this.state.brandName
|
|
|
|
: "Hyperspace"}
|
|
|
|
</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
|
|
|
|
}}
|
|
|
|
onKeyUp={event => {
|
|
|
|
if (event.keyCode === 13) {
|
|
|
|
this.searchForQuery(
|
|
|
|
event.currentTarget.value
|
|
|
|
);
|
|
|
|
}
|
|
|
|
}}
|
|
|
|
/>
|
|
|
|
</div>
|
|
|
|
<div className={classes.appBarFlexGrow} />
|
|
|
|
<div className={classes.appBarActionButtons}>
|
|
|
|
<Tooltip title="Notifications">
|
|
|
|
<LinkableIconButton
|
|
|
|
color="inherit"
|
|
|
|
to="/notifications"
|
|
|
|
onClick={this.clearBadge}
|
|
|
|
>
|
|
|
|
<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-04-12 19:53:48 +02:00
|
|
|
|
2019-09-18 19:44:10 +02:00
|
|
|
<Menu
|
|
|
|
id="acct-menu"
|
|
|
|
anchorEl={document.getElementById(
|
|
|
|
"acctMenuBtn"
|
|
|
|
)}
|
|
|
|
open={this.state.acctMenuOpen}
|
|
|
|
className={classes.acctMenu}
|
|
|
|
>
|
|
|
|
<ClickAwayListener
|
|
|
|
onClickAway={this.toggleAcctMenu}
|
|
|
|
>
|
|
|
|
<div>
|
|
|
|
<LinkableListItem
|
2019-10-05 19:31:51 +02:00
|
|
|
button={true}
|
2019-09-18 19:44:10 +02:00
|
|
|
to={`/profile/${
|
|
|
|
this.state.currentUser
|
|
|
|
? this.state.currentUser
|
|
|
|
.id
|
|
|
|
: "1"
|
|
|
|
}`}
|
|
|
|
>
|
|
|
|
<ListItemAvatar>
|
|
|
|
<Avatar
|
|
|
|
alt="You"
|
|
|
|
src={
|
|
|
|
this.state
|
|
|
|
.currentUser
|
|
|
|
? this.state
|
|
|
|
.currentUser
|
|
|
|
.avatar_static
|
|
|
|
: ""
|
|
|
|
}
|
|
|
|
/>
|
|
|
|
</ListItemAvatar>
|
|
|
|
<ListItemText
|
|
|
|
primary={
|
|
|
|
this.state.currentUser
|
|
|
|
? this.state
|
|
|
|
.currentUser
|
|
|
|
.display_name ||
|
|
|
|
this.state
|
|
|
|
.currentUser
|
|
|
|
.acct
|
|
|
|
: "Loading..."
|
|
|
|
}
|
|
|
|
secondary={
|
|
|
|
"@" +
|
|
|
|
(this.state.currentUser
|
|
|
|
? this.state
|
|
|
|
.currentUser
|
|
|
|
.acct
|
|
|
|
: "Loading...")
|
|
|
|
}
|
|
|
|
/>
|
|
|
|
</LinkableListItem>
|
|
|
|
<Divider />
|
2019-10-05 19:31:51 +02:00
|
|
|
<LinkableListItem
|
|
|
|
button={true}
|
|
|
|
to={"/you"}
|
|
|
|
>
|
2019-09-18 19:44:10 +02:00
|
|
|
<ListItemText>
|
|
|
|
Edit profile
|
|
|
|
</ListItemText>
|
|
|
|
</LinkableListItem>
|
2019-10-05 19:31:51 +02:00
|
|
|
<LinkableListItem
|
|
|
|
to={"/welcome"}
|
|
|
|
button={true}
|
|
|
|
>
|
2019-10-03 17:16:21 +02:00
|
|
|
<ListItemText>
|
|
|
|
{getAccountRegistry()
|
|
|
|
.length > 1
|
|
|
|
? "Switch account"
|
|
|
|
: "Add account"}
|
|
|
|
</ListItemText>
|
|
|
|
</LinkableListItem>
|
2019-09-18 19:44:10 +02:00
|
|
|
<MenuItem
|
|
|
|
onClick={() =>
|
|
|
|
this.toggleLogOutDialog()
|
|
|
|
}
|
|
|
|
>
|
|
|
|
Log out
|
|
|
|
</MenuItem>
|
|
|
|
</div>
|
|
|
|
</ClickAwayListener>
|
|
|
|
</Menu>
|
|
|
|
</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-10-03 19:03:42 +02:00
|
|
|
{this.logoutDialog()}
|
2019-09-18 19:44:10 +02:00
|
|
|
<Tooltip title="Create a new post">
|
|
|
|
<LinkableFab
|
|
|
|
to="/compose"
|
|
|
|
className={classes.composeButton}
|
|
|
|
color="secondary"
|
|
|
|
aria-label="Compose"
|
|
|
|
>
|
|
|
|
<CreateIcon />
|
|
|
|
</LinkableFab>
|
|
|
|
</Tooltip>
|
|
|
|
</div>
|
|
|
|
);
|
|
|
|
}
|
2019-10-03 19:03:42 +02:00
|
|
|
|
|
|
|
logoutDialog() {
|
|
|
|
return (
|
|
|
|
<Dialog
|
|
|
|
open={this.state.logOutOpen}
|
|
|
|
onClose={() => this.toggleLogOutDialog()}
|
|
|
|
>
|
|
|
|
<DialogTitle id="alert-dialog-title">
|
|
|
|
Log out of{" "}
|
|
|
|
{this.state.brandName ? this.state.brandName : "Hyperspace"}
|
|
|
|
</DialogTitle>
|
|
|
|
<DialogContent>
|
|
|
|
<DialogContentText id="alert-dialog-description">
|
|
|
|
<Typography paragraph>
|
|
|
|
You'll need to remove{" "}
|
|
|
|
{this.state.brandName
|
|
|
|
? this.state.brandName
|
|
|
|
: "Hyperspace"}{" "}
|
|
|
|
from your list of authorized apps and log in again
|
|
|
|
if you want to use{" "}
|
|
|
|
{this.state.brandName
|
|
|
|
? this.state.brandName
|
|
|
|
: "Hyperspace"}
|
|
|
|
.
|
|
|
|
</Typography>
|
|
|
|
<Typography paragraph>
|
|
|
|
Logging out will also remove this account from the
|
|
|
|
account list.
|
|
|
|
</Typography>
|
|
|
|
</DialogContentText>
|
|
|
|
</DialogContent>
|
|
|
|
<DialogActions>
|
|
|
|
<Button
|
|
|
|
onClick={() => this.toggleLogOutDialog()}
|
|
|
|
color="primary"
|
|
|
|
autoFocus
|
|
|
|
>
|
|
|
|
Cancel
|
|
|
|
</Button>
|
|
|
|
<Button
|
|
|
|
onClick={() => {
|
|
|
|
this.logOutAndRestart();
|
|
|
|
}}
|
|
|
|
color="primary"
|
|
|
|
>
|
|
|
|
Log out
|
|
|
|
</Button>
|
|
|
|
</DialogActions>
|
|
|
|
</Dialog>
|
|
|
|
);
|
|
|
|
}
|
2019-03-26 02:37:02 +01:00
|
|
|
}
|
|
|
|
|
2019-05-23 00:52:19 +02:00
|
|
|
export default withStyles(styles)(withSnackbar(AppLayout));
|