Prep for T3k Flow of user and tone URLS.

This commit is contained in:
Robin E.R. Davies
2026-05-29 00:19:11 -04:00
parent 100b5bed05
commit 7c8f18d83b
3 changed files with 133 additions and 2 deletions
+25
View File
@@ -1129,6 +1129,28 @@ export default withStyles(
}
handleT3kLinkClick(href: string): boolean {
if (!href.startsWith("https://tone3000.com/")) {
return false;
}
return false;
// STUB: Waiting for a way to do a popup flow starting with a tone or user home page.
// let uri = new URL(href);
// if (uri.pathname.split("/").filter(segment => segment.length > 0).length === 1) {
// // It's a username. Launch a select flow with username as a filter.
// let username = uri.pathname.split("/").filter(segment => segment.length > 0)[0];
// this.model.showTone3000DownloadPopup(
// Tone3000DownloadType.Nam,
// this.state.currentDirectory,
// {
// username: username
// }
// );
// }
return true;
}
render() {
const isTracksDirectory = this.isTracksDirectory();
const isToobNamModelFile = this.props.fileProperty.patchProperty === ToobNamModelFileUrl;
@@ -1803,6 +1825,9 @@ export default withStyles(
<TextInfoDialog open={true}
title={pathFileNameOnly(this.state.textFileName)}
fileName={this.state.textFileName} onClose={() => this.setState({ textFileName: undefined })}
onT3kLinkClick={(href) => {
return this.handleT3kLinkClick(href); }
}
/>
)}
</DialogEx>
+6 -2
View File
@@ -773,7 +773,10 @@ export class PiPedalModel //implements PiPedalModel
showTone3000DownloadPopup(
downloadType: Tone3000DownloadType,
downloadPath: string
downloadPath: string,
options?: {
userName?: string;
}
): void {
if (this.tone3000DownloadHandler === null) {
this.tone3000DownloadHandler = new Tone3000DownloadHandler(this);
@@ -781,7 +784,7 @@ export class PiPedalModel //implements PiPedalModel
this.tone3000DownloadHandler.launchTone3000Popup(
downloadType,
downloadPath,
);
options);
};
@@ -1375,6 +1378,7 @@ export class PiPedalModel //implements PiPedalModel
}
this.debug = !!data.debug;
let { socket_server_port, socket_server_address, max_upload_size } = data;
if ((!socket_server_address) || socket_server_address === "*") {
socket_server_address = window.location.hostname;
}
+102
View File
@@ -0,0 +1,102 @@
/*
* Copyright (c) 2026 Robin E. R. Davies
* All rights reserved.
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER 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 type { Root } from 'hast';
// Rewrite <a> tags with "t3klink?id=xxx" hrefs to call the T3kLinkHandler handler instead of navigating to a new page.
// // Hook in the rewriter as follows:
// <ReactMarkdown urlTransform={urlTransform} rehypePlugins={
// [
// [remarkGfm],
// [rehypeRaw],
// [rehypeSanitize, extendedSchema],
// [rehypeExternalLinks, {target: '_blank'}]
// [rewriteT3kUrls, {...options}]
// ]}>
// {this.state.textFileContent}
// </ReactMarkdown>
type HastNode = {
type: string;
tagName?: string;
properties?: Record<string, unknown>;
children?: HastNode[];
};
export type T3kLinkClickHandler = (href: string) => boolean;
export interface RewriteT3kUrlsOptions {
prefixUrl?: string;
onT3kLinkClick?: T3kLinkClickHandler;
}
// Default callback. Supply `onT3kLinkClick` in options to handle links.
export function T3kLinkHandler(href: string): boolean {
void href;
return false;
}
function getHref(properties: Record<string, unknown>): string | null {
const href = properties.href;
return typeof href === 'string' ? href : null;
}
function rewriteNode(node: HastNode, prefixUrl: string, onT3kLinkClick: T3kLinkClickHandler): void {
if (node.type === 'element' && node.tagName === 'a') {
const properties = node.properties ?? {};
const href = getHref(properties);
if (href && href.startsWith(prefixUrl)) {
properties.target = '_blank';
properties.rel = 'noopener noreferrer';
properties.onClick = (event: { preventDefault?: () => void; stopPropagation?: () => void; }) => {
const handled = onT3kLinkClick(href);
if (handled) {
event.preventDefault?.();
event.stopPropagation?.();
}
};
node.properties = properties;
}
}
if (node.children) {
for (const child of node.children) {
rewriteNode(child, prefixUrl, onT3kLinkClick);
}
}
}
export function rewriteT3kUrls(options?: RewriteT3kUrlsOptions) {
const prefixUrl = options?.prefixUrl;
const onT3kLinkClick = options?.onT3kLinkClick ?? ((href: string) => T3kLinkHandler(href));
return (tree: Root) => {
if (!prefixUrl) {
return;
}
rewriteNode(tree as unknown as HastNode, prefixUrl, onT3kLinkClick);
};
}