diff --git a/.github/workflows/build_apk.yaml.bak b/.github/workflows/build_apk.yaml.bak
new file mode 100644
index 0000000..83c464c
--- /dev/null
+++ b/.github/workflows/build_apk.yaml.bak
@@ -0,0 +1,70 @@
+name: Build APK
+
+on:
+ workflow_run:
+ workflows:
+ - "Publish to Play Store and Bump Version"
+ types:
+ - completed
+
+jobs:
+ build_release_apk:
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/create-github-app-token@v1
+ id: app-token
+ with:
+ app-id: ${{ vars.PUBLIVERSIONER_ID }}
+ private-key: ${{ secrets.PUBLIVERSIONER_SECRET }}
+
+ - name: Checkout repository
+ uses: actions/checkout@v4
+
+ - name: Get current version from source
+ env:
+ FILE_PATH: "version.properties"
+ id: version_source
+ run: |
+ current_version=$(awk -F"=" '/VERSION_NAME/ {print $2}' "$FILE_PATH")
+ echo "version=$current_version" >> $GITHUB_OUTPUT
+
+ - name: Decode and create google-services.json
+ run: |
+ mkdir -p app/src/prod/release
+ echo "$GOOGLE_SERVICES_JSON" | base64 -d > app/src/prod/release/google-services.json
+ env:
+ GOOGLE_SERVICES_JSON: ${{ secrets.GOOGLE_SERVICES_FILE_AS_BASE64 }}
+
+ - name: Decode Keystore
+ run: |
+ echo "$KEYSTORE_AS_BASE64" | base64 --decode > app/keystore.jks
+ env:
+ KEYSTORE_AS_BASE64: ${{ secrets.GOOGLE_PLAY_SIGNING_KEY_FILE_AS_BASE64 }}
+
+ - name: Set up JDK 20
+ uses: actions/setup-java@v4
+ with:
+ java-version: "20"
+ distribution: "zulu"
+
+ - name: Build Release APK
+ run: ./gradlew assembleProdRelease
+ env:
+ SIGNING_STORE_FILE: ${{ github.workspace }}/app/keystore.jks
+ SIGNING_STORE_PASSWORD: ${{ secrets.RELEASE_STORE_PASSWORD }}
+ SIGNING_KEY_ALIAS: ${{ secrets.RELEASE_KEY_ALIAS }}
+ SIGNING_KEY_PASSWORD: ${{ secrets.RELEASE_KEY_PASSWORD }}
+
+ - name: Prepare release directory
+ run: |
+ mkdir -p release
+ cp app/build/outputs/apk/prod/release/app-prod-release.apk release/
+
+ - name: Create release
+ env:
+ TAG: ${{ steps.version_source.outputs.version }}
+ GH_TOKEN: ${{ steps.app-token.outputs.token }}
+ run: |
+ gh release create "v$TAG" ./release/app-prod-release.apk \
+ --title=$TAG \
+ --generate-notes
diff --git a/.github/workflows/publish.yaml.bak b/.github/workflows/publish.yaml.bak
new file mode 100644
index 0000000..697a83a
--- /dev/null
+++ b/.github/workflows/publish.yaml.bak
@@ -0,0 +1,24 @@
+name: Publish to Play Store and Bump Version
+
+on:
+ pull_request:
+ types:
+ - closed
+ workflow_dispatch:
+
+jobs:
+ publish_and_version_bump:
+ uses: rees46/workflow/.github/workflows/reusable-android-google-play-publish.yaml@master
+ with:
+ githubAppId: ${{ vars.PUBLIVERSIONER_ID }}
+ packageName: "rees46.demo_shop"
+ aabReleasePath: "app/build/outputs/bundle/prodRelease/app-prod-release.aab"
+ propertiesFilePath: "version.properties"
+ secrets:
+ GITHUB_APP_PRIVATE_KEY: ${{ secrets.PUBLIVERSIONER_SECRET }}
+ GOOGLE_SERVICES_FILE_AS_BASE64: ${{ secrets.GOOGLE_SERVICES_FILE_AS_BASE64 }}
+ GOOGLE_PLAY_SIGNING_KEY_FILE_AS_BASE64: ${{ secrets.GOOGLE_PLAY_SIGNING_KEY_FILE_AS_BASE64 }}
+ RELEASE_STORE_PASSWORD: ${{ secrets.RELEASE_STORE_PASSWORD }}
+ RELEASE_KEY_ALIAS: ${{ secrets.RELEASE_KEY_ALIAS }}
+ RELEASE_KEY_PASSWORD: ${{ secrets.RELEASE_KEY_PASSWORD }}
+ PLAY_ACCOUNT_AS_BASE64: ${{ secrets.PLAY_ACCOUNT_AS_BASE64 }}
diff --git a/.github/workflows/sync.yaml b/.github/workflows/sync.yaml
new file mode 100644
index 0000000..d7ca662
--- /dev/null
+++ b/.github/workflows/sync.yaml
@@ -0,0 +1,28 @@
+name: Sync repositories
+
+on:
+ pull_request:
+ # TODO uncomment
+ # workflow_run:
+ # workflows:
+ # - "Publish to Play Store and Bump Version"
+ # types:
+ # - completed
+ # workflow_dispatch:
+
+jobs:
+ run:
+ # TODO uncomment
+ # uses: personaClick/workflow/.github/workflows/reusable-android-synchronization.yaml@master
+ uses: personaClick/workflow/.github/workflows/reusable-android-synchronization.yaml@refactor/reusable-android-synchronization
+ permissions: write-all
+ with:
+ appId: ${{ vars.PERSONACLICK_COURIER_ID }}
+ targetRepository: personaclick/demo-android
+ sourceDirname: personaClick
+ targetDirname: personaClick
+ syncIgnore: ".git,.idea,version.properties,app/src/main/res/drawable/ic_app.xml,app/src/main/res/drawable/ic_logo.xml"
+ replacementExtentions: "*.kts,*.kt,*.md,*.xml,*.toml,*.yml,*.yaml"
+ replacementContents: "42a4cd11ebab3b0454778d18d4f3d5|42a4cd11ebab3b0454778d18d4f3d5,5a57812604806d58d3d98f8e9480cb97|5a57812604806d58d3d98f8e9480cb97,e4fd6e3a19610f7aea5534e96eec69d6|e4fd6e3a19610f7aea5534e96eec69d6,5a57812604806d58d3d98f8e9480cb97|aabc899d3db3d71c4032832e4291c16a,09d291f54de95e9e5bde43b343b0b0d7|09d291f54de95e9e5bde43b343b0b0d7,https://api.personaclick.com/|https://api.personaclick.com/,com.personaclick:personaclick-sdk|com.personaclick:personaclick-sdk,api.personaclick.com|api.personaclick.com,personaclick.com|personaclick.com,personaClick|personaClick,PersonaClick|PersonaClick,PersonaClick|PersonaClick"
+ secrets:
+ privateKey: ${{ secrets.PERSONACLICK_COURIER_SECRET }}
diff --git a/.vim/coc-settings.json b/.vim/coc-settings.json
new file mode 100644
index 0000000..be97557
--- /dev/null
+++ b/.vim/coc-settings.json
@@ -0,0 +1,3 @@
+{
+ "java.compile.nullAnalysis.mode": "disabled"
+}
\ No newline at end of file
diff --git a/LICENSE b/LICENSE
new file mode 100644
index 0000000..c2fba6b
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,28 @@
+BSD 3-Clause License
+
+Copyright (c) 2024, REES46
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+1. Redistributions of source code must retain the above copyright notice, this
+ list of conditions and the following disclaimer.
+
+2. Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+3. Neither the name of the copyright holder nor the names of its
+ contributors may be used to endorse or promote products derived from
+ this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/README.md b/README.md
index 6b67f91..3b7d686 100644
--- a/README.md
+++ b/README.md
@@ -1 +1,28 @@
-# trigger-repository
+# PersonaClick Demo Android
+
+## Description
+
+PersonaClick Demo Android - application to demonstrate working with SDK.
+
+## Configure
+
+Versions:
+- PersonaClick SDK 2.0.20
+- Java 20
+- Kotlin 2.0.0
+- Gradle 8.8
+- Android Gradle Plugin 8.5.2
+
+Copy `google-services.json` file from [Firebase console](https://console.firebase.google.com/u/0/) to app module.
+
+## Documentation
+
+For detailed information on methods used from the SDK, please refer to the documentation available at the following link:
+
+[Official API references](https://reference.api.personaclick.com/#introduction)
+
+## Screenshots
+
+
+
+
diff --git a/app/.gitignore b/app/.gitignore
new file mode 100644
index 0000000..796b96d
--- /dev/null
+++ b/app/.gitignore
@@ -0,0 +1 @@
+/build
diff --git a/app/src/main/java/personaClick/demo_android/app/DemoApplication.kt b/app/src/main/java/personaClick/demo_android/app/DemoApplication.kt
index f0f31cb..03e7a9a 100644
--- a/app/src/main/java/personaClick/demo_android/app/DemoApplication.kt
+++ b/app/src/main/java/personaClick/demo_android/app/DemoApplication.kt
@@ -54,6 +54,6 @@ class DemoApplication : Application() {
}
companion object {
- private const val SHOP_ID = "357382bf66ac0ce2f1722677c59511"
+ private const val SHOP_ID = "42a4cd11ebab3b0454778d18d4f3d5"
}
}
diff --git a/app/src/main/res/drawable/ic_app.xml b/app/src/main/res/drawable/ic_app.xml
deleted file mode 100644
index cc21897..0000000
--- a/app/src/main/res/drawable/ic_app.xml
+++ /dev/null
@@ -1,9 +0,0 @@
-
-
-
diff --git a/app/src/main/res/drawable/ic_logo.xml b/app/src/main/res/drawable/ic_logo.xml
deleted file mode 100644
index 2dbf407..0000000
--- a/app/src/main/res/drawable/ic_logo.xml
+++ /dev/null
@@ -1,36 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/buildConfig/.gitignore b/buildConfig/.gitignore
new file mode 100644
index 0000000..42afabf
--- /dev/null
+++ b/buildConfig/.gitignore
@@ -0,0 +1 @@
+/build
\ No newline at end of file
diff --git a/buildConfig/bin/main/AppBuildConfig.kt b/buildConfig/bin/main/AppBuildConfig.kt
new file mode 100644
index 0000000..835ba56
--- /dev/null
+++ b/buildConfig/bin/main/AppBuildConfig.kt
@@ -0,0 +1,237 @@
+@file:Suppress("DEPRECATION")
+
+import com.android.build.gradle.AppExtension
+import com.android.build.gradle.LibraryExtension
+import java.io.File
+import java.io.FileInputStream
+import java.io.FileOutputStream
+import java.util.Properties
+import org.gradle.api.JavaVersion
+import org.gradle.api.Plugin
+import org.gradle.api.Project
+import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
+
+class AppBuildConfig : Plugin {
+
+ override fun apply(project: Project) {
+ project.plugins.withId(ANDROID_APPLICATION_LIB) {
+ configureAppExtension(project.extensions.getByType(AppExtension::class.java), project)
+ }
+
+ project.plugins.withId(ANDROID_LIB) {
+ configureLibraryExtension(project.extensions.getByType(LibraryExtension::class.java))
+ }
+
+ configureKotlinCompile(project)
+ }
+
+ private fun configureAppExtension(androidExtension: AppExtension, project: Project) {
+ val versionPropsFile = File(project.rootProject.projectDir, "version.properties")
+ val versionProps = Properties()
+ if (versionPropsFile.exists()) {
+ versionProps.load(FileInputStream(versionPropsFile))
+ }
+
+ val currentVersionCode = versionProps[VERSION_CODE]?.toString()?.toInt() ?: 1
+ val currentVersionName = versionProps[VERSION_NAME]?.toString() ?: "1.0.0"
+
+ androidExtension.apply {
+ compileSdkVersion(TARGET_SDK)
+ defaultConfig {
+ applicationId = APPLICATION_ID
+ minSdk = MIN_SDK
+ targetSdk = TARGET_SDK
+ versionCode = currentVersionCode
+ versionName = currentVersionName
+ viewBinding {
+ enable = true
+ }
+ }
+ flavorDimensions(DIMENSION_FLAVORS)
+ configureProductFlavors()
+ configureSigningConfigs(project)
+ configureBuildTypes()
+ configurePackagingOptions()
+ configureJavaAndKotlinOptions()
+
+ project.tasks.register(PUBLISH_TO_ITERNAL_TESTING) {
+ dependsOn(RELEASE_BUNDLE)
+ finalizedBy(PUBLISH_RELEASE_BUNDLE)
+ }
+
+ project.tasks.register(INCREMENT_VERSION) {
+ doLast {
+ incrementVersion(versionProps, versionPropsFile)
+ }
+ }
+ }
+ }
+
+ private fun incrementVersion(versionProps: Properties, versionPropsFile: File) {
+ val currentVersionCode = versionProps[VERSION_CODE]?.toString()?.toInt() ?: 1
+ val newVersionCode = currentVersionCode + 1
+
+ val currentVersionName = versionProps[VERSION_NAME]?.toString() ?: "1.0.0"
+ val versionNameParts = currentVersionName.split(".").toMutableList()
+
+ if (versionNameParts.size == 3) {
+ val patchVersion = versionNameParts[2].toIntOrNull() ?: 0
+ versionNameParts[2] = (patchVersion + 1).toString()
+ }
+
+ val newVersionName = versionNameParts.joinToString(".")
+
+ versionProps[VERSION_CODE] = newVersionCode.toString()
+ versionProps[VERSION_NAME] = newVersionName
+ versionProps.store(FileOutputStream(versionPropsFile), null)
+
+ println("Version updated to: versionCode=$newVersionCode, versionName=$newVersionName")
+ }
+
+ private fun AppExtension.configureProductFlavors() {
+ productFlavors {
+ create(DEV_FLAVOR) {
+ dimension = DIMENSION_FLAVORS
+ }
+ create(STAGE_FLAVOR) {
+ dimension = DIMENSION_FLAVORS
+ applicationIdSuffix = APPLICATION_STAGE_SUFFIX
+ }
+ create(PROD_FLAVOR) {
+ dimension = DIMENSION_FLAVORS
+ }
+ }
+ }
+
+ private fun AppExtension.configureSigningConfigs(project: Project) {
+ val localProperties = Properties()
+ val localPropertiesFile = project.rootProject.file(LOCAL_PROPERTIES_FILE)
+ if (localPropertiesFile.exists()) {
+ localProperties.load(FileInputStream(localPropertiesFile))
+ }
+
+ signingConfigs {
+ create(RELEASE_CONFIG) {
+ storeFile = File(
+ localProperties.getProperty(RELEASE_STORE_FILE) ?: System.getenv("SIGNING_STORE_FILE")
+ )
+ storePassword = localProperties.getProperty(RELEASE_STORE_PASSWORD) ?: System.getenv("SIGNING_STORE_PASSWORD")
+ keyAlias = localProperties.getProperty(RELEASE_KEY_ALIAS) ?: System.getenv("SIGNING_KEY_ALIAS")
+ keyPassword = localProperties.getProperty(RELEASE_KEY_PASSWORD) ?: System.getenv("SIGNING_KEY_PASSWORD")
+ }
+ create(DEBUG_CONFIG) {
+ }
+ }
+ }
+
+ private fun AppExtension.configureBuildTypes() {
+ buildTypes {
+ getByName(RELEASE_TYPE) {
+ signingConfig = signingConfigs.getByName(RELEASE_CONFIG)
+ isMinifyEnabled = false
+ proguardFiles(
+ getDefaultProguardFile(PROGUARD_ANDROID_TXT),
+ PROGUARD_RULES
+ )
+ }
+ getByName(DEBUG_TYPE) {
+ isDebuggable = true
+ }
+ }
+ }
+
+ private fun AppExtension.configurePackagingOptions() {
+ packagingOptions {
+ exclude("META-INF/*.kotlin_module")
+ exclude("META-INF/AL2.0")
+ exclude("META-INF/LGPL2.1")
+ }
+ }
+
+ private fun configureLibraryExtension(androidExtension: LibraryExtension) {
+ androidExtension.apply {
+ compileSdk = TARGET_SDK
+ configureDefaultConfig()
+ configureBuildTypes()
+ configureJavaAndKotlinOptions()
+ }
+ }
+
+ private fun LibraryExtension.configureDefaultConfig() {
+ defaultConfig {
+ minSdk = MIN_SDK
+ targetSdk = TARGET_SDK
+ }
+ }
+
+ private fun LibraryExtension.configureBuildTypes() {
+ buildTypes {
+ getByName(RELEASE_TYPE) {
+ isMinifyEnabled = false
+ proguardFiles(
+ getDefaultProguardFile(PROGUARD_ANDROID_TXT),
+ PROGUARD_RULES
+ )
+ }
+ }
+ }
+
+ private fun configureKotlinCompile(project: Project) {
+ project.tasks.withType(KotlinCompile::class.java).configureEach {
+ kotlinOptions {
+ jvmTarget = JVM_TARGET
+ }
+ }
+ }
+
+ private fun AppExtension.configureJavaAndKotlinOptions() {
+ compileOptions {
+ sourceCompatibility = JavaVersion.VERSION_20
+ targetCompatibility = JavaVersion.VERSION_20
+ }
+ }
+
+ private fun LibraryExtension.configureJavaAndKotlinOptions() {
+ compileOptions {
+ sourceCompatibility = JavaVersion.VERSION_20
+ targetCompatibility = JavaVersion.VERSION_20
+ }
+ }
+
+ companion object {
+ private const val PUBLISH_TO_ITERNAL_TESTING = "publishProdReleaseToPlay"
+ private const val PUBLISH_RELEASE_BUNDLE = "publishProdReleaseBundle"
+ private const val LOCAL_PROPERTIES_FILE = "local.properties"
+ private const val INCREMENT_VERSION = "incrementVersion"
+ private const val RELEASE_BUNDLE = "bundleProdRelease"
+
+ private const val VERSION_NAME = "VERSION_NAME"
+ private const val VERSION_CODE = "VERSION_CODE"
+
+ private const val RELEASE_STORE_PASSWORD = "RELEASE_STORE_PASSWORD"
+ private const val RELEASE_KEY_PASSWORD = "RELEASE_KEY_PASSWORD"
+ private const val RELEASE_STORE_FILE = "RELEASE_STORE_FILE"
+ private const val RELEASE_KEY_ALIAS = "RELEASE_KEY_ALIAS"
+
+ private const val ANDROID_APPLICATION_LIB = "com.android.application"
+ private const val APPLICATION_ID = "personaClick.demo_android"
+ private const val ANDROID_LIB = "com.android.library"
+ private const val JVM_TARGET = "20"
+ private const val TARGET_SDK = 34
+ private const val MIN_SDK = 24
+
+ private const val RELEASE_CONFIG = "releaseConfig"
+ private const val DEBUG_CONFIG = "debugConfig"
+ private const val RELEASE_TYPE = "release"
+ private const val DEBUG_TYPE = "debug"
+
+ private const val STAGE_FLAVOR = "stage"
+ private const val PROD_FLAVOR = "prod"
+ private const val DEV_FLAVOR = "dev"
+ private const val APPLICATION_STAGE_SUFFIX = ".test"
+ private const val DIMENSION_FLAVORS = "demoShop"
+
+ private const val PROGUARD_ANDROID_TXT = "proguard-android-optimize.txt"
+ private const val PROGUARD_RULES = "proguard-rules.pro"
+ }
+}
\ No newline at end of file
diff --git a/core/.gitignore b/core/.gitignore
new file mode 100644
index 0000000..42afabf
--- /dev/null
+++ b/core/.gitignore
@@ -0,0 +1 @@
+/build
\ No newline at end of file
diff --git a/core/src/main/java/personaClick/demo_android/core/settings/RecommendationSettings.kt b/core/src/main/java/personaClick/demo_android/core/settings/RecommendationSettings.kt
index d6898cf..b21c649 100644
--- a/core/src/main/java/personaClick/demo_android/core/settings/RecommendationSettings.kt
+++ b/core/src/main/java/personaClick/demo_android/core/settings/RecommendationSettings.kt
@@ -1,7 +1,7 @@
package personaClick.demo_android.core.settings
object RecommendationSettings {
- const val SIMPLE_RECOMMENDED_CODE = "a043dbc2f852ffe18861a2cdfc364ef2"
- const val CART_RECOMMENDED_CODE = "2dbebc39bee259b118bcc0ac3fa74a42"
- const val ALSO_LIKE_RECOMMENDED_CODE = "a043dbc2f852ffe18861a2cdfc364ef2"
+ const val SIMPLE_RECOMMENDED_CODE = "5a57812604806d58d3d98f8e9480cb97"
+ const val CART_RECOMMENDED_CODE = "e4fd6e3a19610f7aea5534e96eec69d6"
+ const val ALSO_LIKE_RECOMMENDED_CODE = "5a57812604806d58d3d98f8e9480cb97"
}
diff --git a/feature/.gitignore b/feature/.gitignore
new file mode 100644
index 0000000..42afabf
--- /dev/null
+++ b/feature/.gitignore
@@ -0,0 +1 @@
+/build
\ No newline at end of file
diff --git a/feature/src/main/res/layout/fragment_home.xml b/feature/src/main/res/layout/fragment_home.xml
index 3002099..16c472d 100644
--- a/feature/src/main/res/layout/fragment_home.xml
+++ b/feature/src/main/res/layout/fragment_home.xml
@@ -32,7 +32,7 @@
android:id="@+id/story"
android:layout_width="match_parent"
android:layout_height="wrap_content"
- app:code="fcaa8d3168ab7d7346e4b4f1a1c92214"
+ app:code="09d291f54de95e9e5bde43b343b0b0d7"
app:layout_constraintTop_toTopOf="parent" />