Release v1.0.4 - Add logging system, lock button, and emoji navigation

- Comprehensive logging system with chrome.storage.session persistence
- NIP-07 action logging in background scripts with standalone functions
- Vault operation logging (unlock, lock, create, reset, import, export)
- Profile and bookmark operation logging
- Logs page with refresh functionality and category icons
- Lock button (🔒) in navigation bar to quickly lock vault
- Reduced nav bar size (40px height, 16px font) with emoji icons
- Reordered navigation: You, Permissions, Bookmarks, Logs, About, Lock
- Bookmarks functionality for saving frequently used Nostr apps
- Fixed lock/unlock flow by properly clearing in-memory session data

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
2025-12-20 12:42:19 +01:00
parent b535a7b967
commit 45b1fb58e9
51 changed files with 1267 additions and 158 deletions

View File

@@ -1,7 +1,8 @@
import { Injectable } from '@angular/core';
import { inject, Injectable } from '@angular/core';
import { SimplePool } from 'nostr-tools/pool';
import { FALLBACK_PROFILE_RELAYS } from '../../constants/fallback-relays';
import { ProfileMetadata, ProfileMetadataCache } from '../storage/types';
import { LoggerService } from '../logger/logger.service';
// eslint-disable-next-line @typescript-eslint/no-explicit-any
declare const chrome: any;
@@ -14,6 +15,7 @@ const STORAGE_KEY = 'profileMetadataCache';
providedIn: 'root',
})
export class ProfileMetadataService {
readonly #logger = inject(LoggerService);
#cache: ProfileMetadataCache = {};
#pool: SimplePool | null = null;
#fetchPromises = new Map<string, Promise<ProfileMetadata | null>>();
@@ -52,7 +54,8 @@ export class ProfileMetadataService {
}
}
} catch (error) {
console.error('Failed to load profile cache from storage:', error);
const errorMsg = error instanceof Error ? error.message : 'Unknown error';
this.#logger.logStorageError('load profile cache', errorMsg);
}
}
@@ -65,7 +68,8 @@ export class ProfileMetadataService {
await chrome.storage.session.set({ [STORAGE_KEY]: this.#cache });
}
} catch (error) {
console.error('Failed to save profile cache to storage:', error);
const errorMsg = error instanceof Error ? error.message : 'Unknown error';
this.#logger.logStorageError('save profile cache', errorMsg);
}
}
@@ -209,7 +213,7 @@ export class ProfileMetadataService {
this.#cache[pubkey] = profile;
results.set(pubkey, profile);
} catch {
console.error(`Failed to parse profile for ${pubkey}`);
this.#logger.logProfileParseError(pubkey);
results.set(pubkey, null);
}
}
@@ -225,7 +229,8 @@ export class ProfileMetadataService {
await this.#saveCacheToStorage();
} catch (error) {
console.error('Failed to fetch profiles:', error);
const errorMsg = error instanceof Error ? error.message : 'Unknown error';
this.#logger.logProfileFetchError('multiple', errorMsg);
// Set null for all unfetched pubkeys on error
for (const pubkey of uncachedPubkeys) {
if (!results.has(pubkey)) {
@@ -283,11 +288,12 @@ export class ProfileMetadataService {
return profile;
} catch {
console.error(`Failed to parse profile content for ${pubkey}`);
this.#logger.logProfileParseError(pubkey);
return null;
}
} catch (error) {
console.error(`Failed to fetch profile for ${pubkey}:`, error);
const errorMsg = error instanceof Error ? error.message : 'Unknown error';
this.#logger.logProfileFetchError(pubkey, errorMsg);
return null;
}
}