diff options
-rw-r--r-- | README.md | 5 | ||||
-rw-r--r-- | deno.json | 3 | ||||
-rw-r--r-- | index.js | 40 | ||||
-rw-r--r-- | keys.js | 2 | ||||
-rw-r--r-- | main.ts | 6 | ||||
-rw-r--r-- | v2/screen.ts | 7 | ||||
-rw-r--r-- | wip-v2.ts | 164 |
7 files changed, 16 insertions, 211 deletions
diff --git a/README.md b/README.md new file mode 100644 index 0000000..35af376 --- /dev/null +++ b/README.md @@ -0,0 +1,5 @@ +# Meower CL + +Meower Command-Line - a cli client for meower built using deno and a custom tui library + +To run this client, download the repo, install the modules and run deno task dev \ No newline at end of file diff --git a/deno.json b/deno.json index d18b550..330f2ce 100644 --- a/deno.json +++ b/deno.json @@ -1,5 +1,6 @@ { "tasks": { - "dev": "deno run wip-v2.ts" + "dev": "deno run --allow-net --allow-env main.ts", + "build": "deno compile --allow-net --allow-env --no-check main.ts" } } \ No newline at end of file diff --git a/index.js b/index.js deleted file mode 100644 index fd9ead0..0000000 --- a/index.js +++ /dev/null @@ -1,40 +0,0 @@ -import * as readline from 'node:readline/promises'; -import { stdin as input, stdout as output } from 'node:process'; - -const rl = readline.createInterface({ input, output }); - -const username = await rl.question('Username: '); -const password = await rl.question('Password: '); - -console.log("logging in as %s", username) - -const authr = await (await fetch("https://api.meower.org/auth/login", { - method: "POST", - headers: { - "content-type": "application/json" - }, - body: JSON.stringify({ - username, - password - }) -})).json(); -let token = authr.token - -console.log('got token', token) - -rl.addListener('line', async (i) => { - await fetch("https://api.meower.org/home", { - method: "POST", - headers: { - "content-type": "application/json", - token - }, - body: JSON.stringify({ - content: i - }) - }) - // console.log("sent") - rl.prompt("> ") -}) - -rl.prompt("> ") \ No newline at end of file diff --git a/keys.js b/keys.js index 3f46f14..3884908 100644 --- a/keys.js +++ b/keys.js @@ -1,3 +1,5 @@ +// util for figuring out key stuff +// run this, press a key, and it'll give you the json :+1: import readline from 'node:readline'; readline.emitKeypressEvents(process.stdin); diff --git a/main.ts b/main.ts index 3a05a48..435e4af 100644 --- a/main.ts +++ b/main.ts @@ -1,3 +1,9 @@ import LoginScreen from "./v2/screen/login.ts"; import { build } from "./v2/screenbuilder.ts"; +import readline from 'node:readline'; + +readline.emitKeypressEvents(process.stdin); + +if (process.stdin.isTTY) process.stdin.setRawMode(true); // makes the terminal send stdin without the user pressing enter + build(LoginScreen) \ No newline at end of file diff --git a/v2/screen.ts b/v2/screen.ts index 4da6482..7a1e265 100644 --- a/v2/screen.ts +++ b/v2/screen.ts @@ -1,7 +1,4 @@ import type { Element, Input, Text, Button } from "./elements.ts" -import readline from 'node:readline'; - -readline.emitKeypressEvents(process.stdin); const logs: string[] = []; @@ -32,7 +29,7 @@ export class Screen { handleKeypress(chunk: any, key: any, screen: Screen) { const focusableIDs = Object.keys(screen.getFocusable()); const focusedIndex = focusableIDs.indexOf(screen.focusedElementId); - if (key && key.name == 'escape') { + if (key && key.name == 'escape' || key.name == "c" && key.ctrl) { onexit(); process.exit(); } @@ -101,5 +98,3 @@ export class Screen { return this.focusedElementId ? this.elements.get(this.focusedElementId) as Element : undefined } } - -if (process.stdin.isTTY) process.stdin.setRawMode(true); // makes the terminal send stdin without the user pressing enter diff --git a/wip-v2.ts b/wip-v2.ts deleted file mode 100644 index 0f701a0..0000000 --- a/wip-v2.ts +++ /dev/null @@ -1,164 +0,0 @@ -import readline, { Key } from 'node:readline'; -import chalk from "chalk"; - -readline.emitKeypressEvents(process.stdin); - -const logs: string[] = []; - -function onexit() { - console.clear() - console.log("\nQuitting meower CL") - for (const log of logs) { - console.log(log) - } -} - -abstract class Element { - focusable: boolean = false; - focused: boolean = false; - screen: Screen; - abstract render(): void; - onkeypres(key: Key): void {}; -} - -class Text extends Element { - text: string; - constructor(text: string) { - super(); - this.text = text; - } - render() { - process.stdout.write(this.text) - } -} - -class Input extends Element { - focusable: boolean = true; - value: string = ""; - - isPassword: boolean = false; - - render(): void { - let text = this.value - if (this.isPassword) text = text.replace(/[^]/g, '*'); - if (this.focused) text += "_" - console.log(text) - } - - onkeypres(key: Key): void { - //@ts-ignore - if (key.meta || key.code || ["return", "backspace"].includes(key.name)) { - switch (key.name) { - case "return": - this.focused = false; - const focusableIDs = Object.keys(this.screen.getFocusable()); - const focusedIndex = focusableIDs.indexOf(this.screen.focusedElementId); - this.screen.focus(focusableIDs[(focusedIndex - 1) % focusableIDs.length]); - break; - - case "backspace": - const prevValue = '' + this.value - // logs.push(`doing backspace : before ${prevValue}, after ${prevValue.substring(0, prevValue.length - 1)} : 0-${prevValue.length - 1}`) - this.value = prevValue.substring(0, prevValue.length - 1) - break; - } - return; - } - if (!key.sequence || key.sequence.length > 1 || key.name != key.sequence?.toLowerCase()) return; - this.value += key.sequence; - } - - constructor(isPassword: boolean, ) { - super() - this.isPassword = isPassword - } -} - -class Button extends Text { - focusable: boolean = true; - constructor (text: string) { - super(text) - } - render(): void { - console.log(`(${(this.focused ? chalk.bgWhite : a=>a)(this.text)})`) - } -} - -class Screen { - elements: Map<string, Element> = new Map<string, Element>(); - name: string; - focusedElementId: string = ''; - constructor(name: string) { - this.name = name - } - addElement(name: string, element: Element) { - if(this.elements.has(name)) throw new Error(); - element.screen = this; - this.elements.set(name, element); - } - render() { - console.clear() - this.elements.forEach(element => { - element.render() - }); - } - - getFocusable() { - return Object.fromEntries([...this.elements.entries()].filter(([k, v]) => v.focusable)) - } - - getElements() { - return Object.fromEntries([...this.elements.entries()]) - } - - focus(id: string) { - this.elements.forEach(e => e.focused = false); - const focusElem = this.elements.get(id) as Element - focusElem.focused = true; - this.focusedElementId = id - } - - getFocusedElement(): Element|undefined { - return this.focusedElementId ? this.elements.get(this.focusedElementId) as Element : undefined - } -} - -// TODO: add focus change with arrows - -const screen = new Screen("login"); -screen.addElement('username-label', new Text("Username: \n")); -screen.addElement('username-input', new Input(false)) -screen.addElement('password-label', new Text("Password: \n")); -screen.addElement('password-input', new Input(true)) -screen.addElement('done-btn', new Button("Done")) - -screen.focus('username-input') - -if (process.stdin.isTTY) process.stdin.setRawMode(true); // makes the terminal send stdin without the user pressing enter - -process.stdin.on('keypress', (chunk, key) => { - const focusableIDs = Object.keys(screen.getFocusable()); - const focusedIndex = focusableIDs.indexOf(screen.focusedElementId); - if (key && key.name == 'escape') { - onexit(); - process.exit(); - } - - if (['up', 'left'].includes(key.name)) { - // logs.push(`Got up key, moving focus upward ${focusedIndex} ${(focusedIndex - 1) % focusableIDs.length}`) - screen.focus(focusableIDs[(focusedIndex - 1) % focusableIDs.length]); - return screen.render() - } - if (['down', 'right'].includes(key.name)) { - // logs.push(`Got down key, moving focus downward ${focusedIndex} ${(focusedIndex + 1) % focusableIDs.length}`) - screen.focus(focusableIDs[(focusedIndex + 1) % focusableIDs.length]); - return screen.render() - } - - // logs.push("pressed key, data: " + JSON.stringify(key)) - if (!screen.focusedElementId) return; - const focusedElement = screen.getFocusedElement(); - focusedElement?.onkeypres(key) - screen.render() -}); -screen.render() \ No newline at end of file |