Skip to content

Commit

Permalink
refacto identifiers
Browse files Browse the repository at this point in the history
  • Loading branch information
jparez committed Jan 16, 2025
1 parent 093a9d3 commit 6bb04f7
Show file tree
Hide file tree
Showing 8 changed files with 142 additions and 146 deletions.
3 changes: 3 additions & 0 deletions src/assets/images/ic_generate.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
205 changes: 82 additions & 123 deletions src/plugins/Identifiers.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
'use strict';

const OverlayPlugin = require('./util/OverlayPlugin');
const {textInput, chipTag} = require('./util/components');

const HEX = '0123456789abcdef';
const DIGITS = '0123456789';
Expand Down Expand Up @@ -29,10 +30,6 @@ module.exports = class Identifiers extends OverlayPlugin {
// Register plugin
this.instance.identifiers = this;

// Initial state
this.invalidAndroidId = false;
this.invalidDeviceId = false;

// Render components
this.renderToolbarButton();
this.renderWidget();
Expand All @@ -46,11 +43,11 @@ module.exports = class Identifiers extends OverlayPlugin {

const deviceId = values[1].match(/(device_id:)(\w+)/);
if (deviceId) {
this.deviceInput.value = deviceId[2];
this.deviceInput.setValue(deviceId[2]);
}
const androidId = values[1].match(/(android_id:)(\w+)/);
if (androidId) {
this.androidInput.value = androidId[2];
this.androidInput.setValue(androidId[2]);
}
});
}
Expand Down Expand Up @@ -79,55 +76,80 @@ module.exports = class Identifiers extends OverlayPlugin {
*/
renderWidget() {
// Create elements
this.widget = document.createElement('div');
this.container = document.createElement('div');

// Generate title
const title = document.createElement('div');
title.className = 'gm-title';
title.innerHTML = this.i18n.IDENTIFIERS_TITLE || 'Identifiers';
this.container.appendChild(title);
const {modal, container} = this.createTemplateModal({
title: this.i18n.IDENTIFIERS_TITLE || 'Identifiers',
classes: 'gm-identifiers-plugin',
width: 378,
height: 422,
});
this.widget = modal;
this.container = container;

// Generate input rows
const inputs = document.createElement('div');
inputs.className = 'gm-inputs';

// Build field list
const android = this.generateInput(
'android',
'Android ID',
'',
this.generateRandomAndroidId.bind(this),
this.validateAndroidId.bind(this),
);
const device = this.generateInput(
'device',
'Device ID',
'(IMEI/MEID)',
this.generateRandomDeviceId.bind(this),
this.validateDeviceId.bind(this),
);
inputs.appendChild(android);
inputs.appendChild(device);
const androidInputDiv = document.createElement('div');
androidInputDiv.className = 'gm-identifier-android';
const labelAndroidId = document.createElement('label');
labelAndroidId.innerHTML = 'Android ID';
this.androidInput = textInput.createTextInput({
regexFilter: new RegExp(`^[${HEX}]{0,16}$`),
regexValidField: new RegExp(`^[${HEX}]{16}$`),
classes: 'gm-identifiers-android-input',
onChange: () => {
this.container.classList.remove('gm-identifiers-saved');
this.checkIDsValidity();
},
});
const generateAndroidIdBtn = document.createElement('div');
generateAndroidIdBtn.className = 'gm-icon-button gm-identifiers-android-generate';
generateAndroidIdBtn.onclick = this.generateRandomAndroidId.bind(this);
androidInputDiv.appendChild(this.androidInput.element);
androidInputDiv.appendChild(generateAndroidIdBtn);
inputs.appendChild(labelAndroidId);
inputs.appendChild(androidInputDiv);

const deviceInputDiv = document.createElement('div');
deviceInputDiv.className = 'gm-identifier-device';
const labelDeviceId = document.createElement('label');
labelDeviceId.innerHTML = 'Device ID (IMEI/MEID)';
this.deviceInput = textInput.createTextInput({
regexFilter: new RegExp(`^[${HEX}]{0,15}$`),
regexValidField: new RegExp(`^[${HEX}]{14,15}$`),
classes: 'gm-identifiers-device-input',
onChange: () => {
this.container.classList.remove('gm-identifiers-saved');
this.checkIDsValidity();
},
});
const generateDeviceIdBtn = document.createElement('div');
generateDeviceIdBtn.className = 'gm-icon-button gm-identifiers-device-generate';
generateDeviceIdBtn.onclick = this.generateRandomDeviceId.bind(this);
deviceInputDiv.appendChild(this.deviceInput.element);
deviceInputDiv.appendChild(generateDeviceIdBtn);
inputs.appendChild(labelDeviceId);
inputs.appendChild(deviceInputDiv);

const actionsDiv = document.createElement('div');
actionsDiv.className = 'gm-actions';
const separator = document.createElement('div');
separator.className = 'gm-separator';

const appliedTag = chipTag.createChip();
actionsDiv.appendChild(appliedTag.element);

this.submitBtn = document.createElement('button');
this.submitBtn.innerHTML = this.i18n.IDENTIFIERS_UPDATE || 'Update';
this.submitBtn.className = 'gm-action gm-identifiers-update';
inputs.appendChild(this.submitBtn);
this.submitBtn.innerHTML = this.i18n.IDENTIFIERS_APPLY || 'Apply';
this.submitBtn.className = 'gm-btn gm-identifiers-update';
actionsDiv.appendChild(this.submitBtn);
this.submitBtn.disabled = true;
this.submitBtn.onclick = this.sendDataToInstance.bind(this);

this.container.appendChild(inputs);

// Setup
this.widget.className = 'gm-overlay gm-identifiers-plugin gm-hidden';

// Add close button
const close = document.createElement('div');
close.className = 'gm-close-btn';
close.onclick = this.toggleWidget.bind(this);

this.widget.appendChild(close);
this.widget.appendChild(this.container);
this.container.appendChild(separator);
this.container.appendChild(actionsDiv);

// Render into document
this.instance.root.appendChild(this.widget);
Expand All @@ -141,25 +163,26 @@ module.exports = class Identifiers extends OverlayPlugin {
sendDataToInstance(event) {
event.preventDefault();

const androidId = this.androidInput.value;
const deviceId = this.deviceInput.value;
const androidId = this.androidInput.getValue();
const deviceId = this.deviceInput.getValue();

if (androidId && this.androidInput.checkValidity()) {
if (androidId) {
const json = {
channel: 'framework',
messages: ['set parameter android_id:' + androidId],
};
this.instance.sendEvent(json);
}

if (deviceId && this.deviceInput.checkValidity()) {
if (deviceId) {
const json = {
channel: 'settings',
messages: ['set parameter device_id:' + deviceId],
};
this.instance.sendEvent(json);
}
this.toggleWidget();

this.container.classList.add('gm-identifiers-saved');
}

/**
Expand All @@ -172,17 +195,8 @@ module.exports = class Identifiers extends OverlayPlugin {
event.preventDefault();
}

this.androidInput.value = this.generateHash(16, HEX);
this.invalidAndroidId = false;
this.checkErrors();
}

/**
* Validate Android ID input value.
*/
validateAndroidId() {
this.invalidAndroidId = !this.androidInput.checkValidity();
this.checkErrors();
this.androidInput.setValue(this.generateHash(16, HEX));
this.checkIDsValidity();
}

/**
Expand All @@ -195,74 +209,19 @@ module.exports = class Identifiers extends OverlayPlugin {
event.preventDefault();
}

this.deviceInput.value = this.generateHash(15, DIGITS);
this.invalidDeviceId = false;
this.checkErrors();
this.deviceInput.setValue(this.generateHash(15, DIGITS));
this.checkIDsValidity();
}

/**
* Validate Device ID input value.
* Check if the IDs are valid.
*/
validateDeviceId() {
this.invalidDeviceId = !this.deviceInput.checkValidity();
this.checkErrors();
}

/**
* Input form validation.
*/
checkErrors() {
this.androidInput.classList[this.invalidAndroidId ? 'add' : 'remove']('gm-error');
this.deviceInput.classList[this.invalidDeviceId ? 'add' : 'remove']('gm-error');

this.submitBtn.disabled = this.invalidAndroidId || this.invalidDeviceId;
}

/**
* Create a form field element.
*
* @param {string} type Input type.
* @param {string} label Input label.
* @param {string} description Input description.
* @param {string} generationMethod Input random value generation method.
* @param {string} validationMethod Input value validation method.
* @return {HTMLElement} The created input.
*/
generateInput(type, label, description, generationMethod, validationMethod) {
const field = document.createElement('div');
const inputWrap = document.createElement('div');
const input = document.createElement('input');
const button = document.createElement('button');

inputWrap.className = 'gm-input-group';
input.className = 'gm-identifier-' + type + '-input';
input.type = 'text';
input.required = true;
this.instance.addListener(input, 'keyup', validationMethod);
inputWrap.appendChild(input);

// Some customization
if (type === 'device') {
input.maxLength = 15;
input.pattern = '[' + HEX + ']{14,15}';
} else if (type === 'android') {
input.maxLength = 16;
input.pattern = '[' + HEX + ']{16}';
checkIDsValidity() {
if (this.androidInput.checkValidity() && this.deviceInput.checkValidity()) {
this.submitBtn.disabled = false;
} else {
this.submitBtn.disabled = true;
}

button.className = 'gm-identifier-' + type + '-generate';
button.innerHTML = this.i18n.IDENTIFIERS_GENERATE || 'Generate';
button.onclick = generationMethod;
inputWrap.appendChild(button);

field.className = 'gm-identifier-' + type;
field.innerHTML = '<label>' + label + '<i class="gm-description">' + description + '</i>' + '</label>';
field.appendChild(inputWrap);

this[type + 'Input'] = input;
this[type + 'Gen'] = button;

return field;
}

/**
Expand Down
12 changes: 11 additions & 1 deletion src/plugins/util/components.js
Original file line number Diff line number Diff line change
Expand Up @@ -181,7 +181,8 @@ const slider = (() => {
*/

const textInput = (() => {
const createTextInput = ({onChange = null, value = '', regexFilter, appendText = '', classes=''}) => {
const createTextInput = ({
onChange = null, value = '', regexFilter, regexValidField, appendText = '', classes=''}) => {
const inputDiv = document.createElement('div');
inputDiv.className = classes;
const inputDivContainer = document.createElement('div');
Expand Down Expand Up @@ -221,8 +222,16 @@ const textInput = (() => {
input.readOnly = readOnly;
};

const checkValidity = () => {
if (regexValidField && regexValidField.test(input.value)) {
return true;
}
return false;
};

input.addEventListener('input', (event) => {
const {value: v, selectionStart} = event.target;

if (regexFilter && !regexFilter.test(v)) {
// delete the last character if it doesn't match the regex
const correctedValue = v.slice(0, selectionStart - 1) + v.slice(selectionStart);
Expand All @@ -240,6 +249,7 @@ const textInput = (() => {
element: inputDiv,
setValue,
getValue,
checkValidity,
setReadOnly,
};
};
Expand Down
6 changes: 5 additions & 1 deletion src/scss/base/_genymotion.scss
Original file line number Diff line number Diff line change
Expand Up @@ -236,8 +236,12 @@
border-radius: 4px;

&:hover{
background: var(--gm-primary-color);
background: color-mix(in srgb, var(--gm-primary-color), transparent 85%);
color: var(--gm-primary-color)
}
&:disabled{
color: color-mix(in srgb, var(--gm-text-color), transparent 70%);
background: none;
cursor: default;
}
}
2 changes: 1 addition & 1 deletion src/scss/components/_chipTag.scss
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
.gm-tag{
&-success{
.gm-tag-container{
display: flex;
display: inline-flex;
align-items: center;
border-radius: 8px;
padding: 2px 6px;
Expand Down
Loading

0 comments on commit 6bb04f7

Please sign in to comment.