<label>Musicfolder<divclassName="folder-field"><inputrequiredreadOnlyplaceholder="Choose the folder that holds your music"value={localSetup.musicFolder}/><buttontype="button"className="button-secondary"onClick={pickMusicFolder}><FolderOpensize={16}/>Choosefolder</button></div></label>
<label>Localpassword<inputtype="password"requiredminLength={8}autoComplete="new-password"placeholder="At least 8 characters"value={localSetup.password}onChange={(event)=>setLocalSetup({...localSetup,password: event.target.value})}/><smallclassName="field-hint">Usedonlytoprotecttheprivatelibraryonthiscomputer.Itstaysinmemoryforthissession.</small></label>
<label>Librarypassword<inputtype="password"requiredminLength={8}autoComplete="current-password"placeholder="At least 8 characters"value={localSetup.password}onChange={(event)=>setLocalSetup({...localSetup,password: event.target.value})}/><smallclassName="field-hint">Savedinyouroperatingsystemcredentialstoreandusedbyyourothermusicapps.</small></label>
<divclassName="privacy-note"><Disc3size={22}/><div><strong>{sourceMode==="local"?"Private by default":"Your server stays yours"}</strong><p>{sourceMode==="local"?"The managed server binds to 127.0.0.1, keeps its database in Resonant’s app data, and stops when Resonant closes.":"Resonant speaks OpenSubsonic directly. Your password stays in memory for this session."}</p></div></div>
<divclassName="privacy-note"><Disc3size={22}/><div><strong>{sourceMode==="local"?"Available on your private network":"Your server stays yours"}</strong><p>{sourceMode==="local"?"The managed server accepts devices on your LAN, keeps its database in Resonant’s app data, and stops when Resonant closes. Avoid exposing port 4533 directly to the internet.":"Resonant speaks OpenSubsonic directly and saves the password in your operating system credential store."}</p></div></div>
</section>
):(
<divclassName="library-view">
@@ -346,14 +395,14 @@ export default function App() {
<divclassName="section-heading"><div><spanclassName="eyebrow">{query?"Matching your search":view==="albums"?"The full shelf":"Back in rotation"}</span><h2id="albums-heading">{view==="favorites"?"Loved records":query?"Albums":"Recently added"}</h2></div><buttontype="button"onClick={()=>goTo("albums")}>Viewall<ChevronRightsize={16}/></button></div>
{visibleAlbums.length?<divclassName="album-grid">{visibleAlbums.slice(0,view==="albums"||query?18 : 6).map((album)=>{constfirstTrack=libraryTracks.find((track)=>track.albumId===album.id);return<articleclassName="album-tile"key={album.id}><buttonclassName="cover-button"type="button"aria-label={`Play ${album.title}`}onClick={()=>firstTrack&&player.play(firstTrack)}><Coveralbum={album}/><spanclassName="cover-play"><Playsize={20}fill="currentColor"/></span></button><div><h3>{album.title}</h3><p>{album.artist}·{album.year||"Unknown year"}</p></div><IconButtonlabel={`More options for ${album.title}`}><Ellipsissize={18}/></IconButton></article>;})}</div>:<divclassName="empty-state"><Searchsize={26}/><h3>Noalbumsfound</h3><p>Tryatitle,artist,ortrackname.</p></div>}
</section>
{visibleAlbums.length?<divclassName="album-grid">{visibleAlbums.slice(0,view==="albums"||query?visibleAlbums.length : 6).map((album)=>{constfirstTrack=libraryTracks.find((track)=>track.albumId===album.id);return<articleclassName="album-tile"key={album.id}><buttonclassName="cover-button"type="button"aria-label={`Play ${album.title}`}onClick={()=>firstTrack&&player.play(firstTrack)}><Coveralbum={album}/><spanclassName="cover-play"><Playsize={20}fill="currentColor"/></span></button><div><h3>{album.title}</h3><p>{album.artist}·{album.year||"Unknown year"}</p></div><IconButtonlabel={`More options for ${album.title}`}><Ellipsissize={18}/></IconButton></article>;})}</div>:<divclassName="empty-state"><Searchsize={26}/><h3>Noalbumsfound</h3><p>Tryatitle,artist,ortrackname.</p></div>}
<divclassName="track-list"role="list">{visibleTracks.slice(0,view==="home"&&!query?6 : 30).map((track,index)=><divclassName={`track-row ${player.current.id===track.id?"is-current":""}`}role="listitem"key={track.id}><buttonclassName="track-main"type="button"onClick={()=>player.play(track)}><spanclassName="track-number">{player.current.id===track.id&&player.isPlaying?<AudioLinessize={15}/>:String(index+1).padStart(2,"0")}</span><Coveralbum={track}size="small"/><span><strong>{track.title}</strong><small>{track.artist}</small></span></button><spanclassName="track-album">{track.album}</span><IconButtonlabel={favorites.has(track.id)?`Remove ${track.title} from favorites`:`Add ${track.title} to favorites`}active={favorites.has(track.id)}onClick={()=>toggleFavorite(track.id)}><Heartsize={16}fill={favorites.has(track.id)?"currentColor":"none"}/></IconButton><spanclassName="track-time">{formatTime(track.duration)}</span><IconButtonlabel={`Add ${track.title} to queue`}onClick={()=>player.addToQueue(track)}><Plussize={17}/></IconButton></div>)}</div>
<divclassName="track-list"role="list">{visibleTracks.slice(0,view==="songs"?visibleTracks.length : view==="home"&&!query?6 : 30).map((track,index)=><divclassName={`track-row ${player.current.id===track.id?"is-current":""}`}role="listitem"key={track.id}><buttonclassName="track-main"type="button"onClick={()=>player.play(track)}><spanclassName="track-number">{player.current.id===track.id&&player.isPlaying?<AudioLinessize={15}/>:String(index+1).padStart(2,"0")}</span><Coveralbum={track}size="small"/><span><strong>{track.title}</strong><small>{track.artist}</small></span></button><spanclassName="track-album">{track.album}</span><IconButtonlabel={favorites.has(track.id)?`Remove ${track.title} from favorites`:`Add ${track.title} to favorites`}active={favorites.has(track.id)}onClick={()=>toggleFavorite(track.id)}><Heartsize={16}fill={favorites.has(track.id)?"currentColor":"none"}/></IconButton><spanclassName="track-time">{formatTime(track.duration)}</span><IconButtonlabel={`Add ${track.title} to queue`}onClick={()=>player.addToQueue(track)}><Plussize={17}/></IconButton></div>)}</div>
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.