2022-12-09 10:13:09 +01:00
|
|
|
.message_row {
|
2023-05-22 18:17:52 +02:00
|
|
|
display: grid;
|
2023-07-20 19:57:31 +02:00
|
|
|
/* Prevent the messagebox column from overflowing the 1fr
|
|
|
|
space allotted by specifying `minmax(0,1fr)`, which
|
|
|
|
sets 0 as the minimum size, not the grid default of
|
|
|
|
`auto`. */
|
|
|
|
grid-template: auto auto / 2px minmax(0, 1fr);
|
2023-07-13 22:00:36 +02:00
|
|
|
grid-template-areas:
|
|
|
|
"date_unread_marker date_row "
|
|
|
|
"message_unread_marker messagebox";
|
|
|
|
|
2023-05-22 18:17:52 +02:00
|
|
|
border-left: 1px solid var(--color-message-list-border);
|
|
|
|
border-right: 1px solid var(--color-message-list-border);
|
|
|
|
background-color: var(--color-background-stream-message-content);
|
|
|
|
|
2024-04-29 23:04:18 +02:00
|
|
|
&.private-message {
|
|
|
|
background-color: var(--color-background-private-message-content);
|
|
|
|
|
|
|
|
.date_row {
|
|
|
|
background-color: var(--color-background-private-message-content);
|
|
|
|
}
|
|
|
|
|
|
|
|
.data-container::after {
|
|
|
|
background: linear-gradient(
|
|
|
|
0deg,
|
|
|
|
var(--color-background-private-message-content),
|
|
|
|
transparent 100%
|
|
|
|
);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-05-22 18:17:52 +02:00
|
|
|
&.direct_mention {
|
|
|
|
background-color: var(--color-background-direct-mention);
|
2024-03-30 20:04:12 +01:00
|
|
|
|
|
|
|
.message_embed .data-container::after {
|
|
|
|
background: linear-gradient(
|
|
|
|
0deg,
|
|
|
|
var(--color-background-direct-mention),
|
|
|
|
transparent 100%
|
|
|
|
);
|
|
|
|
}
|
2023-05-22 18:17:52 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
&.group_mention {
|
|
|
|
background-color: var(--color-background-group-mention);
|
2024-03-30 20:04:12 +01:00
|
|
|
|
|
|
|
.message_embed .data-container::after {
|
|
|
|
background: linear-gradient(
|
|
|
|
0deg,
|
|
|
|
var(--color-background-group-mention),
|
|
|
|
transparent 100%
|
|
|
|
);
|
|
|
|
}
|
2023-05-22 18:17:52 +02:00
|
|
|
}
|
|
|
|
|
2024-04-25 19:50:22 +02:00
|
|
|
&.sender_info_hovered {
|
|
|
|
.sender_name {
|
|
|
|
cursor: pointer;
|
|
|
|
/* TODO: Refactor the teetering nested classes
|
|
|
|
above so that !important can be removed. */
|
2024-04-25 19:57:03 +02:00
|
|
|
color: var(--color-text-sender-name-hover) !important;
|
2024-04-25 19:50:22 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
.message-avatar {
|
|
|
|
cursor: pointer;
|
|
|
|
}
|
|
|
|
}
|
2022-12-09 10:13:09 +01:00
|
|
|
}
|
2023-05-22 18:28:52 +02:00
|
|
|
|
2024-04-30 23:22:17 +02:00
|
|
|
.messagebox {
|
|
|
|
grid-area: messagebox;
|
|
|
|
word-wrap: break-word;
|
|
|
|
cursor: pointer;
|
|
|
|
border: none;
|
|
|
|
/* The left padding value accounts for a 2px
|
|
|
|
unread marker, ensuring a uniform 5px of
|
|
|
|
padding on either side of the message box. */
|
|
|
|
padding: 0 5px 0 3px;
|
|
|
|
|
2024-09-11 05:31:26 +02:00
|
|
|
&:hover .message_controls {
|
2024-04-30 23:22:17 +02:00
|
|
|
.empty-star:hover {
|
|
|
|
cursor: pointer;
|
|
|
|
}
|
|
|
|
|
2024-07-29 22:09:41 +02:00
|
|
|
> .message_control_button {
|
2024-04-30 23:22:17 +02:00
|
|
|
opacity: 1;
|
|
|
|
visibility: visible;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-04-30 23:31:23 +02:00
|
|
|
.messagebox-content {
|
|
|
|
display: grid;
|
|
|
|
align-items: baseline;
|
|
|
|
padding-left: 10px;
|
|
|
|
/* Prevent the message column from overflowing the 1fr
|
|
|
|
space allotted by specifying `minmax(0,1fr)`, which
|
|
|
|
sets 0 as the minimum size, not the grid default of
|
|
|
|
`auto`.
|
|
|
|
|
|
|
|
The calculated `--message-box-timestamp-column-width`
|
|
|
|
should match `max-content` exactly, but `max-content`
|
|
|
|
ensures the timestamp will always have enough space
|
|
|
|
in the column. */
|
|
|
|
grid-template:
|
2024-06-25 21:58:49 +02:00
|
|
|
var(--message-box-sender-line-height) repeat(3, auto) /
|
2024-04-30 23:31:23 +02:00
|
|
|
var(--message-box-avatar-column-width) minmax(0, 1fr) calc(
|
|
|
|
3 * var(--message-box-icon-width)
|
|
|
|
)
|
|
|
|
8px minmax(var(--message-box-timestamp-column-width), max-content);
|
|
|
|
/* Named grid areas provide flexibility for positioning grid items
|
|
|
|
reliably, even if the row or column definitions of the grid change. */
|
|
|
|
grid-template-areas:
|
|
|
|
"edited message controls . time"
|
|
|
|
". message . . . "
|
|
|
|
". more . . . "
|
|
|
|
". reactions . . . ";
|
|
|
|
|
|
|
|
&.content_edit_mode {
|
|
|
|
cursor: default;
|
|
|
|
/* Set the controls area to 0 to give more space
|
|
|
|
to the edit/source view area. */
|
|
|
|
grid-template-columns:
|
|
|
|
var(--message-box-avatar-column-width) minmax(0, 1fr)
|
|
|
|
0 8px minmax(
|
|
|
|
var(--message-box-timestamp-column-width),
|
|
|
|
max-content
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
@media (width < $sm_min), ((width >= $md_min) and (width < $mc_min)) {
|
|
|
|
grid-template-columns:
|
|
|
|
var(--message-box-avatar-column-width) minmax(0, 1fr) calc(
|
|
|
|
2 * var(--message-box-icon-width)
|
|
|
|
)
|
|
|
|
8px minmax(var(--message-box-timestamp-column-width), max-content);
|
|
|
|
}
|
|
|
|
|
|
|
|
.message_controls {
|
|
|
|
grid-area: controls;
|
|
|
|
|
|
|
|
@media (width < $sm_min), ((width >= $md_min) and (width < $mc_min)) {
|
|
|
|
/* This is intended to target the first message_controls child
|
2024-09-11 05:31:26 +02:00
|
|
|
when there are 3 displayed. */
|
|
|
|
.message_control_button:nth-last-child(3) {
|
2024-04-30 23:31:23 +02:00
|
|
|
display: none;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
.message_edit_notice {
|
|
|
|
grid-area: edited;
|
|
|
|
}
|
|
|
|
|
|
|
|
.slow-send-spinner {
|
|
|
|
display: none;
|
|
|
|
justify-self: end;
|
|
|
|
margin-right: 10px;
|
|
|
|
text-align: end;
|
|
|
|
grid-area: time;
|
|
|
|
}
|
|
|
|
|
|
|
|
.message_content {
|
|
|
|
grid-area: message;
|
|
|
|
/*
|
|
|
|
Space between two single line messages is kept in
|
|
|
|
lockstep with adjacent Markdown elements.
|
|
|
|
*/
|
|
|
|
padding: var(--message-box-markdown-aligned-vertical-space) 0 0;
|
|
|
|
color: var(--color-text-message-default);
|
2024-06-07 18:15:41 +02:00
|
|
|
/* We explicitly set line-height here so that
|
|
|
|
the message area is not beholden to the legacy
|
|
|
|
`max()` declaration on `body`. */
|
2024-04-30 23:31:23 +02:00
|
|
|
line-height: var(--base-line-height-unitless);
|
|
|
|
min-height: 17px;
|
|
|
|
display: block;
|
|
|
|
position: relative;
|
|
|
|
overflow: hidden;
|
|
|
|
|
|
|
|
&:empty {
|
|
|
|
display: none;
|
|
|
|
}
|
|
|
|
|
|
|
|
&.condensed {
|
|
|
|
max-height: 8.5em;
|
|
|
|
min-height: 0;
|
|
|
|
overflow: hidden;
|
|
|
|
mask-image: linear-gradient(
|
|
|
|
to top,
|
|
|
|
hsl(0deg 0% 100% / 0%) 0%,
|
|
|
|
hsl(0deg 0% 100%) 60px
|
|
|
|
);
|
|
|
|
mask-size: cover;
|
|
|
|
}
|
|
|
|
|
|
|
|
&.collapsed {
|
|
|
|
padding: 0;
|
|
|
|
max-height: 0;
|
|
|
|
min-height: 0;
|
|
|
|
overflow: hidden;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
.message_reactions {
|
|
|
|
grid-area: reactions;
|
|
|
|
display: flex;
|
|
|
|
/* Allow reactions to wrap in mobile viewports */
|
|
|
|
flex-wrap: wrap;
|
|
|
|
/* Keep reactions aligned to start (top), so that the
|
|
|
|
margin on the reaction button doesn't appear to
|
|
|
|
stretch the reactions taller. */
|
|
|
|
align-items: flex-start;
|
|
|
|
/* Control reaction spacing with a gap */
|
|
|
|
gap: 4px;
|
|
|
|
}
|
|
|
|
|
|
|
|
.message_edit {
|
|
|
|
grid-area: message;
|
|
|
|
/* Align self to start, rather than baseline, so the baseline
|
|
|
|
is preserved from the message itself--keeping the time,
|
|
|
|
edit message, and controls at the same vertical alignment. */
|
|
|
|
align-self: start;
|
|
|
|
margin-top: var(--message-box-vertical-margin);
|
|
|
|
}
|
|
|
|
|
|
|
|
.message_length_controller {
|
|
|
|
grid-area: more;
|
|
|
|
}
|
|
|
|
|
|
|
|
.collapsed ~ .message_length_controller {
|
|
|
|
/* When content is collapsed, the length controller
|
|
|
|
should occupy the space ordinarily assigned to
|
|
|
|
the message. */
|
|
|
|
grid-area: message;
|
|
|
|
/* However, don't let the SHOW MORE button participate
|
|
|
|
in the baseline group. */
|
|
|
|
align-self: start;
|
|
|
|
|
|
|
|
.message_length_toggle {
|
|
|
|
/* Ensure that a collapsed message maintains the
|
|
|
|
same space around the toggle button as any other
|
|
|
|
message-row content. */
|
|
|
|
margin: 4px 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
&.content_edit_mode .message_length_controller {
|
|
|
|
/* If entering edit mode on a collapsed message,
|
|
|
|
just hide the controller area. This preserves
|
|
|
|
the collapsed state of the message, which need
|
|
|
|
not be touched. We just need to hide the button.
|
|
|
|
This works for condensed messages, too. */
|
|
|
|
display: none;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-05-03 17:06:55 +02:00
|
|
|
.messagebox-includes-sender {
|
2024-04-30 23:31:23 +02:00
|
|
|
.messagebox-content {
|
|
|
|
grid-template-areas:
|
|
|
|
"avatar sender controls . time"
|
|
|
|
"avatar message . . . "
|
|
|
|
". more . . . "
|
|
|
|
". reactions . . . ";
|
|
|
|
|
|
|
|
.message_edit {
|
|
|
|
/* No top margin when there's a sender row */
|
|
|
|
margin-top: 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
&.is-me-message {
|
|
|
|
grid-template-areas:
|
|
|
|
"avatar sender controls . time"
|
|
|
|
"avatar sender . . . "
|
|
|
|
". more . . . "
|
|
|
|
". reactions . . . ";
|
|
|
|
|
|
|
|
.message-avatar {
|
|
|
|
/* Set the line-height to match the height of the avatar image
|
|
|
|
to center me-messages within the baseline group. */
|
|
|
|
line-height: var(--message-box-avatar-height);
|
|
|
|
align-self: baseline;
|
2024-06-28 22:16:58 +02:00
|
|
|
/* Because the avatar may be the tallest element in a
|
|
|
|
single-line me message, this margin preserves the
|
|
|
|
overall height of the message box. */
|
|
|
|
margin-bottom: var(--message-box-vertical-margin);
|
2024-04-30 23:31:23 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
.message_sender {
|
|
|
|
/* Don't display message sender as flexbox for me-messages. */
|
|
|
|
display: block;
|
|
|
|
/* Set the same line-height as on message content for
|
|
|
|
me-messages. */
|
|
|
|
line-height: var(--base-line-height-unitless);
|
|
|
|
/* Ensure the same spacing below messages as for any other
|
|
|
|
paragraph. */
|
|
|
|
padding-bottom: var(
|
|
|
|
--message-box-markdown-aligned-vertical-space
|
|
|
|
);
|
|
|
|
|
|
|
|
/* Display message components inline, with wrapping white-space,
|
|
|
|
so the sender name and message display as a continuous line
|
|
|
|
of wrapping text. */
|
|
|
|
.sender_name {
|
|
|
|
white-space: normal;
|
|
|
|
display: inline;
|
|
|
|
}
|
|
|
|
|
|
|
|
.sender_name_text {
|
|
|
|
max-width: 100%;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
&.content_edit_mode {
|
|
|
|
.message_sender {
|
|
|
|
/* Keep the me-message participating in the baseline */
|
|
|
|
visibility: hidden;
|
|
|
|
}
|
|
|
|
|
|
|
|
.message_edit {
|
|
|
|
/* Use the sender grid area for the me-message edit/view-source box */
|
|
|
|
grid-area: sender;
|
|
|
|
margin-top: var(--message-box-vertical-margin);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
.message-avatar {
|
|
|
|
grid-area: avatar;
|
|
|
|
/* The picture should not participate in the baseline group. */
|
|
|
|
align-self: start;
|
2024-06-28 22:16:58 +02:00
|
|
|
margin-top: var(--message-box-vertical-margin);
|
2024-04-30 23:31:23 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
.status-message {
|
|
|
|
font-weight: normal;
|
|
|
|
}
|
|
|
|
|
|
|
|
.message_content {
|
2024-06-25 21:58:49 +02:00
|
|
|
/* Pull message content up closer to sender to
|
|
|
|
let the text baseline sit adjacent the bottom
|
2024-07-05 16:10:05 +02:00
|
|
|
of the avatar. We also need to account for the
|
|
|
|
padding atop .message_content. */
|
2024-06-25 21:58:49 +02:00
|
|
|
margin-top: calc(
|
2024-07-05 16:10:05 +02:00
|
|
|
(var(--message-box-markdown-aligned-vertical-space) * 0.5 * -1) -
|
|
|
|
var(--message-box-markdown-aligned-vertical-space)
|
2024-06-25 21:58:49 +02:00
|
|
|
);
|
2024-04-30 23:31:23 +02:00
|
|
|
grid-area: message;
|
|
|
|
}
|
|
|
|
|
|
|
|
.slow-send-spinner {
|
|
|
|
align-self: center;
|
|
|
|
position: unset;
|
|
|
|
margin-top: 1px;
|
|
|
|
}
|
|
|
|
|
|
|
|
.message_edit_notice {
|
|
|
|
/* When the edit notice is inline, as on edited me-messages,
|
|
|
|
the inline-block and accompanying vertical-align styles will
|
|
|
|
apply */
|
|
|
|
display: inline-block;
|
|
|
|
vertical-align: baseline;
|
|
|
|
/* A bit of margin here helps these not look associated with the name. */
|
|
|
|
margin-left: 4px;
|
2024-07-23 17:48:48 +02:00
|
|
|
/* Unset the padding used on edited notices under the avatar. */
|
|
|
|
padding-right: 0;
|
2024-04-30 23:31:23 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
.message_sender {
|
|
|
|
overflow: hidden;
|
|
|
|
text-overflow: ellipsis;
|
|
|
|
grid-area: sender;
|
|
|
|
display: flex;
|
|
|
|
/* A generous line-height on the sender name is necessary
|
|
|
|
for internationalization and non-Western Latin character
|
|
|
|
sets. */
|
|
|
|
line-height: var(--message-box-sender-line-height);
|
|
|
|
/* Ensure flexed sender info (name, status emoji, inline EDITED)
|
|
|
|
forms a baseline group, which will participate with the
|
|
|
|
message-box grid's baseline group, too. */
|
|
|
|
align-items: baseline;
|
|
|
|
|
|
|
|
.zulip-icon.zulip-icon-bot {
|
|
|
|
align-self: center;
|
2024-09-19 21:37:01 +02:00
|
|
|
margin-left: 5px;
|
2024-04-30 23:31:23 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
.sender_name {
|
|
|
|
display: inline-flex;
|
|
|
|
font-weight: 700;
|
|
|
|
color: var(--color-text-sender-name);
|
|
|
|
column-gap: 3px;
|
|
|
|
overflow: hidden;
|
|
|
|
text-overflow: ellipsis;
|
|
|
|
white-space: nowrap;
|
|
|
|
outline: none;
|
|
|
|
align-self: baseline;
|
|
|
|
|
|
|
|
.sender_name_text {
|
|
|
|
overflow: hidden;
|
|
|
|
white-space: nowrap;
|
|
|
|
display: inline-flex;
|
|
|
|
|
|
|
|
.user-name {
|
|
|
|
overflow: hidden;
|
|
|
|
text-overflow: ellipsis;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2024-09-10 22:19:15 +02:00
|
|
|
|
|
|
|
.collapsed ~ .message_length_controller .message_length_toggle {
|
|
|
|
/* Collapse top margin to avoid extra space
|
|
|
|
between the button and sender line. */
|
|
|
|
margin-top: 0;
|
|
|
|
}
|
2024-04-30 23:31:23 +02:00
|
|
|
}
|
|
|
|
|
2024-07-29 22:01:28 +02:00
|
|
|
.message_controls {
|
|
|
|
display: flex;
|
|
|
|
align-items: baseline;
|
|
|
|
font-size: 16px;
|
|
|
|
/* This is a bit tricky; we need to reserve space for the message
|
|
|
|
controls even when the message isn't hovered, so that hover
|
|
|
|
doesn't disturb the layout. Usually that would be just
|
|
|
|
visibility: hidden, but that cannot be animated, so we set
|
|
|
|
opacity as well, which can be animated. */
|
|
|
|
.message_control_button {
|
|
|
|
opacity: 0;
|
|
|
|
visibility: hidden;
|
|
|
|
transition: all 0.2s ease;
|
|
|
|
width: var(--message-box-icon-width);
|
|
|
|
height: var(--message-box-icon-height);
|
|
|
|
text-align: center;
|
|
|
|
color: var(--color-message-action-visible);
|
|
|
|
|
2024-07-29 22:07:01 +02:00
|
|
|
& .message-controls-icon {
|
2024-07-29 22:01:28 +02:00
|
|
|
vertical-align: middle;
|
|
|
|
/* TODO: Math for these values, possibly with variables.
|
|
|
|
In short, the icon body is 16px square; the current
|
|
|
|
area for the icon is 26px wide by 25px tall, so these
|
|
|
|
values ensure a 26px x 25px clickable area for the icon. */
|
|
|
|
padding: 2.5px 3px;
|
|
|
|
|
|
|
|
&::before {
|
|
|
|
/* We specify block display so the
|
|
|
|
scaling transform below works as
|
|
|
|
expected. */
|
|
|
|
display: block;
|
|
|
|
}
|
|
|
|
|
|
|
|
&:active::before {
|
|
|
|
transform: scale(0.92);
|
|
|
|
transform-origin: center;
|
|
|
|
outline: 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
&:focus {
|
|
|
|
/* Remove the outline but do not color on focus;
|
|
|
|
focus-visible is more appropriate for the color
|
|
|
|
changes, as it only applies color when focus
|
|
|
|
is achieved from a keyboard or other pointerless
|
|
|
|
device. */
|
|
|
|
outline: 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
&:hover,
|
|
|
|
&:focus-visible {
|
|
|
|
outline: 0;
|
|
|
|
color: var(--color-message-action-interactive);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Separate hover colors for stars */
|
|
|
|
&.star:hover,
|
|
|
|
&.star:focus-visible {
|
|
|
|
color: var(--color-message-star-action);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
.zulip-icon-more-vertical {
|
|
|
|
/* Increase visual prominence of the vdots. */
|
|
|
|
font-size: 21px;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Tooltips should not follow the width restrictions of their parent element. */
|
|
|
|
[data-tippy-root] {
|
|
|
|
width: max-content;
|
|
|
|
word-wrap: unset;
|
|
|
|
}
|
|
|
|
|
|
|
|
.edit_content {
|
|
|
|
/* Icons for editing content are determined on message hover;
|
|
|
|
we set an empty `.edit_content` to have 0 height in order to
|
|
|
|
preserve the layout of the other icons prior to any hovering. */
|
|
|
|
&:empty {
|
|
|
|
height: 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
&:hover {
|
|
|
|
cursor: pointer;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-09-11 05:31:26 +02:00
|
|
|
.failed_message_action {
|
|
|
|
color: var(--color-failed-message-send-icon);
|
|
|
|
font-weight: bold;
|
|
|
|
padding: 1px;
|
|
|
|
opacity: 1;
|
|
|
|
visibility: visible;
|
2024-07-29 22:01:28 +02:00
|
|
|
|
|
|
|
.rotating {
|
|
|
|
animation: rotate 1s infinite linear;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
.star_container {
|
|
|
|
&:not(.empty-star) {
|
|
|
|
/* Color, opacity, and visibility, as though the message is hovered. */
|
|
|
|
color: var(--color-message-star-action);
|
|
|
|
opacity: 1;
|
|
|
|
visibility: visible !important;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-04-30 18:08:23 +02:00
|
|
|
.unread_marker {
|
|
|
|
margin-left: var(--unread-marker-left);
|
|
|
|
opacity: 0;
|
|
|
|
transition: all 0.3s ease-out;
|
|
|
|
|
|
|
|
&.slow_fade {
|
|
|
|
transition: all 2s ease-out;
|
|
|
|
}
|
|
|
|
|
|
|
|
&.fast_fade {
|
|
|
|
transition: all 0.3s ease-out;
|
|
|
|
}
|
|
|
|
|
|
|
|
&.date_unread_marker {
|
|
|
|
grid-area: date_unread_marker;
|
|
|
|
|
|
|
|
.unread-marker-fill {
|
|
|
|
border-radius: 0 !important;
|
|
|
|
height: 100% !important;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
&.message_unread_marker {
|
|
|
|
grid-area: message_unread_marker;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
.unread-marker-fill {
|
|
|
|
height: 100%;
|
|
|
|
width: 2px;
|
|
|
|
background: linear-gradient(
|
|
|
|
90deg,
|
|
|
|
var(--color-unread-marker) 30%,
|
|
|
|
hsl(217deg 64% 59% / 0%)
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
.unread .unread_marker {
|
|
|
|
transition: all 0.3s ease-out;
|
|
|
|
opacity: 1;
|
|
|
|
}
|
|
|
|
|
2024-03-28 20:55:28 +01:00
|
|
|
.message-time {
|
|
|
|
justify-self: end;
|
|
|
|
padding-right: 5px;
|
|
|
|
/* Maintain first-line baseline regardless of
|
|
|
|
what happens in the message-content area (e.g., a
|
|
|
|
collapsed message, or source/edit view). This
|
|
|
|
line-height also keeps EDITED/MOVED messages
|
|
|
|
in place, care of their baseline-group participation
|
2024-04-19 22:34:23 +02:00
|
|
|
within the grid. */
|
|
|
|
line-height: var(--message-box-sender-line-height);
|
2024-03-28 20:55:28 +01:00
|
|
|
grid-area: time;
|
|
|
|
display: block;
|
2024-06-18 16:13:07 +02:00
|
|
|
/* 13px at 14px/1em */
|
|
|
|
font-size: 0.9286em;
|
2024-03-28 20:55:28 +01:00
|
|
|
font-weight: 350;
|
|
|
|
text-align: end;
|
|
|
|
opacity: 0.8;
|
|
|
|
color: var(--color-text-default);
|
|
|
|
letter-spacing: 0.02em;
|
|
|
|
/* Disable blue link styling for the message timestamp link. */
|
|
|
|
&:hover {
|
|
|
|
text-decoration: none;
|
|
|
|
color: var(--color-message-action-interactive);
|
|
|
|
}
|
|
|
|
|
|
|
|
&.notvisible {
|
|
|
|
/* This happens when message failed to send. We don't want to
|
|
|
|
display time but still want it to occupy space. */
|
|
|
|
width: 45px !important;
|
|
|
|
position: unset !important;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-04-30 23:41:25 +02:00
|
|
|
/* Message-editing styles */
|
|
|
|
.message-edit-buttons-and-timer {
|
|
|
|
margin-top: 5px;
|
|
|
|
display: flex;
|
|
|
|
gap: 5px;
|
|
|
|
/* Allow items to occupy full height.
|
|
|
|
This is especially important for
|
|
|
|
buttons that are flex items. */
|
|
|
|
align-items: stretch;
|
|
|
|
}
|
|
|
|
|
|
|
|
.message-actions-button {
|
|
|
|
box-sizing: border-box;
|
|
|
|
/* Display the actions buttons as
|
|
|
|
flex containers for positioning
|
|
|
|
text and spinners. */
|
|
|
|
display: flex;
|
|
|
|
align-items: center;
|
|
|
|
justify-content: center;
|
|
|
|
height: 28px;
|
|
|
|
padding: 0 10px;
|
|
|
|
border-radius: 4px;
|
|
|
|
border: 0;
|
|
|
|
line-height: 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
.message_edit_save {
|
|
|
|
/* Match Save button's basic colors to
|
|
|
|
the compose box Send button. */
|
|
|
|
color: var(--color-compose-send-button-icon-color);
|
|
|
|
background-color: var(--color-compose-send-button-background);
|
|
|
|
|
|
|
|
&:hover {
|
|
|
|
background-color: var(
|
|
|
|
--color-compose-send-button-background-interactive
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
&:disabled {
|
2024-09-11 20:46:53 +02:00
|
|
|
/* Replicate disabled values, without any color shifts. */
|
2024-04-30 23:41:25 +02:00
|
|
|
cursor: not-allowed;
|
|
|
|
opacity: 0.5;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
.message_edit_cancel,
|
|
|
|
.message_edit_close {
|
|
|
|
color: var(--color-exit-button-text);
|
|
|
|
background: var(--color-exit-button-background);
|
|
|
|
|
|
|
|
&:hover {
|
|
|
|
background: var(--color-exit-button-background-interactive);
|
|
|
|
}
|
|
|
|
}
|
2024-01-11 17:00:01 +01:00
|
|
|
|
2024-05-18 10:30:24 +02:00
|
|
|
.edit-content-container {
|
2024-08-20 16:16:22 +02:00
|
|
|
position: relative;
|
2024-05-18 10:30:24 +02:00
|
|
|
border-radius: 4px;
|
|
|
|
border: 1px solid var(--color-message-content-container-border);
|
|
|
|
transition: border 0.2s ease;
|
|
|
|
|
|
|
|
&:has(.message_edit_content:focus) {
|
|
|
|
border-color: var(--color-message-content-container-border-focus);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-01-11 17:00:01 +01:00
|
|
|
.message_edit_content {
|
2024-07-30 22:03:41 +02:00
|
|
|
max-height: var(--max-message-edit-height);
|
2024-04-24 20:00:12 +02:00
|
|
|
width: 100%;
|
|
|
|
min-width: 206px;
|
2024-05-18 10:30:24 +02:00
|
|
|
min-height: 52px;
|
2024-04-24 20:00:12 +02:00
|
|
|
box-sizing: border-box;
|
|
|
|
/* Setting resize as none hides the bottom right diagonal box
|
|
|
|
(which even has a background color of its own!). */
|
|
|
|
resize: none !important;
|
2024-07-16 20:36:18 +02:00
|
|
|
color: var(--color-text-default);
|
2024-04-24 20:00:12 +02:00
|
|
|
background-color: hsl(0deg 0% 100%);
|
2024-05-18 10:30:24 +02:00
|
|
|
border-radius: 3px;
|
2024-04-24 20:00:12 +02:00
|
|
|
vertical-align: middle;
|
2024-05-18 10:30:24 +02:00
|
|
|
border: none;
|
2024-04-24 20:06:18 +02:00
|
|
|
/* Match textarea padding to compose box and
|
|
|
|
message-edit preview area. */
|
2024-07-30 17:49:21 +02:00
|
|
|
padding: 5px 5px 0;
|
2024-05-18 10:30:24 +02:00
|
|
|
margin: 0;
|
2024-04-24 20:00:12 +02:00
|
|
|
|
2024-05-18 10:30:24 +02:00
|
|
|
box-shadow: none;
|
2024-04-24 20:00:12 +02:00
|
|
|
|
|
|
|
&:focus {
|
|
|
|
outline: 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
&:read-only,
|
|
|
|
&:disabled {
|
|
|
|
cursor: not-allowed;
|
|
|
|
}
|
2024-01-11 17:00:01 +01:00
|
|
|
}
|
|
|
|
|
2024-03-21 17:34:56 +01:00
|
|
|
/* The selector needs to be written this way to override the specificity
|
|
|
|
of the base style defined for a read-only textarea in dark mode. */
|
|
|
|
.message_edit_form .edit-controls textarea.message_edit_content:read-only {
|
|
|
|
opacity: 1;
|
|
|
|
}
|
|
|
|
|
2024-01-11 17:00:01 +01:00
|
|
|
.message_edit_countdown_timer {
|
|
|
|
text-align: right;
|
|
|
|
display: inline;
|
|
|
|
color: hsl(0deg 0% 63%);
|
|
|
|
|
|
|
|
&.expired {
|
|
|
|
color: hsl(4deg 58% 33%);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
.message-edit-timer {
|
|
|
|
display: none;
|
|
|
|
/* Center vertically relative to
|
|
|
|
buttons. */
|
|
|
|
align-self: center;
|
|
|
|
/* Use flexbox to position to far right of
|
|
|
|
the Save and Cancel buttons. */
|
|
|
|
margin-left: auto;
|
|
|
|
}
|
|
|
|
|
|
|
|
.message-edit-feature-group {
|
|
|
|
display: flex;
|
|
|
|
align-items: baseline;
|
2024-05-18 10:30:24 +02:00
|
|
|
border-radius: 0 0 3px 3px;
|
|
|
|
background-color: var(--color-message-formatting-controls-container);
|
|
|
|
/* margin on either side to let the border of
|
|
|
|
.edit-content-container show through. */
|
|
|
|
margin: 0 1px;
|
2024-01-11 17:00:01 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
.message_edit_save .loader {
|
|
|
|
display: none;
|
|
|
|
height: 28px;
|
|
|
|
width: 28px;
|
|
|
|
}
|
|
|
|
|
|
|
|
.edit-controls {
|
|
|
|
.btn-wrapper {
|
|
|
|
cursor: not-allowed;
|
|
|
|
}
|
|
|
|
|
|
|
|
.disable-btn {
|
|
|
|
pointer-events: none;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Reduce some of the heavy padding from Bootstrap. */
|
|
|
|
.message_edit_form {
|
|
|
|
margin-bottom: 10px;
|
|
|
|
cursor: default;
|
|
|
|
|
|
|
|
.edit-controls {
|
|
|
|
margin-left: 0;
|
|
|
|
margin-top: 0;
|
|
|
|
}
|
2024-07-30 22:03:41 +02:00
|
|
|
|
|
|
|
.preview_message_area {
|
|
|
|
max-height: var(--max-message-edit-height);
|
|
|
|
}
|
2024-01-11 17:00:01 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
.message_edit_notice {
|
2024-08-30 19:14:35 +02:00
|
|
|
/* 10px at 14px/1em */
|
|
|
|
font-size: 0.7143em;
|
2024-01-11 17:00:01 +01:00
|
|
|
opacity: 0.5;
|
|
|
|
user-select: none;
|
|
|
|
white-space: nowrap;
|
|
|
|
overflow-x: hidden;
|
|
|
|
overflow-x: clip;
|
2024-07-23 17:48:48 +02:00
|
|
|
text-overflow: ellipsis;
|
|
|
|
padding-right: 5.5px;
|
2024-01-11 17:00:01 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
.fade-in-message {
|
|
|
|
animation-name: fadeInMessage;
|
|
|
|
animation-duration: 1s;
|
|
|
|
animation-iteration-count: 1;
|
|
|
|
|
|
|
|
.message_edit_notice {
|
|
|
|
animation-name: fadeInEditNotice;
|
|
|
|
animation-duration: 1s;
|
|
|
|
animation-iteration-count: 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
.message_edit_notice_hover:hover {
|
|
|
|
opacity: 1;
|
|
|
|
}
|
|
|
|
|
2024-04-30 23:37:29 +02:00
|
|
|
/* Locally echoed messages. */
|
|
|
|
.locally-echoed .message-time {
|
|
|
|
opacity: 0;
|
|
|
|
/* Don't show pointer when message-time doesn't have a link. */
|
|
|
|
cursor: default;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Show the spinner only for messages that are still locally echoed. */
|
|
|
|
.locally-echoed .slow-send-spinner {
|
|
|
|
display: unset !important;
|
|
|
|
cursor: default;
|
|
|
|
}
|
|
|
|
|
2023-05-22 18:28:52 +02:00
|
|
|
.recipient_row {
|
|
|
|
/* See https://stackoverflow.com/questions/2717480/css-selector-for-first-element-with-class/8539107#8539107
|
|
|
|
for details on how this works */
|
|
|
|
.message_row.unread {
|
|
|
|
.date_unread_marker {
|
|
|
|
display: none;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Select all but the first .message_row.unread,
|
|
|
|
and remove the properties set from the previous rule. */
|
|
|
|
.message_row.unread ~ .message_row.unread {
|
|
|
|
.date_unread_marker {
|
|
|
|
display: block;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2024-04-29 23:08:12 +02:00
|
|
|
|
|
|
|
.date_row {
|
|
|
|
grid-area: date_row;
|
|
|
|
|
2024-04-29 22:58:41 +02:00
|
|
|
& .timerender-content {
|
2024-04-30 17:30:19 +02:00
|
|
|
display: block;
|
|
|
|
overflow: hidden;
|
|
|
|
text-transform: uppercase;
|
2024-04-29 23:08:12 +02:00
|
|
|
font-size: calc(12em / 14);
|
|
|
|
font-style: normal;
|
|
|
|
font-weight: 600;
|
|
|
|
line-height: 17px; /* identical to box height, or 131% */
|
|
|
|
text-align: right;
|
|
|
|
letter-spacing: 0.04em;
|
|
|
|
color: var(--color-date);
|
|
|
|
/* Right padding matches time in message row and date in recipient row. */
|
|
|
|
padding: 8px 6px 8px 4px;
|
|
|
|
}
|
|
|
|
}
|