UX: Chat browse redesign (#25698)

* UX: fix search input placeholder cutoff

* UX: use transparent button for new-channel

* UX: remove settings link

* UX: removed joined tag

* UX: increase lock icon size

* UX: use grid for channel card

* UX: chat-channel-card styling + cleanup

* UX: dont space about tabs on mobile

* specs

* PR feedback

Co-authored-by: Joffrey JAFFEUX <j.jaffeux@gmail.com>

* PR feedback > translation

* Remove import

* UX: update copy

---------

Co-authored-by: Joffrey JAFFEUX <j.jaffeux@gmail.com>
This commit is contained in:
chapoi 2024-02-15 19:00:22 +02:00 committed by GitHub
parent 95bf1e1e9a
commit 292685d3de
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
9 changed files with 88 additions and 171 deletions

View File

@ -18,8 +18,8 @@ export default class ChatChannelCard extends Component {
<div
class={{concatClass
"chat-channel-card"
(if @channel.isClosed "-closed")
(if @channel.isArchived "-archived")
(if @channel.isClosed "--closed")
(if @channel.isArchived "--archived")
}}
style={{borderColor @channel.chatable.color}}
data-channel-id={{@channel.id}}
@ -36,52 +36,28 @@ export default class ChatChannelCard extends Component {
{{#if @channel.chatable.read_restricted}}
{{dIcon "lock" class="chat-channel-card__read-restricted"}}
{{/if}}
{{#if @channel.currentUserMembership.muted}}
<span
class="chat-channel-card__muted"
aria-label={{i18n "chat.muted"}}
title={{i18n "chat.muted"}}
>{{dIcon "d-muted"}}</span>
{{/if}}
</LinkTo>
<div class="chat-channel-card__header-actions">
{{#if @channel.currentUserMembership.muted}}
<LinkTo
@route="chat.channel.info.settings"
@models={{@channel.routeModels}}
class="chat-channel-card__tag -muted"
tabindex="-1"
>
{{i18n "chat.muted"}}
</LinkTo>
{{/if}}
<LinkTo
@route="chat.channel.info.settings"
@models={{@channel.routeModels}}
class="chat-channel-card__setting"
tabindex="-1"
>
{{dIcon "cog"}}
</LinkTo>
</div>
</div>
{{#if @channel.description}}
<div class="chat-channel-card__description">
{{replaceEmoji @channel.description}}
</div>
{{/if}}
<div class="chat-channel-card__cta">
{{#if @channel.isFollowing}}
<div class="chat-channel-card__tags">
<span class="chat-channel-card__tag -joined">
{{i18n "chat.joined"}}
</span>
<ToggleChannelMembershipButton
@channel={{@channel}}
@options={{hash
leaveClass="btn-link btn-small chat-channel-card__leave-btn"
labelType="short"
}}
/>
</div>
<ToggleChannelMembershipButton
@channel={{@channel}}
@options={{hash
leaveClass="btn-transparent btn-danger chat-channel-card__leave-btn"
labelType="short"
}}
/>
{{else if @channel.isJoinable}}
<ToggleChannelMembershipButton
@channel={{@channel}}
@ -91,21 +67,28 @@ export default class ChatChannelCard extends Component {
}}
/>
{{/if}}
{{#if (gt @channel.membershipsCount 0)}}
<LinkTo
@route="chat.channel.info.members"
@models={{@channel.routeModels}}
class="chat-channel-card__members"
tabindex="-1"
>
{{i18n
"chat.channel.memberships_count"
count=@channel.membershipsCount
}}
</LinkTo>
{{/if}}
</div>
{{#if (gt @channel.membershipsCount 0)}}
<LinkTo
@route="chat.channel.info.members"
@models={{@channel.routeModels}}
class="chat-channel-card__members"
tabindex="-1"
>
{{i18n
"chat.channel.memberships_count"
count=@channel.membershipsCount
}}
</LinkTo>
{{/if}}
{{#if @channel.description}}
<div class="chat-channel-card__description">
{{replaceEmoji @channel.description}}
</div>
{{/if}}
</div>
{{/if}}
</template>

View File

@ -2,7 +2,6 @@ import Component from "@glimmer/component";
import { action } from "@ember/object";
import { inject as service } from "@ember/service";
import DButton from "discourse/components/d-button";
import concatClass from "discourse/helpers/concat-class";
import CreateChannelModal from "discourse/plugins/chat/discourse/components/chat/modal/create-channel";
export default class ChatNavbarNewChannelButton extends Component {
@ -22,10 +21,7 @@ export default class ChatNavbarNewChannelButton extends Component {
@action={{this.createChannel}}
@icon="plus"
@label={{if this.site.desktopView "chat.create_channel.title"}}
class={{concatClass
"c-navbar__new-channel-button"
(if this.site.mobileView "btn-flat")
}}
class="c-navbar__new-channel-button btn-transparent"
/>
{{/if}}
</template>

View File

@ -22,11 +22,11 @@
&__cards {
display: grid;
grid-template-columns: repeat(2, 1fr);
grid-gap: 2rem;
grid-gap: 1.25rem;
@include breakpoint(tablet) {
grid-template-columns: repeat(1, 1fr);
grid-gap: 1.5rem;
grid-gap: 1rem;
}
}
@ -56,10 +56,6 @@
&:before {
content: none; //there is a strange thing applied on nav-pills and this resets it
}
@include breakpoint(mobile-large) {
justify-content: space-between;
}
}
&__filter {
@ -85,18 +81,4 @@
font-size: var(--font-up-1);
}
}
.chat-channel-card {
.chat-channel-card__leave-btn {
padding: 0;
&:hover,
&:focus {
background: none;
}
&:focus {
@include default-focus;
}
}
}
}

View File

@ -1,55 +1,53 @@
.chat-channel-card {
display: flex;
flex-direction: column;
display: grid;
grid-template-areas:
"title cta"
"membercount ."
"description description";
grid-template-rows: auto auto 1fr;
align-items: center;
position: relative;
padding: 1.25rem;
padding: 0.75rem 1rem;
background-color: var(--primary-very-low);
border-radius: var(--d-border-radius);
min-height: 0;
min-width: 0;
border-left: 5px solid transparent;
&.--closed,
&.--archived {
opacity: 0.6;
}
&__header {
@include ellipsis;
align-items: center;
display: flex;
grid-area: title;
height: min-content;
}
&__header-actions {
align-items: center;
display: flex;
margin-left: auto;
}
&__read-restricted {
&__read-restricted,
&__muted {
color: var(--primary-medium);
font-size: var(--font-down-4);
padding: 0 0.25rem;
}
&__read-restricted {
font-size: var(--font-down-2-rem);
}
&__muted {
font-size: var(--font-down-1-rem);
}
&__description {
@include line-clamp(2);
color: var(--primary-medium);
padding-top: 1rem;
.-closed &,
.-archived & {
opacity: 0.5;
}
}
&__setting {
svg {
fill: var(--primary-medium);
}
.-archived & {
opacity: 0.5;
}
padding-top: 0.5rem;
grid-area: description;
}
&__members {
margin-left: auto;
font-size: 0.875rem;
font-size: var(--font-down-1-rem);
grid-area: membercount;
}
&__name {
@ -58,59 +56,30 @@
&__name-container {
display: flex;
gap: 0.25em;
align-items: center;
color: var(--primary);
font-size: 1.15rem;
font-size: var(--font-up-1-rem);
text-decoration: none;
min-width: 0;
margin-right: 2rem;
&:visited,
&:hover {
color: var(--primary);
}
.-closed &,
.-archived & {
opacity: 0.5;
}
}
&__tag {
border-radius: 10px;
margin-right: 0.5rem;
padding: 0.25rem 0.5rem;
text-transform: uppercase;
font-size: 0.7rem;
font-weight: bold;
background-color: var(--secondary);
&__leave-btn {
padding-right: 0;
&.-muted {
color: var(--primary-medium);
border: 1px solid var(--primary-low-mid);
& + .chat-channel-card__setting {
margin-left: 0.5rem;
}
}
&.-joined {
color: var(--success);
border: 1px solid var(--success);
}
&.-closed,
&.-archived {
display: inline-block;
padding-left: 0;
margin-bottom: 0.5rem;
&:focus {
@include default-focus;
}
}
&__cta {
flex-grow: 1;
display: flex;
justify-content: space-between;
align-items: end;
margin-top: 1rem;
align-items: center;
justify-content: flex-end;
}
}

View File

@ -98,10 +98,7 @@
margin-left: auto;
display: flex;
align-items: center;
> .btn {
height: var(--chat-header-offset);
}
height: var(--chat-header-offset);
}
.c-navbar__back-button ~ .c-navbar__title {

View File

@ -15,6 +15,12 @@
margin: 0;
border: none;
outline: none;
@include breakpoint(tablet, min-width) {
.chat-browse-view__actions & {
width: 210px;
}
}
}
.d-icon {

View File

@ -308,7 +308,7 @@ en:
back: "Back"
title: Channels
filter_all: All
filter_open: Opened
filter_open: Open
filter_closed: Closed
filter_archived: Archived
filter_input_placeholder: Search channel by name

View File

@ -17,7 +17,6 @@ RSpec.describe "Channel - Info - Settings page", type: :system do
context "when clicking back button" do
it "redirects to browse page" do
chat_page.visit_browse
find(".chat-channel-card__setting").click
find(".c-navbar__back-button").click
expect(page).to have_current_path("/chat/browse/open")

View File

@ -35,14 +35,14 @@ module("Discourse Chat | Component | chat-channel-card", function (hooks) {
this.channel.status = "closed";
await render(hbs`<ChatChannelCard @channel={{this.channel}} />`);
assert.true(exists(".chat-channel-card.-closed"));
assert.true(exists(".chat-channel-card.--closed"));
});
test("Archived channel", async function (assert) {
this.channel.status = "archived";
await render(hbs`<ChatChannelCard @channel={{this.channel}} />`);
assert.true(exists(".chat-channel-card.-archived"));
assert.true(exists(".chat-channel-card.--archived"));
});
test("Muted channel", async function (assert) {
@ -50,21 +50,12 @@ module("Discourse Chat | Component | chat-channel-card", function (hooks) {
this.channel.currentUserMembership.following = true;
await render(hbs`<ChatChannelCard @channel={{this.channel}} />`);
assert.strictEqual(
query(".chat-channel-card__tag.-muted").textContent.trim(),
I18n.t("chat.muted")
);
assert.true(exists(".chat-channel-card__muted"));
});
test("Joined channel", async function (assert) {
this.channel.currentUserMembership.following = true;
await render(hbs`<ChatChannelCard @channel={{this.channel}} />`);
assert.strictEqual(
query(".chat-channel-card__tag.-joined").textContent.trim(),
I18n.t("chat.joined")
);
assert.true(exists(".toggle-channel-membership-button.-leave"));
});
@ -109,12 +100,6 @@ module("Discourse Chat | Component | chat-channel-card", function (hooks) {
);
});
test("Settings button", async function (assert) {
await render(hbs`<ChatChannelCard @channel={{this.channel}} />`);
assert.true(exists(".chat-channel-card__setting"));
});
test("Read restricted chatable", async function (assert) {
this.channel.chatable.read_restricted = true;
await render(hbs`<ChatChannelCard @channel={{this.channel}} />`);