Thread
#compose
    Dmitriy Gaiduk

    Dmitriy Gaiduk

    11 months ago
    Hello, What’s the preferred way to implement a custom string resource system in Compose? Problem: We are adding the Lokalise SDK https://docs.lokalise.com/en/articles/1400668-lokalise-android-sdk. And working with strings looks like this:
    val resources = new LokaliseResources(context)
    val text = resources.getString(R.string.screen_title)
    What’s the best way to store and create the
    LokaliseResources
    object in Compose? We want to use the
    LokaliseResources.getString ()
    function as a replacement for
    androidx.compose.ui.res.stringResource ()
    . We now have an implementation like this:
    @Composable
    fun CustomTheme(
      useDarkTheme: Boolean = false,
      content: @Composable () -> Unit,
    ) {
      val colors = if (useDarkTheme) DarkColorPalette else LightColorPalette
      val colorPalette = remember { colors }
      colorPalette.update(colors)
      
      MaterialTheme(
        colors = debugColors(),
        typography = MaterialTypography,
      ) {
        CompositionLocalProvider(
          CustomColors provides colorPalette,
          content = content,
        )
      }
    }
    
    class Screen : com.bluelinelabs.conductor.Controller {
      private val lokaliseResources: LokaliseResources by lazy { LokaliseResources(activity) }
      private fun getString(@StringRes resId: Int): String {
        return lokaliseResources.getString(resId)
      }
    
     @Composable
     fun Content() {
        CustomTheme(useDarkTheme = false) {
          Text(value = getString(R.string.screen_title))
        }
      }
    }
    But the problem is that you cannot get a string resource outside of the
    Screen
    class in any Compose method. Is it possible to create LokaliseResources in a singleton? Or can this be added to
    CustomTheme
    somehow?
    a

    annsofi

    11 months ago
    What’s the reason for not using Compose’s
    stringResourse
    ? We’re also using Lokalise and that seems to work, when you override the base context just as you do with “regular” fragments and activities.
    Csaba Kozák

    Csaba Kozák

    11 months ago
    The built-in in
    stringResource()
    function calls
    LocalConfiguration.current
    under the hood, to get the
    Resources
    object, and read the strings from it. You could provide
    LocalConfiguration
    and wrap the original one with yours, like in a
    ProvideLocaliseConfiguration
    function.
    @Composable
    fun ProvideLocaliseConfiguration(
      content: @Composable () -> Unit
    ) {
    
      val orig = LocalConfiguration.current
    
       CompositionLocalProvider(LocalConfiguration provides LocaliseConfiguration(orig) {
        content()
      }
    }
    Edit: checking the sources again, actually you have to provide
    LocalContext
    instead, or both. But you get the idea. 🙂
    Yeah, overriding the base context should also work, but in a pure compose app, i would rather go with the
    CompositionLocal
    .
    Dmitriy Gaiduk

    Dmitriy Gaiduk

    11 months ago
    What’s the reason for not using Compose’s stringResourse?
    For some reason Compose’s
    stringResourse
    does not work. Override the base context:
    MainActivity {
     override fun attachBaseContext(context: Context) {
       super.attachBaseContext(LokaliseContextWrapper.wrap(context))
     }
    }
    d

    dimsuz

    11 months ago
    Maybe you also need to wrap application context:
    MyApplication : Application {
     override fun attachBaseContext(context: Context) {
       super.attachBaseContext(LokaliseContextWrapper.wrap(context))
     }   
    }