mirror of
https://github.com/hcengineering/platform.git
synced 2025-04-16 21:35:10 +00:00
Inbox scroll to new (#3036)
Signed-off-by: Denis Bykhov <bykhov.denis@gmail.com>
This commit is contained in:
parent
f6f917d18b
commit
43713dd508
@ -143,7 +143,10 @@
|
|||||||
<div class="popupPanel-body__mobile-content clear-mins" class:max={useMaxWidth}>
|
<div class="popupPanel-body__mobile-content clear-mins" class:max={useMaxWidth}>
|
||||||
<slot />
|
<slot />
|
||||||
{#if !withoutActivity}
|
{#if !withoutActivity}
|
||||||
<Component is={activity.component.Activity} props={{ object, showCommenInput: !withoutInput }} />
|
<Component
|
||||||
|
is={activity.component.Activity}
|
||||||
|
props={{ object, showCommenInput: !withoutInput, shouldScroll: embedded }}
|
||||||
|
/>
|
||||||
{/if}
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
{:else}
|
{:else}
|
||||||
@ -151,7 +154,10 @@
|
|||||||
<div class="popupPanel-body__main-content py-8 clear-mins" class:max={useMaxWidth}>
|
<div class="popupPanel-body__main-content py-8 clear-mins" class:max={useMaxWidth}>
|
||||||
<slot />
|
<slot />
|
||||||
{#if !withoutActivity}
|
{#if !withoutActivity}
|
||||||
<Component is={activity.component.Activity} props={{ object, showCommenInput: !withoutInput }} />
|
<Component
|
||||||
|
is={activity.component.Activity}
|
||||||
|
props={{ object, showCommenInput: !withoutInput, shouldScroll: embedded }}
|
||||||
|
/>
|
||||||
{/if}
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
</Scroller>
|
</Scroller>
|
||||||
|
@ -28,6 +28,7 @@
|
|||||||
export let object: Doc
|
export let object: Doc
|
||||||
export let showCommenInput: boolean = true
|
export let showCommenInput: boolean = true
|
||||||
export let transparent: boolean = false
|
export let transparent: boolean = false
|
||||||
|
export let shouldScroll: boolean = false
|
||||||
|
|
||||||
getResource(notification.function.GetNotificationClient).then((res) => {
|
getResource(notification.function.GetNotificationClient).then((res) => {
|
||||||
updatesStore = res().docUpdatesStore
|
updatesStore = res().docUpdatesStore
|
||||||
@ -83,13 +84,29 @@
|
|||||||
|
|
||||||
let filtered: DisplayTx[] = []
|
let filtered: DisplayTx[] = []
|
||||||
|
|
||||||
|
let newTxIndexes: number[] = []
|
||||||
|
$: newTxIndexes = getNewTxes(filtered, newTxes)
|
||||||
|
|
||||||
|
function getNewTxes (filtered: DisplayTx[], newTxes: [Ref<TxCUD<Doc>>, number][]): number[] {
|
||||||
|
const res: number[] = []
|
||||||
|
for (let i = 0; i < filtered.length; i++) {
|
||||||
|
if (isNew(filtered[i], newTxes)) {
|
||||||
|
res.push(i)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return res
|
||||||
|
}
|
||||||
|
|
||||||
function isNew (tx: DisplayTx | undefined, newTxes: [Ref<TxCUD<Doc>>, number][]): boolean {
|
function isNew (tx: DisplayTx | undefined, newTxes: [Ref<TxCUD<Doc>>, number][]): boolean {
|
||||||
if (tx === undefined) return false
|
if (tx === undefined) return false
|
||||||
const index = newTxes.findIndex((p) => p[0] === tx.originTx._id)
|
const index = newTxes.findIndex((p) => p[0] === tx.originTx._id)
|
||||||
return index !== -1
|
return index !== -1
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$: scrollIndex = shouldScroll ? newTxIndexes[0] ?? -1 : -1
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
{shouldScroll}
|
||||||
<div class="antiSection-header high mt-9" class:invisible={transparent}>
|
<div class="antiSection-header high mt-9" class:invisible={transparent}>
|
||||||
<span class="antiSection-header__title flex-row-center">
|
<span class="antiSection-header__title flex-row-center">
|
||||||
<Label label={activity.string.Activity} />
|
<Label label={activity.string.Activity} />
|
||||||
@ -105,7 +122,13 @@
|
|||||||
{#if filtered}
|
{#if filtered}
|
||||||
<Grid column={1} rowGap={0.75}>
|
<Grid column={1} rowGap={0.75}>
|
||||||
{#each filtered as tx, i}
|
{#each filtered as tx, i}
|
||||||
<TxView {tx} {viewlets} isNew={isNew(tx, newTxes)} isNextNew={isNew(filtered[i + 1], newTxes)} />
|
<TxView
|
||||||
|
{tx}
|
||||||
|
{viewlets}
|
||||||
|
isNew={newTxIndexes.includes(i)}
|
||||||
|
isNextNew={newTxIndexes.includes(i + 1)}
|
||||||
|
shouldScroll={i === scrollIndex}
|
||||||
|
/>
|
||||||
{/each}
|
{/each}
|
||||||
</Grid>
|
</Grid>
|
||||||
{/if}
|
{/if}
|
||||||
|
@ -40,6 +40,7 @@
|
|||||||
import { getValue, TxDisplayViewlet, updateViewlet } from '../utils'
|
import { getValue, TxDisplayViewlet, updateViewlet } from '../utils'
|
||||||
import TxViewTx from './TxViewTx.svelte'
|
import TxViewTx from './TxViewTx.svelte'
|
||||||
import Edit from './icons/Edit.svelte'
|
import Edit from './icons/Edit.svelte'
|
||||||
|
import { tick } from 'svelte'
|
||||||
|
|
||||||
export let tx: DisplayTx
|
export let tx: DisplayTx
|
||||||
export let viewlets: Map<ActivityKey, TxViewlet>
|
export let viewlets: Map<ActivityKey, TxViewlet>
|
||||||
@ -47,6 +48,7 @@
|
|||||||
export let isNew: boolean = false
|
export let isNew: boolean = false
|
||||||
export let isNextNew: boolean = false
|
export let isNextNew: boolean = false
|
||||||
export let contentHidden: boolean = false
|
export let contentHidden: boolean = false
|
||||||
|
export let shouldScroll: boolean = false
|
||||||
// export let showDocument = false
|
// export let showDocument = false
|
||||||
|
|
||||||
let ptx: DisplayTx | undefined
|
let ptx: DisplayTx | undefined
|
||||||
@ -87,6 +89,9 @@
|
|||||||
modelIcon = result.modelIcon
|
modelIcon = result.modelIcon
|
||||||
iconComponent = result.iconComponent
|
iconComponent = result.iconComponent
|
||||||
props = getProps(result.props, edit)
|
props = getProps(result.props, edit)
|
||||||
|
if (shouldScroll) {
|
||||||
|
tick().then(scrollIntoView)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
@ -164,10 +169,24 @@
|
|||||||
$: withAvatar = isComment || isMentioned || isAttached
|
$: withAvatar = isComment || isMentioned || isAttached
|
||||||
$: isEmphasized = viewlet?.display === 'emphasized' || model.every((m) => isMessageType(m.attribute))
|
$: isEmphasized = viewlet?.display === 'emphasized' || model.every((m) => isMessageType(m.attribute))
|
||||||
$: isColumn = isComment || isEmphasized || hasMessageType
|
$: isColumn = isComment || isEmphasized || hasMessageType
|
||||||
|
|
||||||
|
let htmlElement: HTMLDivElement
|
||||||
|
|
||||||
|
function scrollIntoView () {
|
||||||
|
htmlElement?.scrollIntoView({ behavior: 'auto', block: 'start' })
|
||||||
|
shouldScroll = false
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
{#if (viewlet !== undefined && !((viewlet?.hideOnRemove ?? false) && tx.removed)) || model.length > 0}
|
{#if (viewlet !== undefined && !((viewlet?.hideOnRemove ?? false) && tx.removed)) || model.length > 0}
|
||||||
<div class="msgactivity-container" class:showIcon class:withAvatar class:isNew class:isNextNew>
|
<div
|
||||||
|
class="msgactivity-container"
|
||||||
|
bind:this={htmlElement}
|
||||||
|
class:showIcon
|
||||||
|
class:withAvatar
|
||||||
|
class:isNew
|
||||||
|
class:isNextNew
|
||||||
|
>
|
||||||
{#if showIcon}
|
{#if showIcon}
|
||||||
{#if withAvatar}
|
{#if withAvatar}
|
||||||
<div class="msgactivity-avatar">
|
<div class="msgactivity-avatar">
|
||||||
|
@ -128,7 +128,7 @@
|
|||||||
font-weight: 600;
|
font-weight: 600;
|
||||||
font-size: 0.75rem;
|
font-size: 0.75rem;
|
||||||
color: var(--theme-accent-color);
|
color: var(--theme-accent-color);
|
||||||
border: 1px solid var(--divider-color);
|
border: 1px solid var(--highlight-red);
|
||||||
border-radius: 50%;
|
border-radius: 50%;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
Loading…
Reference in New Issue
Block a user