v1.1.20 Release
This commit is contained in:
+189
-159
@@ -21,176 +21,206 @@ add_custom_command(
|
||||
WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}/react
|
||||
|
||||
DEPENDS
|
||||
src/AlsaMidiDeviceInfo.tsx
|
||||
src/SearchControl.tsx
|
||||
src/SplitControlView.tsx
|
||||
src/WifiConfigSettings.tsx
|
||||
src/FullScreenIME.tsx
|
||||
src/OkCancelDialog.tsx
|
||||
src/PluginControl.tsx
|
||||
src/reportWebVitals.ts
|
||||
src/JackHostStatus.tsx
|
||||
src/PluginPresetsDialog.tsx
|
||||
src/ToobSpectrumAnalyzerView.tsx
|
||||
src/MidiBindingsDialog.tsx
|
||||
src/MidiBinding.tsx
|
||||
src/TemporaryDrawer.tsx
|
||||
src/ToobFrequencyResponseView.tsx
|
||||
src/index.css
|
||||
src/setupTests.ts
|
||||
src/SearchFilter.tsx
|
||||
src/PluginOutputControl.tsx
|
||||
src/BankDialog.tsx
|
||||
src/VuMeter.tsx
|
||||
src/StringBuilder.tsx
|
||||
src/FilePropertyDialog.tsx
|
||||
src/GxTunerControl.tsx
|
||||
src/App.tsx
|
||||
src/GxTunerView.tsx
|
||||
src/Rect.tsx
|
||||
src/ToobSpectrumResponseView.tsx
|
||||
src/DialogEx.tsx
|
||||
src/GovernorSettings.tsx
|
||||
src/FilePropertyControl.tsx
|
||||
src/JackServerSettingsDialog.tsx
|
||||
src/ZoomedUiControl.tsx
|
||||
src/Pedal.tsx
|
||||
src/FullScreenIME.tsx
|
||||
src/PluginPreset.tsx
|
||||
src/SystemMidiBindingsDialog.tsx
|
||||
src/AppThemed.tsx
|
||||
src/MainPage.tsx
|
||||
src/PiPedalModel.tsx
|
||||
src/AppThemed.css
|
||||
src/PedalboardView.tsx
|
||||
src/ControlViewFactory.tsx
|
||||
src/PiPedalSocket.tsx
|
||||
src/PluginClass.tsx
|
||||
src/SplitControlView.tsx
|
||||
src/logo.svg
|
||||
src/ToobToneStackView.tsx
|
||||
src/Banks.tsx
|
||||
src/ToobPowerStage2View.tsx
|
||||
src/ListSelectDialog.tsx
|
||||
src/ToobWaveShapeView.tsx
|
||||
src/PluginInfoDialog.tsx
|
||||
src/SearchFilter.tsx
|
||||
src/SearchControl.tsx
|
||||
src/JackServerSettings.tsx
|
||||
src/WifiChannel.tsx
|
||||
src/WifiConfigDialog.tsx
|
||||
src/App.test.tsx
|
||||
src/PluginPresetSelector.tsx
|
||||
src/Pedal.tsx
|
||||
src/ToobMLView.tsx
|
||||
src/SettingsDialog.tsx
|
||||
src/ObservableProperty.tsx
|
||||
src/PresetDialog.tsx
|
||||
src/AndroidHost.tsx
|
||||
src/SelectHoverBackground.tsx
|
||||
src/WifiDirectConfigDialog.tsx
|
||||
src/WifiDirectConfigSettings.tsx
|
||||
src/PiPedalSocket.tsx
|
||||
src/ToobFrequencyResponseView.tsx
|
||||
src/ControlViewFactory.tsx
|
||||
src/Utility.tsx
|
||||
src/ToobToneStackView.tsx
|
||||
src/SelectHoverBackground.tsx
|
||||
src/MidiBindingsDialog.tsx
|
||||
src/TemporaryDrawer.tsx
|
||||
src/GxTunerView.tsx
|
||||
src/ToobInputStageView.tsx
|
||||
src/DraggableGrid.tsx
|
||||
src/JackStatusView.tsx
|
||||
src/PluginControl.tsx
|
||||
src/XxxSnippet.tsx
|
||||
src/PluginPreset.tsx
|
||||
src/Jack.tsx
|
||||
src/AlsaDeviceInfo.tsx
|
||||
src/MidiBinding.tsx
|
||||
src/PiPedalError.tsx
|
||||
src/IControlViewFactory.tsx
|
||||
src/Lv2Plugin.tsx
|
||||
src/Pedalboard.tsx
|
||||
src/AndroidHost.tsx
|
||||
src/PedalboardView.tsx
|
||||
src/PresetDialog.tsx
|
||||
src/AppThemed.tsx
|
||||
src/ZoomedDial.tsx
|
||||
src/RenameDialog.tsx
|
||||
src/SplitUiControls.tsx
|
||||
src/GovernorSettings.tsx
|
||||
src/AboutDialog.tsx
|
||||
src/ToobSpectrumResponseView.tsx
|
||||
src/PluginControlView.tsx
|
||||
src/NoChangePassword.tsx
|
||||
src/ToobSpectrumAnalyzerView.tsx
|
||||
src/MidiBindingView.tsx
|
||||
src/GxTunerControl.tsx
|
||||
src/Banks.tsx
|
||||
src/PluginPresetsDialog.tsx
|
||||
src/BankDialog.tsx
|
||||
src/UploadPresetDialog.tsx
|
||||
src/ToobPowerStage2View.tsx
|
||||
src/index.tsx
|
||||
src/Units.tsx
|
||||
src/VuMeter.tsx
|
||||
src/App.test.tsx
|
||||
src/DialogEx.tsx
|
||||
src/StringBuilder.tsx
|
||||
src/SelectChannelsDialog.tsx
|
||||
src/WifiConfigSettings.tsx
|
||||
src/Draggable.tsx
|
||||
src/ZoomedUiControl.tsx
|
||||
src/logo.svg
|
||||
src/Rect.tsx
|
||||
src/PluginClass.tsx
|
||||
src/reportWebVitals.ts
|
||||
src/PluginIcon.tsx
|
||||
src/App.tsx
|
||||
src/ResizeResponsiveComponent.tsx
|
||||
src/SvgPathBuilder.tsx
|
||||
src/JsonAtom.tsx
|
||||
src/SplitUiControls.tsx
|
||||
src/SelectChannelsDialog.tsx
|
||||
src/ToobMLView.tsx
|
||||
src/IControlViewFactory.tsx
|
||||
src/AppThemed.css
|
||||
src/ZoomedDial.tsx
|
||||
src/Units.tsx
|
||||
src/UploadPresetDialog.tsx
|
||||
src/NumericInput.tsx
|
||||
src/JackServerSettings.tsx
|
||||
src/ListSelectDialog.tsx
|
||||
src/react-app-env.d.ts
|
||||
src/JackServerSettingsDialog.tsx
|
||||
src/ObservableProperty.tsx
|
||||
src/Pedalboard.tsx
|
||||
src/SelectMidiChannelsDialog.tsx
|
||||
src/WifiChannel.tsx
|
||||
src/LoadPluginDialog.tsx
|
||||
src/WifiConfigDialog.tsx
|
||||
src/PluginInfoDialog.tsx
|
||||
src/ToobWaveShapeView.tsx
|
||||
src/ToobCabSimView.tsx
|
||||
src/AlsaMidiDeviceInfo.tsx
|
||||
src/ResizeResponsiveComponent.tsx
|
||||
src/RenameDialog.tsx
|
||||
src/SystemMidiBindingView.tsx
|
||||
src/OldDeleteIcon.tsx
|
||||
src/ToobInputStageView.tsx
|
||||
src/XxxSnippet.tsx
|
||||
src/NoChangePassword.tsx
|
||||
src/react-app-env.d.ts
|
||||
src/PiPedalError.tsx
|
||||
src/AlsaDeviceInfo.tsx
|
||||
src/index.tsx
|
||||
src/SettingsDialog.tsx
|
||||
src/PluginControlView.tsx
|
||||
src/PresetSelector.tsx
|
||||
src/OkCancelDialog.tsx
|
||||
|
||||
public/css/roboto.css
|
||||
public/fonts/Roboto-BlackItalic.woff2
|
||||
public/fonts/Roboto-Black.woff2
|
||||
public/fonts/Roboto-BoldItalic.woff2
|
||||
public/fonts/Roboto-Bold.woff2
|
||||
public/fonts/Roboto-Italic.woff2
|
||||
public/fonts/Roboto-LightItalic.woff2
|
||||
public/fonts/Roboto-Light.woff2
|
||||
public/fonts/Roboto-MediumItalic.woff2
|
||||
public/fonts/Roboto-Medium.woff2
|
||||
public/fonts/Roboto-Regular.woff2
|
||||
public/fonts/Roboto-ThinItalic.woff2
|
||||
public/fonts/Roboto-Thin.woff2
|
||||
|
||||
public/iso_codes.json
|
||||
public/logo512.png
|
||||
public/index.html
|
||||
public/manifest.json
|
||||
public/var
|
||||
public/var/current_pedalboard.json
|
||||
public/var/uiplugins.json
|
||||
public/var/config.json
|
||||
public/var/plugin_classes.json
|
||||
public/logo192.png
|
||||
public/serve.json
|
||||
public/robots.txt
|
||||
public/sample_lv2_plugins.json
|
||||
public/logo192x.png
|
||||
public/img/fx_analyzer.svg
|
||||
public/img/fx_flanger.svg
|
||||
public/img/cx_stereo.svg
|
||||
public/img/fx_split_a.svg
|
||||
public/img/fx_dial.svg
|
||||
public/img/drive_file_rename_outline_black_24dp.svg
|
||||
public/img/fx_filter.svg
|
||||
public/img/fx_filter_hp.svg
|
||||
public/img/cx_mono.svg
|
||||
public/img/fx_limiter.svg
|
||||
public/img/fx_converter.svg
|
||||
public/img/fx_simulator.svg
|
||||
public/img/fx_delay.svg
|
||||
public/img/fx_reverb.svg
|
||||
public/img/fx_empty.svg
|
||||
public/img/fx_eq.svg
|
||||
public/img/edit_banks.svg
|
||||
public/img/fx_gate.svg
|
||||
public/img/settings_black_24dp.svg
|
||||
public/img/help_outline_black_24dp.svg
|
||||
public/img/fx_oscillator.svg
|
||||
public/img/fx_split_b.svg
|
||||
public/img/fx_phaser.svg
|
||||
public/img/fx_amplifier.svg
|
||||
public/img/fx_plugin.svg
|
||||
public/img/ic_drawer.svg
|
||||
public/img/ic_drawer_2.png
|
||||
|
||||
public/img/fx_terminal.svg
|
||||
public/img/fx_spatial.svg
|
||||
public/img/fx_pitch.svg
|
||||
public/img/ic_logo.svg
|
||||
public/img/fx_flanger2.svg
|
||||
public/img/fx_function.svg
|
||||
public/img/fx_lr.svg
|
||||
public/img/fx_generator.svg
|
||||
public/img/fx_spectral.svg
|
||||
public/img/fx_chorus.svg
|
||||
public/img/fx_utility.svg
|
||||
public/img/fx_mixer.svg
|
||||
public/img/ic_presets.svg
|
||||
public/img/fx_instrument.svg
|
||||
public/img/fx_modulator.svg
|
||||
public/img/fx_compressor.svg
|
||||
public/img/fx_constant.svg
|
||||
public/img/fx_distortion.svg
|
||||
public/img/save_bank_as.svg
|
||||
public/favicon.ico
|
||||
|
||||
src/ToobCabSimView.tsx
|
||||
src/Utility.tsx
|
||||
src/Lv2Plugin.tsx
|
||||
src/Jack.tsx
|
||||
src/JackStatusView.tsx
|
||||
src/AboutDialog.tsx
|
||||
src/setupTests.ts
|
||||
src/DraggableGrid.tsx
|
||||
src/SvgPathBuilder.tsx
|
||||
src/LoadPluginDialog.tsx
|
||||
src/MidiBindingView.tsx
|
||||
src/PluginIcon.tsx
|
||||
src/UploadFileDialog.tsx
|
||||
|
||||
public/
|
||||
public/css
|
||||
public/css/roboto.css
|
||||
public/logo192x.png
|
||||
public/robots.txt
|
||||
public/img
|
||||
public/img/ic_drawer_2.png
|
||||
public/img/fx_constant.svg
|
||||
public/img/cx_mono.svg
|
||||
public/img/cx_stereo.svg
|
||||
public/img/fx_distortion.svg
|
||||
public/img/fx_oscillator.svg
|
||||
public/img/settings_black_24dp.svg
|
||||
public/img/fx_filter.svg
|
||||
public/img/delete_outline_black_24dp.svg
|
||||
public/img/fx_function.svg
|
||||
public/img/fx_generator.svg
|
||||
public/img/old_delete_outline_black_24dp.svg
|
||||
public/img/ic_bank.svg
|
||||
public/img/fx_compressor.svg
|
||||
public/img/file_download_black_24dp.svg
|
||||
public/img/fx_filter_hp.svg
|
||||
public/img/fx_plugin.svg
|
||||
public/img/fx_error.svg
|
||||
public/img/fx_gate.svg
|
||||
public/img/cc-by.png
|
||||
public/img/ic_midi.svg
|
||||
public/img/ic_pluginpreset.svg
|
||||
public/img/fx_split_a.svg
|
||||
public/img/fx_utility.svg
|
||||
public/img/ic_navigate_before.svg
|
||||
public/img/ic_drawer_2.svg
|
||||
public/img/ic_pluginpreset2.svg
|
||||
public/img/fx_parametric_eq.svg
|
||||
public/img/fx_terminal.svg
|
||||
public/img/ic_presets.svg
|
||||
public/img/VST_Logo_Steinberg.ico
|
||||
public/img/fx_flanger.svg
|
||||
public/img/fx_analyzer.svg
|
||||
public/img/fx_delay.svg
|
||||
public/img/fx_spectral.svg
|
||||
public/img/edit_banks.svg
|
||||
public/img/fx_chorus.svg
|
||||
public/img/fx_simulator.svg
|
||||
public/img/drive_file_rename_outline_black_24dp.svg
|
||||
public/img/fx_mixer.svg
|
||||
public/img/fx_eq.svg
|
||||
public/img/fx_modulator.svg
|
||||
public/img/file_upload_black_24dp.svg
|
||||
public/img/fx_pitch.svg
|
||||
public/img/ic_navigate_next.svg
|
||||
public/img/fx_phaser.svg
|
||||
public/img/ic_drawer.svg
|
||||
public/img/fx_amplifier.svg
|
||||
public/img/save_bank_as.svg
|
||||
public/img/fx_lr.svg
|
||||
public/img/fx_instrument.svg
|
||||
public/img/fx_reverb.svg
|
||||
public/img/fx_limiter.svg
|
||||
public/img/VST_Logo_Steinberg.png
|
||||
public/img/fx_empty.svg
|
||||
public/img/fx_dial.svg
|
||||
public/img/ic_logo.svg
|
||||
public/img/help_outline_black_24dp.svg
|
||||
public/img/fx_flanger2.svg
|
||||
public/img/old_delete_outline_white_24dp.svg
|
||||
public/img/fx_split_b.svg
|
||||
public/img/fx_spatial.svg
|
||||
public/img/fx_converter.svg
|
||||
public/img/vst.svg
|
||||
public/img/vst.png
|
||||
public/sample_lv2_plugins.json
|
||||
public/serve.json
|
||||
public/fonts
|
||||
public/fonts/Roboto-LightItalic.woff2
|
||||
public/fonts/Roboto-Light.woff2
|
||||
public/fonts/Roboto-BlackItalic.woff2
|
||||
public/fonts/Roboto-ThinItalic.woff2
|
||||
public/fonts/Roboto-Bold.woff2
|
||||
public/fonts/Roboto-Italic.woff2
|
||||
public/fonts/Roboto-Black.woff2
|
||||
public/fonts/Roboto-BoldItalic.woff2
|
||||
public/fonts/Roboto-Regular.woff2
|
||||
public/fonts/Roboto-Medium.woff2
|
||||
public/fonts/Roboto-Thin.woff2
|
||||
public/fonts/LICENSE.txt
|
||||
public/fonts/Roboto-MediumItalic.woff2
|
||||
public/favicon.ico
|
||||
public/iso_codes.json
|
||||
public/logo192.png
|
||||
public/logo512.png
|
||||
public/index.html
|
||||
public/manifest.json
|
||||
public/var
|
||||
public/var/config.json
|
||||
public/var/current_pedalboard.json
|
||||
public/var/uiplugins.json
|
||||
public/var/plugin_classes.json
|
||||
|
||||
)
|
||||
|
||||
add_custom_target (
|
||||
|
||||
@@ -837,9 +837,11 @@ const AppThemed = withStyles(appStyles)(class extends ResizeResponsiveComponent<
|
||||
>
|
||||
<DialogContent>
|
||||
<DialogContentText id="alert-dialog-description">
|
||||
{
|
||||
this.model_.alertMessage.get()
|
||||
}
|
||||
<Typography variant="body2">
|
||||
{
|
||||
this.state.alertDialogMessage
|
||||
}
|
||||
</Typography>
|
||||
</DialogContentText>
|
||||
</DialogContent>
|
||||
<DialogActions>
|
||||
|
||||
@@ -27,15 +27,12 @@ import { Theme } from '@mui/material/styles';
|
||||
import { WithStyles } from '@mui/styles';
|
||||
import createStyles from '@mui/styles/createStyles';
|
||||
import withStyles from '@mui/styles/withStyles';
|
||||
import { PiPedalFileProperty } from './Lv2Plugin';
|
||||
import { UiFileProperty } from './Lv2Plugin';
|
||||
import Typography from '@mui/material/Typography';
|
||||
import { PiPedalModel, PiPedalModelFactory, ListenHandle, StateChangedHandle } from './PiPedalModel';
|
||||
import ButtonBase from '@mui/material/ButtonBase'
|
||||
import MoreHorizIcon from '@mui/icons-material/MoreHoriz';
|
||||
|
||||
|
||||
|
||||
|
||||
import {PedalboardItem} from './Pedalboard';
|
||||
|
||||
|
||||
export const StandardItemSize = { width: 80, height: 140 }
|
||||
@@ -73,13 +70,14 @@ const styles = (theme: Theme) => createStyles({
|
||||
|
||||
|
||||
export interface FilePropertyControlProps extends WithStyles<typeof styles> {
|
||||
instanceId: number;
|
||||
fileProperty: PiPedalFileProperty;
|
||||
onFileClick: (fileProperty: PiPedalFileProperty, value: string) => void;
|
||||
fileProperty: UiFileProperty;
|
||||
pedalboardItem: PedalboardItem;
|
||||
onFileClick: (fileProperty: UiFileProperty, value: string) => void;
|
||||
theme: Theme;
|
||||
}
|
||||
type FilePropertyControlState = {
|
||||
error: boolean;
|
||||
hasValue: boolean;
|
||||
value: string;
|
||||
};
|
||||
|
||||
@@ -96,6 +94,7 @@ const FilePropertyControl =
|
||||
|
||||
this.state = {
|
||||
error: false,
|
||||
hasValue: false,
|
||||
value: "",
|
||||
};
|
||||
this.model = PiPedalModelFactory.getInstance();
|
||||
@@ -108,12 +107,12 @@ const FilePropertyControl =
|
||||
|
||||
refreshPatchProperty()
|
||||
{
|
||||
this.model.getPatchProperty(this.props.instanceId, this.props.fileProperty.patchProperty)
|
||||
this.model.getPatchProperty(this.props.pedalboardItem.instanceId, this.props.fileProperty.patchProperty)
|
||||
.then(
|
||||
(json: any) => {
|
||||
if (json && json.otype_ === "Path") {
|
||||
let path = json.value as string;
|
||||
this.setState({ value: path });
|
||||
this.setState({ value: path, hasValue: true });
|
||||
}
|
||||
}
|
||||
)
|
||||
@@ -138,7 +137,7 @@ const FilePropertyControl =
|
||||
}
|
||||
this.refreshPatchProperty();
|
||||
this.stateChangedHandle = this.model.addLv2StateChangedListener(
|
||||
this.props.instanceId,
|
||||
this.props.pedalboardItem.instanceId,
|
||||
() => {
|
||||
this.refreshPatchProperty();
|
||||
});
|
||||
@@ -149,19 +148,25 @@ const FilePropertyControl =
|
||||
this.model.removeLv2StateChangedListener(this.stateChangedHandle);
|
||||
}
|
||||
}
|
||||
private mounted: boolean = false;
|
||||
componentDidMount() {
|
||||
this.mounted = true;
|
||||
this.subscribeToPropertyGet();
|
||||
}
|
||||
componentWillUnmount() {
|
||||
this.unsubscribeToPropertyGet();
|
||||
this.mounted = false;
|
||||
}
|
||||
componentDidUpdate(prevProps: Readonly<FilePropertyControlProps>, prevState: Readonly<FilePropertyControlState>, snapshot?: any): void {
|
||||
if (prevProps.fileProperty.patchProperty !== this.props.fileProperty.patchProperty
|
||||
|| prevProps.instanceId !== this.props.instanceId) {
|
||||
this.setState({ value: "" });
|
||||
|| prevProps.pedalboardItem.instanceId !== this.props.pedalboardItem.instanceId
|
||||
|| prevProps.pedalboardItem.stateUpdateCount !== this.props.pedalboardItem.stateUpdateCount
|
||||
|
||||
) {
|
||||
this.unsubscribeToPropertyGet();
|
||||
this.subscribeToPropertyGet();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -193,9 +198,15 @@ const FilePropertyControl =
|
||||
//let classes = this.props.classes;
|
||||
let fileProperty = this.props.fileProperty;
|
||||
|
||||
let value = this.fileNameOnly(this.state.value);
|
||||
if (!value || value.length === 0) {
|
||||
value = "\u00A0";
|
||||
let value = "\u00A0";
|
||||
if (this.state.hasValue)
|
||||
{
|
||||
if (this.state.value.length === 0)
|
||||
{
|
||||
value = "<none>";
|
||||
} else {
|
||||
value = this.fileNameOnly(this.state.value);
|
||||
}
|
||||
}
|
||||
|
||||
let item_width = 264;
|
||||
|
||||
@@ -33,7 +33,7 @@ import IconButton from '@mui/material/IconButton';
|
||||
import OldDeleteIcon from './OldDeleteIcon';
|
||||
|
||||
import ResizeResponsiveComponent from './ResizeResponsiveComponent';
|
||||
import { PiPedalFileProperty } from './Lv2Plugin';
|
||||
import { UiFileProperty } from './Lv2Plugin';
|
||||
import ButtonBase from '@mui/material/ButtonBase';
|
||||
import Typography from '@mui/material/Typography';
|
||||
import DialogEx from './DialogEx';
|
||||
@@ -42,9 +42,9 @@ import OkCancelDialog from './OkCancelDialog';
|
||||
|
||||
export interface FilePropertyDialogProps {
|
||||
open: boolean,
|
||||
fileProperty: PiPedalFileProperty,
|
||||
fileProperty: UiFileProperty,
|
||||
selectedFile: string,
|
||||
onOk: (fileProperty: PiPedalFileProperty, selectedItem: string) => void,
|
||||
onOk: (fileProperty: UiFileProperty, selectedItem: string) => void,
|
||||
onCancel: () => void
|
||||
};
|
||||
|
||||
@@ -53,6 +53,8 @@ export interface FilePropertyDialogState {
|
||||
selectedFile: string;
|
||||
hasSelection: boolean;
|
||||
files: string[];
|
||||
columns: number;
|
||||
columnWidth: number;
|
||||
openUploadFileDialog: boolean;
|
||||
openConfirmDeleteDialog: boolean;
|
||||
};
|
||||
@@ -70,13 +72,33 @@ export default class FilePropertyDialog extends ResizeResponsiveComponent<FilePr
|
||||
fullScreen: false,
|
||||
selectedFile: props.selectedFile,
|
||||
hasSelection: false,
|
||||
columns: 0,
|
||||
columnWidth: 1,
|
||||
files: [],
|
||||
openUploadFileDialog: false,
|
||||
openConfirmDeleteDialog: false
|
||||
};
|
||||
|
||||
this.requestScroll = true;
|
||||
this.requestFiles();
|
||||
}
|
||||
|
||||
private scrollRef: HTMLDivElement | null = null;
|
||||
|
||||
onScrollRef(element: HTMLDivElement | null) {
|
||||
this.scrollRef = element;
|
||||
this.maybeScrollIntoView();
|
||||
}
|
||||
private maybeScrollIntoView()
|
||||
{
|
||||
if (this.scrollRef !== null && this.state.files.length !== 0 && this.mounted && this.requestScroll)
|
||||
{
|
||||
this.requestScroll = false;
|
||||
let options: ScrollIntoViewOptions = { block: "nearest"};
|
||||
options.block = "nearest";
|
||||
|
||||
this.scrollRef.scrollIntoView(options);
|
||||
}
|
||||
}
|
||||
private mounted: boolean = false;
|
||||
private model: PiPedalModel;
|
||||
|
||||
@@ -91,6 +113,7 @@ export default class FilePropertyDialog extends ResizeResponsiveComponent<FilePr
|
||||
this.model.requestFileList(this.props.fileProperty)
|
||||
.then((files) => {
|
||||
if (this.mounted) {
|
||||
files.splice(0,0,"");
|
||||
this.setState({ files: files, hasSelection: this.isFileInList(files, this.state.selectedFile) });
|
||||
}
|
||||
}).catch((error) => {
|
||||
@@ -98,10 +121,39 @@ export default class FilePropertyDialog extends ResizeResponsiveComponent<FilePr
|
||||
});
|
||||
}
|
||||
|
||||
private lastDivRef : HTMLDivElement | null = null;
|
||||
|
||||
onMeasureRef(div: HTMLDivElement | null)
|
||||
{
|
||||
this.lastDivRef = div;
|
||||
if (div) {
|
||||
let width = div.offsetWidth;
|
||||
if (width === 0) return;
|
||||
let columns = Math.floor((width-40)/280);
|
||||
if(columns === 0)
|
||||
{
|
||||
columns = 1;
|
||||
}
|
||||
let columnWidth = (width-40)/columns;
|
||||
if (columns !== this.state.columns || columnWidth !== this.state.columnWidth)
|
||||
{
|
||||
this.setState({columns: columns, columnWidth: columnWidth});
|
||||
}
|
||||
}
|
||||
}
|
||||
onWindowSizeChanged(width: number, height: number): void {
|
||||
this.setState({ fullScreen: height < 200 })
|
||||
|
||||
this.setState({
|
||||
fullScreen: height < 200
|
||||
})
|
||||
if (this.lastDivRef !== null)
|
||||
{
|
||||
this.onMeasureRef(this.lastDivRef);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private requestScroll: boolean = false;
|
||||
|
||||
componentDidMount() {
|
||||
super.componentDidMount();
|
||||
@@ -110,6 +162,7 @@ export default class FilePropertyDialog extends ResizeResponsiveComponent<FilePr
|
||||
componentWillUnmount() {
|
||||
super.componentWillUnmount();
|
||||
this.mounted = false;
|
||||
this.lastDivRef = null;
|
||||
}
|
||||
componentDidUpdate(prevProps: Readonly<FilePropertyDialogProps>, prevState: Readonly<FilePropertyDialogState>, snapshot?: any): void {
|
||||
super.componentDidUpdate?.(prevProps, prevState, snapshot);
|
||||
@@ -118,6 +171,11 @@ export default class FilePropertyDialog extends ResizeResponsiveComponent<FilePr
|
||||
if (this.props.open)
|
||||
{
|
||||
this.requestFiles()
|
||||
this.requestScroll = true;
|
||||
if (this.state.selectedFile !== this.props.selectedFile)
|
||||
{
|
||||
this.setState({selectedFile: this.props.selectedFile});
|
||||
}
|
||||
}
|
||||
} else if (prevProps.fileProperty !== this.props.fileProperty) {
|
||||
this.requestFiles()
|
||||
@@ -144,6 +202,7 @@ export default class FilePropertyDialog extends ResizeResponsiveComponent<FilePr
|
||||
private isFileInList(files: string[], file: string) {
|
||||
|
||||
let hasSelection = false;
|
||||
if (file === "") return true;
|
||||
for (var listFile of files) {
|
||||
if (listFile === file) {
|
||||
hasSelection = true;
|
||||
@@ -154,6 +213,7 @@ export default class FilePropertyDialog extends ResizeResponsiveComponent<FilePr
|
||||
}
|
||||
|
||||
onSelectValue(selectedFile: string) {
|
||||
this.requestScroll = true;
|
||||
this.setState({ selectedFile: selectedFile, hasSelection: this.isFileInList(this.state.files, selectedFile) })
|
||||
}
|
||||
onDoubleClickValue(selectedFile: string) {
|
||||
@@ -205,9 +265,13 @@ export default class FilePropertyDialog extends ResizeResponsiveComponent<FilePr
|
||||
}
|
||||
}
|
||||
|
||||
private wantsScrollRef: boolean = true;
|
||||
|
||||
mapKey: number = 0;
|
||||
render() {
|
||||
this.mapKey = 0;
|
||||
let columnWidth = this.state.columnWidth;
|
||||
|
||||
return this.props.open &&
|
||||
(
|
||||
<DialogEx onClose={() => this.props.onCancel()} open={this.props.open} tag="FilePropertyDialog" fullWidth maxWidth="xl" style={{ height: "90%" }}
|
||||
@@ -223,22 +287,40 @@ export default class FilePropertyDialog extends ResizeResponsiveComponent<FilePr
|
||||
</div>
|
||||
</DialogTitle>
|
||||
<div style={{ flex: "0 0 auto", height: "1px", background: "rgba(0,0,0,0.2" }}> </div>
|
||||
<div style={{ flex: "1 1 auto", height: "300", display: "flex", flexFlow: "row nowrap", overflowX: "auto", overflowY: "visible" }}>
|
||||
<div style={{ flex: "1 1 100%", display: "flex", flexFlow: "column wrap", justifyContent: "start", alignItems: "flex-start", paddingLeft: 16, paddingTop: 16 }}>
|
||||
<div style={{ flex: "1 1 auto", height: "300", display: "flex", flexFlow: "row wrap", overflowX: "hidden", overflowY: "auto" }}>
|
||||
<div
|
||||
ref={(element)=> this.onMeasureRef(element)}
|
||||
style={{ flex: "1 1 100%", display: "flex", flexFlow: "row wrap",
|
||||
justifyContent: "flex-start", alignContent: "flex-start", paddingLeft: 16, paddingTop: 16,paddingBottom: 16 }}>
|
||||
{
|
||||
(this.state.columns !== 0) && // don't render until we have number of columns derived from layout.
|
||||
this.state.files.map(
|
||||
(value: string, index: number) => {
|
||||
let displayValue = value;
|
||||
if (displayValue === "")
|
||||
{
|
||||
displayValue = "<none>";
|
||||
} else {
|
||||
displayValue = this.fileNameOnly(value);
|
||||
}
|
||||
let selected = value === this.state.selectedFile;
|
||||
let selectBg = selected ? "rgba(0,0,0,0.15)" : "rgba(0,0,0,0.0)";
|
||||
let scrollRef: ((element: HTMLDivElement | null) => void) | undefined = undefined;
|
||||
if (selected)
|
||||
{
|
||||
scrollRef = (element)=> { this.onScrollRef(element)};
|
||||
}
|
||||
|
||||
return (
|
||||
<ButtonBase key={this.mapKey++}
|
||||
style={{ width: "320px", flex: "0 0 48px", position: "relative" }}
|
||||
|
||||
style={{ width: columnWidth, flex: "0 0 auto", height: 48, position: "relative" }}
|
||||
onClick={() => this.onSelectValue(value)} onDoubleClick={()=> {this.onDoubleClickValue(value);}}
|
||||
>
|
||||
<div style={{ position: "absolute", background: selectBg, width: "100%", height: "100%", borderRadius: 4 }} />
|
||||
<div style={{ display: "flex", flexFlow: "row nowrap", justifyContent: "start", alignItems: "center", width: "100%", height: "100%" }}>
|
||||
<div ref={scrollRef} style={{ position: "absolute", background: selectBg, width: "100%", height: "100%", borderRadius: 4 }} />
|
||||
<div style={{ display: "flex", flexFlow: "row nowrap", textOverflow: "ellipsis", justifyContent: "start", alignItems: "center", width: "100%", height: "100%" }}>
|
||||
<AudioFileIcon style={{ flex: "0 0 auto", opacity: 0.7, marginRight: 8, marginLeft: 8 }} />
|
||||
<Typography noWrap style={{ flex: "1 1 auto", textAlign: "left" }}>{this.fileNameOnly(value)}</Typography>
|
||||
<Typography noWrap style={{ flex: "1 1 auto", textAlign: "left" }}>{displayValue}</Typography>
|
||||
</div>
|
||||
</ButtonBase>
|
||||
);
|
||||
@@ -265,7 +347,11 @@ export default class FilePropertyDialog extends ResizeResponsiveComponent<FilePr
|
||||
<Button onClick={() => { this.props.onCancel(); }} aria-label="cancel">
|
||||
Cancel
|
||||
</Button>
|
||||
<Button style={{ flex: "0 0 auto" }} onClick={() => { this.props.onOk(this.props.fileProperty, this.state.selectedFile); }} color="secondary" disabled={!this.state.hasSelection} aria-label="select">
|
||||
<Button style={{ flex: "0 0 auto" }}
|
||||
onClick={() => { this.props.onOk(this.props.fileProperty, this.state.selectedFile); }}
|
||||
color="secondary"
|
||||
disabled={(!this.state.hasSelection) && this.state.selectedFile !== ""} aria-label="select"
|
||||
>
|
||||
Select
|
||||
</Button>
|
||||
</div>
|
||||
|
||||
+73
-18
@@ -107,23 +107,78 @@ export class PortGroup {
|
||||
program_list_id: number = -1;
|
||||
};
|
||||
|
||||
export class PiPedalFileType {
|
||||
deserialize(input: any): PiPedalFileType {
|
||||
export class UiFileType {
|
||||
deserialize(input: any): UiFileType {
|
||||
this.name = input.name;
|
||||
this.fileExtension = input.fileExtension;
|
||||
this.mimeType = input.mimeType;
|
||||
return this;
|
||||
}
|
||||
static deserialize_array(input: any): PiPedalFileType[]
|
||||
static deserialize_array(input: any): UiFileType[]
|
||||
{
|
||||
let result: PiPedalFileType[] = [];
|
||||
let result: UiFileType[] = [];
|
||||
for (let i = 0; i < input.length; ++i)
|
||||
{
|
||||
result[i] = new PiPedalFileType().deserialize(input[i]);
|
||||
result[i] = new UiFileType().deserialize(input[i]);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private static IsAndroid() : boolean
|
||||
{
|
||||
return /Android/i.test(navigator.userAgent);
|
||||
}
|
||||
static MergeMimeTypes(fileTypes: UiFileType[]): string
|
||||
{
|
||||
if (fileTypes.length === 0) {
|
||||
return "";
|
||||
}
|
||||
let result = fileTypes[0].mimeType;
|
||||
for (let i = 1; i < fileTypes.length; ++i)
|
||||
{
|
||||
let fileType = fileTypes[i];
|
||||
if (fileType.mimeType !== result)
|
||||
{
|
||||
if (result.startsWith("audio/") && fileType.mimeType.startsWith("audio/"))
|
||||
{
|
||||
result = "audio/*";
|
||||
} else if (result.startsWith("video/") && fileType.mimeType.startsWith("video/"))
|
||||
{
|
||||
result = "video/*";
|
||||
} else if (result.startsWith("text/") && fileType.mimeType.startsWith("text/"))
|
||||
{
|
||||
result = "text/*";
|
||||
} else {
|
||||
result = "application/octet-stream";
|
||||
}
|
||||
}
|
||||
}
|
||||
if (this.IsAndroid())
|
||||
{
|
||||
if (result.startsWith("audio/")) result = "audio/*";
|
||||
if (result.startsWith("video/")) result = "video/*";
|
||||
if (result.startsWith("text/")) result = "text/*";
|
||||
} else {
|
||||
// chrome desktop thinks "application/octet-stream" is .exe, .com, or .bat.
|
||||
// Feed it file extensions isntead.
|
||||
if (result = "application/octet-stream")
|
||||
{
|
||||
result = "";
|
||||
for (let i = 0; i < fileTypes.length; ++i)
|
||||
{
|
||||
if (i !== 0)
|
||||
{
|
||||
result += ',';
|
||||
}
|
||||
result += fileTypes[i].fileExtension;
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
name: string = "";
|
||||
fileExtension: string = "";
|
||||
mimeType: string = "";
|
||||
}
|
||||
|
||||
export class UiPropertyNotification {
|
||||
@@ -150,23 +205,23 @@ export class UiPropertyNotification {
|
||||
protocol: string = "";
|
||||
|
||||
};
|
||||
export class PiPedalFileProperty {
|
||||
deserialize(input: any): PiPedalFileProperty
|
||||
export class UiFileProperty {
|
||||
deserialize(input: any): UiFileProperty
|
||||
{
|
||||
this.label = input.label;
|
||||
this.fileTypes = PiPedalFileType.deserialize_array(input.fileTypes);
|
||||
this.fileTypes = UiFileType.deserialize_array(input.fileTypes);
|
||||
this.patchProperty = input.patchProperty;
|
||||
this.directory = input.directory;
|
||||
this.index = input.index;
|
||||
this.portGroup = input.portGroup;
|
||||
return this;
|
||||
}
|
||||
static deserialize_array(input: any): PiPedalFileProperty[]
|
||||
static deserialize_array(input: any): UiFileProperty[]
|
||||
{
|
||||
let result: PiPedalFileProperty[] = [];
|
||||
let result: UiFileProperty[] = [];
|
||||
for (let i = 0; i < input.length; ++i)
|
||||
{
|
||||
result[i] = new PiPedalFileProperty().deserialize(input[i]);
|
||||
result[i] = new UiFileProperty().deserialize(input[i]);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
@@ -191,7 +246,7 @@ export class PiPedalFileProperty {
|
||||
if (this.fileTypes.length === 0) {
|
||||
return true;
|
||||
}
|
||||
let extension = PiPedalFileProperty.getFileExtension(filename);
|
||||
let extension = UiFileProperty.getFileExtension(filename);
|
||||
for (let fileType of this.fileTypes)
|
||||
{
|
||||
if (fileType.fileExtension === extension )
|
||||
@@ -203,7 +258,7 @@ export class PiPedalFileProperty {
|
||||
}
|
||||
|
||||
label: string = "";
|
||||
fileTypes: PiPedalFileType[] = [];
|
||||
fileTypes: UiFileType[] = [];
|
||||
patchProperty: string = "";
|
||||
directory: string = "";
|
||||
index: number = -1;
|
||||
@@ -226,7 +281,7 @@ export class Lv2Plugin implements Deserializable<Lv2Plugin> {
|
||||
this.port_groups = PortGroup.deserialize_array(input.port_groups);
|
||||
if (input.fileProperties)
|
||||
{
|
||||
this.fileProperties = PiPedalFileProperty.deserialize_array(input.fileProperties)
|
||||
this.fileProperties = UiFileProperty.deserialize_array(input.fileProperties)
|
||||
} else {
|
||||
this.fileProperties = [];
|
||||
}
|
||||
@@ -251,7 +306,7 @@ export class Lv2Plugin implements Deserializable<Lv2Plugin> {
|
||||
comment: string = "";
|
||||
ports: Port[] = Port.EmptyPorts;
|
||||
port_groups: PortGroup[] = [];
|
||||
fileProperties: PiPedalFileProperty[] = [];
|
||||
fileProperties: UiFileProperty[] = [];
|
||||
uiPortNotifications: UiPropertyNotification[] = [];
|
||||
}
|
||||
|
||||
@@ -508,7 +563,7 @@ export class UiControl implements Deserializable<UiControl> {
|
||||
}
|
||||
|
||||
formatDisplayValue(value: number): string {
|
||||
if (this.integer_property || this.enumeration_property) {
|
||||
if (this.integer_property) {
|
||||
value = Math.round(value);
|
||||
}
|
||||
|
||||
@@ -614,7 +669,7 @@ export class UiPlugin implements Deserializable<UiPlugin> {
|
||||
this.port_groups = PortGroup.deserialize_array(input.port_groups);
|
||||
if (input.fileProperties)
|
||||
{
|
||||
this.fileProperties = PiPedalFileProperty.deserialize_array(input.fileProperties)
|
||||
this.fileProperties = UiFileProperty.deserialize_array(input.fileProperties)
|
||||
} else {
|
||||
this.fileProperties = [];
|
||||
}
|
||||
@@ -682,7 +737,7 @@ export class UiPlugin implements Deserializable<UiPlugin> {
|
||||
description: string = "";
|
||||
controls: UiControl[] = [];
|
||||
port_groups: PortGroup[] = [];
|
||||
fileProperties: PiPedalFileProperty[] = [];
|
||||
fileProperties: UiFileProperty[] = [];
|
||||
is_vst3 : boolean = false;
|
||||
}
|
||||
|
||||
|
||||
@@ -67,6 +67,7 @@ export class PedalboardItem implements Deserializable<PedalboardItem> {
|
||||
|
||||
this.controlValues = ControlValue.deserializeArray(input.controlValues);
|
||||
this.vstState = input.vstState ?? "";
|
||||
this.stateUpdateCount = input.stateUpdateCount;
|
||||
this.lv2State = input.lv2State;
|
||||
return this;
|
||||
}
|
||||
@@ -195,6 +196,7 @@ export class PedalboardItem implements Deserializable<PedalboardItem> {
|
||||
controlValues: ControlValue[] = ControlValue.EmptyArray;
|
||||
midiBindings: MidiBinding[] = [];
|
||||
vstState: string = "";
|
||||
stateUpdateCount: number = 0;
|
||||
lv2State: [boolean,any] = [false,{}]
|
||||
};
|
||||
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
import { UiPlugin, UiControl, PluginType, PiPedalFileProperty } from './Lv2Plugin';
|
||||
import { UiPlugin, UiControl, PluginType, UiFileProperty } from './Lv2Plugin';
|
||||
|
||||
import { PiPedalArgumentError, PiPedalStateError } from './PiPedalError';
|
||||
|
||||
@@ -588,6 +588,10 @@ export class PiPedalModel //implements PiPedalModel
|
||||
} else if (message === "onSystemMidiBindingsChanged") {
|
||||
let bindings = MidiBinding.deserialize_array(body);
|
||||
this.systemMidiBindings.set(bindings);
|
||||
} else if (message === "onErrorMessage")
|
||||
{
|
||||
this.showAlert(body as string);
|
||||
|
||||
} else {
|
||||
throw new PiPedalStateError("Unrecognized message received from server: " + message);
|
||||
}
|
||||
@@ -1054,6 +1058,8 @@ export class PiPedalModel //implements PiPedalModel
|
||||
|
||||
|
||||
handleOnLoadPluginPreset(instanceId: number, controlValues: ControlValue[]) {
|
||||
// note that plugins with state are dealt with server-side.
|
||||
// if we made it here, we can just load the controls.
|
||||
let pedalboard = this.pedalboard.get();
|
||||
if (pedalboard === undefined) throw new PiPedalStateError("Pedalboard not ready.");
|
||||
let newPedalboard = pedalboard.clone();
|
||||
@@ -1342,13 +1348,15 @@ export class PiPedalModel //implements PiPedalModel
|
||||
while (true) {
|
||||
let v = it.next();
|
||||
if (v.done) break;
|
||||
let item = v.value;
|
||||
let item = v.value;
|
||||
if (item.instanceId === itemId) {
|
||||
item.deserialize(new PedalboardItem()); // skeezy way to re-initialize.
|
||||
item.instanceId = ++newPedalboard.nextInstanceId;
|
||||
item.uri = selectedUri;
|
||||
item.pluginName = plugin.name;
|
||||
item.controlValues = this.getDefaultValues(item.uri);
|
||||
item.isEnabled = true;
|
||||
// lv2State: not valid. vstState : not valid.
|
||||
this.pedalboard.set(newPedalboard);
|
||||
this.updateServerPedalboard()
|
||||
return item.instanceId;
|
||||
@@ -1590,7 +1598,7 @@ export class PiPedalModel //implements PiPedalModel
|
||||
});
|
||||
}
|
||||
|
||||
requestFileList(piPedalFileProperty: PiPedalFileProperty): Promise<string[]> {
|
||||
requestFileList(piPedalFileProperty: UiFileProperty): Promise<string[]> {
|
||||
return nullCast(this.webSocket)
|
||||
.request<string[]>('requestFileList', piPedalFileProperty);
|
||||
}
|
||||
|
||||
@@ -23,7 +23,7 @@ import { WithStyles } from '@mui/styles';
|
||||
import createStyles from '@mui/styles/createStyles';
|
||||
import withStyles from '@mui/styles/withStyles';
|
||||
import { PiPedalModel, PiPedalModelFactory } from './PiPedalModel';
|
||||
import { UiPlugin, UiControl, PiPedalFileProperty, ScalePoint } from './Lv2Plugin';
|
||||
import { UiPlugin, UiControl, UiFileProperty, ScalePoint } from './Lv2Plugin';
|
||||
import {
|
||||
Pedalboard, PedalboardItem, ControlValue
|
||||
} from './Pedalboard';
|
||||
@@ -239,7 +239,7 @@ type PluginControlViewState = {
|
||||
imeCaption: string;
|
||||
imeInitialHeight: number;
|
||||
showFileDialog: boolean,
|
||||
dialogFileProperty: PiPedalFileProperty,
|
||||
dialogFileProperty: UiFileProperty,
|
||||
dialogFileValue: string
|
||||
};
|
||||
|
||||
@@ -260,7 +260,7 @@ const PluginControlView =
|
||||
imeCaption: "",
|
||||
imeInitialHeight: 0,
|
||||
showFileDialog: false,
|
||||
dialogFileProperty: new PiPedalFileProperty(),
|
||||
dialogFileProperty: new UiFileProperty(),
|
||||
dialogFileValue: ""
|
||||
|
||||
}
|
||||
@@ -323,10 +323,10 @@ const PluginControlView =
|
||||
});
|
||||
}
|
||||
|
||||
makeFilePropertyUI(fileProperty: PiPedalFileProperty): ReactNode {
|
||||
makeFilePropertyUI(fileProperty: UiFileProperty): ReactNode {
|
||||
return ((
|
||||
|
||||
<FilePropertyControl instanceId={this.props.instanceId}
|
||||
<FilePropertyControl pedalboardItem={this.props.item}
|
||||
fileProperty={fileProperty}
|
||||
onFileClick={(fileProperty, selectedFile) => {
|
||||
this.setState({ showFileDialog: true, dialogFileProperty: fileProperty, dialogFileValue: selectedFile });
|
||||
|
||||
@@ -259,7 +259,7 @@ const PluginPresetsDialog = withStyles(styles, { withTheme: true })(
|
||||
<img src="img/ic_pluginpreset2.svg" className={classes.itemIcon} alt="" />
|
||||
</div>
|
||||
<div className={classes.itemLabel}>
|
||||
<Typography> noWrap
|
||||
<Typography noWrap>
|
||||
{presetEntry.label}
|
||||
</Typography>
|
||||
</div>
|
||||
|
||||
@@ -80,13 +80,10 @@ export const SelectHoverBackground =
|
||||
}
|
||||
|
||||
handleMouseOver(e: SyntheticEvent): void {
|
||||
console.log("onMouseOver")
|
||||
if (this.props.showHover ?? true) {
|
||||
if (this.hoverElementRef.current)
|
||||
{
|
||||
this.hoverElementRef.current.style.display = "block";
|
||||
} else {
|
||||
console.log("No hoverElementRef")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -96,9 +93,7 @@ export const SelectHoverBackground =
|
||||
if (this.hoverElementRef.current)
|
||||
{
|
||||
this.hoverElementRef.current.style.display = "none";
|
||||
} else {
|
||||
console.log("No hoverElementRef")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -27,7 +27,7 @@ import DialogActions from '@mui/material/DialogActions';
|
||||
import DialogContent from '@mui/material/DialogContent';
|
||||
import ResizeResponsiveComponent from './ResizeResponsiveComponent';
|
||||
import Typography from '@mui/material/Typography';
|
||||
import { PiPedalFileProperty } from './Lv2Plugin';
|
||||
import { UiFileProperty,UiFileType } from './Lv2Plugin';
|
||||
import SvgIcon from '@mui/material/SvgIcon';
|
||||
import ErrorIcon from '@mui/icons-material/Error';
|
||||
import ArrowBackIcon from '@mui/icons-material/ArrowBack';
|
||||
@@ -45,7 +45,7 @@ export interface UploadFileDialogProps {
|
||||
onClose: () => void,
|
||||
onUploaded: (fileName: string) => void,
|
||||
uploadPage: string,
|
||||
fileProperty: PiPedalFileProperty
|
||||
fileProperty: UiFileProperty
|
||||
|
||||
};
|
||||
|
||||
@@ -204,6 +204,10 @@ export default class UploadFileDialog extends ResizeResponsiveComponent<UploadFi
|
||||
this.updateUploadDisplayList();
|
||||
try {
|
||||
upload.abortController = new AbortController();
|
||||
if (!this.wantsFile(this.uploadList[i].file))
|
||||
{
|
||||
throw new Error("Invalid file type.");
|
||||
}
|
||||
let filename = await this.model.uploadFile(this.props.uploadPage, this.uploadList[i].file, "application/octet-stream", upload.abortController);
|
||||
this.props.onUploaded(filename);
|
||||
upload.status = FileUploadStatus.Uploaded;
|
||||
@@ -262,7 +266,12 @@ export default class UploadFileDialog extends ResizeResponsiveComponent<UploadFi
|
||||
e.currentTarget.style.background = "#D8D8D8";
|
||||
}
|
||||
|
||||
handleButtonSelect(e: React.ChangeEvent<HTMLInputElement>) {
|
||||
private static IsAndroid() : boolean
|
||||
{
|
||||
return /Android/i.test(navigator.userAgent);
|
||||
}
|
||||
|
||||
handleButtonSelect(e: any) {
|
||||
if (e.currentTarget.files) {
|
||||
this.uploadFiles(e.currentTarget.files);
|
||||
}
|
||||
@@ -290,20 +299,13 @@ export default class UploadFileDialog extends ResizeResponsiveComponent<UploadFi
|
||||
}
|
||||
}
|
||||
makeBrowserAcceptList() {
|
||||
let fileTypes = this.props.fileProperty.fileTypes;
|
||||
let result = "";
|
||||
for (let i = 0; i < fileTypes.length; ++i) {
|
||||
if (result.length !== 0) {
|
||||
result += ',';
|
||||
}
|
||||
result += fileTypes[i].fileExtension;
|
||||
}
|
||||
let result = UiFileType.MergeMimeTypes(this.props.fileProperty.fileTypes);
|
||||
return result;
|
||||
}
|
||||
|
||||
render() {
|
||||
|
||||
|
||||
let isAndroid = UploadFileDialog.IsAndroid();
|
||||
return (
|
||||
<DialogEx tag="UploadFileDialog" open={this.props.open} fullWidth onClose={() => this.handleClose()}
|
||||
fullScreen={this.state.fullScreen}
|
||||
@@ -321,7 +323,7 @@ export default class UploadFileDialog extends ResizeResponsiveComponent<UploadFi
|
||||
<DialogContent style={{ paddingBottom: 0 }}>
|
||||
<div style={{
|
||||
width: "100%", height: 140, marginBottom: 0,
|
||||
border: "2px dashed #CCC",
|
||||
border: (isAndroid? "2px solid #CCC" :"2px dashed #CCC"),
|
||||
borderRadius: "10px",
|
||||
fontFamily: "Roboto",
|
||||
padding: 0
|
||||
@@ -334,7 +336,8 @@ export default class UploadFileDialog extends ResizeResponsiveComponent<UploadFi
|
||||
}}
|
||||
>
|
||||
{!this.hasFileList() && (
|
||||
<Typography noWrap color="textSecondary" align="center" display="block" variant="caption" style={{ width: "100%", marginTop: 20, verticalAlign: "middle" }} >Drop files here</Typography>
|
||||
<Typography noWrap color="textSecondary" align="center" display="block" variant="caption" style={{ width: "100%", marginTop: 20, verticalAlign: "middle" }} >
|
||||
{ isAndroid? "Select files": "Drop files here" }</Typography>
|
||||
)}
|
||||
{this.hasFileList() && (
|
||||
<div style={{ width: "100%", height: "100%", overflow: "auto" }}>
|
||||
@@ -381,15 +384,15 @@ export default class UploadFileDialog extends ResizeResponsiveComponent<UploadFi
|
||||
|
||||
<DialogActions >
|
||||
<Button
|
||||
component="label" color="primary" style={{ marginLeft: 16, width: 120, flex: "0 0 auto" }}
|
||||
component="label" color="primary" style={{ whiteSpace: "nowrap", textOverflow: "ellipsis", marginLeft: 16, width: 120, flex: "0 0 auto" }}
|
||||
>
|
||||
Select Files
|
||||
Select Files
|
||||
<input
|
||||
type="file"
|
||||
hidden
|
||||
accept={this.makeBrowserAcceptList()}
|
||||
multiple
|
||||
onChange={(e) => this.handleButtonSelect(e)}
|
||||
onInput={(e) => this.handleButtonSelect(e)}
|
||||
/>
|
||||
</Button>
|
||||
<div style={{ flex: "1 1 20px" }} />
|
||||
|
||||
@@ -1,81 +0,0 @@
|
||||
src/SearchControl.tsx
|
||||
src/SplitControlView.tsx
|
||||
src/WifiConfigSettings.tsx
|
||||
src/FullScreenIME.tsx
|
||||
src/JackHostStatus.tsx
|
||||
src/SearchFilter.tsx
|
||||
src/MainPage.tsx
|
||||
src/PiPedalModel.tsx
|
||||
src/PluginPresetSelector.tsx
|
||||
src/Pedal.tsx
|
||||
src/ToobMLView.tsx
|
||||
src/SettingsDialog.tsx
|
||||
src/PiPedalSocket.tsx
|
||||
src/ToobFrequencyResponseView.tsx
|
||||
src/ControlViewFactory.tsx
|
||||
src/Utility.tsx
|
||||
src/ToobToneStackView.tsx
|
||||
src/SelectHoverBackground.tsx
|
||||
src/MidiBindingsDialog.tsx
|
||||
src/TemporaryDrawer.tsx
|
||||
src/GxTunerView.tsx
|
||||
src/ToobInputStageView.tsx
|
||||
src/DraggableGrid.tsx
|
||||
src/JackStatusView.tsx
|
||||
src/PluginControl.tsx
|
||||
src/XxxSnippet.tsx
|
||||
src/PluginPreset.tsx
|
||||
src/Jack.tsx
|
||||
src/AlsaDeviceInfo.tsx
|
||||
src/MidiBinding.tsx
|
||||
src/PiPedalError.tsx
|
||||
src/IControlViewFactory.tsx
|
||||
src/Lv2Plugin.tsx
|
||||
src/Pedalboard.tsx
|
||||
src/PedalboardView.tsx
|
||||
src/PresetDialog.tsx
|
||||
src/AppThemed.tsx
|
||||
src/ZoomedDial.tsx
|
||||
src/RenameDialog.tsx
|
||||
src/SplitUiControls.tsx
|
||||
src/GovernorSettings.tsx
|
||||
src/AboutDialog.tsx
|
||||
src/ToobSpectrumResponseView.tsx
|
||||
src/PluginControlView.tsx
|
||||
src/NoChangePassword.tsx
|
||||
src/ToobSpectrumAnalyzerView.tsx
|
||||
src/MidiBindingView.tsx
|
||||
src/GxTunerControl.tsx
|
||||
src/Banks.tsx
|
||||
src/PluginPresetsDialog.tsx
|
||||
src/BankDialog.tsx
|
||||
src/UploadPresetDialog.tsx
|
||||
src/ToobPowerStage2View.tsx
|
||||
src/index.tsx
|
||||
src/Units.tsx
|
||||
src/VuMeter.tsx
|
||||
src/App.test.tsx
|
||||
src/DialogEx.tsx
|
||||
src/StringBuilder.tsx
|
||||
src/SelectChannelsDialog.tsx
|
||||
src/Draggable.tsx
|
||||
src/ZoomedUiControl.tsx
|
||||
src/Rect.tsx
|
||||
src/PluginClass.tsx
|
||||
src/PluginIcon.tsx
|
||||
src/App.tsx
|
||||
src/ResizeResponsiveComponent.tsx
|
||||
src/SvgPathBuilder.tsx
|
||||
src/NumericInput.tsx
|
||||
src/JackServerSettings.tsx
|
||||
src/ListSelectDialog.tsx
|
||||
src/JackServerSettingsDialog.tsx
|
||||
src/ObservableProperty.tsx
|
||||
src/SelectMidiChannelsDialog.tsx
|
||||
src/WifiChannel.tsx
|
||||
src/LoadPluginDialog.tsx
|
||||
src/WifiConfigDialog.tsx
|
||||
src/PluginInfoDialog.tsx
|
||||
src/ToobWaveShapeView.tsx
|
||||
src/ToobCabSimView.tsx
|
||||
src/PresetSelector.tsx
|
||||
Reference in New Issue
Block a user