mirror of
https://github.com/hcengineering/platform.git
synced 2025-04-15 04:49:00 +00:00
Chunter: Open message links without reload (#2124)
Signed-off-by: Denis Bunakalya <denis.bunakalya@xored.com>
This commit is contained in:
parent
b12ee1d8b7
commit
c7e916abd1
@ -14,7 +14,7 @@
|
||||
// limitations under the License.
|
||||
-->
|
||||
<script lang="ts">
|
||||
import { CheckBox, Component } from '@anticrm/ui'
|
||||
import { CheckBox, Component, navigate, parseLocation } from '@anticrm/ui'
|
||||
import view from '@anticrm/view'
|
||||
|
||||
export let nodes: NodeListOf<any>
|
||||
@ -63,8 +63,19 @@
|
||||
{:else if node.nodeName === 'DIV'}
|
||||
<div><svelte:self nodes={node.childNodes} /></div>
|
||||
{:else if node.nodeName === 'A'}
|
||||
<a href={node.getAttribute('href')} target={node.getAttribute('target')}
|
||||
><svelte:self nodes={node.childNodes} /></a
|
||||
<a
|
||||
href={node.getAttribute('href')}
|
||||
target={node.getAttribute('target')}
|
||||
on:click={(e) => {
|
||||
try {
|
||||
const url = new URL(node.getAttribute('href'))
|
||||
|
||||
if (url.origin === window.location.origin) {
|
||||
e.preventDefault()
|
||||
navigate(parseLocation(url))
|
||||
}
|
||||
} catch {}
|
||||
}}><svelte:self nodes={node.childNodes} /></a
|
||||
>
|
||||
{:else if node.nodeName === 'LABEL'}
|
||||
<svelte:self nodes={node.childNodes} />
|
||||
|
@ -40,5 +40,5 @@
|
||||
dispatch('close')
|
||||
}}
|
||||
>
|
||||
<EditBox placeholder={linkPlaceholder} bind:value={link} maxWidth={'16rem'} focus />
|
||||
<EditBox placeholder={linkPlaceholder} bind:value={link} maxWidth={'37.75rem'} focus />
|
||||
</Card>
|
||||
|
@ -43,7 +43,7 @@ export function locationToUrl (location: PlatformLocation): string {
|
||||
return result
|
||||
}
|
||||
|
||||
function parseLocation (location: Location): PlatformLocation {
|
||||
export function parseLocation (location: Location | URL): PlatformLocation {
|
||||
return {
|
||||
path: parsePath(location.pathname),
|
||||
query: parseQuery(location.search),
|
||||
|
@ -19,10 +19,10 @@
|
||||
import core, { Doc, Ref, Space, Timestamp, WithLookup } from '@anticrm/core'
|
||||
import { NotificationClientImpl } from '@anticrm/notification-resources'
|
||||
import { createQuery } from '@anticrm/presentation'
|
||||
import { getCurrentLocation, navigate } from '@anticrm/ui'
|
||||
import { afterUpdate, beforeUpdate } from 'svelte'
|
||||
import { location as locationStore } from '@anticrm/ui'
|
||||
import { afterUpdate, beforeUpdate, onDestroy } from 'svelte'
|
||||
import chunter from '../plugin'
|
||||
import { getDay } from '../utils'
|
||||
import { getDay, messageIdForScroll, shouldScrollToMessage, isMessageHighlighted, scrollAndHighLight } from '../utils'
|
||||
import ChannelSeparator from './ChannelSeparator.svelte'
|
||||
import JumpToDateSelector from './JumpToDateSelector.svelte'
|
||||
import MessageComponent from './Message.svelte'
|
||||
@ -35,24 +35,31 @@
|
||||
|
||||
let div: HTMLDivElement | undefined
|
||||
let autoscroll: boolean = false
|
||||
let messageIdForScroll = ''
|
||||
let isMessageHighlighted = false
|
||||
|
||||
const unsubscribe = locationStore.subscribe((newLocation) => {
|
||||
const messageId = newLocation.fragment
|
||||
|
||||
if (!messageId) {
|
||||
messageIdForScroll.set('')
|
||||
|
||||
return
|
||||
}
|
||||
if (messageId === $messageIdForScroll) {
|
||||
return
|
||||
}
|
||||
messageIdForScroll.set(messageId)
|
||||
shouldScrollToMessage.set(true)
|
||||
scrollAndHighLight()
|
||||
})
|
||||
onDestroy(unsubscribe)
|
||||
|
||||
beforeUpdate(() => {
|
||||
autoscroll = div !== undefined && div.offsetHeight + div.scrollTop > div.scrollHeight - 20
|
||||
})
|
||||
|
||||
afterUpdate(() => {
|
||||
if (messageIdForScroll && !isMessageHighlighted) {
|
||||
const messageElement = document.getElementById(messageIdForScroll)
|
||||
|
||||
messageElement?.scrollIntoView()
|
||||
isMessageHighlighted = true
|
||||
|
||||
setTimeout(() => {
|
||||
messageIdForScroll = ''
|
||||
isMessageHighlighted = false
|
||||
}, 2000)
|
||||
if ($shouldScrollToMessage && !$isMessageHighlighted) {
|
||||
scrollAndHighLight()
|
||||
|
||||
return
|
||||
}
|
||||
@ -101,15 +108,6 @@
|
||||
messages = res
|
||||
newMessagesPos = newMessagesStart(messages)
|
||||
notificationClient.updateLastView(space, chunter.class.ChunterSpace)
|
||||
|
||||
const location = getCurrentLocation()
|
||||
const messageId = location.fragment
|
||||
|
||||
if (messageId && location.path.length === 3) {
|
||||
messageIdForScroll = messageId
|
||||
location.fragment = undefined
|
||||
navigate(location)
|
||||
}
|
||||
},
|
||||
{
|
||||
lookup: {
|
||||
@ -230,7 +228,7 @@
|
||||
<JumpToDateSelector selectedDate={message.createOn} on:jumpToDate={handleJumpToDate} />
|
||||
{/if}
|
||||
<MessageComponent
|
||||
isHighlighted={messageIdForScroll === message._id && isMessageHighlighted}
|
||||
isHighlighted={$messageIdForScroll === message._id && $isMessageHighlighted}
|
||||
{message}
|
||||
{employees}
|
||||
on:openThread
|
||||
|
@ -24,6 +24,7 @@
|
||||
import { afterUpdate, beforeUpdate, createEventDispatcher } from 'svelte'
|
||||
import { createBacklinks } from '../backlinks'
|
||||
import chunter from '../plugin'
|
||||
import { messageIdForScroll, shouldScrollToMessage, isMessageHighlighted, scrollAndHighLight } from '../utils'
|
||||
import ChannelSeparator from './ChannelSeparator.svelte'
|
||||
import MsgView from './Message.svelte'
|
||||
|
||||
@ -40,24 +41,14 @@
|
||||
let div: HTMLDivElement | undefined
|
||||
let autoscroll: boolean = false
|
||||
let isScrollForced = false
|
||||
let messageIdForScroll = ''
|
||||
let isMessageHighlighted = false
|
||||
|
||||
beforeUpdate(() => {
|
||||
autoscroll = div !== undefined && div.offsetHeight + div.scrollTop > div.scrollHeight - 20
|
||||
})
|
||||
|
||||
afterUpdate(() => {
|
||||
if (messageIdForScroll && !isMessageHighlighted) {
|
||||
const messageElement = document.getElementById(messageIdForScroll)
|
||||
|
||||
messageElement?.scrollIntoView()
|
||||
isMessageHighlighted = true
|
||||
|
||||
setTimeout(() => {
|
||||
messageIdForScroll = ''
|
||||
isMessageHighlighted = false
|
||||
}, 2000)
|
||||
if ($shouldScrollToMessage && !$isMessageHighlighted) {
|
||||
scrollAndHighLight()
|
||||
|
||||
return
|
||||
}
|
||||
@ -112,15 +103,6 @@
|
||||
comments = res
|
||||
newMessagesPos = newMessagesStart(comments, $lastViews)
|
||||
notificationClient.updateLastView(id, chunter.class.Message)
|
||||
|
||||
const location = getCurrentLocation()
|
||||
const messageId = location.fragment
|
||||
|
||||
if (messageId && location.path.length === 4) {
|
||||
messageIdForScroll = messageId
|
||||
location.fragment = undefined
|
||||
navigate(location)
|
||||
}
|
||||
},
|
||||
{
|
||||
lookup
|
||||
@ -235,7 +217,7 @@
|
||||
<ChannelSeparator title={chunter.string.New} line reverse isNew />
|
||||
{/if}
|
||||
<MsgView
|
||||
isHighlighted={messageIdForScroll === comment._id && isMessageHighlighted}
|
||||
isHighlighted={$messageIdForScroll === comment._id && $isMessageHighlighted}
|
||||
message={comment}
|
||||
{employees}
|
||||
thread
|
||||
|
@ -3,6 +3,7 @@ import contact, { EmployeeAccount, formatName } from '@anticrm/contact'
|
||||
import { Account, Class, Client, Obj, Ref, Space, getCurrentAccount, Timestamp } from '@anticrm/core'
|
||||
import { Asset } from '@anticrm/platform'
|
||||
import { getCurrentLocation, locationToUrl, navigate } from '@anticrm/ui'
|
||||
import { writable, get } from 'svelte/store'
|
||||
|
||||
import chunter from './plugin'
|
||||
|
||||
@ -97,3 +98,26 @@ export enum SearchType {
|
||||
Files,
|
||||
Contacts
|
||||
}
|
||||
|
||||
export const messageIdForScroll = writable('')
|
||||
export const shouldScrollToMessage = writable(false)
|
||||
export const isMessageHighlighted = writable(false)
|
||||
|
||||
let highlightFinishTaskId: number
|
||||
|
||||
export function scrollAndHighLight (): void {
|
||||
const messageElement = document.getElementById(get(messageIdForScroll))
|
||||
|
||||
if (messageElement == null) {
|
||||
return
|
||||
}
|
||||
messageElement.scrollIntoView()
|
||||
shouldScrollToMessage.set(false)
|
||||
|
||||
clearTimeout(highlightFinishTaskId)
|
||||
isMessageHighlighted.set(true)
|
||||
|
||||
highlightFinishTaskId = window.setTimeout(() => {
|
||||
isMessageHighlighted.set(false)
|
||||
}, 2000)
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user