Show rating prompt after share sheet is dismissed
iOS: moved registerSuccessfulExport() into onDismiss so it fires after the share sheet closes, not while it is still open. Android: hold launchReview() until the activity is RESUMED so the dialog cannot overlap the share chooser. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -219,7 +219,10 @@ struct LoadsView: View {
|
|||||||
}
|
}
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
.sheet(item: $overviewShareItem, onDismiss: cleanupOverviewShareItem) { item in
|
.sheet(item: $overviewShareItem, onDismiss: {
|
||||||
|
cleanupOverviewShareItem()
|
||||||
|
ReviewPrompt.registerSuccessfulExport()
|
||||||
|
}) { item in
|
||||||
ShareSheet(items: item.shareItems)
|
ShareSheet(items: item.shareItems)
|
||||||
}
|
}
|
||||||
.alert(
|
.alert(
|
||||||
@@ -1133,7 +1136,6 @@ struct LoadsView: View {
|
|||||||
await MainActor.run {
|
await MainActor.run {
|
||||||
overviewShareItem = OverviewShareItem(shareItems: [url], tempURL: url)
|
overviewShareItem = OverviewShareItem(shareItems: [url], tempURL: url)
|
||||||
isExportingOverview = false
|
isExportingOverview = false
|
||||||
ReviewPrompt.registerSuccessfulExport()
|
|
||||||
}
|
}
|
||||||
} catch {
|
} catch {
|
||||||
await MainActor.run {
|
await MainActor.run {
|
||||||
@@ -1163,7 +1165,6 @@ struct LoadsView: View {
|
|||||||
"system": snapshot.systemName,
|
"system": snapshot.systemName,
|
||||||
])
|
])
|
||||||
overviewShareItem = OverviewShareItem(shareItems: [url], tempURL: url)
|
overviewShareItem = OverviewShareItem(shareItems: [url], tempURL: url)
|
||||||
ReviewPrompt.registerSuccessfulExport()
|
|
||||||
} else {
|
} else {
|
||||||
overviewExportError = OverviewExportError(
|
overviewExportError = OverviewExportError(
|
||||||
message: String(localized: "overview.share.diagram.error", defaultValue: "Could not generate diagram. Check your internet connection.")
|
message: String(localized: "overview.share.diagram.error", defaultValue: "Could not generate diagram. Check your internet connection.")
|
||||||
|
|||||||
@@ -301,7 +301,10 @@ struct SystemBillOfMaterialsView: View {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
.accessibilityIdentifier("system-bom-view")
|
.accessibilityIdentifier("system-bom-view")
|
||||||
.sheet(item: $activeShareItem, onDismiss: cleanupShareItem) { item in
|
.sheet(item: $activeShareItem, onDismiss: {
|
||||||
|
cleanupShareItem()
|
||||||
|
ReviewPrompt.registerSuccessfulExport()
|
||||||
|
}) { item in
|
||||||
ShareSheet(items: [item.url])
|
ShareSheet(items: [item.url])
|
||||||
}
|
}
|
||||||
.alert(item: $exportError) { error in
|
.alert(item: $exportError) { error in
|
||||||
@@ -346,7 +349,6 @@ struct SystemBillOfMaterialsView: View {
|
|||||||
)
|
)
|
||||||
await MainActor.run {
|
await MainActor.run {
|
||||||
activeShareItem = ExportedPDFShareItem(url: url)
|
activeShareItem = ExportedPDFShareItem(url: url)
|
||||||
ReviewPrompt.registerSuccessfulExport()
|
|
||||||
}
|
}
|
||||||
} catch {
|
} catch {
|
||||||
await MainActor.run {
|
await MainActor.run {
|
||||||
|
|||||||
@@ -7,11 +7,14 @@ import androidx.datastore.preferences.core.edit
|
|||||||
import androidx.datastore.preferences.core.intPreferencesKey
|
import androidx.datastore.preferences.core.intPreferencesKey
|
||||||
import androidx.datastore.preferences.core.longPreferencesKey
|
import androidx.datastore.preferences.core.longPreferencesKey
|
||||||
import androidx.datastore.preferences.core.stringPreferencesKey
|
import androidx.datastore.preferences.core.stringPreferencesKey
|
||||||
|
import androidx.lifecycle.Lifecycle
|
||||||
|
import androidx.lifecycle.LifecycleOwner
|
||||||
import app.voltplan.cable.BuildConfig
|
import app.voltplan.cable.BuildConfig
|
||||||
import app.voltplan.cable.analytics.Analytics
|
import app.voltplan.cable.analytics.Analytics
|
||||||
import com.google.android.play.core.ktx.launchReview
|
import com.google.android.play.core.ktx.launchReview
|
||||||
import com.google.android.play.core.ktx.requestReview
|
import com.google.android.play.core.ktx.requestReview
|
||||||
import com.google.android.play.core.review.ReviewManagerFactory
|
import com.google.android.play.core.review.ReviewManagerFactory
|
||||||
|
import kotlinx.coroutines.flow.filter
|
||||||
import kotlinx.coroutines.flow.first
|
import kotlinx.coroutines.flow.first
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -113,6 +116,11 @@ object ReviewPrompt {
|
|||||||
runCatching {
|
runCatching {
|
||||||
val manager = ReviewManagerFactory.create(context)
|
val manager = ReviewManagerFactory.create(context)
|
||||||
val reviewInfo = manager.requestReview()
|
val reviewInfo = manager.requestReview()
|
||||||
|
// Wait until the activity is resumed so the dialog doesn't overlap a share sheet
|
||||||
|
// that was just launched (startActivity returns immediately, so we may still be paused).
|
||||||
|
(activity as? LifecycleOwner)?.lifecycle?.currentStateFlow
|
||||||
|
?.filter { state: Lifecycle.State -> state.isAtLeast(Lifecycle.State.RESUMED) }
|
||||||
|
?.first()
|
||||||
manager.launchReview(activity, reviewInfo)
|
manager.launchReview(activity, reviewInfo)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user