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
Original file line number Diff line number Diff line change
Expand Up @@ -16,22 +16,25 @@
import { Attachment } from '@hcengineering/attachment'
import { type Doc, type Ref, type WithLookup } from '@hcengineering/core'
import { createQuery } from '@hcengineering/presentation'
import { onMount } from 'svelte'

import attachment from '../plugin'
import { AttachmentImageSize } from '../types'
import AttachmentGroup from './AttachmentGroup.svelte'
import { loadSavedAttachments, savedAttachmentsStore } from '../stores'

export let value: Doc & { attachments?: number }
export let attachments: Attachment[] | undefined = undefined
export let imageSize: AttachmentImageSize = 'auto'
export let videoPreload = true

const query = createQuery()
const savedAttachmentsQuery = createQuery()

let savedAttachmentsIds: Ref<Attachment>[] = []
let resAttachments: WithLookup<Attachment>[] = []

$: savedAttachmentsIds = $savedAttachmentsStore.map((it) => it.attachedTo)

$: updateQuery(value, attachments)

function updateQuery (value: Doc & { attachments?: number }, attachments?: Attachment[]): void {
Expand All @@ -57,8 +60,8 @@
}
}

savedAttachmentsQuery.query(attachment.class.SavedAttachments, {}, (res) => {
savedAttachmentsIds = res.map(({ attachedTo }) => attachedTo)
onMount(() => {
loadSavedAttachments()
})
</script>

Expand Down
1 change: 1 addition & 0 deletions plugins/attachment-resources/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ import PreviewPopupActions from './components/PreviewPopupActions.svelte'
import DrawingPresenter from './components/DrawingPresenter.svelte'

export * from './types'
export * from './stores'

export {
AccordionEditor,
Expand Down
42 changes: 42 additions & 0 deletions plugins/attachment-resources/src/stores.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
//
// Copyright © 2025 Hardcore Engineering Inc.
//
// Licensed under the Eclipse Public License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License. You may
// obtain a copy of the License at https://www.eclipse.org/legal/epl-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
//
// See the License for the specific language governing permissions and
// limitations under the License.
//

import { get, writable } from 'svelte/store'
import core, { SortingOrder, type WithLookup } from '@hcengineering/core'
import attachment, { type SavedAttachments } from '@hcengineering/attachment'
import { createQuery, onClient } from '@hcengineering/presentation'

export const savedAttachmentsStore = writable<Array<WithLookup<SavedAttachments>>>([])
export const isSavedAttachmentsLoaded = writable(false)

const savedAttachmentsQuery = createQuery(true)

export function loadSavedAttachments (): void {
if (get(isSavedAttachmentsLoaded)) {
return
}

onClient(() => {
savedAttachmentsQuery.query(
attachment.class.SavedAttachments,
{ space: core.space.Workspace },
(res) => {
isSavedAttachmentsLoaded.set(true)
savedAttachmentsStore.set(res.filter(({ $lookup }) => $lookup?.attachedTo !== undefined))
},
{ lookup: { attachedTo: attachment.class.Attachment }, sort: { modifiedOn: SortingOrder.Descending } }
)
})
}
3 changes: 2 additions & 1 deletion plugins/chunter-assets/lang/cs.json
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,7 @@
"StartConversation": "Začít konverzaci",
"ViewingThreadFromArchivedChannel": "Prohlížíte vlákno z archivovaného kanálu",
"ViewingArchivedChannel": "Prohlížíte archivovaný kanál",
"OpenChatInSidebar": "Otevřít chat v postranním panelu"
"OpenChatInSidebar": "Otevřít chat v postranním panelu",
"NoThreadsYet": "Zatím nejsou žádné vlákna."
}
}
3 changes: 2 additions & 1 deletion plugins/chunter-assets/lang/de.json
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,7 @@
"ViewingThreadFromArchivedChannel": "Sie sehen einen Thread aus einem archivierten Kanal",
"ViewingArchivedChannel": "Sie sehen einen archivierten Kanal",
"OpenChatInSidebar": "Chat in Seitenleiste öffnen",
"ResolveThread": "Thread abschließen"
"ResolveThread": "Thread abschließen",
"NoThreadsYet": "Es gibt noch keine Threads."
}
}
3 changes: 2 additions & 1 deletion plugins/chunter-assets/lang/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,7 @@
"ViewingThreadFromArchivedChannel": "You are viewing a thread from an archived channel",
"ViewingArchivedChannel": "You are viewing an archived channel",
"OpenChatInSidebar": "Open chat in sidebar",
"ResolveThread": "Resolve"
"ResolveThread": "Resolve",
"NoThreadsYet": "There are no threads yet."
}
}
3 changes: 2 additions & 1 deletion plugins/chunter-assets/lang/es.json
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,7 @@
"StartConversation": "Iniciar conversación",
"ViewingThreadFromArchivedChannel": "Estás viendo un hilo de un canal archivado",
"ViewingArchivedChannel": "Estás viendo un canal archivado",
"OpenChatInSidebar": "Abrir chat en la barra lateral"
"OpenChatInSidebar": "Abrir chat en la barra lateral",
"NoThreadsYet": "No hay hilos todavía."
}
}
3 changes: 2 additions & 1 deletion plugins/chunter-assets/lang/fr.json
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,7 @@
"StartConversation": "Démarrer la conversation",
"ViewingThreadFromArchivedChannel": "Vous consultez un fil de discussion d'un canal archivé",
"ViewingArchivedChannel": "Vous consultez un canal archivé",
"OpenChatInSidebar": "Ouvrir le chat dans la barre latérale"
"OpenChatInSidebar": "Ouvrir le chat dans la barre latérale",
"NoThreadsYet": "Il n'y a pas encore de fils de discussion."
}
}
3 changes: 2 additions & 1 deletion plugins/chunter-assets/lang/it.json
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,7 @@
"StartConversation": "Inizia conversazione",
"ViewingThreadFromArchivedChannel": "Stai visualizzando una discussione da un canale archiviato",
"ViewingArchivedChannel": "Stai visualizzando un canale archiviato",
"OpenChatInSidebar": "Apri chat nella barra laterale"
"OpenChatInSidebar": "Apri chat nella barra laterale",
"NoThreadsYet": "Non ci sono ancora discussioni."
}
}
3 changes: 2 additions & 1 deletion plugins/chunter-assets/lang/pt.json
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,7 @@
"StartConversation": "Iniciar conversa",
"ViewingThreadFromArchivedChannel": "Está a visualizar uma conversa em cadeia de um canal arquivado",
"ViewingArchivedChannel": "Está a visualizar um canal arquivado",
"OpenChatInSidebar": "Abrir chat na barra lateral"
"OpenChatInSidebar": "Abrir chat na barra lateral",
"NoThreadsYet": "Não há conversas ainda."
}
}
3 changes: 2 additions & 1 deletion plugins/chunter-assets/lang/ru.json
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,7 @@
"ViewingThreadFromArchivedChannel": "Вы просматриваете обсуждение из архивированного канала",
"ViewingArchivedChannel": "Вы просматриваете архивированный канал",
"OpenChatInSidebar": "Открыть чат в боковой панели",
"ResolveThread": "Пометить завершенным"
"ResolveThread": "Пометить завершенным",
"NoThreadsYet": "Пока нет обсуждений."
}
}
3 changes: 2 additions & 1 deletion plugins/chunter-assets/lang/zh.json
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,7 @@
"StartConversation": "开始对话",
"ViewingThreadFromArchivedChannel": "你正在查看已归档频道的线程",
"ViewingArchivedChannel": "你正在查看已归档频道",
"OpenChatInSidebar": "在侧边栏中打开聊天"
"OpenChatInSidebar": "在侧边栏中打开聊天",
"NoThreadsYet": "还没有线程。"
}
}
3 changes: 2 additions & 1 deletion plugins/chunter-resources/src/components/chat/Chat.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -33,10 +33,11 @@
import view, { decodeObjectURI } from '@hcengineering/view'
import { parseLinkId, getObjectLinkId } from '@hcengineering/view-resources'
import { ActivityMessage } from '@hcengineering/activity'
import { loadSavedAttachments } from '@hcengineering/attachment-resources'

import ChatNavigator from './navigator/ChatNavigator.svelte'
import ChannelView from '../ChannelView.svelte'
import { chatSpecials, loadSavedAttachments } from './utils'
import { chatSpecials } from './utils'
import { SelectChannelEvent } from './types'
import { openChannel, openThreadInSidebar } from '../../navigation'

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,9 @@
import { SavedAttachments } from '@hcengineering/attachment'
import { SavedMessage } from '@hcengineering/activity'
import { savedMessagesStore } from '@hcengineering/activity-resources'
import { savedAttachmentsStore } from '@hcengineering/attachment-resources'

import NavItem from './NavItem.svelte'
import { savedAttachmentsStore } from '../utils'

export let special: SpecialNavModel
export let currentSpecial: SpecialNavModel | undefined = undefined
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,17 +14,16 @@
-->
<script lang="ts">
import { Attachment, SavedAttachments } from '@hcengineering/attachment'
import { AttachmentPreview } from '@hcengineering/attachment-resources'
import { AttachmentPreview, savedAttachmentsStore } from '@hcengineering/attachment-resources'
import { Person, PersonAccount, getName as getContactName } from '@hcengineering/contact'
import { personAccountByIdStore, personByIdStore } from '@hcengineering/contact-resources'
import { getDisplayTime, IdMap, Ref, WithLookup } from '@hcengineering/core'
import { getClient } from '@hcengineering/presentation'
import { Label, Scroller } from '@hcengineering/ui'
import { Label, Scroller, Lazy } from '@hcengineering/ui'
import activity, { ActivityMessage, SavedMessage } from '@hcengineering/activity'
import { ActivityMessagePresenter, savedMessagesStore } from '@hcengineering/activity-resources'

import chunter from '../../../plugin'
import { savedAttachmentsStore } from '../utils'
import Header from '../../Header.svelte'
import { openMessageFromSpecial } from '../../../navigation'
import BlankView from '../../BlankView.svelte'
Expand Down Expand Up @@ -65,23 +64,28 @@
function handleMessageClicked (message?: ActivityMessage): void {
void openMessageFromSpecial(message)
}

$: isEmpty = savedMessages.length === 0 && savedAttachments.length === 0
</script>

<Header icon={chunter.icon.Bookmarks} intlLabel={chunter.string.Saved} titleKind={'breadcrumbs'} />

<Scroller padding={'.75rem .5rem'} bottomPadding={'.75rem'}>
{#if savedMessages.length > 0 || savedAttachments.length > 0}
<Scroller padding={'.75rem .5rem'} bottomPadding={'.75rem'} noStretch={!isEmpty}>
{#if !isEmpty}
{#each savedMessages as message}
{#if message.$lookup?.attachedTo}
<!-- svelte-ignore a11y-click-events-have-key-events -->
<!-- svelte-ignore a11y-no-static-element-interactions -->

<ActivityMessagePresenter
value={message.$lookup?.attachedTo}
onClick={() => {
handleMessageClicked(message.$lookup?.attachedTo)
}}
/>
<div class="message-container">
<!-- svelte-ignore a11y-click-events-have-key-events -->
<!-- svelte-ignore a11y-no-static-element-interactions -->
<Lazy>
<ActivityMessagePresenter
value={message.$lookup?.attachedTo}
onClick={() => {
handleMessageClicked(message.$lookup?.attachedTo)
}}
/>
</Lazy>
</div>
{/if}
{/each}
{#each savedAttachments as attach}
Expand All @@ -92,16 +96,18 @@
class="attachmentContainer flex-no-shrink clear-mins"
on:click={() => openAttachment(attach.$lookup?.attachedTo)}
>
<AttachmentPreview value={attach.$lookup.attachedTo} isSaved={true} />
<div class="label">
<Label
label={chunter.string.SharedBy}
params={{
name: getName(attach.$lookup.attachedTo, $personAccountByIdStore, $personByIdStore),
time: getDisplayTime(attach.modifiedOn)
}}
/>
</div>
<Lazy>
<AttachmentPreview value={attach.$lookup.attachedTo} isSaved={true} />
<div class="label">
<Label
label={chunter.string.SharedBy}
params={{
name: getName(attach.$lookup.attachedTo, $personAccountByIdStore, $personByIdStore),
time: getDisplayTime(attach.modifiedOn)
}}
/>
</div>
</Lazy>
</div>
{/if}
{/each}
Expand All @@ -119,6 +125,7 @@
cursor: pointer;
padding: 2rem;
border-radius: 0.25rem;
min-height: 3.75rem;

&:hover {
background-color: var(--global-ui-BackgroundColor);
Expand All @@ -128,4 +135,10 @@
padding-top: 1rem;
}
}

.message-container {
display: flex;
flex-direction: column;
min-height: 3.75rem;
}
</style>
25 changes: 4 additions & 21 deletions plugins/chunter-resources/src/components/chat/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,23 +12,21 @@
// See the License for the specific language governing permissions and
// limitations under the License.
//
import attachment, { type SavedAttachments } from '@hcengineering/attachment'

import { type DirectMessage } from '@hcengineering/chunter'
import contact, { type PersonAccount } from '@hcengineering/contact'
import core, {
import {
type Account,
AccountRole,
getCurrentAccount,
hasAccountRole,
type IdMap,
type Ref,
SortingOrder,
type UserStatus,
type WithLookup
type UserStatus
} from '@hcengineering/core'
import notification, { type DocNotifyContext } from '@hcengineering/notification'
import { InboxNotificationsClientImpl } from '@hcengineering/notification-resources'
import { createQuery, getClient, MessageBox, onClient } from '@hcengineering/presentation'
import { getClient, MessageBox } from '@hcengineering/presentation'
import { type Action, showPopup } from '@hcengineering/ui'
import view from '@hcengineering/view'
import workbench, { type SpecialNavModel } from '@hcengineering/workbench'
Expand All @@ -43,7 +41,6 @@ interface NavigatorState {
collapsedSections: string[]
}

export const savedAttachmentsStore = writable<Array<WithLookup<SavedAttachments>>>([])
export const navigatorStateStore = writable<NavigatorState>(restoreNavigatorState())

function restoreNavigatorState (): NavigatorState {
Expand Down Expand Up @@ -364,20 +361,6 @@ function archiveActivityChannels (contexts: DocNotifyContext[]): void {
)
}

const savedAttachmentsQuery = createQuery(true)
export function loadSavedAttachments (): void {
onClient(() => {
savedAttachmentsQuery.query(
attachment.class.SavedAttachments,
{ space: core.space.Workspace },
(res) => {
savedAttachmentsStore.set(res.filter(({ $lookup }) => $lookup?.attachedTo !== undefined))
},
{ lookup: { attachedTo: attachment.class.Attachment }, sort: { modifiedOn: SortingOrder.Descending } }
)
})
}

export async function hideActivityChannels (contexts: DocNotifyContext[]): Promise<void> {
const ops = getClient().apply(undefined, 'hideActivityChannels')

Expand Down
Loading