Skip to content

Commit

Permalink
Supports hash and loading of config
Browse files Browse the repository at this point in the history
Signed-off-by: Daniel Kastl <[email protected]>
  • Loading branch information
dkastl committed Oct 3, 2024
1 parent 80b71a9 commit d810261
Show file tree
Hide file tree
Showing 3 changed files with 85 additions and 6 deletions.
21 changes: 21 additions & 0 deletions src/formHandler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,3 +44,24 @@ export function getFormValues() {
ignoreMqtt,
};
}

/**
* Populate the form with values from the configuration.
* @param formValues - The object containing values to populate the form.
*/
export function populateForm(formValues: any) {
const form = document.getElementById('meshtasticForm') as HTMLFormElement | null;
if (!form) throw new Error('Form element not found.');

(form.elements.namedItem('channelName') as HTMLInputElement).value = formValues.channelName || '';
(form.elements.namedItem('psk') as HTMLInputElement).value = formValues.psk || '';
(form.elements.namedItem('uplinkEnabled') as HTMLInputElement).checked = formValues.uplinkEnabled || false;
(form.elements.namedItem('downlinkEnabled') as HTMLInputElement).checked = formValues.downlinkEnabled || false;
(form.elements.namedItem('positionPrecision') as HTMLInputElement).value = String(formValues.positionPrecision || 0);
(form.elements.namedItem('isClientMuted') as HTMLInputElement).checked = formValues.isClientMuted || false;
(form.elements.namedItem('region') as HTMLSelectElement).value = String(formValues.region || 0);
(form.elements.namedItem('modemPreset') as HTMLSelectElement).value = String(formValues.modemPreset || 0);
(form.elements.namedItem('hopLimit') as HTMLInputElement).value = String(formValues.hopLimit || 3);
(form.elements.namedItem('ignoreMqtt') as HTMLInputElement).checked = formValues.ignoreMqtt || false;
(form.elements.namedItem('configOkToMqtt') as HTMLInputElement).checked = formValues.configOkToMqtt || false;
}
52 changes: 47 additions & 5 deletions src/main.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,24 @@
import { getFormValues } from './formHandler';
import { getFormValues, populateForm } from './formHandler';
import { generatePSK } from './pskGenerator';
import { buildProtobuf } from './protobufBuilder';
import { generateQRCode } from './qrCodeGenerator';
import { getByteLength, toUrlSafeBase64 } from './utils';
import { getByteLength, toUrlSafeBase64, fromUrlSafeBase64 } from './utils';
import { Protobuf } from "@meshtastic/js";

/**
* Handle the DOMContentLoaded event.
* Add event listeners to the buttons and form fields.
*/
document.addEventListener('DOMContentLoaded', () => {
// Check if there is a configuration in the URL hash and load it
const urlHash = window.location.hash.substring(1); // Remove the "#" character
if (urlHash) {
loadConfigurationFromHash(urlHash);
}

// Generate QR code for the default form values
generateConfig();

// Listen for changes on all form inputs and selects
document.querySelectorAll('#meshtasticForm input, #meshtasticForm select').forEach(element => {
element.addEventListener('input', generateConfig);
Expand All @@ -22,11 +32,40 @@ document.addEventListener('DOMContentLoaded', () => {

// Add click listener for copying the URL
document.getElementById('copyUrlButton')?.addEventListener('click', copyUrlToClipboard);

// Generate QR Code on first page load
generateConfig();
});

/**
* Load the configuration from the hash and populate the form.
* @param {string} hash - The URL-safe Base64 configuration string.
*/
function loadConfigurationFromHash(hash: string): void {
try {
const binaryData = fromUrlSafeBase64(hash);
const channelSet = Protobuf.AppOnly.ChannelSet.fromBinary(binaryData);

// Extract the channel settings from the Protobuf message
const channelSettings = channelSet.settings[0];
const formValues = {
channelName: channelSettings.name,
psk: new TextDecoder().decode(channelSettings.psk),
uplinkEnabled: channelSettings.uplinkEnabled,
downlinkEnabled: channelSettings.downlinkEnabled,
positionPrecision: channelSettings.moduleSettings?.positionPrecision || 0,
isClientMuted: channelSettings.moduleSettings?.isClientMuted || false,
region: channelSet.loraConfig.region,
modemPreset: channelSet.loraConfig.modemPreset,
hopLimit: channelSet.loraConfig.hopLimit,
ignoreMqtt: channelSet.loraConfig.ignoreMqtt,
configOkToMqtt: channelSet.loraConfig.configOkToMqtt,
};

// Populate the form with these values using formHandler
populateForm(formValues);
} catch (error) {
console.error("Error loading configuration from URL hash:", error);
}
}

/**
* Handle the change event on the PSK type select element.
* Enable or disable the PSK input field based on the selected PSK type.
Expand Down Expand Up @@ -80,6 +119,9 @@ async function generateConfig(): Promise<void> {
// Convert to URL-safe Base64 string
const base64 = toUrlSafeBase64(binaryData);

// Update the URL hash with the generated configuration
window.location.hash = `#${base64}`;

// Create the Meshtastic URL
const meshtasticUrl = `https://meshtastic.org/e/#${base64}`;
console.log("Generated Meshtastic URL:", meshtasticUrl);
Expand Down
18 changes: 17 additions & 1 deletion src/utils.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { fromByteArray } from "base64-js";
import { fromByteArray, toByteArray } from "base64-js";

/**
* Utility function to calculate the byte length of a string.
Expand All @@ -21,3 +21,19 @@ export function toUrlSafeBase64(binaryData: Uint8Array): string {
.replace(/\+/g, "-")
.replace(/\//g, "_");
}

/**
* Convert a URL-safe Base64 string back to binary data.
* @param base64String - The URL-safe Base64 string to decode.
* @returns {Uint8Array} - The decoded binary data.
*/
export function fromUrlSafeBase64(base64String: string): Uint8Array {
// Replace URL-safe characters with standard Base64 characters
const paddedBase64 = base64String
.replace(/-/g, "+")
.replace(/_/g, "/")
// Re-add padding if necessary (Base64 strings must be divisible by 4)
.padEnd(base64String.length + (4 - (base64String.length % 4)) % 4, "=");

return toByteArray(paddedBase64);
}

0 comments on commit d810261

Please sign in to comment.