This commit also removes the majority of the playback widget,
though most of it's code will make it to the PlayerWidget once
it starts to get wired to the gtreamer_plaer::Player.
Previously each time we wanted to inspect the `Progress` struct we
were blocking which was problematic since the downloader also wants
to block to update it.
Now we use try_lock() and if a lock can't be aquired we requeue another
callback. That way we can also be way more aggressive about the interval
in whihc it the callbacks will run.
If an episode is being downloaded we setup a callback that will
supervise the widget and update it's state once the download action is
completed and the episode rowid is removed from `manager::ACTIVEDOWNLOADS`.
The size might be provided by the rss feed but not alwasy. Additionally it might be
missleading so when a download starts we replace the label with the
HTTP ContentLength header.
State machines were a fun experiement but a nightmare to deal with
after the fact. This is the first steps for a refactor in a tradition
style with the goal to ultimatly making it easy to and port to relm.
This code is ugly and terrible but it works™. Previsously when a download
would finish it would refresh all the views. Now the if the widget get's
into the Donwloading state, it will setup a callback that will check
periodicly if it's still downloading and update the widget state when
the episode stops downloading.
Since gtk Widgets are not Send, and the callbacks all run in the gtk
main loop, it *should* not be possible that 2 things try to access the
same widget at the same time.
It was only used to call the podcast.id() method. This allows EpisodeViewWidget
to be created whithout the need for a call to the database to get a Podcst
Object for each widget.
When iteration of data is finished, None will be returned and
the or_else() block will be executed. Now a callback can be
passed that will be executd when the iteration/loading finishes.
If you clicked unsub, then undo and then the same show widget you
would navigated to the previous ShowWidget and the unsub button
would still be insensitive.
Previously we would refresh all the views when download/cancel
button was clicked. This was done mainly to avoid zombie widget bugs
that would arise from shared state.
Now we still refresh all the background views but not the visible one.
Instead the widget has the reponsibility of recalculating it's state.
make the data: Vec<T> mutable, then reverse the vector
so it can be used as a stack, and then use the ::pop()
method to retrieve the item.
This also avoid the constrain for Clone on T.
Instead of stipping all the html tags and just using the text
in the label we could *try* converting it to pango markup
which is a bit more flexible than plain text.
The code was copied from Fractal.
Requires a gtk::Image as argument now, it sets the pixbuf to the
img directly instead of returning it.
New name is set_image_from_path.
This is ground work so we can later keep the image reference, and
use it to set the image with a callback.
The state machines are not send and the code is sequnecial.
We only need `&mut machine` refference to pass to `take_mut::take`
to change the state of the machine. In 2/3 cases we can even use
`.get_mut()` method and even avoid the dynamic borrow checks at
runtime. For the `TitleMachine` The only thing that will hold
a refference to it after initialization will be the play_button
callback. So it's justifiable to use `RefCell` insetead of a `Mutex`.
`DateMachine` and `DurationMachine` are only mutated during initialization
and thus do not need shared ownership.
`TitleMachine` is only mutated during initialization and after that only
the callback will keep holding a referrence to it. The `EpisodeWidget`s
get dropped after initialization. So it's justifiable to use `Rc<Mutex<T>>`
instead of `Arc`.
At first I tried creating custom InAppNotifications and send
them to the main loop to be added. That does not work sicne gtk
widgets are not thread safe. For now we can try having Action messages
that create them on demand. As oppose to create first then pass them.