summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--build.gradle.kts8
-rw-r--r--gradle.properties1
-rw-r--r--src/main/kotlin/moe/nea89/website/App.kt26
-rw-r--r--src/main/kotlin/moe/nea89/website/AsciiArt.kt5
-rw-r--r--src/main/kotlin/moe/nea89/website/Command.kt7
-rw-r--r--src/main/kotlin/moe/nea89/website/KConsole.kt112
-rw-r--r--src/main/kotlin/moe/nea89/website/Styles.kt31
-rw-r--r--src/main/kotlin/moe/nea89/website/index.kt24
-rw-r--r--src/main/resources/asciiart/boob.txt96
-rw-r--r--src/main/resources/index.html1
-rw-r--r--webpack.conf.d/style.js1
-rw-r--r--webpack.config.d/style.js2
12 files changed, 276 insertions, 38 deletions
diff --git a/build.gradle.kts b/build.gradle.kts
index 140e1e2..a88b52f 100644
--- a/build.gradle.kts
+++ b/build.gradle.kts
@@ -1,7 +1,6 @@
plugins {
- kotlin("js") version "1.5.31"
- kotlin("plugin.serialization") version "1.5.31"
- id("com.bnorm.react.kotlin-react-function") version "0.6.0"
+ kotlin("js") version "1.6.0"
+ kotlin("plugin.serialization") version "1.6.0"
id("com.github.node-gradle.node") version "3.1.1"
}
@@ -24,10 +23,7 @@ kotlin {
val processResources by tasks.getting(Copy::class)
dependencies {
- implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:1.3.0")
- implementation("org.jetbrains.kotlinx:kotlinx-datetime:0.2.1")
implementation(enforcedPlatform("org.jetbrains.kotlin-wrappers:kotlin-wrappers-bom:0.0.1-pre.256-kotlin-1.5.31"))
- implementation("org.jetbrains.kotlin-wrappers:kotlin-react-dom")
implementation("org.jetbrains.kotlin-wrappers:kotlin-styled")
implementation(npm("@fontsource/comic-mono", "^4.5.0"))
implementation(npm("prop-types", "^15.6.2"))
diff --git a/gradle.properties b/gradle.properties
index cc2c342..06f6685 100644
--- a/gradle.properties
+++ b/gradle.properties
@@ -1,2 +1 @@
kotlin.incremental=false
-kotlin.js.webpack.major.version=4
diff --git a/src/main/kotlin/moe/nea89/website/App.kt b/src/main/kotlin/moe/nea89/website/App.kt
deleted file mode 100644
index aa96825..0000000
--- a/src/main/kotlin/moe/nea89/website/App.kt
+++ /dev/null
@@ -1,26 +0,0 @@
-package moe.nea89.website
-
-import com.bnorm.react.RFunction
-import react.RBuilder
-import react.dom.li
-import react.dom.nav
-import react.dom.ul
-
-
-@RFunction
-fun RBuilder.App() {
- Navigation()
-}
-
-@RFunction
-fun RBuilder.Navigation() {
- nav {
- ul {
- li { +"Hehe" }
- li { +"Hihi" }
- li { +"Hoho" }
- li { +"Haha" }
- li { +"Huhu" }
- }
- }
-}
diff --git a/src/main/kotlin/moe/nea89/website/AsciiArt.kt b/src/main/kotlin/moe/nea89/website/AsciiArt.kt
new file mode 100644
index 0000000..6acc8b5
--- /dev/null
+++ b/src/main/kotlin/moe/nea89/website/AsciiArt.kt
@@ -0,0 +1,5 @@
+package moe.nea89.website
+
+import kotlinext.js.require
+
+val boobs = require("./asciiart/boob.txt") as String \ No newline at end of file
diff --git a/src/main/kotlin/moe/nea89/website/Command.kt b/src/main/kotlin/moe/nea89/website/Command.kt
new file mode 100644
index 0000000..f896987
--- /dev/null
+++ b/src/main/kotlin/moe/nea89/website/Command.kt
@@ -0,0 +1,7 @@
+package moe.nea89.website
+
+interface Command {
+ val name: String
+ val aliases: Set<String>
+ fun run(console: KConsole, name: String, args: List<String>)
+} \ No newline at end of file
diff --git a/src/main/kotlin/moe/nea89/website/KConsole.kt b/src/main/kotlin/moe/nea89/website/KConsole.kt
new file mode 100644
index 0000000..d6e4349
--- /dev/null
+++ b/src/main/kotlin/moe/nea89/website/KConsole.kt
@@ -0,0 +1,112 @@
+package moe.nea89.website
+
+import kotlinx.browser.document
+import kotlinx.html.dom.append
+import kotlinx.html.js.pre
+import org.w3c.dom.HTMLElement
+import org.w3c.dom.HTMLPreElement
+import org.w3c.dom.events.KeyboardEvent
+
+class KConsole(private val root: HTMLElement, private val text: HTMLPreElement) {
+
+ companion object {
+ val shlexRegex =
+ """"([^"\\]+|\\.)+"|([^ "'\\]+|\\.)+|'([^'\\]+|\\.)+'""".toRegex()
+
+ fun createFor(element: HTMLElement): KConsole {
+ val text = element.append.pre()
+ element.classList.add(Styles.consoleClass)
+ val console = KConsole(element, text)
+ document.body!!.onkeydown = console::keydown
+ console.addLine("Starting up terminal.")
+ console.rerender()
+ return console
+ }
+ }
+
+ val lines = mutableListOf<String>()
+
+ var input: String = ""
+
+ fun addLines(newLines: List<String>) {
+ lines.addAll(newLines)
+ }
+
+ fun addMultilineText(text: String) {
+ addLines(text.split("\n"))
+ }
+
+ fun addLine(line: String) {
+ lines.add(line)
+ scrollDown()
+ }
+
+ fun rerender() {
+ val view = lines.joinToString(separator = "\n") + "\n${'$'} $input"
+ text.innerText = view
+ }
+
+ fun registerCommand(command: Command) {
+ command.aliases.forEach {
+ commands[it] = command
+ }
+ commands[command.name] = command
+ }
+
+ val commands = mutableMapOf<String, Command>()
+
+ fun scrollDown() {} // TODO scroooooll
+
+ fun executeCommand(command: String) {
+ val parts = shlex(command)
+ if (parts.isNullOrEmpty()) {
+ addLine("Syntax Error")
+ return
+ }
+ val command = parts[0]
+ println("Running command: $command")
+ val arguments = parts.drop(1)
+ val commandThing = commands[command]
+ if (commandThing == null) {
+ addLine("Unknown command")
+ return
+ }
+ commandThing.run(this, command, arguments)
+ }
+
+ @OptIn(ExperimentalStdlibApi::class)
+ fun shlex(command: String): List<String>? {
+ var i = 0
+ val parts = mutableListOf<String>()
+ while (i < command.length) {
+ val match = shlexRegex.matchAt(command, i)
+ if (match == null) {
+ println("Could not shlex: $command")
+ return null
+ }
+ parts.add(match.groupValues.drop(1).firstOrNull { it != "" } ?: "")
+ i += match.value.length
+ while (command[i] == ' ' && i < command.length)
+ i++
+ }
+ return parts
+ }
+
+ fun keydown(event: KeyboardEvent) {
+ if (event.altKey || event.ctrlKey || event.metaKey) return
+ if (event.isComposing || event.keyCode == 229) return
+ when (event.key) {
+ "Enter" -> {
+ val toExecute = input
+ addLine("${'$'} $toExecute")
+ input = ""
+ executeCommand(toExecute)
+ }
+ "Backspace" -> input = input.substring(0, input.length - 1)
+ else ->
+ if (event.key.length == 1 || event.key.any { it !in 'a'..'z' && it !in 'A'..'Z' })
+ input += event.key
+ }
+ rerender()
+ }
+}
diff --git a/src/main/kotlin/moe/nea89/website/Styles.kt b/src/main/kotlin/moe/nea89/website/Styles.kt
new file mode 100644
index 0000000..6d10e7e
--- /dev/null
+++ b/src/main/kotlin/moe/nea89/website/Styles.kt
@@ -0,0 +1,31 @@
+package moe.nea89.website
+
+import kotlinx.css.*
+import styled.StyleSheet
+
+
+object Styles : StyleSheet("Styles") {
+ val consoleClass = "Console"
+
+ val bgColor = Color("#123456")
+ val fgColor = Color("#efefef")
+ val comicMono = "\"Comic Mono\", monospace"
+
+ val global by css {
+ root {
+ margin(0.px)
+ boxSizing = BoxSizing.borderBox
+ }
+ body {
+ width = 100.pct
+ height = 100.pct
+ backgroundColor = bgColor
+ color = fgColor
+ fontFamily = comicMono
+ }
+ ".$consoleClass" {
+ width = 100.pct
+ height = 100.pct
+ }
+ }
+} \ No newline at end of file
diff --git a/src/main/kotlin/moe/nea89/website/index.kt b/src/main/kotlin/moe/nea89/website/index.kt
index f10728a..8496b3a 100644
--- a/src/main/kotlin/moe/nea89/website/index.kt
+++ b/src/main/kotlin/moe/nea89/website/index.kt
@@ -1,10 +1,28 @@
package moe.nea89.website
-import kotlinx.browser.document
-import react.dom.render
import kotlinext.js.require
+import kotlinx.browser.document
+import kotlinx.html.dom.append
+import kotlinx.html.js.div
+import styled.injectGlobal
fun main() {
require("@fontsource/comic-mono/index.css")
- render(document.getElementById("root") ?: throw RuntimeException("Could not find root element")) { App() }
+ injectGlobal(Styles.global)
+ val root = document.body!!.append.div()
+ val console = KConsole.createFor(root)
+ console.registerCommand(object : Command {
+ override val name: String = "dick"
+ override val aliases: Set<String> = setOf("cock")
+ override fun run(console: KConsole, name: String, args: List<String>) {
+ console.addMultilineText("Hehe")
+ }
+ })
+ console.registerCommand(object : Command {
+ override val name: String = "booob"
+ override val aliases: Set<String> = setOf("boob")
+ override fun run(console: KConsole, name: String, args: List<String>) {
+ console.addMultilineText(boobs)
+ }
+ })
} \ No newline at end of file
diff --git a/src/main/resources/asciiart/boob.txt b/src/main/resources/asciiart/boob.txt
new file mode 100644
index 0000000..6ce2b11
--- /dev/null
+++ b/src/main/resources/asciiart/boob.txt
@@ -0,0 +1,96 @@
+ ,c="""=c,_
+ _,j "==c,
+ ,="`J" "h.
+ ,r"" c="?r `L
+ p" "$ ",
+ c" ;F `"c. ".
+ J' $ `h `h.
+ J' ,-"j" t `h
+ ,P ," " `h.
+ ,J' ," c `h
+ J' J' "h `h
+ J / ". `h.
+ $ ; ; `h `$.
+ $ `. ``; `. .`h `=q
+ J `. . `.`; `. .`.h "
+ F `. `.; ` `.; `. `.?
+ j' .`. `.\ `.` `.`?`.`.`.?:
+ $ `.`.` `.j`.`.;.`. `.3.`.`.`L`.
+ .f `.`.`. `.?$.`.?.`.`.`.`$`.`.`$`.`
+ $ `.`.`.`.`.`.$.`.`Lc.`.`.`.h.`.`$`.`.
+ j' `.`.`.`.`.`.$.`.`.h?cccci';h`.`?L.`.`.
+ J `.`.`.`.`.`$'?h.`J?,c$?`.?hP'?""?r`.`.`
+ `P `.`.L.`.`.j'`.`."=-"`.`z?$??$$F'3F`.J.`.
+ `L `.`.`h`.`.$$??`.`.`.`.$,c$$P".`.J..J`.`.
+ ? `.`.`?i,c$$?$"3$`.`.`.`.`.`.`.`.$.j'`.`.
+ `h `.`.`.$$$.$i$P".`)`.`.`.`.`.`.`.$.$.`.`.
+ `r `.`.`.;;F.`.`.`.`.`.`.`.`.`.`.`.$.$.`.P'
+ ;f `.`.`(;;h.`.`.`.`.`.`.`.`.`.`.`.$.F.`$`.`
+ J" `.`.`.t;$.`.`.`.`.`.`.`;;.`.`.`.$.$.j'`.`.`
+ P .`.`.`\9;`.`.`.`.`.,c'J?.`.`.`.$;$.J.`.`.`.
+ j' .`.`.`.?C`.`.`;;`."".`.`.`.`.`.?'`h$.`.`.`.`.
+ L .`.`.`.`.h.`./.`.`,ccc$??hJ?$F.`.`.?r`.`.`.`.`.
+ $ y`.`.`.`.`?i.`.;??li??"' .$$`.`.`.`$`.`.`.`.`.`
+ `) ; ; u.`.`.`.`.`?;.`$?; .,;c?iP.`.`.`.`?,.`.`.`.`.`. .`
+ f t l $.`.`.`.`.``?;.`?;;;;;;iP"`.`.`.`.`;$,`.`.`.`.`.`.` `.
+ t ) ,q l $.`.`.`.`.`.`"h.`"??""`.`.`.`.`.`.J?J`t.`.`.`.`.`.` `.`
+ "j=" "f $.`.`.`.`.`.`.`$`.`.`.`.`.`.`.``c?;;$.`.t.`.`.`.`. `.`
+ $.`.`.`.`.`.`.`.?h`.`.`.`.`.`.j";;;9'.`.`.?.`,P.` `.`
+ $.`.`.`.`.`.`.`.`"?y`.`.`.`,J?;;;;;F`.`.`.J?".`. `.`
+ .P.`.`.`.`.`.`.`.`.`.?hccd??;;;;;;;9c$r`.`j'.`.`. .`.`
+ J`.`.`.\.`.`.`.`.`.`.`.`$;;;;;;;;;;;;;$`.`P`.`.`. .`.`
+ $`.`.`.`?`.`.`.`.`.`.`.`.h;;;;;;;;;;;;9`.f.`.`,P `.`.`
+ ?`.`.`.`.h.`.`.`.`.`.`.`.`h;;;;;;;;;;;9`j`.`.$' .`.`.`
+ h.`;`.l.$.`.`.`.`.`.`.`.`.?;;;;;;;;;;$".`.`J.` `.`.`.`
+ ?.`P`.l.F.c.`.`f`.`.`.`.`.`?;;;;;jjii$`.`.`$.` .`.`$`.`
+ "$.`P`J`.$.`.`h`.`.`.`.`.`.F""""` $`.`.`$.` ?.`.`$`.`
+ J"`$.,"$.`.`?`.`.`.`.`.`j' ,JL.`.`$.` `3.`.`?`.`
+ `=chJ" ?.`.`.?i`.`.`.`.`$$?????"" L`.`$`.`.3r`.`(l,c
+ ,P ?`.`.`.?.`.`.`.J" ?`.`3`.`.`h`.`P
+ J ,c ?i`.`.`3`.`.`J" "i,$"=i,J"c;P
+ j' J" `h.`.`3`.`_J"
+ $ J" ?`.`3P""'
+ ,LJ' h._$
+ J" . `" -c,
+ j'(r "??cc,,_ h $
+ 3.P `"""""=c,,_ ? `L
+ zP""??cc,__ "=,_ ? ". L
+ .P ""??cc,_ "=c_ $ ". $ .
+ ," `"h,_ `=c. $ ". h $
+ ,J' `"==c, `"$h ". $ .F
+ ," """===cc,,, "?c, "??h `L J
+ J' "=c,_ `?. ?. P
+ J' "c, `?. h j'
+ ,J??;;??$c,,_ `=cccc, "r $$ $
+ c"`.`.`.`;;;;;;??c,._ "=c . "h. 3 .f
+ J??P`.`.`.`.`.;;;;;;;;;??;"==ccy, "c `h "c, 3 j
+,$i;;P`.`.`.`.`.`;;;;;;;;P`.`;ccc,"c `h ". "h. j.$
+'hC;9F`.`.`.`.`.`.;;;;;;F.`.$9?;h;;$F ?. ". "?$'
+ ?h;P.`.`.`.`.`.`.;;;;;j'.`3;;???;;$?L ?. "c $
+ $P`.`.`.`.`.`.`.,;;;;9`.`?h;;;;;?'`.h ? "h $
+ ?;`.`.`.`.`.`.`.;;;;;9`.`.`"????`.`.?L "h $
+ $`.`.`.`.`.`.`;;;;;;9`.`.`.`.`.`.`.``h `$
+ L.`.`.`.`.``;;;;;;;?`.`.`.`.`.`.`.`.`$ `, $
+ `L`.`.`.`.`;;;j;;;;;L.`.`.`.`.`.`.`.`.?. ", ?.
+ ?i`.`.`.;;;j;;;;;;?;`.`.`.`.`.`.`.`.`.h `, L
+ `?i..`,;;$;;';;;.`.h.`.`.`.`.`.`.`.`.`?c $ h
+ "?h$??F.``;;;.`.;$c.`.`.`.`.`.`.`.`.`$L `h J
+ $;`.`;;`.`.`;;?hy_.`.`.`.`.`.`,c$$h. ?.j'
+ .$`.`.;;`.`.`.;;;;"??$ccyyyccJ??;;;$3c $$
+ j'`.`.;.`.`.`.`.;;;;;;;;;;;;;;;;;;;;$`h `$
+ .$.`.`.`.`.`.`.`.``;;;;;;;;;;;;;;.`;;;$ "c $
+ j'.`.`.`.`.`.`.`.`.`.`.`.`.`.`.`.`.`;;;$. "c $-
+ $`.`.`.`.`.`.`.`.`.`.`.`.`.`.`.`.`.`.;;;$. $L, $
+ $`.`.`.`.`.`.`.`.`.`.`.`.`.`.`.`.`.`.`;;;$ `h "h .$ ,P
+ F`.`.`.`.`.`.`.`.`.`.`.`.`.`.`.`.`.`.`.;;;h `h "h ;F. $
+ C`.`.`.`.`.`.`.`.`.`.`.`.`.`.`.`.`.`.`.`;;;L `r $, $ ?,f
+ h`.`.`.`.`.`.`.`.`.`.`.`.`.`.`.`.`.`.`.`.;;9r ? `fcF $
+ $`.`.`.`.`.`.`.`.`.`.`.`.`.`.`.`.`.`.`.`.;;;$ L $ j'
+ $`.`.`.`.`.`.`.`.`.`.`.`.`.`.`.`.`.`.`.`.;;;;$ $ $ J'
+ $`.`.`.`.`.`.`.`.`.`.`.`.`.`.`.`.`.`.`.`;;;;;?h `cc=' J'
+ $`.`.`.`.`.`.`.`.`.`.`.`.`.`.`.`.`.`.`.,;;;;;;9.J $
+ ?`.`.`.`.`.`.`.`.`.`.`.`.`.`.`.`.`.`.`,;;;;;;;$$' $
+ `h.`.`.`.`.`.`.`.`.`.`.`.`.`.`.`.`.`.,;;;;;;;9" $
+ $.`.`.`.`.`.`.`.`.`.`.`.`.`.`.`.`.`.;;;;;;;;9 "h
+ $.`.`.`.`.`.`.`.`.`.`.`.`.`.`.`.`.`;;;;;;;;;$ c????c
+ j.`.`.`.`.`.`.`.`.`.`.`.`.`.`.`.`.`;;;;;;;;;9 .P \ No newline at end of file
diff --git a/src/main/resources/index.html b/src/main/resources/index.html
index 31e2631..ca5f28f 100644
--- a/src/main/resources/index.html
+++ b/src/main/resources/index.html
@@ -9,7 +9,6 @@
</head>
<body>
<noscript>You need to enable JavaScript to run this app.</noscript>
-<div id="root"></div >
<script type="text/javascript" src="neamoe.js"></script>
</body>
</html> \ No newline at end of file
diff --git a/webpack.conf.d/style.js b/webpack.conf.d/style.js
deleted file mode 100644
index 24f6324..0000000
--- a/webpack.conf.d/style.js
+++ /dev/null
@@ -1 +0,0 @@
-config.resolve.modules.push("src/main/resources/") \ No newline at end of file
diff --git a/webpack.config.d/style.js b/webpack.config.d/style.js
new file mode 100644
index 0000000..0e46452
--- /dev/null
+++ b/webpack.config.d/style.js
@@ -0,0 +1,2 @@
+config.resolve.modules.push("src/main/resources/")
+config.module.rules.push({test: /\.txt$/, type: 'asset/source'}) \ No newline at end of file