Skip to content

Commit ed8122e

Browse files
authored
chore: fix chat alignment and disable auto focus for mobile (#233)
1 parent a340c9e commit ed8122e

3 files changed

Lines changed: 67 additions & 49 deletions

File tree

components/chat/ChatLobby.vue

Lines changed: 20 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -353,6 +353,10 @@ export default {
353353
type: Object as PropType<unknown>,
354354
required: false,
355355
},
356+
disableAutoFocusOnActivate: {
357+
type: Boolean,
358+
default: false,
359+
},
356360
},
357361
data() {
358362
return {
@@ -604,23 +608,25 @@ export default {
604608
}
605609
606610
// When activating a tab, always jump to the bottom so the latest
607-
// messages are immediately visible.
611+
// messages are immediately visible, and optionally focus the input.
608612
if (active && !this.isMinimized) {
609613
this.safeScrollToBottom(true);
610-
this.$nextTick(() => {
611-
const chatInput = this.$refs.chatInputRef as any;
612-
if (chatInput) {
613-
if (typeof chatInput.focus === "function") {
614-
chatInput.focus();
615-
} else if (chatInput.$el) {
616-
// Fallback: try to focus the first input inside the component root.
617-
const el = chatInput.$el.querySelector(
618-
"input, textarea, [tabindex]",
619-
) as HTMLElement | null;
620-
el?.focus();
614+
if (!this.disableAutoFocusOnActivate) {
615+
this.$nextTick(() => {
616+
const chatInput = this.$refs.chatInputRef as any;
617+
if (chatInput) {
618+
if (typeof chatInput.focus === "function") {
619+
chatInput.focus();
620+
} else if (chatInput.$el) {
621+
// Fallback: try to focus the first input inside the component root.
622+
const el = chatInput.$el.querySelector(
623+
"input, textarea, [tabindex]",
624+
) as HTMLElement | null;
625+
el?.focus();
626+
}
621627
}
622-
}
623-
});
628+
});
629+
}
624630
}
625631
},
626632
},

components/chat/ChatMessage.vue

Lines changed: 43 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -4,43 +4,48 @@ import PlayerDisplay from "~/components/PlayerDisplay.vue";
44
</script>
55

66
<template>
7-
<div class="my-1.5 text-[11px] leading-snug">
8-
<div class="grid grid-cols-[40px_1fr] gap-x-1.5 items-start">
9-
<div class="mt-0.5 mx-2">
10-
<PlayerDisplay
11-
:player="message.from"
12-
size="sm"
13-
:compact="true"
14-
:align-top="true"
15-
:show-online="false"
16-
:show-elo="false"
17-
:show-steam-id="false"
18-
:show-add-friend="false"
19-
:tooltip="false"
20-
:linkable="false"
21-
:show-name="false"
22-
:show-flag="false"
23-
:show-role="false"
24-
v-if="!isSameSender || !isCloseTogether"
25-
/>
26-
</div>
7+
<div
8+
:class="[
9+
'relative pl-12 text-[11px] leading-snug',
10+
isSameSender && isCloseTogether ? 'mt-0.5 mb-0.5' : 'my-1.5',
11+
]"
12+
>
13+
<div
14+
v-if="showMeta"
15+
class="absolute left-2 top-0"
16+
>
17+
<PlayerDisplay
18+
:player="message.from"
19+
size="sm"
20+
:compact="true"
21+
:align-top="true"
22+
:show-online="false"
23+
:show-elo="false"
24+
:show-steam-id="false"
25+
:show-add-friend="false"
26+
:tooltip="false"
27+
:linkable="false"
28+
:show-name="false"
29+
:show-flag="false"
30+
:show-role="false"
31+
/>
32+
</div>
2733

28-
<div>
29-
<div
30-
class="flex items-center space-x-1.5 text-muted-foreground text-[10px]"
31-
v-if="!isSameSender || !isCloseTogether"
32-
>
33-
<h4 class="font-semibold truncate max-w-[140px]">
34-
{{ message.from.name }}
35-
</h4>
36-
<span class="text-[10px] whitespace-nowrap">
37-
<time-ago :date="message.timestamp"></time-ago>
38-
</span>
39-
</div>
40-
<p class="text-[11px] leading-snug break-words">
41-
{{ message.message }}
42-
</p>
34+
<div>
35+
<div
36+
v-if="showMeta"
37+
class="flex items-center space-x-1.5 text-muted-foreground text-[10px]"
38+
>
39+
<h4 class="font-semibold truncate max-w-[140px]">
40+
{{ message.from.name }}
41+
</h4>
42+
<span class="text-[10px] whitespace-nowrap">
43+
<time-ago :date="message.timestamp"></time-ago>
44+
</span>
4345
</div>
46+
<p class="text-[11px] leading-snug break-words">
47+
{{ message.message }}
48+
</p>
4449
</div>
4550
</div>
4651
</template>
@@ -75,6 +80,9 @@ export default {
7580
7681
return previousTimestamp > messageTimestamp;
7782
},
83+
showMeta() {
84+
return !this.isSameSender || !this.isCloseTogether;
85+
},
7886
},
7987
};
8088
</script>

components/hub/ChatPanel.vue

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
<script setup lang="ts">
22
import { ref, computed, watch } from "vue";
3+
import { useMediaQuery } from "@vueuse/core";
34
import {
45
Megaphone,
56
Merge,
@@ -29,6 +30,7 @@ const { tabs, unreadCounts, setActiveTab, resetUnread, incrementUnread } =
2930
useChatTabs();
3031
3132
const matchLobbyStore = useMatchLobbyStore();
33+
const isMobile = useMediaQuery("(max-width: 768px)");
3234
3335
const activeChatId = ref<string | null>(null);
3436
const isOverlayOpen = ref(false);
@@ -470,6 +472,7 @@ function handlePopOut() {
470472
:frameless="true"
471473
:is-global-context="true"
472474
:hide-participants-summary="true"
475+
:disable-auto-focus-on-activate="isMobile"
473476
:is-active-tab="
474477
tab.id === activeChatId && isSidebarOpen && isTabActive
475478
"
@@ -567,6 +570,7 @@ function handlePopOut() {
567570
:tab-id="tab.id"
568571
:frameless="true"
569572
:is-global-context="true"
573+
:disable-auto-focus-on-activate="isMobile"
570574
:is-active-tab="
571575
tab.id === activeOverlayTab.id && isSidebarOpen && isTabActive
572576
"

0 commit comments

Comments
 (0)