diff --git a/CHANGELOG.md b/CHANGELOG.md index 2b0ff225c..00c5975e5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,8 @@ v0.22.6 (trunk) * Add the message menu in the Picture preview * Move the info logic from the JS to the CSS * Refactor and cleanup the info for stickers messages +* Move the file message related logic to the Message model +* Refactor the Stickers and File display and cleanup the related CSS v0.22.5 --------------------------- diff --git a/app/Message.php b/app/Message.php index 547de4a82..b51df996d 100644 --- a/app/Message.php +++ b/app/Message.php @@ -101,6 +101,38 @@ class Message extends Model $file['cleansize'] = humanSize((float)$file['size']); } + if ( + \array_key_exists('type', $file) + && typeIsPicture($file['type']) + ) { + $file['preview'] = [ + 'thumb' => protectPicture($file['uri']), + 'url' => $file['uri'], + 'picture' => true + ]; + } + + $url = parse_url($file['uri']); + if (\array_key_exists('host', $url)) { + $file['host'] = $url['host']; + + switch ($url['host']) { + case 'i.imgur.com': + $thumb = getImgurThumbnail($file['uri']); + + if ($thumb) { + $file['preview'] = [ + 'url' => $file['uri'], + 'thumb' => $thumb, + 'picture' => true + ]; + } + break; + } + } + + $file['id'] = hashId($file['uri']); + return $file; } @@ -629,6 +661,11 @@ class Message extends Model return ($this->user_id == $this->jidfrom); } + public function isClassic(): bool + { + return in_array($this->type, ['chat', 'groupchat']); + } + public function retract() { $this->retracted = true; diff --git a/app/widgets/Chat/Chat.php b/app/widgets/Chat/Chat.php index d0eb42b2e..f6ab948fb 100644 --- a/app/widgets/Chat/Chat.php +++ b/app/widgets/Chat/Chat.php @@ -856,16 +856,18 @@ class Chat extends \Movim\Widget\Base */ public function ajaxHttpDaemonReply($mid) { - $m = $this->user->messages() + $message = $this->user->messages() ->where('mid', $mid) ->first(); - if (($m->isMuc() && $m->stanzaid) - || (!$m->isMuc() && $m->messageid) - || isset($m->thread) + if ( + $message->isClassic() + && (($message->isMuc() && $message->stanzaid) + || (!$message->isMuc() && $message->messageid) + || isset($message->thread)) ) { $view = $this->tpl(); - $view->assign('message', $m); + $view->assign('message', $message); $this->rpc('MovimTpl.fill', '#reply', $view->draw('_chat_reply')); $this->rpc('Chat.focus'); } @@ -1145,7 +1147,6 @@ class Chat extends \Movim\Widget\Base if ($unreadsCount > 0) { $this->rpc('Chat.insertSeparator', $unreadsCount); } - } public function prepareMessage(&$message, $jid = null) @@ -1229,7 +1230,7 @@ class Chat extends \Movim\Widget\Base if ( $emoji->isSingleEmoji() && !isset($message->html) - && in_array($message->type, ['chat', 'groupchat']) + && $message->isClassic() ) { $message->sticker = [ 'url' => $emoji->getLastSingleEmojiURL(), @@ -1242,47 +1243,6 @@ class Chat extends \Movim\Widget\Base // Attached file if (isset($message->file)) { - // We proxify pictures links even if they are advertized as small ones - if ( - \array_key_exists('type', $message->file) - && typeIsPicture($message->file['type']) - && $message->file['size'] <= SMALL_PICTURE_LIMIT * 4 - ) { - $message->sticker = [ - 'thumb' => protectPicture($message->file['uri']), - 'url' => $message->file['uri'], - 'picture' => true - ]; - } - - // Set an id for all the files - $file = $message->file; - $file['id'] = hashId($file['uri']); - $message->file = $file; - - $url = parse_url($message->file['uri']); - - // Other image websites - if (\array_key_exists('host', $url)) { - $file = $message->file; - $file['host'] = $url['host']; - $message->file = $file; - - switch ($url['host']) { - case 'i.imgur.com': - $thumb = getImgurThumbnail($message->file['uri']); - - if ($thumb) { - $message->sticker = [ - 'url' => $message->file['uri'], - 'thumb' => $thumb, - 'picture' => true - ]; - } - break; - } - } - // Build cards for the URIs $uri = explodeXMPPURI($message->file['uri']); diff --git a/app/widgets/Chat/chat.css b/app/widgets/Chat/chat.css index 8240883ae..6cfd72d11 100644 --- a/app/widgets/Chat/chat.css +++ b/app/widgets/Chat/chat.css @@ -298,50 +298,30 @@ main:not(.enabled) #chat_widget { margin: 0; } -#chat_widget li img:not(.emoji):not(.hfr) { +#chat_widget li img:not(.emoji) { max-height: 30rem; max-width: 100%; display: block; -} - -#chat_widget li div.bubble.sticker.file img.active:hover { - cursor: pointer; -} - -#chat_widget li div.bubble.sticker img:not(.emoji):not(.hfr), -#chat_widget ul li div.bubble.file video { - border-radius: 0.75rem; width: auto; - max-height: 150px; -} - -#chat_widget ul li div.bubble.file video { - display: block; - max-height: 200px; - background-color: rgba(var(--movim-font), 0.15); } -#chat_widget ul li div.bubble.file video:not(.gif) { - height: 200px; - max-width: 100%; +#chat_widget li img.active { + transition: opacity 0.1s ease-in-out; } -li div.bubble.sticker.file img:not(.emoji):not(.hfr) { - max-height: 170px; - object-fit: cover; - transition: opacity 0.2s ease-in-out; - background-color: rgba(var(--movim-gray), 0.1); - background-image: url(/theme/img/broken_image.svg); - background-position: center; - background-repeat: no-repeat; +#chat_widget li img.active:hover { + cursor: pointer; + opacity: 0.6; } -#chat_widget li.oppose div.bubble.sticker.file img:not(.emoji):not(.hfr) { - float: right; +#chat_widget li img.active:active { + opacity: 0.8; } -#chat_widget li.oppose div.bubble.sticker.file img:not(.emoji):not(.hfr) + div.file { - clear: right; +#chat_widget li img.sticker { + max-height: 150px; + border-radius: 0.75rem; + margin-bottom: 3rem; } #chat_widget ul.list:after { @@ -432,43 +412,6 @@ li div.bubble.sticker.file img:not(.emoji):not(.hfr) { border-radius: 0 3px 3px; } -/* File preview */ - -div.file:not(.bubble) { - min-height: 2rem; - word-break: break-all; - margin-right: 5rem; -} - -#chat_widget div.file:not(.bubble) a:not(.button) { - padding: 1rem 0; -} - -#chat_widget div.file:not(.bubble) div:not(.audio_player) p { - max-width: 31rem; - text-overflow: ellipsis; - white-space: nowrap; - display: inline-block; - margin-bottom: -0.5rem; -} - -#chat_widget div.file:not(.bubble) p ~ span.host:before { - content: ''; - height: 0; - display: block; -} - -#chat_widget div.file:not(.bubble) span.size:before { - content: '–'; - margin: 0 0.75rem; -} - -#chat_widget audio { - border-radius: 0.5rem; - width: 100%; - min-width: 23rem; -} - /* Parent */ #chat_widget div.parent { @@ -504,16 +447,31 @@ div.file:not(.bubble) { white-space: pre-wrap; } +/* Date element */ + +li div.bubble:after { + content: attr(data-publishedprepared); + line-height: 1.5rem; + right: 1rem; + bottom: 1rem; + position: absolute; + pointer-events: none; +} + +li div.bubble.file:not(.audio):after { + right: 0; + bottom: 0.5rem; +} + /* Emojis */ #chat_widget .bubble ul.reactions { - margin-bottom: -0.25rem; - margin-right: 5rem; display: flex; } -#chat_widget .bubble:not(.file) ul.reactions { - margin-top: 0.25rem; +#chat_widget .bubble.file .reactions { + margin-right: 4.5rem; + margin-top: -2rem; } #chat_widget .bubble div span.reaction, @@ -563,7 +521,7 @@ div.file:not(.bubble) { margin-right: -7rem; } -#chat_widget .bubble:not(.sticker):not(.file) > div:last-child { +#chat_widget .bubble:not(.file) > div:last-child { padding-right: 12rem; } @@ -579,12 +537,12 @@ div.file:not(.bubble) { display: inline-flex; position: absolute; left: 100%; - transform: translate(-0.75rem, -0.25rem); + transform: translate(-0.5rem, -0.5rem); } #chat_widget li .bubble.file div:hover ul.reactions:empty ~ span.reaction, #chat_widget li .bubble.file div:not(.encrypted):hover span.reply { - transform: translate(-0.75rem, -7.25rem); + transform: translate(-0.5rem, -5.5rem); } #chat_widget li .bubble div:hover ul.reactions:not(:empty) ~ span.reply { @@ -610,28 +568,91 @@ div.file:not(.bubble) { order: 0; } +/* File element */ + +li .bubble.file { + margin-bottom: 1.5rem; +} + +li .bubble.file div.file { + margin-bottom: 3rem; +} + +li .bubble.file span.resource + div.file { + margin-top: 1rem; +} + +li .bubble.file div.file img, +li .bubble.file div.file video { + display: block; + border-radius: 0.75rem; + width: auto; + max-height: 200px; + margin-bottom: 1rem; +} + +li div.bubble.file div.file img { + max-height: 170px; + min-width: 12rem; + object-fit: cover; + transition: opacity 0.2s ease-in-out; + background-color: rgba(var(--movim-gray), 0.1); + background-image: url(/theme/img/broken_image.svg); + background-position: center; + background-repeat: no-repeat; +} + +li div.bubble.file video { + max-height: 200px; + background-color: rgba(var(--movim-font), 0.15); + max-width: 100%; +} + +li.oppose .bubble.file div.file img, +li.oppose .bubble.file div.file video { + display: block; + margin-right: 0; + margin-left: auto; +} + +li .bubble.file div.file[data-type="image/gif"]:after { + color: white; + font-family: 'Material Icons'; + text-shadow: 0 0 1rem rgba(0, 0, 0, 0.5); + position: absolute; + font-size: 5rem; + line-height: 5rem; + content: "\e908"; + top: 0; + left: 0.5rem; + display: block; + pointer-events: none; +} + /* Message Info */ #chat_widget .bubble .message span.info:after { display: inline-block; font-family: 'Material Icons'; + vertical-align: middle; } -#chat_widget .bubble.sticker .message p:before { +#chat_widget .bubble.file .message div.file:before { display: inline-block; position: absolute; - bottom: 1rem; + top: 1rem; right: 1rem; font-family: 'Material Icons'; + color: white; text-shadow: 0 0 1rem rgba(0, 0, 0, 0.85); } -#chat_widget .bubble.sticker .message.delivered p:before, +#chat_widget .bubble.file .message.delivered div.file:before, #chat_widget .bubble .message.delivered span.info:after { content: '\e5ca'; } -#chat_widget .bubble.sticker .message.displayed p:before, +#chat_widget .bubble.file .message.displayed div.file:before, #chat_widget .bubble .message.displayed span.info:after { content: '\e877'; } @@ -640,7 +661,7 @@ div.file:not(.bubble) { content: '\e897'; } -#chat_widget .bubble.sticker .message.edited.delivered p:before, +#chat_widget .bubble.file .message.edited.delivered div.file:before, #chat_widget .bubble .message.edited.delivered span.info:after { content: '\e3c9 \e5ca'; } @@ -649,7 +670,7 @@ div.file:not(.bubble) { content: '\e897 \e5ca'; } -#chat_widget .bubble.sticker .message.edited.displayed p:before, +#chat_widget .bubble.file .message.edited.displayed div.file:before, #chat_widget .bubble .message.edited.displayed span.info:after { content: '\e3c9 \e877'; } @@ -658,7 +679,7 @@ div.file:not(.bubble) { content: '\e897 \e877'; } -#chat_widget .bubble.sticker .message span.info:after { +#chat_widget .bubble.file .message span.info:after { display: none; } diff --git a/app/widgets/Chat/chat.js b/app/widgets/Chat/chat.js index 297dfaef3..17b557b81 100644 --- a/app/widgets/Chat/chat.js +++ b/app/widgets/Chat/chat.js @@ -606,7 +606,7 @@ var Chat = { discussion.onscroll = function () { if (this.scrollTop < 1 - && discussion.querySelectorAll('ul li div.bubble p').length >= Chat.pagination && Chat.currentDateTime) { + && discussion.querySelectorAll('li div.bubble p').length >= Chat.pagination && Chat.currentDateTime) { Chat_ajaxGetHistory( Chat.getTextarea().dataset.jid, Chat.currentDateTime, @@ -804,7 +804,7 @@ var Chat = { ); }, setMessagePressBehaviour: function () { - document.querySelectorAll('#chat_widget ul li div.bubble:not(.sticker):not(.file) > div.message').forEach(message => { + document.querySelectorAll('#chat_widget li div.bubble:not(.file) > div.message').forEach(message => { message.onmousedown = function (e) { setTimeout(() => { if (e.button == 0 @@ -818,7 +818,7 @@ var Chat = { } }); - document.querySelectorAll('#chat_widget ul li div.bubble.file > div.message').forEach(message => { + document.querySelectorAll('#chat_widget li div.bubble.file > div.message').forEach(message => { if (card = message.querySelector('ul.list.card > li > div')) { card.onclick = function (e) { ChatActions_ajaxShowMessageDialog(message.dataset.mid); @@ -1063,27 +1063,6 @@ var Chat = { p.innerHTML = data.body; } - if (data.sticker != null && data.retracted == false) { - bubble.querySelector('div.bubble').classList.add('sticker'); - p.appendChild(Chat.getStickerHtml(data)); - - if (data.file != null) { - p.dataset.type = data.file.type; - p.classList.add('previewable'); - } - } - - if (data.file != null && data.card === undefined && data.file.type !== 'xmpp' && data.retracted == false) { - bubble.querySelector('div.bubble').classList.add('file'); - - // Ugly fix to clear the paragraph if the file contains a similar link - if (p.querySelector('a') && p.querySelector('a').href == data.file.uri) { - p.querySelector('a').remove(); - } - - p.appendChild(Chat.getFileHtml(data.file, data.sticker)); - } - if (data.replaceid) { msg.classList.add('edited'); } @@ -1109,6 +1088,21 @@ var Chat = { msg.appendChild(resourceSpan); } + if (data.sticker != null && data.retracted == false) { + bubble.querySelector('div.bubble').classList.add('file'); + p.appendChild(Chat.getStickerHtml(data)); + + } else if (data.file != null && data.card === undefined && data.file.type !== 'xmpp' && data.retracted == false) { + bubble.querySelector('div.bubble').classList.add('file'); + + // Ugly fix to clear the paragraph if the file contains a similar link + if (p.querySelector('a') && p.querySelector('a').href == data.file.uri) { + p.querySelector('a').remove(); + } + + msg.appendChild(Chat.getFileHtml(data.file, data)); + } + if (data.published) { info.title = data.published; } @@ -1170,7 +1164,7 @@ var Chat = { } if (data.sticker != null && data.retracted == false) { - msg.parentElement.classList.add('sticker'); + msg.parentElement.classList.add('sticker', 'file'); } else { msg.parentElement.classList.remove('sticker'); } @@ -1274,6 +1268,8 @@ var Chat = { }, getStickerHtml: function (data) { var img = document.createElement('img'); + img.classList.add('sticker'); + if (data.sticker.url) { if (data.sticker.thumb) { img.setAttribute('src', data.sticker.thumb); @@ -1289,15 +1285,6 @@ var Chat = { } } - if (data.sticker.title) { - img.title = data.sticker.title; - } - - if (data.sticker.picture) { - img.classList.add('active'); - img.setAttribute('onclick', 'Preview_ajaxHttpShow("' + data.sticker.url + '", ' + data.mid + ')'); - } - return img; }, getCardHtml: function (card) { @@ -1311,11 +1298,42 @@ var Chat = { return ul; }, - getFileHtml: function (file, sticker) { + getFileHtml: function (file, data) { var div = document.createElement('div'); div.setAttribute('class', 'file'); if (file.name) { + div.dataset.type = file.type; + + if (file.preview) { + var img = document.createElement('img'); + if (file.preview.url) { + if (file.preview.thumb) { + img.setAttribute('src', file.preview.thumb); + } else { + img.setAttribute('src', file.preview.url); + } + + if (file.preview.width) img.setAttribute('width', file.preview.width); + if (file.preview.height) { + img.setAttribute('height', file.preview.height); + } else { + img.setAttribute('height', '170'); + } + } + + if (file.preview.title) { + img.title = file.preview.title; + } + + if (file.preview.picture) { + img.classList.add('active'); + img.setAttribute('onclick', 'Preview_ajaxHttpShow("' + file.preview.url + '", ' + data.mid + ')'); + } + + div.appendChild(img); + } + if (file.type == 'audio/ogg' || file.type == 'audio/opus' || file.type == 'audio/mpeg') { div.appendChild(Chat.getAudioPlayer(file)); } else if (file.type == 'video/webm' || file.type == 'video/mp4') { @@ -1328,7 +1346,7 @@ var Chat = { return div; } - var a = document.createElement('a'); + /*var a = document.createElement('a'); if (sticker == null) { var link = document.createElement('p'); @@ -1336,13 +1354,14 @@ var Chat = { link.setAttribute('title', file.name); a.appendChild(link); } + a.setAttribute('href', file.uri); a.setAttribute('target', '_blank'); a.setAttribute('rel', 'noopener'); - div.appendChild(a); + div.appendChild(a);*/ - if (file.host) { + /*if (file.host) { var host = document.createElement('span'); host.innerHTML = file.host; host.setAttribute('class', 'host'); @@ -1356,7 +1375,7 @@ var Chat = { span.setAttribute('class', 'size'); a.appendChild(span); - } + }*/ } return div; diff --git a/app/widgets/ChatActions/ChatActions.php b/app/widgets/ChatActions/ChatActions.php index 0c4bc97bc..f657cf853 100644 --- a/app/widgets/ChatActions/ChatActions.php +++ b/app/widgets/ChatActions/ChatActions.php @@ -59,7 +59,7 @@ class ChatActions extends \Movim\Widget\Base ->where('mid', $mid) ->first(); - if ($message && in_array($message->type, ['chat', 'groupchat'])) { + if ($message && $message->isClassic()) { $view = $this->tpl(); $view->assign('message', $message); diff --git a/public/theme/css/color.css b/public/theme/css/color.css index a22bbaff6..c28fbe313 100644 --- a/public/theme/css/color.css +++ b/public/theme/css/color.css @@ -46,7 +46,7 @@ ul.list li span.control.divided:before { } label, span.info, -ul li div.bubble:after, +li div.bubble:after, table tr th { color: rgba(var(--movim-font), 0.54); } @@ -106,7 +106,7 @@ span.icon span.counter.alt { .button.indigo, .icon.indigo, span.resource.indigo { color: var(--p-indigo); } .button.blue, .icon.blue , span.resource.blue { color: var(--p-blue); } .button.green, .icon.green , span.resource.green { color: var(--p-green); } -ul li div.bubble.moderator:after, +li div.bubble.moderator:after, ul li div > p > span.moderator, .button.orange, .icon.orange, span.resource.orange { color: var(--p-orange); } .button.yellow, .icon.yellow, span.resource.yellow { color: #FBC02D; } diff --git a/public/theme/css/fonts.css b/public/theme/css/fonts.css index be945d5af..93a98556c 100644 --- a/public/theme/css/fonts.css +++ b/public/theme/css/fonts.css @@ -26,7 +26,3 @@ ul.list p + p .emoji { height: 5rem; margin: 0; } - -.hfr { - display: inline-block; -} diff --git a/public/theme/css/listn.css b/public/theme/css/listn.css index fd2b63ef0..a2e61bd4a 100644 --- a/public/theme/css/listn.css +++ b/public/theme/css/listn.css @@ -72,7 +72,7 @@ ul.list li>span.bubble.active:hover { } ul.list li>span:not(.bubble).active:hover, -ul.list li div.bubble:not(.sticker):not(.file):hover { +ul.list li div.bubble:not(.file):hover { cursor: pointer; background-color: rgba(var(--movim-element-action), 0.1); } @@ -91,7 +91,7 @@ ul.list li>span.bubble.active:active { } ul.list li>span:not(.bubble).active:active, -ul.list li div.bubble:not(.sticker):not(.file):active { +ul.list li div.bubble:not(.file):active { cursor: pointer; background-color: rgba(var(--movim-element-action), 0.2); } @@ -236,7 +236,7 @@ ul.list li>div>p>span.second.sticked { } ul.list li>div>p>span.info, -ul li div.bubble:after { +li div.bubble:after { float: right; font-size: 1.5rem; margin-left: 0.5rem; @@ -380,7 +380,7 @@ ul.tabs>li.active { /* Bubble */ -ul li div.bubble { +li div.bubble { position: relative; box-sizing: border-box; display: block; @@ -392,12 +392,12 @@ ul li div.bubble { transition: background 0.3s ease, box-shadow 0.3s ease; } -ul li div.bubble div[dir="rtl"] { +li div.bubble div[dir="rtl"] { text-align: right; } -ul li div.bubble:not(.sticker):not(.file), -ul li div.bubble.file div.audio_player { +li div.bubble:not(.file), +li div.bubble.file div.audio_player { padding: 1rem 1rem 1rem 1.5rem; border-radius: 0 1rem 1rem; line-height: 2.75rem; @@ -405,21 +405,20 @@ ul li div.bubble.file div.audio_player { margin-bottom: 1.5rem; } -ul li div.bubble.sticker, -ul li div.bubble.file { - margin-bottom: 1rem; +li div.bubble.file div.audio_player { + margin-bottom: 3rem; } -ul li div.bubble ul.card p:not(.line):not(:last-child) { +li div.bubble ul.card p:not(.line):not(:last-child) { display: block; } -ul li div.bubble ul.card p:last-child { +li div.bubble ul.card p:last-child { white-space: inherit; display: block; } -ul li div.bubble p { +li div.bubble p { overflow: hidden; display: inline; max-width: 100%; @@ -431,31 +430,31 @@ ul li div.bubble p { position: relative; } -ul li div.bubble p:empty { +li div.bubble p:empty { display: none; } -ul li div.bubble:not(.file) p { +li div.bubble:not(.file) p { margin-right: 1rem; } -ul li div.bubble p.retracted, -ul li div.bubble p.encrypted { +li div.bubble p.retracted, +li div.bubble p.encrypted { opacity: 0.5; } -ul li div.bubble p.previewable { +li div.bubble p.previewable { display: block; min-width: 0; margin-bottom: 0.5rem; } -ul li div.bubble p.code { +li div.bubble p.code { display: inline-block; margin: 0; } -ul li div.bubble span.resource { +li div.bubble span.resource { display: none; } @@ -464,16 +463,12 @@ ul li:not(.oppose):not(.sequel) div.bubble div:first-child span.resource { line-height: 2.5rem; } -ul li.oppose div.bubble.file { - word-break: break-all; -} - -ul li div.bubble:not(.sticker):not(.file), -ul li div.bubble.file div.audio_player { +li div.bubble:not(.file), +li div.bubble.file div.audio_player { background-color: rgb(var(--movim-background-main)); } -ul li.oppose div.bubble:not(.sticker):not(.file), +ul li.oppose div.bubble:not(.file), ul li.oppose div.bubble.file div.audio_player { background-color: rgba(var(--movim-background-main), 0.5); border-color: rgba(var(--movim-background-main), 0.5); @@ -481,36 +476,15 @@ ul li.oppose div.bubble.file div.audio_player { padding: 1rem 1rem 1rem 1.5rem; } -ul li div.bubble.file div.audio_player, -ul li.oppose div.bubble.file div.audio_player { - padding: 0.5rem; - margin-bottom: 0.25rem; -} - -ul li div.bubble p i.icon { +li div.bubble p i.icon { margin-right: 0.25rem; } -ul li div.bubble:after { - content: attr(data-publishedprepared); - line-height: 1.5rem; - right: 1rem; - bottom: 1rem; - position: absolute; - pointer-events: none; -} - -ul li div.bubble.sticker:after, -ul li div.bubble.file:after { - right: 0; - bottom: 0; -} - ul li .quote { font-style: italic; } -ul li div.bubble:not(.sticker):not(.file):before { +li div.bubble:not(.file):before { content: ""; position: absolute; top: 0; @@ -525,17 +499,17 @@ ul li div.bubble:not(.sticker):not(.file):before { transition: background-color 0.3s ease; } -ul li div.bubble:not(.sticker):not(.file):hover:before, -ul li.oppose div.bubble:not(.sticker):not(.file):hover:before { +li div.bubble:not(.file):hover:before, +ul li.oppose div.bubble:not(.file):hover:before { background-color: rgba(var(--movim-element-action), 0.1); } -ul li div.bubble:not(.sticker):not(.file):active:before, -ul li.oppose div.bubble:not(.sticker):not(.file):active:before { +li div.bubble:not(.file):active:before, +ul li.oppose div.bubble:not(.file):active:before { background-color: rgba(var(--movim-element-action), 0.2); } -ul li.oppose div.bubble:not(.sticker):not(.file):before { +ul li.oppose div.bubble:not(.file):before { left: initial; right: -1.6rem; background-color: rgba(var(--movim-background-main), 0.5);