From a0ca36756b1aec5c59e8f6cf2028982c2afcee14 Mon Sep 17 00:00:00 2001 From: "Timothy Z." Date: Thu, 3 Oct 2024 14:11:30 +0300 Subject: [PATCH 01/44] feat: streaming-server urls bucket --- src/constants.rs | 3 + src/models/streaming_server.rs | 54 +++++++-- src/types/streaming_server/mod.rs | 6 + .../streaming_server/server_url_bucket.rs | 108 ++++++++++++++++++ src/types/streaming_server/server_url_item.rs | 26 +++++ stremio-core-web/src/model/model.rs | 15 ++- .../src/model/serialize_discover.rs | 4 +- .../src/model/serialize_meta_details.rs | 12 +- .../src/model/serialize_player.rs | 6 +- .../src/model/serialize_streaming_server.rs | 6 +- 10 files changed, 214 insertions(+), 26 deletions(-) create mode 100644 src/types/streaming_server/server_url_bucket.rs create mode 100644 src/types/streaming_server/server_url_item.rs diff --git a/src/constants.rs b/src/constants.rs index a778df3a0..710bce63a 100644 --- a/src/constants.rs +++ b/src/constants.rs @@ -29,6 +29,9 @@ pub const CATALOG_PREVIEW_SIZE: usize = 100; pub const LIBRARY_RECENT_COUNT: usize = 200; pub const NOTIFICATION_ITEMS_COUNT: usize = 100; +pub const SERVER_URL_BUCKET_MAX_ITEMS: usize = 5; +pub const SERVER_URL_BUCKET_DEFAULT_ITEM_ID: &str = "0"; + /// A `LibraryItem` is considered watched once we've watched more than the `duration * threshold`: /// /// `LibraryItem.state.time_watched` > `LibraryItem.state.duration` * [`WATCHED_THRESHOLD_COEF`] diff --git a/src/models/streaming_server.rs b/src/models/streaming_server.rs index 5dc04be84..d6e426217 100644 --- a/src/models/streaming_server.rs +++ b/src/models/streaming_server.rs @@ -19,7 +19,8 @@ use crate::types::empty_string_as_null; use crate::types::profile::{AuthKey, Profile}; use crate::types::streaming_server::{ CreateMagnetRequest, CreateTorrentBlobRequest, DeviceInfo, GetHTTPSResponse, NetworkInfo, - Settings, SettingsResponse, Statistics, StatisticsRequest, TorrentStatisticsRequest, + ServerUrlBucket, Settings, SettingsResponse, Statistics, StatisticsRequest, + TorrentStatisticsRequest, }; use crate::types::torrent::InfoHash; @@ -43,7 +44,7 @@ pub struct Selected { pub struct StreamingServer { pub selected: Selected, pub settings: Loadable, - pub base_url: Option, + pub base_url_bucket: ServerUrlBucket, pub remote_url: Option, pub playback_devices: Loadable, EnvError>, pub network_info: Loadable, @@ -68,7 +69,10 @@ impl StreamingServer { statistics: None, }, settings: Loadable::Loading, - base_url: None, + base_url_bucket: ServerUrlBucket::new( + profile.uid().to_owned(), + profile.settings.streaming_server_url.to_owned(), + ), remote_url: None, playback_devices: Loadable::Loading, network_info: Loadable::Loading, @@ -88,7 +92,13 @@ impl UpdateWithCtx for StreamingServer { let settings_effects = eq_update(&mut self.settings, Loadable::Loading); let network_info_effects = eq_update(&mut self.network_info, Loadable::Loading); let device_info_effects = eq_update(&mut self.device_info, Loadable::Loading); - let base_url_effects = eq_update(&mut self.base_url, None); + let base_url_bucket_effects = eq_update( + &mut self.base_url_bucket, + ServerUrlBucket::new( + ctx.profile.uid().to_owned(), + ctx.profile.settings.streaming_server_url.to_owned(), + ), + ); let remote_url_effects = eq_update(&mut self.remote_url, None); Effects::many(vec![ get_settings::(&self.selected.transport_url), @@ -100,7 +110,7 @@ impl UpdateWithCtx for StreamingServer { .join(settings_effects) .join(network_info_effects) .join(device_info_effects) - .join(base_url_effects) + .join(base_url_bucket_effects) .join(remote_url_effects) } Msg::Action(Action::StreamingServer(ActionStreamingServer::UpdateSettings( @@ -229,7 +239,10 @@ impl UpdateWithCtx for StreamingServer { self.settings = Loadable::Loading; self.network_info = Loadable::Loading; self.device_info = Loadable::Loading; - self.base_url = None; + self.base_url_bucket = ServerUrlBucket::new( + ctx.profile.uid().to_owned(), + ctx.profile.settings.streaming_server_url.to_owned(), + ); self.remote_url = None; self.torrent = None; self.statistics = None; @@ -249,8 +262,13 @@ impl UpdateWithCtx for StreamingServer { &mut self.settings, Loadable::Ready(settings.values.to_owned()), ); - let base_url_effects = - eq_update(&mut self.base_url, Some(settings.base_url.to_owned())); + let base_url_bucket_effects = eq_update( + &mut self.base_url_bucket, + ServerUrlBucket::new( + ctx.profile.uid().to_owned(), + self.selected.transport_url.to_owned(), + ), + ); let remote_url_effects = update_remote_url::( &mut self.remote_url, &self.selected, @@ -258,11 +276,17 @@ impl UpdateWithCtx for StreamingServer { ctx, ); settings_effects - .join(base_url_effects) + .join(base_url_bucket_effects) .join(remote_url_effects) } Err(error) => { - let base_url_effects = eq_update(&mut self.base_url, None); + let base_url_bucket_effects = eq_update( + &mut self.base_url_bucket, + ServerUrlBucket::new( + ctx.profile.uid().to_owned(), + self.selected.transport_url.to_owned(), + ), + ); let remote_url_effects = eq_update(&mut self.remote_url, None); let playback_devices_effects = eq_update(&mut self.playback_devices, Loadable::Err(error.to_owned())); @@ -273,7 +297,7 @@ impl UpdateWithCtx for StreamingServer { let settings_effects = eq_update(&mut self.settings, Loadable::Err(error.to_owned())); let torrent_effects = eq_update(&mut self.torrent, None); - base_url_effects + base_url_bucket_effects .join(remote_url_effects) .join(playback_devices_effects) .join(network_info_effects) @@ -326,7 +350,13 @@ impl UpdateWithCtx for StreamingServer { match result { Ok(_) => Effects::none().unchanged(), Err(error) => { - let base_url_effects = eq_update(&mut self.base_url, None); + let base_url_effects = eq_update( + &mut self.base_url_bucket, + ServerUrlBucket::new( + ctx.profile.uid().to_owned(), + self.selected.transport_url.to_owned(), + ), + ); let remote_url_effects = eq_update(&mut self.remote_url, None); let playback_devices_effects = eq_update(&mut self.playback_devices, Loadable::Err(error.to_owned())); diff --git a/src/types/streaming_server/mod.rs b/src/types/streaming_server/mod.rs index d527051de..0992ffe14 100644 --- a/src/types/streaming_server/mod.rs +++ b/src/types/streaming_server/mod.rs @@ -19,6 +19,12 @@ pub use settings::*; mod statistics; pub use statistics::*; +mod server_url_item; +pub use server_url_item::*; + +mod server_url_bucket; +pub use server_url_bucket::*; + use super::resource::SeriesInfo; use crate::types::{torrent::InfoHash, DefaultOnBool}; diff --git a/src/types/streaming_server/server_url_bucket.rs b/src/types/streaming_server/server_url_bucket.rs new file mode 100644 index 000000000..ebe45ad0d --- /dev/null +++ b/src/types/streaming_server/server_url_bucket.rs @@ -0,0 +1,108 @@ +use super::ServerUrlItem; +use crate::{ + constants::{SERVER_URL_BUCKET_DEFAULT_ITEM_ID, SERVER_URL_BUCKET_MAX_ITEMS}, + types::profile::UID, +}; +use serde::{Deserialize, Serialize}; +use std::collections::HashMap; +use std::time::{SystemTime, UNIX_EPOCH}; +use url::Url; + +#[derive(Debug, Clone, Serialize, Deserialize, Default, PartialEq)] +pub struct ServerUrlBucket { + /// User ID + pub uid: UID, + /// [`HashMap`] Key is the [`ServerUrlItem`]`.id`. + pub items: HashMap, +} + +impl ServerUrlBucket { + /// Create a new [`ServerUrlBucket`] with the base URL inserted. + pub fn new(uid: UID, base_url: Url) -> Self { + let mut items = HashMap::new(); + + let server_url_item = ServerUrlItem { + id: SERVER_URL_BUCKET_DEFAULT_ITEM_ID.to_string(), + url: base_url.clone(), + mtime: Self::current_timestamp() as i64, + selected: true, + }; + + // Use the item's id as the key in the HashMap + items.insert(server_url_item.id.clone(), server_url_item); + + ServerUrlBucket { uid, items } + } + + fn current_timestamp() -> u64 { + SystemTime::now() + .duration_since(UNIX_EPOCH) + .expect("Time went backwards") + .as_secs() + } + + pub fn merge_bucket(&mut self, bucket: ServerUrlBucket) { + if self.uid == bucket.uid { + self.merge_items(bucket.items.into_values().collect()); + } + } + + pub fn merge_items(&mut self, items: Vec) { + for new_item in items.into_iter() { + match self.items.get_mut(&new_item.id) { + Some(item) => { + *item = new_item; + } + None => { + if self.items.len() < SERVER_URL_BUCKET_MAX_ITEMS { + self.items.insert(new_item.id.to_owned(), new_item); + } else { + let oldest_item_id_option = self + .items + .values() + .filter(|item| item.id != SERVER_URL_BUCKET_DEFAULT_ITEM_ID) + .min_by_key(|item| item.mtime) + .map(|item| item.id.clone()); + + if let Some(oldest_item_id) = oldest_item_id_option { + if new_item.mtime > self.items[&oldest_item_id].mtime { + self.items.remove(&oldest_item_id); + self.items.insert(new_item.id.to_owned(), new_item); + } + } + } + } + } + } + } + + pub fn edit_item(&mut self, id: &str, new_url: Url) -> Result<(), String> { + if let Some(item) = self.items.get_mut(id) { + item.url = new_url; + item.mtime = Self::current_timestamp() as i64; + Ok(()) + } else { + Err("Item not found".to_string()) + } + } + + /// Delete an item by its ID + pub fn delete_item(&mut self, id: &str) -> Result<(), String> { + if id == SERVER_URL_BUCKET_DEFAULT_ITEM_ID { + return Err("Cannot remove the base URL item.".to_string()); + } + if self.items.remove(id).is_some() { + Ok(()) + } else { + Err("Item not found".to_string()) + } + } + + pub fn selected_item(&self) -> Option<&ServerUrlItem> { + self.items.values().find(|item| item.selected) + } + + pub fn selected_item_url(&self) -> Option { + self.selected_item().map(|item| item.url.clone()) + } +} diff --git a/src/types/streaming_server/server_url_item.rs b/src/types/streaming_server/server_url_item.rs new file mode 100644 index 000000000..b1c3477b6 --- /dev/null +++ b/src/types/streaming_server/server_url_item.rs @@ -0,0 +1,26 @@ +use serde::{Deserialize, Serialize}; +use url::Url; + +/// Server URL Item +#[derive(Debug, Serialize, Deserialize, Clone, PartialEq)] +pub struct ServerUrlItem { + /// Unique ID + pub id: String, + /// URL + pub url: Url, + /// Timestamp + pub mtime: i64, + /// Selected + pub selected: bool, +} + +impl ServerUrlItem { + pub fn new(id: String, url: Url, mtime: i64) -> Self { + ServerUrlItem { + id, + url, + mtime, + selected: false, + } + } +} diff --git a/stremio-core-web/src/model/model.rs b/stremio-core-web/src/model/model.rs index 451e47ec5..17d5e0484 100644 --- a/stremio-core-web/src/model/model.rs +++ b/stremio-core-web/src/model/model.rs @@ -125,7 +125,10 @@ impl WebModel { WebModelField::ContinueWatchingPreview => serialize_continue_watching_preview( &self.continue_watching_preview, &self.ctx.streams, - self.streaming_server.base_url.as_ref(), + self.streaming_server + .base_url_bucket + .selected_item_url() + .as_ref(), &self.ctx.profile.settings, ), WebModelField::Board => { @@ -143,13 +146,19 @@ impl WebModel { WebModelField::Library => serialize_library( &self.library, &self.ctx, - self.streaming_server.base_url.as_ref(), + self.streaming_server + .base_url_bucket + .selected_item_url() + .as_ref(), "library".to_owned(), ), WebModelField::ContinueWatching => serialize_library( &self.continue_watching, &self.ctx, - self.streaming_server.base_url.as_ref(), + self.streaming_server + .base_url_bucket + .selected_item_url() + .as_ref(), "continuewatching".to_owned(), ), WebModelField::Search => { diff --git a/stremio-core-web/src/model/serialize_discover.rs b/stremio-core-web/src/model/serialize_discover.rs index 865073141..86f4da924 100644 --- a/stremio-core-web/src/model/serialize_discover.rs +++ b/stremio-core-web/src/model/serialize_discover.rs @@ -195,7 +195,9 @@ pub fn serialize_discover( stream, deep_links: StreamDeepLinks::from(( stream, - &streaming_server.base_url, + &streaming_server + .base_url_bucket + .selected_item_url(), &ctx.profile.settings, )) .into_web_deep_links(), diff --git a/stremio-core-web/src/model/serialize_meta_details.rs b/stremio-core-web/src/model/serialize_meta_details.rs index 7c0b60012..512aa3cb2 100644 --- a/stremio-core-web/src/model/serialize_meta_details.rs +++ b/stremio-core-web/src/model/serialize_meta_details.rs @@ -169,7 +169,7 @@ pub fn serialize_meta_details( deep_links: VideoDeepLinks::from(( video, request, - &streaming_server.base_url, + &streaming_server.base_url_bucket.selected_item_url(), &ctx.profile.settings, )) .into_web_deep_links(), @@ -184,7 +184,7 @@ pub fn serialize_meta_details( progress: None, deep_links: StreamDeepLinks::from(( stream, - &streaming_server.base_url, + &streaming_server.base_url_bucket.selected_item_url(), &ctx.profile.settings, )) .into_web_deep_links(), @@ -257,7 +257,9 @@ pub fn serialize_meta_details( || { StreamDeepLinks::from(( stream, - &streaming_server.base_url, + &streaming_server + .base_url_bucket + .selected_item_url(), &ctx.profile.settings, )) }, @@ -266,7 +268,9 @@ pub fn serialize_meta_details( stream, request, &meta_item.request, - &streaming_server.base_url, + &streaming_server + .base_url_bucket + .selected_item_url(), &ctx.profile.settings, )) }, diff --git a/stremio-core-web/src/model/serialize_player.rs b/stremio-core-web/src/model/serialize_player.rs index 2d7c56289..51ec6ea14 100644 --- a/stremio-core-web/src/model/serialize_player.rs +++ b/stremio-core-web/src/model/serialize_player.rs @@ -119,7 +119,7 @@ pub fn serialize_player( stream: &selected.stream, deep_links: StreamDeepLinks::from(( &selected.stream, - &streaming_server.base_url, + &streaming_server.base_url_bucket.selected_item_url(), &ctx.profile.settings, )) .into_web_deep_links(), @@ -150,7 +150,7 @@ pub fn serialize_player( deep_links: VideoDeepLinks::from(( video, request, - &streaming_server.base_url, + &streaming_server.base_url_bucket.selected_item_url(), &ctx.profile.settings, )) .into_web_deep_links(), @@ -231,7 +231,7 @@ pub fn serialize_player( video, stream_request, meta_request, - &streaming_server.base_url, + &streaming_server.base_url_bucket.selected_item_url(), &ctx.profile.settings, )) .into_web_deep_links(), diff --git a/stremio-core-web/src/model/serialize_streaming_server.rs b/stremio-core-web/src/model/serialize_streaming_server.rs index 1b64d77ad..edcba8142 100644 --- a/stremio-core-web/src/model/serialize_streaming_server.rs +++ b/stremio-core-web/src/model/serialize_streaming_server.rs @@ -12,7 +12,7 @@ use url::Url; use wasm_bindgen::JsValue; mod model { - use stremio_core::types::torrent::InfoHash; + use stremio_core::types::{streaming_server::ServerUrlBucket, torrent::InfoHash}; use super::*; type TorrentLoadable<'a> = Loadable<(&'a ResourcePath, MetaItemDeepLinks), &'a EnvError>; @@ -21,7 +21,7 @@ mod model { pub struct StreamingServer<'a> { pub selected: &'a Selected, pub settings: &'a Loadable, - pub base_url: &'a Option, + pub base_url_bucket: &'a ServerUrlBucket, pub remote_url: &'a Option, pub playback_devices: &'a Loadable, EnvError>, pub network_info: &'a Loadable, @@ -39,7 +39,7 @@ pub fn serialize_streaming_server( ::from_serde(&model::StreamingServer { selected: &streaming_server.selected, settings: &streaming_server.settings, - base_url: &streaming_server.base_url, + base_url_bucket: &streaming_server.base_url_bucket, remote_url: &streaming_server.remote_url, playback_devices: &streaming_server.playback_devices, network_info: &streaming_server.network_info, From 80eaf4ee6c5ddabac7bef9f410318291f7f72ecc Mon Sep 17 00:00:00 2001 From: "Timothy Z." Date: Thu, 3 Oct 2024 14:25:35 +0300 Subject: [PATCH 02/44] feat: add select_item fn --- src/types/streaming_server/server_url_bucket.rs | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/src/types/streaming_server/server_url_bucket.rs b/src/types/streaming_server/server_url_bucket.rs index ebe45ad0d..3b0d6d6e0 100644 --- a/src/types/streaming_server/server_url_bucket.rs +++ b/src/types/streaming_server/server_url_bucket.rs @@ -98,6 +98,19 @@ impl ServerUrlBucket { } } + pub fn select_item(&mut self, id: &str) -> Result<(), String> { + if let Some(current_selected_item) = self.items.values_mut().find(|item| item.selected) { + current_selected_item.selected = false; + } + + if let Some(new_selected_item) = self.items.get_mut(id) { + new_selected_item.selected = true; + Ok(()) + } else { + Err("Item not found".to_string()) + } + } + pub fn selected_item(&self) -> Option<&ServerUrlItem> { self.items.values().find(|item| item.selected) } From d8a8240b9f2e5a617df584110f91120c16c7592d Mon Sep 17 00:00:00 2001 From: "Timothy Z." Date: Thu, 3 Oct 2024 14:30:59 +0300 Subject: [PATCH 03/44] chore(fmt): fmt --all --- src/types/streaming_server/server_url_bucket.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/types/streaming_server/server_url_bucket.rs b/src/types/streaming_server/server_url_bucket.rs index 3b0d6d6e0..878a797dd 100644 --- a/src/types/streaming_server/server_url_bucket.rs +++ b/src/types/streaming_server/server_url_bucket.rs @@ -102,7 +102,7 @@ impl ServerUrlBucket { if let Some(current_selected_item) = self.items.values_mut().find(|item| item.selected) { current_selected_item.selected = false; } - + if let Some(new_selected_item) = self.items.get_mut(id) { new_selected_item.selected = true; Ok(()) From 5bee75ab0a8b4227b2f1325301dea3fd312076b2 Mon Sep 17 00:00:00 2001 From: "Timothy Z." Date: Thu, 3 Oct 2024 14:36:58 +0300 Subject: [PATCH 04/44] delete: comments --- src/types/streaming_server/server_url_bucket.rs | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/types/streaming_server/server_url_bucket.rs b/src/types/streaming_server/server_url_bucket.rs index 878a797dd..4239a5336 100644 --- a/src/types/streaming_server/server_url_bucket.rs +++ b/src/types/streaming_server/server_url_bucket.rs @@ -28,7 +28,6 @@ impl ServerUrlBucket { selected: true, }; - // Use the item's id as the key in the HashMap items.insert(server_url_item.id.clone(), server_url_item); ServerUrlBucket { uid, items } @@ -86,7 +85,6 @@ impl ServerUrlBucket { } } - /// Delete an item by its ID pub fn delete_item(&mut self, id: &str) -> Result<(), String> { if id == SERVER_URL_BUCKET_DEFAULT_ITEM_ID { return Err("Cannot remove the base URL item.".to_string()); From 67baef4f9d7c47249f53dec48764123fdb997807 Mon Sep 17 00:00:00 2001 From: "Timothy Z." Date: Thu, 3 Oct 2024 14:43:37 +0300 Subject: [PATCH 05/44] refactor: rename base item variable --- src/types/streaming_server/server_url_bucket.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/types/streaming_server/server_url_bucket.rs b/src/types/streaming_server/server_url_bucket.rs index 4239a5336..83d8f725f 100644 --- a/src/types/streaming_server/server_url_bucket.rs +++ b/src/types/streaming_server/server_url_bucket.rs @@ -21,14 +21,14 @@ impl ServerUrlBucket { pub fn new(uid: UID, base_url: Url) -> Self { let mut items = HashMap::new(); - let server_url_item = ServerUrlItem { + let server_base_url_item = ServerUrlItem { id: SERVER_URL_BUCKET_DEFAULT_ITEM_ID.to_string(), url: base_url.clone(), mtime: Self::current_timestamp() as i64, selected: true, }; - items.insert(server_url_item.id.clone(), server_url_item); + items.insert(server_base_url_item.id.clone(), server_base_url_item); ServerUrlBucket { uid, items } } From 18c06a139c13a8d39c51e304cdc4d688213115ec Mon Sep 17 00:00:00 2001 From: "Timothy Z." Date: Thu, 3 Oct 2024 14:48:57 +0300 Subject: [PATCH 06/44] refactor: use chrono for timestamps --- src/types/streaming_server/server_url_bucket.rs | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/src/types/streaming_server/server_url_bucket.rs b/src/types/streaming_server/server_url_bucket.rs index 83d8f725f..d7e7f1063 100644 --- a/src/types/streaming_server/server_url_bucket.rs +++ b/src/types/streaming_server/server_url_bucket.rs @@ -5,7 +5,6 @@ use crate::{ }; use serde::{Deserialize, Serialize}; use std::collections::HashMap; -use std::time::{SystemTime, UNIX_EPOCH}; use url::Url; #[derive(Debug, Clone, Serialize, Deserialize, Default, PartialEq)] @@ -34,10 +33,7 @@ impl ServerUrlBucket { } fn current_timestamp() -> u64 { - SystemTime::now() - .duration_since(UNIX_EPOCH) - .expect("Time went backwards") - .as_secs() + chrono::Utc::now().timestamp() as u64 } pub fn merge_bucket(&mut self, bucket: ServerUrlBucket) { From 698c83eedc1a2f1f67b21052f1726814214c2fa1 Mon Sep 17 00:00:00 2001 From: "Timothy Z." Date: Thu, 3 Oct 2024 15:04:01 +0300 Subject: [PATCH 07/44] refactor: rename bucket --- src/models/streaming_server.rs | 26 +++++++++---------- stremio-core-web/src/model/model.rs | 6 ++--- .../src/model/serialize_discover.rs | 2 +- .../src/model/serialize_meta_details.rs | 8 +++--- .../src/model/serialize_player.rs | 6 ++--- .../src/model/serialize_streaming_server.rs | 4 +-- 6 files changed, 26 insertions(+), 26 deletions(-) diff --git a/src/models/streaming_server.rs b/src/models/streaming_server.rs index d6e426217..c357a835c 100644 --- a/src/models/streaming_server.rs +++ b/src/models/streaming_server.rs @@ -44,7 +44,7 @@ pub struct Selected { pub struct StreamingServer { pub selected: Selected, pub settings: Loadable, - pub base_url_bucket: ServerUrlBucket, + pub server_urls_bucket: ServerUrlBucket, pub remote_url: Option, pub playback_devices: Loadable, EnvError>, pub network_info: Loadable, @@ -69,7 +69,7 @@ impl StreamingServer { statistics: None, }, settings: Loadable::Loading, - base_url_bucket: ServerUrlBucket::new( + server_urls_bucket: ServerUrlBucket::new( profile.uid().to_owned(), profile.settings.streaming_server_url.to_owned(), ), @@ -92,8 +92,8 @@ impl UpdateWithCtx for StreamingServer { let settings_effects = eq_update(&mut self.settings, Loadable::Loading); let network_info_effects = eq_update(&mut self.network_info, Loadable::Loading); let device_info_effects = eq_update(&mut self.device_info, Loadable::Loading); - let base_url_bucket_effects = eq_update( - &mut self.base_url_bucket, + let server_urls_bucket_effects = eq_update( + &mut self.server_urls_bucket, ServerUrlBucket::new( ctx.profile.uid().to_owned(), ctx.profile.settings.streaming_server_url.to_owned(), @@ -110,7 +110,7 @@ impl UpdateWithCtx for StreamingServer { .join(settings_effects) .join(network_info_effects) .join(device_info_effects) - .join(base_url_bucket_effects) + .join(server_urls_bucket_effects) .join(remote_url_effects) } Msg::Action(Action::StreamingServer(ActionStreamingServer::UpdateSettings( @@ -239,7 +239,7 @@ impl UpdateWithCtx for StreamingServer { self.settings = Loadable::Loading; self.network_info = Loadable::Loading; self.device_info = Loadable::Loading; - self.base_url_bucket = ServerUrlBucket::new( + self.server_urls_bucket = ServerUrlBucket::new( ctx.profile.uid().to_owned(), ctx.profile.settings.streaming_server_url.to_owned(), ); @@ -262,8 +262,8 @@ impl UpdateWithCtx for StreamingServer { &mut self.settings, Loadable::Ready(settings.values.to_owned()), ); - let base_url_bucket_effects = eq_update( - &mut self.base_url_bucket, + let server_urls_bucket_effects = eq_update( + &mut self.server_urls_bucket, ServerUrlBucket::new( ctx.profile.uid().to_owned(), self.selected.transport_url.to_owned(), @@ -276,12 +276,12 @@ impl UpdateWithCtx for StreamingServer { ctx, ); settings_effects - .join(base_url_bucket_effects) + .join(server_urls_bucket_effects) .join(remote_url_effects) } Err(error) => { - let base_url_bucket_effects = eq_update( - &mut self.base_url_bucket, + let server_urls_bucket_effects = eq_update( + &mut self.server_urls_bucket, ServerUrlBucket::new( ctx.profile.uid().to_owned(), self.selected.transport_url.to_owned(), @@ -297,7 +297,7 @@ impl UpdateWithCtx for StreamingServer { let settings_effects = eq_update(&mut self.settings, Loadable::Err(error.to_owned())); let torrent_effects = eq_update(&mut self.torrent, None); - base_url_bucket_effects + server_urls_bucket_effects .join(remote_url_effects) .join(playback_devices_effects) .join(network_info_effects) @@ -351,7 +351,7 @@ impl UpdateWithCtx for StreamingServer { Ok(_) => Effects::none().unchanged(), Err(error) => { let base_url_effects = eq_update( - &mut self.base_url_bucket, + &mut self.server_urls_bucket, ServerUrlBucket::new( ctx.profile.uid().to_owned(), self.selected.transport_url.to_owned(), diff --git a/stremio-core-web/src/model/model.rs b/stremio-core-web/src/model/model.rs index 17d5e0484..30bad6d9a 100644 --- a/stremio-core-web/src/model/model.rs +++ b/stremio-core-web/src/model/model.rs @@ -126,7 +126,7 @@ impl WebModel { &self.continue_watching_preview, &self.ctx.streams, self.streaming_server - .base_url_bucket + .server_urls_bucket .selected_item_url() .as_ref(), &self.ctx.profile.settings, @@ -147,7 +147,7 @@ impl WebModel { &self.library, &self.ctx, self.streaming_server - .base_url_bucket + .server_urls_bucket .selected_item_url() .as_ref(), "library".to_owned(), @@ -156,7 +156,7 @@ impl WebModel { &self.continue_watching, &self.ctx, self.streaming_server - .base_url_bucket + .server_urls_bucket .selected_item_url() .as_ref(), "continuewatching".to_owned(), diff --git a/stremio-core-web/src/model/serialize_discover.rs b/stremio-core-web/src/model/serialize_discover.rs index 86f4da924..4fe91085c 100644 --- a/stremio-core-web/src/model/serialize_discover.rs +++ b/stremio-core-web/src/model/serialize_discover.rs @@ -196,7 +196,7 @@ pub fn serialize_discover( deep_links: StreamDeepLinks::from(( stream, &streaming_server - .base_url_bucket + .server_urls_bucket .selected_item_url(), &ctx.profile.settings, )) diff --git a/stremio-core-web/src/model/serialize_meta_details.rs b/stremio-core-web/src/model/serialize_meta_details.rs index 512aa3cb2..06b704ee2 100644 --- a/stremio-core-web/src/model/serialize_meta_details.rs +++ b/stremio-core-web/src/model/serialize_meta_details.rs @@ -169,7 +169,7 @@ pub fn serialize_meta_details( deep_links: VideoDeepLinks::from(( video, request, - &streaming_server.base_url_bucket.selected_item_url(), + &streaming_server.server_urls_bucket.selected_item_url(), &ctx.profile.settings, )) .into_web_deep_links(), @@ -184,7 +184,7 @@ pub fn serialize_meta_details( progress: None, deep_links: StreamDeepLinks::from(( stream, - &streaming_server.base_url_bucket.selected_item_url(), + &streaming_server.server_urls_bucket.selected_item_url(), &ctx.profile.settings, )) .into_web_deep_links(), @@ -258,7 +258,7 @@ pub fn serialize_meta_details( StreamDeepLinks::from(( stream, &streaming_server - .base_url_bucket + .server_urls_bucket .selected_item_url(), &ctx.profile.settings, )) @@ -269,7 +269,7 @@ pub fn serialize_meta_details( request, &meta_item.request, &streaming_server - .base_url_bucket + .server_urls_bucket .selected_item_url(), &ctx.profile.settings, )) diff --git a/stremio-core-web/src/model/serialize_player.rs b/stremio-core-web/src/model/serialize_player.rs index 51ec6ea14..d36956bfa 100644 --- a/stremio-core-web/src/model/serialize_player.rs +++ b/stremio-core-web/src/model/serialize_player.rs @@ -119,7 +119,7 @@ pub fn serialize_player( stream: &selected.stream, deep_links: StreamDeepLinks::from(( &selected.stream, - &streaming_server.base_url_bucket.selected_item_url(), + &streaming_server.server_urls_bucket.selected_item_url(), &ctx.profile.settings, )) .into_web_deep_links(), @@ -150,7 +150,7 @@ pub fn serialize_player( deep_links: VideoDeepLinks::from(( video, request, - &streaming_server.base_url_bucket.selected_item_url(), + &streaming_server.server_urls_bucket.selected_item_url(), &ctx.profile.settings, )) .into_web_deep_links(), @@ -231,7 +231,7 @@ pub fn serialize_player( video, stream_request, meta_request, - &streaming_server.base_url_bucket.selected_item_url(), + &streaming_server.server_urls_bucket.selected_item_url(), &ctx.profile.settings, )) .into_web_deep_links(), diff --git a/stremio-core-web/src/model/serialize_streaming_server.rs b/stremio-core-web/src/model/serialize_streaming_server.rs index edcba8142..7e802da40 100644 --- a/stremio-core-web/src/model/serialize_streaming_server.rs +++ b/stremio-core-web/src/model/serialize_streaming_server.rs @@ -21,7 +21,7 @@ mod model { pub struct StreamingServer<'a> { pub selected: &'a Selected, pub settings: &'a Loadable, - pub base_url_bucket: &'a ServerUrlBucket, + pub server_urls_bucket: &'a ServerUrlBucket, pub remote_url: &'a Option, pub playback_devices: &'a Loadable, EnvError>, pub network_info: &'a Loadable, @@ -39,7 +39,7 @@ pub fn serialize_streaming_server( ::from_serde(&model::StreamingServer { selected: &streaming_server.selected, settings: &streaming_server.settings, - base_url_bucket: &streaming_server.base_url_bucket, + server_urls_bucket: &streaming_server.server_urls_bucket, remote_url: &streaming_server.remote_url, playback_devices: &streaming_server.playback_devices, network_info: &streaming_server.network_info, From 84f4dc2ae9d87503d5bf06f6d1a3819959399e92 Mon Sep 17 00:00:00 2001 From: "Timothy Z." Date: Fri, 4 Oct 2024 13:42:39 +0300 Subject: [PATCH 08/44] refactor: bucket logic --- src/constants.rs | 2 +- src/models/streaming_server.rs | 31 +++++++++++++------ src/types/streaming_server/mod.rs | 7 ++--- src/types/streaming_server/server_urls/mod.rs | 5 +++ .../{ => server_urls}/server_url_item.rs | 4 +-- .../server_urls_bucket.rs} | 26 ++++++++-------- .../src/model/serialize_streaming_server.rs | 4 +-- 7 files changed, 46 insertions(+), 33 deletions(-) create mode 100644 src/types/streaming_server/server_urls/mod.rs rename src/types/streaming_server/{ => server_urls}/server_url_item.rs (84%) rename src/types/streaming_server/{server_url_bucket.rs => server_urls/server_urls_bucket.rs} (80%) diff --git a/src/constants.rs b/src/constants.rs index 710bce63a..cb0ce0f0e 100644 --- a/src/constants.rs +++ b/src/constants.rs @@ -30,7 +30,7 @@ pub const LIBRARY_RECENT_COUNT: usize = 200; pub const NOTIFICATION_ITEMS_COUNT: usize = 100; pub const SERVER_URL_BUCKET_MAX_ITEMS: usize = 5; -pub const SERVER_URL_BUCKET_DEFAULT_ITEM_ID: &str = "0"; +pub const SERVER_URL_BUCKET_DEFAULT_ITEM_ID: usize = 0; /// A `LibraryItem` is considered watched once we've watched more than the `duration * threshold`: /// diff --git a/src/models/streaming_server.rs b/src/models/streaming_server.rs index c357a835c..e797ff19d 100644 --- a/src/models/streaming_server.rs +++ b/src/models/streaming_server.rs @@ -19,7 +19,7 @@ use crate::types::empty_string_as_null; use crate::types::profile::{AuthKey, Profile}; use crate::types::streaming_server::{ CreateMagnetRequest, CreateTorrentBlobRequest, DeviceInfo, GetHTTPSResponse, NetworkInfo, - ServerUrlBucket, Settings, SettingsResponse, Statistics, StatisticsRequest, + ServerUrlsBucket, Settings, SettingsResponse, Statistics, StatisticsRequest, TorrentStatisticsRequest, }; use crate::types::torrent::InfoHash; @@ -44,7 +44,8 @@ pub struct Selected { pub struct StreamingServer { pub selected: Selected, pub settings: Loadable, - pub server_urls_bucket: ServerUrlBucket, + pub base_url: Option, + pub server_urls_bucket: ServerUrlsBucket, pub remote_url: Option, pub playback_devices: Loadable, EnvError>, pub network_info: Loadable, @@ -69,7 +70,8 @@ impl StreamingServer { statistics: None, }, settings: Loadable::Loading, - server_urls_bucket: ServerUrlBucket::new( + base_url: None, + server_urls_bucket: ServerUrlsBucket::new( profile.uid().to_owned(), profile.settings.streaming_server_url.to_owned(), ), @@ -92,9 +94,10 @@ impl UpdateWithCtx for StreamingServer { let settings_effects = eq_update(&mut self.settings, Loadable::Loading); let network_info_effects = eq_update(&mut self.network_info, Loadable::Loading); let device_info_effects = eq_update(&mut self.device_info, Loadable::Loading); + let base_url_effects = eq_update(&mut self.base_url, None); let server_urls_bucket_effects = eq_update( &mut self.server_urls_bucket, - ServerUrlBucket::new( + ServerUrlsBucket::new( ctx.profile.uid().to_owned(), ctx.profile.settings.streaming_server_url.to_owned(), ), @@ -110,6 +113,7 @@ impl UpdateWithCtx for StreamingServer { .join(settings_effects) .join(network_info_effects) .join(device_info_effects) + .join(base_url_effects) .join(server_urls_bucket_effects) .join(remote_url_effects) } @@ -239,7 +243,8 @@ impl UpdateWithCtx for StreamingServer { self.settings = Loadable::Loading; self.network_info = Loadable::Loading; self.device_info = Loadable::Loading; - self.server_urls_bucket = ServerUrlBucket::new( + self.base_url = None; + self.server_urls_bucket = ServerUrlsBucket::new( ctx.profile.uid().to_owned(), ctx.profile.settings.streaming_server_url.to_owned(), ); @@ -262,9 +267,10 @@ impl UpdateWithCtx for StreamingServer { &mut self.settings, Loadable::Ready(settings.values.to_owned()), ); + let base_url_effects = eq_update(&mut self.base_url, Some(url.to_owned())); let server_urls_bucket_effects = eq_update( &mut self.server_urls_bucket, - ServerUrlBucket::new( + ServerUrlsBucket::new( ctx.profile.uid().to_owned(), self.selected.transport_url.to_owned(), ), @@ -276,13 +282,15 @@ impl UpdateWithCtx for StreamingServer { ctx, ); settings_effects + .join(base_url_effects) .join(server_urls_bucket_effects) .join(remote_url_effects) } Err(error) => { + let base_url_effects = eq_update(&mut self.base_url, None); let server_urls_bucket_effects = eq_update( &mut self.server_urls_bucket, - ServerUrlBucket::new( + ServerUrlsBucket::new( ctx.profile.uid().to_owned(), self.selected.transport_url.to_owned(), ), @@ -297,7 +305,8 @@ impl UpdateWithCtx for StreamingServer { let settings_effects = eq_update(&mut self.settings, Loadable::Err(error.to_owned())); let torrent_effects = eq_update(&mut self.torrent, None); - server_urls_bucket_effects + base_url_effects + .join(server_urls_bucket_effects) .join(remote_url_effects) .join(playback_devices_effects) .join(network_info_effects) @@ -350,9 +359,10 @@ impl UpdateWithCtx for StreamingServer { match result { Ok(_) => Effects::none().unchanged(), Err(error) => { - let base_url_effects = eq_update( + let base_url_effects = eq_update(&mut self.base_url, None); + let server_urls_bucket_effects = eq_update( &mut self.server_urls_bucket, - ServerUrlBucket::new( + ServerUrlsBucket::new( ctx.profile.uid().to_owned(), self.selected.transport_url.to_owned(), ), @@ -368,6 +378,7 @@ impl UpdateWithCtx for StreamingServer { eq_update(&mut self.settings, Loadable::Err(error.to_owned())); let torrent_effects = eq_update(&mut self.torrent, None); base_url_effects + .join(server_urls_bucket_effects) .join(remote_url_effects) .join(playback_devices_effects) .join(network_info_effects) diff --git a/src/types/streaming_server/mod.rs b/src/types/streaming_server/mod.rs index 0992ffe14..d44477ac5 100644 --- a/src/types/streaming_server/mod.rs +++ b/src/types/streaming_server/mod.rs @@ -19,11 +19,8 @@ pub use settings::*; mod statistics; pub use statistics::*; -mod server_url_item; -pub use server_url_item::*; - -mod server_url_bucket; -pub use server_url_bucket::*; +pub mod server_urls; +pub use server_urls::*; use super::resource::SeriesInfo; use crate::types::{torrent::InfoHash, DefaultOnBool}; diff --git a/src/types/streaming_server/server_urls/mod.rs b/src/types/streaming_server/server_urls/mod.rs new file mode 100644 index 000000000..27d08716e --- /dev/null +++ b/src/types/streaming_server/server_urls/mod.rs @@ -0,0 +1,5 @@ +mod server_urls_bucket; +pub use server_urls_bucket::*; + +mod server_url_item; +pub use server_url_item::*; diff --git a/src/types/streaming_server/server_url_item.rs b/src/types/streaming_server/server_urls/server_url_item.rs similarity index 84% rename from src/types/streaming_server/server_url_item.rs rename to src/types/streaming_server/server_urls/server_url_item.rs index b1c3477b6..e68cd6844 100644 --- a/src/types/streaming_server/server_url_item.rs +++ b/src/types/streaming_server/server_urls/server_url_item.rs @@ -5,7 +5,7 @@ use url::Url; #[derive(Debug, Serialize, Deserialize, Clone, PartialEq)] pub struct ServerUrlItem { /// Unique ID - pub id: String, + pub id: usize, /// URL pub url: Url, /// Timestamp @@ -15,7 +15,7 @@ pub struct ServerUrlItem { } impl ServerUrlItem { - pub fn new(id: String, url: Url, mtime: i64) -> Self { + pub fn new(id: usize, url: Url, mtime: i64) -> Self { ServerUrlItem { id, url, diff --git a/src/types/streaming_server/server_url_bucket.rs b/src/types/streaming_server/server_urls/server_urls_bucket.rs similarity index 80% rename from src/types/streaming_server/server_url_bucket.rs rename to src/types/streaming_server/server_urls/server_urls_bucket.rs index d7e7f1063..570ed6074 100644 --- a/src/types/streaming_server/server_url_bucket.rs +++ b/src/types/streaming_server/server_urls/server_urls_bucket.rs @@ -8,35 +8,35 @@ use std::collections::HashMap; use url::Url; #[derive(Debug, Clone, Serialize, Deserialize, Default, PartialEq)] -pub struct ServerUrlBucket { +pub struct ServerUrlsBucket { /// User ID pub uid: UID, /// [`HashMap`] Key is the [`ServerUrlItem`]`.id`. - pub items: HashMap, + pub items: HashMap, } -impl ServerUrlBucket { - /// Create a new [`ServerUrlBucket`] with the base URL inserted. +impl ServerUrlsBucket { + /// Create a new [`ServerUrlsBucket`] with the base URL inserted. pub fn new(uid: UID, base_url: Url) -> Self { let mut items = HashMap::new(); let server_base_url_item = ServerUrlItem { - id: SERVER_URL_BUCKET_DEFAULT_ITEM_ID.to_string(), + id: SERVER_URL_BUCKET_DEFAULT_ITEM_ID, url: base_url.clone(), mtime: Self::current_timestamp() as i64, selected: true, }; - items.insert(server_base_url_item.id.clone(), server_base_url_item); + items.insert(server_base_url_item.id, server_base_url_item); - ServerUrlBucket { uid, items } + ServerUrlsBucket { uid, items } } fn current_timestamp() -> u64 { chrono::Utc::now().timestamp() as u64 } - pub fn merge_bucket(&mut self, bucket: ServerUrlBucket) { + pub fn merge_bucket(&mut self, bucket: ServerUrlsBucket) { if self.uid == bucket.uid { self.merge_items(bucket.items.into_values().collect()); } @@ -57,7 +57,7 @@ impl ServerUrlBucket { .values() .filter(|item| item.id != SERVER_URL_BUCKET_DEFAULT_ITEM_ID) .min_by_key(|item| item.mtime) - .map(|item| item.id.clone()); + .map(|item| item.id); if let Some(oldest_item_id) = oldest_item_id_option { if new_item.mtime > self.items[&oldest_item_id].mtime { @@ -71,7 +71,7 @@ impl ServerUrlBucket { } } - pub fn edit_item(&mut self, id: &str, new_url: Url) -> Result<(), String> { + pub fn edit_item(&mut self, id: &usize, new_url: Url) -> Result<(), String> { if let Some(item) = self.items.get_mut(id) { item.url = new_url; item.mtime = Self::current_timestamp() as i64; @@ -81,8 +81,8 @@ impl ServerUrlBucket { } } - pub fn delete_item(&mut self, id: &str) -> Result<(), String> { - if id == SERVER_URL_BUCKET_DEFAULT_ITEM_ID { + pub fn delete_item(&mut self, id: &usize) -> Result<(), String> { + if *id == SERVER_URL_BUCKET_DEFAULT_ITEM_ID { return Err("Cannot remove the base URL item.".to_string()); } if self.items.remove(id).is_some() { @@ -92,7 +92,7 @@ impl ServerUrlBucket { } } - pub fn select_item(&mut self, id: &str) -> Result<(), String> { + pub fn select_item(&mut self, id: &usize) -> Result<(), String> { if let Some(current_selected_item) = self.items.values_mut().find(|item| item.selected) { current_selected_item.selected = false; } diff --git a/stremio-core-web/src/model/serialize_streaming_server.rs b/stremio-core-web/src/model/serialize_streaming_server.rs index 7e802da40..a53d01c65 100644 --- a/stremio-core-web/src/model/serialize_streaming_server.rs +++ b/stremio-core-web/src/model/serialize_streaming_server.rs @@ -12,7 +12,7 @@ use url::Url; use wasm_bindgen::JsValue; mod model { - use stremio_core::types::{streaming_server::ServerUrlBucket, torrent::InfoHash}; + use stremio_core::types::{streaming_server::ServerUrlsBucket, torrent::InfoHash}; use super::*; type TorrentLoadable<'a> = Loadable<(&'a ResourcePath, MetaItemDeepLinks), &'a EnvError>; @@ -21,7 +21,7 @@ mod model { pub struct StreamingServer<'a> { pub selected: &'a Selected, pub settings: &'a Loadable, - pub server_urls_bucket: &'a ServerUrlBucket, + pub server_urls_bucket: &'a ServerUrlsBucket, pub remote_url: &'a Option, pub playback_devices: &'a Loadable, EnvError>, pub network_info: &'a Loadable, From f1c02249e11ea28974bbd8df35403ea8e0261b68 Mon Sep 17 00:00:00 2001 From: "Timothy Z." Date: Fri, 4 Oct 2024 13:50:42 +0300 Subject: [PATCH 09/44] refactor: use anyhow for better err handling --- src/models/ctx/update_streaming_server_urls.rs | 0 .../server_urls/server_urls_bucket.rs | 15 ++++++++------- 2 files changed, 8 insertions(+), 7 deletions(-) create mode 100644 src/models/ctx/update_streaming_server_urls.rs diff --git a/src/models/ctx/update_streaming_server_urls.rs b/src/models/ctx/update_streaming_server_urls.rs new file mode 100644 index 000000000..e69de29bb diff --git a/src/types/streaming_server/server_urls/server_urls_bucket.rs b/src/types/streaming_server/server_urls/server_urls_bucket.rs index 570ed6074..159d21844 100644 --- a/src/types/streaming_server/server_urls/server_urls_bucket.rs +++ b/src/types/streaming_server/server_urls/server_urls_bucket.rs @@ -3,6 +3,7 @@ use crate::{ constants::{SERVER_URL_BUCKET_DEFAULT_ITEM_ID, SERVER_URL_BUCKET_MAX_ITEMS}, types::profile::UID, }; +use anyhow::{anyhow, Result}; use serde::{Deserialize, Serialize}; use std::collections::HashMap; use url::Url; @@ -71,28 +72,28 @@ impl ServerUrlsBucket { } } - pub fn edit_item(&mut self, id: &usize, new_url: Url) -> Result<(), String> { + pub fn edit_item(&mut self, id: &usize, new_url: Url) -> Result<()> { if let Some(item) = self.items.get_mut(id) { item.url = new_url; item.mtime = Self::current_timestamp() as i64; Ok(()) } else { - Err("Item not found".to_string()) + Err(anyhow!("Item not found")) } } - pub fn delete_item(&mut self, id: &usize) -> Result<(), String> { + pub fn delete_item(&mut self, id: &usize) -> Result<()> { if *id == SERVER_URL_BUCKET_DEFAULT_ITEM_ID { - return Err("Cannot remove the base URL item.".to_string()); + return Err(anyhow!("Cannot remove the base URL item.")); } if self.items.remove(id).is_some() { Ok(()) } else { - Err("Item not found".to_string()) + Err(anyhow!("Item not found")) } } - pub fn select_item(&mut self, id: &usize) -> Result<(), String> { + pub fn select_item(&mut self, id: &usize) -> Result<()> { if let Some(current_selected_item) = self.items.values_mut().find(|item| item.selected) { current_selected_item.selected = false; } @@ -101,7 +102,7 @@ impl ServerUrlsBucket { new_selected_item.selected = true; Ok(()) } else { - Err("Item not found".to_string()) + Err(anyhow!("Item not found")) } } From 768a432a06eb8646652e6cbf1cb9d8215e89c78c Mon Sep 17 00:00:00 2001 From: "Timothy Z." Date: Fri, 4 Oct 2024 16:30:53 +0300 Subject: [PATCH 10/44] refactor: impl update_server_urls --- src/constants.rs | 1 + src/models/ctx/mod.rs | 3 ++ .../ctx/update_streaming_server_urls.rs | 53 +++++++++++++++++++ src/runtime/msg/action.rs | 10 ++++ src/runtime/msg/event.rs | 6 +++ src/runtime/msg/internal.rs | 4 ++ .../server_urls/server_urls_bucket.rs | 10 ++++ 7 files changed, 87 insertions(+) diff --git a/src/constants.rs b/src/constants.rs index cb0ce0f0e..2c21bc132 100644 --- a/src/constants.rs +++ b/src/constants.rs @@ -12,6 +12,7 @@ pub const LIBRARY_STORAGE_KEY: &str = "library"; pub const LIBRARY_RECENT_STORAGE_KEY: &str = "library_recent"; pub const STREAMS_STORAGE_KEY: &str = "streams"; pub const SEARCH_HISTORY_STORAGE_KEY: &str = "search_history"; +pub const STREAMING_SERVER_URLS_STORAGE_KEY: &str = "streaming_server_urls"; pub const NOTIFICATIONS_STORAGE_KEY: &str = "notifications"; pub const DISMISSED_EVENTS_STORAGE_KEY: &str = "dismissed_events"; pub const LIBRARY_COLLECTION_NAME: &str = "libraryItem"; diff --git a/src/models/ctx/mod.rs b/src/models/ctx/mod.rs index 7bae221e8..51d28c436 100644 --- a/src/models/ctx/mod.rs +++ b/src/models/ctx/mod.rs @@ -19,6 +19,9 @@ use update_search_history::*; mod update_trakt_addon; use update_trakt_addon::*; +mod update_streaming_server_urls; +use update_streaming_server_urls::*; + mod error; pub use error::*; diff --git a/src/models/ctx/update_streaming_server_urls.rs b/src/models/ctx/update_streaming_server_urls.rs index e69de29bb..d397eb28a 100644 --- a/src/models/ctx/update_streaming_server_urls.rs +++ b/src/models/ctx/update_streaming_server_urls.rs @@ -0,0 +1,53 @@ +use crate::constants::STREAMING_SERVER_URLS_STORAGE_KEY; +use crate::runtime::msg::{Action, ActionStreamingServer}; +use crate::runtime::EnvFutureExt; +use crate::{ + runtime::{ + msg::{ActionServerUrlsBucket, Event, Internal, Msg}, + Effect, EffectFuture, Effects, Env, + }, + types::{profile::Profile, streaming_server::ServerUrlsBucket}, +}; +use futures::FutureExt; + +use super::CtxError; + +pub fn update_streaming_server_urls( + server_urls_bucket: &mut ServerUrlsBucket, + profile: &Profile, + msg: &Msg, +) -> Effects { + match msg { + Msg::Action(Action::StreamingServer(ActionStreamingServer::ServerUrlsBucket(action))) => { + match action { + ActionServerUrlsBucket::AddServerUrl(url) => { + server_urls_bucket.add_url(url.clone()); + Effects::msg(Msg::Internal(Internal::StreamingServerUrlsBucketChanged)) + } + } + } + Msg::Internal(Internal::StreamingServerUrlsBucketChanged) => { + Effects::one(push_server_urls_to_storage::(server_urls_bucket)).unchanged() + } + _ => Effects::none().unchanged(), + } +} + +fn push_server_urls_to_storage(server_urls_bucket: &ServerUrlsBucket) -> Effect { + let uid = server_urls_bucket.uid.clone(); + + EffectFuture::Sequential( + E::set_storage(STREAMING_SERVER_URLS_STORAGE_KEY, Some(server_urls_bucket)) + .map(move |result| match result { + Ok(_) => Msg::Event(Event::StreamingServerUrlsPushedToStorage { uid: uid.clone() }), + Err(error) => Msg::Event(Event::Error { + error: CtxError::from(error), + source: Box::new(Event::StreamingServerUrlsPushedToStorage { + uid: uid.clone(), + }), + }), + }) + .boxed_env(), + ) + .into() +} diff --git a/src/runtime/msg/action.rs b/src/runtime/msg/action.rs index 7f36d4fc8..ca9aefb6c 100644 --- a/src/runtime/msg/action.rs +++ b/src/runtime/msg/action.rs @@ -127,6 +127,15 @@ pub struct PlayOnDeviceArgs { pub time: Option, } +#[derive(Clone, Deserialize, Debug)] +#[serde(tag = "action", content = "args")] +pub enum ActionServerUrlsBucket { + AddServerUrl(Url), + // EditServerUrl { id: usize, new_url: Url }, + // DeleteServerUrl(usize), + // SelectServerUrl(usize), +} + #[derive(Clone, Deserialize, Debug)] #[serde(tag = "action", content = "args")] pub enum ActionStreamingServer { @@ -135,6 +144,7 @@ pub enum ActionStreamingServer { CreateTorrent(CreateTorrentArgs), GetStatistics(StreamingServerStatisticsRequest), PlayOnDevice(PlayOnDeviceArgs), + ServerUrlsBucket(ActionServerUrlsBucket), } #[derive(Clone, Deserialize, Debug)] diff --git a/src/runtime/msg/event.rs b/src/runtime/msg/event.rs index 747c14f29..86c980860 100644 --- a/src/runtime/msg/event.rs +++ b/src/runtime/msg/event.rs @@ -142,6 +142,12 @@ pub enum Event { PlayingOnDevice { device: String, }, + StreamingServerUrlsBucketChanged { + uid: UID, + }, + StreamingServerUrlsPushedToStorage { + uid: UID, + }, Error { error: CtxError, source: Box, diff --git a/src/runtime/msg/internal.rs b/src/runtime/msg/internal.rs index ebd380ce0..1f4c53664 100644 --- a/src/runtime/msg/internal.rs +++ b/src/runtime/msg/internal.rs @@ -89,6 +89,8 @@ pub enum Internal { StreamsChanged(bool), /// Search history has changed. SearchHistoryChanged, + /// Server URLs bucket has changed. + StreamingServerUrlsBucketChanged, /// User notifications have changed NotificationsChanged, /// Pulling of notifications triggered either by the user (with an action) or @@ -106,6 +108,8 @@ pub enum Internal { StreamingServerSettingsResult(Url, Result), /// Result for loading streaming server base url. StreamingServerBaseURLResult(Url, Result), + /// Result for loading streaming server urls bucket. + StreamingServerUrlsBucketResult(Result, EnvError>), // Result for loading streaming server playback devices. StreamingServerPlaybackDevicesResult(Url, Result, EnvError>), // Result for network info. diff --git a/src/types/streaming_server/server_urls/server_urls_bucket.rs b/src/types/streaming_server/server_urls/server_urls_bucket.rs index 159d21844..aefc10855 100644 --- a/src/types/streaming_server/server_urls/server_urls_bucket.rs +++ b/src/types/streaming_server/server_urls/server_urls_bucket.rs @@ -37,12 +37,22 @@ impl ServerUrlsBucket { chrono::Utc::now().timestamp() as u64 } + pub fn generate_new_id(&self) -> usize { + self.items.keys().max().cloned().unwrap_or(0) + 1 + } + pub fn merge_bucket(&mut self, bucket: ServerUrlsBucket) { if self.uid == bucket.uid { self.merge_items(bucket.items.into_values().collect()); } } + pub fn add_url(&mut self, url: Url) { + let new_id = self.generate_new_id(); + let new_item = ServerUrlItem::new(new_id, url, Self::current_timestamp() as i64); + self.merge_items(vec![new_item]); + } + pub fn merge_items(&mut self, items: Vec) { for new_item in items.into_iter() { match self.items.get_mut(&new_item.id) { From 142591d236c8c06e36c0b125d46c8acea92bec3c Mon Sep 17 00:00:00 2001 From: "Timothy Z." Date: Mon, 7 Oct 2024 13:07:30 +0300 Subject: [PATCH 11/44] refactor: bucket logic --- src/models/ctx/ctx.rs | 16 +++++- .../ctx/update_streaming_server_urls.rs | 50 +++++++++++++------ src/models/streaming_server.rs | 34 +++---------- src/runtime/msg/action.rs | 6 +-- src/types/mod.rs | 1 + .../{streaming_server => }/server_urls/mod.rs | 0 .../server_urls/server_url_item.rs | 0 .../server_urls/server_urls_bucket.rs | 39 ++++++--------- src/types/streaming_server/mod.rs | 3 -- .../catalog_with_filters/load_action.rs | 3 ++ src/unit_tests/ctx/add_to_library.rs | 3 ++ src/unit_tests/ctx/authenticate.rs | 5 ++ src/unit_tests/ctx/install_addon.rs | 5 ++ src/unit_tests/ctx/logout.rs | 2 + .../ctx/notifications/update_notifications.rs | 4 ++ src/unit_tests/ctx/pull_addons_from_api.rs | 3 ++ src/unit_tests/ctx/push_addons_to_api.rs | 3 ++ src/unit_tests/ctx/remove_from_library.rs | 3 ++ src/unit_tests/ctx/rewind_library_item.rs | 3 ++ src/unit_tests/ctx/sync_library_with_api.rs | 4 ++ src/unit_tests/ctx/uninstall_addon.rs | 6 +++ src/unit_tests/ctx/update_search_history.rs | 4 +- src/unit_tests/ctx/update_settings.rs | 3 ++ src/unit_tests/ctx/upgrade_addon.rs | 3 ++ src/unit_tests/data_export.rs | 3 ++ src/unit_tests/link.rs | 2 + stremio-core-web/src/model/model.rs | 5 +- .../src/model/serialize_streaming_server.rs | 2 +- stremio-core-web/src/stremio_core_web.rs | 7 ++- 29 files changed, 145 insertions(+), 77 deletions(-) rename src/types/{streaming_server => }/server_urls/mod.rs (100%) rename src/types/{streaming_server => }/server_urls/server_url_item.rs (100%) rename src/types/{streaming_server => }/server_urls/server_urls_bucket.rs (74%) diff --git a/src/models/ctx/ctx.rs b/src/models/ctx/ctx.rs index 6d71c88e8..3e6a25486 100644 --- a/src/models/ctx/ctx.rs +++ b/src/models/ctx/ctx.rs @@ -2,7 +2,7 @@ use crate::constants::LIBRARY_COLLECTION_NAME; use crate::models::common::{DescriptorLoadable, Loadable, ResourceLoadable}; use crate::models::ctx::{ update_events, update_library, update_notifications, update_profile, update_search_history, - update_streams, update_trakt_addon, CtxError, + update_streaming_server_urls, update_streams, update_trakt_addon, CtxError, }; use crate::runtime::msg::{Action, ActionCtx, CtxAuthResponse, Event, Internal, Msg}; use crate::runtime::{Effect, EffectFuture, Effects, Env, EnvFutureExt, Update}; @@ -16,6 +16,7 @@ use crate::types::notifications::NotificationsBucket; use crate::types::profile::{Auth, AuthKey, Profile}; use crate::types::resource::MetaItem; use crate::types::search_history::SearchHistoryBucket; +use crate::types::server_urls::ServerUrlsBucket; use crate::types::streams::StreamsBucket; #[cfg(test)] @@ -48,6 +49,8 @@ pub struct Ctx { #[serde(skip)] pub streams: StreamsBucket, #[serde(skip)] + pub server_urls: ServerUrlsBucket, + #[serde(skip)] pub search_history: SearchHistoryBucket, #[serde(skip)] pub dismissed_events: DismissedEventsBucket, @@ -67,6 +70,7 @@ impl Ctx { profile: Profile, library: LibraryBucket, streams: StreamsBucket, + server_urls: ServerUrlsBucket, notifications: NotificationsBucket, search_history: SearchHistoryBucket, dismissed_events: DismissedEventsBucket, @@ -75,6 +79,7 @@ impl Ctx { profile, library, streams, + server_urls, search_history, dismissed_events, notifications, @@ -107,6 +112,8 @@ impl Update for Ctx { let library_effects = update_library::(&mut self.library, &self.profile, &self.status, msg); let streams_effects = update_streams::(&mut self.streams, &self.status, msg); + let server_urls_effects = + update_streaming_server_urls::(&mut self.server_urls, &self.status, msg); let search_history_effects = update_search_history::(&mut self.search_history, &self.status, msg); let events_effects = @@ -132,6 +139,7 @@ impl Update for Ctx { .join(profile_effects) .join(library_effects) .join(streams_effects) + .join(server_urls_effects) .join(search_history_effects) .join(events_effects) .join(trakt_addon_effects) @@ -157,6 +165,8 @@ impl Update for Ctx { msg, ); let streams_effects = update_streams::(&mut self.streams, &self.status, msg); + let server_urls_effects = + update_streaming_server_urls::(&mut self.server_urls, &self.status, msg); let search_history_effects = update_search_history::(&mut self.search_history, &self.status, msg); let events_effects = @@ -225,6 +235,7 @@ impl Update for Ctx { profile_effects .join(library_effects) .join(streams_effects) + .join(server_urls_effects) .join(trakt_addon_effects) .join(notifications_effects) .join(search_history_effects) @@ -237,6 +248,8 @@ impl Update for Ctx { let library_effects = update_library::(&mut self.library, &self.profile, &self.status, msg); let streams_effects = update_streams::(&mut self.streams, &self.status, msg); + let server_urls_effects = + update_streaming_server_urls::(&mut self.server_urls, &self.status, msg); let trakt_addon_effects = update_trakt_addon::( &mut self.trakt_addon, &self.profile, @@ -258,6 +271,7 @@ impl Update for Ctx { profile_effects .join(library_effects) .join(streams_effects) + .join(server_urls_effects) .join(trakt_addon_effects) .join(notifications_effects) .join(search_history_effects) diff --git a/src/models/ctx/update_streaming_server_urls.rs b/src/models/ctx/update_streaming_server_urls.rs index d397eb28a..d12bbc322 100644 --- a/src/models/ctx/update_streaming_server_urls.rs +++ b/src/models/ctx/update_streaming_server_urls.rs @@ -1,43 +1,63 @@ use crate::constants::STREAMING_SERVER_URLS_STORAGE_KEY; -use crate::runtime::msg::{Action, ActionStreamingServer}; +use crate::runtime::msg::{Action, ActionStreamingServer, CtxAuthResponse}; use crate::runtime::EnvFutureExt; -use crate::{ - runtime::{ - msg::{ActionServerUrlsBucket, Event, Internal, Msg}, - Effect, EffectFuture, Effects, Env, - }, - types::{profile::Profile, streaming_server::ServerUrlsBucket}, +use crate::runtime::{ + msg::{ActionServerUrlsBucket, Event, Internal, Msg}, + Effect, EffectFuture, Effects, Env, }; +use crate::types::server_urls::ServerUrlsBucket; use futures::FutureExt; -use super::CtxError; +use super::{CtxError, CtxStatus}; pub fn update_streaming_server_urls( - server_urls_bucket: &mut ServerUrlsBucket, - profile: &Profile, + server_urls: &mut ServerUrlsBucket, + status: &CtxStatus, msg: &Msg, ) -> Effects { match msg { Msg::Action(Action::StreamingServer(ActionStreamingServer::ServerUrlsBucket(action))) => { match action { ActionServerUrlsBucket::AddServerUrl(url) => { - server_urls_bucket.add_url(url.clone()); + server_urls.add_url(url.clone()); + Effects::msg(Msg::Internal(Internal::StreamingServerUrlsBucketChanged)) + } + ActionServerUrlsBucket::EditServerUrl { id, new_url } => { + server_urls.edit_item(id, new_url.clone()); + Effects::msg(Msg::Internal(Internal::StreamingServerUrlsBucketChanged)) + } + ActionServerUrlsBucket::DeleteServerUrl(id) => { + server_urls.delete_item(id); + Effects::msg(Msg::Internal(Internal::StreamingServerUrlsBucketChanged)) + } + ActionServerUrlsBucket::SelectServerUrl(id) => { + server_urls.select_item(id); Effects::msg(Msg::Internal(Internal::StreamingServerUrlsBucketChanged)) } } } + Msg::Internal(Internal::CtxAuthResult(auth_request, result)) => match (status, result) { + (CtxStatus::Loading(loading_auth_request), Ok(CtxAuthResponse { auth, .. })) + if loading_auth_request == auth_request => + { + let next_server_urls = ServerUrlsBucket::new(Some(auth.user.id.to_owned())); + *server_urls = next_server_urls; + Effects::msg(Msg::Internal(Internal::StreamingServerUrlsBucketChanged)) + } + _ => Effects::none().unchanged(), + }, Msg::Internal(Internal::StreamingServerUrlsBucketChanged) => { - Effects::one(push_server_urls_to_storage::(server_urls_bucket)).unchanged() + Effects::one(push_server_urls_to_storage::(server_urls)).unchanged() } _ => Effects::none().unchanged(), } } -fn push_server_urls_to_storage(server_urls_bucket: &ServerUrlsBucket) -> Effect { - let uid = server_urls_bucket.uid.clone(); +fn push_server_urls_to_storage(server_urls: &ServerUrlsBucket) -> Effect { + let uid: Option = server_urls.uid.clone(); EffectFuture::Sequential( - E::set_storage(STREAMING_SERVER_URLS_STORAGE_KEY, Some(server_urls_bucket)) + E::set_storage(STREAMING_SERVER_URLS_STORAGE_KEY, Some(server_urls)) .map(move |result| match result { Ok(_) => Msg::Event(Event::StreamingServerUrlsPushedToStorage { uid: uid.clone() }), Err(error) => Msg::Event(Event::Error { diff --git a/src/models/streaming_server.rs b/src/models/streaming_server.rs index e797ff19d..30e73756b 100644 --- a/src/models/streaming_server.rs +++ b/src/models/streaming_server.rs @@ -17,10 +17,10 @@ use crate::types::addon::ResourcePath; use crate::types::api::SuccessResponse; use crate::types::empty_string_as_null; use crate::types::profile::{AuthKey, Profile}; +use crate::types::server_urls::ServerUrlsBucket; use crate::types::streaming_server::{ CreateMagnetRequest, CreateTorrentBlobRequest, DeviceInfo, GetHTTPSResponse, NetworkInfo, - ServerUrlsBucket, Settings, SettingsResponse, Statistics, StatisticsRequest, - TorrentStatisticsRequest, + Settings, SettingsResponse, Statistics, StatisticsRequest, TorrentStatisticsRequest, }; use crate::types::torrent::InfoHash; @@ -71,10 +71,7 @@ impl StreamingServer { }, settings: Loadable::Loading, base_url: None, - server_urls_bucket: ServerUrlsBucket::new( - profile.uid().to_owned(), - profile.settings.streaming_server_url.to_owned(), - ), + server_urls_bucket: ServerUrlsBucket::new(profile.uid().to_owned()), remote_url: None, playback_devices: Loadable::Loading, network_info: Loadable::Loading, @@ -97,10 +94,7 @@ impl UpdateWithCtx for StreamingServer { let base_url_effects = eq_update(&mut self.base_url, None); let server_urls_bucket_effects = eq_update( &mut self.server_urls_bucket, - ServerUrlsBucket::new( - ctx.profile.uid().to_owned(), - ctx.profile.settings.streaming_server_url.to_owned(), - ), + ServerUrlsBucket::new(ctx.profile.uid().to_owned()), ); let remote_url_effects = eq_update(&mut self.remote_url, None); Effects::many(vec![ @@ -244,10 +238,7 @@ impl UpdateWithCtx for StreamingServer { self.network_info = Loadable::Loading; self.device_info = Loadable::Loading; self.base_url = None; - self.server_urls_bucket = ServerUrlsBucket::new( - ctx.profile.uid().to_owned(), - ctx.profile.settings.streaming_server_url.to_owned(), - ); + self.server_urls_bucket = ServerUrlsBucket::new(ctx.profile.uid().to_owned()); self.remote_url = None; self.torrent = None; self.statistics = None; @@ -270,10 +261,7 @@ impl UpdateWithCtx for StreamingServer { let base_url_effects = eq_update(&mut self.base_url, Some(url.to_owned())); let server_urls_bucket_effects = eq_update( &mut self.server_urls_bucket, - ServerUrlsBucket::new( - ctx.profile.uid().to_owned(), - self.selected.transport_url.to_owned(), - ), + ServerUrlsBucket::new(ctx.profile.uid().to_owned()), ); let remote_url_effects = update_remote_url::( &mut self.remote_url, @@ -290,10 +278,7 @@ impl UpdateWithCtx for StreamingServer { let base_url_effects = eq_update(&mut self.base_url, None); let server_urls_bucket_effects = eq_update( &mut self.server_urls_bucket, - ServerUrlsBucket::new( - ctx.profile.uid().to_owned(), - self.selected.transport_url.to_owned(), - ), + ServerUrlsBucket::new(ctx.profile.uid().to_owned()), ); let remote_url_effects = eq_update(&mut self.remote_url, None); let playback_devices_effects = @@ -362,10 +347,7 @@ impl UpdateWithCtx for StreamingServer { let base_url_effects = eq_update(&mut self.base_url, None); let server_urls_bucket_effects = eq_update( &mut self.server_urls_bucket, - ServerUrlsBucket::new( - ctx.profile.uid().to_owned(), - self.selected.transport_url.to_owned(), - ), + ServerUrlsBucket::new(ctx.profile.uid().to_owned()), ); let remote_url_effects = eq_update(&mut self.remote_url, None); let playback_devices_effects = diff --git a/src/runtime/msg/action.rs b/src/runtime/msg/action.rs index ca9aefb6c..b5c03b44d 100644 --- a/src/runtime/msg/action.rs +++ b/src/runtime/msg/action.rs @@ -131,9 +131,9 @@ pub struct PlayOnDeviceArgs { #[serde(tag = "action", content = "args")] pub enum ActionServerUrlsBucket { AddServerUrl(Url), - // EditServerUrl { id: usize, new_url: Url }, - // DeleteServerUrl(usize), - // SelectServerUrl(usize), + EditServerUrl { id: usize, new_url: Url }, + DeleteServerUrl(usize), + SelectServerUrl(usize), } #[derive(Clone, Deserialize, Debug)] diff --git a/src/types/mod.rs b/src/types/mod.rs index 22093f407..79eb70aa1 100644 --- a/src/types/mod.rs +++ b/src/types/mod.rs @@ -7,6 +7,7 @@ pub mod player; pub mod profile; pub mod resource; pub mod search_history; +pub mod server_urls; pub mod streaming_server; pub mod streams; pub mod torrent; diff --git a/src/types/streaming_server/server_urls/mod.rs b/src/types/server_urls/mod.rs similarity index 100% rename from src/types/streaming_server/server_urls/mod.rs rename to src/types/server_urls/mod.rs diff --git a/src/types/streaming_server/server_urls/server_url_item.rs b/src/types/server_urls/server_url_item.rs similarity index 100% rename from src/types/streaming_server/server_urls/server_url_item.rs rename to src/types/server_urls/server_url_item.rs diff --git a/src/types/streaming_server/server_urls/server_urls_bucket.rs b/src/types/server_urls/server_urls_bucket.rs similarity index 74% rename from src/types/streaming_server/server_urls/server_urls_bucket.rs rename to src/types/server_urls/server_urls_bucket.rs index aefc10855..1d85bb460 100644 --- a/src/types/streaming_server/server_urls/server_urls_bucket.rs +++ b/src/types/server_urls/server_urls_bucket.rs @@ -1,9 +1,10 @@ use super::ServerUrlItem; use crate::{ - constants::{SERVER_URL_BUCKET_DEFAULT_ITEM_ID, SERVER_URL_BUCKET_MAX_ITEMS}, + constants::{ + SERVER_URL_BUCKET_DEFAULT_ITEM_ID, SERVER_URL_BUCKET_MAX_ITEMS, STREAMING_SERVER_URL, + }, types::profile::UID, }; -use anyhow::{anyhow, Result}; use serde::{Deserialize, Serialize}; use std::collections::HashMap; use url::Url; @@ -18,8 +19,9 @@ pub struct ServerUrlsBucket { impl ServerUrlsBucket { /// Create a new [`ServerUrlsBucket`] with the base URL inserted. - pub fn new(uid: UID, base_url: Url) -> Self { + pub fn new(uid: UID) -> Self { let mut items = HashMap::new(); + let base_url: &Url = &STREAMING_SERVER_URL; let server_base_url_item = ServerUrlItem { id: SERVER_URL_BUCKET_DEFAULT_ITEM_ID, @@ -82,37 +84,24 @@ impl ServerUrlsBucket { } } - pub fn edit_item(&mut self, id: &usize, new_url: Url) -> Result<()> { + pub fn edit_item(&mut self, id: &usize, new_url: Url) { if let Some(item) = self.items.get_mut(id) { item.url = new_url; item.mtime = Self::current_timestamp() as i64; - Ok(()) - } else { - Err(anyhow!("Item not found")) } } - pub fn delete_item(&mut self, id: &usize) -> Result<()> { - if *id == SERVER_URL_BUCKET_DEFAULT_ITEM_ID { - return Err(anyhow!("Cannot remove the base URL item.")); - } - if self.items.remove(id).is_some() { - Ok(()) - } else { - Err(anyhow!("Item not found")) + pub fn delete_item(&mut self, id: &usize) { + if *id != SERVER_URL_BUCKET_DEFAULT_ITEM_ID { + self.items.remove(id); } } - pub fn select_item(&mut self, id: &usize) -> Result<()> { - if let Some(current_selected_item) = self.items.values_mut().find(|item| item.selected) { - current_selected_item.selected = false; - } - - if let Some(new_selected_item) = self.items.get_mut(id) { - new_selected_item.selected = true; - Ok(()) - } else { - Err(anyhow!("Item not found")) + pub fn select_item(&mut self, id: &usize) { + if self.items.contains_key(id) { + for item in self.items.values_mut() { + item.selected = item.id == *id; + } } } diff --git a/src/types/streaming_server/mod.rs b/src/types/streaming_server/mod.rs index d44477ac5..d527051de 100644 --- a/src/types/streaming_server/mod.rs +++ b/src/types/streaming_server/mod.rs @@ -19,9 +19,6 @@ pub use settings::*; mod statistics; pub use statistics::*; -pub mod server_urls; -pub use server_urls::*; - use super::resource::SeriesInfo; use crate::types::{torrent::InfoHash, DefaultOnBool}; diff --git a/src/unit_tests/catalog_with_filters/load_action.rs b/src/unit_tests/catalog_with_filters/load_action.rs index e902e7c19..6041684a0 100644 --- a/src/unit_tests/catalog_with_filters/load_action.rs +++ b/src/unit_tests/catalog_with_filters/load_action.rs @@ -10,6 +10,7 @@ use crate::types::notifications::NotificationsBucket; use crate::types::profile::Profile; use crate::types::resource::MetaItemPreview; use crate::types::search_history::SearchHistoryBucket; +use crate::types::server_urls::ServerUrlsBucket; use crate::types::streams::StreamsBucket; use crate::unit_tests::{ default_fetch_handler, Request, TestEnv, EVENTS, FETCH_HANDLER, REQUESTS, STATES, @@ -50,6 +51,7 @@ fn default_catalog() { Profile::default(), LibraryBucket::default(), StreamsBucket::default(), + ServerUrlsBucket::new(None), NotificationsBucket::new::(None, vec![]), SearchHistoryBucket::default(), DismissedEventsBucket::default(), @@ -151,6 +153,7 @@ fn search_catalog() { Profile::default(), LibraryBucket::default(), StreamsBucket::default(), + ServerUrlsBucket::new(None), NotificationsBucket::new::(None, vec![]), SearchHistoryBucket::default(), DismissedEventsBucket::default(), diff --git a/src/unit_tests/ctx/add_to_library.rs b/src/unit_tests/ctx/add_to_library.rs index 85fec1aec..25bb117e2 100644 --- a/src/unit_tests/ctx/add_to_library.rs +++ b/src/unit_tests/ctx/add_to_library.rs @@ -9,6 +9,7 @@ use crate::types::notifications::NotificationsBucket; use crate::types::profile::{Auth, AuthKey, GDPRConsent, Profile, User}; use crate::types::resource::{MetaItemBehaviorHints, MetaItemPreview, PosterShape}; use crate::types::search_history::SearchHistoryBucket; +use crate::types::server_urls::ServerUrlsBucket; use crate::types::streams::StreamsBucket; use crate::types::True; use crate::unit_tests::{ @@ -106,6 +107,7 @@ fn actionctx_addtolibrary() { ..Default::default() }, StreamsBucket::default(), + ServerUrlsBucket::new(None), NotificationsBucket::new::(None, vec![]), SearchHistoryBucket::default(), DismissedEventsBucket::default(), @@ -243,6 +245,7 @@ fn actionctx_addtolibrary_already_added() { .collect(), }, StreamsBucket::default(), + ServerUrlsBucket::new(None), NotificationsBucket::new::(None, vec![]), SearchHistoryBucket::default(), DismissedEventsBucket::default(), diff --git a/src/unit_tests/ctx/authenticate.rs b/src/unit_tests/ctx/authenticate.rs index d5155a417..3cf751f73 100644 --- a/src/unit_tests/ctx/authenticate.rs +++ b/src/unit_tests/ctx/authenticate.rs @@ -1,6 +1,7 @@ use crate::types::events::DismissedEventsBucket; use crate::types::notifications::NotificationsBucket; use crate::types::search_history::SearchHistoryBucket; +use crate::types::server_urls::ServerUrlsBucket; use crate::types::streams::StreamsBucket; use crate::{ constants::{LIBRARY_RECENT_STORAGE_KEY, LIBRARY_STORAGE_KEY, PROFILE_STORAGE_KEY}, @@ -107,6 +108,7 @@ fn actionctx_authenticate_login() { Profile::default(), LibraryBucket::default(), StreamsBucket::default(), + ServerUrlsBucket::new(None), NotificationsBucket::new::(None, vec![]), SearchHistoryBucket::default(), DismissedEventsBucket::default(), @@ -248,6 +250,7 @@ fn actionctx_authenticate_login_with_token() { Profile::default(), LibraryBucket::default(), StreamsBucket::default(), + ServerUrlsBucket::new(None), NotificationsBucket::new::(None, vec![]), SearchHistoryBucket::default(), DismissedEventsBucket::default(), @@ -388,6 +391,7 @@ fn actionctx_authenticate_facebook() { Profile::default(), LibraryBucket::default(), StreamsBucket::default(), + ServerUrlsBucket::new(None), NotificationsBucket::new::(None, vec![]), SearchHistoryBucket::default(), DismissedEventsBucket::default(), @@ -528,6 +532,7 @@ fn actionctx_authenticate_register() { Profile::default(), LibraryBucket::default(), StreamsBucket::default(), + ServerUrlsBucket::new(None), NotificationsBucket::new::(None, vec![]), SearchHistoryBucket::default(), DismissedEventsBucket::default(), diff --git a/src/unit_tests/ctx/install_addon.rs b/src/unit_tests/ctx/install_addon.rs index 7e189bf53..fbabad68d 100644 --- a/src/unit_tests/ctx/install_addon.rs +++ b/src/unit_tests/ctx/install_addon.rs @@ -9,6 +9,7 @@ use crate::types::library::LibraryBucket; use crate::types::notifications::NotificationsBucket; use crate::types::profile::{Auth, AuthKey, GDPRConsent, Profile, User}; use crate::types::search_history::SearchHistoryBucket; +use crate::types::server_urls::ServerUrlsBucket; use crate::types::streams::StreamsBucket; use crate::types::True; use crate::unit_tests::{ @@ -56,6 +57,7 @@ fn actionctx_installaddon_install() { }, LibraryBucket::default(), StreamsBucket::default(), + ServerUrlsBucket::new(None), NotificationsBucket::new::(None, vec![]), SearchHistoryBucket::default(), DismissedEventsBucket::default(), @@ -161,6 +163,7 @@ fn actionctx_installaddon_install_with_user() { }, LibraryBucket::default(), StreamsBucket::default(), + ServerUrlsBucket::new(None), NotificationsBucket::new::(None, vec![]), SearchHistoryBucket::default(), DismissedEventsBucket::default(), @@ -284,6 +287,7 @@ fn actionctx_installaddon_update() { }, LibraryBucket::default(), StreamsBucket::default(), + ServerUrlsBucket::new(None), NotificationsBucket::new::(None, vec![]), SearchHistoryBucket::default(), DismissedEventsBucket::default(), @@ -361,6 +365,7 @@ fn actionctx_installaddon_already_installed() { profile, LibraryBucket::default(), StreamsBucket::default(), + ServerUrlsBucket::new(None), NotificationsBucket::new::(None, vec![]), SearchHistoryBucket::default(), DismissedEventsBucket::default(), diff --git a/src/unit_tests/ctx/logout.rs b/src/unit_tests/ctx/logout.rs index b8dc7a258..6ce02b362 100644 --- a/src/unit_tests/ctx/logout.rs +++ b/src/unit_tests/ctx/logout.rs @@ -8,6 +8,7 @@ use crate::types::library::LibraryBucket; use crate::types::notifications::NotificationsBucket; use crate::types::profile::{Auth, AuthKey, GDPRConsent, Profile, User}; use crate::types::search_history::SearchHistoryBucket; +use crate::types::server_urls::ServerUrlsBucket; use crate::types::streams::StreamsBucket; use crate::types::True; use crate::unit_tests::{ @@ -87,6 +88,7 @@ fn actionctx_logout() { profile, library, StreamsBucket::default(), + ServerUrlsBucket::new(None), NotificationsBucket::new::(None, vec![]), SearchHistoryBucket::default(), DismissedEventsBucket::default(), diff --git a/src/unit_tests/ctx/notifications/update_notifications.rs b/src/unit_tests/ctx/notifications/update_notifications.rs index d6015bc6a..4067d6ada 100644 --- a/src/unit_tests/ctx/notifications/update_notifications.rs +++ b/src/unit_tests/ctx/notifications/update_notifications.rs @@ -39,6 +39,7 @@ use crate::{ Video, VideoId, }, search_history::SearchHistoryBucket, + server_urls::ServerUrlsBucket, streams::StreamsBucket, }, unit_tests::{ @@ -239,6 +240,7 @@ fn test_pull_notifications_and_play_in_player() { }], ), StreamsBucket::default(), + ServerUrlsBucket::new(None), NotificationsBucket::new::(None, vec![]), SearchHistoryBucket::default(), DismissedEventsBucket::default(), @@ -388,6 +390,7 @@ fn test_pull_notifications_test_cases() { }, LibraryBucket::new(None, test.library_items), StreamsBucket::default(), + ServerUrlsBucket::new(None), NotificationsBucket::new::(None, test.notification_items), SearchHistoryBucket::default(), DismissedEventsBucket::default(), @@ -485,6 +488,7 @@ fn test_dismiss_notification() { ], ), StreamsBucket::default(), + ServerUrlsBucket::new(None), NotificationsBucket::new::( None, vec![ diff --git a/src/unit_tests/ctx/pull_addons_from_api.rs b/src/unit_tests/ctx/pull_addons_from_api.rs index 5000c3282..d852d24ea 100644 --- a/src/unit_tests/ctx/pull_addons_from_api.rs +++ b/src/unit_tests/ctx/pull_addons_from_api.rs @@ -9,6 +9,7 @@ use crate::types::library::LibraryBucket; use crate::types::notifications::NotificationsBucket; use crate::types::profile::{Auth, AuthKey, GDPRConsent, Profile, User}; use crate::types::search_history::SearchHistoryBucket; +use crate::types::server_urls::ServerUrlsBucket; use crate::types::streams::StreamsBucket; use crate::unit_tests::{ default_fetch_handler, Request, TestEnv, FETCH_HANDLER, REQUESTS, STORAGE, @@ -44,6 +45,7 @@ fn actionctx_pulladdonsfromapi() { }, LibraryBucket::default(), StreamsBucket::default(), + ServerUrlsBucket::new(None), NotificationsBucket::new::(None, vec![]), SearchHistoryBucket::default(), DismissedEventsBucket::default(), @@ -152,6 +154,7 @@ fn actionctx_pulladdonsfromapi_with_user() { }, LibraryBucket::default(), StreamsBucket::default(), + ServerUrlsBucket::new(None), NotificationsBucket::new::(None, vec![]), SearchHistoryBucket::default(), DismissedEventsBucket::default(), diff --git a/src/unit_tests/ctx/push_addons_to_api.rs b/src/unit_tests/ctx/push_addons_to_api.rs index b2ecd414c..553722dad 100644 --- a/src/unit_tests/ctx/push_addons_to_api.rs +++ b/src/unit_tests/ctx/push_addons_to_api.rs @@ -8,6 +8,7 @@ use crate::types::library::LibraryBucket; use crate::types::notifications::NotificationsBucket; use crate::types::profile::{Auth, AuthKey, GDPRConsent, Profile, User}; use crate::types::search_history::SearchHistoryBucket; +use crate::types::server_urls::ServerUrlsBucket; use crate::types::streams::StreamsBucket; use crate::types::True; use crate::unit_tests::{default_fetch_handler, Request, TestEnv, FETCH_HANDLER, REQUESTS}; @@ -52,6 +53,7 @@ fn actionctx_pushaddonstoapi() { }, LibraryBucket::default(), StreamsBucket::default(), + ServerUrlsBucket::new(None), NotificationsBucket::new::(None, vec![]), SearchHistoryBucket::default(), DismissedEventsBucket::default(), @@ -142,6 +144,7 @@ fn actionctx_pushaddonstoapi_with_user() { }, LibraryBucket::default(), StreamsBucket::default(), + ServerUrlsBucket::new(None), NotificationsBucket::new::(None, vec![]), SearchHistoryBucket::default(), DismissedEventsBucket::default(), diff --git a/src/unit_tests/ctx/remove_from_library.rs b/src/unit_tests/ctx/remove_from_library.rs index 1ddb1669a..2b50fb525 100644 --- a/src/unit_tests/ctx/remove_from_library.rs +++ b/src/unit_tests/ctx/remove_from_library.rs @@ -8,6 +8,7 @@ use crate::types::library::{LibraryBucket, LibraryItem}; use crate::types::notifications::NotificationsBucket; use crate::types::profile::{Auth, AuthKey, GDPRConsent, Profile, User}; use crate::types::search_history::SearchHistoryBucket; +use crate::types::server_urls::ServerUrlsBucket; use crate::types::streams::StreamsBucket; use crate::types::True; use crate::unit_tests::{ @@ -101,6 +102,7 @@ fn actionctx_removefromlibrary() { .collect(), }, StreamsBucket::default(), + ServerUrlsBucket::new(None), NotificationsBucket::new::(None, vec![]), SearchHistoryBucket::default(), DismissedEventsBucket::default(), @@ -189,6 +191,7 @@ fn actionctx_removefromlibrary_not_added() { .collect(), }, StreamsBucket::default(), + ServerUrlsBucket::new(None), NotificationsBucket::new::(None, vec![]), SearchHistoryBucket::default(), DismissedEventsBucket::default(), diff --git a/src/unit_tests/ctx/rewind_library_item.rs b/src/unit_tests/ctx/rewind_library_item.rs index f6ff7144e..774858c77 100644 --- a/src/unit_tests/ctx/rewind_library_item.rs +++ b/src/unit_tests/ctx/rewind_library_item.rs @@ -8,6 +8,7 @@ use crate::types::library::{LibraryBucket, LibraryItem, LibraryItemState}; use crate::types::notifications::NotificationsBucket; use crate::types::profile::{Auth, AuthKey, GDPRConsent, Profile, User}; use crate::types::search_history::SearchHistoryBucket; +use crate::types::server_urls::ServerUrlsBucket; use crate::types::streams::StreamsBucket; use crate::types::True; use crate::unit_tests::{ @@ -109,6 +110,7 @@ fn actionctx_rewindlibraryitem() { .collect(), }, StreamsBucket::default(), + ServerUrlsBucket::new(None), NotificationsBucket::new::(None, vec![]), SearchHistoryBucket::default(), DismissedEventsBucket::default(), @@ -200,6 +202,7 @@ fn actionctx_rewindlibraryitem_not_added() { .collect(), }, StreamsBucket::default(), + ServerUrlsBucket::new(None), NotificationsBucket::new::(None, vec![]), SearchHistoryBucket::default(), DismissedEventsBucket::default(), diff --git a/src/unit_tests/ctx/sync_library_with_api.rs b/src/unit_tests/ctx/sync_library_with_api.rs index 0050f7077..4d349222c 100644 --- a/src/unit_tests/ctx/sync_library_with_api.rs +++ b/src/unit_tests/ctx/sync_library_with_api.rs @@ -10,6 +10,7 @@ use crate::types::library::{LibraryBucket, LibraryItem}; use crate::types::notifications::NotificationsBucket; use crate::types::profile::{Auth, AuthKey, GDPRConsent, Profile, User}; use crate::types::search_history::SearchHistoryBucket; +use crate::types::server_urls::ServerUrlsBucket; use crate::types::streams::StreamsBucket; use crate::types::True; use crate::unit_tests::{ @@ -35,6 +36,7 @@ fn actionctx_synclibrarywithapi() { Profile::default(), LibraryBucket::default(), StreamsBucket::default(), + ServerUrlsBucket::new(None), NotificationsBucket::new::(None, vec![]), SearchHistoryBucket::default(), DismissedEventsBucket::default(), @@ -291,6 +293,7 @@ fn actionctx_synclibrarywithapi_with_user() { .collect(), }, StreamsBucket::default(), + ServerUrlsBucket::new(None), NotificationsBucket::new::(None, vec![]), SearchHistoryBucket::default(), DismissedEventsBucket::default(), @@ -428,6 +431,7 @@ fn actionctx_synclibrarywithapi_with_user_empty_library() { }, LibraryBucket::default(), StreamsBucket::default(), + ServerUrlsBucket::new(None), NotificationsBucket::new::(None, vec![]), SearchHistoryBucket::default(), DismissedEventsBucket::default(), diff --git a/src/unit_tests/ctx/uninstall_addon.rs b/src/unit_tests/ctx/uninstall_addon.rs index be4d380da..9bc334763 100644 --- a/src/unit_tests/ctx/uninstall_addon.rs +++ b/src/unit_tests/ctx/uninstall_addon.rs @@ -10,6 +10,7 @@ use crate::types::notifications::NotificationsBucket; use crate::types::profile::{Auth, AuthKey, GDPRConsent, Profile, User}; use crate::types::resource::{Stream, StreamBehaviorHints, StreamSource}; use crate::types::search_history::SearchHistoryBucket; +use crate::types::server_urls::ServerUrlsBucket; use crate::types::streams::{StreamsBucket, StreamsItem, StreamsItemKey}; use crate::types::True; use crate::unit_tests::{ @@ -108,6 +109,7 @@ fn actionctx_uninstalladdon() { profile, LibraryBucket::default(), StreamsBucket::default(), + ServerUrlsBucket::new(None), NotificationsBucket::new::(None, vec![]), SearchHistoryBucket::default(), DismissedEventsBucket::default(), @@ -221,6 +223,7 @@ fn actionctx_uninstalladdon_with_user() { profile, LibraryBucket::default(), StreamsBucket::default(), + ServerUrlsBucket::new(None), NotificationsBucket::new::(None, vec![]), SearchHistoryBucket::default(), DismissedEventsBucket::default(), @@ -314,6 +317,7 @@ fn actionctx_uninstalladdon_protected() { profile, LibraryBucket::default(), StreamsBucket::default(), + ServerUrlsBucket::new(None), NotificationsBucket::new::(None, vec![]), SearchHistoryBucket::default(), DismissedEventsBucket::default(), @@ -390,6 +394,7 @@ fn actionctx_uninstalladdon_not_installed() { profile, LibraryBucket::default(), StreamsBucket::default(), + ServerUrlsBucket::new(None), NotificationsBucket::new::(None, vec![]), SearchHistoryBucket::default(), DismissedEventsBucket::default(), @@ -474,6 +479,7 @@ fn actionctx_uninstalladdon_streams_bucket() { profile, LibraryBucket::default(), streams, + ServerUrlsBucket::new(None), NotificationsBucket::new::(None, vec![]), SearchHistoryBucket::default(), DismissedEventsBucket::default(), diff --git a/src/unit_tests/ctx/update_search_history.rs b/src/unit_tests/ctx/update_search_history.rs index 08dc69555..e28ff7737 100644 --- a/src/unit_tests/ctx/update_search_history.rs +++ b/src/unit_tests/ctx/update_search_history.rs @@ -13,7 +13,7 @@ use crate::{ types::{ addon::ExtraValue, events::DismissedEventsBucket, library::LibraryBucket, notifications::NotificationsBucket, profile::Profile, search_history::SearchHistoryBucket, - streams::StreamsBucket, + server_urls::ServerUrlsBucket, streams::StreamsBucket, }, unit_tests::{TestEnv, STORAGE}, }; @@ -33,6 +33,7 @@ fn test_search_history_update() { Profile::default(), LibraryBucket::default(), StreamsBucket::default(), + ServerUrlsBucket::new(None), NotificationsBucket::new::(None, vec![]), SearchHistoryBucket::default(), DismissedEventsBucket::default(), @@ -106,6 +107,7 @@ fn test_search_history_clear_items() { Profile::default(), LibraryBucket::default(), StreamsBucket::default(), + ServerUrlsBucket::new(None), NotificationsBucket::new::(None, vec![]), SearchHistoryBucket::default(), DismissedEventsBucket::default(), diff --git a/src/unit_tests/ctx/update_settings.rs b/src/unit_tests/ctx/update_settings.rs index 1ae521e39..18b7c7368 100644 --- a/src/unit_tests/ctx/update_settings.rs +++ b/src/unit_tests/ctx/update_settings.rs @@ -7,6 +7,7 @@ use crate::types::library::LibraryBucket; use crate::types::notifications::NotificationsBucket; use crate::types::profile::{Profile, Settings}; use crate::types::search_history::SearchHistoryBucket; +use crate::types::server_urls::ServerUrlsBucket; use crate::types::streams::StreamsBucket; use crate::unit_tests::{TestEnv, REQUESTS, STORAGE}; use stremio_derive::Model; @@ -28,6 +29,7 @@ fn actionctx_updatesettings() { Profile::default(), LibraryBucket::default(), StreamsBucket::default(), + ServerUrlsBucket::new(None), NotificationsBucket::new::(None, vec![]), SearchHistoryBucket::default(), DismissedEventsBucket::default(), @@ -87,6 +89,7 @@ fn actionctx_updatesettings_not_changed() { profile, LibraryBucket::default(), StreamsBucket::default(), + ServerUrlsBucket::new(None), NotificationsBucket::new::(None, vec![]), SearchHistoryBucket::default(), DismissedEventsBucket::default(), diff --git a/src/unit_tests/ctx/upgrade_addon.rs b/src/unit_tests/ctx/upgrade_addon.rs index 4c0208bb9..819429f55 100644 --- a/src/unit_tests/ctx/upgrade_addon.rs +++ b/src/unit_tests/ctx/upgrade_addon.rs @@ -8,6 +8,7 @@ use crate::types::library::LibraryBucket; use crate::types::notifications::NotificationsBucket; use crate::types::profile::Profile; use crate::types::search_history::SearchHistoryBucket; +use crate::types::server_urls::ServerUrlsBucket; use crate::types::streams::StreamsBucket; use crate::unit_tests::{TestEnv, REQUESTS, STORAGE}; use semver::Version; @@ -88,6 +89,7 @@ fn actionctx_addon_upgrade() { }, LibraryBucket::default(), StreamsBucket::default(), + ServerUrlsBucket::new(None), NotificationsBucket::new::(None, vec![]), SearchHistoryBucket::default(), DismissedEventsBucket::default(), @@ -180,6 +182,7 @@ fn actionctx_addon_upgrade_fail_due_to_different_url() { }, LibraryBucket::default(), StreamsBucket::default(), + ServerUrlsBucket::new(None), NotificationsBucket::new::(None, vec![]), SearchHistoryBucket::default(), DismissedEventsBucket::default(), diff --git a/src/unit_tests/data_export.rs b/src/unit_tests/data_export.rs index 289e6e4ad..0009c0908 100644 --- a/src/unit_tests/data_export.rs +++ b/src/unit_tests/data_export.rs @@ -10,6 +10,7 @@ use crate::types::notifications::NotificationsBucket; use crate::types::profile::Profile; use crate::types::profile::{Auth, AuthKey, User}; use crate::types::search_history::SearchHistoryBucket; +use crate::types::server_urls::ServerUrlsBucket; use crate::types::streams::StreamsBucket; use crate::unit_tests::{ default_fetch_handler, Request, TestEnv, EVENTS, FETCH_HANDLER, REQUESTS, STATES, @@ -53,6 +54,7 @@ fn data_export_with_user() { Profile::default(), LibraryBucket::default(), StreamsBucket::default(), + ServerUrlsBucket::new(None), NotificationsBucket::new::(None, vec![]), SearchHistoryBucket::default(), DismissedEventsBucket::default(), @@ -135,6 +137,7 @@ fn data_export_without_a_user() { Profile::default(), LibraryBucket::default(), StreamsBucket::default(), + ServerUrlsBucket::new(None), NotificationsBucket::new::(None, vec![]), SearchHistoryBucket::default(), DismissedEventsBucket::default(), diff --git a/src/unit_tests/link.rs b/src/unit_tests/link.rs index 5f0906d28..c310f751c 100644 --- a/src/unit_tests/link.rs +++ b/src/unit_tests/link.rs @@ -9,6 +9,7 @@ use crate::types::library::LibraryBucket; use crate::types::notifications::NotificationsBucket; use crate::types::profile::Profile; use crate::types::search_history::SearchHistoryBucket; +use crate::types::server_urls::ServerUrlsBucket; use crate::types::streams::StreamsBucket; use crate::unit_tests::{default_fetch_handler, Request, TestEnv, FETCH_HANDLER, REQUESTS}; use futures::future; @@ -61,6 +62,7 @@ fn create_link_code() { Profile::default(), LibraryBucket::default(), StreamsBucket::default(), + ServerUrlsBucket::new(None), NotificationsBucket::new::(None, vec![]), SearchHistoryBucket::default(), DismissedEventsBucket::default(), diff --git a/stremio-core-web/src/model/model.rs b/stremio-core-web/src/model/model.rs index 30bad6d9a..52413054c 100644 --- a/stremio-core-web/src/model/model.rs +++ b/stremio-core-web/src/model/model.rs @@ -26,7 +26,8 @@ use stremio_core::{ types::{ addon::DescriptorPreview, api::LinkAuthKey, events::DismissedEventsBucket, library::LibraryBucket, notifications::NotificationsBucket, profile::Profile, - resource::MetaItemPreview, search_history::SearchHistoryBucket, streams::StreamsBucket, + resource::MetaItemPreview, search_history::SearchHistoryBucket, + server_urls::ServerUrlsBucket, streams::StreamsBucket, }, Model, }; @@ -62,6 +63,7 @@ impl WebModel { profile: Profile, library: LibraryBucket, streams: StreamsBucket, + server_urls: ServerUrlsBucket, notifications: NotificationsBucket, search_history: SearchHistoryBucket, dismissed_events: DismissedEventsBucket, @@ -84,6 +86,7 @@ impl WebModel { profile, library, streams, + server_urls, notifications, search_history, dismissed_events, diff --git a/stremio-core-web/src/model/serialize_streaming_server.rs b/stremio-core-web/src/model/serialize_streaming_server.rs index a53d01c65..9a691b89b 100644 --- a/stremio-core-web/src/model/serialize_streaming_server.rs +++ b/stremio-core-web/src/model/serialize_streaming_server.rs @@ -12,7 +12,7 @@ use url::Url; use wasm_bindgen::JsValue; mod model { - use stremio_core::types::{streaming_server::ServerUrlsBucket, torrent::InfoHash}; + use stremio_core::types::{server_urls::ServerUrlsBucket, torrent::InfoHash}; use super::*; type TorrentLoadable<'a> = Loadable<(&'a ResourcePath, MetaItemDeepLinks), &'a EnvError>; diff --git a/stremio-core-web/src/stremio_core_web.rs b/stremio-core-web/src/stremio_core_web.rs index d04863357..2d446aada 100644 --- a/stremio-core-web/src/stremio_core_web.rs +++ b/stremio-core-web/src/stremio_core_web.rs @@ -19,7 +19,7 @@ use stremio_core::{ types::{ events::DismissedEventsBucket, library::LibraryBucket, notifications::NotificationsBucket, profile::Profile, resource::Stream, search_history::SearchHistoryBucket, - streams::StreamsBucket, + server_urls::ServerUrlsBucket, streams::StreamsBucket, }, }; @@ -68,6 +68,7 @@ pub async fn initialize_runtime(emit_to_ui: js_sys::Function) -> Result<(), JsVa WebEnv::get_storage::(LIBRARY_RECENT_STORAGE_KEY), WebEnv::get_storage::(LIBRARY_STORAGE_KEY), WebEnv::get_storage::(STREAMS_STORAGE_KEY), + WebEnv::get_storage::(STREAMS_STORAGE_KEY), WebEnv::get_storage::(NOTIFICATIONS_STORAGE_KEY), WebEnv::get_storage::(SEARCH_HISTORY_STORAGE_KEY), WebEnv::get_storage::(DISMISSED_EVENTS_STORAGE_KEY), @@ -78,6 +79,7 @@ pub async fn initialize_runtime(emit_to_ui: js_sys::Function) -> Result<(), JsVa recent_bucket, other_bucket, streams_bucket, + server_urls_bucket, notifications_bucket, search_history_bucket, dismissed_events_bucket, @@ -92,6 +94,8 @@ pub async fn initialize_runtime(emit_to_ui: js_sys::Function) -> Result<(), JsVa }; let streams_bucket = streams_bucket.unwrap_or_else(|| StreamsBucket::new(profile.uid())); + let server_urls_bucket = + server_urls_bucket.unwrap_or(ServerUrlsBucket::new(profile.uid())); let notifications_bucket = notifications_bucket .unwrap_or(NotificationsBucket::new::(profile.uid(), vec![])); let search_history_bucket = @@ -102,6 +106,7 @@ pub async fn initialize_runtime(emit_to_ui: js_sys::Function) -> Result<(), JsVa profile, library, streams_bucket, + server_urls_bucket, notifications_bucket, search_history_bucket, dismissed_events_bucket, From eae1404051a8875675fa6e1da198c61f9b478281 Mon Sep 17 00:00:00 2001 From: "Timothy Z." Date: Mon, 7 Oct 2024 14:10:59 +0300 Subject: [PATCH 12/44] remove: serverurl bucket from server_settings --- src/models/streaming_server.rs | 24 ------------------------ 1 file changed, 24 deletions(-) diff --git a/src/models/streaming_server.rs b/src/models/streaming_server.rs index 30e73756b..fbc8c5a07 100644 --- a/src/models/streaming_server.rs +++ b/src/models/streaming_server.rs @@ -17,7 +17,6 @@ use crate::types::addon::ResourcePath; use crate::types::api::SuccessResponse; use crate::types::empty_string_as_null; use crate::types::profile::{AuthKey, Profile}; -use crate::types::server_urls::ServerUrlsBucket; use crate::types::streaming_server::{ CreateMagnetRequest, CreateTorrentBlobRequest, DeviceInfo, GetHTTPSResponse, NetworkInfo, Settings, SettingsResponse, Statistics, StatisticsRequest, TorrentStatisticsRequest, @@ -45,7 +44,6 @@ pub struct StreamingServer { pub selected: Selected, pub settings: Loadable, pub base_url: Option, - pub server_urls_bucket: ServerUrlsBucket, pub remote_url: Option, pub playback_devices: Loadable, EnvError>, pub network_info: Loadable, @@ -71,7 +69,6 @@ impl StreamingServer { }, settings: Loadable::Loading, base_url: None, - server_urls_bucket: ServerUrlsBucket::new(profile.uid().to_owned()), remote_url: None, playback_devices: Loadable::Loading, network_info: Loadable::Loading, @@ -92,10 +89,6 @@ impl UpdateWithCtx for StreamingServer { let network_info_effects = eq_update(&mut self.network_info, Loadable::Loading); let device_info_effects = eq_update(&mut self.device_info, Loadable::Loading); let base_url_effects = eq_update(&mut self.base_url, None); - let server_urls_bucket_effects = eq_update( - &mut self.server_urls_bucket, - ServerUrlsBucket::new(ctx.profile.uid().to_owned()), - ); let remote_url_effects = eq_update(&mut self.remote_url, None); Effects::many(vec![ get_settings::(&self.selected.transport_url), @@ -108,7 +101,6 @@ impl UpdateWithCtx for StreamingServer { .join(network_info_effects) .join(device_info_effects) .join(base_url_effects) - .join(server_urls_bucket_effects) .join(remote_url_effects) } Msg::Action(Action::StreamingServer(ActionStreamingServer::UpdateSettings( @@ -238,7 +230,6 @@ impl UpdateWithCtx for StreamingServer { self.network_info = Loadable::Loading; self.device_info = Loadable::Loading; self.base_url = None; - self.server_urls_bucket = ServerUrlsBucket::new(ctx.profile.uid().to_owned()); self.remote_url = None; self.torrent = None; self.statistics = None; @@ -259,10 +250,6 @@ impl UpdateWithCtx for StreamingServer { Loadable::Ready(settings.values.to_owned()), ); let base_url_effects = eq_update(&mut self.base_url, Some(url.to_owned())); - let server_urls_bucket_effects = eq_update( - &mut self.server_urls_bucket, - ServerUrlsBucket::new(ctx.profile.uid().to_owned()), - ); let remote_url_effects = update_remote_url::( &mut self.remote_url, &self.selected, @@ -271,15 +258,10 @@ impl UpdateWithCtx for StreamingServer { ); settings_effects .join(base_url_effects) - .join(server_urls_bucket_effects) .join(remote_url_effects) } Err(error) => { let base_url_effects = eq_update(&mut self.base_url, None); - let server_urls_bucket_effects = eq_update( - &mut self.server_urls_bucket, - ServerUrlsBucket::new(ctx.profile.uid().to_owned()), - ); let remote_url_effects = eq_update(&mut self.remote_url, None); let playback_devices_effects = eq_update(&mut self.playback_devices, Loadable::Err(error.to_owned())); @@ -291,7 +273,6 @@ impl UpdateWithCtx for StreamingServer { eq_update(&mut self.settings, Loadable::Err(error.to_owned())); let torrent_effects = eq_update(&mut self.torrent, None); base_url_effects - .join(server_urls_bucket_effects) .join(remote_url_effects) .join(playback_devices_effects) .join(network_info_effects) @@ -345,10 +326,6 @@ impl UpdateWithCtx for StreamingServer { Ok(_) => Effects::none().unchanged(), Err(error) => { let base_url_effects = eq_update(&mut self.base_url, None); - let server_urls_bucket_effects = eq_update( - &mut self.server_urls_bucket, - ServerUrlsBucket::new(ctx.profile.uid().to_owned()), - ); let remote_url_effects = eq_update(&mut self.remote_url, None); let playback_devices_effects = eq_update(&mut self.playback_devices, Loadable::Err(error.to_owned())); @@ -360,7 +337,6 @@ impl UpdateWithCtx for StreamingServer { eq_update(&mut self.settings, Loadable::Err(error.to_owned())); let torrent_effects = eq_update(&mut self.torrent, None); base_url_effects - .join(server_urls_bucket_effects) .join(remote_url_effects) .join(playback_devices_effects) .join(network_info_effects) From 4c449ef617e0a9373b7821d26bb8f837c85b7bbe Mon Sep 17 00:00:00 2001 From: "Timothy Z." Date: Mon, 7 Oct 2024 14:21:51 +0300 Subject: [PATCH 13/44] refactor: model seralization --- stremio-core-web/src/model/model.rs | 15 +++------------ 1 file changed, 3 insertions(+), 12 deletions(-) diff --git a/stremio-core-web/src/model/model.rs b/stremio-core-web/src/model/model.rs index 52413054c..90ec6e776 100644 --- a/stremio-core-web/src/model/model.rs +++ b/stremio-core-web/src/model/model.rs @@ -128,10 +128,7 @@ impl WebModel { WebModelField::ContinueWatchingPreview => serialize_continue_watching_preview( &self.continue_watching_preview, &self.ctx.streams, - self.streaming_server - .server_urls_bucket - .selected_item_url() - .as_ref(), + self.streaming_server.base_url.as_ref(), &self.ctx.profile.settings, ), WebModelField::Board => { @@ -149,19 +146,13 @@ impl WebModel { WebModelField::Library => serialize_library( &self.library, &self.ctx, - self.streaming_server - .server_urls_bucket - .selected_item_url() - .as_ref(), + self.streaming_server.base_url.as_ref(), "library".to_owned(), ), WebModelField::ContinueWatching => serialize_library( &self.continue_watching, &self.ctx, - self.streaming_server - .server_urls_bucket - .selected_item_url() - .as_ref(), + self.streaming_server.base_url.as_ref(), "continuewatching".to_owned(), ), WebModelField::Search => { From bbb638fe3667aa303d4a243095b4f1256edb5bcc Mon Sep 17 00:00:00 2001 From: "Timothy Z." Date: Mon, 7 Oct 2024 14:24:52 +0300 Subject: [PATCH 14/44] refactor: remove unecessary logic --- src/models/ctx/update_streaming_server_urls.rs | 4 ---- src/runtime/msg/action.rs | 1 - src/types/server_urls/server_urls_bucket.rs | 16 ---------------- stremio-core-web/src/model/serialize_discover.rs | 4 +--- .../src/model/serialize_meta_details.rs | 12 ++++-------- stremio-core-web/src/model/serialize_player.rs | 6 +++--- .../src/model/serialize_streaming_server.rs | 4 +--- 7 files changed, 9 insertions(+), 38 deletions(-) diff --git a/src/models/ctx/update_streaming_server_urls.rs b/src/models/ctx/update_streaming_server_urls.rs index d12bbc322..694fb9c96 100644 --- a/src/models/ctx/update_streaming_server_urls.rs +++ b/src/models/ctx/update_streaming_server_urls.rs @@ -30,10 +30,6 @@ pub fn update_streaming_server_urls( server_urls.delete_item(id); Effects::msg(Msg::Internal(Internal::StreamingServerUrlsBucketChanged)) } - ActionServerUrlsBucket::SelectServerUrl(id) => { - server_urls.select_item(id); - Effects::msg(Msg::Internal(Internal::StreamingServerUrlsBucketChanged)) - } } } Msg::Internal(Internal::CtxAuthResult(auth_request, result)) => match (status, result) { diff --git a/src/runtime/msg/action.rs b/src/runtime/msg/action.rs index b5c03b44d..efe344a2c 100644 --- a/src/runtime/msg/action.rs +++ b/src/runtime/msg/action.rs @@ -133,7 +133,6 @@ pub enum ActionServerUrlsBucket { AddServerUrl(Url), EditServerUrl { id: usize, new_url: Url }, DeleteServerUrl(usize), - SelectServerUrl(usize), } #[derive(Clone, Deserialize, Debug)] diff --git a/src/types/server_urls/server_urls_bucket.rs b/src/types/server_urls/server_urls_bucket.rs index 1d85bb460..20b2b713a 100644 --- a/src/types/server_urls/server_urls_bucket.rs +++ b/src/types/server_urls/server_urls_bucket.rs @@ -96,20 +96,4 @@ impl ServerUrlsBucket { self.items.remove(id); } } - - pub fn select_item(&mut self, id: &usize) { - if self.items.contains_key(id) { - for item in self.items.values_mut() { - item.selected = item.id == *id; - } - } - } - - pub fn selected_item(&self) -> Option<&ServerUrlItem> { - self.items.values().find(|item| item.selected) - } - - pub fn selected_item_url(&self) -> Option { - self.selected_item().map(|item| item.url.clone()) - } } diff --git a/stremio-core-web/src/model/serialize_discover.rs b/stremio-core-web/src/model/serialize_discover.rs index 4fe91085c..865073141 100644 --- a/stremio-core-web/src/model/serialize_discover.rs +++ b/stremio-core-web/src/model/serialize_discover.rs @@ -195,9 +195,7 @@ pub fn serialize_discover( stream, deep_links: StreamDeepLinks::from(( stream, - &streaming_server - .server_urls_bucket - .selected_item_url(), + &streaming_server.base_url, &ctx.profile.settings, )) .into_web_deep_links(), diff --git a/stremio-core-web/src/model/serialize_meta_details.rs b/stremio-core-web/src/model/serialize_meta_details.rs index 06b704ee2..7c0b60012 100644 --- a/stremio-core-web/src/model/serialize_meta_details.rs +++ b/stremio-core-web/src/model/serialize_meta_details.rs @@ -169,7 +169,7 @@ pub fn serialize_meta_details( deep_links: VideoDeepLinks::from(( video, request, - &streaming_server.server_urls_bucket.selected_item_url(), + &streaming_server.base_url, &ctx.profile.settings, )) .into_web_deep_links(), @@ -184,7 +184,7 @@ pub fn serialize_meta_details( progress: None, deep_links: StreamDeepLinks::from(( stream, - &streaming_server.server_urls_bucket.selected_item_url(), + &streaming_server.base_url, &ctx.profile.settings, )) .into_web_deep_links(), @@ -257,9 +257,7 @@ pub fn serialize_meta_details( || { StreamDeepLinks::from(( stream, - &streaming_server - .server_urls_bucket - .selected_item_url(), + &streaming_server.base_url, &ctx.profile.settings, )) }, @@ -268,9 +266,7 @@ pub fn serialize_meta_details( stream, request, &meta_item.request, - &streaming_server - .server_urls_bucket - .selected_item_url(), + &streaming_server.base_url, &ctx.profile.settings, )) }, diff --git a/stremio-core-web/src/model/serialize_player.rs b/stremio-core-web/src/model/serialize_player.rs index d36956bfa..2d7c56289 100644 --- a/stremio-core-web/src/model/serialize_player.rs +++ b/stremio-core-web/src/model/serialize_player.rs @@ -119,7 +119,7 @@ pub fn serialize_player( stream: &selected.stream, deep_links: StreamDeepLinks::from(( &selected.stream, - &streaming_server.server_urls_bucket.selected_item_url(), + &streaming_server.base_url, &ctx.profile.settings, )) .into_web_deep_links(), @@ -150,7 +150,7 @@ pub fn serialize_player( deep_links: VideoDeepLinks::from(( video, request, - &streaming_server.server_urls_bucket.selected_item_url(), + &streaming_server.base_url, &ctx.profile.settings, )) .into_web_deep_links(), @@ -231,7 +231,7 @@ pub fn serialize_player( video, stream_request, meta_request, - &streaming_server.server_urls_bucket.selected_item_url(), + &streaming_server.base_url, &ctx.profile.settings, )) .into_web_deep_links(), diff --git a/stremio-core-web/src/model/serialize_streaming_server.rs b/stremio-core-web/src/model/serialize_streaming_server.rs index 9a691b89b..0753c4ca7 100644 --- a/stremio-core-web/src/model/serialize_streaming_server.rs +++ b/stremio-core-web/src/model/serialize_streaming_server.rs @@ -12,7 +12,7 @@ use url::Url; use wasm_bindgen::JsValue; mod model { - use stremio_core::types::{server_urls::ServerUrlsBucket, torrent::InfoHash}; + use stremio_core::types::torrent::InfoHash; use super::*; type TorrentLoadable<'a> = Loadable<(&'a ResourcePath, MetaItemDeepLinks), &'a EnvError>; @@ -21,7 +21,6 @@ mod model { pub struct StreamingServer<'a> { pub selected: &'a Selected, pub settings: &'a Loadable, - pub server_urls_bucket: &'a ServerUrlsBucket, pub remote_url: &'a Option, pub playback_devices: &'a Loadable, EnvError>, pub network_info: &'a Loadable, @@ -39,7 +38,6 @@ pub fn serialize_streaming_server( ::from_serde(&model::StreamingServer { selected: &streaming_server.selected, settings: &streaming_server.settings, - server_urls_bucket: &streaming_server.server_urls_bucket, remote_url: &streaming_server.remote_url, playback_devices: &streaming_server.playback_devices, network_info: &streaming_server.network_info, From 662672c81fe1ff8daae6826abdfa66d0ae572d23 Mon Sep 17 00:00:00 2001 From: "Timothy Z." Date: Mon, 7 Oct 2024 15:40:18 +0300 Subject: [PATCH 15/44] remove: selected field in ServerUrlItem --- src/types/server_urls/server_url_item.rs | 3 --- src/types/server_urls/server_urls_bucket.rs | 1 - 2 files changed, 4 deletions(-) diff --git a/src/types/server_urls/server_url_item.rs b/src/types/server_urls/server_url_item.rs index e68cd6844..21e1f8462 100644 --- a/src/types/server_urls/server_url_item.rs +++ b/src/types/server_urls/server_url_item.rs @@ -10,8 +10,6 @@ pub struct ServerUrlItem { pub url: Url, /// Timestamp pub mtime: i64, - /// Selected - pub selected: bool, } impl ServerUrlItem { @@ -20,7 +18,6 @@ impl ServerUrlItem { id, url, mtime, - selected: false, } } } diff --git a/src/types/server_urls/server_urls_bucket.rs b/src/types/server_urls/server_urls_bucket.rs index 20b2b713a..5a3ac80f9 100644 --- a/src/types/server_urls/server_urls_bucket.rs +++ b/src/types/server_urls/server_urls_bucket.rs @@ -27,7 +27,6 @@ impl ServerUrlsBucket { id: SERVER_URL_BUCKET_DEFAULT_ITEM_ID, url: base_url.clone(), mtime: Self::current_timestamp() as i64, - selected: true, }; items.insert(server_base_url_item.id, server_base_url_item); From 3a09e3ab1a5d1315e238069c1752104b2e6a0af1 Mon Sep 17 00:00:00 2001 From: "Timothy Z." Date: Mon, 7 Oct 2024 15:42:59 +0300 Subject: [PATCH 16/44] chore(fmt): fmt --- src/types/server_urls/server_url_item.rs | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/src/types/server_urls/server_url_item.rs b/src/types/server_urls/server_url_item.rs index 21e1f8462..06d8b0b65 100644 --- a/src/types/server_urls/server_url_item.rs +++ b/src/types/server_urls/server_url_item.rs @@ -14,10 +14,6 @@ pub struct ServerUrlItem { impl ServerUrlItem { pub fn new(id: usize, url: Url, mtime: i64) -> Self { - ServerUrlItem { - id, - url, - mtime, - } + ServerUrlItem { id, url, mtime } } } From c0b638cfd0e5beea4bad1b2270c3dec3781cbf08 Mon Sep 17 00:00:00 2001 From: "Timothy Z." Date: Mon, 7 Oct 2024 16:02:02 +0300 Subject: [PATCH 17/44] add: ctx serialization for server_urls --- stremio-core-web/src/model/serialize_ctx.rs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/stremio-core-web/src/model/serialize_ctx.rs b/stremio-core-web/src/model/serialize_ctx.rs index 53f4a587f..15b018cbd 100644 --- a/stremio-core-web/src/model/serialize_ctx.rs +++ b/stremio-core-web/src/model/serialize_ctx.rs @@ -16,6 +16,7 @@ mod model { use serde::Serialize; use stremio_core::deep_links::SearchHistoryItemDeepLinks; + use stremio_core::types::server_urls::ServerUrlsBucket; use stremio_core::types::{ events::Events, notifications::NotificationItem, profile::Profile, resource::MetaItemId, }; @@ -30,6 +31,7 @@ mod model { pub notifications: Notifications<'a>, pub search_history: Vec>, pub events: &'a Events, + pub streaming_server_urls: &'a ServerUrlsBucket, } #[derive(Serialize)] @@ -75,6 +77,7 @@ mod model { }) .collect(), events: &ctx.events, + streaming_server_urls: &ctx.server_urls, } } } From 4fccc7e164415075e00728089f26a064e197cceb Mon Sep 17 00:00:00 2001 From: "Timothy Z." Date: Mon, 7 Oct 2024 16:19:43 +0300 Subject: [PATCH 18/44] add: migation to v15 --- src/constants.rs | 2 +- src/runtime/env.rs | 31 +++++++++++++++++++++++++++---- 2 files changed, 28 insertions(+), 5 deletions(-) diff --git a/src/constants.rs b/src/constants.rs index 2c21bc132..a9e83f351 100644 --- a/src/constants.rs +++ b/src/constants.rs @@ -39,7 +39,7 @@ pub const SERVER_URL_BUCKET_DEFAULT_ITEM_ID: usize = 0; pub const WATCHED_THRESHOLD_COEF: f64 = 0.7; pub const CREDITS_THRESHOLD_COEF: f64 = 0.9; /// The latest migration scheme version -pub const SCHEMA_VERSION: u32 = 14; +pub const SCHEMA_VERSION: u32 = 15; pub const IMDB_LINK_CATEGORY: &str = "imdb"; pub const GENRES_LINK_CATEGORY: &str = "Genres"; pub const CINEMETA_TOP_CATALOG_ID: &str = "top"; diff --git a/src/runtime/env.rs b/src/runtime/env.rs index 4728aa9a2..f4fa2ebb6 100644 --- a/src/runtime/env.rs +++ b/src/runtime/env.rs @@ -1,8 +1,6 @@ use crate::addon_transport::{AddonHTTPTransport, AddonTransport, UnsupportedTransport}; use crate::constants::{ - DISMISSED_EVENTS_STORAGE_KEY, LIBRARY_RECENT_STORAGE_KEY, LIBRARY_STORAGE_KEY, - PROFILE_STORAGE_KEY, SCHEMA_VERSION, SCHEMA_VERSION_STORAGE_KEY, SEARCH_HISTORY_STORAGE_KEY, - STREAMS_STORAGE_KEY, + DISMISSED_EVENTS_STORAGE_KEY, LIBRARY_RECENT_STORAGE_KEY, LIBRARY_STORAGE_KEY, PROFILE_STORAGE_KEY, SCHEMA_VERSION, SCHEMA_VERSION_STORAGE_KEY, SEARCH_HISTORY_STORAGE_KEY, STREAMING_SERVER_URLS_STORAGE_KEY, STREAMS_STORAGE_KEY }; use crate::models::ctx::Ctx; use crate::models::streaming_server::StreamingServer; @@ -265,6 +263,12 @@ pub trait Env { .await?; schema_version = 14; } + if schema_version == 14 { + migrate_storage_schema_to_v15::() + .map_err(|error| EnvError::StorageSchemaVersionUpgrade(Box::new(error))) + .await?; + schema_version = 15; + } if schema_version != SCHEMA_VERSION { panic!( "Storage schema version must be upgraded from {} to {}", @@ -594,6 +598,12 @@ fn migrate_storage_schema_to_v14() -> TryEnvFuture<()> { .boxed_env() } +fn migrate_storage_schema_to_v15() -> TryEnvFuture<()> { + E::set_storage::<()>(STREAMING_SERVER_URLS_STORAGE_KEY, None) + .and_then(|_| E::set_storage(STREAMING_SERVER_URLS_STORAGE_KEY, Some(&15))) + .boxed_env() +} + #[cfg(test)] mod test { use serde_json::{json, Value}; @@ -608,7 +618,7 @@ mod test { migrate_storage_schema_to_v12, migrate_storage_schema_to_v13, migrate_storage_schema_to_v14, migrate_storage_schema_to_v6, migrate_storage_schema_to_v7, migrate_storage_schema_to_v8, - migrate_storage_schema_to_v9, + migrate_storage_schema_to_v9, migrate_storage_schema_to_v15, }, Env, }, @@ -1125,4 +1135,17 @@ mod test { "Profile should match" ); } + + #[tokio::test] + async fn test_migration_from_14_to_15() { + let _test_env_guard = TestEnv::reset().expect("Should lock TestEnv"); + + migrate_storage_schema_to_v15::() + .await + .expect("Should migrate"); + + { + assert_storage_schema_version(15); + } + } } From 5743f3432899fbfa520dbf163e45f5ea5eec6618 Mon Sep 17 00:00:00 2001 From: "Timothy Z." Date: Mon, 7 Oct 2024 16:20:06 +0300 Subject: [PATCH 19/44] chore: fmt --- src/runtime/env.rs | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/runtime/env.rs b/src/runtime/env.rs index f4fa2ebb6..5093658f7 100644 --- a/src/runtime/env.rs +++ b/src/runtime/env.rs @@ -1,6 +1,8 @@ use crate::addon_transport::{AddonHTTPTransport, AddonTransport, UnsupportedTransport}; use crate::constants::{ - DISMISSED_EVENTS_STORAGE_KEY, LIBRARY_RECENT_STORAGE_KEY, LIBRARY_STORAGE_KEY, PROFILE_STORAGE_KEY, SCHEMA_VERSION, SCHEMA_VERSION_STORAGE_KEY, SEARCH_HISTORY_STORAGE_KEY, STREAMING_SERVER_URLS_STORAGE_KEY, STREAMS_STORAGE_KEY + DISMISSED_EVENTS_STORAGE_KEY, LIBRARY_RECENT_STORAGE_KEY, LIBRARY_STORAGE_KEY, + PROFILE_STORAGE_KEY, SCHEMA_VERSION, SCHEMA_VERSION_STORAGE_KEY, SEARCH_HISTORY_STORAGE_KEY, + STREAMING_SERVER_URLS_STORAGE_KEY, STREAMS_STORAGE_KEY, }; use crate::models::ctx::Ctx; use crate::models::streaming_server::StreamingServer; @@ -616,9 +618,9 @@ mod test { env::{ migrate_storage_schema_to_v10, migrate_storage_schema_to_v11, migrate_storage_schema_to_v12, migrate_storage_schema_to_v13, - migrate_storage_schema_to_v14, migrate_storage_schema_to_v6, - migrate_storage_schema_to_v7, migrate_storage_schema_to_v8, - migrate_storage_schema_to_v9, migrate_storage_schema_to_v15, + migrate_storage_schema_to_v14, migrate_storage_schema_to_v15, + migrate_storage_schema_to_v6, migrate_storage_schema_to_v7, + migrate_storage_schema_to_v8, migrate_storage_schema_to_v9, }, Env, }, From 8366e31f94e4ec860e76ac6aee4ec4a3cb41386c Mon Sep 17 00:00:00 2001 From: "Timothy Z." Date: Mon, 7 Oct 2024 16:28:40 +0300 Subject: [PATCH 20/44] rename: var streaming_server_urls --- src/models/ctx/ctx.rs | 12 ++++++------ stremio-core-web/src/model/serialize_ctx.rs | 2 +- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/models/ctx/ctx.rs b/src/models/ctx/ctx.rs index 3e6a25486..b0fd7f83f 100644 --- a/src/models/ctx/ctx.rs +++ b/src/models/ctx/ctx.rs @@ -49,7 +49,7 @@ pub struct Ctx { #[serde(skip)] pub streams: StreamsBucket, #[serde(skip)] - pub server_urls: ServerUrlsBucket, + pub streaming_server_urls: ServerUrlsBucket, #[serde(skip)] pub search_history: SearchHistoryBucket, #[serde(skip)] @@ -70,7 +70,7 @@ impl Ctx { profile: Profile, library: LibraryBucket, streams: StreamsBucket, - server_urls: ServerUrlsBucket, + streaming_server_urls: ServerUrlsBucket, notifications: NotificationsBucket, search_history: SearchHistoryBucket, dismissed_events: DismissedEventsBucket, @@ -79,7 +79,7 @@ impl Ctx { profile, library, streams, - server_urls, + streaming_server_urls, search_history, dismissed_events, notifications, @@ -113,7 +113,7 @@ impl Update for Ctx { update_library::(&mut self.library, &self.profile, &self.status, msg); let streams_effects = update_streams::(&mut self.streams, &self.status, msg); let server_urls_effects = - update_streaming_server_urls::(&mut self.server_urls, &self.status, msg); + update_streaming_server_urls::(&mut self.streaming_server_urls, &self.status, msg); let search_history_effects = update_search_history::(&mut self.search_history, &self.status, msg); let events_effects = @@ -166,7 +166,7 @@ impl Update for Ctx { ); let streams_effects = update_streams::(&mut self.streams, &self.status, msg); let server_urls_effects = - update_streaming_server_urls::(&mut self.server_urls, &self.status, msg); + update_streaming_server_urls::(&mut self.streaming_server_urls, &self.status, msg); let search_history_effects = update_search_history::(&mut self.search_history, &self.status, msg); let events_effects = @@ -249,7 +249,7 @@ impl Update for Ctx { update_library::(&mut self.library, &self.profile, &self.status, msg); let streams_effects = update_streams::(&mut self.streams, &self.status, msg); let server_urls_effects = - update_streaming_server_urls::(&mut self.server_urls, &self.status, msg); + update_streaming_server_urls::(&mut self.streaming_server_urls, &self.status, msg); let trakt_addon_effects = update_trakt_addon::( &mut self.trakt_addon, &self.profile, diff --git a/stremio-core-web/src/model/serialize_ctx.rs b/stremio-core-web/src/model/serialize_ctx.rs index 15b018cbd..300cbde4c 100644 --- a/stremio-core-web/src/model/serialize_ctx.rs +++ b/stremio-core-web/src/model/serialize_ctx.rs @@ -77,7 +77,7 @@ mod model { }) .collect(), events: &ctx.events, - streaming_server_urls: &ctx.server_urls, + streaming_server_urls: &ctx.streaming_server_urls, } } } From c6f54056099a73f8aad9c95b7e63aa66cce9a246 Mon Sep 17 00:00:00 2001 From: "Timothy Z." Date: Mon, 7 Oct 2024 16:29:40 +0300 Subject: [PATCH 21/44] chore: fmt & clippy --- src/models/ctx/ctx.rs | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/src/models/ctx/ctx.rs b/src/models/ctx/ctx.rs index b0fd7f83f..2995fc99f 100644 --- a/src/models/ctx/ctx.rs +++ b/src/models/ctx/ctx.rs @@ -112,8 +112,11 @@ impl Update for Ctx { let library_effects = update_library::(&mut self.library, &self.profile, &self.status, msg); let streams_effects = update_streams::(&mut self.streams, &self.status, msg); - let server_urls_effects = - update_streaming_server_urls::(&mut self.streaming_server_urls, &self.status, msg); + let server_urls_effects = update_streaming_server_urls::( + &mut self.streaming_server_urls, + &self.status, + msg, + ); let search_history_effects = update_search_history::(&mut self.search_history, &self.status, msg); let events_effects = @@ -165,8 +168,11 @@ impl Update for Ctx { msg, ); let streams_effects = update_streams::(&mut self.streams, &self.status, msg); - let server_urls_effects = - update_streaming_server_urls::(&mut self.streaming_server_urls, &self.status, msg); + let server_urls_effects = update_streaming_server_urls::( + &mut self.streaming_server_urls, + &self.status, + msg, + ); let search_history_effects = update_search_history::(&mut self.search_history, &self.status, msg); let events_effects = @@ -248,8 +254,11 @@ impl Update for Ctx { let library_effects = update_library::(&mut self.library, &self.profile, &self.status, msg); let streams_effects = update_streams::(&mut self.streams, &self.status, msg); - let server_urls_effects = - update_streaming_server_urls::(&mut self.streaming_server_urls, &self.status, msg); + let server_urls_effects = update_streaming_server_urls::( + &mut self.streaming_server_urls, + &self.status, + msg, + ); let trakt_addon_effects = update_trakt_addon::( &mut self.trakt_addon, &self.profile, From 4fa6ffd98e66799f35d1dcaeb0929e5e8ade2738 Mon Sep 17 00:00:00 2001 From: "Timothy Z." Date: Mon, 7 Oct 2024 17:08:08 +0300 Subject: [PATCH 22/44] fix: env storage key missmatch --- src/runtime/env.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/runtime/env.rs b/src/runtime/env.rs index 5093658f7..9c3d02683 100644 --- a/src/runtime/env.rs +++ b/src/runtime/env.rs @@ -602,7 +602,7 @@ fn migrate_storage_schema_to_v14() -> TryEnvFuture<()> { fn migrate_storage_schema_to_v15() -> TryEnvFuture<()> { E::set_storage::<()>(STREAMING_SERVER_URLS_STORAGE_KEY, None) - .and_then(|_| E::set_storage(STREAMING_SERVER_URLS_STORAGE_KEY, Some(&15))) + .and_then(|_| E::set_storage(SCHEMA_VERSION_STORAGE_KEY, Some(&15))) .boxed_env() } From 1cf708f9577f5ac8fd10cf3cc2c4ff4b814a5529 Mon Sep 17 00:00:00 2001 From: "Timothy Z." Date: Mon, 7 Oct 2024 17:39:18 +0300 Subject: [PATCH 23/44] feat: tests --- src/unit_tests/ctx/mod.rs | 1 + .../ctx/update_streaming_server_urls.rs | 185 ++++++++++++++++++ 2 files changed, 186 insertions(+) create mode 100644 src/unit_tests/ctx/update_streaming_server_urls.rs diff --git a/src/unit_tests/ctx/mod.rs b/src/unit_tests/ctx/mod.rs index 724f9ed14..98f7cd3b0 100644 --- a/src/unit_tests/ctx/mod.rs +++ b/src/unit_tests/ctx/mod.rs @@ -14,4 +14,5 @@ mod sync_library_with_api; mod uninstall_addon; mod update_search_history; mod update_settings; +mod update_streaming_server_urls; mod upgrade_addon; diff --git a/src/unit_tests/ctx/update_streaming_server_urls.rs b/src/unit_tests/ctx/update_streaming_server_urls.rs new file mode 100644 index 000000000..eb774c228 --- /dev/null +++ b/src/unit_tests/ctx/update_streaming_server_urls.rs @@ -0,0 +1,185 @@ +use crate::constants::STREAMING_SERVER_URLS_STORAGE_KEY; +use crate::models::ctx::Ctx; +use crate::runtime::msg::{Action, ActionServerUrlsBucket, ActionStreamingServer}; +use crate::runtime::{Env, Runtime, RuntimeAction}; +use crate::types::events::DismissedEventsBucket; +use crate::types::library::LibraryBucket; +use crate::types::notifications::NotificationsBucket; +use crate::types::profile::Profile; +use crate::types::search_history::SearchHistoryBucket; +use crate::types::server_urls::{ServerUrlItem, ServerUrlsBucket}; +use crate::types::streams::StreamsBucket; +use crate::unit_tests::{TestEnv, STORAGE}; +use stremio_derive::Model; +use url::Url; + +#[test] +fn test_add_server_url() { + #[derive(Model, Clone, Default)] + #[model(TestEnv)] + struct TestModel { + ctx: Ctx, + } + let _env_mutex = TestEnv::reset().expect("Should have exclusive lock to TestEnv"); + let ctx = Ctx::new( + Profile::default(), + LibraryBucket::default(), + StreamsBucket::default(), + ServerUrlsBucket::new(None), + NotificationsBucket::new::(None, vec![]), + SearchHistoryBucket::default(), + DismissedEventsBucket::default(), + ); + let (runtime, _rx) = Runtime::::new(TestModel { ctx }, vec![], 1000); + let new_url = Url::parse("http://localhost:11470").unwrap(); + TestEnv::run(|| { + runtime.dispatch(RuntimeAction { + field: None, + action: Action::StreamingServer(ActionStreamingServer::ServerUrlsBucket( + ActionServerUrlsBucket::AddServerUrl(new_url.clone()), + )), + }) + }); + let server_urls = &runtime.model().unwrap().ctx.streaming_server_urls; + assert!( + server_urls.items.values().any(|item| item.url == new_url), + "New server URL should be added" + ); + assert!( + STORAGE + .read() + .unwrap() + .get(STREAMING_SERVER_URLS_STORAGE_KEY) + .map_or(false, |data| { + let stored_bucket: ServerUrlsBucket = serde_json::from_str(data).unwrap(); + stored_bucket.items.values().any(|item| item.url == new_url) + }), + "New server URL should be stored" + ); +} + +#[test] +fn test_edit_server_url() { + #[derive(Model, Clone, Default)] + #[model(TestEnv)] + struct TestModel { + ctx: Ctx, + } + let _env_mutex = TestEnv::reset().expect("Should have exclusive lock to TestEnv"); + + // Initialize with a server URL + let initial_url = Url::parse("http://localhost:11470").unwrap(); + let mut server_urls = ServerUrlsBucket::new(None); + let item_id = 1; + let server_url_item = + ServerUrlItem::new(item_id, initial_url.clone(), TestEnv::now().timestamp()); + server_urls.items.insert(item_id, server_url_item); + + STORAGE.write().unwrap().insert( + STREAMING_SERVER_URLS_STORAGE_KEY.to_owned(), + serde_json::to_string(&server_urls).unwrap(), + ); + + let ctx = Ctx::new( + Profile::default(), + LibraryBucket::default(), + StreamsBucket::default(), + server_urls, + NotificationsBucket::new::(None, vec![]), + SearchHistoryBucket::default(), + DismissedEventsBucket::default(), + ); + let (runtime, _rx) = Runtime::::new(TestModel { ctx }, vec![], 1000); + let new_url = Url::parse("http://localhost:11471").unwrap(); + TestEnv::run(|| { + runtime.dispatch(RuntimeAction { + field: None, + action: Action::StreamingServer(ActionStreamingServer::ServerUrlsBucket( + ActionServerUrlsBucket::EditServerUrl { + id: item_id, + new_url: new_url.clone(), + }, + )), + }) + }); + let server_urls = &runtime.model().unwrap().ctx.streaming_server_urls; + assert!( + server_urls + .items + .get(&item_id) + .map_or(false, |item| item.url == new_url), + "Server URL should be updated" + ); + assert!( + STORAGE + .read() + .unwrap() + .get(STREAMING_SERVER_URLS_STORAGE_KEY) + .map_or(false, |data| { + let stored_bucket: ServerUrlsBucket = serde_json::from_str(data).unwrap(); + stored_bucket + .items + .get(&item_id) + .map_or(false, |item| item.url == new_url) + }), + "Updated server URL should be stored" + ); +} + +#[test] +fn test_delete_server_url() { + #[derive(Model, Clone, Default)] + #[model(TestEnv)] + struct TestModel { + ctx: Ctx, + } + let _env_mutex = TestEnv::reset().expect("Should have exclusive lock to TestEnv"); + + // Initialize with a server URL + let initial_url = Url::parse("http://localhost:11470").unwrap(); + let mut server_urls = ServerUrlsBucket::new(None); + let item_id = 1; + let server_url_item = + ServerUrlItem::new(item_id, initial_url.clone(), TestEnv::now().timestamp()); + server_urls.items.insert(item_id, server_url_item); + + STORAGE.write().unwrap().insert( + STREAMING_SERVER_URLS_STORAGE_KEY.to_owned(), + serde_json::to_string(&server_urls).unwrap(), + ); + + let ctx = Ctx::new( + Profile::default(), + LibraryBucket::default(), + StreamsBucket::default(), + server_urls, + NotificationsBucket::new::(None, vec![]), + SearchHistoryBucket::default(), + DismissedEventsBucket::default(), + ); + let (runtime, _rx) = Runtime::::new(TestModel { ctx }, vec![], 1000); + TestEnv::run(|| { + runtime.dispatch(RuntimeAction { + field: None, + action: Action::StreamingServer(ActionStreamingServer::ServerUrlsBucket( + ActionServerUrlsBucket::DeleteServerUrl(item_id), + )), + }) + }); + let server_urls = &runtime.model().unwrap().ctx.streaming_server_urls; + assert!( + !server_urls.items.contains_key(&item_id), + "Server URL should be deleted" + ); + assert!( + STORAGE + .read() + .unwrap() + .get(STREAMING_SERVER_URLS_STORAGE_KEY) + .map_or(true, |data| { + let stored_bucket: ServerUrlsBucket = serde_json::from_str(data).unwrap(); + !stored_bucket.items.contains_key(&item_id) + }), + "Deleted server URL should not be stored" + ); +} From 784a00f1e65f3cd123241927b4231565853b1a71 Mon Sep 17 00:00:00 2001 From: "Timothy Z." Date: Mon, 7 Oct 2024 20:38:07 +0300 Subject: [PATCH 24/44] remove: unnecessary bucket result --- src/runtime/msg/internal.rs | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/runtime/msg/internal.rs b/src/runtime/msg/internal.rs index 1f4c53664..56650fccc 100644 --- a/src/runtime/msg/internal.rs +++ b/src/runtime/msg/internal.rs @@ -108,8 +108,6 @@ pub enum Internal { StreamingServerSettingsResult(Url, Result), /// Result for loading streaming server base url. StreamingServerBaseURLResult(Url, Result), - /// Result for loading streaming server urls bucket. - StreamingServerUrlsBucketResult(Result, EnvError>), // Result for loading streaming server playback devices. StreamingServerPlaybackDevicesResult(Url, Result, EnvError>), // Result for network info. From 23a04e41d1fea8d7ad105d170f00b037fd25f928 Mon Sep 17 00:00:00 2001 From: "Timothy Z." Date: Wed, 9 Oct 2024 13:19:27 +0300 Subject: [PATCH 25/44] refactor: serialization of streaming_server_urls --- stremio-core-web/src/model/serialize_ctx.rs | 22 ++++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) diff --git a/stremio-core-web/src/model/serialize_ctx.rs b/stremio-core-web/src/model/serialize_ctx.rs index 300cbde4c..c75478a6b 100644 --- a/stremio-core-web/src/model/serialize_ctx.rs +++ b/stremio-core-web/src/model/serialize_ctx.rs @@ -16,7 +16,6 @@ mod model { use serde::Serialize; use stremio_core::deep_links::SearchHistoryItemDeepLinks; - use stremio_core::types::server_urls::ServerUrlsBucket; use stremio_core::types::{ events::Events, notifications::NotificationItem, profile::Profile, resource::MetaItemId, }; @@ -31,7 +30,15 @@ mod model { pub notifications: Notifications<'a>, pub search_history: Vec>, pub events: &'a Events, - pub streaming_server_urls: &'a ServerUrlsBucket, + pub streaming_server_urls: Vec, + } + + #[derive(Serialize)] + #[serde(rename_all = "camelCase")] + pub struct StreamingServerUrlItem { + pub id: usize, + pub url: String, + pub mtime: i64, } #[derive(Serialize)] @@ -77,7 +84,16 @@ mod model { }) .collect(), events: &ctx.events, - streaming_server_urls: &ctx.streaming_server_urls, + streaming_server_urls: ctx + .streaming_server_urls + .items + .values() + .map(|item| StreamingServerUrlItem { + id: item.id, + url: item.url.to_string(), + mtime: item.mtime, + }) + .collect(), } } } From c9c18447a0ab006c230699205aebfd78f41c9902 Mon Sep 17 00:00:00 2001 From: "Timothy Z." Date: Wed, 9 Oct 2024 15:11:23 +0300 Subject: [PATCH 26/44] refactor: update variable name --- .../ctx/update_streaming_server_urls.rs | 41 ++++++++++--------- 1 file changed, 22 insertions(+), 19 deletions(-) diff --git a/src/models/ctx/update_streaming_server_urls.rs b/src/models/ctx/update_streaming_server_urls.rs index 694fb9c96..fa0ac7e2c 100644 --- a/src/models/ctx/update_streaming_server_urls.rs +++ b/src/models/ctx/update_streaming_server_urls.rs @@ -11,7 +11,7 @@ use futures::FutureExt; use super::{CtxError, CtxStatus}; pub fn update_streaming_server_urls( - server_urls: &mut ServerUrlsBucket, + streaming_server_urls: &mut ServerUrlsBucket, status: &CtxStatus, msg: &Msg, ) -> Effects { @@ -19,15 +19,15 @@ pub fn update_streaming_server_urls( Msg::Action(Action::StreamingServer(ActionStreamingServer::ServerUrlsBucket(action))) => { match action { ActionServerUrlsBucket::AddServerUrl(url) => { - server_urls.add_url(url.clone()); + streaming_server_urls.add_url(url.clone()); Effects::msg(Msg::Internal(Internal::StreamingServerUrlsBucketChanged)) } ActionServerUrlsBucket::EditServerUrl { id, new_url } => { - server_urls.edit_item(id, new_url.clone()); + streaming_server_urls.edit_item(id, new_url.clone()); Effects::msg(Msg::Internal(Internal::StreamingServerUrlsBucketChanged)) } ActionServerUrlsBucket::DeleteServerUrl(id) => { - server_urls.delete_item(id); + streaming_server_urls.delete_item(id); Effects::msg(Msg::Internal(Internal::StreamingServerUrlsBucketChanged)) } } @@ -37,33 +37,36 @@ pub fn update_streaming_server_urls( if loading_auth_request == auth_request => { let next_server_urls = ServerUrlsBucket::new(Some(auth.user.id.to_owned())); - *server_urls = next_server_urls; + *streaming_server_urls = next_server_urls; Effects::msg(Msg::Internal(Internal::StreamingServerUrlsBucketChanged)) } _ => Effects::none().unchanged(), }, Msg::Internal(Internal::StreamingServerUrlsBucketChanged) => { - Effects::one(push_server_urls_to_storage::(server_urls)).unchanged() + Effects::one(push_server_urls_to_storage::(streaming_server_urls)).unchanged() } _ => Effects::none().unchanged(), } } -fn push_server_urls_to_storage(server_urls: &ServerUrlsBucket) -> Effect { - let uid: Option = server_urls.uid.clone(); +fn push_server_urls_to_storage( + streaming_server_urls: &ServerUrlsBucket, +) -> Effect { + let uid: Option = streaming_server_urls.uid.clone(); EffectFuture::Sequential( - E::set_storage(STREAMING_SERVER_URLS_STORAGE_KEY, Some(server_urls)) - .map(move |result| match result { - Ok(_) => Msg::Event(Event::StreamingServerUrlsPushedToStorage { uid: uid.clone() }), - Err(error) => Msg::Event(Event::Error { - error: CtxError::from(error), - source: Box::new(Event::StreamingServerUrlsPushedToStorage { - uid: uid.clone(), - }), - }), - }) - .boxed_env(), + E::set_storage( + STREAMING_SERVER_URLS_STORAGE_KEY, + Some(streaming_server_urls), + ) + .map(move |result| match result { + Ok(_) => Msg::Event(Event::StreamingServerUrlsPushedToStorage { uid: uid.clone() }), + Err(error) => Msg::Event(Event::Error { + error: CtxError::from(error), + source: Box::new(Event::StreamingServerUrlsPushedToStorage { uid: uid.clone() }), + }), + }) + .boxed_env(), ) .into() } From 2184cf78627f38c6b3ea554ddab420fb81b45429 Mon Sep 17 00:00:00 2001 From: "Timothy Z." Date: Wed, 9 Oct 2024 16:07:45 +0300 Subject: [PATCH 27/44] fix: serde + correct key for storage --- src/types/server_urls/server_urls_bucket.rs | 3 +++ stremio-core-web/src/stremio_core_web.rs | 6 ++---- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/src/types/server_urls/server_urls_bucket.rs b/src/types/server_urls/server_urls_bucket.rs index 5a3ac80f9..e6260ad63 100644 --- a/src/types/server_urls/server_urls_bucket.rs +++ b/src/types/server_urls/server_urls_bucket.rs @@ -6,14 +6,17 @@ use crate::{ types::profile::UID, }; use serde::{Deserialize, Serialize}; +use serde_with::serde_as; use std::collections::HashMap; use url::Url; +#[serde_as] #[derive(Debug, Clone, Serialize, Deserialize, Default, PartialEq)] pub struct ServerUrlsBucket { /// User ID pub uid: UID, /// [`HashMap`] Key is the [`ServerUrlItem`]`.id`. + #[serde_as(as = "Vec<(_, _)>")] pub items: HashMap, } diff --git a/stremio-core-web/src/stremio_core_web.rs b/stremio-core-web/src/stremio_core_web.rs index 2d446aada..4ad6e093a 100644 --- a/stremio-core-web/src/stremio_core_web.rs +++ b/stremio-core-web/src/stremio_core_web.rs @@ -10,9 +10,7 @@ use wasm_bindgen::{prelude::wasm_bindgen, JsValue}; use stremio_core::{ constants::{ - DISMISSED_EVENTS_STORAGE_KEY, LIBRARY_RECENT_STORAGE_KEY, LIBRARY_STORAGE_KEY, - NOTIFICATIONS_STORAGE_KEY, PROFILE_STORAGE_KEY, SEARCH_HISTORY_STORAGE_KEY, - STREAMS_STORAGE_KEY, + DISMISSED_EVENTS_STORAGE_KEY, LIBRARY_RECENT_STORAGE_KEY, LIBRARY_STORAGE_KEY, NOTIFICATIONS_STORAGE_KEY, PROFILE_STORAGE_KEY, SEARCH_HISTORY_STORAGE_KEY, STREAMING_SERVER_URLS_STORAGE_KEY, STREAMS_STORAGE_KEY }, models::common::Loadable, runtime::{msg::Action, Env, EnvError, Runtime, RuntimeAction, RuntimeEvent}, @@ -68,7 +66,7 @@ pub async fn initialize_runtime(emit_to_ui: js_sys::Function) -> Result<(), JsVa WebEnv::get_storage::(LIBRARY_RECENT_STORAGE_KEY), WebEnv::get_storage::(LIBRARY_STORAGE_KEY), WebEnv::get_storage::(STREAMS_STORAGE_KEY), - WebEnv::get_storage::(STREAMS_STORAGE_KEY), + WebEnv::get_storage::(STREAMING_SERVER_URLS_STORAGE_KEY), WebEnv::get_storage::(NOTIFICATIONS_STORAGE_KEY), WebEnv::get_storage::(SEARCH_HISTORY_STORAGE_KEY), WebEnv::get_storage::(DISMISSED_EVENTS_STORAGE_KEY), From f74613777eca181effb1127dfe109bf9b960681e Mon Sep 17 00:00:00 2001 From: "Timothy Z." Date: Wed, 9 Oct 2024 16:08:17 +0300 Subject: [PATCH 28/44] chore: fmt & clippy --- stremio-core-web/src/stremio_core_web.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/stremio-core-web/src/stremio_core_web.rs b/stremio-core-web/src/stremio_core_web.rs index 4ad6e093a..f0b632195 100644 --- a/stremio-core-web/src/stremio_core_web.rs +++ b/stremio-core-web/src/stremio_core_web.rs @@ -10,7 +10,9 @@ use wasm_bindgen::{prelude::wasm_bindgen, JsValue}; use stremio_core::{ constants::{ - DISMISSED_EVENTS_STORAGE_KEY, LIBRARY_RECENT_STORAGE_KEY, LIBRARY_STORAGE_KEY, NOTIFICATIONS_STORAGE_KEY, PROFILE_STORAGE_KEY, SEARCH_HISTORY_STORAGE_KEY, STREAMING_SERVER_URLS_STORAGE_KEY, STREAMS_STORAGE_KEY + DISMISSED_EVENTS_STORAGE_KEY, LIBRARY_RECENT_STORAGE_KEY, LIBRARY_STORAGE_KEY, + NOTIFICATIONS_STORAGE_KEY, PROFILE_STORAGE_KEY, SEARCH_HISTORY_STORAGE_KEY, + STREAMING_SERVER_URLS_STORAGE_KEY, STREAMS_STORAGE_KEY, }, models::common::Loadable, runtime::{msg::Action, Env, EnvError, Runtime, RuntimeAction, RuntimeEvent}, From dba9afde938c635addb6b2e56fc040c0699e1e4b Mon Sep 17 00:00:00 2001 From: "Timothy Z." Date: Wed, 9 Oct 2024 16:42:44 +0300 Subject: [PATCH 29/44] remove: unnecessary serde and merge_bucket fn --- src/types/server_urls/server_urls_bucket.rs | 9 --------- 1 file changed, 9 deletions(-) diff --git a/src/types/server_urls/server_urls_bucket.rs b/src/types/server_urls/server_urls_bucket.rs index e6260ad63..5aa159018 100644 --- a/src/types/server_urls/server_urls_bucket.rs +++ b/src/types/server_urls/server_urls_bucket.rs @@ -6,17 +6,14 @@ use crate::{ types::profile::UID, }; use serde::{Deserialize, Serialize}; -use serde_with::serde_as; use std::collections::HashMap; use url::Url; -#[serde_as] #[derive(Debug, Clone, Serialize, Deserialize, Default, PartialEq)] pub struct ServerUrlsBucket { /// User ID pub uid: UID, /// [`HashMap`] Key is the [`ServerUrlItem`]`.id`. - #[serde_as(as = "Vec<(_, _)>")] pub items: HashMap, } @@ -45,12 +42,6 @@ impl ServerUrlsBucket { self.items.keys().max().cloned().unwrap_or(0) + 1 } - pub fn merge_bucket(&mut self, bucket: ServerUrlsBucket) { - if self.uid == bucket.uid { - self.merge_items(bucket.items.into_values().collect()); - } - } - pub fn add_url(&mut self, url: Url) { let new_id = self.generate_new_id(); let new_item = ServerUrlItem::new(new_id, url, Self::current_timestamp() as i64); From 01776ed804eacdbc9c2adebdbd41152d98ccca9d Mon Sep 17 00:00:00 2001 From: "Timothy Z." Date: Thu, 10 Oct 2024 11:42:28 +0300 Subject: [PATCH 30/44] refactor: mtime on URLs bucket --- src/types/server_urls/server_url_item.rs | 7 ++++--- src/types/server_urls/server_urls_bucket.rs | 11 ++++++----- src/unit_tests/ctx/update_streaming_server_urls.rs | 6 ++---- stremio-core-web/src/model/serialize_ctx.rs | 3 ++- 4 files changed, 14 insertions(+), 13 deletions(-) diff --git a/src/types/server_urls/server_url_item.rs b/src/types/server_urls/server_url_item.rs index 06d8b0b65..d029b9f37 100644 --- a/src/types/server_urls/server_url_item.rs +++ b/src/types/server_urls/server_url_item.rs @@ -1,3 +1,4 @@ +use chrono::{DateTime, Utc}; use serde::{Deserialize, Serialize}; use url::Url; @@ -8,12 +9,12 @@ pub struct ServerUrlItem { pub id: usize, /// URL pub url: Url, - /// Timestamp - pub mtime: i64, + /// Modification time + pub mtime: DateTime, } impl ServerUrlItem { - pub fn new(id: usize, url: Url, mtime: i64) -> Self { + pub fn new(id: usize, url: Url, mtime: DateTime) -> Self { ServerUrlItem { id, url, mtime } } } diff --git a/src/types/server_urls/server_urls_bucket.rs b/src/types/server_urls/server_urls_bucket.rs index 5aa159018..ed0f69018 100644 --- a/src/types/server_urls/server_urls_bucket.rs +++ b/src/types/server_urls/server_urls_bucket.rs @@ -5,6 +5,7 @@ use crate::{ }, types::profile::UID, }; +use chrono::{DateTime, Utc}; use serde::{Deserialize, Serialize}; use std::collections::HashMap; use url::Url; @@ -26,7 +27,7 @@ impl ServerUrlsBucket { let server_base_url_item = ServerUrlItem { id: SERVER_URL_BUCKET_DEFAULT_ITEM_ID, url: base_url.clone(), - mtime: Self::current_timestamp() as i64, + mtime: Self::current_timestamp(), }; items.insert(server_base_url_item.id, server_base_url_item); @@ -34,8 +35,8 @@ impl ServerUrlsBucket { ServerUrlsBucket { uid, items } } - fn current_timestamp() -> u64 { - chrono::Utc::now().timestamp() as u64 + fn current_timestamp() -> DateTime { + chrono::Utc::now() } pub fn generate_new_id(&self) -> usize { @@ -44,7 +45,7 @@ impl ServerUrlsBucket { pub fn add_url(&mut self, url: Url) { let new_id = self.generate_new_id(); - let new_item = ServerUrlItem::new(new_id, url, Self::current_timestamp() as i64); + let new_item = ServerUrlItem::new(new_id, url, Self::current_timestamp()); self.merge_items(vec![new_item]); } @@ -80,7 +81,7 @@ impl ServerUrlsBucket { pub fn edit_item(&mut self, id: &usize, new_url: Url) { if let Some(item) = self.items.get_mut(id) { item.url = new_url; - item.mtime = Self::current_timestamp() as i64; + item.mtime = Self::current_timestamp(); } } diff --git a/src/unit_tests/ctx/update_streaming_server_urls.rs b/src/unit_tests/ctx/update_streaming_server_urls.rs index eb774c228..b1e8549ba 100644 --- a/src/unit_tests/ctx/update_streaming_server_urls.rs +++ b/src/unit_tests/ctx/update_streaming_server_urls.rs @@ -71,8 +71,7 @@ fn test_edit_server_url() { let initial_url = Url::parse("http://localhost:11470").unwrap(); let mut server_urls = ServerUrlsBucket::new(None); let item_id = 1; - let server_url_item = - ServerUrlItem::new(item_id, initial_url.clone(), TestEnv::now().timestamp()); + let server_url_item = ServerUrlItem::new(item_id, initial_url.clone(), TestEnv::now()); server_urls.items.insert(item_id, server_url_item); STORAGE.write().unwrap().insert( @@ -139,8 +138,7 @@ fn test_delete_server_url() { let initial_url = Url::parse("http://localhost:11470").unwrap(); let mut server_urls = ServerUrlsBucket::new(None); let item_id = 1; - let server_url_item = - ServerUrlItem::new(item_id, initial_url.clone(), TestEnv::now().timestamp()); + let server_url_item = ServerUrlItem::new(item_id, initial_url.clone(), TestEnv::now()); server_urls.items.insert(item_id, server_url_item); STORAGE.write().unwrap().insert( diff --git a/stremio-core-web/src/model/serialize_ctx.rs b/stremio-core-web/src/model/serialize_ctx.rs index c75478a6b..f8f848059 100644 --- a/stremio-core-web/src/model/serialize_ctx.rs +++ b/stremio-core-web/src/model/serialize_ctx.rs @@ -38,7 +38,8 @@ mod model { pub struct StreamingServerUrlItem { pub id: usize, pub url: String, - pub mtime: i64, + #[serde(rename = "_mtime")] + pub mtime: DateTime, } #[derive(Serialize)] From cd903bb3c2645d0d8916c7ac7e87d87b5464d9c7 Mon Sep 17 00:00:00 2001 From: "Timothy Z." Date: Thu, 10 Oct 2024 12:55:07 +0300 Subject: [PATCH 31/44] refactor: simplify bucket logic --- .../ctx/update_streaming_server_urls.rs | 8 +- src/runtime/msg/action.rs | 4 +- src/types/server_urls/mod.rs | 3 - src/types/server_urls/server_url_item.rs | 20 ---- src/types/server_urls/server_urls_bucket.rs | 93 ++++++++----------- .../ctx/update_streaming_server_urls.rs | 43 +++++---- stremio-core-web/src/model/serialize_ctx.rs | 10 +- 7 files changed, 72 insertions(+), 109 deletions(-) delete mode 100644 src/types/server_urls/server_url_item.rs diff --git a/src/models/ctx/update_streaming_server_urls.rs b/src/models/ctx/update_streaming_server_urls.rs index fa0ac7e2c..0ab980fa5 100644 --- a/src/models/ctx/update_streaming_server_urls.rs +++ b/src/models/ctx/update_streaming_server_urls.rs @@ -22,12 +22,12 @@ pub fn update_streaming_server_urls( streaming_server_urls.add_url(url.clone()); Effects::msg(Msg::Internal(Internal::StreamingServerUrlsBucketChanged)) } - ActionServerUrlsBucket::EditServerUrl { id, new_url } => { - streaming_server_urls.edit_item(id, new_url.clone()); + ActionServerUrlsBucket::EditServerUrl { old_url, new_url } => { + streaming_server_urls.edit_url(old_url, new_url.clone()); Effects::msg(Msg::Internal(Internal::StreamingServerUrlsBucketChanged)) } - ActionServerUrlsBucket::DeleteServerUrl(id) => { - streaming_server_urls.delete_item(id); + ActionServerUrlsBucket::DeleteServerUrl(url) => { + streaming_server_urls.delete_url(url); Effects::msg(Msg::Internal(Internal::StreamingServerUrlsBucketChanged)) } } diff --git a/src/runtime/msg/action.rs b/src/runtime/msg/action.rs index efe344a2c..f2284d69c 100644 --- a/src/runtime/msg/action.rs +++ b/src/runtime/msg/action.rs @@ -131,8 +131,8 @@ pub struct PlayOnDeviceArgs { #[serde(tag = "action", content = "args")] pub enum ActionServerUrlsBucket { AddServerUrl(Url), - EditServerUrl { id: usize, new_url: Url }, - DeleteServerUrl(usize), + EditServerUrl { old_url: Url, new_url: Url }, + DeleteServerUrl(Url), } #[derive(Clone, Deserialize, Debug)] diff --git a/src/types/server_urls/mod.rs b/src/types/server_urls/mod.rs index 27d08716e..ab892ef3d 100644 --- a/src/types/server_urls/mod.rs +++ b/src/types/server_urls/mod.rs @@ -1,5 +1,2 @@ mod server_urls_bucket; pub use server_urls_bucket::*; - -mod server_url_item; -pub use server_url_item::*; diff --git a/src/types/server_urls/server_url_item.rs b/src/types/server_urls/server_url_item.rs deleted file mode 100644 index d029b9f37..000000000 --- a/src/types/server_urls/server_url_item.rs +++ /dev/null @@ -1,20 +0,0 @@ -use chrono::{DateTime, Utc}; -use serde::{Deserialize, Serialize}; -use url::Url; - -/// Server URL Item -#[derive(Debug, Serialize, Deserialize, Clone, PartialEq)] -pub struct ServerUrlItem { - /// Unique ID - pub id: usize, - /// URL - pub url: Url, - /// Modification time - pub mtime: DateTime, -} - -impl ServerUrlItem { - pub fn new(id: usize, url: Url, mtime: DateTime) -> Self { - ServerUrlItem { id, url, mtime } - } -} diff --git a/src/types/server_urls/server_urls_bucket.rs b/src/types/server_urls/server_urls_bucket.rs index ed0f69018..4220730ee 100644 --- a/src/types/server_urls/server_urls_bucket.rs +++ b/src/types/server_urls/server_urls_bucket.rs @@ -1,8 +1,5 @@ -use super::ServerUrlItem; use crate::{ - constants::{ - SERVER_URL_BUCKET_DEFAULT_ITEM_ID, SERVER_URL_BUCKET_MAX_ITEMS, STREAMING_SERVER_URL, - }, + constants::{SERVER_URL_BUCKET_MAX_ITEMS, STREAMING_SERVER_URL}, types::profile::UID, }; use chrono::{DateTime, Utc}; @@ -14,23 +11,17 @@ use url::Url; pub struct ServerUrlsBucket { /// User ID pub uid: UID, - /// [`HashMap`] Key is the [`ServerUrlItem`]`.id`. - pub items: HashMap, + /// HashMap where key is `Url`, value is `DateTime` + pub items: HashMap>, } impl ServerUrlsBucket { - /// Create a new [`ServerUrlsBucket`] with the base URL inserted. + /// Create a new `ServerUrlsBucket` with the base URL inserted. pub fn new(uid: UID) -> Self { let mut items = HashMap::new(); let base_url: &Url = &STREAMING_SERVER_URL; - - let server_base_url_item = ServerUrlItem { - id: SERVER_URL_BUCKET_DEFAULT_ITEM_ID, - url: base_url.clone(), - mtime: Self::current_timestamp(), - }; - - items.insert(server_base_url_item.id, server_base_url_item); + let mtime = Self::current_timestamp(); + items.insert(base_url.clone(), mtime); ServerUrlsBucket { uid, items } } @@ -39,55 +30,53 @@ impl ServerUrlsBucket { chrono::Utc::now() } - pub fn generate_new_id(&self) -> usize { - self.items.keys().max().cloned().unwrap_or(0) + 1 - } - + /// Add a new URL to the bucket. pub fn add_url(&mut self, url: Url) { - let new_id = self.generate_new_id(); - let new_item = ServerUrlItem::new(new_id, url, Self::current_timestamp()); - self.merge_items(vec![new_item]); + let mtime = Self::current_timestamp(); + self.merge_items(vec![(url, mtime)]); } - pub fn merge_items(&mut self, items: Vec) { - for new_item in items.into_iter() { - match self.items.get_mut(&new_item.id) { - Some(item) => { - *item = new_item; - } - None => { - if self.items.len() < SERVER_URL_BUCKET_MAX_ITEMS { - self.items.insert(new_item.id.to_owned(), new_item); - } else { - let oldest_item_id_option = self - .items - .values() - .filter(|item| item.id != SERVER_URL_BUCKET_DEFAULT_ITEM_ID) - .min_by_key(|item| item.mtime) - .map(|item| item.id); + /// Merge multiple URL items into the bucket. + pub fn merge_items(&mut self, items: Vec<(Url, DateTime)>) { + for (url, mtime) in items.into_iter() { + if let Some(existing_mtime) = self.items.get_mut(&url) { + *existing_mtime = mtime; + } else if self.items.len() < SERVER_URL_BUCKET_MAX_ITEMS { + self.items.insert(url.clone(), mtime); + } else { + let default_url: &Url = &STREAMING_SERVER_URL; + + let oldest_item_option = self + .items + .iter() + .filter(|(item_url, _)| *item_url != default_url) + .min_by_key(|(_, &item_mtime)| item_mtime) + .map(|(item_url, _)| item_url.clone()); - if let Some(oldest_item_id) = oldest_item_id_option { - if new_item.mtime > self.items[&oldest_item_id].mtime { - self.items.remove(&oldest_item_id); - self.items.insert(new_item.id.to_owned(), new_item); - } - } + if let Some(oldest_url) = oldest_item_option { + if mtime > *self.items.get(&oldest_url).unwrap() { + self.items.remove(&oldest_url); + self.items.insert(url.clone(), mtime); } } } } } - pub fn edit_item(&mut self, id: &usize, new_url: Url) { - if let Some(item) = self.items.get_mut(id) { - item.url = new_url; - item.mtime = Self::current_timestamp(); - } + /// Edit an existing URL in the bucket. + pub fn edit_url(&mut self, old_url: &Url, new_url: Url) { + let default_url: &Url = &STREAMING_SERVER_URL; + if old_url != default_url && self.items.remove(old_url).is_some() { + let new_mtime = Self::current_timestamp(); + self.items.insert(new_url, new_mtime); + }m } - pub fn delete_item(&mut self, id: &usize) { - if *id != SERVER_URL_BUCKET_DEFAULT_ITEM_ID { - self.items.remove(id); + /// Delete a URL from the bucket. + pub fn delete_url(&mut self, url: &Url) { + let default_url: &Url = &STREAMING_SERVER_URL; + if url != default_url { + self.items.remove(url); } } } diff --git a/src/unit_tests/ctx/update_streaming_server_urls.rs b/src/unit_tests/ctx/update_streaming_server_urls.rs index b1e8549ba..c91eb9576 100644 --- a/src/unit_tests/ctx/update_streaming_server_urls.rs +++ b/src/unit_tests/ctx/update_streaming_server_urls.rs @@ -7,7 +7,7 @@ use crate::types::library::LibraryBucket; use crate::types::notifications::NotificationsBucket; use crate::types::profile::Profile; use crate::types::search_history::SearchHistoryBucket; -use crate::types::server_urls::{ServerUrlItem, ServerUrlsBucket}; +use crate::types::server_urls::ServerUrlsBucket; use crate::types::streams::StreamsBucket; use crate::unit_tests::{TestEnv, STORAGE}; use stremio_derive::Model; @@ -42,7 +42,7 @@ fn test_add_server_url() { }); let server_urls = &runtime.model().unwrap().ctx.streaming_server_urls; assert!( - server_urls.items.values().any(|item| item.url == new_url), + server_urls.items.contains_key(&new_url), "New server URL should be added" ); assert!( @@ -52,7 +52,7 @@ fn test_add_server_url() { .get(STREAMING_SERVER_URLS_STORAGE_KEY) .map_or(false, |data| { let stored_bucket: ServerUrlsBucket = serde_json::from_str(data).unwrap(); - stored_bucket.items.values().any(|item| item.url == new_url) + stored_bucket.items.contains_key(&new_url) }), "New server URL should be stored" ); @@ -70,9 +70,9 @@ fn test_edit_server_url() { // Initialize with a server URL let initial_url = Url::parse("http://localhost:11470").unwrap(); let mut server_urls = ServerUrlsBucket::new(None); - let item_id = 1; - let server_url_item = ServerUrlItem::new(item_id, initial_url.clone(), TestEnv::now()); - server_urls.items.insert(item_id, server_url_item); + server_urls + .items + .insert(initial_url.clone(), TestEnv::now()); STORAGE.write().unwrap().insert( STREAMING_SERVER_URLS_STORAGE_KEY.to_owned(), @@ -95,7 +95,7 @@ fn test_edit_server_url() { field: None, action: Action::StreamingServer(ActionStreamingServer::ServerUrlsBucket( ActionServerUrlsBucket::EditServerUrl { - id: item_id, + old_url: initial_url.clone(), new_url: new_url.clone(), }, )), @@ -103,11 +103,12 @@ fn test_edit_server_url() { }); let server_urls = &runtime.model().unwrap().ctx.streaming_server_urls; assert!( - server_urls - .items - .get(&item_id) - .map_or(false, |item| item.url == new_url), - "Server URL should be updated" + !server_urls.items.contains_key(&initial_url), + "Old server URL should be removed" + ); + assert!( + server_urls.items.contains_key(&new_url), + "New server URL should be added" ); assert!( STORAGE @@ -116,10 +117,8 @@ fn test_edit_server_url() { .get(STREAMING_SERVER_URLS_STORAGE_KEY) .map_or(false, |data| { let stored_bucket: ServerUrlsBucket = serde_json::from_str(data).unwrap(); - stored_bucket - .items - .get(&item_id) - .map_or(false, |item| item.url == new_url) + !stored_bucket.items.contains_key(&initial_url) + && stored_bucket.items.contains_key(&new_url) }), "Updated server URL should be stored" ); @@ -137,9 +136,9 @@ fn test_delete_server_url() { // Initialize with a server URL let initial_url = Url::parse("http://localhost:11470").unwrap(); let mut server_urls = ServerUrlsBucket::new(None); - let item_id = 1; - let server_url_item = ServerUrlItem::new(item_id, initial_url.clone(), TestEnv::now()); - server_urls.items.insert(item_id, server_url_item); + server_urls + .items + .insert(initial_url.clone(), TestEnv::now()); STORAGE.write().unwrap().insert( STREAMING_SERVER_URLS_STORAGE_KEY.to_owned(), @@ -160,13 +159,13 @@ fn test_delete_server_url() { runtime.dispatch(RuntimeAction { field: None, action: Action::StreamingServer(ActionStreamingServer::ServerUrlsBucket( - ActionServerUrlsBucket::DeleteServerUrl(item_id), + ActionServerUrlsBucket::DeleteServerUrl(initial_url.clone()), )), }) }); let server_urls = &runtime.model().unwrap().ctx.streaming_server_urls; assert!( - !server_urls.items.contains_key(&item_id), + !server_urls.items.contains_key(&initial_url), "Server URL should be deleted" ); assert!( @@ -176,7 +175,7 @@ fn test_delete_server_url() { .get(STREAMING_SERVER_URLS_STORAGE_KEY) .map_or(true, |data| { let stored_bucket: ServerUrlsBucket = serde_json::from_str(data).unwrap(); - !stored_bucket.items.contains_key(&item_id) + !stored_bucket.items.contains_key(&initial_url) }), "Deleted server URL should not be stored" ); diff --git a/stremio-core-web/src/model/serialize_ctx.rs b/stremio-core-web/src/model/serialize_ctx.rs index f8f848059..061de2841 100644 --- a/stremio-core-web/src/model/serialize_ctx.rs +++ b/stremio-core-web/src/model/serialize_ctx.rs @@ -36,7 +36,6 @@ mod model { #[derive(Serialize)] #[serde(rename_all = "camelCase")] pub struct StreamingServerUrlItem { - pub id: usize, pub url: String, #[serde(rename = "_mtime")] pub mtime: DateTime, @@ -88,11 +87,10 @@ mod model { streaming_server_urls: ctx .streaming_server_urls .items - .values() - .map(|item| StreamingServerUrlItem { - id: item.id, - url: item.url.to_string(), - mtime: item.mtime, + .iter() + .map(|(url, mtime)| StreamingServerUrlItem { + url: url.to_string(), + mtime: *mtime, }) .collect(), } From 1aac7ce87e5cde5ad1a368a5905a6f5251340f61 Mon Sep 17 00:00:00 2001 From: "Timothy Z." Date: Thu, 10 Oct 2024 12:56:57 +0300 Subject: [PATCH 32/44] fix: errors --- src/constants.rs | 1 - src/types/server_urls/server_urls_bucket.rs | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/src/constants.rs b/src/constants.rs index a9e83f351..557a7037d 100644 --- a/src/constants.rs +++ b/src/constants.rs @@ -31,7 +31,6 @@ pub const LIBRARY_RECENT_COUNT: usize = 200; pub const NOTIFICATION_ITEMS_COUNT: usize = 100; pub const SERVER_URL_BUCKET_MAX_ITEMS: usize = 5; -pub const SERVER_URL_BUCKET_DEFAULT_ITEM_ID: usize = 0; /// A `LibraryItem` is considered watched once we've watched more than the `duration * threshold`: /// diff --git a/src/types/server_urls/server_urls_bucket.rs b/src/types/server_urls/server_urls_bucket.rs index 4220730ee..80b8f9a26 100644 --- a/src/types/server_urls/server_urls_bucket.rs +++ b/src/types/server_urls/server_urls_bucket.rs @@ -69,7 +69,7 @@ impl ServerUrlsBucket { if old_url != default_url && self.items.remove(old_url).is_some() { let new_mtime = Self::current_timestamp(); self.items.insert(new_url, new_mtime); - }m + } } /// Delete a URL from the bucket. From cafe0ebfc1ccd888989af31713a290ebc55223fd Mon Sep 17 00:00:00 2001 From: "Timothy Z." Date: Tue, 15 Oct 2024 11:40:42 +0300 Subject: [PATCH 33/44] remove: edit URL feature --- .../ctx/update_streaming_server_urls.rs | 4 -- src/runtime/msg/action.rs | 1 - src/types/server_urls/server_urls_bucket.rs | 9 --- .../ctx/update_streaming_server_urls.rs | 67 ------------------- 4 files changed, 81 deletions(-) diff --git a/src/models/ctx/update_streaming_server_urls.rs b/src/models/ctx/update_streaming_server_urls.rs index 0ab980fa5..a1149975b 100644 --- a/src/models/ctx/update_streaming_server_urls.rs +++ b/src/models/ctx/update_streaming_server_urls.rs @@ -22,10 +22,6 @@ pub fn update_streaming_server_urls( streaming_server_urls.add_url(url.clone()); Effects::msg(Msg::Internal(Internal::StreamingServerUrlsBucketChanged)) } - ActionServerUrlsBucket::EditServerUrl { old_url, new_url } => { - streaming_server_urls.edit_url(old_url, new_url.clone()); - Effects::msg(Msg::Internal(Internal::StreamingServerUrlsBucketChanged)) - } ActionServerUrlsBucket::DeleteServerUrl(url) => { streaming_server_urls.delete_url(url); Effects::msg(Msg::Internal(Internal::StreamingServerUrlsBucketChanged)) diff --git a/src/runtime/msg/action.rs b/src/runtime/msg/action.rs index f2284d69c..8305a4df5 100644 --- a/src/runtime/msg/action.rs +++ b/src/runtime/msg/action.rs @@ -131,7 +131,6 @@ pub struct PlayOnDeviceArgs { #[serde(tag = "action", content = "args")] pub enum ActionServerUrlsBucket { AddServerUrl(Url), - EditServerUrl { old_url: Url, new_url: Url }, DeleteServerUrl(Url), } diff --git a/src/types/server_urls/server_urls_bucket.rs b/src/types/server_urls/server_urls_bucket.rs index 80b8f9a26..2a71b05a3 100644 --- a/src/types/server_urls/server_urls_bucket.rs +++ b/src/types/server_urls/server_urls_bucket.rs @@ -63,15 +63,6 @@ impl ServerUrlsBucket { } } - /// Edit an existing URL in the bucket. - pub fn edit_url(&mut self, old_url: &Url, new_url: Url) { - let default_url: &Url = &STREAMING_SERVER_URL; - if old_url != default_url && self.items.remove(old_url).is_some() { - let new_mtime = Self::current_timestamp(); - self.items.insert(new_url, new_mtime); - } - } - /// Delete a URL from the bucket. pub fn delete_url(&mut self, url: &Url) { let default_url: &Url = &STREAMING_SERVER_URL; diff --git a/src/unit_tests/ctx/update_streaming_server_urls.rs b/src/unit_tests/ctx/update_streaming_server_urls.rs index c91eb9576..0909fbdc4 100644 --- a/src/unit_tests/ctx/update_streaming_server_urls.rs +++ b/src/unit_tests/ctx/update_streaming_server_urls.rs @@ -57,73 +57,6 @@ fn test_add_server_url() { "New server URL should be stored" ); } - -#[test] -fn test_edit_server_url() { - #[derive(Model, Clone, Default)] - #[model(TestEnv)] - struct TestModel { - ctx: Ctx, - } - let _env_mutex = TestEnv::reset().expect("Should have exclusive lock to TestEnv"); - - // Initialize with a server URL - let initial_url = Url::parse("http://localhost:11470").unwrap(); - let mut server_urls = ServerUrlsBucket::new(None); - server_urls - .items - .insert(initial_url.clone(), TestEnv::now()); - - STORAGE.write().unwrap().insert( - STREAMING_SERVER_URLS_STORAGE_KEY.to_owned(), - serde_json::to_string(&server_urls).unwrap(), - ); - - let ctx = Ctx::new( - Profile::default(), - LibraryBucket::default(), - StreamsBucket::default(), - server_urls, - NotificationsBucket::new::(None, vec![]), - SearchHistoryBucket::default(), - DismissedEventsBucket::default(), - ); - let (runtime, _rx) = Runtime::::new(TestModel { ctx }, vec![], 1000); - let new_url = Url::parse("http://localhost:11471").unwrap(); - TestEnv::run(|| { - runtime.dispatch(RuntimeAction { - field: None, - action: Action::StreamingServer(ActionStreamingServer::ServerUrlsBucket( - ActionServerUrlsBucket::EditServerUrl { - old_url: initial_url.clone(), - new_url: new_url.clone(), - }, - )), - }) - }); - let server_urls = &runtime.model().unwrap().ctx.streaming_server_urls; - assert!( - !server_urls.items.contains_key(&initial_url), - "Old server URL should be removed" - ); - assert!( - server_urls.items.contains_key(&new_url), - "New server URL should be added" - ); - assert!( - STORAGE - .read() - .unwrap() - .get(STREAMING_SERVER_URLS_STORAGE_KEY) - .map_or(false, |data| { - let stored_bucket: ServerUrlsBucket = serde_json::from_str(data).unwrap(); - !stored_bucket.items.contains_key(&initial_url) - && stored_bucket.items.contains_key(&new_url) - }), - "Updated server URL should be stored" - ); -} - #[test] fn test_delete_server_url() { #[derive(Model, Clone, Default)] From 6f32b6034d1a89f5805156d52c4e962d000b2af2 Mon Sep 17 00:00:00 2001 From: "Timothy Z." Date: Mon, 21 Oct 2024 13:51:45 +0300 Subject: [PATCH 34/44] refactor: move the URL actions to CtxAction --- .../ctx/update_streaming_server_urls.rs | 22 ++++++++----------- src/runtime/msg/action.rs | 12 ++++------ .../ctx/update_streaming_server_urls.rs | 10 +++------ 3 files changed, 16 insertions(+), 28 deletions(-) diff --git a/src/models/ctx/update_streaming_server_urls.rs b/src/models/ctx/update_streaming_server_urls.rs index a1149975b..abfed5eff 100644 --- a/src/models/ctx/update_streaming_server_urls.rs +++ b/src/models/ctx/update_streaming_server_urls.rs @@ -1,8 +1,8 @@ use crate::constants::STREAMING_SERVER_URLS_STORAGE_KEY; -use crate::runtime::msg::{Action, ActionStreamingServer, CtxAuthResponse}; +use crate::runtime::msg::{Action, ActionCtx, CtxAuthResponse}; use crate::runtime::EnvFutureExt; use crate::runtime::{ - msg::{ActionServerUrlsBucket, Event, Internal, Msg}, + msg::{Event, Internal, Msg}, Effect, EffectFuture, Effects, Env, }; use crate::types::server_urls::ServerUrlsBucket; @@ -16,17 +16,13 @@ pub fn update_streaming_server_urls( msg: &Msg, ) -> Effects { match msg { - Msg::Action(Action::StreamingServer(ActionStreamingServer::ServerUrlsBucket(action))) => { - match action { - ActionServerUrlsBucket::AddServerUrl(url) => { - streaming_server_urls.add_url(url.clone()); - Effects::msg(Msg::Internal(Internal::StreamingServerUrlsBucketChanged)) - } - ActionServerUrlsBucket::DeleteServerUrl(url) => { - streaming_server_urls.delete_url(url); - Effects::msg(Msg::Internal(Internal::StreamingServerUrlsBucketChanged)) - } - } + Msg::Action(Action::Ctx(ActionCtx::AddServerUrl(url))) => { + streaming_server_urls.add_url(url.clone()); + Effects::msg(Msg::Internal(Internal::StreamingServerUrlsBucketChanged)) + } + Msg::Action(Action::Ctx(ActionCtx::DeleteServerUrl(url))) => { + streaming_server_urls.delete_url(url); + Effects::msg(Msg::Internal(Internal::StreamingServerUrlsBucketChanged)) } Msg::Internal(Internal::CtxAuthResult(auth_request, result)) => match (status, result) { (CtxStatus::Loading(loading_auth_request), Ok(CtxAuthResponse { auth, .. })) diff --git a/src/runtime/msg/action.rs b/src/runtime/msg/action.rs index 8305a4df5..7f39fb1af 100644 --- a/src/runtime/msg/action.rs +++ b/src/runtime/msg/action.rs @@ -68,6 +68,10 @@ pub enum ActionCtx { GetEvents, /// Dismiss an event by id, either a Modal or Notification DismissEvent(String), + /// Add a server URL to the list of available streaming servers + AddServerUrl(Url), + /// Delete a server URL from the list of available streaming servers + DeleteServerUrl(Url), } #[derive(Clone, Deserialize, Debug)] @@ -127,13 +131,6 @@ pub struct PlayOnDeviceArgs { pub time: Option, } -#[derive(Clone, Deserialize, Debug)] -#[serde(tag = "action", content = "args")] -pub enum ActionServerUrlsBucket { - AddServerUrl(Url), - DeleteServerUrl(Url), -} - #[derive(Clone, Deserialize, Debug)] #[serde(tag = "action", content = "args")] pub enum ActionStreamingServer { @@ -142,7 +139,6 @@ pub enum ActionStreamingServer { CreateTorrent(CreateTorrentArgs), GetStatistics(StreamingServerStatisticsRequest), PlayOnDevice(PlayOnDeviceArgs), - ServerUrlsBucket(ActionServerUrlsBucket), } #[derive(Clone, Deserialize, Debug)] diff --git a/src/unit_tests/ctx/update_streaming_server_urls.rs b/src/unit_tests/ctx/update_streaming_server_urls.rs index 0909fbdc4..aecaaf68f 100644 --- a/src/unit_tests/ctx/update_streaming_server_urls.rs +++ b/src/unit_tests/ctx/update_streaming_server_urls.rs @@ -1,6 +1,6 @@ use crate::constants::STREAMING_SERVER_URLS_STORAGE_KEY; use crate::models::ctx::Ctx; -use crate::runtime::msg::{Action, ActionServerUrlsBucket, ActionStreamingServer}; +use crate::runtime::msg::{Action, ActionCtx}; use crate::runtime::{Env, Runtime, RuntimeAction}; use crate::types::events::DismissedEventsBucket; use crate::types::library::LibraryBucket; @@ -35,9 +35,7 @@ fn test_add_server_url() { TestEnv::run(|| { runtime.dispatch(RuntimeAction { field: None, - action: Action::StreamingServer(ActionStreamingServer::ServerUrlsBucket( - ActionServerUrlsBucket::AddServerUrl(new_url.clone()), - )), + action: Action::Ctx(ActionCtx::AddServerUrl(new_url.clone())), }) }); let server_urls = &runtime.model().unwrap().ctx.streaming_server_urls; @@ -91,9 +89,7 @@ fn test_delete_server_url() { TestEnv::run(|| { runtime.dispatch(RuntimeAction { field: None, - action: Action::StreamingServer(ActionStreamingServer::ServerUrlsBucket( - ActionServerUrlsBucket::DeleteServerUrl(initial_url.clone()), - )), + action: Action::Ctx(ActionCtx::DeleteServerUrl(initial_url.clone())), }) }); let server_urls = &runtime.model().unwrap().ctx.streaming_server_urls; From 2f663b1d82076fc87b2ce1578eba113c7f97b497 Mon Sep 17 00:00:00 2001 From: "Timothy Z." Date: Wed, 23 Oct 2024 16:57:22 +0300 Subject: [PATCH 35/44] add: Env implementation for the bucket --- src/models/ctx/update_streaming_server_urls.rs | 4 ++-- src/types/server_urls/server_urls_bucket.rs | 13 +++++-------- src/unit_tests/catalog_with_filters/load_action.rs | 4 ++-- src/unit_tests/ctx/add_to_library.rs | 4 ++-- src/unit_tests/ctx/authenticate.rs | 8 ++++---- src/unit_tests/ctx/install_addon.rs | 8 ++++---- src/unit_tests/ctx/logout.rs | 2 +- .../ctx/notifications/update_notifications.rs | 6 +++--- src/unit_tests/ctx/pull_addons_from_api.rs | 4 ++-- src/unit_tests/ctx/push_addons_to_api.rs | 4 ++-- src/unit_tests/ctx/remove_from_library.rs | 4 ++-- src/unit_tests/ctx/rewind_library_item.rs | 4 ++-- src/unit_tests/ctx/sync_library_with_api.rs | 6 +++--- src/unit_tests/ctx/uninstall_addon.rs | 10 +++++----- src/unit_tests/ctx/update_search_history.rs | 4 ++-- src/unit_tests/ctx/update_settings.rs | 4 ++-- src/unit_tests/ctx/update_streaming_server_urls.rs | 4 ++-- src/unit_tests/ctx/upgrade_addon.rs | 4 ++-- src/unit_tests/data_export.rs | 4 ++-- src/unit_tests/link.rs | 2 +- stremio-core-web/src/stremio_core_web.rs | 3 ++- 21 files changed, 52 insertions(+), 54 deletions(-) diff --git a/src/models/ctx/update_streaming_server_urls.rs b/src/models/ctx/update_streaming_server_urls.rs index abfed5eff..93ebd70b4 100644 --- a/src/models/ctx/update_streaming_server_urls.rs +++ b/src/models/ctx/update_streaming_server_urls.rs @@ -17,7 +17,7 @@ pub fn update_streaming_server_urls( ) -> Effects { match msg { Msg::Action(Action::Ctx(ActionCtx::AddServerUrl(url))) => { - streaming_server_urls.add_url(url.clone()); + streaming_server_urls.add_url::(url.clone()); Effects::msg(Msg::Internal(Internal::StreamingServerUrlsBucketChanged)) } Msg::Action(Action::Ctx(ActionCtx::DeleteServerUrl(url))) => { @@ -28,7 +28,7 @@ pub fn update_streaming_server_urls( (CtxStatus::Loading(loading_auth_request), Ok(CtxAuthResponse { auth, .. })) if loading_auth_request == auth_request => { - let next_server_urls = ServerUrlsBucket::new(Some(auth.user.id.to_owned())); + let next_server_urls = ServerUrlsBucket::new::(Some(auth.user.id.to_owned())); *streaming_server_urls = next_server_urls; Effects::msg(Msg::Internal(Internal::StreamingServerUrlsBucketChanged)) } diff --git a/src/types/server_urls/server_urls_bucket.rs b/src/types/server_urls/server_urls_bucket.rs index 2a71b05a3..3d9c0283a 100644 --- a/src/types/server_urls/server_urls_bucket.rs +++ b/src/types/server_urls/server_urls_bucket.rs @@ -1,5 +1,6 @@ use crate::{ constants::{SERVER_URL_BUCKET_MAX_ITEMS, STREAMING_SERVER_URL}, + runtime::Env, types::profile::UID, }; use chrono::{DateTime, Utc}; @@ -17,22 +18,18 @@ pub struct ServerUrlsBucket { impl ServerUrlsBucket { /// Create a new `ServerUrlsBucket` with the base URL inserted. - pub fn new(uid: UID) -> Self { + pub fn new(uid: UID) -> Self { let mut items = HashMap::new(); let base_url: &Url = &STREAMING_SERVER_URL; - let mtime = Self::current_timestamp(); + let mtime = E::now(); items.insert(base_url.clone(), mtime); ServerUrlsBucket { uid, items } } - fn current_timestamp() -> DateTime { - chrono::Utc::now() - } - /// Add a new URL to the bucket. - pub fn add_url(&mut self, url: Url) { - let mtime = Self::current_timestamp(); + pub fn add_url(&mut self, url: Url) { + let mtime = E::now(); self.merge_items(vec![(url, mtime)]); } diff --git a/src/unit_tests/catalog_with_filters/load_action.rs b/src/unit_tests/catalog_with_filters/load_action.rs index 6041684a0..3ed94d1fd 100644 --- a/src/unit_tests/catalog_with_filters/load_action.rs +++ b/src/unit_tests/catalog_with_filters/load_action.rs @@ -51,7 +51,7 @@ fn default_catalog() { Profile::default(), LibraryBucket::default(), StreamsBucket::default(), - ServerUrlsBucket::new(None), + ServerUrlsBucket::new::(None), NotificationsBucket::new::(None, vec![]), SearchHistoryBucket::default(), DismissedEventsBucket::default(), @@ -153,7 +153,7 @@ fn search_catalog() { Profile::default(), LibraryBucket::default(), StreamsBucket::default(), - ServerUrlsBucket::new(None), + ServerUrlsBucket::new::(None), NotificationsBucket::new::(None, vec![]), SearchHistoryBucket::default(), DismissedEventsBucket::default(), diff --git a/src/unit_tests/ctx/add_to_library.rs b/src/unit_tests/ctx/add_to_library.rs index 25bb117e2..bf8630335 100644 --- a/src/unit_tests/ctx/add_to_library.rs +++ b/src/unit_tests/ctx/add_to_library.rs @@ -107,7 +107,7 @@ fn actionctx_addtolibrary() { ..Default::default() }, StreamsBucket::default(), - ServerUrlsBucket::new(None), + ServerUrlsBucket::new::(None), NotificationsBucket::new::(None, vec![]), SearchHistoryBucket::default(), DismissedEventsBucket::default(), @@ -245,7 +245,7 @@ fn actionctx_addtolibrary_already_added() { .collect(), }, StreamsBucket::default(), - ServerUrlsBucket::new(None), + ServerUrlsBucket::new::(None), NotificationsBucket::new::(None, vec![]), SearchHistoryBucket::default(), DismissedEventsBucket::default(), diff --git a/src/unit_tests/ctx/authenticate.rs b/src/unit_tests/ctx/authenticate.rs index 3cf751f73..7541d835d 100644 --- a/src/unit_tests/ctx/authenticate.rs +++ b/src/unit_tests/ctx/authenticate.rs @@ -108,7 +108,7 @@ fn actionctx_authenticate_login() { Profile::default(), LibraryBucket::default(), StreamsBucket::default(), - ServerUrlsBucket::new(None), + ServerUrlsBucket::new::(None), NotificationsBucket::new::(None, vec![]), SearchHistoryBucket::default(), DismissedEventsBucket::default(), @@ -250,7 +250,7 @@ fn actionctx_authenticate_login_with_token() { Profile::default(), LibraryBucket::default(), StreamsBucket::default(), - ServerUrlsBucket::new(None), + ServerUrlsBucket::new::(None), NotificationsBucket::new::(None, vec![]), SearchHistoryBucket::default(), DismissedEventsBucket::default(), @@ -391,7 +391,7 @@ fn actionctx_authenticate_facebook() { Profile::default(), LibraryBucket::default(), StreamsBucket::default(), - ServerUrlsBucket::new(None), + ServerUrlsBucket::new::(None), NotificationsBucket::new::(None, vec![]), SearchHistoryBucket::default(), DismissedEventsBucket::default(), @@ -532,7 +532,7 @@ fn actionctx_authenticate_register() { Profile::default(), LibraryBucket::default(), StreamsBucket::default(), - ServerUrlsBucket::new(None), + ServerUrlsBucket::new::(None), NotificationsBucket::new::(None, vec![]), SearchHistoryBucket::default(), DismissedEventsBucket::default(), diff --git a/src/unit_tests/ctx/install_addon.rs b/src/unit_tests/ctx/install_addon.rs index fbabad68d..ff9e70fb4 100644 --- a/src/unit_tests/ctx/install_addon.rs +++ b/src/unit_tests/ctx/install_addon.rs @@ -57,7 +57,7 @@ fn actionctx_installaddon_install() { }, LibraryBucket::default(), StreamsBucket::default(), - ServerUrlsBucket::new(None), + ServerUrlsBucket::new::(None), NotificationsBucket::new::(None, vec![]), SearchHistoryBucket::default(), DismissedEventsBucket::default(), @@ -163,7 +163,7 @@ fn actionctx_installaddon_install_with_user() { }, LibraryBucket::default(), StreamsBucket::default(), - ServerUrlsBucket::new(None), + ServerUrlsBucket::new::(None), NotificationsBucket::new::(None, vec![]), SearchHistoryBucket::default(), DismissedEventsBucket::default(), @@ -287,7 +287,7 @@ fn actionctx_installaddon_update() { }, LibraryBucket::default(), StreamsBucket::default(), - ServerUrlsBucket::new(None), + ServerUrlsBucket::new::(None), NotificationsBucket::new::(None, vec![]), SearchHistoryBucket::default(), DismissedEventsBucket::default(), @@ -365,7 +365,7 @@ fn actionctx_installaddon_already_installed() { profile, LibraryBucket::default(), StreamsBucket::default(), - ServerUrlsBucket::new(None), + ServerUrlsBucket::new::(None), NotificationsBucket::new::(None, vec![]), SearchHistoryBucket::default(), DismissedEventsBucket::default(), diff --git a/src/unit_tests/ctx/logout.rs b/src/unit_tests/ctx/logout.rs index 6ce02b362..f00ea119b 100644 --- a/src/unit_tests/ctx/logout.rs +++ b/src/unit_tests/ctx/logout.rs @@ -88,7 +88,7 @@ fn actionctx_logout() { profile, library, StreamsBucket::default(), - ServerUrlsBucket::new(None), + ServerUrlsBucket::new::(None), NotificationsBucket::new::(None, vec![]), SearchHistoryBucket::default(), DismissedEventsBucket::default(), diff --git a/src/unit_tests/ctx/notifications/update_notifications.rs b/src/unit_tests/ctx/notifications/update_notifications.rs index 4067d6ada..d92ffbfbe 100644 --- a/src/unit_tests/ctx/notifications/update_notifications.rs +++ b/src/unit_tests/ctx/notifications/update_notifications.rs @@ -240,7 +240,7 @@ fn test_pull_notifications_and_play_in_player() { }], ), StreamsBucket::default(), - ServerUrlsBucket::new(None), + ServerUrlsBucket::new::(None), NotificationsBucket::new::(None, vec![]), SearchHistoryBucket::default(), DismissedEventsBucket::default(), @@ -390,7 +390,7 @@ fn test_pull_notifications_test_cases() { }, LibraryBucket::new(None, test.library_items), StreamsBucket::default(), - ServerUrlsBucket::new(None), + ServerUrlsBucket::new::(None), NotificationsBucket::new::(None, test.notification_items), SearchHistoryBucket::default(), DismissedEventsBucket::default(), @@ -488,7 +488,7 @@ fn test_dismiss_notification() { ], ), StreamsBucket::default(), - ServerUrlsBucket::new(None), + ServerUrlsBucket::new::(None), NotificationsBucket::new::( None, vec![ diff --git a/src/unit_tests/ctx/pull_addons_from_api.rs b/src/unit_tests/ctx/pull_addons_from_api.rs index d852d24ea..c8d123c0c 100644 --- a/src/unit_tests/ctx/pull_addons_from_api.rs +++ b/src/unit_tests/ctx/pull_addons_from_api.rs @@ -45,7 +45,7 @@ fn actionctx_pulladdonsfromapi() { }, LibraryBucket::default(), StreamsBucket::default(), - ServerUrlsBucket::new(None), + ServerUrlsBucket::new::(None), NotificationsBucket::new::(None, vec![]), SearchHistoryBucket::default(), DismissedEventsBucket::default(), @@ -154,7 +154,7 @@ fn actionctx_pulladdonsfromapi_with_user() { }, LibraryBucket::default(), StreamsBucket::default(), - ServerUrlsBucket::new(None), + ServerUrlsBucket::new::(None), NotificationsBucket::new::(None, vec![]), SearchHistoryBucket::default(), DismissedEventsBucket::default(), diff --git a/src/unit_tests/ctx/push_addons_to_api.rs b/src/unit_tests/ctx/push_addons_to_api.rs index 553722dad..c130a7f30 100644 --- a/src/unit_tests/ctx/push_addons_to_api.rs +++ b/src/unit_tests/ctx/push_addons_to_api.rs @@ -53,7 +53,7 @@ fn actionctx_pushaddonstoapi() { }, LibraryBucket::default(), StreamsBucket::default(), - ServerUrlsBucket::new(None), + ServerUrlsBucket::new::(None), NotificationsBucket::new::(None, vec![]), SearchHistoryBucket::default(), DismissedEventsBucket::default(), @@ -144,7 +144,7 @@ fn actionctx_pushaddonstoapi_with_user() { }, LibraryBucket::default(), StreamsBucket::default(), - ServerUrlsBucket::new(None), + ServerUrlsBucket::new::(None), NotificationsBucket::new::(None, vec![]), SearchHistoryBucket::default(), DismissedEventsBucket::default(), diff --git a/src/unit_tests/ctx/remove_from_library.rs b/src/unit_tests/ctx/remove_from_library.rs index 2b50fb525..83b1bfd01 100644 --- a/src/unit_tests/ctx/remove_from_library.rs +++ b/src/unit_tests/ctx/remove_from_library.rs @@ -102,7 +102,7 @@ fn actionctx_removefromlibrary() { .collect(), }, StreamsBucket::default(), - ServerUrlsBucket::new(None), + ServerUrlsBucket::new::(None), NotificationsBucket::new::(None, vec![]), SearchHistoryBucket::default(), DismissedEventsBucket::default(), @@ -191,7 +191,7 @@ fn actionctx_removefromlibrary_not_added() { .collect(), }, StreamsBucket::default(), - ServerUrlsBucket::new(None), + ServerUrlsBucket::new::(None), NotificationsBucket::new::(None, vec![]), SearchHistoryBucket::default(), DismissedEventsBucket::default(), diff --git a/src/unit_tests/ctx/rewind_library_item.rs b/src/unit_tests/ctx/rewind_library_item.rs index 774858c77..ff358dc15 100644 --- a/src/unit_tests/ctx/rewind_library_item.rs +++ b/src/unit_tests/ctx/rewind_library_item.rs @@ -110,7 +110,7 @@ fn actionctx_rewindlibraryitem() { .collect(), }, StreamsBucket::default(), - ServerUrlsBucket::new(None), + ServerUrlsBucket::new::(None), NotificationsBucket::new::(None, vec![]), SearchHistoryBucket::default(), DismissedEventsBucket::default(), @@ -202,7 +202,7 @@ fn actionctx_rewindlibraryitem_not_added() { .collect(), }, StreamsBucket::default(), - ServerUrlsBucket::new(None), + ServerUrlsBucket::new::(None), NotificationsBucket::new::(None, vec![]), SearchHistoryBucket::default(), DismissedEventsBucket::default(), diff --git a/src/unit_tests/ctx/sync_library_with_api.rs b/src/unit_tests/ctx/sync_library_with_api.rs index 4d349222c..0ddda97a0 100644 --- a/src/unit_tests/ctx/sync_library_with_api.rs +++ b/src/unit_tests/ctx/sync_library_with_api.rs @@ -36,7 +36,7 @@ fn actionctx_synclibrarywithapi() { Profile::default(), LibraryBucket::default(), StreamsBucket::default(), - ServerUrlsBucket::new(None), + ServerUrlsBucket::new::(None), NotificationsBucket::new::(None, vec![]), SearchHistoryBucket::default(), DismissedEventsBucket::default(), @@ -293,7 +293,7 @@ fn actionctx_synclibrarywithapi_with_user() { .collect(), }, StreamsBucket::default(), - ServerUrlsBucket::new(None), + ServerUrlsBucket::new::(None), NotificationsBucket::new::(None, vec![]), SearchHistoryBucket::default(), DismissedEventsBucket::default(), @@ -431,7 +431,7 @@ fn actionctx_synclibrarywithapi_with_user_empty_library() { }, LibraryBucket::default(), StreamsBucket::default(), - ServerUrlsBucket::new(None), + ServerUrlsBucket::new::(None), NotificationsBucket::new::(None, vec![]), SearchHistoryBucket::default(), DismissedEventsBucket::default(), diff --git a/src/unit_tests/ctx/uninstall_addon.rs b/src/unit_tests/ctx/uninstall_addon.rs index 9bc334763..009e32b94 100644 --- a/src/unit_tests/ctx/uninstall_addon.rs +++ b/src/unit_tests/ctx/uninstall_addon.rs @@ -109,7 +109,7 @@ fn actionctx_uninstalladdon() { profile, LibraryBucket::default(), StreamsBucket::default(), - ServerUrlsBucket::new(None), + ServerUrlsBucket::new::(None), NotificationsBucket::new::(None, vec![]), SearchHistoryBucket::default(), DismissedEventsBucket::default(), @@ -223,7 +223,7 @@ fn actionctx_uninstalladdon_with_user() { profile, LibraryBucket::default(), StreamsBucket::default(), - ServerUrlsBucket::new(None), + ServerUrlsBucket::new::(None), NotificationsBucket::new::(None, vec![]), SearchHistoryBucket::default(), DismissedEventsBucket::default(), @@ -317,7 +317,7 @@ fn actionctx_uninstalladdon_protected() { profile, LibraryBucket::default(), StreamsBucket::default(), - ServerUrlsBucket::new(None), + ServerUrlsBucket::new::(None), NotificationsBucket::new::(None, vec![]), SearchHistoryBucket::default(), DismissedEventsBucket::default(), @@ -394,7 +394,7 @@ fn actionctx_uninstalladdon_not_installed() { profile, LibraryBucket::default(), StreamsBucket::default(), - ServerUrlsBucket::new(None), + ServerUrlsBucket::new::(None), NotificationsBucket::new::(None, vec![]), SearchHistoryBucket::default(), DismissedEventsBucket::default(), @@ -479,7 +479,7 @@ fn actionctx_uninstalladdon_streams_bucket() { profile, LibraryBucket::default(), streams, - ServerUrlsBucket::new(None), + ServerUrlsBucket::new::(None), NotificationsBucket::new::(None, vec![]), SearchHistoryBucket::default(), DismissedEventsBucket::default(), diff --git a/src/unit_tests/ctx/update_search_history.rs b/src/unit_tests/ctx/update_search_history.rs index e28ff7737..1b50fb1f7 100644 --- a/src/unit_tests/ctx/update_search_history.rs +++ b/src/unit_tests/ctx/update_search_history.rs @@ -33,7 +33,7 @@ fn test_search_history_update() { Profile::default(), LibraryBucket::default(), StreamsBucket::default(), - ServerUrlsBucket::new(None), + ServerUrlsBucket::new::(None), NotificationsBucket::new::(None, vec![]), SearchHistoryBucket::default(), DismissedEventsBucket::default(), @@ -107,7 +107,7 @@ fn test_search_history_clear_items() { Profile::default(), LibraryBucket::default(), StreamsBucket::default(), - ServerUrlsBucket::new(None), + ServerUrlsBucket::new::(None), NotificationsBucket::new::(None, vec![]), SearchHistoryBucket::default(), DismissedEventsBucket::default(), diff --git a/src/unit_tests/ctx/update_settings.rs b/src/unit_tests/ctx/update_settings.rs index 18b7c7368..d907c850b 100644 --- a/src/unit_tests/ctx/update_settings.rs +++ b/src/unit_tests/ctx/update_settings.rs @@ -29,7 +29,7 @@ fn actionctx_updatesettings() { Profile::default(), LibraryBucket::default(), StreamsBucket::default(), - ServerUrlsBucket::new(None), + ServerUrlsBucket::new::(None), NotificationsBucket::new::(None, vec![]), SearchHistoryBucket::default(), DismissedEventsBucket::default(), @@ -89,7 +89,7 @@ fn actionctx_updatesettings_not_changed() { profile, LibraryBucket::default(), StreamsBucket::default(), - ServerUrlsBucket::new(None), + ServerUrlsBucket::new::(None), NotificationsBucket::new::(None, vec![]), SearchHistoryBucket::default(), DismissedEventsBucket::default(), diff --git a/src/unit_tests/ctx/update_streaming_server_urls.rs b/src/unit_tests/ctx/update_streaming_server_urls.rs index aecaaf68f..c28360155 100644 --- a/src/unit_tests/ctx/update_streaming_server_urls.rs +++ b/src/unit_tests/ctx/update_streaming_server_urls.rs @@ -25,7 +25,7 @@ fn test_add_server_url() { Profile::default(), LibraryBucket::default(), StreamsBucket::default(), - ServerUrlsBucket::new(None), + ServerUrlsBucket::new::(None), NotificationsBucket::new::(None, vec![]), SearchHistoryBucket::default(), DismissedEventsBucket::default(), @@ -66,7 +66,7 @@ fn test_delete_server_url() { // Initialize with a server URL let initial_url = Url::parse("http://localhost:11470").unwrap(); - let mut server_urls = ServerUrlsBucket::new(None); + let mut server_urls = ServerUrlsBucket::new::(None); server_urls .items .insert(initial_url.clone(), TestEnv::now()); diff --git a/src/unit_tests/ctx/upgrade_addon.rs b/src/unit_tests/ctx/upgrade_addon.rs index 819429f55..a08557ed8 100644 --- a/src/unit_tests/ctx/upgrade_addon.rs +++ b/src/unit_tests/ctx/upgrade_addon.rs @@ -89,7 +89,7 @@ fn actionctx_addon_upgrade() { }, LibraryBucket::default(), StreamsBucket::default(), - ServerUrlsBucket::new(None), + ServerUrlsBucket::new::(None), NotificationsBucket::new::(None, vec![]), SearchHistoryBucket::default(), DismissedEventsBucket::default(), @@ -182,7 +182,7 @@ fn actionctx_addon_upgrade_fail_due_to_different_url() { }, LibraryBucket::default(), StreamsBucket::default(), - ServerUrlsBucket::new(None), + ServerUrlsBucket::new::(None), NotificationsBucket::new::(None, vec![]), SearchHistoryBucket::default(), DismissedEventsBucket::default(), diff --git a/src/unit_tests/data_export.rs b/src/unit_tests/data_export.rs index 0009c0908..db2bf7512 100644 --- a/src/unit_tests/data_export.rs +++ b/src/unit_tests/data_export.rs @@ -54,7 +54,7 @@ fn data_export_with_user() { Profile::default(), LibraryBucket::default(), StreamsBucket::default(), - ServerUrlsBucket::new(None), + ServerUrlsBucket::new::(None), NotificationsBucket::new::(None, vec![]), SearchHistoryBucket::default(), DismissedEventsBucket::default(), @@ -137,7 +137,7 @@ fn data_export_without_a_user() { Profile::default(), LibraryBucket::default(), StreamsBucket::default(), - ServerUrlsBucket::new(None), + ServerUrlsBucket::new::(None), NotificationsBucket::new::(None, vec![]), SearchHistoryBucket::default(), DismissedEventsBucket::default(), diff --git a/src/unit_tests/link.rs b/src/unit_tests/link.rs index c310f751c..3ed909d5f 100644 --- a/src/unit_tests/link.rs +++ b/src/unit_tests/link.rs @@ -62,7 +62,7 @@ fn create_link_code() { Profile::default(), LibraryBucket::default(), StreamsBucket::default(), - ServerUrlsBucket::new(None), + ServerUrlsBucket::new::(None), NotificationsBucket::new::(None, vec![]), SearchHistoryBucket::default(), DismissedEventsBucket::default(), diff --git a/stremio-core-web/src/stremio_core_web.rs b/stremio-core-web/src/stremio_core_web.rs index f0b632195..572ae9ef2 100644 --- a/stremio-core-web/src/stremio_core_web.rs +++ b/stremio-core-web/src/stremio_core_web.rs @@ -95,7 +95,8 @@ pub async fn initialize_runtime(emit_to_ui: js_sys::Function) -> Result<(), JsVa let streams_bucket = streams_bucket.unwrap_or_else(|| StreamsBucket::new(profile.uid())); let server_urls_bucket = - server_urls_bucket.unwrap_or(ServerUrlsBucket::new(profile.uid())); + server_urls_bucket + .unwrap_or(ServerUrlsBucket::new::(profile.uid())); let notifications_bucket = notifications_bucket .unwrap_or(NotificationsBucket::new::(profile.uid(), vec![])); let search_history_bucket = From 3eeca2d2c7211ee9c7130f6126c5e27712a1c482 Mon Sep 17 00:00:00 2001 From: "Timothy Z." Date: Wed, 23 Oct 2024 17:20:41 +0300 Subject: [PATCH 36/44] refactor: delete the max items constrains --- .../ctx/update_streaming_server_urls.rs | 2 +- src/types/server_urls/server_urls_bucket.rs | 39 +---------------- .../ctx/update_streaming_server_urls.rs | 42 ------------------- 3 files changed, 2 insertions(+), 81 deletions(-) diff --git a/src/models/ctx/update_streaming_server_urls.rs b/src/models/ctx/update_streaming_server_urls.rs index 93ebd70b4..677e2a80d 100644 --- a/src/models/ctx/update_streaming_server_urls.rs +++ b/src/models/ctx/update_streaming_server_urls.rs @@ -17,7 +17,7 @@ pub fn update_streaming_server_urls( ) -> Effects { match msg { Msg::Action(Action::Ctx(ActionCtx::AddServerUrl(url))) => { - streaming_server_urls.add_url::(url.clone()); + streaming_server_urls.items.insert(url.clone(), E::now()); Effects::msg(Msg::Internal(Internal::StreamingServerUrlsBucketChanged)) } Msg::Action(Action::Ctx(ActionCtx::DeleteServerUrl(url))) => { diff --git a/src/types/server_urls/server_urls_bucket.rs b/src/types/server_urls/server_urls_bucket.rs index 3d9c0283a..42163138c 100644 --- a/src/types/server_urls/server_urls_bucket.rs +++ b/src/types/server_urls/server_urls_bucket.rs @@ -1,8 +1,4 @@ -use crate::{ - constants::{SERVER_URL_BUCKET_MAX_ITEMS, STREAMING_SERVER_URL}, - runtime::Env, - types::profile::UID, -}; +use crate::{constants::STREAMING_SERVER_URL, runtime::Env, types::profile::UID}; use chrono::{DateTime, Utc}; use serde::{Deserialize, Serialize}; use std::collections::HashMap; @@ -27,39 +23,6 @@ impl ServerUrlsBucket { ServerUrlsBucket { uid, items } } - /// Add a new URL to the bucket. - pub fn add_url(&mut self, url: Url) { - let mtime = E::now(); - self.merge_items(vec![(url, mtime)]); - } - - /// Merge multiple URL items into the bucket. - pub fn merge_items(&mut self, items: Vec<(Url, DateTime)>) { - for (url, mtime) in items.into_iter() { - if let Some(existing_mtime) = self.items.get_mut(&url) { - *existing_mtime = mtime; - } else if self.items.len() < SERVER_URL_BUCKET_MAX_ITEMS { - self.items.insert(url.clone(), mtime); - } else { - let default_url: &Url = &STREAMING_SERVER_URL; - - let oldest_item_option = self - .items - .iter() - .filter(|(item_url, _)| *item_url != default_url) - .min_by_key(|(_, &item_mtime)| item_mtime) - .map(|(item_url, _)| item_url.clone()); - - if let Some(oldest_url) = oldest_item_option { - if mtime > *self.items.get(&oldest_url).unwrap() { - self.items.remove(&oldest_url); - self.items.insert(url.clone(), mtime); - } - } - } - } - } - /// Delete a URL from the bucket. pub fn delete_url(&mut self, url: &Url) { let default_url: &Url = &STREAMING_SERVER_URL; diff --git a/src/unit_tests/ctx/update_streaming_server_urls.rs b/src/unit_tests/ctx/update_streaming_server_urls.rs index c28360155..b6b052d56 100644 --- a/src/unit_tests/ctx/update_streaming_server_urls.rs +++ b/src/unit_tests/ctx/update_streaming_server_urls.rs @@ -13,48 +13,6 @@ use crate::unit_tests::{TestEnv, STORAGE}; use stremio_derive::Model; use url::Url; -#[test] -fn test_add_server_url() { - #[derive(Model, Clone, Default)] - #[model(TestEnv)] - struct TestModel { - ctx: Ctx, - } - let _env_mutex = TestEnv::reset().expect("Should have exclusive lock to TestEnv"); - let ctx = Ctx::new( - Profile::default(), - LibraryBucket::default(), - StreamsBucket::default(), - ServerUrlsBucket::new::(None), - NotificationsBucket::new::(None, vec![]), - SearchHistoryBucket::default(), - DismissedEventsBucket::default(), - ); - let (runtime, _rx) = Runtime::::new(TestModel { ctx }, vec![], 1000); - let new_url = Url::parse("http://localhost:11470").unwrap(); - TestEnv::run(|| { - runtime.dispatch(RuntimeAction { - field: None, - action: Action::Ctx(ActionCtx::AddServerUrl(new_url.clone())), - }) - }); - let server_urls = &runtime.model().unwrap().ctx.streaming_server_urls; - assert!( - server_urls.items.contains_key(&new_url), - "New server URL should be added" - ); - assert!( - STORAGE - .read() - .unwrap() - .get(STREAMING_SERVER_URLS_STORAGE_KEY) - .map_or(false, |data| { - let stored_bucket: ServerUrlsBucket = serde_json::from_str(data).unwrap(); - stored_bucket.items.contains_key(&new_url) - }), - "New server URL should be stored" - ); -} #[test] fn test_delete_server_url() { #[derive(Model, Clone, Default)] From 5ab960d7b4aa7ec84e4fd4508327f4900d0dabe8 Mon Sep 17 00:00:00 2001 From: "Timothy Z." Date: Wed, 23 Oct 2024 17:28:29 +0300 Subject: [PATCH 37/44] feat: add add_url function --- src/models/ctx/update_streaming_server_urls.rs | 2 +- src/types/server_urls/server_urls_bucket.rs | 6 ++++++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/src/models/ctx/update_streaming_server_urls.rs b/src/models/ctx/update_streaming_server_urls.rs index 677e2a80d..93ebd70b4 100644 --- a/src/models/ctx/update_streaming_server_urls.rs +++ b/src/models/ctx/update_streaming_server_urls.rs @@ -17,7 +17,7 @@ pub fn update_streaming_server_urls( ) -> Effects { match msg { Msg::Action(Action::Ctx(ActionCtx::AddServerUrl(url))) => { - streaming_server_urls.items.insert(url.clone(), E::now()); + streaming_server_urls.add_url::(url.clone()); Effects::msg(Msg::Internal(Internal::StreamingServerUrlsBucketChanged)) } Msg::Action(Action::Ctx(ActionCtx::DeleteServerUrl(url))) => { diff --git a/src/types/server_urls/server_urls_bucket.rs b/src/types/server_urls/server_urls_bucket.rs index 42163138c..2a5ed007f 100644 --- a/src/types/server_urls/server_urls_bucket.rs +++ b/src/types/server_urls/server_urls_bucket.rs @@ -23,6 +23,12 @@ impl ServerUrlsBucket { ServerUrlsBucket { uid, items } } + /// Add a URL to the bucket. + pub fn add_url(&mut self, url: Url) { + let mtime = E::now(); + self.items.insert(url, mtime); + } + /// Delete a URL from the bucket. pub fn delete_url(&mut self, url: &Url) { let default_url: &Url = &STREAMING_SERVER_URL; From 463ba076ac739b10f8119d78c672f387bf57489a Mon Sep 17 00:00:00 2001 From: "Timothy Z." Date: Wed, 23 Oct 2024 17:32:05 +0300 Subject: [PATCH 38/44] add: tests for add_url --- src/types/server_urls/server_urls_bucket.rs | 2 +- .../ctx/update_streaming_server_urls.rs | 43 +++++++++++++++++++ 2 files changed, 44 insertions(+), 1 deletion(-) diff --git a/src/types/server_urls/server_urls_bucket.rs b/src/types/server_urls/server_urls_bucket.rs index 2a5ed007f..7f7862ff3 100644 --- a/src/types/server_urls/server_urls_bucket.rs +++ b/src/types/server_urls/server_urls_bucket.rs @@ -24,7 +24,7 @@ impl ServerUrlsBucket { } /// Add a URL to the bucket. - pub fn add_url(&mut self, url: Url) { + pub fn add_url(&mut self, url: Url) { let mtime = E::now(); self.items.insert(url, mtime); } diff --git a/src/unit_tests/ctx/update_streaming_server_urls.rs b/src/unit_tests/ctx/update_streaming_server_urls.rs index b6b052d56..05467a732 100644 --- a/src/unit_tests/ctx/update_streaming_server_urls.rs +++ b/src/unit_tests/ctx/update_streaming_server_urls.rs @@ -13,6 +13,49 @@ use crate::unit_tests::{TestEnv, STORAGE}; use stremio_derive::Model; use url::Url; +#[test] +fn test_add_server_url() { + #[derive(Model, Clone, Default)] + #[model(TestEnv)] + struct TestModel { + ctx: Ctx, + } + let _env_mutex = TestEnv::reset().expect("Should have exclusive lock to TestEnv"); + let ctx = Ctx::new( + Profile::default(), + LibraryBucket::default(), + StreamsBucket::default(), + ServerUrlsBucket::new::(None), + NotificationsBucket::new::(None, vec![]), + SearchHistoryBucket::default(), + DismissedEventsBucket::default(), + ); + let (runtime, _rx) = Runtime::::new(TestModel { ctx }, vec![], 1000); + let new_url = Url::parse("http://localhost:11470").unwrap(); + TestEnv::run(|| { + runtime.dispatch(RuntimeAction { + field: None, + action: Action::Ctx(ActionCtx::AddServerUrl(new_url.clone())), + }) + }); + let server_urls = &runtime.model().unwrap().ctx.streaming_server_urls; + assert!( + server_urls.items.contains_key(&new_url), + "New server URL should be added" + ); + assert!( + STORAGE + .read() + .unwrap() + .get(STREAMING_SERVER_URLS_STORAGE_KEY) + .map_or(false, |data| { + let stored_bucket: ServerUrlsBucket = serde_json::from_str(data).unwrap(); + stored_bucket.items.contains_key(&new_url) + }), + "New server URL should be stored" + ); +} + #[test] fn test_delete_server_url() { #[derive(Model, Clone, Default)] From 2b8c6ae41c6a2d8ad05205a479f86e6856254d42 Mon Sep 17 00:00:00 2001 From: "Timothy Z." Date: Thu, 24 Oct 2024 10:41:33 +0300 Subject: [PATCH 39/44] refactor: address comments --- src/models/ctx/update_streaming_server_urls.rs | 6 +++--- stremio-core-web/src/model/serialize_ctx.rs | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/models/ctx/update_streaming_server_urls.rs b/src/models/ctx/update_streaming_server_urls.rs index 93ebd70b4..2f5c0a6d2 100644 --- a/src/models/ctx/update_streaming_server_urls.rs +++ b/src/models/ctx/update_streaming_server_urls.rs @@ -1,12 +1,12 @@ +use futures::FutureExt; + use crate::constants::STREAMING_SERVER_URLS_STORAGE_KEY; use crate::runtime::msg::{Action, ActionCtx, CtxAuthResponse}; -use crate::runtime::EnvFutureExt; use crate::runtime::{ msg::{Event, Internal, Msg}, - Effect, EffectFuture, Effects, Env, + Effect, EffectFuture, Effects, Env, EnvFutureExt, }; use crate::types::server_urls::ServerUrlsBucket; -use futures::FutureExt; use super::{CtxError, CtxStatus}; diff --git a/stremio-core-web/src/model/serialize_ctx.rs b/stremio-core-web/src/model/serialize_ctx.rs index 061de2841..5bec500ab 100644 --- a/stremio-core-web/src/model/serialize_ctx.rs +++ b/stremio-core-web/src/model/serialize_ctx.rs @@ -19,6 +19,7 @@ mod model { use stremio_core::types::{ events::Events, notifications::NotificationItem, profile::Profile, resource::MetaItemId, }; + use url::Url; use crate::model::deep_links_ext::DeepLinksExt; @@ -36,8 +37,7 @@ mod model { #[derive(Serialize)] #[serde(rename_all = "camelCase")] pub struct StreamingServerUrlItem { - pub url: String, - #[serde(rename = "_mtime")] + pub url: Url, pub mtime: DateTime, } @@ -89,7 +89,7 @@ mod model { .items .iter() .map(|(url, mtime)| StreamingServerUrlItem { - url: url.to_string(), + url: url.clone(), mtime: *mtime, }) .collect(), From 923c51d6c11a52e247c37b2d0983b25f62e1dc16 Mon Sep 17 00:00:00 2001 From: "Timothy Z." Date: Thu, 24 Oct 2024 13:57:28 +0300 Subject: [PATCH 40/44] refactor: add sorting in serialization --- stremio-core-web/src/model/serialize_ctx.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/stremio-core-web/src/model/serialize_ctx.rs b/stremio-core-web/src/model/serialize_ctx.rs index 5bec500ab..f01dde58e 100644 --- a/stremio-core-web/src/model/serialize_ctx.rs +++ b/stremio-core-web/src/model/serialize_ctx.rs @@ -92,6 +92,7 @@ mod model { url: url.clone(), mtime: *mtime, }) + .sorted_by(|a, b| Ord::cmp(&a.mtime, &b.mtime)) .collect(), } } From 5dc65a9f8ab1e2cdb55ef58f09fd0fd9396fe6dd Mon Sep 17 00:00:00 2001 From: "Timothy Z." Date: Mon, 28 Oct 2024 14:22:44 +0200 Subject: [PATCH 41/44] remove: unnecessary const --- src/constants.rs | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/constants.rs b/src/constants.rs index 557a7037d..e1bec70bb 100644 --- a/src/constants.rs +++ b/src/constants.rs @@ -30,8 +30,6 @@ pub const CATALOG_PREVIEW_SIZE: usize = 100; pub const LIBRARY_RECENT_COUNT: usize = 200; pub const NOTIFICATION_ITEMS_COUNT: usize = 100; -pub const SERVER_URL_BUCKET_MAX_ITEMS: usize = 5; - /// A `LibraryItem` is considered watched once we've watched more than the `duration * threshold`: /// /// `LibraryItem.state.time_watched` > `LibraryItem.state.duration` * [`WATCHED_THRESHOLD_COEF`] From 8ee6557465afb5376f384b5e1f8b4630af5b9758 Mon Sep 17 00:00:00 2001 From: "Timothy Z." Date: Thu, 14 Nov 2024 12:34:09 +0200 Subject: [PATCH 42/44] refactor: docs in server_urls_bucket.rs Co-authored-by: Lachezar Lechev <8925621+elpiel@users.noreply.github.com> --- src/types/server_urls/server_urls_bucket.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/types/server_urls/server_urls_bucket.rs b/src/types/server_urls/server_urls_bucket.rs index 7f7862ff3..a9426bd8a 100644 --- a/src/types/server_urls/server_urls_bucket.rs +++ b/src/types/server_urls/server_urls_bucket.rs @@ -8,7 +8,7 @@ use url::Url; pub struct ServerUrlsBucket { /// User ID pub uid: UID, - /// HashMap where key is `Url`, value is `DateTime` + /// A map of the the server Url as a key and the modified/added datetime of that particular url. pub items: HashMap>, } From 7cb5664177bddd2c20ef6e8c040f7bf4e12aa7f7 Mon Sep 17 00:00:00 2001 From: "Timothy Z." Date: Thu, 14 Nov 2024 13:44:47 +0200 Subject: [PATCH 43/44] chore: cargo fmt --- stremio-core-web/src/model/model.rs | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/stremio-core-web/src/model/model.rs b/stremio-core-web/src/model/model.rs index 9e70ca4e3..02ad7fa6d 100644 --- a/stremio-core-web/src/model/model.rs +++ b/stremio-core-web/src/model/model.rs @@ -25,10 +25,9 @@ use stremio_core::{ }, runtime::Effects, types::{ - addon::Descriptor, api::LinkAuthKey, events::DismissedEventsBucket, - library::LibraryBucket, notifications::NotificationsBucket, profile::Profile, - resource::MetaItemPreview, search_history::SearchHistoryBucket, - server_urls::ServerUrlsBucket, streams::StreamsBucket, + addon::Descriptor, api::LinkAuthKey, events::DismissedEventsBucket, library::LibraryBucket, + notifications::NotificationsBucket, profile::Profile, resource::MetaItemPreview, + search_history::SearchHistoryBucket, server_urls::ServerUrlsBucket, streams::StreamsBucket, }, Model, }; From 44c23a71a261db5ee48e73607f799f7569fcc776 Mon Sep 17 00:00:00 2001 From: "Timothy Z." Date: Tue, 26 Nov 2024 23:09:49 +0200 Subject: [PATCH 44/44] fix: base_url stremio-video support --- src/models/streaming_server.rs | 3 ++- stremio-core-web/src/model/serialize_streaming_server.rs | 2 ++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/src/models/streaming_server.rs b/src/models/streaming_server.rs index fbc8c5a07..5dc04be84 100644 --- a/src/models/streaming_server.rs +++ b/src/models/streaming_server.rs @@ -249,7 +249,8 @@ impl UpdateWithCtx for StreamingServer { &mut self.settings, Loadable::Ready(settings.values.to_owned()), ); - let base_url_effects = eq_update(&mut self.base_url, Some(url.to_owned())); + let base_url_effects = + eq_update(&mut self.base_url, Some(settings.base_url.to_owned())); let remote_url_effects = update_remote_url::( &mut self.remote_url, &self.selected, diff --git a/stremio-core-web/src/model/serialize_streaming_server.rs b/stremio-core-web/src/model/serialize_streaming_server.rs index 0753c4ca7..1b64d77ad 100644 --- a/stremio-core-web/src/model/serialize_streaming_server.rs +++ b/stremio-core-web/src/model/serialize_streaming_server.rs @@ -21,6 +21,7 @@ mod model { pub struct StreamingServer<'a> { pub selected: &'a Selected, pub settings: &'a Loadable, + pub base_url: &'a Option, pub remote_url: &'a Option, pub playback_devices: &'a Loadable, EnvError>, pub network_info: &'a Loadable, @@ -38,6 +39,7 @@ pub fn serialize_streaming_server( ::from_serde(&model::StreamingServer { selected: &streaming_server.selected, settings: &streaming_server.settings, + base_url: &streaming_server.base_url, remote_url: &streaming_server.remote_url, playback_devices: &streaming_server.playback_devices, network_info: &streaming_server.network_info,