Skip to content

Commit 050bd5b

Browse files
YuurinBeeJSKittyclaude
authored
Frontend Onboarding Improvements (#41)
* User Profile: Add Share Button, Copy, Multi-Theme Support * Frontend: New Design for Create New Chat Page * Fix missing </div> * UX/UI Improvement for Toast Actions & Multi-Theme Support * Fix Bugs & Claude Suggestions * Adjust background transition effect for Toast * Update Login Screen - Consistent Input Field * Final Fix for Login Input Field * Add Back Bar (Return) on Login Screen * Fix a series of bugs and dead code * Fix Create Account Font Weight * Add missing closing div * fix: Toast backdrop fade transition, New Chat responsive layout, and text selection - Fix toast backdrop snap-on/off: CSS cannot transition between a solid background and a gradient, switched to opacity transitions matching the toast itself - Fix New Chat "Need Help?" section hiding behind nPub input on small screens: converted center content to flex column with margin-top: auto anchoring the help section above the input - Add user-select: none to New Chat menu (excluding the input field) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * cleanup: Remove dead share-npub references The share-npub element was removed from HTML but its JS declaration and usage remained as dead code. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> --------- Co-authored-by: JSKitty <mail@jskitty.cat> Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
1 parent 7db5068 commit 050bd5b

11 files changed

Lines changed: 304 additions & 96 deletions

File tree

src/icons/chat-bubble.svg

Lines changed: 3 additions & 0 deletions
Loading

src/icons/help.svg

Lines changed: 3 additions & 0 deletions
Loading

src/icons/share.svg

Lines changed: 3 additions & 0 deletions
Loading

src/index.html

Lines changed: 44 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -572,6 +572,10 @@ <h3 id="profile-secondary-name" class="chat-contact-with-status btn"></h3>
572572
<span class="icon icon-volume-mute navbar-icon"></span>
573573
<p class="navbar-text">Mute</p>
574574
</div>
575+
<div id="profile-option-share" class="profile-option">
576+
<span class="icon icon-share navbar-icon"></span>
577+
<p class="navbar-text">Share</p>
578+
</div>
575579
</div>
576580
<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>
577581
<textarea id="profile-description-editor" class="chat-contact-status profile-description-editor" style="display: none; margin-top: 10px;"></textarea>
@@ -715,31 +719,35 @@ <h3 id="chat-contact" class="cutoff chat-contact-with-status btn"></h3>
715719
<span class="icon icon-chevron-double-left nav-icon"></span>
716720
<p class="chat-new-back-text">Back</p>
717721
</div>
718-
</div>
719-
<center class="chat-new-content" style="margin-top: 80px;">
720-
<h2 class="chat-new-title">My nPub Key</h2>
721-
<hr class="divider chat-new-divider">
722-
<div class="profile-npub-container" style="justify-content: center; margin-top: 10px;">
723-
<span class="chat-new-npub" id="share-npub"></span>
724-
<button id="chat-new-npub-copy" class="btn profile-npub-copy">
725-
<span class="icon icon-copy"></span>
726-
</button>
727-
</div>
728-
</center>
722+
</div>
729723
<center class="chat-new-center-content">
730-
<span class="icon icon-add-user chat-new-icon"></span>
731-
<h2 class="chat-new-subtitle">Start a New Chat</h2>
724+
<span class="icon icon-chat-bubble chat-new-icon"></span>
725+
<h2 class="chat-new-subtitle">Create New Chat</h2>
732726
<hr class="divider chat-new-subtitle-divider">
733727
<div class="chat-new-content">
734-
<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>
728+
<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>
729+
</div>
730+
<div class="chat-new-help">
731+
<a href="https://vector-privacy.gitbook.io/vector-privacy/vector-messenger/features/add-contacts" target="_blank" class="chat-new-help-link">
732+
<span class="icon icon-help chat-new-help-icon"></span>
733+
</a>
734+
<span class="chat-new-help-title">Need Help?</span>
735+
</div>
736+
<div class="chat-new-help-steps">
737+
<span class="chat-new-help-step">Profile</span>
738+
<span class="chat-new-help-arrow"></span>
739+
<span class="chat-new-help-step">nPub Key</span>
740+
<span class="chat-new-help-arrow"></span>
741+
<span class="chat-new-help-step">Copy</span>
735742
</div>
736743
</center>
737-
<div class="row input-box chat-new-input-box">
738-
<input id="chat-new-input" placeholder="Enter npub..." class="chat-input-container chat-new-input">
739-
<span id="chat-new-btn" class="icon icon-add-user btn chat-new-add-btn"></span>
744+
<div class="row input-box" id="chat-new-box">
745+
<div class="row chat-input-container">
746+
<input id="chat-new-input" type="text" placeholder="Paste nPub Key...">
747+
<button id="chat-new-btn" style="display: none; margin-right: 3px;"><span class="icon icon-add-user"></span></button>
748+
</div>
740749
</div>
741750
</div>
742-
743751
<div id="create-group" class="create-group-container" style="display: none;">
744752
<div class="chat-new-header">
745753
<div id="create-group-back-text-btn" class="btn chat-new-back-text-btn">
@@ -1122,6 +1130,12 @@ <h3 class="invite-code-label">Your Invite Code</h3>
11221130
</div>
11231131

11241132
<div id="login-form" class="fadein-anim">
1133+
<div id="login-back-bar" class="chat-new-header" style="display: none;">
1134+
<div id="login-back-btn" class="btn chat-new-back-text-btn">
1135+
<span class="icon icon-chevron-double-left nav-icon"></span>
1136+
<p class="chat-new-back-text">Back</p>
1137+
</div>
1138+
</div>
11251139
<img src="./icons/vector-logo.svg" class="login-logo">
11261140
<h4 class="startup-subtext-gradient login-subtext">Private & Encrypted Messenger</h4>
11271141
<div id="login-start">
@@ -1133,25 +1147,29 @@ <h4 class="startup-subtext-gradient login-subtext">Private & Encrypted Messenger
11331147
</div>
11341148
<div id="login-import" class="login-import-container" style="display: none;">
11351149
<img src="./icons/by-formlesslabs.svg" class="login-credits">
1136-
<div class="row input-box login-input-container">
1150+
<div class="row input-box login-input-container">
1151+
<div class="row chat-input-container">
11371152
<input type="password" class="login-input" id="login-input" placeholder="Enter nsec or Seed Phrase..." />
1138-
<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">
1153+
<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">
11391154
<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"/>
11401155
</svg>
11411156
</div>
11421157
</div>
1158+
</div>
11431159
<div id="login-invite" class="login-invite-container" style="display: none;">
11441160
<div class="login-invite-header">
11451161
<h3 class="login-invite-title">Enter Invite Code</h3>
11461162
</div>
11471163
<p class="login-invite-description">Enter your invite code to join Vector Beta</p>
11481164
<div class="row input-box login-input-container">
1149-
<input type="text" class="login-input" id="invite-input" placeholder="Invite code..." />
1150-
<button id="invite-btn" class="btn login-btn">
1151-
<svg width="100%" height="100%" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
1152-
<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"/>
1153-
</svg>
1154-
</button>
1165+
<div class="row chat-input-container">
1166+
<input type="text" class="login-input" id="invite-input" placeholder="Invite code..." />
1167+
<button id="invite-btn" class="btn login-btn">
1168+
<svg width="100%" height="100%" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
1169+
<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"/>
1170+
</svg>
1171+
</button>
1172+
</div>
11551173
</div>
11561174
</div>
11571175
<div id="login-welcome" class="login-welcome-container" style="display: none;">

src/main.js

Lines changed: 78 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,11 @@ const domLoginImport = document.getElementById('login-import');
2222
const domLoginInput = document.getElementById('login-input');
2323
const domLoginBtn = document.getElementById('login-btn');
2424

25+
const domLoginImportError = document.getElementById('login-import-error');
26+
27+
const domLoginBackBar = document.getElementById('login-back-bar');
28+
const domLoginBackBtn = document.getElementById('login-back-btn');
29+
2530
const domLoginInvite = document.getElementById('login-invite');
2631
const domInviteInput = document.getElementById('invite-input');
2732
const domInviteBtn = document.getElementById('invite-btn');
@@ -53,6 +58,7 @@ const domProfileOptions = document.getElementById('profile-option-list');
5358
const domProfileOptionMute = document.getElementById('profile-option-mute');
5459
const domProfileOptionMessage = document.getElementById('profile-option-message');
5560
const domProfileOptionNickname = document.getElementById('profile-option-nickname');
61+
const domProfileOptionShare = document.getElementById('profile-option-share');
5662
const domProfileId = document.getElementById('profile-id');
5763

5864
const domGroupOverview = document.getElementById('group-overview');
@@ -131,7 +137,6 @@ const domChatInputContainer = document.querySelector('.chat-input-container');
131137

132138
const domChatNew = document.getElementById('chat-new');
133139
const domChatNewBackBtn = document.getElementById('chat-new-back-text-btn');
134-
const domShareNpub = document.getElementById('share-npub');
135140
const domChatNewInput = document.getElementById('chat-new-input');
136141
const domChatNewStartBtn = document.getElementById('chat-new-btn');
137142

@@ -429,6 +434,13 @@ function showToast(message) {
429434
left: 50%;
430435
transform: translateX(-50%);
431436
background: rgba(0, 0, 0, 0.8);
437+
backdrop-filter: blur(20px);
438+
-webkit-backdrop-filter: blur(10px);
439+
border: 1px solid var(--toast-border-color, #161616);
440+
box-shadow:
441+
0 0 4px rgba(0, 0, 0, 0.8),
442+
0 0 12px rgba(0, 0, 0, 0.6),
443+
0 0 30px rgba(0, 0, 0, 0.4);
432444
color: white;
433445
padding: 12px 24px;
434446
border-radius: 8px;
@@ -441,14 +453,33 @@ function showToast(message) {
441453
document.body.appendChild(toast);
442454
}
443455

456+
let backdrop = document.getElementById('toast-backdrop');
457+
if (!backdrop) {
458+
backdrop = document.createElement('div');
459+
backdrop.id = 'toast-backdrop';
460+
backdrop.style.cssText = `
461+
position:fixed;
462+
top:0;
463+
left:0;
464+
width:100%;
465+
height:100%;
466+
background:linear-gradient(to bottom, rgba(0,0,0,0) 0%, rgba(0,0,0,0) 50%, rgba(0,0,0,0.8) 100%);
467+
opacity:0;
468+
z-index:9999;pointer-events:none;
469+
transition:opacity 0.3s ease;
470+
`;
471+
document.body.appendChild(backdrop);
472+
}
444473
toast.textContent = message;
445474
toast.style.opacity = '1';
475+
backdrop.style.opacity = '1';
446476

447-
// Hide after 3 seconds
477+
// Hide after 1 second
448478
clearTimeout(toast._timeout);
449479
toast._timeout = setTimeout(() => {
480+
backdrop.style.opacity = '0';
450481
toast.style.opacity = '0';
451-
}, 3000);
482+
}, 1000);
452483
}
453484

454485
/**
@@ -6500,9 +6531,6 @@ function renderCurrentProfile(cProfile) {
65006531
domAccountStatus.onclick = askForStatus;
65016532
twemojify(domAccountStatus);
65026533

6503-
/* Start Chat Tab */
6504-
// Render our Share npub
6505-
domShareNpub.textContent = strPubkey;
65066534
}
65076535

65086536
/**
@@ -6637,13 +6665,15 @@ function renderProfileTab(cProfile) {
66376665
domProfileId.textContent = cProfile.id;
66386666

66396667
// Add npub copy functionality
6640-
document.getElementById('profile-npub-copy')?.addEventListener('click', (e) => {
6668+
document.getElementById('profile-npub-copy').onclick = (e) => {
66416669
const npub = document.getElementById('profile-npub')?.textContent;
66426670
if (npub) {
66436671
// Copy the full profile URL for easy sharing
6644-
const profileUrl = `https://vectorapp.io/profile/${npub}`;
6645-
navigator.clipboard.writeText(profileUrl).then(() => {
6646-
const copyBtn = e.target.closest('.profile-npub-copy');
6672+
navigator.clipboard.writeText(npub).then(() => {
6673+
showToast('Copied!');
6674+
}).catch(() => {
6675+
showToast('Failed to copy');
6676+
const copyBtn = e.target.closest('#profile-npub-copy');
66476677
if (copyBtn) {
66486678
copyBtn.innerHTML = '<span class="icon icon-check"></span>';
66496679
setTimeout(() => {
@@ -6652,7 +6682,7 @@ function renderProfileTab(cProfile) {
66526682
}
66536683
});
66546684
}
6655-
});
6685+
};
66566686

66576687
// If this is OUR profile: make the elements clickable, hide the "Contact Options"
66586688
if (cProfile.mine) {
@@ -6710,6 +6740,23 @@ function renderProfileTab(cProfile) {
67106740
await invoke('set_nickname', { npub: cProfile.id, nickname: nick });
67116741
}
67126742

6743+
// Setup Share option
6744+
domProfileOptionShare.onclick = () => {
6745+
const npub = document.getElementById('profile-npub')?.textContent;
6746+
if (npub) {
6747+
const profileUrl = `https://vectorapp.io/profile/${npub}`;
6748+
navigator.clipboard.writeText(profileUrl).then(() => {
6749+
// Brief visual feedback
6750+
const icon = domProfileOptionShare.querySelector('span');
6751+
showToast('Profile Link Copied');
6752+
icon.classList.replace('icon-share', 'icon-check');
6753+
setTimeout(() => icon.classList.replace('icon-check', 'icon-share'), 2000);
6754+
}).catch(() => {
6755+
showToast('Failed to copy profile link');
6756+
});
6757+
}
6758+
};
6759+
67136760
// Hide edit buttons
67146761
document.querySelector('.profile-avatar-edit').style.display = 'none';
67156762
document.querySelector('.profile-banner-edit').style.display = 'none';
@@ -10580,6 +10627,16 @@ window.addEventListener("DOMContentLoaded", async () => {
1058010627
domLoginAccountBtn.onclick = () => {
1058110628
domLoginImport.style.display = '';
1058210629
domLoginStart.style.display = 'none';
10630+
domLoginBackBar.style.display = '';
10631+
document.getElementById('login-form').classList.add('has-back-bar');
10632+
};
10633+
domLoginBackBtn.onclick = () => {
10634+
domLoginImport.style.display = 'none';
10635+
domLoginInvite.style.display = 'none';
10636+
domLoginBackBar.style.display = 'none';
10637+
domLoginStart.style.display = '';
10638+
domLoginInput.value = '';
10639+
document.getElementById('login-form').classList.remove('has-back-bar');
1058310640
};
1058410641
domLoginBtn.onclick = async () => {
1058510642
// Import and derive our keys
@@ -10628,6 +10685,16 @@ window.addEventListener("DOMContentLoaded", async () => {
1062810685
domChatNewStartBtn.click();
1062910686
}
1063010687
};
10688+
domChatNewInput.addEventListener('input', function() {
10689+
domChatNewStartBtn.style.display = this.value.length > 0 ? '' : 'none';
10690+
});
10691+
10692+
// Tooltip for help icon
10693+
document.querySelector('.chat-new-help-link').addEventListener('mouseenter', function() {
10694+
showGlobalTooltip('Visit the Vector Privacy Docs', this);
10695+
});
10696+
document.querySelector('.chat-new-help-link').addEventListener('mouseleave', hideGlobalTooltip);
10697+
1063110698
domChatMessageInputCancel.onclick = () => {
1063210699
// Cancel edit mode if active, otherwise cancel reply
1063310700
if (strCurrentEditMessageId) {
@@ -11312,24 +11379,6 @@ domChatMessageInput.oninput = async () => {
1131211379
popupConfirm('PIVX Wallet Restored', 'The PIVX Wallet has been restored to your Mini Apps panel.', true);
1131311380
};
1131411381
}
11315-
11316-
// Add npub copy functionality for chat-new section
11317-
document.getElementById('chat-new-npub-copy')?.addEventListener('click', (e) => {
11318-
const npub = document.getElementById('share-npub')?.textContent;
11319-
if (npub) {
11320-
// Copy the full profile URL for easy sharing
11321-
const profileUrl = `https://vectorapp.io/profile/${npub}`;
11322-
navigator.clipboard.writeText(profileUrl).then(() => {
11323-
const copyBtn = e.target.closest('.profile-npub-copy');
11324-
if (copyBtn) {
11325-
copyBtn.innerHTML = '<span class="icon icon-check"></span>';
11326-
setTimeout(() => {
11327-
copyBtn.innerHTML = '<span class="icon icon-copy"></span>';
11328-
}, 2000);
11329-
}
11330-
});
11331-
}
11332-
});
1133311382
});
1133411383

1133511384
// Listen for app-wide click interations

0 commit comments

Comments
 (0)