Fix: Change message length counter from characters to UTF-8 bytes

Updated the message length validation to count actual UTF-8 bytes instead of Unicode characters. This ensures accurate enforcement of the 200-byte LoRa limit, preventing message truncation.

Changes:
- Frontend: Use TextEncoder to count UTF-8 bytes in real-time
- Backend: Validate byte length using text.encode('utf-8')
- HTML: Increased maxlength to 500 to allow more ASCII while JS enforces 200 bytes

Example: "zażółć gęślą jaźń 😀😁"
- Before: ~22 chars 
- After: ~35 bytes  (Polish chars = 2 bytes, emoji = 4 bytes each)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
MarekWo
2025-12-21 20:50:08 +01:00
parent f5fedbc96c
commit dd867c9fac
3 changed files with 14 additions and 9 deletions

View File

@@ -96,10 +96,12 @@ def send_message():
}), 400
# MeshCore message length limit (~180-200 bytes for LoRa)
if len(text) > 200:
# Count UTF-8 bytes, not Unicode characters
byte_length = len(text.encode('utf-8'))
if byte_length > 200:
return jsonify({
'success': False,
'error': f'Message too long ({len(text)} chars). Maximum 200 characters allowed due to LoRa constraints.'
'error': f'Message too long ({byte_length} bytes). Maximum 200 bytes allowed due to LoRa constraints.'
}), 400
reply_to = data.get('reply_to')

View File

@@ -398,21 +398,24 @@ function formatTime(timestamp) {
}
/**
* Update character counter
* Update character counter (counts UTF-8 bytes, not characters)
*/
function updateCharCounter() {
const input = document.getElementById('messageInput');
const counter = document.getElementById('charCounter');
const length = input.value.length;
const maxLength = 200;
counter.textContent = `${length} / ${maxLength}`;
// Count UTF-8 bytes, not Unicode characters
const encoder = new TextEncoder();
const byteLength = encoder.encode(input.value).length;
const maxBytes = 200;
counter.textContent = `${byteLength} / ${maxBytes}`;
// Visual warning when approaching limit
if (length >= maxLength * 0.9) {
if (byteLength >= maxBytes * 0.9) {
counter.classList.remove('text-muted', 'text-warning');
counter.classList.add('text-danger', 'fw-bold');
} else if (length >= maxLength * 0.75) {
} else if (byteLength >= maxBytes * 0.75) {
counter.classList.remove('text-muted', 'text-danger');
counter.classList.add('text-warning', 'fw-bold');
} else {

View File

@@ -31,7 +31,7 @@
class="form-control"
placeholder="Type a message..."
rows="2"
maxlength="200"
maxlength="500"
required
></textarea>
<button type="submit" class="btn btn-primary px-4" id="sendBtn">