Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 20 additions & 14 deletions components/chat/ChatLobby.vue
Original file line number Diff line number Diff line change
Expand Up @@ -353,6 +353,10 @@ export default {
type: Object as PropType<unknown>,
required: false,
},
disableAutoFocusOnActivate: {
type: Boolean,
default: false,
},
},
data() {
return {
Expand Down Expand Up @@ -604,23 +608,25 @@ export default {
}

// When activating a tab, always jump to the bottom so the latest
// messages are immediately visible.
// messages are immediately visible, and optionally focus the input.
if (active && !this.isMinimized) {
this.safeScrollToBottom(true);
this.$nextTick(() => {
const chatInput = this.$refs.chatInputRef as any;
if (chatInput) {
if (typeof chatInput.focus === "function") {
chatInput.focus();
} else if (chatInput.$el) {
// Fallback: try to focus the first input inside the component root.
const el = chatInput.$el.querySelector(
"input, textarea, [tabindex]",
) as HTMLElement | null;
el?.focus();
if (!this.disableAutoFocusOnActivate) {
this.$nextTick(() => {
const chatInput = this.$refs.chatInputRef as any;
if (chatInput) {
if (typeof chatInput.focus === "function") {
chatInput.focus();
} else if (chatInput.$el) {
// Fallback: try to focus the first input inside the component root.
const el = chatInput.$el.querySelector(
"input, textarea, [tabindex]",
) as HTMLElement | null;
el?.focus();
}
}
}
});
});
}
}
},
},
Expand Down
78 changes: 43 additions & 35 deletions components/chat/ChatMessage.vue
Original file line number Diff line number Diff line change
Expand Up @@ -4,43 +4,48 @@ import PlayerDisplay from "~/components/PlayerDisplay.vue";
</script>

<template>
<div class="my-1.5 text-[11px] leading-snug">
<div class="grid grid-cols-[40px_1fr] gap-x-1.5 items-start">
<div class="mt-0.5 mx-2">
<PlayerDisplay
:player="message.from"
size="sm"
:compact="true"
:align-top="true"
:show-online="false"
:show-elo="false"
:show-steam-id="false"
:show-add-friend="false"
:tooltip="false"
:linkable="false"
:show-name="false"
:show-flag="false"
:show-role="false"
v-if="!isSameSender || !isCloseTogether"
/>
</div>
<div
:class="[
'relative pl-12 text-[11px] leading-snug',
isSameSender && isCloseTogether ? 'mt-0.5 mb-0.5' : 'my-1.5',
]"
>
<div
v-if="showMeta"
class="absolute left-2 top-0"
>
<PlayerDisplay
:player="message.from"
size="sm"
:compact="true"
:align-top="true"
:show-online="false"
:show-elo="false"
:show-steam-id="false"
:show-add-friend="false"
:tooltip="false"
:linkable="false"
:show-name="false"
:show-flag="false"
:show-role="false"
/>
</div>

<div>
<div
class="flex items-center space-x-1.5 text-muted-foreground text-[10px]"
v-if="!isSameSender || !isCloseTogether"
>
<h4 class="font-semibold truncate max-w-[140px]">
{{ message.from.name }}
</h4>
<span class="text-[10px] whitespace-nowrap">
<time-ago :date="message.timestamp"></time-ago>
</span>
</div>
<p class="text-[11px] leading-snug break-words">
{{ message.message }}
</p>
<div>
<div
v-if="showMeta"
class="flex items-center space-x-1.5 text-muted-foreground text-[10px]"
>
<h4 class="font-semibold truncate max-w-[140px]">
{{ message.from.name }}
</h4>
<span class="text-[10px] whitespace-nowrap">
<time-ago :date="message.timestamp"></time-ago>
</span>
</div>
<p class="text-[11px] leading-snug break-words">
{{ message.message }}
</p>
</div>
</div>
</template>
Expand Down Expand Up @@ -75,6 +80,9 @@ export default {

return previousTimestamp > messageTimestamp;
},
showMeta() {
return !this.isSameSender || !this.isCloseTogether;
},
},
};
</script>
4 changes: 4 additions & 0 deletions components/hub/ChatPanel.vue
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
<script setup lang="ts">
import { ref, computed, watch } from "vue";
import { useMediaQuery } from "@vueuse/core";
import {
Megaphone,
Merge,
Expand Down Expand Up @@ -29,6 +30,7 @@ const { tabs, unreadCounts, setActiveTab, resetUnread, incrementUnread } =
useChatTabs();

const matchLobbyStore = useMatchLobbyStore();
const isMobile = useMediaQuery("(max-width: 768px)");

const activeChatId = ref<string | null>(null);
const isOverlayOpen = ref(false);
Expand Down Expand Up @@ -470,6 +472,7 @@ function handlePopOut() {
:frameless="true"
:is-global-context="true"
:hide-participants-summary="true"
:disable-auto-focus-on-activate="isMobile"
:is-active-tab="
tab.id === activeChatId && isSidebarOpen && isTabActive
"
Expand Down Expand Up @@ -567,6 +570,7 @@ function handlePopOut() {
:tab-id="tab.id"
:frameless="true"
:is-global-context="true"
:disable-auto-focus-on-activate="isMobile"
:is-active-tab="
tab.id === activeOverlayTab.id && isSidebarOpen && isTabActive
"
Expand Down