Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

external ledger #119

Open
wants to merge 14 commits into
base: feature/ledger_usb
Choose a base branch
from
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,13 @@ package com.tonapps.wallet.data.collectibles.entities

import android.net.Uri
import android.os.Parcelable
import androidx.core.net.toUri
import com.tonapps.blockchain.ton.extensions.equalsAddress
import com.tonapps.blockchain.ton.extensions.toUserFriendly
import com.tonapps.wallet.api.entity.AccountEntity
import com.tonapps.wallet.data.core.Trust
import io.tonapi.models.NftItem
import kotlinx.parcelize.IgnoredOnParcel
import kotlinx.parcelize.Parcelize

@Parcelize
Expand Down Expand Up @@ -56,18 +58,26 @@ data class NftEntity(
val ownerAddress: String
get() = owner?.address ?: address

@IgnoredOnParcel
val thumbUri: Uri by lazy {
getImageUri(64, 320) ?: previews.first().url.let { Uri.parse(it) }
}

@IgnoredOnParcel
val mediumUri: Uri by lazy {
getImageUri(256, 512) ?: previews.first().url.let { Uri.parse(it) }
}

@IgnoredOnParcel
val bigUri: Uri by lazy {
getImageUri(512, 1024) ?: previews.last().url.let { Uri.parse(it) }
}

@IgnoredOnParcel
val lottieUri: Uri? by lazy {
metadata.lottie?.toUri()
}

val isTrusted: Boolean
get() = trust == Trust.whitelist

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,9 @@ data class NftMetadataEntity(
val description: String?
get() = strings["description"]

val lottie: String?
get() = strings["lottie"]

constructor(map: Map<String, Any>) : this(
strings = map.filter { it.value is String }.mapValues { it.value as String } as HashMap<String, String>,
buttons = map["buttons"]?.let { buttons ->
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ class SettingsRepository(
private const val SHOW_SAFE_MODE_SETUP_KEY = "show_safe_mode_setup"
private const val ADDRESS_COPY_COUNT_KEY = "address_copy_count"
private const val STORIES_VIEWED_PREFIX = "stories_viewed_"
private const val LEDGER_CONNECT_USB = "ledger_connect_usb"
}

private val _currencyFlow = MutableEffectFlow<WalletCurrency>()
Expand Down Expand Up @@ -112,6 +113,14 @@ class SettingsRepository(
id
}

var ledgerConnectUsb: Boolean = prefs.getBoolean(LEDGER_CONNECT_USB, false)
set(value) {
if (value != field) {
prefs.edit().putBoolean(LEDGER_CONNECT_USB, value).apply()
field = value
}
}

var searchEngine: SearchEngine = SearchEngine(prefs.getString(SEARCH_ENGINE_KEY, "Google")!!)
set(value) {
if (value != field) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -191,7 +191,7 @@ data class TransferEntity(
}
val builder = TransactionBuilder()
if (isNft) {
builder.setCoins(coins)
builder.setCoins(jettonTransferAmount.toGrams())
builder.setDestination(AddrStd.parse(nftAddress!!))
builder.setPayload(
TonPayloadFormat.NftTransfer(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import android.content.res.Configuration
import android.net.Uri
import android.os.Build
import android.os.PersistableBundle
import android.provider.Settings
import android.text.Spannable
import android.text.SpannableString
import android.text.SpannableStringBuilder
Expand Down Expand Up @@ -182,4 +183,11 @@ fun Context.debugToast(text: String) {
if (BuildConfig.DEBUG) {
Navigation.from(this)?.toast(text)
}
}

fun Context.openAppSettings() {
val intent = Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS)
intent.setData(Uri.fromParts("package", packageName, null))
intent.flags = Intent.FLAG_ACTIVITY_NEW_TASK
startActivity(intent)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
package com.tonapps.tonkeeper.ui.component

import android.content.Context
import android.net.Uri
import android.os.Build
import android.util.AttributeSet
import android.webkit.WebSettings
import android.webkit.WebView
import android.webkit.WebViewClient
import com.tonapps.extensions.rawText
import com.tonapps.tonkeeperx.R

class LottieView @JvmOverloads constructor(
context: Context,
attrs: AttributeSet? = null,
defStyle: Int = 0,
) : WebView(context, attrs, defStyle) {

var doOnReady: (() -> Unit)? = null

init {
settings.apply {
javaScriptEnabled = true
allowFileAccess = false
allowContentAccess = false
domStorageEnabled = true
cacheMode = WebSettings.LOAD_NO_CACHE
displayZoomControls = false
builtInZoomControls = false
setSupportZoom(false)
setEnableSmoothTransition(false)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
setRendererPriorityPolicy(RENDERER_PRIORITY_IMPORTANT, true)
}
}

isVerticalScrollBarEnabled = false
isHorizontalScrollBarEnabled = false
overScrollMode = OVER_SCROLL_NEVER

setBackgroundColor(0x00000000)
setLayerType(LAYER_TYPE_HARDWARE, null)

setInitialScale(100)

webViewClient = object : WebViewClient() {
override fun onPageFinished(view: WebView?, url: String?) {
doOnReady?.invoke()
}
}
}

fun setUri(uri: Uri) {
val data = loadHtml(context).replace("{lottieUrl}", uri.toString())
loadDataWithBaseURL(null, data, "text/html", "utf-8", null)
}

override fun onDetachedFromWindow() {
clearCache(true)
clearHistory()
super.onDetachedFromWindow()
}


override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
super.onMeasure(widthMeasureSpec, widthMeasureSpec)
}

private companion object {

@Volatile
private var cachedLottie: String? = null

private fun loadHtml(context: Context): String {
return cachedLottie ?: synchronized(this) {
cachedLottie ?: context.rawText(R.raw.lottie_webview).also {
cachedLottie = it
}
}
}
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
package com.tonapps.tonkeeper.ui.component.ledger

import android.content.Context
import android.util.AttributeSet
import android.view.View
import androidx.appcompat.widget.AppCompatTextView
import com.tonapps.tonkeeperx.R
import uikit.widget.RowLayout

class LedgerTaskView @JvmOverloads constructor(
context: Context,
attrs: AttributeSet? = null,
defStyle: Int = 0,
) : RowLayout(context, attrs, defStyle) {

private val dotIconView: View
private val doneIconView: View
private val loaderView: View
private val labelView: AppCompatTextView

var label: CharSequence
get() = labelView.text
set(value) {
labelView.text = value
}

init {
inflate(context, R.layout.view_ledger_task, this)

dotIconView = findViewById(R.id.dot_icon)
doneIconView = findViewById(R.id.done_icon)
loaderView = findViewById(R.id.loader)
labelView = findViewById(R.id.label)
}

fun setDefault() {
dotIconView.visibility = View.VISIBLE
doneIconView.visibility = View.GONE
loaderView.visibility = View.GONE
}

fun setDone() {
dotIconView.visibility = View.GONE
doneIconView.visibility = View.VISIBLE
loaderView.visibility = View.GONE
}

fun setLoading() {
dotIconView.visibility = View.GONE
doneIconView.visibility = View.GONE
loaderView.visibility = View.VISIBLE
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import android.view.View
import androidx.lifecycle.lifecycleScope
import com.tonapps.tonkeeper.extensions.toast
import com.tonapps.tonkeeper.ui.screen.ledger.steps.LedgerConnectionFragment
import com.tonapps.tonkeeper.ui.screen.ledger.steps.LedgerConnectionType
import com.tonapps.tonkeeper.ui.screen.ledger.steps.LedgerConnectionViewModel
import com.tonapps.tonkeeper.ui.screen.ledger.steps.LedgerEvent
import com.tonapps.tonkeeper.ui.screen.root.RootViewModel
Expand Down Expand Up @@ -33,6 +34,8 @@ class PairLedgerScreen : BaseFragment(R.layout.fragment_ledger_pair), BaseFragme
}

private lateinit var continueButton: LoadableButton
private lateinit var tabUsbView: View
private lateinit var tabBluetoothView: View

override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
Expand All @@ -42,6 +45,12 @@ class PairLedgerScreen : BaseFragment(R.layout.fragment_ledger_pair), BaseFragme

continueButton = view.findViewById(R.id.continue_button)

tabUsbView = view.findViewById(R.id.tab_usb)
tabUsbView.setOnClickListener { connectionViewModel.setConnectionType(LedgerConnectionType.USB) }

tabBluetoothView = view.findViewById(R.id.tab_bluetooth)
tabBluetoothView.setOnClickListener { connectionViewModel.setConnectionType(LedgerConnectionType.BLUETOOTH) }

view.findViewById<View>(R.id.close).setOnClickListener { finish() }
view.findViewById<View>(R.id.cancel).setOnClickListener { finish() }
continueButton.isEnabled = false
Expand All @@ -55,6 +64,20 @@ class PairLedgerScreen : BaseFragment(R.layout.fragment_ledger_pair), BaseFragme
}

collectFlow(connectionViewModel.eventFlow, ::onEvent)
collectFlow(connectionViewModel.connectionType, ::onConnectionType)
}

private fun onConnectionType(type: LedgerConnectionType) {
when (type) {
LedgerConnectionType.USB -> {
tabUsbView.setBackgroundResource(uikit.R.drawable.bg_button_tertiary)
tabBluetoothView.background = null
}
LedgerConnectionType.BLUETOOTH -> {
tabUsbView.background = null
tabBluetoothView.setBackgroundResource(uikit.R.drawable.bg_button_tertiary)
}
}
}

private fun onEvent(event: LedgerEvent) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import com.tonapps.blockchain.ton.extensions.toByteArray
import com.tonapps.tonkeeper.extensions.toast
import com.tonapps.tonkeeper.ui.screen.ledger.sign.LedgerSignScreen.Companion.SIGNED_MESSAGE
import com.tonapps.tonkeeper.ui.screen.ledger.steps.LedgerConnectionFragment
import com.tonapps.tonkeeper.ui.screen.ledger.steps.LedgerConnectionType
import com.tonapps.tonkeeper.ui.screen.ledger.steps.LedgerConnectionViewModel
import com.tonapps.tonkeeper.ui.screen.ledger.steps.LedgerEvent
import com.tonapps.tonkeeper.ui.screen.ledger.update.LedgerUpdateScreen
Expand All @@ -33,6 +34,8 @@ class LedgerProofScreen : BaseFragment(R.layout.fragment_ledger_sign), BaseFragm
}

private var isSuccessful: Boolean = false
private lateinit var tabUsbView: View
private lateinit var tabBluetoothView: View

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
Expand All @@ -42,6 +45,11 @@ class LedgerProofScreen : BaseFragment(R.layout.fragment_ledger_sign), BaseFragm

override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
tabUsbView = view.findViewById(R.id.tab_usb)
tabUsbView.setOnClickListener { connectionViewModel.setConnectionType(LedgerConnectionType.USB) }

tabBluetoothView = view.findViewById(R.id.tab_bluetooth)
tabBluetoothView.setOnClickListener { connectionViewModel.setConnectionType(LedgerConnectionType.BLUETOOTH) }

view.findViewById<View>(R.id.container)
.applyNavBottomPadding(requireContext().getDimensionPixelSize(uikit.R.dimen.offsetMedium))
Expand All @@ -55,6 +63,20 @@ class LedgerProofScreen : BaseFragment(R.layout.fragment_ledger_sign), BaseFragm
}

collectFlow(connectionViewModel.eventFlow, ::onEvent)
collectFlow(connectionViewModel.connectionType, ::onConnectionType)
}

private fun onConnectionType(type: LedgerConnectionType) {
when (type) {
LedgerConnectionType.USB -> {
tabUsbView.setBackgroundResource(uikit.R.drawable.bg_button_tertiary)
tabBluetoothView.background = null
}
LedgerConnectionType.BLUETOOTH -> {
tabUsbView.background = null
tabBluetoothView.setBackgroundResource(uikit.R.drawable.bg_button_tertiary)
}
}
}

/*override fun onDestroy() {
Expand Down
Loading