From 3c8896874740550839e66bfdb6ded652b428c4c2 Mon Sep 17 00:00:00 2001 From: "Victoria.Petrakovich" Date: Mon, 8 Jan 2024 22:49:35 +0000 Subject: [PATCH] [kotlin] Add K2 feedback survey KTIJ-28299 ^Fixed Co-authored-by: Ilya Kirillov Merge-request: IJ-MR-123182 Merged-by: Victoria Petrakovich GitOrigin-RevId: db3bb8228131f749b500e6ee36db0597ff19ef35 --- .../feedback/impl/OnDemandFeedbackResolver.kt | 41 +++++++++ .../kotlin/onboarding/kotlin.onboarding.iml | 4 + .../resources/kotlin.onboarding.xml | 21 +++++ .../messages/FeedbackBundle.properties | 19 +++- .../satisfaction/survey/K2FeedbackDialog.kt | 69 +++++++++++++++ .../satisfaction/survey/K2FeedbackSurvey.kt | 14 +++ .../survey/K2FeedbackSurveyConfig.kt | 50 +++++++++++ .../k2/satisfaction/survey/K2UserTracker.kt | 86 +++++++++++++++++++ .../survey/ShowK2FeedbackDialogAction.kt | 11 +++ ...ficationAfterRestartPostStartupActivity.kt | 21 +++++ .../satisfaction/survey/K2UserTrackerTest.kt | 66 ++++++++++++++ .../KotlinPluginKindSwitcherListener.kt | 9 ++ .../ui/KotlinPluginKindSwitcherController.kt | 10 ++- 13 files changed, 419 insertions(+), 2 deletions(-) create mode 100644 platform/feedback/src/com/intellij/platform/feedback/impl/OnDemandFeedbackResolver.kt create mode 100644 plugins/kotlin/onboarding/src/org/jetbrains/kotlin/onboarding/k2/satisfaction/survey/K2FeedbackDialog.kt create mode 100644 plugins/kotlin/onboarding/src/org/jetbrains/kotlin/onboarding/k2/satisfaction/survey/K2FeedbackSurvey.kt create mode 100644 plugins/kotlin/onboarding/src/org/jetbrains/kotlin/onboarding/k2/satisfaction/survey/K2FeedbackSurveyConfig.kt create mode 100644 plugins/kotlin/onboarding/src/org/jetbrains/kotlin/onboarding/k2/satisfaction/survey/K2UserTracker.kt create mode 100644 plugins/kotlin/onboarding/src/org/jetbrains/kotlin/onboarding/k2/satisfaction/survey/ShowK2FeedbackDialogAction.kt create mode 100644 plugins/kotlin/onboarding/src/org/jetbrains/kotlin/onboarding/k2/satisfaction/survey/ShowK2SurveyNotificationAfterRestartPostStartupActivity.kt create mode 100644 plugins/kotlin/onboarding/test/onboarding/k2/satisfaction/survey/K2UserTrackerTest.kt create mode 100644 plugins/kotlin/preferences/src/org/jetbrains/kotlin/idea/configuration/KotlinPluginKindSwitcherListener.kt diff --git a/platform/feedback/src/com/intellij/platform/feedback/impl/OnDemandFeedbackResolver.kt b/platform/feedback/src/com/intellij/platform/feedback/impl/OnDemandFeedbackResolver.kt new file mode 100644 index 000000000000..f1188a460111 --- /dev/null +++ b/platform/feedback/src/com/intellij/platform/feedback/impl/OnDemandFeedbackResolver.kt @@ -0,0 +1,41 @@ +// Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. +package com.intellij.platform.feedback.impl + +import com.intellij.internal.statistic.utils.getPluginInfoByDescriptor +import com.intellij.openapi.components.Service +import com.intellij.openapi.components.service +import com.intellij.openapi.extensions.ExtensionPointName +import com.intellij.openapi.project.Project +import com.intellij.openapi.util.registry.Registry +import com.intellij.platform.feedback.FeedbackSurvey +import com.intellij.platform.feedback.impl.state.DontShowAgainFeedbackService +import kotlin.reflect.KClass + +@Service(Service.Level.APP) +class OnDemandFeedbackResolver { + companion object { + @JvmStatic + fun getInstance(): OnDemandFeedbackResolver = service() + + private fun getJbOnDemandFeedbackSurveyExtension(surveyClass: KClass): S { + return IdleFeedbackResolver.getJbIdleFeedbackSurveyExtensionList().filterIsInstance(surveyClass.java).first() + } + + private fun canShowFeedbackNotification(): Boolean { + return DontShowAgainFeedbackService.checkIsAllowedToShowFeedback() && Registry.`is`("platform.feedback", true) + } + } + + /** + * Shows [survey] if it's suitable and user allows showing surveys. + * + * @return `true` if a survey notification was shown, `false` otherwise + */ + fun showFeedbackNotification(surveyClass: KClass, project: Project): Boolean { + val survey = getJbOnDemandFeedbackSurveyExtension(surveyClass) + if (!canShowFeedbackNotification()) return false + if (!survey.isSuitableToShow(project)) return false + survey.showNotification(project) + return true + } +} \ No newline at end of file diff --git a/plugins/kotlin/onboarding/kotlin.onboarding.iml b/plugins/kotlin/onboarding/kotlin.onboarding.iml index 8f1a140c7746..4f489bdb492b 100644 --- a/plugins/kotlin/onboarding/kotlin.onboarding.iml +++ b/plugins/kotlin/onboarding/kotlin.onboarding.iml @@ -9,6 +9,7 @@ + @@ -18,10 +19,13 @@ + + + \ No newline at end of file diff --git a/plugins/kotlin/onboarding/resources/kotlin.onboarding.xml b/plugins/kotlin/onboarding/resources/kotlin.onboarding.xml index bb9b7116be21..1aff27cd8464 100644 --- a/plugins/kotlin/onboarding/resources/kotlin.onboarding.xml +++ b/plugins/kotlin/onboarding/resources/kotlin.onboarding.xml @@ -6,7 +6,10 @@ + + + @@ -14,6 +17,24 @@ class="org.jetbrains.kotlin.onboarding.ShowKotlinOnboardingFeedbackDialogAction" internal="true"/> + + + + + + + + + \ No newline at end of file diff --git a/plugins/kotlin/onboarding/resources/messages/FeedbackBundle.properties b/plugins/kotlin/onboarding/resources/messages/FeedbackBundle.properties index 00568715ef0d..5b2fdddc9999 100644 --- a/plugins/kotlin/onboarding/resources/messages/FeedbackBundle.properties +++ b/plugins/kotlin/onboarding/resources/messages/FeedbackBundle.properties @@ -30,4 +30,21 @@ notification.thanks.feedback.content=You are helping improve the Kotlin plugin! notification.request.title=Share feedback about the Kotlin plugin notification.request.content=Please answer a few questions. It will take about 2 minutes. -action.org.jetbrains.kotlin.onboarding.ShowKotlinOnboardingFeedbackDialogAction.text=Show Kotlin Onboarding Feedback Dialog \ No newline at end of file +action.org.jetbrains.kotlin.onboarding.ShowKotlinOnboardingFeedbackDialogAction.text=Show Kotlin Onboarding Feedback Dialog + +dialog.k2.satisfaction.top.title=Feedback +dialog.k2.satisfaction.title=K2 Kotlin Mode Feedback +dialog.k2.satisfaction.description=You have been using K2 Kotlin mode recently, share your feedback with us. + +dialog.k2.satisfaction.performance.rating.label=How satisfied are you with the IDE performance in K2-based mode? +dialog.k2.satisfaction.quality.rating.label=How satisfied are you with the quality of Kotlin support in IDE? +dialog.k2.satisfaction.biggest.quality.problems.text.label=What are the biggest quality problems you have noticed, if any? +dialog.k2.satisfaction.features.missed.most.text.label=What features did you miss the most, if any? + +notification.k2.satisfaction.thanks.feedback.content=You are helping improve the Kotlin K2-based plugin! + +notification.k2.satisfaction.request.title=Share feedback about the K2 Kotlin mode +notification.k2.satisfaction.request.content=Please answer a few questions. It will take about 2 minutes. + +action.org.jetbrains.kotlin.onboarding.k2.satisfaction.survey.ShowK2FeedbackDialogAction.text=Show K2 Kotlin Feedback Dialog + diff --git a/plugins/kotlin/onboarding/src/org/jetbrains/kotlin/onboarding/k2/satisfaction/survey/K2FeedbackDialog.kt b/plugins/kotlin/onboarding/src/org/jetbrains/kotlin/onboarding/k2/satisfaction/survey/K2FeedbackDialog.kt new file mode 100644 index 000000000000..d4100c74a570 --- /dev/null +++ b/plugins/kotlin/onboarding/src/org/jetbrains/kotlin/onboarding/k2/satisfaction/survey/K2FeedbackDialog.kt @@ -0,0 +1,69 @@ +// Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. +package org.jetbrains.kotlin.onboarding.k2.satisfaction.survey + +import com.intellij.openapi.project.Project +import com.intellij.platform.feedback.dialog.BlockBasedFeedbackDialogWithEmail +import com.intellij.platform.feedback.dialog.CommonFeedbackSystemData +import com.intellij.platform.feedback.dialog.showFeedbackSystemInfoDialog +import com.intellij.platform.feedback.dialog.uiBlocks.* +import com.intellij.platform.feedback.impl.notification.ThanksForFeedbackNotification +import org.jetbrains.kotlin.onboarding.FeedbackBundle + +class K2FeedbackDialog( + project: Project?, + forTest: Boolean +) : BlockBasedFeedbackDialogWithEmail(project, forTest) { + + /** Increase the additional number when feedback format is changed */ + override val myFeedbackJsonVersion: Int = super.myFeedbackJsonVersion + 1 + + override val zendeskTicketTitle: String = "K2 in-IDE Feedback" + override val zendeskFeedbackType: String = "K2 in-IDE Feedback" + override val myFeedbackReportId: String = "k2_feedback" + + override fun shouldAutoCloseZendeskTicket(): Boolean { + return false + } + + override val mySystemInfoData: CommonFeedbackSystemData by lazy { + CommonFeedbackSystemData.getCurrentData() + } + + override val myShowFeedbackSystemInfoDialog: () -> Unit = { + showFeedbackSystemInfoDialog(myProject, mySystemInfoData) + } + + override val myTitle: String = FeedbackBundle.message("dialog.k2.satisfaction.top.title") + override val myBlocks: List = listOf( + TopLabelBlock(FeedbackBundle.message("dialog.k2.satisfaction.title")), + DescriptionBlock(FeedbackBundle.message("dialog.k2.satisfaction.description")), + RatingBlock( + FeedbackBundle.message("dialog.k2.satisfaction.performance.rating.label"), + "performance_rating" + ), + RatingBlock( + FeedbackBundle.message("dialog.k2.satisfaction.quality.rating.label"), + "quality_rating" + ), + TextAreaBlock( + FeedbackBundle.message("dialog.k2.satisfaction.biggest.quality.problems.text.label"), + "biggest_quality_problems" + ), + TextAreaBlock( + FeedbackBundle.message("dialog.k2.satisfaction.features.missed.most.text.label"), + "most_missed_features" + ) + ) + + init { + init() + } + + override fun showThanksNotification() { + ThanksForFeedbackNotification( + description = FeedbackBundle.message( + "notification.k2.satisfaction.thanks.feedback.content" + ) + ).notify(myProject) + } +} \ No newline at end of file diff --git a/plugins/kotlin/onboarding/src/org/jetbrains/kotlin/onboarding/k2/satisfaction/survey/K2FeedbackSurvey.kt b/plugins/kotlin/onboarding/src/org/jetbrains/kotlin/onboarding/k2/satisfaction/survey/K2FeedbackSurvey.kt new file mode 100644 index 000000000000..b19b47144e6e --- /dev/null +++ b/plugins/kotlin/onboarding/src/org/jetbrains/kotlin/onboarding/k2/satisfaction/survey/K2FeedbackSurvey.kt @@ -0,0 +1,14 @@ +// Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. +package org.jetbrains.kotlin.onboarding.k2.satisfaction.survey + +import com.intellij.platform.feedback.FeedbackSurvey +import com.intellij.platform.feedback.FeedbackSurveyType +import com.intellij.platform.feedback.InIdeFeedbackSurveyConfig +import com.intellij.platform.feedback.InIdeFeedbackSurveyType + +class K2FeedbackSurvey : FeedbackSurvey() { + + override val feedbackSurveyType: FeedbackSurveyType = + InIdeFeedbackSurveyType(K2FeedbackSurveyConfig()) + +} \ No newline at end of file diff --git a/plugins/kotlin/onboarding/src/org/jetbrains/kotlin/onboarding/k2/satisfaction/survey/K2FeedbackSurveyConfig.kt b/plugins/kotlin/onboarding/src/org/jetbrains/kotlin/onboarding/k2/satisfaction/survey/K2FeedbackSurveyConfig.kt new file mode 100644 index 000000000000..32192704deb0 --- /dev/null +++ b/plugins/kotlin/onboarding/src/org/jetbrains/kotlin/onboarding/k2/satisfaction/survey/K2FeedbackSurveyConfig.kt @@ -0,0 +1,50 @@ +// Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. +package org.jetbrains.kotlin.onboarding.k2.satisfaction.survey + +import com.intellij.openapi.application.ApplicationInfo +import com.intellij.openapi.project.Project +import com.intellij.platform.feedback.InIdeFeedbackSurveyConfig +import com.intellij.platform.feedback.dialog.BlockBasedFeedbackDialogWithEmail +import com.intellij.platform.feedback.dialog.SystemDataJsonSerializable +import com.intellij.platform.feedback.impl.notification.RequestFeedbackNotification +import com.intellij.util.PlatformUtils +import kotlinx.datetime.LocalDate +import org.jetbrains.kotlin.onboarding.FeedbackBundle + +class K2FeedbackSurveyConfig : InIdeFeedbackSurveyConfig { + + override val surveyId: String = "k2_feedback" + override val lastDayOfFeedbackCollection: LocalDate = LocalDate(2024, 3, 18) + override val requireIdeEAP: Boolean = true + + private val suitableIdeVersion = "2024.1" + + override fun checkIdeIsSuitable(): Boolean { + return PlatformUtils.isIdeaUltimate() || PlatformUtils.isIdeaCommunity() + } + + override fun checkExtraConditionSatisfied(project: Project): Boolean { + return suitableIdeVersion == ApplicationInfo.getInstance().shortVersion && + K2UserTracker.getInstance().shouldShowK2FeedbackDialog() + } + + override fun updateStateAfterDialogClosedOk(project: Project) { + K2UserTracker.getInstance().state.userSawSurvey = true + } + + override fun createFeedbackDialog(project: Project, forTest: Boolean): BlockBasedFeedbackDialogWithEmail { + return K2FeedbackDialog(project, forTest) + } + + override fun createNotification(project: Project, forTest: Boolean): RequestFeedbackNotification { + return RequestFeedbackNotification( + "Feedback In IDE", + FeedbackBundle.message("notification.k2.satisfaction.request.title"), + FeedbackBundle.message("notification.k2.satisfaction.request.content") + ) + } + + override fun updateStateAfterNotificationShowed(project: Project) { + // do nothing + } +} \ No newline at end of file diff --git a/plugins/kotlin/onboarding/src/org/jetbrains/kotlin/onboarding/k2/satisfaction/survey/K2UserTracker.kt b/plugins/kotlin/onboarding/src/org/jetbrains/kotlin/onboarding/k2/satisfaction/survey/K2UserTracker.kt new file mode 100644 index 000000000000..1f5b1fca02a5 --- /dev/null +++ b/plugins/kotlin/onboarding/src/org/jetbrains/kotlin/onboarding/k2/satisfaction/survey/K2UserTracker.kt @@ -0,0 +1,86 @@ +// Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. +package org.jetbrains.kotlin.onboarding.k2.satisfaction.survey + +import com.intellij.openapi.application.ApplicationManager +import com.intellij.openapi.components.* +import com.intellij.openapi.diagnostic.Logger +import com.intellij.openapi.util.registry.Registry +import org.jetbrains.kotlin.idea.base.plugin.KotlinPluginMode +import org.jetbrains.kotlin.idea.base.plugin.KotlinPluginModeProvider +import org.jetbrains.kotlin.idea.configuration.KotlinPluginKindSwitcherListener +import java.time.Duration +import java.time.Instant + +class K2UserTrackerState : BaseState(), KotlinPluginKindSwitcherListener { + + // Unix time seconds + var k2UserSince by property(Instant.now().epochSecond) // We don't have any information earlier, so always start from now + /* We need to store that the user saw the survey because the state in com.intellij.platform.feedback.impl.state.CommonFeedbackSurveyService + doesn't migrate when updating the IDE */ + var userSawSurvey by property(false) + // The following flag is needed to explicitly define that the user has just switched to K1 – we need this state after IDE restart + var switchedToK1 by property(false) // If they are on K1 from the beginning, then they didn't switch + + override fun kotlinPluginKindChanged(kotlinPluginMode: KotlinPluginMode) { + if (kotlinPluginMode == KotlinPluginMode.K2) { + switchedToK1 = false + k2UserSince = Instant.now().epochSecond + } else if (kotlinPluginMode == KotlinPluginMode.K1) { + switchedToK1 = true + } + } +} + +@State(name = "K2NewUserTracker", storages = [Storage("k2-feedback.xml")]) +class K2UserTracker : PersistentStateComponent { + companion object { + private val LOG = Logger.getInstance(K2UserTracker::class.java) + + fun getInstance(): K2UserTracker { + return service() + } + } + + internal var forUnitTests = false + internal var k2PluginModeForTests = false // Want the test to not depend on a real K1/K2 mode + + internal var currentState = K2UserTrackerState() + + override fun getState(): K2UserTrackerState = currentState + + override fun loadState(state: K2UserTrackerState) { + currentState = state + } + + internal fun shouldShowK2FeedbackDialog(): Boolean { + if (!Registry.`is`("test.k2.feedback.survey", false)) { + if (!forUnitTests) { + if (ApplicationManager.getApplication().isInternal) return false // Don't show in Nightly builds or in `IDEA (dev build)` + } + if (state.userSawSurvey) return false // We show this survey only once + } else { + state.userSawSurvey = false // We reset this state for manual testing to be able to see the survey more than once + } + if (state.switchedToK1) { + return true + } else { + val k2Chosen = if (forUnitTests) { + k2PluginModeForTests + } else { + KotlinPluginModeProvider.currentPluginMode == KotlinPluginMode.K2 + } + if (!k2Chosen) { + LOG.debug("Not showing the K2 feedback dialog because the user doesn't use K2") + return false + } else { + val k2UserSince = Instant.ofEpochSecond(state.k2UserSince) + val durationSinceK2User = Duration.between(k2UserSince, Instant.now()) + + LOG.debug("Duration since user became a K2 Kotlin user: ${durationSinceK2User.toDays()} day(s)") + return durationSinceK2User > Duration.ofSeconds( + Registry.intValue("minimum.usage.time.before.showing.k2.survey").toLong() + ) + } + } + } +} \ No newline at end of file diff --git a/plugins/kotlin/onboarding/src/org/jetbrains/kotlin/onboarding/k2/satisfaction/survey/ShowK2FeedbackDialogAction.kt b/plugins/kotlin/onboarding/src/org/jetbrains/kotlin/onboarding/k2/satisfaction/survey/ShowK2FeedbackDialogAction.kt new file mode 100644 index 000000000000..d952070c9cc7 --- /dev/null +++ b/plugins/kotlin/onboarding/src/org/jetbrains/kotlin/onboarding/k2/satisfaction/survey/ShowK2FeedbackDialogAction.kt @@ -0,0 +1,11 @@ +// Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. +package org.jetbrains.kotlin.onboarding.k2.satisfaction.survey + +import com.intellij.openapi.actionSystem.AnAction +import com.intellij.openapi.actionSystem.AnActionEvent + +class ShowK2FeedbackDialogAction : AnAction() { + override fun actionPerformed(e: AnActionEvent) { + K2FeedbackDialog(e.project, true).show() + } +} \ No newline at end of file diff --git a/plugins/kotlin/onboarding/src/org/jetbrains/kotlin/onboarding/k2/satisfaction/survey/ShowK2SurveyNotificationAfterRestartPostStartupActivity.kt b/plugins/kotlin/onboarding/src/org/jetbrains/kotlin/onboarding/k2/satisfaction/survey/ShowK2SurveyNotificationAfterRestartPostStartupActivity.kt new file mode 100644 index 000000000000..a3397d4a6951 --- /dev/null +++ b/plugins/kotlin/onboarding/src/org/jetbrains/kotlin/onboarding/k2/satisfaction/survey/ShowK2SurveyNotificationAfterRestartPostStartupActivity.kt @@ -0,0 +1,21 @@ +// Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. +package org.jetbrains.kotlin.onboarding.k2.satisfaction.survey + +import com.intellij.ide.util.PropertiesComponent +import com.intellij.openapi.components.serviceAsync +import com.intellij.openapi.project.Project +import com.intellij.openapi.startup.ProjectActivity +import com.intellij.platform.feedback.impl.OnDemandFeedbackResolver + +internal class ShowK2SurveyNotificationAfterRestartPostStartupActivity : ProjectActivity { + + override suspend fun execute(project: Project) { + val propertiesComponent = serviceAsync() + val propertiesComponentKey = "K2KotlinSurveyWasProposedOnAppRestart" + if (!propertiesComponent.getBoolean(propertiesComponentKey)) { + if (OnDemandFeedbackResolver.getInstance().showFeedbackNotification(K2FeedbackSurvey::class, project)) { + propertiesComponent.updateValue(propertiesComponentKey, /* newValue = */ true) + } + } + } +} \ No newline at end of file diff --git a/plugins/kotlin/onboarding/test/onboarding/k2/satisfaction/survey/K2UserTrackerTest.kt b/plugins/kotlin/onboarding/test/onboarding/k2/satisfaction/survey/K2UserTrackerTest.kt new file mode 100644 index 000000000000..3a177567d08e --- /dev/null +++ b/plugins/kotlin/onboarding/test/onboarding/k2/satisfaction/survey/K2UserTrackerTest.kt @@ -0,0 +1,66 @@ +// Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. +package onboarding.k2.satisfaction.survey + +import com.intellij.testFramework.fixtures.LightJavaCodeInsightFixtureTestCase +import org.jetbrains.kotlin.onboarding.k2.satisfaction.survey.K2UserTracker +import java.time.Instant + +class K2UserTrackerTest: LightJavaCodeInsightFixtureTestCase() { + + private fun createInstance(): K2UserTracker { + val tracker = K2UserTracker() + tracker.forUnitTests = true + tracker.k2PluginModeForTests = true + return tracker + } + + fun `test the empty state should have correct values`() { + val instance = createInstance() + + assertFalse(instance.state.switchedToK1) + assertFalse(instance.state.userSawSurvey) + } + + fun `test don't show dialog without explicit switch to K1`() { + val instance = createInstance() + + assertFalse(instance.state.switchedToK1) + assertFalse(instance.state.userSawSurvey) + + assertFalse(instance.shouldShowK2FeedbackDialog()) + + assertFalse(instance.state.userSawSurvey) + } + + fun `test show dialog when explicit switch to K1`() { + val instance = createInstance() + instance.state.switchedToK1 = true + // instance.k2PluginModeForTests = false // it's not needed because the first branch with switchedToK1 should work + + assertFalse(instance.state.userSawSurvey) + + assertTrue(instance.shouldShowK2FeedbackDialog()) + } + + fun `test don't show dialog if less than one day on K2`() { + val instance = createInstance() + instance.state.k2UserSince = Instant.now().epochSecond.minus(1 * 60 * 60) // They've been on K2 just for 1 hour + + assertFalse(instance.state.switchedToK1) + assertFalse(instance.state.userSawSurvey) + + assertFalse(instance.shouldShowK2FeedbackDialog()) + + assertFalse(instance.state.userSawSurvey) + } + + fun `test show dialog if more than one day on K2`() { + val instance = createInstance() + instance.state.k2UserSince = Instant.now().epochSecond.minus(25 * 60 * 60) // They've been on K2 for 25 hours + + assertFalse(instance.state.switchedToK1) + assertFalse(instance.state.userSawSurvey) + + assertTrue(instance.shouldShowK2FeedbackDialog()) + } +} \ No newline at end of file diff --git a/plugins/kotlin/preferences/src/org/jetbrains/kotlin/idea/configuration/KotlinPluginKindSwitcherListener.kt b/plugins/kotlin/preferences/src/org/jetbrains/kotlin/idea/configuration/KotlinPluginKindSwitcherListener.kt new file mode 100644 index 000000000000..c7d5613ae739 --- /dev/null +++ b/plugins/kotlin/preferences/src/org/jetbrains/kotlin/idea/configuration/KotlinPluginKindSwitcherListener.kt @@ -0,0 +1,9 @@ +// Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. +package org.jetbrains.kotlin.idea.configuration + +import org.jetbrains.kotlin.idea.base.plugin.KotlinPluginMode +import java.util.* + +interface KotlinPluginKindSwitcherListener : EventListener { + fun kotlinPluginKindChanged(kotlinPluginMode: KotlinPluginMode) +} \ No newline at end of file diff --git a/plugins/kotlin/preferences/src/org/jetbrains/kotlin/idea/configuration/ui/KotlinPluginKindSwitcherController.kt b/plugins/kotlin/preferences/src/org/jetbrains/kotlin/idea/configuration/ui/KotlinPluginKindSwitcherController.kt index 53049c2e32e5..7f57f6db75e5 100644 --- a/plugins/kotlin/preferences/src/org/jetbrains/kotlin/idea/configuration/ui/KotlinPluginKindSwitcherController.kt +++ b/plugins/kotlin/preferences/src/org/jetbrains/kotlin/idea/configuration/ui/KotlinPluginKindSwitcherController.kt @@ -13,10 +13,12 @@ import com.intellij.ui.dsl.builder.AlignY import com.intellij.ui.dsl.builder.Panel import com.intellij.ui.dsl.builder.RightGap import com.intellij.ui.dsl.builder.panel +import com.intellij.util.EventDispatcher +import org.jetbrains.kotlin.idea.base.plugin.KotlinPluginKindSwitcher import org.jetbrains.kotlin.idea.base.plugin.KotlinPluginMode import org.jetbrains.kotlin.idea.base.plugin.KotlinPluginModeProvider -import org.jetbrains.kotlin.idea.base.plugin.KotlinPluginKindSwitcher import org.jetbrains.kotlin.idea.base.plugin.getPluginModeDescription +import org.jetbrains.kotlin.idea.configuration.KotlinPluginKindSwitcherListener import org.jetbrains.kotlin.idea.preferences.KotlinPreferencesBundle import javax.swing.JComponent @@ -32,6 +34,11 @@ internal class KotlinPluginKindSwitcherController { private lateinit var pluginTypeChooserPanel: Panel private lateinit var currentPluginPanel: Panel + private val pluginKindChangedDispatcher: EventDispatcher = + EventDispatcher.create( + KotlinPluginKindSwitcherListener::class.java + ) + private val productName: @NlsSafe String get() = ApplicationNamesInfo.getInstance().fullProductName @@ -42,6 +49,7 @@ internal class KotlinPluginKindSwitcherController { fun applyChanges() { KotlinPluginKindSwitcher.setPluginKindByVmOptions(chosenKind) updatePanels() + pluginKindChangedDispatcher.multicaster.kotlinPluginKindChanged(chosenKind) if (pluginKindWillBeSwitchedAfterRestart) { suggestRestart() }