Skip to content

Commit db9df40

Browse files
committed
feat: add on-hover timestamps for message-body-only messages
fixes #418
1 parent fdde455 commit db9df40

File tree

2 files changed

+51
-8
lines changed

2 files changed

+51
-8
lines changed

packages/core/demo/index.html

+13
Original file line numberDiff line numberDiff line change
@@ -170,14 +170,27 @@ <h3 class="title">Compact mode</h3>
170170
<h3 class="title">With subsequent messages</h3>
171171
<discord-messages>
172172
<discord-message profile="favna">I can send multiple messages with my avatar showing only once</discord-message>
173+
<discord-message profile="favna" message-body-only message-body-only-time="12:39"
174+
>That's how Discord handles multiple messages from the same author as well</discord-message
175+
>
173176
<discord-message profile="favna" message-body-only
177+
>Just keep in mind that Discord does some funky stuff like with time between messages, this library doesn't automatically
178+
change what is displayed!</discord-message
179+
>
180+
</discord-messages>
181+
182+
<h3 class="title">With subsequent messages in compact mode</h3>
183+
<discord-messages compact-mode>
184+
<discord-message profile="favna">I can send multiple messages with my avatar showing only once</discord-message>
185+
<discord-message profile="favna" message-body-only message-body-only-time="12:39"
174186
>That's how Discord handles multiple messages from the same author as well</discord-message
175187
>
176188
<discord-message profile="favna" message-body-only
177189
>Just keep in mind that Discord does some funky stuff like with time between messages, this library doesn't automatically
178190
change what is displayed!</discord-message
179191
>
180192
</discord-messages>
193+
181194
<h3 class="title">Markdown Styling</h3>
182195
<discord-messages>
183196
<discord-message profile="favna">

packages/core/src/components/discord-message/DiscordMessage.ts

+38-8
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import { consume } from '@lit/context';
22
import { css, html, LitElement } from 'lit';
33
import { customElement, property } from 'lit/decorators.js';
44
import { ifDefined } from 'lit/directives/if-defined.js';
5+
import { createRef, ref, type Ref } from 'lit/directives/ref.js';
56
import { when } from 'lit/directives/when.js';
67
import { avatars, profiles } from '../../config.js';
78
import type { DiscordMessageProps, Profile, LightTheme, DiscordTimestamp } from '../../types.js';
@@ -35,17 +36,20 @@ export class DiscordMessage extends LitElement implements DiscordMessageProps, L
3536
padding-right: 48px;
3637
margin-top: inherit;
3738
margin-bottom: inherit;
39+
line-height: 16px;
3840
}
3941
4042
.discord-message-inner {
4143
display: flex;
44+
align-items: center;
4245
position: relative;
4346
-webkit-box-flex: 0;
4447
-ms-flex: 0 0 auto;
4548
flex: 0 0 auto;
4649
}
4750
4851
:host([message-body-only]) {
52+
min-height: 24px !important;
4953
margin-top: 0px !important;
5054
padding-top: 0.125rem !important;
5155
padding-bottom: 0.0625rem !important;
@@ -244,6 +248,8 @@ export class DiscordMessage extends LitElement implements DiscordMessageProps, L
244248
}
245249
`;
246250

251+
protected messageBodyOnlyTimeRef: Ref<HTMLTimeElement> = createRef();
252+
247253
/**
248254
* The id of the profile data to use.
249255
*/
@@ -337,6 +343,12 @@ export class DiscordMessage extends LitElement implements DiscordMessageProps, L
337343
})
338344
public accessor timestamp: DiscordTimestamp = new Date();
339345

346+
/**
347+
* The timestamp to use for the message time if {@link DiscordMessage.messageBodyOnly} is `true`.
348+
*/
349+
@property({ type: String, attribute: 'message-body-only-time' })
350+
public accessor messageBodyOnlyTime: DiscordTimestamp | null = null;
351+
340352
/**
341353
* Whether to use 24-hour format for the timestamp.
342354
*/
@@ -373,8 +385,17 @@ export class DiscordMessage extends LitElement implements DiscordMessageProps, L
373385
);
374386
}
375387

376-
private resolveAvatar(avatar: string | undefined): string {
377-
return avatar === undefined ? avatars.default : avatars[avatar] ?? avatar ?? avatars.default;
388+
protected handleMessageEnter() {
389+
if (this.messageBodyOnly && this.messageBodyOnlyTimeRef.value && this.messageBodyOnlyTime) {
390+
const computedTimestamp = handleTimestamp(this.messageBodyOnlyTime, true, this.twentyFour);
391+
this.messageBodyOnlyTimeRef.value.textContent = computedTimestamp ?? '';
392+
}
393+
}
394+
395+
protected handleMessageLeave() {
396+
if (this.messageBodyOnlyTimeRef.value) {
397+
this.messageBodyOnlyTimeRef.value.textContent = '';
398+
}
378399
}
379400

380401
protected override render() {
@@ -392,19 +413,24 @@ export class DiscordMessage extends LitElement implements DiscordMessageProps, L
392413
const profileData: Profile = ((this.profile !== undefined && Reflect.get(profiles, this.profile)) as Profile) || {};
393414
const profile: Profile = { ...defaultData, ...profileData, avatar: this.resolveAvatar(profileData.avatar ?? this.avatar) };
394415

395-
const computedTimestamp = handleTimestamp(this.timestamp, this.compactMode, this.twentyFour);
416+
const computedTimestamp = handleTimestamp(this.timestamp, this.compactMode, this.twentyFour) ?? undefined;
396417

397418
return html`
398419
<slot name="reply"></slot>
399-
<div class="discord-message-inner">
420+
<div class="discord-message-inner" @mouseenter=${this.handleMessageEnter} @mouseleave=${this.handleMessageLeave}>
400421
${when(
401422
this.compactMode,
402-
() => html`<span class="discord-message-timestamp">${computedTimestamp}</span>`,
423+
() => html`<time datetime="${ifDefined(computedTimestamp)}" class="discord-message-timestamp">${computedTimestamp}</time>`,
403424
() => null
404425
)}
405426
${when(
406-
this.messageBodyOnly,
407-
() => html`<span class="discord-message-timestamp discord-message-body-only-indent"></span>`,
427+
this.messageBodyOnly && !this.compactMode,
428+
() =>
429+
html`<time
430+
${ref(this.messageBodyOnlyTimeRef)}
431+
datetime="${ifDefined(computedTimestamp)}"
432+
class="discord-message-timestamp discord-message-body-only-indent"
433+
></time>`,
408434
() => null
409435
)}
410436
${when(
@@ -432,7 +458,7 @@ export class DiscordMessage extends LitElement implements DiscordMessageProps, L
432458
roleName=${profile.roleName ?? ''}
433459
?compact=${false}
434460
></discord-author-info
435-
><span class="discord-message-timestamp">${computedTimestamp}</span>
461+
><time datetime="${ifDefined(computedTimestamp)}" class="discord-message-timestamp">${computedTimestamp}</time>
436462
`
437463
)}
438464
<div class="discord-message-body">
@@ -479,6 +505,10 @@ export class DiscordMessage extends LitElement implements DiscordMessageProps, L
479505
</div>
480506
`;
481507
}
508+
509+
private resolveAvatar(avatar: string | undefined): string {
510+
return avatar === undefined ? avatars.default : avatars[avatar] ?? avatar ?? avatars.default;
511+
}
482512
}
483513

484514
declare global {

0 commit comments

Comments
 (0)