Hackathon mid-point.

This commit is contained in:
Kevin Gorham 2020-06-27 03:46:47 -04:00
parent adda661311
commit baf3522e89
No known key found for this signature in database
GPG Key ID: CCA55602DF49FC38
27 changed files with 1492 additions and 0 deletions

View File

@ -0,0 +1,439 @@
package cash.z.ecc.android.ui.home
import android.content.Context
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.widget.TextView
import androidx.lifecycle.lifecycleScope
import cash.z.ecc.android.R
import cash.z.ecc.android.databinding.FragmentHomeBinding
import cash.z.ecc.android.di.viewmodel.activityViewModel
import cash.z.ecc.android.di.viewmodel.viewModel
import cash.z.ecc.android.ext.*
import cash.z.ecc.android.feedback.Report
import cash.z.ecc.android.feedback.Report.Tap.*
import cash.z.ecc.android.ui.base.BaseFragment
import cash.z.ecc.android.ui.home.OgHomeFragment.BannerAction.*
import cash.z.ecc.android.ui.send.SendViewModel
import cash.z.ecc.android.ui.setup.WalletSetupViewModel
import cash.z.ecc.android.ui.setup.WalletSetupViewModel.WalletSetupState.NO_SEED
import cash.z.ecc.android.sdk.Synchronizer
import cash.z.ecc.android.sdk.Synchronizer.Status.*
import cash.z.ecc.android.sdk.block.CompactBlockProcessor
import cash.z.ecc.android.sdk.ext.convertZatoshiToZecString
import cash.z.ecc.android.sdk.ext.convertZecToZatoshi
import cash.z.ecc.android.sdk.ext.safelyConvertToBigDecimal
import cash.z.ecc.android.sdk.ext.twig
import com.google.android.material.dialog.MaterialAlertDialogBuilder
import kotlinx.coroutines.delay
import kotlinx.coroutines.flow.*
import kotlinx.coroutines.isActive
import kotlinx.coroutines.launch
class OgHomeFragment : BaseFragment<FragmentHomeBinding>() {
override val screen = Report.Screen.HOME
private lateinit var numberPad: List<TextView>
private lateinit var uiModel: HomeViewModel.UiModel
private val walletSetup: WalletSetupViewModel by activityViewModel(false)
private val sendViewModel: SendViewModel by activityViewModel()
private val viewModel: HomeViewModel by viewModel()
lateinit var snake: MagicSnakeLoader
override fun inflate(inflater: LayoutInflater): FragmentHomeBinding =
FragmentHomeBinding.inflate(inflater)
//
// LifeCycle
//
override fun onAttach(context: Context) {
twig("HomeFragment.onAttach")
twig("ZZZ")
twig("ZZZ")
twig("ZZZ")
twig("ZZZ ===================== HOME FRAGMENT CREATED ==================================")
super.onAttach(context)
// this will call startSync either now or later (after initializing with newly created seed)
walletSetup.checkSeed().onEach {
twig("Checking seed")
if (it == NO_SEED) {
// interact with user to create, backup and verify seed
// leads to a call to startSync(), later (after accounts are created from seed)
twig("Seed not found, therefore, launching seed creation flow")
mainActivity?.safeNavigate(R.id.action_nav_home_to_nav_landing)
} else {
twig("Found seed. Re-opening existing wallet")
mainActivity?.startSync(walletSetup.openWallet())
}
}.launchIn(lifecycleScope)
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
twig("HomeFragment.onViewCreated uiModel: ${::uiModel.isInitialized} saved: ${savedInstanceState != null}")
with(binding) {
numberPad = arrayListOf(
buttonNumberPad0.asKey(),
buttonNumberPad1.asKey(),
buttonNumberPad2.asKey(),
buttonNumberPad3.asKey(),
buttonNumberPad4.asKey(),
buttonNumberPad5.asKey(),
buttonNumberPad6.asKey(),
buttonNumberPad7.asKey(),
buttonNumberPad8.asKey(),
buttonNumberPad9.asKey(),
buttonNumberPadDecimal.asKey(),
buttonNumberPadBack.asKey()
)
hitAreaReceive.onClickNavTo(R.id.action_nav_home_to_nav_profile) { tapped(HOME_PROFILE) }
textDetail.onClickNavTo(R.id.action_nav_home_to_nav_detail) { tapped(HOME_DETAIL) }
hitAreaScan.setOnClickListener {
mainActivity?.maybeOpenScan().also { tapped(HOME_SCAN) }
}
textBannerAction.setOnClickListener {
onBannerAction(BannerAction.from((it as? TextView)?.text?.toString()))
}
buttonSendAmount.setOnClickListener {
onSend().also { tapped(HOME_SEND) }
}
setSendAmount("0", false)
snake = MagicSnakeLoader(binding.lottieButtonLoading)
}
binding.buttonNumberPadBack.setOnLongClickListener {
onClearAmount().also { tapped(HOME_CLEAR_AMOUNT) }
true
}
if (::uiModel.isInitialized) {
twig("uiModel exists!")
onModelUpdated(null, uiModel)
}
}
private fun onClearAmount() {
if (::uiModel.isInitialized) {
resumedScope.launch {
binding.textSendAmount.text.apply {
while (uiModel.pendingSend != "0") {
viewModel.onChar('<')
delay(5)
}
}
}
}
}
override fun onResume() {
super.onResume()
// twig("HomeFragment.onResume resumeScope.isActive: ${resumedScope.isActive} $resumedScope")
// viewModel.initializeMaybe()
// onClearAmount()
// viewModel.uiModels.scanReduce { old, new ->
// onModelUpdated(old, new)
// new
// }.onCompletion {
// twig("uiModel.scanReduce completed.")
// }.catch { e ->
// twig("exception while processing uiModels $e")
// throw e
// }.launchIn(resumedScope)
//
// // TODO: see if there is a better way to trigger a refresh of the uiModel on resume
// // the latest one should just be in the viewmodel and we should just "resubscribe"
// // but for some reason, this doesn't always happen, which kind of defeats the purpose
// // of having a cold stream in the view model
// resumedScope.launch {
// viewModel.refreshBalance()
// }
}
override fun onSaveInstanceState(outState: Bundle) {
super.onSaveInstanceState(outState)
twig("HomeFragment.onSaveInstanceState")
if (::uiModel.isInitialized) {
// outState.putParcelable("uiModel", uiModel)
}
}
override fun onViewStateRestored(savedInstanceState: Bundle?) {
super.onViewStateRestored(savedInstanceState)
savedInstanceState?.let { inState ->
twig("HomeFragment.onViewStateRestored")
// onModelUpdated(HomeViewModel.UiModel(), inState.getParcelable("uiModel")!!)
}
}
//
// Public UI API
//
var isSendEnabled = false
fun setSendEnabled(enabled: Boolean, isSynced: Boolean) {
isSendEnabled = enabled
binding.buttonSendAmount.apply {
if (enabled || !isSynced) {
isEnabled = true
isClickable = isSynced
binding.lottieButtonLoading.alpha = 1.0f
} else {
isEnabled = false
isClickable = false
binding.lottieButtonLoading.alpha = 0.32f
}
}
}
fun setProgress(uiModel: HomeViewModel.UiModel) {
if (!uiModel.processorInfo.hasData && !uiModel.isDisconnected) {
twig("Warning: ignoring progress update because the processor is still starting.")
return
}
snake.isSynced = uiModel.isSynced
if (!uiModel.isSynced) {
snake.downloadProgress = uiModel.downloadProgress
snake.scanProgress = uiModel.scanProgress
}
val sendText = when {
uiModel.status == DISCONNECTED -> "Reconnecting . . ."
uiModel.isSynced -> if (uiModel.hasFunds) "SEND AMOUNT" else "NO FUNDS AVAILABLE"
uiModel.status == STOPPED -> "IDLE"
uiModel.isDownloading -> "Downloading . . . ${snake.downloadProgress}%"
uiModel.isValidating -> "Validating . . ."
uiModel.isScanning -> "Scanning . . . ${snake.scanProgress}%"
else -> "Updating"
}
binding.buttonSendAmount.text = sendText
twig("Send button set to: $sendText")
val resId = if (uiModel.isSynced) R.color.selector_button_text_dark else R.color.selector_button_text_light
binding.buttonSendAmount.setTextColor(resources.getColorStateList(resId))
binding.lottieButtonLoading.invisibleIf(uiModel.isDisconnected)
}
/**
* @param amount the amount to send represented as ZEC, without the dollar sign.
*/
fun setSendAmount(amount: String, updateModel: Boolean = true) {
binding.textSendAmount.text = "\$$amount".toColoredSpan(R.color.text_light_dimmed, "$")
if (updateModel) {
sendViewModel.zatoshiAmount = amount.safelyConvertToBigDecimal().convertZecToZatoshi()
}
binding.buttonSendAmount.disabledIf(amount == "0")
}
fun setAvailable(availableBalance: Long = -1L, totalBalance: Long = -1L) {
val missingBalance = availableBalance < 0
val availableString = if (missingBalance) "Updating" else availableBalance.convertZatoshiToZecString()
binding.textBalanceAvailable.text = availableString
binding.textBalanceAvailable.transparentIf(missingBalance)
binding.labelBalance.transparentIf(missingBalance)
binding.textBalanceDescription.apply {
goneIf(missingBalance)
text = if (availableBalance != -1L && (availableBalance < totalBalance)) {
val change = (totalBalance - availableBalance).convertZatoshiToZecString()
"(expecting +$change ZEC)".toColoredSpan(R.color.text_light, "+$change")
} else {
"(enter an amount to send)"
}
}
}
fun setBanner(message: String = "", action: BannerAction = CLEAR) {
with(binding) {
val hasMessage = !message.isEmpty() || action != CLEAR
groupBalance.goneIf(hasMessage)
groupBanner.goneIf(!hasMessage)
layerLock.goneIf(!hasMessage)
textBannerMessage.text = message
textBannerAction.text = action.action
}
}
//
// Private UI Events
//
private fun onModelUpdated(old: HomeViewModel.UiModel?, new: HomeViewModel.UiModel) {
logUpdate(old, new)
uiModel = new
if (old?.pendingSend != new.pendingSend) {
setSendAmount(new.pendingSend)
}
setProgress(uiModel) // TODO: we may not need to separate anymore
// if (new.status = SYNCING) onSyncing(new) else onSynced(new)
if (new.status == SYNCED) onSynced(new) else onSyncing(new)
setSendEnabled(new.isSendEnabled, new.status == SYNCED)
}
private fun logUpdate(old: HomeViewModel.UiModel?, new: HomeViewModel.UiModel) {
var message = ""
fun maybeComma() = if (message.length > "UiModel(".length) ", " else ""
message = when {
old == null -> "$new"
new == null -> "null"
else -> {
buildString {
append("UiModel(")
if (old.status != new.status) append ("status=${new.status}")
if (old.processorInfo != new.processorInfo) {
append ("${maybeComma()}processorInfo=ProcessorInfo(")
val startLength = length
fun innerComma() = if (length > startLength) ", " else ""
if (old.processorInfo.networkBlockHeight != new.processorInfo.networkBlockHeight) append("networkBlockHeight=${new.processorInfo.networkBlockHeight}")
if (old.processorInfo.lastScannedHeight != new.processorInfo.lastScannedHeight) append("${innerComma()}lastScannedHeight=${new.processorInfo.lastScannedHeight}")
if (old.processorInfo.lastDownloadedHeight != new.processorInfo.lastDownloadedHeight) append("${innerComma()}lastDownloadedHeight=${new.processorInfo.lastDownloadedHeight}")
if (old.processorInfo.lastDownloadRange != new.processorInfo.lastDownloadRange) append("${innerComma()}lastDownloadRange=${new.processorInfo.lastDownloadRange}")
if (old.processorInfo.lastScanRange != new.processorInfo.lastScanRange) append("${innerComma()}lastScanRange=${new.processorInfo.lastScanRange}")
append(")")
}
if (old.availableBalance != new.availableBalance) append ("${maybeComma()}availableBalance=${new.availableBalance}")
if (old.totalBalance != new.totalBalance) append ("${maybeComma()}totalBalance=${new.totalBalance}")
if (old.pendingSend != new.pendingSend) append ("${maybeComma()}pendingSend=${new.pendingSend}")
append(")")
}
}
}
twig("onModelUpdated: $message")
}
private fun onSyncing(uiModel: HomeViewModel.UiModel) {
setAvailable()
}
private fun onSynced(uiModel: HomeViewModel.UiModel) {
snake.isSynced = true
if (!uiModel.hasBalance) {
onNoFunds()
} else {
setBanner("")
setAvailable(uiModel.availableBalance, uiModel.totalBalance)
}
}
private fun onSend() {
if (isSendEnabled) mainActivity?.safeNavigate(R.id.action_nav_home_to_send)
}
private fun onBannerAction(action: BannerAction) {
when (action) {
FUND_NOW -> {
MaterialAlertDialogBuilder(requireActivity())
.setMessage("To make full use of this wallet, deposit funds to your address.")
.setTitle("No Balance")
.setCancelable(true)
.setPositiveButton("View Address") { dialog, _ ->
tapped(HOME_FUND_NOW)
dialog.dismiss()
mainActivity?.safeNavigate(R.id.action_nav_home_to_nav_receive)
}
.show()
// MaterialAlertDialogBuilder(activity)
// .setMessage("To make full use of this wallet, deposit funds to your address or tap the faucet to trigger a tiny automatic deposit.\n\nFaucet funds are made available for the community by the community for testing. So please be kind enough to return what you borrow!")
// .setTitle("No Balance")
// .setCancelable(true)
// .setPositiveButton("Tap Faucet") { dialog, _ ->
// dialog.dismiss()
// setBanner("Tapping faucet...", CANCEL)
// }
// .setNegativeButton("View Address") { dialog, _ ->
// dialog.dismiss()
// mainActivity?.safeNavigate(R.id.action_nav_home_to_nav_receive)
// }
// .show()
}
CANCEL -> {
// TODO: trigger banner / balance update
onNoFunds()
}
}
}
private fun onNoFunds() {
setBanner("No Balance", FUND_NOW)
}
//
// Inner classes and extensions
//
enum class BannerAction(val action: String) {
FUND_NOW(""),
CANCEL("Cancel"),
NONE(""),
CLEAR("clear");
companion object {
fun from(action: String?): BannerAction {
values().forEach {
if (it.action == action) return it
}
throw IllegalArgumentException("Invalid BannerAction: $action")
}
}
}
private fun TextView.asKey(): TextView {
val c = text[0]
setOnClickListener {
lifecycleScope.launch {
twig("CHAR TYPED: $c")
viewModel.onChar(c)
}
}
return this
}
// TODO: remove these troubleshooting logs
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
twig("HomeFragment.onCreate")
}
override fun onActivityCreated(savedInstanceState: Bundle?) {
super.onActivityCreated(savedInstanceState)
twig("HomeFragment.onActivityCreated")
}
override fun onStart() {
super.onStart()
twig("HomeFragment.onStart")
}
override fun onPause() {
super.onPause()
twig("HomeFragment.onPause resumeScope.isActive: ${resumedScope.isActive}")
}
override fun onStop() {
super.onStop()
twig("HomeFragment.onStop")
}
override fun onDestroyView() {
super.onDestroyView()
twig("HomeFragment.onDestroyView")
}
override fun onDestroy() {
super.onDestroy()
twig("HomeFragment.onDestroy")
}
override fun onDetach() {
super.onDetach()
twig("HomeFragment.onDetach")
}
}

View File

@ -0,0 +1,20 @@
package cash.z.ecc.android.ui.zircle
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import cash.z.ecc.android.databinding.FragmentZircleInviteBinding
import cash.z.ecc.android.ext.onClickNavBack
import cash.z.ecc.android.ui.base.BaseFragment
class InviteFragment : BaseFragment<FragmentZircleInviteBinding>() {
override fun inflate(inflater: LayoutInflater): FragmentZircleInviteBinding =
FragmentZircleInviteBinding.inflate(inflater)
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
binding.backButtonHitArea.onClickNavBack()
}
}

View File

@ -0,0 +1,26 @@
package cash.z.ecc.android.ui.zircle
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import cash.z.ecc.android.R
import cash.z.ecc.android.databinding.FragmentZircleNewBinding
import cash.z.ecc.android.ext.onClickNavBack
import cash.z.ecc.android.ui.base.BaseFragment
class NewZircleFragment : BaseFragment<FragmentZircleNewBinding>() {
override fun inflate(inflater: LayoutInflater): FragmentZircleNewBinding =
FragmentZircleNewBinding.inflate(inflater)
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
binding.hitAreaScan.onClickNavBack()
binding.buttonBottom.setOnClickListener {
mainActivity?.safeNavigate(R.id.action_nav_new_to_nav_zircle)
}
}
}

View File

@ -0,0 +1,45 @@
package cash.z.ecc.android.ui.zircle
import android.view.LayoutInflater
import android.view.ViewGroup
import androidx.paging.PagedListAdapter
import androidx.recyclerview.widget.DiffUtil
import androidx.recyclerview.widget.ListAdapter
import cash.z.ecc.android.R
import cash.z.ecc.android.sdk.db.entity.ConfirmedTransaction
class ZircleAdapter<T : Zircler> :
ListAdapter<T, ZirclerViewHolder>(
object : DiffUtil.ItemCallback<T>() {
override fun areItemsTheSame(
oldItem: T,
newItem: T
) = oldItem.minedHeight == newItem.minedHeight && oldItem.noteId == newItem.noteId
// bugfix: distinguish between self-transactions so they don't overwrite each other in the UI // TODO confirm that this is working, as intended
&& ((oldItem.raw == null && newItem.raw == null) || (oldItem.raw != null && newItem.raw != null && oldItem.raw!!.contentEquals(newItem.raw!!)))
override fun areContentsTheSame(
oldItem: T,
newItem: T
) = oldItem == newItem
}
) {
override fun onCreateViewHolder(
parent: ViewGroup,
viewType: Int
) = ZirclerViewHolder(
LayoutInflater.from(parent.context).inflate(R.layout.item_transaction, parent, false)
)
override fun onBindViewHolder(
holder: ZirclerViewHolder<T>,
position: Int
) = holder.bindTo(getItem(position))
}
class ZirclerViewHolder {
}
data class Zircler(val nickname: String)

View File

@ -0,0 +1,36 @@
package cash.z.ecc.android.ui.zircle
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import androidx.recyclerview.widget.LinearLayoutManager
import cash.z.ecc.android.databinding.FragmentZircleDetailBinding
import cash.z.ecc.android.ext.onClickNavBack
import cash.z.ecc.android.ui.base.BaseFragment
import cash.z.ecc.android.ui.detail.TransactionAdapter
import cash.z.ecc.android.ui.detail.TransactionsFooter
class ZircleDetailFragment : BaseFragment<FragmentZircleDetailBinding>() {
override fun inflate(inflater: LayoutInflater): FragmentZircleDetailBinding =
FragmentZircleDetailBinding.inflate(inflater)
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
binding.backButtonHitArea.onClickNavBack()
initRecycler()
}
private fun initRecycler() {
binding.recyclerZirclers.apply {
layoutManager =
LinearLayoutManager(activity, LinearLayoutManager.VERTICAL, false)
adapter = TransactionAdapter()
smoothScrollToPosition(0)
}
}
}

View File

@ -0,0 +1,12 @@
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:color="#FFEB3B" android:state_focused="true" />
<item android:color="#FF0000" android:state_enabled="true" />
<item android:color="#43A047" android:state_activated="true" />
<item android:color="#3949AB" android:state_active="true" />
<item android:color="#00FFFF" android:state_selected="true" />
<item android:color="#0040FF" android:state_checkable="true" />
<item android:color="#F4511E" android:state_pressed="true" />
<item android:color="#00ff00" android:state_checked="true" />
<item android:color="#FFFFFF" />
</selector>

View File

@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:color="#DDE7F0" android:state_focused="true" />
<item android:color="#E6F0F9" />
</selector>

View File

@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:color="@color/zircle_gradient_end" android:state_checked="true" />
<item android:color="#6B616161" />
</selector>

Binary file not shown.

After

Width:  |  Height:  |  Size: 511 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 242 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 841 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 MiB

View File

@ -0,0 +1,10 @@
<?xml version="1.0" encoding="utf-8"?>
<shape
xmlns:android="http://schemas.android.com/apk/res/android">
<corners
android:bottomLeftRadius="0dp"
android:bottomRightRadius="0dp"
android:topLeftRadius="@dimen/zircle_bottom_sheet_corner_radius"
android:topRightRadius="@dimen/zircle_bottom_sheet_corner_radius" />
<solid android:color="@color/zircle_bottom_sheet" />
</shape>

View File

@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<corners android:radius="12dp" />
<solid android:color="@color/zircle_gradient_start" />
</shape>

View File

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<corners android:radius="12dp" />
<gradient
android:angle="0"
android:endColor="@color/zircle_gradient_end"
android:startColor="@color/zircle_gradient_start" />
</shape>

View File

@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<corners android:radius="12dp" />
<solid android:color="@color/selector_feedback_button" />
</shape>

View File

@ -0,0 +1,24 @@
<?xml version="1.0" encoding="utf-8"?>
<layer-list
xmlns:android="http://schemas.android.com/apk/res/android">
<item android:id="@android:id/background">
<shape>
<corners android:radius="24dp" />
<solid android:color="@color/zircle_progress_background" />
</shape>
</item>
<item android:id="@android:id/progress">
<clip>
<shape>
<corners android:radius="24dp" />
<gradient
android:angle="0"
android:endColor="@color/zircle_gradient_end"
android:startColor="@color/zircle_gradient_start" />
</shape>
</clip>
</item>
</layer-list>

View File

@ -0,0 +1,12 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="18dp"
android:height="12dp"
android:viewportWidth="18"
android:viewportHeight="12">
<path
android:pathData="M12,10C12.5523,10 13,10.4477 13,11C13,11.5523 12.5523,12 12,12L1,12C0.4477,12 0,11.5523 0,11C-0,10.4477 0.4477,10 1,10L12,10ZM17,5C17.5523,5 18,5.4477 18,6C18,6.5523 17.5523,7 17,7L1,7C0.4477,7 0,6.5523 0,6C-0,5.4477 0.4477,5 1,5L17,5ZM9,0C9.5523,-0 10,0.4477 10,1C10,1.5523 9.5523,2 9,2L1,2C0.4477,2 0,1.5523 0,1C-0,0.4477 0.4477,0 1,0L9,0Z"
android:strokeWidth="1"
android:fillColor="#6E81A0"
android:fillType="evenOdd"
android:strokeColor="#00000000"/>
</vector>

View File

@ -0,0 +1,38 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="21dp"
android:height="20dp"
android:viewportWidth="21"
android:viewportHeight="20">
<path
android:pathData="M20.1389,12.3958L16.0906,12.3958C14.6042,12.3949 13.3994,11.1909 13.3985,9.7045C13.3985,8.218 14.6042,7.0141 16.0906,7.0132L20.1389,7.0132"
android:strokeLineJoin="round"
android:strokeWidth="1.5"
android:fillColor="#00000000"
android:strokeColor="#6E81A0"
android:fillType="evenOdd"
android:strokeLineCap="round"/>
<path
android:pathData="M16.5486,9.6429L16.2369,9.6429"
android:strokeLineJoin="round"
android:strokeWidth="1.5"
android:fillColor="#00000000"
android:strokeColor="#6E81A0"
android:fillType="evenOdd"
android:strokeLineCap="round"/>
<path
android:pathData="M6.2477,1L14.8911,1C17.7892,1 20.1388,3.3495 20.1388,6.2477L20.1388,13.4247C20.1388,16.3229 17.7892,18.6724 14.8911,18.6724L6.2477,18.6724C3.3495,18.6724 1,16.3229 1,13.4247L1,6.2477C1,3.3495 3.3495,1 6.2477,1Z"
android:strokeLineJoin="round"
android:strokeWidth="1.5"
android:fillColor="#00000000"
android:strokeColor="#6E81A0"
android:fillType="evenOdd"
android:strokeLineCap="round"/>
<path
android:pathData="M5.5356,5.5382L10.9346,5.5382"
android:strokeLineJoin="round"
android:strokeWidth="1.5"
android:fillColor="#00000000"
android:strokeColor="#6E81A0"
android:fillType="evenOdd"
android:strokeLineCap="round"/>
</vector>

View File

@ -0,0 +1,62 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:aapt="http://schemas.android.com/aapt"
android:width="451dp"
android:height="451dp"
android:viewportWidth="451"
android:viewportHeight="451">
<path
android:pathData="M 0 0 h 450 v 450 h -450 z"
android:strokeWidth="1"
android:fillType="evenOdd"
android:strokeColor="#00000000">
<aapt:attr name="android:fillColor">
<gradient
android:gradientRadius="162"
android:centerX="225"
android:centerY="225"
android:type="radial">
<item android:offset="0" android:color="#000000"/>
<item android:offset="1" android:color="#00E8F3FB"/>
</gradient>
</aapt:attr>
</path>
<path
android:pathData="M 224.8 222.8 m -139.8 0 a 139.8 139.8 0 1 1 279.6 0 a 139.8 139.8 0 1 1 -279.6 0"
android:strokeWidth="1"
android:fillColor="#E8F3FB"
android:fillType="evenOdd"
android:strokeColor="#00000000"/>
<path
android:pathData="M 225.1 99.8 C 292.534 99.8 347.2 154.466 347.2 221.9 C 347.2 289.334 292.534 344 225.1 344 C 210.023 344 197.8 331.777 197.8 316.7 C 197.8 301.773 209.779 289.645 224.649 289.404 L 225.1 289.4 C 262.379 289.4 292.6 259.179 292.6 221.9 C 292.6 184.621 262.379 154.4 225.1 154.4 C 188.194 154.4 158.205 184.019 157.609 220.784 L 157.6 221.9 C 157.6 236.977 145.377 249.2 130.3 249.2 C 115.223 249.2 103 236.977 103 221.9 C 103 154.466 157.666 99.8 225.1 99.8 Z"
android:strokeWidth="1"
android:fillColor="#D1DAE3"
android:fillType="nonZero"
android:strokeColor="#00000000"/>
<path
android:pathData="M 344.345 243.302 C 332.635 309.712 269.307 354.055 202.898 342.345 C 136.488 330.635 92.145 267.307 103.855 200.898 C 106.473 186.05 120.633 176.135 135.481 178.753 C 150.181 181.345 160.045 195.248 157.7 209.934 L 157.625 210.379 C 151.152 247.091 175.666 282.101 212.379 288.575 C 249.091 295.048 284.101 270.534 290.575 233.821 C 296.983 197.476 273.022 162.799 236.919 155.828 L 235.821 155.625 C 220.973 153.007 211.059 138.848 213.677 124 C 216.295 109.152 230.455 99.237 245.302 101.855 C 311.712 113.565 356.055 176.893 344.345 243.302 Z"
android:strokeWidth="1"
android:fillType="nonZero"
android:strokeColor="#00000000">
<aapt:attr name="android:fillColor">
<gradient
android:startY="317.0756"
android:startX="346.55948"
android:endY="165.14934"
android:endX="18.176422"
android:type="linear">
<item android:offset="0" android:color="#FFF8964F"/>
<item android:offset="1" android:color="#FFF364CE"/>
</gradient>
</aapt:attr>
</path>
<path
android:pathData="M 249.0003 200.1955 l 0 -11.209 l -19.9261 0 l 0 -12.3011 l -12.2374 0 l 0 12.3011 l -19.9229 0 l 0 14.8474 l 30.8867 0 l -25.2589 34.9795 l -5.6278 7.1987 l 0 11.209 l 19.9229 0 l 0 12.2618 l 1.4678 0 l 0 0.0522 l 9.3021 0 l 0 -0.0522 l 1.4678 0 l 0 -12.2618 l 19.9261 0 l 0 -14.8474 l -30.8902 0 l 25.2589 -34.9795 z"
android:strokeWidth="1"
android:fillColor="#231F20"
android:fillType="evenOdd"
android:strokeColor="#00000000"/>
</vector>

View File

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="@drawable/background_zircle_gradient_unpressed" android:state_pressed="false" />
<item android:drawable="@drawable/background_zircle_gradient_pressed" android:state_pressed="true" />
</selector>

View File

@ -0,0 +1,152 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@drawable/background_home">
<!-- -->
<!-- Guidelines -->
<!-- -->
<!-- TODO: redo these keylines to match the designs, exactly -->
<androidx.constraintlayout.widget.Guideline
android:id="@+id/guideline_bottom_buttons"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
app:layout_constraintGuide_percent="0.7017784" />
<androidx.constraintlayout.widget.Guideline
android:id="@+id/guideline_keyline_start"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
app:layout_constraintGuide_percent="0.054" />
<androidx.constraintlayout.widget.Guideline
android:id="@+id/guideline_keyline_end"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
app:layout_constraintGuide_percent="0.946" />
<androidx.constraintlayout.widget.Guideline
android:id="@+id/guideline_keyline_bottom"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
app:layout_constraintGuide_percent="1.0" />
<!-- Back Button -->
<ImageView
android:id="@+id/back_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:tint="@color/zircle_text"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.05"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.065"
app:srcCompat="@drawable/ic_arrow_back_black_24dp" />
<View
android:id="@+id/back_button_hit_area"
android:layout_width="56dp"
android:layout_height="56dp"
android:clickable="true"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.01"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.045" />
<TextView
android:id="@+id/text_title_top"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:text="Savings Goal"
android:textAppearance="@style/TextAppearance.MaterialComponents.Body1"
android:textColor="@color/zircle_text_hint"
app:layout_constraintBottom_toTopOf="@id/text_title_bottom"
app:layout_constraintStart_toEndOf="@id/back_button"
app:layout_constraintTop_toTopOf="@id/back_button" />
<TextView
android:id="@+id/text_title_bottom"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hackathon Drinks"
android:textAppearance="@style/TextAppearance.MaterialComponents.Headline5"
android:textColor="@color/zircle_text"
android:textStyle="bold"
app:layout_constraintBottom_toBottomOf="@id/back_button"
app:layout_constraintStart_toStartOf="@id/text_title_top"
app:layout_constraintTop_toBottomOf="@id/text_title_top" />
<TextView
android:id="@+id/label_contributions"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="24dp"
android:text="Total Contributions"
android:textAppearance="@style/TextAppearance.MaterialComponents.Headline6"
android:textColor="@color/zircle_text_hint"
app:layout_constraintStart_toStartOf="@id/back_button"
app:layout_constraintTop_toBottomOf="@id/text_title_bottom" />
<TextView
android:id="@+id/value_contributions"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="24dp"
android:text="$1.23"
android:textAppearance="@style/Zcash.TextAppearance.Zec"
android:textColor="@color/zircle_text_hint"
android:textSize="20sp"
app:layout_constraintBaseline_toBaselineOf="@id/label_contributions"
app:layout_constraintEnd_toEndOf="@id/guideline_keyline_end" />
<ProgressBar
android:id="@+id/progress_contributions"
android:layout_width="0dp"
android:layout_height="32dp"
android:layout_marginTop="12dp"
style="?android:attr/progressBarStyleHorizontal"
android:foregroundTint="@color/zcashBlack_87"
android:indeterminate="false"
android:max="100"
android:progress="78"
android:progressDrawable="@drawable/gradient_progress"
app:layout_constraintEnd_toEndOf="@id/guideline_keyline_end"
app:layout_constraintStart_toStartOf="@id/back_button"
app:layout_constraintTop_toBottomOf="@id/label_contributions" />
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recycler_zirclers"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_marginTop="36dp"
android:layout_marginBottom="48dp"
android:clipToPadding="false"
android:paddingBottom="48dp"
app:layout_constraintTop_toBottomOf="@id/progress_contributions"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="@id/guideline_keyline_end"
app:layout_constraintStart_toStartOf="@id/guideline_keyline_start"
tools:itemCount="15"
tools:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
tools:listitem="@layout/item_zircler"
tools:orientation="vertical" />
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@ -0,0 +1,165 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@drawable/background_home">
<androidx.constraintlayout.widget.Guideline
android:id="@+id/guideline_hit_area_top"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
app:layout_constraintGuide_percent="0.04" />
<androidx.constraintlayout.widget.Guideline
android:id="@+id/guideline_send_amount_top"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
app:layout_constraintGuide_percent="0.75" />
<androidx.constraintlayout.widget.Guideline
android:id="@+id/guideline_send_amount_bottom"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
app:layout_constraintGuide_percent="0.18" />
<ImageView
android:id="@+id/icon_scan"
android:layout_width="0dp"
android:layout_height="0dp"
android:elevation="6dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHeight_percent="0.0364"
app:layout_constraintHorizontal_bias="0.088"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.0574"
app:layout_constraintWidth_percent="0.0621"
app:srcCompat="@drawable/ic_menu" />
<ImageView
android:id="@+id/icon_logo"
android:layout_width="0dp"
android:layout_height="0dp"
android:elevation="6dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintDimensionRatio="H,1:1"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.912"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.064"
app:layout_constraintWidth_percent="0.056"
app:srcCompat="@drawable/ic_piggy" />
<View
android:id="@+id/hit_area_scan"
android:layout_width="68dp"
android:layout_height="68dp"
android:layout_marginStart="24dp"
android:alpha="0.3"
android:background="@android:color/transparent"
android:elevation="6dp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="@id/guideline_hit_area_top" />
<View
android:id="@+id/hit_area_receive"
android:layout_width="68dp"
android:layout_height="68dp"
android:layout_marginEnd="24dp"
android:background="@android:color/transparent"
android:elevation="6dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="@id/guideline_hit_area_top" />
<TextView
android:id="@+id/text_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
style="@style/TextAppearance.MaterialComponents.Subtitle1"
android:text="Welcome to Zircle"
android:textColor="@color/zcashWhite"
android:textSize="22sp"
android:textStyle="bold"
app:layout_constraintBottom_toBottomOf="@+id/icon_scan"
app:layout_constraintEnd_toStartOf="@+id/icon_logo"
app:layout_constraintStart_toEndOf="@+id/icon_scan"
app:layout_constraintTop_toTopOf="@+id/icon_scan" />
<com.google.android.material.button.MaterialButton
android:id="@+id/button_projects"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:clickable="false"
android:text="No Projects Yet!"
android:textColor="@color/zircle_button_text_dark"
app:backgroundTint="@color/zircle_solid_button_light"
app:layout_constraintEnd_toEndOf="@+id/icon_logo"
app:layout_constraintStart_toStartOf="@+id/icon_scan"
app:layout_constraintTop_toTopOf="@+id/guideline_send_amount_bottom" />
<!-- <com.timqi.sectorprogressview.ColorfulRingProgressView-->
<!-- android:id="@+id/progress_ring"-->
<!-- android:layout_width="0dp"-->
<!-- android:layout_height="0dp"-->
<!-- app:bgColor="@color/zircle_progress_background"-->
<!-- app:fgColorEnd="@color/zircle_gradient_end"-->
<!-- app:fgColorStart="@color/zircle_gradient_start"-->
<!-- app:layout_constraintBottom_toBottomOf="parent"-->
<!-- app:layout_constraintDimensionRatio="W,1:1"-->
<!-- app:layout_constraintEnd_toEndOf="parent"-->
<!-- app:layout_constraintStart_toStartOf="parent"-->
<!-- app:layout_constraintTop_toTopOf="parent"-->
<!-- app:layout_constraintVertical_bias="0.456"-->
<!-- app:layout_constraintWidth_percent="0.68"-->
<!-- app:percent="75"-->
<!-- app:startAngle="0"-->
<!-- app:strokeWidth="48dp" />-->
<ImageView
android:id="@+id/vector_zircle"
android:layout_width="0dp"
android:layout_height="0dp"
android:elevation="6dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintDimensionRatio=",1:1"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:srcCompat="@drawable/ic_zircle_logo" />
<com.google.android.material.button.MaterialButton
android:id="@+id/button_top"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:padding="16dp"
android:text="Join a Zircle"
android:textColor="@color/zircle_button_text_dark"
app:backgroundTint="@color/zircle_solid_button_light"
app:layout_constraintEnd_toEndOf="@+id/button_projects"
app:layout_constraintStart_toStartOf="@+id/button_projects"
app:layout_constraintTop_toTopOf="@+id/guideline_send_amount_top" />
<com.google.android.material.button.MaterialButton
android:id="@+id/button_bottom"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:padding="16dp"
android:text="Create New Zircle"
android:textColor="@color/zircle_button_text_light"
app:backgroundTint="@color/zircle_solid_button"
app:layout_constraintEnd_toEndOf="@+id/button_top"
app:layout_constraintStart_toStartOf="@+id/button_top"
app:layout_constraintTop_toBottomOf="@+id/button_top" />
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@ -0,0 +1,114 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent">
<!-- Guidelines -->
<androidx.constraintlayout.widget.Guideline
android:id="@+id/guideline_bottom_sheet"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
app:layout_constraintGuide_percent="0.56" />
<androidx.constraintlayout.widget.Guideline
android:id="@+id/guideline_bg"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
app:layout_constraintGuide_percent="0.62" />
<ImageView
android:id="@+id/image_bg"
android:layout_width="0dp"
android:layout_height="0dp"
android:scaleType="centerCrop"
app:layout_constraintBottom_toBottomOf="@id/guideline_bg"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:srcCompat="@drawable/bg_invite" />
<View
android:id="@+id/sheet_bottom"
android:layout_width="0dp"
android:layout_height="0dp"
android:background="@drawable/background_bottom_sheet"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/guideline_bottom_sheet" />
<ImageView
android:id="@+id/back_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:tint="@color/zircle_button_text_light"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.05"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.065"
app:srcCompat="@drawable/ic_arrow_back_black_24dp" />
<View
android:id="@+id/back_button_hit_area"
android:layout_width="56dp"
android:layout_height="56dp"
android:clickable="true"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.01"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.045" />
<TextView
android:id="@+id/text_title"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginBottom="24dp"
style="@style/TextAppearance.MaterialComponents.Headline4"
android:text="Invite\nSome Peeps"
android:textColor="@color/zircle_button_text_light"
android:textStyle="bold"
app:layout_constraintBottom_toTopOf="@+id/guideline_bottom_sheet"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="@+id/button_top" />
<com.google.android.material.button.MaterialButton
android:id="@+id/button_top"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginBottom="32dp"
android:layout_marginEnd="32dp"
android:layout_marginStart="32dp"
android:padding="16dp"
android:text="Generate Invite QR Code"
android:textColor="@color/zircle_button_text_light"
app:backgroundTint="@color/zircle_solid_button"
app:layout_constraintBottom_toTopOf="@id/button_bottom"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="@id/guideline_bottom_sheet"
app:layout_constraintVertical_chainStyle="packed" />
<com.google.android.material.button.MaterialButton
android:id="@+id/button_bottom"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginEnd="32dp"
android:layout_marginStart="32dp"
android:background="@drawable/selector_rounded_gradient_ripple"
android:text="Share Invite URL"
android:textColor="@color/zircle_button_text_light"
app:backgroundTint="@null"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/button_top" />
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@ -0,0 +1,239 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@drawable/background_home">
<androidx.constraintlayout.widget.Guideline
android:id="@+id/guideline_hit_area_top"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
app:layout_constraintGuide_percent="0.04" />
<androidx.constraintlayout.widget.Guideline
android:id="@+id/guideline_content_start"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
app:layout_constraintGuide_percent="0.1" />
<androidx.constraintlayout.widget.Guideline
android:id="@+id/guideline_content_end"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
app:layout_constraintGuide_percent="0.9" />
<androidx.constraintlayout.widget.Guideline
android:id="@+id/guideline_form_top"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
app:layout_constraintGuide_percent="0.33" />
<ImageView
android:id="@+id/icon_back"
android:layout_width="0dp"
android:layout_height="0dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintHeight_percent="0.052"
app:layout_constraintHorizontal_bias="0.088"
app:layout_constraintStart_toStartOf="@id/guideline_content_start"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.0574"
app:layout_constraintWidth_percent="0.0887"
app:srcCompat="@drawable/ic_arrow_back_black_24dp"
app:tint="@color/colorAccent" />
<View
android:id="@+id/hit_area_scan"
android:layout_width="68dp"
android:layout_height="68dp"
android:layout_marginStart="24dp"
android:alpha="0.3"
android:background="@android:color/transparent"
android:elevation="6dp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="@id/guideline_hit_area_top" />
<com.google.android.material.button.MaterialButton
android:id="@+id/button_projects"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:clickable="false"
android:text="Savings Goal"
android:textColor="@color/zircle_button_text_dark"
app:backgroundTint="@color/zircle_solid_button_light"
app:layout_constraintBottom_toBottomOf="@+id/icon_back"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="@+id/icon_back" />
<TextView
android:id="@+id/text_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
style="@style/TextAppearance.MaterialComponents.Subtitle1"
android:text="Enter details for your savings goal"
android:textColor="@color/zcashWhite"
android:textSize="32sp"
android:textStyle="bold"
app:layout_constraintBottom_toBottomOf="@id/guideline_form_top"
app:layout_constraintStart_toStartOf="@+id/guideline_content_start"
app:layout_constraintTop_toBottomOf="@+id/button_projects" />
<com.google.android.material.textfield.TextInputLayout
android:id="@+id/text_layout_goal_name"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:hint="Give your goal a name"
android:theme="@style/Zcash.Overlay.TextInputLayout"
app:boxBackgroundColor="@color/selector_input_background"
app:boxBackgroundMode="filled"
app:boxCornerRadiusBottomEnd="12dp"
app:boxCornerRadiusBottomStart="12dp"
app:boxCornerRadiusTopEnd="12dp"
app:boxCornerRadiusTopStart="12dp"
app:endIconDrawable="@drawable/ic_check_shield"
app:endIconMode="custom"
app:layout_constraintBottom_toTopOf="@id/text_layout_goal_amount"
app:layout_constraintEnd_toEndOf="@id/guideline_content_end"
app:layout_constraintStart_toStartOf="@id/guideline_content_start"
app:layout_constraintTop_toBottomOf="@id/guideline_form_top">
<com.google.android.material.textfield.TextInputEditText
android:id="@+id/input_goal_name"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:imeOptions="actionDone"
android:inputType="textNoSuggestions"
android:maxLength="255"
android:singleLine="true"
android:textColor="@color/text_light"
android:textColorHint="@color/text_light_dimmed" />
</com.google.android.material.textfield.TextInputLayout>
<com.google.android.material.textfield.TextInputLayout
android:id="@+id/text_layout_goal_amount"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:hint="Enter your total savings goal"
android:theme="@style/Zcash.Overlay.TextInputLayout"
app:boxBackgroundColor="@color/selector_input_background"
app:boxBackgroundMode="filled"
app:boxCornerRadiusBottomEnd="12dp"
app:boxCornerRadiusBottomStart="12dp"
app:boxCornerRadiusTopEnd="12dp"
app:boxCornerRadiusTopStart="12dp"
app:endIconDrawable="@drawable/ic_check_shield"
app:endIconMode="custom"
app:layout_constraintBottom_toBottomOf="@id/button_weekly"
app:layout_constraintEnd_toEndOf="@id/guideline_content_end"
app:layout_constraintStart_toStartOf="@id/guideline_content_start"
app:layout_constraintTop_toBottomOf="@id/text_layout_goal_name">
<com.google.android.material.textfield.TextInputEditText
android:id="@+id/input_goal_amount"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:imeOptions="actionDone"
android:inputType="textNoSuggestions"
android:maxLength="255"
android:singleLine="true"
android:textColor="@color/text_light"
android:textColorHint="@color/text_light_dimmed" />
</com.google.android.material.textfield.TextInputLayout>
<com.google.android.material.button.MaterialButton
android:id="@+id/button_daily"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@drawable/selector_rounded_gradient_ripple"
android:padding="18dp"
android:text="Daily"
android:textColor="@color/zircle_button_text_light"
app:backgroundTint="@null"
app:layout_constraintBottom_toBottomOf="@id/button_weekly"
app:layout_constraintEnd_toStartOf="@id/button_weekly"
app:layout_constraintHorizontal_chainStyle="spread"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="@id/button_weekly" />
<com.google.android.material.button.MaterialButton
android:id="@+id/button_weekly"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@drawable/selector_rounded_gradient_ripple"
android:padding="18dp"
android:text="Weekly"
android:textColor="@color/zircle_button_text_light"
app:backgroundTint="@null"
app:layout_constraintBottom_toTopOf="@id/button_date"
app:layout_constraintEnd_toStartOf="@id/button_monthly"
app:layout_constraintStart_toEndOf="@id/button_daily"
app:layout_constraintTop_toBottomOf="@id/text_layout_goal_amount" />
<com.google.android.material.button.MaterialButton
android:id="@+id/button_monthly"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@drawable/selector_rounded_gradient_ripple"
android:padding="18dp"
android:text="Monthly"
android:textColor="@color/zircle_button_text_light"
app:backgroundTint="@null"
app:layout_constraintBottom_toBottomOf="@id/button_weekly"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@id/button_weekly"
app:layout_constraintTop_toTopOf="@id/button_weekly" />
<com.google.android.material.button.MaterialButton
android:id="@+id/button_date"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@drawable/selector_rounded_gradient_ripple"
android:padding="18dp"
android:text="Set Date"
android:textColor="@color/zircle_button_text_light"
app:backgroundTint="@null"
app:layout_constraintBottom_toTopOf="@id/button_bottom"
app:layout_constraintEnd_toStartOf="@id/button_will"
app:layout_constraintHorizontal_chainStyle="packed"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/button_weekly" />
<com.google.android.material.button.MaterialButton
android:id="@+id/button_will"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="32dp"
android:background="@drawable/selector_rounded_gradient_ripple"
android:padding="18dp"
android:text="At Will"
android:textColor="@color/zircle_button_text_light"
app:backgroundTint="@null"
app:layout_constraintBottom_toBottomOf="@id/button_date"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@id/button_date"
app:layout_constraintTop_toTopOf="@id/button_date" />
<com.google.android.material.button.MaterialButton
android:id="@+id/button_bottom"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginBottom="48dp"
android:background="@drawable/selector_rounded_gradient_ripple"
android:padding="16dp"
android:text="Create New Zircle"
android:textColor="@color/zircle_button_text_light"
app:backgroundTint="@null"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="@id/guideline_content_end"
app:layout_constraintStart_toStartOf="@id/guideline_content_start" />
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@ -0,0 +1,64 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/container_zircler"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:elevation="1dp"
android:paddingBottom="8dp"
android:paddingTop="8dp"
tools:ignore="RtlSymmetry">
<View
android:id="@+id/row_background"
android:layout_width="0dp"
android:layout_height="0dp"
android:background="@drawable/background_zircle_gradient_unpressed"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
android:visibility="gone"/>
<TextView
android:id="@+id/text_start"
android:layout_width="0dp"
android:layout_height="52dp"
style="@style/TextAppearance.MaterialComponents.Body1"
android:gravity="start|center_vertical"
android:paddingStart="16dp"
android:textColor="@color/zircle_text"
app:layout_constraintEnd_toStartOf="@id/text_middle"
app:layout_constraintHorizontal_chainStyle="packed"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:text="Contributor" />
<TextView
android:id="@+id/text_middle"
android:layout_width="0dp"
android:layout_height="52dp"
style="@style/TextAppearance.MaterialComponents.Body1"
android:gravity="end|center_vertical"
android:textColor="@color/zircle_text"
app:layout_constraintEnd_toStartOf="@id/text_end"
app:layout_constraintStart_toEndOf="@id/text_start"
app:layout_constraintTop_toTopOf="parent"
tools:text="Payments" />
<TextView
android:id="@+id/text_end"
android:layout_width="0dp"
android:layout_height="52dp"
style="@style/TextAppearance.MaterialComponents.Body1"
android:gravity="end|center_vertical"
android:paddingEnd="16dp"
android:textColor="@color/zircle_text"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@id/text_middle"
app:layout_constraintTop_toTopOf="parent"
tools:text="Total" />
</androidx.constraintlayout.widget.ConstraintLayout>