From a759707a316aae1fb6e32493240b5ba5b53ffd37 Mon Sep 17 00:00:00 2001 From: Dmitry Avdeev Date: Mon, 19 Jun 2023 16:19:59 +0200 Subject: [PATCH] smart update: scheduling GitOrigin-RevId: a0d813e6d5ecbd3c15fb2780f7468138cfe3052e --- .../messages/SmartUpdateBundle.properties | 4 ++- .../com/intellij/smartUpdate/SmartUpdate.kt | 27 ++++++++++++++++--- .../intellij/smartUpdate/SmartUpdateDialog.kt | 25 +++++++++++++++++ 3 files changed, 52 insertions(+), 4 deletions(-) diff --git a/platform/smart-update/resources/messages/SmartUpdateBundle.properties b/platform/smart-update/resources/messages/SmartUpdateBundle.properties index 390164e5371f..20a2f67789e4 100644 --- a/platform/smart-update/resources/messages/SmartUpdateBundle.properties +++ b/platform/smart-update/resources/messages/SmartUpdateBundle.properties @@ -4,4 +4,6 @@ checkbox.build.project=&Build project checkbox.update.project=&Update project checkbox.update.ide=Update &IDE dialog.title.smart.update=Update and Build -no.updates.available=No updates available \ No newline at end of file +no.updates.available=No updates available +checkbox.schedule.update=Schedule update +label.every.day.at=Every day at \ No newline at end of file diff --git a/platform/smart-update/src/com/intellij/smartUpdate/SmartUpdate.kt b/platform/smart-update/src/com/intellij/smartUpdate/SmartUpdate.kt index 1904e0f52aec..6279eb7b7e8f 100644 --- a/platform/smart-update/src/com/intellij/smartUpdate/SmartUpdate.kt +++ b/platform/smart-update/src/com/intellij/smartUpdate/SmartUpdate.kt @@ -5,9 +5,9 @@ import com.intellij.ide.util.PropertiesComponent import com.intellij.openapi.Disposable import com.intellij.openapi.actionSystem.ActionUpdateThread import com.intellij.openapi.actionSystem.AnActionEvent -import com.intellij.openapi.actionSystem.impl.SimpleDataContext import com.intellij.openapi.application.ApplicationManager import com.intellij.openapi.components.* +import com.intellij.openapi.progress.blockingContext import com.intellij.openapi.project.DumbAwareAction import com.intellij.openapi.project.Project import com.intellij.openapi.startup.ProjectActivity @@ -16,14 +16,22 @@ import com.intellij.openapi.vcs.update.CommonUpdateProjectAction import com.intellij.ui.dsl.builder.MutableProperty import com.intellij.util.xmlb.XmlSerializerUtil import com.intellij.util.xmlb.annotations.MapAnnotation +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.async +import kotlinx.coroutines.delay import org.jetbrains.ide.UpdateActionsListener +import java.time.Duration +import java.time.LocalTime import java.util.* @State(name = "SmartUpdateOptions", storages = [Storage(value = StoragePathMacros.WORKSPACE_FILE, roamingType = RoamingType.DISABLED)]) @Service(Service.Level.PROJECT) -class SmartUpdate(val project: Project) : PersistentStateComponent, Disposable { +class SmartUpdate(val project: Project, private val coroutineScope: CoroutineScope) : PersistentStateComponent, Disposable { class Options: BaseState() { + var scheduled = false + var scheduledTime: LocalTime = LocalTime.of(6, 0) + @get:MapAnnotation(surroundWithTag = false) var map: MutableMap by linkedMap() fun value(id: String) = map[id] ?: true @@ -54,12 +62,23 @@ class SmartUpdate(val project: Project) : PersistentStateComponent, project: Project, e: AnActionEvent?) { steps.poll()?.performUpdateStep(project, e) { executeNext(steps, project, e) } } + internal fun scheduleUpdate() { + if (!options.scheduled) return + coroutineScope.async { + var duration = Duration.between(LocalTime.now(), options.scheduledTime) + if (duration.isNegative) duration = duration.plusDays(1) + delay(duration.toMillis()) + blockingContext { execute(project) } + } + } + override fun dispose() { } } @@ -91,9 +110,11 @@ const val IDE_RESTARTED_KEY = "smart.update.ide.restarted" class IdeRestartedActivity: ProjectActivity { override suspend fun execute(project: Project) { + val service = project.service() if (PropertiesComponent.getInstance().isTrueValue(IDE_RESTARTED_KEY)) { PropertiesComponent.getInstance().setValue(IDE_RESTARTED_KEY, false) - project.service().execute(project) + service.execute(project) } + else service.scheduleUpdate() } } \ No newline at end of file diff --git a/platform/smart-update/src/com/intellij/smartUpdate/SmartUpdateDialog.kt b/platform/smart-update/src/com/intellij/smartUpdate/SmartUpdateDialog.kt index 297ab1b71fc1..7b3a42a22cc8 100644 --- a/platform/smart-update/src/com/intellij/smartUpdate/SmartUpdateDialog.kt +++ b/platform/smart-update/src/com/intellij/smartUpdate/SmartUpdateDialog.kt @@ -4,8 +4,18 @@ import com.intellij.openapi.components.service import com.intellij.openapi.project.Project import com.intellij.openapi.ui.DialogPanel import com.intellij.openapi.ui.DialogWrapper +import com.intellij.ui.components.JBCheckBox +import com.intellij.ui.dsl.builder.Cell import com.intellij.ui.dsl.builder.bindSelected import com.intellij.ui.dsl.builder.panel +import com.intellij.ui.dsl.builder.selected +import java.time.Instant +import java.time.LocalDate +import java.time.LocalTime +import java.time.ZoneId +import java.util.* +import javax.swing.JSpinner +import javax.swing.SpinnerDateModel class SmartUpdateDialog(private val project: Project) : DialogWrapper(project) { init { @@ -26,6 +36,21 @@ class SmartUpdateDialog(private val project: Project) : DialogWrapper(project) { indent { row { cell(it).enabled(enabled) } } } } + lateinit var scheduled: Cell + row { scheduled = checkBox(SmartUpdateBundle.message("checkbox.schedule.update")).bindSelected({ options.scheduled }, { options.scheduled = it}) } + indent { + val spinner = JSpinner(SpinnerDateModel().apply { value = getScheduled(options.scheduledTime) }) + spinner.editor = JSpinner.DateEditor(spinner, "hh:mm") + row { + label(SmartUpdateBundle.message("label.every.day.at")) + cell(spinner) + }.enabledIf(scheduled.selected) + } } } + + private fun getScheduled(time: LocalTime): Date { + val instant: Instant = time.atDate(LocalDate.now()).atZone(ZoneId.systemDefault()).toInstant() + return Date.from(instant) + } } \ No newline at end of file