diff options
| author | RblSb <msrblsb@gmail.com> | 2023-06-20 23:33:13 +0300 |
|---|---|---|
| committer | RblSb <msrblsb@gmail.com> | 2023-06-20 23:33:13 +0300 |
| commit | c476a16ad982e778580d74b8e4120ed29118129a (patch) | |
| tree | c326895bc9eb57cf50123eadb049ec73b3a201f2 /src/client | |
| parent | cdf7f00f613d636e587b7840ec8b263017513486 (diff) | |
Scroll to chat end button
Diffstat (limited to 'src/client')
| -rw-r--r-- | src/client/Buttons.hx | 19 | ||||
| -rw-r--r-- | src/client/Main.hx | 28 | ||||
| -rw-r--r-- | src/client/Utils.hx | 9 |
3 files changed, 48 insertions, 8 deletions
diff --git a/src/client/Buttons.hx b/src/client/Buttons.hx index aa7c1b2..7152a31 100644 --- a/src/client/Buttons.hx +++ b/src/client/Buttons.hx @@ -60,6 +60,25 @@ class Buttons { } } + final scrollToChatEndBtn = ge("#scroll-to-chat-end"); + function scrollToChatEndBtnAnim():Void { + if (scrollToChatEndBtn.style.opacity == "0") return; + scrollToChatEndBtn.style.opacity = "0"; + scrollToChatEndBtn.addEventListener("transitionend", e -> { + scrollToChatEndBtn.style.display = "none"; + }, {once: true}); + } + scrollToChatEndBtn.onclick = e -> { + main.scrollChatToEnd(); + scrollToChatEndBtnAnim(); + } + // hide scroll button when chat is scrolled to the end + final msgBuf = ge("#messagebuffer"); + msgBuf.onscroll = e -> { + if (msgBuf.offsetHeight + msgBuf.scrollTop < msgBuf.scrollHeight - 1) return; + scrollToChatEndBtnAnim(); + } + ge("#clearchatbtn").onclick = e -> { if (main.isAdmin()) main.send({type: ClearChat}); } diff --git a/src/client/Main.hx b/src/client/Main.hx index a7417fb..69450d9 100644 --- a/src/client/Main.hx +++ b/src/client/Main.hx @@ -52,6 +52,7 @@ class Main { } function new() { + haxe.Log.trace = Utils.nativeTrace; player = new Player(this); host = Browser.location.hostname; if (host == "") host = "localhost"; @@ -790,22 +791,22 @@ class Main { ws.send(Json.stringify(data)); } - static function chatMessageConnected():Void { + function chatMessageConnected():Void { final div = document.createDivElement(); div.className = "server-msg-reconnect"; div.textContent = Lang.get("msgConnected"); final msgBuf = ge("#messagebuffer"); msgBuf.appendChild(div); - msgBuf.scrollTop = msgBuf.scrollHeight; + scrollChatToEnd(); } - static function chatMessageDisconnected():Void { + function chatMessageDisconnected():Void { final div = document.createDivElement(); div.className = "server-msg-disconnect"; div.textContent = Lang.get("msgDisconnected"); final msgBuf = ge("#messagebuffer"); msgBuf.appendChild(div); - msgBuf.scrollTop = msgBuf.scrollHeight; + scrollChatToEnd(); } public static function serverMessage(text:String, isText = true, withTimestamp = true):Void { @@ -897,7 +898,8 @@ class Main { text = filter.regex.replace(text, filter.replace); } textDiv.innerHTML = text; - final isInChatEnd = msgBuf.scrollTop + msgBuf.clientHeight >= msgBuf.scrollHeight - 1; + final isInChatEnd = msgBuf.scrollTop + + msgBuf.clientHeight >= msgBuf.scrollHeight - 50; if (isInChatEnd) { // scroll chat to end after images loaded for (img in textDiv.getElementsByTagName("img")) { @@ -917,17 +919,27 @@ class Main { while (msgBuf.children.length > 200) { msgBuf.removeChild(msgBuf.firstChild); } - msgBuf.scrollTop = msgBuf.scrollHeight; } - if (name == personal.name) { - msgBuf.scrollTop = msgBuf.scrollHeight; + if (isInChatEnd || name == personal.name) { + scrollChatToEnd(); + } else { + showScrollToChatEndBtn(); } if (onBlinkTab == null) blinkTabWithTitle("*Chat*"); } + function showScrollToChatEndBtn() { + final btn = ge("#scroll-to-chat-end"); + btn.style.display = "block"; + Timer.delay(() -> btn.style.opacity = "1", 0); + } + function onChatImageLoaded(e:Event):Void { scrollChatToEnd(); (cast e.target : Element).onload = null; + final btn = ge("#scroll-to-chat-end"); + btn.style.opacity = "0"; + btn.style.display = "none"; } var emoteMaxSize:Null<Int>; diff --git a/src/client/Utils.hx b/src/client/Utils.hx index cdf9f21..a0e19f7 100644 --- a/src/client/Utils.hx +++ b/src/client/Utils.hx @@ -8,6 +8,15 @@ import js.html.Element; import js.html.URL; class Utils { + public static function nativeTrace(msg:Dynamic, ?infos:haxe.PosInfos):Void { + final fileData = '${infos.fileName}:${infos.lineNumber}'; + var args:Array<Dynamic> = [fileData, msg]; + if (infos.customParams != null) args = args.concat(infos.customParams); + js.Browser.window.console.log( + ...haxe.Rest.of(args) + ); + } + public static function isTouch():Bool { return js.Syntax.code("'ontouchstart' in window"); } |
