Skip to content

Commit

Permalink
[#75] Add Moko for localization
Browse files Browse the repository at this point in the history
  • Loading branch information
blyscuit committed Nov 18, 2022
1 parent 9016703 commit 9447c53
Show file tree
Hide file tree
Showing 22 changed files with 238 additions and 125 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/ios_review_pull_request.yml
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ jobs:
review_pull_request:
name: Review pull request
runs-on: macOS-latest
timeout-minutes: 30
timeout-minutes: 60
steps:
- name: Cancel Previous Runs
uses: styfle/cancel-workflow-action@0.10.0
Expand Down
1 change: 1 addition & 0 deletions build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ buildscript {
classpath(Dependency.KOVER)
classpath(Dependency.KOTLIN_SERIALIZATION)
classpath(Dependency.BUILD_KONFIG)
classpath(Dependency.MOKO_RESOURCES_GENERATOR)
}
}

Expand Down
4 changes: 4 additions & 0 deletions buildSrc/src/main/kotlin/appPackage/Dependency.kt
Original file line number Diff line number Diff line change
Expand Up @@ -40,4 +40,8 @@ object Dependency {
const val KOTEST_FRAMEWORK = "io.kotest:kotest-framework-engine:${Version.KOTEST}"
const val KOTEST_ASSERTIONS = "io.kotest:kotest-assertions-core:${Version.KOTEST}"
const val KOTEST_PROPERTY = "io.kotest:kotest-property:${Version.KOTEST}"

// Resources
const val MOKO_RESOURCES_GENERATOR = "dev.icerock.moko:resources-generator:${Version.MOKO_RESOURCES}"
const val MOKO_RESOURCES = "dev.icerock.moko:resources:${Version.MOKO_RESOURCES}"
}
2 changes: 2 additions & 0 deletions buildSrc/src/main/kotlin/appPackage/Plugin.kt
Original file line number Diff line number Diff line change
Expand Up @@ -16,4 +16,6 @@ object Plugin {

const val MOCKMP = "org.kodein.mock.mockmp"
const val KSP = "com.google.devtools.ksp"

const val MOKO_RESOURCES = "dev.icerock.mobile.multiplatform-resources"
}
1 change: 1 addition & 0 deletions buildSrc/src/main/kotlin/appPackage/Versions.kt
Original file line number Diff line number Diff line change
Expand Up @@ -18,4 +18,5 @@ object Version {
const val MOCKMP = "1.6.0"
const val KSP = "1.7.10-1.0.6"
const val KOTEST = "5.5.1"
const val MOKO_RESOURCES = "0.20.1"
}
2 changes: 1 addition & 1 deletion iosApp/Podfile
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ target 'Survey' do

# Development
pod 'SwiftLint'
pod 'Wormholy', :configurations => ['Debug Staging', 'Debug Production']
pod 'Wormholy', :configurations => ['DebugStaging', 'DebugProduction']

# KMM
platform :ios, '14.0'
Expand Down
2 changes: 1 addition & 1 deletion iosApp/Podfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,6 @@ SPEC CHECKSUMS:
SwiftLint: 32ee33ded0636d0905ef6911b2b67bbaeeedafa5
Wormholy: 3252bc3e55a1847ef9a0976c1377bd77bf3635fa

PODFILE CHECKSUM: c506be3005eec4560de93594e4fa87416d1c33d1
PODFILE CHECKSUM: dcc37a55f6c647528fa4ef7e0ea79d380849df73

COCOAPODS: 1.11.3
198 changes: 119 additions & 79 deletions iosApp/Survey.xcodeproj/project.pbxproj

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
</BuildActionEntries>
</BuildAction>
<TestAction
buildConfiguration = "Debug Staging"
buildConfiguration = "DebugStaging"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
shouldUseLaunchSchemeArgsEnv = "YES">
Expand Down Expand Up @@ -51,7 +51,7 @@
</Testables>
</TestAction>
<LaunchAction
buildConfiguration = "Debug Staging"
buildConfiguration = "DebugStaging"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
launchStyle = "0"
Expand All @@ -72,7 +72,7 @@
</BuildableProductRunnable>
</LaunchAction>
<ProfileAction
buildConfiguration = "Debug Staging"
buildConfiguration = "DebugStaging"
shouldUseLaunchSchemeArgsEnv = "YES"
savedToolIdentifier = ""
useCustomWorkingDirectory = "NO"
Expand All @@ -89,10 +89,10 @@
</BuildableProductRunnable>
</ProfileAction>
<AnalyzeAction
buildConfiguration = "Debug Staging">
buildConfiguration = "DebugStaging">
</AnalyzeAction>
<ArchiveAction
buildConfiguration = "Release Staging"
buildConfiguration = "ReleaseStaging"
revealArchiveInOrganizer = "YES">
</ArchiveAction>
</Scheme>
10 changes: 5 additions & 5 deletions iosApp/Survey.xcodeproj/xcshareddata/xcschemes/Survey.xcscheme
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
</BuildActionEntries>
</BuildAction>
<TestAction
buildConfiguration = "Debug Production"
buildConfiguration = "DebugProduction"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
shouldUseLaunchSchemeArgsEnv = "YES">
Expand Down Expand Up @@ -51,7 +51,7 @@
</Testables>
</TestAction>
<LaunchAction
buildConfiguration = "Debug Production"
buildConfiguration = "DebugProduction"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
launchStyle = "0"
Expand All @@ -72,7 +72,7 @@
</BuildableProductRunnable>
</LaunchAction>
<ProfileAction
buildConfiguration = "Debug Production"
buildConfiguration = "DebugProduction"
shouldUseLaunchSchemeArgsEnv = "YES"
savedToolIdentifier = ""
useCustomWorkingDirectory = "NO"
Expand All @@ -89,10 +89,10 @@
</BuildableProductRunnable>
</ProfileAction>
<AnalyzeAction
buildConfiguration = "Debug Production">
buildConfiguration = "DebugProduction">
</AnalyzeAction>
<ArchiveAction
buildConfiguration = "Release Production"
buildConfiguration = "ReleaseProduction"
revealArchiveInOrganizer = "YES">
</ArchiveAction>
</Scheme>
4 changes: 4 additions & 0 deletions iosApp/Survey/Configurations/Plists/Info.plist
Original file line number Diff line number Diff line change
Expand Up @@ -44,5 +44,9 @@
<string>UIInterfaceOrientationLandscapeLeft</string>
<string>UIInterfaceOrientationLandscapeRight</string>
</array>
<key>CFBundleLocalizations</key>
<array>
<string>en</string>
</array>
</dict>
</plist>
15 changes: 0 additions & 15 deletions iosApp/Survey/Resources/Localizations/en.lproj/Localizable.strings

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -76,18 +76,18 @@ struct LoginView: View {
}

var loginField: some View {
TextField(Localize.loginFieldEmail(), text: $email)
TextField(LocalizeId().login_fields_email.localized, text: $email)
.keyboardType(.emailAddress)
.primaryTextField()
.accessibility(.login(.emailField))
}

var passwordField: some View {
HStack {
SecureField(Localize.loginFieldPassword(), text: $password)
SecureField(LocalizeId().login_fields_password.localized, text: $password)
.accessibility(.login(.passwordField))
if password.isEmpty {
Button(Localize.loginButtonForgot()) {
Button(LocalizeId().login_button_forgot.localized) {
coordinator.showResetPassword()
}
.overlayButton()
Expand All @@ -102,7 +102,7 @@ struct LoginView: View {
Button {
// TODO: Add action when press `login`
} label: {
Text(Localize.loginButtonLogin())
Text(LocalizeId().login_button_login.localized)
.frame(maxWidth: .infinity)
.primaryButton()
.accessibility(.login(.loginButton))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ struct ResetPasswordView: View {

Assets.logoWhite.image

Text(Localize.resetPasswordTextInstruction())
Text(LocalizeId().reset_password_text_instruction.localized)
.multilineTextAlignment(.center)

Spacer().frame(maxHeight: 70.0)
Expand All @@ -51,15 +51,15 @@ struct ResetPasswordView: View {
}

var emailField: some View {
TextField(Localize.resetPasswordFieldEmail(), text: $email)
TextField(LocalizeId().reset_password_field_email.localized, text: $email)
.keyboardType(.emailAddress)
.primaryTextField()
.accessibility(.resetPassword(.emailField))
}

var resetButton: some View {
Button {} label: {
Text(Localize.resetPasswordButtonReset())
Text(LocalizeId().reset_password_button_reset.localized)
.frame(maxWidth: .infinity)
.primaryButton()
.accessibility(.resetPassword(.resetButton))
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
//
// StringResource+Localized.swift
// Survey
//
// Created by Bliss on 18/10/22.
// Copyright © 2022 Nimble. All rights reserved.
//

import Shared

typealias LocalizeId = MR.strings

extension StringResource {

var localized: String {
desc().localized()
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,3 @@

typealias Assets = R.image
typealias Fonts = R.font
typealias Localize = R.string.localizable
2 changes: 1 addition & 1 deletion nimble-jsonapi-kotlin
23 changes: 17 additions & 6 deletions shared/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ plugins {
id(Plugin.MOCKMP).version(Version.MOCKMP)
id(Plugin.KSP).version(Version.KSP)
id(Plugin.KOVER)
id(Plugin.MOKO_RESOURCES)
}

version = "1.0"
Expand All @@ -30,11 +31,12 @@ kotlin {
podfile = project.file("../iosApp/Podfile")
framework {
baseName = "Shared"
export(Dependency.MOKO_RESOURCES)
}
xcodeConfigurationToNativeBuildType["Debug Staging"] = NativeBuildType.DEBUG
xcodeConfigurationToNativeBuildType["Debug Production"] = NativeBuildType.DEBUG
xcodeConfigurationToNativeBuildType["Release Staging"] = NativeBuildType.RELEASE
xcodeConfigurationToNativeBuildType["Release Production"] = NativeBuildType.RELEASE
xcodeConfigurationToNativeBuildType["DebugStaging"] = NativeBuildType.DEBUG
xcodeConfigurationToNativeBuildType["DebugProduction"] = NativeBuildType.DEBUG
xcodeConfigurationToNativeBuildType["ReleaseStaging"] = NativeBuildType.RELEASE
xcodeConfigurationToNativeBuildType["ReleaseProduction"] = NativeBuildType.RELEASE
}

sourceSets {
Expand Down Expand Up @@ -93,6 +95,10 @@ kotlin {
}
}

dependencies {
commonMainApi(Dependency.MOKO_RESOURCES)
}

android {
compileSdk = Android.COMPILE_SDK
sourceSets["main"].manifest.srcFile("src/androidMain/AndroidManifest.xml")
Expand All @@ -105,7 +111,7 @@ android {
unitTests.all {
if (it.name == "testReleaseUnitTest") {
it.extensions.configure(kotlinx.kover.api.KoverTaskExtension::class) {
isDisabled.set(true)
isDisabled.set(true)
}
}
it.extensions.configure(kotlinx.kover.api.KoverTaskExtension::class) {
Expand All @@ -114,7 +120,7 @@ android {
}
}

detekt {
detekt {
source = files(
"./"
)
Expand Down Expand Up @@ -208,3 +214,8 @@ kover {
}
}
}

multiplatformResources {
multiplatformResourcesPackage = "co.nimblehq.blisskmmic"
disableStaticFrameworkWarning = true
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package co.nimblehq.blisskmmic.presentation.helpers

import co.nimblehq.blisskmmic.MR
import dev.icerock.moko.resources.AssetResource
import dev.icerock.moko.resources.ResourceContainer
import dev.icerock.moko.resources.StringResource
import dev.icerock.moko.resources.desc.Resource
import dev.icerock.moko.resources.desc.StringDesc

class MokoLocalize {
fun localize(id: String?): StringDesc? {
if (id == MR.strings.common_error.toString()) {
return StringDesc.Resource(MR.strings.common_error)
}
return null
}
}
11 changes: 11 additions & 0 deletions shared/src/commonMain/resources/MR/base/strings.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="common_error">An error occurred. Please try again.</string>
<string name="login_fields_email">Email</string>
<string name="login_fields_password">Password</string>
<string name="login_button_login">Log in</string>
<string name="login_button_forgot">Forgot?</string>
<string name="reset_password_field_email">Email</string>
<string name="reset_password_text_instruction">Enter your email to receive instructions for resetting your password.</string>
<string name="reset_password_button_reset">Reset</string>
</resources>
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package co.nimblehq.blisskmmic.presentation.helpers

import co.nimblehq.blisskmmic.MR
import dev.icerock.moko.resources.desc.Resource
import dev.icerock.moko.resources.desc.StringDesc
import io.kotest.matchers.shouldBe
import kotlin.test.Test

class MokoLocalizeTest {

@Test
fun `When calling localize with common_error desc, it returns correct StringDesc`() {
StringDesc.Resource(MR.strings.common_error) shouldBe
MokoLocalize().localize(MR.strings.common_error.toString())
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,18 @@ import co.nimblehq.blisskmmic.domain.usecase.LogInUseCase
import io.kotest.matchers.shouldBe
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.flow.*
import kotlinx.coroutines.flow.first
import kotlinx.coroutines.flow.flow
import kotlinx.coroutines.newSingleThreadContext
import kotlinx.coroutines.test.resetMain
import kotlinx.coroutines.test.runTest
import kotlinx.coroutines.test.setMain
import org.kodein.mock.*
import org.kodein.mock.Fake
import org.kodein.mock.Mock
import org.kodein.mock.tests.TestsWithMocks
import kotlin.test.*
import kotlin.test.AfterTest
import kotlin.test.BeforeTest
import kotlin.test.Test

@ExperimentalCoroutinesApi
class LoginViewModelTest : TestsWithMocks() {
Expand Down

0 comments on commit 9447c53

Please sign in to comment.