mirror of
https://github.com/MarekWo/mc-webui.git
synced 2026-08-06 16:53:21 +02:00
fix(contacts): disable ignore/block buttons for protected contacts
- Existing Contacts: Ignore and Block buttons are now disabled when contact is protected, matching the existing Delete button behavior - updateProtectionUI: toggling protection now also enables/disables Ignore, Block, and Delete buttons dynamically - Chat: Ignore and Block buttons are hidden in message bubbles for protected contacts (loads protected pubkeys on init) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
+22
-1
@@ -23,6 +23,7 @@ let markersGroup = null;
|
||||
let contactsGeoCache = {}; // { 'contactName': { lat, lon }, ... }
|
||||
let contactsPubkeyMap = {}; // { 'contactName': 'full_pubkey', ... }
|
||||
let blockedContactNames = new Set(); // Names of blocked contacts
|
||||
let protectedContactPubkeys = new Set(); // Pubkeys of protected contacts
|
||||
let allContactsWithGps = []; // Device contacts for map filtering
|
||||
let allCachedContactsWithGps = []; // Cache-only contacts for map
|
||||
let _selfInfo = null; // Own device info (for map marker)
|
||||
@@ -372,6 +373,23 @@ async function loadBlockedNames() {
|
||||
}
|
||||
}
|
||||
|
||||
async function loadProtectedPubkeys() {
|
||||
try {
|
||||
const resp = await fetch('/api/contacts/protected');
|
||||
const data = await resp.json();
|
||||
if (data.success) {
|
||||
protectedContactPubkeys = new Set((data.protected_contacts || []).map(pk => pk.toLowerCase()));
|
||||
}
|
||||
} catch (err) {
|
||||
console.error('Error loading protected contacts:', err);
|
||||
}
|
||||
}
|
||||
|
||||
function isContactProtectedByName(senderName) {
|
||||
const pubkey = contactsPubkeyMap[senderName];
|
||||
return pubkey && protectedContactPubkeys.has(pubkey.toLowerCase());
|
||||
}
|
||||
|
||||
// Initialize on page load
|
||||
/**
|
||||
* Connect to SocketIO /chat namespace for real-time message updates
|
||||
@@ -486,6 +504,7 @@ document.addEventListener('DOMContentLoaded', async function() {
|
||||
const messagesPromise = loadMessages();
|
||||
const geoCachePromise = loadContactsGeoCache(); // Non-blocking, Map buttons update when ready
|
||||
const blockedPromise = loadBlockedNames(); // Non-blocking, for real-time filtering
|
||||
const protectedPromise = loadProtectedPubkeys(); // Non-blocking, for disabling ignore/block on protected
|
||||
|
||||
// Also start archive list loading in parallel
|
||||
loadArchiveList();
|
||||
@@ -1187,14 +1206,16 @@ function createMessageElement(msg) {
|
||||
<i class="bi bi-clipboard-data"></i>
|
||||
</button>
|
||||
` : ''}
|
||||
${contactsPubkeyMap[msg.sender] ? `
|
||||
${contactsPubkeyMap[msg.sender] && !isContactProtectedByName(msg.sender) ? `
|
||||
<button class="btn btn-outline-secondary btn-msg-action" onclick="ignoreContactFromChat('${contactsPubkeyMap[msg.sender]}')" title="Ignore ${escapeHtml(msg.sender)}">
|
||||
<i class="bi bi-eye-slash"></i>
|
||||
</button>
|
||||
` : ''}
|
||||
${!isContactProtectedByName(msg.sender) ? `
|
||||
<button class="btn btn-outline-danger btn-msg-action" onclick="blockContactFromChat('${escapeHtml(msg.sender)}')" title="Block ${escapeHtml(msg.sender)}">
|
||||
<i class="bi bi-slash-circle"></i>
|
||||
</button>
|
||||
` : ''}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -1082,12 +1082,15 @@ function updateProtectionUI(publicKey, isProtected, buttonEl) {
|
||||
if (lockIcon) lockIcon.remove();
|
||||
}
|
||||
|
||||
// Enable/disable delete button
|
||||
const deleteBtn = cardEl.querySelector('.btn-outline-danger');
|
||||
if (deleteBtn) {
|
||||
deleteBtn.disabled = isProtected;
|
||||
deleteBtn.title = isProtected ? 'Cannot delete protected contact' : '';
|
||||
}
|
||||
// Enable/disable delete, ignore, and block buttons based on protection
|
||||
cardEl.querySelectorAll('button').forEach(btn => {
|
||||
const icon = btn.querySelector('i');
|
||||
if (!icon) return;
|
||||
if (icon.classList.contains('bi-trash') || icon.classList.contains('bi-eye-slash') || icon.classList.contains('bi-slash-circle')) {
|
||||
btn.disabled = isProtected;
|
||||
btn.title = isProtected ? 'Protected contact' : '';
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
async function toggleContactIgnore(publicKey, ignored) {
|
||||
@@ -2335,12 +2338,20 @@ function createExistingContactCard(contact, index) {
|
||||
ignoreBtn.className = 'btn btn-sm btn-outline-secondary';
|
||||
ignoreBtn.innerHTML = '<i class="bi bi-eye-slash"></i> <span class="btn-label">Ignore</span>';
|
||||
ignoreBtn.onclick = () => toggleContactIgnore(contact.public_key, true);
|
||||
if (isProtected) {
|
||||
ignoreBtn.disabled = true;
|
||||
ignoreBtn.title = 'Cannot ignore protected contact';
|
||||
}
|
||||
actionsDiv.appendChild(ignoreBtn);
|
||||
|
||||
const blockBtn = document.createElement('button');
|
||||
blockBtn.className = 'btn btn-sm btn-outline-danger';
|
||||
blockBtn.innerHTML = '<i class="bi bi-slash-circle"></i> <span class="btn-label">Block</span>';
|
||||
blockBtn.onclick = () => toggleContactBlock(contact.public_key, true);
|
||||
if (isProtected) {
|
||||
blockBtn.disabled = true;
|
||||
blockBtn.title = 'Cannot block protected contact';
|
||||
}
|
||||
actionsDiv.appendChild(blockBtn);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user