import React, { useReducer, Reducer } from 'react'; import { ThemeProvider, CssBaseline, createMuiTheme } from '@material-ui/core'; import { grey } from '@material-ui/core/colors'; import AppBar from './appbar/AppBar'; import QueryWindow from './windows/query/QueryWindow'; import { NewTabProps } from './appbar/AddTabMenu'; import { newWindowState, newWindowReducer, WindowType } from './windows/Windows'; import ArtistWindow from './windows/artist/ArtistWindow'; import AlbumWindow from './windows/album/AlbumWindow'; import TagWindow from './windows/tag/TagWindow'; import SongWindow from './windows/song/SongWindow'; import ManageTagsWindow from './windows/manage_tags/ManageTagsWindow'; var _ = require('lodash'); const darkTheme = createMuiTheme({ palette: { type: 'dark', primary: { main: grey[100], } }, }); export interface MainWindowState { tabStates: any[], tabReducers: Reducer[], tabTypes: WindowType[], activeTab: number, } export enum MainWindowStateActions { SetActiveTab = "setActiveTab", DispatchToTab = "dispatchToTab", CloseTab = "closeTab", AddTab = "addTab", } export function MainWindowReducer(state: MainWindowState, action: any) { switch (action.type) { case MainWindowStateActions.SetActiveTab: return { ...state, activeTab: action.value } case MainWindowStateActions.CloseTab: const newSize = state.tabStates.length - 1; return { ...state, tabStates: state.tabStates.filter((i: any, idx: number) => idx != action.idx), tabReducers: state.tabReducers.filter((i: any, idx: number) => idx != action.idx), tabTypes: state.tabTypes.filter((i: any, idx: number) => idx != action.idx), activeTab: state.activeTab >= (newSize - 1) ? (newSize - 1) : state.activeTab, } case MainWindowStateActions.AddTab: return { ...state, tabStates: [...state.tabStates, action.tabState], tabReducers: [...state.tabReducers, action.tabReducer], tabTypes: [...state.tabTypes, action.tabType], } case MainWindowStateActions.DispatchToTab: return { ...state, tabStates: state.tabStates.map((item: any, i: number) => { return i === action.idx ? state.tabReducers[i](item, action.tabAction) : item; }) } default: throw new Error("Unimplemented MainWindow state update.") } } export default function MainWindow(props: any) { const [state, dispatch] = useReducer(MainWindowReducer, { tabStates: [ newWindowState[WindowType.Query](), newWindowState[WindowType.Song](), newWindowState[WindowType.Album](), newWindowState[WindowType.Artist](), newWindowState[WindowType.Tag](), newWindowState[WindowType.ManageTags](), ], tabReducers: [ newWindowReducer[WindowType.Query], newWindowReducer[WindowType.Song], newWindowReducer[WindowType.Album], newWindowReducer[WindowType.Artist], newWindowReducer[WindowType.Tag], newWindowReducer[WindowType.ManageTags], ], tabTypes: [ WindowType.Query, WindowType.Song, WindowType.Album, WindowType.Artist, WindowType.Tag, WindowType.ManageTags, ], activeTab: 0 }) const windows = state.tabStates.map((tabState: any, i: number) => { const tabDispatch = (action: any) => { dispatch({ type: MainWindowStateActions.DispatchToTab, tabAction: action, idx: i }); } switch (state.tabTypes[i]) { case WindowType.Query: return case WindowType.Artist: return case WindowType.Album: return case WindowType.Tag: return case WindowType.Song: return case WindowType.ManageTags: return default: throw new Error("Unimplemented window type"); } }); return s.tabLabel)} selectedTab={state.activeTab} setSelectedTab={(t: number) => dispatch({ type: MainWindowStateActions.SetActiveTab, value: t })} onCloseTab={(t: number) => dispatch({ type: MainWindowStateActions.CloseTab, idx: t })} onAddTab={(w: NewTabProps) => { dispatch({ type: MainWindowStateActions.AddTab, tabState: newWindowState[w.windowType](), tabReducer: newWindowReducer[w.windowType], tabType: w.windowType, }) }} /> {windows[state.activeTab]} }