UX: implements swipe on row channel
This commit is contained in:
parent
19567daeb9
commit
63bdd93622
|
@ -0,0 +1,204 @@
|
|||
import { inject as service } from "@ember/service";
|
||||
import Component from "@glimmer/component";
|
||||
import { action } from "@ember/object";
|
||||
import { LinkTo } from "@ember/routing";
|
||||
import concatClass from "discourse/helpers/concat-class";
|
||||
import eq from "truth-helpers/helpers/eq";
|
||||
import and from "truth-helpers/helpers/and";
|
||||
import ChatChannelTitle from "discourse/plugins/chat/discourse/components/chat-channel-title";
|
||||
import ChatChannelMetadata from "discourse/plugins/chat/discourse/components/chat-channel-metadata";
|
||||
import didInsert from "@ember/render-modifiers/modifiers/did-insert";
|
||||
import ToggleChannelMembershipButton from "discourse/plugins/chat/discourse/components/toggle-channel-membership-button";
|
||||
import willDestroy from "@ember/render-modifiers/modifiers/will-destroy";
|
||||
import { hash } from "@ember/helper";
|
||||
import I18n from "I18n";
|
||||
import { modifier } from "ember-modifier";
|
||||
import { bind } from "discourse-common/utils/decorators";
|
||||
import { tracked } from "@glimmer/tracking";
|
||||
import discourseLater from "discourse-common/lib/later";
|
||||
import { cancel } from "@ember/runloop";
|
||||
import { popupAjaxError } from "discourse/lib/ajax-error";
|
||||
|
||||
export default class ChatChannelRow extends Component {
|
||||
<template>
|
||||
<LinkTo
|
||||
@route="chat.channel"
|
||||
@models={{@channel.routeModels}}
|
||||
class={{concatClass
|
||||
"chat-channel-row"
|
||||
(if @channel.focused "focused")
|
||||
(if @channel.currentUserMembership.muted "muted")
|
||||
(if @options.leaveButton "can-leave")
|
||||
(if (eq this.chat.activeChannel.id @channel.id) "active")
|
||||
(if this.channelHasUnread "has-unread")
|
||||
}}
|
||||
tabindex="0"
|
||||
data-chat-channel-id={{@channel.id}}
|
||||
{{didInsert this.startTrackingStatus}}
|
||||
{{willDestroy this.stopTrackingStatus}}
|
||||
{{this.handleSwipe}}
|
||||
{{(if this.scheduleRowRemoval (modifier this.rowRemoval))}}
|
||||
>
|
||||
<ChatChannelTitle @channel={{@channel}} />
|
||||
<ChatChannelMetadata @channel={{@channel}} @unreadIndicator={{true}} />
|
||||
|
||||
{{#if
|
||||
(and @options.leaveButton @channel.isFollowing this.site.desktopView)
|
||||
}}
|
||||
<ToggleChannelMembershipButton
|
||||
@channel={{@channel}}
|
||||
@options={{hash
|
||||
leaveClass="btn-flat chat-channel-leave-btn"
|
||||
labelType="none"
|
||||
leaveIcon="times"
|
||||
leaveTitle=(if
|
||||
@channel.isDirectMessageChannel
|
||||
this.leaveDirectMessageLabel
|
||||
this.leaveChanelLabel
|
||||
)
|
||||
}}
|
||||
/>
|
||||
{{/if}}
|
||||
|
||||
<div
|
||||
class={{concatClass
|
||||
"chat-channel-row__action-btn"
|
||||
(if this.canCancelAction "-cancel" "-remove")
|
||||
}}
|
||||
{{this.removeButton}}
|
||||
>
|
||||
{{#if this.canCancelAction}}
|
||||
{{this.cancelActionLabel}}
|
||||
{{else}}
|
||||
{{this.removeActionLabel}}
|
||||
{{/if}}
|
||||
</div>
|
||||
</LinkTo>
|
||||
</template>
|
||||
|
||||
@service router;
|
||||
@service chat;
|
||||
@service currentUser;
|
||||
@service site;
|
||||
@service api;
|
||||
|
||||
@tracked scheduleRowRemoval = false;
|
||||
@tracked reachedThreshold = false;
|
||||
@tracked canCancelAction = false;
|
||||
|
||||
removeButton = modifier((element) => {
|
||||
this.removeButton = element;
|
||||
this.removeButton.style.left = window.innerWidth + "px";
|
||||
});
|
||||
|
||||
rowRemoval = modifier((element) => {
|
||||
element.classList.add("-fade-out");
|
||||
|
||||
const handler = discourseLater(
|
||||
() => this.chat.unfollowChannel(this.args.channel).catch(popupAjaxError),
|
||||
250
|
||||
);
|
||||
|
||||
return () => {
|
||||
cancel(handler);
|
||||
};
|
||||
});
|
||||
|
||||
handleSwipe = modifier((element) => {
|
||||
this.element = element;
|
||||
|
||||
element.addEventListener("touchstart", this.onSwipeStart);
|
||||
element.addEventListener("touchmove", this.onSwipeMove);
|
||||
element.addEventListener("touchend", this.onSwipeEnd);
|
||||
|
||||
return () => {
|
||||
element.removeEventListener("touchstart", this.onSwipeStart);
|
||||
element.removeEventListener("touchmove", this.onSwipeMove);
|
||||
element.removeEventListener("touchend", this.onSwipeEnd);
|
||||
};
|
||||
});
|
||||
|
||||
@bind
|
||||
onSwipeStart(event) {
|
||||
if (!this.removeButton) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.reachedThreshold = false;
|
||||
this.canCancelAction = false;
|
||||
this.initialX = event.changedTouches[0].screenX;
|
||||
}
|
||||
|
||||
@bind
|
||||
onSwipeMove(event) {
|
||||
event.preventDefault();
|
||||
|
||||
const diff = this.initialX - event.changedTouches[0].screenX;
|
||||
|
||||
if (diff < 10) {
|
||||
this.canCancelAction = false;
|
||||
this.reachedThreshold = false;
|
||||
this.element.style.left = "0px";
|
||||
return;
|
||||
}
|
||||
|
||||
if (diff >= window.innerWidth / 3) {
|
||||
this.canCancelAction = false;
|
||||
this.reachedThreshold = true;
|
||||
return;
|
||||
} else {
|
||||
if (this.reachedThreshold) {
|
||||
this.canCancelAction = true;
|
||||
}
|
||||
}
|
||||
|
||||
this.removeButton.style.width = diff + "px";
|
||||
this.element.style.left =
|
||||
-(this.initialX - event.changedTouches[0].screenX) + "px";
|
||||
}
|
||||
|
||||
@bind
|
||||
onSwipeEnd() {
|
||||
const diff = this.initialX - event.changedTouches[0].screenX;
|
||||
|
||||
if (diff >= window.innerWidth / 3) {
|
||||
this.scheduleRowRemoval = true;
|
||||
}
|
||||
|
||||
this.element.style.left = "0px";
|
||||
}
|
||||
|
||||
get cancelActionLabel() {
|
||||
return "Cancel";
|
||||
}
|
||||
|
||||
get removeActionLabel() {
|
||||
return "Remove";
|
||||
}
|
||||
|
||||
get leaveDirectMessageLabel() {
|
||||
return I18n.t("chat.direct_messages.leave");
|
||||
}
|
||||
|
||||
get leaveChanelLabel() {
|
||||
return I18n.t("chat.channel_settings.leave_channel");
|
||||
}
|
||||
|
||||
@action
|
||||
startTrackingStatus() {
|
||||
this.#firstDirectMessageUser?.trackStatus();
|
||||
}
|
||||
|
||||
@action
|
||||
stopTrackingStatus() {
|
||||
this.#firstDirectMessageUser?.stopTrackingStatus();
|
||||
}
|
||||
|
||||
get channelHasUnread() {
|
||||
return this.args.channel.tracking.unreadCount > 0;
|
||||
}
|
||||
|
||||
get #firstDirectMessageUser() {
|
||||
return this.args.channel?.chatable?.users?.firstObject;
|
||||
}
|
||||
}
|
|
@ -1,35 +0,0 @@
|
|||
<LinkTo
|
||||
@route="chat.channel"
|
||||
@models={{@channel.routeModels}}
|
||||
class={{concat-class
|
||||
"chat-channel-row"
|
||||
(if @channel.focused "focused")
|
||||
(if @channel.currentUserMembership.muted "muted")
|
||||
(if @options.leaveButton "can-leave")
|
||||
(if (eq this.chat.activeChannel.id @channel.id) "active")
|
||||
(if this.channelHasUnread "has-unread")
|
||||
}}
|
||||
tabindex="0"
|
||||
data-chat-channel-id={{@channel.id}}
|
||||
{{did-insert this.startTrackingStatus}}
|
||||
{{will-destroy this.stopTrackingStatus}}
|
||||
>
|
||||
<ChatChannelTitle @channel={{@channel}} />
|
||||
<ChatChannelMetadata @channel={{@channel}} @unreadIndicator={{true}} />
|
||||
|
||||
{{#if (and @options.leaveButton @channel.isFollowing this.site.desktopView)}}
|
||||
<ToggleChannelMembershipButton
|
||||
@channel={{@channel}}
|
||||
@options={{hash
|
||||
leaveClass="btn-flat chat-channel-leave-btn"
|
||||
labelType="none"
|
||||
leaveIcon="times"
|
||||
leaveTitle=(if
|
||||
@channel.isDirectMessageChannel
|
||||
(i18n "chat.direct_messages.leave")
|
||||
(i18n "chat.channel_settings.leave_channel")
|
||||
)
|
||||
}}
|
||||
/>
|
||||
{{/if}}
|
||||
</LinkTo>
|
|
@ -1,28 +0,0 @@
|
|||
import { inject as service } from "@ember/service";
|
||||
import Component from "@glimmer/component";
|
||||
import { action } from "@ember/object";
|
||||
|
||||
export default class ChatChannelRow extends Component {
|
||||
@service router;
|
||||
@service chat;
|
||||
@service currentUser;
|
||||
@service site;
|
||||
|
||||
@action
|
||||
startTrackingStatus() {
|
||||
this.#firstDirectMessageUser?.trackStatus();
|
||||
}
|
||||
|
||||
@action
|
||||
stopTrackingStatus() {
|
||||
this.#firstDirectMessageUser?.stopTrackingStatus();
|
||||
}
|
||||
|
||||
get channelHasUnread() {
|
||||
return this.args.channel.tracking.unreadCount > 0;
|
||||
}
|
||||
|
||||
get #firstDirectMessageUser() {
|
||||
return this.args.channel?.chatable?.users?.firstObject;
|
||||
}
|
||||
}
|
|
@ -12,6 +12,26 @@ import discourseDebounce from "discourse-common/lib/debounce";
|
|||
import { bind } from "discourse-common/utils/decorators";
|
||||
import { updateUserStatusOnMention } from "discourse/lib/update-user-status-on-mention";
|
||||
import { tracked } from "@glimmer/tracking";
|
||||
import ChatMessageSeparatorDate from "discourse/plugins/chat/discourse/components/chat-message-separator-date";
|
||||
import ChatMessageSeparatorNew from "discourse/plugins/chat/discourse/components/chat-message-separator-new";
|
||||
import concatClass from "discourse/helpers/concat-class";
|
||||
import DButton from "discourse/components/d-button";
|
||||
import ChatMessageInReplyToIndicator from "discourse/plugins/chat/discourse/components/chat-message-in-reply-to-indicator";
|
||||
import ChatMessageLeftGutter from "discourse/plugins/chat/discourse/components/chat/message/left-gutter";
|
||||
import ChatMessageAvatar from "discourse/plugins/chat/discourse/components/chat/message/avatar";
|
||||
import ChatMessageError from "discourse/plugins/chat/discourse/components/chat/message/error";
|
||||
import ChatMessageInfo from "discourse/plugins/chat/discourse/components/chat/message/info";
|
||||
import ChatMessageText from "discourse/plugins/chat/discourse/components/chat-message-text";
|
||||
import ChatMessageReaction from "discourse/plugins/chat/discourse/components/chat-message-reaction";
|
||||
import ChatMessageThreadIndicator from "discourse/plugins/chat/discourse/components/chat-message-thread-indicator";
|
||||
import eq from "truth-helpers/helpers/eq";
|
||||
import not from "truth-helpers/helpers/not";
|
||||
import { on } from "@ember/modifier";
|
||||
import { Input } from "@ember/component";
|
||||
import didInsert from "@ember/render-modifiers/modifiers/did-insert";
|
||||
import didUpdate from "@ember/render-modifiers/modifiers/did-update";
|
||||
import willDestroy from "@ember/render-modifiers/modifiers/will-destroy";
|
||||
import ChatOnLongPress from "discourse/plugins/chat/discourse/modifiers/chat/on-long-press";
|
||||
|
||||
let _chatMessageDecorators = [];
|
||||
let _tippyInstances = [];
|
||||
|
@ -28,6 +48,139 @@ export const MENTION_KEYWORDS = ["here", "all"];
|
|||
export const MESSAGE_CONTEXT_THREAD = "thread";
|
||||
|
||||
export default class ChatMessage extends Component {
|
||||
<template>
|
||||
{{! template-lint-disable no-invalid-interactive }}
|
||||
|
||||
{{#if this.shouldRender}}
|
||||
{{#if (eq @context "channel")}}
|
||||
<ChatMessageSeparatorDate
|
||||
@fetchMessagesByDate={{@fetchMessagesByDate}}
|
||||
@message={{@message}}
|
||||
/>
|
||||
<ChatMessageSeparatorNew @message={{@message}} />
|
||||
{{/if}}
|
||||
|
||||
<div
|
||||
class={{concatClass
|
||||
"chat-message-container"
|
||||
(if this.pane.selectingMessages "-selectable")
|
||||
(if @message.highlighted "-highlighted")
|
||||
(if (eq @message.user.id this.currentUser.id) "is-by-current-user")
|
||||
(if @message.staged "-staged" "-persisted")
|
||||
(if this.hasActiveState "-active")
|
||||
(if @message.bookmark "-bookmarked")
|
||||
(if @message.deletedAt "-deleted")
|
||||
(if @message.selected "-selected")
|
||||
(if @message.error "-errored")
|
||||
(if this.showThreadIndicator "has-thread-indicator")
|
||||
(if this.hideUserInfo "-user-info-hidden")
|
||||
(if this.hasReply "has-reply")
|
||||
}}
|
||||
data-id={{@message.id}}
|
||||
data-thread-id={{@message.thread.id}}
|
||||
{{didInsert this.didInsertMessage}}
|
||||
{{didUpdate this.didUpdateMessageId @message.id}}
|
||||
{{didUpdate this.didUpdateMessageVersion @message.version}}
|
||||
{{willDestroy this.willDestroyMessage}}
|
||||
{{on "mouseenter" this.onMouseEnter passive=true}}
|
||||
{{on "mouseleave" this.onMouseLeave passive=true}}
|
||||
{{on "mousemove" this.onMouseMove passive=true}}
|
||||
{{ChatOnLongPress
|
||||
this.onLongPressStart
|
||||
this.onLongPressEnd
|
||||
this.onLongPressCancel
|
||||
}}
|
||||
...attributes
|
||||
>
|
||||
{{#if this.show}}
|
||||
{{#if this.pane.selectingMessages}}
|
||||
<Input
|
||||
@type="checkbox"
|
||||
class="chat-message-selector"
|
||||
@checked={{@message.selected}}
|
||||
{{on "click" this.toggleChecked}}
|
||||
/>
|
||||
{{/if}}
|
||||
|
||||
{{#if this.deletedAndCollapsed}}
|
||||
<div class="chat-message-text -deleted">
|
||||
<DButton
|
||||
@action={{this.expand}}
|
||||
@translatedLabel={{this.deletedMessageLabel}}
|
||||
class="btn-flat chat-message-expand"
|
||||
/>
|
||||
</div>
|
||||
{{else if this.hiddenAndCollapsed}}
|
||||
<div class="chat-message-text -hidden">
|
||||
<DButton
|
||||
@action={{this.expand}}
|
||||
@label="chat.hidden"
|
||||
class="btn-flat chat-message-expand"
|
||||
/>
|
||||
</div>
|
||||
{{else}}
|
||||
<div class="chat-message">
|
||||
{{#unless this.hideReplyToInfo}}
|
||||
<ChatMessageInReplyToIndicator @message={{@message}} />
|
||||
{{/unless}}
|
||||
|
||||
{{#if this.hideUserInfo}}
|
||||
<ChatMessageLeftGutter @message={{@message}} />
|
||||
{{else}}
|
||||
<ChatMessageAvatar @message={{@message}} />
|
||||
{{/if}}
|
||||
|
||||
<div class="chat-message-content">
|
||||
<ChatMessageInfo
|
||||
@message={{@message}}
|
||||
@show={{not this.hideUserInfo}}
|
||||
/>
|
||||
|
||||
<ChatMessageText
|
||||
@cooked={{@message.cooked}}
|
||||
@uploads={{@message.uploads}}
|
||||
@edited={{@message.edited}}
|
||||
>
|
||||
{{#if @message.reactions.length}}
|
||||
<div class="chat-message-reaction-list">
|
||||
{{#each @message.reactions as |reaction|}}
|
||||
<ChatMessageReaction
|
||||
@reaction={{reaction}}
|
||||
@onReaction={{this.messageInteractor.react}}
|
||||
@message={{@message}}
|
||||
@showTooltip={{true}}
|
||||
/>
|
||||
{{/each}}
|
||||
|
||||
{{#if this.shouldRenderOpenEmojiPickerButton}}
|
||||
<DButton
|
||||
@action={{this.messageInteractor.openEmojiPicker}}
|
||||
@icon="discourse-emojis"
|
||||
@title="chat.react"
|
||||
@forwardEvent={{true}}
|
||||
class="chat-message-react-btn"
|
||||
/>
|
||||
{{/if}}
|
||||
</div>
|
||||
{{/if}}
|
||||
</ChatMessageText>
|
||||
|
||||
<ChatMessageError
|
||||
@message={{@message}}
|
||||
@onRetry={{@resendStagedMessage}}
|
||||
/>
|
||||
</div>
|
||||
|
||||
{{#if this.showThreadIndicator}}
|
||||
<ChatMessageThreadIndicator @message={{@message}} />
|
||||
{{/if}}
|
||||
</div>
|
||||
{{/if}}
|
||||
{{/if}}
|
||||
</div>
|
||||
{{/if}}
|
||||
</template>
|
||||
|
||||
@service site;
|
||||
@service dialog;
|
||||
@service currentUser;
|
|
@ -1,130 +0,0 @@
|
|||
{{! template-lint-disable no-invalid-interactive }}
|
||||
|
||||
{{#if this.shouldRender}}
|
||||
{{#if (eq @context "channel")}}
|
||||
<ChatMessageSeparatorDate
|
||||
@fetchMessagesByDate={{@fetchMessagesByDate}}
|
||||
@message={{@message}}
|
||||
/>
|
||||
<ChatMessageSeparatorNew @message={{@message}} />
|
||||
{{/if}}
|
||||
|
||||
<div
|
||||
class={{concat-class
|
||||
"chat-message-container"
|
||||
(if this.pane.selectingMessages "-selectable")
|
||||
(if @message.highlighted "-highlighted")
|
||||
(if (eq @message.user.id this.currentUser.id) "is-by-current-user")
|
||||
(if @message.staged "-staged" "-persisted")
|
||||
(if this.hasActiveState "-active")
|
||||
(if @message.bookmark "-bookmarked")
|
||||
(if @message.deletedAt "-deleted")
|
||||
(if @message.selected "-selected")
|
||||
(if @message.error "-errored")
|
||||
(if this.showThreadIndicator "has-thread-indicator")
|
||||
(if this.hideUserInfo "-user-info-hidden")
|
||||
(if this.hasReply "has-reply")
|
||||
}}
|
||||
data-id={{@message.id}}
|
||||
data-thread-id={{@message.thread.id}}
|
||||
{{did-insert this.didInsertMessage}}
|
||||
{{did-update this.didUpdateMessageId @message.id}}
|
||||
{{did-update this.didUpdateMessageVersion @message.version}}
|
||||
{{will-destroy this.willDestroyMessage}}
|
||||
{{on "mouseenter" this.onMouseEnter passive=true}}
|
||||
{{on "mouseleave" this.onMouseLeave passive=true}}
|
||||
{{on "mousemove" this.onMouseMove passive=true}}
|
||||
{{chat/on-long-press
|
||||
this.onLongPressStart
|
||||
this.onLongPressEnd
|
||||
this.onLongPressCancel
|
||||
}}
|
||||
...attributes
|
||||
>
|
||||
{{#if this.show}}
|
||||
{{#if this.pane.selectingMessages}}
|
||||
<Input
|
||||
@type="checkbox"
|
||||
class="chat-message-selector"
|
||||
@checked={{@message.selected}}
|
||||
{{on "click" this.toggleChecked}}
|
||||
/>
|
||||
{{/if}}
|
||||
|
||||
{{#if this.deletedAndCollapsed}}
|
||||
<div class="chat-message-text -deleted">
|
||||
<DButton
|
||||
@action={{this.expand}}
|
||||
@translatedLabel={{this.deletedMessageLabel}}
|
||||
class="btn-flat chat-message-expand"
|
||||
/>
|
||||
</div>
|
||||
{{else if this.hiddenAndCollapsed}}
|
||||
<div class="chat-message-text -hidden">
|
||||
<DButton
|
||||
@action={{this.expand}}
|
||||
@label="chat.hidden"
|
||||
class="btn-flat chat-message-expand"
|
||||
/>
|
||||
</div>
|
||||
{{else}}
|
||||
<div class="chat-message">
|
||||
{{#unless this.hideReplyToInfo}}
|
||||
<ChatMessageInReplyToIndicator @message={{@message}} />
|
||||
{{/unless}}
|
||||
|
||||
{{#if this.hideUserInfo}}
|
||||
<Chat::Message::LeftGutter @message={{@message}} />
|
||||
{{else}}
|
||||
<Chat::Message::Avatar @message={{@message}} />
|
||||
{{/if}}
|
||||
|
||||
<div class="chat-message-content">
|
||||
<Chat::Message::Info
|
||||
@message={{@message}}
|
||||
@show={{not this.hideUserInfo}}
|
||||
/>
|
||||
|
||||
<ChatMessageText
|
||||
@cooked={{@message.cooked}}
|
||||
@uploads={{@message.uploads}}
|
||||
@edited={{@message.edited}}
|
||||
>
|
||||
{{#if @message.reactions.length}}
|
||||
<div class="chat-message-reaction-list">
|
||||
{{#each @message.reactions as |reaction|}}
|
||||
<ChatMessageReaction
|
||||
@reaction={{reaction}}
|
||||
@onReaction={{this.messageInteractor.react}}
|
||||
@message={{@message}}
|
||||
@showTooltip={{true}}
|
||||
/>
|
||||
{{/each}}
|
||||
|
||||
{{#if this.shouldRenderOpenEmojiPickerButton}}
|
||||
<DButton
|
||||
@action={{this.messageInteractor.openEmojiPicker}}
|
||||
@icon="discourse-emojis"
|
||||
@title="chat.react"
|
||||
@forwardEvent={{true}}
|
||||
class="chat-message-react-btn"
|
||||
/>
|
||||
{{/if}}
|
||||
</div>
|
||||
{{/if}}
|
||||
</ChatMessageText>
|
||||
|
||||
<Chat::Message::Error
|
||||
@message={{@message}}
|
||||
@onRetry={{@resendStagedMessage}}
|
||||
/>
|
||||
</div>
|
||||
|
||||
{{#if this.showThreadIndicator}}
|
||||
<ChatMessageThreadIndicator @message={{@message}} />
|
||||
{{/if}}
|
||||
</div>
|
||||
{{/if}}
|
||||
{{/if}}
|
||||
</div>
|
||||
{{/if}}
|
|
@ -97,6 +97,34 @@
|
|||
position: relative;
|
||||
cursor: pointer;
|
||||
color: var(--primary-high);
|
||||
transition: height 0.25s ease-out, opacity 0.25s ease-out;
|
||||
transform-origin: top center;
|
||||
opacity: 1;
|
||||
will-change: height, opacity, left;
|
||||
|
||||
&__action-btn {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
position: absolute;
|
||||
top: 0px;
|
||||
bottom: 0px;
|
||||
padding-inline: 0.5rem;
|
||||
color: var(--primary);
|
||||
|
||||
&.-cancel {
|
||||
background: var(--tertiary);
|
||||
}
|
||||
|
||||
&.-remove {
|
||||
background: var(--danger);
|
||||
}
|
||||
}
|
||||
|
||||
&.-fade-out {
|
||||
opacity: 0;
|
||||
height: 0 !important;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
@media (hover: none) {
|
||||
&:hover,
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
|
||||
.channels-list-container {
|
||||
background: var(--secondary);
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.chat-channel-row {
|
||||
|
|
Loading…
Reference in New Issue