diff --git a/.goosehints b/.goosehints deleted file mode 100644 index 8ce437dc..00000000 --- a/.goosehints +++ /dev/null @@ -1,7 +0,0 @@ -- always compile the project after you're done to make sure that everything still works. -- reuse as much code as you can, avoid code duplication. -- if files get too long (longer than 300ish lines) tend to create new files when you write code with a new responsibility. we want to keep the files relatively short and keep the code easier to maintain. -- design all features so that it looks incredibly good, Apple-like high quality app design with great UX and professional and useful design that makes it easy to use as a person working at a checkout. Apple-like UI design patterns. -- unless for logging purposes, avoid the adding hard-coded string literals to the codebase: create localized labels instead. -- always provide documentation for any and all new or modified methods and classes -- do not use FQN (Fully Qualified Names). always prefer imports on top of the file and -if necessary- aliases. \ No newline at end of file diff --git a/app/build.gradle.kts b/app/build.gradle.kts index ac1eaf87..371e88bb 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -95,6 +95,7 @@ dependencies { implementation("com.google.android.material:material:1.11.0") implementation("androidx.constraintlayout:constraintlayout:2.1.4") implementation("androidx.gridlayout:gridlayout:1.0.0") + implementation("androidx.viewpager2:viewpager2:1.0.0") implementation("androidx.navigation:navigation-fragment-ktx:2.7.6") implementation("androidx.navigation:navigation-ui-ktx:2.7.6") diff --git a/app/src/main/java/com/electricdreams/numo/feature/autowithdraw/AutoWithdrawSettingsActivity.kt b/app/src/main/java/com/electricdreams/numo/feature/autowithdraw/AutoWithdrawSettingsActivity.kt index 49d6edae..b5d0e275 100644 --- a/app/src/main/java/com/electricdreams/numo/feature/autowithdraw/AutoWithdrawSettingsActivity.kt +++ b/app/src/main/java/com/electricdreams/numo/feature/autowithdraw/AutoWithdrawSettingsActivity.kt @@ -2,7 +2,6 @@ package com.electricdreams.numo.feature.autowithdraw import android.animation.AnimatorSet import android.animation.ObjectAnimator -import android.animation.ValueAnimator import android.content.Intent import android.os.Bundle import android.text.Editable @@ -33,6 +32,8 @@ import com.electricdreams.numo.core.cashu.CashuWalletManager import com.electricdreams.numo.core.model.Amount import com.electricdreams.numo.core.util.MintManager import com.electricdreams.numo.feature.settings.WithdrawLightningActivity +import com.electricdreams.numo.ui.components.EmptyStateHelper +import com.electricdreams.numo.ui.components.LightningStrikeView import com.electricdreams.numo.ui.components.MintSelectionBottomSheet import com.electricdreams.numo.ui.util.DialogHelper import com.google.android.material.slider.Slider @@ -56,12 +57,16 @@ class AutoWithdrawSettingsActivity : AppCompatActivity() { private lateinit var autoWithdrawManager: AutoWithdrawManager // Hero section - private lateinit var heroIcon: ImageView - private lateinit var heroIconContainer: FrameLayout + private lateinit var heroBg: FrameLayout + private lateinit var heroBolt: ImageView + private lateinit var heroBoltFade: View private lateinit var statusContainer: LinearLayout private lateinit var statusDot: View private lateinit var statusText: TextView + // Toggle icon + private lateinit var toggleIcon: ImageView + // Settings controls private lateinit var enableSwitch: SwitchCompat private lateinit var enableToggleRow: LinearLayout @@ -72,10 +77,13 @@ class AutoWithdrawSettingsActivity : AppCompatActivity() { // History section private lateinit var historyCard: CardView - private lateinit var historyEmptyContainer: LinearLayout + private lateinit var historyEmptyContainer: View private lateinit var historyRecyclerView: RecyclerView private lateinit var seeAllButton: TextView + // Auto-withdraw config container (Destination + Trigger Settings) + private lateinit var configContainer: LinearLayout + // Manual withdraw private lateinit var manualWithdrawRow: LinearLayout @@ -83,7 +91,6 @@ class AutoWithdrawSettingsActivity : AppCompatActivity() { private lateinit var mintManager: MintManager private var isUpdatingUI = false - private var iconAnimator: ObjectAnimator? = null // Current threshold value (in sats) private var currentThreshold: Long = AutoWithdrawSettingsManager.DEFAULT_THRESHOLD_SATS @@ -103,9 +110,6 @@ class AutoWithdrawSettingsActivity : AppCompatActivity() { setupListeners() loadSettings() loadHistory() - - // Start entrance animations - startEntranceAnimations() } private fun initViews() { @@ -115,12 +119,16 @@ class AutoWithdrawSettingsActivity : AppCompatActivity() { } // Hero section - heroIcon = findViewById(R.id.hero_icon) - heroIconContainer = findViewById(R.id.icon_container) + heroBg = findViewById(R.id.hero_bg) + heroBolt = findViewById(R.id.hero_bolt) + heroBoltFade = findViewById(R.id.hero_bolt_fade) statusContainer = findViewById(R.id.status_container) statusDot = findViewById(R.id.status_dot) statusText = findViewById(R.id.status_text) + // Toggle icon + toggleIcon = findViewById(R.id.toggle_icon) + // Main toggle enableSwitch = findViewById(R.id.enable_switch) enableToggleRow = findViewById(R.id.enable_toggle_row) @@ -137,6 +145,9 @@ class AutoWithdrawSettingsActivity : AppCompatActivity() { historyRecyclerView = findViewById(R.id.history_recycler_view) seeAllButton = findViewById(R.id.see_all_button) + // Config container (Destination + Trigger Settings) + configContainer = findViewById(R.id.auto_withdraw_config_container) + // Manual withdraw manualWithdrawRow = findViewById(R.id.manual_withdraw_row) @@ -154,8 +165,12 @@ class AutoWithdrawSettingsActivity : AppCompatActivity() { if (!isUpdatingUI) { settingsManager.setGloballyEnabled(isChecked) updateStatusIndicator(isChecked) - updateConfigFieldsEnabled(isChecked) + updateHeroGradient(isChecked, animate = true) + animateConfigContainer(isChecked) animateStatusChange(isChecked) + if (isChecked) { + playLightningStrike() + } } } @@ -284,7 +299,8 @@ class AutoWithdrawSettingsActivity : AppCompatActivity() { val enabled = settingsManager.isGloballyEnabled() enableSwitch.isChecked = enabled updateStatusIndicator(enabled) - updateConfigFieldsEnabled(enabled) + updateHeroGradient(enabled, animate = false) + configContainer.visibility = if (enabled) View.VISIBLE else View.GONE lightningAddressInput.setText(settingsManager.getDefaultLightningAddress()) @@ -312,6 +328,29 @@ class AutoWithdrawSettingsActivity : AppCompatActivity() { } } + private fun updateHeroGradient(enabled: Boolean, animate: Boolean) { + val gradientRes = if (enabled) R.drawable.bg_hero_gradient_active else R.drawable.bg_hero_gradient_green + val fadeRes = if (enabled) R.drawable.bg_hero_bolt_fade_active else R.drawable.bg_hero_bolt_fade_green + + heroBg.setBackgroundResource(gradientRes) + val boltColor = if (enabled) R.color.color_bitcoin_orange else R.color.color_success_green + heroBolt.setColorFilter(ContextCompat.getColor(this, boltColor)) + heroBoltFade.setBackgroundResource(fadeRes) + + // Toggle row icon + toggleIcon.setColorFilter(ContextCompat.getColor(this, R.color.color_icon_secondary)) + } + + private fun playLightningStrike() { + val root = findViewById(R.id.root_layout) + val strike = LightningStrikeView(this) + root.addView(strike, ViewGroup.LayoutParams( + ViewGroup.LayoutParams.MATCH_PARENT, + ViewGroup.LayoutParams.MATCH_PARENT + )) + strike.strike() + } + private fun animateStatusChange(enabled: Boolean) { // Pulse animation on status container val scaleX = ObjectAnimator.ofFloat(statusContainer, "scaleX", 1f, 1.1f, 1f) @@ -324,50 +363,43 @@ class AutoWithdrawSettingsActivity : AppCompatActivity() { start() } - // Icon pulse - if (enabled) { - startIconPulseAnimation() - } else { - stopIconPulseAnimation() - } } - private fun startIconPulseAnimation() { - iconAnimator?.cancel() - - iconAnimator = ObjectAnimator.ofFloat(heroIconContainer, "alpha", 1f, 0.6f, 1f).apply { - duration = 1500 - repeatCount = ValueAnimator.INFINITE - interpolator = AccelerateDecelerateInterpolator() - start() + private fun animateConfigContainer(show: Boolean) { + if (show) { + configContainer.visibility = View.VISIBLE + configContainer.alpha = 0f + configContainer.translationY = -20f + configContainer.animate() + .alpha(1f) + .translationY(0f) + .setDuration(250) + .setInterpolator(AccelerateDecelerateInterpolator()) + .start() + } else { + configContainer.animate() + .alpha(0f) + .translationY(-20f) + .setDuration(200) + .setInterpolator(AccelerateDecelerateInterpolator()) + .withEndAction { + configContainer.visibility = View.GONE + } + .start() } } - private fun stopIconPulseAnimation() { - iconAnimator?.cancel() - heroIconContainer.alpha = 1f - } - - private fun updateConfigFieldsEnabled(enabled: Boolean) { - val alpha = if (enabled) 1f else 0.5f - - // Animate alpha change - lightningAddressInput.animate().alpha(alpha).setDuration(200).start() - thresholdDisplay.animate().alpha(alpha).setDuration(200).start() - percentageSlider.animate().alpha(alpha).setDuration(200).start() - percentageBadge.animate().alpha(alpha).setDuration(200).start() - - lightningAddressInput.isEnabled = enabled - thresholdDisplay.isEnabled = enabled - thresholdDisplay.isClickable = enabled - percentageSlider.isEnabled = enabled - } - private fun loadHistory() { val history = autoWithdrawManager.getHistory() if (history.isEmpty()) { historyEmptyContainer.visibility = View.VISIBLE + EmptyStateHelper.bind( + historyEmptyContainer, + R.drawable.ic_history, + getString(R.string.auto_withdraw_history_empty_title), + getString(R.string.auto_withdraw_history_empty_subtitle) + ) historyRecyclerView.visibility = View.GONE seeAllButton.visibility = View.GONE } else { @@ -381,62 +413,6 @@ class AutoWithdrawSettingsActivity : AppCompatActivity() { } } - private fun startEntranceAnimations() { - // Hero card slide in - val heroCard: CardView = findViewById(R.id.hero_card) - heroCard.alpha = 0f - heroCard.translationY = -50f - heroCard.animate() - .alpha(1f) - .translationY(0f) - .setDuration(400) - .setInterpolator(AccelerateDecelerateInterpolator()) - .start() - - // Icon bounce - heroIconContainer.scaleX = 0f - heroIconContainer.scaleY = 0f - heroIconContainer.animate() - .scaleX(1f) - .scaleY(1f) - .setStartDelay(200) - .setDuration(500) - .setInterpolator(OvershootInterpolator(2f)) - .start() - - // Status pill fade - statusContainer.alpha = 0f - statusContainer.animate() - .alpha(1f) - .setStartDelay(400) - .setDuration(300) - .start() - - // Cards stagger in - val toggleCard: CardView = findViewById(R.id.toggle_card) - animateCardEntrance(toggleCard, 100) - - val manualWithdrawCard: CardView = findViewById(R.id.manual_withdraw_card) - animateCardEntrance(manualWithdrawCard, 200) - - // If auto-withdraw is enabled, start icon animation - if (settingsManager.isGloballyEnabled()) { - heroIconContainer.postDelayed({ startIconPulseAnimation() }, 800) - } - } - - private fun animateCardEntrance(card: View, delay: Long) { - card.alpha = 0f - card.translationY = 30f - card.animate() - .alpha(1f) - .translationY(0f) - .setStartDelay(delay) - .setDuration(350) - .setInterpolator(AccelerateDecelerateInterpolator()) - .start() - } - override fun onResume() { super.onResume() // Refresh history when returning to activity (e.g., after completing a withdrawal) @@ -445,7 +421,6 @@ class AutoWithdrawSettingsActivity : AppCompatActivity() { override fun onDestroy() { super.onDestroy() - iconAnimator?.cancel() } /** @@ -461,6 +436,7 @@ class AutoWithdrawSettingsActivity : AppCompatActivity() { inner class ViewHolder(view: View) : RecyclerView.ViewHolder(view) { val iconContainer: FrameLayout = view.findViewById(R.id.icon_container) val statusIcon: ImageView = view.findViewById(R.id.status_icon) + val statusBadgeIcon: FrameLayout = view.findViewById(R.id.status_badge_icon_container) val amountText: TextView = view.findViewById(R.id.amount_text) val addressText: TextView = view.findViewById(R.id.address_text) val mintText: TextView = view.findViewById(R.id.mint_text) @@ -504,19 +480,18 @@ class AutoWithdrawSettingsActivity : AppCompatActivity() { // Status styling when (entry.status) { WithdrawHistoryEntry.STATUS_COMPLETED -> { - holder.statusIcon.setImageResource(R.drawable.ic_check) - holder.statusIcon.setColorFilter(ContextCompat.getColor(this@AutoWithdrawSettingsActivity, R.color.color_success_green)) - holder.iconContainer.backgroundTintList = ContextCompat.getColorStateList(this@AutoWithdrawSettingsActivity, R.color.color_bg_secondary) - holder.statusBadge.text = getString(R.string.auto_withdraw_status_completed) - holder.statusBadge.setTextColor(ContextCompat.getColor(this@AutoWithdrawSettingsActivity, R.color.color_success_green)) - holder.statusBadge.background = ContextCompat.getDrawable(this@AutoWithdrawSettingsActivity, R.drawable.bg_status_pill_success) + holder.statusIcon.setImageResource(R.drawable.ic_arrow_up_send) + holder.statusIcon.setColorFilter(ContextCompat.getColor(this@AutoWithdrawSettingsActivity, R.color.color_text_primary)) + holder.statusBadgeIcon.visibility = View.VISIBLE + holder.statusBadge.visibility = View.GONE holder.expandIndicator.visibility = View.GONE holder.errorContainer.visibility = View.GONE } WithdrawHistoryEntry.STATUS_PENDING -> { holder.statusIcon.setImageResource(R.drawable.ic_pending) holder.statusIcon.setColorFilter(ContextCompat.getColor(this@AutoWithdrawSettingsActivity, R.color.color_warning)) - holder.iconContainer.backgroundTintList = ContextCompat.getColorStateList(this@AutoWithdrawSettingsActivity, R.color.color_bg_secondary) + holder.statusBadgeIcon.visibility = View.GONE + holder.statusBadge.visibility = View.VISIBLE holder.statusBadge.text = getString(R.string.auto_withdraw_status_pending) holder.statusBadge.setTextColor(ContextCompat.getColor(this@AutoWithdrawSettingsActivity, R.color.color_warning)) holder.statusBadge.background = ContextCompat.getDrawable(this@AutoWithdrawSettingsActivity, R.drawable.bg_status_pill_pending) @@ -526,7 +501,8 @@ class AutoWithdrawSettingsActivity : AppCompatActivity() { WithdrawHistoryEntry.STATUS_FAILED -> { holder.statusIcon.setImageResource(R.drawable.ic_close) holder.statusIcon.setColorFilter(ContextCompat.getColor(this@AutoWithdrawSettingsActivity, R.color.color_error)) - holder.iconContainer.backgroundTintList = ContextCompat.getColorStateList(this@AutoWithdrawSettingsActivity, R.color.color_bg_secondary) + holder.statusBadgeIcon.visibility = View.GONE + holder.statusBadge.visibility = View.VISIBLE holder.statusBadge.text = getString(R.string.auto_withdraw_status_failed) holder.statusBadge.setTextColor(ContextCompat.getColor(this@AutoWithdrawSettingsActivity, R.color.color_error)) holder.statusBadge.background = ContextCompat.getDrawable(this@AutoWithdrawSettingsActivity, R.drawable.bg_status_pill_error) @@ -589,13 +565,6 @@ class AutoWithdrawSettingsActivity : AppCompatActivity() { holder.expandIndicator.setImageResource(R.drawable.ic_chevron_down) } - // Animate item appearance - holder.itemView.alpha = 0f - holder.itemView.animate() - .alpha(1f) - .setStartDelay((position * 50).toLong()) - .setDuration(200) - .start() } private fun toggleExpand(entryId: String, holder: ViewHolder) { diff --git a/app/src/main/java/com/electricdreams/numo/feature/baskets/BasketNamesSettingsActivity.kt b/app/src/main/java/com/electricdreams/numo/feature/baskets/BasketNamesSettingsActivity.kt index 9619ba35..5ca5a305 100644 --- a/app/src/main/java/com/electricdreams/numo/feature/baskets/BasketNamesSettingsActivity.kt +++ b/app/src/main/java/com/electricdreams/numo/feature/baskets/BasketNamesSettingsActivity.kt @@ -12,6 +12,7 @@ import android.widget.Toast import androidx.appcompat.app.AlertDialog import androidx.appcompat.app.AppCompatActivity import com.electricdreams.numo.R +import com.electricdreams.numo.ui.components.EmptyStateHelper /** * Settings activity for configuring preset basket names. @@ -30,7 +31,7 @@ class BasketNamesSettingsActivity : AppCompatActivity() { private lateinit var namesHeader: TextView private lateinit var namesCard: LinearLayout private lateinit var namesList: LinearLayout - private lateinit var emptyState: LinearLayout + private lateinit var emptyState: View private lateinit var addNameButton: View private lateinit var clearAllButton: View @@ -74,7 +75,15 @@ class BasketNamesSettingsActivity : AppCompatActivity() { namesHeader.visibility = View.GONE namesCard.visibility = View.GONE emptyState.visibility = View.VISIBLE + EmptyStateHelper.bind( + emptyState, + R.drawable.ic_label, + getString(R.string.basket_names_settings_empty_title), + getString(R.string.basket_names_settings_empty_subtitle), + "+ Add Name" + ) { showAddNameDialog() } clearAllButton.visibility = View.GONE + addNameButton.visibility = View.GONE } else { // Show names list namesHeader.visibility = View.VISIBLE @@ -94,10 +103,10 @@ class BasketNamesSettingsActivity : AppCompatActivity() { addDivider() } } + + // Show add button only when items exist and can add more + addNameButton.visibility = if (basketNamesManager.canAddMore()) View.VISIBLE else View.GONE } - - // Update add button visibility - addNameButton.visibility = if (basketNamesManager.canAddMore()) View.VISIBLE else View.GONE } private fun bindNameItem(view: View, index: Int, name: String, totalCount: Int) { diff --git a/app/src/main/java/com/electricdreams/numo/feature/history/PaymentsHistoryActivity.kt b/app/src/main/java/com/electricdreams/numo/feature/history/PaymentsHistoryActivity.kt index e0a968ca..0e8ab157 100644 --- a/app/src/main/java/com/electricdreams/numo/feature/history/PaymentsHistoryActivity.kt +++ b/app/src/main/java/com/electricdreams/numo/feature/history/PaymentsHistoryActivity.kt @@ -26,6 +26,7 @@ import com.electricdreams.numo.core.model.Amount import com.electricdreams.numo.core.util.CurrencyManager import com.electricdreams.numo.core.worker.BitcoinPriceWorker import com.electricdreams.numo.databinding.ActivityHistoryBinding +import com.electricdreams.numo.ui.components.EmptyStateHelper import com.electricdreams.numo.feature.autowithdraw.AutoWithdrawManager import com.electricdreams.numo.feature.autowithdraw.WithdrawHistoryEntry import com.electricdreams.numo.payment.PaymentIntentFactory @@ -349,7 +350,15 @@ class PaymentsHistoryActivity : AppCompatActivity() { adapter.setEntries(currentHistoryList) val isEmpty = currentHistoryList.isEmpty() - binding.emptyView.visibility = if (isEmpty) View.VISIBLE else View.GONE + binding.emptyView.root.visibility = if (isEmpty) View.VISIBLE else View.GONE + if (isEmpty) { + EmptyStateHelper.bind( + binding.emptyView.root, + R.drawable.ic_receipt, + "No Payments Yet", + "Payment history will appear here once you start accepting payments" + ) + } } private fun clearAllHistory() { diff --git a/app/src/main/java/com/electricdreams/numo/feature/history/TokenHistoryActivity.kt b/app/src/main/java/com/electricdreams/numo/feature/history/TokenHistoryActivity.kt index d7ce7a10..8bf6aa99 100644 --- a/app/src/main/java/com/electricdreams/numo/feature/history/TokenHistoryActivity.kt +++ b/app/src/main/java/com/electricdreams/numo/feature/history/TokenHistoryActivity.kt @@ -9,6 +9,7 @@ import androidx.appcompat.app.AppCompatActivity import androidx.recyclerview.widget.LinearLayoutManager import com.electricdreams.numo.feature.enableEdgeToEdgeWithPill import com.electricdreams.numo.R +import com.electricdreams.numo.ui.components.EmptyStateHelper import com.electricdreams.numo.core.data.model.TokenHistoryEntry import com.electricdreams.numo.databinding.ActivityHistoryBinding import com.electricdreams.numo.ui.adapter.TokenHistoryAdapter @@ -59,7 +60,15 @@ class TokenHistoryActivity : AppCompatActivity() { adapter.setEntries(history) val isEmpty = history.isEmpty() - binding.emptyView.visibility = if (isEmpty) View.VISIBLE else View.GONE + binding.emptyView.root.visibility = if (isEmpty) View.VISIBLE else View.GONE + if (isEmpty) { + EmptyStateHelper.bind( + binding.emptyView.root, + R.drawable.ic_receipt, + "No Tokens Yet", + "Cashu token history will appear here" + ) + } } private fun showClearHistoryConfirmation() { diff --git a/app/src/main/java/com/electricdreams/numo/feature/items/ItemListActivity.kt b/app/src/main/java/com/electricdreams/numo/feature/items/ItemListActivity.kt index 28cffb22..c453d6df 100644 --- a/app/src/main/java/com/electricdreams/numo/feature/items/ItemListActivity.kt +++ b/app/src/main/java/com/electricdreams/numo/feature/items/ItemListActivity.kt @@ -45,7 +45,6 @@ class ItemListActivity : AppCompatActivity() { private lateinit var bottomActions: LinearLayout private lateinit var fabAddItem: ImageButton private lateinit var doneReorderButton: ImageButton - private lateinit var headerDivider: View private lateinit var topBar: View private lateinit var adapter: ItemAdapter private lateinit var itemTouchHelper: ItemTouchHelper @@ -111,7 +110,6 @@ class ItemListActivity : AppCompatActivity() { bottomActions = findViewById(R.id.bottom_actions) fabAddItem = findViewById(R.id.fab_add_item) doneReorderButton = findViewById(R.id.done_reorder_button) - headerDivider = findViewById(R.id.header_divider) topBar = findViewById(R.id.top_bar) val importCsvButton: Button = findViewById(R.id.import_csv_button) val exportCsvButton: Button = findViewById(R.id.export_csv_button) @@ -209,7 +207,6 @@ class ItemListActivity : AppCompatActivity() { emptyView.visibility = View.GONE itemsContent.visibility = View.VISIBLE fabAddItem.visibility = View.VISIBLE - headerDivider.visibility = View.VISIBLE topBar.visibility = View.VISIBLE topBar.setBackgroundResource(R.color.color_bg_white) @@ -223,7 +220,6 @@ class ItemListActivity : AppCompatActivity() { emptyView.visibility = View.VISIBLE itemsContent.visibility = View.GONE fabAddItem.visibility = View.GONE - headerDivider.visibility = View.GONE topBar.visibility = View.GONE // Set navigation bar to match empty state background diff --git a/app/src/main/java/com/electricdreams/numo/feature/onboarding/AddMintBottomSheet.kt b/app/src/main/java/com/electricdreams/numo/feature/onboarding/AddMintBottomSheet.kt new file mode 100644 index 00000000..d4201208 --- /dev/null +++ b/app/src/main/java/com/electricdreams/numo/feature/onboarding/AddMintBottomSheet.kt @@ -0,0 +1,121 @@ +package com.electricdreams.numo.feature.onboarding + +import android.app.Dialog +import android.os.Bundle +import android.text.Editable +import android.text.TextWatcher +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import android.view.WindowManager +import android.widget.EditText +import android.widget.Button +import android.widget.FrameLayout +import android.widget.LinearLayout +import androidx.core.content.ContextCompat +import com.electricdreams.numo.R +import com.google.android.material.bottomsheet.BottomSheetBehavior +import com.google.android.material.bottomsheet.BottomSheetDialog +import com.google.android.material.bottomsheet.BottomSheetDialogFragment + +class AddMintBottomSheet : BottomSheetDialogFragment() { + + interface Listener { + fun onAddMintUrl(url: String) + fun onScanQrCode() + } + + private var listener: Listener? = null + + companion object { + fun newInstance(listener: Listener): AddMintBottomSheet { + return AddMintBottomSheet().apply { + this.listener = listener + } + } + } + + override fun getTheme(): Int = R.style.Theme_Numo_BottomSheet + + override fun onCreateDialog(savedInstanceState: Bundle?): Dialog { + val dialog = super.onCreateDialog(savedInstanceState) + dialog.window?.setSoftInputMode( + WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE + ) + dialog.window?.navigationBarColor = android.graphics.Color.parseColor("#0A2540") + return dialog + } + + override fun onCreateView( + inflater: LayoutInflater, + container: ViewGroup?, + savedInstanceState: Bundle? + ): View? { + return inflater.inflate(R.layout.bottom_sheet_add_mint, container, false) + } + + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + super.onViewCreated(view, savedInstanceState) + + val urlInput = view.findViewById(R.id.mint_url_input) + val addButton = view.findViewById