Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions mpp-core/src/androidMain/kotlin/cc/unitmesh/agent/Platform.kt
Original file line number Diff line number Diff line change
Expand Up @@ -45,5 +45,12 @@ actual object Platform {
actual fun getLogDir(): String {
return "${getUserHomeDir()}/.autodev/logs"
}

actual fun prefersReducedMotion(): Boolean {
// Android requires Context to check Settings.Global.ANIMATOR_DURATION_SCALE
// Since Platform is a static object without Context access, we return false.
// TODO: Consider providing a Context-aware initialization or companion method
return false
}
}

6 changes: 6 additions & 0 deletions mpp-core/src/commonMain/kotlin/cc/unitmesh/agent/Platform.kt
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,12 @@ expect object Platform {
* Default: ~/.autodev/logs
*/
fun getLogDir(): String

/**
* Check if user prefers reduced motion (accessibility setting)
* Used to disable or simplify animations for users who are sensitive to motion
*/
fun prefersReducedMotion(): Boolean
}

/**
Expand Down
6 changes: 6 additions & 0 deletions mpp-core/src/iosMain/kotlin/cc/unitmesh/agent/Platform.ios.kt
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import kotlinx.cinterop.ExperimentalForeignApi
import kotlinx.datetime.Clock
import platform.Foundation.NSHomeDirectory
import platform.Foundation.NSProcessInfo
import platform.UIKit.UIAccessibilityIsReduceMotionEnabled

@OptIn(ExperimentalForeignApi::class)
actual object Platform {
Expand Down Expand Up @@ -43,5 +44,10 @@ actual object Platform {
actual fun getLogDir(): String {
return "${getUserHomeDir()}/.autodev/logs"
}

actual fun prefersReducedMotion(): Boolean {
// iOS: Check reduce motion accessibility setting
return UIAccessibilityIsReduceMotionEnabled()
}
}

16 changes: 16 additions & 0 deletions mpp-core/src/jsMain/kotlin/cc/unitmesh/agent/Platform.js.kt
Original file line number Diff line number Diff line change
Expand Up @@ -63,4 +63,20 @@ actual object Platform {
actual fun getLogDir(): String {
return "${getUserHomeDir()}/.autodev/logs"
}

actual fun prefersReducedMotion(): Boolean {
// In browser, check prefers-reduced-motion media query
// In Node.js, return false as there's no UI
return try {
val isBrowser = js("typeof window !== 'undefined'") as Boolean
if (isBrowser) {
val matches = js("window.matchMedia && window.matchMedia('(prefers-reduced-motion: reduce)').matches") as Boolean
matches
} else {
false
}
} catch (e: Exception) {
false
}
}
}
39 changes: 39 additions & 0 deletions mpp-core/src/jvmMain/kotlin/cc/unitmesh/agent/Platform.jvm.kt
Original file line number Diff line number Diff line change
Expand Up @@ -48,4 +48,43 @@ actual object Platform {
actual fun getLogDir(): String {
return "${getUserHomeDir()}/.autodev/logs"
}

actual fun prefersReducedMotion(): Boolean {
// On JVM Desktop, check system properties or environment variables
// macOS: defaults read com.apple.universalaccess reduceMotion
// Windows: Check registry for SystemParameters.HighContrast or animations disabled
// Linux: Check GTK settings or GNOME accessibility settings
return try {
val osName = getOSName().lowercase()
when {
osName.contains("mac") -> {
// Check macOS reduce motion setting via defaults command
val process = ProcessBuilder("defaults", "read", "com.apple.universalaccess", "reduceMotion")
.redirectErrorStream(true)
.start()
val result = process.inputStream.bufferedReader().readText().trim()
val completed = process.waitFor(1, java.util.concurrent.TimeUnit.SECONDS)
if (!completed) {
process.destroyForcibly()
return false
}
result == "1"
}
osName.contains("windows") -> {
// Windows: Proper implementation requires JNA/JNI to call
// SystemParametersInfo(SPI_GETCLIENTAREAANIMATION) or read registry
// For now, return false as a safe default
false
}
else -> {
// Linux/other: Check GTK_ENABLE_ANIMATIONS or GNOME settings
val gtkAnimations = System.getenv("GTK_ENABLE_ANIMATIONS")
gtkAnimations == "0" || gtkAnimations == "false"
}
}
} catch (e: Exception) {
// Default to false if we can't determine the setting
false
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -41,4 +41,11 @@ actual object Platform {
// WASM typically runs in browser, use a virtual path
return "~/.autodev/logs"
}

actual fun prefersReducedMotion(): Boolean {
// WASM runs in browser, default to false
// Full media query check is limited in WASM due to js() expression restrictions
// This can be enhanced in the future if needed
return false
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package cc.unitmesh.devins.idea.renderer

import cc.unitmesh.devins.llm.MessageRole
import cc.unitmesh.agent.render.TimelineItem
import cc.unitmesh.agent.render.TaskStatus
import cc.unitmesh.llm.compression.TokenInfo
import kotlinx.coroutines.flow.first
import kotlinx.coroutines.runBlocking
Expand Down
Loading
Loading