From eac85169d9b8042c0344f8b6ba2c9a3296f34022 Mon Sep 17 00:00:00 2001 From: Marquis Kurt Date: Tue, 1 Oct 2019 16:56:57 -0400 Subject: [PATCH 01/12] Fix notifications not deleting due to old API, add notification badge support --- src/components/AppLayout/AppLayout.tsx | 15 ++++++++++++++- src/pages/Notifications.tsx | 2 +- src/pages/PageLayout.styles.tsx | 12 ++++++------ src/utilities/desktop.tsx | 9 +++++++++ 4 files changed, 30 insertions(+), 8 deletions(-) diff --git a/src/components/AppLayout/AppLayout.tsx b/src/components/AppLayout/AppLayout.tsx index 73dfcea..2bc0b70 100644 --- a/src/components/AppLayout/AppLayout.tsx +++ b/src/components/AppLayout/AppLayout.tsx @@ -53,7 +53,11 @@ import { Notification } from "../../types/Notification"; import { sendNotificationRequest } from "../../utilities/notifications"; import { withSnackbar } from "notistack"; import { getConfig, getUserDefaultBool } from "../../utilities/settings"; -import { isDesktopApp, isDarwinApp } from "../../utilities/desktop"; +import { + isDesktopApp, + isDarwinApp, + getElectronApp +} from "../../utilities/desktop"; import { Config } from "../../types/Config"; interface IAppLayoutState { @@ -139,6 +143,11 @@ export class AppLayout extends Component { this.streamListener.on("notification", (notif: Notification) => { const notificationCount = this.state.notificationCount + 1; this.setState({ notificationCount }); + + if (isDesktopApp()) { + getElectronApp().setBadgeCount(notificationCount); + } + if (!document.hasFocus()) { let primaryMessage = ""; let secondaryMessage = ""; @@ -238,6 +247,10 @@ export class AppLayout extends Component { if (!getUserDefaultBool("displayAllOnNotificationBadge")) { this.setState({ notificationCount: 0 }); } + + if (isDesktopApp() && getElectronApp().getBadgeCount() > 0) { + getElectronApp().setBadgeCount(0); + } } titlebar() { diff --git a/src/pages/Notifications.tsx b/src/pages/Notifications.tsx index 35fd444..85f5c8d 100644 --- a/src/pages/Notifications.tsx +++ b/src/pages/Notifications.tsx @@ -110,7 +110,7 @@ class NotificationsPage extends Component { removeNotification(id: string) { this.client - .post("/notifications/dismiss", { id: id }) + .post(`/notifications/${id}/dismiss`) .then((resp: any) => { let notifications = this.state.notifications; if (notifications !== undefined && notifications.length > 0) { diff --git a/src/pages/PageLayout.styles.tsx b/src/pages/PageLayout.styles.tsx index 04f6a1c..7e03332 100644 --- a/src/pages/PageLayout.styles.tsx +++ b/src/pages/PageLayout.styles.tsx @@ -156,16 +156,16 @@ export const styles = (theme: Theme) => pageProfileNameEmoji: { minHeight: theme.typography.h4.fontSize, fontWeight: theme.typography.fontWeightMedium, - '& img': { - height: theme.typography.h4.fontSize, + "& img": { + height: theme.typography.h4.fontSize } }, pageProfileBioEmoji: { - height: '0.875rem', - '& img': { - height: '0.875rem', + height: "0.875rem", + "& img": { + height: "0.875rem", paddingLeft: 4, - paddingRight: 4, + paddingRight: 4 } }, pageProfileStatsDiv: { diff --git a/src/utilities/desktop.tsx b/src/utilities/desktop.tsx index 2b77783..799a11a 100644 --- a/src/utilities/desktop.tsx +++ b/src/utilities/desktop.tsx @@ -29,3 +29,12 @@ export function isDarkMode() { const { remote } = eWin.require("electron"); return remote.systemPreferences.isDarkMode(); } + +/** + * Get the app component from the desktop app + */ +export function getElectronApp() { + const eWin = window as ElectronWindow; + const { remote } = eWin.require("electron"); + return remote.app; +} From 39f850dbd148ce5c83bfda0dbef2c9524631308e Mon Sep 17 00:00:00 2001 From: Marquis Kurt Date: Wed, 2 Oct 2019 11:22:49 -0400 Subject: [PATCH 02/12] Perform node-mac-notifier regression --- package-lock.json | 48 +++++++++++++++++++++----- src/components/AppLayout/AppLayout.tsx | 11 ++++-- src/utilities/notifications.tsx | 4 +-- 3 files changed, 49 insertions(+), 14 deletions(-) diff --git a/package-lock.json b/package-lock.json index 8452ce4..0a9221f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -3220,6 +3220,14 @@ "integrity": "sha512-Un7MIEDdUC5gNpcGDV97op1Ywk748MpHcFTHoYs6qnj1Z3j7I53VG3nwZhKzoBZmbdRNnb6WRdFlwl7tSDuZGw==", "dev": true }, + "bindings": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz", + "integrity": "sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==", + "requires": { + "file-uri-to-path": "1.0.0" + } + }, "bluebird": { "version": "3.5.4", "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.5.4.tgz", @@ -7262,10 +7270,13 @@ } }, "eslint-utils": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-1.3.1.tgz", - "integrity": "sha512-Z7YjnIldX+2XMcjr7ZkgEsOj/bREONV60qYeB/bjMAqqqZ4zxKyWX+BOUkdmRmA9riiIPVvo5x86m5elviOk0Q==", - "dev": true + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-1.4.2.tgz", + "integrity": "sha512-eAZS2sEUMlIeCjBeubdj45dmBHQwPHWyBcT1VSYB7o9x9WRRqKxyUoiXlRjyAwzN7YEzHJlYg0NmzDRWx6GP4Q==", + "dev": true, + "requires": { + "eslint-visitor-keys": "^1.0.0" + } }, "eslint-visitor-keys": { "version": "1.0.0", @@ -7325,6 +7336,11 @@ "integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=", "dev": true }, + "event-target-shim": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/event-target-shim/-/event-target-shim-1.1.1.tgz", + "integrity": "sha1-qG5e5r2qFgVEddp5fM3fDFVphJE=" + }, "eventemitter3": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-3.1.0.tgz", @@ -8022,6 +8038,11 @@ "schema-utils": "^1.0.0" } }, + "file-uri-to-path": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz", + "integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==" + }, "filename-regex": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/filename-regex/-/filename-regex-2.0.1.tgz", @@ -9448,9 +9469,9 @@ "dev": true }, "handlebars": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.1.2.tgz", - "integrity": "sha512-nvfrjqvt9xQ8Z/w0ijewdD/vvWDTOweBUm96NTr66Wfvo1mJenBLwcYmPs3TIBP5ruzYGD7Hx/DaM9RmhroGPw==", + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.4.0.tgz", + "integrity": "sha512-xkRtOt3/3DzTKMOt3xahj2M/EqNhY988T+imYSlMgs5fVhLN2fmKVVj0LtEGmb+3UUYV5Qmm1052Mm3dIQxOvw==", "dev": true, "requires": { "neo-async": "^2.6.0", @@ -12840,6 +12861,16 @@ } } }, + "node-mac-notifier": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/node-mac-notifier/-/node-mac-notifier-1.2.0.tgz", + "integrity": "sha512-+9FZ01BbPMv3pQVRWgPlaIKbhQl35Pn3WmRg96zIrCJHb4XvClnAqc0+aPfHrWs8o1PYMAQFeYK5tF69ljkKQw==", + "requires": { + "bindings": "^1.2.1", + "event-target-shim": "^1.1.1", + "uuid": "^3.3.2" + } + }, "node-notifier": { "version": "5.4.0", "resolved": "https://registry.npmjs.org/node-notifier/-/node-notifier-5.4.0.tgz", @@ -20242,8 +20273,7 @@ "uuid": { "version": "3.3.2", "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.2.tgz", - "integrity": "sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA==", - "dev": true + "integrity": "sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA==" }, "validate-npm-package-license": { "version": "3.0.4", diff --git a/src/components/AppLayout/AppLayout.tsx b/src/components/AppLayout/AppLayout.tsx index 2bc0b70..8dd04e3 100644 --- a/src/components/AppLayout/AppLayout.tsx +++ b/src/components/AppLayout/AppLayout.tsx @@ -206,7 +206,14 @@ export class AppLayout extends Component { break; } - sendNotificationRequest(primaryMessage, secondaryMessage); + sendNotificationRequest( + primaryMessage, + secondaryMessage, + notif.type == "mention", + (response: string) => { + console.log(response); + } + ); } }); } @@ -229,7 +236,7 @@ export class AppLayout extends Component { window.location.href = isDesktopApp() ? "hyperspace://hyperspace/app/index.html#/search?query=" + what : "/#/search?query=" + what; - window.location.reload; + window.location.reload(); } logOutAndRestart() { diff --git a/src/utilities/notifications.tsx b/src/utilities/notifications.tsx index bbd3390..db2193f 100644 --- a/src/utilities/notifications.tsx +++ b/src/utilities/notifications.tsx @@ -45,9 +45,7 @@ export function canSendNotifications() { */ export function sendNotificationRequest(title: string, body: string) { if (canSendNotifications()) { - let notif = new Notification(title, { - body: body - }); + let notif = new Notification(title, { body }); notif.onclick = () => { window.focus(); From 35f75c7ad437c4b64c5020c344326eff1e4d94a6 Mon Sep 17 00:00:00 2001 From: Marquis Kurt Date: Wed, 2 Oct 2019 11:22:49 -0400 Subject: [PATCH 03/12] Perform node-mac-notifier regression --- package-lock.json | 48 +++++++++++++++++++++----- src/components/AppLayout/AppLayout.tsx | 2 +- src/utilities/notifications.tsx | 4 +-- 3 files changed, 41 insertions(+), 13 deletions(-) diff --git a/package-lock.json b/package-lock.json index 8452ce4..0a9221f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -3220,6 +3220,14 @@ "integrity": "sha512-Un7MIEDdUC5gNpcGDV97op1Ywk748MpHcFTHoYs6qnj1Z3j7I53VG3nwZhKzoBZmbdRNnb6WRdFlwl7tSDuZGw==", "dev": true }, + "bindings": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz", + "integrity": "sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==", + "requires": { + "file-uri-to-path": "1.0.0" + } + }, "bluebird": { "version": "3.5.4", "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.5.4.tgz", @@ -7262,10 +7270,13 @@ } }, "eslint-utils": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-1.3.1.tgz", - "integrity": "sha512-Z7YjnIldX+2XMcjr7ZkgEsOj/bREONV60qYeB/bjMAqqqZ4zxKyWX+BOUkdmRmA9riiIPVvo5x86m5elviOk0Q==", - "dev": true + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-1.4.2.tgz", + "integrity": "sha512-eAZS2sEUMlIeCjBeubdj45dmBHQwPHWyBcT1VSYB7o9x9WRRqKxyUoiXlRjyAwzN7YEzHJlYg0NmzDRWx6GP4Q==", + "dev": true, + "requires": { + "eslint-visitor-keys": "^1.0.0" + } }, "eslint-visitor-keys": { "version": "1.0.0", @@ -7325,6 +7336,11 @@ "integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=", "dev": true }, + "event-target-shim": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/event-target-shim/-/event-target-shim-1.1.1.tgz", + "integrity": "sha1-qG5e5r2qFgVEddp5fM3fDFVphJE=" + }, "eventemitter3": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-3.1.0.tgz", @@ -8022,6 +8038,11 @@ "schema-utils": "^1.0.0" } }, + "file-uri-to-path": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz", + "integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==" + }, "filename-regex": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/filename-regex/-/filename-regex-2.0.1.tgz", @@ -9448,9 +9469,9 @@ "dev": true }, "handlebars": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.1.2.tgz", - "integrity": "sha512-nvfrjqvt9xQ8Z/w0ijewdD/vvWDTOweBUm96NTr66Wfvo1mJenBLwcYmPs3TIBP5ruzYGD7Hx/DaM9RmhroGPw==", + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.4.0.tgz", + "integrity": "sha512-xkRtOt3/3DzTKMOt3xahj2M/EqNhY988T+imYSlMgs5fVhLN2fmKVVj0LtEGmb+3UUYV5Qmm1052Mm3dIQxOvw==", "dev": true, "requires": { "neo-async": "^2.6.0", @@ -12840,6 +12861,16 @@ } } }, + "node-mac-notifier": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/node-mac-notifier/-/node-mac-notifier-1.2.0.tgz", + "integrity": "sha512-+9FZ01BbPMv3pQVRWgPlaIKbhQl35Pn3WmRg96zIrCJHb4XvClnAqc0+aPfHrWs8o1PYMAQFeYK5tF69ljkKQw==", + "requires": { + "bindings": "^1.2.1", + "event-target-shim": "^1.1.1", + "uuid": "^3.3.2" + } + }, "node-notifier": { "version": "5.4.0", "resolved": "https://registry.npmjs.org/node-notifier/-/node-notifier-5.4.0.tgz", @@ -20242,8 +20273,7 @@ "uuid": { "version": "3.3.2", "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.2.tgz", - "integrity": "sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA==", - "dev": true + "integrity": "sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA==" }, "validate-npm-package-license": { "version": "3.0.4", diff --git a/src/components/AppLayout/AppLayout.tsx b/src/components/AppLayout/AppLayout.tsx index 2bc0b70..afc9f03 100644 --- a/src/components/AppLayout/AppLayout.tsx +++ b/src/components/AppLayout/AppLayout.tsx @@ -229,7 +229,7 @@ export class AppLayout extends Component { window.location.href = isDesktopApp() ? "hyperspace://hyperspace/app/index.html#/search?query=" + what : "/#/search?query=" + what; - window.location.reload; + window.location.reload(); } logOutAndRestart() { diff --git a/src/utilities/notifications.tsx b/src/utilities/notifications.tsx index bbd3390..db2193f 100644 --- a/src/utilities/notifications.tsx +++ b/src/utilities/notifications.tsx @@ -45,9 +45,7 @@ export function canSendNotifications() { */ export function sendNotificationRequest(title: string, body: string) { if (canSendNotifications()) { - let notif = new Notification(title, { - body: body - }); + let notif = new Notification(title, { body }); notif.onclick = () => { window.focus(); From 74bb71631ab8f3c547b46e3719597ec34be033a5 Mon Sep 17 00:00:00 2001 From: Marquis Kurt Date: Wed, 2 Oct 2019 11:46:07 -0400 Subject: [PATCH 04/12] Perform node-mac-notifier regression Signed-off-by: Marquis Kurt --- src/components/AppLayout/AppLayout.tsx | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/src/components/AppLayout/AppLayout.tsx b/src/components/AppLayout/AppLayout.tsx index 8dd04e3..afc9f03 100644 --- a/src/components/AppLayout/AppLayout.tsx +++ b/src/components/AppLayout/AppLayout.tsx @@ -206,14 +206,7 @@ export class AppLayout extends Component { break; } - sendNotificationRequest( - primaryMessage, - secondaryMessage, - notif.type == "mention", - (response: string) => { - console.log(response); - } - ); + sendNotificationRequest(primaryMessage, secondaryMessage); } }); } From e52ae2e332de47d8a246310cee48d9ad392f2f31 Mon Sep 17 00:00:00 2001 From: Marquis Kurt Date: Wed, 2 Oct 2019 16:46:56 -0400 Subject: [PATCH 05/12] Create MultiAccount type and utilities for managing multiple accounts Signed-off-by: Marquis Kurt --- src/pages/PageLayout.styles.tsx | 12 +++--- src/types/Account.tsx | 23 ++++++++++ src/utilities/accounts.tsx | 76 +++++++++++++++++++++++++++++---- 3 files changed, 97 insertions(+), 14 deletions(-) diff --git a/src/pages/PageLayout.styles.tsx b/src/pages/PageLayout.styles.tsx index 04f6a1c..7e03332 100644 --- a/src/pages/PageLayout.styles.tsx +++ b/src/pages/PageLayout.styles.tsx @@ -156,16 +156,16 @@ export const styles = (theme: Theme) => pageProfileNameEmoji: { minHeight: theme.typography.h4.fontSize, fontWeight: theme.typography.fontWeightMedium, - '& img': { - height: theme.typography.h4.fontSize, + "& img": { + height: theme.typography.h4.fontSize } }, pageProfileBioEmoji: { - height: '0.875rem', - '& img': { - height: '0.875rem', + height: "0.875rem", + "& img": { + height: "0.875rem", paddingLeft: 4, - paddingRight: 4, + paddingRight: 4 } }, pageProfileStatsDiv: { diff --git a/src/types/Account.tsx b/src/types/Account.tsx index 09622f4..a6454a9 100644 --- a/src/types/Account.tsx +++ b/src/types/Account.tsx @@ -26,9 +26,32 @@ export type Account = { bot: boolean | null; }; +/** + * Watered-down type for Mastodon accounts + */ export type UAccount = { id: string; acct: string; display_name: string; avatar_static: string; }; + +/** + * Account type for use with multi-account support + */ +export type MultiAccount = { + /** + * The host name of the account (ex.: mastodon.social) + */ + host: string; + + /** + * The username of the account (@test) + */ + username: string; + + /** + * The access token generated from the login + */ + access_token: string; +}; diff --git a/src/utilities/accounts.tsx b/src/utilities/accounts.tsx index cae9078..da2423c 100644 --- a/src/utilities/accounts.tsx +++ b/src/utilities/accounts.tsx @@ -1,14 +1,10 @@ import Mastodon from "megalodon"; +import { MultiAccount } from "../types/Account"; export function userLoggedIn(): boolean { - if ( - localStorage.getItem("baseurl") && - localStorage.getItem("access_token") - ) { - return true; - } else { - return false; - } + return !!( + localStorage.getItem("baseurl") && localStorage.getItem("access_token") + ); } export function refreshUserAccountData() { @@ -31,3 +27,67 @@ export function refreshUserAccountData() { ); }); } + +/** + * Set the access token and base URL to a given multi-account user. + * @param account The multi-account from localStorage to use + */ +export function loginWithAccount(account: MultiAccount) { + if (localStorage.getItem("access_token") !== null) { + console.info( + "Existing login detected. Removing and using assigned token..." + ); + } + localStorage.setItem("access_token", account.access_token); + localStorage.setItem("baseurl", account.host); +} + +/** + * Gets the account registry. + * @returns A list of accounts + */ +function getAccountRegistry(): MultiAccount[] { + let accountRegistry: MultiAccount[] = []; + + let accountRegistryString = localStorage.getItem("registry"); + if (accountRegistryString !== null) { + accountRegistry = JSON.parse(accountRegistryString); + } + return accountRegistry; +} + +/** + * Add an account to the multi-account registry if it doesn't exist already. + * @param base_url The base URL of the user (eg., the instance) + * @param access_token The access token for the user + * @param username The username of the user + */ +export function addAccountToRegistry( + base_url: string, + access_token: string, + username: string +) { + const newAccount: MultiAccount = { + host: base_url, + username, + access_token + }; + + let accountRegistry = getAccountRegistry(); + + if (!accountRegistry.includes(newAccount)) { + accountRegistry.push(newAccount); + } + + localStorage.setItem("registry", JSON.stringify(accountRegistry)); +} + +export function removeAccountFromRegistry(index: number) { + let accountRegistry = getAccountRegistry(); + if (accountRegistry.length > index) { + accountRegistry.splice(index); + } else { + console.warn("Index of multi-account registry may be out of range."); + } + localStorage.setItem("registry", JSON.stringify(accountRegistry)); +} From 359f18a6cec30a13fcfcd63cbb4b713fb1b71b1a Mon Sep 17 00:00:00 2001 From: Marquis Kurt Date: Wed, 2 Oct 2019 16:54:24 -0400 Subject: [PATCH 06/12] Allow removal of multi-accounts via account registry, add docs Signed-off-by: Marquis Kurt --- src/utilities/accounts.tsx | 22 +++++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-) diff --git a/src/utilities/accounts.tsx b/src/utilities/accounts.tsx index da2423c..a0deadc 100644 --- a/src/utilities/accounts.tsx +++ b/src/utilities/accounts.tsx @@ -82,12 +82,24 @@ export function addAccountToRegistry( localStorage.setItem("registry", JSON.stringify(accountRegistry)); } -export function removeAccountFromRegistry(index: number) { +/** + * Remove an account from the multi-account registry, if possible + * @param accountIdentifier The index of the account from the registry or the MultiAccount object itself + */ +export function removeAccountFromRegistry( + accountIdentifier: number | MultiAccount +) { let accountRegistry = getAccountRegistry(); - if (accountRegistry.length > index) { - accountRegistry.splice(index); + + if (typeof accountIdentifier === "number") { + if (accountRegistry.length > accountIdentifier) { + accountRegistry.splice(accountIdentifier); + } else { + console.log("Multi account index may be out of range"); + } } else { - console.warn("Index of multi-account registry may be out of range."); + if (accountRegistry.includes(accountIdentifier)) { + accountRegistry.splice(accountRegistry.indexOf(accountIdentifier)); + } } - localStorage.setItem("registry", JSON.stringify(accountRegistry)); } From 3229d0a337382f83d9683a6041ce4d400c09d90e Mon Sep 17 00:00:00 2001 From: Marquis Kurt Date: Wed, 2 Oct 2019 18:03:32 -0400 Subject: [PATCH 07/12] Do the JavaScript things because object lists are weird Signed-off-by: Marquis Kurt --- src/utilities/accounts.tsx | 26 ++++++++++++++++---------- 1 file changed, 16 insertions(+), 10 deletions(-) diff --git a/src/utilities/accounts.tsx b/src/utilities/accounts.tsx index a0deadc..f9015ac 100644 --- a/src/utilities/accounts.tsx +++ b/src/utilities/accounts.tsx @@ -1,5 +1,5 @@ import Mastodon from "megalodon"; -import { MultiAccount } from "../types/Account"; +import { MultiAccount, Account } from "../types/Account"; export function userLoggedIn(): boolean { return !!( @@ -8,14 +8,17 @@ export function userLoggedIn(): boolean { } export function refreshUserAccountData() { - let client = new Mastodon( - localStorage.getItem("access_token") as string, - (localStorage.getItem("baseurl") as string) + "/api/v1" - ); + let host = localStorage.getItem("baseurl") as string; + let token = localStorage.getItem("access_token") as string; + + let client = new Mastodon(token, host + "/api/v1"); + client .get("/accounts/verify_credentials") .then((resp: any) => { - localStorage.setItem("account", JSON.stringify(resp.data)); + let account: Account = resp.data; + localStorage.setItem("account", JSON.stringify(account)); + addAccountToRegistry(host, token, account.acct); }) .catch((err: Error) => { console.error(err.message); @@ -46,10 +49,10 @@ export function loginWithAccount(account: MultiAccount) { * Gets the account registry. * @returns A list of accounts */ -function getAccountRegistry(): MultiAccount[] { +export function getAccountRegistry(): MultiAccount[] { let accountRegistry: MultiAccount[] = []; - let accountRegistryString = localStorage.getItem("registry"); + let accountRegistryString = localStorage.getItem("accountRegistry"); if (accountRegistryString !== null) { accountRegistry = JSON.parse(accountRegistryString); } @@ -74,12 +77,15 @@ export function addAccountToRegistry( }; let accountRegistry = getAccountRegistry(); + const stringifiedRegistry = accountRegistry.map(account => + account.toString() + ); - if (!accountRegistry.includes(newAccount)) { + if (stringifiedRegistry.indexOf(newAccount.toString()) === -1) { accountRegistry.push(newAccount); } - localStorage.setItem("registry", JSON.stringify(accountRegistry)); + localStorage.setItem("accountRegistry", JSON.stringify(accountRegistry)); } /** From e75a964a399b7da230fd946eb100bf186c6fb103 Mon Sep 17 00:00:00 2001 From: Marquis Kurt Date: Thu, 3 Oct 2019 11:16:21 -0400 Subject: [PATCH 08/12] Add switch account UI from login and update accounts functionality Signed-off-by: Marquis Kurt --- src/App.tsx | 40 ++++++-- src/components/AppLayout/AppLayout.tsx | 67 ++++++++----- src/pages/Compose.tsx | 6 +- src/pages/Welcome.tsx | 133 ++++++++++++++++++++----- src/utilities/accounts.tsx | 39 +++++++- 5 files changed, 226 insertions(+), 59 deletions(-) diff --git a/src/App.tsx b/src/App.tsx index eeafea5..d621a99 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -3,7 +3,7 @@ import { MuiThemeProvider, CssBaseline, withStyles } from "@material-ui/core"; import { setHyperspaceTheme, darkMode } from "./utilities/themes"; import AppLayout from "./components/AppLayout"; import { styles } from "./App.styles"; -import { Route } from "react-router-dom"; +import { Route, withRouter } from "react-router-dom"; import AboutPage from "./pages/About"; import Settings from "./pages/Settings"; import { getUserDefaultBool, getUserDefaultTheme } from "./utilities/settings"; @@ -27,14 +27,22 @@ import { userLoggedIn } from "./utilities/accounts"; import { isDarwinApp } from "./utilities/desktop"; let theme = setHyperspaceTheme(getUserDefaultTheme()); -class App extends Component { +interface IAppState { + theme: any; + showLayout: boolean; +} + +class App extends Component { offline: any; + unlisten: any; constructor(props: any) { super(props); this.state = { - theme: theme + theme: theme, + showLayout: + userLoggedIn() && !window.location.hash.includes("#/welcome") }; } @@ -43,17 +51,34 @@ class App extends Component { this.state.theme, getUserDefaultBool("darkModeEnabled") ); - this.setState({ theme: newTheme }); + this.setState({ + theme: newTheme, + showLayout: + userLoggedIn() && !window.location.hash.includes("#/welcome") + }); } componentDidMount() { this.removeBodyBackground(); + this.unlisten = this.props.history.listen( + (location: Location, action: any) => { + console.log(location.pathname); + this.setState({ + showLayout: + userLoggedIn() && + !location.pathname.includes("/welcome") + }); + } + ); } componentDidUpdate() { this.removeBodyBackground(); } + componentWillUnmount() { + this.unlisten(); + } removeBodyBackground() { if (isDarwinApp()) { @@ -71,7 +96,7 @@ class App extends Component {
- {userLoggedIn() ? : null} + {this.state.showLayout ? : null} @@ -91,7 +116,7 @@ class App extends Component { /> - + @@ -105,4 +130,5 @@ class App extends Component { } } -export default withStyles(styles)(withSnackbar(App)); +// @ts-ignore +export default withStyles(styles)(withSnackbar(withRouter(App))); diff --git a/src/components/AppLayout/AppLayout.tsx b/src/components/AppLayout/AppLayout.tsx index 73dfcea..3237a41 100644 --- a/src/components/AppLayout/AppLayout.tsx +++ b/src/components/AppLayout/AppLayout.tsx @@ -39,7 +39,7 @@ 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"; -//import SupervisedUserCircleIcon from '@material-ui/icons/SupervisedUserCircle'; +import SupervisedUserCircleIcon from "@material-ui/icons/SupervisedUserCircle"; import ExitToAppIcon from "@material-ui/icons/ExitToApp"; import { styles } from "./AppLayout.styles"; import { UAccount } from "../../types/Account"; @@ -55,6 +55,7 @@ import { withSnackbar } from "notistack"; import { getConfig, getUserDefaultBool } from "../../utilities/settings"; import { isDesktopApp, isDarwinApp } from "../../utilities/desktop"; import { Config } from "../../types/Config"; +import { getAccountRegistry } from "../../utilities/accounts"; interface IAppLayoutState { acctMenuOpen: boolean; @@ -92,23 +93,7 @@ export class AppLayout extends Component { } 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.getAccountData(); getConfig().then((result: any) => { if (result !== undefined) { @@ -126,6 +111,23 @@ export class AppLayout extends Component { this.streamNotifications(); } + private getAccountData() { + 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); + let acct = localStorage.getItem("account") as string; + this.setState({ currentUser: JSON.parse(acct) }); + }); + } + streamNotifications() { this.streamListener = this.client.stream("/streaming/user"); @@ -304,10 +306,22 @@ export class AppLayout extends Component { } /> - {/* - - - */} + + + + + 1 + ? "Switch account" + : "Add account" + } + /> + { Edit profile - {/* Switch account */} + + + {getAccountRegistry() + .length > 1 + ? "Switch account" + : "Add account"} + + this.toggleLogOutDialog() diff --git a/src/pages/Compose.tsx b/src/pages/Compose.tsx index 5c1494f..f9288d9 100644 --- a/src/pages/Compose.tsx +++ b/src/pages/Compose.tsx @@ -84,6 +84,10 @@ class Composer extends Component { componentDidMount() { let state = this.getComposerParams(this.props); let text = state.acct ? `@${state.acct}: ` : ""; + this.client.get("/accounts/verify_credentials").then((resp: any) => { + let account: UAccount = resp.data; + this.setState({ account }); + }); getConfig().then((config: any) => { this.setState({ federated: config.federation.allowPublicPosts, @@ -439,7 +443,7 @@ class Composer extends Component { event.target.value ) } - > + /> ) : null} {this.state.visibility === "direct" ? ( diff --git a/src/pages/Welcome.tsx b/src/pages/Welcome.tsx index 3be6821..2dd15aa 100644 --- a/src/pages/Welcome.tsx +++ b/src/pages/Welcome.tsx @@ -12,7 +12,13 @@ import { Dialog, DialogTitle, DialogActions, - DialogContent + DialogContent, + List, + ListItem, + ListItemText, + ListItemAvatar, + ListItemSecondaryAction, + IconButton } from "@material-ui/core"; import { styles } from "./WelcomePage.styles"; import Mastodon from "megalodon"; @@ -28,6 +34,16 @@ import { isDarwinApp } from "../utilities/desktop"; import axios from "axios"; import { withSnackbar, withSnackbarProps } from "notistack"; import { Config } from "../types/Config"; +import { + addAccountToRegistry, + getAccountRegistry, + loginWithAccount, + removeAccountFromRegistry +} from "../utilities/accounts"; +import { Account, MultiAccount } from "../types/Account"; + +import AccountCircleIcon from "@material-ui/icons/AccountCircle"; +import CloseIcon from "@material-ui/icons/Close"; interface IWelcomeProps extends withSnackbarProps { classes: any; @@ -39,7 +55,7 @@ interface IWelcomeState { brandName?: string; registerBase?: string; federates?: boolean; - wantsToLogin: boolean; + proceedToGetCode: boolean; user: string; userInputError: boolean; userInputErrorMessage: string; @@ -47,7 +63,7 @@ interface IWelcomeState { clientSecret?: string; authUrl?: string; foundSavedLogin: boolean; - authority: boolean; + authorizing: boolean; license?: string; repo?: string; defaultRedirectAddress: string; @@ -55,6 +71,7 @@ interface IWelcomeState { authCode: string; emergencyMode: boolean; version: string; + willAddAccount: boolean; } class WelcomePage extends Component { @@ -64,17 +81,18 @@ class WelcomePage extends Component { super(props); this.state = { - wantsToLogin: false, + proceedToGetCode: false, user: "", userInputError: false, foundSavedLogin: false, - authority: false, + authorizing: false, userInputErrorMessage: "", defaultRedirectAddress: "", openAuthDialog: false, authCode: "", emergencyMode: false, - version: "" + version: "", + willAddAccount: false }; getConfig() @@ -155,6 +173,11 @@ class WelcomePage extends Component { } } + clear() { + localStorage.removeItem("access_token"); + localStorage.removeItem("baseurl"); + } + getSavedSession() { let loginData = localStorage.getItem("login"); if (loginData) { @@ -253,7 +276,7 @@ class WelcomePage extends Component { clientId: resp.clientId, clientSecret: resp.clientSecret, authUrl: resp.url, - wantsToLogin: true + proceedToGetCode: true }); }); } else { @@ -304,7 +327,7 @@ class WelcomePage extends Component { clientSecret: session.clientSecret, authUrl: session.authUrl, emergencyMode: session.emergency, - wantsToLogin: true + proceedToGetCode: true }); } } @@ -332,8 +355,8 @@ class WelcomePage extends Component { axios .get( "https://" + - baseUrl + - "/api/v1/timelines/public" + baseUrl + + "/api/v1/timelines/public" ) .catch((err: Error) => { let userInputError = true; @@ -375,7 +398,7 @@ class WelcomePage extends Component { let location = window.location.href; if (location.includes("?code=")) { let code = parseUrl(location).query.code as string; - this.setState({ authority: true }); + this.setState({ authorizing: true }); let loginData = localStorage.getItem("login"); if (loginData) { let clientLoginSession: SaveClientSession = JSON.parse( @@ -389,12 +412,12 @@ class WelcomePage extends Component { this.state.emergencyMode ? undefined : clientLoginSession.authUrl.includes( - "urn%3Aietf%3Awg%3Aoauth%3A2.0%3Aoob" - ) + "urn%3Aietf%3Awg%3Aoauth%3A2.0%3Aoob" + ) ? undefined : window.location.protocol === "hyperspace:" - ? "hyperspace://hyperspace/app/" - : `https://${window.location.host}` + ? "hyperspace://hyperspace/app/" + : `https://${window.location.host}` ) .then((tokenData: any) => { localStorage.setItem( @@ -436,6 +459,65 @@ class WelcomePage extends Component { } } + showMultiAccount() { + const { classes } = this.props; + return ( +
+ Select an account + from the list below or add a new one + + + {getAccountRegistry().map( + (account: MultiAccount, index: number) => ( + { + loginWithAccount(account); + window.location.href = + window.location.protocol === + "hyperspace:" + ? "hyperspace://hyperspace/app/" + : `https://${window.location.host}/#/`; + }} + button={true} + > + + + + + + { + e.preventDefault(); + removeAccountFromRegistry(index); + window.location.reload(); + }} + > + + + + + ) + )} + +
+ + +
+ ); + } + showLanding() { const { classes } = this.props; return ( @@ -452,7 +534,7 @@ class WelcomePage extends Component { onKeyDown={event => this.watchUsernameField(event)} error={this.state.userInputError} onBlur={() => this.checkForErrors()} - > + /> {this.state.userInputError ? ( {this.state.userInputErrorMessage} @@ -597,7 +679,7 @@ class WelcomePage extends Component { this.updateAuthCode(event.target.value) } onKeyDown={event => this.watchAuthField(event)} - > + /> - - - + {this.logoutDialog()} {
); } + + logoutDialog() { + return ( + 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"} + . + + + Logging out will also remove this account from the + account list. + + + + + + + + + ); + } } export default withStyles(styles)(withSnackbar(AppLayout)); diff --git a/src/components/Post/Post.tsx b/src/components/Post/Post.tsx index f413294..f31025e 100644 --- a/src/components/Post/Post.tsx +++ b/src/components/Post/Post.tsx @@ -1,33 +1,32 @@ import React from "react"; import { - Typography, - IconButton, - Card, - CardHeader, Avatar, - CardContent, - CardActions, - withStyles, - Menu, - MenuItem, - Chip, - Divider, - CardMedia, - CardActionArea, - ExpansionPanel, - ExpansionPanelSummary, - ExpansionPanelDetails, - Zoom, - Tooltip, - RadioGroup, - Radio, - FormControlLabel, Button, + Card, + CardActionArea, + CardActions, + CardContent, + CardHeader, + CardMedia, Dialog, - DialogTitle, + DialogActions, DialogContent, DialogContentText, - DialogActions + DialogTitle, + Divider, + ExpansionPanel, + ExpansionPanelDetails, + ExpansionPanelSummary, + FormControlLabel, + IconButton, + Menu, + MenuItem, + Radio, + RadioGroup, + Tooltip, + Typography, + withStyles, + Zoom } from "@material-ui/core"; import MoreVertIcon from "@material-ui/icons/MoreVert"; import ReplyIcon from "@material-ui/icons/Reply"; @@ -51,10 +50,10 @@ import moment from "moment"; import AttachmentComponent from "../Attachment"; import Mastodon from "megalodon"; import { + LinkableAvatar, LinkableChip, - LinkableMenuItem, LinkableIconButton, - LinkableAvatar + LinkableMenuItem } from "../../interfaces/overrides"; import { withSnackbar } from "notistack"; import ShareMenu from "./PostShareMenu"; @@ -73,6 +72,7 @@ interface IPostState { menuIsOpen: boolean; myVote?: [number]; deletePostDialog: boolean; + myAccount?: Account; } export class Post extends React.Component { @@ -94,6 +94,25 @@ export class Post extends React.Component { this.client = this.props.client; } + componentWillMount() { + this.client + .get("/accounts/verify_credentials") + .then((resp: any) => { + let account: Account = resp.data; + this.setState({ + myAccount: account + }); + }) + .catch((err: Error) => { + console.error(err); + this.setState({ + myAccount: JSON.parse(localStorage.getItem( + "account" + ) as string) + }); + }); + } + togglePostMenu() { this.setState({ menuIsOpen: !this.state.menuIsOpen }); } @@ -105,7 +124,7 @@ export class Post extends React.Component { deletePost() { this.client .del("/statuses/" + this.state.post.id) - .then((resp: any) => { + .then(() => { this.props.enqueueSnackbar( "Post deleted. Refresh to see changes." ); @@ -261,7 +280,7 @@ export class Post extends React.Component { {status.poll.options.map( (pollOption: PollOption) => { - let x = ( + return ( { } /> ); - return x; } )} @@ -302,7 +320,7 @@ export class Post extends React.Component { > {status.poll.options.map( (pollOption: PollOption) => { - let x = ( + return ( } @@ -313,13 +331,12 @@ export class Post extends React.Component { } /> ); - return x; } )} @@ -380,7 +397,6 @@ export class Post extends React.Component { } getReblogOfPost(of: Status | null) { - const { classes } = this.props; if (of !== null) { return of.sensitive ? this.getSensitiveContent(of.spoiler_text, of) @@ -653,7 +669,7 @@ export class Post extends React.Component { dangerouslySetInnerHTML={{ __html: this.getReblogAuthors(post) }} - > + /> } subheader={moment(post.created_at).format( "MMMM Do YYYY [at] h:mm A" @@ -827,9 +843,8 @@ export class Post extends React.Component { Open in Web
- {post.account.id == - JSON.parse(localStorage.getItem("account") as string) - .id ? ( + {this.state.myAccount && + post.account.id == this.state.myAccount.id ? (
{ + if (event.key == "account") { + window.location.reload(); + } +}; + ReactDOM.render( { @@ -42,12 +39,42 @@ class You extends Component { ); this.state = { - currentAccount: this.getAccount() + viewIsLoading: true, + viewLoaded: false, + viewErrored: false }; } + componentWillMount() { + this.client + .get("/accounts/verify_credentials") + .then((resp: any) => { + let currentAccount: Account = resp.data; + this.setState({ + currentAccount, + viewIsLoading: false, + viewLoaded: true + }); + }) + .catch(() => { + if (this.getAccount()) { + this.setState({ + currentAccount: this.getAccount(), + viewIsLoading: false, + viewLoaded: true + }); + } else { + this.setState({ + viewIsLoading: false, + viewErrored: true + }); + } + }); + } + getAccount() { let acct = localStorage.getItem("account"); + console.log(acct); if (acct) { return JSON.parse(acct); } @@ -142,15 +169,16 @@ class You extends Component { removeHTMLContent(text: string) { const div = document.createElement("div"); div.innerHTML = text; - let innerContent = div.textContent || div.innerText || ""; - return innerContent; + return div.textContent || div.innerText || ""; } changeDisplayName() { this.client .patch("/accounts/update_credentials", { display_name: this.state.newDisplayName ? this.state.newDisplayName - : this.state.currentAccount.display_name + : this.state.currentAccount + ? this.state.currentAccount.display_name + : "" }) .then((acct: any) => { let currentAccount: Account = acct.data; @@ -179,7 +207,9 @@ class You extends Component { .patch("/accounts/update_credentials", { note: this.state.newBio ? this.state.newBio - : this.state.currentAccount.note + : this.state.currentAccount + ? this.state.currentAccount.note + : "" }) .then((acct: any) => { let currentAccount: Account = acct.data; @@ -205,116 +235,155 @@ class You extends Component { const { classes } = this.props; return (
-
-
-
-
- -
- - Edit your profile - - - Change information such as your display name, - bio, and images used here. - -
- - + + Edit your profile + + + Change information such as your display + name, bio, and images used here. + +
+ + +
+
+
+ + + Display Name + +
+ + this.updateDisplayName( + event.target.value + ) + } + /> +
+ +
+
+
+ + + About you + +
+ + this.updateBio(event.target.value) + } + /> +
+ +
+
+
-
-
- - - Display Name - -
- - this.updateDisplayName(event.target.value) - } + ) : ( + "AAA" + )} + {this.state.viewIsLoading ? ( +
+ -
- -
- -
- - - About you - -
- - this.updateBio(event.target.value) - } - /> -
- -
-
-
+
+ ) : ( + + )}
); } diff --git a/src/utilities/accounts.tsx b/src/utilities/accounts.tsx index d673299..014bb17 100644 --- a/src/utilities/accounts.tsx +++ b/src/utilities/accounts.tsx @@ -71,7 +71,6 @@ export function addAccountToRegistry( access_token: string, username: string ) { - console.log("Firing!"); const newAccount: MultiAccount = { host: base_url, username, From 91c1694560108493d87c0d4bc12f6eba51195c88 Mon Sep 17 00:00:00 2001 From: Marquis Kurt Date: Thu, 3 Oct 2019 16:17:08 -0400 Subject: [PATCH 10/12] Update Electron menus Signed-off-by: Marquis Kurt --- public/electron.js | 63 ++++++++++++++++++++++++++++++---------------- 1 file changed, 41 insertions(+), 22 deletions(-) diff --git a/public/electron.js b/public/electron.js index 35cdd30..031a124 100644 --- a/public/electron.js +++ b/public/electron.js @@ -20,7 +20,7 @@ let mainWindow; // to when authorizing Hyperspace. protocol.registerSchemesAsPrivileged([ { scheme: 'hyperspace', privileges: { standard: true, secure: true } } -]) +]); /** * Determine whether the desktop app is on macOS @@ -218,15 +218,8 @@ function createMenubar() { click() { safelyGoTo("hyperspace://hyperspace/app/#compose") } - }, - { type: 'separator' }, - { - label: 'Edit Profile', - accelerator: "Shift+CmdOrCtrl+P", - click() { - safelyGoTo("hyperspace://hyperspace/app/#/you") - } - }, + } + ] }, { @@ -284,7 +277,7 @@ function createMenubar() { ] }, { - label: "Places", + label: "Timelines", submenu: [ { label: 'Home', @@ -308,27 +301,53 @@ function createMenubar() { } }, { - label: 'Recommendations', + label: 'Messages', accelerator: "CmdOrCtrl+3", + click() { + safelyGoTo("hyperspace://hyperspace/app/#/messages") + } + } + ] + }, + { + label: "Account", + submenu: [ + { + label: 'Notifications', + accelerator: "Alt+CmdOrCtrl+N", + click() { + safelyGoTo("hyperspace://hyperspace/app/#/notifications") + } + }, + { + label: 'Recommendations...', + accelerator: "Alt+CmdOrCtrl+R", click() { safelyGoTo("hyperspace://hyperspace/app/#/recommended") } }, { type: 'separator' }, { - label: 'Notifications', - accelerator: "CmdOrCtrl+4", + label: 'Edit Profile', + accelerator: "Shift+CmdOrCtrl+P", click() { - safelyGoTo("hyperspace://hyperspace/app/#/notifications") + safelyGoTo("hyperspace://hyperspace/app/#/you") } }, { - label: 'Messages', - accelerator: "CmdOrCtrl+5", + label: 'Blocked Servers', + accelerator: "Shift+CmdOrCtrl+B", click() { - safelyGoTo("hyperspace://hyperspace/app/#/messages") + safelyGoTo("hyperspace://hyperspace/app/#/blocked") } }, + { type: 'separator'}, + { + label: 'Switch Accounts...', + click() { + safelyGoTo("hyperspace://hyperspace/app/#/welcome") + } + } ] }, { @@ -357,7 +376,7 @@ function createMenubar() { } ] } - ] + ]; if (process.platform === 'darwin') { menuBar.unshift({ @@ -386,7 +405,7 @@ function createMenubar() { { type: 'separator' }, { role: 'quit' } ] - }) + }); // Edit menu menuBar[2].submenu.push( @@ -398,10 +417,10 @@ function createMenubar() { { role: 'stopspeaking' } ] } - ) + ); // Window menu - menuBar[5].submenu = [ + menuBar[6].submenu = [ { role: 'close' }, { role: 'minimize' }, { role: 'zoom' }, From 0c785fd11a7237ba9e4df6bbabcd4812d4deac58 Mon Sep 17 00:00:00 2001 From: Marquis Kurt Date: Thu, 3 Oct 2019 16:35:26 -0400 Subject: [PATCH 11/12] General improvements to verify_credentials Signed-off-by: Marquis Kurt --- src/App.tsx | 1 - src/components/AppLayout/AppLayout.tsx | 2 +- src/components/Post/Post.tsx | 19 +++---------------- 3 files changed, 4 insertions(+), 18 deletions(-) diff --git a/src/App.tsx b/src/App.tsx index d621a99..da77bbb 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -62,7 +62,6 @@ class App extends Component { this.removeBodyBackground(); this.unlisten = this.props.history.listen( (location: Location, action: any) => { - console.log(location.pathname); this.setState({ showLayout: userLoggedIn() && diff --git a/src/components/AppLayout/AppLayout.tsx b/src/components/AppLayout/AppLayout.tsx index dc5c5b2..ff88eec 100644 --- a/src/components/AppLayout/AppLayout.tsx +++ b/src/components/AppLayout/AppLayout.tsx @@ -114,7 +114,7 @@ export class AppLayout extends Component { this.streamNotifications(); } - private getAccountData() { + getAccountData() { this.client .get("/accounts/verify_credentials") .then((resp: any) => { diff --git a/src/components/Post/Post.tsx b/src/components/Post/Post.tsx index f31025e..89fc350 100644 --- a/src/components/Post/Post.tsx +++ b/src/components/Post/Post.tsx @@ -95,22 +95,9 @@ export class Post extends React.Component { } componentWillMount() { - this.client - .get("/accounts/verify_credentials") - .then((resp: any) => { - let account: Account = resp.data; - this.setState({ - myAccount: account - }); - }) - .catch((err: Error) => { - console.error(err); - this.setState({ - myAccount: JSON.parse(localStorage.getItem( - "account" - ) as string) - }); - }); + this.setState({ + myAccount: JSON.parse(localStorage.getItem("account") as string) + }); } togglePostMenu() { From 700fd10a5849c305aafc24d51b10e6864060fae8 Mon Sep 17 00:00:00 2001 From: Marquis Kurt Date: Thu, 3 Oct 2019 16:48:11 -0400 Subject: [PATCH 12/12] Store account ID in session storage for quicker access Signed-off-by: Marquis Kurt --- src/components/AppLayout/AppLayout.tsx | 1 + src/components/Post/Post.tsx | 6 +++--- src/utilities/accounts.tsx | 1 + 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/src/components/AppLayout/AppLayout.tsx b/src/components/AppLayout/AppLayout.tsx index ff88eec..f07608b 100644 --- a/src/components/AppLayout/AppLayout.tsx +++ b/src/components/AppLayout/AppLayout.tsx @@ -120,6 +120,7 @@ export class AppLayout extends Component { .then((resp: any) => { let data: UAccount = resp.data; this.setState({ currentUser: data }); + sessionStorage.setItem("id", data.id); }) .catch((err: Error) => { this.props.enqueueSnackbar( diff --git a/src/components/Post/Post.tsx b/src/components/Post/Post.tsx index 89fc350..29ed420 100644 --- a/src/components/Post/Post.tsx +++ b/src/components/Post/Post.tsx @@ -72,7 +72,7 @@ interface IPostState { menuIsOpen: boolean; myVote?: [number]; deletePostDialog: boolean; - myAccount?: Account; + myAccount?: string; } export class Post extends React.Component { @@ -96,7 +96,7 @@ export class Post extends React.Component { componentWillMount() { this.setState({ - myAccount: JSON.parse(localStorage.getItem("account") as string) + myAccount: sessionStorage.getItem("id") as string }); } @@ -831,7 +831,7 @@ export class Post extends React.Component {
{this.state.myAccount && - post.account.id == this.state.myAccount.id ? ( + post.account.id === this.state.myAccount ? (
{ let account: Account = resp.data; localStorage.setItem("account", JSON.stringify(account)); + sessionStorage.setItem("id", account.id); addAccountToRegistry(host, token, account.acct); })