Skip to content

Commit

Permalink
Merge branch 'master' into mainnet
Browse files Browse the repository at this point in the history
  • Loading branch information
dpad85 committed Jul 2, 2024
2 parents 88120cc + 2fe74ee commit 34e1a34
Show file tree
Hide file tree
Showing 105 changed files with 3,948 additions and 490 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/testnet-build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ name: Build
on:
workflow_dispatch:
push:
branches: [ master, test-ci-build ]
branches: [ master, test-ci-build, offer ]
paths:
- 'phoenix-legacy/**'
- 'phoenix-android/**'
Expand Down
2 changes: 1 addition & 1 deletion buildSrc/src/main/kotlin/Versions.kt
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
object Versions {
const val lightningKmp = "1.6.3"
const val lightningKmp = "1.7.0"
const val secp256k1 = "0.14.0"
const val torMobile = "0.2.0"

Expand Down
5 changes: 3 additions & 2 deletions phoenix-android/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,8 @@ android {
applicationId = "fr.acinq.phoenix.mainnet"
minSdk = 26
targetSdk = 34
versionCode = 80
versionName = "2.2.4"
versionCode = 81
versionName = gitCommitHash()
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
resourceConfigurations.addAll(listOf("en", "fr", "de", "es", "b+es+419", "cs", "pt-rBR", "sk", "vi"))
}
Expand Down Expand Up @@ -136,6 +136,7 @@ dependencies {

// firebase cloud messaging
implementation("com.google.firebase:firebase-messaging:${Versions.Android.fcm}")
implementation("com.google.android.gms:play-services-base:18.5.0")

implementation("com.google.guava:listenablefuture:9999.0-empty-to-avoid-conflict-with-guava")

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ import com.google.accompanist.permissions.ExperimentalPermissionsApi
import com.google.accompanist.permissions.isGranted
import com.google.accompanist.permissions.rememberPermissionState
import com.google.firebase.messaging.FirebaseMessaging
import fr.acinq.lightning.db.IncomingPayment
import fr.acinq.lightning.utils.currentTimestampMillis
import fr.acinq.phoenix.PhoenixBusiness
import fr.acinq.phoenix.android.components.Button
Expand Down Expand Up @@ -89,6 +90,7 @@ import fr.acinq.phoenix.android.settings.walletinfo.SwapInWallet
import fr.acinq.phoenix.android.settings.walletinfo.WalletInfoView
import fr.acinq.phoenix.android.startup.LegacySwitcherView
import fr.acinq.phoenix.android.startup.StartupView
import fr.acinq.phoenix.android.utils.SystemNotificationHelper
import fr.acinq.phoenix.android.utils.appBackground
import fr.acinq.phoenix.android.utils.logger
import fr.acinq.phoenix.data.BitcoinUnit
Expand Down Expand Up @@ -149,7 +151,6 @@ fun AppView(
factory = NoticesViewModel.Factory(
appConfigurationManager = business.appConfigurationManager,
peerManager = business.peerManager,
internalDataRepository = internalData
)
)
MonitorNotices(vm = noticesViewModel)
Expand Down Expand Up @@ -248,7 +249,11 @@ fun AppView(
)
}
composable(
Screen.ScanData.route, deepLinks = listOf(
route = "${Screen.ScanData.route}?input={input}",
arguments = listOf(
navArgument("input") { type = NavType.StringType ; nullable = true },
),
deepLinks = listOf(
navDeepLink { uriPattern = "lightning:{data}" },
navDeepLink { uriPattern = "bitcoin:{data}" },
navDeepLink { uriPattern = "lnurl:{data}" },
Expand All @@ -260,6 +265,7 @@ fun AppView(
navDeepLink { uriPattern = "scanview:{data}" },
)
) {
log.info("input arg=${it.arguments?.getString("input")}")
val intent = try {
it.arguments?.getParcelable<Intent>(NavController.KEY_DEEP_LINK_INTENT)
} catch (e: Exception) {
Expand All @@ -270,12 +276,13 @@ fun AppView(
// prevents forwarding an internal deeplink intent coming from androidx-navigation framework.
// TODO properly parse deeplinks following f0ae90444a23cc17d6d7407dfe43c0c8d20e62fc
!it.contains("androidx.navigation")
}
} ?: it.arguments?.getString("input")
ScanDataView(
input = input,
onBackClick = { popToHome(navController) },
onBackClick = { navController.popBackStack() },
onAuthSchemeInfoClick = { navController.navigate("${Screen.PaymentSettings.route}/true") },
onFeeManagementClick = { navController.navigate(Screen.LiquidityPolicy.route) },
onProcessingFinished = { popToHome(navController) },
)
}
}
Expand Down Expand Up @@ -303,8 +310,10 @@ fun AppView(
paymentId = paymentId,
onBackClick = {
val previousNav = navController.previousBackStackEntry
if (!navController.popBackStack() || (fromEvent && previousNav?.destination?.route == Screen.ScanData.route)) {
if (fromEvent && previousNav?.destination?.route == Screen.ScanData.route) {
popToHome(navController)
} else {
navController.popBackStack()
}
},
fromEvent = fromEvent
Expand Down Expand Up @@ -464,17 +473,27 @@ fun AppView(
)
}
}
composable(Screen.Contacts.route) {
SettingsContactsView(onBackClick = { navController.popBackStack() })
}
}
}
}

val isDataMigrationExpected by LegacyPrefsDatastore.getDataMigrationExpected(context).collectAsState(initial = null)
val lastCompletedPayment by business.paymentsManager.lastCompletedPayment.collectAsState()
lastCompletedPayment?.let {
// log.debug { "completed payment=${lastCompletedPayment?.id()} with data-migration=$isDataMigrationExpected" }
LaunchedEffect(key1 = it.walletPaymentId()) {
val userPrefs = userPrefs
val exchangeRates = fiatRates
lastCompletedPayment?.let { payment ->
LaunchedEffect(key1 = payment.walletPaymentId()) {
if (isDataMigrationExpected == false) {
navigateToPaymentDetails(navController, id = it.walletPaymentId(), isFromEvent = true)
if (payment is IncomingPayment && payment.origin is IncomingPayment.Origin.Offer) {
SystemNotificationHelper.notifyPaymentsReceived(
context, userPrefs, paymentHash = payment.paymentHash, amount = payment.amount, rates = exchangeRates, isHeadless = false
)
} else {
navigateToPaymentDetails(navController, id = payment.walletPaymentId(), isFromEvent = true)
}
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ sealed class Screen(val route: String) {
data object LiquidityRequest: Screen("settings/requestliquidity")
data object AdvancedLiquidityPolicy: Screen("settings/advancedliquiditypolicy")
data object Notifications: Screen("notifications")
data object Contacts: Screen("settings/contacts")
data object ResetWallet: Screen("settings/resetwallet")
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,19 @@

package fr.acinq.phoenix.android

import android.content.BroadcastReceiver
import android.content.Context
import android.content.Intent
import android.content.IntentFilter
import android.os.PowerManager
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateListOf
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.setValue
import androidx.lifecycle.ViewModel
import androidx.lifecycle.ViewModelProvider
import androidx.lifecycle.viewModelScope
import androidx.lifecycle.viewmodel.CreationExtras
import fr.acinq.phoenix.android.utils.datastore.InternalDataRepository
import fr.acinq.phoenix.data.WalletNotice
import fr.acinq.phoenix.managers.AppConfigurationManager
Expand All @@ -33,29 +42,52 @@ sealed class Notice() {
abstract val priority: Int
sealed class ShowInHome(override val priority: Int) : Notice()

object MigrationFromLegacy : ShowInHome(1)
data object MigrationFromLegacy : ShowInHome(1)
data class RemoteMessage(val notice: WalletNotice) : ShowInHome(1)
object CriticalUpdateAvailable : ShowInHome(2)
object SwapInCloseToTimeout : ShowInHome(3)
object BackupSeedReminder : ShowInHome(5)
object MempoolFull : ShowInHome(10)
object UpdateAvailable : ShowInHome(20)
object NotificationPermission : ShowInHome(30)
data object CriticalUpdateAvailable : ShowInHome(2)
data object SwapInCloseToTimeout : ShowInHome(3)
data object BackupSeedReminder : ShowInHome(5)
data object MempoolFull : ShowInHome(10)
data object UpdateAvailable : ShowInHome(20)
data object NotificationPermission : ShowInHome(30)

// less important notices
sealed class DoNotShowInHome(override val priority: Int = 999) : Notice()
object WatchTowerLate : DoNotShowInHome()
data object WatchTowerLate : DoNotShowInHome()
}

class NoticesViewModel(val appConfigurationManager: AppConfigurationManager, val peerManager: PeerManager, val internalDataRepository: InternalDataRepository) : ViewModel() {
class NoticesViewModel(
val appConfigurationManager: AppConfigurationManager,
val peerManager: PeerManager,
val internalDataRepository: InternalDataRepository,
val context: Context

) : ViewModel() {
private val log = LoggerFactory.getLogger(this::class.java)

val notices = mutableStateListOf<Notice>()
var isPowerSaverModeOn by mutableStateOf(false)

private val receiver = object : BroadcastReceiver() {
override fun onReceive(context: Context, intent: Intent?) {
val powerManager = context.getSystemService(Context.POWER_SERVICE) as PowerManager
log.info("power_saver=${powerManager.isPowerSaveMode}")
isPowerSaverModeOn = powerManager.isPowerSaveMode
}
}

init {
viewModelScope.launch { monitorWalletContext() }
viewModelScope.launch { monitorSwapInCloseToTimeout() }
viewModelScope.launch { monitorWalletNotice() }
val powerManager = context.getSystemService(Context.POWER_SERVICE) as PowerManager
isPowerSaverModeOn = powerManager.isPowerSaveMode
context.registerReceiver(receiver, IntentFilter(PowerManager.ACTION_POWER_SAVE_MODE_CHANGED))
}

override fun onCleared() {
super.onCleared()
context.unregisterReceiver(receiver)
}

fun addNotice(notice: Notice) {
Expand All @@ -70,7 +102,7 @@ class NoticesViewModel(val appConfigurationManager: AppConfigurationManager, val

private suspend fun monitorWalletContext() {
appConfigurationManager.walletContext.collect {
log.debug("collecting wallet-context=$it")
log.debug("collecting wallet-context={}", it)
val isMempoolFull = it?.isMempoolFull ?: false
val isUpdateAvailable = it?.androidLatestVersion?.let { it > BuildConfig.VERSION_CODE } ?: false
val isCriticalUpdateAvailable = it?.androidLatestCriticalVersion?.let { it > BuildConfig.VERSION_CODE } ?: false
Expand Down Expand Up @@ -98,7 +130,7 @@ class NoticesViewModel(val appConfigurationManager: AppConfigurationManager, val
combine(appConfigurationManager.walletNotice, internalDataRepository.getLastReadWalletNoticeIndex) { notice, lastReadIndex ->
notice to lastReadIndex
}.collect { (notice, lastReadIndex) ->
log.debug("collecting wallet-notice=$notice")
log.debug("collecting wallet-notice={}", notice)
if (notice != null && notice.index > lastReadIndex) {
addNotice(Notice.RemoteMessage(notice))
} else {
Expand All @@ -119,11 +151,15 @@ class NoticesViewModel(val appConfigurationManager: AppConfigurationManager, val
class Factory(
private val appConfigurationManager: AppConfigurationManager,
private val peerManager: PeerManager,
private val internalDataRepository: InternalDataRepository,
) : ViewModelProvider.Factory {
override fun <T : ViewModel> create(modelClass: Class<T>): T {
override fun <T : ViewModel> create(modelClass: Class<T>, extras: CreationExtras): T {
val application = checkNotNull(extras[ViewModelProvider.AndroidViewModelFactory.APPLICATION_KEY] as? PhoenixApplication)
@Suppress("UNCHECKED_CAST")
return NoticesViewModel(appConfigurationManager, peerManager, internalDataRepository) as T
return NoticesViewModel(
appConfigurationManager, peerManager,
internalDataRepository = application.internalDataRepository,
application.applicationContext
) as T
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ fun BorderButton(
enabled: Boolean = true,
enabledEffect: Boolean = true,
space: Dp = 12.dp,
maxLines: Int = Int.MAX_VALUE,
textStyle: TextStyle = MaterialTheme.typography.button,
padding: PaddingValues = PaddingValues(horizontal = 16.dp, vertical = 12.dp),
interactionSource: MutableInteractionSource = remember { MutableInteractionSource() },
Expand All @@ -85,6 +86,7 @@ fun BorderButton(
border = BorderStroke(ButtonDefaults.OutlinedBorderSize, if (enabled) borderColor else borderColor.copy(alpha = 0.4f)),
textStyle = textStyle,
padding = padding,
maxLines = maxLines,
interactionSource = interactionSource,
modifier = modifier
)
Expand All @@ -99,6 +101,7 @@ fun FilledButton(
iconTint: Color = MaterialTheme.colors.onPrimary,
maxLines: Int = Int.MAX_VALUE,
enabled: Boolean = true,
enabledEffect: Boolean = true,
space: Dp = 12.dp,
shape: Shape = CircleShape,
textStyle: TextStyle = MaterialTheme.typography.button.copy(color = MaterialTheme.colors.onPrimary),
Expand All @@ -112,6 +115,7 @@ fun FilledButton(
iconTint = iconTint,
maxLines = maxLines,
enabled = enabled,
enabledEffect = enabledEffect,
space = space,
onClick = onClick,
shape = shape,
Expand Down Expand Up @@ -298,7 +302,7 @@ fun Button(
Row(
Modifier
.defaultMinSize(
minWidth = 42.dp,
minWidth = 0.dp,
minHeight = 0.dp
)
.indication(interactionSource, LocalIndication.current)
Expand All @@ -323,7 +327,7 @@ fun Button(
} else if (text != null) {
Text(text = text, maxLines = maxLines, overflow = TextOverflow.Ellipsis)
} else if (icon != null) {
PhoenixIcon(resourceId = icon, tint = iconTint, modifier = Modifier.padding(vertical = 1.dp))
PhoenixIcon(resourceId = icon, tint = iconTint)
}
}
)
Expand Down
Loading

0 comments on commit 34e1a34

Please sign in to comment.