Skip to content

Commit

Permalink
Merge pull request #362 from Zekiah-A/main
Browse files Browse the repository at this point in the history
Chat hisstory hotfix, refine live chat reactions styles & top level singleton emoji panel component
  • Loading branch information
Zekiah-A authored Nov 30, 2024
2 parents 6731549 + 30e78fe commit b1b6f22
Show file tree
Hide file tree
Showing 4 changed files with 75 additions and 26 deletions.
31 changes: 22 additions & 9 deletions index.html
Original file line number Diff line number Diff line change
Expand Up @@ -378,7 +378,7 @@
let channel = decoder.decode(data.buffer.slice(i, (i += channelLen)))

let newChatScroll = chatMessages.scrollTop
let messageRenderPromises = []
const messageRenderPromises = []

if (channel !== currentChannel) {
return
Expand Down Expand Up @@ -417,7 +417,7 @@
const newMessage = createLiveChatMessage(messageId, txt, intId, name, sendDate, repliesTo, reactions)
if (before) {
chatMessages.prepend(newMessage)
const channelMessages = chatMessages.get(currentChannel)
const channelMessages = cMessages.get(currentChannel)
channelMessages.unshift(newMessage)
}
messageRenderPromises.push(
Expand Down Expand Up @@ -1650,6 +1650,7 @@ <h2 style="white-space:nowrap" translate="liveChat" class="live-chat-header1">Li
</li>
</ul>
</div>
<r-emoji-panel id="chatReactionsPanel" onclose="this.removeAttribute('open')"></r-emoji-panel>
<a id="ad" target="_blank">
<button class="ad-close" onclick="
event.preventDefault()
Expand Down Expand Up @@ -2456,23 +2457,32 @@ <h4>Quest complete! 🥳</h4>
function switchLanguageChannel(selected) {
channelMine.style.opacity = "0.5"
channelEn.style.opacity = "0.5"
if (currentChannel != selected) chatCancelReplies()
if (currentChannel != selected) {
chatCancelReplies()
}
currentChannel = selected
chatMessages.style.direction = (LANG_INFOS.get(selected)?.rtl) ? "rtl" : "ltr"

if (selected == "en")
if (selected == "en") {
channelEn.style.opacity = "1"
else if (selected == extraLanguage)
}
else if (selected == extraLanguage) {
channelMine.style.opacity = "1"

}
chatMessages.innerHTML = ""
// User must ask to load previous at least once for each channel before site
// will start auto loading previous chat messages
chatPreviousAutoLoad = false
const messageRenderPromises = []

if (cMessages.get(selected)?.length) {
for (const el of cMessages.get(selected)) {
chatMessages.appendChild(el)
for (const messageEl of cMessages.get(selected)) {
messageRenderPromises.push(messageEl.updateComplete)
chatMessages.appendChild(messageEl)
}
Promise.all(messageRenderPromises).then(() => {
chatMessages.scrollTo(0, chatMessages.scrollHeight)
})
}
else if (typeof requestLoadChannelPrevious === "function") {
// If we don't have any cached messages for this channel, try pre-populate with a few
Expand All @@ -2489,7 +2499,7 @@ <h4>Quest complete! 🥳</h4>
}

function chatMentionUser(senderId) {
let [start, end] = [messageInput.selectionStart, messageInput.selectionEnd]
const [ start, end ] = [ messageInput.selectionStart, messageInput.selectionEnd ]
let mentionText = "@"
const identifier = intIdNames.get(senderId) || ("#" + senderId)
if (typeof identifier === "string") {
Expand Down Expand Up @@ -3103,6 +3113,9 @@ <h4>Quest complete! 🥳</h4>
},
get intIdNames() {
return intIdNames
},
get chatReactionsPanel() {
return chatReactionsPanel
}
}
</script>
Expand Down
34 changes: 23 additions & 11 deletions live-chat-elements.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { LitElement, html, styleMap, unsafeHTML } from "./lit.all.min.js"
// @ts-expect-error Hack to access window globals from module script
// eslint-disable-next-line @typescript-eslint/no-unused-vars
var { cMessages, currentChannel, chatMessages, x, y, pos, chatMentionUser, onChatContext, chatReply, chatReport, chatModerate, CHAT_COLOURS, hash, chatReact, EMOJIS, CUSTOM_EMOJIS, intIdNames } = window.moduleExports
var { cMessages, currentChannel, chatMessages, x, y, pos, chatMentionUser, onChatContext, chatReply, chatReport, chatModerate, chatReactionsPanel, CHAT_COLOURS, hash, chatReact, EMOJIS, CUSTOM_EMOJIS, intIdNames } = window.moduleExports

class LiveChatMessage extends LitElement {
static properties = {
Expand All @@ -12,7 +12,6 @@ class LiveChatMessage extends LitElement {
repliesTo: { type: Number, reflect: true, attribute: "repliesto" },
content: { type: String, reflect: true, attribute: "content" },
reactions: { type: Object, attribute: false },
showReactionsPanel: { type: Boolean, attribute: false },
openedReactionDetails: { type: String, attribute: false },
class: { reflect: true }
}
Expand All @@ -27,7 +26,6 @@ class LiveChatMessage extends LitElement {
this.content = null
/** @type {Map<string, Set<number>>|null} */ this.reactions = null
this.replyingMessage = null
this.showReactionsPanel = false
this.openedReactionDetails = ""
this.addEventListener("contextmenu", this.#handleContextMenu)
}
Expand Down Expand Up @@ -103,7 +101,7 @@ class LiveChatMessage extends LitElement {
return { name: "[ERROR]", content: "Channel not found", fake: true }
}

const message = cMessages[currentChannel].find(msg => msg.messageId === this.repliesTo)
const message = cMessages.get(currentChannel).find(msg => msg.messageId === this.repliesTo)
return message || {
name: "[?????]",
content: translate("messageNotFound"),
Expand Down Expand Up @@ -159,7 +157,25 @@ class LiveChatMessage extends LitElement {
chatModerate("delete", this.senderId, this.messageId, this)
}

#handleReact(e) {
#handleReact() {
// Open react panel singleton element
chatReactionsPanel.setAttribute("open", "true")

const bounds = this.getBoundingClientRect()
const panelHeight = chatReactionsPanel.offsetHeight
const viewportHeight = window.innerHeight
const topPosition = Math.min(bounds.bottom, viewportHeight - panelHeight - 8) // Ensure it stays on screen

// Apply position
chatReactionsPanel.style.right = "8px"
chatReactionsPanel.style.top = `${Math.max(8, topPosition)}px` // Ensure it doesn't go off the top

chatReactionsPanel.onemojiselection = (e) => {
this.#onReactEmojiSelected(e)
}
}

#onReactEmojiSelected(e) {
const { key } = e.detail
chatReact(this.messageId, key)
}
Expand Down Expand Up @@ -197,18 +213,14 @@ class LiveChatMessage extends LitElement {
<img class="action-button" src="svg/reply-action.svg"
title=${translate("replyTo")} tabindex="0" @click=${this.#handleReply}>
<img class="action-button" src="svg/react-action.svg"
title=${translate("addReaction")} tabindex="0" @click=${() => this.showReactionsPanel = true}>
title=${translate("addReaction")} tabindex="0" @click=${this.#handleReact}>
<img class="action-button" src="svg/report-action.svg"
title=${translate("report")} tabindex="0" @click=${this.#handleReport}>
${localStorage.vip?.startsWith("!") ? html`
<img class="action-button" src="svg/moderate-action.svg"
title=${translate("Moderation options")} tabindex="0" @click=${this.#handleModerate}>
` : null}
</div>
${this.showReactionsPanel
? html`<r-emoji-panel @selectionchanged=${this.#handleReact} @close=${() => this.showReactionsPanel = false}
@mouseleave=${() => this.showReactionsPanel = false}></r-emoji-panel>`
: null}`
</div>`
}

#renderReactions() {
Expand Down
18 changes: 17 additions & 1 deletion shared-elements.js
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,8 @@ class CloseIcon extends HTMLElement {
customElements.define("r-close-icon", CloseIcon)

class EmojiPanel extends LitElement {
#onEmojiSelection = null

constructor() {
super()
}
Expand All @@ -82,6 +84,20 @@ class EmojiPanel extends LitElement {
this.classList.add("context-menu")
}

set onemojiselection(handler) {
if (this.#onEmojiSelection) {
this.removeEventListener("emojiselection", this.#onEmojiSelection)
}
if (typeof handler === "function") {
this.#onEmojiSelection = handler
this.addEventListener("emojiselection", handler)
}
}

get onemojiselection() {
return this.#onEmojiSelection
}

// @ts-expect-error Remove shadow DOM by using element itself as the shadowroot
createRenderRoot() {
return this
Expand Down Expand Up @@ -138,7 +154,7 @@ class EmojiPanel extends LitElement {
}

#notifySelection(key, value) {
const event = new CustomEvent("selectionchanged", {
const event = new CustomEvent("emojiselection", {
detail: { key, value },
bubbles: true,
composed: true
Expand Down
18 changes: 13 additions & 5 deletions style.css
Original file line number Diff line number Diff line change
Expand Up @@ -1420,6 +1420,12 @@ r-live-chat-message .reactions {
list-style: none;
margin-left: 12px;
flex-wrap: wrap;
opacity: 0.8;
padding-top: 6px;
transition: .2s opacity;
}
r-live-chat-message .reactions:hover {
opacity: 1;
}
r-live-chat-message .reaction {
list-style: none;
Expand Down Expand Up @@ -1459,14 +1465,14 @@ r-live-chat-messaage hr {
margin: 4px;
}
r-live-chat-message .reaction-details {
padding: 4px 8px 4px 8px;
padding: 2px 4px 2px 4px;
border: 1px solid gray;
border-radius: 64px;
max-height: 42px;
background-color: white;
box-shadow: 0 1px 1px rgba(0, 0, 0, .2), 0 2px 0 0 rgba(255, 255, 255, .7) inset;
margin-left: -8px;
margin-bottom: -8px;
margin-top: -8px;
overflow: hidden;
transition: .2s max-height, .2s box-shadow;
}
Expand All @@ -1490,16 +1496,18 @@ r-live-chat-message .reactor {
}

r-emoji-panel.context-menu {
display: block;
display: none;
width: 240px;
max-height: 360px;
overflow-y: auto;
position: absolute;
position: fixed;
resize: vertical;
min-height: 120px;
padding: 0;
}

r-emoji-panel[open].context-menu {
display: block;
}
r-emoji-panel .emojis-header {
display: flex;
justify-content: space-between;
Expand Down

0 comments on commit b1b6f22

Please sign in to comment.