@@ -15,6 +15,7 @@ import kotlinx.serialization.json.JsonPrimitive
1515import kotlinx.serialization.json.contentOrNull
1616import kotlinx.serialization.json.jsonObject
1717import org.lightningdevkit.ldknode.Event
18+ import to.bitkit.data.CacheStore
1819import to.bitkit.data.SettingsStore
1920import to.bitkit.di.json
2021import to.bitkit.ext.amountOnClose
@@ -28,10 +29,12 @@ import to.bitkit.models.BlocktankNotificationType.wakeToTimeout
2829import to.bitkit.models.NewTransactionSheetDetails
2930import to.bitkit.models.NewTransactionSheetDirection
3031import to.bitkit.models.NewTransactionSheetType
32+ import to.bitkit.models.NotificationDetails
3133import to.bitkit.repositories.ActivityRepo
3234import to.bitkit.repositories.BlocktankRepo
3335import to.bitkit.repositories.LightningRepo
3436import to.bitkit.services.CoreService
37+ import to.bitkit.R
3538import to.bitkit.ui.pushNotification
3639import to.bitkit.utils.Logger
3740import to.bitkit.utils.withPerformanceLogging
@@ -47,13 +50,11 @@ class WakeNodeWorker @AssistedInject constructor(
4750 private val blocktankRepo : BlocktankRepo ,
4851 private val activityRepo : ActivityRepo ,
4952 private val settingsStore : SettingsStore ,
53+ private val cacheStore : CacheStore ,
5054) : CoroutineWorker(appContext, workerParams) {
5155 private val self = this
5256
53- // TODO extract as global model and turn into data class.
54- class VisibleNotification (var title : String = " " , var body : String = " " )
55-
56- private var bestAttemptContent: VisibleNotification ? = VisibleNotification ()
57+ private var bestAttemptContent: NotificationDetails ? = null
5758
5859 private var notificationType: BlocktankNotificationType ? = null
5960 private var notificationPayload: JsonObject ? = null
@@ -93,8 +94,10 @@ class WakeNodeWorker @AssistedInject constructor(
9394 coreService.blocktank.open(orderId = orderId)
9495 } catch (e: Exception ) {
9596 Logger .error(" failed to open channel" , e)
96- self.bestAttemptContent?.title = " Channel open failed"
97- self.bestAttemptContent?.body = e.message ? : " Unknown error"
97+ self.bestAttemptContent = NotificationDetails (
98+ title = appContext.getString(R .string.notification_channel_open_failed_title),
99+ body = e.message ? : appContext.getString(R .string.notification_unknown_error),
100+ )
98101 self.deliver()
99102 }
100103 }
@@ -103,10 +106,12 @@ class WakeNodeWorker @AssistedInject constructor(
103106 withTimeout(timeout) { deliverSignal.await() } // Stops node on timeout & avoids notification replay by OS
104107 return Result .success()
105108 } catch (e: Exception ) {
106- val reason = e.message ? : " Unknown error "
109+ val reason = e.message ? : appContext.getString( R .string.notification_unknown_error)
107110
108- self.bestAttemptContent?.title = " Lightning error"
109- self.bestAttemptContent?.body = reason
111+ self.bestAttemptContent = NotificationDetails (
112+ title = appContext.getString(R .string.notification_lightning_error_title),
113+ body = reason,
114+ )
110115 Logger .error(" Lightning error" , e)
111116 self.deliver()
112117
@@ -120,22 +125,26 @@ class WakeNodeWorker @AssistedInject constructor(
120125 */
121126 private suspend fun handleLdkEvent (event : Event ) {
122127 val showDetails = settingsStore.data.first().showNotificationDetails
123- val openBitkitMessage = " Open Bitkit to see details "
128+ val hiddenBody = appContext.getString( R .string.notification_received_body_hidden)
124129 when (event) {
125- is Event .PaymentReceived -> onPaymentReceived(event, showDetails, openBitkitMessage )
130+ is Event .PaymentReceived -> onPaymentReceived(event, showDetails, hiddenBody )
126131
127132 is Event .ChannelPending -> {
128- self.bestAttemptContent?.title = " Channel Opened"
129- self.bestAttemptContent?.body = " Pending"
133+ self.bestAttemptContent = NotificationDetails (
134+ title = appContext.getString(R .string.notification_channel_opened_title),
135+ body = appContext.getString(R .string.notification_channel_pending_body),
136+ )
130137 // Don't deliver, give a chance for channelReady event to update the content if it's a turbo channel
131138 }
132139
133- is Event .ChannelReady -> onChannelReady(event, showDetails, openBitkitMessage )
140+ is Event .ChannelReady -> onChannelReady(event, showDetails, hiddenBody )
134141 is Event .ChannelClosed -> onChannelClosed(event)
135142
136143 is Event .PaymentFailed -> {
137- self.bestAttemptContent?.title = " Payment failed"
138- self.bestAttemptContent?.body = " ⚡ ${event.reason} "
144+ self.bestAttemptContent = NotificationDetails (
145+ title = appContext.getString(R .string.notification_payment_failed_title),
146+ body = " ⚡ ${event.reason} " ,
147+ )
139148
140149 if (self.notificationType == wakeToTimeout) {
141150 self.deliver()
@@ -147,14 +156,19 @@ class WakeNodeWorker @AssistedInject constructor(
147156 }
148157
149158 private suspend fun onChannelClosed (event : Event .ChannelClosed ) {
150- self.bestAttemptContent?.title = " Channel closed"
151- self.bestAttemptContent?.body = " Reason: ${event.reason} "
152-
153- if (self.notificationType == mutualClose) {
154- self.bestAttemptContent?.body = " Balance moved from spending to savings"
155- } else if (self.notificationType == orderPaymentConfirmed) {
156- self.bestAttemptContent?.title = " Channel failed to open in the background"
157- self.bestAttemptContent?.body = " Please try again"
159+ self.bestAttemptContent = when (self.notificationType) {
160+ mutualClose -> NotificationDetails (
161+ title = appContext.getString(R .string.notification_channel_closed_title),
162+ body = appContext.getString(R .string.notification_channel_closed_mutual_body),
163+ )
164+ orderPaymentConfirmed -> NotificationDetails (
165+ title = appContext.getString(R .string.notification_channel_open_bg_failed_title),
166+ body = appContext.getString(R .string.notification_please_try_again_body),
167+ )
168+ else -> NotificationDetails (
169+ title = appContext.getString(R .string.notification_channel_closed_title),
170+ body = appContext.getString(R .string.notification_channel_closed_reason_body, event.reason),
171+ )
158172 }
159173
160174 self.deliver()
@@ -163,22 +177,23 @@ class WakeNodeWorker @AssistedInject constructor(
163177 private suspend fun onPaymentReceived (
164178 event : Event .PaymentReceived ,
165179 showDetails : Boolean ,
166- openBitkitMessage : String ,
180+ hiddenBody : String ,
167181 ) {
168- bestAttemptContent?.title = " Payment Received"
169182 val sats = event.amountMsat / 1000u
170183 // Save for UI to pick up
171- NewTransactionSheetDetails .save(
172- appContext,
184+ cacheStore.setBackgroundReceive(
173185 NewTransactionSheetDetails (
174186 type = NewTransactionSheetType .LIGHTNING ,
175187 direction = NewTransactionSheetDirection .RECEIVED ,
176188 paymentHashOrTxId = event.paymentHash,
177189 sats = sats.toLong(),
178190 )
179191 )
180- val content = if (showDetails) " $BITCOIN_SYMBOL $sats " else openBitkitMessage
181- bestAttemptContent?.body = content
192+ val content = if (showDetails) " $BITCOIN_SYMBOL $sats " else hiddenBody
193+ bestAttemptContent = NotificationDetails (
194+ title = appContext.getString(R .string.notification_received_title),
195+ body = content,
196+ )
182197 if (self.notificationType == incomingHtlc) {
183198 self.deliver()
184199 }
@@ -187,21 +202,26 @@ class WakeNodeWorker @AssistedInject constructor(
187202 private suspend fun onChannelReady (
188203 event : Event .ChannelReady ,
189204 showDetails : Boolean ,
190- openBitkitMessage : String ,
205+ hiddenBody : String ,
191206 ) {
207+ val viaNewChannel = appContext.getString(R .string.notification_via_new_channel_body)
192208 if (self.notificationType == cjitPaymentArrived) {
193- self.bestAttemptContent?.title = " Payment received"
194- self.bestAttemptContent?.body = " Via new channel"
209+ self.bestAttemptContent = NotificationDetails (
210+ title = appContext.getString(R .string.notification_received_title),
211+ body = viaNewChannel,
212+ )
195213
196214 lightningRepo.getChannels()?.find { it.channelId == event.channelId }?.let { channel ->
197215 val sats = channel.amountOnClose
198- val content = if (showDetails) " $BITCOIN_SYMBOL $sats " else openBitkitMessage
199- self.bestAttemptContent?.title = content
216+ val content = if (showDetails) " $BITCOIN_SYMBOL $sats " else hiddenBody
217+ self.bestAttemptContent = NotificationDetails (
218+ title = content,
219+ body = viaNewChannel,
220+ )
200221 val cjitEntry = channel.let { blocktankRepo.getCjitEntry(it) }
201222 if (cjitEntry != null ) {
202223 // Save for UI to pick up
203- NewTransactionSheetDetails .save(
204- appContext,
224+ cacheStore.setBackgroundReceive(
205225 NewTransactionSheetDetails (
206226 type = NewTransactionSheetType .LIGHTNING ,
207227 direction = NewTransactionSheetDirection .RECEIVED ,
@@ -212,8 +232,10 @@ class WakeNodeWorker @AssistedInject constructor(
212232 }
213233 }
214234 } else if (self.notificationType == orderPaymentConfirmed) {
215- self.bestAttemptContent?.title = " Channel opened"
216- self.bestAttemptContent?.body = " Ready to send"
235+ self.bestAttemptContent = NotificationDetails (
236+ title = appContext.getString(R .string.notification_channel_opened_title),
237+ body = appContext.getString(R .string.notification_channel_ready_body),
238+ )
217239 }
218240 self.deliver()
219241 }
@@ -222,7 +244,7 @@ class WakeNodeWorker @AssistedInject constructor(
222244 lightningRepo.stop()
223245
224246 bestAttemptContent?.run {
225- pushNotification(title, body, context = appContext )
247+ appContext. pushNotification(title, body)
226248 Logger .info(" Delivered notification" )
227249 }
228250
0 commit comments