Skip to content

Commit

Permalink
Refactor file paths for JavaScript resources and update QRCode featur…
Browse files Browse the repository at this point in the history
…e implementation
  • Loading branch information
TMHSDigital committed Dec 26, 2024
1 parent 2e19db1 commit c2ebeb1
Showing 1 changed file with 113 additions and 25 deletions.
138 changes: 113 additions & 25 deletions js/features/qr-code.js
Original file line number Diff line number Diff line change
@@ -1,32 +1,27 @@
class QRCode extends BaseTool {
import { BaseTool } from './base-tool.js';
import { notifications } from '../utils/ui.js';

export default class QRCode extends BaseTool {
constructor() {
super();
this.initializeElements();
this.initializeState();
this.elements = this.initializeElements();
this.state = this.initializeState();
this.initialize();
this.bindEvents();
}

initializeElements() {
return {
// Input elements
textInput: document.getElementById('text-input'),

// QR code options
errorCorrectionSelect: document.getElementById('error-correction'),
sizeInput: document.getElementById('size'),
colorInput: document.getElementById('color'),
backgroundInput: document.getElementById('background'),

// Action buttons
generateButton: document.getElementById('generate-button'),
downloadButton: document.getElementById('download-button'),
clearButton: document.getElementById('clear-button'),

// Display elements
qrContainer: document.getElementById('qr-container'),
qrCanvas: document.getElementById('qr-canvas'),

// Notification
notification: document.querySelector('.notification')
};
}
Expand All @@ -46,47 +41,140 @@ class QRCode extends BaseTool {
bindEvents() {
const { textInput, errorCorrectionSelect, sizeInput, colorInput, backgroundInput, generateButton, downloadButton, clearButton } = this.elements;

// Input events
textInput.addEventListener('input', this.validateInput.bind(this));
textInput.addEventListener('keypress', (e) => {
if (e.key === 'Enter') this.generateQRCode();
});

// Option events
errorCorrectionSelect.addEventListener('change', this.updateOptions.bind(this));
sizeInput.addEventListener('input', this.updateOptions.bind(this));
colorInput.addEventListener('input', this.updateOptions.bind(this));
backgroundInput.addEventListener('input', this.updateOptions.bind(this));

// Button events
generateButton.addEventListener('click', this.generateQRCode.bind(this));
downloadButton.addEventListener('click', this.downloadQRCode.bind(this));
clearButton.addEventListener('click', this.clearInput.bind(this));

// Keyboard shortcuts
this.addKeyboardShortcut('g', this.generateQRCode.bind(this), { ctrl: true });
this.addKeyboardShortcut('d', this.downloadQRCode.bind(this), { ctrl: true });
}

initialize() {
// Set initial values
this.elements.errorCorrectionSelect.value = this.state.options.errorCorrectionLevel;
this.elements.sizeInput.value = this.state.options.size;
this.elements.colorInput.value = this.state.options.color;
this.elements.backgroundInput.value = this.state.options.background;

// Hide QR container initially
this.elements.qrContainer.style.display = 'none';

// Disable buttons initially
this.elements.generateButton.disabled = true;
this.elements.downloadButton.disabled = true;
}

// ... rest of the class implementation ...
validateInput() {
const text = this.elements.textInput.value.trim();
this.elements.generateButton.disabled = !text;
if (this.state.qr && !text) {
this.clearQRCode();
}
}

updateOptions() {
this.state.options = {
errorCorrectionLevel: this.elements.errorCorrectionSelect.value,
size: parseInt(this.elements.sizeInput.value),
color: this.elements.colorInput.value,
background: this.elements.backgroundInput.value
};

if (this.state.qr) {
this.generateQRCode();
}
}

async generateQRCode() {
const text = this.elements.textInput.value.trim();
if (!text) return;

try {
if (!this.state.qr) {
this.state.qr = new QRCodeStyling({
width: this.state.options.size,
height: this.state.options.size,
type: 'canvas',
data: text,
dotsOptions: {
color: this.state.options.color,
type: 'square'
},
backgroundOptions: {
color: this.state.options.background
},
qrOptions: {
errorCorrectionLevel: this.state.options.errorCorrectionLevel
}
});
} else {
this.state.qr.update({
data: text,
width: this.state.options.size,
height: this.state.options.size,
dotsOptions: {
color: this.state.options.color
},
backgroundOptions: {
color: this.state.options.background
},
qrOptions: {
errorCorrectionLevel: this.state.options.errorCorrectionLevel
}
});
}

this.elements.qrContainer.innerHTML = '';
await this.state.qr.append(this.elements.qrContainer);
this.elements.qrContainer.style.display = 'block';
this.elements.downloadButton.disabled = false;
this.showNotification('QR code generated successfully');
} catch (error) {
console.error('QR code generation error:', error);
this.showNotification('Failed to generate QR code', 'error');
}
}

async downloadQRCode() {
if (!this.state.qr) return;

try {
const canvas = this.elements.qrContainer.querySelector('canvas');
const dataUrl = canvas.toDataURL('image/png');
const link = document.createElement('a');
link.href = dataUrl;
link.download = 'qr-code.png';
document.body.appendChild(link);
link.click();
document.body.removeChild(link);
} catch (error) {
console.error('Download error:', error);
this.showNotification('Failed to download QR code', 'error');
}
}

clearInput() {
this.elements.textInput.value = '';
this.validateInput();
this.clearQRCode();
}

clearQRCode() {
if (this.state.qr) {
this.elements.qrContainer.innerHTML = '';
this.elements.qrContainer.style.display = 'none';
this.elements.downloadButton.disabled = true;
this.state.qr = null;
}
}
}

// Initialize the feature when the DOM is ready
document.addEventListener('DOMContentLoaded', () => {
// Initialize the tool if we're on the QR code page
if (document.querySelector('.qr-controls')) {
new QRCode();
});
}

0 comments on commit c2ebeb1

Please sign in to comment.