Skip to content

Commit

Permalink
Merge pull request #632 from qonversion/tech/deprecatePushToken
Browse files Browse the repository at this point in the history
The `setNotificationsToken` and `handleNotification` methods were marked as deprecated.
  • Loading branch information
suriksarkisyan authored Sep 13, 2024
2 parents 4ebec02 + 5fd8c9a commit 1f11214
Show file tree
Hide file tree
Showing 16 changed files with 20 additions and 394 deletions.
28 changes: 13 additions & 15 deletions config/detekt/baseline.xml
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
<ID>ConstructorParameterNaming:Environment.kt$Environment$@Json(name = "app_version") val app_version: String</ID>
<ID>EmptyCatchBlock:AdvertisingProvider.kt$AdvertisingProvider.AdvertisingConnection${ }</ID>
<ID>EmptyFunctionBlock:AdvertisingProvider.kt$AdvertisingProvider.AdvertisingConnection${}</ID>
<ID>EmptyFunctionBlock:AutomationsInternal.kt$AutomationsInternal${ }</ID>
<ID>EmptyFunctionBlock:QAutomationsManagerTest.kt$QAutomationsManagerTest.&lt;no name provided&gt;${}</ID>
<ID>EmptyFunctionBlock:QIdentityManagerTest.kt$QIdentityManagerTest.Identify.&lt;no name provided&gt;${}</ID>
<ID>EmptyFunctionBlock:QProductCenterManager.kt$QProductCenterManager.&lt;no name provided&gt;${}</ID>
Expand All @@ -32,11 +33,10 @@
<ID>LargeClass:QProductCenterManager.kt$QProductCenterManager : PurchasesListenerUserStateProvider</ID>
<ID>LongParameterList:IBillingClientWrapper.kt$IBillingClientWrapper$( activity: Activity, product: QProduct, offerId: String?, applyOffer: Boolean? = true, updatePurchaseInfo: UpdatePurchaseInfo?, onFailed: (error: BillingError) -&gt; Unit )</ID>
<ID>LongParameterList:ManagersModule.kt$ManagersModule$( appContext: Application, repository: QRepository, propertiesStorage: UserPropertiesStorage, incrementalDelayCalculator: IncrementalDelayCalculator, appStateProvider: AppStateProvider, logger: Logger )</ID>
<ID>LongParameterList:ManagersModule.kt$ManagersModule$( repository: QRepository, preferences: SharedPreferences, eventMapper: AutomationsEventMapper, appContext: Application, activityProvider: ActivityProvider, appStateProvider: AppStateProvider )</ID>
<ID>LongParameterList:QonversionBillingService.kt$QonversionBillingService$( activity: Activity, product: QProduct, offerId: String?, applyOffer: Boolean?, oldProduct: QProduct, updatePolicy: QPurchaseUpdatePolicy? )</ID>
<ID>LongParameterList:QonversionBillingService.kt$QonversionBillingService$( private val mainHandler: Handler, private val purchasesListener: PurchasesListener, private val logger: Logger, private val isAnalyticsMode: Boolean, private val billingClientHolder: BillingClientHolder, private val billingClientWrapper: BillingClientWrapper, private val legacyBillingClientWrapper: LegacyBillingClientWrapper )</ID>
<ID>LongParameterList:RepositoryModule.kt$RepositoryModule$( retrofit: Retrofit, environmentProvider: EnvironmentProvider, config: InternalConfig, logger: Logger, apiErrorMapper: ApiErrorMapper, sharedPreferences: SharedPreferences, delayCalculator: IncrementalDelayCalculator )</ID>
<ID>LongParameterList:RepositoryModule.kt$RepositoryModule$( retrofit: Retrofit, environmentProvider: EnvironmentProvider, config: InternalConfig, logger: Logger, apiErrorMapper: ApiErrorMapper, sharedPreferences: SharedPreferences, delayCalculator: IncrementalDelayCalculator, rateLimiter: RateLimiter )</ID>
<ID>LongParameterList:RepositoryModule.kt$RepositoryModule$( retrofit: Retrofit, environmentProvider: EnvironmentProvider, config: InternalConfig, logger: Logger, apiErrorMapper: ApiErrorMapper, delayCalculator: IncrementalDelayCalculator )</ID>
<ID>LongParameterList:RepositoryModule.kt$RepositoryModule$( retrofit: Retrofit, environmentProvider: EnvironmentProvider, config: InternalConfig, logger: Logger, apiErrorMapper: ApiErrorMapper, delayCalculator: IncrementalDelayCalculator, rateLimiter: RateLimiter )</ID>
<ID>MagicNumber:ApiErrorMapper.kt$ApiErrorMapper$10002</ID>
<ID>MagicNumber:ApiErrorMapper.kt$ApiErrorMapper$10003</ID>
<ID>MagicNumber:ApiErrorMapper.kt$ApiErrorMapper$10004</ID>
Expand Down Expand Up @@ -93,7 +93,6 @@
<ID>MaxLineLength:LaunchResultCacheWrapperTest.kt$LaunchResultCacheWrapperTest$cacheWrapper = LaunchResultCacheWrapper(mockMoshi, mockPrefsCache, mockCacheConfigProvider, mockQFallbacksService)</ID>
<ID>MaxLineLength:OutagerIntegrationTest.kt$OutagerIntegrationTest$"lgeigljfpmeoddkcebkcepjc.AO-J1Oy305qZj99jXTPEVBN8UZGoYAtjDLj4uTjRQvUFaG0vie-nr6VBlN0qnNDMU8eJR-sI7o3CwQyMOEHKl8eJsoQ86KSFzxKBR07PSpHLI_o7agXhNKY"</ID>
<ID>MaxLineLength:OutagerIntegrationTest.kt$OutagerIntegrationTest$purchaseToken = "lgeigljfpmeoddkcebkcepjc.AO-J1Oy305qZj99jXTPEVBN8UZGoYAtjDLj4uTjRQvUFaG0vie-nr6VBlN0qnNDMU8eJR-sI7o3CwQyMOEHKl8eJsoQ86KSFzxKBR07PSpHLI_o7agXhNKY"</ID>
<ID>MaxLineLength:OutagerIntegrationTest.kt$OutagerIntegrationTest$val token = "dt70kovLQdKymNnhIY6I94:APA91bGfg6m108VFio2ZdgLR6U0B2PtqAn0hIPVU7M4jKklkMxqDUrjoThpX_K60M7CfH8IVZqtku31ei2hmjdJZDfm-bdAl7uxLDWFU8yVcA6-3wBMn3nsYmUrhYWom-qgGC7yIUYzR"</ID>
<ID>MaxLineLength:OutagerIntegrationTest.kt$OutagerIntegrationTest.&lt;no name provided&gt;$assertEquals(error.additionalMessage, """HTTP status code=503, data={"message":"Service Unavailable","code":0,"status":503}. """)</ID>
<ID>MaxLineLength:PurchasesCacheTest.kt$PurchasesCacheTest$"\"purchaseToken\":\"gfegjilekkmecbonpfjiaakm.AO-J1OxQCaAn0NPlHTh5CoOiXK0p19X7qEymW9SHtssrggp7S9YafjA1oPBPlWO4Ur3W5rtyNJBzIrVoLOb5In0Jxofv4xV_7t1HaUYYd_f8xOBk7nRIY7g\"}"</ID>
<ID>MaxLineLength:PurchasesCacheTest.kt$PurchasesCacheTest$private val fourPurchasesStr = "[${generatePurchaseJson()},${generatePurchaseJson("2")},${generatePurchaseJson("3")},${generatePurchaseJson("4")}]"</ID>
Expand Down Expand Up @@ -123,7 +122,6 @@
<ID>MaxLineLength:QonversionRepositoryIntegrationTest.kt$QonversionRepositoryIntegrationTest$"lcbfeigohklhpdgmpildjabg.AO-J1OyV-EE2bKGqDcRCvqjZ2NI1uHDRuvonRn5RorP6LNsyK7yHK8FaFlXp6bjTEX3-4JvZKtbY_bpquKBfux09Mfkx05M9YGZsfsr5BJk74r719m77Oyo"</ID>
<ID>MaxLineLength:QonversionRepositoryIntegrationTest.kt$QonversionRepositoryIntegrationTest$"lgeigljfpmeoddkcebkcepjc.AO-J1Oy305qZj99jXTPEVBN8UZGoYAtjDLj4uTjRQvUFaG0vie-nr6VBlN0qnNDMU8eJR-sI7o3CwQyMOEHKl8eJsoQ86KSFzxKBR07PSpHLI_o7agXhNKY"</ID>
<ID>MaxLineLength:QonversionRepositoryIntegrationTest.kt$QonversionRepositoryIntegrationTest$purchaseToken = "lgeigljfpmeoddkcebkcepjc.AO-J1Oy305qZj99jXTPEVBN8UZGoYAtjDLj4uTjRQvUFaG0vie-nr6VBlN0qnNDMU8eJR-sI7o3CwQyMOEHKl8eJsoQ86KSFzxKBR07PSpHLI_o7agXhNKY"</ID>
<ID>MaxLineLength:QonversionRepositoryIntegrationTest.kt$QonversionRepositoryIntegrationTest$val token = "dt70kovLQdKymNnhIY6I94:APA91bGfg6m108VFio2ZdgLR6U0B2PtqAn0hIPVU7M4jKklkMxqDUrjoThpX_K60M7CfH8IVZqtku31ei2hmjdJZDfm-bdAl7uxLDWFU8yVcA6-3wBMn3nsYmUrhYWom-qgGC7yIUYzR"</ID>
<ID>MaxLineLength:ScreenPresenterTest.kt$ScreenPresenterTest$fun</ID>
<ID>MaxLineLength:SharedPreferencesCacheTest.kt$SharedPreferencesCacheTest.Object${ Assert.assertEquals("Wrong available offerings size value", 1, realValue?.offerings?.availableOfferings?.size) }</ID>
<ID>MaxLineLength:SharedPreferencesCacheTest.kt$SharedPreferencesCacheTest.Object${ Assert.assertEquals("Wrong offering products value", expectedValue.offerings?.main?.products, realValue?.offerings?.main?.products) }</ID>
Expand All @@ -145,8 +143,8 @@
<ID>MaximumLineLength:com.qonversion.android.sdk.automations.internal.AutomationsEventMapperTest.kt:115</ID>
<ID>MaximumLineLength:com.qonversion.android.sdk.automations.internal.AutomationsEventMapperTest.kt:116</ID>
<ID>MaximumLineLength:com.qonversion.android.sdk.automations.internal.AutomationsEventMapperTest.kt:117</ID>
<ID>MaximumLineLength:com.qonversion.android.sdk.automations.internal.QAutomationsManager.kt:135</ID>
<ID>MaximumLineLength:com.qonversion.android.sdk.automations.internal.QAutomationsManager.kt:142</ID>
<ID>MaximumLineLength:com.qonversion.android.sdk.automations.internal.QAutomationsManager.kt:102</ID>
<ID>MaximumLineLength:com.qonversion.android.sdk.automations.internal.QAutomationsManager.kt:95</ID>
<ID>MaximumLineLength:com.qonversion.android.sdk.automations.mvp.ScreenPresenterTest.kt:159</ID>
<ID>MaximumLineLength:com.qonversion.android.sdk.dto.QonversionError.kt:46</ID>
<ID>MaximumLineLength:com.qonversion.android.sdk.dto.products.QProduct.kt:109</ID>
Expand All @@ -155,18 +153,16 @@
<ID>MaximumLineLength:com.qonversion.android.sdk.dto.products.QProductStoreDetails.kt:130</ID>
<ID>MaximumLineLength:com.qonversion.android.sdk.internal.OutagerIntegrationTest.kt:214</ID>
<ID>MaximumLineLength:com.qonversion.android.sdk.internal.OutagerIntegrationTest.kt:371</ID>
<ID>MaximumLineLength:com.qonversion.android.sdk.internal.OutagerIntegrationTest.kt:430</ID>
<ID>MaximumLineLength:com.qonversion.android.sdk.internal.OutagerIntegrationTest.kt:90</ID>
<ID>MaximumLineLength:com.qonversion.android.sdk.internal.QProductCenterManager.kt:332</ID>
<ID>MaximumLineLength:com.qonversion.android.sdk.internal.QProductCenterManagerTest.kt:152</ID>
<ID>MaximumLineLength:com.qonversion.android.sdk.internal.QProductCenterManagerTest.kt:153</ID>
<ID>MaximumLineLength:com.qonversion.android.sdk.internal.QRemoteConfigManager.kt:225</ID>
<ID>MaximumLineLength:com.qonversion.android.sdk.internal.QUserPropertiesManagerTest.kt:175</ID>
<ID>MaximumLineLength:com.qonversion.android.sdk.internal.QUserPropertiesManagerTest.kt:178</ID>
<ID>MaximumLineLength:com.qonversion.android.sdk.internal.QonversionRepositoryIntegrationTest.kt:287</ID>
<ID>MaximumLineLength:com.qonversion.android.sdk.internal.QonversionRepositoryIntegrationTest.kt:356</ID>
<ID>MaximumLineLength:com.qonversion.android.sdk.internal.QonversionRepositoryIntegrationTest.kt:685</ID>
<ID>MaximumLineLength:com.qonversion.android.sdk.internal.QonversionRepositoryIntegrationTest.kt:878</ID>
<ID>MaximumLineLength:com.qonversion.android.sdk.internal.QonversionRepositoryIntegrationTest.kt:89</ID>
<ID>MaximumLineLength:com.qonversion.android.sdk.internal.QonversionRepositoryIntegrationTest.kt:906</ID>
<ID>MaximumLineLength:com.qonversion.android.sdk.internal.api.ApiErrorMapper.kt:118</ID>
<ID>MaximumLineLength:com.qonversion.android.sdk.internal.api.ApiErrorMapper.kt:119</ID>
<ID>MaximumLineLength:com.qonversion.android.sdk.internal.billing.QonversionBillingService.kt:253</ID>
Expand Down Expand Up @@ -202,12 +198,14 @@
<ID>NewLineAtEndOfFile:ScreenPresenterTest.kt$com.qonversion.android.sdk.automations.mvp.ScreenPresenterTest.kt</ID>
<ID>NewLineAtEndOfFile:util.kt$com.qonversion.android.sdk.internal.storage.util.kt</ID>
<ID>NewLineAtEndOfFile:utils.kt$com.qonversion.android.sdk.utils.kt</ID>
<ID>NoBlankLineBeforeRbrace:com.qonversion.android.sdk.automations.internal.QAutomationsManagerTest.kt:270</ID>
<ID>NoBlankLineBeforeRbrace:com.qonversion.android.sdk.automations.internal.QAutomationsManagerTest.kt:261</ID>
<ID>NoBlankLineBeforeRbrace:com.qonversion.android.sdk.internal.validator.TokenValidatorTest.kt:20</ID>
<ID>NoConsecutiveBlankLines:com.qonversion.android.sdk.QonversionConfigTest.kt:118</ID>
<ID>NoConsecutiveBlankLines:com.qonversion.android.sdk.automations.internal.QAutomationsManagerTest.kt:396</ID>
<ID>NoConsecutiveBlankLines:com.qonversion.android.sdk.internal.QAttributionManagerTest.kt:141</ID>
<ID>NoConsecutiveBlankLines:com.qonversion.android.sdk.internal.requests.ProviderDataRequestTest.kt:18</ID>
<ID>NoUnusedImports:com.qonversion.android.sdk.automations.internal.QAutomationsManagerTest.kt:20</ID>
<ID>NoUnusedImports:com.qonversion.android.sdk.automations.internal.QAutomationsManagerTest.kt:22</ID>
<ID>NoUnusedImports:com.qonversion.android.sdk.automations.internal.QAutomationsManagerTest.kt:7</ID>
<ID>NoUnusedImports:com.qonversion.android.sdk.internal.storage.PurchasesCacheTest.kt:4</ID>
<ID>NoUnusedImports:com.qonversion.android.sdk.internal.storage.PurchasesCacheTest.kt:5</ID>
<ID>NoWildcardImports:com.qonversion.android.sdk.automations.internal.AutomationsEventMapperTest.kt:12</ID>
Expand Down Expand Up @@ -248,10 +246,10 @@
<ID>ReturnCount:QProductCenterManager.kt$QProductCenterManager$private fun calculatePurchasePermissionsLocally( purchase: Purchase, purchaseCallback: QonversionEntitlementsCallback?, purchaseError: QonversionError )</ID>
<ID>ReturnCount:ScreenPresenter.kt$ScreenPresenter$override fun shouldOverrideUrlLoading(url: String?): Boolean</ID>
<ID>SpacingAroundColon:com.qonversion.android.sdk.internal.requests.ProviderDataRequestTest.kt:45</ID>
<ID>SpacingAroundCurly:com.qonversion.android.sdk.automations.internal.QAutomationsManagerTest.kt:263</ID>
<ID>SpacingAroundCurly:com.qonversion.android.sdk.automations.internal.QAutomationsManagerTest.kt:254</ID>
<ID>SpacingAroundCurly:com.qonversion.android.sdk.internal.QAttributionManagerTest.kt:39</ID>
<ID>SpacingAroundCurly:com.qonversion.android.sdk.internal.QAttributionManagerTest.kt:54</ID>
<ID>SpacingAroundParens:com.qonversion.android.sdk.internal.QUserPropertiesManagerTest.kt:497</ID>
<ID>SpacingAroundParens:com.qonversion.android.sdk.internal.QUserPropertiesManagerTest.kt:468</ID>
<ID>SpacingAroundParens:com.qonversion.android.sdk.internal.storage.SharedPreferencesCacheTest.kt:209</ID>
<ID>SpacingAroundParens:com.qonversion.android.sdk.internal.storage.SharedPreferencesCacheTest.kt:238</ID>
<ID>SpacingAroundParens:com.qonversion.android.sdk.internal.storage.SharedPreferencesCacheTest.kt:257</ID>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -422,34 +422,6 @@ internal class OutagerIntegrationTest {
signal.await()
}

@Test
fun sendPushToken() {
// given
val signal = CountDownLatch(1)

val token = "dt70kovLQdKymNnhIY6I94:APA91bGfg6m108VFio2ZdgLR6U0B2PtqAn0hIPVU7M4jKklkMxqDUrjoThpX_K60M7CfH8IVZqtku31ei2hmjdJZDfm-bdAl7uxLDWFU8yVcA6-3wBMn3nsYmUrhYWom-qgGC7yIUYzR"

val uid = UID_PREFIX + "_sendPushToken"
val repository = initRepository(uid)

// when
withNewUserCreated(repository) { error ->
error?.let {
fail("Failed to create user")
}

repository.sendPushToken(token)
}

// then
// check that nothing critical happens
Handler(Looper.getMainLooper()).postDelayed(
{ signal.countDown() },
1000
)
signal.await()
}

@Test
fun screens() {
// given
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -677,34 +677,6 @@ internal class QonversionRepositoryIntegrationTest {
signal.await()
}

@Test
fun sendPushToken() {
// given
val signal = CountDownLatch(1)

val token = "dt70kovLQdKymNnhIY6I94:APA91bGfg6m108VFio2ZdgLR6U0B2PtqAn0hIPVU7M4jKklkMxqDUrjoThpX_K60M7CfH8IVZqtku31ei2hmjdJZDfm-bdAl7uxLDWFU8yVcA6-3wBMn3nsYmUrhYWom-qgGC7yIUYzR"

val uid = UID_PREFIX + "_sendPushToken"
val repository = initRepository(uid)

// when
withNewUserCreated(repository) { error ->
error?.let {
fail("Failed to create user")
}

repository.sendPushToken(token)
}

// then
// check that nothing critical happens
Handler(Looper.getMainLooper()).postDelayed(
{ signal.countDown() },
1000
)
signal.await()
}

@Test
fun screens() {
// given
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ interface Automations {
/**
* Set push token to Qonversion to enable Qonversion push notifications
*/
@Deprecated("Consider removing this method as it isn't needed anymore")
fun setNotificationsToken(token: String)

/**
Expand All @@ -71,6 +72,7 @@ interface Automations {
* @return true when a push notification was received from Qonversion.
* Otherwise returns false, so you need to handle a notification yourself.
*/
@Deprecated("Consider removing this method. Qonversion is not working with push notifications anymore")
fun handleNotification(messageData: Map<String, String>): Boolean

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,11 @@ internal class AutomationsInternal : Automations {
automationsManager.loadScreen(withID, callback)
}

@Deprecated("Consider removing this method as it isn't needed anymore")
override fun setNotificationsToken(token: String) {
automationsManager.setPushToken(token)
}

@Deprecated("Consider removing this method. Qonversion is not working with push notifications anymore")
override fun handleNotification(messageData: Map<String, String>): Boolean {
return automationsManager.handlePushIfPossible(messageData)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,21 +4,17 @@ import android.app.Activity
import android.app.Application
import android.content.Context
import android.content.Intent.FLAG_ACTIVITY_NEW_TASK
import android.content.SharedPreferences
import com.qonversion.android.sdk.automations.AutomationsDelegate
import com.qonversion.android.sdk.automations.ScreenCustomizationDelegate
import com.qonversion.android.sdk.automations.dto.QActionResult
import com.qonversion.android.sdk.automations.dto.QScreenPresentationConfig
import com.qonversion.android.sdk.internal.Constants.PENDING_PUSH_TOKEN_KEY
import com.qonversion.android.sdk.internal.Constants.PUSH_TOKEN_KEY
import com.qonversion.android.sdk.dto.QonversionError
import com.qonversion.android.sdk.dto.QonversionErrorCode
import com.qonversion.android.sdk.internal.repository.QRepository
import com.qonversion.android.sdk.listeners.QonversionShowScreenCallback
import com.qonversion.android.sdk.internal.toBoolean
import com.qonversion.android.sdk.internal.logger.ConsoleLogger
import com.qonversion.android.sdk.automations.mvp.ScreenActivity
import com.qonversion.android.sdk.internal.provider.AppStateProvider
import com.qonversion.android.sdk.internal.toMap
import java.lang.Exception
import java.lang.ref.WeakReference
Expand All @@ -28,11 +24,9 @@ import org.json.JSONObject

internal class QAutomationsManager @Inject constructor(
private val repository: QRepository,
private val preferences: SharedPreferences,
private val eventMapper: AutomationsEventMapper,
private val appContext: Application,
private val activityProvider: ActivityProvider,
private val appStateProvider: AppStateProvider
) {
@Volatile
var automationsDelegate: WeakReference<AutomationsDelegate>? = null
Expand All @@ -45,14 +39,6 @@ internal class QAutomationsManager @Inject constructor(
@Synchronized get

private val logger = ConsoleLogger()
private var pendingToken: String? = null
internal var isLaunchFinished = false

fun onAppForeground() {
pendingToken?.let {
sendPushToken(it)
}
}

fun handlePushIfPossible(messageData: Map<String, String>): Boolean {
val pickScreen = messageData[PICK_SCREEN]
Expand Down Expand Up @@ -86,32 +72,6 @@ internal class QAutomationsManager @Inject constructor(
}
}

fun setPushToken(token: String) {
val oldToken = loadToken()
if (token.isEmpty() || oldToken.equals(token)) {
return
}

savePendingTokenToPref(token)
if (!isLaunchFinished || appStateProvider.appState.isBackground()) {
pendingToken = token
} else {
sendPushToken(token)
}
}

private fun processPushToken() {
val token = getPendingToken()
if (!token.isNullOrEmpty()) {
sendPushToken(token)
}
}

internal fun onLaunchProcessed() {
isLaunchFinished = true
processPushToken()
}

fun loadScreen(screenId: String, callback: QonversionShowScreenCallback? = null) {
repository.screens(screenId,
{ screen ->
Expand Down Expand Up @@ -218,21 +178,6 @@ internal class QAutomationsManager @Inject constructor(
)
}

private fun sendPushToken(token: String) {
repository.sendPushToken(token)

pendingToken = null
}

private fun getPendingToken(): String? {
return preferences.getString(PENDING_PUSH_TOKEN_KEY, null)
}

private fun savePendingTokenToPref(token: String) =
preferences.edit().putString(PENDING_PUSH_TOKEN_KEY, token).apply()

private fun loadToken() = preferences.getString(PUSH_TOKEN_KEY, "")

companion object {
private const val PICK_SCREEN = "qonv.pick_screen"
private const val KEY_CUSTOM_PAYLOAD = "qonv.custom_payload"
Expand Down
Loading

0 comments on commit 1f11214

Please sign in to comment.