-
Notifications
You must be signed in to change notification settings - Fork 50
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #288 from hotwired/strada-sample
Strada sample components in the Demo app
- Loading branch information
Showing
18 changed files
with
472 additions
and
5 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -26,7 +26,8 @@ | |
}, | ||
{ | ||
"patterns": [ | ||
"/signin$" | ||
"/signin$", | ||
"/strada-form$" | ||
], | ||
"properties": { | ||
"context": "modal", | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
9 changes: 9 additions & 0 deletions
9
demo/src/main/kotlin/dev/hotwire/turbo/demo/strada/BridgeComponentFactories.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
package dev.hotwire.turbo.demo.strada | ||
|
||
import dev.hotwire.strada.BridgeComponentFactory | ||
|
||
val bridgeComponentFactories = listOf( | ||
BridgeComponentFactory("form", ::FormComponent), | ||
BridgeComponentFactory("menu", ::MenuComponent), | ||
BridgeComponentFactory("overflow-menu", ::OverflowMenuComponent) | ||
) |
92 changes: 92 additions & 0 deletions
92
demo/src/main/kotlin/dev/hotwire/turbo/demo/strada/FormComponent.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,92 @@ | ||
package dev.hotwire.turbo.demo.strada | ||
|
||
import android.util.Log | ||
import android.view.LayoutInflater | ||
import android.view.Menu | ||
import android.view.MenuItem | ||
import androidx.appcompat.widget.Toolbar | ||
import androidx.fragment.app.Fragment | ||
import dev.hotwire.strada.BridgeComponent | ||
import dev.hotwire.strada.BridgeDelegate | ||
import dev.hotwire.strada.Message | ||
import dev.hotwire.turbo.demo.R | ||
import dev.hotwire.turbo.demo.base.NavDestination | ||
import dev.hotwire.turbo.demo.databinding.FormComponentSubmitBinding | ||
import kotlinx.serialization.SerialName | ||
import kotlinx.serialization.Serializable | ||
|
||
/** | ||
* Bridge component to display a submit button in the native toolbar, | ||
* which will submit the form on the page when tapped. | ||
*/ | ||
class FormComponent( | ||
name: String, | ||
private val delegate: BridgeDelegate<NavDestination> | ||
) : BridgeComponent<NavDestination>(name, delegate) { | ||
|
||
private val submitButtonItemId = 37 | ||
private var submitMenuItem: MenuItem? = null | ||
private val fragment: Fragment | ||
get() = delegate.destination.fragment | ||
private val toolbar: Toolbar? | ||
get() = fragment.view?.findViewById(R.id.toolbar) | ||
|
||
override fun onReceive(message: Message) { | ||
when (message.event) { | ||
"connect" -> handleConnectEvent(message) | ||
"submitEnabled" -> handleSubmitEnabled() | ||
"submitDisabled" -> handleSubmitDisabled() | ||
else -> Log.w("TurboDemo", "Unknown event for message: $message") | ||
} | ||
} | ||
|
||
private fun handleConnectEvent(message: Message) { | ||
val data = message.data<MessageData>() ?: return | ||
showToolbarButton(data) | ||
} | ||
|
||
private fun handleSubmitEnabled() { | ||
toggleSubmitButton(true) | ||
} | ||
|
||
private fun handleSubmitDisabled() { | ||
toggleSubmitButton(false) | ||
} | ||
|
||
private fun showToolbarButton(data: MessageData) { | ||
val menu = toolbar?.menu ?: return | ||
val inflater = LayoutInflater.from(fragment.requireContext()) | ||
val binding = FormComponentSubmitBinding.inflate(inflater) | ||
val order = 999 // Show as the right-most button | ||
|
||
binding.formSubmit.apply { | ||
text = data.title | ||
setOnClickListener { | ||
performSubmit() | ||
} | ||
} | ||
|
||
menu.removeItem(submitButtonItemId) | ||
submitMenuItem = menu.add(Menu.NONE, submitButtonItemId, order, data.title).apply { | ||
actionView = binding.root | ||
setShowAsAction(MenuItem.SHOW_AS_ACTION_ALWAYS) | ||
} | ||
} | ||
|
||
private fun toggleSubmitButton(enable: Boolean) { | ||
val layout = submitMenuItem?.actionView ?: return | ||
|
||
FormComponentSubmitBinding.bind(layout).apply { | ||
formSubmit.isEnabled = enable | ||
} | ||
} | ||
|
||
private fun performSubmit(): Boolean { | ||
return replyTo("connect") | ||
} | ||
|
||
@Serializable | ||
data class MessageData( | ||
@SerialName("submitTitle") val title: String | ||
) | ||
} |
82 changes: 82 additions & 0 deletions
82
demo/src/main/kotlin/dev/hotwire/turbo/demo/strada/MenuComponent.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,82 @@ | ||
package dev.hotwire.turbo.demo.strada | ||
|
||
import android.util.Log | ||
import android.view.LayoutInflater | ||
import androidx.fragment.app.Fragment | ||
import androidx.recyclerview.widget.LinearLayoutManager | ||
import com.google.android.material.bottomsheet.BottomSheetDialog | ||
import dev.hotwire.strada.BridgeComponent | ||
import dev.hotwire.strada.BridgeDelegate | ||
import dev.hotwire.strada.Message | ||
import dev.hotwire.turbo.demo.base.NavDestination | ||
import dev.hotwire.turbo.demo.databinding.MenuComponentBottomSheetBinding | ||
import kotlinx.serialization.SerialName | ||
import kotlinx.serialization.Serializable | ||
|
||
/** | ||
* Bridge component to display a native bottom sheet menu, which will | ||
* send the selected index of the tapped menu item back to the web. | ||
*/ | ||
class MenuComponent( | ||
name: String, | ||
private val delegate: BridgeDelegate<NavDestination> | ||
) : BridgeComponent<NavDestination>(name, delegate) { | ||
|
||
private val fragment: Fragment | ||
get() = delegate.destination.fragment | ||
|
||
override fun onReceive(message: Message) { | ||
when (message.event) { | ||
"display" -> handleDisplayEvent(message) | ||
else -> Log.w("TurboDemo", "Unknown event for message: $message") | ||
} | ||
} | ||
|
||
private fun handleDisplayEvent(message: Message) { | ||
val data = message.data<MessageData>() ?: return | ||
showBottomSheet(data.title, data.items) | ||
} | ||
|
||
private fun showBottomSheet(title: String, items: List<Item>) { | ||
val view = fragment.view?.rootView ?: return | ||
val inflater = LayoutInflater.from(view.context) | ||
val bottomSheet = BottomSheetDialog(view.context) | ||
val binding = MenuComponentBottomSheetBinding.inflate(inflater) | ||
|
||
binding.toolbar.title = title | ||
binding.recyclerView.layoutManager = LinearLayoutManager(view.context) | ||
binding.recyclerView.adapter = MenuComponentAdapter().apply { | ||
setData(items) | ||
setListener { | ||
bottomSheet.dismiss() | ||
onItemSelected(it) | ||
} | ||
} | ||
|
||
bottomSheet.apply { | ||
setContentView(binding.root) | ||
show() | ||
} | ||
} | ||
|
||
private fun onItemSelected(item: Item) { | ||
replyTo("display", SelectionMessageData(item.index)) | ||
} | ||
|
||
@Serializable | ||
data class MessageData( | ||
@SerialName("title") val title: String, | ||
@SerialName("items") val items: List<Item> | ||
) | ||
|
||
@Serializable | ||
data class Item( | ||
@SerialName("title") val title: String, | ||
@SerialName("index") val index: Int | ||
) | ||
|
||
@Serializable | ||
data class SelectionMessageData( | ||
@SerialName("selectedIndex") val selectedIndex: Int | ||
) | ||
} |
Oops, something went wrong.