cleaned up visuals

This commit is contained in:
Your Name
2025-09-15 14:52:21 -04:00
parent 12d4810f4c
commit 77ea4a8e67
3 changed files with 193 additions and 63 deletions

View File

@@ -675,7 +675,7 @@ class FloatingTab {
appearance: {
style: 'pill', // 'pill', 'square', 'circle'
theme: 'auto', // 'auto', 'light', 'dark'
icon: '[LOGIN]',
icon: '',
text: 'Login',
iconOnly: false
},
@@ -685,11 +685,14 @@ class FloatingTab {
autoSlide: true,
persistent: false
},
getUserInfo: false,
getUserRelay: [],
...options
};
this.isAuthenticated = false;
this.userInfo = null;
this.userProfile = null;
this.container = null;
this.isVisible = false;
@@ -790,11 +793,24 @@ class FloatingTab {
}
}
_handleAuth(authData) {
async _handleAuth(authData) {
console.log('FloatingTab: Handling authentication:', authData);
this.isAuthenticated = true;
this.userInfo = authData;
// Fetch user profile if enabled and we have a pubkey
if (this.options.getUserInfo && authData.pubkey) {
console.log('FloatingTab: Fetching user profile for:', authData.pubkey);
try {
const profile = await this._fetchUserProfile(authData.pubkey);
this.userProfile = profile;
console.log('FloatingTab: User profile fetched:', profile);
} catch (error) {
console.warn('FloatingTab: Failed to fetch user profile:', error);
this.userProfile = null;
}
}
if (this.options.behavior.hideWhenAuthenticated) {
this.hide();
} else {
@@ -806,6 +822,7 @@ class FloatingTab {
console.log('FloatingTab: Handling logout');
this.isAuthenticated = false;
this.userInfo = null;
this.userProfile = null;
if (this.options.behavior.hideWhenAuthenticated) {
this.show();
@@ -873,18 +890,29 @@ class FloatingTab {
// Update content
if (this.isAuthenticated && this.options.behavior.showUserInfo) {
const display = this.userInfo?.pubkey ?
(this.options.appearance.iconOnly ?
'[USER]' :
\`[USER] \${this.userInfo.pubkey.slice(0, 6)}...\`) :
(this.options.appearance.iconOnly ? '[AUTH]' : '[AUTH] Logged In');
let display;
// Use profile name if available, otherwise fall back to pubkey
if (this.userProfile?.name || this.userProfile?.display_name) {
const userName = this.userProfile.name || this.userProfile.display_name;
display = this.options.appearance.iconOnly
? userName.slice(0, 8)
: userName;
} else if (this.userInfo?.pubkey) {
// Fallback to pubkey display
display = this.options.appearance.iconOnly
? this.userInfo.pubkey.slice(0, 6)
: \`\${this.userInfo.pubkey.slice(0, 6)}...\`;
} else {
display = this.options.appearance.iconOnly ? 'User' : 'Authenticated';
}
this.container.textContent = display;
this.container.className = 'nl-floating-tab nl-floating-tab--logged-in';
} else {
const display = this.options.appearance.iconOnly ?
this.options.appearance.icon :
\`\${this.options.appearance.icon} \${this.options.appearance.text}\`;
(this.options.appearance.icon ? \`\${this.options.appearance.icon} \${this.options.appearance.text}\` : this.options.appearance.text);
this.container.textContent = display;
this.container.className = 'nl-floating-tab nl-floating-tab--logged-out';
@@ -915,6 +943,62 @@ class FloatingTab {
}
}
async _fetchUserProfile(pubkey) {
if (!this.options.getUserInfo) {
console.log('FloatingTab: getUserInfo disabled, skipping profile fetch');
return null;
}
// Determine which relays to use
const relays = this.options.getUserRelay.length > 0
? this.options.getUserRelay
: (this.modal?.options?.relays || ['wss://relay.damus.io', 'wss://nos.lol']);
console.log('FloatingTab: Fetching profile from relays:', relays);
try {
// Create a SimplePool instance for querying
const pool = new window.NostrTools.nip46.SimplePool();
// Query for kind 0 (user metadata) events
const events = await pool.querySync(relays, {
kinds: [0],
authors: [pubkey],
limit: 1
}, { timeout: 5000 });
console.log('FloatingTab: Profile query returned', events.length, 'events');
if (events.length === 0) {
console.log('FloatingTab: No profile events found');
return null;
}
// Get the most recent event
const latestEvent = events.sort((a, b) => b.created_at - a.created_at)[0];
try {
const profile = JSON.parse(latestEvent.content);
console.log('FloatingTab: Parsed profile:', profile);
// Return relevant profile fields
return {
name: profile.name || null,
display_name: profile.display_name || null,
about: profile.about || null,
picture: profile.picture || null,
nip05: profile.nip05 || null
};
} catch (parseError) {
console.warn('FloatingTab: Failed to parse profile JSON:', parseError);
return null;
}
} catch (error) {
console.error('FloatingTab: Profile fetch error:', error);
return null;
}
}
_position() {
if (!this.container) return;
@@ -1076,7 +1160,7 @@ class NostrLite {
appearance: {
style: 'pill',
theme: 'auto',
icon: '[LOGIN]',
icon: '',
text: 'Login',
iconOnly: false
},
@@ -1085,7 +1169,9 @@ class NostrLite {
showUserInfo: true,
autoSlide: true,
persistent: false
}
},
getUserInfo: false,
getUserRelay: []
},
...options
};

View File

@@ -8,7 +8,7 @@
* Two-file architecture:
* 1. Load nostr.bundle.js (official nostr-tools bundle)
* 2. Load nostr-lite.js (this file - NOSTR_LOGIN_LITE library with CSS-only themes)
* Generated on: 2025-09-15T18:15:24.222Z
* Generated on: 2025-09-15T18:50:50.789Z
*/
// Verify dependencies are loaded
@@ -1076,26 +1076,6 @@ class Modal {
button.style.background = 'var(--nl-secondary-color)';
};
const iconDiv = document.createElement('div');
// Replace emoji icons with text-based ones
const iconMap = {
'🔌': '[EXT]',
'🔑': '[KEY]',
'🌐': '[NET]',
'👁️': '[VIEW]',
'📱': '[SMS]'
};
iconDiv.textContent = iconMap[option.icon] || option.icon;
iconDiv.style.cssText = `
font-size: 16px;
font-weight: bold;
margin-right: 16px;
width: 50px;
text-align: center;
color: var(--nl-primary-color);
font-family: var(--nl-font-family, 'Courier New', monospace);
`;
const contentDiv = document.createElement('div');
contentDiv.style.cssText = 'flex: 1; text-align: left;';
@@ -1119,7 +1099,6 @@ class Modal {
contentDiv.appendChild(titleDiv);
contentDiv.appendChild(descDiv);
button.appendChild(iconDiv);
button.appendChild(contentDiv);
this.modalBody.appendChild(button);
});
@@ -2144,7 +2123,7 @@ class FloatingTab {
appearance: {
style: 'pill', // 'pill', 'square', 'circle'
theme: 'auto', // 'auto', 'light', 'dark'
icon: '[LOGIN]',
icon: '',
text: 'Login',
iconOnly: false
},
@@ -2154,11 +2133,14 @@ class FloatingTab {
autoSlide: true,
persistent: false
},
getUserInfo: false,
getUserRelay: [],
...options
};
this.isAuthenticated = false;
this.userInfo = null;
this.userProfile = null;
this.container = null;
this.isVisible = false;
@@ -2259,11 +2241,24 @@ class FloatingTab {
}
}
_handleAuth(authData) {
async _handleAuth(authData) {
console.log('FloatingTab: Handling authentication:', authData);
this.isAuthenticated = true;
this.userInfo = authData;
// Fetch user profile if enabled and we have a pubkey
if (this.options.getUserInfo && authData.pubkey) {
console.log('FloatingTab: Fetching user profile for:', authData.pubkey);
try {
const profile = await this._fetchUserProfile(authData.pubkey);
this.userProfile = profile;
console.log('FloatingTab: User profile fetched:', profile);
} catch (error) {
console.warn('FloatingTab: Failed to fetch user profile:', error);
this.userProfile = null;
}
}
if (this.options.behavior.hideWhenAuthenticated) {
this.hide();
} else {
@@ -2275,6 +2270,7 @@ class FloatingTab {
console.log('FloatingTab: Handling logout');
this.isAuthenticated = false;
this.userInfo = null;
this.userProfile = null;
if (this.options.behavior.hideWhenAuthenticated) {
this.show();
@@ -2342,18 +2338,29 @@ class FloatingTab {
// Update content
if (this.isAuthenticated && this.options.behavior.showUserInfo) {
const display = this.userInfo?.pubkey ?
(this.options.appearance.iconOnly ?
'[USER]' :
`[USER] ${this.userInfo.pubkey.slice(0, 6)}...`) :
(this.options.appearance.iconOnly ? '[AUTH]' : '[AUTH] Logged In');
let display;
// Use profile name if available, otherwise fall back to pubkey
if (this.userProfile?.name || this.userProfile?.display_name) {
const userName = this.userProfile.name || this.userProfile.display_name;
display = this.options.appearance.iconOnly
? userName.slice(0, 8)
: userName;
} else if (this.userInfo?.pubkey) {
// Fallback to pubkey display
display = this.options.appearance.iconOnly
? this.userInfo.pubkey.slice(0, 6)
: `${this.userInfo.pubkey.slice(0, 6)}...`;
} else {
display = this.options.appearance.iconOnly ? 'User' : 'Authenticated';
}
this.container.textContent = display;
this.container.className = 'nl-floating-tab nl-floating-tab--logged-in';
} else {
const display = this.options.appearance.iconOnly ?
this.options.appearance.icon :
`${this.options.appearance.icon} ${this.options.appearance.text}`;
(this.options.appearance.icon ? `${this.options.appearance.icon} ${this.options.appearance.text}` : this.options.appearance.text);
this.container.textContent = display;
this.container.className = 'nl-floating-tab nl-floating-tab--logged-out';
@@ -2384,6 +2391,62 @@ class FloatingTab {
}
}
async _fetchUserProfile(pubkey) {
if (!this.options.getUserInfo) {
console.log('FloatingTab: getUserInfo disabled, skipping profile fetch');
return null;
}
// Determine which relays to use
const relays = this.options.getUserRelay.length > 0
? this.options.getUserRelay
: (this.modal?.options?.relays || ['wss://relay.damus.io', 'wss://nos.lol']);
console.log('FloatingTab: Fetching profile from relays:', relays);
try {
// Create a SimplePool instance for querying
const pool = new window.NostrTools.nip46.SimplePool();
// Query for kind 0 (user metadata) events
const events = await pool.querySync(relays, {
kinds: [0],
authors: [pubkey],
limit: 1
}, { timeout: 5000 });
console.log('FloatingTab: Profile query returned', events.length, 'events');
if (events.length === 0) {
console.log('FloatingTab: No profile events found');
return null;
}
// Get the most recent event
const latestEvent = events.sort((a, b) => b.created_at - a.created_at)[0];
try {
const profile = JSON.parse(latestEvent.content);
console.log('FloatingTab: Parsed profile:', profile);
// Return relevant profile fields
return {
name: profile.name || null,
display_name: profile.display_name || null,
about: profile.about || null,
picture: profile.picture || null,
nip05: profile.nip05 || null
};
} catch (parseError) {
console.warn('FloatingTab: Failed to parse profile JSON:', parseError);
return null;
}
} catch (error) {
console.error('FloatingTab: Profile fetch error:', error);
return null;
}
}
_position() {
if (!this.container) return;
@@ -2545,7 +2608,7 @@ class NostrLite {
appearance: {
style: 'pill',
theme: 'auto',
icon: '[LOGIN]',
icon: '',
text: 'Login',
iconOnly: false
},
@@ -2554,7 +2617,9 @@ class NostrLite {
showUserInfo: true,
autoSlide: true,
persistent: false
}
},
getUserInfo: false,
getUserRelay: []
},
...options
};

View File

@@ -280,26 +280,6 @@ class Modal {
button.style.background = 'var(--nl-secondary-color)';
};
const iconDiv = document.createElement('div');
// Replace emoji icons with text-based ones
const iconMap = {
'🔌': '[EXT]',
'🔑': '[KEY]',
'🌐': '[NET]',
'👁️': '[VIEW]',
'📱': '[SMS]'
};
iconDiv.textContent = iconMap[option.icon] || option.icon;
iconDiv.style.cssText = `
font-size: 16px;
font-weight: bold;
margin-right: 16px;
width: 50px;
text-align: center;
color: var(--nl-primary-color);
font-family: var(--nl-font-family, 'Courier New', monospace);
`;
const contentDiv = document.createElement('div');
contentDiv.style.cssText = 'flex: 1; text-align: left;';
@@ -323,7 +303,6 @@ class Modal {
contentDiv.appendChild(titleDiv);
contentDiv.appendChild(descDiv);
button.appendChild(iconDiv);
button.appendChild(contentDiv);
this.modalBody.appendChild(button);
});