You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
170 lines
6.1 KiB
170 lines
6.1 KiB
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<any, any>[], |
|
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 <QueryWindow |
|
state={tabState} |
|
dispatch={tabDispatch} |
|
mainDispatch={dispatch} |
|
/> |
|
case WindowType.Artist: |
|
return <ArtistWindow |
|
state={tabState} |
|
dispatch={tabDispatch} |
|
mainDispatch={dispatch} |
|
/> |
|
case WindowType.Album: |
|
return <AlbumWindow |
|
state={tabState} |
|
dispatch={tabDispatch} |
|
mainDispatch={dispatch} |
|
/> |
|
case WindowType.Tag: |
|
return <TagWindow |
|
state={tabState} |
|
dispatch={tabDispatch} |
|
mainDispatch={dispatch} |
|
/> |
|
case WindowType.Song: |
|
return <SongWindow |
|
state={tabState} |
|
dispatch={tabDispatch} |
|
mainDispatch={dispatch} |
|
/> |
|
case WindowType.ManageTags: |
|
return <ManageTagsWindow |
|
state={tabState} |
|
dispatch={tabDispatch} |
|
mainDispatch={dispatch} |
|
/> |
|
default: |
|
throw new Error("Unimplemented window type"); |
|
} |
|
}); |
|
|
|
return <ThemeProvider theme={darkTheme}> |
|
<CssBaseline /> |
|
<AppBar |
|
tabLabels={state.tabStates.map((s: any) => 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]} |
|
</ThemeProvider> |
|
} |