diff --git a/build.gradle.kts b/build.gradle.kts index 95e8c8f83..6e7ce6033 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -8,7 +8,7 @@ plugins { // Custom plugin for building all the themes id("doki-theme-plugin") // Kotlin support - kotlin("jvm") version "1.8.10" + kotlin("jvm") version "1.9.22" // gradle-intellij-plugin - read more: https://github.com/JetBrains/gradle-intellij-plugin id("org.jetbrains.intellij") version "1.16.1" // detekt linter - read more: https://detekt.github.io/detekt/gradle.html @@ -57,7 +57,7 @@ intellij { plugins.set( properties("platformPlugins").split(',') .map(String::trim) - .filter(String::isNotEmpty) + .filter(String::isNotEmpty), ) } diff --git a/buildSrc/build.gradle.kts b/buildSrc/build.gradle.kts index 07b6b342a..6e6dfb013 100644 --- a/buildSrc/build.gradle.kts +++ b/buildSrc/build.gradle.kts @@ -1,5 +1,5 @@ plugins { - kotlin("jvm") version "1.8.10" + kotlin("jvm") version "1.9.22" `kotlin-dsl` } diff --git a/detekt-config.yml b/detekt-config.yml index 5d70d58a7..ad3e80f12 100644 --- a/detekt-config.yml +++ b/detekt-config.yml @@ -18,7 +18,7 @@ formatting: active: false autoCorrect: false Indentation: - active: true + active: false autoCorrect: false indentSize: 2 ParameterListWrapping: diff --git a/src/main/kotlin/io/unthrottled/doki/TheDokiTheme.kt b/src/main/kotlin/io/unthrottled/doki/TheDokiTheme.kt index b71c9694c..1c14c102d 100644 --- a/src/main/kotlin/io/unthrottled/doki/TheDokiTheme.kt +++ b/src/main/kotlin/io/unthrottled/doki/TheDokiTheme.kt @@ -47,7 +47,7 @@ class TheDokiTheme : Disposable { .map { it.toOptional() } .orElseGet { PluginManagerCore.getPlugin( - PluginId.getId(ULTIMATE_PLUGIN_ID) + PluginId.getId(ULTIMATE_PLUGIN_ID), ).toOptional() } .map { it.version } @@ -73,7 +73,7 @@ class TheDokiTheme : Disposable { setSVGColorPatcher(it) } } - } + }, ) connection.subscribe( @@ -89,7 +89,7 @@ class TheDokiTheme : Disposable { IconPathReplacementComponent.removePatchers() LookAndFeelInstaller.removeIcons() } - } + }, ) } @@ -118,7 +118,7 @@ class TheDokiTheme : Disposable { UpdateNotification.display( project, version, - isNewUser + isNewUser, ) } } diff --git a/src/main/kotlin/io/unthrottled/doki/actions/BackgroundToggleAction.kt b/src/main/kotlin/io/unthrottled/doki/actions/BackgroundToggleAction.kt index b65894d14..8c1985abe 100644 --- a/src/main/kotlin/io/unthrottled/doki/actions/BackgroundToggleAction.kt +++ b/src/main/kotlin/io/unthrottled/doki/actions/BackgroundToggleAction.kt @@ -5,10 +5,12 @@ import io.unthrottled.doki.config.ThemeConfig import io.unthrottled.doki.settings.actors.BackgroundActor class BackgroundToggleAction : BaseToggleAction() { - override fun isSelected(e: AnActionEvent): Boolean = - ThemeConfig.instance.isDokiBackground + override fun isSelected(e: AnActionEvent): Boolean = ThemeConfig.instance.isDokiBackground - override fun setSelected(e: AnActionEvent, state: Boolean) { + override fun setSelected( + e: AnActionEvent, + state: Boolean, + ) { BackgroundActor.handleBackgroundUpdate(state) } } diff --git a/src/main/kotlin/io/unthrottled/doki/actions/DiscreetModeAction.kt b/src/main/kotlin/io/unthrottled/doki/actions/DiscreetModeAction.kt index d86981ab2..78785c423 100644 --- a/src/main/kotlin/io/unthrottled/doki/actions/DiscreetModeAction.kt +++ b/src/main/kotlin/io/unthrottled/doki/actions/DiscreetModeAction.kt @@ -6,10 +6,12 @@ import io.unthrottled.doki.discreet.toDiscreetMode import io.unthrottled.doki.settings.actors.DiscreetModeActor class DiscreetModeAction : BaseToggleAction() { - override fun isSelected(e: AnActionEvent): Boolean = - ThemeConfig.instance.discreetMode + override fun isSelected(e: AnActionEvent): Boolean = ThemeConfig.instance.discreetMode - override fun setSelected(e: AnActionEvent, state: Boolean) { + override fun setSelected( + e: AnActionEvent, + state: Boolean, + ) { DiscreetModeActor.dispatchDiscreetMode(state.toDiscreetMode()) } } diff --git a/src/main/kotlin/io/unthrottled/doki/actions/HideOnHoverAction.kt b/src/main/kotlin/io/unthrottled/doki/actions/HideOnHoverAction.kt index c5c30483b..d196c0e3c 100644 --- a/src/main/kotlin/io/unthrottled/doki/actions/HideOnHoverAction.kt +++ b/src/main/kotlin/io/unthrottled/doki/actions/HideOnHoverAction.kt @@ -8,10 +8,13 @@ import io.unthrottled.doki.settings.actors.StickerHideActor class HideOnHoverAction : BaseToggleAction(), DumbAware { override fun isSelected(e: AnActionEvent): Boolean = ThemeConfig.instance.hideOnHover - override fun setSelected(e: AnActionEvent, state: Boolean) { + override fun setSelected( + e: AnActionEvent, + state: Boolean, + ) { StickerHideActor.setStickerHideStuff( state, - ThemeConfig.instance.hideDelayMS + ThemeConfig.instance.hideDelayMS, ) } } diff --git a/src/main/kotlin/io/unthrottled/doki/actions/MoveableStickerToggleAction.kt b/src/main/kotlin/io/unthrottled/doki/actions/MoveableStickerToggleAction.kt index 61fe83e37..8bb537495 100644 --- a/src/main/kotlin/io/unthrottled/doki/actions/MoveableStickerToggleAction.kt +++ b/src/main/kotlin/io/unthrottled/doki/actions/MoveableStickerToggleAction.kt @@ -5,10 +5,12 @@ import io.unthrottled.doki.config.ThemeConfig import io.unthrottled.doki.settings.actors.MoveableStickerActor class MoveableStickerToggleAction : BaseToggleAction() { - override fun isSelected(e: AnActionEvent): Boolean = - ThemeConfig.instance.isMoveableStickers + override fun isSelected(e: AnActionEvent): Boolean = ThemeConfig.instance.isMoveableStickers - override fun setSelected(e: AnActionEvent, state: Boolean) { + override fun setSelected( + e: AnActionEvent, + state: Boolean, + ) { MoveableStickerActor.moveableStickers(state) } } diff --git a/src/main/kotlin/io/unthrottled/doki/actions/ShowSettingsAction.kt b/src/main/kotlin/io/unthrottled/doki/actions/ShowSettingsAction.kt index f23e67f3d..e7cdd08f7 100644 --- a/src/main/kotlin/io/unthrottled/doki/actions/ShowSettingsAction.kt +++ b/src/main/kotlin/io/unthrottled/doki/actions/ShowSettingsAction.kt @@ -15,10 +15,10 @@ class ShowSettingsAction : AnAction(), DumbAware { { ShowSettingsUtil.getInstance().showSettingsDialog( ProjectManager.getInstance().defaultProject, - THEME_SETTINGS_DISPLAY_NAME + THEME_SETTINGS_DISPLAY_NAME, ) }, - ModalityState.NON_MODAL + ModalityState.NON_MODAL, ) } } diff --git a/src/main/kotlin/io/unthrottled/doki/actions/ShowUpdateNotification.kt b/src/main/kotlin/io/unthrottled/doki/actions/ShowUpdateNotification.kt index 1e797dbdd..9c843b173 100644 --- a/src/main/kotlin/io/unthrottled/doki/actions/ShowUpdateNotification.kt +++ b/src/main/kotlin/io/unthrottled/doki/actions/ShowUpdateNotification.kt @@ -7,14 +7,13 @@ import io.unthrottled.doki.TheDokiTheme import io.unthrottled.doki.notification.UpdateNotification class ShowUpdateNotification : AnAction(), DumbAware { - override fun actionPerformed(e: AnActionEvent) { TheDokiTheme.getVersion() .ifPresent { UpdateNotification.display( e.project!!, it, - false + false, ) } } diff --git a/src/main/kotlin/io/unthrottled/doki/actions/StickersToggleAction.kt b/src/main/kotlin/io/unthrottled/doki/actions/StickersToggleAction.kt index 28447c3a4..4c6bb8783 100644 --- a/src/main/kotlin/io/unthrottled/doki/actions/StickersToggleAction.kt +++ b/src/main/kotlin/io/unthrottled/doki/actions/StickersToggleAction.kt @@ -6,10 +6,12 @@ import io.unthrottled.doki.settings.actors.StickerActor import io.unthrottled.doki.stickers.StickerLevel.ON class StickersToggleAction : BaseToggleAction() { - override fun isSelected(e: AnActionEvent): Boolean = - ThemeConfig.instance.currentStickerLevel == ON + override fun isSelected(e: AnActionEvent): Boolean = ThemeConfig.instance.currentStickerLevel == ON - override fun setSelected(e: AnActionEvent, state: Boolean) { + override fun setSelected( + e: AnActionEvent, + state: Boolean, + ) { StickerActor.enableStickers(state) } } diff --git a/src/main/kotlin/io/unthrottled/doki/actions/SwapStickerAction.kt b/src/main/kotlin/io/unthrottled/doki/actions/SwapStickerAction.kt index 574040bd1..bb3720c1f 100644 --- a/src/main/kotlin/io/unthrottled/doki/actions/SwapStickerAction.kt +++ b/src/main/kotlin/io/unthrottled/doki/actions/SwapStickerAction.kt @@ -6,10 +6,12 @@ import io.unthrottled.doki.settings.actors.StickerActor import io.unthrottled.doki.stickers.CurrentSticker class SwapStickerAction : BaseToggleAction() { - override fun isSelected(e: AnActionEvent): Boolean = - ThemeConfig.instance.currentSticker == CurrentSticker.SECONDARY + override fun isSelected(e: AnActionEvent): Boolean = ThemeConfig.instance.currentSticker == CurrentSticker.SECONDARY - override fun setSelected(e: AnActionEvent, state: Boolean) { + override fun setSelected( + e: AnActionEvent, + state: Boolean, + ) { StickerActor.swapStickers(if (state) CurrentSticker.SECONDARY else CurrentSticker.DEFAULT) } } diff --git a/src/main/kotlin/io/unthrottled/doki/actions/ThemeAnimationToggle.kt b/src/main/kotlin/io/unthrottled/doki/actions/ThemeAnimationToggle.kt index 06d521420..eaa1947a8 100644 --- a/src/main/kotlin/io/unthrottled/doki/actions/ThemeAnimationToggle.kt +++ b/src/main/kotlin/io/unthrottled/doki/actions/ThemeAnimationToggle.kt @@ -5,10 +5,12 @@ import io.unthrottled.doki.config.ThemeConfig import io.unthrottled.doki.settings.actors.LafAnimationActor class ThemeAnimationToggle : BaseToggleAction() { - override fun isSelected(e: AnActionEvent): Boolean = - ThemeConfig.instance.isLafAnimation + override fun isSelected(e: AnActionEvent): Boolean = ThemeConfig.instance.isLafAnimation - override fun setSelected(e: AnActionEvent, state: Boolean) { + override fun setSelected( + e: AnActionEvent, + state: Boolean, + ) { LafAnimationActor.enableAnimation(state) } } diff --git a/src/main/kotlin/io/unthrottled/doki/assets/AssetManager.kt b/src/main/kotlin/io/unthrottled/doki/assets/AssetManager.kt index 88faa1758..acff8b7b5 100644 --- a/src/main/kotlin/io/unthrottled/doki/assets/AssetManager.kt +++ b/src/main/kotlin/io/unthrottled/doki/assets/AssetManager.kt @@ -19,9 +19,10 @@ import java.util.Optional import java.util.concurrent.Callable enum class AssetCategory(val category: String) { - STICKERS("stickers"), BACKGROUNDS("backgrounds"), + STICKERS("stickers"), + BACKGROUNDS("backgrounds"), PROMOTION("promotion"), - MISC("misc") + MISC("misc"), } object HttpClientFactory { @@ -41,7 +42,10 @@ object AssetManager { * file:// url to the local asset. If it was not able to get the asset then it * will return empty if the asset is not available locally. */ - fun resolveAssetUrl(assetCategory: AssetCategory, assetPath: String): Optional = + fun resolveAssetUrl( + assetCategory: AssetCategory, + assetPath: String, + ): Optional = cachedResolve(assetCategory, assetPath, ASSET_SOURCE) .map { it.toOptional() } .orElseGet { @@ -52,7 +56,10 @@ object AssetManager { * Works just like resolveAssetUrl except that it will always * download the remote asset. */ - fun forceResolveAssetUrl(assetCategory: AssetCategory, assetPath: String): Optional = + fun forceResolveAssetUrl( + assetCategory: AssetCategory, + assetPath: String, + ): Optional = forceResolve(assetCategory, assetPath, ASSET_SOURCE) .map { it.toOptional() } .orElseGet { @@ -62,7 +69,7 @@ object AssetManager { private fun cachedResolve( assetCategory: AssetCategory, assetPath: String, - assetSource: String + assetSource: String, ): Optional = resolveAsset(assetCategory, assetPath, assetSource) { localAssetPath, remoteAssetUrl -> resolveTheAssetUrl(localAssetPath, remoteAssetUrl) @@ -71,7 +78,7 @@ object AssetManager { private fun forceResolve( assetCategory: AssetCategory, assetPath: String, - assetSource: String + assetSource: String, ): Optional = resolveAsset(assetCategory, assetPath, assetSource) { localAssetPath, remoteAssetUrl -> downloadAndGetAssetUrl(localAssetPath, remoteAssetUrl) @@ -81,29 +88,34 @@ object AssetManager { assetCategory: AssetCategory, assetPath: String, assetSource: String, - resolveAsset: (Path, String) -> Optional + resolveAsset: (Path, String) -> Optional, ): Optional = constructLocalAssetPath(assetCategory, assetPath) .toOptional() .flatMap { - val remoteAssetUrl = constructRemoteAssetUrl( - assetCategory, - assetPath, - assetSource - ) + val remoteAssetUrl = + constructRemoteAssetUrl( + assetCategory, + assetPath, + assetSource, + ) resolveAsset(it, remoteAssetUrl) } private fun constructRemoteAssetUrl( assetCategory: AssetCategory, assetPath: String, - assetSource: String - ): String = when (assetCategory) { - AssetCategory.STICKERS -> "$assetSource/${assetCategory.category}/jetbrains/v2$assetPath" - else -> "$assetSource/${assetCategory.category}/$assetPath" - } + assetSource: String, + ): String = + when (assetCategory) { + AssetCategory.STICKERS -> "$assetSource/${assetCategory.category}/jetbrains/v2$assetPath" + else -> "$assetSource/${assetCategory.category}/$assetPath" + } - private fun resolveTheAssetUrl(localAssetPath: Path, remoteAssetUrl: String): Optional = + private fun resolveTheAssetUrl( + localAssetPath: Path, + remoteAssetUrl: String, + ): Optional = when { hasAssetChanged(localAssetPath, remoteAssetUrl) -> downloadAndGetAssetUrl(localAssetPath, remoteAssetUrl) @@ -114,30 +126,30 @@ object AssetManager { fun constructLocalAssetPath( assetCategory: AssetCategory, - assetPath: String + assetPath: String, ): Path = Paths.get( getLocalAssetDirectory(), assetCategory.category, - assetPath + assetPath, ).normalize().toAbsolutePath() fun constructGlobalAssetPath( assetCategory: AssetCategory, - assetPath: String + assetPath: String, ): Optional = getGlobalAssetDirectory() .map { Paths.get( it, assetCategory.category, - assetPath + assetPath, ) } private fun downloadAndGetAssetUrl( localAssetPath: Path, - remoteAssetUrl: String + remoteAssetUrl: String, ): Optional { createDirectories(localAssetPath) return ApplicationManager.getApplication().executeOnPooledThread( @@ -146,13 +158,13 @@ object AssetManager { Files.newOutputStream( localAssetPath, StandardOpenOption.CREATE, - StandardOpenOption.TRUNCATE_EXISTING + StandardOpenOption.TRUNCATE_EXISTING, ).use { bufferedWriter -> IOUtils.copy(inputStream, bufferedWriter) } localAssetPath.toUri().toString() } - } + }, ).get() } } diff --git a/src/main/kotlin/io/unthrottled/doki/assets/LocalAssetService.kt b/src/main/kotlin/io/unthrottled/doki/assets/LocalAssetService.kt index 8c5a83c78..dd53ac062 100644 --- a/src/main/kotlin/io/unthrottled/doki/assets/LocalAssetService.kt +++ b/src/main/kotlin/io/unthrottled/doki/assets/LocalAssetService.kt @@ -21,7 +21,9 @@ import java.util.Optional import java.util.concurrent.ConcurrentHashMap private enum class AssetChangedStatus { - SAME, DIFFERENT, LUL_DUNNO + SAME, + DIFFERENT, + LUL_DUNNO, } object LocalAssetService { @@ -31,14 +33,14 @@ object LocalAssetService { fun hasAssetChanged( localInstallPath: Path, - remoteAssetUrl: String + remoteAssetUrl: String, ): Boolean = !Files.exists(localInstallPath) || ( Registry.`is`("doki.theme.update.assets", true) && !hasBeenCheckedToday(localInstallPath) && isLocalDifferentFromRemote(localInstallPath, remoteAssetUrl) == AssetChangedStatus.DIFFERENT - ) + ) private fun computeCheckSum(byteArray: ByteArray): String { val messageDigest = MessageDigest.getInstance("MD5") @@ -47,11 +49,13 @@ object LocalAssetService { } private fun getRemoteAssetChecksum(remoteAssetUrl: String): Optional = - RestClient.performGet("$remoteAssetUrl.checksum.txt") + RestClient.performGet( + "$remoteAssetUrl.checksum.txt", + ) private fun isLocalDifferentFromRemote( localInstallPath: Path, - remoteAssetUrl: String + remoteAssetUrl: String, ): AssetChangedStatus = getRemoteAssetChecksum(remoteAssetUrl) .map { @@ -62,11 +66,11 @@ object LocalAssetService { } else { log.warn( """ - Local asset: $localInstallPath - is different from remote asset $remoteAssetUrl - Local Checksum: $onDiskCheckSum - Remote Checksum: $it - """.trimIndent() + Local asset: $localInstallPath + is different from remote asset $remoteAssetUrl + Local Checksum: $onDiskCheckSum + Remote Checksum: $it + """.trimIndent(), ) AssetChangedStatus.DIFFERENT } @@ -85,7 +89,7 @@ object LocalAssetService { assetCheckPath, Charset.defaultCharset(), StandardOpenOption.CREATE, - StandardOpenOption.TRUNCATE_EXISTING + StandardOpenOption.TRUNCATE_EXISTING, ).use { writer -> writer.write(gson.toJson(assetChecks)) } @@ -102,7 +106,7 @@ object LocalAssetService { Files.newBufferedReader(it).use { reader -> gson.fromJson>( reader, - object : TypeToken>() {}.type + object : TypeToken>() {}.type, ) } }.orElseGet { ConcurrentHashMap() } @@ -111,9 +115,7 @@ object LocalAssetService { ConcurrentHashMap() } - private fun getAssetChecksFile() = - Paths.get(LocalStorageService.getLocalAssetDirectory(), "assetChecks.json") + private fun getAssetChecksFile() = Paths.get(LocalStorageService.getLocalAssetDirectory(), "assetChecks.json") - private fun getAssetCheckKey(localInstallPath: Path) = - localInstallPath.toAbsolutePath().toString() + private fun getAssetCheckKey(localInstallPath: Path) = localInstallPath.toAbsolutePath().toString() } diff --git a/src/main/kotlin/io/unthrottled/doki/assets/LocalStorageService.kt b/src/main/kotlin/io/unthrottled/doki/assets/LocalStorageService.kt index db7796f9b..e7972d019 100644 --- a/src/main/kotlin/io/unthrottled/doki/assets/LocalStorageService.kt +++ b/src/main/kotlin/io/unthrottled/doki/assets/LocalStorageService.kt @@ -25,7 +25,7 @@ object LocalStorageService { fun getLocalAssetDirectory(): String { return Paths.get( PathManager.getConfigPath(), - ASSET_DIRECTORY + ASSET_DIRECTORY, ).toAbsolutePath().toString() } @@ -33,7 +33,7 @@ object LocalStorageService { Paths.get( PathManager.getConfigPath(), "..", - ASSET_DIRECTORY + ASSET_DIRECTORY, ).toAbsolutePath() .normalize() .toOptional() diff --git a/src/main/kotlin/io/unthrottled/doki/config/ThemeConfig.kt b/src/main/kotlin/io/unthrottled/doki/config/ThemeConfig.kt index 3524740e5..a1e34ea50 100644 --- a/src/main/kotlin/io/unthrottled/doki/config/ThemeConfig.kt +++ b/src/main/kotlin/io/unthrottled/doki/config/ThemeConfig.kt @@ -13,7 +13,7 @@ import java.util.Locale @OptIn(ExperimentalStdlibApi::class) @State( name = "DokiDokiThemeConfig", - storages = [Storage("doki_doki_theme.xml")] + storages = [Storage("doki_doki_theme.xml")], ) class ThemeConfig : PersistentStateComponent, Cloneable { companion object { @@ -63,8 +63,7 @@ class ThemeConfig : PersistentStateComponent, Cloneable { var discreetMode = false var discreetModeConfig = "{}" - override fun getState(): ThemeConfig? = - createCopy(this) + override fun getState(): ThemeConfig? = createCopy(this) override fun loadState(state: ThemeConfig) { copyBean(state, this) diff --git a/src/main/kotlin/io/unthrottled/doki/discreet/AbstractDiscreetModeListener.kt b/src/main/kotlin/io/unthrottled/doki/discreet/AbstractDiscreetModeListener.kt index d32bc939c..7c3eff288 100644 --- a/src/main/kotlin/io/unthrottled/doki/discreet/AbstractDiscreetModeListener.kt +++ b/src/main/kotlin/io/unthrottled/doki/discreet/AbstractDiscreetModeListener.kt @@ -31,15 +31,16 @@ abstract class AbstractDiscreetModeListener : DiscreetModeListener, Logging { private fun liftDiscreetMode() { currentMode = DiscreetMode.INACTIVE val discreetModeConfig = ThemeConfig.instance.discreetModeConfig - val restorationConfig = runSafelyWithResult({ - gson.fromJson( - discreetModeConfig, - object : TypeToken() {}.type - ) - }) { - logger().warn("Unable to read discreet mode restoration config $discreetModeConfig", it) - captureRestorationConfig() - } + val restorationConfig = + runSafelyWithResult({ + gson.fromJson( + discreetModeConfig, + object : TypeToken() {}.type, + ) + }) { + logger().warn("Unable to read discreet mode restoration config $discreetModeConfig", it) + captureRestorationConfig() + } ThemeConfig.instance.discreetModeConfig = "{}" ThemeConfig.instance.showThemeStatusBar = restorationConfig.statusBarWidgetEnabled ?: true @@ -81,13 +82,14 @@ abstract class AbstractDiscreetModeListener : DiscreetModeListener, Logging { abstract fun dispatchExtraEvents() - private fun captureRestorationConfig() = DiscreetModeRestorationConfig( - ThemeConfig.instance.showThemeStatusBar, - ThemeConfig.instance.currentStickerLevel == StickerLevel.ON, - ThemeConfig.instance.isDokiBackground, - EditorBackgroundWallpaperService.instance.getCurrentBackgroundValue(), - ThemeConfig.instance.isEmptyFrameBackground - ) + private fun captureRestorationConfig() = + DiscreetModeRestorationConfig( + ThemeConfig.instance.showThemeStatusBar, + ThemeConfig.instance.currentStickerLevel == StickerLevel.ON, + ThemeConfig.instance.isDokiBackground, + EditorBackgroundWallpaperService.instance.getCurrentBackgroundValue(), + ThemeConfig.instance.isEmptyFrameBackground, + ) } data class DiscreetModeRestorationConfig( @@ -95,5 +97,5 @@ data class DiscreetModeRestorationConfig( val stickersEnabled: Boolean?, val editorWallpaperEnabled: Boolean?, val savedBackground: String?, - val emptyWallpaperEnabled: Boolean? + val emptyWallpaperEnabled: Boolean?, ) diff --git a/src/main/kotlin/io/unthrottled/doki/discreet/DiscreetModeListener.kt b/src/main/kotlin/io/unthrottled/doki/discreet/DiscreetModeListener.kt index 940496ec3..eb20e81da 100644 --- a/src/main/kotlin/io/unthrottled/doki/discreet/DiscreetModeListener.kt +++ b/src/main/kotlin/io/unthrottled/doki/discreet/DiscreetModeListener.kt @@ -4,11 +4,11 @@ import com.intellij.util.messages.Topic import java.util.EventListener enum class DiscreetMode { - ACTIVE, INACTIVE + ACTIVE, + INACTIVE, } -fun Boolean.toDiscreetMode(): DiscreetMode = - if (this) DiscreetMode.ACTIVE else DiscreetMode.INACTIVE +fun Boolean.toDiscreetMode(): DiscreetMode = if (this) DiscreetMode.ACTIVE else DiscreetMode.INACTIVE fun interface DiscreetModeListener : EventListener { companion object { diff --git a/src/main/kotlin/io/unthrottled/doki/hax/FieldHacker.kt b/src/main/kotlin/io/unthrottled/doki/hax/FieldHacker.kt index a0fbd75f6..c1f6e263a 100644 --- a/src/main/kotlin/io/unthrottled/doki/hax/FieldHacker.kt +++ b/src/main/kotlin/io/unthrottled/doki/hax/FieldHacker.kt @@ -6,13 +6,12 @@ import java.lang.reflect.Field import java.lang.reflect.Modifier object FieldHacker { - private val log = Logger.getInstance(javaClass) fun setFinalStatic( cls: Class<*>, @NonNls fieldName: String, - newValue: Any? + newValue: Any?, ) { val fields = cls.declaredFields for (field in fields) { @@ -26,7 +25,7 @@ object FieldHacker { fun setFieldValue( objectToHack: Any, fieldName: String?, - value: Any? + value: Any?, ) { try { val field = objectToHack.javaClass.getDeclaredField(fieldName) @@ -37,7 +36,10 @@ object FieldHacker { } } - fun setFinalStatic(field: Field, newValue: Any?) { + fun setFinalStatic( + field: Field, + newValue: Any?, + ) { field.isAccessible = true val modifiersField = Field::class.java.getDeclaredField("modifiers") modifiersField.isAccessible = true diff --git a/src/main/kotlin/io/unthrottled/doki/hax/HackComponent.kt b/src/main/kotlin/io/unthrottled/doki/hax/HackComponent.kt index d23d60fc9..2f3ae25bb 100644 --- a/src/main/kotlin/io/unthrottled/doki/hax/HackComponent.kt +++ b/src/main/kotlin/io/unthrottled/doki/hax/HackComponent.kt @@ -52,9 +52,10 @@ object HackComponent : Disposable { val cp = ClassPool(true) cp.insertClassPath(ClassClassPath(Class.forName("com.intellij.codeInsight.actions.DirectoryFormattingOptions"))) val ctClass = cp.get("com.intellij.codeInsight.actions.FileInEditorProcessor\$FormattedMessageBuilder") - val init = ctClass.getDeclaredMethod( - "getMessage" - ) + val init = + ctClass.getDeclaredMethod( + "getMessage", + ) init.instrument( object : ExprEditor() { override fun edit(e: MethodCall?) { @@ -62,7 +63,7 @@ object HackComponent : Disposable { e.replace("{ \$1 = com.intellij.util.ui.UIUtil.getContextHelpForeground(); \$_ = \$proceed(\$\$); }") } } - } + }, ) ctClass.toClass() }) { @@ -92,7 +93,7 @@ object HackComponent : Disposable { e.replace("{ \$1 = com.intellij.util.ui.UIUtil.getLabelForeground(); \$_ = \$proceed(\$\$);}") } } - } + }, ) ctClass.toClass() }) { @@ -105,8 +106,8 @@ object HackComponent : Disposable { val cp = ClassPool(true) cp.insertClassPath( ClassClassPath( - Class.forName("com.intellij.ui.SideBorder") - ) + Class.forName("com.intellij.ui.SideBorder"), + ), ) val ctClass = cp.get("com.intellij.ui.SimpleColoredComponent") val doPaintText = ctClass.getDeclaredMethods("doPaintText")[0] @@ -116,11 +117,11 @@ object HackComponent : Disposable { if (e?.className == "com.intellij.ui.JBColor") { e.replace( "{ \$_ = com.intellij.ui.JBColor.namedColor(\"SearchMatch.foreground\", " + - "com.intellij.ui.JBColor.BLACK); }" + "com.intellij.ui.JBColor.BLACK); }", ) } } - } + }, ) ctClass.toClass() }) { @@ -140,11 +141,11 @@ object HackComponent : Disposable { if (e?.methodName == "setBackground") { e.replace( "{ \$1 = com.intellij.ui.JBColor.namedColor(\"ParameterInfo.background\", " + - "com.intellij.codeInsight.hint.HintUtil.getInformationColor()); \$_ = \$proceed(\$\$); }" + "com.intellij.codeInsight.hint.HintUtil.getInformationColor()); \$_ = \$proceed(\$\$); }", ) } } - } + }, ) } ctClass.getDeclaredMethods("setup").forEach(hackBackground) @@ -166,20 +167,21 @@ object HackComponent : Disposable { val cp = ClassPool(true) cp.insertClassPath(ClassClassPath(ProcessProxy::class.java)) val ctClass = cp.get("com.intellij.execution.runners.ExecutionUtil") - val init = ctClass.getDeclaredMethods( - "getLiveIndicator" - )[1] + val init = + ctClass.getDeclaredMethods( + "getLiveIndicator", + )[1] init.instrument( object : ExprEditor() { override fun edit(e: MethodCall?) { if (e?.methodName == "getIndicator") { e.replace( "{ \$4 = com.intellij.ui.JBColor.namedColor(\"Doki.Accent.color\", " + - "java.awt.Color.GREEN); \$_ = \$proceed(\$\$); }" + "java.awt.Color.GREEN); \$_ = \$proceed(\$\$); }", ) } } - } + }, ) ctClass.toClass() }) { @@ -196,9 +198,10 @@ object HackComponent : Disposable { val cp = ClassPool(true) cp.insertClassPath(ClassClassPath(CustomMatcherModel::class.java)) val ctClass = cp.get("com.intellij.ide.util.gotoByName.GotoActionModel\$GotoActionListCellRenderer") - val init = ctClass.getDeclaredMethods( - "getListCellRendererComponent" - )[0] + val init = + ctClass.getDeclaredMethods( + "getListCellRendererComponent", + )[0] init.instrument( object : ExprEditor() { override fun edit(e: MethodCall?) { @@ -206,7 +209,7 @@ object HackComponent : Disposable { e.replace("{ \$_ = true; }") } } - } + }, ) ctClass.toClass() }) { @@ -234,11 +237,11 @@ object HackComponent : Disposable { if (e?.className == "com.intellij.ui.JBColor") { e.replace( "{ \$_ = com.intellij.util.ui.JBUI.CurrentTheme." + - "CustomFrameDecorations.separatorForeground(); }" + "CustomFrameDecorations.separatorForeground(); }", ) } } - } + }, ) ctClass.toClass() }) { @@ -257,9 +260,10 @@ object HackComponent : Disposable { val cp = ClassPool(true) cp.insertClassPath(ClassClassPath(EditorHistoryManager::class.java)) val ctClass = cp.get("com.intellij.openapi.fileEditor.impl.EditorsSplitters") - val init = ctClass.getDeclaredMethods( - "paintComponent" - )[0] + val init = + ctClass.getDeclaredMethods( + "paintComponent", + )[0] init.instrument( object : ExprEditor() { override fun edit(e: MethodCall?) { @@ -267,7 +271,7 @@ object HackComponent : Disposable { e.replace("{ \$_ = true; }") } } - } + }, ) ctClass.toClass() }) { @@ -280,9 +284,10 @@ object HackComponent : Disposable { val cp = ClassPool(true) cp.insertClassPath(ClassClassPath(RunAnythingAction::class.java)) val ctClass = cp.get("com.intellij.ide.actions.runAnything.RunAnythingUtil") - val init = ctClass.getDeclaredMethods( - "createTitle" - )[0] + val init = + ctClass.getDeclaredMethods( + "createTitle", + )[0] init.instrument( object : ExprEditor() { override fun edit(e: NewExpr?) { @@ -290,7 +295,7 @@ object HackComponent : Disposable { e.replace("{ \$_ = com.intellij.util.ui.JBUI.CurrentTheme.Advertiser.borderColor(); }") } } - } + }, ) ctClass.toClass() }) { @@ -303,9 +308,10 @@ object HackComponent : Disposable { val cp = ClassPool(true) cp.insertClassPath(ClassClassPath(DocumentTracker::class.java)) val ctClass = cp.get("com.intellij.openapi.vcs.ex.LineStatusMarkerPopupPanel") - val init = ctClass.getDeclaredMethods( - "getBorderColor" - )[0] + val init = + ctClass.getDeclaredMethods( + "getBorderColor", + )[0] init.instrument( object : ExprEditor() { override fun edit(e: NewExpr?) { @@ -313,7 +319,7 @@ object HackComponent : Disposable { e.replace("{ \$_ = com.intellij.util.ui.JBUI.CurrentTheme.Advertiser.borderColor(); }") } } - } + }, ) ctClass.toClass() }) { @@ -338,7 +344,7 @@ object HackComponent : Disposable { e.replace("{ \$_ = com.intellij.ide.plugins.PluginManagerConfigurable.SEARCH_FIELD_BORDER_COLOR; }") } } - } + }, ) ctClass.toClass() }) { @@ -388,7 +394,7 @@ object HackComponent : Disposable { m.replace("{ \$_ = \"Show \\\"Monika's Writing Tip of the Day\\\" on Startup!\"; }") } } - } + }, ) ctClass.toClass() }) { @@ -421,7 +427,7 @@ object HackComponent : Disposable { override fun edit(m: MethodCall?) { m?.replace("{ \$_ = com.intellij.util.ui.UIUtil.getPanelBackground(); }") } - } + }, ) // enable disposable stickers @@ -434,7 +440,7 @@ object HackComponent : Disposable { m.replace("{ \$2 = \"$DOKI_BACKGROUND_PROP\"; \$_ = \$proceed(\$\$); }") } } - } + }, ) val initFramePaintersMethod = ctClass2.getDeclaredMethod("initFramePainters") @@ -448,7 +454,7 @@ object HackComponent : Disposable { m.replace("{ \$1 = \"$DOKI_BACKGROUND_PROP\"; \$_ = \$proceed(\$\$); }") } } - } + }, ) ctClass2.toClass() diff --git a/src/main/kotlin/io/unthrottled/doki/hax/SvgLoaderHacker.kt b/src/main/kotlin/io/unthrottled/doki/hax/SvgLoaderHacker.kt index a5f135831..978037e21 100644 --- a/src/main/kotlin/io/unthrottled/doki/hax/SvgLoaderHacker.kt +++ b/src/main/kotlin/io/unthrottled/doki/hax/SvgLoaderHacker.kt @@ -10,7 +10,6 @@ import java.util.Optional typealias PatcherProvider = SVGLoader.SvgElementColorPatcherProvider object SvgLoaderHacker { - /** * Enables the ability to have more than one color patcher. */ @@ -33,7 +32,7 @@ object SvgLoaderHacker { private fun collectOtherPatcher(): Optional = Optional.ofNullable( SVGLoader::class.java.declaredFields - .firstOrNull { it.name == "colorPatcherProvider" } + .firstOrNull { it.name == "colorPatcherProvider" }, ) .map { ourColorPatcherField -> ourColorPatcherField.isAccessible = true diff --git a/src/main/kotlin/io/unthrottled/doki/icon/ColorPatcher.kt b/src/main/kotlin/io/unthrottled/doki/icon/ColorPatcher.kt index b62ebc0da..a4b222ab0 100644 --- a/src/main/kotlin/io/unthrottled/doki/icon/ColorPatcher.kt +++ b/src/main/kotlin/io/unthrottled/doki/icon/ColorPatcher.kt @@ -24,16 +24,17 @@ object NoOptPatcher : SvgAttributePatcher { } } -val noOptPatcherProvider = object : PatcherProvider { - val longArray = longArrayOf(0) - override fun digest(): LongArray { - return longArray +val noOptPatcherProvider = + object : PatcherProvider { + val longArray = longArrayOf(0) + + override fun digest(): LongArray { + return longArray + } } -} @Suppress("TooManyFunctions") object ColorPatcher : PatcherProvider { - private var otherColorPatcherProvider: PatcherProvider = noOptPatcherProvider private var uiColorPatcherProvider: PatcherProvider = noOptPatcherProvider private lateinit var dokiTheme: DokiTheme @@ -63,6 +64,7 @@ object ColorPatcher : PatcherProvider { } private lateinit var _digest: LongArray + override fun digest(): LongArray { return if (this::_digest.isInitialized) { _digest @@ -97,18 +99,19 @@ object ColorPatcher : PatcherProvider { override fun attributeForPath(path: String): SvgAttributePatcher? { val safeKey = path ?: "ayyLmao" return if (patcherProviderCache.add(safeKey)) { - val hackedPatcher = buildHackedPatcher( - listOf(otherColorPatcherProvider, uiColorPatcherProvider) - .distinct() - .mapNotNull { patcherProvider -> - runSafelyWithResult({ - patcherProvider.attributeForPath(path) - }) { - null - } - }, - safeKey - ) + val hackedPatcher = + buildHackedPatcher( + listOf(otherColorPatcherProvider, uiColorPatcherProvider) + .distinct() + .mapNotNull { patcherProvider -> + runSafelyWithResult({ + patcherProvider.attributeForPath(path) + }) { + null + } + }, + safeKey, + ) patcherProviderCache.remove(safeKey) hackedPatcher } else { @@ -118,77 +121,79 @@ object ColorPatcher : PatcherProvider { private fun buildHackedPatcher( otherPatchers: List, - patcherKey: String + patcherKey: String, ): SvgAttributePatcher { val cachedPatcher = patcherCache.getIfPresent(patcherKey) if (cachedPatcher !== null) { return cachedPatcher } - val recursionResistantPatcher = object : SvgAttributePatcher { - private val svgCache = HashSet>() - override fun patchColors(attributes: MutableMap) { - if (svgCache.add(attributes)) { - try { - runSafely({ - patchAttributes(attributes) - }) - } finally { - svgCache.remove(attributes) + val recursionResistantPatcher = + object : SvgAttributePatcher { + private val svgCache = HashSet>() + + override fun patchColors(attributes: MutableMap) { + if (svgCache.add(attributes)) { + try { + runSafely({ + patchAttributes(attributes) + }) + } finally { + svgCache.remove(attributes) + } } - } - patchAttributes(attributes) - } - - private fun patchAttributes(attributes: MutableMap) { - otherPatchers.forEach { otherPatcher -> - runSafely({ - otherPatcher.patchColors(attributes) - }) - } - - patchAccent(attributes["accentTint"], attributes) { - it.toHexString() - } - patchAccent(attributes["accentTintDarker"], attributes) { - ColorUtil.darker(it, 1).toHexString() - } - patchAccent(attributes["accentContrastTint"], attributes) { - getIconAccentContrastColor().toHexString() - } - patchAccent(attributes["stopTint"], attributes) { - getThemedStopColor() - } - patchAccent(attributes["editorAccentTint"], attributes) { - ThemeManager.instance.currentTheme - .map { it.editorAccentColor.toHexString() } - .orElseGet { JBColor.CYAN.toHexString() } + patchAttributes(attributes) } - val themedStartAttr = attributes["themedStart"] - val themedStopAttr = attributes["themedStop"] - val themedFillAttr = attributes["themedFill"] - when { - "true" == themedStartAttr -> { - val themedStart = getThemedStartColor() - attributes["stop-color"] = themedStart - attributes["fill"] = themedStart + private fun patchAttributes(attributes: MutableMap) { + otherPatchers.forEach { otherPatcher -> + runSafely({ + otherPatcher.patchColors(attributes) + }) } - "true" == themedStopAttr -> { - val themedStop = getThemedStopColor() - attributes["stop-color"] = themedStop - attributes["fill"] = themedStop + patchAccent(attributes["accentTint"], attributes) { + it.toHexString() + } + patchAccent(attributes["accentTintDarker"], attributes) { + ColorUtil.darker(it, 1).toHexString() + } + patchAccent(attributes["accentContrastTint"], attributes) { + getIconAccentContrastColor().toHexString() } + patchAccent(attributes["stopTint"], attributes) { + getThemedStopColor() + } + patchAccent(attributes["editorAccentTint"], attributes) { + ThemeManager.instance.currentTheme + .map { it.editorAccentColor.toHexString() } + .orElseGet { JBColor.CYAN.toHexString() } + } + + val themedStartAttr = attributes["themedStart"] + val themedStopAttr = attributes["themedStop"] + val themedFillAttr = attributes["themedFill"] + when { + "true" == themedStartAttr -> { + val themedStart = getThemedStartColor() + attributes["stop-color"] = themedStart + attributes["fill"] = themedStart + } - "true" == themedFillAttr -> { - val themedStart = getThemedStartColor() - attributes["fill"] = themedStart - attributes["stroke"] = themedStart + "true" == themedStopAttr -> { + val themedStop = getThemedStopColor() + attributes["stop-color"] = themedStop + attributes["fill"] = themedStop + } + + "true" == themedFillAttr -> { + val themedStart = getThemedStartColor() + attributes["fill"] = themedStart + attributes["stroke"] = themedStart + } } } } - } patcherCache.put(patcherKey, recursionResistantPatcher) @@ -198,7 +203,7 @@ object ColorPatcher : PatcherProvider { private fun patchAccent( attribute: String?, attributes: MutableMap, - colorDecorator: (Color) -> String + colorDecorator: (Color) -> String, ) { when (attribute) { "fill" -> attributes["fill"] = colorDecorator(getAccentColor()) @@ -212,15 +217,11 @@ object ColorPatcher : PatcherProvider { } } - private fun getAccentColor() = - namedColor("Doki.Accent.color", JBColor.CYAN) + private fun getAccentColor() = namedColor("Doki.Accent.color", JBColor.CYAN) - private fun getIconAccentContrastColor() = - namedColor("Doki.Icon.Accent.Contrast.color", JBColor.WHITE) + private fun getIconAccentContrastColor() = namedColor("Doki.Icon.Accent.Contrast.color", JBColor.WHITE) - private fun getThemedStartColor() = - namedColor("Doki.startColor", JBColor.CYAN).toHexString() + private fun getThemedStartColor() = namedColor("Doki.startColor", JBColor.CYAN).toHexString() - private fun getThemedStopColor() = - namedColor("Doki.stopColor", JBColor.CYAN).toHexString() + private fun getThemedStopColor() = namedColor("Doki.stopColor", JBColor.CYAN).toHexString() } diff --git a/src/main/kotlin/io/unthrottled/doki/icon/DokiIconPathPatcher.kt b/src/main/kotlin/io/unthrottled/doki/icon/DokiIconPathPatcher.kt index d56e0a8f9..2969d1b6f 100644 --- a/src/main/kotlin/io/unthrottled/doki/icon/DokiIconPathPatcher.kt +++ b/src/main/kotlin/io/unthrottled/doki/icon/DokiIconPathPatcher.kt @@ -8,16 +8,15 @@ import io.unthrottled.doki.util.logger data class PathMapping( val originalPath: String, - val replacementPath: String + val replacementPath: String, ) class DokiIconPathPatcher(mappingFile: String) : IconPathPatcher(), Logging { - private val pathMappings: Map = readJsonFromResources>( "/mappings", mappingFile, - object : TypeToken>() {}.type + object : TypeToken>() {}.type, ) .map { def -> def.associate { @@ -30,12 +29,11 @@ class DokiIconPathPatcher(mappingFile: String) : IconPathPatcher(), Logging { override fun patchPath( path: String, - classLoader: ClassLoader? + classLoader: ClassLoader?, ): String? = pathMappings[path] override fun getContextClassLoader( path: String, - originalClassLoader: ClassLoader? - ): ClassLoader? = - javaClass.classLoader + originalClassLoader: ClassLoader?, + ): ClassLoader? = javaClass.classLoader } diff --git a/src/main/kotlin/io/unthrottled/doki/icon/DokiIcons.kt b/src/main/kotlin/io/unthrottled/doki/icon/DokiIcons.kt index 165f932c6..d37e33871 100644 --- a/src/main/kotlin/io/unthrottled/doki/icon/DokiIcons.kt +++ b/src/main/kotlin/io/unthrottled/doki/icon/DokiIcons.kt @@ -5,10 +5,10 @@ import javax.swing.Icon object DokiIcons { object General { - @JvmStatic val PLUGIN_LOGO = load("icons/doki/Doki-Doki-Logo.svg") } + object Plugins { object Motivator { val TOOL_WINDOW = load("icons/plugins/motivator/motivator_toolwindow.svg") @@ -41,6 +41,5 @@ object DokiIcons { val EXPANDED = load("icons/tree/treeExpanded.svg") } - private fun load(path: String): Icon = - IconLoader.getIcon(path, DokiIcons::class.java) + private fun load(path: String): Icon = IconLoader.getIcon(path, DokiIcons::class.java) } diff --git a/src/main/kotlin/io/unthrottled/doki/icon/IconPathReplacementComponent.kt b/src/main/kotlin/io/unthrottled/doki/icon/IconPathReplacementComponent.kt index d53277489..3f7c7d725 100644 --- a/src/main/kotlin/io/unthrottled/doki/icon/IconPathReplacementComponent.kt +++ b/src/main/kotlin/io/unthrottled/doki/icon/IconPathReplacementComponent.kt @@ -8,15 +8,15 @@ import io.unthrottled.doki.service.PluginService import io.unthrottled.doki.themes.ThemeManager data class IconReplacementPack( - val iconPatcher: DokiIconPathPatcher + val iconPatcher: DokiIconPathPatcher, ) object IconPathReplacementComponent : LafManagerListener { private val iconInstallPacs = listOf( IconReplacementPack( - DokiIconPathPatcher("ui-icons.path.mappings.json") - ) + DokiIconPathPatcher("ui-icons.path.mappings.json"), + ), ) private val connection = ApplicationManager.getApplication().messageBus.connect() diff --git a/src/main/kotlin/io/unthrottled/doki/ide/DokiThemeColorAnnotator.kt b/src/main/kotlin/io/unthrottled/doki/ide/DokiThemeColorAnnotator.kt index 492f591de..072a7007c 100644 --- a/src/main/kotlin/io/unthrottled/doki/ide/DokiThemeColorAnnotator.kt +++ b/src/main/kotlin/io/unthrottled/doki/ide/DokiThemeColorAnnotator.kt @@ -35,10 +35,9 @@ import java.util.regex.Pattern import javax.swing.Icon class DokiThemeColorAnnotator : Annotator { - override fun annotate( element: PsiElement, - holder: AnnotationHolder + holder: AnnotationHolder, ) { if ( !isColorLineMarkerProviderEnabled || @@ -54,9 +53,8 @@ class DokiThemeColorAnnotator : Annotator { private class ColorBoxRenderer( private val myColorText: String, - private var myLiteral: JsonStringLiteral + private var myLiteral: JsonStringLiteral, ) : GutterIconRenderer() { - override fun getIcon(): Icon = getColor(myColorText) ?.let { ColorIcon(ICON_SIZE, it) } @@ -91,16 +89,17 @@ class DokiThemeColorAnnotator : Annotator { if (Registry.`is`("ide.new.color.picker")) { showColorPickerPopup( e.project, - currentColor + currentColor, ) { c: Color?, _ -> applyColor(currentColor, withAlpha, c) } } else { - val newColor = ColorChooser.chooseColor( - editor.project, - editor.component, - "Choose Color", - currentColor, - withAlpha - ) + val newColor = + ColorChooser.chooseColor( + editor.project, + editor.component, + "Choose Color", + currentColor, + withAlpha, + ) applyColor(currentColor, withAlpha, newColor) } } @@ -109,7 +108,7 @@ class DokiThemeColorAnnotator : Annotator { private fun applyColor( currentColor: Color, withAlpha: Boolean, - newColor: Color? + newColor: Color?, ) { newColor.toOptional() .filter { it != currentColor } @@ -124,8 +123,7 @@ class DokiThemeColorAnnotator : Annotator { } } - private fun canChooseColor(): Boolean = - isColorCode(myColorText) + private fun canChooseColor(): Boolean = isColorCode(myColorText) private fun getColor(colorText: String): Color? = if (!isColorCode(colorText)) { @@ -157,11 +155,11 @@ class DokiThemeColorAnnotator : Annotator { myLiteral == renderer.myLiteral } - override fun hashCode(): Int = - Objects.hash(myColorText, myLiteral) + override fun hashCode(): Int = Objects.hash(myColorText, myLiteral) companion object { private const val ICON_SIZE = 10 + private fun parseColor(colorHex: String): Color? = colorHex.toOptional() .map { isRgbaColorHex(it) } @@ -169,11 +167,12 @@ class DokiThemeColorAnnotator : Annotator { .map { isRgba -> try { val alpha = if (isRgba) colorHex.substring(HEX_COLOR_LENGTH_RGB) else null - val colorHexWithoutAlpha = if (isRgba) { - colorHex.substring(0, HEX_COLOR_LENGTH_RGB) - } else { - colorHex - } + val colorHexWithoutAlpha = + if (isRgba) { + colorHex.substring(0, HEX_COLOR_LENGTH_RGB) + } else { + colorHex + } val color = colorHexWithoutAlpha.toColor() if (isRgba) { toAlpha(color, alpha?.toInt(16) ?: 1) @@ -186,11 +185,9 @@ class DokiThemeColorAnnotator : Annotator { } .orElseGet { null } - private fun isRgbaColorHex(colorHex: String): Boolean = - colorHex.length == HEX_COLOR_LENGTH_RGBA + private fun isRgbaColorHex(colorHex: String): Boolean = colorHex.length == HEX_COLOR_LENGTH_RGBA - private fun isRgbColorHex(colorHex: String): Boolean = - colorHex.length == HEX_COLOR_LENGTH_RGB + private fun isRgbColorHex(colorHex: String): Boolean = colorHex.length == HEX_COLOR_LENGTH_RGB } } @@ -203,7 +200,10 @@ class DokiThemeColorAnnotator : Annotator { private val isColorLineMarkerProviderEnabled: Boolean get() = LineMarkerSettings.getSettings().isEnabled(ColorLineMarkerProvider.INSTANCE) - private fun isTargetElement(element: PsiElement, containingFile: PsiFile): Boolean { + private fun isTargetElement( + element: PsiElement, + containingFile: PsiFile, + ): Boolean { return element.toOptional() .filter { it is JsonStringLiteral } .map { it as JsonStringLiteral } @@ -214,8 +214,7 @@ class DokiThemeColorAnnotator : Annotator { .orElse(false) } - private fun isNamedColor(text: String): Boolean = - StringUtil.isLatinAlphanumeric(text) + private fun isNamedColor(text: String): Boolean = StringUtil.isLatinAlphanumeric(text) private fun isColorCode(text: String?): Boolean { if (!StringUtil.startsWithChar(text, '#')) return false @@ -225,10 +224,11 @@ class DokiThemeColorAnnotator : Annotator { false } else { COLOR_HEX_PATTERN_RGB.matcher( - text - ).matches() || COLOR_HEX_PATTERN_RGBA.matcher( - text - ).matches() + text, + ).matches() || + COLOR_HEX_PATTERN_RGBA.matcher( + text, + ).matches() } } } diff --git a/src/main/kotlin/io/unthrottled/doki/integrations/ErrorReporter.kt b/src/main/kotlin/io/unthrottled/doki/integrations/ErrorReporter.kt index 809c8152d..cb239d57c 100644 --- a/src/main/kotlin/io/unthrottled/doki/integrations/ErrorReporter.kt +++ b/src/main/kotlin/io/unthrottled/doki/integrations/ErrorReporter.kt @@ -32,12 +32,11 @@ class ErrorReporter : ErrorReportSubmitter() { override fun getReportActionText(): String = "Report Anonymously" companion object { - init { Sentry.setUser( User().apply { this.id = ThemeConfig.instance.userId - } + }, ) } } @@ -46,19 +45,19 @@ class ErrorReporter : ErrorReportSubmitter() { events: Array, additionalInfo: String?, parentComponent: Component, - consumer: Consumer + consumer: Consumer, ): Boolean { return runSafelyWithResult({ runSafely({ Sentry.init { options: SentryOptions -> options.dsn = RestClient.performGet( - "https://jetbrains.assets.unthrottled.io/doki-theme/sentry-dsn.txt" + "https://jetbrains.assets.unthrottled.io/doki-theme/sentry-dsn.txt", ) .map { it.trim() } .orElse( "https://54daf566d8854f7d98e4c09ced2d34c5" + - "@o403546.ingest.sentry.io/5266340?maxmessagelength=50000" + "@o403546.ingest.sentry.io/5266340?maxmessagelength=50000", ) } }) @@ -70,12 +69,13 @@ class ErrorReporter : ErrorReportSubmitter() { this.level = SentryLevel.ERROR this.serverName = getAppName().second this.setExtra("Additional Info", additionalInfo ?: "None") - } + }, ).apply { - this.message = Message().apply { - this.message = it.throwableText - } - } + this.message = + Message().apply { + this.message = it.throwableText + } + }, ) } true @@ -115,8 +115,10 @@ class ErrorReporter : ErrorReportSubmitter() { val vmVendor = properties.getProperty("java.vendor", "unknown") return IdeBundle.message("about.box.vm", vmVersion, vmVendor) } - private fun getGC() = ManagementFactory.getGarbageCollectorMXBeans().stream() - .map { it.name }.collect(Collectors.joining(",")) + + private fun getGC() = + ManagementFactory.getGarbageCollectorMXBeans().stream() + .map { it.name }.collect(Collectors.joining(",")) private fun getBuildInfo(appInfo: ApplicationInfoImpl): String { var buildInfo = IdeBundle.message("about.box.build.number", appInfo.build.asString()) diff --git a/src/main/kotlin/io/unthrottled/doki/integrations/IDEPluginInstallListener.kt b/src/main/kotlin/io/unthrottled/doki/integrations/IDEPluginInstallListener.kt index 07d7f58b0..5a9a32ad8 100644 --- a/src/main/kotlin/io/unthrottled/doki/integrations/IDEPluginInstallListener.kt +++ b/src/main/kotlin/io/unthrottled/doki/integrations/IDEPluginInstallListener.kt @@ -8,13 +8,12 @@ import io.unthrottled.doki.service.DOKI_ICONS_PLUGIN_ID import io.unthrottled.doki.util.Logging class IDEPluginInstallListener : DynamicPluginListener, Logging { - override fun beforePluginLoaded(pluginDescriptor: IdeaPluginDescriptor) { } override fun beforePluginUnload( pluginDescriptor: IdeaPluginDescriptor, - isUpdate: Boolean + isUpdate: Boolean, ) { } @@ -28,12 +27,11 @@ class IDEPluginInstallListener : DynamicPluginListener, Logging { } } - private fun isDokiIconPlugin(pluginDescriptor: IdeaPluginDescriptor) = - pluginDescriptor.pluginId.idString == DOKI_ICONS_PLUGIN_ID + private fun isDokiIconPlugin(pluginDescriptor: IdeaPluginDescriptor) = pluginDescriptor.pluginId.idString == DOKI_ICONS_PLUGIN_ID override fun pluginUnloaded( pluginDescriptor: IdeaPluginDescriptor, - isUpdate: Boolean + isUpdate: Boolean, ) { if (isDokiIconPlugin(pluginDescriptor)) { IconPathReplacementComponent.installPatchers() diff --git a/src/main/kotlin/io/unthrottled/doki/integrations/RestClient.kt b/src/main/kotlin/io/unthrottled/doki/integrations/RestClient.kt index 722b08229..278efeba3 100644 --- a/src/main/kotlin/io/unthrottled/doki/integrations/RestClient.kt +++ b/src/main/kotlin/io/unthrottled/doki/integrations/RestClient.kt @@ -14,7 +14,6 @@ import java.util.Optional import java.util.concurrent.Callable object RestClient : Logging { - fun performGet(url: String): Optional = ApplicationManager.getApplication().executeOnPooledThread( Callable { @@ -26,7 +25,7 @@ object RestClient : Logging { logger().warn("Unable to complete request for $url for raisins.", it) Optional.empty() } - } + }, ).get() } @@ -35,8 +34,8 @@ object RestTools { fun performRequest( url: String, - bodyExtractor: (InputStream) -> T - ): Optional { + bodyExtractor: (InputStream) -> T, + ): Optional { log.info("Attempting to download remote asset: $url") return runSafelyWithResult({ HttpRequests.request(url) diff --git a/src/main/kotlin/io/unthrottled/doki/integrations/XPathListener.kt b/src/main/kotlin/io/unthrottled/doki/integrations/XPathListener.kt index c624b4f8f..920d00726 100644 --- a/src/main/kotlin/io/unthrottled/doki/integrations/XPathListener.kt +++ b/src/main/kotlin/io/unthrottled/doki/integrations/XPathListener.kt @@ -20,12 +20,14 @@ class XPathListener : LafManagerListener, ProjectActivity { private fun installColors() { ThemeManager.instance.currentTheme.doOrElse({ val schemeForCurrentUITheme = EditorColorsManager.getInstance().schemeForCurrentUITheme - XPathAppComponent.getInstance().config.attributes.backgroundColor = schemeForCurrentUITheme.getColor( - EditorColors.SELECTION_BACKGROUND_COLOR - ) - XPathAppComponent.getInstance().config.attributes.foregroundColor = schemeForCurrentUITheme.getColor( - EditorColors.SELECTION_FOREGROUND_COLOR - ) + XPathAppComponent.getInstance().config.attributes.backgroundColor = + schemeForCurrentUITheme.getColor( + EditorColors.SELECTION_BACKGROUND_COLOR, + ) + XPathAppComponent.getInstance().config.attributes.foregroundColor = + schemeForCurrentUITheme.getColor( + EditorColors.SELECTION_FOREGROUND_COLOR, + ) XPathAppComponent.getInstance().config.contextAttributes.backgroundColor = IDENTIFIER_UNDER_CARET_ATTRIBUTES.defaultAttributes.backgroundColor diff --git a/src/main/kotlin/io/unthrottled/doki/internal/DokiEditorNotificationProvider.kt b/src/main/kotlin/io/unthrottled/doki/internal/DokiEditorNotificationProvider.kt index f4b0343d0..90427cecb 100644 --- a/src/main/kotlin/io/unthrottled/doki/internal/DokiEditorNotificationProvider.kt +++ b/src/main/kotlin/io/unthrottled/doki/internal/DokiEditorNotificationProvider.kt @@ -9,7 +9,6 @@ import com.intellij.ui.EditorNotifications import io.unthrottled.doki.actions.EditorNotificationManager class DokiEditorNotificationProvider : EditorNotifications.Provider() { - companion object { private const val KEY = "io.unthrottled.doki.editor.notification" private val PROVIDER_KEY = Key.create(KEY) @@ -32,6 +31,6 @@ class DokiEditorNotificationProvider : EditorNotifications.Provider Rimuru - ) + private val renamedThemes = + setOf( + "4fd5cb34-d36e-4a3c-8639-052b19b26ba1", // Zero Two Light + "8c99ec4b-fda0-4ab7-95ad-a6bf80c3924b", // Zero Two Dark + "5ca2846d-31a9-40b3-8908-965dad3c127d", // Rimiru -> Rimuru + ) private fun handleThemeRenames() { ThemeManager.instance.currentTheme @@ -82,7 +87,7 @@ object LegacyMigration { setDokiTheme( ThemeManager.instance.allThemes.first { renamedTheme.id != it.id - }.toOptional() + }.toOptional(), ) setDokiTheme(renamedTheme.toOptional()) } diff --git a/src/main/kotlin/io/unthrottled/doki/listener/ApplicationLifecycleListener.kt b/src/main/kotlin/io/unthrottled/doki/listener/ApplicationLifecycleListener.kt index 3d24262cd..842eb3789 100644 --- a/src/main/kotlin/io/unthrottled/doki/listener/ApplicationLifecycleListener.kt +++ b/src/main/kotlin/io/unthrottled/doki/listener/ApplicationLifecycleListener.kt @@ -7,7 +7,6 @@ import io.unthrottled.doki.hax.HackComponent import io.unthrottled.doki.stickers.StickerComponent class ApplicationLifecycleListener : AppLifecycleListener, DumbAware { - companion object { init { HackComponent.init() diff --git a/src/main/kotlin/io/unthrottled/doki/listener/PluginPostStartUpActivity.kt b/src/main/kotlin/io/unthrottled/doki/listener/PluginPostStartUpActivity.kt index 744134b4e..525b99040 100644 --- a/src/main/kotlin/io/unthrottled/doki/listener/PluginPostStartUpActivity.kt +++ b/src/main/kotlin/io/unthrottled/doki/listener/PluginPostStartUpActivity.kt @@ -5,7 +5,6 @@ import com.intellij.openapi.startup.ProjectActivity import io.unthrottled.doki.TheDokiTheme class PluginPostStartUpActivity : ProjectActivity { - override suspend fun execute(project: Project) { doStuff(project) } diff --git a/src/main/kotlin/io/unthrottled/doki/notification/UpdateNotification.kt b/src/main/kotlin/io/unthrottled/doki/notification/UpdateNotification.kt index 8cba9fc75..d8d1b4c9b 100644 --- a/src/main/kotlin/io/unthrottled/doki/notification/UpdateNotification.kt +++ b/src/main/kotlin/io/unthrottled/doki/notification/UpdateNotification.kt @@ -38,266 +38,271 @@ import java.awt.Color private fun buildUpdateMessage( currentTheme: DokiTheme, isNewUser: Boolean, - versionNumber: String + versionNumber: String, ): String { - val accentColor = JBColor.namedColor( - DokiTheme.ACCENT_COLOR, - UIUtil.getTextAreaForeground() - ) + val accentColor = + JBColor.namedColor( + DokiTheme.ACCENT_COLOR, + UIUtil.getTextAreaForeground(), + ) val darkerAccentColor = ColorUtil.darker(accentColor, 1).toHexString() val accentHex = accentColor.toHexString() - val strokeColor = JBColor.namedColor("Doki.Icon.Accent.Contrast.color", Color.WHITE) - .toHexString() + val strokeColor = + JBColor.namedColor("Doki.Icon.Accent.Contrast.color", Color.WHITE) + .toHexString() val infoForegroundHex = UIUtil.getContextHelpForeground().toHexString() - val background = currentTheme.getBackground().orElse( - Background("essex_dark.png", IdeBackgroundUtil.Anchor.MIDDLE_RIGHT, 1) - ) + val background = + currentTheme.getBackground().orElse( + Background("essex_dark.png", IdeBackgroundUtil.Anchor.MIDDLE_RIGHT, 1), + ) - val greeting = if (isNewUser) { - //language=html - """ + val greeting = + if (isNewUser) { + //language=html + """

Looks like you are new, welcome! You now have a lot of themes now.
Feel free to browse
https://doki-theme.unthrottled.io/themes

- """.trimIndent() - } else { - //language=html - """ + """.trimIndent() + } else { + //language=html + """

Thank You for updating! I changed some things.
You can find more information here:
https://doki-theme.unthrottled.io/products/jetbrains/updates/$versionNumber

- """.trimIndent() - } + """.trimIndent() + } - val anchor = getAnchor( - background.position - ) + val anchor = + getAnchor( + background.position, + ) return """ - - - - - - - - - -
- -
-
-
-

Doki Theme

- - - - - - -

A large collection of themes built with love and care

- -

Unfortunately, I was unable to load your update.
- So you are stuck with me, the offline fallback.

- $greeting -
- - - - """.trimIndent() + const listener = () => { + drawBackground(); + }; + previousListener = listener; + window.addEventListener('resize', listener); + }); + + + + +
+ +
+
+
+

Doki Theme

+ + + + + + +

A large collection of themes built with love and care

+ +

Unfortunately, I was unable to load your update.
+ So you are stuck with me, the offline fallback.

+ $greeting +
+ + + + """.trimIndent() } fun getAnchor(position: IdeBackgroundUtil.Anchor): String { @@ -309,17 +314,18 @@ fun getAnchor(position: IdeBackgroundUtil.Anchor): String { } object UpdateNotification : Logging { - - private val notificationGroup = NotificationGroupManager.getInstance() - .getNotificationGroup("Doki Theme Updates") + private val notificationGroup = + NotificationGroupManager.getInstance() + .getNotificationGroup("Doki Theme Updates") private val defaultListener = NotificationListener.UrlOpeningListener(false) + fun showDokiNotification( @Nls(capitalization = Nls.Capitalization.Sentence) title: String = "", @Nls(capitalization = Nls.Capitalization.Sentence) content: String, project: Project? = null, listener: NotificationListener = defaultListener, - actions: List = emptyList() + actions: List = emptyList(), ) { val notification = buildNotification(content, title, listener, actions) notification.notify(project) @@ -329,15 +335,16 @@ object UpdateNotification : Logging { content: String, title: String, listener: NotificationListener, - actions: List + actions: List, ): Notification { - val notification = notificationGroup.createNotification( - content, - NotificationType.INFORMATION - ) - .setTitle(title) - .setListener(listener) - .setIcon(DokiIcons.General.PLUGIN_LOGO) + val notification = + notificationGroup.createNotification( + content, + NotificationType.INFORMATION, + ) + .setTitle(title) + .setListener(listener) + .setIcon(DokiIcons.General.PLUGIN_LOGO) actions.forEach { notification.addAction(it) } @@ -352,13 +359,13 @@ object UpdateNotification : Logging { project: Project, listener: NotificationListener = defaultListener, actions: List = emptyList(), - balloonPosition: BalloonPosition + balloonPosition: BalloonPosition, ) { val notification = buildNotification(content, title, listener, actions) BalloonTools.showStickyNotification( project, notification, - balloonPosition + balloonPosition, ) { } } @@ -367,7 +374,7 @@ object UpdateNotification : Logging { @Nls(capitalization = Nls.Capitalization.Sentence) title: String = "", @Nls(capitalization = Nls.Capitalization.Sentence) content: String, listener: NotificationListener = defaultListener, - actions: List<(Project?) -> AnAction> = emptyList() + actions: List<(Project?) -> AnAction> = emptyList(), ) { ProjectManager.getInstance().openProjects.forEach { project -> showDokiNotification(title, content, project, listener, actions.map { it(project) }) @@ -377,20 +384,20 @@ object UpdateNotification : Logging { fun sendMessage( title: String, message: String, - project: Project? = null + project: Project? = null, ) { showDokiNotification( title, message, project = project, - listener = defaultListener + listener = defaultListener, ) } fun display( project: Project, newVersion: String, - isNewUser: Boolean + isNewUser: Boolean, ) { val title = getPluginUpdateTitle() val currentTheme = ThemeManager.instance.currentTheme.orElse(ThemeManager.instance.defaultTheme) @@ -402,7 +409,7 @@ object UpdateNotification : Logging { project, title, url, - content + content, ) }) { logger().warn("Unable to show update notification for raisins.", it) @@ -411,6 +418,7 @@ object UpdateNotification : Logging { } private val lastWorkingBuild = BuildNumber.fromString("212.5712.43") + private fun needsToFixUpdateNotification(): Boolean { val build = ApplicationInfoEx.getInstanceEx().build return (lastWorkingBuild?.compareTo(build) ?: 0) < 0 && @@ -420,7 +428,7 @@ object UpdateNotification : Logging { private fun buildUrl( isNewUser: Boolean, newVersion: String, - currentTheme: DokiTheme + currentTheme: DokiTheme, ): String { val urlParameters = if (isNewUser) { @@ -442,22 +450,21 @@ object UpdateNotification : Logging { val pluginName = getPlugin( PluginManager.getPluginByClass( - UpdateNotification::class.java - )?.pluginId + UpdateNotification::class.java, + )?.pluginId, )?.name return "$pluginName Update" } - fun reconstructUrlAndContent( - dokiTheme: DokiTheme - ): Pair { + fun reconstructUrlAndContent(dokiTheme: DokiTheme): Pair { val versionNumber = ThemeConfig.instance.version.substringAfter("v") val newUrl = buildUrl(false, versionNumber, dokiTheme) - val content = buildUpdateMessage( - dokiTheme, - false, - versionNumber - ) + val content = + buildUpdateMessage( + dokiTheme, + false, + versionNumber, + ) return newUrl to content } } diff --git a/src/main/kotlin/io/unthrottled/doki/promotions/AniMemePluginPromotionRunner.kt b/src/main/kotlin/io/unthrottled/doki/promotions/AniMemePluginPromotionRunner.kt index b5df23532..779ba5c4e 100644 --- a/src/main/kotlin/io/unthrottled/doki/promotions/AniMemePluginPromotionRunner.kt +++ b/src/main/kotlin/io/unthrottled/doki/promotions/AniMemePluginPromotionRunner.kt @@ -13,18 +13,20 @@ import java.util.concurrent.TimeUnit import kotlin.random.Random enum class PromotionStatus { - ACCEPTED, REJECTED, BLOCKED, UNKNOWN + ACCEPTED, + REJECTED, + BLOCKED, + UNKNOWN, } data class PromotionResults( - val status: PromotionStatus + val status: PromotionStatus, ) object AniMemePromotionService { - fun runPromotion( onPromotion: (PromotionResults) -> Unit, - onReject: () -> Unit + onReject: () -> Unit, ) { AniMemePluginPromotionRunner(onPromotion, onReject) } @@ -32,18 +34,17 @@ object AniMemePromotionService { class AniMemePluginPromotionRunner( private val onPromotion: (PromotionResults) -> Unit, - private val onReject: () -> Unit + private val onReject: () -> Unit, ) : Runnable { - init { IdeEventQueue.getInstance().addIdleListener( this, TimeUnit.MILLISECONDS.convert( 5, - TimeUnit.MINUTES - ).toInt() + Random(System.currentTimeMillis()) - .nextInt(0, 2000) - + TimeUnit.MINUTES, + ).toInt() + + Random(System.currentTimeMillis()) + .nextInt(0, 2000), ) } @@ -56,7 +57,7 @@ class AniMemePluginPromotionRunner( object AniMemePluginPromotion { fun runPromotion( onPromotion: (PromotionResults) -> Unit, - onReject: () -> Unit + onReject: () -> Unit, ) { ApplicationManager.getApplication().executeOnPooledThread { ThemeManager.instance.currentTheme.ifPresent { dokiTheme -> @@ -70,22 +71,23 @@ object AniMemePluginPromotion { AniMemePromotionDialog( promotionAssets, project, - onPromotion + onPromotion, ).show() } }, - onReject + onReject, ) }, 0, - TimeUnit.SECONDS + TimeUnit.SECONDS, ) } } } } -fun getFirstProject(): Optional = ProjectManager.getInstance().openProjects - .toOptional() - .filter { it.isNotEmpty() } - .map { it.first() } +fun getFirstProject(): Optional = + ProjectManager.getInstance().openProjects + .toOptional() + .filter { it.isNotEmpty() } + .map { it.first() } diff --git a/src/main/kotlin/io/unthrottled/doki/promotions/CulturedContentDialog.kt b/src/main/kotlin/io/unthrottled/doki/promotions/CulturedContentDialog.kt index 45594c7f6..30f2f1e14 100644 --- a/src/main/kotlin/io/unthrottled/doki/promotions/CulturedContentDialog.kt +++ b/src/main/kotlin/io/unthrottled/doki/promotions/CulturedContentDialog.kt @@ -20,9 +20,8 @@ import javax.swing.event.HyperlinkEvent class CulturedContentDialog( private val bannerUrl: String, - project: Project + project: Project, ) : DialogWrapper(project, true) { - companion object { const val ALLOW_CULTURE_EXIT_CODE = 69 } @@ -36,7 +35,7 @@ class CulturedContentDialog( override fun createActions(): Array { return arrayOf( cancelAction, - buildInstallAction() + buildInstallAction(), ) } @@ -61,15 +60,17 @@ class CulturedContentDialog( val pane = JTextPane() pane.isEditable = false pane.contentType = "text/html" - val accentHex = JBColor.namedColor( - DokiTheme.ACCENT_COLOR, - UIUtil.getTextAreaForeground() - ).toHexString() + val accentHex = + JBColor.namedColor( + DokiTheme.ACCENT_COLOR, + UIUtil.getTextAreaForeground(), + ).toHexString() val infoForegroundHex = UIUtil.getContextHelpForeground().toHexString() - pane.background = JBColor.namedColor( - "Menu.background", - UIUtil.getEditorPaneBackground() - ) + pane.background = + JBColor.namedColor( + "Menu.background", + UIUtil.getEditorPaneBackground(), + ) @Language("HTML") val content = """ diff --git a/src/main/kotlin/io/unthrottled/doki/promotions/CulturedContentLedgerMaster.kt b/src/main/kotlin/io/unthrottled/doki/promotions/CulturedContentLedgerMaster.kt index b3cafca2c..96ca8c646 100644 --- a/src/main/kotlin/io/unthrottled/doki/promotions/CulturedContentLedgerMaster.kt +++ b/src/main/kotlin/io/unthrottled/doki/promotions/CulturedContentLedgerMaster.kt @@ -5,21 +5,20 @@ import io.unthrottled.doki.assets.AssetManager import io.unthrottled.doki.stickers.CurrentSticker data class CulturedContentLedger( - val allowedCulturedContent: MutableMap> + val allowedCulturedContent: MutableMap>, ) object CulturedContentLedgerMaster : LedgerMaster( AssetManager.constructGlobalAssetPath( AssetCategory.MISC, - "cultured-ledger.json" + "cultured-ledger.json", ).orElseGet { AssetManager.constructLocalAssetPath( AssetCategory.MISC, - "cultured-ledger.json" + "cultured-ledger.json", ) }, - CulturedContentLedger::class.java + CulturedContentLedger::class.java, ) { - override fun initialLedger(): CulturedContentLedger = - CulturedContentLedger(mutableMapOf()) + override fun initialLedger(): CulturedContentLedger = CulturedContentLedger(mutableMapOf()) } diff --git a/src/main/kotlin/io/unthrottled/doki/promotions/CulturedContentManager.kt b/src/main/kotlin/io/unthrottled/doki/promotions/CulturedContentManager.kt index 7798b1ced..feea7bc6e 100644 --- a/src/main/kotlin/io/unthrottled/doki/promotions/CulturedContentManager.kt +++ b/src/main/kotlin/io/unthrottled/doki/promotions/CulturedContentManager.kt @@ -12,50 +12,50 @@ import io.unthrottled.doki.util.toOptional import java.util.Optional object CulturedContentManager { - - private val culturedThemes = setOf( - "ea9a13f6-fa7f-46a4-ba6e-6cefe1f55160" - ) + private val culturedThemes = + setOf( + "ea9a13f6-fa7f-46a4-ba6e-6cefe1f55160", + ) private var isAsking = false fun safelyGetSticker(dokiTheme: DokiTheme): Optional = safelyGetContent( dokiTheme, - dokiTheme.stickers.secondary ?: dokiTheme.stickers.default + dokiTheme.stickers.secondary ?: dokiTheme.stickers.default, ) fun safelyGetBackground(dokiTheme: DokiTheme): Optional = safelyGetContent( dokiTheme, - dokiTheme.backgrounds.secondary ?: dokiTheme.backgrounds.default + dokiTheme.backgrounds.secondary ?: dokiTheme.backgrounds.default, ) private fun safelyGetContent( dokiTheme: DokiTheme, - content: T - ) = - if (isCultured(dokiTheme) && !hasAccepted(dokiTheme)) { - if (!isAsking) { - askToShowCulturedContent(dokiTheme) - } - Optional.empty() - } else { - content.toOptional() + content: T, + ) = if (isCultured(dokiTheme) && !hasAccepted(dokiTheme)) { + if (!isAsking) { + askToShowCulturedContent(dokiTheme) } + Optional.empty() + } else { + content.toOptional() + } private fun askToShowCulturedContent(dokiTheme: DokiTheme) { isAsking = true getFirstProject() .doOrElse({ ApplicationManager.getApplication().invokeLater { - val dialog = CulturedContentDialog( - AssetManager.resolveAssetUrl( - AssetCategory.MISC, - "suggestive/cultured.gif" - ).orElse("${AssetManager.ASSET_SOURCE}/misc/suggestive/cultured.gif"), - it - ) + val dialog = + CulturedContentDialog( + AssetManager.resolveAssetUrl( + AssetCategory.MISC, + "suggestive/cultured.gif", + ).orElse("${AssetManager.ASSET_SOURCE}/misc/suggestive/cultured.gif"), + it, + ) dialog.showAndGet() if (dialog.exitCode == CulturedContentDialog.ALLOW_CULTURE_EXIT_CODE) { @@ -74,6 +74,5 @@ object CulturedContentManager { private fun hasAccepted(dokiTheme: DokiTheme): Boolean = CulturedContentLedgerMaster.readLedger().allowedCulturedContent.containsKey(dokiTheme.id) - private fun isCultured(dokiTheme: DokiTheme): Boolean = - culturedThemes.contains(dokiTheme.id) + private fun isCultured(dokiTheme: DokiTheme): Boolean = culturedThemes.contains(dokiTheme.id) } diff --git a/src/main/kotlin/io/unthrottled/doki/promotions/LedgerMaster.kt b/src/main/kotlin/io/unthrottled/doki/promotions/LedgerMaster.kt index 87a349a5e..ee0c87fb6 100644 --- a/src/main/kotlin/io/unthrottled/doki/promotions/LedgerMaster.kt +++ b/src/main/kotlin/io/unthrottled/doki/promotions/LedgerMaster.kt @@ -14,15 +14,16 @@ import kotlin.io.path.exists abstract class LedgerMaster( private val ledgerPath: Path, - private val clazz: Class + private val clazz: Class, ) { private val log = Logger.getInstance(PromotionLedgerMaster::class.java) abstract fun initialLedger(): T - private val gson = GsonBuilder() - .setPrettyPrinting() - .create() + private val gson = + GsonBuilder() + .setPrettyPrinting() + .create() fun getInitialLedger(): T = if (ledgerPath.exists()) { @@ -37,7 +38,7 @@ abstract class LedgerMaster( .use { gson.fromJson( InputStreamReader(it, StandardCharsets.UTF_8), - clazz + clazz, ) } }) { @@ -54,10 +55,10 @@ abstract class LedgerMaster( Files.newBufferedWriter( ledgerPath, StandardOpenOption.CREATE, - StandardOpenOption.TRUNCATE_EXISTING + StandardOpenOption.TRUNCATE_EXISTING, ).use { it.write( - gson.toJson(promotionLedger) + gson.toJson(promotionLedger), ) } }) { diff --git a/src/main/kotlin/io/unthrottled/doki/promotions/LockMaster.kt b/src/main/kotlin/io/unthrottled/doki/promotions/LockMaster.kt index 391f4b332..a318e9cb3 100644 --- a/src/main/kotlin/io/unthrottled/doki/promotions/LockMaster.kt +++ b/src/main/kotlin/io/unthrottled/doki/promotions/LockMaster.kt @@ -16,25 +16,27 @@ import java.util.Optional data class Lock( val lockedBy: String, - val lockedDate: Instant + val lockedDate: Instant, ) object LockMaster { private val log = Logger.getInstance(LockMaster::class.java) - private val gson = GsonBuilder() - .setPrettyPrinting() - .create() + private val gson = + GsonBuilder() + .setPrettyPrinting() + .create() - private val lockPath = AssetManager.constructGlobalAssetPath( - AssetCategory.PROMOTION, - "lock.json" - ).orElseGet { - AssetManager.constructLocalAssetPath( + private val lockPath = + AssetManager.constructGlobalAssetPath( AssetCategory.PROMOTION, - "lock.json" - ) - } + "lock.json", + ).orElseGet { + AssetManager.constructLocalAssetPath( + AssetCategory.PROMOTION, + "lock.json", + ) + } fun acquireLock(id: String): Boolean = when { @@ -48,7 +50,7 @@ object LockMaster { .map { Duration.between( it.lockedDate, - Instant.now() + Instant.now(), ).toHours() > 1 } .orElse(true) @@ -84,8 +86,7 @@ object LockMaster { true } - private fun lockPromotion(id: String): Boolean = - writeLock(Lock(id, Instant.now())) + private fun lockPromotion(id: String): Boolean = writeLock(Lock(id, Instant.now())) private fun readLock(): Optional = runSafelyWithResult({ @@ -93,7 +94,7 @@ object LockMaster { .use { gson.fromJson( InputStreamReader(it, StandardCharsets.UTF_8), - Lock::class.java + Lock::class.java, ) }.toOptional() }) { diff --git a/src/main/kotlin/io/unthrottled/doki/promotions/MemePromotionDialog.kt b/src/main/kotlin/io/unthrottled/doki/promotions/MemePromotionDialog.kt index 800a1a44e..512624601 100644 --- a/src/main/kotlin/io/unthrottled/doki/promotions/MemePromotionDialog.kt +++ b/src/main/kotlin/io/unthrottled/doki/promotions/MemePromotionDialog.kt @@ -22,9 +22,8 @@ import org.intellij.lang.annotations.Language import java.util.Locale class PromotionAssets( - private val dokiTheme: DokiTheme + private val dokiTheme: DokiTheme, ) { - val pluginLogoURL: String val promotionAssetURL: String @@ -33,15 +32,16 @@ class PromotionAssets( promotionAssetURL = getPromotionAsset() } - private fun getPluginLogo(): String = AssetManager.resolveAssetUrl( - AssetCategory.PROMOTION, - "amii/logo.png" - ).orElse("$ASSET_SOURCE/promotion/amii/logo.png") + private fun getPluginLogo(): String = + AssetManager.resolveAssetUrl( + AssetCategory.PROMOTION, + "amii/logo.png", + ).orElse("$ASSET_SOURCE/promotion/amii/logo.png") private fun getPromotionAsset(): String = AssetManager.resolveAssetUrl( AssetCategory.PROMOTION, - "motivator/${dokiTheme.displayName.lowercase(Locale.getDefault())}.gif" + "motivator/${dokiTheme.displayName.lowercase(Locale.getDefault())}.gif", ) .orElseGet { AssetManager.resolveAssetUrl(AssetCategory.PROMOTION, "motivator/promotion.gif") @@ -52,15 +52,15 @@ class PromotionAssets( class AniMemePromotionDialog( private val promotionAssets: PromotionAssets, private val project: Project, - private val onPromotion: (PromotionResults) -> Unit + private val onPromotion: (PromotionResults) -> Unit, ) { - init { MessageBundle.message("amii.name") } - private val notificationGroup = NotificationGroupManager.getInstance() - .getNotificationGroup("Doki Theme Promotions") + private val notificationGroup = + NotificationGroupManager.getInstance() + .getNotificationGroup("Doki Theme Promotions") @Suppress("MaxLineLength") @Language("HTML") @@ -89,40 +89,49 @@ class AniMemePromotionDialog(
- """.trimIndent() + """.trimIndent() } fun show() { - val neverShowAction = object : NotificationAction(MessageBundle.message("promotions.dont.ask")) { - override fun actionPerformed(e: AnActionEvent, notification: Notification) { - emitStatus(PromotionStatus.BLOCKED) - notification.expire() + val neverShowAction = + object : NotificationAction(MessageBundle.message("promotions.dont.ask")) { + override fun actionPerformed( + e: AnActionEvent, + notification: Notification, + ) { + emitStatus(PromotionStatus.BLOCKED) + notification.expire() + } } - } - val installAction = object : NotificationAction(MessageBundle.message("promotion.action.ok")) { - override fun actionPerformed(e: AnActionEvent, notification: Notification) { - installAndEnable( - e.project, - setOf( - PluginId.getId(AMII_PLUGIN_ID) - ) + val installAction = + object : NotificationAction(MessageBundle.message("promotion.action.ok")) { + override fun actionPerformed( + e: AnActionEvent, + notification: Notification, ) { - emitStatus(PromotionStatus.ACCEPTED) + installAndEnable( + e.project, + setOf( + PluginId.getId(AMII_PLUGIN_ID), + ), + ) { + emitStatus(PromotionStatus.ACCEPTED) + } + notification.expire() } - notification.expire() } - } - val updateNotification = notificationGroup.createNotification( - buildPromotionMessage( - promotionAssets - ), - NotificationType.INFORMATION - ) - .setTitle("Doki Theme Promotion: ${MessageBundle.message("amii.name")}") - .setIcon(DokiIcons.General.PLUGIN_LOGO) - .addAction(installAction) - .addAction(neverShowAction) - .setListener(NotificationListener.UrlOpeningListener(false)) + val updateNotification = + notificationGroup.createNotification( + buildPromotionMessage( + promotionAssets, + ), + NotificationType.INFORMATION, + ) + .setTitle("Doki Theme Promotion: ${MessageBundle.message("amii.name")}") + .setIcon(DokiIcons.General.PLUGIN_LOGO) + .addAction(installAction) + .addAction(neverShowAction) + .setListener(NotificationListener.UrlOpeningListener(false)) updateNotification.whenExpired { emitStatus(PromotionStatus.BLOCKED) @@ -131,7 +140,7 @@ class AniMemePromotionDialog( BalloonTools.showStickyNotification( project, updateNotification, - BalloonPosition.RIGHT + BalloonPosition.RIGHT, ) { emitStatus(PromotionStatus.BLOCKED) } @@ -139,6 +148,7 @@ class AniMemePromotionDialog( private var emitted = false private var savedStatus = PromotionStatus.UNKNOWN + private fun emitStatus(status: PromotionStatus) { if (!emitted || savedStatus != status) { emitted = true diff --git a/src/main/kotlin/io/unthrottled/doki/promotions/MessageBundle.kt b/src/main/kotlin/io/unthrottled/doki/promotions/MessageBundle.kt index 49e9db170..825bd107d 100644 --- a/src/main/kotlin/io/unthrottled/doki/promotions/MessageBundle.kt +++ b/src/main/kotlin/io/unthrottled/doki/promotions/MessageBundle.kt @@ -4,11 +4,10 @@ import com.intellij.AbstractBundle import org.jetbrains.annotations.PropertyKey object MessageBundle : AbstractBundle(MESSAGE_BUNDLE) { - @JvmStatic fun message( @PropertyKey(resourceBundle = MESSAGE_BUNDLE) key: String, - vararg params: Any + vararg params: Any, ): String { return getMessage(key, params) } diff --git a/src/main/kotlin/io/unthrottled/doki/promotions/PromotionLedgerMaster.kt b/src/main/kotlin/io/unthrottled/doki/promotions/PromotionLedgerMaster.kt index 66181d2e4..a36c78b69 100644 --- a/src/main/kotlin/io/unthrottled/doki/promotions/PromotionLedgerMaster.kt +++ b/src/main/kotlin/io/unthrottled/doki/promotions/PromotionLedgerMaster.kt @@ -8,28 +8,33 @@ import java.util.UUID data class Promotion( val id: UUID, val datePromoted: Instant, - val result: PromotionStatus + val result: PromotionStatus, ) data class PromotionLedger( val user: UUID, val versionInstallDates: MutableMap, val seenPromotions: MutableMap, - var allowedToPromote: Boolean + var allowedToPromote: Boolean, ) object PromotionLedgerMaster : LedgerMaster( AssetManager.constructGlobalAssetPath( AssetCategory.PROMOTION, - "ledger.json" + "ledger.json", ).orElseGet { AssetManager.constructLocalAssetPath( AssetCategory.PROMOTION, - "ledger.json" + "ledger.json", ) }, - PromotionLedger::class.java + PromotionLedger::class.java, ) { override fun initialLedger(): PromotionLedger = - PromotionLedger(UUID.randomUUID(), mutableMapOf(), mutableMapOf(), true) + PromotionLedger( + UUID.randomUUID(), + mutableMapOf(), + mutableMapOf(), + true, + ) } diff --git a/src/main/kotlin/io/unthrottled/doki/promotions/PromotionManager.kt b/src/main/kotlin/io/unthrottled/doki/promotions/PromotionManager.kt index b924601bc..7aa447bf8 100644 --- a/src/main/kotlin/io/unthrottled/doki/promotions/PromotionManager.kt +++ b/src/main/kotlin/io/unthrottled/doki/promotions/PromotionManager.kt @@ -26,7 +26,6 @@ val MOTIVATION_PROMOTION_ID: UUID = UUID.fromString("63e1da85-1285-40c4-873a-3ed object PromotionManager : PromotionManagerImpl() open class PromotionManagerImpl { - private val log = Logger.getInstance(PromotionManager::class.java) private var initialized = false @@ -44,7 +43,10 @@ open class PromotionManagerImpl { } } - fun registerPromotion(newVersion: String, forceRegister: Boolean = false) { + fun registerPromotion( + newVersion: String, + forceRegister: Boolean = false, + ) { if (initialized.not() || forceRegister) { promotionRegistry(newVersion) initialized = true @@ -91,8 +93,7 @@ open class PromotionManagerImpl { } } - private fun areAniMemePluginsInstalled() = - isMotivatorInstalled() || isAmiiInstalled() + private fun areAniMemePluginsInstalled() = isMotivatorInstalled() || isAmiiInstalled() private val id: String get() = getApplicationName() @@ -103,22 +104,20 @@ open class PromotionManagerImpl { ( promotionLedger.seenPromotions.containsKey(MOTIVATION_PROMOTION_ID).not() || promotionLedger.seenPromotions[MOTIVATION_PROMOTION_ID]?.result == PromotionStatus.ACCEPTED - ) && + ) && WeebService.isWeebStuffOn() && canAmiiBeInstalled() } object WeebService { - fun isWeebStuffOn(): Boolean = ThemeConfig.instance.currentStickerLevel == StickerLevel.ON || isBackgroundOn() - fun isBackgroundOn(): Boolean = - ThemeConfig.instance.isDokiBackground + + fun isBackgroundOn(): Boolean = ThemeConfig.instance.isDokiBackground } object OnlineService { - fun isOnline(): Boolean = isOnlineCheck(ASSET_SOURCE) .map { it.toOptional() } diff --git a/src/main/kotlin/io/unthrottled/doki/schema/DokiJetbrainsThemeJsonSchemaProvider.kt b/src/main/kotlin/io/unthrottled/doki/schema/DokiJetbrainsThemeJsonSchemaProvider.kt index c4fb0854d..58d734f7c 100644 --- a/src/main/kotlin/io/unthrottled/doki/schema/DokiJetbrainsThemeJsonSchemaProvider.kt +++ b/src/main/kotlin/io/unthrottled/doki/schema/DokiJetbrainsThemeJsonSchemaProvider.kt @@ -24,14 +24,12 @@ class DokiJetbrainsThemeJsonSchemaProvider : override fun isAvailable(file: VirtualFile): Boolean = StringUtil.endsWithIgnoreCase( file.name, - ".jetbrains.definition.json" + ".jetbrains.definition.json", ) - override fun getSchemaFile(): VirtualFile? = - VfsUtil.findFileByURL(javaClass.getResource(THEME_SCHEMA)) + override fun getSchemaFile(): VirtualFile? = VfsUtil.findFileByURL(javaClass.getResource(THEME_SCHEMA)) - override fun getSchemaType(): SchemaType = - SchemaType.embeddedSchema - } + override fun getSchemaType(): SchemaType = SchemaType.embeddedSchema + }, ) } diff --git a/src/main/kotlin/io/unthrottled/doki/schema/DokiMasterThemeJsonSchemaProvider.kt b/src/main/kotlin/io/unthrottled/doki/schema/DokiMasterThemeJsonSchemaProvider.kt index 8020d9e1c..80cd370a5 100644 --- a/src/main/kotlin/io/unthrottled/doki/schema/DokiMasterThemeJsonSchemaProvider.kt +++ b/src/main/kotlin/io/unthrottled/doki/schema/DokiMasterThemeJsonSchemaProvider.kt @@ -20,13 +20,14 @@ class DokiMasterThemeJsonSchemaProvider : JsonSchemaProviderFactory { override fun getName(): String = "Doki Master Themes" override fun isAvailable(file: VirtualFile): Boolean = - StringUtil.endsWithIgnoreCase(file.name, ".master.definition.json") + StringUtil.endsWithIgnoreCase( + file.name, + ".master.definition.json", + ) - override fun getSchemaFile(): VirtualFile? = - VfsUtil.findFileByURL(javaClass.getResource(THEME_SCHEMA)) + override fun getSchemaFile(): VirtualFile? = VfsUtil.findFileByURL(javaClass.getResource(THEME_SCHEMA)) - override fun getSchemaType(): SchemaType = - SchemaType.embeddedSchema - } + override fun getSchemaType(): SchemaType = SchemaType.embeddedSchema + }, ) } diff --git a/src/main/kotlin/io/unthrottled/doki/service/AppService.kt b/src/main/kotlin/io/unthrottled/doki/service/AppService.kt index 6b9b9d5e7..d61fff569 100644 --- a/src/main/kotlin/io/unthrottled/doki/service/AppService.kt +++ b/src/main/kotlin/io/unthrottled/doki/service/AppService.kt @@ -3,6 +3,5 @@ package io.unthrottled.doki.service import com.intellij.openapi.application.ApplicationNamesInfo object AppService { - fun getApplicationName(): String = - ApplicationNamesInfo.getInstance().fullProductNameWithEdition + fun getApplicationName(): String = ApplicationNamesInfo.getInstance().fullProductNameWithEdition } diff --git a/src/main/kotlin/io/unthrottled/doki/service/ConsoleFontService.kt b/src/main/kotlin/io/unthrottled/doki/service/ConsoleFontService.kt index 7264a88f6..6d42947b5 100644 --- a/src/main/kotlin/io/unthrottled/doki/service/ConsoleFontService.kt +++ b/src/main/kotlin/io/unthrottled/doki/service/ConsoleFontService.kt @@ -7,7 +7,6 @@ import io.unthrottled.doki.settings.actors.ConsoleFontActor import io.unthrottled.doki.themes.ThemeManager object ConsoleFontService { - fun applyConsoleFont() { ThemeManager.instance.currentTheme .filter { ThemeConfig.instance.isOverrideConsoleFont } diff --git a/src/main/kotlin/io/unthrottled/doki/service/CustomFontSizeService.kt b/src/main/kotlin/io/unthrottled/doki/service/CustomFontSizeService.kt index 55450fbec..48a0ca376 100644 --- a/src/main/kotlin/io/unthrottled/doki/service/CustomFontSizeService.kt +++ b/src/main/kotlin/io/unthrottled/doki/service/CustomFontSizeService.kt @@ -5,7 +5,6 @@ import io.unthrottled.doki.config.ThemeConfig import io.unthrottled.doki.themes.ThemeManager object CustomFontSizeService { - fun applyCustomFontSize() { ThemeManager.instance.currentTheme .filter { ThemeConfig.instance.isGlobalFontSize } diff --git a/src/main/kotlin/io/unthrottled/doki/service/GlassNotificationService.kt b/src/main/kotlin/io/unthrottled/doki/service/GlassNotificationService.kt index c40b333b2..7cec1a52b 100644 --- a/src/main/kotlin/io/unthrottled/doki/service/GlassNotificationService.kt +++ b/src/main/kotlin/io/unthrottled/doki/service/GlassNotificationService.kt @@ -9,7 +9,6 @@ import java.awt.Color import javax.swing.UIManager object GlassNotificationService { - fun makeNotificationSeeThrough() { ThemeManager.instance.currentTheme .filter { ThemeConfig.instance.isSeeThroughNotifications } @@ -21,24 +20,27 @@ object GlassNotificationService { defaults["Notification.background"] = newNotificationBackground defaults["Notification.MoreButton.innerBorderColor"] = newNotificationBackground - defaults["Notification.MoreButton.background"] = toAlpha( - JBColor.namedColor( - "Table.stripeColor", - UIUtil.getHeaderActiveColor() + defaults["Notification.MoreButton.background"] = + toAlpha( + JBColor.namedColor( + "Table.stripeColor", + UIUtil.getHeaderActiveColor(), + ), ) - ) - defaults["Notification.errorBackground"] = toAlpha( - JBColor.namedColor( - "FileColor.Yellow", - defaultNotificationBackground + defaults["Notification.errorBackground"] = + toAlpha( + JBColor.namedColor( + "FileColor.Yellow", + defaultNotificationBackground, + ), ) - ) } } - private fun toAlpha(treeBackground: Color) = ColorUtil.withAlpha( - treeBackground, - ThemeConfig.instance.notificationOpacity / 100.0 - ) + private fun toAlpha(treeBackground: Color) = + ColorUtil.withAlpha( + treeBackground, + ThemeConfig.instance.notificationOpacity / 100.0, + ) } diff --git a/src/main/kotlin/io/unthrottled/doki/service/PluginService.kt b/src/main/kotlin/io/unthrottled/doki/service/PluginService.kt index 6ee8f6eff..41db667a7 100644 --- a/src/main/kotlin/io/unthrottled/doki/service/PluginService.kt +++ b/src/main/kotlin/io/unthrottled/doki/service/PluginService.kt @@ -22,24 +22,27 @@ const val RANDOMIZER_PLUGIN_ID = "io.unthrottled.theme.randomizer" const val DOKI_ICONS_PLUGIN_ID = "io.unthrottled.doki.icons" object PluginService : Logging { - private val objectMapper by lazy { ObjectMapper() } - fun isMotivatorInstalled(): Boolean = PluginManagerCore.isPluginInstalled( - PluginId.getId(MOTIVATOR_PLUGIN_ID) - ) + fun isMotivatorInstalled(): Boolean = + PluginManagerCore.isPluginInstalled( + PluginId.getId(MOTIVATOR_PLUGIN_ID), + ) - fun areIconsInstalled(): Boolean = PluginManagerCore.isPluginInstalled( - PluginId.getId(DOKI_ICONS_PLUGIN_ID) - ) + fun areIconsInstalled(): Boolean = + PluginManagerCore.isPluginInstalled( + PluginId.getId(DOKI_ICONS_PLUGIN_ID), + ) - fun isAmiiInstalled(): Boolean = PluginManagerCore.isPluginInstalled( - PluginId.getId(AMII_PLUGIN_ID) - ) + fun isAmiiInstalled(): Boolean = + PluginManagerCore.isPluginInstalled( + PluginId.getId(AMII_PLUGIN_ID), + ) - fun isRandomizerInstalled(): Boolean = PluginManagerCore.isPluginInstalled( - PluginId.getId(RANDOMIZER_PLUGIN_ID) - ) + fun isRandomizerInstalled(): Boolean = + PluginManagerCore.isPluginInstalled( + PluginId.getId(RANDOMIZER_PLUGIN_ID), + ) private val PLUGIN_MANAGER_URL by lazy { ApplicationInfoImpl.getInstanceEx() @@ -50,7 +53,7 @@ object PluginService : Logging { private data class CompatibleUpdateRequest( val build: String, - val pluginXMLIds: List + val pluginXMLIds: List, ) /** @@ -66,24 +69,23 @@ object PluginService : Logging { val externalPluginId: String = "", @get:JsonProperty("pluginXmlId") val pluginId: String = "", - val version: String = "" + val version: String = "", ) - private fun getLastCompatiblePluginUpdate( - ids: Set - ): List { + private fun getLastCompatiblePluginUpdate(ids: Set): List { return try { if (ids.isEmpty()) { return emptyList() } - val data = objectMapper.writeValueAsString( - CompatibleUpdateRequest( - ApplicationInfoImpl.getInstanceEx() - .build.asString(), - ids.map { it.idString } + val data = + objectMapper.writeValueAsString( + CompatibleUpdateRequest( + ApplicationInfoImpl.getInstanceEx() + .build.asString(), + ids.map { it.idString }, + ), ) - ) HttpRequests .post(Urls.newFromEncoded(COMPATIBLE_UPDATE_URL).toExternalForm(), HttpRequests.JSON_CONTENT_TYPE) .productNameAsUserAgent() @@ -103,9 +105,10 @@ object PluginService : Logging { Callable { runSafelyWithResult({ val pluginId = PluginId.getId(AMII_PLUGIN_ID) - val lastCompatiblePluginUpdate = getLastCompatiblePluginUpdate( - Collections.singleton(pluginId) - ) + val lastCompatiblePluginUpdate = + getLastCompatiblePluginUpdate( + Collections.singleton(pluginId), + ) lastCompatiblePluginUpdate.firstOrNull { pluginNode -> pluginNode.pluginId == AMII_PLUGIN_ID } != null @@ -113,7 +116,7 @@ object PluginService : Logging { logger().warn("Unable to check to see if AMII can be installed", it) false } - } + }, ).get() } } diff --git a/src/main/kotlin/io/unthrottled/doki/service/UpdateNotificationUpdater.kt b/src/main/kotlin/io/unthrottled/doki/service/UpdateNotificationUpdater.kt index a9e3efc42..25c87511c 100644 --- a/src/main/kotlin/io/unthrottled/doki/service/UpdateNotificationUpdater.kt +++ b/src/main/kotlin/io/unthrottled/doki/service/UpdateNotificationUpdater.kt @@ -9,34 +9,37 @@ import io.unthrottled.doki.themes.DokiTheme import io.unthrottled.doki.util.AlarmDebouncer object UpdateNotificationUpdater : Disposable { - private val debouncer = AlarmDebouncer(80) + fun attemptToRefreshUpdateNotification(dokiTheme: DokiTheme) { debouncer.debounce { ProjectManager.getInstance().openProjects.forEach { project -> val instance = FileEditorManager.getInstance(project) val title = UpdateNotification.getPluginUpdateTitle() - val updateNotifications = instance.openFiles.filter { - it.name == title - } + val updateNotifications = + instance.openFiles.filter { + it.name == title + } if (updateNotifications.isNotEmpty()) { updateNotifications.forEach { openEditor -> - val (newUrl, content) = UpdateNotification.reconstructUrlAndContent( - dokiTheme - ) + val (newUrl, content) = + UpdateNotification.reconstructUrlAndContent( + dokiTheme, + ) instance.closeFile(openEditor) HTMLEditorProvider.openEditor( project, title, newUrl, - content + content, ) } } } } } + override fun dispose() { this.debouncer.dispose() } diff --git a/src/main/kotlin/io/unthrottled/doki/settings/ThemeSettings.kt b/src/main/kotlin/io/unthrottled/doki/settings/ThemeSettings.kt index f41100465..0d14b077c 100644 --- a/src/main/kotlin/io/unthrottled/doki/settings/ThemeSettings.kt +++ b/src/main/kotlin/io/unthrottled/doki/settings/ThemeSettings.kt @@ -56,14 +56,12 @@ data class ThemeSettingsModel( var hideOnHover: Boolean, var hideDelayMS: Int, var isSeeThroughNotifications: Boolean, - var notificationOpacity: Int + var notificationOpacity: Int, ) { - fun duplicate(): ThemeSettingsModel = copy() } object ThemeSettings { - const val SETTINGS_ID = "io.unthrottled.doki.settings.ThemeSettings" const val THEME_SETTINGS_DISPLAY_NAME = "Doki Theme Settings" val CHANGELOG_URI = @@ -103,7 +101,7 @@ object ThemeSettings { ignoreScaling = ThemeConfig.instance.ignoreScaling, hideOnHover = ThemeConfig.instance.hideOnHover, hideDelayMS = ThemeConfig.instance.hideDelayMS, - allowPromotionalContent = ThemeConfig.instance.allowPromotions + allowPromotionalContent = ThemeConfig.instance.allowPromotions, ) fun apply(themeSettingsModel: ThemeSettingsModel) { @@ -115,17 +113,17 @@ object ThemeSettings { StickerActor.setCustomSticker( themeSettingsModel.customStickerPath, themeSettingsModel.isCustomSticker, - false + false, ) StickerActor.setDimensionCapping( themeSettingsModel.capStickerDimensions, themeSettingsModel.maxStickerWidth, - themeSettingsModel.maxStickerHeight + themeSettingsModel.maxStickerHeight, ) StickerActor.setSmolStickers( themeSettingsModel.showSmallStickers, themeSettingsModel.smallMaxStickerWidth, - themeSettingsModel.smallMaxStickerHeight + themeSettingsModel.smallMaxStickerHeight, ) ThemeActor.applyTheme(themeSettingsModel.currentTheme) ThemeStatusBarActor.applyConfig(themeSettingsModel.showThemeStatusBar) @@ -134,34 +132,35 @@ object ThemeSettings { EmptyFrameBackgroundActor.handleBackgroundUpdate(themeSettingsModel.isEmptyFrameBackground) CustomFontSizeActor.enableCustomFontSize( themeSettingsModel.isCustomFontSize, - themeSettingsModel.customFontSizeValue + themeSettingsModel.customFontSizeValue, ) ConsoleFontActor.enableCustomFontSize( themeSettingsModel.isOverrideConsoleFont, - themeSettingsModel.consoleFontValue + themeSettingsModel.consoleFontValue, ) SeeThroughNotificationsActor.enableSeeThroughNotifications( themeSettingsModel.isSeeThroughNotifications, - themeSettingsModel.notificationOpacity + themeSettingsModel.notificationOpacity, ) DiscreetModeActor.enableDiscreetMode(themeSettingsModel.discreetMode) StickerHideActor.setStickerHideStuff(themeSettingsModel.hideOnHover, themeSettingsModel.hideDelayMS) PromotionSettingActor.optInToPromotion(themeSettingsModel.allowPromotionalContent) ApplicationManager.getApplication().messageBus.syncPublisher( - THEME_CONFIG_TOPIC + THEME_CONFIG_TOPIC, ).themeConfigUpdated(ThemeConfig.instance) } fun createThemeComboBoxModel(settingsSupplier: () -> ThemeSettingsModel): ComboBox { - val themeComboBox = ComboBox( - DefaultComboBoxModel( - Vector( - ThemeManager.instance.allThemes - .sortedBy { theme -> theme.name } - .map { it.name } - ) + val themeComboBox = + ComboBox( + DefaultComboBoxModel( + Vector( + ThemeManager.instance.allThemes + .sortedBy { theme -> theme.name } + .map { it.name }, + ), + ), ) - ) themeComboBox.model.selectedItem = settingsSupplier().currentTheme themeComboBox.addActionListener { settingsSupplier().currentTheme = themeComboBox.model.selectedItem as String diff --git a/src/main/kotlin/io/unthrottled/doki/settings/actors/BackgroundActor.kt b/src/main/kotlin/io/unthrottled/doki/settings/actors/BackgroundActor.kt index fdad24c6e..4e699d903 100644 --- a/src/main/kotlin/io/unthrottled/doki/settings/actors/BackgroundActor.kt +++ b/src/main/kotlin/io/unthrottled/doki/settings/actors/BackgroundActor.kt @@ -18,13 +18,17 @@ object BackgroundActor { UpdateNotification.showNotificationAcrossProjects( MessageBundle.message("wallpaper.install.title"), MessageBundle.message("wallpaper.install.body"), - actions = listOf { - object : NotificationAction(MessageBundle.message("wallpaper.install.show-settings")) { - override fun actionPerformed(e: AnActionEvent, notification: Notification) { - ActionManager.getInstance().getAction("Images.SetBackgroundImage")?.actionPerformed(e) + actions = + listOf { + object : NotificationAction(MessageBundle.message("wallpaper.install.show-settings")) { + override fun actionPerformed( + e: AnActionEvent, + notification: Notification, + ) { + ActionManager.getInstance().getAction("Images.SetBackgroundImage")?.actionPerformed(e) + } } - } - } + }, ) } else { EditorBackgroundWallpaperService.instance.removeEditorBackground() diff --git a/src/main/kotlin/io/unthrottled/doki/settings/actors/ConsoleFontActor.kt b/src/main/kotlin/io/unthrottled/doki/settings/actors/ConsoleFontActor.kt index 54c359644..ac658b536 100644 --- a/src/main/kotlin/io/unthrottled/doki/settings/actors/ConsoleFontActor.kt +++ b/src/main/kotlin/io/unthrottled/doki/settings/actors/ConsoleFontActor.kt @@ -8,7 +8,10 @@ import io.unthrottled.doki.util.logger import io.unthrottled.doki.util.runSafely object ConsoleFontActor : Logging { - fun enableCustomFontSize(enabled: Boolean, consoleFontName: String) { + fun enableCustomFontSize( + enabled: Boolean, + consoleFontName: String, + ) { val previousEnablement = ThemeConfig.instance.isOverrideConsoleFont ThemeConfig.instance.isOverrideConsoleFont = enabled val previousFontSize = ThemeConfig.instance.consoleFontName diff --git a/src/main/kotlin/io/unthrottled/doki/settings/actors/CustomFontSizeActor.kt b/src/main/kotlin/io/unthrottled/doki/settings/actors/CustomFontSizeActor.kt index 77e99ddbe..b64625ec2 100644 --- a/src/main/kotlin/io/unthrottled/doki/settings/actors/CustomFontSizeActor.kt +++ b/src/main/kotlin/io/unthrottled/doki/settings/actors/CustomFontSizeActor.kt @@ -5,7 +5,10 @@ import io.unthrottled.doki.config.ThemeConfig import io.unthrottled.doki.service.CustomFontSizeService object CustomFontSizeActor { - fun enableCustomFontSize(enabled: Boolean, customFontSize: Int) { + fun enableCustomFontSize( + enabled: Boolean, + customFontSize: Int, + ) { val previousEnablement = ThemeConfig.instance.isGlobalFontSize ThemeConfig.instance.isGlobalFontSize = enabled val previousFontSize = ThemeConfig.instance.customFontSize diff --git a/src/main/kotlin/io/unthrottled/doki/settings/actors/LafAnimationActor.kt b/src/main/kotlin/io/unthrottled/doki/settings/actors/LafAnimationActor.kt index 95c35f60f..a4a64e689 100644 --- a/src/main/kotlin/io/unthrottled/doki/settings/actors/LafAnimationActor.kt +++ b/src/main/kotlin/io/unthrottled/doki/settings/actors/LafAnimationActor.kt @@ -13,7 +13,7 @@ object LafAnimationActor { if (enabled) { UpdateNotification.showDokiNotification( MessageBundle.getMessage("notification.animation.install.title"), - MessageBundle.getMessage("notification.animation.install.body") + MessageBundle.getMessage("notification.animation.install.body"), ) } } diff --git a/src/main/kotlin/io/unthrottled/doki/settings/actors/MoveableStickerActor.kt b/src/main/kotlin/io/unthrottled/doki/settings/actors/MoveableStickerActor.kt index 17ab32452..e871d989b 100644 --- a/src/main/kotlin/io/unthrottled/doki/settings/actors/MoveableStickerActor.kt +++ b/src/main/kotlin/io/unthrottled/doki/settings/actors/MoveableStickerActor.kt @@ -13,12 +13,12 @@ object MoveableStickerActor { if (enabled) { UpdateNotification.showNotificationAcrossProjects( MessageBundle.message("stickers.movable.sticker.title"), - MessageBundle.message("stickers.movable.sticker.body") + MessageBundle.message("stickers.movable.sticker.body"), ) } else { UpdateNotification.showNotificationAcrossProjects( MessageBundle.message("sticker.stationary.title"), - MessageBundle.message("sticker.stationary.body") + MessageBundle.message("sticker.stationary.body"), ) } } diff --git a/src/main/kotlin/io/unthrottled/doki/settings/actors/PromotionSettingActor.kt b/src/main/kotlin/io/unthrottled/doki/settings/actors/PromotionSettingActor.kt index 164d03df2..32714d54e 100644 --- a/src/main/kotlin/io/unthrottled/doki/settings/actors/PromotionSettingActor.kt +++ b/src/main/kotlin/io/unthrottled/doki/settings/actors/PromotionSettingActor.kt @@ -4,10 +4,7 @@ import io.unthrottled.doki.config.ThemeConfig import io.unthrottled.doki.promotions.PromotionManager object PromotionSettingActor { - - fun optInToPromotion( - allowedToPromote: Boolean - ) { + fun optInToPromotion(allowedToPromote: Boolean) { if (allowedToPromote != ThemeConfig.instance.allowPromotions) { ThemeConfig.instance.allowPromotions = allowedToPromote PromotionManager.setPromotionsEnabled(allowedToPromote) diff --git a/src/main/kotlin/io/unthrottled/doki/settings/actors/SeeThroughNotificationsActor.kt b/src/main/kotlin/io/unthrottled/doki/settings/actors/SeeThroughNotificationsActor.kt index d53bcbc32..1bbe04225 100644 --- a/src/main/kotlin/io/unthrottled/doki/settings/actors/SeeThroughNotificationsActor.kt +++ b/src/main/kotlin/io/unthrottled/doki/settings/actors/SeeThroughNotificationsActor.kt @@ -7,8 +7,10 @@ import io.unthrottled.doki.promotions.MessageBundle import io.unthrottled.doki.service.GlassNotificationService object SeeThroughNotificationsActor { - - fun enableSeeThroughNotifications(enabled: Boolean, notificationOpacity: Int) { + fun enableSeeThroughNotifications( + enabled: Boolean, + notificationOpacity: Int, + ) { val previousEnablement = ThemeConfig.instance.isSeeThroughNotifications ThemeConfig.instance.isSeeThroughNotifications = enabled val previousOpacity = ThemeConfig.instance.notificationOpacity @@ -21,7 +23,7 @@ object SeeThroughNotificationsActor { UpdateNotification.sendMessage( MessageBundle.message("notification.glass.notification.title"), MessageBundle.message("notification.glass.notification.body"), - ProjectManager.getInstance().openProjects.firstOrNull() + ProjectManager.getInstance().openProjects.firstOrNull(), ) } } diff --git a/src/main/kotlin/io/unthrottled/doki/settings/actors/ShowReadmeActor.kt b/src/main/kotlin/io/unthrottled/doki/settings/actors/ShowReadmeActor.kt index 463ed0c44..93758b5d9 100644 --- a/src/main/kotlin/io/unthrottled/doki/settings/actors/ShowReadmeActor.kt +++ b/src/main/kotlin/io/unthrottled/doki/settings/actors/ShowReadmeActor.kt @@ -13,7 +13,7 @@ object ShowReadmeActor { if (enabled) { UpdateNotification.showDokiNotification( MessageBundle.message("notification.no.show.readme.title"), - MessageBundle.message("notification.no.show.readme.body") + MessageBundle.message("notification.no.show.readme.body"), ) } } diff --git a/src/main/kotlin/io/unthrottled/doki/settings/actors/StickerActor.kt b/src/main/kotlin/io/unthrottled/doki/settings/actors/StickerActor.kt index 51ffa4b22..8d748bf54 100644 --- a/src/main/kotlin/io/unthrottled/doki/settings/actors/StickerActor.kt +++ b/src/main/kotlin/io/unthrottled/doki/settings/actors/StickerActor.kt @@ -12,8 +12,10 @@ import io.unthrottled.doki.themes.ThemeManager import io.unthrottled.doki.util.performWithAnimation object StickerActor { - - fun swapStickers(newStickerType: CurrentSticker, withAnimation: Boolean = true) { + fun swapStickers( + newStickerType: CurrentSticker, + withAnimation: Boolean = true, + ) { if (ThemeConfig.instance.currentSticker != newStickerType) { performWithAnimation(withAnimation) { ThemeConfig.instance.currentSticker = newStickerType @@ -35,13 +37,19 @@ object StickerActor { } } - fun enableStickers(enabled: Boolean, withAnimation: Boolean = true) { + fun enableStickers( + enabled: Boolean, + withAnimation: Boolean = true, + ) { if (enabled != (ThemeConfig.instance.currentStickerLevel == StickerLevel.ON)) { setStickers(withAnimation, enabled) } } - fun setStickers(withAnimation: Boolean, enabled: Boolean) { + fun setStickers( + withAnimation: Boolean, + enabled: Boolean, + ) { performWithAnimation(withAnimation) { if (enabled) { ThemeConfig.instance.stickerLevel = StickerLevel.ON.name @@ -58,14 +66,15 @@ object StickerActor { fun setCustomSticker( customStickerPath: String, isCustomStickers: Boolean, - withAnimation: Boolean + withAnimation: Boolean, ) { val isCustomStickersChanged = CustomStickerService.isCustomStickers != isCustomStickers CustomStickerService.isCustomStickers = isCustomStickers - val isNewStickerPath = CustomStickerService.getCustomStickerPath() - .map { it != customStickerPath } - .orElse(true) && customStickerPath.isNotBlank() + val isNewStickerPath = + CustomStickerService.getCustomStickerPath() + .map { it != customStickerPath } + .orElse(true) && customStickerPath.isNotBlank() if (isNewStickerPath) { CustomStickerService.setCustomStickerPath(customStickerPath) } @@ -79,7 +88,7 @@ object StickerActor { fun setDimensionCapping( capStickerDimensions: Boolean, maxStickerWidth: Int, - maxStickerHeight: Int + maxStickerHeight: Int, ) { val ogWidth = ThemeConfig.instance.maxStickerWidth ThemeConfig.instance.maxStickerWidth = maxStickerWidth @@ -99,7 +108,7 @@ object StickerActor { fun setSmolStickers( isSmolStickers: Boolean, smolMaxStickerWidth: Int, - smolMaxStickerHeight: Int + smolMaxStickerHeight: Int, ) { val ogWidth = ThemeConfig.instance.smallMaxStickerWidth ThemeConfig.instance.smallMaxStickerWidth = smolMaxStickerWidth diff --git a/src/main/kotlin/io/unthrottled/doki/settings/actors/StickerHideActor.kt b/src/main/kotlin/io/unthrottled/doki/settings/actors/StickerHideActor.kt index 5f09d117a..86c3be105 100644 --- a/src/main/kotlin/io/unthrottled/doki/settings/actors/StickerHideActor.kt +++ b/src/main/kotlin/io/unthrottled/doki/settings/actors/StickerHideActor.kt @@ -5,18 +5,17 @@ import io.unthrottled.doki.stickers.StickerHideConfig import io.unthrottled.doki.stickers.StickerPaneService object StickerHideActor { - fun setStickerHideStuff( hideOnHover: Boolean, - hideDelayMS: Int + hideDelayMS: Int, ) { if (hideOnHover != ThemeConfig.instance.hideOnHover) { ThemeConfig.instance.hideOnHover = hideOnHover StickerPaneService.instance.setStickerHideConfig( StickerHideConfig( hideOnHover, - hideDelayMS - ) + hideDelayMS, + ), ) } } diff --git a/src/main/kotlin/io/unthrottled/doki/settings/actors/ThemeActor.kt b/src/main/kotlin/io/unthrottled/doki/settings/actors/ThemeActor.kt index e77bc2a22..24aacfb56 100644 --- a/src/main/kotlin/io/unthrottled/doki/settings/actors/ThemeActor.kt +++ b/src/main/kotlin/io/unthrottled/doki/settings/actors/ThemeActor.kt @@ -19,13 +19,13 @@ object ThemeActor : Logging { private fun getDokiTheme( currentTheme: Optional, - selectedTheme: String + selectedTheme: String, ) = getTheme(currentTheme, selectedTheme) .flatMap { ThemeManager.instance.themeByName(selectedTheme) } private fun getTheme( currentTheme: Optional, - selectedTheme: String + selectedTheme: String, ): Optional { return if (currentTheme.isPresent) { currentTheme @@ -49,7 +49,7 @@ object ThemeActor : Logging { QuickChangeLookAndFeel.switchLafAndUpdateUI( LafManager.getInstance(), it, - true + true, ) }) { logger().warn("Unable to set doki theme for reasons", it) diff --git a/src/main/kotlin/io/unthrottled/doki/stickers/CurrentSticker.kt b/src/main/kotlin/io/unthrottled/doki/stickers/CurrentSticker.kt index 4795aa5bc..5ba616140 100644 --- a/src/main/kotlin/io/unthrottled/doki/stickers/CurrentSticker.kt +++ b/src/main/kotlin/io/unthrottled/doki/stickers/CurrentSticker.kt @@ -1,5 +1,6 @@ package io.unthrottled.doki.stickers enum class CurrentSticker { - DEFAULT, SECONDARY + DEFAULT, + SECONDARY, } diff --git a/src/main/kotlin/io/unthrottled/doki/stickers/CustomStickerService.kt b/src/main/kotlin/io/unthrottled/doki/stickers/CustomStickerService.kt index 635825b4a..c057b07fc 100644 --- a/src/main/kotlin/io/unthrottled/doki/stickers/CustomStickerService.kt +++ b/src/main/kotlin/io/unthrottled/doki/stickers/CustomStickerService.kt @@ -8,10 +8,11 @@ import java.util.Optional object CustomStickerService { private const val CUSTOM_STICKER_PROPERTY = "io.unthrottled.doki.theme.custom-sticker" private const val CUSTOM_STICKER_ENABLED_PROPERTY = "io.unthrottled.doki.theme.custom-sticker.enabled" + fun setCustomStickerPath(path: String) { PropertiesComponent.getInstance().setValue( CUSTOM_STICKER_PROPERTY, - path + path, ) } diff --git a/src/main/kotlin/io/unthrottled/doki/stickers/DimensionCappingService.kt b/src/main/kotlin/io/unthrottled/doki/stickers/DimensionCappingService.kt index 1dc217cb3..f28641da7 100644 --- a/src/main/kotlin/io/unthrottled/doki/stickers/DimensionCappingService.kt +++ b/src/main/kotlin/io/unthrottled/doki/stickers/DimensionCappingService.kt @@ -3,10 +3,9 @@ package io.unthrottled.doki.stickers import java.awt.Dimension object DimensionCappingService { - fun getCappingStyle( stickerDimensions: Dimension, - maxDimension: Dimension + maxDimension: Dimension, ): Dimension { val maxHeight = maxDimension.height val maxWidth = maxDimension.width diff --git a/src/main/kotlin/io/unthrottled/doki/stickers/EditorBackgroundWallpaperService.kt b/src/main/kotlin/io/unthrottled/doki/stickers/EditorBackgroundWallpaperService.kt index 91e6fc0e9..f90ab7af8 100644 --- a/src/main/kotlin/io/unthrottled/doki/stickers/EditorBackgroundWallpaperService.kt +++ b/src/main/kotlin/io/unthrottled/doki/stickers/EditorBackgroundWallpaperService.kt @@ -20,7 +20,6 @@ private const val PREVIOUS_BACKGROUND = "io.unthrottled.doki.previous-background @Suppress("TooManyFunctions") // cuz I said so internal class EditorBackgroundWallpaperService { - companion object { val instance: EditorBackgroundWallpaperService get() = ApplicationManager.getApplication().getService(EditorBackgroundWallpaperService::class.java) @@ -43,8 +42,9 @@ internal class EditorBackgroundWallpaperService { private fun installEditorBackgroundImage(dokiTheme: DokiTheme) = getLocallyInstalledWallpaperImagePath(dokiTheme) .doOrElse({ - val isSameWallpaper = getCurrentBackgroundValue() - .startsWith(it.first) + val isSameWallpaper = + getCurrentBackgroundValue() + .startsWith(it.first) if (isSameWallpaper) return@doOrElse @@ -54,7 +54,7 @@ internal class EditorBackgroundWallpaperService { it.second.opacity?.toString() ?: if (dokiTheme.isDark) "5" else "10", Fill.SCALE.name, it.second.position.name, - EDITOR_PROP + EDITOR_PROP, ) }) { if (getNonDokiBackground().isPresent().not()) { // y u no like isEmpty() ??? @@ -62,8 +62,9 @@ internal class EditorBackgroundWallpaperService { } } - fun getCurrentBackgroundValue() = PropertiesComponent.getInstance() - .getValue(EDITOR_PROP, "") + fun getCurrentBackgroundValue() = + PropertiesComponent.getInstance() + .getValue(EDITOR_PROP, "") fun setBackgroundValue(backgroundProperty: String) { PropertiesComponent.getInstance() @@ -83,14 +84,12 @@ internal class EditorBackgroundWallpaperService { .toOptional() .filter { it.contains(ASSET_DIRECTORY).not() } - private fun getLocallyInstalledWallpaperImagePath( - dokiTheme: DokiTheme - ): Optional> = + private fun getLocallyInstalledWallpaperImagePath(dokiTheme: DokiTheme): Optional> = dokiTheme.getBackground() .flatMap { background -> AssetManager.resolveAssetUrl( AssetCategory.BACKGROUNDS, - "wallpapers/${background.name}" + "wallpapers/${background.name}", ).map { it to background } } @@ -132,16 +131,20 @@ internal fun setBackgroundImageProperty( opacity: String, fill: String, anchor: String, - propertyKey: String + propertyKey: String, ) { // org.intellij.images.editor.actions.SetBackgroundImageDialog has all of the answers // as to why this looks this way - val propertyValue = listOf(imagePath, opacity, fill, anchor) - .reduceRight { a, b -> "$a,$b" } + val propertyValue = + listOf(imagePath, opacity, fill, anchor) + .reduceRight { a, b -> "$a,$b" } setPropertyValue(propertyKey, propertyValue) } -private fun setPropertyValue(propertyKey: String, propertyValue: String) { +private fun setPropertyValue( + propertyKey: String, + propertyValue: String, +) { PropertiesComponent.getInstance().unsetValue(propertyKey) PropertiesComponent.getInstance().setValue(propertyKey, propertyValue) } diff --git a/src/main/kotlin/io/unthrottled/doki/stickers/EmptyFrameWallpaperService.kt b/src/main/kotlin/io/unthrottled/doki/stickers/EmptyFrameWallpaperService.kt index c5208fc94..67731b3f0 100644 --- a/src/main/kotlin/io/unthrottled/doki/stickers/EmptyFrameWallpaperService.kt +++ b/src/main/kotlin/io/unthrottled/doki/stickers/EmptyFrameWallpaperService.kt @@ -13,7 +13,6 @@ import io.unthrottled.doki.util.doOrElse import java.util.Optional class EmptyFrameWallpaperService { - companion object { val instance: EmptyFrameWallpaperService get() = ApplicationManager.getApplication().getService(EmptyFrameWallpaperService::class.java) @@ -50,20 +49,18 @@ class EmptyFrameWallpaperService { "100", IdeBackgroundUtil.Fill.SCALE.name, it.second.position.name, - DOKI_BACKGROUND_PROP + DOKI_BACKGROUND_PROP, ) }) { remove() } - private fun getLocallyInstalledBackgroundImagePath( - dokiTheme: DokiTheme - ): Optional> = + private fun getLocallyInstalledBackgroundImagePath(dokiTheme: DokiTheme): Optional> = dokiTheme.getBackground() .flatMap { background -> AssetManager.resolveAssetUrl( AssetCategory.BACKGROUNDS, - background.name + background.name, ).map { it to background } } diff --git a/src/main/kotlin/io/unthrottled/doki/stickers/MarginService.kt b/src/main/kotlin/io/unthrottled/doki/stickers/MarginService.kt index 03f87e5be..c7658708d 100644 --- a/src/main/kotlin/io/unthrottled/doki/stickers/MarginService.kt +++ b/src/main/kotlin/io/unthrottled/doki/stickers/MarginService.kt @@ -12,7 +12,6 @@ import io.unthrottled.doki.util.runSafelyWithResult import java.util.concurrent.ConcurrentHashMap class MarginService : Logging { - companion object { private const val STICKER_Y_OFFSET = 0.05 private const val STICKER_X_OFFSET = 0.03 @@ -21,8 +20,9 @@ class MarginService : Logging { ApplicationManager.getApplication().getService(MarginService::class.java) } - private val gson = GsonBuilder() - .create() + private val gson = + GsonBuilder() + .create() private val savedMargins: MutableMap = readMargins() @@ -30,7 +30,7 @@ class MarginService : Logging { return runSafelyWithResult({ gson.fromJson( ThemeConfig.instance.savedMargins, - object : TypeToken>() {}.type + object : TypeToken>() {}.type, ) }) { logger().warn("Unable to read saved margins!", it) @@ -49,12 +49,15 @@ class MarginService : Logging { private fun getWindowKey(windowBro: Any) = windowBro::class.java.canonicalName - fun saveMargin(window: Any, margin: Margin) { + fun saveMargin( + window: Any, + margin: Margin, + ) { savedMargins[getWindowKey(window)] = margin ThemeConfig.instance.savedMargins = gson.toJson(savedMargins.toMutableMap()) UpdateNotification.showNotificationAcrossProjects( MessageBundle.message("notification.margin.saved.title"), - MessageBundle.message("notification.margin.saved.message") + MessageBundle.message("notification.margin.saved.message"), ) } } diff --git a/src/main/kotlin/io/unthrottled/doki/stickers/StickerComponent.kt b/src/main/kotlin/io/unthrottled/doki/stickers/StickerComponent.kt index 3d804db9c..0f90b8ba5 100644 --- a/src/main/kotlin/io/unthrottled/doki/stickers/StickerComponent.kt +++ b/src/main/kotlin/io/unthrottled/doki/stickers/StickerComponent.kt @@ -26,14 +26,14 @@ class StickerComponent : LafManager.getInstance()?.currentUIThemeLookAndFeel.toOptional() .ifPresent { currentLaf -> ThemeManager.instance.processLaf( - currentLaf + currentLaf, ).doOrElse({ processLaf(currentLaf) // is doki theme }) { // allow custom stickers to show up if (CustomStickerService.isCustomStickers) { StickerPaneService.instance.activateForTheme( - ThemeManager.instance.defaultTheme + ThemeManager.instance.defaultTheme, ) } } @@ -41,7 +41,6 @@ class StickerComponent : } companion object { - val instance: StickerComponent get() = ApplicationManager.getApplication().getService(StickerComponent::class.java) @@ -64,8 +63,7 @@ class StickerComponent : } } - override fun lookAndFeelChanged(source: LafManager) = - processLaf(source.currentUIThemeLookAndFeel) + override fun lookAndFeelChanged(source: LafManager) = processLaf(source.currentUIThemeLookAndFeel) override fun dispose() { connection.dispose() diff --git a/src/main/kotlin/io/unthrottled/doki/stickers/StickerLevel.kt b/src/main/kotlin/io/unthrottled/doki/stickers/StickerLevel.kt index a10f89793..6bd701130 100644 --- a/src/main/kotlin/io/unthrottled/doki/stickers/StickerLevel.kt +++ b/src/main/kotlin/io/unthrottled/doki/stickers/StickerLevel.kt @@ -1,5 +1,6 @@ package io.unthrottled.doki.stickers enum class StickerLevel { - OFF, ON + OFF, + ON, } diff --git a/src/main/kotlin/io/unthrottled/doki/stickers/StickerPane.kt b/src/main/kotlin/io/unthrottled/doki/stickers/StickerPane.kt index 9eff3de2d..6cd7ba02b 100644 --- a/src/main/kotlin/io/unthrottled/doki/stickers/StickerPane.kt +++ b/src/main/kotlin/io/unthrottled/doki/stickers/StickerPane.kt @@ -51,16 +51,17 @@ import javax.swing.MenuElement import javax.swing.SwingUtilities enum class StickerType { - REGULAR, SMOL, ALL + REGULAR, + SMOL, + ALL, } data class Margin( val marginX: Double, - val marginY: Double + val marginY: Double, ) interface StickerListener { - fun onDoubleClick(margin: Margin) } @@ -69,9 +70,8 @@ internal class StickerPane( private val drawablePane: JLayeredPane, val type: StickerType, initialMargin: Margin, - private val stickerListener: StickerListener + private val stickerListener: StickerListener, ) : HwFacadeJPanel(), Disposable, Logging { - private lateinit var stickerContent: JPanel var ignoreScaling = ThemeConfig.instance.ignoreScaling @@ -84,7 +84,7 @@ internal class StickerPane( } positionStickerPanel( this.size.width, - this.size.height + this.size.height, ) } @@ -126,38 +126,40 @@ internal class StickerPane( @Volatile private var parentY = drawablePane.height - private val dragListenerInitiationListener = object : MouseListener { - private val doubleClickAlarm = Alarm(this@StickerPane) - private var clickCount = 0 - override fun mouseClicked(e: MouseEvent?) { - clickCount += 1 - if (clickCount > 1) { - stickerListener.onDoubleClick(captureMargin()) + private val dragListenerInitiationListener = + object : MouseListener { + private val doubleClickAlarm = Alarm(this@StickerPane) + private var clickCount = 0 + + override fun mouseClicked(e: MouseEvent?) { + clickCount += 1 + if (clickCount > 1) { + stickerListener.onDoubleClick(captureMargin()) + } + doubleClickAlarm.cancelAllRequests() + doubleClickAlarm.addRequest( + { + clickCount = 0 + }, + 250, + ) } - doubleClickAlarm.cancelAllRequests() - doubleClickAlarm.addRequest( - { - clickCount = 0 - }, - 250 - ) - } - override fun mousePressed(e: MouseEvent) { - screenX = e.xOnScreen - screenY = e.yOnScreen - myX = x - myY = y - } + override fun mousePressed(e: MouseEvent) { + screenX = e.xOnScreen + screenY = e.yOnScreen + myX = x + myY = y + } - override fun mouseReleased(e: MouseEvent?) { - saveMargin() - } + override fun mouseReleased(e: MouseEvent?) { + saveMargin() + } - override fun mouseEntered(e: MouseEvent?) {} + override fun mouseEntered(e: MouseEvent?) {} - override fun mouseExited(e: MouseEvent?) {} - } + override fun mouseExited(e: MouseEvent?) {} + } private fun saveMargin() { _margin = captureMargin() @@ -168,20 +170,21 @@ internal class StickerPane( val stickerSize = stickerContent.size return Margin( (parentX - (stickerPos.x + stickerSize.width)) / parentX.toDouble(), - (parentY - (stickerPos.y + stickerSize.height)) / parentY.toDouble() + (parentY - (stickerPos.y + stickerSize.height)) / parentY.toDouble(), ) } - private val dragListener = object : MouseMotionListener { - override fun mouseDragged(e: MouseEvent) { - val deltaX = e.xOnScreen - screenX - val deltaY = e.yOnScreen - screenY + private val dragListener = + object : MouseMotionListener { + override fun mouseDragged(e: MouseEvent) { + val deltaX = e.xOnScreen - screenX + val deltaY = e.yOnScreen - screenY - setLocation(myX + deltaX, myY + deltaY) - } + setLocation(myX + deltaX, myY + deltaY) + } - override fun mouseMoved(e: MouseEvent?) {} - } + override fun mouseMoved(e: MouseEvent?) {} + } private val mouseListener: AWTEventListener = createMouseListener() @@ -217,7 +220,7 @@ internal class StickerPane( removeListeners() } }, - this.hideConfig.hideDelayMS + this.hideConfig.hideDelayMS, ) } } else if ( @@ -240,7 +243,7 @@ internal class StickerPane( } runFadeAnimation(runForwards = true) }, - fadeInDelay + fadeInDelay, ) } else if (stickerShowing && !makingStickerReAppear) { hoveredInside = false @@ -250,13 +253,16 @@ internal class StickerPane( } } - private fun isStickerShowing() = alpha == CLEARED_ALPHA || - alpha == VISIBLE_ALPHA + private fun isStickerShowing() = + alpha == CLEARED_ALPHA || + alpha == VISIBLE_ALPHA - private fun isInsideMemePanel(e: MouseEvent): Boolean = - isInsideComponent(e, this) + private fun isInsideMemePanel(e: MouseEvent): Boolean = isInsideComponent(e, this) - private fun isInsideComponent(e: MouseEvent, rootPane1: JComponent): Boolean { + private fun isInsideComponent( + e: MouseEvent, + rootPane1: JComponent, + ): Boolean { val target = RelativePoint(e) val ogComponent = target.originalComponent return when { @@ -285,7 +291,7 @@ internal class StickerPane( Toolkit.getDefaultToolkit().addAWTEventListener( mouseListener, - AWTEvent.MOUSE_MOTION_EVENT_MASK + AWTEvent.MOUSE_MOTION_EVENT_MASK, ) drawablePane.addComponentListener( @@ -301,10 +307,10 @@ internal class StickerPane( positionStickerPanel( stickerContent.width, - stickerContent.height + stickerContent.height, ) } - } + }, ) if (positionable) { @@ -354,7 +360,7 @@ internal class StickerPane( positionStickerPanel( this.size.width, - this.size.height + this.size.height, ) drawablePane.remove(this) @@ -390,48 +396,50 @@ internal class StickerPane( val stickerDimension = getUsableStickerDimension(stickerUrl) val originalImage = ImageIcon(URL(stickerUrl)).image - val lessGarbageImage = originalImage.getScaledInstance( - stickerDimension.width, - stickerDimension.height, - if (stickerUrl.contains(".gif")) Image.SCALE_DEFAULT else Image.SCALE_SMOOTH - ) - val stickerDisplay = object : JBLabel(ImageIcon(lessGarbageImage)) { - - // Java 9+ Does automatic DPI scaling, - // but we want to ignore that, cause the sticker - // will grow to be pixelated - // fixes https://github.com/doki-theme/doki-theme-jetbrains/issues/465 - override fun paintComponent(g: Graphics) { - if (g is Graphics2D) { - val t: AffineTransform = g.transform - currentScaleX = t.scaleX - currentScaleY = t.scaleY - if (g.transform.scaleX.compareTo(1.0) > 0 && ignoreScaling) { - if (!positioned) { - positioned = true - val scaledDimension = getScaledDimension() - this@StickerPane.size = scaledDimension - this@StickerPane.positionStickerPanel( - scaledDimension.width, - scaledDimension.height - ) + val lessGarbageImage = + originalImage.getScaledInstance( + stickerDimension.width, + stickerDimension.height, + if (stickerUrl.contains(".gif")) Image.SCALE_DEFAULT else Image.SCALE_SMOOTH, + ) + val stickerDisplay = + object : JBLabel(ImageIcon(lessGarbageImage)) { + // Java 9+ Does automatic DPI scaling, + // but we want to ignore that, cause the sticker + // will grow to be pixelated + // fixes https://github.com/doki-theme/doki-theme-jetbrains/issues/465 + override fun paintComponent(g: Graphics) { + if (g is Graphics2D) { + val t: AffineTransform = g.transform + currentScaleX = t.scaleX + currentScaleY = t.scaleY + if (g.transform.scaleX.compareTo(1.0) > 0 && ignoreScaling) { + if (!positioned) { + positioned = true + val scaledDimension = getScaledDimension() + this@StickerPane.size = scaledDimension + this@StickerPane.positionStickerPanel( + scaledDimension.width, + scaledDimension.height, + ) + } + val xTrans = t.translateX + val yTrans = t.translateY + t.setToScale(1.0, 1.0) + t.translate(xTrans, yTrans) + g.transform = t } - val xTrans = t.translateX - val yTrans = t.translateY - t.setToScale(1.0, 1.0) - t.translate(xTrans, yTrans) - g.transform = t } + super.paintComponent(g) } - super.paintComponent(g) } - } val stickerSize = stickerDisplay.preferredSize - stickerContent.size = Dimension( - stickerSize.width, - stickerSize.height - ) + stickerContent.size = + Dimension( + stickerSize.width, + stickerSize.height, + ) stickerContent.isOpaque = false stickerContent.add(stickerDisplay) val parentInsets = stickerDisplay.insets @@ -439,7 +447,7 @@ internal class StickerPane( parentInsets.left, parentInsets.top, stickerSize.width, - stickerSize.height + stickerSize.height, ) return stickerContent @@ -454,7 +462,7 @@ internal class StickerPane( } return Dimension( (stickerContentSize.width / currentScaleX).toInt(), - (stickerContentSize.height / currentScaleY).toInt() + (stickerContentSize.height / currentScaleY).toInt(), ) } @@ -466,8 +474,8 @@ internal class StickerPane( originalDimension, Dimension( ThemeConfig.instance.smallMaxStickerWidth, - ThemeConfig.instance.smallMaxStickerHeight - ) + ThemeConfig.instance.smallMaxStickerHeight, + ), ) type == StickerType.REGULAR && @@ -476,8 +484,8 @@ internal class StickerPane( originalDimension, Dimension( ThemeConfig.instance.maxStickerWidth, - ThemeConfig.instance.maxStickerHeight - ) + ThemeConfig.instance.maxStickerHeight, + ), ) else -> originalDimension @@ -499,12 +507,16 @@ internal class StickerPane( } }) { Dimension(1, 1) } - private fun positionStickerPanel(width: Int, height: Int) { - val (x, y) = getPosition( - drawablePane.width, - drawablePane.height, - Rectangle(width, height) - ) + private fun positionStickerPanel( + width: Int, + height: Int, + ) { + val (x, y) = + getPosition( + drawablePane.width, + drawablePane.height, + Rectangle(width, height), + ) myX = x myY = y setLocation(x, y) @@ -515,7 +527,7 @@ internal class StickerPane( private fun getPosition( parentWidth: Int, parentHeight: Int, - stickerPanelBoundingBox: Rectangle + stickerPanelBoundingBox: Rectangle, ): Pair = parentWidth - stickerPanelBoundingBox.width - (parentWidth * _margin.marginX).toInt() to parentHeight - stickerPanelBoundingBox.height - (parentHeight * _margin.marginY).toInt() @@ -532,40 +544,49 @@ internal class StickerPane( _margin = margin positionStickerPanel( size.width, - size.height + size.height, ) } private var alpha = CLEARED_ALPHA private var overlay: BufferedImage? = null + private fun clear() { alpha = CLEARED_ALPHA overlay = null } - private fun makeColorTransparent(image: Image, color: Color): Image { + private fun makeColorTransparent( + image: Image, + color: Color, + ): Image { val markerRGB = color.rgb or -0x1000000 return ImageUtil.filter( image, object : RGBImageFilter() { - override fun filterRGB(x: Int, y: Int, rgb: Int): Int = + override fun filterRGB( + x: Int, + y: Int, + rgb: Int, + ): Int = if (rgb or -0x1000000 == markerRGB) { WHITE_HEX and rgb // set alpha to 0 } else { rgb } - } + }, ) } private fun fancyPaintChildren(imageGraphics2d: Graphics2D) { // Paint to an image without alpha to preserve fonts subpixel antialiasing - val image: BufferedImage = ImageUtil.createImage( - imageGraphics2d, - width, - height, - BufferedImage.TYPE_INT_RGB - ) + val image: BufferedImage = + ImageUtil.createImage( + imageGraphics2d, + width, + height, + BufferedImage.TYPE_INT_RGB, + ) val fillColor = MessageType.INFO.popupBackground UIUtil.useSafely(image.createGraphics()) { imageGraphics: Graphics2D -> @@ -618,30 +639,36 @@ internal class StickerPane( */ private fun runFadeAnimation(runForwards: Boolean = true) { val self = this - val animator = object : Animator( - "Sticker Fadeout", - TOTAL_FRAMES, - CYCLE_DURATION, - false, - runForwards - ) { - override fun paintNow(frame: Int, totalFrames: Int, cycle: Int) { - alpha = frame.toFloat() / totalFrames - paintImmediately(0, 0, width, height) - } - - override fun paintCycleEnd() { - if (isForward) { - clear() - self.repaint() + val animator = + object : Animator( + "Sticker Fadeout", + TOTAL_FRAMES, + CYCLE_DURATION, + false, + runForwards, + ) { + override fun paintNow( + frame: Int, + totalFrames: Int, + cycle: Int, + ) { + alpha = frame.toFloat() / totalFrames + paintImmediately(0, 0, width, height) } - Disposer.dispose(this) + override fun paintCycleEnd() { + if (isForward) { + clear() + self.repaint() + } + + Disposer.dispose(this) + } } - } animator.resume() } + companion object { private const val fadeInDelay = 500 private const val TOTAL_FRAMES = 8 diff --git a/src/main/kotlin/io/unthrottled/doki/stickers/StickerPaneService.kt b/src/main/kotlin/io/unthrottled/doki/stickers/StickerPaneService.kt index d28e8e035..790641c04 100644 --- a/src/main/kotlin/io/unthrottled/doki/stickers/StickerPaneService.kt +++ b/src/main/kotlin/io/unthrottled/doki/stickers/StickerPaneService.kt @@ -21,12 +21,11 @@ import javax.swing.JFrame data class StickerHideConfig( val hideOnHover: Boolean, - val hideDelayMS: Int + val hideDelayMS: Int, ) @Suppress("TooManyFunctions") class StickerPaneService { - companion object { val instance: StickerPaneService get() = ApplicationManager.getApplication().getService(StickerPaneService::class.java) @@ -53,7 +52,7 @@ class StickerPaneService { } } }, - AWTEvent.WINDOW_EVENT_MASK + AWTEvent.WINDOW_EVENT_MASK, ) } @@ -78,15 +77,16 @@ class StickerPaneService { val primaryStickersOn = ThemeConfig.instance.currentStickerLevel == StickerLevel.ON val smolStickersOn = ThemeConfig.instance.showSmallStickers if (primaryStickersOn || smolStickersOn) { - val candidateStickers = stickers.filter { - (it.type == StickerType.SMOL && smolStickersOn) || - (it.type == StickerType.REGULAR && primaryStickersOn) - } + val candidateStickers = + stickers.filter { + (it.type == StickerType.SMOL && smolStickersOn) || + (it.type == StickerType.REGULAR && primaryStickersOn) + } displayStickers( dokiTheme, { stickerUrl -> candidateStickers.forEach { it.displaySticker(stickerUrl) } - } + }, ) { stickers.forEach { it.detach() } } @@ -109,26 +109,28 @@ class StickerPaneService { } } - private val allowedFrames = setOf( - "com.intellij.openapi.ui.FrameWrapper\$MyJFrame", - "com.intellij.openapi.wm.impl.IdeFrameImpl", - "com.intellij.openapi.ui.MyJFrame", - "com.intellij.openapi.wm.impl.welcomeScreen.FlatWelcomeFrame" - ) + private val allowedFrames = + setOf( + "com.intellij.openapi.ui.FrameWrapper\$MyJFrame", + "com.intellij.openapi.wm.impl.IdeFrameImpl", + "com.intellij.openapi.ui.MyJFrame", + "com.intellij.openapi.wm.impl.welcomeScreen.FlatWelcomeFrame", + ) private fun captureFrame(window: JFrame) { if (!isRightClass(window)) return val drawablePane = window.rootPane.layeredPane - val stickerPane = StickerPane( - drawablePane, - StickerType.REGULAR, - MarginService.instance.getMargin(window), - object : StickerListener { - override fun onDoubleClick(margin: Margin) { - MarginService.instance.saveMargin(window, margin) - } - } - ) + val stickerPane = + StickerPane( + drawablePane, + StickerType.REGULAR, + MarginService.instance.getMargin(window), + object : StickerListener { + override fun onDoubleClick(margin: Margin) { + MarginService.instance.saveMargin(window, margin) + } + }, + ) windowsToAddStickersTo[window] = stickerPane if (ThemeConfig.instance.currentStickerLevel == StickerLevel.ON) { showSingleSticker(stickerPane) @@ -137,16 +139,17 @@ class StickerPaneService { private fun captureDialogWrapper(wrapper: DialogWrapperDialog) { val drawablePane = wrapper.dialogWrapper?.rootPane?.layeredPane ?: return - val stickerPane = StickerPane( - drawablePane, - StickerType.SMOL, - MarginService.instance.getMargin(wrapper), - object : StickerListener { - override fun onDoubleClick(margin: Margin) { - MarginService.instance.saveMargin(wrapper, margin) - } - } - ) + val stickerPane = + StickerPane( + drawablePane, + StickerType.SMOL, + MarginService.instance.getMargin(wrapper), + object : StickerListener { + override fun onDoubleClick(margin: Margin) { + MarginService.instance.saveMargin(wrapper, margin) + } + }, + ) windowsToAddStickersTo[wrapper] = stickerPane if (ThemeConfig.instance.showSmallStickers) { showSingleSticker(stickerPane) @@ -167,7 +170,7 @@ class StickerPaneService { dokiTheme, { stickerUrl -> stickerPane.displaySticker(stickerUrl) - } + }, ) { stickerPane.detach() } @@ -176,13 +179,12 @@ class StickerPaneService { } } - private fun isRightClass(window: Any): Boolean = - allowedFrames.contains(window.javaClass.name) + private fun isRightClass(window: Any): Boolean = allowedFrames.contains(window.javaClass.name) private fun displayStickers( currentTheme: DokiTheme, stickerWorkerSupplier: (String) -> Unit, - stickerRemoval: () -> Unit + stickerRemoval: () -> Unit, ) { ApplicationManager.getApplication().executeOnPooledThread { if (CustomStickerService.isCustomStickers) { @@ -215,14 +217,12 @@ class StickerPaneService { } } - private fun getLocallyInstalledStickerPath( - dokiTheme: DokiTheme - ): Optional = + private fun getLocallyInstalledStickerPath(dokiTheme: DokiTheme): Optional = dokiTheme.getStickerPath() .flatMap { AssetManager.resolveAssetUrl( AssetCategory.STICKERS, - it + it, ) } @@ -233,8 +233,9 @@ class StickerPaneService { } } -fun repaintWindows() = runSafely({ - ApplicationManager.getApplication().invokeLater { - IdeBackgroundUtil.repaintAllWindows() - } -}) +fun repaintWindows() = + runSafely({ + ApplicationManager.getApplication().invokeLater { + IdeBackgroundUtil.repaintAllWindows() + } + }) diff --git a/src/main/kotlin/io/unthrottled/doki/themes/DokiTheme.kt b/src/main/kotlin/io/unthrottled/doki/themes/DokiTheme.kt index ce7b16ae7..22af1524a 100644 --- a/src/main/kotlin/io/unthrottled/doki/themes/DokiTheme.kt +++ b/src/main/kotlin/io/unthrottled/doki/themes/DokiTheme.kt @@ -18,18 +18,18 @@ import java.util.Optional class Stickers( val default: String, - val secondary: String? + val secondary: String?, ) class Background( val name: String, val position: IdeBackgroundUtil.Anchor, - val opacity: Int? + val opacity: Int?, ) class Backgrounds( val default: Background, - val secondary: Background? + val secondary: Background?, ) @Suppress("LongParameterList") @@ -43,14 +43,13 @@ class JetBrainsThemeDefinition( val group: String, val colors: Map, val ui: Map, - val meta: Map + val meta: Map, ) class DokiTheme( private val uiTheme: JetBrainsThemeDefinition, - val version: String + val version: String, ) { - init { validateThemeDefinition() } @@ -73,11 +72,12 @@ class DokiTheme( get() = uiTheme.name val displayName: String - get() = uiTheme.displayName ?: error( - """ + get() = + uiTheme.displayName ?: error( + """ |$name's theme.json requires "displayName" to be defined - """.trimMargin() - ) + """.trimMargin(), + ) fun getStickerPath(): Optional = when (ThemeConfig.instance.currentSticker) { @@ -114,9 +114,10 @@ class DokiTheme( val editorAccentColor: Color get() = getColor("editorAccentColor") - fun getColor(s: String) = ( - (uiTheme.colors[s] as? String)?.toColor() - ?: error("Expected 'colors.$s' to be present in theme $name json.") + fun getColor(s: String) = + ( + (uiTheme.colors[s] as? String)?.toColor() + ?: error("Expected 'colors.$s' to be present in theme $name json.") ) companion object { @@ -127,21 +128,22 @@ class DokiTheme( init { val gson = Gson() - requiredNamedColors = runSafelyWithResult({ - this::class.java.classLoader - .getResourceAsStream("theme-schema/DokiTheme.themeMetadata.json") - .use { - gson.fromJson( - InputStreamReader(it!!, StandardCharsets.UTF_8), - UIThemeMetadata::class.java - ) - }.uiKeyMetadata.map { - it.key - }.toMutableList().plus(ACCENT_COLOR) - }) { - log.warn("Unable to get required named colors for raisins", it) - listOf() - } + requiredNamedColors = + runSafelyWithResult({ + this::class.java.classLoader + .getResourceAsStream("theme-schema/DokiTheme.themeMetadata.json") + .use { + gson.fromJson( + InputStreamReader(it!!, StandardCharsets.UTF_8), + UIThemeMetadata::class.java, + ) + }.uiKeyMetadata.map { + it.key + }.toMutableList().plus(ACCENT_COLOR) + }) { + log.warn("Unable to get required named colors for raisins", it) + listOf() + } } } @@ -163,7 +165,7 @@ class DokiTheme( """ Expected "$requiredColor" to be present in "colors" as a valid hex color in $name's theme json. "$requiredNamedColor" is not a valid hex color or reference to a defined color - """.trimIndent() + """.trimIndent(), ) } } diff --git a/src/main/kotlin/io/unthrottled/doki/themes/impl/ThemeManagerImpl.kt b/src/main/kotlin/io/unthrottled/doki/themes/impl/ThemeManagerImpl.kt index 899f20870..44cdd600a 100644 --- a/src/main/kotlin/io/unthrottled/doki/themes/impl/ThemeManagerImpl.kt +++ b/src/main/kotlin/io/unthrottled/doki/themes/impl/ThemeManagerImpl.kt @@ -19,47 +19,49 @@ import java.util.Optional import java.util.stream.Collectors class ThemeManagerImpl : ThemeManager { - private val themeMap: Map init { val gson = Gson() - val themeURI = javaClass.classLoader - .getResource("doki/themes") - ?.toURI() - .toString() - .split("!") + val themeURI = + javaClass.classLoader + .getResource("doki/themes") + ?.toURI() + .toString() + .split("!") val currentVersion = TheDokiTheme.getVersion().orElse("69") val fileSystem = newFileSystem(create(themeURI[0]), mapOf()) - themeMap = walk( - fileSystem.getPath( - themeURI[1] + themeMap = + walk( + fileSystem.getPath( + themeURI[1], + ), ) - ) - .filter { it.fileName.toString().endsWith(".theme.meta.json") } - .map { it.inputStream() } - .map { - gson.fromJson( - InputStreamReader(it, StandardCharsets.UTF_8), - JetBrainsThemeDefinition::class.java - ) - } - .map { DokiTheme(it, currentVersion) } - .collect( - Collectors.toMap( - { it.name }, - { it }, - { a, _ -> a } + .filter { it.fileName.toString().endsWith(".theme.meta.json") } + .map { it.inputStream() } + .map { + gson.fromJson( + InputStreamReader(it, StandardCharsets.UTF_8), + JetBrainsThemeDefinition::class.java, + ) + } + .map { DokiTheme(it, currentVersion) } + .collect( + Collectors.toMap( + { it.name }, + { it }, + { a, _ -> a }, + ), ) - ) } override val isCurrentThemeDoki: Boolean get() = currentTheme.isPresent override val currentTheme: Optional - get() = LafManager.getInstance()?.currentUIThemeLookAndFeel.toOptional() - .flatMap { processLaf(it) } + get() = + LafManager.getInstance()?.currentUIThemeLookAndFeel.toOptional() + .flatMap { processLaf(it) } override val allThemes: List get() = themeMap.values.toList() @@ -74,8 +76,7 @@ class ThemeManagerImpl : ThemeManager { .map { themeMap[it.name] } } - override fun themeByName(selectedTheme: String): Optional = - themeMap[selectedTheme].toOptional() + override fun themeByName(selectedTheme: String): Optional = themeMap[selectedTheme].toOptional() override fun dispose() { } diff --git a/src/main/kotlin/io/unthrottled/doki/ui/ToggleButtonUI.kt b/src/main/kotlin/io/unthrottled/doki/ui/ToggleButtonUI.kt index b65cb8031..aaffdcdf2 100644 --- a/src/main/kotlin/io/unthrottled/doki/ui/ToggleButtonUI.kt +++ b/src/main/kotlin/io/unthrottled/doki/ui/ToggleButtonUI.kt @@ -58,16 +58,20 @@ class ToggleButtonUI : BasicToggleButtonUI() { override fun getMinimumSize(c: JComponent): Dimension = getPreferredSize(c) - override fun paint(g: Graphics, button: JComponent) { + override fun paint( + g: Graphics, + button: JComponent, + ) { if (button !is OnOffButton) return val g2 = g.create() as Graphics2D val config = GraphicsUtil.setupAAPainting(g2) try { val insets = button.getInsets() - val origin = Point( - (button.getWidth() - BUTTON_SIZE.width) / 2 + insets.left, - (button.getHeight() - BUTTON_SIZE.height) / 2 + insets.top - ) + val origin = + Point( + (button.getWidth() - BUTTON_SIZE.width) / 2 + insets.left, + (button.getHeight() - BUTTON_SIZE.height) / 2 + insets.top, + ) g2.color = if (button.isSelected) { @@ -85,10 +89,11 @@ class ToggleButtonUI : BasicToggleButtonUI() { g2.color = BUTTON_COLOR val halfWay = BUTTON_SIZE.width / 2 - val location = Point( - (if (button.isSelected) JBUI.scale(halfWay) else JBUI.scale(0)) + origin.x, - origin.y - ) + val location = + Point( + (if (button.isSelected) JBUI.scale(halfWay) else JBUI.scale(0)) + origin.x, + origin.y, + ) g2.fillRoundRect(location.x, location.y, halfWay, BUTTON_SIZE.height, ARC, ARC) config.restore() } finally { @@ -97,20 +102,22 @@ class ToggleButtonUI : BasicToggleButtonUI() { } companion object { - val BUTTON_COLOR: Color = JBColor.namedColor( - "ToggleButton.buttonColor", - JBColor( - Gray._200, - Gray._100 + val BUTTON_COLOR: Color = + JBColor.namedColor( + "ToggleButton.buttonColor", + JBColor( + Gray._200, + Gray._100, + ), ) - ) - val ON_BACKGROUND: Color = JBColor.namedColor( - "ToggleButton.onBackground", - JBColor( - Color(74, 146, 73), - Color(77, 105, 76) + val ON_BACKGROUND: Color = + JBColor.namedColor( + "ToggleButton.onBackground", + JBColor( + Color(74, 146, 73), + Color(77, 105, 76), + ), ) - ) private val BUTTON_SIZE: Dimension = JBDimension(42, 14) private val BUTTON_BORDER: Border = JBUI.Borders.empty(1, 10) diff --git a/src/main/kotlin/io/unthrottled/doki/ui/status/ThemeStatusBarProvider.kt b/src/main/kotlin/io/unthrottled/doki/ui/status/ThemeStatusBarProvider.kt index 0e0a005bf..699a09613 100644 --- a/src/main/kotlin/io/unthrottled/doki/ui/status/ThemeStatusBarProvider.kt +++ b/src/main/kotlin/io/unthrottled/doki/ui/status/ThemeStatusBarProvider.kt @@ -9,25 +9,19 @@ import io.unthrottled.doki.config.ThemeConfig @Suppress("UnstableApiUsage") class ThemeStatusBarProvider : StatusBarWidgetFactory, LightEditCompatible { + override fun getId(): String = "io.unthrottled.doki.ui.status.StatusBarFactory" - override fun getId(): String = - "io.unthrottled.doki.ui.status.StatusBarFactory" - - override fun getDisplayName(): String = - "Doki Theme Display" + override fun getDisplayName(): String = "Doki Theme Display" override fun disposeWidget(widget: StatusBarWidget) { widget.dispose() } - override fun isAvailable(project: Project): Boolean = - true + override fun isAvailable(project: Project): Boolean = true - override fun createWidget(project: Project): StatusBarWidget = - ThemeStatusBarWidget(project) + override fun createWidget(project: Project): StatusBarWidget = ThemeStatusBarWidget(project) - override fun canBeEnabledOn(statusBar: StatusBar): Boolean = - true + override fun canBeEnabledOn(statusBar: StatusBar): Boolean = true override fun isConfigurable(): Boolean = true diff --git a/src/main/kotlin/io/unthrottled/doki/ui/status/ThemeStatusBarWidget.kt b/src/main/kotlin/io/unthrottled/doki/ui/status/ThemeStatusBarWidget.kt index f470c492f..847b559da 100644 --- a/src/main/kotlin/io/unthrottled/doki/ui/status/ThemeStatusBarWidget.kt +++ b/src/main/kotlin/io/unthrottled/doki/ui/status/ThemeStatusBarWidget.kt @@ -33,7 +33,7 @@ class ThemeStatusBarWidget(private val project: Project) : LafManagerListener.TOPIC, LafManagerListener { updateWidget() - } + }, ) connect.subscribe( THEME_CONFIG_TOPIC, @@ -41,7 +41,7 @@ class ThemeStatusBarWidget(private val project: Project) : override fun themeConfigUpdated(themeConfig: ThemeConfig) { updateWidget() } - } + }, ) } @@ -77,15 +77,16 @@ class ThemeStatusBarWidget(private val project: Project) : .map { AllIcons.Nodes.Favorite } .orElseGet { null } - override fun getClickConsumer(): Consumer = Consumer { - ApplicationManager.getApplication().invokeLater( - { - ShowSettingsUtil.getInstance().showSettingsDialog( - project, - THEME_SETTINGS_DISPLAY_NAME - ) - }, - ModalityState.NON_MODAL - ) - } + override fun getClickConsumer(): Consumer = + Consumer { + ApplicationManager.getApplication().invokeLater( + { + ShowSettingsUtil.getInstance().showSettingsDialog( + project, + THEME_SETTINGS_DISPLAY_NAME, + ) + }, + ModalityState.NON_MODAL, + ) + } } diff --git a/src/main/kotlin/io/unthrottled/doki/util/AssetTools.kt b/src/main/kotlin/io/unthrottled/doki/util/AssetTools.kt index 0c1da573b..50d1bce6b 100644 --- a/src/main/kotlin/io/unthrottled/doki/util/AssetTools.kt +++ b/src/main/kotlin/io/unthrottled/doki/util/AssetTools.kt @@ -14,17 +14,17 @@ object AssetTools : Logging { fun readJsonFromResources( basePath: String, filePath: String, - type: Type + type: Type, ): Optional { return runSafelyWithResult({ ResourceUtil.getResourceAsStream( AssetTools::class.java.classLoader, basePath, - filePath + filePath, ).use { inputStream -> gson.fromJson( InputStreamReader(inputStream, StandardCharsets.UTF_8), - type + type, ).toOptional() } }) { diff --git a/src/main/kotlin/io/unthrottled/doki/util/BalloonTools.kt b/src/main/kotlin/io/unthrottled/doki/util/BalloonTools.kt index 05e0d3629..87bcf4e0b 100644 --- a/src/main/kotlin/io/unthrottled/doki/util/BalloonTools.kt +++ b/src/main/kotlin/io/unthrottled/doki/util/BalloonTools.kt @@ -14,8 +14,10 @@ import com.intellij.ui.awt.RelativePoint import java.awt.Point enum class BalloonPosition { - LEFT, RIGHT, + LEFT, + RIGHT, } + object BalloonTools { private const val NOTIFICATION_Y_OFFSET = 20 private const val NOTIFICATION_X_OFFSET = 10 @@ -24,23 +26,26 @@ object BalloonTools { project: Project, notificationToShow: Notification, balloonPosition: BalloonPosition, - onClosed: () -> Unit + onClosed: () -> Unit, ) { try { val (ideFrame, notificationPosition) = fetchBalloonParameters(project, balloonPosition) - val balloon = NotificationsManagerImpl.createBalloon( - ideFrame, - notificationToShow, - true, - false, - BalloonLayoutData.fullContent(), - Disposer.newDisposable() + val balloon = + NotificationsManagerImpl.createBalloon( + ideFrame, + notificationToShow, + true, + false, + BalloonLayoutData.fullContent(), + Disposer.newDisposable(), + ) + balloon.addListener( + object : JBPopupListener { + override fun onClosed(event: LightweightWindowEvent) { + onClosed() + } + }, ) - balloon.addListener(object : JBPopupListener { - override fun onClosed(event: LightweightWindowEvent) { - onClosed() - } - }) balloon.show(notificationPosition, Balloon.Position.below) } catch (e: Throwable) { notificationToShow.notify(project) @@ -49,19 +54,21 @@ object BalloonTools { private fun fetchBalloonParameters( project: Project, - balloonPosition: BalloonPosition + balloonPosition: BalloonPosition, ): Pair { val ideFrame = getIDEFrame(project) val frameBounds = ideFrame.component.bounds - val xPosition = when (balloonPosition) { - BalloonPosition.RIGHT -> frameBounds.x + frameBounds.width - BalloonPosition.LEFT -> frameBounds.x + NOTIFICATION_X_OFFSET - } + val xPosition = + when (balloonPosition) { + BalloonPosition.RIGHT -> frameBounds.x + frameBounds.width + BalloonPosition.LEFT -> frameBounds.x + NOTIFICATION_X_OFFSET + } - val notificationPosition = RelativePoint( - ideFrame.component, - Point(xPosition, NOTIFICATION_Y_OFFSET) - ) + val notificationPosition = + RelativePoint( + ideFrame.component, + Point(xPosition, NOTIFICATION_Y_OFFSET), + ) return Pair(ideFrame, notificationPosition) } @@ -69,5 +76,5 @@ object BalloonTools { ( WindowManager.getInstance().getIdeFrame(project) ?: WindowManager.getInstance().allProjectFrames.first() - ) + ) } diff --git a/src/main/kotlin/io/unthrottled/doki/util/Debouncer.kt b/src/main/kotlin/io/unthrottled/doki/util/Debouncer.kt index 29adb72bb..74fd5b4e5 100644 --- a/src/main/kotlin/io/unthrottled/doki/util/Debouncer.kt +++ b/src/main/kotlin/io/unthrottled/doki/util/Debouncer.kt @@ -9,15 +9,18 @@ fun interface Debouncer { } fun interface BufferedDebouncer { - fun debounceAndBuffer(t: T, onDebounced: (List) -> Unit) + fun debounceAndBuffer( + t: T, + onDebounced: (List) -> Unit, + ) } class AlarmDebouncer( - private val interval: Int + private val interval: Int, ) : Debouncer, - BufferedDebouncer, - Disposable { + BufferedDebouncer, + Disposable { private val alarm: Alarm = Alarm() override fun debounce(toDebounce: () -> Unit) { @@ -28,7 +31,10 @@ class AlarmDebouncer( private val buffer = LinkedList() - override fun debounceAndBuffer(t: T, onDebounced: (List) -> Unit) { + override fun debounceAndBuffer( + t: T, + onDebounced: (List) -> Unit, + ) { performDebounce({ alarm.addRequest( { @@ -37,7 +43,7 @@ class AlarmDebouncer( buffer.clear() previousOnDebounce = null }, - interval + interval, ) }) { buffer.push(t) @@ -47,7 +53,10 @@ class AlarmDebouncer( @Volatile private var previousOnDebounce: (() -> Unit)? = null - private fun performDebounce(setupDebounce: () -> Unit, onDebounced: () -> Unit = {}) { + private fun performDebounce( + setupDebounce: () -> Unit, + onDebounced: () -> Unit = {}, + ) { previousOnDebounce?.invoke() previousOnDebounce = onDebounced alarm.cancelAllRequests() diff --git a/src/main/kotlin/io/unthrottled/doki/util/LAFAnimator.kt b/src/main/kotlin/io/unthrottled/doki/util/LAFAnimator.kt index 4df255ae3..3b3f061c5 100644 --- a/src/main/kotlin/io/unthrottled/doki/util/LAFAnimator.kt +++ b/src/main/kotlin/io/unthrottled/doki/util/LAFAnimator.kt @@ -33,75 +33,82 @@ class LAFAnimator { val window = rootPaneContainer as Window val bounds = window.bounds val layeredPane = rootPaneContainer.layeredPane - val image: BufferedImage = ImageUtil.createImage( - window.graphicsConfiguration, - bounds.width, - bounds.height, - BufferedImage.TYPE_INT_ARGB - ) + val image: BufferedImage = + ImageUtil.createImage( + window.graphicsConfiguration, + bounds.width, + bounds.height, + BufferedImage.TYPE_INT_ARGB, + ) val imageGraphics = image.graphics GraphicsUtil.setupAntialiasing(imageGraphics) rootPaneContainer.rootPane.paint(imageGraphics) - val imageLayer = object : JComponent() { - override fun updateUI() {} + val imageLayer = + object : JComponent() { + override fun updateUI() {} - override fun paint(g: Graphics) { - val newG = g.create() as Graphics2D - newG.composite = AlphaComposite.getInstance(AlphaComposite.SRC_OVER, myAlpha) - UIUtil.drawImage( - newG, - image, - 0, - 0, - this - ) - } + override fun paint(g: Graphics) { + val newG = g.create() as Graphics2D + newG.composite = AlphaComposite.getInstance(AlphaComposite.SRC_OVER, myAlpha) + UIUtil.drawImage( + newG, + image, + 0, + 0, + this, + ) + } - override fun getBounds(): Rectangle = layeredPane.bounds - } + override fun getBounds(): Rectangle = layeredPane.bounds + } imageLayer.size = layeredPane.size layeredPane.add(imageLayer, JLayeredPane.DRAG_LAYER) myMap[layeredPane] = imageLayer } - myAnimator = object : Animator( - "ChangeLAF", - 60, - 800, - false - ) { - override fun paintNow(frame: Int, totalFrames: Int, cycle: Int) { - myAlpha = - 1 - (1 - Math.cos(Math.PI * frame / totalFrames.toFloat())).toFloat() / 2 - doPaint() - } + myAnimator = + object : Animator( + "ChangeLAF", + 60, + 800, + false, + ) { + override fun paintNow( + frame: Int, + totalFrames: Int, + cycle: Int, + ) { + myAlpha = + 1 - (1 - Math.cos(Math.PI * frame / totalFrames.toFloat())).toFloat() / 2 + doPaint() + } - override fun resume() { - doPaint() - super.resume() - } + override fun resume() { + doPaint() + super.resume() + } - override fun dispose() { - try { - super.dispose() - for ((layeredPane, value) in myMap) { - layeredPane.remove(value) - layeredPane.revalidate() - layeredPane.repaint() + override fun dispose() { + try { + super.dispose() + for ((layeredPane, value) in myMap) { + layeredPane.remove(value) + layeredPane.revalidate() + layeredPane.repaint() + } + } finally { + myMap.clear() } - } finally { - myMap.clear() } - } - override fun paintCycleEnd() { - if (!isDisposed) { - Disposer.dispose(this) + override fun paintCycleEnd() { + if (!isDisposed) { + Disposer.dispose(this) + } + super.paintCycleEnd() } - super.paintCycleEnd() } - } } fun hideSnapshotWithAnimation() { @@ -118,7 +125,10 @@ class LAFAnimator { } } -fun performWithAnimation(animate: Boolean, actionToPerform: () -> Unit) { +fun performWithAnimation( + animate: Boolean, + actionToPerform: () -> Unit, +) { val animator = if (animate) LAFAnimator.showSnapshot() else null actionToPerform() animator?.hideSnapshotWithAnimation() diff --git a/src/main/kotlin/io/unthrottled/doki/util/ToolBox.kt b/src/main/kotlin/io/unthrottled/doki/util/ToolBox.kt index 479e94e5e..8920333d7 100644 --- a/src/main/kotlin/io/unthrottled/doki/util/ToolBox.kt +++ b/src/main/kotlin/io/unthrottled/doki/util/ToolBox.kt @@ -8,45 +8,53 @@ import java.util.Optional import java.util.concurrent.Callable import java.util.stream.Stream -fun getSafely(callable: Callable): Optional = +fun getSafely(callable: Callable): Optional = try { callable.call().toOptional() } catch (e: Throwable) { Optional.empty() } -fun runSafely(runner: () -> Unit, onError: (Throwable) -> Unit = {}): Unit = +fun runSafely( + runner: () -> Unit, + onError: (Throwable) -> Unit = {}, +): Unit = try { runner() } catch (e: Throwable) { onError(e) } -fun runSafelyWithResult(runner: () -> T, onError: (Throwable) -> T): T = +fun runSafelyWithResult( + runner: () -> T, + onError: (Throwable) -> T, +): T = try { runner() } catch (e: Throwable) { onError(e) } -fun T?.toOptional() = Optional.ofNullable(this) +fun T?.toOptional() = Optional.ofNullable(this) fun T?.toStream(): Stream = Stream.of(this) -fun Optional.doOrElse(present: (T) -> Unit, notThere: () -> Unit) = - this.map { - it to true - }.map { - it.toOptional() - }.orElseGet { - (null to false).toOptional() - }.ifPresent { - if (it.second) { - present(it.first) - } else { - notThere() - } +fun Optional.doOrElse( + present: (T) -> Unit, + notThere: () -> Unit, +) = this.map { + it to true +}.map { + it.toOptional() +}.orElseGet { + (null to false).toOptional() +}.ifPresent { + if (it.second) { + present(it.first) + } else { + notThere() } +} interface Runner { fun run() diff --git a/src/main/kotlin/io/unthrottled/doki/util/WhenComparator.kt b/src/main/kotlin/io/unthrottled/doki/util/WhenComparator.kt index 4cbd31b73..44b424fb3 100644 --- a/src/main/kotlin/io/unthrottled/doki/util/WhenComparator.kt +++ b/src/main/kotlin/io/unthrottled/doki/util/WhenComparator.kt @@ -2,13 +2,16 @@ package io.unthrottled.doki.util interface WhenComparator { fun test(other: T): Boolean + operator fun contains(other: T) = test(other) } -fun > lt(value: T) = object : WhenComparator { - override fun test(other: T) = other < value -} +fun > lt(value: T) = + object : WhenComparator { + override fun test(other: T) = other < value + } -fun > gt(value: T) = object : WhenComparator { - override fun test(other: T) = other > value -} +fun > gt(value: T) = + object : WhenComparator { + override fun test(other: T) = other > value + } diff --git a/src/test/kotlin/io/unthrottled/doki/config/ThemeConfigTest.kt b/src/test/kotlin/io/unthrottled/doki/config/ThemeConfigTest.kt index 5bd8911fa..7626aefd8 100644 --- a/src/test/kotlin/io/unthrottled/doki/config/ThemeConfigTest.kt +++ b/src/test/kotlin/io/unthrottled/doki/config/ThemeConfigTest.kt @@ -6,7 +6,6 @@ import org.assertj.core.api.Assertions.assertThat import org.junit.Test class ThemeConfigTest { - @Test fun getCurrentStickerShouldCorrectBadSettings() { val themeConfig = ThemeConfig() @@ -21,7 +20,7 @@ class ThemeConfigTest { Triple("off", StickerLevel.OFF, "off"), Triple("oFF", StickerLevel.OFF, "oFF"), Triple("OFF", StickerLevel.OFF, "OFF"), - Triple("Off", StickerLevel.OFF, "Off") + Triple("Off", StickerLevel.OFF, "Off"), ).forEach { themeConfig.stickerLevel = it.first assertThat(themeConfig.currentStickerLevel).isEqualTo(it.second) @@ -40,7 +39,7 @@ class ThemeConfigTest { Triple("Default", CurrentSticker.DEFAULT, "Default"), Triple("Secondary", CurrentSticker.SECONDARY, "Secondary"), Triple("secondary", CurrentSticker.SECONDARY, "secondary"), - Triple("SECONDARY", CurrentSticker.SECONDARY, "SECONDARY") + Triple("SECONDARY", CurrentSticker.SECONDARY, "SECONDARY"), ).forEach { themeConfig.currentStickerName = it.first assertThat(themeConfig.currentSticker).isEqualTo(it.second) diff --git a/src/test/kotlin/io/unthrottled/doki/promotions/PromotionManagerIntegrationTest.kt b/src/test/kotlin/io/unthrottled/doki/promotions/PromotionManagerIntegrationTest.kt index cdf5ec619..0d0a31674 100644 --- a/src/test/kotlin/io/unthrottled/doki/promotions/PromotionManagerIntegrationTest.kt +++ b/src/test/kotlin/io/unthrottled/doki/promotions/PromotionManagerIntegrationTest.kt @@ -33,9 +33,8 @@ import java.util.UUID import java.util.concurrent.TimeUnit class PromotionManagerIntegrationTest { - companion object { - private const val testDirectory = "testOne" + private const val TEST_DIRECTORY = "testOne" @JvmStatic @BeforeClass @@ -65,7 +64,7 @@ class PromotionManagerIntegrationTest { @Before fun cleanUp() { clearMocks(AniMemePromotionService) - Files.walk(TestTools.getTestAssetPath(testDirectory)) + Files.walk(TestTools.getTestAssetPath(TEST_DIRECTORY)) .filter { it.isFile() } .forEach { Files.deleteIfExists(it) } } @@ -73,7 +72,7 @@ class PromotionManagerIntegrationTest { @Test fun `should write new version`() { every { LocalStorageService.getGlobalAssetDirectory() } returns - TestTools.getTestAssetPath(testDirectory).toString().toOptional() + TestTools.getTestAssetPath(TEST_DIRECTORY).toString().toOptional() every { PluginService.isMotivatorInstalled() } returns false every { WeebService.isWeebStuffOn() } returns true every { ThemeConfig.instance.allowPromotions } returns true @@ -96,7 +95,7 @@ class PromotionManagerIntegrationTest { assertThat(postLedger.versionInstallDates.size).isEqualTo(1) assertThat(postLedger.versionInstallDates["Ryuko"]).isBetween( beforePromotion, - Instant.now() + Instant.now(), ) verify { AniMemePromotionService wasNot Called } @@ -105,7 +104,7 @@ class PromotionManagerIntegrationTest { @Test fun `should always write new version`() { every { LocalStorageService.getGlobalAssetDirectory() } returns - TestTools.getTestAssetPath(testDirectory).toString().toOptional() + TestTools.getTestAssetPath(TEST_DIRECTORY).toString().toOptional() every { PluginService.isMotivatorInstalled() } returns false every { WeebService.isWeebStuffOn() } returns true every { ThemeConfig.instance.allowPromotions } returns true @@ -128,7 +127,7 @@ class PromotionManagerIntegrationTest { assertThat(postRyukoLedger.versionInstallDates.size).isEqualTo(1) assertThat(postRyukoLedger.versionInstallDates["Ryuko"]).isBetween( beforeRyuko, - Instant.now() + Instant.now(), ) val beforeRin = Instant.now() @@ -143,11 +142,11 @@ class PromotionManagerIntegrationTest { assertThat(postRinLedger.versionInstallDates.size).isEqualTo(2) assertThat(postRyukoLedger.versionInstallDates["Ryuko"]).isBetween( beforeRyuko, - Instant.now() + Instant.now(), ) assertThat(postRinLedger.versionInstallDates["Rin"]).isBetween( beforeRin, - Instant.now() + Instant.now(), ) verify { AniMemePromotionService wasNot Called } @@ -156,7 +155,7 @@ class PromotionManagerIntegrationTest { @Test fun `should not do anything when install is less than a day old`() { every { LocalStorageService.getGlobalAssetDirectory() } returns - TestTools.getTestAssetPath(testDirectory).toString().toOptional() + TestTools.getTestAssetPath(TEST_DIRECTORY).toString().toOptional() every { PluginService.isMotivatorInstalled() } returns false every { WeebService.isWeebStuffOn() } returns true every { ThemeConfig.instance.allowPromotions } returns true @@ -166,12 +165,13 @@ class PromotionManagerIntegrationTest { """.toOptional() - val currentLedger = PromotionLedger( - UUID.randomUUID(), - mutableMapOf("Ryuko" to Instant.now()), - mutableMapOf(), - true - ) + val currentLedger = + PromotionLedger( + UUID.randomUUID(), + mutableMapOf("Ryuko" to Instant.now()), + mutableMapOf(), + true, + ) PromotionLedgerMaster.persistLedger(currentLedger) val promotionManager = PromotionManagerImpl() @@ -187,7 +187,7 @@ class PromotionManagerIntegrationTest { @Test fun `should not do anything when motivator is installed`() { every { LocalStorageService.getGlobalAssetDirectory() } returns - TestTools.getTestAssetPath(testDirectory).toString().toOptional() + TestTools.getTestAssetPath(TEST_DIRECTORY).toString().toOptional() every { PluginService.isMotivatorInstalled() } returns true every { PluginService.isAmiiInstalled() } returns false @@ -199,12 +199,13 @@ class PromotionManagerIntegrationTest { """.toOptional() - val currentLedger = PromotionLedger( - UUID.randomUUID(), - mutableMapOf("Ryuko" to Instant.now().minus(Period.ofDays(8))), - mutableMapOf(), - true - ) + val currentLedger = + PromotionLedger( + UUID.randomUUID(), + mutableMapOf("Ryuko" to Instant.now().minus(Period.ofDays(8))), + mutableMapOf(), + true, + ) PromotionLedgerMaster.persistLedger(currentLedger) @@ -221,7 +222,7 @@ class PromotionManagerIntegrationTest { @Test fun `should not do anything when AMII is installed`() { every { LocalStorageService.getGlobalAssetDirectory() } returns - TestTools.getTestAssetPath(testDirectory).toString().toOptional() + TestTools.getTestAssetPath(TEST_DIRECTORY).toString().toOptional() every { PluginService.isMotivatorInstalled() } returns false every { PluginService.isAmiiInstalled() } returns true @@ -233,12 +234,13 @@ class PromotionManagerIntegrationTest { """.toOptional() - val currentLedger = PromotionLedger( - UUID.randomUUID(), - mutableMapOf("Ryuko" to Instant.now().minus(Period.ofDays(8))), - mutableMapOf(), - true - ) + val currentLedger = + PromotionLedger( + UUID.randomUUID(), + mutableMapOf("Ryuko" to Instant.now().minus(Period.ofDays(8))), + mutableMapOf(), + true, + ) PromotionLedgerMaster.persistLedger(currentLedger) @@ -255,7 +257,7 @@ class PromotionManagerIntegrationTest { @Test fun `should not do anything when AMII and Motivator are installed`() { every { LocalStorageService.getGlobalAssetDirectory() } returns - TestTools.getTestAssetPath(testDirectory).toString().toOptional() + TestTools.getTestAssetPath(TEST_DIRECTORY).toString().toOptional() every { PluginService.isMotivatorInstalled() } returns true every { PluginService.isAmiiInstalled() } returns true @@ -267,12 +269,13 @@ class PromotionManagerIntegrationTest { """.toOptional() - val currentLedger = PromotionLedger( - UUID.randomUUID(), - mutableMapOf("Ryuko" to Instant.now().minus(Period.ofDays(8))), - mutableMapOf(), - true - ) + val currentLedger = + PromotionLedger( + UUID.randomUUID(), + mutableMapOf("Ryuko" to Instant.now().minus(Period.ofDays(8))), + mutableMapOf(), + true, + ) PromotionLedgerMaster.persistLedger(currentLedger) @@ -289,7 +292,7 @@ class PromotionManagerIntegrationTest { @Test fun `should not do anything when has been promoted before`() { every { LocalStorageService.getGlobalAssetDirectory() } returns - TestTools.getTestAssetPath(testDirectory).toString().toOptional() + TestTools.getTestAssetPath(TEST_DIRECTORY).toString().toOptional() every { PluginService.isMotivatorInstalled() } returns false every { PluginService.isAmiiInstalled() } returns false every { WeebService.isWeebStuffOn() } returns true @@ -300,18 +303,20 @@ class PromotionManagerIntegrationTest { """.toOptional() - val currentLedger = PromotionLedger( - UUID.randomUUID(), - mutableMapOf("Ryuko" to Instant.now().minus(Period.ofDays(8))), - mutableMapOf( - MOTIVATION_PROMOTION_ID to Promotion( - MOTIVATION_PROMOTION_ID, - Instant.now(), - PromotionStatus.REJECTED - ) - ), - true - ) + val currentLedger = + PromotionLedger( + UUID.randomUUID(), + mutableMapOf("Ryuko" to Instant.now().minus(Period.ofDays(8))), + mutableMapOf( + MOTIVATION_PROMOTION_ID to + Promotion( + MOTIVATION_PROMOTION_ID, + Instant.now(), + PromotionStatus.REJECTED, + ), + ), + true, + ) PromotionLedgerMaster.persistLedger(currentLedger) @@ -328,7 +333,7 @@ class PromotionManagerIntegrationTest { @Test fun `should not do anything when weeb stuff is not on`() { every { LocalStorageService.getGlobalAssetDirectory() } returns - TestTools.getTestAssetPath(testDirectory).toString().toOptional() + TestTools.getTestAssetPath(TEST_DIRECTORY).toString().toOptional() every { PluginService.isMotivatorInstalled() } returns false every { PluginService.isAmiiInstalled() } returns false every { WeebService.isWeebStuffOn() } returns false @@ -339,12 +344,13 @@ class PromotionManagerIntegrationTest { """.toOptional() - val currentLedger = PromotionLedger( - UUID.randomUUID(), - mutableMapOf("Ryuko" to Instant.now().minus(Period.ofDays(8))), - mutableMapOf(), - true - ) + val currentLedger = + PromotionLedger( + UUID.randomUUID(), + mutableMapOf("Ryuko" to Instant.now().minus(Period.ofDays(8))), + mutableMapOf(), + true, + ) PromotionLedgerMaster.persistLedger(currentLedger) @@ -361,7 +367,7 @@ class PromotionManagerIntegrationTest { @Test fun `should not do anything when not online`() { every { LocalStorageService.getGlobalAssetDirectory() } returns - TestTools.getTestAssetPath(testDirectory).toString().toOptional() + TestTools.getTestAssetPath(TEST_DIRECTORY).toString().toOptional() every { PluginService.isMotivatorInstalled() } returns false every { PluginService.isAmiiInstalled() } returns false every { WeebService.isWeebStuffOn() } returns true @@ -371,12 +377,13 @@ class PromotionManagerIntegrationTest { every { RestClient.performGet("$FALLBACK_ASSET_SOURCE/misc/am-i-online.txt") } returns "no".toOptional() andThen Optional.empty() - val currentLedger = PromotionLedger( - UUID.randomUUID(), - mutableMapOf("Ryuko" to Instant.now().minus(Period.ofDays(8))), - mutableMapOf(), - true - ) + val currentLedger = + PromotionLedger( + UUID.randomUUID(), + mutableMapOf("Ryuko" to Instant.now().minus(Period.ofDays(8))), + mutableMapOf(), + true, + ) PromotionLedgerMaster.persistLedger(currentLedger) @@ -394,7 +401,7 @@ class PromotionManagerIntegrationTest { @Test fun `should not do anything when not owner of lock`() { every { LocalStorageService.getGlobalAssetDirectory() } returns - TestTools.getTestAssetPath(testDirectory).toString().toOptional() + TestTools.getTestAssetPath(TEST_DIRECTORY).toString().toOptional() every { PluginService.isMotivatorInstalled() } returns false every { PluginService.isAmiiInstalled() } returns false every { WeebService.isWeebStuffOn() } returns true @@ -407,12 +414,13 @@ class PromotionManagerIntegrationTest { assertThat(LockMaster.acquireLock("Misato")).isTrue - val currentLedger = PromotionLedger( - UUID.randomUUID(), - mutableMapOf("Ryuko" to Instant.now().minus(Period.ofDays(8))), - mutableMapOf(), - true - ) + val currentLedger = + PromotionLedger( + UUID.randomUUID(), + mutableMapOf("Ryuko" to Instant.now().minus(Period.ofDays(8))), + mutableMapOf(), + true, + ) PromotionLedgerMaster.persistLedger(currentLedger) @@ -429,7 +437,7 @@ class PromotionManagerIntegrationTest { @Test fun `should not promote when not allowed`() { every { LocalStorageService.getGlobalAssetDirectory() } returns - TestTools.getTestAssetPath(testDirectory).toString().toOptional() + TestTools.getTestAssetPath(TEST_DIRECTORY).toString().toOptional() every { PluginService.isMotivatorInstalled() } returns false every { PluginService.isAmiiInstalled() } returns false every { WeebService.isWeebStuffOn() } returns true @@ -440,12 +448,13 @@ class PromotionManagerIntegrationTest { """.toOptional() - val currentLedger = PromotionLedger( - UUID.randomUUID(), - mutableMapOf("Ryuko" to Instant.now().minus(Period.ofDays(8))), - mutableMapOf(), - false - ) + val currentLedger = + PromotionLedger( + UUID.randomUUID(), + mutableMapOf("Ryuko" to Instant.now().minus(Period.ofDays(8))), + mutableMapOf(), + false, + ) PromotionLedgerMaster.persistLedger(currentLedger) @@ -464,7 +473,7 @@ class PromotionManagerIntegrationTest { @Test fun `should not promote when previous promotion was rejected`() { every { LocalStorageService.getGlobalAssetDirectory() } returns - TestTools.getTestAssetPath(testDirectory).toString().toOptional() + TestTools.getTestAssetPath(TEST_DIRECTORY).toString().toOptional() every { PluginService.isMotivatorInstalled() } returns false every { PluginService.isAmiiInstalled() } returns false every { WeebService.isWeebStuffOn() } returns true @@ -475,14 +484,15 @@ class PromotionManagerIntegrationTest { """.toOptional() - val currentLedger = PromotionLedger( - UUID.randomUUID(), - mutableMapOf("Ryuko" to Instant.now().minus(Period.ofDays(8))), - mutableMapOf( - MOTIVATION_PROMOTION_ID to Promotion(MOTIVATION_PROMOTION_ID, Instant.now(), PromotionStatus.REJECTED) - ), - true - ) + val currentLedger = + PromotionLedger( + UUID.randomUUID(), + mutableMapOf("Ryuko" to Instant.now().minus(Period.ofDays(8))), + mutableMapOf( + MOTIVATION_PROMOTION_ID to Promotion(MOTIVATION_PROMOTION_ID, Instant.now(), PromotionStatus.REJECTED), + ), + true, + ) PromotionLedgerMaster.persistLedger(currentLedger) @@ -501,7 +511,7 @@ class PromotionManagerIntegrationTest { @Test fun `should not promote when AniMeme plugin is not compatible`() { every { LocalStorageService.getGlobalAssetDirectory() } returns - TestTools.getTestAssetPath(testDirectory).toString().toOptional() + TestTools.getTestAssetPath(TEST_DIRECTORY).toString().toOptional() every { PluginService.isMotivatorInstalled() } returns false every { PluginService.isAmiiInstalled() } returns false every { PluginService.canAmiiBeInstalled() } returns false @@ -513,14 +523,15 @@ class PromotionManagerIntegrationTest { """.toOptional() - val currentLedger = PromotionLedger( - UUID.randomUUID(), - mutableMapOf("Ryuko" to Instant.now().minus(Period.ofDays(8))), - mutableMapOf( - MOTIVATION_PROMOTION_ID to Promotion(MOTIVATION_PROMOTION_ID, Instant.now(), PromotionStatus.ACCEPTED) - ), - true - ) + val currentLedger = + PromotionLedger( + UUID.randomUUID(), + mutableMapOf("Ryuko" to Instant.now().minus(Period.ofDays(8))), + mutableMapOf( + MOTIVATION_PROMOTION_ID to Promotion(MOTIVATION_PROMOTION_ID, Instant.now(), PromotionStatus.ACCEPTED), + ), + true, + ) PromotionLedgerMaster.persistLedger(currentLedger) @@ -539,7 +550,7 @@ class PromotionManagerIntegrationTest { @Test fun `should not promote when opted out`() { every { LocalStorageService.getGlobalAssetDirectory() } returns - TestTools.getTestAssetPath(testDirectory).toString().toOptional() + TestTools.getTestAssetPath(TEST_DIRECTORY).toString().toOptional() every { PluginService.isMotivatorInstalled() } returns false every { PluginService.isAmiiInstalled() } returns false every { PluginService.canAmiiBeInstalled() } returns true @@ -551,14 +562,15 @@ class PromotionManagerIntegrationTest { """.toOptional() - val currentLedger = PromotionLedger( - UUID.randomUUID(), - mutableMapOf("Ryuko" to Instant.now().minus(Period.ofDays(8))), - mutableMapOf( - MOTIVATION_PROMOTION_ID to Promotion(MOTIVATION_PROMOTION_ID, Instant.now(), PromotionStatus.ACCEPTED) - ), - true - ) + val currentLedger = + PromotionLedger( + UUID.randomUUID(), + mutableMapOf("Ryuko" to Instant.now().minus(Period.ofDays(8))), + mutableMapOf( + MOTIVATION_PROMOTION_ID to Promotion(MOTIVATION_PROMOTION_ID, Instant.now(), PromotionStatus.ACCEPTED), + ), + true, + ) PromotionLedgerMaster.persistLedger(currentLedger) @@ -577,7 +589,7 @@ class PromotionManagerIntegrationTest { @Test fun `should promote when previous promotion was accepted`() { every { LocalStorageService.getGlobalAssetDirectory() } returns - TestTools.getTestAssetPath(testDirectory).toString().toOptional() + TestTools.getTestAssetPath(TEST_DIRECTORY).toString().toOptional() every { PluginService.isMotivatorInstalled() } returns false every { PluginService.isAmiiInstalled() } returns false every { PluginService.canAmiiBeInstalled() } returns true @@ -589,14 +601,15 @@ class PromotionManagerIntegrationTest { """.toOptional() - val currentLedger = PromotionLedger( - UUID.randomUUID(), - mutableMapOf("Ryuko" to Instant.now().minus(Period.ofDays(8))), - mutableMapOf( - MOTIVATION_PROMOTION_ID to Promotion(MOTIVATION_PROMOTION_ID, Instant.now(), PromotionStatus.ACCEPTED) - ), - true - ) + val currentLedger = + PromotionLedger( + UUID.randomUUID(), + mutableMapOf("Ryuko" to Instant.now().minus(Period.ofDays(8))), + mutableMapOf( + MOTIVATION_PROMOTION_ID to Promotion(MOTIVATION_PROMOTION_ID, Instant.now(), PromotionStatus.ACCEPTED), + ), + true, + ) PromotionLedgerMaster.persistLedger(currentLedger) @@ -616,7 +629,7 @@ class PromotionManagerIntegrationTest { @Test fun `should promote when previous promotion was not shown`() { every { LocalStorageService.getGlobalAssetDirectory() } returns - TestTools.getTestAssetPath(testDirectory).toString().toOptional() + TestTools.getTestAssetPath(TEST_DIRECTORY).toString().toOptional() every { PluginService.isMotivatorInstalled() } returns false every { PluginService.isAmiiInstalled() } returns false every { PluginService.canAmiiBeInstalled() } returns true @@ -628,14 +641,15 @@ class PromotionManagerIntegrationTest { """.toOptional() - val currentLedger = PromotionLedger( - UUID.randomUUID(), - mutableMapOf("Ryuko" to Instant.now().minus(Period.ofDays(8))), - mutableMapOf( - MOTIVATION_PROMOTION_ID to Promotion(MOTIVATION_PROMOTION_ID, Instant.now(), PromotionStatus.ACCEPTED) - ), - true - ) + val currentLedger = + PromotionLedger( + UUID.randomUUID(), + mutableMapOf("Ryuko" to Instant.now().minus(Period.ofDays(8))), + mutableMapOf( + MOTIVATION_PROMOTION_ID to Promotion(MOTIVATION_PROMOTION_ID, Instant.now(), PromotionStatus.ACCEPTED), + ), + true, + ) PromotionLedgerMaster.persistLedger(currentLedger) @@ -664,7 +678,7 @@ class PromotionManagerIntegrationTest { @Test fun `should promote when not locked`() { every { LocalStorageService.getGlobalAssetDirectory() } returns - TestTools.getTestAssetPath(testDirectory).toString().toOptional() + TestTools.getTestAssetPath(TEST_DIRECTORY).toString().toOptional() every { PluginService.isMotivatorInstalled() } returns false every { PluginService.isAmiiInstalled() } returns false every { PluginService.canAmiiBeInstalled() } returns true @@ -676,12 +690,13 @@ class PromotionManagerIntegrationTest { """.toOptional() - val currentLedger = PromotionLedger( - UUID.randomUUID(), - mutableMapOf("Ryuko" to Instant.now().minus(Period.ofDays(8))), - mutableMapOf(), - true - ) + val currentLedger = + PromotionLedger( + UUID.randomUUID(), + mutableMapOf("Ryuko" to Instant.now().minus(Period.ofDays(8))), + mutableMapOf(), + true, + ) PromotionLedgerMaster.persistLedger(currentLedger) @@ -701,7 +716,7 @@ class PromotionManagerIntegrationTest { @Test fun `should promote when primary assets are down`() { every { LocalStorageService.getGlobalAssetDirectory() } returns - TestTools.getTestAssetPath(testDirectory).toString().toOptional() + TestTools.getTestAssetPath(TEST_DIRECTORY).toString().toOptional() every { PluginService.isMotivatorInstalled() } returns false every { PluginService.isAmiiInstalled() } returns false every { PluginService.canAmiiBeInstalled() } returns true @@ -718,12 +733,13 @@ class PromotionManagerIntegrationTest { """.toOptional() - val currentLedger = PromotionLedger( - UUID.randomUUID(), - mutableMapOf("Ryuko" to Instant.now().minus(Period.ofDays(8))), - mutableMapOf(), - true - ) + val currentLedger = + PromotionLedger( + UUID.randomUUID(), + mutableMapOf("Ryuko" to Instant.now().minus(Period.ofDays(8))), + mutableMapOf(), + true, + ) PromotionLedgerMaster.persistLedger(currentLedger) @@ -743,7 +759,7 @@ class PromotionManagerIntegrationTest { @Test fun `should break old lock`() { every { LocalStorageService.getGlobalAssetDirectory() } returns - TestTools.getTestAssetPath(testDirectory).toString().toOptional() + TestTools.getTestAssetPath(TEST_DIRECTORY).toString().toOptional() every { PluginService.isMotivatorInstalled() } returns false every { PluginService.isAmiiInstalled() } returns false every { PluginService.canAmiiBeInstalled() } returns true @@ -759,17 +775,18 @@ class PromotionManagerIntegrationTest { Lock( "Misato", Instant.now().minusMillis( - TimeUnit.MILLISECONDS.convert(3, TimeUnit.HOURS) - ) - ) + TimeUnit.MILLISECONDS.convert(3, TimeUnit.HOURS), + ), + ), ) - val currentLedger = PromotionLedger( - UUID.randomUUID(), - mutableMapOf("Ryuko" to Instant.now().minus(Period.ofDays(8))), - mutableMapOf(), - true - ) + val currentLedger = + PromotionLedger( + UUID.randomUUID(), + mutableMapOf("Ryuko" to Instant.now().minus(Period.ofDays(8))), + mutableMapOf(), + true, + ) PromotionLedgerMaster.persistLedger(currentLedger) @@ -788,7 +805,7 @@ class PromotionManagerIntegrationTest { private fun validateLedgerCallback( currentLedger: PromotionLedger, - beforePromotion: Instant? + beforePromotion: Instant?, ) { val promotionSlot = slot<(PromotionResults) -> Unit>() val rejectionSlot = slot<() -> Unit>() @@ -806,7 +823,7 @@ class PromotionManagerIntegrationTest { assertThat(postBlocked.seenPromotions[MOTIVATION_PROMOTION_ID]?.id).isEqualTo(MOTIVATION_PROMOTION_ID) assertThat(postBlocked.seenPromotions[MOTIVATION_PROMOTION_ID]?.datePromoted).isBetween( beforePromotion, - postBlockedTime + postBlockedTime, ) promotionCallback(PromotionResults(PromotionStatus.REJECTED)) @@ -820,7 +837,7 @@ class PromotionManagerIntegrationTest { assertThat(postRejected.seenPromotions[MOTIVATION_PROMOTION_ID]?.id).isEqualTo(MOTIVATION_PROMOTION_ID) assertThat(postRejected.seenPromotions[MOTIVATION_PROMOTION_ID]?.datePromoted).isBetween( postBlockedTime, - postRejectedTime + postRejectedTime, ) promotionCallback(PromotionResults(PromotionStatus.ACCEPTED)) @@ -834,7 +851,7 @@ class PromotionManagerIntegrationTest { assertThat(postAccepted.seenPromotions[MOTIVATION_PROMOTION_ID]?.id).isEqualTo(MOTIVATION_PROMOTION_ID) assertThat(postAccepted.seenPromotions[MOTIVATION_PROMOTION_ID]?.datePromoted).isBetween( postRejectedTime, - postAcceptedTime + postAcceptedTime, ) } } diff --git a/src/test/kotlin/io/unthrottled/doki/stickers/DimensionCappingServiceTest.kt b/src/test/kotlin/io/unthrottled/doki/stickers/DimensionCappingServiceTest.kt index ab2428545..6ad8ca2a7 100644 --- a/src/test/kotlin/io/unthrottled/doki/stickers/DimensionCappingServiceTest.kt +++ b/src/test/kotlin/io/unthrottled/doki/stickers/DimensionCappingServiceTest.kt @@ -5,13 +5,13 @@ import org.junit.Test import java.awt.Dimension class DimensionCappingServiceTest { - @Test fun getCappingStyleShouldNotCapIfBothNegativeOne() { - val result = DimensionCappingService.getCappingStyle( - Dimension(69, 420), - Dimension(-1, -1) - ) + val result = + DimensionCappingService.getCappingStyle( + Dimension(69, 420), + Dimension(-1, -1), + ) Assertions.assertThat(result) .isEqualTo(Dimension(69, 420)) @@ -19,10 +19,11 @@ class DimensionCappingServiceTest { @Test fun getCappingStyleShouldMaintainAspectRationWhenScalingWidthHeightGreater() { - val result = DimensionCappingService.getCappingStyle( - Dimension(20, 40), - Dimension(10, -1) - ) + val result = + DimensionCappingService.getCappingStyle( + Dimension(20, 40), + Dimension(10, -1), + ) Assertions.assertThat(result) .isEqualTo(Dimension(10, 20)) @@ -30,10 +31,11 @@ class DimensionCappingServiceTest { @Test fun getCappingStyleShouldMaintainAspectRationWhenScalingHeightHeightGreater() { - val result = DimensionCappingService.getCappingStyle( - Dimension(20, 40), - Dimension(-1, 10) - ) + val result = + DimensionCappingService.getCappingStyle( + Dimension(20, 40), + Dimension(-1, 10), + ) Assertions.assertThat(result) .isEqualTo(Dimension(5, 10)) @@ -41,10 +43,11 @@ class DimensionCappingServiceTest { @Test fun getCappingStyleShouldMaintainAspectRationWhenScalingWidthWidthGreater() { - val result = DimensionCappingService.getCappingStyle( - Dimension(40, 20), - Dimension(10, -1) - ) + val result = + DimensionCappingService.getCappingStyle( + Dimension(40, 20), + Dimension(10, -1), + ) Assertions.assertThat(result) .isEqualTo(Dimension(10, 5)) @@ -52,10 +55,11 @@ class DimensionCappingServiceTest { @Test fun getCappingStyleShouldMaintainAspectRationWhenScalingHeightWidthGreater() { - val result = DimensionCappingService.getCappingStyle( - Dimension(40, 20), - Dimension(-1, 10) - ) + val result = + DimensionCappingService.getCappingStyle( + Dimension(40, 20), + Dimension(-1, 10), + ) Assertions.assertThat(result) .isEqualTo(Dimension(20, 10)) @@ -63,10 +67,11 @@ class DimensionCappingServiceTest { @Test fun getCappingStyleShouldMaintainAspectRatioAndRespectSmallestCapHeight() { - val result = DimensionCappingService.getCappingStyle( - Dimension(40, 20), - Dimension(4, 10) - ) + val result = + DimensionCappingService.getCappingStyle( + Dimension(40, 20), + Dimension(4, 10), + ) Assertions.assertThat(result) .isEqualTo(Dimension(4, 2)) @@ -74,10 +79,11 @@ class DimensionCappingServiceTest { @Test fun getCappingStyleShouldMaintainAspectRatioAndRespectSmallestCapWidth() { - val result = DimensionCappingService.getCappingStyle( - Dimension(40, 20), - Dimension(10, 4) - ) + val result = + DimensionCappingService.getCappingStyle( + Dimension(40, 20), + Dimension(10, 4), + ) Assertions.assertThat(result) .isEqualTo(Dimension(8, 4)) diff --git a/src/test/kotlin/io/unthrottled/doki/test/tools/TestTools.kt b/src/test/kotlin/io/unthrottled/doki/test/tools/TestTools.kt index daffd05f6..5a4a5ba16 100644 --- a/src/test/kotlin/io/unthrottled/doki/test/tools/TestTools.kt +++ b/src/test/kotlin/io/unthrottled/doki/test/tools/TestTools.kt @@ -13,9 +13,10 @@ import java.nio.file.Paths object TestTools { fun getTestAssetPath(vararg extraDirectories: String): Path { - val testAssetDirectory = Paths.get(".", "testAssets", *extraDirectories) - .normalize() - .toAbsolutePath() + val testAssetDirectory = + Paths.get(".", "testAssets", *extraDirectories) + .normalize() + .toAbsolutePath() if (Files.exists(testAssetDirectory).not()) { Files.createDirectories(testAssetDirectory) }