UI: simplify chat thread title (#29998)

We were using a complex logic to make it change size based on scroll position but this was imperfect and not visually pleasing. Also the title had been made a button which was causing the ellipsis to not work correctly, and I would prefer to not mix page knowledge (thread) with title component so I made this click logic directly in the chat-thread component.

---------

Co-authored-by: Jordan Vidrine <jordan@jordanvidrine.com>
This commit is contained in:
Joffrey JAFFEUX 2024-11-29 22:39:18 +01:00 committed by GitHub
parent 2f932812e0
commit b546c31b7f
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
12 changed files with 87 additions and 74 deletions

View File

@ -0,0 +1,22 @@
import Component from "@glimmer/component";
import replaceEmoji from "discourse/helpers/replace-emoji";
import icon from "discourse-common/helpers/d-icon";
export default class ChatThreadHeading extends Component {
get showHeading() {
return this.args.thread?.title;
}
<template>
{{#if this.showHeading}}
<div class="chat-thread__heading">
<div class="chat-thread__heading-icon">
{{icon "discourse-threads"}}
</div>
<h2 class="chat-thread__heading-title">
{{replaceEmoji @thread.title}}
</h2>
</div>
{{/if}}
</template>
}

View File

@ -38,6 +38,7 @@ import Message from "./chat-message";
import ChatMessagesContainer from "./chat-messages-container";
import ChatMessagesScroller from "./chat-messages-scroller";
import ChatSkeleton from "./chat-skeleton";
import ChatThreadHeading from "./chat-thread-heading";
import ChatUploadDropZone from "./chat-upload-drop-zone";
export default class ChatThread extends Component {
@ -143,7 +144,6 @@ export default class ChatThread extends Component {
(state.distanceToBottom.pixels > 250 && !state.atBottom);
this.isScrolling = false;
this.atBottom = state.atBottom;
this.args.setFullTitle?.(state.atTop);
if (state.atBottom) {
this.fetchMoreMessages({ direction: FUTURE });
@ -569,6 +569,8 @@ export default class ChatThread extends Component {
{{/if}}
{{/unless}}
</ChatMessagesContainer>
<ChatThreadHeading @thread={{@thread}} />
</ChatMessagesScroller>
<ChatScrollToBottomArrow

View File

@ -1,5 +1,4 @@
import Component from "@glimmer/component";
import { tracked } from "@glimmer/tracking";
import { array } from "@ember/helper";
import { service } from "@ember/service";
import { i18n } from "discourse-i18n";
@ -12,19 +11,9 @@ export default class ChatDrawerRoutesBrowse extends Component {
@service chatChannelsManager;
@service chatHistory;
@tracked showThreadFullTitle = false;
get showfullTitle() {
return this.chatStateManager.isDrawerExpanded && this.showThreadFullTitle;
}
<template>
<div class="c-drawer-routes --browse">
<Navbar
@onClick={{this.chat.toggleDrawer}}
@showFullTitle={{this.showfullTitle}}
as |navbar|
>
<Navbar @onClick={{this.chat.toggleDrawer}} as |navbar|>
<navbar.BackButton @route="chat.channels" />
<navbar.Title @title={{i18n "chat.browse.title"}} />
<navbar.Actions as |a|>

View File

@ -1,5 +1,4 @@
import Component from "@glimmer/component";
import { tracked } from "@glimmer/tracking";
import { array } from "@ember/helper";
import { action } from "@ember/object";
import didInsert from "@ember/render-modifiers/modifiers/did-insert";
@ -16,12 +15,6 @@ export default class ChatDrawerRoutesChannelThread extends Component {
@service chatChannelsManager;
@service chatHistory;
@tracked showThreadFullTitle = false;
get showfullTitle() {
return this.chatStateManager.isDrawerExpanded && this.showThreadFullTitle;
}
get backButton() {
const link = {
models: this.chat.activeChannel?.routeModels,
@ -71,11 +64,6 @@ export default class ChatDrawerRoutesChannelThread extends Component {
}
}
@action
setFullTitle(value) {
this.showThreadFullTitle = value;
}
<template>
<div
class="c-drawer-routes --channel-thread"
@ -109,7 +97,6 @@ export default class ChatDrawerRoutesChannelThread extends Component {
<ChatThread
@thread={{thread}}
@targetMessageId={{@params.messageId}}
@setFullTitle={{this.setFullTitle}}
/>
{{/if}}
{{/each}}

View File

@ -28,11 +28,7 @@ export default class ChatNavbar extends Component {
<template>
{{! template-lint-disable no-invalid-interactive }}
<div
class={{concatClass
"c-navbar-container"
(if @onClick "-clickable")
(if @showFullTitle "-full-title")
}}
class={{concatClass "c-navbar-container" (if @onClick "-clickable")}}
{{on "click" (if @onClick @onClick (noop))}}
{{ChatOnResize this.handleResize}}
>

View File

@ -1,5 +1,4 @@
import { hash } from "@ember/helper";
import DButton from "discourse/components/d-button";
import concatClass from "discourse/helpers/concat-class";
import icon from "discourse-common/helpers/d-icon";
import SubTitle from "./sub-title";
@ -8,20 +7,13 @@ const ChatNavbarTitle = <template>
<div
title={{@title}}
class={{concatClass "c-navbar__title" (if @showFullTitle "full-title")}}
...attributes
>
{{#if @openThreadTitleModal}}
<DButton
class="c-navbar__title-text btn-transparent"
@icon={{@icon}}
@action={{@openThreadTitleModal}}
@translatedLabel={{@title}}
/>
{{else}}
<span class="c-navbar__title-text">
{{if @icon (icon @icon)}}
{{@title}}
</span>
{{/if}}
<span class="c-navbar__title-text">
{{if @icon (icon @icon)}}
{{@title}}
</span>
{{#if (has-block)}}
{{yield (hash SubTitle=SubTitle)}}
{{/if}}

View File

@ -1,4 +1,5 @@
import Component from "@glimmer/component";
import { on } from "@ember/modifier";
import { service } from "@ember/service";
import noop from "discourse/helpers/noop";
import replaceEmoji from "discourse/helpers/replace-emoji";
@ -91,7 +92,9 @@ export default class ChatThreadHeader extends Component {
<navbar.Title
@title={{replaceEmoji this.headerTitle}}
@openThreadTitleModal={{this.openThreadTitleModal}}
{{on "click" this.openThreadTitleModal}}
role={{if this.openThreadTitleModal "button"}}
class="clickable"
/>
<navbar.Actions as |action|>
<action.ThreadTrackingDropdown @thread={{@thread}} />

View File

@ -10,21 +10,6 @@
&.-clickable {
cursor: pointer;
}
&.-full-title {
.c-navbar__title {
min-height: var(--chat-header-offset);
}
.c-navbar__title,
.c-navbar__title-text {
height: auto;
overflow: visible;
white-space: normal;
text-overflow: unset;
overflow-wrap: anywhere;
}
}
}
.c-navbar {

View File

@ -0,0 +1,19 @@
.chat-thread__heading {
padding: 0.5rem 0.5rem 0 0.5rem;
display: flex;
align-items: baseline;
}
.chat-thread__heading-icon {
color: var(--secondary-low);
display: flex;
background-color: var(--primary-100);
padding: 0.5em;
border-radius: 100%;
}
.chat-thread__heading-title {
padding-left: 0.5em;
color: var(--secondary-low);
margin-bottom: 0;
}

View File

@ -14,6 +14,7 @@
@import "chat-composer-dropdown";
@import "chat-composer-upload";
@import "chat-composer-uploads";
@import "chat-thread-heading";
@import "chat-composer";
@import "chat-composer-button";
@import "chat-message-blocks";

View File

@ -10,17 +10,4 @@
&__back-button {
align-self: stretch;
}
&.-full-title {
.c-navbar {
&__actions,
&__back-button {
height: calc(var(--chat-header-offset) - 2px) !important;
}
&__title {
padding-block: calc(1rem + 2px);
}
}
left: 0.25rem;
width: calc(100% - 0.5rem);
}
}

View File

@ -0,0 +1,30 @@
import { getOwner } from "@ember/owner";
import { render } from "@ember/test-helpers";
import { module, test } from "qunit";
import { setupRenderingTest } from "discourse/tests/helpers/component-test";
import ChatThreadHeading from "discourse/plugins/chat/discourse/components/chat-thread-heading";
import ChatFabricators from "discourse/plugins/chat/discourse/lib/fabricators";
module("Discourse Chat | Component | chat-thread-heading", function (hooks) {
setupRenderingTest(hooks);
test("it renders the title", async function (assert) {
const thread = new ChatFabricators(getOwner(this)).thread({
title: "A nice thread title",
});
await render(<template><ChatThreadHeading @thread={{thread}} /></template>);
assert.dom(".chat-thread__heading-title").hasText("A nice thread title");
});
test("it doesnt render heading when no title", async function (assert) {
const thread = new ChatFabricators(getOwner(this)).thread({
title: null,
});
await render(<template><ChatThreadHeading @thread={{thread}} /></template>);
assert.dom(".chat-thread__heading").doesNotExist();
});
});