Skip to content

Commit

Permalink
small fixes for linking modes smaller now
Browse files Browse the repository at this point in the history
  • Loading branch information
Unreal-Dan committed Jan 29, 2025
1 parent ebcdefe commit e93f186
Show file tree
Hide file tree
Showing 2 changed files with 109 additions and 34 deletions.
86 changes: 74 additions & 12 deletions js/ModesPanel.js
Original file line number Diff line number Diff line change
Expand Up @@ -292,29 +292,78 @@ export default class ModesPanel extends Panel {
Notification.failure("Must select a mode to share");
return;
}

const modeJson = this.lightshow.vortex.printModeJson(false);
const modeData = JSON.parse(modeJson);
const pat = modeData.single_pats[0] ? modeData.single_pats[0] : modeData.multi_pat;
const base64EncodedData = btoa(JSON.stringify(pat));
const lightshowUrl = `https://lightshow.lol/importMode?data=${base64EncodedData}`;
this.shareModal.show({
defaultValue: lightshowUrl,
placeholder: 'Link URL',
title: 'Link Mode',
});

// Compress with Pako (Gzip)
const compressed = pako.deflate(modeJson, { level: 9 });

// Convert to Base64 (URL-safe)
let compressedBase64 = btoa(String.fromCharCode(...compressed))
.replace(/\+/g, '-')
.replace(/\//g, '_')
.replace(/=+$/, ''); // Remove padding

// Generate the link
const lightshowUrl = `https://lightshow.lol/importMode?data=${compressedBase64}`;

// Show the modal
this.shareModal.show({
defaultValue: lightshowUrl,
placeholder: 'Link URL',
title: 'Link Mode',
});

this.shareModal.selectAndCopyText();
Notification.success("Copied mode URL to clipboard");
}

importModeFromLink(data) {
try {
if (!data) {
Notification.failure("No mode data provided in the link.");
return;
}

// Decode Base64 URL-safe format
data = data.replace(/-/g, '+').replace(/_/g, '/');
while (data.length % 4 !== 0) {
data += '=';
}

// Decode Base64
const binaryString = atob(data);
const byteArray = new Uint8Array(binaryString.length);
for (let i = 0; i < binaryString.length; i++) {
byteArray[i] = binaryString.charCodeAt(i);
}

// Decompress using Pako
const decompressedJson = pako.inflate(byteArray, { to: 'string' });

// Parse and import mode
this.importModeFromData(JSON.parse(decompressedJson));

Notification.success("Successfully imported mode from link");
} catch (error) {
Notification.failure("Failed to import mode from link.");
console.error("Error decoding and importing mode:", error);
}
}

exportMode() {
if (!this.lightshow.vortex.engine().modes().curMode()) {
Notification.failure("Must select a mode to export");
return;
}
const modeJson = this.lightshow.vortex.printModeJson(false);
// Compress with pako (Gzip)
const compressed = pako.deflate(modeJson, { level: 9 });
// Convert to Base64 (for clipboard/export safety)
const compressedBase64 = btoa(String.fromCharCode(...compressed));
this.exportModal.show({
buttons: [],
defaultValue: modeJson,
defaultValue: compressedBase64,
title: 'Export/Copy a Mode',
});
this.exportModal.selectAndCopyText();
Expand All @@ -323,12 +372,25 @@ export default class ModesPanel extends Panel {

importMode() {
this.importModal.show({
placeholder: 'Paste a JSON mode',
placeholder: 'Paste a compressed JSON mode',
title: 'Import/Paste a Mode',
onInput: (event) => {
this.importModeFromData(JSON.parse(event.target.value));
try {
const data = event.target.value;
const binaryString = atob(data);
const byteArray = new Uint8Array(binaryString.length);
for (let i = 0; i < binaryString.length; i++) {
byteArray[i] = binaryString.charCodeAt(i);
}
const decompressedJson = pako.inflate(byteArray, { to: 'string' });
this.importModeFromData(JSON.parse(decompressedJson));
} catch (error) {
Notification.failure("Invalid compressed mode data");
console.error("Failed to decompress/import mode:", error);
}
}
});

this.importModal.selectText();
}

Expand Down
57 changes: 35 additions & 22 deletions js/VortexEditor.js
Original file line number Diff line number Diff line change
Expand Up @@ -175,22 +175,39 @@ export default class VortexEditor {
return;
}
const { type, data } = event.data;
const parsedData = JSON.parse(atob(data));
if (type === 'mode') {
try {
this.modesPanel.importModeFromData(parsedData, true);
console.log('Mode loaded successfully via postMessage');
} catch (error) {
console.error('Error loading mode via postMessage:', error);
try {
// Decode Base64
const binaryString = atob(data);
const byteArray = new Uint8Array(binaryString.length);

for (let i = 0; i < binaryString.length; i++) {
byteArray[i] = binaryString.charCodeAt(i);
}
}
if (type === 'pattern') {
try {
this.modesPanel.importPatternFromData(parsedData, true);
console.log('Mode loaded successfully via postMessage');
} catch (error) {
console.error('Error loading pattern via postMessage:', error);

// Decompress using Pako
const decompressedJson = pako.inflate(byteArray, { to: 'string' });

// Parse JSON
const parsedData = JSON.parse(decompressedJson);
if (type === 'mode') {
try {
this.modesPanel.importModeFromData(parsedData, true);
console.log('Mode loaded successfully via postMessage');
} catch (error) {
console.error('Error loading mode via postMessage:', error);
}
}
if (type === 'pattern') {
try {
this.modesPanel.importPatternFromData(parsedData, true);
console.log('Mode loaded successfully via postMessage');
} catch (error) {
console.error('Error loading pattern via postMessage:', error);
}
}

} catch (error) {
console.error('Error decoding or decompressing mode data:', error);
}
});

Expand Down Expand Up @@ -279,6 +296,7 @@ export default class VortexEditor {
this.loadStylesheet("fontsAwesomeStyles", "https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.6.0/css/all.min.css");
await this.loadScript("pako", "https://cdn.jsdelivr.net/npm/[email protected]/dist/pako.min.js");
await this.loadScript("jszip", "https://cdnjs.cloudflare.com/ajax/libs/jszip/3.10.1/jszip.min.js");
await this.loadScript("lzstring", "https://cdnjs.cloudflare.com/ajax/libs/lz-string/1.4.4/lz-string.min.js");

// Dynamically load ESPTool
window.esptoolPackage = await import("https://cdn.jsdelivr.net/gh/adafruit/Adafruit_WebSerial_ESPTool@latest/dist/web/index.js");
Expand Down Expand Up @@ -324,9 +342,8 @@ export default class VortexEditor {

// update the stylesheet
const currentStylesheet = document.getElementById('mainStyles');
if (currentStylesheet) {
const styleSheet = this.isMobile ? 'css/mobile-styles.css' : 'css/styles.css';
currentStylesheet.href = styleSheet + "?v=__CACHE_BUSTER__";
if (this.isMobile && currentStylesheet) {
currentStylesheet.href = "css/mobile-styles.css?v=__CACHE_BUSTER__";
}

// Update layout for all panels
Expand Down Expand Up @@ -371,11 +388,7 @@ export default class VortexEditor {
const encodedData = urlParams.get('data');

if (encodedData) {
try {
this.modesPanel.importPatternFromData(JSON.parse(atob(encodedData)), false);
} catch (error) {
console.error('Error parsing mode data:', error);
}
this.modesPanel.importModeFromLink(encodedData);
}
}

Expand Down

0 comments on commit e93f186

Please sign in to comment.