Release v1.0.8 - Add wallet tab and UI improvements

- Add new wallet tab with placeholder for future functionality
- Reorder bottom tabs: You, Identities, Wallet, Bookmarks, Settings
- Move Reset Extension button to bottom-right corner on login page
- Improve header layout consistency across all pages
- Add custom scrollbar styling for Chrome (thin, dark track, light thumb)
- Update edit button to use emoji icon on identity page
- Fix horizontal overflow issues in global styles

Files modified:
- package.json (version bump)
- projects/{chrome,firefox}/src/app/app.routes.ts (wallet route)
- projects/{chrome,firefox}/src/app/components/home/wallet/* (new)
- projects/{chrome,firefox}/src/app/components/home/home.component.* (tabs)
- projects/{chrome,firefox}/src/app/components/vault-login/* (reset btn)
- projects/{chrome,firefox}/src/styles.scss (scrollbar, overflow)
- Various component HTML/SCSS files (header consistency)

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
woikos
2025-12-21 07:30:55 +01:00
parent 2c1f3265b7
commit 3750e99e61
37 changed files with 344 additions and 117 deletions

View File

@@ -1,12 +1,12 @@
{ {
"name": "plebeian-signer", "name": "plebeian-signer",
"version": "v1.0.7", "version": "v1.0.8",
"custom": { "custom": {
"chrome": { "chrome": {
"version": "v1.0.7" "version": "v1.0.8"
}, },
"firefox": { "firefox": {
"version": "v1.0.7" "version": "v1.0.8"
} }
}, },
"scripts": { "scripts": {

View File

@@ -2,7 +2,7 @@
"manifest_version": 3, "manifest_version": 3,
"name": "Plebeian Signer - Nostr Identity Manager & Signer", "name": "Plebeian Signer - Nostr Identity Manager & Signer",
"description": "Manage and switch between multiple identities while interacting with Nostr apps", "description": "Manage and switch between multiple identities while interacting with Nostr apps",
"version": "1.0.7", "version": "1.0.8",
"homepage_url": "https://git.mleku.dev/mleku/plebeian-signer", "homepage_url": "https://git.mleku.dev/mleku/plebeian-signer",
"options_page": "options.html", "options_page": "options.html",
"permissions": [ "permissions": [

View File

@@ -11,6 +11,7 @@ import { InfoComponent } from './components/home/info/info.component';
import { SettingsComponent } from './components/home/settings/settings.component'; import { SettingsComponent } from './components/home/settings/settings.component';
import { LogsComponent } from './components/home/logs/logs.component'; import { LogsComponent } from './components/home/logs/logs.component';
import { BookmarksComponent } from './components/home/bookmarks/bookmarks.component'; import { BookmarksComponent } from './components/home/bookmarks/bookmarks.component';
import { WalletComponent } from './components/home/wallet/wallet.component';
import { NewIdentityComponent } from './components/new-identity/new-identity.component'; import { NewIdentityComponent } from './components/new-identity/new-identity.component';
import { EditIdentityComponent } from './components/edit-identity/edit-identity.component'; import { EditIdentityComponent } from './components/edit-identity/edit-identity.component';
import { HomeComponent as EditIdentityHomeComponent } from './components/edit-identity/home/home.component'; import { HomeComponent as EditIdentityHomeComponent } from './components/edit-identity/home/home.component';
@@ -76,6 +77,10 @@ export const routes: Routes = [
path: 'bookmarks', path: 'bookmarks',
component: BookmarksComponent, component: BookmarksComponent,
}, },
{
path: 'wallet',
component: WalletComponent,
},
], ],
}, },
{ {

View File

@@ -5,8 +5,8 @@
<span class="emoji">🔒</span> <span class="emoji">🔒</span>
</button> </button>
<span>Bookmarks</span> <span>Bookmarks</span>
<button class="action-btn btn btn-primary btn-sm" (click)="onBookmarkThisPage()"> <button class="add-btn" title="Bookmark This Page" (click)="onBookmarkThisPage()">
<span class="emoji">🔖</span> Bookmark This Page <span class="emoji"></span>
</button> </button>
</div> </div>

View File

@@ -15,9 +15,26 @@
margin-bottom: var(--size); margin-bottom: var(--size);
flex-shrink: 0; flex-shrink: 0;
.action-btn { .add-btn {
position: absolute; position: absolute;
right: 0; right: 0;
background: transparent;
border: none;
padding: 8px;
cursor: pointer;
display: flex;
align-items: center;
justify-content: center;
border-radius: 4px;
transition: background-color 0.2s;
&:hover {
background-color: var(--background-light);
}
.emoji {
font-size: 20px;
}
} }
} }
} }

View File

@@ -3,34 +3,23 @@
</div> </div>
<div class="tabs"> <div class="tabs">
<a <a class="tab" routerLink="/home/identity" routerLinkActive="active" title="You">
class="tab"
routerLink="/home/identity"
routerLinkActive="active"
title="Your selected identity"
>
<span class="emoji">👤</span> <span class="emoji">👤</span>
</a> </a>
<a <a class="tab" routerLink="/home/identities" routerLinkActive="active" title="Identities">
class="tab"
routerLink="/home/identities"
routerLinkActive="active"
title="Identities"
>
<span class="emoji">👥</span> <span class="emoji">👥</span>
</a> </a>
<a <a class="tab" routerLink="/home/wallet" routerLinkActive="active" title="Wallet">
class="tab" <span class="emoji">💰</span>
routerLink="/home/settings"
routerLinkActive="active"
title="Settings"
>
<span class="emoji">⚙️</span>
</a> </a>
<a class="tab" routerLink="/home/bookmarks" routerLinkActive="active" title="Bookmarks"> <a class="tab" routerLink="/home/bookmarks" routerLinkActive="active" title="Bookmarks">
<span class="emoji">🔖</span> <span class="emoji">🔖</span>
</a> </a>
<a class="tab" routerLink="/home/settings" routerLinkActive="active" title="Settings">
<span class="emoji">⚙️</span>
</a>
</div> </div>

View File

@@ -4,12 +4,12 @@
flex-direction: column; flex-direction: column;
.tab-content { .tab-content {
height: calc(100% - 40px); height: calc(100% - 48px);
} }
.tabs { .tabs {
height: 40px; height: 48px;
min-height: 40px; min-height: 48px;
background: var(--background-light); background: var(--background-light);
display: flex; display: flex;
flex-direction: row; flex-direction: row;
@@ -23,7 +23,6 @@
display: flex; display: flex;
align-items: center; align-items: center;
justify-content: center; justify-content: center;
font-size: 16px;
color: var(--muted-foreground); color: var(--muted-foreground);
border-top: 2px solid transparent; border-top: 2px solid transparent;
@@ -31,6 +30,10 @@
cursor: pointer; cursor: pointer;
.emoji {
font-size: 20px;
}
&:hover { &:hover {
background: var(--background-light-hover); background: var(--background-light-hover);
color: var(--foreground); color: var(--foreground);

View File

@@ -6,11 +6,8 @@
</button> </button>
<span class="text">Identities</span> <span class="text">Identities</span>
<button class="button btn btn-primary btn-sm" (click)="onClickNewIdentity()"> <button class="add-btn" title="New Identity" (click)="onClickNewIdentity()">
<div class="sam-flex-row gap-h"> <span class="emoji"></span>
<i class="bi bi-plus-lg"></i>
<span>New</span>
</div>
</button> </button>
</div> </div>

View File

@@ -19,9 +19,9 @@
background: var(--background); background: var(--background);
position: relative; position: relative;
.lock-btn { .lock-btn,
.add-btn {
position: absolute; position: absolute;
left: 0;
background: transparent; background: transparent;
border: none; border: none;
padding: 8px; padding: 8px;
@@ -41,8 +41,11 @@
} }
} }
.button { .lock-btn {
position: absolute; left: 0;
}
.add-btn {
right: 0; right: 0;
} }

View File

@@ -6,7 +6,7 @@
</button> </button>
<span>You</span> <span>You</span>
<button class="edit-btn" title="Edit profile" (click)="onClickEditProfile()"> <button class="edit-btn" title="Edit profile" (click)="onClickEditProfile()">
<img src="edit.svg" alt="Edit" class="edit-icon" /> <span class="emoji">📝</span>
</button> </button>
</div> </div>

View File

@@ -21,10 +21,8 @@
background-color: var(--background-light); background-color: var(--background-light);
} }
.edit-icon { .emoji {
width: 20px; font-size: 20px;
height: 20px;
filter: brightness(0) invert(1);
} }
} }
} }

View File

@@ -4,8 +4,8 @@
</button> </button>
<span>Logs</span> <span>Logs</span>
<div class="logs-actions"> <div class="logs-actions">
<button class="btn btn-sm btn-secondary" (click)="onRefresh()">Refresh</button> <button class="btn btn-sm btn-secondary" title="Refresh logs" (click)="onRefresh()">Refresh</button>
<button class="btn btn-sm btn-secondary" (click)="onClear()">Clear</button> <button class="btn btn-sm btn-secondary" title="Clear logs" (click)="onClear()">Clear</button>
</div> </div>
</div> </div>

View File

@@ -0,0 +1,14 @@
<div class="sam-text-header">
<button class="lock-btn" title="Lock" (click)="onClickLock()">
<span class="emoji">🔒</span>
</button>
<span>Wallet</span>
</div>
<div class="wallet-container">
<div class="empty-state">
<span class="sam-text-muted">
Wallet functionality coming soon.
</span>
</div>
</div>

View File

@@ -0,0 +1,32 @@
:host {
height: 100%;
display: flex;
flex-direction: column;
padding-top: var(--size);
padding-bottom: var(--size);
overflow: hidden;
> *:not(.sam-text-header) {
margin-left: var(--size);
margin-right: var(--size);
}
.sam-text-header {
margin-bottom: var(--size);
flex-shrink: 0;
}
}
.wallet-container {
flex: 1;
overflow-y: auto;
}
.empty-state {
flex: 1;
display: flex;
align-items: center;
justify-content: center;
text-align: center;
color: var(--muted-foreground);
}

View File

@@ -0,0 +1,21 @@
import { Component, inject } from '@angular/core';
import { Router } from '@angular/router';
import { LoggerService, StorageService } from '@common';
@Component({
selector: 'app-wallet',
templateUrl: './wallet.component.html',
styleUrl: './wallet.component.scss',
imports: [],
})
export class WalletComponent {
readonly #logger = inject(LoggerService);
readonly #storage = inject(StorageService);
readonly #router = inject(Router);
async onClickLock() {
this.#logger.logVaultLock();
await this.#storage.lockVault();
this.#router.navigateByUrl('/vault-login');
}
}

View File

@@ -43,9 +43,11 @@
<span>Sign in</span> <span>Sign in</span>
</div> </div>
</button> </button>
</div>
</div>
<button <button
class="sam-mt" class="reset-btn"
(click)=" (click)="
confirm.show( confirm.show(
'Do you really want to reset the extension? All data will be lost.', 'Do you really want to reset the extension? All data will be lost.',
@@ -53,12 +55,9 @@
) )
" "
type="button" type="button"
class="btn btn-link"
> >
Reset Extension Reset Extension
</button> </button>
</div>
</div>
<!-----------> <!----------->
<!-- ALERT --> <!-- ALERT -->

View File

@@ -3,6 +3,7 @@
display: flex; display: flex;
flex-direction: column; flex-direction: column;
justify-items: center; justify-items: center;
position: relative;
.logo-frame { .logo-frame {
border: 2px solid var(--secondary); border: 2px solid var(--secondary);
@@ -16,4 +17,21 @@
justify-content: center; justify-content: center;
padding: 0 var(--size) var(--size) var(--size); padding: 0 var(--size) var(--size) var(--size);
} }
.reset-btn {
position: absolute;
bottom: var(--size);
right: var(--size);
background: transparent;
border: none;
color: var(--muted-foreground);
font-size: 0.75rem;
cursor: pointer;
padding: 4px 8px;
&:hover {
color: var(--foreground);
text-decoration: underline;
}
}
} }

View File

@@ -18,6 +18,7 @@ body {
background: var(--background); background: var(--background);
margin: 0; margin: 0;
overflow: hidden;
} }
// Button styling to match market // Button styling to match market
@@ -128,3 +129,35 @@ button {
.modal-body { .modal-body {
color: #fafafa; color: #fafafa;
} }
// Custom scrollbar styling for Chrome
* {
// Thin scrollbar
&::-webkit-scrollbar {
width: 6px;
}
// Track - black background, transparent by default
&::-webkit-scrollbar-track {
background: transparent;
}
// Thumb - white, transparent by default
&::-webkit-scrollbar-thumb {
background: transparent;
border-radius: 3px;
}
// Show scrollbar on hover over scrollable area
&:hover::-webkit-scrollbar-track {
background: #1a1a1a;
}
&:hover::-webkit-scrollbar-thumb {
background: rgba(255, 255, 255, 0.5);
}
&::-webkit-scrollbar-thumb:hover {
background: rgba(255, 255, 255, 0.7);
}
}

View File

@@ -2,7 +2,7 @@
"manifest_version": 3, "manifest_version": 3,
"name": "Plebeian Signer", "name": "Plebeian Signer",
"description": "Nostr Identity Manager & Signer", "description": "Nostr Identity Manager & Signer",
"version": "1.0.7", "version": "1.0.8",
"homepage_url": "https://git.mleku.dev/mleku/plebeian-signer", "homepage_url": "https://git.mleku.dev/mleku/plebeian-signer",
"options_page": "options.html", "options_page": "options.html",
"permissions": [ "permissions": [

View File

@@ -8,6 +8,7 @@ import { InfoComponent } from './components/home/info/info.component';
import { SettingsComponent } from './components/home/settings/settings.component'; import { SettingsComponent } from './components/home/settings/settings.component';
import { LogsComponent } from './components/home/logs/logs.component'; import { LogsComponent } from './components/home/logs/logs.component';
import { BookmarksComponent } from './components/home/bookmarks/bookmarks.component'; import { BookmarksComponent } from './components/home/bookmarks/bookmarks.component';
import { WalletComponent } from './components/home/wallet/wallet.component';
import { NewIdentityComponent } from './components/new-identity/new-identity.component'; import { NewIdentityComponent } from './components/new-identity/new-identity.component';
import { EditIdentityComponent } from './components/edit-identity/edit-identity.component'; import { EditIdentityComponent } from './components/edit-identity/edit-identity.component';
import { HomeComponent as EditIdentityHomeComponent } from './components/edit-identity/home/home.component'; import { HomeComponent as EditIdentityHomeComponent } from './components/edit-identity/home/home.component';
@@ -76,6 +77,10 @@ export const routes: Routes = [
path: 'bookmarks', path: 'bookmarks',
component: BookmarksComponent, component: BookmarksComponent,
}, },
{
path: 'wallet',
component: WalletComponent,
},
], ],
}, },
{ {

View File

@@ -5,8 +5,8 @@
<span class="emoji">🔒</span> <span class="emoji">🔒</span>
</button> </button>
<span>Bookmarks</span> <span>Bookmarks</span>
<button class="action-btn btn btn-primary btn-sm" (click)="onBookmarkThisPage()"> <button class="add-btn" title="Bookmark This Page" (click)="onBookmarkThisPage()">
<span class="emoji">🔖</span> Bookmark This Page <span class="emoji"></span>
</button> </button>
</div> </div>

View File

@@ -15,9 +15,26 @@
margin-bottom: var(--size); margin-bottom: var(--size);
flex-shrink: 0; flex-shrink: 0;
.action-btn { .add-btn {
position: absolute; position: absolute;
right: 0; right: 0;
background: transparent;
border: none;
padding: 8px;
cursor: pointer;
display: flex;
align-items: center;
justify-content: center;
border-radius: 4px;
transition: background-color 0.2s;
&:hover {
background-color: var(--background-light);
}
.emoji {
font-size: 20px;
}
} }
} }
} }

View File

@@ -3,34 +3,23 @@
</div> </div>
<div class="tabs"> <div class="tabs">
<a <a class="tab" routerLink="/home/identity" routerLinkActive="active" title="You">
class="tab"
routerLink="/home/identity"
routerLinkActive="active"
title="Your selected identity"
>
<span class="emoji">👤</span> <span class="emoji">👤</span>
</a> </a>
<a <a class="tab" routerLink="/home/identities" routerLinkActive="active" title="Identities">
class="tab"
routerLink="/home/identities"
routerLinkActive="active"
title="Identities"
>
<span class="emoji">👥</span> <span class="emoji">👥</span>
</a> </a>
<a <a class="tab" routerLink="/home/wallet" routerLinkActive="active" title="Wallet">
class="tab" <span class="emoji">💰</span>
routerLink="/home/settings"
routerLinkActive="active"
title="Settings"
>
<span class="emoji">⚙️</span>
</a> </a>
<a class="tab" routerLink="/home/bookmarks" routerLinkActive="active" title="Bookmarks"> <a class="tab" routerLink="/home/bookmarks" routerLinkActive="active" title="Bookmarks">
<span class="emoji">🔖</span> <span class="emoji">🔖</span>
</a> </a>
<a class="tab" routerLink="/home/settings" routerLinkActive="active" title="Settings">
<span class="emoji">⚙️</span>
</a>
</div> </div>

View File

@@ -4,12 +4,12 @@
flex-direction: column; flex-direction: column;
.tab-content { .tab-content {
height: calc(100% - 40px); height: calc(100% - 48px);
} }
.tabs { .tabs {
height: 40px; height: 48px;
min-height: 40px; min-height: 48px;
background: var(--background-light); background: var(--background-light);
display: flex; display: flex;
flex-direction: row; flex-direction: row;
@@ -23,7 +23,6 @@
display: flex; display: flex;
align-items: center; align-items: center;
justify-content: center; justify-content: center;
font-size: 16px;
color: var(--muted-foreground); color: var(--muted-foreground);
border-top: 2px solid transparent; border-top: 2px solid transparent;
@@ -31,6 +30,10 @@
cursor: pointer; cursor: pointer;
.emoji {
font-size: 20px;
}
&:hover { &:hover {
background: var(--background-light-hover); background: var(--background-light-hover);
color: var(--foreground); color: var(--foreground);

View File

@@ -6,11 +6,8 @@
</button> </button>
<span class="text">Identities</span> <span class="text">Identities</span>
<button class="button btn btn-primary btn-sm" (click)="onClickNewIdentity()"> <button class="add-btn" title="New Identity" (click)="onClickNewIdentity()">
<div class="sam-flex-row gap-h"> <span class="emoji"></span>
<i class="bi bi-plus-lg"></i>
<span>New</span>
</div>
</button> </button>
</div> </div>

View File

@@ -19,9 +19,9 @@
background: var(--background); background: var(--background);
position: relative; position: relative;
.lock-btn { .lock-btn,
.add-btn {
position: absolute; position: absolute;
left: 0;
background: transparent; background: transparent;
border: none; border: none;
padding: 8px; padding: 8px;
@@ -41,8 +41,11 @@
} }
} }
.button { .lock-btn {
position: absolute; left: 0;
}
.add-btn {
right: 0; right: 0;
} }

View File

@@ -6,7 +6,7 @@
</button> </button>
<span>You</span> <span>You</span>
<button class="edit-btn" title="Edit profile" (click)="onClickEditProfile()"> <button class="edit-btn" title="Edit profile" (click)="onClickEditProfile()">
<img src="edit.svg" alt="Edit" class="edit-icon" /> <span class="emoji">📝</span>
</button> </button>
</div> </div>

View File

@@ -21,10 +21,8 @@
background-color: var(--background-light); background-color: var(--background-light);
} }
.edit-icon { .emoji {
width: 20px; font-size: 20px;
height: 20px;
filter: brightness(0) invert(1);
} }
} }
} }

View File

@@ -4,8 +4,8 @@
</button> </button>
<span>Logs</span> <span>Logs</span>
<div class="logs-actions"> <div class="logs-actions">
<button class="btn btn-sm btn-secondary" (click)="onRefresh()">Refresh</button> <button class="btn btn-sm btn-secondary" title="Refresh logs" (click)="onRefresh()">Refresh</button>
<button class="btn btn-sm btn-secondary" (click)="onClear()">Clear</button> <button class="btn btn-sm btn-secondary" title="Clear logs" (click)="onClear()">Clear</button>
</div> </div>
</div> </div>

View File

@@ -0,0 +1,14 @@
<div class="sam-text-header">
<button class="lock-btn" title="Lock" (click)="onClickLock()">
<span class="emoji">🔒</span>
</button>
<span>Wallet</span>
</div>
<div class="wallet-container">
<div class="empty-state">
<span class="sam-text-muted">
Wallet functionality coming soon.
</span>
</div>
</div>

View File

@@ -0,0 +1,32 @@
:host {
height: 100%;
display: flex;
flex-direction: column;
padding-top: var(--size);
padding-bottom: var(--size);
overflow: hidden;
> *:not(.sam-text-header) {
margin-left: var(--size);
margin-right: var(--size);
}
.sam-text-header {
margin-bottom: var(--size);
flex-shrink: 0;
}
}
.wallet-container {
flex: 1;
overflow-y: auto;
}
.empty-state {
flex: 1;
display: flex;
align-items: center;
justify-content: center;
text-align: center;
color: var(--muted-foreground);
}

View File

@@ -0,0 +1,21 @@
import { Component, inject } from '@angular/core';
import { Router } from '@angular/router';
import { LoggerService, StorageService } from '@common';
@Component({
selector: 'app-wallet',
templateUrl: './wallet.component.html',
styleUrl: './wallet.component.scss',
imports: [],
})
export class WalletComponent {
readonly #logger = inject(LoggerService);
readonly #storage = inject(StorageService);
readonly #router = inject(Router);
async onClickLock() {
this.#logger.logVaultLock();
await this.#storage.lockVault();
this.#router.navigateByUrl('/vault-login');
}
}

View File

@@ -43,9 +43,11 @@
<span>Sign in</span> <span>Sign in</span>
</div> </div>
</button> </button>
</div>
</div>
<button <button
class="sam-mt" class="reset-btn"
(click)=" (click)="
confirm.show( confirm.show(
'Do you really want to reset the extension? All data will be lost.', 'Do you really want to reset the extension? All data will be lost.',
@@ -53,12 +55,9 @@
) )
" "
type="button" type="button"
class="btn btn-link"
> >
Reset Extension Reset Extension
</button> </button>
</div>
</div>
<!-----------> <!----------->
<!-- ALERT --> <!-- ALERT -->

View File

@@ -3,6 +3,7 @@
display: flex; display: flex;
flex-direction: column; flex-direction: column;
justify-items: center; justify-items: center;
position: relative;
.logo-frame { .logo-frame {
border: 2px solid var(--secondary); border: 2px solid var(--secondary);
@@ -16,4 +17,21 @@
justify-content: center; justify-content: center;
padding: 0 var(--size) var(--size) var(--size); padding: 0 var(--size) var(--size) var(--size);
} }
.reset-btn {
position: absolute;
bottom: var(--size);
right: var(--size);
background: transparent;
border: none;
color: var(--muted-foreground);
font-size: 0.75rem;
cursor: pointer;
padding: 4px 8px;
&:hover {
color: var(--foreground);
text-decoration: underline;
}
}
} }

View File

@@ -18,6 +18,7 @@ body {
background: var(--background); background: var(--background);
margin: 0; margin: 0;
overflow: hidden;
} }
// Button styling to match market // Button styling to match market
@@ -128,3 +129,4 @@ button {
.modal-body { .modal-body {
color: #fafafa; color: #fafafa;
} }