|
| 1 | +@page |
| 2 | +@{ |
| 3 | +} |
| 4 | +<!DOCTYPE html> |
| 5 | + |
| 6 | +<html> |
| 7 | +<head> |
| 8 | + <meta name="viewport" content="width=device-width" /> |
| 9 | + <title>ToDo Widget</title> |
| 10 | + <link rel="stylesheet" href="~/css/site.css" /> |
| 11 | + <script src="https://kit.fontawesome.com/8ac2e0bf60.js" crossorigin="anonymous"></script> |
| 12 | +</head> |
| 13 | +<body class="todoWidget"> |
| 14 | + <h4>@Fritz.Chatbot.Commands.ProjectCommand.CurrentProject</h4> |
| 15 | + |
| 16 | + <div id="checklistContainer"> |
| 17 | + <ul id="todos"> |
| 18 | + @foreach(var item in Fritz.Chatbot.Commands.ToDoCommand.ToDos) { |
| 19 | + var cssClass = item.Value.completed ? "far fa-check-square" : "far fa-square"; |
| 20 | + <li data-id="@item.Key"><i class="@cssClass"></i> @($"{item.Key}.") @item.Value.text</li> |
| 21 | + } |
| 22 | + </ul> |
| 23 | + </div> |
| 24 | + |
| 25 | + <script src="~/lib/signalr/signalr-client.js"></script> |
| 26 | + <script> |
| 27 | +
|
| 28 | + var debug = false; |
| 29 | + var scrollSpeed = 0.5; |
| 30 | +
|
| 31 | +
|
| 32 | + (function () { |
| 33 | +
|
| 34 | + this._hub = new signalR.HubConnectionBuilder() |
| 35 | + .withUrl("/obshub") |
| 36 | + .withHubProtocol(new signalR.protocols.msgpack.MessagePackHubProtocol()) |
| 37 | + .build(); |
| 38 | +
|
| 39 | + this._hub.onclose(() => { |
| 40 | + if (debug) console.debug("hub connection closed"); |
| 41 | +
|
| 42 | + // Hub connection was closed for some reason |
| 43 | + let interval = setInterval(() => { |
| 44 | + // Try to reconnect hub every 5 secs |
| 45 | + this.start(groups).then(() => { |
| 46 | + // Reconnect succeeded |
| 47 | + clearInterval(interval); |
| 48 | + if (this.debug) console.debug("hub reconnected"); |
| 49 | + }); |
| 50 | + }, 5000); |
| 51 | + }); |
| 52 | +
|
| 53 | + this._hub.on("project_update", (text) => { |
| 54 | + if (debug) console.debug(`Project update: ${text}`, null); |
| 55 | + document.querySelector("h4").innerText = text; |
| 56 | + }); |
| 57 | +
|
| 58 | + this._hub.on('todo_new', (id, text) => { |
| 59 | + if (debug) console.debug("New ToDo", { id, text }); |
| 60 | + this.Add(id, text); |
| 61 | + }); |
| 62 | + this._hub.on('todo_done', (id) => { |
| 63 | + if (this.debug) console.debug("Done ToDo", { id }); |
| 64 | + this.Complete(id); |
| 65 | + }); |
| 66 | + this._hub.on("todo_remove", (id) => { |
| 67 | + if (this.debug) console.debug("Remove ToDo", { id }); |
| 68 | + this.Remove(id); |
| 69 | + }); |
| 70 | + this._hub.on("todo_speed", (s) => { |
| 71 | + if (this.debug) console.debug("ToDo Speed", { s }); |
| 72 | + scrollSpeed = s; |
| 73 | + ConfigureScroll(); |
| 74 | + }); |
| 75 | +
|
| 76 | + var todos = document.getElementById("todos"); |
| 77 | + var todosClone; |
| 78 | + var myStylesheet; |
| 79 | + var projectTitle = document.querySelector("h4"); |
| 80 | + var container = document.getElementById("checklistContainer"); |
| 81 | +
|
| 82 | + this.Add = function (id, text) { |
| 83 | + var newEl = document.createElement("li"); |
| 84 | + newEl.setAttribute("data-id", id); |
| 85 | + newEl.innerHTML = `<i class="far fa-square"></i> ${id}. ${text}`; |
| 86 | + todos.appendChild(newEl); |
| 87 | + ConfigureScroll(); |
| 88 | + } |
| 89 | +
|
| 90 | + this.Complete = function (id) { |
| 91 | + var el = document.querySelectorAll(`li[data-id='${id}'] > i`); |
| 92 | + el[0].className = "far fa-check-square"; |
| 93 | + if (el.length > 1) el[1].className = "far fa-check-square"; |
| 94 | + } |
| 95 | +
|
| 96 | + this.Remove = function (id) { |
| 97 | + var el = document.querySelectorAll(`li[data-id='${id}'] > i`); |
| 98 | + el[0].parentElement.parentElement.removeChild(el[0].parentElement); |
| 99 | + if (el.length > 1) el[1].parentElement.parentElement.removeChild(el[1].parentElement); |
| 100 | + ConfigureScroll(); |
| 101 | + } |
| 102 | +
|
| 103 | + this.ConfigureScroll = function () { |
| 104 | + console.log(`todos: ${todos.scrollHeight} ,project ${projectTitle.offsetHeight}`); |
| 105 | + if (todosClone != null) container.removeChild(todosClone); |
| 106 | + if (myStylesheet) myStylesheet.sheet.deleteRule(0); // stop scrolling |
| 107 | +
|
| 108 | + if (todos.scrollHeight + projectTitle.scrollHeight > 265) { |
| 109 | +
|
| 110 | + todos.style.animationName = "scroller"; |
| 111 | + todos.style.animationDuration = `${(todos.querySelectorAll("li").length * scrollSpeed).toString()}s`; |
| 112 | +
|
| 113 | + console.log("Scrolling"); |
| 114 | +
|
| 115 | + todosClone = todos.cloneNode(true); |
| 116 | + todosClone.style.top = `${todos.scrollHeight}px`; |
| 117 | + todosClone.id = 'todosClone'; |
| 118 | + container.appendChild(todosClone); |
| 119 | + ConfigureAnimation(); |
| 120 | +
|
| 121 | + } |
| 122 | + }; |
| 123 | +
|
| 124 | + this.AddKeyFrames = function (name, frames) { |
| 125 | + var pos = myStylesheet.length; |
| 126 | + myStylesheet.sheet.insertRule(`@@keyframes ${name} {${frames}}`, pos); |
| 127 | + }; |
| 128 | +
|
| 129 | + this.ConfigureAnimation = function () { |
| 130 | +
|
| 131 | + if (myStylesheet) { |
| 132 | + // myStylesheet.sheet.deleteRule(0); |
| 133 | + } else { |
| 134 | + myStylesheet = document.createElement("style"); |
| 135 | + document.head.appendChild(myStylesheet); |
| 136 | + } |
| 137 | + AddKeyFrames("scroller", `from {transform: translateY(0)} to {transform: translateY(-${todos.scrollHeight}px)}`); |
| 138 | +
|
| 139 | + }; |
| 140 | +
|
| 141 | + ConfigureScroll(); |
| 142 | +
|
| 143 | + this._hub.start(); |
| 144 | +
|
| 145 | + })(); |
| 146 | + </script> |
| 147 | +</body> |
| 148 | +</html> |
0 commit comments