diff --git a/index.html b/index.html
index a5baf4e..c9d7869 100644
--- a/index.html
+++ b/index.html
@@ -208,7 +208,7 @@
3. Finetune stick calibration
${
l("It appears the latest joystick calibration has not been saved.")
}
${
- l("You should save your changes, or reboot the controller if you don't want to keep them.")
+ l("You should save your changes, or reboot the controller to revert back to the previous state.")
}
`, true);
}
@@ -1144,16 +1143,6 @@ window.ds5_finetune = () => ds5_finetune(
(success) => success && switchToRangeMode()
);
-window.apply_finetune_revert = async (finetuneData) => {
- if (!controller || !controller.isConnected()) {
- throw new Error('Controller not connected');
- }
- if (!Array.isArray(finetuneData) || finetuneData.length !== 12) {
- throw new Error('Invalid finetune data');
- }
- await controller.writeFinetuneData(finetuneData);
-};
-
window.openCalibrationHistoryModal = async () => {
let currentFinetuneData = null;
let controllerSerialNumber = null;
@@ -1161,7 +1150,6 @@ window.openCalibrationHistoryModal = async () => {
if (controller && typeof controller.getInMemoryModuleData === 'function') {
currentFinetuneData = await controller.getInMemoryModuleData('finetune');
}
- // Get serial number from device info
if (controller && typeof controller.getDeviceInfo === 'function') {
const info = await controller.getDeviceInfo();
const serialNumberItem = info?.infoItems?.find(item => item.key === l("Serial Number"));
@@ -1170,7 +1158,10 @@ window.openCalibrationHistoryModal = async () => {
} catch (error) {
console.warn('Could not retrieve current finetune data or serial number:', error);
}
- window.show_calibration_history_modal(currentFinetuneData, controllerSerialNumber);
+ await show_calibration_history_modal(controller, currentFinetuneData, controllerSerialNumber, (success, message) => {
+ if(!message) return;
+ success ? infoAlert(message) : errorAlert(message);
+ });
};
window.flash_all_changes = flash_all_changes;
diff --git a/js/modals/calibration-history-modal.js b/js/modals/calibration-history-modal.js
index 10d5ab2..745bed2 100644
--- a/js/modals/calibration-history-modal.js
+++ b/js/modals/calibration-history-modal.js
@@ -2,31 +2,46 @@
import { FinetuneHistory } from '../finetune-history.js';
import { formatLocalizedDate } from '../utils.js';
+import { l } from '../translations.js';
export class CalibrationHistoryModal {
- static modalElement = null;
- static bootstrapModal = null;
- static currentFinetuneData = null;
- static currentControllerSerialNumber = null;
+ constructor(controllerInstance = null, doneCallback = null) {
+ this.modalElement = null;
+ this.bootstrapModal = null;
+ this.currentFinetuneData = null;
+ this.currentControllerSerialNumber = null;
+ this.controller = controllerInstance;
+ this.doneCallback = doneCallback;
- static init() {
+ this._boundModalHidden = () => {
+ destroyCurrentInstance();
+ };
+
+ this._initEventListeners();
+ }
+
+ _initEventListeners() {
this.modalElement = document.getElementById('calibrationHistoryModal');
if (this.modalElement) {
this.bootstrapModal = new bootstrap.Modal(this.modalElement);
+ this.modalElement.addEventListener('hidden.bs.modal', this._boundModalHidden);
}
}
- static async show(currentFinetuneData = null, controllerSerialNumber = null) {
- if (!this.bootstrapModal) {
- this.init();
+ removeEventListeners() {
+ if (this.modalElement) {
+ this.modalElement.removeEventListener('hidden.bs.modal', this._boundModalHidden);
}
+ }
+
+ async open(currentFinetuneData = null, controllerSerialNumber = null) {
this.currentFinetuneData = currentFinetuneData;
this.currentControllerSerialNumber = controllerSerialNumber;
await this._populateHistory();
this.bootstrapModal.show();
}
- static hide() {
+ close() {
if (this.bootstrapModal) {
this.bootstrapModal.hide();
}
@@ -36,12 +51,12 @@ export class CalibrationHistoryModal {
* Populate the history list
* @private
*/
- static async _populateHistory() {
+ async _populateHistory() {
const history = FinetuneHistory.getAll(this.currentControllerSerialNumber);
const container = document.getElementById('historyListContainer');
if (!history || history.length === 0) {
- container.innerHTML = 'No saved calibration settings found.
';
+ container.innerHTML = `${l('No saved calibrations found')}.
`;
document.getElementById('clearAllBtn').style.display = 'none';
return;
}
@@ -59,13 +74,13 @@ export class CalibrationHistoryModal {
${date}
-
Values: ${entry.data.join(', ')}
+
${l('Values')}: ${entry.data.join(', ')}
${isCurrent ?
- `Current ` :
- `Revert
- Delete `
+ `${l('Current')} ` :
+ `${l('Restore')}
+ ${l('Delete')} `
}
@@ -81,7 +96,7 @@ export class CalibrationHistoryModal {
* Compare two data arrays for equality
* @private
*/
- static _dataEquals(data1, data2) {
+ _dataEquals(data1, data2) {
if (!Array.isArray(data1) || !Array.isArray(data2)) {
return false;
}
@@ -92,66 +107,45 @@ export class CalibrationHistoryModal {
}
/**
- * Escape HTML special characters
+ * Apply finetune calibration to the controller
+ * @param {Array} finetuneData - The finetune data to apply
* @private
*/
- static _escapeHtml(text) {
- const div = document.createElement('div');
- div.textContent = text;
- return div.innerHTML;
+ async _applyCalibration(finetuneData) {
+ if (!this.controller || !this.controller.isConnected()) {
+ throw new Error('Controller not connected');
+ }
+ if (!Array.isArray(finetuneData) || finetuneData.length !== 12) {
+ throw new Error('Invalid finetune data');
+ }
+ await this.controller.writeFinetuneData(finetuneData);
+ this.controller.setHasChangesToWrite(true);
}
/**
- * Revert to a saved calibration
+ * Restore a saved calibration
* @param {string} entryId - The ID of the entry to revert to
*/
- static revertTo(entryId) {
+ async restoreCalibration(entryId) {
const entry = FinetuneHistory.getById(entryId, this.currentControllerSerialNumber);
- if (!entry) {
- alert('Calibration settings not found.');
- return;
- }
+ if (!entry) throw new Error('Calibration settings not found.');
- // Export revert function to window for onclick handlers
- window.calibration_history_pending_revert_id = entryId;
- window.calibration_history_pending_revert_data = entry.data;
-
- // Show confirmation dialog
- const confirmMsg = `Revert to this version?\n\nThis will restore the stored finetune settings.`;
- if (confirm(confirmMsg)) {
- this._executeRevert(entryId, entry.data);
- }
- }
-
- /**
- * Execute the revert operation
- * @private
- */
- static _executeRevert(entryId, finetuneData) {
- // Call the revert function exposed in core.js
- if (typeof window.apply_finetune_revert === 'function') {
- window.apply_finetune_revert(finetuneData).then(() => {
- this.hide();
- alert('Calibration reverted successfully. Remember to save changes permanently.');
- }).catch(err => {
- alert('Failed to revert calibration: ' + err.message);
- });
- } else {
- alert('Controller not ready. Please try again.');
- }
+ await this._applyCalibration(entry.data);
+ this.close();
+ this.doneCallback(true, l('The calibration was restored successfully! Remember to save the changes in order not to loose them when the controller is rebooted.'));
}
/**
* Delete a saved entry
* @param {string} entryId - The ID of the entry to delete
*/
- static async delete(entryId) {
+ async delete(entryId) {
const entry = FinetuneHistory.getById(entryId, this.currentControllerSerialNumber);
if (!entry) {
return;
}
- if (confirm(`Delete this calibration entry?`)) {
+ if (confirm(l(`Delete this calibration entry?`))) {
FinetuneHistory.delete(entryId, this.currentControllerSerialNumber);
await this._populateHistory();
}
@@ -160,16 +154,46 @@ export class CalibrationHistoryModal {
/**
* Clear all saved entries
*/
- static async clearAll() {
- if (confirm('Delete all calibration history for this controller? This cannot be undone.')) {
+ async clearAll() {
+ if (confirm(l('Delete all calibration history for this controller? This cannot be undone.'))) {
FinetuneHistory.clearAll(this.currentControllerSerialNumber);
await this._populateHistory();
}
}
}
-// Export functions to window for onclick handlers
-window.calibration_history_revert = (entryId) => CalibrationHistoryModal.revertTo(entryId);
-window.calibration_history_delete = (entryId) => CalibrationHistoryModal.delete(entryId);
-window.calibration_history_clear_all = () => CalibrationHistoryModal.clearAll();
-window.show_calibration_history_modal = (currentFinetuneData = null, controllerSerialNumber = null) => CalibrationHistoryModal.show(currentFinetuneData, controllerSerialNumber);
\ No newline at end of file
+let currentCalibrationHistoryInstance = null;
+
+function destroyCurrentInstance() {
+ if (currentCalibrationHistoryInstance) {
+ currentCalibrationHistoryInstance.removeEventListeners();
+ currentCalibrationHistoryInstance = null;
+ }
+}
+
+export async function show_calibration_history_modal(controllerInstance = null, currentFinetuneData = null, controllerSerialNumber = null, doneCallback = null) {
+ destroyCurrentInstance();
+
+ currentCalibrationHistoryInstance = new CalibrationHistoryModal(controllerInstance, doneCallback);
+ await currentCalibrationHistoryInstance.open(currentFinetuneData, controllerSerialNumber);
+}
+
+window.calibration_history_restore = (entryId) => {
+ if (currentCalibrationHistoryInstance) {
+ currentCalibrationHistoryInstance.restoreCalibration(entryId);
+ }
+};
+
+window.calibration_history_delete = (entryId) => {
+ if (currentCalibrationHistoryInstance) {
+ currentCalibrationHistoryInstance.delete(entryId);
+ }
+};
+
+window.calibration_history_clear_all = () => {
+ if (currentCalibrationHistoryInstance) {
+ currentCalibrationHistoryInstance.clearAll();
+ }
+};
+
+window.show_calibration_history_modal = show_calibration_history_modal;
\ No newline at end of file