import React, { SyntheticEvent,Component } from 'react'; import IconButton from '@material-ui/core/IconButton'; import Typography from '@material-ui/core/Typography'; import { PiPedalModel, PiPedalModelFactory, PresetIndexEntry, PresetIndex } from './PiPedalModel'; import Button from "@material-ui/core/Button"; import ButtonBase from "@material-ui/core/ButtonBase"; import { TransitionProps } from '@material-ui/core/transitions/transition'; import Slide from '@material-ui/core/Slide'; import Dialog from '@material-ui/core/Dialog'; import AppBar from '@material-ui/core/AppBar'; import Toolbar from '@material-ui/core/Toolbar'; import { Theme, withStyles, WithStyles, createStyles } from '@material-ui/core/styles'; import DraggableGrid, { ScrollDirection } from './DraggableGrid'; import MoreVertIcon from '@material-ui/icons/MoreVert'; import ListItemIcon from '@material-ui/core/ListItemIcon'; import ListItemText from '@material-ui/core/ListItemText'; import Menu from '@material-ui/core/Menu'; import MenuItem from '@material-ui/core/MenuItem'; import Fade from '@material-ui/core/Fade'; import UploadDialog from './UploadDialog'; import SelectHoverBackground from './SelectHoverBackground'; import CloseIcon from '@material-ui/icons/Close'; import ArrowBackIcon from '@material-ui/icons/ArrowBack'; import EditIcon from '@material-ui/icons/Edit'; import RenameDialog from './RenameDialog'; interface PresetDialogProps extends WithStyles { show: boolean; isEditDialog: boolean; onDialogClose: () => void; }; interface PresetDialogState { presets: PresetIndex; showActionBar: boolean; selectedItem: number; renameOpen: boolean; moreMenuAnchorEl: HTMLElement | null; openUploadDialog: boolean; }; const styles = (theme: Theme) => createStyles({ dialogAppBar: { position: 'relative', top: 0, left: 0 }, dialogActionBar: { position: 'relative', top: 0, left: 0, background: "black" }, dialogTitle: { marginLeft: theme.spacing(2), flex: 1, }, itemFrame: { display: "flex", flexDirection: "row", flexWrap: "nowrap", width: "100%", height: "56px", alignItems: "center", textAlign: "left", justifyContent: "center", paddingLeft: 8 }, iconFrame: { flex: "0 0 auto", }, itemIcon: { width: 24, height: 24, margin: 12, opacity: 0.6 }, itemLabel: { flex: "1 1 1px", marginLeft: 8 } }); const Transition = React.forwardRef(function Transition( props: TransitionProps & { children?: React.ReactElement }, ref: React.Ref, ) { return ; }); // eslint-disable-next-line @typescript-eslint/no-unused-vars const ActionBarTransition = React.forwardRef(function Transition( props: TransitionProps & { children?: React.ReactElement }, ref: React.Ref, ) { return ; }); const PresetDialog = withStyles(styles, { withTheme: true })( class extends Component { model: PiPedalModel; constructor(props: PresetDialogProps) { super(props); this.model = PiPedalModelFactory.getInstance(); this.handleDialogClose = this.handleDialogClose.bind(this); let presets = this.model.presets.get(); this.state = { presets: presets, showActionBar: false, selectedItem: presets.selectedInstanceId, renameOpen: false, moreMenuAnchorEl: null, openUploadDialog: false }; this.handlePresetsChanged = this.handlePresetsChanged.bind(this); } selectItemAtIndex(index: number) { let instanceId = this.state.presets.presets[index].instanceId; this.setState({ selectedItem: instanceId }); } isEditMode() { return this.state.showActionBar || this.props.isEditDialog; } onMoreClick(e: SyntheticEvent): void { this.setState({ moreMenuAnchorEl: e.currentTarget as HTMLElement }) } handleDownloadPreset() { this.handleMoreClose(); this.model.download("downloadPreset", this.model.presets.get().selectedInstanceId); } handleUploadPreset() { this.handleMoreClose(); this.setState({ openUploadDialog: true }); } handleMoreClose(): void { this.setState({ moreMenuAnchorEl: null }); } handlePresetsChanged() { let presets = this.model.presets.get(); if (!presets.areEqual(this.state.presets, false)) // avoid a bunch of peculiar effects if we update while a drag is in progress { // if we don't have a valid selection, then use the current preset. if (this.state.presets.getItem(this.state.selectedItem) == null) { this.setState({ presets: presets, selectedItem: presets.selectedInstanceId }); } else { this.setState({ presets: presets }); } } } componentDidMount() { this.model.presets.addOnChangedHandler(this.handlePresetsChanged); this.handlePresetsChanged(); // scroll selected item into view. } componentWillUnmount() { this.model.presets.removeOnChangedHandler(this.handlePresetsChanged); } getSelectedIndex() { let instanceId = this.isEditMode() ? this.state.selectedItem : this.state.presets.selectedInstanceId; let presets = this.state.presets; for (let i = 0; i < presets.presets.length; ++i) { if (presets.presets[i].instanceId === instanceId) return i; } return -1; } handleDeleteClick() { if (!this.state.selectedItem) return; let selectedItem = this.state.selectedItem; if (selectedItem !== -1) { this.model.deletePresetItem(selectedItem) .then((selectedItem: number) => { this.setState({ selectedItem: selectedItem }); }) .catch((error) => { this.model.showAlert(error); }); } } handleDialogClose() { this.props.onDialogClose(); } handleItemClick(instanceId: number): void { if (this.isEditMode()) { this.setState({ selectedItem: instanceId }); } else { this.model.loadPreset(instanceId); this.props.onDialogClose(); } } showActionBar(show: boolean): void { this.setState({ showActionBar: show }); } mapElement(el: any): React.ReactNode { let presetEntry = el as PresetIndexEntry; let classes = this.props.classes; let selectedItem = this.isEditMode() ? this.state.selectedItem : this.state.presets.selectedInstanceId; return (
this.handleItemClick(presetEntry.instanceId)} >
{presetEntry.name}
); } updateServerPresets(newPresets: PresetIndex) { newPresets = newPresets.clone(); this.model.updatePresets(newPresets) .catch((error) => { this.model.showAlert(error); }); } moveElement(from: number, to: number): void { let newPresets = this.state.presets.clone(); newPresets.movePreset(from, to); this.setState({ presets: newPresets, selectedItem: newPresets.presets[to].instanceId }); this.updateServerPresets(newPresets); } getSelectedName(): string { let item = this.state.presets.getItem(this.state.selectedItem); if (item) return item.name; return ""; } handleRenameClick() { let item = this.state.presets.getItem(this.state.selectedItem); if (item) { this.setState({ renameOpen: true }); } } handleRenameOk(text: string) { let item = this.state.presets.getItem(this.state.selectedItem); if (!item) return; if (item.name !== text) { this.model.renamePresetItem(this.state.selectedItem, text) .catch((error) => { this.onError(error); }); } this.setState({ renameOpen: false }); } handleCopy() { let item = this.state.presets.getItem(this.state.selectedItem); if (!item) return; this.model.duplicatePreset(this.state.selectedItem) .then((newId) => { this.setState({ selectedItem: newId }); }).catch((error) => { this.onError(error); }); } onError(error: string): void { this.model?.showAlert(error); } render() { let classes = this.props.classes; let actionBarClass = this.props.isEditDialog ? classes.dialogAppBar : classes.dialogActionBar; let defaultSelectedIndex = this.getSelectedIndex(); return ( { this.handleDialogClose() }} TransitionComponent={Transition}>
Presets this.showActionBar(true)} > { e.stopPropagation(); e.preventDefault(); }} > {(!this.props.isEditDialog) ? ( this.showActionBar(false)} aria-label="close"> ) : ( )} Presets {(this.state.presets.getItem(this.state.selectedItem) != null) && (
{ this.setState({ renameOpen: false }) }} onOk={(text: string) => { this.handleRenameOk(text); } } /> this.handleDeleteClick()} > Delete { this.onMoreClick(e) }} > this.handleMoreClose()} TransitionComponent={Fade} > { this.handleDownloadPreset(); }} > Download preset { this.handleUploadPreset() }}> Upload preset
) }
this.showActionBar(true)} canDrag={this.isEditMode()} onDragStart={(index, x, y) => { this.selectItemAtIndex(index) }} moveElement={(from, to) => { this.moveElement(from, to); }} scroll={ScrollDirection.Y} defaultSelectedIndex={defaultSelectedIndex} > { this.state.presets.presets.map((element) => { return this.mapElement(element); }) }
this.setState({selectedItem: instanceId}) } uploadAfter={this.state.selectedItem} open={this.state.openUploadDialog} onClose={() => { this.setState({ openUploadDialog: false }) }} />
); } } ); export default PresetDialog;