mirror of
https://github.com/hcengineering/platform.git
synced 2025-01-24 20:40:59 +00:00
Improve directs sort order (#5588)
Signed-off-by: Kristina Fefelova <kristin.fefelova@gmail.com>
This commit is contained in:
parent
f560afe0b9
commit
adca777b33
@ -21,10 +21,11 @@
|
||||
import contact from '@hcengineering/contact'
|
||||
import { getResource, translate } from '@hcengineering/platform'
|
||||
import view from '@hcengineering/view'
|
||||
import { personAccountByIdStore, statusByUserStore } from '@hcengineering/contact-resources'
|
||||
|
||||
import ChatNavItem from './ChatNavItem.svelte'
|
||||
import chunter from '../../../plugin'
|
||||
import { ChatNavItemModel } from '../types'
|
||||
import { ChatNavItemModel, SortFnOptions } from '../types'
|
||||
import { getObjectIcon, getChannelName } from '../../../utils'
|
||||
import { navigatorStateStore, toggleSections } from '../utils'
|
||||
|
||||
@ -35,11 +36,12 @@
|
||||
export let actions: Action[] = []
|
||||
export let maxItems: number | undefined = undefined
|
||||
export let objectId: Ref<Doc> | undefined
|
||||
export let sortFn: (items: ChatNavItemModel[], contexts: DocNotifyContext[]) => ChatNavItemModel[]
|
||||
export let sortFn: (items: ChatNavItemModel[], options: SortFnOptions) => ChatNavItemModel[]
|
||||
|
||||
const client = getClient()
|
||||
const hierarchy = client.getHierarchy()
|
||||
|
||||
let sortedItems: ChatNavItemModel[] = []
|
||||
let items: ChatNavItemModel[] = []
|
||||
let visibleItems: ChatNavItemModel[] = []
|
||||
|
||||
@ -50,12 +52,17 @@
|
||||
$: isCollapsed = $navigatorStateStore.collapsedSections.includes(id)
|
||||
|
||||
$: void getChatNavItems(objects).then((res) => {
|
||||
items = sortFn(res, contexts)
|
||||
items = res
|
||||
})
|
||||
|
||||
$: sortedItems = sortFn(items, {
|
||||
contexts,
|
||||
userStatusByAccount: $statusByUserStore,
|
||||
personAccountById: $personAccountByIdStore
|
||||
})
|
||||
$: canShowMore = !!maxItems && items.length > maxItems
|
||||
|
||||
$: visibleItems = getVisibleItems(canShowMore, isShownMore, maxItems, items, objectId)
|
||||
$: visibleItems = getVisibleItems(canShowMore, isShownMore, maxItems, sortedItems, objectId)
|
||||
|
||||
async function getChatNavItems (objects: Doc[]): Promise<ChatNavItemModel[]> {
|
||||
const items: ChatNavItemModel[] = []
|
||||
@ -132,7 +139,7 @@
|
||||
}
|
||||
</script>
|
||||
|
||||
{#if items.length > 0 && contexts.length > 0}
|
||||
{#if visibleItems.length > 0 && contexts.length > 0}
|
||||
<NavGroup
|
||||
title={header}
|
||||
categoryName={id}
|
||||
@ -161,7 +168,7 @@
|
||||
</div>
|
||||
{/if}
|
||||
{:else if objectId}
|
||||
{@const item = items.find(({ id }) => id === objectId)}
|
||||
{@const item = visibleItems.find(({ id }) => id === objectId)}
|
||||
{#if item}
|
||||
{@const context = contexts.find(({ attachedTo }) => attachedTo === item.id)}
|
||||
<ChatNavItem {context} isSelected {item} on:select />
|
||||
|
@ -13,17 +13,24 @@
|
||||
// limitations under the License.
|
||||
//
|
||||
import { type Asset, type IntlString } from '@hcengineering/platform'
|
||||
import { type Doc, type DocumentQuery, type Ref } from '@hcengineering/core'
|
||||
import { type Account, type Doc, type DocumentQuery, type IdMap, type Ref, type UserStatus } from '@hcengineering/core'
|
||||
import { type DocNotifyContext } from '@hcengineering/notification'
|
||||
import { type AnySvelteComponent, type IconSize, type Action } from '@hcengineering/ui'
|
||||
import { type PersonAccount } from '@hcengineering/contact'
|
||||
|
||||
export type ChatGroup = 'activity' | 'direct' | 'channels' | 'starred'
|
||||
|
||||
export interface SortFnOptions {
|
||||
contexts: DocNotifyContext[]
|
||||
userStatusByAccount: Map<Ref<Account>, UserStatus>
|
||||
personAccountById: IdMap<PersonAccount>
|
||||
}
|
||||
|
||||
export interface ChatNavGroupModel {
|
||||
id: ChatGroup
|
||||
label?: IntlString
|
||||
query: DocumentQuery<DocNotifyContext>
|
||||
sortFn: (items: ChatNavItemModel[], contexts: DocNotifyContext[]) => ChatNavItemModel[]
|
||||
sortFn: (items: ChatNavItemModel[], options: SortFnOptions) => ChatNavItemModel[]
|
||||
wrap: boolean
|
||||
getActionsFn?: (contexts: DocNotifyContext[]) => Action[]
|
||||
maxSectionItems?: number
|
||||
|
@ -22,7 +22,10 @@ import {
|
||||
type WithLookup,
|
||||
hasAccountRole,
|
||||
getCurrentAccount,
|
||||
AccountRole
|
||||
AccountRole,
|
||||
type IdMap,
|
||||
type Account,
|
||||
type UserStatus
|
||||
} from '@hcengineering/core'
|
||||
import { createQuery, getClient, MessageBox } from '@hcengineering/presentation'
|
||||
import { get, writable } from 'svelte/store'
|
||||
@ -32,9 +35,10 @@ import attachment, { type SavedAttachments } from '@hcengineering/attachment'
|
||||
import activity, { type ActivityMessage } from '@hcengineering/activity'
|
||||
import { InboxNotificationsClientImpl } from '@hcengineering/notification-resources'
|
||||
import { type Action, showPopup } from '@hcengineering/ui'
|
||||
import contact from '@hcengineering/contact'
|
||||
import contact, { type PersonAccount } from '@hcengineering/contact'
|
||||
import { type DirectMessage } from '@hcengineering/chunter'
|
||||
|
||||
import { type ChatNavGroupModel, type ChatNavItemModel } from './types'
|
||||
import { type ChatNavGroupModel, type ChatNavItemModel, type SortFnOptions } from './types'
|
||||
import chunter from '../../plugin'
|
||||
|
||||
const channelStorageKey = 'chunter.openedChannel'
|
||||
@ -184,7 +188,7 @@ export const chatNavGroupModels: ChatNavGroupModel[] = [
|
||||
},
|
||||
{
|
||||
id: 'direct',
|
||||
sortFn: sortAlphabetically,
|
||||
sortFn: sortDirects,
|
||||
wrap: true,
|
||||
getActionsFn: getDirectActions,
|
||||
query: {
|
||||
@ -212,7 +216,85 @@ function sortAlphabetically (items: ChatNavItemModel[]): ChatNavItemModel[] {
|
||||
return items.sort((i1, i2) => i1.title.localeCompare(i2.title))
|
||||
}
|
||||
|
||||
function sortActivityChannels (items: ChatNavItemModel[], contexts: DocNotifyContext[]): ChatNavItemModel[] {
|
||||
function getDirectCompanion (
|
||||
direct: DirectMessage,
|
||||
me: PersonAccount,
|
||||
personAccountById: IdMap<PersonAccount>
|
||||
): Ref<Account> | undefined {
|
||||
return direct.members.find((member) => personAccountById.get(member as Ref<PersonAccount>)?.person !== me.person)
|
||||
}
|
||||
|
||||
function isOnline (account: Ref<Account> | undefined, userStatusByAccount: Map<Ref<Account>, UserStatus>): boolean {
|
||||
if (account === undefined) {
|
||||
return false
|
||||
}
|
||||
|
||||
return userStatusByAccount.get(account)?.online ?? false
|
||||
}
|
||||
|
||||
function isGroupChat (direct: DirectMessage, personAccountById: IdMap<PersonAccount>): boolean {
|
||||
const persons = new Set(
|
||||
direct.members
|
||||
.map((member) => personAccountById.get(member as Ref<PersonAccount>)?.person)
|
||||
.filter((it) => it !== undefined)
|
||||
)
|
||||
|
||||
return persons.size > 2
|
||||
}
|
||||
|
||||
function sortDirects (items: ChatNavItemModel[], option: SortFnOptions): ChatNavItemModel[] {
|
||||
const { userStatusByAccount, personAccountById } = option
|
||||
const me = getCurrentAccount() as PersonAccount
|
||||
|
||||
return items.sort((i1, i2) => {
|
||||
const direct1 = i1.object as DirectMessage
|
||||
const direct2 = i2.object as DirectMessage
|
||||
|
||||
const isGroupChat1 = isGroupChat(direct1, personAccountById)
|
||||
const isGroupChat2 = isGroupChat(direct2, personAccountById)
|
||||
|
||||
if (isGroupChat1 && isGroupChat2) {
|
||||
return i1.title.localeCompare(i2.title)
|
||||
}
|
||||
|
||||
if (isGroupChat1 && !isGroupChat2) {
|
||||
const isOnline2 = isOnline(getDirectCompanion(direct2, me, personAccountById), userStatusByAccount)
|
||||
return isOnline2 ? 1 : -1
|
||||
}
|
||||
|
||||
if (!isGroupChat1 && isGroupChat2) {
|
||||
const isOnline1 = isOnline(getDirectCompanion(direct1, me, personAccountById), userStatusByAccount)
|
||||
return isOnline1 ? -1 : 1
|
||||
}
|
||||
|
||||
const account1 = getDirectCompanion(direct1, me, personAccountById)
|
||||
const account2 = getDirectCompanion(direct2, me, personAccountById)
|
||||
|
||||
if (account1 === undefined) {
|
||||
return 1
|
||||
}
|
||||
|
||||
if (account2 === undefined) {
|
||||
return -1
|
||||
}
|
||||
|
||||
const isOnline1 = isOnline(account1, userStatusByAccount)
|
||||
const isOnline2 = isOnline(account2, userStatusByAccount)
|
||||
|
||||
if (isOnline1 === isOnline2) {
|
||||
return i1.title.localeCompare(i2.title)
|
||||
}
|
||||
|
||||
if (isOnline1 && !isOnline2) {
|
||||
return -1
|
||||
}
|
||||
|
||||
return 1
|
||||
})
|
||||
}
|
||||
|
||||
function sortActivityChannels (items: ChatNavItemModel[], option: SortFnOptions): ChatNavItemModel[] {
|
||||
const { contexts } = option
|
||||
const contextByDoc = new Map(contexts.map((context) => [context.attachedTo, context]))
|
||||
|
||||
return items.sort((i1, i2) => {
|
||||
|
Loading…
Reference in New Issue
Block a user