mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-03-22 15:19:59 +07:00
[feedback] IJPL-177421 Permanent CSAT survey in IDEs
Store feedback dates globally to consider several major versions and RD scenario (cherry picked from commit 7194d98f019efecc0dbbca2e8b097be19fd11cfc) (cherry picked from commit 8729b09d1ef21adbecbf3cb15cdd9a329046ebf3) IJ-MR-155667 GitOrigin-RevId: f908baec1667d1e10cada10250253ce315d9ff6c
This commit is contained in:
committed by
intellij-monorepo-bot
parent
579d2eefad
commit
88af5d2f2d
@@ -26,7 +26,7 @@ internal class CsatFeedbackNextDayAction : AnAction(), ActionRemoteBehaviorSpeci
|
||||
|
||||
NotificationGroupManager.getInstance().getNotificationGroup("System Messages")
|
||||
.createNotification(
|
||||
"Next CSAT feedback day is " + nextDate.date.format(DateTimeFormatter.ISO_DATE) +
|
||||
"Next CSAT feedback day is " + nextDate.date.format(DateTimeFormatter.ISO_DATE) + ". " +
|
||||
"User is${if (!nextDate.isNewUser) " not " else " "}new.",
|
||||
NotificationType.INFORMATION
|
||||
)
|
||||
|
||||
@@ -6,6 +6,9 @@ import com.intellij.idea.AppMode
|
||||
import com.intellij.internal.statistic.eventLog.fus.MachineIdManager
|
||||
import com.intellij.openapi.application.ApplicationInfo
|
||||
import com.intellij.openapi.application.ConfigImportHelper
|
||||
import com.intellij.openapi.client.ClientKind
|
||||
import com.intellij.openapi.client.currentSessionOrNull
|
||||
import com.intellij.openapi.client.sessions
|
||||
import com.intellij.openapi.diagnostic.Logger
|
||||
import com.intellij.openapi.project.Project
|
||||
import com.intellij.openapi.util.registry.Registry
|
||||
@@ -26,8 +29,6 @@ import kotlin.math.abs
|
||||
internal const val USER_CONSIDERED_NEW_DAYS = 30
|
||||
internal const val NEW_USER_SURVEY_PERIOD = 29
|
||||
internal const val EXISTING_USER_SURVEY_PERIOD = 97
|
||||
internal const val CSAT_SURVEY_LAST_FEEDBACK_DATE_KEY = "csat.survey.last.feedback.date"
|
||||
internal const val CSAT_SURVEY_LAST_NOTIFICATION_DATE_KEY = "csat.survey.last.notification.date"
|
||||
|
||||
internal class CsatFeedbackSurvey : FeedbackSurvey() {
|
||||
override val feedbackSurveyType: InIdeFeedbackSurveyType<InIdeFeedbackSurveyConfig> =
|
||||
@@ -54,10 +55,19 @@ internal class CsatFeedbackSurveyConfig : InIdeFeedbackSurveyConfig {
|
||||
}
|
||||
|
||||
override fun updateStateAfterDialogClosedOk(project: Project) {
|
||||
PropertiesComponent.getInstance().setValue(CSAT_SURVEY_LAST_FEEDBACK_DATE_KEY, getCsatToday().format(DateTimeFormatter.ISO_LOCAL_DATE))
|
||||
CsatGlobalSettings.getInstance().lastFeedbackDate = getCsatToday().format(DateTimeFormatter.ISO_LOCAL_DATE)
|
||||
}
|
||||
|
||||
override fun checkExtraConditionSatisfied(project: Project): Boolean {
|
||||
if (project.currentSessionOrNull?.isGuest == true) {
|
||||
LOG.debug("We are a CWM guest, do not really need CSAT")
|
||||
return false
|
||||
}
|
||||
if (project.sessions(ClientKind.GUEST).isNotEmpty()) {
|
||||
LOG.debug("We are the CWM host at the moment, not the perfect time for CSAT")
|
||||
return false
|
||||
}
|
||||
|
||||
if (ConfigImportHelper.isFirstSession()) {
|
||||
LOG.debug("It's a first user session, skip the survey")
|
||||
return false
|
||||
@@ -66,7 +76,7 @@ internal class CsatFeedbackSurveyConfig : InIdeFeedbackSurveyConfig {
|
||||
val today = getCsatToday()
|
||||
LOG.debug("Today is ${today.format(DateTimeFormatter.ISO_LOCAL_DATE)}")
|
||||
|
||||
PropertiesComponent.getInstance().getValue(CSAT_SURVEY_LAST_NOTIFICATION_DATE_KEY)
|
||||
CsatGlobalSettings.getInstance().lastNotificationDate
|
||||
?.let { tryParseDate(it) }
|
||||
?.let {
|
||||
if (it.isEqual(today)) {
|
||||
@@ -75,7 +85,7 @@ internal class CsatFeedbackSurveyConfig : InIdeFeedbackSurveyConfig {
|
||||
}
|
||||
}
|
||||
|
||||
val lastFeedbackDate = PropertiesComponent.getInstance().getValue(CSAT_SURVEY_LAST_FEEDBACK_DATE_KEY)
|
||||
val lastFeedbackDate = CsatGlobalSettings.getInstance().lastFeedbackDate
|
||||
?.let { tryParseDate(it) }
|
||||
if (lastFeedbackDate != null && lastFeedbackDate.plusDays(EXISTING_USER_SURVEY_PERIOD.toLong()).isAfter(today)) {
|
||||
LOG.debug("User recently filled the survey, vacation period is in progress")
|
||||
@@ -116,10 +126,10 @@ internal class CsatFeedbackSurveyConfig : InIdeFeedbackSurveyConfig {
|
||||
}
|
||||
|
||||
override fun updateStateAfterNotificationShowed(project: Project) {
|
||||
val propertiesComponent = PropertiesComponent.getInstance()
|
||||
propertiesComponent.setValue(CSAT_SURVEY_LAST_NOTIFICATION_DATE_KEY, getCsatToday().format(DateTimeFormatter.ISO_LOCAL_DATE))
|
||||
CsatGlobalSettings.getInstance().lastNotificationDate = getCsatToday().format(DateTimeFormatter.ISO_LOCAL_DATE)
|
||||
|
||||
// disable an automatic Evaluate Feedback form so we don't have them both shown
|
||||
propertiesComponent.setValue("evaluation.feedback.enabled", "false")
|
||||
PropertiesComponent.getInstance().setValue("evaluation.feedback.enabled", "false")
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,48 @@
|
||||
// Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
package com.intellij.platform.feedback.csat
|
||||
|
||||
import com.intellij.frontend.HostIdeInfoService
|
||||
import com.intellij.ide.Prefs
|
||||
import com.intellij.openapi.application.ApplicationInfo
|
||||
import com.intellij.openapi.components.service
|
||||
|
||||
private const val CSAT_NEW_USER_CREATED_AT_KEY = "csat.user.created.at"
|
||||
private const val CSAT_SURVEY_LAST_FEEDBACK_DATE_KEY = "csat.survey.last.feedback.date"
|
||||
private const val CSAT_SURVEY_LAST_NOTIFICATION_DATE_KEY = "csat.survey.last.notification.date"
|
||||
|
||||
internal class CsatGlobalSettings private constructor(
|
||||
private val productCode: String,
|
||||
) {
|
||||
companion object {
|
||||
fun getInstance(): CsatGlobalSettings {
|
||||
return CsatGlobalSettings(service<HostIdeInfoService>().getHostInfo()?.productCode
|
||||
?: ApplicationInfo.getInstance().build.productCode)
|
||||
}
|
||||
}
|
||||
|
||||
private fun productKey(keyName: String): String = "JetBrains.$productCode.$keyName"
|
||||
|
||||
var lastFeedbackDate: String?
|
||||
get() = Prefs.get(productKey(CSAT_SURVEY_LAST_FEEDBACK_DATE_KEY), null)
|
||||
set(value) {
|
||||
val key = productKey(CSAT_SURVEY_LAST_FEEDBACK_DATE_KEY)
|
||||
Prefs.put(key, value)
|
||||
Prefs.flush(key)
|
||||
}
|
||||
|
||||
var lastNotificationDate: String?
|
||||
get() = Prefs.get(productKey(CSAT_SURVEY_LAST_NOTIFICATION_DATE_KEY), null)
|
||||
set(value) {
|
||||
val key = productKey(CSAT_SURVEY_LAST_NOTIFICATION_DATE_KEY)
|
||||
Prefs.put(key, value)
|
||||
Prefs.flush(key)
|
||||
}
|
||||
|
||||
var newUserCreatedAt: String?
|
||||
get() = Prefs.get(productKey(CSAT_NEW_USER_CREATED_AT_KEY), null)
|
||||
set(value) {
|
||||
val key = productKey(CSAT_NEW_USER_CREATED_AT_KEY)
|
||||
Prefs.put(key, value)
|
||||
Prefs.flush(key)
|
||||
}
|
||||
}
|
||||
@@ -1,7 +1,6 @@
|
||||
// Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
package com.intellij.platform.feedback.csat
|
||||
|
||||
import com.intellij.ide.util.PropertiesComponent
|
||||
import com.intellij.openapi.application.ConfigImportHelper
|
||||
import com.intellij.openapi.project.Project
|
||||
import com.intellij.openapi.startup.ProjectActivity
|
||||
@@ -9,16 +8,12 @@ import com.intellij.openapi.util.registry.Registry
|
||||
import java.time.LocalDate
|
||||
import java.time.format.DateTimeFormatter.ISO_LOCAL_DATE
|
||||
|
||||
internal const val CSAT_NEW_USER_CREATED_AT_PROPERTY = "csat.user.created.at"
|
||||
|
||||
internal class CsatNewUserTracker : ProjectActivity {
|
||||
override suspend fun execute(project: Project) {
|
||||
if (ConfigImportHelper.isNewUser()) {
|
||||
val propertiesComponent = PropertiesComponent.getInstance()
|
||||
|
||||
if (!propertiesComponent.isValueSet(CSAT_NEW_USER_CREATED_AT_PROPERTY)) {
|
||||
propertiesComponent.setValue(CSAT_NEW_USER_CREATED_AT_PROPERTY,
|
||||
LocalDate.now().format(ISO_LOCAL_DATE))
|
||||
val settings = CsatGlobalSettings.getInstance()
|
||||
if (settings.newUserCreatedAt == null) {
|
||||
settings.newUserCreatedAt = LocalDate.now().format(ISO_LOCAL_DATE)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -30,6 +25,6 @@ internal fun getCsatUserCreatedDate(): LocalDate? {
|
||||
return tryParseDate(mocked)
|
||||
}
|
||||
|
||||
val date = PropertiesComponent.getInstance().getValue(CSAT_NEW_USER_CREATED_AT_PROPERTY) ?: return null
|
||||
val date = CsatGlobalSettings.getInstance().newUserCreatedAt ?: return null
|
||||
return tryParseDate(date)
|
||||
}
|
||||
Reference in New Issue
Block a user