* attempt to fix https://github.com/hrkfdn/ncspot/issues/1358
mpris runs inside `tokio::runtime.spawn`. At some point it hits `metadata_changed->WebApi::track->api_with_retry`, which gets 401 response and tries to update the token.
This goes into `update_token`, which at a certain point calls *blocking* `token_rx.recv()`. Tokio runtime is not happy about that, as it uses the same thread for the `run_loop` in the worker. That's why `tokio::select!` doesn't work, we're essentially deadlocking, so the worker never pick up `RequestToken` command and `update_token` block forever.
Here I'm changing `update_token` to wrap `recv` in `spawn_blocking`, which makes `update_token` return a `JoinHandle`, on which the caller has to await. This doesn't work nicely in case of mpris though, as it is not an async function, and I don't know how to make it async as it goes through the dbus `metadata_changed` interface. My best effort here is to do `and_then`, which seems to work, but I'm not confident that's the right approach.
* fmt
* move token_rx.recv inside spawn_blocking
- Remove `expect` in favor of `unwrap` when the `Result`'s error variant
contains the info in the `expect` anyway (eg. when locking things).
The line number/context are given by the backtrace.
- Remove over-specification of types (`&T` instead of
`&RWReadLockGuard`)
- Put reused values into constants
- `FromStr` instead of manual function
- Change `if let Some(()) = ...` to `if T.is_some()`
* docs: small overall documentation improvements
- Add documentation comments to various items
- Change web API return types from bool/Option to Result
- Create helper functions with descriptive names instead of comments
- Remove redundant/confusing types
- Fix some documentation comments as instructed by `cargo doc`
- Rename variables to clear names
* docs: small fixes to the documentation update
Lots of small fixes to the APIs and functions in the `library` module,
mostly following best practices outlined in the Rust library guidelines.
Changes outside the `library` module were mostly required changes after
changing function signatures.
Move the Rust and Clippy linting options into the Cargo manifest and
share them with all the packages in the workspace. This ensures a
consistent style in all packages.
* chore: remove unnecessary asynchronous channel
The channel does not need to be asynchronous as the receiving end is
used in a blocking manner and the sending end of a regular channel never
blocks.
* Fix broken merge
---------
Co-authored-by: Henrik Friedrichsen <henrik@affekt.org>
Instead of crashing on Termux, no IPC socket is created. This is a
temporary solution until a suitable runtime directory for the Termux
platform can be found.
Tabs relied heavily on `ViewExt`'s `title()` function, while also
requiring a separate `id`. The `id`, if used, should be an internal part
of the struct and not part of its API. This also removes the hashmap as
it will never be faster than sequentially looking up all the names,
since there will most likely never be that many tabs in a `TabbedView`.
Cleans up the error messages generated when errors are encountered in
the configuration file. Instead of showing the raw error message, give
clear information about the problem.
* feat: add `info` command line subcommand
Adding an info command allows the documentation to refer to it when
mentioning platform specific information. This gives users a nicer
experience since they don't need to think about how `ncspot` will behave
on their system, but can run `ncspot info` to get that information.
* fix: info command don't create runtime directory
* fix: don't print runtime path on Windows
Windows doesn't use the runtime path so it shouldn't be printed there.
* fix: make `info` command easier to parse
* docs: add back the default configuration directory
Each user has their own runtime directory at `/run/user/<uid>`. Creating
the IPC socket in there makes sure it is cleaned up regardless of
whether `ncspot` exits normally.
BREAKING CHANGE: move IPC socket location
This fixes a bug that would cause a panic when quiting the process
normally. `tokio::select!()` was used to await a single branch, which is
useless as it can be replaced by a normal await.
Instead of trying to handle signals for every step of the `cursive`
event loop, move the signal handling into its own asynchronous task and
send callbacks to `cursive` when a signal arrives.
The `lazy_static` crate was superseded by the `once_cell` crate which
has been included in Rust's standard library since version `1.70`.
Remove the `lazy_static` dependency and refactor all use cases to use
`std::sync::OnceLock` instead.
Co-authored-by: Henrik Friedrichsen <henrik@affekt.org>
Clippy's `use_self` line ensures that `Self` is used instead of the real
name whenever possible. This makes searching easier and cleans up the
code a bit.
* Add command for adding song to playlist
* edits for code style
* Return playlist dialog via `CommandResult::Modal`
---------
Co-authored-by: Henrik Friedrichsen <henrik@affekt.org>
- Show error on deletion, as we currently do not have a Uri we can pass to the
Spotify API to delete local files in playlists
- Mark local files in `ListView`
fixes#1213
* Sorting QoL
Ignore leading "The" when sorting albums and artists by artist name
in the library.
* Simplify stripping of `The ` prefix in artist
---------
Co-authored-by: Henrik Friedrichsen <henrik@affekt.org>
The `screenchange` member variable on `Layout` didn't seem to be used
for anything except for debugging. A comment in `on_layout` makes it
seem like it wasn't meant to be used for debugging purposes but for
actual functionality that wasn't implemented.
After refactoring layout, the if statements were removed in favor of a
single match. This changed the control flow a bit, breaking mouse event
propagation.