Handle permission denied errors.
This commit is contained in:
@@ -105,7 +105,6 @@ add_custom_command(
|
||||
public/var/current_pedalboard.json
|
||||
public/var/config.json
|
||||
public/favicon.ico
|
||||
public/index.html
|
||||
public/iso_codes.json
|
||||
public/logo512.png
|
||||
public/sample_lv2_plugins.json
|
||||
|
||||
+1
-1
@@ -3,7 +3,7 @@
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<link rel="icon" href="/favicon.ico" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0, interactive-widget=resizes-visual" />
|
||||
<meta name="theme-color" content="#000000" />
|
||||
<meta name="color-scheme" content="dark light"/> <!-- uses media queries in web views. -->
|
||||
<meta name="description" content="PiPedal Guitar Stomp Box for Raspberry Pi" />
|
||||
|
||||
@@ -1,136 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<link rel="icon" href="%PUBLIC_URL%/favicon.ico" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
<meta name="theme-color" content="#000000" />
|
||||
<meta name="color-scheme" content="dark light"/> <!-- uses media queries in web views. -->
|
||||
<meta name="description" content="PiPedal Guitar Pedals" />
|
||||
<!--
|
||||
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Roboto:300,400,500,700&display=swap" />
|
||||
-->
|
||||
<link rel="stylesheet" href="/css/roboto.css" />
|
||||
|
||||
<link rel="apple-touch-icon" href="%PUBLIC_URL%/logo192.png" />
|
||||
<!--
|
||||
manifest.json provides metadata used when your web app is installed on a
|
||||
user's mobile device or desktop. See https://developers.google.com/web/fundamentals/web-app-manifest/
|
||||
-->
|
||||
<link rel="manifest" href="%PUBLIC_URL%/manifest.json" />
|
||||
<!--
|
||||
Notice the use of %PUBLIC_URL% in the tags above.
|
||||
It will be replaced with the URL of the `public` folder during the build.
|
||||
Only files inside the `public` folder can be referenced from the HTML.
|
||||
|
||||
Unlike "/favicon.ico" or "favicon.ico", "%PUBLIC_URL%/favicon.ico" will
|
||||
work correctly both with client-side routing and a non-root public URL.
|
||||
Learn how to configure a non-root public URL by running `npm run build`.
|
||||
-->
|
||||
<title>PiPedal</title>
|
||||
<style>
|
||||
BODY {
|
||||
background: #D0D0D0;
|
||||
}
|
||||
</style>
|
||||
|
||||
<style id="bgStyle">
|
||||
BODY {
|
||||
background: #333; overscroll-behavior: "none"
|
||||
}
|
||||
</style>
|
||||
<script>
|
||||
const androidHosted = !!(window.AndroidHost);
|
||||
|
||||
var colorScheme = localStorage.getItem("colorScheme");
|
||||
if (androidHosted)
|
||||
{
|
||||
var hostColorScheme = window.AndroidHost.getThemePreference();
|
||||
switch (hostColorScheme)
|
||||
{
|
||||
case 0:
|
||||
colorScheme = "Light";
|
||||
break;
|
||||
case 1:
|
||||
colorScheme = "Dark";
|
||||
break;
|
||||
case 2:
|
||||
{
|
||||
// use the host's interpretation of the current system night mode.
|
||||
colorScheme = window.AndroidHost.isDarkTheme() ? "Dark": "Light";
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!colorScheme)
|
||||
{
|
||||
colorScheme = "Dark";
|
||||
}
|
||||
var darkMode = false;
|
||||
var useSystem = false;
|
||||
|
||||
var prefersDark = window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches;
|
||||
|
||||
switch (colorScheme) {
|
||||
case null:
|
||||
default:
|
||||
darkMode = false;
|
||||
break;
|
||||
|
||||
case "Light":
|
||||
darkMode = false;
|
||||
break;
|
||||
case "Dark":
|
||||
darkMode = true;
|
||||
break;
|
||||
case "System":
|
||||
useSystem = true;
|
||||
break;
|
||||
}
|
||||
if (useSystem) {
|
||||
darkMode = prefersDark;
|
||||
}
|
||||
|
||||
if (!darkMode) {
|
||||
let bgStyle = document.getElementById("bgStyle");
|
||||
if (bgStyle) {
|
||||
// disable the style block.
|
||||
bgStyle.setAttribute('media', "max-width: 1px");
|
||||
}
|
||||
}
|
||||
function removeHashOnLoad() {
|
||||
if (window.location.hash) {
|
||||
// Store the hash value (without the '#' symbol)
|
||||
var hash = window.location.hash.substring(1);
|
||||
|
||||
// Replace the current URL without the hash
|
||||
var newUrl = window.location.href.replace(window.location.hash, '');
|
||||
|
||||
// Use HTML5 history API to change the URL without reloading the page
|
||||
history.replaceState(null, document.title, newUrl);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
// Run the function when the window loads
|
||||
window.addEventListener('load', removeHashOnLoad);
|
||||
</script>
|
||||
</head>
|
||||
|
||||
<body style="overscroll-behavior: none; overflow: hidden">
|
||||
<noscript>You need to enable JavaScript to run this app.</noscript>
|
||||
<div id="root" style="height: 100%;position: absolute;left: px;right: 0px;top:0px;bottom: 0px"></div>
|
||||
<!--
|
||||
This HTML file is a template.
|
||||
If you open it directly in the browser, you will see an empty page.
|
||||
|
||||
You can add webfonts, meta tags, or analytics to this file.
|
||||
The build step will place the bundled scripts into the <body> tag.
|
||||
|
||||
To begin the development, run `npm start` or `yarn start`.
|
||||
To create a production bundle, use `npm run build` or `yarn build`.
|
||||
-->
|
||||
</body>
|
||||
|
||||
</html>
|
||||
@@ -26,6 +26,7 @@ import ButtonBase, { ButtonBaseProps } from "@mui/material/ButtonBase";
|
||||
|
||||
export interface DraggableButtonBaseProps extends ButtonBaseProps {
|
||||
onClick?: (e: React.MouseEvent<HTMLButtonElement>) => void;
|
||||
onDoubleClick?: (e: React.MouseEvent<HTMLButtonElement>) => void;
|
||||
onLongPressStart?: (currentTarget: HTMLButtonElement, e: React.PointerEvent<HTMLButtonElement> | React.MouseEvent<HTMLButtonElement>) => boolean;
|
||||
onLongPressMove?: (e: React.PointerEvent<HTMLButtonElement>) => void;
|
||||
onLongPressEnd?: (e: React.PointerEvent<HTMLButtonElement>| React.MouseEvent<HTMLButtonElement>) => void;
|
||||
@@ -59,7 +60,7 @@ function screenToClient(e: React.PointerEvent): Point {
|
||||
|
||||
export default function DraggableButtonBase(props: DraggableButtonBaseProps) {
|
||||
// Ensure that the props are spread correctly
|
||||
const { onClick, onLongPressStart, onLongPressMove:
|
||||
const { onClick, onDoubleClick, onLongPressStart, onLongPressMove:
|
||||
doLongPressMove,onLongPressEnd, longPressDelay,instantMouseLongPress, ...rest } = props;
|
||||
|
||||
let [hTimeout, setHTimeout] = React.useState<number | null>(null);
|
||||
@@ -68,6 +69,7 @@ export default function DraggableButtonBase(props: DraggableButtonBaseProps) {
|
||||
let [clickSuppressed, setClickSuppressed] = React.useState<boolean>(false);
|
||||
let [pointerDownPoint, setPointerDownPoint] = React.useState<Point>({ x: 0, y: 0 });
|
||||
let [ longPressedElement, setLongPressedElement ] = React.useState<HTMLButtonElement | null>(null);
|
||||
let [lastClick, setLastClick] = React.useState<number | null>(null);
|
||||
|
||||
|
||||
function handleSuppressClick(e: MouseEvent) {
|
||||
@@ -278,8 +280,26 @@ export default function DraggableButtonBase(props: DraggableButtonBaseProps) {
|
||||
if (onClick) {
|
||||
onClick(e);
|
||||
}
|
||||
// check to see whether this is a double-click
|
||||
let time = Date.now();
|
||||
if (lastClick && time-lastClick < 500) {
|
||||
if (onDoubleClick) {
|
||||
onDoubleClick(e);
|
||||
}
|
||||
setLastClick(null);
|
||||
} else {
|
||||
setLastClick(time);
|
||||
}
|
||||
}
|
||||
}}
|
||||
onDoubleClick={(e) => {
|
||||
// chrome doesnt' do double-click for touch events
|
||||
// so we need to re-implement it on the onclick handler.
|
||||
e.stopPropagation();
|
||||
e.preventDefault();
|
||||
return false;
|
||||
|
||||
}}
|
||||
onPointerCancelCapture={(e) => {
|
||||
if (pointerId !== null) {
|
||||
e.currentTarget.releasePointerCapture(e.pointerId);
|
||||
|
||||
@@ -31,7 +31,7 @@ import Typography from '@mui/material/Typography';
|
||||
import Input from '@mui/material/Input';
|
||||
import Select from '@mui/material/Select';
|
||||
import Switch from '@mui/material/Switch';
|
||||
import Utility, { nullCast } from './Utility';
|
||||
import Utility from './Utility';
|
||||
import MenuItem from '@mui/material/MenuItem';
|
||||
import { PiPedalModel, PiPedalModelFactory } from './PiPedalModel';
|
||||
import DialIcon from './svg/fx_dial.svg?react';
|
||||
@@ -231,12 +231,12 @@ const PluginControl =
|
||||
onInputFocus(event: SyntheticEvent): void {
|
||||
//this.displayValueRef.current!.style.display = "none";
|
||||
this.setState({ editFocused: true });
|
||||
if (Utility.hasIMEKeyboard()) {
|
||||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
this.inputRef.current?.blur();
|
||||
this.props.requestIMEEdit(nullCast(this.props.uiControl), this.props.value)
|
||||
}
|
||||
// if (Utility.hasIMEKeyboard()) {
|
||||
// event.preventDefault();
|
||||
// event.stopPropagation();
|
||||
// this.inputRef.current?.blur();
|
||||
// this.props.requestIMEEdit(nullCast(this.props.uiControl), this.props.value)
|
||||
// }
|
||||
}
|
||||
onInputKeyPress(e: any): void {
|
||||
if (e.charCode === 13 && this.inputChanged) {
|
||||
|
||||
@@ -713,24 +713,17 @@ export default function ToobPlayerControl(
|
||||
bottom: 0
|
||||
}}
|
||||
>
|
||||
{/**
|
||||
*
|
||||
sx={{
|
||||
'& .MuiTouchRipple-root': {
|
||||
},
|
||||
'& .MuiTouchRipple-ripple': {
|
||||
transform: 'scale(1.9) !important',
|
||||
}
|
||||
}}
|
||||
*/}
|
||||
<ButtonEx tooltip="Loop Settings" variant="dialogSecondary"
|
||||
style={{
|
||||
flex: "0 1 auto", maxWidth: 200,
|
||||
textTransform: "none", padding: "4px 8px"
|
||||
}}
|
||||
disabled={audioFile === ""}
|
||||
startIcon={(<RepeatIcon />)}
|
||||
onClick={() => {
|
||||
setShowLoopDialog(true);
|
||||
if (audioFile !== "") {
|
||||
setShowLoopDialog(true);
|
||||
}
|
||||
}}
|
||||
>
|
||||
<Typography noWrap variant="caption">
|
||||
|
||||
Reference in New Issue
Block a user