diff options
Diffstat (limited to 'v2')
-rw-r--r-- | v2/client.ts | 67 | ||||
-rw-r--r-- | v2/elements.ts | 124 | ||||
-rw-r--r-- | v2/logger.ts | 24 | ||||
-rw-r--r-- | v2/screen.ts | 101 | ||||
-rw-r--r-- | v2/screen/home.ts | 53 | ||||
-rw-r--r-- | v2/screen/login.ts | 55 | ||||
-rw-r--r-- | v2/screenbuilder.ts | 43 | ||||
-rw-r--r-- | v2/strftime.js | 92 |
8 files changed, 0 insertions, 559 deletions
diff --git a/v2/client.ts b/v2/client.ts deleted file mode 100644 index 3e09f7e..0000000 --- a/v2/client.ts +++ /dev/null @@ -1,67 +0,0 @@ - -import { Screen } from "./screen.ts"; -import type { Text } from "./elements.ts"; -import strftime from "./strftime.js"; - -export let token: string; -export let account; -export const connection = new WebSocket("wss://api.meower.org/v0/cloudlink?v=1") - -export let home: any[] = []; - -let screen: Screen; - -export function setScreen(screenN: Screen) { - screen = screenN -} - -export async function login(username: string, password: string) { - screen.logs.push(`logging in as ${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(); - screen.logs.push(`got auth response (${authr.error ? "error" : "not error"})`) - token = authr.token; - account = authr.account; - screen.logs.push(`Got token ${token}`); - connection.addEventListener("message", (ev) => { - const data = JSON.parse(ev.data.toString()); - screen.logs.push("INC: " + JSON.stringify(data)) - if(data.cmd != "post") return; - home.push(data.val); - const textHome: string[] = home.map(p => `[${strftime("%H:%M:%S", new Date(p.t.e * 1000))}] ${p.u}: ${p.p}`); - const homeElem: Text = screen.elements.get("home") as Text; - homeElem.text = textHome.join("\n")+"\n"; - screen.render() - }) -} - -export async function loadHome(screen: Screen) { - home = (await (await fetch("https://api.meower.org/home")).json()).autoget.reverse(); - const textHome: string[] = home.map(p => `[${strftime("%H:%M:%S")}] ${p.u}: ${p.p}`); - const homeElem: Text = screen.elements.get("home") as Text; - homeElem.text = textHome.join("\n")+"\n"; - screen.logs.push("loadHome ran", home.length.toString()) - screen.render() -} - -export async function sendHome(post:string) { - screen.logs.push("sendHome ran", home.length.toString()) - fetch("https://api.meower.org/home", { - method: "POST", - headers: { - token, - "content-type": "application/json" - }, - body: JSON.stringify({ - content: post - }) - }).then(async r=>screen.logs.push(`Got send response (${r.status} ${r.statusText}) ${await r.text()}`)) -} diff --git a/v2/elements.ts b/v2/elements.ts deleted file mode 100644 index c364930..0000000 --- a/v2/elements.ts +++ /dev/null @@ -1,124 +0,0 @@ -import chalk from "chalk"; -import { type Key } from 'node:readline'; -import { type Screen } from "./screen.ts"; - -export abstract class Element { - focusable: boolean = false; - focused: boolean = false; - // screen property is asigned by the addElement function of Scren - //@ts-ignore - screen: Screen; - abstract render(): void; - onkeypres(key: Key): void {}; -} - -export class Text extends Element { - text: string; - br: boolean; - - processText: (text: string) => string; - - constructor(text: string, processText = (t:string)=>t) { - super(); - this.text = text; - this.processText = processText - } - render() { - process.stdout.write(this.processText(this.text)) - } -} - -export class HR extends Element { - constructor() { - super() - } - render(): void { - console.log('-'.repeat(process.stdout.columns)) - } -} - -export class BR extends Element { - constructor() { - super() - } - render(): void { - console.log() - } -} - -export class Input extends Element { - focusable: boolean = true; - value: string = ""; - - textarea = false; - br = false; - - isPassword: boolean = false; - - render(): void { - let text = this.value - if (this.isPassword) text = text.replace(/[^]/g, '*'); - if (this.focused) text += "_" - process.stdout.write(text) - } - - onkeypres(key: Key): void { - //@ts-ignore - if (key.meta || key.code || ["return", "backspace"].includes(key.name)) { - switch (key.name) { - case "return": - if(this.textarea) { - this.value += '\n' - break; - } - 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; - } - this.screen.render() - return; - } - // check if the character ism't typable - // checks: - // sequience length > 1 (eg ^[ ^[[A) - // key name != sequence (and if name exists) - //@ts-ignore - if (!key.sequence || key.sequence.length > 1 || key.name != key.sequence?.toLowerCase() && !["space"].includes(key.name) && key.name) return; - this.value += key.sequence; - this.screen.render() - } - - constructor(isPassword: boolean = false, br: boolean = false, textarea: boolean = false) { - super() - this.br = br - this.isPassword = isPassword; - this.textarea = textarea; - } -} - -export class Button extends Text { - focusable: boolean = true; - onclick: ()=>void; - constructor (text: string, onclick=()=>{}) { - super(text); - this.onclick = onclick - } - render(): void { - process.stdout.write(`(${(this.focused ? chalk.bgWhite : (a:string)=>a)(this.text)})`) - } - - onkeypres(key: Key): void { - //@ts-ignore - if (["return", "space"].includes(key.name)) { - this.onclick.call(this.screen) - } - } -} diff --git a/v2/logger.ts b/v2/logger.ts deleted file mode 100644 index 641a406..0000000 --- a/v2/logger.ts +++ /dev/null @@ -1,24 +0,0 @@ -class Log { - time: number = Number(new Date()); - data: string = ""; - constructor (data: string, time?: number) { - this.data = data; - if(time) this.time = time; - } -} - -class Logger { - logs: Log[] = []; - - constructor () { - - } - - log (data: string) { - this.logs.push(new Log(data)) - } - - dump (): string[] { - return this.logs.map(log => ``) - } -} \ No newline at end of file diff --git a/v2/screen.ts b/v2/screen.ts deleted file mode 100644 index 5e09d57..0000000 --- a/v2/screen.ts +++ /dev/null @@ -1,101 +0,0 @@ -import type { Element, Input, Text, Button } from "./elements.ts" - -const logs: string[] = []; - -function onexit() { - console.clear() - console.log("\nQuitting meower CL") - for (const log of logs) { - console.log(log) - } -} - -export class Screen { - elements: Map<string, Element|Input|Text|Button> = new Map(); - name: string; - focusedElementId: string = ''; - logs = logs - - constructor(name: string) { - this.name = name; - } - - call(function_name:string, ...args:any) { - for (const element of this.elements) { - element[1][function_name](...args) - } - } - - handleKeypress(chunk: any, key: any, screen: Screen) { - const focusableIDs = Object.keys(screen.getFocusable()); - const focusedIndex = focusableIDs.indexOf(screen.focusedElementId); - if (key && key.name == 'escape' || key.name == "c" && key.ctrl) { - onexit(); - process.exit(); - } - - if (['up', 'left'].includes(key.name) || key.name == "tab" && key.shift) { - // 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) || key.name == "tab" && !key.shift) { - // 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) - } - - getKeypressHandler(screen: Screen) { - return (chunk: any, key: any) => this.handleKeypress(chunk,key, screen); - } - - keypressHandler = this.getKeypressHandler(this) - - ready() { - process.stdin.on('keypress', this.keypressHandler); - this.render() - } - - off() { - process.stdin.off('keypress', this.keypressHandler) - } - - addElement(name: string, element: Element) { - if(this.elements.has(name)) throw new Error(); - element.screen = this; - this.elements.set(name, element); - } - - render() { - console.clear() - process.stdout.write("\u001b[2J") // use an ansi escape code to clear the screen if console.clear doesn't clear fully - 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 - } -} diff --git a/v2/screen/home.ts b/v2/screen/home.ts deleted file mode 100644 index 0be3ef9..0000000 --- a/v2/screen/home.ts +++ /dev/null @@ -1,53 +0,0 @@ -import { ElemType } from "../screenbuilder.ts"; -import { Screen } from "../screen.ts"; -import type { Input, Element, Text } from "../elements.ts"; -import * as client from "../client.ts" - -export default { - elements: [ - { - type: ElemType.TextElem, - id: 'home', - data: ["Loading home posts...\n", function (this: Text, text: string) { - const msgInput: Input = this.screen.elements.get("msg-input") as Input; - const inputValueHeight = msgInput.value.split("\n").length + 1; - const termHeight = process.stdout.rows; - const termWidth = process.stdout.columns; - - let splitText = this.text.split("\n"); - splitText = splitText.map(t => t.replace(new RegExp(`([^]){${termWidth}}`, "g"),"$1\n")); - splitText = splitText.join("\n").split("\n") - - splitText = splitText.slice(-(termHeight - inputValueHeight)); - - return splitText.join("\n") - }] - }, - { - type: ElemType.HR, - id: 'hr', - data: [] - }, - { - type: ElemType.InputElem, - id: 'msg-input', - data: [false, false, true] - }, - { - type: ElemType.ButtonElem, - id: 'done-btn', - data: ["Send", async function (this: Screen) { - const msgInput: Input = this.elements.get('msg-input') as Input - client.sendHome(msgInput.value); - msgInput.value = "" - this.render() - }] - } - ], - focus: "msg-input", - name: 'home', - onload (screen: Screen) { - client.setScreen(screen) - client.loadHome(screen) - } -} \ No newline at end of file diff --git a/v2/screen/login.ts b/v2/screen/login.ts deleted file mode 100644 index bc39655..0000000 --- a/v2/screen/login.ts +++ /dev/null @@ -1,55 +0,0 @@ -import { ElemType } from "../screenbuilder.ts"; -import { Screen } from "../screen.ts"; -import * as client from "../client.ts" -import { build } from "../screenbuilder.ts"; -import HomeScreen from "./home.ts"; - -export default { - elements: [ - { - type: ElemType.TextElem, - id: 'username-label', - data: ["Username: \n"] - }, - { - type: ElemType.InputElem, - id: 'username-input', - data: [false] - }, - { - type: ElemType.BR, - id: 'naoiuou' - }, - { - type: ElemType.TextElem, - id: 'password-label', - data: ["Password: \n"] - }, - { - type: ElemType.InputElem, - id: 'password-input', - data: [true] - }, - { - type: ElemType.BR, - id: 'faij0ifsj' - }, - { - type: ElemType.ButtonElem, - id: 'done-btn', - data: ["Done", async function (this: Screen) { - client.setScreen(this) - this.off() - this.logs.push(`clicked button`) - console.clear() - console.log("logging in...") - //@ts-ignore - await client.login(this.elements.get("username-input").value, this.elements.get("password-input").value) - build(HomeScreen); - client - }] - } - ], - focus: "username-input", - name: 'login' -} \ No newline at end of file diff --git a/v2/screenbuilder.ts b/v2/screenbuilder.ts deleted file mode 100644 index e8ce587..0000000 --- a/v2/screenbuilder.ts +++ /dev/null @@ -1,43 +0,0 @@ -import { Screen } from "./screen.ts"; -import * as elements from "./elements.ts"; - -export enum ElemType { - TextElem, - InputElem, - ButtonElem, - HR, - BR -} - -const types = { - 0: elements.Text, - 1: elements.Input, - 2: elements.Button, - 3: elements.HR, - 4: elements.BR -} - -type BuilderElem = { - type: ElemType, - id: string, - data?: any[], -} - -type Data = { - elements: BuilderElem[], - focus?: string, - name: string - onload?: (screen: Screen) => any -} - -export function build(data: Data) { - const screen = new Screen(data.name); - for (const element of data.elements) { - if (!element.data) element.data = [] - //@ts-ignore - screen.addElement(element.id, new types[element.type](...element.data)) - } - if (data.focus) screen.focus(data.focus); - screen.ready() - if (data.onload) data.onload(screen) -} \ No newline at end of file diff --git a/v2/strftime.js b/v2/strftime.js deleted file mode 100644 index ecc3f77..0000000 --- a/v2/strftime.js +++ /dev/null @@ -1,92 +0,0 @@ -/* Port of strftime(). Compatibility notes: - * - * %c - formatted string is slightly different - * %D - not implemented (use "%m/%d/%y" or "%d/%m/%y") - * %e - space is not added - * %E - not implemented - * %h - not implemented (use "%b") - * %k - space is not added - * %n - not implemented (use "\n") - * %O - not implemented - * %r - not implemented (use "%I:%M:%S %p") - * %R - not implemented (use "%H:%M") - * %t - not implemented (use "\t") - * %T - not implemented (use "%H:%M:%S") - * %U - not implemented - * %W - not implemented - * %+ - not implemented - * %% - not implemented (use "%") - * - * strftime() reference: - * http://man7.org/linux/man-pages/man3/strftime.3.html - * - * Day of year (%j) code based on Joe Orost's answer: - * http://stackoverflow.com/questions/8619879/javascript-calculate-the-day-of-the-year-1-366 - * - * Week number (%V) code based on Taco van den Broek's prototype: - * http://techblog.procurios.nl/k/news/view/33796/14863/calculate-iso-8601-week-and-year-in-javascript.html - */ -export default function strftime(sFormat, date) { - if (!(date instanceof Date)) date = new Date(); - let nDay = date.getDay(), - nDate = date.getDate(), - nMonth = date.getMonth(), - nYear = date.getFullYear(), - nHour = date.getHours(), - aDays = ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'], - aMonths = ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'], - aDayCount = [0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334], - isLeapYear = function () { - return (nYear % 4 === 0 && nYear % 100 !== 0) || nYear % 400 === 0; - }, - getThursday = function () { - let target = new Date(date); - target.setDate(nDate - ((nDay + 6) % 7) + 3); - return target; - }, - zeroPad = function (nNum, nPad) { - return ('' + (Math.pow(10, nPad) + nNum)).slice(1); - }; - return sFormat.replace(/%[a-z]/gi, function (sMatch) { - return { - '%a': aDays[nDay].slice(0, 3), - '%A': aDays[nDay], - '%b': aMonths[nMonth].slice(0, 3), - '%B': aMonths[nMonth], - '%c': date.toUTCString(), - '%C': Math.floor(nYear / 100), - '%d': zeroPad(nDate, 2), - '%e': nDate, - '%F': date.toISOString().slice(0, 10), - '%G': getThursday().getFullYear(), - '%g': ('' + getThursday().getFullYear()).slice(2), - '%H': zeroPad(nHour, 2), - '%I': zeroPad((nHour + 11) % 12 + 1, 2), - '%j': zeroPad(aDayCount[nMonth] + nDate + ((nMonth > 1 && isLeapYear()) ? 1 : 0), 3), - '%k': '' + nHour, - '%l': (nHour + 11) % 12 + 1, - '%m': zeroPad(nMonth + 1, 2), - '%M': zeroPad(date.getMinutes(), 2), - '%p': (nHour < 12) ? 'AM' : 'PM', - '%P': (nHour < 12) ? 'am' : 'pm', - '%s': Math.round(date.getTime() / 1000), - '%S': zeroPad(date.getSeconds(), 2), - '%u': nDay || 7, - '%V': (function () { - let target = getThursday(), - n1stThu = target.valueOf(); - target.setMonth(0, 1); - let nJan1 = target.getDay(); - if (nJan1 !== 4) target.setMonth(0, 1 + ((4 - nJan1) + 7) % 7); - return zeroPad(1 + Math.ceil((n1stThu - target) / 604800000), 2); - })(), - '%w': '' + nDay, - '%x': date.toLocaleDateString(), - '%X': date.toLocaleTimeString(), - '%y': ('' + nYear).slice(2), - '%Y': nYear, - '%z': date.toTimeString().replace(/.+GMT([+-]\d+).+/, '$1'), - '%Z': date.toTimeString().replace(/.+\((.+?)\)$/, '$1') - }[sMatch] || sMatch; - }); -} \ No newline at end of file |