Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
68 commits
Select commit Hold shift + click to select a range
1636d74
refactor: move logic and shared states from viewmodel to WalletRepo.k…
jvsena42 May 2, 2025
2f46752
refactor: move logic and shared states from viewmodel to LightningRep…
jvsena42 May 2, 2025
b993a25
refactor: move logic and shared states from viewmodel to LightningRep…
jvsena42 May 2, 2025
0a322f7
refactor: move logic and shared states from viewmodel to repository
jvsena42 May 2, 2025
52f8341
refactor: remove reference
jvsena42 May 2, 2025
345f3d7
fix: dependency injection
jvsena42 May 2, 2025
8dc59ad
feat: add comments
jvsena42 May 2, 2025
dc57927
Merge branch 'master' into feat/keep-node-in-background
jvsena42 May 5, 2025
fc97264
feat: create the LightningNodeService.kt
jvsena42 May 5, 2025
cba301f
feat: check if the node is running before call start
jvsena42 May 5, 2025
9e5b571
feat: create the notification channel
jvsena42 May 5, 2025
82af9c1
refactor: remove stop call from view
jvsena42 May 5, 2025
5866cd8
feat: start service
jvsena42 May 5, 2025
490b192
feat: refresh bip 21
jvsena42 May 5, 2025
b62b4a7
feat: add retry
jvsena42 May 5, 2025
611b185
refactor: remove comment
jvsena42 May 5, 2025
0553436
refactor: deprecate walletViewModel
jvsena42 May 5, 2025
f229fb4
test: WalletRepoTest.kt WIP
jvsena42 May 5, 2025
8a01b5d
test: WalletRepoTest.kt
jvsena42 May 5, 2025
ae511c4
test: update tests
jvsena42 May 5, 2025
6a45eb1
test: LightningRepoTest.kt
jvsena42 May 6, 2025
1081307
test: update WalletViewModelTest.kt
jvsena42 May 6, 2025
0e63f35
refactor: restoring wallet state access
jvsena42 May 6, 2025
15b1c1f
refactor: remove imports
jvsena42 May 6, 2025
273ef07
fix: clear states when wipe wallet
jvsena42 May 6, 2025
f1b363e
Merge branch 'master' into feat/keep-node-in-background
jvsena42 May 6, 2025
4f5932d
fix: only trigger onInputChanged if the primary display has changed
jvsena42 May 6, 2025
931c68f
fix: keep states
jvsena42 May 6, 2025
c129e4c
fix: continue button label
jvsena42 May 6, 2025
ac631f6
fix: keep the balance input state while the qr code is displayed and …
jvsena42 May 6, 2025
43a0ee3
fix: keep the balance input state while the qr code is displayed and …
jvsena42 May 6, 2025
51c00e6
fix: keep the balance input state while the qr code is displayed and …
jvsena42 May 6, 2025
7d35202
fix: set ime option as done
jvsena42 May 6, 2025
1d5d72d
Merge pull request #127 from synonymdev/fix/edit-invoice-keep-state
ovitrif May 6, 2025
9a041c9
refactor: change notification name and ID
jvsena42 May 7, 2025
c1c4d25
refactor: use initNotificationChannel
jvsena42 May 7, 2025
a1f7736
fix: add service permission
jvsena42 May 7, 2025
9766445
fix: move initAppStoragePath before service call
jvsena42 May 7, 2025
6a2cf13
fix: Round icon
jvsena42 May 7, 2025
6d95584
refactor: remove unused code
jvsena42 May 7, 2025
dc8bd92
fix: isRefreshing state update
jvsena42 May 7, 2025
761960c
refactor: updateBip21Invoice overload
jvsena42 May 7, 2025
b56085c
refactor:remove unnecessary setWalletExistsState calls
jvsena42 May 7, 2025
0971b2d
refactor: sync node only at specific events
jvsena42 May 7, 2025
fc1b041
refactor: restore observeLdkWallet logic
jvsena42 May 7, 2025
c0de93c
fix: call syncState and sync balance also before sync
jvsena42 May 8, 2025
2ef9e33
Merge branch 'master' into feat/keep-node-in-background
jvsena42 May 8, 2025
65579be
fix: solve conflicts
jvsena42 May 8, 2025
0d6ef4b
fix: sync balances at start
jvsena42 May 8, 2025
d305dd1
fix: stop node and reset lone state when wipe the wallet
jvsena42 May 8, 2025
37a6fd8
fix: log
jvsena42 May 8, 2025
e53e1a0
fix: move notification methods to LightningNodeService and add execut…
jvsena42 May 8, 2025
0fe84dd
fix: clear bip 21 state at start of refreshBip21
jvsena42 May 8, 2025
36de195
feat: add button to stop the service
jvsena42 May 8, 2025
29ba400
feat: move service intent to MainActivity
jvsena42 May 8, 2025
17af26a
test: update tests
jvsena42 May 8, 2025
531a167
test: update tests
jvsena42 May 8, 2025
cea53d0
test: update tests
jvsena42 May 8, 2025
1bfc621
test: update tests
jvsena42 May 8, 2025
47bc392
test: update tests
jvsena42 May 8, 2025
20824d7
test: update tests
jvsena42 May 9, 2025
509f51d
test: update tests
jvsena42 May 9, 2025
e5cba64
Merge branch 'master' into feat/keep-node-in-background
jvsena42 May 9, 2025
1262b70
test: implement bg image
jvsena42 May 9, 2025
17b4bf6
feat: fading animation
jvsena42 May 9, 2025
3e7aab6
feat: move softKeyboard logic to a keyboardAsState method
jvsena42 May 9, 2025
7ceda66
Merge pull request #132 from synonymdev/feat/bg-edit-invoice
ovitrif May 9, 2025
3a04a15
feat: preview
jvsena42 May 9, 2025
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
9 changes: 9 additions & 0 deletions app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.READ_MEDIA_IMAGES" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE_DATA_SYNC" />

<application
android:name=".App"
Expand All @@ -20,6 +22,12 @@
android:roundIcon="@mipmap/ic_launcher_regtest_round"
android:supportsRtl="true"
android:theme="@style/Theme.App">
<service
android:name=".androidServices.LightningNodeService"
android:foregroundServiceType="dataSync"
android:enabled="true"
android:exported="false"/>

<activity
android:name=".ui.MainActivity"
android:exported="true"
Expand All @@ -28,6 +36,7 @@
android:windowSoftInputMode="adjustResize|stateHidden">
<intent-filter>
<action android:name="android.intent.action.MAIN" />

<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
Expand Down
1 change: 0 additions & 1 deletion app/src/main/java/to/bitkit/App.kt
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@ internal open class App : Application(), Configuration.Provider {
override fun onCreate() {
super.onCreate()
currentActivity = CurrentActivity().also { registerActivityLifecycleCallbacks(it) }

Env.initAppStoragePath(filesDir.absolutePath)
}

Expand Down
125 changes: 125 additions & 0 deletions app/src/main/java/to/bitkit/androidServices/LightningNodeService.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
package to.bitkit.androidServices

import android.app.Notification
import android.app.PendingIntent
import android.app.Service
import android.content.Intent
import android.os.IBinder
import androidx.core.app.NotificationCompat
import dagger.hilt.android.AndroidEntryPoint
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.SupervisorJob
import kotlinx.coroutines.cancel
import kotlinx.coroutines.launch
import to.bitkit.App
import to.bitkit.R
import to.bitkit.repositories.LightningRepo
import to.bitkit.repositories.WalletRepo
import to.bitkit.ui.MainActivity
import to.bitkit.utils.Logger
import javax.inject.Inject

@AndroidEntryPoint
class LightningNodeService : Service() {

private val serviceScope = CoroutineScope(SupervisorJob() + Dispatchers.Main)

@Inject
lateinit var lightningRepo: LightningRepo

@Inject
lateinit var walletRepo: WalletRepo

override fun onCreate() {
super.onCreate()
startForeground(NOTIFICATION_ID, createNotification())
setupService()
}

private fun setupService() {
serviceScope.launch {
launch {
lightningRepo.start(
eventHandler = { event ->
walletRepo.refreshBip21ForEvent(event)
}
).onSuccess {
val notification = createNotification()
startForeground(NOTIFICATION_ID, notification)

walletRepo.setWalletExistsState()
walletRepo.refreshBip21()
walletRepo.syncBalances()
}
}
}
}

// Update the createNotification method in LightningNodeService.kt
private fun createNotification(
contentText: String = "Bitkit is running in background so you can receive Lightning payments"
): Notification {
val notificationIntent = Intent(this, MainActivity::class.java).apply {
flags = Intent.FLAG_ACTIVITY_CLEAR_TOP or Intent.FLAG_ACTIVITY_SINGLE_TOP
}
val pendingIntent = PendingIntent.getActivity(
this, 0, notificationIntent, PendingIntent.FLAG_IMMUTABLE
)

// Create stop action that will close both service and app
val stopIntent = Intent(this, LightningNodeService::class.java).apply {
action = ACTION_STOP_SERVICE_AND_APP
}
val stopPendingIntent = PendingIntent.getService(
this, 0, stopIntent, PendingIntent.FLAG_IMMUTABLE
)

return NotificationCompat.Builder(this, CHANNEL_ID_NODE)
.setContentTitle(getString(R.string.app_name))
.setContentText(contentText)
.setSmallIcon(R.drawable.ic_launcher_fg_regtest)
.setContentIntent(pendingIntent)
.addAction(
R.drawable.ic_x,
"Stop App", // TODO: Get from resources
stopPendingIntent
)
.build()
}

// Update the onStartCommand method
override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
Logger.debug("onStartCommand", context = TAG)
when (intent?.action) {
ACTION_STOP_SERVICE_AND_APP -> {
Logger.debug("ACTION_STOP_SERVICE_AND_APP detected", context = TAG)
// Close all activities
App.currentActivity?.value?.finishAffinity()
// Stop the service
stopSelf()
return START_NOT_STICKY
}
}
return START_STICKY
}

override fun onDestroy() {
Logger.debug("onDestroy", context = TAG)
serviceScope.launch {
lightningRepo.stop().onSuccess {
serviceScope.cancel()
}
}
super.onDestroy()
}

override fun onBind(intent: Intent?): IBinder? = null

companion object {
private const val NOTIFICATION_ID = 1
const val CHANNEL_ID_NODE = "bitkit_notification_channel_node"
const val TAG = "LightningNodeService"
const val ACTION_STOP_SERVICE_AND_APP = "to.bitkit.androidServices.action.STOP_SERVICE_AND_APP"
}
}
20 changes: 20 additions & 0 deletions app/src/main/java/to/bitkit/di/EnvModule.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
@file:Suppress("unused")

package to.bitkit.di

import dagger.Module
import dagger.Provides
import dagger.hilt.InstallIn
import dagger.hilt.components.SingletonComponent
import org.lightningdevkit.ldknode.Network
import to.bitkit.env.Env

@Module
@InstallIn(SingletonComponent::class)
object EnvModule {

@Provides
fun provideNetwork(): Network {
return Env.network
}
}
Loading