From 42d306e1f207e6697017593c8708c8535653f2ad Mon Sep 17 00:00:00 2001 From: rainbow napkin Date: Sat, 21 Dec 2024 16:47:19 -0500 Subject: [PATCH] Emote Palette UI Complete --- src/views/partial/panels/emote.ejs | 33 +++++++++---- www/css/adminPanel.css | 4 ++ www/css/channel.css | 5 ++ www/css/panel/emote.css | 28 +++++++++++ www/css/theme/movie-night.css | 21 ++++++-- www/js/channel/panels/emotePanel.js | 74 +++++++++++++++++++++++++++-- 6 files changed, 148 insertions(+), 17 deletions(-) diff --git a/src/views/partial/panels/emote.ejs b/src/views/partial/panels/emote.ejs index cc5d3f2..84b4955 100644 --- a/src/views/partial/panels/emote.ejs +++ b/src/views/partial/panels/emote.ejs @@ -14,21 +14,36 @@ GNU Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program. If not, see .--> + -

Site Emotes

+

Personal Emotes

+ +
+
+ +
+ +
+
+ + [] + +
+
+
+
+ + +

Site Emotes

-

Channel Emotes

+

Channel Emotes

-
- - -

Personal Emotes

- -
-
\ No newline at end of file +
\ No newline at end of file diff --git a/www/css/adminPanel.css b/www/css/adminPanel.css index 98fdd00..c94607d 100644 --- a/www/css/adminPanel.css +++ b/www/css/adminPanel.css @@ -126,6 +126,10 @@ i.toke-command-list{ margin: 0.2em; } +#new-emote-button{ + margin-left: 0.3em; +} + #emote-list{ display: grid; grid-template-columns: repeat(auto-fit, minmax(10em, 1fr)); diff --git a/www/css/channel.css b/www/css/channel.css index da4f2a7..ff5c10b 100644 --- a/www/css/channel.css +++ b/www/css/channel.css @@ -101,6 +101,7 @@ div#chat-panel-main-div{ .right-drag-handle{ right: 0; + width: 0.6em; } #chat-panel-multipanel-div{ @@ -236,10 +237,14 @@ span.user-entry{ top: 0; bottom: 0; left: 0; + overflow-y: auto; + scrollbar-width: thin; } #cpanel-pinned-div{ position: relative; + overflow-y: auto; + scrollbar-width: thin; } .cpanel-div{ diff --git a/www/css/panel/emote.css b/www/css/panel/emote.css index 519550e..cb0a565 100644 --- a/www/css/panel/emote.css +++ b/www/css/panel/emote.css @@ -2,6 +2,7 @@ display: flex; flex-direction: row; text-wrap: nowrap; + user-select: none; } .title-filler-span{ @@ -13,6 +14,7 @@ .emote-panel-list{ display: grid; grid-template-columns: repeat(auto-fit, minmax(9em, 1fr)); + flex-direction: column; padding: 1em; justify-items: center; } @@ -23,6 +25,13 @@ div.emote-panel-list-emote{ flex-direction: column; padding: 0.5em 0; margin: 0.5em; + user-select: none; + cursor: pointer; +} + +div.emote-panel-list-big-emote{ + width: 100%; + margin: 0.5em auto; } p.emote-list-title{ @@ -34,4 +43,23 @@ p.emote-list-title{ max-height: 8em; max-width: 8em; margin: auto; +} + +.emote-list-big-media{ + max-height: 80VH; + max-width: 100%; + margin: 0.5em; +} + +div.panel-control-prompt{ + margin: 0.5em; + flex: 1; +} + +#emote-panel-personal-prompts{ + display: flex; +} + +#new-emote-button{ + margin-left: 0.3em; } \ No newline at end of file diff --git a/www/css/theme/movie-night.css b/www/css/theme/movie-night.css index e0580d8..c74f983 100644 --- a/www/css/theme/movie-night.css +++ b/www/css/theme/movie-night.css @@ -37,7 +37,9 @@ along with this program. If not, see .*/ --focus0-alt0: rgb(229, 255, 229); --focus0-alt1: rgb(12, 85, 12); --focus-glow0: 2px 2px 3px var(--focus0), -2px 2px 3px var(--focus0), 2px -2px 3px var(--focus0), -2px -2px 3px var(--focus0); + --focus-glow0-inset: 2px 2px 3px var(--focus0) inset, -2px 2px 3px var(--focus0) inset, 2px -2px 3px var(--focus0) inset, -2px -2px 3px var(--focus0) inset; --focus-glow0-alt0: 2px 2px 3px var(--focus0-alt0), -2px 2px 3px var(--focus0-alt0), 2px -2px 3px var(--focus0-alt0), -2px -2px 3px var(--focus0-alt0); + --focus-glow0-alt0-inset: 2px 2px 3px var(--focus0-alt0) inset, -2px 2px 3px var(--focus0-alt0) inset, 2px -2px 3px var(--focus0-alt0) inset, -2px -2px 3px var(--focus0-alt0) inset; --danger0: firebrick; --danger0-alt0: rgb(121, 11, 11); @@ -71,12 +73,12 @@ a{ color: var(--accent0); } -a:hover, i:hover{ +a:hover, i:hover, .interactive:hover{ color: var(--focus0-alt0); text-shadow: var(--focus-glow0); } -a:active, i:active{ +a:active, i:active, .interactive:active{ color: var(--focus0-alt1); text-shadow: var(--focus-glow0-alt0); } @@ -347,7 +349,20 @@ select.panel-head-element{ background-color: var(--accent0); } - div.emote-panel-list-emote{ border: 1px solid var(--accent0); +} + +.emote-panel-list-emote:hover{ + color: var(--focus0-alt0); + border: 1px solid var(--focus0-alt0); + text-shadow: var(--focus-glow0); + box-shadow: var(--focus-glow0), var(--focus-glow0-inset); +} + +.emote-panel-list-emote:active{ + color: var(--focus0-alt1); + text-shadow: var(--focus-glow0-alt0); + border: 1px solid var(--focus0-alt1); + box-shadow: var(--focus-glow0-alt0), var(--focus-glow0-alt0-inset); } \ No newline at end of file diff --git a/www/js/channel/panels/emotePanel.js b/www/js/channel/panels/emotePanel.js index ea8a55d..efbc593 100644 --- a/www/js/channel/panels/emotePanel.js +++ b/www/js/channel/panels/emotePanel.js @@ -1,22 +1,27 @@ class emotePanel extends panelObj{ constructor(client, panelDocument){ - super(client, "Emote Panel", "/panel/emote", panelDocument); + super(client, "Emote Palette", "/panel/emote", panelDocument); } docSwitch(){ + this.siteEmoteTitle = this.panelDocument.querySelector('#site-emotes-title'); + this.chanEmoteTitle = this.panelDocument.querySelector('#chan-emotes-title'); + this.personalEmoteTitle = this.panelDocument.querySelector('#personal-emotes-title'); + this.siteEmoteToggle = this.panelDocument.querySelector('#site-emotes-toggle'); this.chanEmoteToggle = this.panelDocument.querySelector('#chan-emotes-toggle'); this.personalEmoteToggle = this.panelDocument.querySelector('#personal-emotes-toggle'); this.siteEmoteList = this.panelDocument.querySelector('#emote-panel-site-list'); this.chanEmoteList = this.panelDocument.querySelector('#emote-panel-chan-list'); + this.personalEmoteSection = this.panelDocument.querySelector('#emote-panel-personal-section'); this.personalEmoteList = this.panelDocument.querySelector('#emote-panel-personal-list'); + this.searchPrompt = this.panelDocument.querySelector('#emote-panel-search-prompt'); + this.setupInput(); - this.renderEmotes(this.client.chatBox.commandPreprocessor.emotes.site, this.siteEmoteList); - this.renderEmotes(this.client.chatBox.commandPreprocessor.emotes.chan, this.chanEmoteList); - this.renderEmotes(this.client.chatBox.commandPreprocessor.emotes.personal, this.personalEmoteList); + this.renderEmoteLists(); } setupInput(){ @@ -29,6 +34,18 @@ class emotePanel extends panelObj{ this.personalEmoteToggle.removeEventListener("click", this.togglePersonalEmotes.bind(this)); this.personalEmoteToggle.addEventListener("click", this.togglePersonalEmotes.bind(this)); + + this.siteEmoteTitle.removeEventListener("click", this.toggleSiteEmotes.bind(this)); + this.siteEmoteTitle.addEventListener("click", this.toggleSiteEmotes.bind(this)); + + this.chanEmoteTitle.removeEventListener("click", this.toggleChanEmotes.bind(this)); + this.chanEmoteTitle.addEventListener("click", this.toggleChanEmotes.bind(this)); + + this.personalEmoteTitle.removeEventListener("click", this.togglePersonalEmotes.bind(this)); + this.personalEmoteTitle.addEventListener("click", this.togglePersonalEmotes.bind(this)); + + this.searchPrompt.removeEventListener('keyup', this.renderEmoteLists.bind(this)); + this.searchPrompt.addEventListener('keyup', this.renderEmoteLists.bind(this)); } toggleSiteEmotes(event){ @@ -40,7 +57,7 @@ class emotePanel extends panelObj{ } togglePersonalEmotes(event){ - this.toggleEmotes(this.personalEmoteToggle, this.personalEmoteList); + this.toggleEmotes(this.personalEmoteToggle, this.personalEmoteSection); } toggleEmotes(icon, list){ @@ -64,16 +81,56 @@ class emotePanel extends panelObj{ this.client.chatBox.chatPrompt.value += `[${emote}]`; } + renderEmoteLists(){ + var search = this.searchPrompt.value; + + var siteEmotes = this.client.chatBox.commandPreprocessor.emotes.site; + var chanEmotes = this.client.chatBox.commandPreprocessor.emotes.chan; + var personalEmotes = this.client.chatBox.commandPreprocessor.emotes.personal; + + + if(search != ''){ + siteEmotes = siteEmotes.filter(filterQuery); + chanEmotes = chanEmotes.filter(filterQuery); + personalEmotes = personalEmotes.filter(filterQuery); + + function filterQuery(emote){ + //return true for anyany case-insensitive matches + return (emote.name.toLowerCase().match(search.toLowerCase())) != null; + } + } + + this.renderEmotes(siteEmotes, this.siteEmoteList); + this.renderEmotes(chanEmotes, this.chanEmoteList); + this.renderEmotes(personalEmotes, this.personalEmoteList); + } + renderEmotes(emoteList, container){ //Clear out the container container.innerHTML = ''; + //If we have two or less emotes + if(emoteList.length <= 2){ + //Set the container display to flex + container.style.display = 'flex'; + //otherwise + }else{ + //Set the container display to grid + container.style.display = 'grid'; + } + //For each emote emoteList.forEach((emote) => { //Create div to hold emote const emoteDiv = document.createElement('div'); emoteDiv.classList.add('emote-panel-list-emote'); + //If we have a low emote count + if(emoteList.length <= 2){ + //render them huuuuuge + emoteDiv.classList.add('emote-panel-list-big-emote'); + } + //If the emote is an image if(emote.type == 'image'){ //Create image node @@ -94,6 +151,13 @@ class emotePanel extends panelObj{ //Set media class emoteMedia.classList.add('emote-list-media'); + //if we have a low emote count + if(emoteList.length <= 2){ + //render them huuuuuge + emoteMedia.classList.add('emote-list-big-media'); + } + + //Create paragraph tag const emoteTitle = document.createElement('p'); //Set title class