feat: rewrite frontend in haxe
This commit is contained in:
parent
6f73a3a698
commit
cea7a26aeb
|
@ -1,6 +0,0 @@
|
||||||
// Formatter configuration for the KubeJS scripts.
|
|
||||||
{
|
|
||||||
tabWidth: 4,
|
|
||||||
trailingComma: "all",
|
|
||||||
}
|
|
||||||
|
|
3
build.hxml
Normal file
3
build.hxml
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
# This only exists for haxe_language_server. It is not used for building!
|
||||||
|
-cp frontend
|
||||||
|
--js .js
|
75
build.zig
75
build.zig
|
@ -1,6 +1,6 @@
|
||||||
const std = @import("std");
|
const std = @import("std");
|
||||||
|
|
||||||
pub fn build(b: *std.build.Builder) void {
|
pub fn build(b: *std.build.Builder) !void {
|
||||||
// Standard target options allows the person running `zig build` to choose
|
// Standard target options allows the person running `zig build` to choose
|
||||||
// what target to build for. Here we do not override the defaults, which
|
// what target to build for. Here we do not override the defaults, which
|
||||||
// means any target is allowed, and the default is native. Other options
|
// means any target is allowed, and the default is native. Other options
|
||||||
|
@ -11,6 +11,8 @@ pub fn build(b: *std.build.Builder) void {
|
||||||
// between Debug, ReleaseSafe, ReleaseFast, and ReleaseSmall.
|
// between Debug, ReleaseSafe, ReleaseFast, and ReleaseSmall.
|
||||||
const mode = b.standardReleaseOptions();
|
const mode = b.standardReleaseOptions();
|
||||||
|
|
||||||
|
const opts = b.addOptions();
|
||||||
|
|
||||||
const exe = b.addExecutable("vidzig", "src/main.zig");
|
const exe = b.addExecutable("vidzig", "src/main.zig");
|
||||||
exe.setTarget(target);
|
exe.setTarget(target);
|
||||||
exe.setBuildMode(mode);
|
exe.setBuildMode(mode);
|
||||||
|
@ -19,6 +21,11 @@ pub fn build(b: *std.build.Builder) void {
|
||||||
|
|
||||||
deps(exe);
|
deps(exe);
|
||||||
|
|
||||||
|
const frontend_step = try BuildFrontendStep.init(b, opts);
|
||||||
|
exe.step.dependOn(&frontend_step.step);
|
||||||
|
|
||||||
|
exe.addOptions("opts", opts);
|
||||||
|
|
||||||
exe.install();
|
exe.install();
|
||||||
|
|
||||||
const run_cmd = exe.run();
|
const run_cmd = exe.run();
|
||||||
|
@ -29,14 +36,6 @@ pub fn build(b: *std.build.Builder) void {
|
||||||
|
|
||||||
const run_step = b.step("run", "Run the app");
|
const run_step = b.step("run", "Run the app");
|
||||||
run_step.dependOn(&run_cmd.step);
|
run_step.dependOn(&run_cmd.step);
|
||||||
|
|
||||||
const exe_tests = b.addTest("src/main.zig");
|
|
||||||
exe_tests.setTarget(target);
|
|
||||||
exe_tests.setBuildMode(mode);
|
|
||||||
deps(exe_tests);
|
|
||||||
|
|
||||||
const test_step = b.step("test", "Run unit tests");
|
|
||||||
test_step.dependOn(&exe_tests.step);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn deps(exe: *std.build.LibExeObjStep) void {
|
fn deps(exe: *std.build.LibExeObjStep) void {
|
||||||
|
@ -76,3 +75,61 @@ const onion_sources = [_][]const u8{
|
||||||
"deps/onion/src/onion/version.c",
|
"deps/onion/src/onion/version.c",
|
||||||
"deps/onion/src/onion/websocket.c",
|
"deps/onion/src/onion/websocket.c",
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const BuildFrontendStep = struct {
|
||||||
|
step: std.build.Step,
|
||||||
|
opts: *std.build.OptionsStep,
|
||||||
|
b: *std.build.Builder,
|
||||||
|
|
||||||
|
pub fn init(b: *std.build.Builder, opts: *std.build.OptionsStep) !*BuildFrontendStep {
|
||||||
|
const self = try b.allocator.create(BuildFrontendStep);
|
||||||
|
|
||||||
|
self.* = .{
|
||||||
|
.step = std.build.Step.init(.custom, "build_frontend", b.allocator, make),
|
||||||
|
.opts = opts,
|
||||||
|
.b = b,
|
||||||
|
};
|
||||||
|
|
||||||
|
return self;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn make(step: *std.build.Step) anyerror!void {
|
||||||
|
const self = @fieldParentPtr(BuildFrontendStep, "step", step);
|
||||||
|
|
||||||
|
const outpath = try std.fs.path.join(
|
||||||
|
self.b.allocator,
|
||||||
|
&.{ self.b.cache_root, "options", "index.js" },
|
||||||
|
);
|
||||||
|
const argv = [_][]const u8{
|
||||||
|
"haxe",
|
||||||
|
|
||||||
|
"-cp",
|
||||||
|
"frontend",
|
||||||
|
|
||||||
|
"-main",
|
||||||
|
"Index",
|
||||||
|
|
||||||
|
"-D",
|
||||||
|
"dce=full",
|
||||||
|
|
||||||
|
"-D",
|
||||||
|
"js_es=6",
|
||||||
|
|
||||||
|
"-D",
|
||||||
|
"js_classic",
|
||||||
|
|
||||||
|
"--js",
|
||||||
|
outpath,
|
||||||
|
};
|
||||||
|
|
||||||
|
var child = std.ChildProcess.init(&argv, self.b.allocator);
|
||||||
|
const term = try child.spawnAndWait();
|
||||||
|
if (!std.meta.eql(term, .{ .Exited = 0 }))
|
||||||
|
return error.UnexpectedExitCode;
|
||||||
|
|
||||||
|
try self.opts.contents.writer().writeAll(
|
||||||
|
\\pub const index_js = @embedFile("index.js");
|
||||||
|
\\
|
||||||
|
);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
21
frontend/EnqueueTask.hx
Normal file
21
frontend/EnqueueTask.hx
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
import haxe.Json;
|
||||||
|
import js.html.XMLHttpRequest;
|
||||||
|
|
||||||
|
class EnqueueTask {
|
||||||
|
var url:String;
|
||||||
|
var outname:Null<String>;
|
||||||
|
var prepend:Bool;
|
||||||
|
|
||||||
|
public function new(url:String, outname:Null<String>, prepend:Bool) {
|
||||||
|
this.url = url;
|
||||||
|
this.outname = outname;
|
||||||
|
this.prepend = prepend;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function send():Void {
|
||||||
|
var xhr = new XMLHttpRequest();
|
||||||
|
xhr.open("POST", Util.resolveUrl("vids/"));
|
||||||
|
xhr.setRequestHeader("Content-Type", "application/json");
|
||||||
|
xhr.send(Json.stringify(this));
|
||||||
|
}
|
||||||
|
}
|
40
frontend/Index.hx
Normal file
40
frontend/Index.hx
Normal file
|
@ -0,0 +1,40 @@
|
||||||
|
import js.html.AnchorElement;
|
||||||
|
import js.html.XMLHttpRequest;
|
||||||
|
import js.html.InputElement;
|
||||||
|
import js.Browser;
|
||||||
|
|
||||||
|
function main():Void {
|
||||||
|
Browser.document.getElementById("enqueue_form").addEventListener("submit", onEnqSubmit);
|
||||||
|
|
||||||
|
for (del_btn in Browser.document.getElementsByClassName("vid_del_btn")) {
|
||||||
|
del_btn.onclick = () -> {
|
||||||
|
var href = cast(del_btn.parentElement.getElementsByTagName("a")[0], AnchorElement).href;
|
||||||
|
|
||||||
|
var xhr = new XMLHttpRequest();
|
||||||
|
xhr.open("DELETE", href);
|
||||||
|
xhr.send();
|
||||||
|
|
||||||
|
del_btn.parentElement.remove();
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
Browser.document.getElementById("pause_btn").onclick = PauseButton.onClick;
|
||||||
|
|
||||||
|
PauseButton.updateDisplay();
|
||||||
|
}
|
||||||
|
|
||||||
|
function onEnqSubmit(e:Dynamic):Void {
|
||||||
|
e.preventDefault();
|
||||||
|
|
||||||
|
var url_inp = cast(Browser.document.getElementById("url_inp"), InputElement);
|
||||||
|
|
||||||
|
var outname = cast(Browser.document.getElementById("outname_inp"), InputElement).value;
|
||||||
|
|
||||||
|
new EnqueueTask(
|
||||||
|
url_inp.value,
|
||||||
|
outname.length == 0 ? null : outname,
|
||||||
|
cast(Browser.document.getElementById("prepend_switch"), InputElement).checked
|
||||||
|
).send();
|
||||||
|
|
||||||
|
url_inp.value = "";
|
||||||
|
}
|
17
frontend/PauseButton.hx
Normal file
17
frontend/PauseButton.hx
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
import js.html.XMLHttpRequest;
|
||||||
|
import js.Browser;
|
||||||
|
|
||||||
|
function onClick() {
|
||||||
|
Util.paused = !Util.paused;
|
||||||
|
|
||||||
|
var xhr = new XMLHttpRequest();
|
||||||
|
xhr.open("POST", Util.resolveUrl("set_paused"));
|
||||||
|
xhr.send(Std.string(Util.paused));
|
||||||
|
|
||||||
|
updateDisplay();
|
||||||
|
}
|
||||||
|
|
||||||
|
function updateDisplay() {
|
||||||
|
var btn = Browser.document.getElementById("pause_btn");
|
||||||
|
btn.innerHTML = Util.paused ? "Unpause" : "Pause";
|
||||||
|
}
|
13
frontend/Util.hx
Normal file
13
frontend/Util.hx
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
import js.Browser;
|
||||||
|
|
||||||
|
@:native("paused")
|
||||||
|
extern var paused: Bool;
|
||||||
|
|
||||||
|
/**
|
||||||
|
Resolves a relative URL like that used in hrefs to a normal, full URL.
|
||||||
|
*/
|
||||||
|
function resolveUrl(s:String):String {
|
||||||
|
var a = Browser.document.createAnchorElement();
|
||||||
|
a.href = s;
|
||||||
|
return a.href;
|
||||||
|
}
|
51
hxformat.json
Normal file
51
hxformat.json
Normal file
|
@ -0,0 +1,51 @@
|
||||||
|
{
|
||||||
|
"wrapping": {
|
||||||
|
"arrayWrap": {
|
||||||
|
"defaultWrap": "onePerLine",
|
||||||
|
"rules": [
|
||||||
|
{
|
||||||
|
"conditions": [
|
||||||
|
{
|
||||||
|
"cond": "totalItemLength <= n",
|
||||||
|
"value": 50
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"type": "noWrap"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"methodChain": {
|
||||||
|
"rules": [
|
||||||
|
{
|
||||||
|
"conditions": [
|
||||||
|
{
|
||||||
|
"cond": "itemCount >= n",
|
||||||
|
"value": 3
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"type": "onePerLine"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"callParameter": {
|
||||||
|
"rules": [
|
||||||
|
{
|
||||||
|
"conditions": [
|
||||||
|
{
|
||||||
|
"cond": "itemCount >= n",
|
||||||
|
"value": 3
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cond": "totalItemLength >= n",
|
||||||
|
"value": 50
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"type": "onePerLine"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"indentation": {
|
||||||
|
"character": " "
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,55 +0,0 @@
|
||||||
function resolveUrl(s) {
|
|
||||||
let a = document.createElement("a");
|
|
||||||
a.href = s;
|
|
||||||
return a.href;
|
|
||||||
}
|
|
||||||
|
|
||||||
document
|
|
||||||
.getElementById("enqueue_form")
|
|
||||||
.addEventListener("submit", function (e) {
|
|
||||||
e.preventDefault();
|
|
||||||
|
|
||||||
const outname = document.getElementById("outname_inp").value;
|
|
||||||
|
|
||||||
const data = {
|
|
||||||
url: document.getElementById("url_inp").value,
|
|
||||||
outname: outname.length == 0 ? null : outname,
|
|
||||||
prepend: document.getElementById("prepend_switch").checked,
|
|
||||||
};
|
|
||||||
|
|
||||||
let xhr = new XMLHttpRequest();
|
|
||||||
xhr.open("POST", resolveUrl("vids/"));
|
|
||||||
xhr.setRequestHeader("Content-Type", "application/json");
|
|
||||||
xhr.send(JSON.stringify(data));
|
|
||||||
|
|
||||||
document.getElementById("url_inp").value = "";
|
|
||||||
});
|
|
||||||
|
|
||||||
for (let del_btn of document.getElementsByClassName("vid_del_btn")) {
|
|
||||||
del_btn.onclick = function () {
|
|
||||||
let xhr = new XMLHttpRequest();
|
|
||||||
xhr.open(
|
|
||||||
"DELETE",
|
|
||||||
del_btn.parentElement.getElementsByTagName("a")[0].href,
|
|
||||||
);
|
|
||||||
xhr.send();
|
|
||||||
del_btn.parentElement.remove();
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
function updatePauseButtonDisplay() {
|
|
||||||
const btn = document.getElementById("pause_btn");
|
|
||||||
btn.innerHTML = paused ? "Unpause" : "Pause";
|
|
||||||
}
|
|
||||||
|
|
||||||
document.getElementById("pause_btn").onclick = function () {
|
|
||||||
paused = !paused;
|
|
||||||
|
|
||||||
let xhr = new XMLHttpRequest();
|
|
||||||
xhr.open("POST", resolveUrl("set_paused"));
|
|
||||||
xhr.send(paused ? "true" : false);
|
|
||||||
|
|
||||||
updatePauseButtonDisplay();
|
|
||||||
};
|
|
||||||
|
|
||||||
updatePauseButtonDisplay();
|
|
|
@ -87,7 +87,7 @@ pub fn main() !void {
|
||||||
_ = c.onion_url_add(
|
_ = c.onion_url_add(
|
||||||
urls,
|
urls,
|
||||||
"static/index.js",
|
"static/index.js",
|
||||||
routes.comptimeStatic(@embedFile("assets/index.js"), "application/javascript"),
|
routes.comptimeStatic(@import("opts").index_js, "application/javascript"),
|
||||||
);
|
);
|
||||||
_ = c.onion_url_add(
|
_ = c.onion_url_add(
|
||||||
urls,
|
urls,
|
||||||
|
|
Loading…
Reference in a new issue