@use "../../../css/colors" as *; @use "../../../css/material" as *; @use "sass:color"; .message { $status-indicator-size: 16px; margin-bottom: 10px; max-width: 70%; position: relative; width: fit-content; display: flex; align-items: flex-start; gap: 8px; .messageInner { border-radius: 20px 20px 8px 8px; // Top corners rounded, bottom corners sharper position: relative; word-wrap: break-word; overflow-wrap: anywhere; word-break: break-word; width: fit-content; max-width: 100%; display: inline-block; .messageUsername { font-weight: 600; margin-bottom: 0.3rem; font-size: 0.9rem; margin: 10px; cursor: pointer; transition: transform 0.2s ease; display: flex; align-items: center; gap: 4px; width: fit-content; &:hover { transform: scale(1.05); } } .messageContent { word-wrap: break-word; margin: 10px 10px 0 10px; white-space: pre-wrap; > p:first-child { margin-block-start: 0; } > p:last-child { margin-block-end: 0; } } :global(.quote).replyPreview { user-select: none; margin: 5px; border-radius: 16px; } .messageAttachments { padding: 5px 0 0 0; overflow: hidden; .attachment { a { text-decoration: none; } .attachementImage { max-width: 200px; border-radius: 8px; cursor: pointer; margin-left: 3px; margin-right: 3px; margin-bottom: 3px; &:last-child { margin-bottom: 0; } &.loading { filter: blur(10px); transition: filter 200ms ease; } } .attachementImage.placeholder { background: $color-dark-surface-container-highest; pointer-events: none; } .imageWrapper { position: relative; display: inline-block; } .loadingOverlay { position: absolute; inset: 0; display: flex; align-items: center; justify-content: center; background: rgba(0, 0, 0, 0.08); backdrop-filter: blur(6px); border-radius: 8px; } .preloadImage { position: absolute; width: 0; height: 0; opacity: 0; pointer-events: none; } .withIconGap { display: inline-flex; align-items: center; gap: 8px; } } } .messageTime { font-size: 0.7rem; color: $color-dark-on-surface-variant; margin-top: 0.3rem; text-align: right; user-select: none; margin: 4px 8px 8px 8px; display: flex; align-items: center; justify-content: flex-end; gap: 4px; .messageStatusIndicator { display: flex; align-items: center; width: $status-indicator-size; height: $status-indicator-size; .errorIcon, .successIcon { font-size: $status-indicator-size; width: $status-indicator-size; height: $status-indicator-size; } mdui-circular-progress { width: $status-indicator-size; height: $status-indicator-size; } } } } &.received { .messageProfilePic { width: 40px; height: 40px; flex-shrink: 0; cursor: pointer; transition: transform 0.2s ease; align-self: flex-end; &:hover { transform: scale(1.05); } img { width: 100%; height: 100%; border-radius: 50%; object-fit: cover; border: 2px solid $color-dark-outline; } } .messageInner { background: $color-dark-surface-container; color: $color-dark-on-surface; border-radius: 20px 20px 20px 8px; // Top-left: 5px, top-right: 20px, bottom: 8px box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1); border: 1px solid rgba($color-dark-outline-variant, 0.4); position: relative; overflow: hidden; &::before { content: ''; position: absolute; top: 0; left: 0; right: 0; bottom: 0; background: linear-gradient(135deg, rgba(147, 51, 234, 0.05), rgba(99, 102, 241, 0.03)); pointer-events: none; z-index: 0; } > * { position: relative; z-index: 1; } } .messageTime { color: $color-dark-on-surface-variant; font-weight: 500; } } &.sent { margin-left: auto; flex-direction: row-reverse; :global(.quote).replyPreview { background: linear-gradient(135deg, rgba(255, 255, 255, 0.15), rgba(255, 255, 255, 0.08)); border: 1px solid rgba(255, 255, 255, 0.2); position: relative; overflow: hidden; box-shadow: 0 2px 8px rgba(147, 51, 234, 0.5); :global(.quote-inner) { position: relative; z-index: 1; } } .messageInner { background: linear-gradient(135deg, #9333EA, #6366F1, #2f68c5); border-radius: 20px 20px 8px 20px; // Top-left: 20px, top-right: 5px, bottom: 8px box-shadow: 0 0 20px rgba($color-dark-primary, 0.4); border: 1px solid rgba($color-dark-primary, 0.5); position: relative; overflow: hidden; > * { position: relative; z-index: 1; } } &.emojiMessage { .messageInner { align-items: flex-end; display: flex; flex-direction: column; .messageContent { &.emojiContent { text-align: right; } } } } .messageTime { font-weight: 500; } } // Emoji message styles &.emojiMessage { .messageInner { background: transparent; border: none; box-shadow: none; padding: 0; border-radius: 0; &::before { display: none; } } .messageContent { margin: 0; padding: 0; text-align: right; &.emojiContent { font-size: 2rem; line-height: 1.2; } &.singleEmojiContent { font-size: 4rem; line-height: 1; margin-bottom: 8px; } } .messageTime { background: rgba(0, 0, 0, 0.3); border-radius: 12px; padding: 4px 8px; margin-top: 8px; margin-right: 0; font-size: 0.75rem; color: rgba(255, 255, 255, 0.7); backdrop-filter: blur(10px); display: flex; align-items: center; justify-content: flex-end; gap: 4px; user-select: none; width: fit-content; } } } .messageUsername { &.loading { opacity: 0.6; cursor: default; } } // Fullscreen Image Viewer .fullscreenImageOverlay { position: fixed; inset: 0; width: 100vw; height: 100vh; background: rgba(0, 0, 0, 0.6); backdrop-filter: blur(20px); z-index: 9999; opacity: 1; transition: opacity 0.3s ease; &.closing { opacity: 0; } .fullscreenAnimatedImage { position: absolute; object-fit: contain; border-radius: 12px; box-shadow: 0 20px 40px rgba(0, 0, 0, 0.4); transition: left 0.3s ease, top 0.3s ease, width 0.3s ease, height 0.3s ease; } .fullscreenControls { position: absolute; display: flex; gap: 8px; &.topRight { top: 12px; right: 12px; } } .progressWrapper { width: 40px; height: 40px; display: flex; align-items: center; justify-content: center; } } // Mention link styling .messageContent { .mentionLink { color: $color-dark-primary; text-decoration: none; font-weight: 500; border-radius: 4px; padding: 2px 4px; transition: all 0.2s ease; background-color: rgba(145, 206, 244, 0.1); // TODO adjust &:hover { background-color: rgba(145, 206, 244, 0.2); // TODO adjust transform: translateY(-1px); } &:active { transform: translateY(0); } } } // Reaction styles .messageReactions { display: flex; flex-wrap: wrap; gap: 4px; margin-top: 8px; margin-left: 10px; margin-right: 10px; animation: messageReactionsFadeIn 0.3s cubic-bezier(0.34, 1.56, 0.64, 1); } .reactionButton { display: flex; align-items: center; gap: 8px; padding: 8px 12px; border: none; border-radius: 16px; background-color: $color-dark-surface-container; cursor: pointer; transition: transform 0.2s ease, background-color 0.2s ease; font-size: 1px; min-height: 28px; animation: reactionFadeIn 0.3s cubic-bezier(0.34, 1.56, 0.64, 1); &.removing { animation: reactionFadeOut 0.2s ease forwards; } &:hover { background-color: $color-dark-surface-container-high; transform: scale(1.05); } &.reacted { background-color: $color-dark-primary-container; border-color: $color-dark-primary; color: $color-dark-on-primary-container; &:hover { background-color: color.adjust($color-dark-primary-container, $lightness: 20%); } } } .reactionEmoji { font-size: 17px; line-height: 1; } .reactionCount { font-size: 12px; font-weight: 500; line-height: 1; } // Animation for reactions appearing/disappearing @keyframes messageReactionsFadeIn { from { opacity: 0; transform: translateY(-10px); } to { opacity: 1; transform: translateY(0); } } @keyframes reactionFadeIn { from { opacity: 0; transform: scale(0.8); } to { opacity: 1; transform: scale(1); } } @keyframes reactionFadeOut { from { opacity: 1; transform: scale(1); } to { opacity: 0; transform: scale(0.8); } }