[notifications] IJPL-245717 migrate do not ask notification settings to their own file (rem-dev friendly)

we now use settings sync based on `RDSettingsController` to synchronize changes to the settings files between fe and be

GitOrigin-RevId: 1fd548622e12463c1ad27297a1839961ea06d024
This commit is contained in:
Marina Mădăraș
2026-08-18 11:55:58 +00:00
committed by intellij-monorepo-bot
parent 4aebca29f0
commit d0f8fdac9b
6 changed files with 189 additions and 50 deletions
@@ -0,0 +1,34 @@
// Copyright 2000-2026 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package com.intellij.notification
import com.intellij.openapi.application.ApplicationManager
import com.intellij.openapi.project.Project
import org.jetbrains.annotations.ApiStatus
import org.jetbrains.annotations.Nls
@ApiStatus.Internal
interface DoNotAskManager {
fun isDoNotAsk(notificationId: String): Boolean
fun markDoNotAsk(notificationId: String, @Nls displayName: String?)
fun clearDoNotAsk(notificationId: String)
fun getDoNotAskNotifications(): Map<String, String>
}
@ApiStatus.Internal
interface DoNotAskAppManager : DoNotAskManager {
companion object {
@JvmStatic
fun getInstance(): DoNotAskAppManager = ApplicationManager.getApplication().getService(DoNotAskAppManager::class.java)
}
}
@ApiStatus.Internal
interface DoNotAskProjectManager : DoNotAskManager {
companion object {
@JvmStatic
fun getInstance(project: Project): DoNotAskProjectManager = project.getService(DoNotAskProjectManager::class.java)
}
}
@@ -3,7 +3,6 @@ package com.intellij.notification;
import com.intellij.ide.IdeCoreBundle;
import com.intellij.ide.ui.IdeUiService;
import com.intellij.ide.util.PropertiesComponent;
import com.intellij.openapi.actionSystem.ActionPlaces;
import com.intellij.openapi.actionSystem.ActionUiKind;
import com.intellij.openapi.actionSystem.AnAction;
@@ -204,13 +203,11 @@ public class Notification {
myDoNotAskDisplayName = title;
myDoNotAskId = myGroupId;
}
var id = "Notification.DoNotAsk-" + myDoNotAskId;
var doNotAsk = PropertiesComponent.getInstance().getBoolean(id, false);
if (doNotAsk) {
if (DoNotAskAppManager.getInstance().isDoNotAsk(myDoNotAskId)) {
return false;
}
if (project != null) {
return !PropertiesComponent.getInstance(project).getBoolean(id, false);
return !DoNotAskProjectManager.getInstance(project).isDoNotAsk(myDoNotAskId);
}
return true;
}
@@ -443,22 +440,22 @@ public class Notification {
);
}
private static final String DO_NOT_ASK_PREFIX = "Notification.DoNotAsk-";
private static final String DO_NOT_ASK_DISPLAY_PREFIX = "Notification.DisplayName-DoNotAsk-";
@ApiStatus.Experimental
@Contract("_ -> this")
public Notification setDoNotAskFor(@Nullable Project project) {
var manager = project == null ? PropertiesComponent.getInstance() : PropertiesComponent.getInstance(project);
manager.setValue(DO_NOT_ASK_PREFIX + myDoNotAskId, true);
manager.setValue(DO_NOT_ASK_DISPLAY_PREFIX + myDoNotAskId, myDoNotAskDisplayName);
if (project == null) {
DoNotAskAppManager.getInstance().markDoNotAsk(myDoNotAskId, myDoNotAskDisplayName);
}
else {
DoNotAskProjectManager.getInstance(project).markDoNotAsk(myDoNotAskId, myDoNotAskDisplayName);
}
return this;
}
@ApiStatus.Experimental
public static boolean isDoNotAskFor(@Nullable Project project, @NotNull String doNotAskId) {
return project != null && PropertiesComponent.getInstance(project).getBoolean(DO_NOT_ASK_PREFIX + doNotAskId) ||
PropertiesComponent.getInstance().getBoolean(DO_NOT_ASK_PREFIX + doNotAskId);
return project != null && DoNotAskProjectManager.getInstance(project).isDoNotAsk(doNotAskId) ||
DoNotAskAppManager.getInstance().isDoNotAsk(doNotAskId);
}
@ApiStatus.Internal
@@ -0,0 +1,42 @@
// Copyright 2000-2026 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package com.intellij.notification.impl
import com.intellij.configurationStore.saveSettingsForRemoteDevelopment
import com.intellij.ide.util.PropertiesComponent
import com.intellij.notification.DoNotAskAppManager
import com.intellij.notification.DoNotAskProjectManager
import com.intellij.openapi.components.State
import com.intellij.openapi.components.Storage
import com.intellij.openapi.project.Project
import com.intellij.util.application
import kotlinx.coroutines.CoroutineScope
@State(name = "DoNotAskAppManager", storages = [Storage(value = "doNotAskNotifications.xml")])
internal class DoNotAskAppManagerImpl(private val cs: CoroutineScope) :
DoNotAskSettings(), DoNotAskAppManager {
override fun saveSettingsForRemDev() {
saveSettingsForRemoteDevelopment(cs, application)
}
override fun getPropertiesComponent() : PropertiesComponent {
return PropertiesComponent.getInstance()
}
}
@State(name = "DoNotAskProjectManager", storages = [Storage(value = "doNotAskNotifications.xml")], useLoadedStateAsExisting = false)
internal class DoNotAskProjectManagerImpl(private val project: Project, private val cs: CoroutineScope) :
DoNotAskSettings(), DoNotAskProjectManager {
override fun saveSettingsForRemDev() {
saveSettingsForRemoteDevelopment(cs, project)
}
override fun getPropertiesComponent() : PropertiesComponent {
return PropertiesComponent.getInstance(project)
}
}
@@ -0,0 +1,71 @@
// Copyright 2000-2026 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package com.intellij.notification.impl
import com.intellij.ide.util.BasePropertyService
import com.intellij.ide.util.PropertiesComponent
import com.intellij.openapi.components.BaseState
import com.intellij.openapi.components.SimplePersistentStateComponent
import org.jetbrains.annotations.Nls
private const val DO_NOT_ASK_KEY_PREFIX = "Notification.DoNotAsk-"
private const val DO_NOT_ASK_DISPLAY_KEY_PREFIX = "Notification.DisplayName-DoNotAsk-"
internal class DoNotAskState : BaseState() {
var idToDisplayName: MutableMap<String, String> by map()
}
internal abstract class DoNotAskSettings : SimplePersistentStateComponent<DoNotAskState>(DoNotAskState()) {
@Synchronized
fun isDoNotAsk(notificationId: String): Boolean = notificationId in state.idToDisplayName
@Synchronized
fun markDoNotAsk(notificationId: String, @Nls displayName: String?) {
state.idToDisplayName[notificationId] = displayName ?: notificationId
saveSettingsForRemDev()
}
@Synchronized
fun getDoNotAskNotifications(): Map<String, String> = LinkedHashMap(state.idToDisplayName)
@Synchronized
open fun clearDoNotAsk(notificationId: String) {
state.idToDisplayName.remove(notificationId)
saveSettingsForRemDev()
}
@Synchronized
override fun noStateLoaded() {
state.idToDisplayName.clear()
migrateFromPropertiesComponent(getPropertiesComponent())
}
abstract fun saveSettingsForRemDev()
abstract fun getPropertiesComponent() : PropertiesComponent
fun migrateFromPropertiesComponent(manager: PropertiesComponent) {
if (manager !is BasePropertyService) return
val idsToMigrate = ArrayList<String>()
manager.forEachPrimitiveValue { key, _ ->
if (key.startsWith(DO_NOT_ASK_KEY_PREFIX)) {
val notificationId = key.substring(DO_NOT_ASK_KEY_PREFIX.length)
idsToMigrate.add(notificationId)
}
}
for (id in idsToMigrate) {
val displayName = manager.getValue(DO_NOT_ASK_DISPLAY_KEY_PREFIX + id, id)
state.idToDisplayName[id] = displayName
manager.unsetValue(DO_NOT_ASK_KEY_PREFIX + id)
manager.unsetValue(DO_NOT_ASK_DISPLAY_KEY_PREFIX + id)
}
}
}
@@ -3,8 +3,8 @@ package com.intellij.notification.impl.ui
import com.intellij.ide.DataManager
import com.intellij.ide.IdeBundle
import com.intellij.ide.util.BasePropertyService
import com.intellij.ide.util.PropertiesComponent
import com.intellij.notification.DoNotAskAppManager
import com.intellij.notification.DoNotAskProjectManager
import com.intellij.openapi.actionSystem.CommonDataKeys
import com.intellij.openapi.project.Project
import com.intellij.openapi.wm.WindowManager
@@ -16,8 +16,6 @@ import javax.swing.DefaultListModel
import javax.swing.JComponent
import kotlin.math.min
private const val DO_NOT_ASK_KEY_PREFIX = "Notification.DoNotAsk-"
internal class DoNotAskConfigurableUi {
private var myCreated = false
private lateinit var myList: JBList<DoNotAskInfo>
@@ -33,33 +31,32 @@ internal class DoNotAskConfigurableUi {
}
private fun getDoNotAskValues(): List<DoNotAskInfo> {
val list = ArrayList<DoNotAskInfo>()
return buildList {
addAll(
convertToDoNotAskValues(
DoNotAskAppManager.getInstance().getDoNotAskNotifications(),
forProject = false
)
)
getValues(PropertiesComponent.getInstance(), list, false)
val project = getProject()
if (project != null) {
getValues(PropertiesComponent.getInstance(project), list, true)
}
list.sortWith(Comparator { o1, o2 -> o1.id.compareTo(o2.id) })
return list
getProject()?.let { project ->
addAll(
convertToDoNotAskValues(
DoNotAskProjectManager.getInstance(project).getDoNotAskNotifications(),
forProject = true
)
)
}
}.sortedBy(DoNotAskInfo::id)
}
private fun getProject(): Project? {
return CommonDataKeys.PROJECT.getData(DataManager.getInstance().getDataContext(WindowManager.getInstance().mostRecentFocusedWindow))
}
private fun getValues(manager: PropertiesComponent, list: ArrayList<DoNotAskInfo>, forProject: Boolean) {
if (manager is BasePropertyService) {
manager.forEachPrimitiveValue { key, _ ->
if (key.startsWith(DO_NOT_ASK_KEY_PREFIX)) {
val id = key.substring(DO_NOT_ASK_KEY_PREFIX.length)
val name = manager.getValue("Notification.DisplayName-DoNotAsk-$id", id)
list.add(DoNotAskInfo(id, name, forProject))
}
}
private fun convertToDoNotAskValues(entries: Map<String, String>, forProject: Boolean): List<DoNotAskInfo> {
return entries.map { (id, name) ->
DoNotAskInfo(id, name, forProject)
}
}
@@ -101,28 +98,18 @@ internal class DoNotAskConfigurableUi {
}
fun apply() {
val manager = PropertiesComponent.getInstance()
val project = getProject()
val projectManager = if (project == null) null else PropertiesComponent.getInstance(project)
for (info in myRemoveList) {
if (info.forProject) {
if (projectManager != null) {
removeKey(projectManager, info.id)
}
project?.let { DoNotAskProjectManager.getInstance(it).clearDoNotAsk(info.id) }
}
else {
removeKey(manager, info.id)
DoNotAskAppManager.getInstance().clearDoNotAsk(info.id)
}
}
}
private fun removeKey(manager: PropertiesComponent, id: String) {
manager.unsetValue("Notification.DoNotAsk-$id")
manager.unsetValue("Notification.DisplayName-DoNotAsk-$id")
}
}
@ApiStatus.Internal
data class DoNotAskInfo(val id: String, val name: String, val forProject: Boolean)
data class DoNotAskInfo(val id: String, val name: String, val forProject: Boolean)
@@ -904,6 +904,14 @@ The refresh itself is toggled by (Preferences | Appearance &amp; Behavior | Syst
serviceImplementation="com.intellij.notification.impl.NotificationsManagerImpl"/>
<applicationService serviceInterface="com.intellij.notification.NotificationsConfiguration"
serviceImplementation="com.intellij.notification.impl.NotificationsConfigurationImpl"/>
<applicationService serviceInterface="com.intellij.notification.DoNotAskAppManager"
serviceImplementation="com.intellij.notification.impl.DoNotAskAppManagerImpl"/>
<projectService serviceInterface="com.intellij.notification.DoNotAskProjectManager"
serviceImplementation="com.intellij.notification.impl.DoNotAskProjectManagerImpl"/>
<applicationSettings service="com.intellij.notification.impl.DoNotAskAppManagerImpl"/>
<projectSettings service="com.intellij.notification.impl.DoNotAskProjectManagerImpl"/>
<applicationSettings service="com.intellij.notification.impl.NotificationsConfigurationImpl"/>