Skip to content
3 changes: 3 additions & 0 deletions src/icons/chat-bubble.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 3 additions & 0 deletions src/icons/help.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 3 additions & 0 deletions src/icons/share.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
71 changes: 44 additions & 27 deletions src/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -510,6 +510,10 @@ <h3 id="profile-secondary-name" class="chat-contact-with-status btn"></h3>
<span class="icon icon-volume-mute navbar-icon"></span>
<p class="navbar-text">Mute</p>
</div>
<div id="profile-option-share" class="profile-option">
<span class="icon icon-share navbar-icon"></span>
<p class="navbar-text">Share</p>
</div>
</div>
<span id="profile-description" class="chat-contact-status" style="width: 90%; white-space: pre-line; overflow-y: auto; max-height: 225px; font-style: normal; margin-top: 10px;"></span>
<textarea id="profile-description-editor" class="chat-contact-status profile-description-editor" style="display: none; margin-top: 10px;"></textarea>
Expand Down Expand Up @@ -652,31 +656,35 @@ <h3 id="chat-contact" class="cutoff chat-contact-with-status btn"></h3>
<span class="icon icon-chevron-double-left nav-icon"></span>
<p class="chat-new-back-text">Back</p>
</div>
</div>
<center class="chat-new-content" style="margin-top: 80px;">
<h2 class="chat-new-title">My nPub Key</h2>
<hr class="divider chat-new-divider">
<div class="profile-npub-container" style="justify-content: center; margin-top: 10px;">
<span class="chat-new-npub" id="share-npub"></span>
<button id="chat-new-npub-copy" class="btn profile-npub-copy">
<span class="icon icon-copy"></span>
</button>
</div>
</center>
</div>
<center class="chat-new-center-content">
<span class="icon icon-add-user chat-new-icon"></span>
<h2 class="chat-new-subtitle">Start a New Chat</h2>
<span class="icon icon-chat-bubble chat-new-icon"></span>
<h2 class="chat-new-subtitle">Create New Chat</h2>
<hr class="divider chat-new-subtitle-divider">
<div class="chat-new-content">
<span class="chat-new-description">Use your friend's 'nPub' key to begin a conversation with them. Enter it below and click the + button.</span>
<span class="chat-new-description">Enter your contact’s nPub Key below to begin a new chat with them.<br><br>This action will also add them as a contact.</span>
</div>
<div class="chat-new-help">
<a href="https://vector-privacy.gitbook.io/vector-privacy/vector-messenger/features/add-contacts" target="_blank" class="chat-new-help-link">
<span class="icon icon-help chat-new-help-icon"></span>
</a>
<span class="chat-new-help-title">Need Help?</span>
</div>
<div class="chat-new-help-steps">
<span class="chat-new-help-step">Profile</span>
<span class="chat-new-help-arrow">›</span>
<span class="chat-new-help-step">nPub Key</span>
<span class="chat-new-help-arrow">›</span>
<span class="chat-new-help-step">Copy</span>
</div>
</center>
<div class="row input-box chat-new-input-box">
<input id="chat-new-input" placeholder="Enter npub..." class="chat-input-container chat-new-input">
<span id="chat-new-btn" class="icon icon-add-user btn chat-new-add-btn"></span>
<div class="row input-box" id="chat-new-box">
<div class="row chat-input-container">
<input id="chat-new-input" type="text" placeholder="Paste nPub Key...">
<button id="chat-new-btn" style="display: none; margin-right: 3px;"><span class="icon icon-add-user"></span></button>
</div>
</div>
</div>

<div id="create-group" class="create-group-container" style="display: none;">
<div class="chat-new-header">
<div id="create-group-back-text-btn" class="btn chat-new-back-text-btn">
Expand Down Expand Up @@ -1044,6 +1052,12 @@ <h3 class="invite-code-label">Your Invite Code</h3>
</div>

<div id="login-form" class="fadein-anim">
<div id="login-back-bar" class="chat-new-header" style="display: none;">
<div id="login-back-btn" class="btn chat-new-back-text-btn">
<span class="icon icon-chevron-double-left nav-icon"></span>
<p class="chat-new-back-text">Back</p>
</div>
</div>
<img src="./icons/vector-logo.svg" class="login-logo">
<h4 class="startup-subtext-gradient login-subtext">Private & Encrypted Messenger</h4>
<div id="login-start">
Expand All @@ -1053,11 +1067,12 @@ <h4 class="startup-subtext-gradient login-subtext">Private & Encrypted Messenger
<br>
<img src="./icons/by-formlesslabs.svg" class="login-credits">
</div>
<div id="login-import" class="login-import-container" style="display: none;">
<div id="login-import" style="display: none;">
<img src="./icons/by-formlesslabs.svg" class="login-credits">
<div class="row input-box login-input-container">
<div class="row input-box login-input-container">
<div class="row chat-input-container">
<input type="password" class="login-input" id="login-input" placeholder="Enter nsec or Seed Phrase..." />
<svg id="login-btn" class="btn login-btn" width="100%" height="100%" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<svg id="login-btn" class="btn login-btn" width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M15 3H16.2C17.8802 3 18.7202 3 19.362 3.32698C19.9265 3.6146 20.3854 4.07354 20.673 4.63803C21 5.27976 21 6.11985 21 7.8V16.2C21 17.8802 21 18.7202 20.673 19.362C20.3854 19.9265 19.9265 20.3854 19.362 20.673C18.7202 21 17.8802 21 16.2 21H15M10 7L15 12M15 12L10 17M15 12L3 12" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
</svg>
</div>
Expand All @@ -1068,12 +1083,14 @@ <h3 class="login-invite-title">Enter Invite Code</h3>
</div>
<p class="login-invite-description">Enter your invite code to join Vector Beta</p>
<div class="row input-box login-input-container">
<input type="text" class="login-input" id="invite-input" placeholder="Invite code..." />
<button id="invite-btn" class="btn login-btn">
<svg width="100%" height="100%" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M15 3H16.2C17.8802 3 18.7202 3 19.362 3.32698C19.9265 3.6146 20.3854 4.07354 20.673 4.63803C21 5.27976 21 6.11985 21 7.8V16.2C21 17.8802 21 18.7202 20.673 19.362C20.3854 19.9265 19.9265 20.3854 19.362 20.673C18.7202 21 17.8802 21 16.2 21H15M10 7L15 12M15 12L10 17M15 12L3 12" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
</svg>
</button>
<div class="row chat-input-container">
<input type="text" class="login-input" id="invite-input" placeholder="Invite code..." />
<button id="invite-btn" class="btn login-btn">
<svg width="100%" height="100%" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M15 3H16.2C17.8802 3 18.7202 3 19.362 3.32698C19.9265 3.6146 20.3854 4.07354 20.673 4.63803C21 5.27976 21 6.11985 21 7.8V16.2C21 17.8802 21 18.7202 20.673 19.362C20.3854 19.9265 19.9265 20.3854 19.362 20.673C18.7202 21 17.8802 21 16.2 21H15M10 7L15 12M15 12L10 17M15 12L3 12" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
</svg>
</button>
</div>
</div>
</div>
<div id="login-welcome" class="login-welcome-container" style="display: none;">
Expand Down
111 changes: 85 additions & 26 deletions src/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,11 @@ const domLoginImport = document.getElementById('login-import');
const domLoginInput = document.getElementById('login-input');
const domLoginBtn = document.getElementById('login-btn');

const domLoginImportError = document.getElementById('login-import-error');

const domLoginBackBar = document.getElementById('login-back-bar');
const domLoginBackBtn = document.getElementById('login-back-btn');

const domLoginInvite = document.getElementById('login-invite');
const domInviteInput = document.getElementById('invite-input');
const domInviteBtn = document.getElementById('invite-btn');
Expand Down Expand Up @@ -50,6 +55,7 @@ const domProfileOptions = document.getElementById('profile-option-list');
const domProfileOptionMute = document.getElementById('profile-option-mute');
const domProfileOptionMessage = document.getElementById('profile-option-message');
const domProfileOptionNickname = document.getElementById('profile-option-nickname');
const domProfileOptionShare = document.getElementById('profile-option-share');
const domProfileId = document.getElementById('profile-id');

const domGroupOverview = document.getElementById('group-overview');
Expand Down Expand Up @@ -426,6 +432,13 @@ function showToast(message) {
left: 50%;
transform: translateX(-50%);
background: rgba(0, 0, 0, 0.8);
backdrop-filter: blur(20px);
-webkit-backdrop-filter: blur(10px);
border: 1px solid var(--toast-border-color, #161616);
box-shadow:
0 0 4px rgba(0, 0, 0, 0.8),
0 0 12px rgba(0, 0, 0, 0.6),
0 0 30px rgba(0, 0, 0, 0.4);
color: white;
padding: 12px 24px;
border-radius: 8px;
Expand All @@ -438,14 +451,39 @@ function showToast(message) {
document.body.appendChild(toast);
}

let backdrop = document.getElementById('toast-backdrop');
if (!backdrop) {
backdrop = document.createElement('div');
backdrop.id = 'toast-backdrop';
backdrop.style.cssText = `
position:fixed;
top:0;
left:0;
width:100%;
height:100%;
background:rgba(0,0,0,0);
backdrop-filter:blur(0px);
-webkit-backdrop-filter:blur(0px);
z-index:9999;pointer-events:none;
transition:background 0.3s ease,backdrop-filter 0.3s ease,-webkit-backdrop-filter 0.3s ease;
`;
document.body.appendChild(backdrop);
}
toast.textContent = message;
toast.style.opacity = '1';

// Hide after 3 seconds
backdrop.style.background = 'linear-gradient(to bottom, rgba(0,0,0,0) 0%, rgba(0,0,0,0) 50%, rgba(0,0,0,0.8) 100%)';
backdrop.style.backdropFilter = 'blur(0px)';
backdrop.style.webkitBackdropFilter = 'blur(0px)';

// Hide after 1 second
clearTimeout(toast._timeout);
toast._timeout = setTimeout(() => {
backdrop.style.background = 'rgba(0, 0, 0, 0)';
backdrop.style.backdropFilter = 'blur(0px)';
backdrop.style.webkitBackdropFilter = 'blur(0px)';
toast.style.opacity = '0';
}, 3000);
}, 1000);
}

/**
Expand Down Expand Up @@ -6417,7 +6455,7 @@ function renderCurrentProfile(cProfile) {

/* Start Chat Tab */
// Render our Share npub
domShareNpub.textContent = strPubkey;
if (domShareNpub) domShareNpub.textContent = strPubkey;
}

/**
Expand Down Expand Up @@ -6552,13 +6590,15 @@ function renderProfileTab(cProfile) {
domProfileId.textContent = cProfile.id;

// Add npub copy functionality
document.getElementById('profile-npub-copy')?.addEventListener('click', (e) => {
document.getElementById('profile-npub-copy').onclick = (e) => {
const npub = document.getElementById('profile-npub')?.textContent;
if (npub) {
// Copy the full profile URL for easy sharing
const profileUrl = `https://vectorapp.io/profile/${npub}`;
navigator.clipboard.writeText(profileUrl).then(() => {
const copyBtn = e.target.closest('.profile-npub-copy');
navigator.clipboard.writeText(npub).then(() => {
showToast('Copied!');
}).catch(() => {
showToast('Failed to copy');
const copyBtn = e.target.closest('#profile-npub-copy');
if (copyBtn) {
copyBtn.innerHTML = '<span class="icon icon-check"></span>';
setTimeout(() => {
Expand All @@ -6567,7 +6607,7 @@ function renderProfileTab(cProfile) {
}
});
}
});
};

// If this is OUR profile: make the elements clickable, hide the "Contact Options"
if (cProfile.mine) {
Expand Down Expand Up @@ -6625,6 +6665,23 @@ function renderProfileTab(cProfile) {
await invoke('set_nickname', { npub: cProfile.id, nickname: nick });
}

// Setup Share option
domProfileOptionShare.onclick = () => {
const npub = document.getElementById('profile-npub')?.textContent;
if (npub) {
const profileUrl = `https://vectorapp.io/profile/${npub}`;
navigator.clipboard.writeText(profileUrl).then(() => {
// Brief visual feedback
const icon = domProfileOptionShare.querySelector('span');
showToast('Profile Link Copied');
icon.classList.replace('icon-share', 'icon-check');
setTimeout(() => icon.classList.replace('icon-check', 'icon-share'), 2000);
}).catch(() => {
showToast('Failed to copy profile link');
});
}
};

// Hide edit buttons
document.querySelector('.profile-avatar-edit').style.display = 'none';
document.querySelector('.profile-banner-edit').style.display = 'none';
Expand Down Expand Up @@ -10320,6 +10377,16 @@ window.addEventListener("DOMContentLoaded", async () => {
domLoginAccountBtn.onclick = () => {
domLoginImport.style.display = '';
domLoginStart.style.display = 'none';
domLoginBackBar.style.display = '';
document.getElementById('login-form').classList.add('has-back-bar');
};
domLoginBackBtn.onclick = () => {
domLoginImport.style.display = 'none';
domLoginInvite.style.display = 'none';
domLoginBackBar.style.display = 'none';
domLoginStart.style.display = '';
domLoginInput.value = '';
document.getElementById('login-form').classList.remove('has-back-bar');
};
domLoginBtn.onclick = async () => {
// Import and derive our keys
Expand Down Expand Up @@ -10368,6 +10435,16 @@ window.addEventListener("DOMContentLoaded", async () => {
domChatNewStartBtn.click();
}
};
domChatNewInput.addEventListener('input', function() {
domChatNewStartBtn.style.display = this.value.length > 0 ? '' : 'none';
});

// Tooltip for help icon
document.querySelector('.chat-new-help-link').addEventListener('mouseenter', function() {
showGlobalTooltip('Visit the Vector Privacy Docs', this);
});
document.querySelector('.chat-new-help-link').addEventListener('mouseleave', hideGlobalTooltip);

domChatMessageInputCancel.onclick = () => {
// Cancel edit mode if active, otherwise cancel reply
if (strCurrentEditMessageId) {
Expand Down Expand Up @@ -11052,24 +11129,6 @@ domChatMessageInput.oninput = async () => {
popupConfirm('PIVX Wallet Restored', 'The PIVX Wallet has been restored to your Mini Apps panel.', true);
};
}

// Add npub copy functionality for chat-new section
document.getElementById('chat-new-npub-copy')?.addEventListener('click', (e) => {
const npub = document.getElementById('share-npub')?.textContent;
if (npub) {
// Copy the full profile URL for easy sharing
const profileUrl = `https://vectorapp.io/profile/${npub}`;
navigator.clipboard.writeText(profileUrl).then(() => {
const copyBtn = e.target.closest('.profile-npub-copy');
if (copyBtn) {
copyBtn.innerHTML = '<span class="icon icon-check"></span>';
setTimeout(() => {
copyBtn.innerHTML = '<span class="icon icon-copy"></span>';
}, 2000);
}
});
}
});
});

// Listen for app-wide click interations
Expand Down
Loading