diff --git a/client/src/components/MainWindow.tsx b/client/src/components/MainWindow.tsx
index b6acbe6..d3737ae 100644
--- a/client/src/components/MainWindow.tsx
+++ b/client/src/components/MainWindow.tsx
@@ -16,7 +16,7 @@ import SettingsWindow from './windows/settings/SettingsWindow';
import { ErrorBoundary } from 'react-error-boundary';
import { ProvideIntegrations } from '../lib/integration/useIntegrations';
import ManageLinksWindow from './windows/manage_links/ManageLinksWindow';
-import ManageWindow from './windows/manage/ManageWindow';
+import ManageWindow, { ManageWhat } from './windows/manage/ManageWindow';
const darkTheme = createMuiTheme({
palette: {
@@ -88,17 +88,16 @@ export default function MainWindow(props: any) {
-
-
-
+
+
+
-
-
-
+
+
+
-
-
-
+
+
diff --git a/client/src/components/appbar/AppBar.tsx b/client/src/components/appbar/AppBar.tsx
index cc69496..fc967ad 100644
--- a/client/src/components/appbar/AppBar.tsx
+++ b/client/src/components/appbar/AppBar.tsx
@@ -3,13 +3,13 @@ import { AppBar as MuiAppBar, Box, Tab as MuiTab, Tabs, IconButton, Typography,
import SearchIcon from '@material-ui/icons/Search';
import LocalOfferIcon from '@material-ui/icons/LocalOffer';
import OpenInNewIcon from '@material-ui/icons/OpenInNew';
+import BuildIcon from '@material-ui/icons/Build';
import { Link, useHistory } from 'react-router-dom';
import { useAuth } from '../../lib/useAuth';
export enum AppBarTab {
Query = 0,
- Tags,
- Links,
+ Manage,
}
export const appBarTabProps: Record = {
@@ -17,13 +17,9 @@ export const appBarTabProps: Record = {
label: Query,
path: "/query",
},
- [AppBarTab.Tags]: {
- label: Tags,
- path: "/tags",
- },
- [AppBarTab.Links]: {
- label: Links,
- path: "/links",
+ [AppBarTab.Manage]: {
+ label: Manage,
+ path: "/manage",
},
}
diff --git a/client/src/components/windows/album/AlbumWindow.tsx b/client/src/components/windows/album/AlbumWindow.tsx
index 02c2708..85b40e0 100644
--- a/client/src/components/windows/album/AlbumWindow.tsx
+++ b/client/src/components/windows/album/AlbumWindow.tsx
@@ -91,7 +91,7 @@ export function AlbumWindowControlled(props: {
value: m
});
})
- .catch((e: NotLoggedInError) => { handleNotLoggedIn(auth, e) })
+ .catch((e: any) => { handleNotLoggedIn(auth, e) })
}, [albumId, dispatch]);
// Effect to get the album's songs.
@@ -108,7 +108,7 @@ export function AlbumWindowControlled(props: {
offset: 0,
limit: -1,
})
- .catch((e: NotLoggedInError) => { handleNotLoggedIn(auth, e) });
+ .catch((e: any) => { handleNotLoggedIn(auth, e) });
dispatch({
type: AlbumWindowStateActions.SetSongs,
value: songs,
@@ -159,7 +159,7 @@ export function AlbumWindowControlled(props: {
type: AlbumWindowStateActions.Reload
})
})
- .catch((e: NotLoggedInError) => { handleNotLoggedIn(auth, e) })
+ .catch((e: any) => { handleNotLoggedIn(auth, e) })
}} />
{applying && }
diff --git a/client/src/components/windows/artist/ArtistWindow.tsx b/client/src/components/windows/artist/ArtistWindow.tsx
index 61cd915..07aaef5 100644
--- a/client/src/components/windows/artist/ArtistWindow.tsx
+++ b/client/src/components/windows/artist/ArtistWindow.tsx
@@ -95,7 +95,7 @@ export function ArtistWindowControlled(props: {
value: m
});
})
- .catch((e: NotLoggedInError) => { handleNotLoggedIn(auth, e) })
+ .catch((e: any) => { handleNotLoggedIn(auth, e) })
}, [artistId, dispatch]);
// Effect to get the artist's songs.
@@ -112,7 +112,7 @@ export function ArtistWindowControlled(props: {
offset: 0,
limit: -1,
})
- .catch((e: NotLoggedInError) => { handleNotLoggedIn(auth, e) });
+ .catch((e: any) => { handleNotLoggedIn(auth, e) });
dispatch({
type: ArtistWindowStateActions.SetSongs,
value: songs,
@@ -163,7 +163,7 @@ export function ArtistWindowControlled(props: {
type: ArtistWindowStateActions.Reload
})
})
- .catch((e: NotLoggedInError) => { handleNotLoggedIn(auth, e) })
+ .catch((e: any) => { handleNotLoggedIn(auth, e) })
}} />
{applying && }
diff --git a/client/src/components/windows/manage/ManageWindow.tsx b/client/src/components/windows/manage/ManageWindow.tsx
index 883486e..0928001 100644
--- a/client/src/components/windows/manage/ManageWindow.tsx
+++ b/client/src/components/windows/manage/ManageWindow.tsx
@@ -1,4 +1,4 @@
-import React, { useReducer } from 'react';
+import React, { ReactFragment, useReducer, useState } from 'react';
import { WindowState } from "../Windows";
import { Box, Paper, Typography, TextField, Button, Tabs, Tab, Divider, IconButton } from "@material-ui/core";
import { useHistory } from 'react-router';
@@ -8,45 +8,52 @@ import { Link } from 'react-router-dom';
import LocalOfferIcon from '@material-ui/icons/LocalOffer';
import OpenInNewIcon from '@material-ui/icons/OpenInNew';
import ManageLinksWindow from '../manage_links/ManageLinksWindow';
+import ManageTagsWindow from '../manage_tags/ManageTagsWindow';
export enum ManageWhat {
Tags = 0,
Links,
}
-export interface ManageWindowState extends WindowState {
- dummy: boolean
-}
-export enum ManageWindowActions {
- SetDummy = "SetDummy",
-}
-export function ManageWindowReducer(state: ManageWindowState, action: any) {
- switch (action.type) {
- case ManageWindowActions.SetDummy: {
- return state;
- }
- default:
- throw new Error("Unimplemented ManageWindow state update.")
- }
-}
+export default function ManageWindow(props: {
+ selectedWindow: ManageWhat,
+}) {
+ let history = useHistory();
-export default function ManageWindow(props: {}) {
- const [state, dispatch] = useReducer(ManageWindowReducer, {
- dummy: true,
- });
+ let NavButton = (props: {
+ label: string,
+ icon: ReactFragment,
+ selected: boolean,
+ onClick?: () => void,
+ }) => {
+ return
- return
-}
+ }
-export function ManageWindowControlled(props: {
- state: ManageWindowState,
- dispatch: (action: any) => void,
-}) {
return
- Tags
- Links
+ }
+ selected={props.selectedWindow === ManageWhat.Tags}
+ onClick={() => history.push('/manage/tags')}
+ />
+ }
+ selected={props.selectedWindow === ManageWhat.Links}
+ onClick={() => history.push('/manage/links')}
+ />
-
-
+ {props.selectedWindow === ManageWhat.Tags && }
+ {props.selectedWindow === ManageWhat.Links && }
+
}
\ No newline at end of file
diff --git a/client/src/components/windows/manage_tags/ManageTagsWindow.tsx b/client/src/components/windows/manage_tags/ManageTagsWindow.tsx
index e6e6c62..14e47e4 100644
--- a/client/src/components/windows/manage_tags/ManageTagsWindow.tsx
+++ b/client/src/components/windows/manage_tags/ManageTagsWindow.tsx
@@ -426,7 +426,7 @@ export function ManageTagsWindowControlled(props: {
type: ManageTagsWindowActions.Reset
});
})
- .catch((e: NotLoggedInError) => { handleNotLoggedIn(auth, e) })
+ .catch((e: any) => { handleNotLoggedIn(auth, e) })
.catch((e: Error) => {
props.dispatch({
type: ManageTagsWindowActions.SetAlert,
diff --git a/client/src/lib/backend/request.tsx b/client/src/lib/backend/request.tsx
index b5fa5f5..0195068 100644
--- a/client/src/lib/backend/request.tsx
+++ b/client/src/lib/backend/request.tsx
@@ -9,6 +9,10 @@ export class NotLoggedInError extends Error {
}
}
+export function isNotLoggedInError(e: any): e is NotLoggedInError {
+ return e.name === NotLoggedInError;
+}
+
export default async function backendRequest(url: any, ...restArgs: any[]): Promise {
let response = await fetch(url, ...restArgs);
if (response.status === 401 && (await response.json()).reason === "NotLoggedIn") {
@@ -18,7 +22,12 @@ export default async function backendRequest(url: any, ...restArgs: any[]): Prom
return response;
}
-export function handleNotLoggedIn(auth: Auth, e: NotLoggedInError) {
- console.log("Not logged in!")
- auth.signout();
+export function handleNotLoggedIn(auth: Auth, e: any) {
+ if (isNotLoggedInError(e)) {
+ console.log("Not logged in!")
+ auth.signout();
+ return;
+ }
+ // Rethrow if unhandled
+ throw e;
}
\ No newline at end of file
diff --git a/client/src/lib/integration/useIntegrations.tsx b/client/src/lib/integration/useIntegrations.tsx
index 19e7888..7eb9ac1 100644
--- a/client/src/lib/integration/useIntegrations.tsx
+++ b/client/src/lib/integration/useIntegrations.tsx
@@ -139,7 +139,7 @@ function useProvideIntegrations(): Integrations {
})
});
})
- .catch((e: NotLoggedInError) => handleNotLoggedIn(auth, e));
+ .catch((e: any) => handleNotLoggedIn(auth, e));
}
let addIntegration = async (v: serverApi.CreateIntegrationRequest) => {