diff --git a/package-lock.json b/package-lock.json index ca84251..8452ce4 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1297,6 +1297,12 @@ "@types/react": "*" } }, + "@types/events": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@types/events/-/events-3.0.0.tgz", + "integrity": "sha512-EaObqwIvayI5a8dCzhFrjKzVwKLxjoG9T6Ppd5CEo07LRKfQ8Yokw54r5+Wq7FaBQ+yXRvQAYPrHwya1/UFt9g==", + "dev": true + }, "@types/history": { "version": "4.7.2", "resolved": "https://registry.npmjs.org/@types/history/-/history-4.7.2.tgz", @@ -1491,12 +1497,13 @@ "@types/unist": "*" } }, - "@types/ws": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/@types/ws/-/ws-6.0.3.tgz", - "integrity": "sha512-yBTM0P05Tx9iXGq00BbJPo37ox68R5vaGTXivs6RGh/BQ6QP5zqZDGWdAO6JbRE/iR1l80xeGAwCQS2nMV9S/w==", + "@types/websocket": { + "version": "0.0.40", + "resolved": "https://registry.npmjs.org/@types/websocket/-/websocket-0.0.40.tgz", + "integrity": "sha512-ldteZwWIgl9cOy7FyvYn+39Ah4+PfpVE72eYKw75iy2L0zTbhbcwvzeJ5IOu6DQP93bjfXq0NGHY6FYtmYoqFQ==", "dev": true, "requires": { + "@types/events": "*", "@types/node": "*" } }, @@ -12191,19 +12198,19 @@ "dev": true }, "megalodon": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/megalodon/-/megalodon-1.0.3.tgz", - "integrity": "sha512-RcJT3HRWCXQcE5ZQUpLEjJ+HgWvwoTpXr4XLUf0tWrtmxrDnIW43pOASDb3G7MOBKYonzM1pMfAmR2Yfh3Qw/g==", + "version": "0.6.4", + "resolved": "https://registry.npmjs.org/megalodon/-/megalodon-0.6.4.tgz", + "integrity": "sha512-WGYhcSxGYlBwZSm5VebxLqnbpPemum9/6lJUi1HBsVzF5jXc9fdumhXH0vqGhWdovdqRT86iXBDJl5SwUrbr2A==", "dev": true, "requires": { "@types/oauth": "^0.9.0", "@types/request": "^2.47.0", - "@types/ws": "^6.0.1", - "axios": "^0.18.1", + "@types/websocket": "0.0.40", + "axios": "^0.18.0", "oauth": "^0.9.15", "request": "^2.87.0", - "typescript": "^3.4.5", - "ws": "^7.0.1" + "typescript": "^2.9.1", + "websocket": "^1.0.28" }, "dependencies": { "axios": { @@ -12247,19 +12254,10 @@ "dev": true }, "typescript": { - "version": "3.6.3", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.6.3.tgz", - "integrity": "sha512-N7bceJL1CtRQ2RiG0AQME13ksR7DiuQh/QehubYcghzv20tnh+MQnQIuJddTmsbqYj+dztchykemz0zFzlvdQw==", + "version": "2.9.2", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-2.9.2.tgz", + "integrity": "sha512-Gr4p6nFNaoufRIY4NMdpQRNmgxVIGMs4Fcu/ujdYk3nAZqk7supzBE9idmvfZIlH/Cuj//dvi+019qEue9lV0w==", "dev": true - }, - "ws": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/ws/-/ws-7.1.2.tgz", - "integrity": "sha512-gftXq3XI81cJCgkUiAVixA0raD9IVmXqsylCrjRygw4+UOOGzPoxnQ6r/CnVL9i+mDncJo94tSkyrtuuQVBmrg==", - "dev": true, - "requires": { - "async-limiter": "^1.0.0" - } } } }, @@ -19851,6 +19849,15 @@ "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=", "dev": true }, + "typedarray-to-buffer": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz", + "integrity": "sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q==", + "dev": true, + "requires": { + "is-typedarray": "^1.0.0" + } + }, "typescript": { "version": "3.4.1", "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.4.1.tgz", @@ -21010,6 +21017,41 @@ } } }, + "websocket": { + "version": "1.0.30", + "resolved": "https://registry.npmjs.org/websocket/-/websocket-1.0.30.tgz", + "integrity": "sha512-aO6klgaTdSMkhfl5VVJzD5fm+Srhh5jLYbS15+OiI1sN6h/RU/XW6WN9J1uVIpUKNmsTvT3Hs35XAFjn9NMfOw==", + "dev": true, + "requires": { + "debug": "^2.2.0", + "nan": "^2.14.0", + "typedarray-to-buffer": "^3.1.5", + "yaeti": "^0.0.6" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + }, + "nan": { + "version": "2.14.0", + "resolved": "https://registry.npmjs.org/nan/-/nan-2.14.0.tgz", + "integrity": "sha512-INOFj37C7k3AfaNTtX8RhsTw7qRy7eLET14cROi9+5HAVbbHuIWUHEauBv5qT4Av2tWasiTY1Jw6puUNqRJXQg==", + "dev": true + } + } + }, "websocket-driver": { "version": "0.7.0", "resolved": "https://registry.npmjs.org/websocket-driver/-/websocket-driver-0.7.0.tgz", @@ -21368,6 +21410,12 @@ "integrity": "sha1-bRX7qITAhnnA136I53WegR4H+kE=", "dev": true }, + "yaeti": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/yaeti/-/yaeti-0.0.6.tgz", + "integrity": "sha1-8m9ITXJoTPQr7ft2lwqhYI+/lXc=", + "dev": true + }, "yallist": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", diff --git a/package.json b/package.json index 283ddce..0397a79 100644 --- a/package.json +++ b/package.json @@ -25,10 +25,10 @@ "file-dialog": "^0.0.7", "material-ui-pickers": "^2.2.4", "mdi-material-ui": "^5.13.0", - "megalodon": "^1.0.3", + "megalodon": "^0.6.4", "moment": "^2.24.0", "notistack": "^0.5.1", - "prettier": "^1.18.2", + "prettier": "1.18.2", "query-string": "^6.8.2", "react": "^16.8.6", "react-dom": "^16.8.6", diff --git a/screenshot.png b/screenshot.png index 95837d9..5c25ea3 100644 Binary files a/screenshot.png and b/screenshot.png differ diff --git a/src/App.styles.tsx b/src/App.styles.tsx index 53c33d5..c5c9a33 100644 --- a/src/App.styles.tsx +++ b/src/App.styles.tsx @@ -2,23 +2,23 @@ import { Theme, createStyles } from "@material-ui/core"; import { isDarwinApp } from "./utilities/desktop"; export const styles = (theme: Theme) => - createStyles({ - root: { - width: "100%", - display: "flex", - height: "100%", - minHeight: "100vh", - backgroundColor: isDarwinApp() - ? "transparent" - : theme.palette.background.default - }, - content: { - marginTop: 72, - flexGrow: 1, - padding: theme.spacing.unit * 3, - [theme.breakpoints.up("md")]: { - marginLeft: 250, - marginTop: 88 - } - } - }); + createStyles({ + root: { + width: "100%", + display: "flex", + height: "100%", + minHeight: "100vh", + backgroundColor: isDarwinApp() + ? "transparent" + : theme.palette.background.default + }, + content: { + marginTop: 72, + flexGrow: 1, + padding: theme.spacing.unit * 3, + [theme.breakpoints.up("md")]: { + marginLeft: 250, + marginTop: 88 + } + } + }); diff --git a/src/App.tsx b/src/App.tsx index 0155cef..fc17344 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -20,7 +20,6 @@ import MessagesPage from "./pages/Messages"; import RecommendationsPage from "./pages/Recommendations"; import Missingno from "./pages/Missingno"; import You from "./pages/You"; -import Blocked from "./pages/Blocked"; import { withSnackbar } from "notistack"; import { PrivateRoute } from "./interfaces/overrides"; import { userLoggedIn } from "./utilities/accounts"; @@ -57,8 +56,6 @@ class App extends Component { removeBodyBackground() { if (isDarwinApp()) { document.body.style.backgroundColor = "transparent"; - console.log("Changed!"); - console.log(`New color: ${document.body.style.backgroundColor}`); } } @@ -91,9 +88,7 @@ class App extends Component { component={Conversation} /> - - diff --git a/src/components/AppLayout/AppLayout.styles.tsx b/src/components/AppLayout/AppLayout.styles.tsx index 56c56df..8726189 100644 --- a/src/components/AppLayout/AppLayout.styles.tsx +++ b/src/components/AppLayout/AppLayout.styles.tsx @@ -5,167 +5,167 @@ import { isDarwinApp } from "../../utilities/desktop"; import { fade } from "@material-ui/core/styles/colorManipulator"; export const styles = (theme: Theme) => - createStyles({ - root: { - width: "100%", - display: "flex" - }, - stickyArea: { - position: "fixed", - width: "100%", - top: 0, - left: 0, - zIndex: 1000 - }, - titleBarRoot: { - top: 0, - left: 0, - height: 24, - width: "100%", - backgroundColor: isDarwinApp() - ? theme.palette.primary.main - : theme.palette.primary.dark, - textAlign: "center", - zIndex: 1000, - verticalAlign: "middle", - WebkitUserSelect: "none", - WebkitAppRegion: "drag" - }, - titleBarText: { - color: theme.palette.common.white, - fontSize: 12, - paddingTop: 2, - paddingBottom: 1 - }, - appBar: { - zIndex: 1000, - backgroundImage: isDarwinApp() - ? `linear-gradient(${theme.palette.primary.main}, ${theme.palette.primary.dark})` - : undefined, - backgroundColor: theme.palette.primary.main, - borderBottomColor: darken(theme.palette.primary.dark, 0.2), - borderBottomWidth: 1, - borderBottomStyle: isDarwinApp() ? "solid" : "none", - boxShadow: isDarwinApp() ? "none" : "inherit" - }, - appBarMenuButton: { - marginLeft: -12, - marginRight: 20, - [theme.breakpoints.up("md")]: { - display: "none" - } - }, - appBarTitle: { - display: "none", - [theme.breakpoints.up("md")]: { - display: "block" - } - }, - appBarSearch: { - position: "relative", - borderRadius: theme.shape.borderRadius, - backgroundColor: fade(theme.palette.common.white, 0.15), - "&:hover": { - backgroundColor: fade(theme.palette.common.white, 0.25) - }, - width: "100%", - marginLeft: 0, - marginRight: theme.spacing.unit, - [theme.breakpoints.up("md")]: { - marginLeft: theme.spacing.unit * 6, - width: "50%" - } - }, - appBarSearchIcon: { - width: theme.spacing.unit * 9, - height: "100%", - position: "absolute", - pointerEvents: "none", - display: "flex", - alignItems: "center", - justifyContent: "center" - }, - appBarSearchInputRoot: { - color: "inherit", - width: "100%" - }, - appBarSearchInputInput: { - paddingTop: theme.spacing.unit, - paddingBottom: theme.spacing.unit, - paddingLeft: theme.spacing.unit * 10, - paddingRight: theme.spacing.unit, - transition: theme.transitions.create("width"), - width: "100%" - }, - appBarFlexGrow: { - flexGrow: 1 - }, - appBarActionButtons: { - display: "none", - [theme.breakpoints.up("sm")]: { - display: "flex" - } - }, - appBarAcctMenuIcon: { - backgroundColor: theme.palette.primary.dark - }, - acctMenu: {}, - drawer: { - [theme.breakpoints.up("sm")]: { - width: 250, - flexShrink: 0 - }, - zIndex: 1 - }, - drawerPaper: { - width: 250, - zIndex: 1 - }, - drawerPaperWithAppBar: { - width: 250, - zIndex: -1, - marginTop: 64, - backgroundColor: isDarwinApp() - ? "transparent" - : theme.palette.background.paper - }, - drawerPaperWithTitleAndAppBar: { - width: 250, - zIndex: -1, - marginTop: 88, - backgroundColor: isDarwinApp() - ? "transparent" - : theme.palette.background.paper - }, - drawerDisplayMobile: { - [theme.breakpoints.up("md")]: { - display: "none" - } - }, - toolbar: theme.mixins.toolbar, - sectionDesktop: { - display: "none", - [theme.breakpoints.up("md")]: { - display: "flex" - } - }, - sectionMobile: { - display: "flex", - [theme.breakpoints.up("md")]: { - display: "none" - } - }, - content: { - padding: theme.spacing.unit * 3, - [theme.breakpoints.up("md")]: { - marginLeft: 250 - }, - overflowY: "auto" - }, - composeButton: { - position: "fixed", - bottom: theme.spacing.unit * 2, - right: theme.spacing.unit * 2, - zIndex: 50 - } - }); + createStyles({ + root: { + width: "100%", + display: "flex" + }, + stickyArea: { + position: "fixed", + width: "100%", + top: 0, + left: 0, + zIndex: 1000 + }, + titleBarRoot: { + top: 0, + left: 0, + height: 24, + width: "100%", + backgroundColor: isDarwinApp() + ? theme.palette.primary.main + : theme.palette.primary.dark, + textAlign: "center", + zIndex: 1000, + verticalAlign: "middle", + WebkitUserSelect: "none", + WebkitAppRegion: "drag" + }, + titleBarText: { + color: theme.palette.common.white, + fontSize: 12, + paddingTop: 2, + paddingBottom: 1 + }, + appBar: { + zIndex: 1000, + backgroundImage: isDarwinApp() + ? `linear-gradient(${theme.palette.primary.main}, ${theme.palette.primary.dark})` + : undefined, + backgroundColor: theme.palette.primary.main, + borderBottomColor: darken(theme.palette.primary.dark, 0.2), + borderBottomWidth: 1, + borderBottomStyle: isDarwinApp() ? "solid" : "none", + boxShadow: isDarwinApp() ? "none" : theme.shadows["4"] + }, + appBarMenuButton: { + marginLeft: -12, + marginRight: 20, + [theme.breakpoints.up("md")]: { + display: "none" + } + }, + appBarTitle: { + display: "none", + [theme.breakpoints.up("md")]: { + display: "block" + } + }, + appBarSearch: { + position: "relative", + borderRadius: theme.shape.borderRadius, + backgroundColor: fade(theme.palette.common.white, 0.15), + "&:hover": { + backgroundColor: fade(theme.palette.common.white, 0.25) + }, + width: "100%", + marginLeft: 0, + marginRight: theme.spacing.unit, + [theme.breakpoints.up("md")]: { + marginLeft: theme.spacing.unit * 6, + width: "50%" + } + }, + appBarSearchIcon: { + width: theme.spacing.unit * 9, + height: "100%", + position: "absolute", + pointerEvents: "none", + display: "flex", + alignItems: "center", + justifyContent: "center" + }, + appBarSearchInputRoot: { + color: "inherit", + width: "100%" + }, + appBarSearchInputInput: { + paddingTop: theme.spacing.unit, + paddingBottom: theme.spacing.unit, + paddingLeft: theme.spacing.unit * 10, + paddingRight: theme.spacing.unit, + transition: theme.transitions.create("width"), + width: "100%" + }, + appBarFlexGrow: { + flexGrow: 1 + }, + appBarActionButtons: { + display: "none", + [theme.breakpoints.up("sm")]: { + display: "flex" + } + }, + appBarAcctMenuIcon: { + backgroundColor: theme.palette.primary.dark + }, + acctMenu: {}, + drawer: { + [theme.breakpoints.up("sm")]: { + width: 250, + flexShrink: 0 + }, + zIndex: 1 + }, + drawerPaper: { + width: 250, + zIndex: 1 + }, + drawerPaperWithAppBar: { + width: 250, + zIndex: -1, + marginTop: 64, + backgroundColor: isDarwinApp() + ? "transparent" + : theme.palette.background.paper + }, + drawerPaperWithTitleAndAppBar: { + width: 250, + zIndex: -1, + marginTop: 88, + backgroundColor: isDarwinApp() + ? "transparent" + : theme.palette.background.paper + }, + drawerDisplayMobile: { + [theme.breakpoints.up("md")]: { + display: "none" + } + }, + toolbar: theme.mixins.toolbar, + sectionDesktop: { + display: "none", + [theme.breakpoints.up("md")]: { + display: "flex" + } + }, + sectionMobile: { + display: "flex", + [theme.breakpoints.up("md")]: { + display: "none" + } + }, + content: { + padding: theme.spacing.unit * 3, + [theme.breakpoints.up("md")]: { + marginLeft: 250 + }, + overflowY: "auto" + }, + composeButton: { + position: "fixed", + bottom: theme.spacing.unit * 2, + right: theme.spacing.unit * 2, + zIndex: 50 + } + }); diff --git a/src/components/AppLayout/AppLayout.tsx b/src/components/AppLayout/AppLayout.tsx index fc24655..73dfcea 100644 --- a/src/components/AppLayout/AppLayout.tsx +++ b/src/components/AppLayout/AppLayout.tsx @@ -1,32 +1,32 @@ 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 + 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"; import MenuIcon from "@material-ui/icons/Menu"; import SearchIcon from "@material-ui/icons/Search"; @@ -44,9 +44,9 @@ import ExitToAppIcon from "@material-ui/icons/ExitToApp"; import { styles } from "./AppLayout.styles"; import { UAccount } from "../../types/Account"; import { - LinkableListItem, - LinkableIconButton, - LinkableFab + LinkableListItem, + LinkableIconButton, + LinkableFab } from "../../interfaces/overrides"; import Mastodon from "megalodon"; import { Notification } from "../../types/Notification"; @@ -57,539 +57,614 @@ import { isDesktopApp, isDarwinApp } from "../../utilities/desktop"; import { Config } from "../../types/Config"; interface IAppLayoutState { - acctMenuOpen: boolean; - drawerOpenOnMobile: boolean; - currentUser?: UAccount; - notificationCount: number; - logOutOpen: boolean; - enableFederation?: boolean; - brandName?: string; - developerMode?: boolean; + acctMenuOpen: boolean; + drawerOpenOnMobile: boolean; + currentUser?: UAccount; + notificationCount: number; + logOutOpen: boolean; + enableFederation?: boolean; + brandName?: string; + developerMode?: boolean; } export class AppLayout extends Component { - client: Mastodon; - streamListener: any; + client: Mastodon; + streamListener: any; - constructor(props: any) { - super(props); + constructor(props: any) { + super(props); - this.client = new Mastodon( - localStorage.getItem("access_token") as string, - (localStorage.getItem("baseurl") as string) + "/api/v1" - ); + this.client = new Mastodon( + localStorage.getItem("access_token") as string, + (localStorage.getItem("baseurl") as string) + "/api/v1" + ); - this.state = { - drawerOpenOnMobile: false, - acctMenuOpen: false, - notificationCount: 0, - logOutOpen: false - }; + this.state = { + drawerOpenOnMobile: false, + acctMenuOpen: false, + notificationCount: 0, + logOutOpen: false + }; - this.toggleDrawerOnMobile = this.toggleDrawerOnMobile.bind(this); - this.toggleAcctMenu = this.toggleAcctMenu.bind(this); - this.clearBadge = this.clearBadge.bind(this); - } - - componentDidMount() { - 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); - }); + this.toggleDrawerOnMobile = this.toggleDrawerOnMobile.bind(this); + this.toggleAcctMenu = this.toggleAcctMenu.bind(this); + this.clearBadge = this.clearBadge.bind(this); } - getConfig().then((result: any) => { - if (result !== undefined) { - let config: Config = result; - this.setState({ - enableFederation: config.federation.enablePublicTimeline, - brandName: config.branding ? config.branding.name : "Hyperspace", - developerMode: config.developer - }); - } - }); - - this.streamNotifications(); - } - - streamNotifications() { - this.streamListener = this.client.stream("/streaming/user"); - - if (getUserDefaultBool("displayAllOnNotificationBadge")) { - this.client.get("/notifications").then((resp: any) => { - let notifArray = resp.data; - this.setState({ notificationCount: notifArray.length }); - }); - } - - 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; + componentDidMount() { + 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); + }); } - sendNotificationRequest(primaryMessage, secondaryMessage); - } - }); - } + getConfig().then((result: any) => { + if (result !== undefined) { + let config: Config = result; + this.setState({ + enableFederation: config.federation.enablePublicTimeline, + brandName: config.branding + ? config.branding.name + : "Hyperspace", + developerMode: config.developer + }); + } + }); - toggleAcctMenu() { - this.setState({ acctMenuOpen: !this.state.acctMenuOpen }); - } - - toggleDrawerOnMobile() { - this.setState({ - drawerOpenOnMobile: !this.state.drawerOpenOnMobile - }); - } - - toggleLogOutDialog() { - this.setState({ logOutOpen: !this.state.logOutOpen }); - } - - searchForQuery(what: string) { - window.location.href = isDesktopApp() - ? "hyperspace://hyperspace/app/index.html#/search?query=" + what - : "/#/search?query=" + what; - window.location.reload; - } - - logOutAndRestart() { - let loginData = localStorage.getItem("login"); - if (loginData) { - let items = ["login", "account", "baseurl", "access_token"]; - items.forEach(entry => { - localStorage.removeItem(entry); - }); - window.location.reload(); + this.streamNotifications(); } - } - clearBadge() { - if (!getUserDefaultBool("displayAllOnNotificationBadge")) { - this.setState({ notificationCount: 0 }); - } - } + streamNotifications() { + this.streamListener = this.client.stream("/streaming/user"); - titlebar() { - const { classes } = this.props; - if (isDarwinApp()) { - return ( -
- - {this.state.brandName ? this.state.brandName : "Hyperspace"}{" "} - {this.state.developerMode ? "(beta)" : null} - -
- ); - } else if ( - this.state.developerMode || - process.env.NODE_ENV === "development" - ) { - return ( -
- - Careful: you're running in developer mode. - -
- ); - } - } + if (getUserDefaultBool("displayAllOnNotificationBadge")) { + this.client.get("/notifications").then((resp: any) => { + let notifArray = resp.data; + this.setState({ notificationCount: notifArray.length }); + }); + } - appDrawer() { - const { classes } = this.props; - return ( -
- -
- - - - - { + 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; } - secondary={ - this.state.currentUser - ? this.state.currentUser.acct - : "Loading..." - } - /> - - {/* + + sendNotificationRequest(primaryMessage, secondaryMessage); + } + }); + } + + toggleAcctMenu() { + this.setState({ acctMenuOpen: !this.state.acctMenuOpen }); + } + + toggleDrawerOnMobile() { + this.setState({ + drawerOpenOnMobile: !this.state.drawerOpenOnMobile + }); + } + + toggleLogOutDialog() { + this.setState({ logOutOpen: !this.state.logOutOpen }); + } + + searchForQuery(what: string) { + window.location.href = isDesktopApp() + ? "hyperspace://hyperspace/app/index.html#/search?query=" + what + : "/#/search?query=" + what; + window.location.reload; + } + + logOutAndRestart() { + let loginData = localStorage.getItem("login"); + if (loginData) { + let items = ["login", "account", "baseurl", "access_token"]; + items.forEach(entry => { + localStorage.removeItem(entry); + }); + window.location.reload(); + } + } + + clearBadge() { + if (!getUserDefaultBool("displayAllOnNotificationBadge")) { + this.setState({ notificationCount: 0 }); + } + } + + titlebar() { + const { classes } = this.props; + if (isDarwinApp()) { + return ( +
+ + {this.state.brandName + ? this.state.brandName + : "Hyperspace"}{" "} + {this.state.developerMode ? "(Beta)" : null} + +
+ ); + } else if (process.env.NODE_ENV === "development") { + return ( +
+ + Careful: you're running in developer mode. + +
+ ); + } + } + + appDrawer() { + const { classes } = this.props; + return ( +
+ +
+ + + + + + + {/* */} - this.toggleLogOutDialog()} - > - - - - - - -
- Timelines - - - - - - - - - - - - - {this.state.enableFederation ? ( - - - - - - - ) : ( - - - - - - - )} - -
- Account - - - 0 - ? this.state.notificationCount - : "" - } - color="secondary" - > - - - - - - - - - - - - -
- More - - - - - - - - - - - - - - - - - - -
-
- ); - } - - render() { - const { classes } = this.props; - return ( -
-
- {this.titlebar()} - - - - - - - {this.state.brandName ? this.state.brandName : "Hyperspace"} - -
-
-
- -
- { - if (event.keyCode === 13) { - this.searchForQuery(event.currentTarget.value); - } - }} - /> -
-
-
- - - 0 - ? this.state.notificationCount - : "" - } - color="secondary" - > - - - - - - - - - - - - - - - - - -
- - - - - - - - {/* Switch account */} - this.toggleLogOutDialog()}> - Log out - + this.toggleLogOutDialog()} + > + + + + + +
-
-
-
- - - -
- this.toggleLogOutDialog()} - > - - Log out of{" "} - {this.state.brandName ? this.state.brandName : "Hyperspace"} - - - - 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"}. - - - - - - - - - - - - -
- ); - } + Timelines + + + + + + + + + + + + + {this.state.enableFederation ? ( + + + + + + + ) : ( + + + + + + + )} + +
+ Account + + + 0 + ? this.state.notificationCount + : "" + } + color="secondary" + > + + + + + + + + + + + + +
+ More + + + + + + + + + + + + + + + + + + + +
+ ); + } + + render() { + const { classes } = this.props; + return ( +
+
+ {this.titlebar()} + + + + + + + {this.state.brandName + ? this.state.brandName + : "Hyperspace"} + +
+
+
+ +
+ { + if (event.keyCode === 13) { + this.searchForQuery( + event.currentTarget.value + ); + } + }} + /> +
+
+
+ + + 0 + ? this.state + .notificationCount + : "" + } + color="secondary" + > + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + Edit profile + + + {/* Switch account */} + + this.toggleLogOutDialog() + } + > + Log out + +
+
+
+
+ + + +
+ this.toggleLogOutDialog()} + > + + Log out of{" "} + {this.state.brandName + ? this.state.brandName + : "Hyperspace"} + + + + 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"} + . + + + + + + + + + + + + +
+ ); + } } export default withStyles(styles)(withSnackbar(AppLayout)); diff --git a/src/components/Attachment/Attachment.styles.tsx b/src/components/Attachment/Attachment.styles.tsx index 9bdcd91..d4aef9d 100644 --- a/src/components/Attachment/Attachment.styles.tsx +++ b/src/components/Attachment/Attachment.styles.tsx @@ -1,17 +1,17 @@ import { Theme, createStyles } from "@material-ui/core"; export const styles = (theme: Theme) => - createStyles({ - mediaContainer: { - padding: theme.spacing.unit * 2 - }, - mediaObject: { - width: "100%", - height: "100%" - }, - mediaSlide: { - backgroundColor: theme.palette.primary.light, - width: "100%", - height: "auto" - } - }); + createStyles({ + mediaContainer: { + padding: theme.spacing.unit * 2 + }, + mediaObject: { + width: "100%", + height: "100%" + }, + mediaSlide: { + backgroundColor: theme.palette.primary.light, + width: "100%", + height: "auto" + } + }); diff --git a/src/components/Attachment/Attachment.tsx b/src/components/Attachment/Attachment.tsx index 0956a7f..348cc2e 100644 --- a/src/components/Attachment/Attachment.tsx +++ b/src/components/Attachment/Attachment.tsx @@ -1,141 +1,146 @@ import React, { Component } from "react"; import { - withStyles, - Typography, - MobileStepper, - Button + withStyles, + Typography, + MobileStepper, + Button } from "@material-ui/core"; import { styles } from "./Attachment.styles"; import { Attachment } from "../../types/Attachment"; import SwipeableViews from "react-swipeable-views"; interface IAttachmentProps { - media: [Attachment]; - classes?: any; + media: [Attachment]; + classes?: any; } interface IAttachmentState { - totalSteps: number; - currentStep: number; - attachments: [Attachment]; + totalSteps: number; + currentStep: number; + attachments: [Attachment]; } class AttachmentComponent extends Component< - IAttachmentProps, - IAttachmentState + IAttachmentProps, + IAttachmentState > { - constructor(props: IAttachmentProps) { - super(props); + constructor(props: IAttachmentProps) { + super(props); - this.state = { - attachments: this.props.media, - totalSteps: this.props.media.length, - currentStep: 0 - }; - } - - moveBack() { - let nextStep = this.state.currentStep - 1; - if (nextStep < 0) { - nextStep = 0; + this.state = { + attachments: this.props.media, + totalSteps: this.props.media.length, + currentStep: 0 + }; } - this.setState({ currentStep: nextStep }); - } - moveForward() { - let nextStep = this.state.currentStep + 1; - if (nextStep > this.state.totalSteps) { - nextStep = this.state.totalSteps; + moveBack() { + let nextStep = this.state.currentStep - 1; + if (nextStep < 0) { + nextStep = 0; + } + this.setState({ currentStep: nextStep }); } - this.setState({ currentStep: nextStep }); - } - handleStepChange(currentStep: number) { - this.setState({ - currentStep - }); - } - - getSlide(slide: Attachment) { - const { classes } = this.props; - switch (slide.type) { - case "image": - return ( - {slide.description - ); - case "video": - return ( -