mirror of
https://github.com/dualshock-tools/dualshock-tools.github.io.git
synced 2026-03-01 11:19:54 +03:00
Add copy button for firmware information
This commit is contained in:
@@ -178,7 +178,7 @@ class DS4Controller extends BaseController {
|
||||
|
||||
if(!is_clone) {
|
||||
// Add Board Model (UI will append the info icon)
|
||||
infoItems.push({ key: l("Board Model"), value: this.hwToBoardModel(hw_ver_minor), cat: "hw", addInfoIcon: 'board' });
|
||||
infoItems.push({ key: l("Board Model"), value: this.hwToBoardModel(hw_ver_minor), cat: "hw", addInfoIcon: 'board', copyable: true });
|
||||
|
||||
const bd_addr = await this.getBdAddr();
|
||||
infoItems.push({ key: l("Bluetooth Address"), value: bd_addr, cat: "hw" });
|
||||
|
||||
@@ -298,16 +298,16 @@ class DS5Controller extends BaseController {
|
||||
const serial_number = await this.getSystemInfo(1, 19, 17);
|
||||
const color = ds5_color(serial_number);
|
||||
const infoItems = [
|
||||
{ key: l("Serial Number"), value: serial_number, cat: "hw" },
|
||||
{ key: l("MCU Unique ID"), value: await this.getSystemInfo(1, 9, 9, false), cat: "hw", isExtra: true },
|
||||
{ key: l("Serial Number"), value: serial_number, cat: "hw", copyable: true },
|
||||
{ key: l("MCU Unique ID"), value: await this.getSystemInfo(1, 9, 9, false), cat: "hw", isExtra: true, copyable: true },
|
||||
{ key: l("PCBA ID"), value: reverse_str(await this.getSystemInfo(1, 17, 14)), cat: "hw", isExtra: true },
|
||||
{ key: l("Battery Barcode"), value: await this.getSystemInfo(1, 24, 23), cat: "hw", isExtra: true },
|
||||
{ key: l("VCM Left Barcode"), value: await this.getSystemInfo(1, 26, 16), cat: "hw", isExtra: true },
|
||||
{ key: l("VCM Right Barcode"), value: await this.getSystemInfo(1, 28, 16), cat: "hw", isExtra: true },
|
||||
{ key: l("Battery Barcode"), value: await this.getSystemInfo(1, 24, 23), cat: "hw", isExtra: true, copyable: true },
|
||||
{ key: l("VCM Left Barcode"), value: await this.getSystemInfo(1, 26, 16), cat: "hw", isExtra: true, copyable: true },
|
||||
{ key: l("VCM Right Barcode"), value: await this.getSystemInfo(1, 28, 16), cat: "hw", isExtra: true, copyable: true },
|
||||
|
||||
{ key: l("Color"), value: l(color), cat: "hw", addInfoIcon: 'color' },
|
||||
{ key: l("Color"), value: l(color), cat: "hw", addInfoIcon: 'color', copyable: true },
|
||||
|
||||
...(is_edge ? [] : [{ key: l("Board Model"), value: this.hwToBoardModel(hwinfo), cat: "hw", addInfoIcon: 'board' }]),
|
||||
...(is_edge ? [] : [{ key: l("Board Model"), value: this.hwToBoardModel(hwinfo), cat: "hw", addInfoIcon: 'board', copyable: true }]),
|
||||
|
||||
{ key: l("FW Build Date"), value: build_date + " " + build_time, cat: "fw" },
|
||||
{ key: l("FW Type"), value: "0x" + dec2hex(fwtype), cat: "fw", isExtra: true },
|
||||
@@ -320,7 +320,7 @@ class DS5Controller extends BaseController {
|
||||
{ key: l("Venom FW Version"), value: "0x" + dec2hex32(fwversion2), cat: "fw", isExtra: true },
|
||||
{ key: l("Spider FW Version"), value: "0x" + dec2hex32(fwversion3), cat: "fw", isExtra: true },
|
||||
|
||||
{ key: l("Touchpad ID"), value: await this.getSystemInfo(5, 2, 8, false), cat: "hw", isExtra: true },
|
||||
{ key: l("Touchpad ID"), value: await this.getSystemInfo(5, 2, 8, false), cat: "hw", isExtra: true, copyable: true },
|
||||
{ key: l("Touchpad FW Version"), value: await this.getSystemInfo(5, 4, 8, false), cat: "fw", isExtra: true },
|
||||
];
|
||||
|
||||
|
||||
65
js/core.js
65
js/core.js
@@ -885,20 +885,11 @@ function render_info_to_dom(infoItems) {
|
||||
if (!Array.isArray(infoItems)) return;
|
||||
|
||||
// Add new info items
|
||||
infoItems.forEach(({key, value, addInfoIcon, severity, isExtra, cat}) => {
|
||||
infoItems.forEach(({key, value, addInfoIcon, severity, isExtra, cat, copyable}) => {
|
||||
if (!key) return;
|
||||
|
||||
// Compose value with optional info icon
|
||||
let valueHtml = String(value ?? "");
|
||||
if (addInfoIcon === 'board') {
|
||||
const icon = ' <a class="link-body-emphasis" href="#" onclick="board_model_info()">' +
|
||||
'<svg class="bi" width="1.3em" height="1.3em"><use xlink:href="#info"/></svg></a>';
|
||||
valueHtml += icon;
|
||||
} else if (addInfoIcon === 'color') {
|
||||
const icon = ' <a class="link-body-emphasis" href="#" onclick="edge_color_info()">' +
|
||||
'<svg class="bi" width="1.3em" height="1.3em"><use xlink:href="#info"/></svg></a>';
|
||||
valueHtml += icon;
|
||||
}
|
||||
|
||||
// Apply severity formatting if requested
|
||||
if (severity) {
|
||||
@@ -908,25 +899,43 @@ function render_info_to_dom(infoItems) {
|
||||
}
|
||||
|
||||
if (isExtra) {
|
||||
append_info_extra(key, valueHtml, cat || "hw");
|
||||
appendInfoExtra(key, valueHtml, cat || "hw", copyable ?? false);
|
||||
} else {
|
||||
append_info(key, valueHtml, cat || "hw");
|
||||
appendInfo(key, valueHtml, cat || "hw", copyable ?? false);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function append_info_extra(key, value, cat) {
|
||||
function copyValueToClipboard(text) {
|
||||
navigator.clipboard.writeText(text).then(function() {
|
||||
infoAlert(l("The item has been copied to the clipboard."), 2000);
|
||||
}).catch(function(err) {
|
||||
errorAlert(l("Cannot copy text to the clipboard:") + " " + str(err));
|
||||
});
|
||||
}
|
||||
|
||||
function genCopyString(value, copyable) {
|
||||
if(!copyable)
|
||||
return '';
|
||||
|
||||
const cleanStringRegex = value.match(/^[A-Za-z0-9_.-]+/);
|
||||
const escapedValue = cleanStringRegex ? cleanStringRegex[0] : "";
|
||||
|
||||
return ' <i style="cursor:pointer;" class="fa-regular fa-copy" onclick=\'copyValueToClipboard("' + escapedValue + '")\'></i>';
|
||||
}
|
||||
|
||||
function appendInfoExtra(key, value, cat, copyable) {
|
||||
// TODO escape html
|
||||
const s = '<dt class="text-muted col-sm-4 col-md-6 col-xl-5">' + key + '</dt><dd class="col-sm-8 col-md-6 col-xl-7" style="text-align: right;">' + value + '</dd>';
|
||||
const s = '<dt class="text-muted col-sm-4 col-md-6 col-xl-5">' + key + '</dt><dd class="col-sm-8 col-md-6 col-xl-7" style="text-align: right;">' + value + genCopyString(value, copyable) + '</dd>';
|
||||
$("#fwinfoextra-" + cat).html($("#fwinfoextra-" + cat).html() + s);
|
||||
}
|
||||
|
||||
|
||||
function append_info(key, value, cat) {
|
||||
function appendInfo(key, value, cat, copyable) {
|
||||
// TODO escape html
|
||||
const s = '<dt class="text-muted col-6">' + key + '</dt><dd class="col-6" style="text-align: right;">' + value + '</dd>';
|
||||
const s = '<dt class="text-muted col-6">' + key + '</dt><dd class="col-6" style="text-align: right;">' + value + genCopyString(value, copyable) + '</dd>';
|
||||
$("#fwinfo").html($("#fwinfo").html() + s);
|
||||
append_info_extra(key, value, cat);
|
||||
appendInfoExtra(key, value, cat, copyable);
|
||||
}
|
||||
|
||||
function show_popup(text, is_html = false) {
|
||||
@@ -964,25 +973,6 @@ function show_info_tab() {
|
||||
$('#info-tab').tab('show');
|
||||
}
|
||||
|
||||
function discord_popup() {
|
||||
la("discord_popup");
|
||||
show_popup(l("My handle on discord is: the_al"));
|
||||
}
|
||||
|
||||
function edge_color_info() {
|
||||
la("cm_info");
|
||||
const text = l("Color detection thanks to") + ' romek77 from Poland.';
|
||||
show_popup(text, true);
|
||||
}
|
||||
|
||||
function board_model_info() {
|
||||
la("bm_info");
|
||||
const l1 = l("This feature is experimental.");
|
||||
const l2 = l("Please let me know if the board model of your controller is not detected correctly.");
|
||||
const l3 = l("Board model detection thanks to") + ' <a href="https://battlebeavercustoms.com/">Battle Beaver Customs</a>.';
|
||||
show_popup(l3 + "<br><br>" + l1 + " " + l2, true);
|
||||
}
|
||||
|
||||
// Alert Management Functions
|
||||
let alertCounter = 0;
|
||||
|
||||
@@ -1068,6 +1058,7 @@ window.connect = connect;
|
||||
window.disconnect = disconnectSync;
|
||||
window.show_faq_modal = show_faq_modal;
|
||||
window.show_info_tab = show_info_tab;
|
||||
window.copyValueToClipboard = copyValueToClipboard;
|
||||
window.calibrate_range = () => calibrate_range(
|
||||
controller,
|
||||
{ ll_data, rr_data },
|
||||
@@ -1112,8 +1103,6 @@ window.nvsunlock = nvsunlock;
|
||||
window.nvslock = nvslock;
|
||||
window.welcome_accepted = welcome_accepted;
|
||||
window.show_donate_modal = show_donate_modal;
|
||||
window.board_model_info = board_model_info;
|
||||
window.edge_color_info = edge_color_info;
|
||||
window.show_quick_test_modal = () => {
|
||||
show_quick_test_modal(controller).catch(error => {
|
||||
throw new Error("Failed to show quick test modal", { cause: error });
|
||||
|
||||
Reference in New Issue
Block a user