-
-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Nexus.R (React)
- Loading branch information
Showing
46 changed files
with
2,839 additions
and
64 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
[submodule "addons/nexus.entour"] | ||
path = addons/nexus.entour | ||
url = https://github.com/ShindouMihou/nexus.entour | ||
|
||
[submodule "addons/nexus.coroutines"] | ||
path = addons/nexus.coroutines | ||
url = https://github.com/ShindouMihou/nexus.coroutines |
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 |
---|---|---|
@@ -0,0 +1,15 @@ | ||
# Addons | ||
|
||
In order to keep the repository specific to the actual functionalities of the Nexus features, | ||
other cool things that would be nice to have in Nexus, such as confirmation menus, etc. are stored into different | ||
repositories and linked here through Git Submodule for others to see. | ||
|
||
Here are the list of each different add-on that extends upon Nexus' features: | ||
- [`entour`](nexus.entour) is a set of handy built-in components, hooks and tools for Nexus.R. This contains many | ||
different things for develoeprs who uses Nexus.R such as Confirmation Menus. | ||
- [`coroutines`](nexus.coroutines) adds coroutine support to the framework. | ||
|
||
### Contributing | ||
|
||
If you want to add your repository into this list, feel free to create a Issue stating the name, repository link and | ||
the description for your repository. |
Submodule nexus.coroutines
added at
70dc51
Submodule nexus.entour
added at
9b2d80
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 |
---|---|---|
@@ -0,0 +1,43 @@ | ||
import org.javacord.api.event.interaction.MessageContextMenuCommandEvent | ||
import org.javacord.api.interaction.MessageContextMenuInteraction | ||
import pw.mihou.nexus.features.command.facade.NexusCommandEvent | ||
import pw.mihou.nexus.features.command.facade.NexusHandler | ||
import pw.mihou.nexus.features.contexts.NexusContextMenuEvent | ||
import pw.mihou.nexus.features.contexts.NexusMessageContextMenu | ||
import pw.mihou.nexus.features.contexts.NexusUserContextMenu | ||
import pw.mihou.nexus.features.messages.R | ||
import pw.mihou.nexus.features.react.elements.Button | ||
import pw.mihou.nexus.features.react.elements.Embed | ||
import java.time.Instant | ||
|
||
/** | ||
* Nexus.R supports basically everything, you can copy-paste the code from one event to another and it'll work | ||
* the same regardless without much if any modification. In this example, we demonstrate how we can use Nexus.R | ||
* to build amazingly simple yet reactive component. | ||
* | ||
* Our example will render a simple message with a button that increments the click count and re-render the | ||
* message whenever a click is registered. | ||
*/ | ||
object ContextMenu: NexusMessageContextMenu() { | ||
val name = "react" | ||
override fun onEvent(event: NexusContextMenuEvent<MessageContextMenuCommandEvent, MessageContextMenuInteraction>) { | ||
event.R { | ||
var clicks by writable(0) | ||
render { | ||
Embed { | ||
Title("Rendered with Nexus.R") | ||
SpacedBody( | ||
p("This message was rendered with Nexus.R."), | ||
p("The button has been clicked ") + bold("$clicks times.") | ||
) | ||
Color(java.awt.Color.YELLOW) | ||
Timestamp(Instant.now()) | ||
} | ||
Button(label = "Click me!") { | ||
it.buttonInteraction.acknowledge() | ||
clicks += 1 | ||
} | ||
} | ||
} | ||
} | ||
} |
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,58 @@ | ||
import org.javacord.api.event.interaction.ButtonClickEvent | ||
import org.javacord.api.event.interaction.MessageContextMenuCommandEvent | ||
import org.javacord.api.event.interaction.SelectMenuChooseEvent | ||
import org.javacord.api.interaction.Interaction | ||
import org.javacord.api.interaction.MessageContextMenuInteraction | ||
import org.javacord.api.listener.interaction.ButtonClickListener | ||
import org.javacord.api.listener.interaction.SelectMenuChooseListener | ||
import pw.mihou.nexus.features.command.facade.NexusCommandEvent | ||
import pw.mihou.nexus.features.command.facade.NexusHandler | ||
import pw.mihou.nexus.features.commons.R | ||
import pw.mihou.nexus.features.contexts.NexusContextMenuEvent | ||
import pw.mihou.nexus.features.contexts.NexusMessageContextMenu | ||
import pw.mihou.nexus.features.contexts.NexusUserContextMenu | ||
import pw.mihou.nexus.features.messages.R | ||
import pw.mihou.nexus.features.react.elements.Button | ||
import pw.mihou.nexus.features.react.elements.Embed | ||
import java.time.Instant | ||
|
||
/** | ||
* Nexus.R supports basically everything, you can copy-paste the code from one event to another and it'll work | ||
* the same regardless without much if any modification. In this example, we demonstrate how we can use Nexus.R | ||
* to build amazingly simple yet reactive component. | ||
* | ||
* Our example will render a simple message with a button that increments the click count and re-render the | ||
* message whenever a click is registered. | ||
*/ | ||
object InteractionExample: ButtonClickListener, SelectMenuChooseListener { | ||
private fun render(interaction: Interaction) { | ||
interaction.R(ephemeral = false) { | ||
var clicks by writable(0) | ||
render { | ||
Embed { | ||
Title("Rendered with Nexus.R") | ||
SpacedBody( | ||
p("This message was rendered with Nexus.R."), | ||
p("The button has been clicked ") + bold("$clicks times.") | ||
) | ||
Color(java.awt.Color.YELLOW) | ||
Timestamp(Instant.now()) | ||
} | ||
Button(label = "Click me!") { | ||
it.buttonInteraction.acknowledge() | ||
clicks += 1 | ||
} | ||
} | ||
} | ||
} | ||
|
||
override fun onButtonClick(event: ButtonClickEvent) { | ||
render(event.interaction) | ||
} | ||
|
||
override fun onSelectMenuChoose(event: SelectMenuChooseEvent) { | ||
render(event.interaction) | ||
} | ||
|
||
|
||
} |
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,39 @@ | ||
import org.javacord.api.event.message.MessageCreateEvent | ||
import org.javacord.api.listener.message.MessageCreateListener | ||
import pw.mihou.nexus.features.messages.R | ||
import pw.mihou.nexus.features.react.elements.Button | ||
import pw.mihou.nexus.features.react.elements.Embed | ||
import java.time.Instant | ||
|
||
/** | ||
* Nexus.R supports basically everything, you can copy-paste the code from one event to another and it'll work | ||
* the same regardless without much if any modification. In this example, we demonstrate how we can use Nexus.R | ||
* to build amazingly simple yet reactive component. | ||
* | ||
* Our example will render a simple message with a button that increments the click count and re-render the | ||
* message whenever a click is registered. | ||
*/ | ||
object MessageEvent: MessageCreateListener { | ||
override fun onMessageCreate(event: MessageCreateEvent) { | ||
if (event.messageContent == "%nexus.r") { | ||
event.R { | ||
var clicks by writable(0) | ||
render { | ||
Embed { | ||
Title("Rendered with Nexus.R") | ||
SpacedBody( | ||
p("This message was rendered with Nexus.R."), | ||
p("The button has been clicked ") + bold("$clicks times.") | ||
) | ||
Color(java.awt.Color.YELLOW) | ||
Timestamp(Instant.now()) | ||
} | ||
Button(label = "Click me!") { | ||
it.buttonInteraction.acknowledge() | ||
clicks += 1 | ||
} | ||
} | ||
} | ||
} | ||
} | ||
} |
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,31 @@ | ||
# nexus.R | ||
|
||
React Native + Svelte for Discord Bots. Nexus.R is an innovative way to create and send responses or messages | ||
to any text channel or interaction from slash commands to messages commands and even Users or text channels | ||
with reactivity, enabling quick and simple re-rendering of messages upon state changes. | ||
|
||
### Features | ||
- [x] Write-once, Use Everywhere | ||
- Nexus.R allows you to easily reuse responses whether it was written for slash commands or | ||
for messages with hardly any changes. | ||
- [x] States in Discord Bot | ||
- Nexus.R introduces the infamous states of JavaScript world into Discord bots, allowing you to create | ||
messages that will re-render itself upon different state changes, just like a reactive website! | ||
- [x] Webdev-like Feel | ||
- In order to make Discord bot development more accessible to even web developers, we've made the | ||
feature feel like writing web code (JSX) but simpler! | ||
|
||
### Table of Contents | ||
|
||
As Nexus.R is incredibly simple, you can read the examples and pretty much get a gist of how to use it. Here | ||
are the examples we think that you should read first though: | ||
1. [**Starting out with Nexus.R**](): It's all the same, except for how it's started. *Read which one you prefer to see.* | ||
- [Slash Commands](SlashCommand.kt) | ||
- [Context Menus](ContextMenu.kt) | ||
- [Message Events i.e. Message Commands](MessageEvent.kt) | ||
- [Interactions i.e. Buttons and Select Menus](Interaction.kt) | ||
2. [**Passing State to Another Function**](%5B1%5D_passing_state): As states are not simply the same regular Kotlin properties, there needs a | ||
little bit of a very tiny change when you want to pass state to another function outside of the `Nexus.R` scope. | ||
3. [**Creating Components**](%5B2%5D_components): Reusing code is also important in coding, and components are just one way to reuse code | ||
4. [**Data Fetching**](%5B3%5D_data_fetching/DataFetching.kt): Data fetching is also an important factor in many bots, this is how you can load data before rending the message! | ||
5. [**Hooks**](%5B4%5D_hooks): Hooks are vital to be able to reuse a lot of code, unlike components, hooks are not affected by rerenders and is a great place to define writables and related! |
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,39 @@ | ||
import pw.mihou.nexus.features.command.facade.NexusCommandEvent | ||
import pw.mihou.nexus.features.command.facade.NexusHandler | ||
import pw.mihou.nexus.features.messages.R | ||
import pw.mihou.nexus.features.react.elements.Button | ||
import pw.mihou.nexus.features.react.elements.Embed | ||
import java.time.Instant | ||
|
||
/** | ||
* Nexus.R supports basically everything, you can copy-paste the code from one event to another and it'll work | ||
* the same regardless without much if any modification. In this example, we demonstrate how we can use Nexus.R | ||
* to build amazingly simple yet reactive component. | ||
* | ||
* Our example will render a simple message with a button that increments the click count and re-render the | ||
* message whenever a click is registered. | ||
*/ | ||
object SlashCommand: NexusHandler { | ||
val name = "react" | ||
val description = "Shows a demonstration of Nexus.R." | ||
override fun onEvent(event: NexusCommandEvent) { | ||
event.R { | ||
var clicks by writable(0) | ||
render { | ||
Embed { | ||
Title("Rendered with Nexus.R") | ||
SpacedBody( | ||
p("This message was rendered with Nexus.R."), | ||
p("The button has been clicked ") + bold("$clicks times.") | ||
) | ||
Color(java.awt.Color.YELLOW) | ||
Timestamp(Instant.now()) | ||
} | ||
Button(label = "Click me!") { | ||
it.buttonInteraction.acknowledge() | ||
clicks += 1 | ||
} | ||
} | ||
} | ||
} | ||
} |
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,73 @@ | ||
import pw.mihou.nexus.features.command.facade.NexusCommandEvent | ||
import pw.mihou.nexus.features.command.facade.NexusHandler | ||
import pw.mihou.nexus.features.react.React | ||
import pw.mihou.nexus.features.react.elements.Button | ||
import pw.mihou.nexus.features.react.elements.Embed | ||
import pw.mihou.nexus.features.react.writable.plusAssign | ||
import java.time.Instant | ||
|
||
/** | ||
* This example demonstrates how you pass [React.Writable] from the render function to another function. | ||
* Unlike JavaScript frameworks, this isn't easily done as Kotlin maintains an immutable-only function argument, | ||
* which means that we have to circumvent this by also maintaining the original [React.Writable] instance itself and | ||
* passing that instead. | ||
*/ | ||
object PassingState: NexusHandler { | ||
val name = "react" | ||
val description = "Shows a demonstration of Nexus.R." | ||
override fun onEvent(event: NexusCommandEvent) { | ||
event.R { | ||
// As we need to maintain the original Writable instance, we need to separate it from the | ||
// delegated property, this property won't have the native setter and related. | ||
val clicksDelegate = writable(0) | ||
var clicks by clicksDelegate | ||
|
||
render { | ||
Embed { | ||
Title("Rendered with Nexus.R") | ||
SpacedBody( | ||
p("This message was rendered with Nexus.R."), | ||
p("The button has been clicked ") + bold("$clicks times.") | ||
) | ||
Color(java.awt.Color.YELLOW) | ||
Timestamp(Instant.now()) | ||
} | ||
Button(label = "Click me!") { | ||
it.buttonInteraction.acknowledge() | ||
increment(clicksDelegate) | ||
} | ||
Button(label = "Click this!") { | ||
it.buttonInteraction.acknowledge() | ||
clicks += 1 | ||
} | ||
Button(label = "Click also!") { | ||
it.buttonInteraction.acknowledge() | ||
incrementDelegated(clicksDelegate) | ||
} | ||
} | ||
} | ||
} | ||
|
||
/** | ||
* This demonstrates using the [React.Writable] methods to manipulate the value of the [React.Writable], thereby | ||
* causing a re-render. Generally, unless you perform a ton of manipulation, you can live with this. | ||
*/ | ||
private fun increment(clicks: React.Writable<Int>) { | ||
// Newer version after a recent commit adding operator overloads over primitive types | ||
// and lists. | ||
clicks += 1 | ||
|
||
// Older method and more optimal for cases that are not supported with the operator overloads | ||
// such as types that are not supported. | ||
// clicks.update { it + 1 } | ||
} | ||
|
||
/** | ||
* This demonstrates how you can also still delegate inside the method as well to maintain | ||
* a similar feel to how a regular property would. | ||
*/ | ||
private fun incrementDelegated(clicksDelegate: React.Writable<Int>) { | ||
var clicks by clicksDelegate | ||
clicks += 1 | ||
} | ||
} |
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,8 @@ | ||
# Passing States (Writables) | ||
|
||
As writables aren't simple properties, we can't just simply pass them to another function outside of the `Nexus.R` scope and expect it to work the same | ||
especially since Kotlin doesn't support mutable function arguments. As such, in this example, we demonstrate how to properly pass writables from the | ||
`Nexus.R` scope to another function by passing the Delegate class (`React.Writable`) itself. | ||
|
||
In the example, we also demonstrate how the `React.Writable` can then be delegated again inside the other function and | ||
will still re-render the message when needed. |
Oops, something went wrong.