diff --git a/web/sub-cond-schema.js b/web/sub-cond-schema.js new file mode 100644 index 0000000..e15b850 --- /dev/null +++ b/web/sub-cond-schema.js @@ -0,0 +1,144 @@ +const subCondSchema = { + iconlib: "spectre", + theme: "html", + // The schema for the editor + schema: { + additionalProperties: false, + title: "Condition", + $ref: "#/definitions/cond", + definitions: { + cond: { + type: "object", + id: "cond", + defaultProperties: [ + "not", + ], + minProperties: 2, + maxProperties: 2, + properties: { + not: { + title: "Not", + id: "not", + type: "boolean", + format: "checkbox", + default: false, + required: true, + }, + gc: { + title: "Group", + type: "object", + id: "gc", + defaultProperties: ["logic", "group"], + properties: { + logic: { + title: "Logic", + id: "logic", + type: "integer", + enum: [0, 1, 2], + options: { + enum_titles: ["And", "Or", "Xor"], + }, + required: true, + }, + group: { + title: "Conditions", + id: "group", + type: "array", + items: { + title: "Condition", + $ref: "#/definitions/cond", + }, + required: true, + minItems: 2, + maxItems: 10, + } + }, + additionalProperties: false, + }, + nc: { + title: "Number", + type: "object", + id: "nc", + defaultProperties: ["key", "op", "val"], + properties: { + key: { + title: "Attribute", + id: "key", + type: "string", + required: true, + minLength: 1, + maxLength: 20, + pattern: "^[a-z0-9]+$", + options: { + inputAttributes: { + placeholder: "e.g. price, revenue, time, ...", + }, + }, + }, + op: { + title: "Operator", + id: "op", + type: "integer", + enum: [1, 2, 3, 4, 5], + default: 3, + options: { + enum_titles: [">", "≥", "=", "≤", "<"], + }, + required: true, + }, + val: { + title: "Value", + id: "val", + type: "number", + required: true, + } + }, + additionalProperties: false, + }, + tc: { + title: "Text", + type: "object", + id: "tc", + defaultProperties: ["key", "term", "exact"], + properties: { + key: { + title: "Attribute", + id: "key", + type: "string", + required: false, + minLength: 0, + maxLength: 20, + pattern: "^[a-z0-9]*$", + options: { + inputAttributes: { + placeholder: "e.g. language, source, title, ...", + } + }, + }, + term: { + title: "Any of words", + id: "term", + type: "string", + required: true, + options: { + inputAttributes: { + placeholder: "e.g. Tesla, iPhone, ...", + } + }, + }, + exact: { + title: "Exact Match", + id: "exact", + type: "boolean", + format: "checkbox", + default: false, + required: true, + } + }, + additionalProperties: false, + }, + } + }, + } + } +}; diff --git a/web/sub-details.html b/web/sub-details.html new file mode 100644 index 0000000..784fc39 --- /dev/null +++ b/web/sub-details.html @@ -0,0 +1,38 @@ +<html lang="en"> +<head> + <meta charset="utf-8"> + <meta http-equiv="X-UA-Compatible" content="IE=edge"> + <meta name="viewport" content="width=device-width, initial-scale=1"> + <meta name="theme-color" content="#0ed3ff"> + + <title>Awakari App</title> + + <script src="https://telegram.org/js/telegram-web-app.js"></script> + + <link rel="stylesheet" href="spectre-icons.min.css"> + <link href="tailwind.output.css" rel="stylesheet"> + <link rel="stylesheet" href="style.css"> + + <script src="jsoneditor.min.js"></script> + <script src="sub-cond-schema.js"></script> + +</head> +<body onload="loadSubscription()"> + +<div id="sub_new" class="flex-1 flex flex-col w-[320px] mx-auto" style="display: flex"> + <p class="py-2 text-md">View or edit the subscription's matching condition:</p> + <form class="space-y-2"> + <div class="container"> + <div class="row"> + <div class="col-md-12"> + <div id="sub_cond_editor"></div> + </div> + </div> + </div> + <script src="sub-details.js"></script> + </form> + <p class="py-2 text-xs">Id: <pre id="subId"></pre></p> +</div> + +</body> +</html> diff --git a/web/sub-details.js b/web/sub-details.js new file mode 100644 index 0000000..adb6253 --- /dev/null +++ b/web/sub-details.js @@ -0,0 +1,47 @@ +// Initialize the editor +const editor = new JSONEditor(document.getElementById("sub_cond_editor"), subCondSchema); + +// Hook up the validation indicator to update its +// status whenever the editor changes +editor.on('change', function () { + // Get an array of errors from the validator + const errors = editor.validate(); + // Not valid + if (errors.length) { + console.log(errors); + } +}); + +function loadSubscription() { + // + const urlParams = new URLSearchParams(window.location.search); + const id = urlParams.get("id"); + document.getElementById("subId").innerHTML = urlParams.get("id"); + // + let authToken = sessionStorage.getItem("authToken"); + let userId = sessionStorage.getItem("userId"); + let optsReq = { + method: "GET", + headers: { + "Authorization": `Bearer ${authToken}`, + "X-Awakari-Group-Id": defaultGroupId, + "X-Awakari-User-Id": userId, + }, + cache: "default", + } + fetch(`/v1/sub/${id}`, optsReq) + .then(resp => { + if (!resp.ok) { + throw new Error(`Request failed with status: ${resp.status}`); + } + return resp.json(); + }) + .then(data => { + if (data != null) { + editor.setValue(data.cond); + } + }) + .catch(err => { + alert(err); + }); +} diff --git a/web/sub.html b/web/sub.html index cd2efe0..75dee7e 100644 --- a/web/sub.html +++ b/web/sub.html @@ -29,7 +29,7 @@ <link href="style.css" rel="stylesheet"> <script src="login.js"></script> - <script src="subs.js"></script> + <script src="sub.js"></script> </head> <body class="bg-gray-200" onload="loadSubscriptions()"> diff --git a/web/subs.js b/web/sub.js similarity index 63% rename from web/subs.js rename to web/sub.js index 3f9abf0..59ab6e4 100644 --- a/web/subs.js +++ b/web/sub.js @@ -1,5 +1,6 @@ const templateSub = (sub) => ` - <div class="p-2 shadow-sm hover:text-blue-500 hover:bg-gray-100 rounded-sm flex"> + <div class="p-2 shadow-sm hover:text-blue-500 hover:bg-gray-100 rounded-sm flex" + onclick="window.location.assign('sub-details.html?id=${sub.id}')"> <span class="truncate w-[240px] sm:w-[600px]"> ${sub.description} </span> @@ -12,8 +13,6 @@ const templateSub = (sub) => ` </div> ` -let eventsLoadingRunning = false; - function loadSubscriptions() { let authToken = sessionStorage.getItem("authToken"); let userId = sessionStorage.getItem("userId"); @@ -73,43 +72,3 @@ function deleteSubscription(id) { }) } } - -function showInbox(id) { - window.location.assign(`//inbox.html?id=${id}`); -} - -async function startEventsLoading(subs) { - eventsLoadingRunning = true; - console.log("Running events loading..."); - try { - await Promise.all(subs.map(sub => loadSubscriptionEvents(sub.id))); - } finally { - console.log("Stopped events loading"); - eventsLoadingRunning = false; - } -} - -async function loadSubscriptionEvents(subId) { - while(true) { - console.log(`Load subscription ${subId} events...`); - await Events - .longPoll(subId) - .finally(_ => { - let evtsHistory = Events.getLocalHistory(subId); - let evtsUnreadCount = 0; - for (const evt of evtsHistory) { - if (!evt.hasOwnProperty("read") || evt.read === false) { - evtsUnreadCount++; - } - } - if (evtsUnreadCount > 0) { - document.getElementById(`unread_count_${subId}`).style.background = "#f0abfc"; // bg-fuchsia-300 - } - if (evtsUnreadCount > 9) { - document.getElementById(`unread_count_${subId}`).innerHTML = "9+"; - } else { - document.getElementById(`unread_count_${subId}`).innerHTML = `${evtsUnreadCount}`; - } - }) - } -} diff --git a/web/subs.html b/web/subs.html index c5ca5e7..7b6e0a6 100644 --- a/web/subs.html +++ b/web/subs.html @@ -19,7 +19,7 @@ <script src="login.js"></script> <script src="evts.js"></script> - <script src="subs.js"></script> + <script src="sub.js"></script> </head> <body class="bg-gray-100" onload="loadSubscriptions()">