Skip to content

Commit

Permalink
Merge pull request #5 from jvsena42/feat/home
Browse files Browse the repository at this point in the history
Feat/home
  • Loading branch information
jvsena42 authored Oct 25, 2024
2 parents fd7dfa1 + c8d1031 commit b4af45f
Show file tree
Hide file tree
Showing 26 changed files with 640 additions and 60 deletions.
18 changes: 9 additions & 9 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -26,17 +26,17 @@ jobs:
- name: Make gradlew executable
run: chmod +x gradlew

- name: Build with Gradle
- name: gradle wrapper
run: gradle wrapper

- name: Build with Gradle
run: ./gradlew build

# - name: Run tests
# run: ./gradlew test
#
# - name: Upload test report
# uses: actions/upload-artifact@v4
# with:
# name: unit_test_report
# path: app/build/reports/test/testDebugUnitTest/
- name: Run tests
run: ./gradlew test --scan

- name: Upload test report
uses: actions/upload-artifact@v4
with:
name: unit_test_report
path: app/build/reports/test/testDebugUnitTest/
2 changes: 2 additions & 0 deletions app/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,9 @@ dependencies {
implementation(project.dependencies.platform(libs.koin.bom))
implementation(libs.koin.core)
implementation(libs.koin.viewmodel)
implementation(libs.koin.compose)
implementation(libs.koin.android)
implementation(libs.koin.test)
testImplementation(libs.junit)
androidTestImplementation(libs.androidx.junit)
androidTestImplementation(libs.androidx.espresso.core)
Expand Down
7 changes: 7 additions & 0 deletions app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,11 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools">

<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE_DATA_SYNC" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />

<application
android:name=".FlorestaApplication"
android:allowBackup="true"
Expand All @@ -26,6 +31,8 @@
<service
android:name=".domain.floresta.FlorestaService"
android:enabled="true"
android:permission="android.permission.FOREGROUND_SERVICE_DATA_SYNC"
android:foregroundServiceType="dataSync"
android:exported="false" />
</application>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,15 @@ package com.github.jvsena42.floresta
import android.app.Application
import android.content.Context
import android.content.Intent
import android.util.Log
import com.github.jvsena42.floresta.domain.bitcoin.WalletManager
import com.github.jvsena42.floresta.domain.bitcoin.WalletRepository
import com.github.jvsena42.floresta.domain.bitcoin.WalletRepositoryImpl
import com.github.jvsena42.floresta.domain.floresta.FlorestaDaemon
import com.github.jvsena42.floresta.domain.floresta.FlorestaDaemonImpl
import com.github.jvsena42.floresta.domain.floresta.FlorestaService
import com.github.jvsena42.floresta.presentation.MainViewmodel
import org.koin.android.ext.koin.androidApplication
import com.github.jvsena42.floresta.presentation.ui.screens.home.HomeViewModel
import org.koin.android.ext.koin.androidContext
import org.koin.android.ext.koin.androidLogger
import org.koin.core.context.startKoin
Expand All @@ -20,7 +21,6 @@ import org.koin.dsl.module
class FlorestaApplication : Application() {
override fun onCreate() {
super.onCreate()
startService(Intent(this, FlorestaService::class.java))
startKoin {
androidLogger()
androidContext(this@FlorestaApplication)
Expand All @@ -29,14 +29,26 @@ class FlorestaApplication : Application() {
presentationModule
)
}
try {
startForegroundService(Intent(this, FlorestaService::class.java))
} catch (e: Exception) {
Log.e("FlorestaApplication", "onCreate: ", e)
}
}
}

private val presentationModule = module {
val presentationModule = module {
viewModel { MainViewmodel() }
viewModel {
HomeViewModel(
walletRepository = get<WalletRepository>(),
walletManager = get(),
florestaDaemon = get()
)
}
}

private val domainModule = module {
val domainModule = module {
single {
WalletManager(
dbPath = androidContext().filesDir.toString(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package com.github.jvsena42.floresta.domain.bitcoin

import android.util.Log
import com.github.jvsena42.floresta.domain.model.ChainPosition
import com.github.jvsena42.floresta.domain.model.Constants.PERSISTENCE_VERSION
import com.github.jvsena42.floresta.domain.model.TransactionDetails
import com.github.jvsena42.floresta.domain.model.TxType
import org.bitcoindevkit.Address
Expand Down Expand Up @@ -36,6 +37,9 @@ class WalletManager(

init {
setPathAndConnectDb(dbPath)
if (walletRepository.doesWalletExist()) {
loadWallet()
}
}

private fun isWalletInitialized() = ::wallet.isInitialized
Expand Down Expand Up @@ -87,22 +91,28 @@ class WalletManager(
}

fun loadWallet(): Result<Unit> {
val result = walletRepository.getInitialWalletData().onFailure { e ->
return@loadWallet Result.failure(e)
}
return try {
val result = walletRepository.getInitialWalletData().onFailure { e ->
return@loadWallet Result.failure(e)
}

val data = result.getOrNull() ?: return Result.failure(Exception())
val data = result.getOrNull() ?: return Result.failure(Exception())

val descriptor = Descriptor(data.descriptor, Network.SIGNET)
val changeDescriptor = Descriptor(data.descriptor, Network.SIGNET)
val descriptor = Descriptor(data.descriptor, Network.SIGNET)
val changeDescriptor = Descriptor(data.changeDescriptor, Network.SIGNET)

wallet = Wallet.load(
descriptor = descriptor,
changeDescriptor = changeDescriptor,
connection = dbConnection
)

return Result.success(Unit)
wallet = Wallet.load(
descriptor = descriptor,
changeDescriptor = changeDescriptor,
connection = dbConnection
)

return Result.success(Unit)
} catch (e: Exception) {
Log.e(TAG, "loadWallet: ", e)
return Result.failure(e)
}
}

fun recoverWallet(recoveryPhrase: String) {
Expand Down Expand Up @@ -236,6 +246,5 @@ class WalletManager(
companion object {
private const val TAG = "WalletObject"
const val ELECTRUM_ADDRESS = "127.0.0.1:50001"
const val PERSISTENCE_VERSION = "V1"
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ package com.github.jvsena42.floresta.domain.bitcoin

import android.content.SharedPreferences
import android.util.Log
import com.github.jvsena42.floresta.domain.bitcoin.WalletManager.Companion.PERSISTENCE_VERSION
import com.github.jvsena42.floresta.domain.model.Constants.PERSISTENCE_VERSION
import com.github.jvsena42.floresta.domain.model.PreferenceKeys
import com.github.jvsena42.floresta.domain.model.RequiredInitialWalletData

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,12 @@ import android.util.Log
import com.florestad.Config
import com.florestad.Florestad
import com.github.jvsena42.floresta.domain.bitcoin.WalletRepository
import kotlinx.coroutines.delay
import org.bitcoindevkit.Descriptor
import org.rustbitcoin.bitcoin.Network
import com.florestad.Network as FlorestaNetwork
import kotlin.let
import kotlin.time.Duration.Companion.seconds

interface FlorestaDaemon {
suspend fun start()
Expand Down Expand Up @@ -61,13 +63,15 @@ class FlorestaDaemonImpl(
override suspend fun restart() {
if (isRunning) {
stop()
delay(3.seconds)
start()
} else {
start()
}
}

override suspend fun stop() {
if (!isRunning) return
daemon.stop()
isRunning = false
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,13 @@
package com.github.jvsena42.floresta.domain.floresta

import android.app.Notification
import android.app.NotificationChannel
import android.app.NotificationManager
import android.app.Service
import android.content.Intent
import android.os.IBinder
import android.util.Log
import androidx.core.app.NotificationCompat
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.SupervisorJob
Expand All @@ -16,6 +20,37 @@ class FlorestaService : Service() {

private val florestaDaemon: FlorestaDaemon by inject()

override fun onCreate() {
super.onCreate()
startForeground(NOTIFICATION_ID, createNotification())
// Your service logic here...
}

private fun createNotification(): Notification {
val channelId = "floresta_service_channel"
val channelName = "Floresta Service"

// Create the NotificationChannel (for Android 8.0 and above)
val channel = NotificationChannel(
channelId,
channelName,
NotificationManager.IMPORTANCE_MIN
)
val notificationManager = getSystemService(NotificationManager::class.java)
notificationManager?.createNotificationChannel(channel)

// Build the notification
val notificationBuilder = NotificationCompat.Builder(this, channelId)
.setContentTitle("Floresta Service")
.setContentText("Service is running in the background")
// .setSmallIcon(R.drawable.notification_icon) // Replace with your notification icon
.setPriority(NotificationCompat.PRIORITY_MIN)
.setAutoCancel(false) // Prevent auto-dismissal
.setOngoing(true) // Indicate ongoing service

return notificationBuilder.build()
}

override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
Log.d(TAG, "onStartCommand: ")
try {
Expand Down Expand Up @@ -44,5 +79,6 @@ class FlorestaService : Service() {

companion object {
private const val TAG = "FlorestaService"
private const val NOTIFICATION_ID = 1000
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package com.github.jvsena42.floresta.domain.model

object Constants {
const val PERSISTENCE_VERSION = "V1"
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,37 +11,22 @@ import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.tooling.preview.Preview
import com.github.jvsena42.floresta.presentation.ui.screens.home.ScreenHome
import com.github.jvsena42.floresta.presentation.ui.theme.FlorestaTheme
import org.koin.androidx.compose.KoinAndroidContext

class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
enableEdgeToEdge()
setContent {
FlorestaTheme {
Scaffold(modifier = Modifier.fillMaxSize()) { innerPadding ->
Greeting(
name = "Android",
modifier = Modifier.padding(innerPadding)
)
KoinAndroidContext {
Scaffold(modifier = Modifier.fillMaxSize()) { innerPadding ->
ScreenHome(innerPadding)
}
}
}
}
}
}

@Composable
fun Greeting(name: String, modifier: Modifier = Modifier) {
Text(
text = "Hello $name!",
modifier = modifier
)
}

@Preview(showBackground = true)
@Composable
fun GreetingPreview() {
FlorestaTheme {
Greeting("Android")
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package com.github.jvsena42.floresta.presentation.ui.screens.home

data class HomeUIState(
val balanceBTC: String = "",
val balanceSats: String = "",
val transactions: List<TransactionVM> = listOf()
)
Loading

0 comments on commit b4af45f

Please sign in to comment.