Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

UBERF-5024: add reactions control to inbox #4414

Merged
merged 3 commits into from
Jan 23, 2024
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
2 changes: 1 addition & 1 deletion plugins/activity-resources/src/activityMessagesUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -244,7 +244,7 @@ function groupByTime<T extends ActivityMessage> (messages: T[]): T[][] {

function getDocUpdateMessageKey (message: DocUpdateMessage): string {
const personAccountById = get(personAccountByIdStore)
const person = personAccountById.get(message.modifiedBy as any)?.person ?? message.modifiedBy
const person = personAccountById.get(message.createdBy as any)?.person ?? message.createdBy

if (message.action === 'update') {
return [message._class, message.attachedTo, message.action, person, getAttributeUpdatesKey(message)].join('_')
Expand Down
1 change: 1 addition & 0 deletions plugins/activity-resources/src/components/Replies.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,7 @@
}
const loc = getLocation()
loc.path[4] = message._id
loc.query = { ...loc.query, thread: message._id }
navigate(loc)
}
</script>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -178,8 +178,9 @@
class:opened={isActionMenuOpened || message.isPinned}
>
{#if withActions}
<AddReactionAction object={message} on:open={handleActionMenuOpened} on:close={handleActionMenuClosed} />

{#if withFlatActions}
<AddReactionAction object={message} />
<PinMessageAction object={message} />
<SaveMessageAction object={message} />

Expand Down Expand Up @@ -231,11 +232,9 @@
}

&.embedded {
padding: 0;

.content {
padding: 0.75rem 0.75rem 0.75rem 0;
}
padding: 0.75rem 0 0 0;
gap: 0.25rem;
border-radius: 0;
}

.actions {
Expand Down Expand Up @@ -292,7 +291,7 @@
}

.embeddedMarker {
width: 6px;
width: 0.25rem;
border-radius: 0.5rem;
background: var(--secondary-button-default);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,10 @@

function handleReply (): void {
const loc = getLocation()

loc.fragment = notification.docNotifyContext
loc.query = { message: notification.attachedTo }
loc.query = { thread: parentMessage?._id ?? message._id }

navigate(loc)
}
</script>
Expand Down
1 change: 1 addition & 0 deletions plugins/activity-resources/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ export { default as ActivityDocLink } from './components/ActivityDocLink.svelte'
export { default as ReactionPresenter } from './components/reactions/ReactionPresenter.svelte'
export { default as ActivityMessageNotificationLabel } from './components/activity-message/ActivityMessageNotificationLabel.svelte'
export { default as ActivityMessageHeader } from './components/activity-message/ActivityMessageHeader.svelte'
export { default as AddReactionAction } from './components/reactions/AddReactionAction.svelte'

export default async (): Promise<Resources> => ({
component: {
Expand Down
2 changes: 1 addition & 1 deletion plugins/chunter-resources/src/components/Channel.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@

onDestroy(unsubscribe)

$: isDocChannel = !hierarchy.isDerived(context.attachedToClass, chunter.class.ChunterSpace)
$: isDocChannel = !hierarchy.isDerived(object._class, chunter.class.ChunterSpace)
$: messagesClass = isDocChannel ? activity.class.ActivityMessage : chunter.class.ChatMessage
$: collection = isDocChannel ? 'comments' : 'messages'
</script>
Expand Down
33 changes: 25 additions & 8 deletions plugins/chunter-resources/src/components/ChannelPanel.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,13 @@
// limitations under the License.
-->
<script lang="ts">
import { Class, Ref } from '@hcengineering/core'
import { DocNotifyContext } from '@hcengineering/notification'
import { Class, Ref, WithLookup } from '@hcengineering/core'
import { ActivityInboxNotification, DocNotifyContext } from '@hcengineering/notification'
import { createQuery, getClient } from '@hcengineering/presentation'
import activity, { ActivityMessage } from '@hcengineering/activity'
import { ChunterSpace } from '@hcengineering/chunter'
import { InboxNotificationsClientImpl } from '@hcengineering/notification-resources'
import { location as locationStore } from '@hcengineering/ui'
import { location as locationStore, Location } from '@hcengineering/ui'
import { isReactionMessage } from '@hcengineering/activity-resources'

import ChannelPresenter from './ChannelView.svelte'
Expand All @@ -37,22 +37,39 @@

let object: ChunterSpace | undefined = undefined
let threadId: Ref<ActivityMessage> | undefined = undefined
let notification: WithLookup<ActivityInboxNotification> | undefined = undefined

let selectedMessageId: Ref<ActivityMessage> | undefined = undefined
let loc: Location | undefined = undefined

locationStore.subscribe((newLocation) => {
loc = newLocation
selectedMessageId = newLocation.query?.message as Ref<ActivityMessage> | undefined
})

$: notification = selectedMessageId
? $activityInboxNotificationsStore.find(({ attachedTo }) => attachedTo === selectedMessageId)
: undefined

$: threadId =
hierarchy.isDerived(context.attachedToClass, activity.class.ActivityMessage) &&
!isReactionMessage(notification?.$lookup?.attachedTo)
? (context.attachedTo as Ref<ActivityMessage>)
: undefined
$: updateThreadId(context, notification, loc)

function updateThreadId (
context: DocNotifyContext,
notification?: WithLookup<ActivityInboxNotification>,
loc?: Location
) {
threadId = loc?.query?.thread as Ref<ActivityMessage> | undefined

if (threadId !== undefined) {
return
}

threadId =
hierarchy.isDerived(context.attachedToClass, activity.class.ActivityMessage) &&
!isReactionMessage(notification?.$lookup?.attachedTo)
? (context.attachedTo as Ref<ActivityMessage>)
: undefined
}

$: objectQuery.query(_class, { _id }, (res) => {
object = res[0]
Expand Down
1 change: 1 addition & 0 deletions plugins/chunter-resources/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -189,6 +189,7 @@ export async function deleteChatMessage (message: ChatMessage): Promise<void> {
export async function replyToThread (message: ActivityMessage): Promise<void> {
const loc = getLocation()
loc.path[4] = message._id
loc.query = { ...loc.query, thread: message._id }
navigate(loc)
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
<script lang="ts">
import { ActionIcon, Component, IconMoreH, Label, showPopup } from '@hcengineering/ui'
import notification, {
ActivityInboxNotification,
ActivityNotificationViewlet,
DisplayInboxNotification,
DocNotifyContext
Expand All @@ -23,19 +24,24 @@
import { getDocTitle, getDocIdentifier, Menu } from '@hcengineering/view-resources'
import chunter from '@hcengineering/chunter'
import { createEventDispatcher } from 'svelte'
import { WithLookup } from '@hcengineering/core'
import { AddReactionAction } from '@hcengineering/activity-resources'

import InboxNotificationPresenter from './inbox/InboxNotificationPresenter.svelte'
import NotifyContextIcon from './NotifyContextIcon.svelte'
import NotifyMarker from './NotifyMarker.svelte'

export let value: DocNotifyContext
export let notifications: DisplayInboxNotification[] = []
export let notifications: WithLookup<DisplayInboxNotification>[] = []
export let viewlets: ActivityNotificationViewlet[] = []

const client = getClient()
const hierarchy = client.getHierarchy()
const dispatch = createEventDispatcher()

let idTitle: string | undefined
let title: string | undefined

$: visibleNotification = notifications[0]

function showMenu (ev: MouseEvent): void {
Expand All @@ -50,15 +56,40 @@
chunter.action.OpenChannel
]
},
ev.target as HTMLElement
ev.target as HTMLElement,
handleActionMenuClosed
)
handleActionMenuOpened()
}

const presenterMixin = hierarchy.classHierarchyMixin(
$: presenterMixin = hierarchy.classHierarchyMixin(
value.attachedToClass,
notification.mixin.NotificationContextPresenter
)
$: isCompact = notifications.length === 1

$: message =
visibleNotification._class === notification.class.ActivityInboxNotification
? (visibleNotification as WithLookup<ActivityInboxNotification>).$lookup?.attachedTo
: undefined

let isActionMenuOpened = false

function handleActionMenuOpened (): void {
isActionMenuOpened = true
}

function handleActionMenuClosed (): void {
isActionMenuOpened = false
}

$: getDocIdentifier(client, value.attachedTo, value.attachedToClass).then((res) => {
idTitle = res
})

$: getDocTitle(client, value.attachedTo, value.attachedToClass).then((res) => {
title = res
})
</script>

{#if visibleNotification}
Expand All @@ -74,13 +105,15 @@
>
{#if isCompact}
<InboxNotificationPresenter value={visibleNotification} {viewlets} showNotify={false} withActions={false} />
<div class="actions compact">
<ActionIcon icon={IconMoreH} size="small" action={showMenu} />
</div>

<div class="notifyMarker compact">
<NotifyMarker count={unreadCount} />
</div>
<div class="actions clear-mins flex flex-gap-2 items-center" class:opened={isActionMenuOpened}>
{#if message}
<AddReactionAction object={message} on:open={handleActionMenuOpened} on:close={handleActionMenuClosed} />
{/if}
<ActionIcon icon={IconMoreH} size="small" action={showMenu} />
</div>
{:else}
<div class="header">
<!-- <CheckBox-->
Expand All @@ -96,30 +129,23 @@
<Component is={presenterMixin.labelPresenter} props={{ notification: visibleNotification, context: value }} />
{:else}
<div class="labels">
{#await getDocIdentifier(client, value.attachedTo, value.attachedToClass) then title}
{#if title}
{title}
{:else}
<Label label={hierarchy.getClass(value.attachedToClass).label} />
{/if}
{/await}
{#await getDocTitle(client, value.attachedTo, value.attachedToClass) then title}
<div class="title overflow-label" {title}>
{title ?? hierarchy.getClass(value.attachedToClass).label}
</div>
{/await}
{#if idTitle}
{idTitle}
{:else}
<Label label={hierarchy.getClass(value.attachedToClass).label} />
{/if}
<div class="title overflow-label" {title}>
{title ?? hierarchy.getClass(value.attachedToClass).label}
</div>
</div>
{/if}

<div class="actions">
<ActionIcon icon={IconMoreH} size="small" action={showMenu} />
</div>

<div class="notifyMarker">
<NotifyMarker count={unreadCount} />
</div>
</div>

<div class="actions clear-mins flex flex-gap-2 items-center" class:opened={isActionMenuOpened}>
<ActionIcon icon={IconMoreH} size="small" action={showMenu} />
</div>
<div class="notifyMarker">
<NotifyMarker count={unreadCount} />
</div>
<div class="notification">
<InboxNotificationPresenter value={visibleNotification} {viewlets} embedded skipLabel />
</div>
Expand All @@ -135,7 +161,8 @@
cursor: pointer;
border: 1px solid transparent;
border-radius: 0.5rem;
padding: 0 1rem;
padding: 0.5rem 1rem;
padding-right: 0;
margin: 0.5rem 0;

&.compact {
Expand All @@ -155,6 +182,22 @@
font-weight: 500;
max-width: 20.5rem;
}

.actions {
position: absolute;
visibility: hidden;
top: 0.75rem;
right: 0.75rem;
color: var(--theme-halfcontent-color);

&.opened {
visibility: visible;
}
}

&:hover > .actions {
visibility: visible;
}
}

.labels {
Expand All @@ -163,28 +206,17 @@
}

.notification {
margin-top: 1rem;
margin-top: 0.25rem;
margin-left: 4rem;
}

.notifyMarker {
position: absolute;
right: 1.875rem;
top: 0;

&.compact {
right: 2.875rem;
top: 0.5rem;
}
}

.actions {
position: absolute;
right: 0;
left: 0.25rem;
top: 0;

&.compact {
right: 1rem;
left: 0.25rem;
top: 0.5rem;
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,8 +40,8 @@

const client = getClient()
const messagesQuery = createQuery()
const notificationsClient = InboxNotificationsClientImpl.getClient()
const notificationsStore = notificationsClient.inboxNotifications
const inboxClient = InboxNotificationsClientImpl.getClient()
const notificationsStore = inboxClient.inboxNotifications

let messages: ActivityMessage[] = []
let viewlet: ActivityNotificationViewlet | undefined = undefined
Expand Down Expand Up @@ -81,6 +81,7 @@

function updateViewlet (viewlets: ActivityNotificationViewlet[], message?: DisplayActivityMessage) {
if (viewlets.length === 0 || message === undefined) {
viewlet = undefined
return
}

Expand All @@ -91,6 +92,8 @@
return
}
}

viewlet = undefined
}

function handleReply (message?: DisplayActivityMessage): void {
Expand All @@ -99,7 +102,7 @@
}
const loc = getLocation()
loc.fragment = value.docNotifyContext
loc.query = { message: message._id }
loc.query = { thread: message._id }
navigate(loc)
}

Expand Down
Loading