feat: persistent multi-share configuration (shares.json + localStorage)

Daemon side:
- internal/shares: new package reads/writes shares.json next to identity
- proto: add ShareEntry type, add_share/remove_share/list_shares IPC commands,
  shares_list event, path field on FileEntry
- netmgr: load shares.json on startup; ScanAllShares combines legacy ShareDir
  with shares.json entries (recursive walk with relative paths)
- mesh: ScanFiles callback lets manager inject multi-share scanning without
  mesh knowing about shares.json
- ipc: handle add_share, remove_share, list_shares commands

Browser side:
- ShareManager component replaces FolderPicker: shows list of named shares
  with remove/re-pick buttons; persists share records to waste_shares in
  localStorage (name, global flag, networkId)
- FolderPicker retained for internal use; Sidebar now uses ShareManager

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Fredrik Johansson
2026-06-26 20:47:11 +02:00
parent 0f54f3bbad
commit e0704f210c
10 changed files with 366 additions and 4 deletions

View File

@@ -32,6 +32,11 @@ export interface FileEntry {
path?: string // relative path including filename, e.g. "docs/report.pdf"
}
export interface ShareEntry {
path: string
networks: string[] // ["*"] = global
}
export interface FileOffer {
xid: string
name: string
@@ -56,6 +61,9 @@ export type IpcMsgType =
| 'get_file_list'
| 'export_identity'
| 'import_identity'
| 'add_share'
| 'remove_share'
| 'list_shares'
// events
| 'state_snapshot'
| 'message_received'
@@ -71,6 +79,7 @@ export type IpcMsgType =
| 'invite_generated'
| 'identity_exported'
| 'identity_imported'
| 'shares_list'
| 'peer_status'
| 'error'
@@ -109,6 +118,8 @@ export interface IpcMessage {
error_message?: string
invite?: string
files?: FileEntry[]
shares?: ShareEntry[]
networks_filter?: string[] // for add_share
// peer_status
conn_state?: PeerConnState
candidate_type?: CandidateType