diff --git a/assets/chat/css/style.scss b/assets/chat/css/style.scss index 4d6c0cf9..b898fca3 100644 --- a/assets/chat/css/style.scss +++ b/assets/chat/css/style.scss @@ -12,28 +12,38 @@ background: rgba($text-color-selected, 0.99); } -*, *::before, *::after { box-sizing: inherit; } -html { box-sizing: border-box; } - -$chat-chrome-font : "Roboto", Helvetica, "Trebuchet MS", Verdana, sans-serif; -$chat-lines-font : "Roboto", Helvetica, "Trebuchet MS", Verdana, sans-serif; -$chat-min-width : 300px; -$menu-width-max : 320px; -$menu-bottom-max : 89px; -$text-size-sm : 11px; -$text-size-md : 13px; -$text-size-lg : 16px; -$chat-line-height : 22px; -$chat-gutter-sm : 6px; - -body, textarea, input, button { +*, +*::before, +*::after { + box-sizing: inherit; +} +html { + box-sizing: border-box; +} + +$chat-chrome-font: "Roboto", Helvetica, "Trebuchet MS", Verdana, sans-serif; +$chat-lines-font: "Roboto", Helvetica, "Trebuchet MS", Verdana, sans-serif; +$chat-min-width: 300px; +$menu-width-max: 320px; +$menu-bottom-max: 89px; +$text-size-sm: 11px; +$text-size-md: 13px; +$text-size-lg: 16px; +$chat-line-height: 22px; +$chat-gutter-sm: 6px; + +body, +textarea, +input, +button { font-family: $chat-chrome-font; font-size: 14px; line-height: 1.42857143; text-rendering: optimizeLegibility; font-feature-settings: "kern"; } -html, body { +html, +body { height: 100%; position: relative; color: $text-color1; @@ -49,7 +59,8 @@ a { word-break: break-all; overflow-wrap: anywhere; } -a:hover, a:focus { +a:hover, +a:focus { color: $color-accent-light; text-decoration: underline; } @@ -76,27 +87,43 @@ label small { } @keyframes emote-complete { - 0% { transform: translate(-10px, 0); opacity: 0;/* text-shadow: 0 0 3px rgba(white, 1);*/ } - 2% { transform: translate(10px, 0); color: white; opacity: 1;/* text-shadow: 0 0 10px rgba(white, 0.5);*/ } - 100% { transform: translate(0, 0); opacity: 1; } + 0% { + transform: translate(-10px, 0); + opacity: 0; /* text-shadow: 0 0 3px rgba(white, 1);*/ + } + 2% { + transform: translate(10px, 0); + color: white; + opacity: 1; /* text-shadow: 0 0 10px rgba(white, 0.5);*/ + } + 100% { + transform: translate(0, 0); + opacity: 1; + } } @keyframes emote-greyout { - 0% { filter: grayscale(0) } - 75% { filter: grayscale(0) } - 100% { filter: grayscale(100%) } + 0% { + filter: grayscale(0); + } + 75% { + filter: grayscale(0); + } + 100% { + filter: grayscale(100%); + } } @keyframes whisper-pulse { 0% { color: white; - background: rgba(255,255,255,0.4); - box-shadow: 0 0 0 0 rgba(255,255,255,0.4); + background: rgba(255, 255, 255, 0.4); + box-shadow: 0 0 0 0 rgba(255, 255, 255, 0.4); } 70% { - background:none; - box-shadow: 0 0 0 10px rgba(255,255,255,0); + background: none; + box-shadow: 0 0 0 10px rgba(255, 255, 255, 0); } 100% { - box-shadow: 0 0 0 0 rgba(255,255,255,0); + box-shadow: 0 0 0 0 rgba(255, 255, 255, 0); } } @@ -218,7 +245,8 @@ label small { display: block; } -#chat-input-scaler, #chat-input-control { +#chat-input-scaler, +#chat-input-control { /** * `input-control` and `input-scaler` should have identical properties * which affect scaling, so as containing the same content they result @@ -226,7 +254,7 @@ label small { */ /* MSEdge seems to not respect `word-wrap` if width is a percentage, so we calculate it manually */ - width: calc( 100vw - #{$chat-gutter-sm*2} ); + width: calc(100vw - #{$chat-gutter-sm * 2}); box-sizing: border-box; padding: 5px; @@ -248,14 +276,14 @@ label small { resize: none; margin: 0; border-radius: 3px; - box-shadow: -1px 1px 2px rgba( black, 0.7 ) inset; + box-shadow: -1px 1px 2px rgba(black, 0.7) inset; display: block; white-space: break-spaces; } #chat-input-control::placeholder { color: $color-chat-place; } -#chat-input-control.invalid-msg-warning{ +#chat-input-control.invalid-msg-warning { border-color: red; } #chat-input-scaler { @@ -274,7 +302,7 @@ label small { /* Creates a space buffer between the chat messages and the bottom */ &::after { - content: ''; + content: ""; display: block; width: 100%; } @@ -291,7 +319,7 @@ label small { color: $color-chat-disabled; position: relative; text-decoration: none; - border-radius:50%; + border-radius: 50%; } .chat-tool-btn.ping { animation: whisper-pulse 2s 1; @@ -362,9 +390,9 @@ label small { border-width: 1px; border-style: solid; border-color: #000000; - background: $color-spoiler-hidden; - color: transparent; - transition: all .2s ease-in-out; + background: $color-spoiler-hidden; + color: transparent; + transition: all 0.2s ease-in-out; user-select: none; cursor: pointer; .weather { @@ -375,7 +403,7 @@ label small { } .generify-container { .chat-emote { - transition: all .2s; + transition: all 0.2s; opacity: 0 !important; transform: scale(0); } @@ -389,7 +417,7 @@ label small { pointer-events: none; color: $color-spoiler-hidden; } - .embed-externallink{ + .embed-externallink { pointer-events: none; visibility: hidden; } @@ -423,8 +451,8 @@ label small { pointer-events: auto; color: $color-link; } - .embed-externallink{ - pointer-events:auto; + .embed-externallink { + pointer-events: auto; visibility: visible; } .externallink:visited { @@ -484,7 +512,7 @@ label small { color: $color-link-hover; } .nsfw-link { - border-bottom: 1px dashed $color-underline-nsfw !important;; + border-bottom: 1px dashed $color-underline-nsfw !important; } .nsfl-link { border-bottom: 1px dashed $color-underline-nsfl !important; @@ -551,7 +579,7 @@ label small { } /* disable animations for emotes that have likely scrolled off-screen to save CPU-time. */ -.msg-chat:nth-last-child(n+50) { +.msg-chat:nth-last-child(n + 50) { /* container is added to all emotes */ .generify-container { .chat-emote { @@ -564,7 +592,7 @@ label small { /* Default */ a.user { $main-color: $color-user-label-background; - $border-color: lighten( $main-color, 2.5 ); + $border-color: lighten($main-color, 2.5); color: $color-label-user; background: $main-color; @@ -576,7 +604,7 @@ a.user { border: 1px solid; text-shadow: 1px 1px 0px black; border-color: $border-color $border-color $main-color $main-color; - box-shadow: -1px 1px 1px rgba( black, 0.6 ); + box-shadow: -1px 1px 1px rgba(black, 0.6); } // disable .pref-viewerstateindicator-0 a.user { @@ -598,7 +626,7 @@ a.user { padding-left: 22px; } a.user:hover { - color: lighten($color-label-user,20%); + color: lighten($color-label-user, 20%); } /* T1, TWITCH */ @@ -608,7 +636,7 @@ a.flair13 { } a.flair9:hover, a.flair13:hover { - color: lighten($color-label-sub1,20%); + color: lighten($color-label-sub1, 20%); } /* T2 */ @@ -616,7 +644,7 @@ a.flair1 { color: $color-label-sub2; } a.flair1:hover { - color: lighten($color-label-sub2,20%); + color: lighten($color-label-sub2, 20%); } /* T3 */ @@ -624,7 +652,7 @@ a.flair3 { color: $color-label-sub3; } a.flair3:hover { - color: lighten($color-label-sub3,20%); + color: lighten($color-label-sub3, 20%); } /* T4 */ @@ -632,42 +660,42 @@ a.flair8 { color: $color-label-sub4; } a.flair8:hover { - color: lighten($color-label-sub4,20%); + color: lighten($color-label-sub4, 20%); } a.vip { color: $color-label-vip; } a.vip:hover { - color: lighten($color-label-vip,20%); + color: lighten($color-label-vip, 20%); } a.bot { color: $color-label-bot; } a.bot:hover { - color: lighten($color-label-bot,20%); + color: lighten($color-label-bot, 20%); } a.admin { color: $color-label-admin; } a.admin:hover { - color: lighten($color-label-admin,20%); + color: lighten($color-label-admin, 20%); } a.flair11 { color: $color-label-bot2; } a.flair11:hover { - color: lighten($color-label-bot2,20%); + color: lighten($color-label-bot2, 20%); } a.flair12 { color: $color-broadcaster; } a.flair12:hover { - color: lighten($color-broadcaster,20%); + color: lighten($color-broadcaster, 20%); } /* Hidden Flairs */ @@ -692,7 +720,7 @@ a.flair12:hover { .msg-command .text:before, .msg-info .text:before, .msg-error .text:before { - content: ''; + content: ""; display: inline-block; vertical-align: text-top; margin-right: 4px; @@ -724,7 +752,7 @@ a.flair12:hover { } .time { - color: lighten( $color-chat-time, 18 ); + color: lighten($color-chat-time, 18); } } @@ -739,7 +767,7 @@ a.flair12:hover { color: $color-accent; cursor: pointer; padding-left: 5px; - content: ''; + content: ""; } .censored .ctrl:hover:after { color: $color-accent-light; @@ -764,7 +792,7 @@ a.flair12:hover { .msg-info.msg-continue .text:before, .msg-error.msg-continue .text:before, .msg-broadcast.msg-continue .text:before { - content: ''; + content: ""; } /* /ME message */ @@ -842,7 +870,7 @@ a.flair12:hover { padding-top: 2.7px; padding-bottom: 2.4px; - $border-highlight: mix( white, $color-chat-tagged, 2 ); + $border-highlight: mix(white, $color-chat-tagged, 2); border-top: 1px solid $border-highlight; border-bottom: 1px solid $border-highlight; @@ -856,13 +884,13 @@ a.flair12:hover { } .msg-tagged:before { position: absolute; - top:0; - left:0; - bottom:0; + top: 0; + left: 0; + bottom: 0; min-width: 4px; display: block; - background: map-get( $tag-color-map, black ); - content: ''; + background: map-get($tag-color-map, black); + content: ""; } .pref-taggedvisibility .msg-tagged, .msg-tagged.msg-highlight { @@ -875,7 +903,7 @@ a.flair12:hover { .msg-highlight.msg-continue, .msg-own.msg-continue { .text:before { - color: lighten( $color-chat-disabled, 20 ); + color: lighten($color-chat-disabled, 20); } } @@ -886,7 +914,7 @@ a.flair12:hover { } @at-root .chat:not(.pref-showtime) & a.user { - border-left-color: mix( $color, black, 18 ); + border-left-color: mix($color, black, 18); } } } @@ -914,7 +942,7 @@ a.flair12:hover { /* Broadcasts */ .msg-broadcast { - text-shadow: 1px 1px 3px rgba(0,0,0,1); + text-shadow: 1px 1px 3px rgba(0, 0, 0, 1); background-color: $color-chat-emphasize; color: $color-text-broadcast !important; font-size: 110%; @@ -928,18 +956,18 @@ a.flair12:hover { /* Highlight */ .msg-highlight { - color: #CCC; + color: #ccc; background-color: $color-chat-highlight; padding-top: 2.7px; padding-bottom: 2.4px; margin-bottom: 3px; - $border-highlight: mix( white, $color-chat-highlight, 3 ); + $border-highlight: mix(white, $color-chat-highlight, 3); border-top: 1px solid $border-highlight; border-bottom: 1px solid $border-highlight; .time { - color: lighten( $color-chat-time, 18 ); + color: lighten($color-chat-time, 18); } .greentext { @@ -952,7 +980,7 @@ a.flair12:hover { /* Focus or highlight a line */ .focus-user .msg-chat { - opacity:0.3; + opacity: 0.3; } /* Emotes and combo */ @@ -968,7 +996,7 @@ a.flair12:hover { text-indent: -90000px; vertical-align: middle; padding-left: 0.5em; - cursor:pointer; + cursor: pointer; } .chat-combo { color: $color-chat-text1; @@ -986,10 +1014,10 @@ a.flair12:hover { .count, .x { text-shadow: - -1px -1px 0 #000, - 1px -1px 0 #000, - -1px 1px 0 #000, - 1px 1px 0 #000; + -1px -1px 0 #000, + 1px -1px 0 #000, + -1px 1px 0 #000, + 1px 1px 0 #000; } .combo { display: none; @@ -1053,7 +1081,8 @@ a.flair12:hover { &.x30, &.x50 { animation: emote-greyout 3500ms 1; - background: transparent url("/assets/chat/img/emote-splat.png") no-repeat center center; + background: transparent url("/assets/chat/img/emote-splat.png") + no-repeat center center; background-size: 100% 100%; filter: grayscale(100%); .combo { @@ -1096,7 +1125,7 @@ a.flair12:hover { /* Extends clickable area on the bottom */ &::after { - content: ''; + content: ""; display: block; height: 8px; position: absolute; @@ -1107,7 +1136,7 @@ a.flair12:hover { .chat-scroll-notify:hover { color: $color-chat-text1; } -#chat.chat-autocomplete-in .chat-scroll-notify { +#chat.chat-autocomplete-in .chat-scroll-notify { display: none; } .chat-output.chat-unpinned .chat-scroll-notify { @@ -1123,9 +1152,15 @@ a.flair12:hover { /* Auto complete */ @keyframes autocompletein { - 0% { opacity: 0; } - 90% { opacity: 0; } - 100% { opacity: 1; } + 0% { + opacity: 0; + } + 90% { + opacity: 0; + } + 100% { + opacity: 1; + } } #chat-auto-complete { pointer-events: none; @@ -1151,8 +1186,8 @@ a.flair12:hover { position: absolute; white-space: nowrap; list-style: none; - padding:0; - margin:0; + padding: 0; + margin: 0; } li { padding: 0 4px; @@ -1168,7 +1203,7 @@ a.flair12:hover { border-radius: 0 3px 0 0; } &:hover { - color: lighten($color-chat-text3,20); + color: lighten($color-chat-text3, 20); } &.active { color: $text-color; @@ -1341,7 +1376,8 @@ a.flair12:hover { margin: 2px 0; color: $color-chat-text2; } - .badge, .remove { + .badge, + .remove { float: right; margin-right: 10px; } @@ -1414,7 +1450,6 @@ a.flair12:hover { } } #chat-settings { - #chat-settings-form { margin: 20px 0; } @@ -1449,7 +1484,6 @@ a.flair12:hover { opacity: 0.6; cursor: pointer; - &:not([disabled]) { color: #ff8700; border-color: #ff8700; @@ -1482,7 +1516,7 @@ a.flair12:hover { margin-right: 20px; } h4 { - font-size:90%; + font-size: 90%; margin-top: 25px; margin-bottom: 10px; padding-left: 18px; @@ -1516,11 +1550,11 @@ a.flair12:hover { padding: 0; &:after { - content: '\f0c8'; + content: "\f0c8"; } &:checked::after { - content: '\f14a'; + content: "\f14a"; } } select { @@ -1537,13 +1571,13 @@ a.flair12:hover { flex-direction: column; align-items: center; justify-content: center; - background: rgba($color-surface-dark1,0.75); + background: rgba($color-surface-dark1, 0.75); position: absolute; text-align: center; - top:0; - left:0; - right:0; - bottom:0; + top: 0; + left: 0; + right: 0; + bottom: 0; z-index: 230; h2 { font-size: 28px; @@ -1560,10 +1594,10 @@ a.flair12:hover { align-items: center; justify-content: center; position: absolute; - top:0; - left:0; - bottom:0; - right:0; + top: 0; + left: 0; + bottom: 0; + right: 0; display: none; } @@ -1581,20 +1615,20 @@ a.flair12:hover { /* Nano */ .nano { - position : relative; - width : 100%; - height : 100%; - overflow : hidden; + position: relative; + width: 100%; + height: 100%; + overflow: hidden; } .nano > .nano-content { - overflow-anchor : none; - position : absolute; - overflow : scroll; - overflow-x : hidden; - top : 0; - right : 0; - bottom : 0; - left : 0; + overflow-anchor: none; + position: absolute; + overflow: scroll; + overflow-x: hidden; + top: 0; + right: 0; + bottom: 0; + left: 0; } .nano > .nano-content:focus { outline: none; @@ -1606,28 +1640,28 @@ a.flair12:hover { display: block; } .nano > .nano-pane { - background : transparent; - position : absolute; - width : 6px; - right : 0; - top : 0; - bottom : 0; - visibility : hidden\9; /* Target only IE7 and IE8 with this hack */ - opacity : .01; - transition : .2s; - border-radius : 5px; + background: transparent; + position: absolute; + width: 6px; + right: 0; + top: 0; + bottom: 0; + visibility: hidden\9; /* Target only IE7 and IE8 with this hack */ + opacity: 0.01; + transition: 0.2s; + border-radius: 5px; } .nano > .nano-pane > .nano-slider { - opacity : 0.5; - background : $color-surface-light2; - position : relative; - border-radius : 3px; + opacity: 0.5; + background: $color-surface-light2; + position: relative; + border-radius: 3px; } .nano:hover > .nano-pane, .nano-pane.active, .nano-pane.flashed { - visibility : visible\9; /* Target only IE7 and IE8 with this hack */ - opacity : 0.99; + visibility: visible\9; /* Target only IE7 and IE8 with this hack */ + opacity: 0.99; } /** Form Controls */ @@ -1698,7 +1732,7 @@ button.btn { } .import-export:hover { - color: rgba(255,255,255,0.75) + color: rgba(255, 255, 255, 0.75); } .hidden-emote { @@ -1710,11 +1744,11 @@ button.btn { top: 0px; } -#maximum-messages-error{ - display:none; - color:#D8000C; +#maximum-messages-error { + display: none; + color: #d8000c; } -#maximum-messages-input{ +#maximum-messages-input { -moz-appearance: textfield; width: 100%; } @@ -1771,11 +1805,11 @@ button.btn { } } -.d-flex{ +.d-flex { display: flex; } -.justify-content-center{ +.justify-content-center { justify-content: center; } @@ -1783,9 +1817,9 @@ button.btn { display: none; position: absolute; z-index: 235; - background-color:$color-surface-dark3; + background-color: $color-surface-dark3; - padding:4px; + padding: 4px; width: -webkit-fit-content; width: -moz-fit-content; @@ -1797,13 +1831,103 @@ button.btn { border-radius: 5px; } -#chat-emote-info-emotename{ +#chat-emote-info-emotename { font-weight: bold; display: flex; justify-content: center; } -#chat-emote-info-creator,#chat-emote-info-seasonal{ +#chat-emote-info-creator, +#chat-emote-info-seasonal { display: block; font-size: 10px; } + +.button-orange { + border: none; + background-color: transparent; + color: #d17134; + &:hover { + color: darken(#d17134, 20%); + } +} + +// modal when image is opened +#image-modal { + position: fixed; + inset: 0; + z-index: 9999; + display: none; +} + +#image-modal.show { + display: flex; +} + +#image-modal__backdrop { + position: absolute; + inset: 0; + background: rgba(0, 0, 0, 0.8); +} + +#image-modal__content { + place-items: end; + margin-left: auto; + margin-right: auto; + display: flex; + justify-content: center; + flex-flow: column; + width: max-content; + z-index: 100; + position: relative; + margin-top: auto; + margin-bottom: auto; +} + +.image-modal__btn { + margin-left: 15px; + cursor: pointer; + &.copySuccessful { + animation: greenFade 1000ms 1; + } +} + +@keyframes greenFade { + 0% { + color: green; + &:hover { + color: green; + } + } + 100% { + color: #d17134; + &:hover { + color: darken(#d17134, 20%); + } + } +} + +#image-modal__toolbar { + margin-bottom: 10px; + user-select: none; + button { + span { + font-size: 25px; + } + } +} + +.in-chat-preview-image { + max-height: 125px; + max-width: 225px; + height: auto; + width: auto; + object-fit: contain; + cursor: pointer; +} + +#image-modal img { + max-width: 90vw; + max-height: 90vh; + user-select: none; +} diff --git a/assets/chat/js/chat.js b/assets/chat/js/chat.js index 132f8515..5ca41e6a 100644 --- a/assets/chat/js/chat.js +++ b/assets/chat/js/chat.js @@ -130,6 +130,8 @@ const settingsdefault = new Map([ ["formatter-green", true], ["formatter-emote", true], ["formatter-combo", true], + ["image-modal-preview", true], + ["in-chat-image-preview", true], ["holidayemotemodifiers", true], ["disablespoilers", false], ["viewerstateindicator", 1], @@ -389,6 +391,13 @@ class Chat { this.spoiler = new ChatSpoiler(this); this.mainwindow = new ChatWindow("main").into(this); + this.imagemodal = this.ui.find("#image-modal"); + this.modalbuttonclose = this.imagemodal.find("#image-modal__close"); + this.modalbuttonopen = this.imagemodal.find("#image-modal__open"); + this.modalbuttoncopy = this.imagemodal.find("#image-modal__copy"); + this.modalbackdrop = this.imagemodal.find("#image-modal__backdrop"); + this.modalimageelement = this.imagemodal.find("#modal-img"); + this.windowToFront("main"); this.menus.set( @@ -434,6 +443,36 @@ class Chat { this.autocomplete.bind(this); this.applySettings(false); + this.modalbackdrop.on("click", (e) => { + this.imagemodal.removeClass("show"); + this.modalimageelement.attr("src", ""); + }) + + this.modalbuttonclose.on("click", (e) => { + this.imagemodal.removeClass("show"); + this.modalimageelement.attr("src", ""); + }) + + this.modalbuttoncopy.on("click", (e) => { + this.modalbuttoncopy.removeClass("copySuccessful"); + + requestAnimationFrame(() => { + requestAnimationFrame(() => { + this.modalbuttoncopy.addClass("copySuccessful"); + }); + }); + + const url = this.modalimageelement.attr("src"); + navigator.clipboard.writeText(url); + }); + + + this.modalbuttonopen.on("click", (e) => { + const url = this.modalimageelement.attr("src"); + window.open(url, '_blank').focus(); + }) + + // Chat input this.input.on("keypress", e => { if (isKeyCode(e, KEYCODES.ENTER) && !e.shiftKey && !e.ctrlKey) { diff --git a/assets/chat/js/formatters.js b/assets/chat/js/formatters.js index d4431f24..93355bed 100644 --- a/assets/chat/js/formatters.js +++ b/assets/chat/js/formatters.js @@ -215,6 +215,21 @@ function moveModifierToFront(modifierList, modifierName) { return modifierList; } +window.__openImageModalFromLink = function (e, src) { + e.preventDefault(); + if (window.location.href.includes("chat.strims.gg") || window.location.href.includes("localhost") ) { + const imagemodal = $("#image-modal"); + const modalImageElement = $("#modal-img"); + modalImageElement.attr("src", src) + imagemodal.addClass("show"); + } else { + window.parent.postMessage( + { action: "IMAGE_MODAL_SRC", payload: src }, + "*", + ); + } +}; + class DisabledFormatter { format(chat, str, message = null) { return str; @@ -623,6 +638,7 @@ class UrlFormatter { this.discordmp4Regex = /https:\/\/(media|cdn)\.discordapp\.(net|com)\/attachments.*?\.(mp4|webm|mov)/i; this.refLinkRegex = /^(https?:\/\/)?(www\.)?(((smile\.)?amazon)|twitter|(open\.)?spotify)\.[a-z]{2,3}/; this.twitterRegex = /^(?:https:\/\/)?(?:www\.)?twitter\.com\/([^ ?]+)/i; + this.imageRegEx = /\.(png|jpe?g|gif|webp|bmp|svg|avif)$/; // make sure to split at "?" if testing URL // e.g. youtube ids include "-" and "_". const embedCommonId = '([\\w-]{1,30})'; @@ -748,7 +764,35 @@ class UrlFormatter { // 70 characters is the 80th percentile for link length if (shortenLinks && url.length > 75) { - url = url.substring(0, 35) + '...' + url.substring(35, url.length - 35) + '' + url.substring(url.length - 35); + url = url.substring(0, 35) + '...' + url.substring(35, url.length - 35) + '' + url.substring(url.length - 35); + } + // if URL is an image, allow modal, otherwise treat it normally + if (this.imageRegEx.test(url.split("?")[0].toLowerCase())) { + let imageMessage = ""; + + // if modal enabled, add on to variable + if (chat.settings.get("image-modal-preview")) { + imageMessage += `${url}${extra}`; + } + + // if image preview enabled and modal enabled / if image preview enabled and modal disabled, add on to variable + if(chat.settings.get("in-chat-image-preview")){ + if (chat.settings.get("image-modal-preview")) { + imageMessage += `
`; + } else { + imageMessage += `${url}${extra}
`; + } + } + // test if variable has anything and return it, if not, continue + if (imageMessage.length > 0) { + return imageMessage; + } } return `${url}${extra}`; } diff --git a/assets/chat/js/messages.js b/assets/chat/js/messages.js index b9f38236..f2f59ef8 100644 --- a/assets/chat/js/messages.js +++ b/assets/chat/js/messages.js @@ -41,6 +41,38 @@ function setFormattersFromSettings(settings) { formatters.set("green", new DisabledFormatter()); } +function moveImagesToEndFlex(htmlString) { + const container = document.createElement("div"); + container.innerHTML = htmlString; + + const extractedImages = []; + + for (const img of Array.from(container.querySelectorAll("img"))) { + const prevEl = img.previousElementSibling; + + if (prevEl && prevEl.tagName === "BR") { + prevEl.remove(); + img.remove(); + extractedImages.push(img); + } + } + + if (extractedImages.length) { + const flexRow = document.createElement("div"); + flexRow.style.display = "flex"; + flexRow.style.flexWrap = "wrap"; + flexRow.style.gap = "8px"; + + for (const img of extractedImages) { + flexRow.appendChild(img); + } + + container.appendChild(flexRow); + } + + return container.innerHTML; +} + function buildMessageTxt(chat, message) { // TODO we strip off the `/me ` of every message -- must be a better way to do this let msg = @@ -79,6 +111,9 @@ function buildMessageTxt(chat, message) { } fullMsg += msgArray[i].value; } + if(chat.settings.get("in-chat-image-preview")) { + fullMsg = moveImagesToEndFlex(fullMsg); + } fullMsg = fullMsg.replace(/\\`/g, "`"); return `${fullMsg}`; } diff --git a/assets/chat/js/settings.js b/assets/chat/js/settings.js index a8ac72af..77a4f436 100644 --- a/assets/chat/js/settings.js +++ b/assets/chat/js/settings.js @@ -40,6 +40,8 @@ function upgradeSettings(chat, oldversion, newversion) { chat.settings.set("notificationsoundfile", arr); chat.settings.set("holidayemotemodifiers", arr); chat.settings.set("formatter-combo", arr); + chat.settings.set("image-modal-preview", arr); + chat.settings.set("in-chat-image-preview", arr); arr = chat.settings.get("notificationtimeout"); chat.settings.set("notificationtimeout", arr !== -1); diff --git a/assets/dev/dev-chat/settings.json b/assets/dev/dev-chat/settings.json index 0dcd5fd5..5e5bf668 100644 --- a/assets/dev/dev-chat/settings.json +++ b/assets/dev/dev-chat/settings.json @@ -43,5 +43,7 @@ ["formatter-green", true], ["formatter-emote", true], ["formatter-combo", true], + ["image-modal-preview", true], + ["in-chat-image-preview", true], ["holidayemotemodifiers", true] ] diff --git a/assets/index.html b/assets/index.html index 6d383b86..93a0ca08 100644 --- a/assets/index.html +++ b/assets/index.html @@ -12,6 +12,27 @@
+
+
+ +
+
+ + + + +
+ + +
+
@@ -143,6 +164,16 @@

Messages

Shorten links
+
+ +
+
+ +