--- /dev/null
+[submodule "lua_async"]
+ path = lua_async
+ url = https://github.com/EliasFleckenstein03/lua_async
+[submodule "luairc"]
+ path = luairc
+ url = https://github.com/EliasFleckenstein03/luairc
+[submodule "cutie"]
+ path = cutie
+ url = https://github.com/EliasFleckenstein03/cutie
+[submodule "luax"]
+ path = luax
+ url = https://github.com/EliasFleckenstein03/luax
--- /dev/null
+# dragonirc
+
+WIP IRC client written in Lua 5.3. Does not function yet.
+
+## Dependencies
+
+(install with luarocks)
+
+- luasocket
+- luaposix
--- /dev/null
+dragonirc.register_command("exit", function()
+ dragonirc.exit(0)
+end)
--- /dev/null
+Subproject commit 1a0439f3029b81915fa4f1c19958128da2ed91d1
--- /dev/null
+#! /usr/bin/env lua
+-- load IRC
+package.path = "luairc/src/?.lua;" .. package.path
+irc = require("irc")
+
+-- load luax
+require("luax")
+
+-- load lua_async
+require("lua_async")("lua_async")
+
+-- load cutie
+cutie = require("cutie")
+
+-- export global table
+dragonirc = EventTarget()
+
+-- config
+dragonirc.config = {
+ colors = {
+ error = "#ED254E",
+ }
+}
+
+-- load files
+dofile("splashscreen.lua")
+dofile("main.lua")
+dofile("input.lua")
+dofile("commands.lua")
+
+-- run
+async(dragonirc.main)()
+lua_async.run()
--- /dev/null
+cutie.input:addEventListener("input", function(evt)
+ dragonirc.input(evt.data.input)
+end)
+
+function dragonirc.input(input, raw)
+ if not raw and not dragonirc:dispatchEvent(Event("input", {input = input})) then
+ return
+ end
+
+ if input:sub(1, 1) == "/" then
+ dragonirc.command(input:sub(2, #input):split(" "), false)
+ else
+ dragonirc.message(input, false)
+ end
+end
+
+function dragonirc.command(args, raw)
+ local cmd = table.remove(args, 1):lower()
+
+ if not raw and not dragonirc:dispatchEvent(Event("command", {cmd = cmd, args = args})) then
+ return
+ end
+
+ if dragonirc:dispatchEvent(Event("command." .. cmd, args)) then
+ dragonirc.add_line(cutie.bold
+ .. cutie.color(dragonirc.config.colors.error)
+ .. "Invalid command: /" .. cmd)
+ end
+end
+
+function dragonirc.message(msg, raw)
+ if not raw and not dragonirc:dispatchEvent(Event("message", {msg = msg})) then
+ return
+ end
+
+ dragonirc.add_line(cutie.bold .. "<user> " .. cutie.no_effects .. msg)
+end
+
+function dragonirc.register_command(cmd, func)
+ dragonirc:addEventListener("command." .. cmd, function(evt)
+ evt:preventDefault()
+ func(table.unpack(evt.data))
+ end)
+end
--- /dev/null
+Subproject commit 6fcf6209e05410d5ac077ecce6c940197d430c8a
--- /dev/null
+Subproject commit 783fefdcb375ab58382579afeb092c67b8832813
--- /dev/null
+Subproject commit 6b5450ce9356e48099a926d1950d9bbfd1db0f6e
--- /dev/null
+local display = {}
+
+function dragonirc.add_line(line)
+ table.insert(display, cutie.no_effects .. line)
+end
+
+function dragonirc.main()
+ cutie.set_alternate_buffer(true)
+ cutie.set_canon_input(false)
+ cutie.set_input_buffer(true)
+
+ await(dragonirc.splashscreen())
+
+ setInterval(function()
+ cutie.clear_effects()
+ cutie.handle_resize()
+ cutie.empty_screen()
+
+ local size = cutie.get_terminal_size()
+
+ cutie.render_at(display, 2, 1)
+ cutie.clear_effects()
+
+ cutie.render_at(cutie.box({size[1] - 6, 1}), 2, size[2] - 4)
+
+ cutie.move_cursor(5, size[2] - 2)
+ cutie.render(cutie.input.buffer)
+
+ cutie.flush_buffer()
+ end, 1000 / 60)
+end
+
+function dragonirc.exit(ret)
+ cutie.clear_effects()
+ cutie.set_alternate_buffer(false)
+ cutie.set_cursor_shown(true)
+ cutie.set_canon_input(true)
+ cutie.flush_buffer()
+ os.exit(ret)
+end
--- /dev/null
+local dragon = string.split([[
+ / )
+ ( |\
+ /| \\
+ // \\
+ /// \|
+ /( \ )\
+ \\ \_ //)
+ \\ :\__ ///
+ \\ ) // \
+ \\: / // |/
+ \\ / \ // \
+ /) \ ___..-' (| \_|
+ // / _.' \ \ \
+ /| \ \________ \ | /
+ (| _ _ __/ '-. ) /.'
+ \\ . '-.__ \_ / / \
+ \\_'. > --._ '. \ / / /
+ \ \ \ \ \ .' /.'
+ \ \ '._ / \ ) / .' |
+ \ \_ \_ | .'_/ __/
+ \ \ \_ | / / _/ \_
+ \ \ / _.' / / \
+ \ | /.' / .' '-,_
+ \ \ .' _.'_/ \
+ /\ /\ ) ___( /_.' \ |
+ | _\__// \ (.' _/ | |
+ \/_ __ /--'` , __/ /
+ (_ ) /b) \ '. : \___.-'_/ \__/
+ /:/: , ) : ( /_.'__/-'|_ _ /
+ /:/: __/\ > __,_.----.__\ / (/(/(/
+(_(,_/V .'/--' _/ __/ | /
+ VvvV //` _.-' _.' \ \
+ n_n// (((/->/ | /
+ '--' ~=' \ |
+ | |_,,,
+ \ \ /
+ '.__)
+]], "\n")
+
+local title = string.split([[
+ ____ ___ ____ ____
+| _ \ _ __ __ _ __ _ ___ _ __ |_ _| _ \ / ___|
+| | | | '__/ _` |/ _` |/ _ \| '_ \ | || |_) | |
+| |_| | | | (_| | (_| | (_) | | | || || _ <| |___
+|____/|_| \__,_|\__, |\___/|_| |_|___|_| \_\\____|
+ |___/
+]], "\n")
+
+local size_dragon = cutie.get_dimensions(dragon)
+local size_title = cutie.get_dimensions(title)
+
+dragonirc.splashscreen = async(function()
+ cutie.set_cursor_shown(false)
+ local promise = Promise()
+ local splashscreen_time = 0
+
+ local interval
+
+ interval = setInterval(function()
+ splashscreen_time = splashscreen_time + 1 / 60
+
+ if splashscreen_time > 1 then
+ promise:resolve()
+ clearInterval(interval)
+ return
+ end
+
+ cutie.handle_resize()
+ cutie.set_background({0, 0, 0})
+ cutie.empty_screen()
+
+ cutie.set_bold()
+
+ local size = cutie.get_terminal_size()
+
+ cutie.set_color(360 * math.max(1 - splashscreen_time * 2 / 3, 0))
+ cutie.render_at(dragon,
+ (size[1] - size_dragon[1]) / 2,
+ (size[2] - size_dragon[2]) / 2
+ )
+
+ cutie.set_color({1, 1, 1})
+ cutie.render_at(title,
+ (size[1] - size_title[1]) / 2,
+ size[2] - size_title[2] - 1
+ )
+
+ cutie.flush_buffer()
+ end, 1000 / 60)
+
+ await(promise)
+
+ cutie.set_cursor_shown(true)
+end)