{
- return if (isErrorResponseNeeded) {
- Result.failure(RuntimeException())
- } else {
- Result.success(user)
- }
-
- }
-
-}
\ No newline at end of file
diff --git a/packages/android/formbricksSDK/src/androidTest/resources/Environment.json b/packages/android/formbricksSDK/src/androidTest/resources/Environment.json
deleted file mode 100644
index 812373f77b..0000000000
--- a/packages/android/formbricksSDK/src/androidTest/resources/Environment.json
+++ /dev/null
@@ -1,372 +0,0 @@
-{
- "data": {
- "data": {
- "actionClasses": [
- {
- "id": "cm6ow6hht000isf0k39hbmi5f",
- "key": "click_demo_button",
- "name": "Clicked the demo button",
- "noCodeConfig": null,
- "type": "code"
- }
- ],
- "project": {
- "clickOutsideClose": true,
- "darkOverlay": false,
- "id": "cm6ovvfnv0003sf0k7zi8r3ac",
- "inAppSurveyBranding": true,
- "placement": "bottomRight",
- "recontactDays": 7,
- "styling": {
- "allowStyleOverwrite": true,
- "brandColor": {
- "light": "#126dec"
- }
- }
- },
- "surveys": [
- {
- "autoClose": null,
- "delay": 0,
- "displayLimit": 1,
- "displayOption": "displayMultiple",
- "displayPercentage": 100,
- "endings": [
- {
- "buttonLabel": {
- "default": "Create your own Survey\u200c\u200c\u200d\u200d\u200c\u200c\u200d\u200c\u200c\u200c\u200c\u200d\u200d\u200d\u200c\u200c\u200d\u200c\u200c\u200c\u200d\u200d\u200c\u200c\u200c\u200c\u200c\u200c\u200c\u200c\u200c\u200d\u200c\u200d\u200c\u200c"
- },
- "buttonLink": "https://formbricks.com",
- "headline": {
- "default": "Thank you!\u200c\u200c\u200d\u200d\u200c\u200c\u200d\u200c\u200c\u200c\u200c\u200d\u200d\u200d\u200c\u200c\u200c\u200c\u200c\u200c\u200d\u200d\u200d\u200c\u200c\u200c\u200c\u200c\u200c\u200c\u200c\u200d\u200c\u200d\u200c\u200c"
- },
- "id": "ik26bumalvsg2hs0sz7kd0dh",
- "subheader": {
- "default": "We appreciate your feedback.\u200c\u200c\u200d\u200d\u200c\u200c\u200d\u200c\u200c\u200c\u200c\u200d\u200d\u200d\u200c\u200c\u200c\u200c\u200c\u200c\u200d\u200d\u200d\u200c\u200c\u200d\u200c\u200c\u200c\u200c\u200c\u200d\u200c\u200d\u200c\u200c"
- },
- "type": "endScreen"
- }
- ],
- "hiddenFields": {
- "enabled": true,
- "fieldIds": []
- },
- "id": "cm6ovw6j7000gsf0kduf4oo4i",
- "isBackButtonHidden": false,
- "languages": [],
- "name": "Start from scratch",
- "projectOverwrites": null,
- "questions": [
- {
- "allowMultipleFiles": true,
- "allowedFileExtensions": ["jpeg", "jpg", "png"],
- "backButtonLabel": {
- "default": "Back"
- },
- "buttonLabel": {
- "default": "Next"
- },
- "headline": {
- "default": "Upload some file"
- },
- "id": "bak70kjkubxq66eup7i6l4lp",
- "logic": [],
- "required": false,
- "subheader": {
- "default": "Yeeeaaahh"
- },
- "type": "fileUpload"
- },
- {
- "backButtonLabel": {
- "default": "Back\u200c\u200c\u200d\u200d\u200c\u200c\u200c\u200d\u200c\u200c\u200c\u200d\u200d\u200c\u200c\u200d\u200c\u200c\u200c\u200c\u200d\u200d\u200c\u200d\u200c\u200c\u200c\u200c\u200c\u200c\u200c\u200d\u200c\u200d\u200c\u200c"
- },
- "buttonExternal": true,
- "buttonLabel": {
- "default": "Book interview\u200c\u200c\u200d\u200d\u200c\u200c\u200c\u200d\u200c\u200c\u200c\u200d\u200d\u200c\u200d\u200c\u200c\u200c\u200c\u200c\u200d\u200d\u200c\u200d\u200c\u200d\u200c\u200c\u200c\u200c\u200c\u200d\u200c\u200d\u200c\u200c"
- },
- "buttonUrl": "https://telex.hu",
- "dismissButtonLabel": {
- "default": "Skip\u200c\u200c\u200d\u200d\u200c\u200c\u200c\u200d\u200c\u200c\u200c\u200d\u200d\u200c\u200d\u200c\u200c\u200c\u200c\u200c\u200d\u200d\u200c\u200d\u200d\u200c\u200c\u200c\u200c\u200c\u200c\u200d\u200c\u200d\u200c\u200c"
- },
- "headline": {
- "default": "Click something"
- },
- "html": {
- "default": "
yeah
"
- },
- "id": "zmjh52gfc92yo4ph2zru4nhn",
- "required": true,
- "type": "cta"
- },
- {
- "buttonLabel": {
- "default": "Next"
- },
- "charLimit": {
- "enabled": false
- },
- "headline": {
- "default": "How are things going?"
- },
- "id": "ve69a3mrkqixhtom8y2mtd9q",
- "inputType": "text",
- "logic": [],
- "longAnswer": true,
- "placeholder": {
- "default": "This is a placeholder. Type your answer though.."
- },
- "required": false,
- "type": "openText"
- },
- {
- "backButtonLabel": {
- "default": "Back"
- },
- "buttonLabel": {
- "default": "Next"
- },
- "headline": {
- "default": "Rate this question"
- },
- "id": "qo5khwchqa7g34qzdwb7p6kr",
- "isColorCodingEnabled": false,
- "lowerLabel": {
- "default": "Not good"
- },
- "range": 5,
- "required": true,
- "scale": "smiley",
- "type": "rating",
- "upperLabel": {
- "default": "Very good"
- }
- },
- {
- "backButtonLabel": {
- "default": "Back"
- },
- "buttonLabel": {
- "default": "Next"
- },
- "choices": [
- {
- "id": "wr01x35k5spyaz5x1d7vsa8g",
- "label": {
- "default": "One"
- }
- },
- {
- "id": "zvqn3rj26ph3krr1e4n8vn91",
- "label": {
- "default": "Kett\u0151"
- }
- },
- {
- "id": "f4e2xuspnajsz8kk7ctrc7sn",
- "label": {
- "default": "Tres"
- }
- }
- ],
- "headline": {
- "default": "Select something"
- },
- "id": "prdku49xb0gfpmipwc97scd4",
- "required": true,
- "shuffleOption": "none",
- "type": "multipleChoiceMulti"
- },
- {
- "backButtonLabel": {
- "default": "Back"
- },
- "buttonLabel": {
- "default": "Next"
- },
- "format": "M-d-y",
- "headline": {
- "default": "Select a date please"
- },
- "id": "yjape17lgfe7v74gbxwadj04",
- "required": true,
- "type": "date"
- },
- {
- "addressLine1": {
- "placeholder": {
- "default": "Address Line 1"
- },
- "required": false,
- "show": true
- },
- "addressLine2": {
- "placeholder": {
- "default": "Address Line 2"
- },
- "required": false,
- "show": false
- },
- "backButtonLabel": {
- "default": "Back"
- },
- "buttonLabel": {
- "default": "Next"
- },
- "city": {
- "placeholder": {
- "default": "City"
- },
- "required": false,
- "show": true
- },
- "country": {
- "placeholder": {
- "default": "Country"
- },
- "required": false,
- "show": true
- },
- "headline": {
- "default": "What is your address?"
- },
- "id": "z78kl00vherihw2oqv2loj2y",
- "required": false,
- "state": {
- "placeholder": {
- "default": "State"
- },
- "required": false,
- "show": true
- },
- "type": "address",
- "zip": {
- "placeholder": {
- "default": "Zip"
- },
- "required": false,
- "show": true
- }
- },
- {
- "backButtonLabel": {
- "default": "Back"
- },
- "buttonLabel": {
- "default": "Next"
- },
- "headline": {
- "default": "I dare you to check this!"
- },
- "html": {
- "default": "
I double dare you
"
- },
- "id": "qq30m24f14vhw356kqfzlrlr",
- "label": {
- "default": "Oookay"
- },
- "required": true,
- "type": "consent"
- },
- {
- "allowMulti": true,
- "backButtonLabel": {
- "default": "Back"
- },
- "buttonLabel": {
- "default": "Next"
- },
- "choices": [
- {
- "id": "m8uxhdlq4yerpzfykb6mfpeb",
- "imageUrl": "http://localhost:3000/storage/cm6ovvfoc000asf0k39wbzc8s/public/Screenshot%25202021-10-18%2520at%252011.35.15--fid--e7d90f81-56fb-4ed7-ad64-3ec869bc96d6.png"
- },
- {
- "id": "ayv30brvesfxrl7dmj2kig4u",
- "imageUrl": "http://localhost:3000/storage/cm6ovvfoc000asf0k39wbzc8s/public/Screenshot%25202022-11-22%2520at%252014.37.51--fid--5e4edd58-62b0-4df8-a096-e8e59b1bf080.png"
- }
- ],
- "headline": {
- "default": "Select a picture"
- },
- "id": "krehs9wlntwtjf9hlh8pp82w",
- "required": true,
- "type": "pictureSelection"
- }
- ],
- "recontactDays": 0,
- "segment": {
- "createdAt": "2025-02-03T10:04:21.922Z",
- "description": null,
- "environmentId": "cm6ovvfoc000asf0k39wbzc8s",
- "filters": [],
- "id": "cm6ovw6jl000hsf0knn547w0y",
- "isPrivate": true,
- "surveys": ["cm6ovw6j7000gsf0kduf4oo4i"],
- "title": "cm6ovw6j7000gsf0kduf4oo4i",
- "updatedAt": "2025-02-03T10:04:21.922Z"
- },
- "showLanguageSwitch": null,
- "status": "inProgress",
- "styling": {
- "background": {
- "bg": "#fff",
- "bgType": "color"
- },
- "brandColor": {
- "light": "#60fa0d"
- },
- "cardArrangement": {
- "appSurveys": "straight",
- "linkSurveys": "straight"
- },
- "cardBackgroundColor": {
- "light": "#ffffff"
- },
- "cardBorderColor": {
- "light": "#f8fafc"
- },
- "inputBorderColor": {
- "light": "#090e14"
- },
- "inputColor": {
- "light": "#ffffff"
- },
- "isDarkModeEnabled": false,
- "isLogoHidden": false,
- "overwriteThemeStyling": true,
- "questionColor": {
- "light": "#3a09ff"
- },
- "roundness": 8
- },
- "triggers": [
- {
- "actionClass": {
- "name": "Clicked the demo button"
- }
- }
- ],
- "type": "app",
- "variables": [],
- "welcomeCard": {
- "buttonLabel": {
- "default": "Next"
- },
- "enabled": false,
- "fileUrl": "",
- "headline": {
- "default": "Welcome!"
- },
- "html": {
- "default": "Thanks for providing your feedback - let's go!
"
- },
- "showResponseCount": false,
- "timeToFinish": false
- }
- }
- ]
- },
- "expiresAt": "2035-03-06T10:33:38.647Z"
- }
-}
diff --git a/packages/android/formbricksSDK/src/androidTest/resources/User.json b/packages/android/formbricksSDK/src/androidTest/resources/User.json
deleted file mode 100644
index 31cc23b6e4..0000000000
--- a/packages/android/formbricksSDK/src/androidTest/resources/User.json
+++ /dev/null
@@ -1,15 +0,0 @@
-{
- "data": {
- "state": {
- "data": {
- "contactId": "cm6ovw6jl000hsf0knn547xyz",
- "displays": [],
- "lastDisplayAt": null,
- "responses": [],
- "segments": ["cm6ovw6jl000hsf0knn547w0y"],
- "userId": "6CCCE716-6783-4D0F-8344-9C7DFA43D8F7"
- },
- "expiresAt": "2035-03-06T10:59:32.359Z"
- }
- }
-}
diff --git a/packages/android/formbricksSDK/src/main/AndroidManifest.xml b/packages/android/formbricksSDK/src/main/AndroidManifest.xml
deleted file mode 100644
index f4a35545b1..0000000000
--- a/packages/android/formbricksSDK/src/main/AndroidManifest.xml
+++ /dev/null
@@ -1,6 +0,0 @@
-
-
-
-
-
-
\ No newline at end of file
diff --git a/packages/android/formbricksSDK/src/main/java/com/formbricks/formbrickssdk/Formbricks.kt b/packages/android/formbricksSDK/src/main/java/com/formbricks/formbrickssdk/Formbricks.kt
deleted file mode 100644
index 944d6217b8..0000000000
--- a/packages/android/formbricksSDK/src/main/java/com/formbricks/formbrickssdk/Formbricks.kt
+++ /dev/null
@@ -1,256 +0,0 @@
-package com.formbricks.formbrickssdk
-
-import android.content.Context
-import android.net.ConnectivityManager
-import android.net.NetworkCapabilities
-import androidx.annotation.Keep
-import androidx.fragment.app.FragmentManager
-import com.formbricks.formbrickssdk.api.FormbricksApi
-import com.formbricks.formbrickssdk.helper.FormbricksConfig
-import com.formbricks.formbrickssdk.logger.Logger
-import com.formbricks.formbrickssdk.manager.SurveyManager
-import com.formbricks.formbrickssdk.manager.UserManager
-import com.formbricks.formbrickssdk.model.enums.SuccessType
-import com.formbricks.formbrickssdk.model.error.SDKError
-import com.formbricks.formbrickssdk.webview.FormbricksFragment
-import java.lang.RuntimeException
-
-@Keep
-interface FormbricksCallback {
- fun onSurveyStarted()
- fun onSurveyFinished()
- fun onSurveyClosed()
- fun onPageCommitVisible()
- fun onError(error: Exception)
- fun onSuccess(successType: SuccessType)
-}
-
-
-@Keep
-object Formbricks {
- internal lateinit var applicationContext: Context
-
- internal lateinit var environmentId: String
- internal lateinit var appUrl: String
- internal var language: String = "default"
- internal var loggingEnabled: Boolean = true
- private var fragmentManager: FragmentManager? = null
- internal var isInitialized = false
-
- var callback: FormbricksCallback? = null
-
- /**
- * Initializes the Formbricks SDK with the given [Context] config [FormbricksConfig].
- * This method is mandatory to be called, and should be only once per application lifecycle.
- * To show a survey, the SDK needs a [FragmentManager] instance.
- *
- * ```
- * class MainActivity : FragmentActivity() {
- *
- * override fun onCreate() {
- * super.onCreate()
- * val config = FormbricksConfig.Builder("http://localhost:3000","my_environment_id")
- * .setLoggingEnabled(true)
- * .setFragmentManager(supportFragmentManager)
- * .build())
- * Formbricks.setup(this, config.build())
- * }
- * }
- * ```
- *
- */
- fun setup(context: Context, config: FormbricksConfig, forceRefresh: Boolean = false) {
- if (isInitialized && !forceRefresh) {
- val error = SDKError.sdkIsAlreadyInitialized
- callback?.onError(error)
- Logger.e(error)
- return
- }
-
- applicationContext = context
-
- appUrl = config.appUrl
- environmentId = config.environmentId
- loggingEnabled = config.loggingEnabled
- fragmentManager = config.fragmentManager
-
- config.userId?.let { UserManager.set(it) }
- config.attributes?.let { UserManager.setAttributes(it) }
- config.attributes?.get("language")?.let { UserManager.setLanguage(it) }
-
- FormbricksApi.initialize()
- SurveyManager.refreshEnvironmentIfNeeded(force = forceRefresh)
- UserManager.syncUserStateIfNeeded()
-
- isInitialized = true
- }
-
- /**
- * Sets the user id for the current user with the given [String].
- * The SDK must be initialized before calling this method.
- *
- * ```
- * Formbricks.setUserId("my_user_id")
- * ```
- *
- */
- fun setUserId(userId: String) {
- if (!isInitialized) {
- val error = SDKError.sdkIsNotInitialized
- callback?.onError(error)
- Logger.e(error)
- return
- }
-
- if(UserManager.userId != null) {
- val error = RuntimeException("A userId is already set ${UserManager.userId} - please call logout first before setting a new one")
- callback?.onError(error)
- Logger.e(error)
- return
- }
-
- UserManager.set(userId)
- }
-
- /**
- * Adds an attribute for the current user with the given [String] value and [String] key.
- * The SDK must be initialized before calling this method.
- *
- * ```
- * Formbricks.setAttribute("my_attribute", "key")
- * ```
- *
- */
- fun setAttribute(attribute: String, key: String) {
- if (!isInitialized) {
- val error = SDKError.sdkIsNotInitialized
- callback?.onError(error)
- Logger.e(error)
- return
- }
- UserManager.addAttribute(attribute, key)
- }
-
- /**
- * Sets the user attributes for the current user with the given [Map] of [String] values and [String] keys.
- * The SDK must be initialized before calling this method.
- *
- * ```
- * Formbricks.setAttributes(mapOf(Pair("key", "my_attribute")))
- * ```
- *
- */
- fun setAttributes(attributes: Map) {
- if (!isInitialized) {
- val error = SDKError.sdkIsNotInitialized
- callback?.onError(error)
- Logger.e(error)
- return
- }
- UserManager.setAttributes(attributes)
- }
-
- /**
- * Sets the language for the current user with the given [String].
- * The SDK must be initialized before calling this method.
- *
- * ```
- * Formbricks.setLanguage("de")
- * ```
- *
- */
- fun setLanguage(language: String) {
- if (!isInitialized) {
- val error = SDKError.sdkIsNotInitialized
- callback?.onError(error)
- Logger.e(error)
- return
- }
- Formbricks.language = language
- UserManager.setLanguage(language)
- }
-
- /**
- * Tracks an action with the given [String]. The SDK will process the action and it will present the survey if any of them can be triggered.
- * The SDK must be initialized before calling this method.
- *
- * ```
- * Formbricks.track("button_clicked")
- * ```
- *
- */
- fun track(action: String) {
- if (!isInitialized) {
- val error = SDKError.sdkIsNotInitialized
- callback?.onError(error)
- Logger.e(error)
- return
- }
-
- if (!isInternetAvailable()) {
- val error = SDKError.connectionIsNotAvailable
- callback?.onError(error)
- Logger.e(error)
- return
- }
-
- SurveyManager.track(action)
- }
-
- /**
- * Logs out the current user. This will clear the user attributes and the user id.
- * The SDK must be initialized before calling this method.
- *
- * ```
- * Formbricks.logout()
- * ```
- *
- */
- fun logout() {
- if (!isInitialized) {
- val error = SDKError.sdkIsNotInitialized
- callback?.onError(error)
- Logger.e(error)
- return
- }
-
- callback?.onSuccess(SuccessType.LOGOUT_SUCCESS)
- UserManager.logout()
- }
-
- /**
- * Sets the [FragmentManager] instance. The SDK always needs the actual [FragmentManager] to
- * display surveys, so make sure you update it whenever it changes.
- * The SDK must be initialized before calling this method.
- *
- * ```
- * Formbricks.setFragmentManager(supportFragmentMananger)
- * ```
- *
- */
- fun setFragmentManager(fragmentManager: FragmentManager) {
- this.fragmentManager = fragmentManager
- }
-
- /// Assembles the survey fragment and presents it
- internal fun showSurvey(id: String) {
- if (fragmentManager == null) {
- val error = SDKError.fragmentManagerIsNotSet
- callback?.onError(error)
- Logger.e(error)
- return
- }
-
- fragmentManager?.let {
- FormbricksFragment.show(it, surveyId = id)
- }
- }
-
- /// Checks if the phone has active network connection
- private fun isInternetAvailable(): Boolean {
- val connectivityManager = applicationContext.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
- val network = connectivityManager.activeNetwork ?: return false
- val capabilities = connectivityManager.getNetworkCapabilities(network) ?: return false
- return capabilities.hasCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
- }
-}
\ No newline at end of file
diff --git a/packages/android/formbricksSDK/src/main/java/com/formbricks/formbrickssdk/api/FormbricksApi.kt b/packages/android/formbricksSDK/src/main/java/com/formbricks/formbrickssdk/api/FormbricksApi.kt
deleted file mode 100644
index 81435e4502..0000000000
--- a/packages/android/formbricksSDK/src/main/java/com/formbricks/formbrickssdk/api/FormbricksApi.kt
+++ /dev/null
@@ -1,58 +0,0 @@
-package com.formbricks.formbrickssdk.api
-
-import com.formbricks.formbrickssdk.Formbricks
-import com.formbricks.formbrickssdk.model.environment.EnvironmentDataHolder
-import com.formbricks.formbrickssdk.model.user.PostUserBody
-import com.formbricks.formbrickssdk.model.user.UserResponse
-import com.formbricks.formbrickssdk.network.FormbricksApiService
-import kotlinx.coroutines.Dispatchers
-import kotlinx.coroutines.delay
-import kotlinx.coroutines.withContext
-
-object FormbricksApi {
- var service = FormbricksApiService()
-
- private suspend fun retryApiCall(
- retries: Int = 2,
- delayTime: Long = 1000,
- block: suspend () -> Result
- ): Result {
- repeat(retries) { attempt ->
- val result = block()
- if (result.isSuccess) return result
- println("⚠️ Retry ${attempt + 1} due to error: ${result.exceptionOrNull()?.localizedMessage}")
- delay(delayTime)
- }
- return block()
- }
-
- fun initialize() {
- service.initialize(
- appUrl = Formbricks.appUrl,
- isLoggingEnabled = Formbricks.loggingEnabled
- )
- }
-
- suspend fun getEnvironmentState(): Result = withContext(Dispatchers.IO) {
- retryApiCall {
- try {
- val response = service.getEnvironmentStateObject(Formbricks.environmentId)
- val result = response.getOrThrow()
- Result.success(result)
- } catch (e: Exception) {
- Result.failure(e)
- }
- }
- }
-
- suspend fun postUser(userId: String, attributes: Map?): Result = withContext(Dispatchers.IO) {
- retryApiCall {
- try {
- val result = service.postUser(Formbricks.environmentId, PostUserBody.create(userId, attributes)).getOrThrow()
- Result.success(result)
- } catch (e: Exception) {
- Result.failure(e)
- }
- }
- }
-}
\ No newline at end of file
diff --git a/packages/android/formbricksSDK/src/main/java/com/formbricks/formbrickssdk/api/error/FormbricksAPIError.kt b/packages/android/formbricksSDK/src/main/java/com/formbricks/formbrickssdk/api/error/FormbricksAPIError.kt
deleted file mode 100644
index d7b02fe82d..0000000000
--- a/packages/android/formbricksSDK/src/main/java/com/formbricks/formbrickssdk/api/error/FormbricksAPIError.kt
+++ /dev/null
@@ -1,9 +0,0 @@
-package com.formbricks.formbrickssdk.api.error
-
-import com.google.gson.annotations.SerializedName
-
-data class FormbricksAPIError(
- @SerializedName("code") val code: String,
- @SerializedName("message") val messageText: String,
- @SerializedName("details") val details: Map? = null
-) : RuntimeException(messageText)
\ No newline at end of file
diff --git a/packages/android/formbricksSDK/src/main/java/com/formbricks/formbrickssdk/extensions/DateExtensions.kt b/packages/android/formbricksSDK/src/main/java/com/formbricks/formbrickssdk/extensions/DateExtensions.kt
deleted file mode 100644
index eb78ed22e7..0000000000
--- a/packages/android/formbricksSDK/src/main/java/com/formbricks/formbrickssdk/extensions/DateExtensions.kt
+++ /dev/null
@@ -1,59 +0,0 @@
-package com.formbricks.formbrickssdk.extensions
-
-import com.formbricks.formbrickssdk.model.environment.EnvironmentDataHolder
-import com.formbricks.formbrickssdk.model.user.UserState
-import com.formbricks.formbrickssdk.model.user.UserStateData
-import java.text.SimpleDateFormat
-import java.util.Date
-import java.util.Locale
-import java.util.TimeZone
-
-internal const val dateFormatPattern = "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'"
-
-fun Date.dateString(): String {
- val dateFormat = SimpleDateFormat(dateFormatPattern, Locale.getDefault())
- dateFormat.timeZone = TimeZone.getTimeZone("UTC")
- return dateFormat.format(this)
-}
-
-fun UserStateData.lastDisplayAt(): Date? {
- lastDisplayAt?.let {
- try {
- val formatter = SimpleDateFormat(dateFormatPattern, Locale.getDefault())
- formatter.timeZone = TimeZone.getTimeZone("UTC")
- return formatter.parse(it)
- } catch (e: Exception) {
- return null
- }
- }
-
- return null
-}
-
-fun UserState.expiresAt(): Date? {
- expiresAt?.let {
- try {
- val formatter = SimpleDateFormat(dateFormatPattern, Locale.getDefault())
- formatter.timeZone = TimeZone.getTimeZone("UTC")
- return formatter.parse(it)
- } catch (e: Exception) {
- return null
- }
- }
-
- return null
-}
-
-fun EnvironmentDataHolder.expiresAt(): Date? {
- data?.expiresAt?.let {
- try {
- val formatter = SimpleDateFormat(dateFormatPattern, Locale.getDefault())
- formatter.timeZone = TimeZone.getTimeZone("UTC")
- return formatter.parse(it)
- } catch (e: Exception) {
- return null
- }
- }
-
- return null
-}
\ No newline at end of file
diff --git a/packages/android/formbricksSDK/src/main/java/com/formbricks/formbrickssdk/extensions/Guard.kt b/packages/android/formbricksSDK/src/main/java/com/formbricks/formbrickssdk/extensions/Guard.kt
deleted file mode 100644
index 783816e024..0000000000
--- a/packages/android/formbricksSDK/src/main/java/com/formbricks/formbrickssdk/extensions/Guard.kt
+++ /dev/null
@@ -1,33 +0,0 @@
-package com.formbricks.formbrickssdk.extensions
-
-/**
- * Swift like guard statement.
- * To achieve that, on null the statement must return an empty T object
- */
-inline fun T?.guard(block: T?.() -> Unit): T {
- this?.let {
- return it
- } ?: run {
- block()
- }
-
- return T::class.java.newInstance()
-}
-
-inline fun String?.guardEmpty(block: String?.() -> Unit): String {
- if (isNullOrBlank()) {
- block()
- } else {
- return this
- }
-
- return ""
-}
-
-inline fun guardLet(vararg elements: T?, closure: () -> Nothing): List {
- return if (elements.all { it != null }) {
- elements.filterNotNull()
- } else {
- closure()
- }
-}
diff --git a/packages/android/formbricksSDK/src/main/java/com/formbricks/formbrickssdk/helper/FormbricksConfig.kt b/packages/android/formbricksSDK/src/main/java/com/formbricks/formbrickssdk/helper/FormbricksConfig.kt
deleted file mode 100644
index 8e7cd9a364..0000000000
--- a/packages/android/formbricksSDK/src/main/java/com/formbricks/formbrickssdk/helper/FormbricksConfig.kt
+++ /dev/null
@@ -1,62 +0,0 @@
-package com.formbricks.formbrickssdk.helper
-
-import androidx.annotation.Keep
-import androidx.fragment.app.FragmentManager
-
-/**
- * Configuration options for the SDK
- *
- * Use the [Builder] to configure the options, then pass the result of [build] to the setup method.
- */
-@Keep
-class FormbricksConfig private constructor(
- val appUrl: String,
- val environmentId: String,
- val userId: String?,
- val attributes: Map?,
- val loggingEnabled: Boolean,
- val fragmentManager: FragmentManager?
-) {
- class Builder(private val appUrl: String, private val environmentId: String) {
- private var userId: String? = null
- private var attributes: MutableMap = mutableMapOf()
- private var loggingEnabled = false
- private var fragmentManager: FragmentManager? = null
-
- fun setUserId(userId: String): Builder {
- this.userId = userId
- return this
- }
-
- fun setAttributes(attributes: MutableMap): Builder {
- this.attributes = attributes
- return this
- }
-
- fun addAttribute(attribute: String, key: String): Builder {
- this.attributes[key] = attribute
- return this
- }
-
- fun setLoggingEnabled(loggingEnabled: Boolean): Builder {
- this.loggingEnabled = loggingEnabled
- return this
- }
-
- fun setFragmentManager(fragmentManager: FragmentManager): Builder {
- this.fragmentManager = fragmentManager
- return this
- }
-
- fun build(): FormbricksConfig {
- return FormbricksConfig(
- appUrl = appUrl,
- environmentId = environmentId,
- userId = userId,
- attributes = attributes,
- loggingEnabled = loggingEnabled,
- fragmentManager = fragmentManager
- )
- }
- }
-}
\ No newline at end of file
diff --git a/packages/android/formbricksSDK/src/main/java/com/formbricks/formbrickssdk/helper/JsonHelper.kt b/packages/android/formbricksSDK/src/main/java/com/formbricks/formbrickssdk/helper/JsonHelper.kt
deleted file mode 100644
index 8e425cc636..0000000000
--- a/packages/android/formbricksSDK/src/main/java/com/formbricks/formbrickssdk/helper/JsonHelper.kt
+++ /dev/null
@@ -1,44 +0,0 @@
-package com.formbricks.formbrickssdk.helper
-
-import kotlinx.serialization.json.JsonArray
-import kotlinx.serialization.json.JsonElement
-import kotlinx.serialization.json.JsonNull
-import kotlinx.serialization.json.JsonPrimitive
-import kotlinx.serialization.json.buildJsonObject
-import kotlinx.serialization.json.put
-
-fun mapToJsonElement(map: Map): JsonElement {
- return buildJsonObject {
- map.forEach { (key, value) ->
- when (value) {
- is String -> put(key, value)
- is Number -> put(key, value)
- is Boolean -> put(key, value)
- is Map<*, *> -> {
- @Suppress("UNCHECKED_CAST")
- put(key, mapToJsonElement(value as Map))
- }
- is List<*> -> {
- put(key, JsonArray(value.map { elem -> mapToJsonElementItem(elem) }))
- }
- null -> put(key, JsonNull)
- else -> throw IllegalArgumentException("Unsupported type: ${value::class}")
- }
- }
- }
-}
-
-fun mapToJsonElementItem(value: Any?): JsonElement {
- return when (value) {
- is String -> JsonPrimitive(value)
- is Number -> JsonPrimitive(value)
- is Boolean -> JsonPrimitive(value)
- is Map<*, *> -> {
- @Suppress("UNCHECKED_CAST")
- mapToJsonElement(value as Map)
- }
- is List<*> -> JsonArray(value.map { elem -> mapToJsonElementItem(elem) })
- null -> JsonNull
- else -> throw IllegalArgumentException("Unsupported type: ${value::class}")
- }
-}
\ No newline at end of file
diff --git a/packages/android/formbricksSDK/src/main/java/com/formbricks/formbrickssdk/logger/Logger.kt b/packages/android/formbricksSDK/src/main/java/com/formbricks/formbrickssdk/logger/Logger.kt
deleted file mode 100644
index 682fd5fa43..0000000000
--- a/packages/android/formbricksSDK/src/main/java/com/formbricks/formbrickssdk/logger/Logger.kt
+++ /dev/null
@@ -1,24 +0,0 @@
-package com.formbricks.formbrickssdk.logger
-
-import android.util.Log
-import com.formbricks.formbrickssdk.Formbricks
-
-object Logger {
- fun d(message: String) {
- if (Formbricks.loggingEnabled) {
- Log.d("FormbricksSDK", message)
- }
- }
-
- fun e(exception: RuntimeException) {
- if (Formbricks.loggingEnabled) {
- Log.e("FormbricksSDK", exception.localizedMessage, exception)
- }
- }
-
- fun w(message: String? = "Warning", exception: RuntimeException? = null) {
- if (Formbricks.loggingEnabled) {
- Log.w("FormbricksSDK", message, exception)
- }
- }
-}
\ No newline at end of file
diff --git a/packages/android/formbricksSDK/src/main/java/com/formbricks/formbrickssdk/manager/SurveyManager.kt b/packages/android/formbricksSDK/src/main/java/com/formbricks/formbrickssdk/manager/SurveyManager.kt
deleted file mode 100644
index d9380c4d4b..0000000000
--- a/packages/android/formbricksSDK/src/main/java/com/formbricks/formbrickssdk/manager/SurveyManager.kt
+++ /dev/null
@@ -1,351 +0,0 @@
-package com.formbricks.formbrickssdk.manager
-
-import android.content.Context
-import com.formbricks.formbrickssdk.Formbricks
-import com.formbricks.formbrickssdk.api.FormbricksApi
-import com.formbricks.formbrickssdk.extensions.expiresAt
-import com.formbricks.formbrickssdk.extensions.guard
-import com.formbricks.formbrickssdk.logger.Logger
-import com.formbricks.formbrickssdk.model.environment.EnvironmentDataHolder
-import com.formbricks.formbrickssdk.model.environment.Survey
-import com.formbricks.formbrickssdk.model.error.SDKError
-import com.formbricks.formbrickssdk.model.enums.SuccessType
-import com.formbricks.formbrickssdk.model.user.Display
-import com.google.gson.Gson
-import kotlinx.coroutines.CoroutineScope
-import kotlinx.coroutines.Dispatchers
-import kotlinx.coroutines.launch
-import java.lang.RuntimeException
-import java.util.Date
-import java.util.Timer
-import java.util.TimerTask
-import java.util.concurrent.TimeUnit
-
-/**
- * The SurveyManager is responsible for managing the surveys that are displayed to the user.
- * Filtering surveys based on the user's segments, responses, and displays.
- */
-object SurveyManager {
- private const val REFRESH_STATE_ON_ERROR_TIMEOUT_IN_MINUTES = 10
- private const val FORMBRICKS_PREFS = "formbricks_prefs"
- private const val PREF_FORMBRICKS_DATA_HOLDER = "formbricksDataHolder"
-
- internal val refreshTimer = Timer()
- internal var displayTimer = Timer()
- internal var hasApiError = false
- internal var isShowingSurvey = false
- private val prefManager by lazy { Formbricks.applicationContext.getSharedPreferences(FORMBRICKS_PREFS, Context.MODE_PRIVATE) }
- internal var filteredSurveys: MutableList = mutableListOf()
-
- private var environmentDataHolderJson: String?
- get() {
- return prefManager.getString(PREF_FORMBRICKS_DATA_HOLDER, "")
- }
- set(value) {
- if (null != value) {
- prefManager.edit().putString(PREF_FORMBRICKS_DATA_HOLDER, value).apply()
- } else {
- prefManager.edit().remove(PREF_FORMBRICKS_DATA_HOLDER).apply()
- }
- }
-
- private var backingEnvironmentDataHolder: EnvironmentDataHolder? = null
- var environmentDataHolder: EnvironmentDataHolder?
- get() {
- if (null != backingEnvironmentDataHolder) {
- return backingEnvironmentDataHolder
- }
- synchronized(this) {
- backingEnvironmentDataHolder = environmentDataHolderJson?.let { json ->
- try {
- Gson().fromJson(json, EnvironmentDataHolder::class.java)
- } catch (e: Exception) {
- Formbricks.callback?.onError(e)
- Logger.e(RuntimeException("Unable to retrieve environment data from the local storage."))
- null
- }
- }
- return backingEnvironmentDataHolder
- }
- }
- set(value) {
- synchronized(this) {
- backingEnvironmentDataHolder = value
- environmentDataHolderJson = Gson().toJson(value)
- }
- }
-
- /**
- * Fills up the [filteredSurveys] array
- */
- fun filterSurveys() {
- val surveys = environmentDataHolder?.data?.data?.surveys.guard { return }
- val displays = UserManager.displays ?: listOf()
- val responses = UserManager.responses ?: listOf()
- val segments = UserManager.segments ?: listOf()
-
- filteredSurveys = filterSurveysBasedOnDisplayType(surveys, displays, responses).toMutableList()
- filteredSurveys = filterSurveysBasedOnRecontactDays(filteredSurveys, environmentDataHolder?.data?.data?.project?.recontactDays?.toInt()).toMutableList()
-
- if (UserManager.userId != null) {
- if (segments.isEmpty()) {
- filteredSurveys = mutableListOf()
- return
- }
-
- filteredSurveys = filterSurveysBasedOnSegments(filteredSurveys, segments).toMutableList()
- }
- }
-
- /**
- * Checks if the environment state needs to be refreshed based on its [expiresAt] property,
- * and if so, refreshes it, starts the refresh timer, and filters the surveys.
- */
- fun refreshEnvironmentIfNeeded(force: Boolean = false) {
- if (!force) {
- environmentDataHolder?.expiresAt()?.let {
- if (it.after(Date())) {
- Logger.d("Environment state is still valid until $it")
- filterSurveys()
- return
- }
- }
- }
-
- CoroutineScope(Dispatchers.IO).launch {
- try {
- environmentDataHolder = FormbricksApi.getEnvironmentState().getOrThrow()
- startRefreshTimer(environmentDataHolder?.expiresAt())
- filterSurveys()
- hasApiError = false
- Formbricks.callback?.onSuccess(SuccessType.GET_ENVIRONMENT_SUCCESS)
- } catch (e: Exception) {
- hasApiError = true
- val error = SDKError.unableToRefreshEnvironment
- Formbricks.callback?.onError(error)
- Logger.e(error)
- startErrorTimer()
- }
- }
- }
-
- /**
- * Checks if there are any surveys to display, based in the track action, and if so, displays the first one.
- * Handles the display percentage and the delay of the survey.
- */
- fun track(action: String) {
- val actionClasses = environmentDataHolder?.data?.data?.actionClasses ?: listOf()
- val codeActionClasses = actionClasses.filter { it.type == "code" }
- val actionClass = codeActionClasses.firstOrNull { it.key == action }
- val firstSurveyWithActionClass = filteredSurveys.firstOrNull { survey ->
- val triggers = survey.triggers ?: listOf()
- triggers.firstOrNull { it.actionClass?.name.equals(actionClass?.name) } != null
- }
-
- if (firstSurveyWithActionClass == null) {
- Formbricks.callback?.onError(SDKError.surveyNotFoundError)
- return
- }
-
- val isMultiLangSurvey = (firstSurveyWithActionClass.languages?.size ?: 0) > 1
- if(isMultiLangSurvey) {
- val currentLanguage = Formbricks.language
- val languageCode = getLanguageCode(firstSurveyWithActionClass, currentLanguage)
-
- if (languageCode == null) {
- val error = RuntimeException("Survey “${firstSurveyWithActionClass.name}” is not available in language “$currentLanguage”. Skipping.")
- Formbricks.callback?.onError(error)
- Logger.e(error)
- return
- }
-
- Formbricks.setLanguage(languageCode)
- }
-
- val shouldDisplay = shouldDisplayBasedOnPercentage(firstSurveyWithActionClass.displayPercentage)
-
- if (shouldDisplay) {
- firstSurveyWithActionClass.id.let {
- isShowingSurvey = true
- val timeout = firstSurveyWithActionClass.delay ?: 0.0
- stopDisplayTimer()
- displayTimer.schedule(object : TimerTask() {
- override fun run() {
- Formbricks.showSurvey(it)
- }
-
- }, Date(System.currentTimeMillis() + timeout.toLong() * 1000))
- }
- } else {
- Formbricks.callback?.onError(SDKError.surveyNotDisplayedError)
- }
- }
-
- private fun stopDisplayTimer() {
- displayTimer.cancel()
- displayTimer = Timer()
- }
-
- /**
- * Posts a survey response to the Formbricks API.
- */
- fun postResponse(surveyId: String?) {
- val id = surveyId.guard {
- val error = SDKError.missingSurveyId
- Formbricks.callback?.onError(error)
- Logger.e(error)
- return
- }
-
- UserManager.onResponse(id)
- }
-
- /**
- * Creates a new display for the survey. It is called when the survey is displayed to the user.
- */
- fun onNewDisplay(surveyId: String?) {
- val id = surveyId.guard {
- val error = SDKError.missingSurveyId
- Formbricks.callback?.onError(error)
- Logger.e(error)
- return
- }
-
- UserManager.onDisplay(id)
- }
-
- /**
- * Starts a timer to refresh the environment state after the given timeout [expiresAt].
- */
- private fun startRefreshTimer(expiresAt: Date?) {
- val date = expiresAt.guard { return }
- refreshTimer.schedule(object: TimerTask() {
- override fun run() {
- Logger.d("Refreshing environment state.")
- refreshEnvironmentIfNeeded()
- }
-
- }, date)
- }
-
- /**
- * When an error occurs, it starts a timer to refresh the environment state after the given timeout.
- */
- private fun startErrorTimer() {
- val targetDate = Date(System.currentTimeMillis() + 1000 * 60 * REFRESH_STATE_ON_ERROR_TIMEOUT_IN_MINUTES)
- refreshTimer.schedule(object: TimerTask() {
- override fun run() {
- Logger.d("Refreshing environment state after an error")
- refreshEnvironmentIfNeeded()
- }
-
- }, targetDate)
- }
-
- /**
- * Filters the surveys based on the display type and limit.
- */
- private fun filterSurveysBasedOnDisplayType(surveys: List, displays: List, responses: List): List {
- return surveys.filter { survey ->
- when (survey.displayOption) {
- "respondMultiple" -> true
-
- "displayOnce" -> {
- displays.none { it.surveyId == survey.id }
- }
-
- "displayMultiple" -> {
- responses.none { it == survey.id }
- }
-
- "displaySome" -> {
- survey.displayLimit?.let { limit ->
- if (responses.any { it == survey.id }) {
- return@filter false
- }
- displays.count { it.surveyId == survey.id } < limit
- } ?: true
- }
-
- else -> {
- val error = SDKError.invalidDisplayOption
- Formbricks.callback?.onError(error)
- Logger.e(error)
- false
- }
- }
- }
- }
-
- /**
- * Filters the surveys based on the recontact days and the [UserManager.lastDisplayedAt] date.
- */
- private fun filterSurveysBasedOnRecontactDays(surveys: List, defaultRecontactDays: Int?): List {
- return surveys.filter { survey ->
- val lastDisplayedAt = UserManager.lastDisplayedAt.guard { return@filter true }
-
- val recontactDays = survey.recontactDays ?: defaultRecontactDays
-
- if (recontactDays != null) {
- val daysBetween = TimeUnit.MILLISECONDS.toDays(Date().time - lastDisplayedAt.time)
- return@filter daysBetween >= recontactDays.toInt()
- }
-
- true
- }
- }
-
- /**
- * Filters the surveys based on the user's segments.
- */
- private fun filterSurveysBasedOnSegments(surveys: List, segments: List): List {
- return surveys.filter { survey ->
- val segmentId = survey.segment?.id?.guard { return@filter false }
- segments.contains(segmentId)
- }
- }
-
- /**
- * Decides if the survey should be displayed based on the display percentage.
- */
- private fun shouldDisplayBasedOnPercentage(displayPercentage: Double?): Boolean {
- val percentage = displayPercentage.guard { return true }
- val randomNum = (0 until 10000).random() / 100.0
- return randomNum <= percentage
- }
-
- private fun getLanguageCode(survey: Survey, language: String?): String? {
- // 1) Gather all valid codes
- val availableLanguageCodes = survey.languages
- ?.map { it.language.code }
- ?: emptyList()
-
- // 2) No input or explicit "default" → default
- val raw = language
- ?.lowercase()
- ?.takeIf { it.isNotEmpty() }
- ?: return "default"
- if (raw == "default") return "default"
-
- // 3) Find matching entry by code or alias
- val selected = survey.languages
- ?.firstOrNull { entry ->
- entry.language.code.lowercase() == raw ||
- entry.language.alias?.lowercase() == raw
- }
-
- // 4) If that entry is marked default → default
- if (selected?.default == true) return "default"
-
- // 5) If missing, disabled, or not in the available list → null
- if (selected == null
- || !selected.enabled
- || !availableLanguageCodes.contains(selected.language.code)
- ) {
- return null
- }
-
- // 6) Otherwise return its code
- return selected.language.code
- }
-}
\ No newline at end of file
diff --git a/packages/android/formbricksSDK/src/main/java/com/formbricks/formbrickssdk/manager/UserManager.kt b/packages/android/formbricksSDK/src/main/java/com/formbricks/formbrickssdk/manager/UserManager.kt
deleted file mode 100644
index 2a59ea6b5b..0000000000
--- a/packages/android/formbricksSDK/src/main/java/com/formbricks/formbrickssdk/manager/UserManager.kt
+++ /dev/null
@@ -1,265 +0,0 @@
-package com.formbricks.formbrickssdk.manager
-
-import android.content.Context
-import com.formbricks.formbrickssdk.Formbricks
-import com.formbricks.formbrickssdk.api.FormbricksApi
-import com.formbricks.formbrickssdk.extensions.dateString
-import com.formbricks.formbrickssdk.extensions.expiresAt
-import com.formbricks.formbrickssdk.extensions.guard
-import com.formbricks.formbrickssdk.extensions.lastDisplayAt
-import com.formbricks.formbrickssdk.logger.Logger
-import com.formbricks.formbrickssdk.model.error.SDKError
-import com.formbricks.formbrickssdk.model.enums.SuccessType
-import com.formbricks.formbrickssdk.model.user.Display
-import com.formbricks.formbrickssdk.network.queue.UpdateQueue
-import com.google.gson.Gson
-import kotlinx.coroutines.CoroutineScope
-import kotlinx.coroutines.Dispatchers
-import kotlinx.coroutines.launch
-import java.util.Date
-import java.util.Timer
-import java.util.TimerTask
-
-/**
- * Store and manage user state and sync with the server when needed.
- */
-object UserManager {
- private const val FORMBROCKS_PERFS = "formbricks_prefs"
- private const val USER_ID_KEY = "userIdKey"
- private const val CONTACT_ID_KEY = "contactIdKey"
- private const val SEGMENTS_KEY = "segmentsKey"
- private const val DISPLAYS_KEY = "displaysKey"
- private const val RESPONSES_KEY = "responsesKey"
- private const val LAST_DISPLAYED_AT_KEY = "lastDisplayedAtKey"
- private const val EXPIRES_AT_KEY = "expiresAtKey"
- private val prefManager by lazy { Formbricks.applicationContext.getSharedPreferences(FORMBROCKS_PERFS, Context.MODE_PRIVATE) }
-
- private var backingUserId: String? = null
- private var backingContactId: String? = null
- private var backingSegments: List? = null
- private var backingDisplays: List? = null
- private var backingResponses: List? = null
- private var backingLastDisplayedAt: Date? = null
- private var backingExpiresAt: Date? = null
- internal val syncTimer = Timer()
-
- /**
- * Starts an update queue with the given user id.
- *
- * @param userId
- */
- fun set(userId: String) {
- UpdateQueue.current.setUserId(userId)
- }
-
- /**
- * Starts an update queue with the given attribute.
- *
- * @param attribute
- * @param key
- */
- fun addAttribute(attribute: String, key: String) {
- UpdateQueue.current.addAttribute(key, attribute)
- }
-
- /**
- * Starts an update queue with the given attributes.
- *
- * @param attributes
- */
- fun setAttributes(attributes: Map) {
- UpdateQueue.current.setAttributes(attributes)
- }
-
- /**
- * Starts an update queue with the given language..
- *
- * @param language
- */
- fun setLanguage(language: String) {
- UpdateQueue.current.setLanguage(language)
- }
-
- /**
- * Saves [surveyId] to the [displays] property and the the current date to the [lastDisplayedAt] property.
- *
- * @param surveyId
- */
- fun onDisplay(surveyId: String) {
- val lastDisplayedAt = Date()
- val newDisplays = displays?.toMutableList() ?: mutableListOf()
- newDisplays.add(Display(surveyId, lastDisplayedAt.dateString()))
- displays = newDisplays
- this.lastDisplayedAt = lastDisplayedAt
- SurveyManager.filterSurveys()
- }
-
- /**
- * Saves [surveyId] to the [responses] property.
- *
- * @param surveyId
- */
- fun onResponse(surveyId: String) {
- val newResponses = responses?.toMutableList() ?: mutableListOf()
- newResponses.add(surveyId)
- responses = newResponses
- SurveyManager.filterSurveys()
- }
-
- /**
- * Syncs the user state with the server if the user id is set and the expiration date has passed.
- */
- fun syncUserStateIfNeeded() {
- val id = userId
- val expiresAt = expiresAt
- if (id != null && expiresAt != null && Date().before(expiresAt)) {
- syncUser(id)
- } else {
- backingSegments = emptyList()
- backingDisplays = emptyList()
- backingResponses = emptyList()
- }
- }
-
- /**
- * Syncs the user state with the server, calls the [SurveyManager.filterSurveys] method and starts the sync timer.
- *
- * @param id
- * @param attributes
- */
- fun syncUser(id: String, attributes: Map? = null) {
- CoroutineScope(Dispatchers.IO).launch {
- try {
- val userResponse = FormbricksApi.postUser(id, attributes).getOrThrow()
- userId = userResponse.data.state.data.userId
- contactId = userResponse.data.state.data.contactId
- segments = userResponse.data.state.data.segments
- displays = userResponse.data.state.data.displays
- responses = userResponse.data.state.data.responses
- lastDisplayedAt = userResponse.data.state.data.lastDisplayAt()
- expiresAt = userResponse.data.state.expiresAt()
- val languageFromUserResponse = userResponse.data.state.data.language
-
- if(languageFromUserResponse != null) {
- Formbricks.language = languageFromUserResponse
- }
-
- UpdateQueue.current.reset()
- SurveyManager.filterSurveys()
- startSyncTimer()
- Formbricks.callback?.onSuccess(SuccessType.SET_USER_SUCCESS)
- } catch (e: Exception) {
- val error = SDKError.unableToPostResponse
- Formbricks.callback?.onError(error)
- Logger.e(error)
- }
- }
- }
-
- /**
- * Logs out the user and clears the user state.
- */
- fun logout() {
- val isUserIdDefined = userId != null
-
- if (!isUserIdDefined) {
- val error = SDKError.noUserIdSetError
- Formbricks.callback?.onError(error)
- Logger.e(error)
- }
-
- prefManager.edit().apply {
- remove(CONTACT_ID_KEY)
- remove(USER_ID_KEY)
- remove(SEGMENTS_KEY)
- remove(DISPLAYS_KEY)
- remove(RESPONSES_KEY)
- remove(LAST_DISPLAYED_AT_KEY)
- remove(EXPIRES_AT_KEY)
- apply()
- }
-
- backingUserId = null
- backingContactId = null
- backingSegments = null
- backingDisplays = null
- backingResponses = null
- backingLastDisplayedAt = null
- backingExpiresAt = null
- Formbricks.language = "default"
- UpdateQueue.current.reset()
-
- if(isUserIdDefined) {
- Logger.d("User logged out successfully!")
- }
- }
-
- private fun startSyncTimer() {
- val expiresAt = expiresAt.guard { return }
- val userId = userId.guard { return }
- syncTimer.schedule(object: TimerTask() {
- override fun run() {
- syncUser(userId)
- }
-
- }, expiresAt)
- }
-
-
- var userId: String?
- get() = backingUserId ?: prefManager.getString(USER_ID_KEY, null).also { backingUserId = it }
- private set(value) {
- backingUserId = value
- prefManager.edit().putString(USER_ID_KEY, value).apply()
- }
-
- var contactId: String?
- get() = backingContactId ?: prefManager.getString(CONTACT_ID_KEY, null).also { backingContactId = it }
- private set(value) {
- backingContactId = value
- prefManager.edit().putString(CONTACT_ID_KEY, value).apply()
- }
-
- var segments: List?
- get() = backingSegments ?: prefManager.getStringSet(SEGMENTS_KEY, emptySet())?.toList().also { backingSegments = it }
- private set(value) {
- backingSegments = value
- prefManager.edit().putStringSet(SEGMENTS_KEY, value?.toSet()).apply()
- }
-
- var displays: List?
- get() {
- if (backingDisplays == null) {
- val json = prefManager.getString(DISPLAYS_KEY, null)
- if (json != null) {
- backingDisplays = Gson().fromJson(json, Array::class.java).toList()
- }
- }
- return backingDisplays
- }
- private set(value) {
- backingDisplays = value
- prefManager.edit().putString(DISPLAYS_KEY, Gson().toJson(value)).apply()
- }
-
- var responses: List?
- get() = backingResponses ?: prefManager.getStringSet(RESPONSES_KEY, emptySet())?.toList().also { backingResponses = it }
- private set(value) {
- backingResponses = value
- prefManager.edit().putStringSet(RESPONSES_KEY, value?.toSet()).apply()
- }
-
- var lastDisplayedAt: Date?
- get() = backingLastDisplayedAt ?: prefManager.getLong(LAST_DISPLAYED_AT_KEY, 0L).takeIf { it > 0 }?.let { Date(it) }.also { backingLastDisplayedAt = it }
- private set(value) {
- backingLastDisplayedAt = value
- prefManager.edit().putLong(LAST_DISPLAYED_AT_KEY, value?.time ?: 0L).apply()
- }
-
- var expiresAt: Date?
- get() = backingExpiresAt ?: prefManager.getLong(EXPIRES_AT_KEY, 0L).takeIf { it > 0 }?.let { Date(it) }.also { backingExpiresAt = it }
- private set(value) {
- backingExpiresAt = value
- prefManager.edit().putLong(EXPIRES_AT_KEY, value?.time ?: 0L).apply()
- }
-}
\ No newline at end of file
diff --git a/packages/android/formbricksSDK/src/main/java/com/formbricks/formbrickssdk/model/BaseFormbricksResponse.kt b/packages/android/formbricksSDK/src/main/java/com/formbricks/formbrickssdk/model/BaseFormbricksResponse.kt
deleted file mode 100644
index 527586c89e..0000000000
--- a/packages/android/formbricksSDK/src/main/java/com/formbricks/formbrickssdk/model/BaseFormbricksResponse.kt
+++ /dev/null
@@ -1,3 +0,0 @@
-package com.formbricks.formbrickssdk.model
-
-interface BaseFormbricksResponse
\ No newline at end of file
diff --git a/packages/android/formbricksSDK/src/main/java/com/formbricks/formbrickssdk/model/enums/SuccessType.kt b/packages/android/formbricksSDK/src/main/java/com/formbricks/formbrickssdk/model/enums/SuccessType.kt
deleted file mode 100644
index 96a119d715..0000000000
--- a/packages/android/formbricksSDK/src/main/java/com/formbricks/formbrickssdk/model/enums/SuccessType.kt
+++ /dev/null
@@ -1,7 +0,0 @@
-package com.formbricks.formbrickssdk.model.enums
-
-enum class SuccessType {
- SET_USER_SUCCESS,
- GET_ENVIRONMENT_SUCCESS,
- LOGOUT_SUCCESS
-}
\ No newline at end of file
diff --git a/packages/android/formbricksSDK/src/main/java/com/formbricks/formbrickssdk/model/environment/ActionClass.kt b/packages/android/formbricksSDK/src/main/java/com/formbricks/formbrickssdk/model/environment/ActionClass.kt
deleted file mode 100644
index 6bda17d616..0000000000
--- a/packages/android/formbricksSDK/src/main/java/com/formbricks/formbrickssdk/model/environment/ActionClass.kt
+++ /dev/null
@@ -1,12 +0,0 @@
-package com.formbricks.formbrickssdk.model.environment
-
-import com.google.gson.annotations.SerializedName
-import kotlinx.serialization.Serializable
-
-@Serializable
-data class ActionClass(
- @SerializedName("id") val id: String?,
- @SerializedName("type") val type: String?,
- @SerializedName("name") val name: String?,
- @SerializedName("key") val key: String?,
-)
\ No newline at end of file
diff --git a/packages/android/formbricksSDK/src/main/java/com/formbricks/formbrickssdk/model/environment/ActionClassReference.kt b/packages/android/formbricksSDK/src/main/java/com/formbricks/formbrickssdk/model/environment/ActionClassReference.kt
deleted file mode 100644
index 13d43bef2e..0000000000
--- a/packages/android/formbricksSDK/src/main/java/com/formbricks/formbrickssdk/model/environment/ActionClassReference.kt
+++ /dev/null
@@ -1,9 +0,0 @@
-package com.formbricks.formbrickssdk.model.environment
-
-import com.google.gson.annotations.SerializedName
-import kotlinx.serialization.Serializable
-
-@Serializable
-data class ActionClassReference(
- @SerializedName("name") val name: String?
-)
\ No newline at end of file
diff --git a/packages/android/formbricksSDK/src/main/java/com/formbricks/formbrickssdk/model/environment/BrandColor.kt b/packages/android/formbricksSDK/src/main/java/com/formbricks/formbrickssdk/model/environment/BrandColor.kt
deleted file mode 100644
index 0cf5aef4a0..0000000000
--- a/packages/android/formbricksSDK/src/main/java/com/formbricks/formbrickssdk/model/environment/BrandColor.kt
+++ /dev/null
@@ -1,9 +0,0 @@
-package com.formbricks.formbrickssdk.model.environment
-
-import com.google.gson.annotations.SerializedName
-import kotlinx.serialization.Serializable
-
-@Serializable
-data class BrandColor(
- @SerializedName("light") val light: String?
-)
diff --git a/packages/android/formbricksSDK/src/main/java/com/formbricks/formbrickssdk/model/environment/EnvironmentData.kt b/packages/android/formbricksSDK/src/main/java/com/formbricks/formbrickssdk/model/environment/EnvironmentData.kt
deleted file mode 100644
index 173aedf841..0000000000
--- a/packages/android/formbricksSDK/src/main/java/com/formbricks/formbrickssdk/model/environment/EnvironmentData.kt
+++ /dev/null
@@ -1,11 +0,0 @@
-package com.formbricks.formbrickssdk.model.environment
-
-import com.google.gson.annotations.SerializedName
-import kotlinx.serialization.Serializable
-
-@Serializable
-data class EnvironmentData(
- @SerializedName("surveys") val surveys: List?,
- @SerializedName("actionClasses") val actionClasses: List?,
- @SerializedName("project") val project: Project
-)
\ No newline at end of file
diff --git a/packages/android/formbricksSDK/src/main/java/com/formbricks/formbrickssdk/model/environment/EnvironmentDataHolder.kt b/packages/android/formbricksSDK/src/main/java/com/formbricks/formbrickssdk/model/environment/EnvironmentDataHolder.kt
deleted file mode 100644
index 7263e33afb..0000000000
--- a/packages/android/formbricksSDK/src/main/java/com/formbricks/formbrickssdk/model/environment/EnvironmentDataHolder.kt
+++ /dev/null
@@ -1,48 +0,0 @@
-package com.formbricks.formbrickssdk.model.environment
-
-import com.google.gson.Gson
-import com.google.gson.JsonElement
-
-data class EnvironmentDataHolder(
- val data: EnvironmentResponseData?,
- val originalResponseMap: Map
-)
-
-@Suppress("UNCHECKED_CAST")
-fun EnvironmentDataHolder.getSurveyJson(surveyId: String): JsonElement? {
- val responseMap = originalResponseMap["data"] as? Map<*, *>
- val dataMap = responseMap?.get("data") as? Map<*, *>
- val surveyArray = dataMap?.get("surveys") as? ArrayList