FEATURE: display last message on mobile (#25384)

Direct messages on mobile will now display the last message in the channels list.
This commit is contained in:
Joffrey JAFFEUX
2024-01-25 15:30:21 +01:00
committed by GitHub
parent 4d1ed4a62d
commit 7b173e883f
20 changed files with 568 additions and 329 deletions
@@ -0,0 +1,49 @@
import Component from "@glimmer/component";
import { htmlSafe } from "@ember/template";
import icon from "discourse-common/helpers/d-icon";
import ChatUserAvatar from "discourse/plugins/chat/discourse/components/chat-user-avatar";
export default class ChatChannelIcon extends Component {
get firstUser() {
return this.args.channel.chatable.users[0];
}
get groupDirectMessage() {
return (
this.args.channel.isDirectMessageChannel &&
this.args.channel.chatable.group
);
}
get channelColorStyle() {
return htmlSafe(`color: #${this.args.channel.chatable.color}`);
}
<template>
{{#if @channel.isDirectMessageChannel}}
<div class="chat-channel-icon">
{{#if this.groupDirectMessage}}
<span class="chat-channel-icon --users-count">
{{@channel.membershipsCount}}
</span>
{{else}}
<div class="chat-channel-icon --avatar">
<ChatUserAvatar @user={{this.firstUser}} @interactive={{false}} />
</div>
{{/if}}
</div>
{{else if @channel.isCategoryChannel}}
<div class="chat-channel-icon">
<span
class="chat-channel-icon --category-badge"
style={{this.channelColorStyle}}
>
{{icon "d-chat"}}
{{#if @channel.chatable.read_restricted}}
{{icon "lock" class="chat-channel-icon__restricted-category-icon"}}
{{/if}}
</span>
</div>
{{/if}}
</template>
}
@@ -0,0 +1,79 @@
import Component from "@glimmer/component";
import { get, hash } from "@ember/helper";
import { inject as service } from "@ember/service";
import { htmlSafe } from "@ember/template";
import PluginOutlet from "discourse/components/plugin-outlet";
import UserStatusMessage from "discourse/components/user-status-message";
import replaceEmoji from "discourse/helpers/replace-emoji";
export default class ChatChannelName extends Component {
@service currentUser;
get firstUser() {
return this.args.channel.chatable.users[0];
}
get users() {
return this.args.channel.chatable.users;
}
get groupDirectMessage() {
return (
this.args.channel.isDirectMessageChannel &&
this.args.channel.chatable.group
);
}
get groupsDirectMessageTitle() {
return this.args.channel.title || this.usernames;
}
get usernames() {
return this.users.mapBy("username").join(", ");
}
get channelColorStyle() {
return htmlSafe(`color: #${this.args.channel.chatable.color}`);
}
get showUserStatus() {
return !!(this.users.length === 1 && this.users[0].status);
}
<template>
<div class="chat-channel-name">
{{#if @channel.isDirectMessageChannel}}
{{#if this.groupDirectMessage}}
<span class="chat-channel-name__label">
{{this.groupsDirectMessageTitle}}
</span>
{{else}}
<span class="chat-channel-name__label">
{{this.firstUser.username}}
</span>
{{#if this.showUserStatus}}
<UserStatusMessage
@status={{get this.users "0.status"}}
@showDescription={{if this.site.mobileView "true"}}
class="chat-channel__user-status-message"
/>
{{/if}}
<PluginOutlet
@name="after-chat-channel-username"
@outletArgs={{hash user=@user}}
@tagName=""
@connectorTagName=""
/>
{{/if}}
{{else if @channel.isCategoryChannel}}
<span class="chat-channel-name__label">
{{replaceEmoji @channel.title}}
</span>
{{#if (has-block)}}
{{yield}}
{{/if}}
{{/if}}
</div>
</template>
}
@@ -1,111 +1,21 @@
import Component from "@glimmer/component";
import { get, hash } from "@ember/helper";
import { inject as service } from "@ember/service";
import { htmlSafe } from "@ember/template";
import PluginOutlet from "discourse/components/plugin-outlet";
import UserStatusMessage from "discourse/components/user-status-message";
import replaceEmoji from "discourse/helpers/replace-emoji";
import icon from "discourse-common/helpers/d-icon";
import ChatUserAvatar from "discourse/plugins/chat/discourse/components/chat-user-avatar";
import concatClass from "discourse/helpers/concat-class";
import ChannelIcon from "discourse/plugins/chat/discourse/components/channel-icon";
import ChannelName from "discourse/plugins/chat/discourse/components/channel-name";
export default class ChatChannelTitle extends Component {
@service currentUser;
const ChatChannelTitle = <template>
<div
class={{concatClass
"chat-channel-title"
(if @channel.isDirectMessageChannel "is-dm" "is-category")
}}
>
<ChannelIcon @channel={{@channel}} />
<ChannelName @channel={{@channel}} />
get firstUser() {
return this.args.channel.chatable.users[0];
}
get users() {
return this.args.channel.chatable.users;
}
get groupDirectMessage() {
return (
this.args.channel.isDirectMessageChannel &&
this.args.channel.chatable.group
);
}
get groupsDirectMessageTitle() {
return this.args.channel.title || this.usernames;
}
get usernames() {
return this.users.mapBy("username").join(", ");
}
get channelColorStyle() {
return htmlSafe(`color: #${this.args.channel.chatable.color}`);
}
get showUserStatus() {
return !!(this.users.length === 1 && this.users[0].status);
}
<template>
{{#if @channel.isDirectMessageChannel}}
<div class="chat-channel-title is-dm">
{{#if this.groupDirectMessage}}
<span class="chat-channel-title__users-count">
{{@channel.membershipsCount}}
</span>
{{else}}
<div class="chat-channel-title__avatar">
<ChatUserAvatar @user={{this.firstUser}} @interactive={{false}} />
</div>
{{/if}}
<div class="chat-channel-title__user-info">
<div class="chat-channel-title__usernames">
{{#if this.groupDirectMessage}}
<span class="chat-channel-title__name">
{{this.groupsDirectMessageTitle}}
</span>
{{else}}
<span class="chat-channel-title__name">
{{this.firstUser.username}}
</span>
{{#if this.showUserStatus}}
<UserStatusMessage
@status={{get this.users "0.status"}}
@showDescription={{if this.site.mobileView "true"}}
class="chat-channel-title__user-status-message"
/>
{{/if}}
<PluginOutlet
@name="after-chat-channel-username"
@outletArgs={{hash user=@user}}
@tagName=""
@connectorTagName=""
/>
{{/if}}
</div>
</div>
{{#if (has-block)}}
{{yield}}
{{/if}}
</div>
{{else if @channel.isCategoryChannel}}
<div class="chat-channel-title is-category">
<span
class="chat-channel-title__category-badge"
style={{this.channelColorStyle}}
>
{{icon "d-chat"}}
{{#if @channel.chatable.read_restricted}}
{{icon "lock" class="chat-channel-title__restricted-category-icon"}}
{{/if}}
</span>
<span class="chat-channel-title__name">
{{replaceEmoji @channel.title}}
</span>
{{#if (has-block)}}
{{yield}}
{{/if}}
</div>
{{#if (has-block)}}
{{yield}}
{{/if}}
</template>
}
</div>
</template>;
export default ChatChannelTitle;
@@ -18,9 +18,9 @@ export default class ChatChannelMetadata extends Component {
}
<template>
<div class="chat-channel-metadata">
<div class="chat-channel__metadata">
{{#if @channel.lastMessage}}
<div class="chat-channel-metadata__date">
<div class="chat-channel__metadata-date">
{{this.lastMessageFormattedDate}}
</div>
{{/if}}
@@ -9,13 +9,15 @@ import { inject as service } from "@ember/service";
import { htmlSafe } from "@ember/template";
import { modifier } from "ember-modifier";
import concatClass from "discourse/helpers/concat-class";
import replaceEmoji from "discourse/helpers/replace-emoji";
import { popupAjaxError } from "discourse/lib/ajax-error";
import icon from "discourse-common/helpers/d-icon";
import { bind } from "discourse-common/utils/decorators";
import I18n from "discourse-i18n";
import and from "truth-helpers/helpers/and";
import eq from "truth-helpers/helpers/eq";
import ChannelTitle from "discourse/plugins/chat/discourse/components/channel-title";
import ChannelIcon from "discourse/plugins/chat/discourse/components/channel-icon";
import ChannelName from "discourse/plugins/chat/discourse/components/channel-name";
import ChatChannelMetadata from "discourse/plugins/chat/discourse/components/chat-channel-metadata";
import ToggleChannelMembershipButton from "discourse/plugins/chat/discourse/components/toggle-channel-membership-button";
@@ -142,6 +144,14 @@ export default class ChatChannelRow extends Component {
return this.args.channel.tracking.unreadCount > 0;
}
get shouldRenderLastMessage() {
return (
this.site.mobileView &&
this.args.channel.isDirectMessageChannel &&
this.args.channel.lastMessage
);
}
get #firstDirectMessageUser() {
return this.args.channel?.chatable?.users?.firstObject;
}
@@ -177,6 +187,7 @@ export default class ChatChannelRow extends Component {
<div
class={{concatClass
"chat-channel-row__content"
(if @channel.isCategoryChannel "is-category" "is-dm")
(if this.shouldReset "-animate-reset")
}}
{{(if this.shouldHandleSwipe (modifier this.registerSwipableRow))}}
@@ -184,8 +195,19 @@ export default class ChatChannelRow extends Component {
{{(if this.shouldReset (modifier this.onReset))}}
style={{this.rowStyle}}
>
<ChannelTitle @channel={{@channel}} />
<ChatChannelMetadata @channel={{@channel}} @unreadIndicator={{true}} />
<ChannelIcon @channel={{@channel}} />
<div class="chat-channel-row__info">
<ChannelName @channel={{@channel}} />
<ChatChannelMetadata
@channel={{@channel}}
@unreadIndicator={{true}}
/>
{{#if this.shouldRenderLastMessage}}
<div class="chat-channel__last-message">
{{replaceEmoji (htmlSafe @channel.lastMessage.excerpt)}}
</div>
{{/if}}
</div>
{{#if
(and @options.leaveButton @channel.isFollowing this.site.desktopView)