mirror of
https://github.com/Spengreb/sync.git
synced 2026-06-10 15:22:04 +00:00
Merge pull request #11 from Spengreb/emote-selector-better-modal
Emote selector can be resized
This commit is contained in:
commit
8e9bd64e5b
2 changed files with 129 additions and 4 deletions
|
|
@ -625,11 +625,18 @@ table td {
|
||||||
position: fixed;
|
position: fixed;
|
||||||
z-index: 1060;
|
z-index: 1060;
|
||||||
width: 340px;
|
width: 340px;
|
||||||
|
height: 360px;
|
||||||
|
min-width: 260px;
|
||||||
|
min-height: 220px;
|
||||||
|
max-width: 90vw;
|
||||||
|
max-height: 85vh;
|
||||||
background: #272b30;
|
background: #272b30;
|
||||||
border: 1px solid #555;
|
border: 1px solid #555;
|
||||||
border-radius: 4px;
|
border-radius: 4px;
|
||||||
box-shadow: 0 4px 14px rgba(0,0,0,.6);
|
box-shadow: 0 4px 14px rgba(0,0,0,.6);
|
||||||
padding: 6px;
|
padding: 6px;
|
||||||
|
--emote-browser-item-size: 52px;
|
||||||
|
--emote-browser-image-size: 48px;
|
||||||
}
|
}
|
||||||
#emote-browser-search {
|
#emote-browser-search {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
|
|
@ -643,12 +650,12 @@ table td {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-wrap: wrap;
|
flex-wrap: wrap;
|
||||||
gap: 3px;
|
gap: 3px;
|
||||||
max-height: 320px;
|
height: calc(100% - 38px);
|
||||||
overflow-y: auto;
|
overflow-y: auto;
|
||||||
}
|
}
|
||||||
.emote-browser-item {
|
.emote-browser-item {
|
||||||
width: 52px;
|
width: var(--emote-browser-item-size);
|
||||||
height: 52px;
|
height: var(--emote-browser-item-size);
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
|
|
@ -657,7 +664,29 @@ table td {
|
||||||
flex-shrink: 0;
|
flex-shrink: 0;
|
||||||
}
|
}
|
||||||
.emote-browser-item:hover { background: #3a3f44; }
|
.emote-browser-item:hover { background: #3a3f44; }
|
||||||
.emote-browser-item img { max-width: 48px; max-height: 48px; object-fit: contain; }
|
.emote-browser-item img { max-width: var(--emote-browser-image-size); max-height: var(--emote-browser-image-size); object-fit: contain; }
|
||||||
|
|
||||||
|
.emote-browser-resize-handle {
|
||||||
|
position: absolute;
|
||||||
|
width: 14px;
|
||||||
|
height: 14px;
|
||||||
|
border-radius: 50%;
|
||||||
|
background: linear-gradient(145deg, rgba(215, 215, 215, 0.65), rgba(150, 150, 150, 0.55));
|
||||||
|
border: 1px solid rgba(18, 20, 22, 0.55);
|
||||||
|
box-shadow: 0 1px 2px rgba(0, 0, 0, 0.35);
|
||||||
|
z-index: 2;
|
||||||
|
opacity: 0.85;
|
||||||
|
transition: transform 120ms ease, opacity 120ms ease, box-shadow 120ms ease;
|
||||||
|
}
|
||||||
|
.emote-browser-resize-handle:hover {
|
||||||
|
opacity: 1;
|
||||||
|
transform: scale(1.08);
|
||||||
|
box-shadow: 0 2px 6px rgba(0, 0, 0, 0.45);
|
||||||
|
}
|
||||||
|
.emote-browser-resize-handle.ne { top: -7px; right: -7px; cursor: nesw-resize; }
|
||||||
|
.emote-browser-resize-handle.nw { top: -7px; left: -7px; cursor: nwse-resize; }
|
||||||
|
.emote-browser-resize-handle.se { bottom: -7px; right: -7px; cursor: nwse-resize; }
|
||||||
|
.emote-browser-resize-handle.sw { bottom: -7px; left: -7px; cursor: nesw-resize; }
|
||||||
|
|
||||||
#leftcontrols .btn {
|
#leftcontrols .btn {
|
||||||
margin-right: 5px;
|
margin-right: 5px;
|
||||||
|
|
|
||||||
96
www/js/ui.js
96
www/js/ui.js
|
|
@ -962,9 +962,28 @@ $('body').append(
|
||||||
'<div id="emote-browser">' +
|
'<div id="emote-browser">' +
|
||||||
'<input id="emote-browser-search" class="form-control input-sm" type="text" placeholder="Search emotes…">' +
|
'<input id="emote-browser-search" class="form-control input-sm" type="text" placeholder="Search emotes…">' +
|
||||||
'<div id="emote-browser-grid"></div>' +
|
'<div id="emote-browser-grid"></div>' +
|
||||||
|
'<div class="emote-browser-resize-handle ne" data-dir="ne"></div>' +
|
||||||
|
'<div class="emote-browser-resize-handle nw" data-dir="nw"></div>' +
|
||||||
|
'<div class="emote-browser-resize-handle se" data-dir="se"></div>' +
|
||||||
|
'<div class="emote-browser-resize-handle sw" data-dir="sw"></div>' +
|
||||||
'</div>'
|
'</div>'
|
||||||
);
|
);
|
||||||
|
|
||||||
|
function updateEmoteBrowserScale() {
|
||||||
|
var panel = document.getElementById('emote-browser');
|
||||||
|
if (!panel) return;
|
||||||
|
|
||||||
|
var panelWidth = panel.clientWidth;
|
||||||
|
var panelHeight = panel.clientHeight;
|
||||||
|
var itemByWidth = Math.floor((panelWidth - 48) / 6);
|
||||||
|
var itemByHeight = Math.floor((panelHeight - 90) / 4);
|
||||||
|
var itemSize = Math.max(40, Math.min(88, itemByWidth, itemByHeight));
|
||||||
|
var imageSize = Math.max(36, itemSize - 4);
|
||||||
|
|
||||||
|
panel.style.setProperty('--emote-browser-item-size', itemSize + 'px');
|
||||||
|
panel.style.setProperty('--emote-browser-image-size', imageSize + 'px');
|
||||||
|
}
|
||||||
|
|
||||||
function emoteBrowserMatches() {
|
function emoteBrowserMatches() {
|
||||||
if (!CHANNEL.emotes) return [];
|
if (!CHANNEL.emotes) return [];
|
||||||
var f = EMOTE_BROWSER_FILTER.toLowerCase();
|
var f = EMOTE_BROWSER_FILTER.toLowerCase();
|
||||||
|
|
@ -1016,6 +1035,74 @@ function emoteBrowserPosition() {
|
||||||
panel.css({ top: top, left: left });
|
panel.css({ top: top, left: left });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function clampEmoteBrowserToViewport() {
|
||||||
|
var panel = document.getElementById('emote-browser');
|
||||||
|
if (!panel) return;
|
||||||
|
|
||||||
|
var rect = panel.getBoundingClientRect();
|
||||||
|
var maxLeft = window.innerWidth - rect.width - 8;
|
||||||
|
var maxTop = window.innerHeight - rect.height - 8;
|
||||||
|
var left = Math.min(Math.max(rect.left, 8), Math.max(8, maxLeft));
|
||||||
|
var top = Math.min(Math.max(rect.top, 8), Math.max(8, maxTop));
|
||||||
|
panel.style.left = left + 'px';
|
||||||
|
panel.style.top = top + 'px';
|
||||||
|
}
|
||||||
|
|
||||||
|
$(document).on('mousedown', '#emote-browser .emote-browser-resize-handle', function (ev) {
|
||||||
|
ev.preventDefault();
|
||||||
|
ev.stopPropagation();
|
||||||
|
|
||||||
|
var panel = document.getElementById('emote-browser');
|
||||||
|
var dir = ev.target.getAttribute('data-dir');
|
||||||
|
if (!panel || !dir) return;
|
||||||
|
|
||||||
|
var startX = ev.clientX;
|
||||||
|
var startY = ev.clientY;
|
||||||
|
var startRect = panel.getBoundingClientRect();
|
||||||
|
var minW = 260, minH = 220;
|
||||||
|
var maxW = Math.floor(window.innerWidth * 0.9);
|
||||||
|
var maxH = Math.floor(window.innerHeight * 0.85);
|
||||||
|
|
||||||
|
function onMove(moveEv) {
|
||||||
|
var dx = moveEv.clientX - startX;
|
||||||
|
var dy = moveEv.clientY - startY;
|
||||||
|
var left = startRect.left;
|
||||||
|
var top = startRect.top;
|
||||||
|
var width = startRect.width;
|
||||||
|
var height = startRect.height;
|
||||||
|
|
||||||
|
if (dir.indexOf('e') !== -1) {
|
||||||
|
width = Math.max(minW, Math.min(maxW, startRect.width + dx));
|
||||||
|
}
|
||||||
|
if (dir.indexOf('s') !== -1) {
|
||||||
|
height = Math.max(minH, Math.min(maxH, startRect.height + dy));
|
||||||
|
}
|
||||||
|
if (dir.indexOf('w') !== -1) {
|
||||||
|
width = Math.max(minW, Math.min(maxW, startRect.width - dx));
|
||||||
|
left = startRect.right - width;
|
||||||
|
}
|
||||||
|
if (dir.indexOf('n') !== -1) {
|
||||||
|
height = Math.max(minH, Math.min(maxH, startRect.height - dy));
|
||||||
|
top = startRect.bottom - height;
|
||||||
|
}
|
||||||
|
|
||||||
|
panel.style.left = Math.max(8, left) + 'px';
|
||||||
|
panel.style.top = Math.max(8, top) + 'px';
|
||||||
|
panel.style.width = width + 'px';
|
||||||
|
panel.style.height = height + 'px';
|
||||||
|
updateEmoteBrowserScale();
|
||||||
|
clampEmoteBrowserToViewport();
|
||||||
|
}
|
||||||
|
|
||||||
|
function onUp() {
|
||||||
|
document.removeEventListener('mousemove', onMove);
|
||||||
|
document.removeEventListener('mouseup', onUp);
|
||||||
|
}
|
||||||
|
|
||||||
|
document.addEventListener('mousemove', onMove);
|
||||||
|
document.addEventListener('mouseup', onUp);
|
||||||
|
});
|
||||||
|
|
||||||
$("#emotelistbtn").on('click', function () {
|
$("#emotelistbtn").on('click', function () {
|
||||||
var panel = $("#emote-browser");
|
var panel = $("#emote-browser");
|
||||||
if (panel.is(':visible')) { panel.hide(); return; }
|
if (panel.is(':visible')) { panel.hide(); return; }
|
||||||
|
|
@ -1023,7 +1110,9 @@ $("#emotelistbtn").on('click', function () {
|
||||||
$("#emote-browser-search").val('');
|
$("#emote-browser-search").val('');
|
||||||
emoteBrowserReset();
|
emoteBrowserReset();
|
||||||
panel.show();
|
panel.show();
|
||||||
|
updateEmoteBrowserScale();
|
||||||
emoteBrowserPosition();
|
emoteBrowserPosition();
|
||||||
|
clampEmoteBrowserToViewport();
|
||||||
document.getElementById('emote-browser-search').focus();
|
document.getElementById('emote-browser-search').focus();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -1042,6 +1131,13 @@ document.getElementById('emote-browser-grid').addEventListener('scroll', functio
|
||||||
emoteBrowserRenderMore();
|
emoteBrowserRenderMore();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
$(window).on('resize', function () {
|
||||||
|
updateEmoteBrowserScale();
|
||||||
|
if ($("#emote-browser").is(':visible')) {
|
||||||
|
clampEmoteBrowserToViewport();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
$("#fullscreenbtn").on('click', function () {
|
$("#fullscreenbtn").on('click', function () {
|
||||||
var elem = document.querySelector("#videowrap .embed-responsive");
|
var elem = document.querySelector("#videowrap .embed-responsive");
|
||||||
// this shit is why frontend web development sucks
|
// this shit is why frontend web development sucks
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue