Feat: Add auto rotation setting for PWA to local storage
Description
Adds auto_rotate_player boolean setting to control screen rotation behavior in the Stremio PWA.
Changes
- Added
auto_rotate_playerfield toSettingsstruct with default valuetrue - Implemented schema migration v19 → v20 to add setting to existing user profiles
- Updated serialization tests in
default_tokens_ext.rsandsettings.rs - All changes maintain backward compatibility
Testing
- ✅ All 191 unit tests pass
- ✅ All 15 doc tests pass
- ✅ Schema migration tested (v19 → v20)
- ✅ Code compiles successfully
Implementation Notes
This PR implements the backend portion of the rotation control feature. The setting:
- Defaults to
true(maintains current auto-rotate behavior) - Is stored in user profile settings
- Will be consumed by stremio-web to control the Screen Orientation API
Frontend implementation in stremio-web will follow to:
- Read
profile.settings.autoRotatePlayer - Call
screen.orientation.lock('landscape')whentrue - Call
screen.orientation.unlock()whenfalse
Related Issues
Part 1 of Stremio/stremio-web/issues/787
hi there, thanks for the PR
you will need to make some changes for the builds to pass
run cargo fmt and then run cargo clippy and commit the lint changes
thank you
PS: you could rename the field to something like: pwa_auto_rotation since this will apply for the whole app not only the player
cargo fmt
Warning: can't set format_code_in_doc_comments = true, unstable features are only available in nightly channel.
Warning: can't set format_code_in_doc_comments = true, unstable features are only available in nightly channel.
Warning: can't set format_code_in_doc_comments = true, unstable features are only available in nightly channel.
Warning: can't set format_code_in_doc_comments = true, unstable features are only available in nightly channel.
cargo clippy
Checking stremio-core v0.1.0 (/workspaces/stremio-core) Finished dev [unoptimized + debuginfo] target(s) in 5.32s
cargo test
Compiling stremio-core v0.1.0 (/workspaces/stremio-core) Finished test [unoptimized + debuginfo] target(s) in 11.16s Running unittests src/lib.rs (target/debug/deps/stremio_core-d61412ff8a264f7d)
running 191 tests test addon_transport::http_transport::legacy::test::query_meta ... ok test addon_transport::http_transport::legacy::test::query_stream ... ok test addon_transport::http_transport::legacy::test::catalog ... ok test addon_transport::http_transport::legacy::test::stream_imdb ... ok test addon_transport::http_transport::legacy::test::subtitles_only_id ... ok test addon_transport::http_transport::legacy::test::subtitles_with_hash ... ok test deep_links::error_link::tests::error_link ... ok test models::addon_details::test::test_deserialization_of_select ... ok test models::library_with_filters::test::test_watched_and_not_watched_sort_items_ordering_of_library_items ... ok test models::local_search::test::test_imdb_rating_parsing ... ok test models::player::tests::test_underflow_calculate_outro ... ok test models::local_search::test::test_deserialization_of_searchable ... ok test runtime::effects::test::test_effects_defaults ... ok test runtime::env::test::test_migration_from_10_to_11 ... ok test runtime::env::test::test_migration_from_11_to_12 ... ok test runtime::env::test::test_migration_from_12_to_13 ... ok test runtime::env::test::test_migration_from_13_to_14 ... ok test runtime::env::test::test_migration_from_15_to_16 ... ok test runtime::env::test::test_migration_from_14_to_15 ... ok test runtime::env::test::test_migration_from_16_to_17 ... ok test runtime::env::test::test_migration_from_17_to_18 ... ok test runtime::env::test::test_migration_from_18_to_19 ... ok test runtime::env::test::test_migration_from_6_to_7 ... ok test runtime::env::test::test_migration_from_7_to_8 ... ok test runtime::env::test::test_migration_from_8_to_9 ... ok test runtime::env::test::test_migration_from_5_to_6 ... ok test runtime::env::test::test_migration_from_9_to_10 ... ok test types::api::request::tests::test_versioning_of_api_fetch_request_params ... ok test types::addon::response::tests::test_response_deserialization_keys ... ok test runtime::env::test::test_migration_to_latest_version ... ok test types::api::response::test::deserialization_of_api_response_with_path_and_without ... ok test types::api::response::test::deserialize_skip_gaps_response ... ok test types::serde_as_ext::tests::test_bool_as_option ... ok test types::resource::stream::tests::test_stream_url_source_with_proxy_headers_to_streaming_url ... ok test types::serde_ext::empty_string_as_null::test::test_empty_field ... ok test types::serde_ext::empty_string_as_null::test::test_field ... ok test types::torrent::tests::test_info_has_for_zero_sized_chunk ... ok test types::streaming_server::response::test::test_server_settings_response_deserialization ... ok test unit_tests::calendar::load_action::calendar ... ok test unit_tests::catalog_with_filters::load_action::default_catalog ... ok test unit_tests::catalog_with_filters::load_action::search_catalog ... ok test unit_tests::ctx::add_to_library::actionctx_addtolibrary ... ok test unit_tests::ctx::add_to_library::actionctx_addtolibrary_already_added ... ok test unit_tests::ctx::authenticate::actionctx_authenticate_apple ... ok test unit_tests::ctx::authenticate::actionctx_authenticate_facebook ... ok test unit_tests::ctx::authenticate::actionctx_authenticate_login ... ok test unit_tests::ctx::authenticate::actionctx_authenticate_login_with_token ... ok test unit_tests::ctx::authenticate::actionctx_authenticate_register ... ok test unit_tests::ctx::delete_account::actionctx_delete_account ... ok test unit_tests::ctx::install_addon::actionctx_installaddon_already_installed ... ok test unit_tests::ctx::install_addon::actionctx_installaddon_install ... ok test unit_tests::ctx::install_addon::actionctx_installaddon_install_with_user ... ok test unit_tests::ctx::install_addon::actionctx_installaddon_update ... ok test unit_tests::ctx::logout::actionctx_logout ... ok test unit_tests::ctx::notifications::update_notifications::test_dismiss_notification ... ok test unit_tests::ctx::notifications::update_notifications::test_pull_notifications_and_play_in_player ... ok test unit_tests::ctx::notifications::update_notifications::test_pull_notifications_test_cases ... ok test unit_tests::ctx::pull_addons_from_api::actionctx_pulladdonsfromapi ... ok test unit_tests::ctx::pull_addons_from_api::actionctx_pulladdonsfromapi_with_user ... ok test unit_tests::ctx::push_addons_to_api::actionctx_pushaddonstoapi ... ok test unit_tests::ctx::push_addons_to_api::actionctx_pushaddonstoapi_with_user ... ok test unit_tests::ctx::remove_from_library::actionctx_removefromlibrary ... ok test unit_tests::ctx::remove_from_library::actionctx_removefromlibrary_not_added ... ok test unit_tests::ctx::rewind_library_item::actionctx_rewindlibraryitem ... ok test unit_tests::ctx::rewind_library_item::actionctx_rewindlibraryitem_not_added ... ok test unit_tests::ctx::sync_library_with_api::actionctx_synclibrarywithapi_with_user_empty_library ... ok test unit_tests::ctx::uninstall_addon::actionctx_uninstalladdon ... ok test models::streaming_server::tests::test_magnet_hash ... ok test unit_tests::ctx::sync_library_with_api::actionctx_synclibrarywithapi_with_user ... ok test unit_tests::ctx::sync_library_with_api::actionctx_synclibrarywithapi ... ok test unit_tests::ctx::uninstall_addon::actionctx_uninstalladdon_not_installed ... ok test unit_tests::ctx::uninstall_addon::actionctx_uninstalladdon_protected ... ok test unit_tests::ctx::uninstall_addon::actionctx_uninstalladdon_streams_bucket ... ok test unit_tests::ctx::uninstall_addon::actionctx_uninstalladdon_with_user ... ok test unit_tests::ctx::update_events::test_dismissed_events ... ok test unit_tests::ctx::update_events::test_events ... ok test unit_tests::ctx::update_events::test_stored_dismissed_events ... ok test unit_tests::ctx::update_search_history::test_search_history_clear_items ... ok test unit_tests::ctx::update_search_history::test_search_history_update ... ok test unit_tests::ctx::update_settings::actionctx_updatesettings ... ok test unit_tests::ctx::update_settings::actionctx_updatesettings_not_changed ... ok test unit_tests::ctx::update_streaming_server_urls::test_add_server_url ... ok test unit_tests::ctx::update_streaming_server_urls::test_delete_server_url ... ok test unit_tests::ctx::upgrade_addon::actionctx_addon_upgrade ... ok test unit_tests::deep_links::addons_deep_links::addons_deep_links_installed_addons_request_no_type ... ok test unit_tests::deep_links::addons_deep_links::addons_deep_links_installed_addons_request_type ... ok test unit_tests::ctx::upgrade_addon::actionctx_addon_upgrade_fail_due_to_different_url ... ok test unit_tests::deep_links::addons_deep_links::addons_deep_links_request ... ok test unit_tests::deep_links::discover_deep_links::discover_deep_links ... ok test unit_tests::data_export::data_export_with_user ... ok test unit_tests::deep_links::external_player_link::external_player_link_external ... ok test unit_tests::data_export::data_export_without_a_user ... ok test unit_tests::deep_links::external_player_link::external_player_link_http ... ok test unit_tests::deep_links::external_player_link::external_player_link_player_frame ... ok test unit_tests::deep_links::external_player_link::external_player_link_torrent ... ok test unit_tests::deep_links::external_player_link::external_player_link_with_infuse ... ok test unit_tests::deep_links::external_player_link::external_player_link_with_justplayer ... ok test unit_tests::deep_links::external_player_link::external_player_link_with_outplayer ... ok test unit_tests::deep_links::external_player_link::external_player_link_with_mxplayer ... ok test unit_tests::deep_links::library_deep_links::library_deep_links_request_no_type ... ok test unit_tests::deep_links::external_player_link::external_player_link_magnet ... ok test unit_tests::deep_links::library_deep_links::library_deep_links_request_type ... ok test unit_tests::deep_links::library_deep_links::library_deep_links_string ... ok test unit_tests::deep_links::external_player_link::external_player_link_with_vlc_player ... ok test unit_tests::deep_links::external_player_link::external_player_link_youtube ... ok test unit_tests::deep_links::library_item_deep_links::library_item_deep_links_no_video ... ok test unit_tests::deep_links::library_item_deep_links::library_item_deep_links_behavior_hints_default_video_id ... ok test unit_tests::deep_links::library_item_deep_links::library_item_deep_links_state_and_behavior_hints_default_video_id ... ok test unit_tests::deep_links::library_item_deep_links::library_item_deep_links_state_no_time_offset_and_behavior_hints_default_video_id ... ok test unit_tests::deep_links::meta_item_deep_links::meta_item_deep_links ... ok test unit_tests::deep_links::meta_item_deep_links::meta_item_deep_links_behavior_hints ... ok test unit_tests::deep_links::search_history_item_deep_links::search_history_item_deep_links ... ok test unit_tests::deep_links::library_item_deep_links::library_item_deep_links_state_video_id_no_time_offset_infuse_player ... ok test unit_tests::deep_links::library_item_deep_links::library_item_deep_links_state_video_id ... ok test unit_tests::deep_links::stream_deep_links::stream_deep_links_external ... ok test unit_tests::deep_links::stream_deep_links::stream_deep_links_http ... ok test unit_tests::deep_links::meta_item_deep_links::meta_item_deep_links_behavior_hints_yt_id ... ok test unit_tests::deep_links::stream_deep_links::stream_deep_links_http_with_request_headers ... ok test unit_tests::deep_links::stream_deep_links::stream_deep_links_http_with_request_response_headers_and_query_params ... ok test unit_tests::deep_links::stream_deep_links::stream_deep_links_player_frame ... ok test unit_tests::deep_links::stream_deep_links::stream_deep_links_requests ... ok test unit_tests::deep_links::stream_deep_links::stream_deep_links_magnet ... ok test unit_tests::deep_links::stream_deep_links::stream_deep_links_torrent ... ok test unit_tests::deep_links::stream_deep_links::stream_deep_links_torrent_without_file_index ... ok test unit_tests::deep_links::stream_deep_links::stream_deep_links_youtube ... ok test unit_tests::link::create_link_code ... ok test unit_tests::meta_details::override_selected::override_selected_default_video_id ... ok test unit_tests::deep_links::video_deep_links::video_deep_links ... ok test unit_tests::serde::api_error::api_error ... ok test unit_tests::serde::api_result::api_result ... ok test unit_tests::serde::api_request::api_request ... ok test unit_tests::serde::auth_key::auth_key ... ok test unit_tests::serde::auth::auth ... ok test unit_tests::serde::auth_request::auth_request ... ok test unit_tests::serde::auth_response::auth_response ... ok test unit_tests::meta_details::override_selected::override_selected_meta_id ... ok test unit_tests::serde::collection_response::cft_test::collection_response ... ok test unit_tests::serde::datastore_command::datastore_command ... ok test unit_tests::serde::datastore_request::datastore_request ... ok test unit_tests::serde::descriptor_flags::descriptor_flags ... ok test unit_tests::serde::extra_prop::extra_prop ... ok test unit_tests::serde::descriptor_preview::descriptor_preview ... ok test unit_tests::serde::extra_value::extra_value ... ok test unit_tests::serde::descriptor::descriptor ... ok test unit_tests::serde::gdpr_consent::gdpr_consent ... ok test unit_tests::serde::library_bucket::library_bucket ... ok test unit_tests::serde::library_bucket_ref::library_bucket_ref ... ok test unit_tests::serde::library_item_modified::library_item_modified ... ok test unit_tests::serde::link::link ... ok test unit_tests::serde::library_item::library_item ... ok test unit_tests::serde::link_code_response::link_code_response ... ok test unit_tests::serde::link_data_response::link_data_response ... ok test unit_tests::player::next_stream::next_stream ... ok test unit_tests::serde::manifest_behavior_hints::manifest_behavior_hints ... ok test unit_tests::serde::manifest::manifest ... ok test unit_tests::serde::manifest_catalog::manifest_catalog ... ok test unit_tests::serde::manifest_extra::manifest_extra ... ok test unit_tests::serde::manifest_resource::manifest_resource ... ok test unit_tests::serde::manifest_preview::manifest_preview ... ok test unit_tests::serde::meta_item::meta_item_de_urls_none_when_empty ... ok test unit_tests::serde::meta_item_behavior_hints::meta_item_behavior_hints ... ok test unit_tests::serde::library_item_state::library_item_state ... ok test unit_tests::serde::meta_item::meta_item ... ok test unit_tests::serde::meta_item_preview::meta_item_preview_de ... ok test unit_tests::serde::meta_item_preview::meta_item_preview_de_null ... ok test unit_tests::serde::meta_item_preview::meta_item_preview_de_minimal ... ok test unit_tests::serde::meta_item_preview::meta_item_preview_de_ignore_legacy_when_links ... ok test unit_tests::serde::meta_item_preview::meta_item_preview_de_numeric_imdb ... ok test unit_tests::serde::meta_item_preview::meta_item_preview_serialize ... ok test unit_tests::serde::poster_shape::poster_shape ... ok test unit_tests::serde::meta_item_preview::meta_item_preview_de_legacy_links ... ok test unit_tests::serde::r#true::r#true ... ok test unit_tests::serde::resource_path::resource_path ... ok test unit_tests::serde::resource_request::resource_request ... ok test unit_tests::serde::series_info::series_info ... ok test unit_tests::serde::profile::profile ... ok test unit_tests::serde::resource_response::resource_response ... ok test unit_tests::serde::settings::settings_de ... ok test unit_tests::serde::settings::settings ... ok test unit_tests::serde::stream::stream ... ok test unit_tests::serde::stream_source::stream_source_from_json ... ok test unit_tests::serde::subtitles::subtitles ... ok test unit_tests::serde::success_response::success_response ... ok test unit_tests::serde::stream_source::stream_source ... ok test unit_tests::serde::user::user ... ok test unit_tests::serde::video::various_videos_deserialization ... ok test unit_tests::serde::video::videos_minimal ... ok test unit_tests::serde::video::video ... ok test unit_tests::serde::video::videos_released_equal ... ok test unit_tests::serde::video::videos_released_sequal ... ok test unit_tests::streaming_server::remote_endpoint::remote_endpoint ... ok
test result: ok. 191 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.07s
Doc-tests stremio-core
running 15 tests test src/models/common/compare_with_priorities.rs - models::common::compare_with_priorities::compare_with_priorities (line 10) ... ok test src/runtime/effects.rs - runtime::effects::Effects (line 21) ... ok test src/types/addon/manifest.rs - types::addon::manifest::Manifest::resources (line 49) ... ok test src/types/addon/manifest.rs - types::addon::manifest::Manifest::resources (line 65) ... ok test src/types/addon/manifest.rs - types::addon::manifest::ManifestResource (line 192) ... ok test src/runtime/msg/action.rs - runtime::msg::action::ActionCtx::PullUserFromAPI (line 60) ... ok test src/types/addon/response.rs - types::addon::response::ResourceResponse::Metas (line 93) ... ok test src/types/resource/meta_item.rs - types::resource::meta_item::MetaItemPreview (line 107) ... ok test src/types/resource/stream.rs - types::resource::stream::Stream (line 24) ... ok test src/types/addon/response.rs - types::addon::response::ResourceResponseCache (line 26) ... ok test src/types/resource/stream.rs - types::resource::stream::StreamSource (line 316) ... ok test src/types/resource/stream.rs - types::resource::stream::StreamSource (line 372) ... ok test src/types/serde_as_ext.rs - types::serde_as_ext::DefaultOnBool (line 132) ... ok test src/types/torrent.rs - types::torrent::InfoHash (line 9) ... ok test src/types/streaming_server/mod.rs - types::streaming_server::CreatedTorrent (line 28) ... ok
test result: ok. 15 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 6.96s
cargo fmt -- --check
Warning: can't set format_code_in_doc_comments = true, unstable features are only available in nightly channel.
Warning: can't set format_code_in_doc_comments = true, unstable features are only available in nightly channel.
Warning: can't set format_code_in_doc_comments = true, unstable features are only available in nightly channel.
Warning: can't set format_code_in_doc_comments = true, unstable features are only available in nightly channel.
cargo check --all
Compiling stremio-derive v0.1.0 (/workspaces/stremio-core/stremio-derive) Checking stremio-watched-bitfield v0.1.0 (/workspaces/stremio-core/stremio-watched-bitfield) Checking stremio-core v0.1.0 (/workspaces/stremio-core) Checking stremio-core-web v0.49.4 (/workspaces/stremio-core/stremio-core-web) Finished dev [unoptimized + debuginfo] target(s) in 7.10s
cargo clippy --all --no-deps
Compiling stremio-derive v0.1.0 (/workspaces/stremio-core/stremio-derive) Checking stremio-watched-bitfield v0.1.0 (/workspaces/stremio-core/stremio-watched-bitfield) Checking stremio-core v0.1.0 (/workspaces/stremio-core) Checking stremio-core-web v0.49.4 (/workspaces/stremio-core/stremio-core-web) Finished dev [unoptimized + debuginfo] target(s) in 7.08s
hi there, thanks for the PR you will need to make some changes for the builds to pass run
cargo fmtand then runcargo clippyand commit the lint changesthank you
PS: you could rename the field to something like:
pwa_auto_rotationsince this will apply for the whole app not only the player
Thanks for your guidance. I had Rust v1.90 installed in the system during the previous PR. After downgrading to v1.77 all checks seemingly passed this time. I have added the output for your perusal.
I have also changed field name as you suggested.