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
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import com.zugaldia.speedofsound.core.plugins.AppPluginCategory
import com.zugaldia.speedofsound.core.plugins.AppPluginRegistry
import com.zugaldia.speedofsound.core.plugins.director.DefaultDirector
import com.zugaldia.speedofsound.core.plugins.director.DirectorEvent
import com.zugaldia.speedofsound.core.plugins.director.PipelineStage
import com.zugaldia.speedofsound.core.plugins.recorder.JvmRecorder
import com.zugaldia.speedofsound.core.plugins.recorder.RecorderEvent
import kotlinx.coroutines.CoroutineScope
Expand Down Expand Up @@ -281,7 +282,10 @@ class MainViewModel(
val finalText = event.finalResult.trim() + suffix
TextUtils.textToKeySym(finalText)
.onSuccess { keySyms -> portalsClient.typeText(keySyms, settingsClient.getTypingDelayMs().toLong()) }
.onFailure { error -> logger.error("Error converting text to key symbols: ${error.message}") }
.onFailure { error ->
logger.error("Error converting text to key symbols: ${error.message}")
portalsClient.showNotification(body = "Failed to type text: ${error.message ?: "Unknown error"}")
}
}
}

Expand All @@ -291,6 +295,12 @@ class MainViewModel(

private fun onPipelineError(event: DirectorEvent.PipelineError) {
logger.error("Pipeline error at ${event.stage}: ${event.error.message}")
val body = when (event.stage) {
PipelineStage.RECORDING -> "Recording failed: ${event.error.message ?: "Unknown error"}"
PipelineStage.TRANSCRIPTION -> "Transcription failed: ${event.error.message ?: "Unknown error"}"
PipelineStage.POLISHING -> "Text processing failed: ${event.error.message ?: "Unknown error"}"
}
portalsClient.showNotification(body = body)
hideAndReset()
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
package com.zugaldia.speedofsound.core.desktop.portals

import com.zugaldia.speedofsound.core.APPLICATION_NAME
import com.zugaldia.speedofsound.core.generateUniqueId
import com.zugaldia.stargate.sdk.DesktopPortal
import com.zugaldia.stargate.sdk.notification.NotificationPriority
import com.zugaldia.stargate.sdk.remotedesktop.DeviceType
import com.zugaldia.stargate.sdk.remotedesktop.InputState
import com.zugaldia.stargate.sdk.remotedesktop.PersistMode
Expand Down Expand Up @@ -30,6 +33,24 @@ class PortalsClient {
persistMode = PersistMode.UNTIL_REVOKED
)

/**
* Sends a desktop notification via the XDG Notification portal.
*
* @param body The main notification message shown to the user.
* @param id Unique identifier for the notification. Defaults to a generated ID. Sending a new
* notification with the same ID replaces any existing notification with that ID.
* @param title The notification title. Defaults to the application name.
* @param priority The notification priority level. Defaults to [NotificationPriority.NORMAL],
* which is appropriate for most informational messages and errors.
*/
fun showNotification(
body: String,
id: String = generateUniqueId(),
title: String = APPLICATION_NAME,
priority: NotificationPriority = NotificationPriority.NORMAL
) = runCatching { portal.notification.addNotification(id = id, title = title, body = body, priority = priority) }
.onFailure { error -> logger.error("Failed to send notification: ${error.message}") }

/**
* Simulates keyboard input by sending each character as a key press/release pair.
*
Expand Down
Loading