Skip to content
Merged
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
v-model:is-viewers-detail-open="isViewersDetailOpen"
:channel-id="channelId"
:viewer-ids="viewingUsers"
:inactive-viewer-ids="inactiveViewingUsers"
:pinned-messages-count="pinnedMessages.length"
@move-to-pinned="moveToPinnedPage"
@move-to-events="moveToEventsPage"
Expand All @@ -30,6 +31,7 @@
<template #opener>
<channel-sidebar-hidden
:viewer-ids="viewingUsers"
:inactive-viewer-ids="inactiveViewingUsers"
@open="openSidebar"
@open-viewers="openViewers"
/>
Expand Down Expand Up @@ -57,6 +59,7 @@ const props = defineProps<{
isSidebarOpenerReady: boolean
pinnedMessages: Pin[]
viewingUsers: UserId[]
inactiveViewingUsers: UserId[]
}>()

const { channelsMap } = useChannelsStore()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
<channel-sidebar-viewers
v-model="isViewersDetailOpen"
:viewer-ids="viewerIds"
:inactive-viewer-ids="inactiveViewerIds"
:class="$style.sidebarItem"
/>
<channel-sidebar-qall
Expand Down Expand Up @@ -56,6 +57,7 @@ const props = withDefaults(
defineProps<{
channelId: ChannelId
viewerIds: readonly UserId[]
inactiveViewerIds: readonly UserId[]
pinnedMessagesCount?: number
isViewersDetailOpen: boolean
}>(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
count-clickable
show-count
:user-ids="viewerIds"
:inactive-user-ids="inactiveViewerIds"
:class="$style.rest"
@count-click="emit('openViewers')"
/>
Expand All @@ -27,6 +28,7 @@ import type { UserId } from '/@/types/entity-ids'
withDefaults(
defineProps<{
viewerIds?: readonly UserId[]
inactiveViewerIds?: readonly UserId[]
}>(),
{
viewerIds: () => []
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,14 @@
direction="row"
transition="fade-right"
:user-ids="viewerIds"
:inactive-user-ids="inactiveViewerIds"
@toggle="toggle"
/>
</sidebar-content-container>
<channel-sidebar-viewers-detail
v-else
:viewer-ids="viewerIds"
:inactive-viewer-ids="inactiveViewerIds"
@toggle="toggle"
/>
</template>
Expand All @@ -31,6 +33,7 @@ import { useModelValueSyncer } from '/@/composables/useModelSyncer'
const props = withDefaults(
defineProps<{
viewerIds?: readonly UserId[]
inactiveViewerIds?: readonly UserId[]
modelValue: boolean
}>(),
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,14 @@
<user-icon :user-id="user.id" :size="32" />
<div :class="$style.userName">{{ user.displayName }}</div>
</div>
<div
v-for="user in inactiveUsers"
:key="user.id"
:class="[$style.item, $style.transparent]"
>
<user-icon :user-id="user.id" :size="32" />
<div :class="$style.userName">{{ user.displayName }}</div>
</div>
</sidebar-content-container>
</template>

Expand All @@ -18,9 +26,11 @@ import { useUsersStore } from '/@/store/entities/users'
const props = withDefaults(
defineProps<{
viewerIds?: readonly UserId[]
inactiveViewerIds?: readonly UserId[]
}>(),
{
viewerIds: () => []
viewerIds: () => [],
inactiveViewerIds: () => []
}
)

Expand All @@ -32,6 +42,9 @@ const { usersMap } = useUsersStore()
const users = computed(() =>
props.viewerIds.map(id => usersMap.value.get(id)).filter(isDefined)
)
const inactiveUsers = computed(() =>
props.inactiveViewerIds.map(id => usersMap.value.get(id)).filter(isDefined)
)
</script>

<style lang="scss" module>
Expand All @@ -46,6 +59,9 @@ const users = computed(() =>
margin-bottom: 0;
}
}
.transparent {
opacity: 0.5;
}
.userName {
margin-left: 8px;
font-weight: bold;
Expand Down
5 changes: 4 additions & 1 deletion src/components/Main/MainView/ChannelView/ChannelView.vue
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
:is-sidebar-opener-ready="isReady"
:pinned-messages="pinnedMessages"
:viewing-users="viewingUsers"
:inactive-viewing-users="inactiveViewingUsers"
/>
</template>
</primary-view-frame>
Expand All @@ -40,5 +41,7 @@ const props = defineProps<{

const channelId = toRef(props, 'channelId')
const pinnedMessages = usePinnedMessages(channelId)
const { viewingUsers, typingUsers } = useCurrentViewers(channelId)

const { viewingUsers, inactiveViewingUsers, typingUsers } =
useCurrentViewers(channelId)
</script>
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,9 @@ const {
onLoadAroundMessagesRequest
} = useChannelMessageFetcher(scrollerEle, props)

const { unreadChannelsMap, deleteUnreadChannelWithSend } =
useSubscriptionStore()

const { messagesMap } = useMessagesStore()
const firstUnreadMessageId = computed(() => {
if (!unreadSince.value) return ''
Expand Down Expand Up @@ -114,9 +117,18 @@ const messagePinnedUserMap = computed(
() => new Map(props.pinnedMessages.map(pin => [pin.message.id, pin.userId]))
)

const { unreadChannelsMap } = useSubscriptionStore()
const resetIsReachedLatest = () => {
if (!unreadChannelsMap.value.get(props.channelId)) return
const unread = unreadChannelsMap.value.get(props.channelId)
if (unread === undefined) return
//最後まで読み込まれている時は「ここから未読」の位置を修正し、未読を消す。
//TODO: 関数名とやってることが違いすぎるので、どうにかする。今日はもう眠いので寝る。
if (
unread.updatedAt ===
messagesMap.value.get(messageIds.value.at(-1) ?? '')?.createdAt
) {
unreadSince.value = unread.since
deleteUnreadChannelWithSend(props.channelId)
}
isReachedLatest.value = false
}

Expand Down
8 changes: 7 additions & 1 deletion src/components/Main/MainView/DMView/DMSidebar/DMSidebar.vue
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
<template #content>
<sidebar-content
:viewer-ids="viewingUsers"
:inactive-viewer-ids="inactiveViewingUsers"
:pinned-messages-count="pinnedMessages.length"
@move-to-pinned="moveToPinnedPage"
@move-to-events="moveToEventsPage"
Expand All @@ -26,7 +27,11 @@
/>
</template>
<template #opener>
<channel-sidebar-hidden :viewer-ids="viewingUsers" @open="openSidebar" />
<channel-sidebar-hidden
:viewer-ids="viewingUsers"
:inactive-viewer-ids="inactiveViewingUsers"
@open="openSidebar"
/>
</template>
</primary-view-sidebar>
</template>
Expand All @@ -49,6 +54,7 @@ defineProps<{
isSidebarOpenerReady: boolean
pinnedMessages: Pin[]
viewingUsers: UserId[]
inactiveViewingUsers: UserId[]
}>()

const {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
<channel-sidebar-viewers
v-model="isViewersDetailOpen"
:viewer-ids="viewerIds"
:inactive-viewer-ids="inactiveViewerIds"
:class="$style.item"
/>
<channel-sidebar-pinned
Expand All @@ -27,6 +28,7 @@ import { ref } from 'vue'
withDefaults(
defineProps<{
viewerIds: readonly UserId[]
inactiveViewerIds?: readonly UserId[]
pinnedMessagesCount?: number
}>(),
{
Expand Down
4 changes: 3 additions & 1 deletion src/components/Main/MainView/DMView/DMView.vue
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
:is-sidebar-opener-ready="isReady"
:pinned-messages="pinnedMessages"
:viewing-users="viewingUsers"
:inactive-viewing-users="inactiveViewingUsers"
/>
</template>
</primary-view-frame>
Expand All @@ -42,5 +43,6 @@ const props = defineProps<{

const channelId = toRef(props, 'channelId')
const pinnedMessages = usePinnedMessages(channelId)
const { viewingUsers, typingUsers } = useCurrentViewers(channelId)
const { viewingUsers, inactiveViewingUsers, typingUsers } =
useCurrentViewers(channelId)
</script>
15 changes: 12 additions & 3 deletions src/components/Main/MainView/MessagesScroller/MessagesScroller.vue
Original file line number Diff line number Diff line change
Expand Up @@ -191,7 +191,6 @@ watch(
(ids, prevIds) => {
if (!rootRef.value) return
/* state.height の更新を忘れないようにすること */

const newHeight = rootRef.value.scrollHeight
if (
props.lastLoadingDirection === 'latest' ||
Expand All @@ -206,7 +205,6 @@ watch(
if (ids.length - prevIds.length === 0) {
const scrollBottom =
rootRef.value.scrollTop + rootRef.value.clientHeight

// 一番下のメッセージあたりを見ているときに、
// 新規に一つ追加された場合は一番下までスクロール
if (state.height - 50 <= scrollBottom) {
Expand Down Expand Up @@ -246,16 +244,27 @@ const requestLoadMessages = () => {
const handleScroll = throttle(17, requestLoadMessages)

const visibilitychangeListener = () => {
emit('resetIsReachedLatest')
if (document.visibilityState === 'visible') {
requestLoadMessages()
nextTick(requestLoadMessages)
}
}
const focusListener = () => {
emit('resetIsReachedLatest')
nextTick(requestLoadMessages)
}
const blurListener = () => {
emit('resetIsReachedLatest')
}
onMounted(() => {
document.addEventListener('visibilitychange', visibilitychangeListener)
window.addEventListener('focus', focusListener)
window.addEventListener('blur', blurListener)
})
onUnmounted(() => {
document.removeEventListener('visibilitychange', visibilitychangeListener)
window.removeEventListener('focus', focusListener)
window.removeEventListener('blur', blurListener)
})

const { onClick } = useMarkdownInternalHandler()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,10 @@ const useMessageFetcher = (
isLoading.value = false
isInitialLoad.value = false
lastLoadingDirection.value = 'latter'
// 一番新しいメッセージに達した時は`latest`にする
if (isReachedLatest.value) {
lastLoadingDirection.value = 'latest'
}
messageIds.value = [...new Set([...messageIds.value, ...newMessageIds])]
}
)
Expand Down
9 changes: 7 additions & 2 deletions src/components/UI/UserIcon.vue
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<template>
<div
:role="isClickable ? 'button' : 'img'"
:class="$style.container"
:class="[$style.container, isInactive && $style.transparent]"
:style="styles.container"
@click.prevent.stop="openModal"
>
Expand Down Expand Up @@ -42,12 +42,14 @@ const props = withDefaults(
indicatorSize?: number
preventModal?: boolean
hasNotification?: boolean
isInactive?: boolean
}>(),
{
size: 36,
indicatorSize: 10,
preventModal: false,
hasNotification: false
hasNotification: false,
isInactive: false
}
)

Expand Down Expand Up @@ -109,4 +111,7 @@ const { isClickable, openModal } = useUserModalOpener(
top: 0;
right: 0;
}
.transparent {
opacity: 0.5;
}
</style>
21 changes: 20 additions & 1 deletion src/components/UI/UserIconEllipsisList.vue
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,16 @@
>
+{{ inVisibleCount }}
</span>
<user-icon
v-for="userId in visibleInactiveIconIds"
:key="userId"
:class="$style.userIcon"
:user-id="userId"
:size="iconSize"
:prevent-modal="preventModal"
:style="styles.userIcon"
is-inactive
/>
<user-icon
v-for="userId in visibleIconIds"
:key="userId"
Expand All @@ -40,6 +50,7 @@ const props = withDefaults(
max?: number
showCount?: boolean
userIds?: readonly UserId[]
inactiveUserIds?: readonly UserId[]
borderWidth?: number
iconSize?: IconSize
overlap?: number
Expand All @@ -51,6 +62,7 @@ const props = withDefaults(
max: 3,
showCount: true,
userIds: () => [],
inactiveUserIds: () => [],
borderWidth: 4,
iconSize: 40 as const,
overlap: 12,
Expand Down Expand Up @@ -91,7 +103,14 @@ const styles = computed(() => {
const visibleIconIds = computed(() =>
[...props.userIds].reverse().slice(0, props.max)
)
const inVisibleCount = computed(() => props.userIds.length - props.max)
const visibleInactiveIconIds = computed(() =>
[...props.inactiveUserIds]
.reverse()
.slice(0, props.max - visibleIconIds.value.length)
)
const inVisibleCount = computed(
() => props.userIds.length + props.inactiveUserIds.length - props.max
)

const onCountClick = () => {
if (props.countClickable) {
Expand Down
Loading
Loading