Skip to content

Setup compose multiplatform and migrate first screen to it#2829

Open
Luna712 wants to merge 1 commit into
recloudstream:masterfrom
Luna712:compose
Open

Setup compose multiplatform and migrate first screen to it#2829
Luna712 wants to merge 1 commit into
recloudstream:masterfrom
Luna712:compose

Conversation

@Luna712
Copy link
Copy Markdown
Contributor

@Luna712 Luna712 commented May 23, 2026

I explained most in code comments the best I could as well. Icons are automatically generated from https://fonts.google.com/icons which provides automatically generated code for Compose as well. In the future most icons will use this if a relevant one is found, otherwise we can use SVG icons. Compose multiplatform also supports android XML versions in a KMP context, but I actually found this to be very inconsistent and we shouldn't use that directly if we can avoid it.

I am also going to go through a lot of other changes here and some reasoning as well:

This adds reusable components that will be useful elsewhere as well:

  • .cloudStreamRipple: replacement for selectableItemBackground
  • .tvFocusable: handle manual focus for TV to ensure it is correctly following it and handles the border outline for it also, will probably need improved/changed more later though as we need different versions for it in some places
  • ProfilePicture: to reuse in all the different profile picture containers, accepts parameters where things will need to be different later
  • SettingsItem: Used for all settings category headers for now, will later also be used in all settings subpages for consistency and avoid code duplication. This may need some changes later though also

This handles Monet/Material You differently. This is a dynamic color scheme only available on Android, therefore to define it it uses expect/actual declarations. Other platforms do have their own concept of dynamic themes though, so in the commonMain API it just uses the DYNAMIC terminology for better support for these later on and a more consistent cross platform API. This applies to both the theme and primary colors for it.

Since things are not XML based (and when we do use XML based stuff like strings in composeResources, there is still no @string/ usage), this also adds new PreferenceKeys and PreferenceDefaults objects with constants for preferences. PreferenceKeys will replace all the string keys values in the current donottranslate-strings.xml and PreferenceDefaults will just include the default values for the preferences. Both are there to ensure consistency (not different defaults in different places) and to avoid accidental typos or something. For now it keeps what is added there only to what we actually use in composeApp as more are needed there these will be populated more as well.

For now, this also duplicates the default profile background images to composeResources so we can use them in :composeApp directly as well.

This also avoids refactoring to much of the app intentionally like removing/moving the companion object from the old SettingsFragment to avoid this PR growing massively. This adds a KMP version for device layout detection though as I needed to get if its a TV in :composeApp.

Eventually we will have to split :app into :androidApp which just includes the signing stuff and entry points (AndroidManifest.xml, MainActivity (but a much slimmer version) and CloudStreamApp and other entry points like services (things defined in AndroidManifest).

AGP 9 prevents the ability to have both com.android.application and com.android.kotlin.multiplatform.library at the same time, which means android entry points/APK generation can't be in a KMP module. :app will slowly be drained into fully KMP APIs into :composeApp. Stuff in there should not be stuff extensions will typically need though, otherwise it should go in :library instead.

Also, it is not immediately necessarily, but eventually we should also add the composeResources directory to weblate. This also sets up the locales python script to support that directory if and/or when we add it.

Happy to make any changes necessary though.

I explained most in code comments the best I could as well. Icons are automatically generated from https://fonts.google.com/icons which provides automatically generated code for Compose as well. In the future most icons will use this if a relevant one is found, otherwise we can use SVG icons. Compose multiplatform also supports android XML versions in a KMP context, but I actually found this to be very inconsistent and we shouldn't use that directly if we can avoid it.

I am also going to go through a lot of other changes here and some reasoning as well:

This adds reusable components that will be useful elsewhere as well:
* `.cloudStreamRipple`: replacement for `selectableItemBackground`
* `.tvFocusable`: handle manual focus for TV to ensure it is correctly following it and handles the border outline for it also, will probably need improved/changed more later though as we need different versions for it in some places
* ProfilePicture: to reuse in all the different profile picture containers, accepts parameters where things will need to be different later
* SettingsItem: Used for all settings category headers for now, will later also be used in all settings subpages for consistency and avoid code duplication. This may need some changes later though also

This handles Monet/Material You differently. This is a dynamic color scheme only available on Android, therefore to define it it uses expect/actual declarations. Other platforms do have their own concept of dynamic themes though, so in the commonMain API it  just uses the `DYNAMIC` terminology for better support for these later on and a more consistent cross platform API. This applies to both the theme and primary colors for it.

Since things are not XML based (and when we do use XML based stuff like strings in composeResources, there is still no `@string/` usage), this also adds new `PreferenceKeys` and `PreferenceDefaults` objects with constants for preferences. `PreferenceKeys` will replace all the string keys values in the current `donottranslate-strings.xml` and `PreferenceDefaults` will just include the default values for the preferences. Both are there to ensure consistency (not different defaults in different places) and to avoid accidental typos or something. For now it keeps what is added there only to what we actually use in `composeApp` as more are needed there these will be populated more as well.

For now, this also duplicates the default profile background images to `composeResources` so we can use them in `:composeApp` directly as well.

This also avoids refactoring to much of the app intentionally like removing/moving the companion object from the old SettingsFragment to avoid this PR growing massively. This adds a KMP version for device layout detection though as I needed to get if its a TV in `:composeApp`. 

Eventually we will have to split `:app` into `:androidApp` which just includes the signing stuff and entry points (AndroidManifest.xml, MainActivity (but a much slimmer version) and CloudStreamApp and other entry points like services (things defined in AndroidManifest).

AGP 9 prevents the ability to have both `com.android.application`  and `com.android.kotlin.multiplatform.library` at the same time, which means android entry points/APK generation can't be in a KMP module. `:app` will slowly be drained into fully KMP APIs into `:composeApp`. Stuff in there should not be stuff extensions will typically need though, otherwise it should go in `:library` instead.

Also, it is not immediately necessarily, but eventually we should also add the `composeResources` directory to weblate. This also sets up the locales python script to support that directory if and/or when we add it.


Happy to make any changes necessary though.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant