UBER-135/TSK-1430: allow changing image in PDFViewer through arrow-keys (keyboard) (#3186)

Signed-off-by: Vyacheslav Tumanov <me@slavatumanov.me>
This commit is contained in:
Vyacheslav Tumanov 2023-05-24 17:51:48 +05:00 committed by GitHub
parent 71193c54c2
commit df5fc73eeb
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
31 changed files with 69 additions and 56 deletions

View File

@ -19,6 +19,7 @@
import presentation from '..'
import { getFileUrl } from '../utils'
import Download from './icons/Download.svelte'
import ActionContext from './ActionContext.svelte'
export let file: string
export let name: string
@ -40,6 +41,7 @@
let download: HTMLAnchorElement
</script>
<ActionContext context={{ mode: 'browser' }} />
<Panel
isHeader={false}
isAside={popupOptions && popupOptions.fullSize}

View File

@ -19,6 +19,7 @@ import { presentationId } from './plugin'
export * from './attributes'
export { default as AttributeBarEditor } from './components/AttributeBarEditor.svelte'
export { default as AttributeEditor } from './components/AttributeEditor.svelte'
export { default as ActionContext } from './components/ActionContext.svelte'
export { default as InlineAttributeBarEditor } from './components/InlineAttributeBarEditor.svelte'
export { default as InlineAttributeBar } from './components/InlineAttributeBar.svelte'
export { default as AttributesBar } from './components/AttributesBar.svelte'
@ -47,6 +48,7 @@ export * from './utils'
export * from './drafts'
export { presentationId }
export * from './configuration'
export * from './context'
addStringsLoader(presentationId, async (lang: string) => {
return await import(`../lang/${lang}.json`)

View File

@ -32,6 +32,16 @@ export interface PopupResult {
export const popupstore = writable<CompAndProps[]>([])
export function updatePopup (id: string, props: Partial<CompAndProps>): void {
popupstore.update((popups) => {
const popupIndex = popups.findIndex((p) => p.id === id)
if (popupIndex !== -1) {
popups[popupIndex] = { ...popups[popupIndex], ...props }
}
return popups
})
}
function addPopup (props: CompAndProps): void {
popupstore.update((popups) => {
popups.push(props)

View File

@ -21,9 +21,13 @@
import AttachmentPresenter from './AttachmentPresenter.svelte'
import AttachmentActions from './AttachmentActions.svelte'
import AudioPlayer from './AudioPlayer.svelte'
import { ListSelectionProvider } from '@hcengineering/view-resources'
import { createEventDispatcher } from 'svelte'
export let value: Attachment
export let isSaved: boolean = false
export let listProvider: ListSelectionProvider | undefined = undefined
const dispatch = createEventDispatcher()
$: type = getType(value.type)
</script>
@ -34,11 +38,13 @@
class="content flex-center buttonContainer cursor-pointer"
on:click={() => {
closeTooltip()
showPopup(
if (listProvider !== undefined) listProvider.updateFocus(value)
const popupInfo = showPopup(
PDFViewer,
{ file: value.file, name: value.name, contentType: value.type },
value.type.startsWith('image/') ? 'centered' : 'float'
)
dispatch('open', popupInfo.id)
}}
>
<img src={getFileUrl(value.file)} alt={value.name} />

View File

@ -18,12 +18,13 @@
import { IntlString, setPlatformStatus, unknownError } from '@hcengineering/platform'
import { createQuery, DraftController, draftsStore, getClient } from '@hcengineering/presentation'
import { StyledTextBox } from '@hcengineering/text-editor'
import { IconSize } from '@hcengineering/ui'
import { IconSize, updatePopup } from '@hcengineering/ui'
import { createEventDispatcher, onDestroy } from 'svelte'
import attachment from '../plugin'
import { deleteFile, uploadFile } from '../utils'
import AttachmentPresenter from './AttachmentPresenter.svelte'
import AttachmentPreview from './AttachmentPreview.svelte'
import { ListSelectionProvider, SelectDirection } from '@hcengineering/view-resources'
export let objectId: Ref<Doc> | undefined = undefined
export let space: Ref<Space> | undefined = undefined
@ -48,6 +49,18 @@
$: draftKey = objectId ? `${objectId}_attachments` : undefined
const dispatch = createEventDispatcher()
let attachmentPopupId: string = ''
const listProvider = new ListSelectionProvider((offset: 1 | -1 | 0, of?: Doc, dir?: SelectDirection) => {
const currentAttachmentIndex = listProvider.current()
if (currentAttachmentIndex === undefined) return
const selected = currentAttachmentIndex + offset
const sel = listProvider.docs()[selected] as Attachment
if (sel !== undefined && attachmentPopupId !== '') {
listProvider.updateFocus(sel)
updatePopup(attachmentPopupId, { props: { file: sel.file, name: sel.name, contentType: sel.type } })
}
})
$: listProvider.update(Array.from(attachments.values()).filter((attachment) => attachment.type.startsWith('image/')))
export function focus (): void {
refInput.focus()
@ -358,10 +371,10 @@
</div>
{#if attachments.size && fakeAttach === 'normal'}
<div class="flex-row-center list scroll-divider-color">
{#each Array.from(attachments.values()) as attachment}
{#each Array.from(attachments.values()) as attachment, index}
<div class="item flex-center flex-no-shrink clear-mins">
{#if useAttachmentPreview}
<AttachmentPreview value={attachment} />
<AttachmentPreview value={attachment} {listProvider} on:open={(res) => (attachmentPopupId = res.detail)} />
{:else}
<AttachmentPresenter
value={attachment}

View File

@ -27,12 +27,11 @@
WithLookup
} from '@hcengineering/core'
import { Kanban as KanbanUI } from '@hcengineering/kanban'
import { createQuery, getClient } from '@hcengineering/presentation'
import { ActionContext, createQuery, getClient } from '@hcengineering/presentation'
import type { DocWithRank, Kanban, SpaceWithStates, State } from '@hcengineering/task'
import task, { calcRank } from '@hcengineering/task'
import { getEventPositionElement, showPopup } from '@hcengineering/ui'
import {
ActionContext,
ContextMenu,
focusStore,
getGroupByValues,

View File

@ -15,11 +15,10 @@
-->
<script lang="ts">
import { Doc, DocumentQuery } from '@hcengineering/core'
import { createQuery, getClient } from '@hcengineering/presentation'
import { createQuery, getClient, ActionContext } from '@hcengineering/presentation'
import { Button, Label, Loading, SearchEdit, showPopup } from '@hcengineering/ui'
import view, { Viewlet, ViewletPreference } from '@hcengineering/view'
import {
ActionContext,
FilterBar,
FilterButton,
getViewOptions,

View File

@ -17,11 +17,10 @@
<script lang="ts">
import { Doc, DocumentQuery } from '@hcengineering/core'
import { Document } from '@hcengineering/document'
import { createQuery, getClient } from '@hcengineering/presentation'
import { createQuery, getClient, ActionContext } from '@hcengineering/presentation'
import { Label, Loading, SearchEdit } from '@hcengineering/ui'
import view, { Viewlet, ViewletPreference } from '@hcengineering/view'
import {
ActionContext,
FilterButton,
getViewOptions,
setActiveViewletId,

View File

@ -17,9 +17,9 @@
import { activityKey, ActivityKey } from '@hcengineering/activity-resources'
import { Doc, getCurrentAccount, Ref } from '@hcengineering/core'
import notification, { DocUpdates } from '@hcengineering/notification'
import { createQuery } from '@hcengineering/presentation'
import { ActionContext, createQuery } from '@hcengineering/presentation'
import { ListView, Loading, Scroller } from '@hcengineering/ui'
import { ActionContext, ListSelectionProvider, SelectDirection } from '@hcengineering/view-resources'
import { ListSelectionProvider, SelectDirection } from '@hcengineering/view-resources'
import { createEventDispatcher } from 'svelte'
import NotificationView from './NotificationView.svelte'

View File

@ -17,9 +17,9 @@
import { activityKey, ActivityKey } from '@hcengineering/activity-resources'
import core, { Account, Doc, getCurrentAccount, Ref } from '@hcengineering/core'
import notification, { DocUpdates } from '@hcengineering/notification'
import { createQuery, getClient } from '@hcengineering/presentation'
import { ActionContext, createQuery, getClient } from '@hcengineering/presentation'
import { ActionIcon, Button, IconBack, ListView, Loading, Scroller } from '@hcengineering/ui'
import { ActionContext, ListSelectionProvider, SelectDirection } from '@hcengineering/view-resources'
import { ListSelectionProvider, SelectDirection } from '@hcengineering/view-resources'
import { createEventDispatcher } from 'svelte'
import NotificationView from './NotificationView.svelte'
import { Employee, EmployeeAccount, getName } from '@hcengineering/contact'

View File

@ -19,9 +19,9 @@
import { employeeAccountByIdStore } from '@hcengineering/contact-resources'
import { Account, Doc, getCurrentAccount, Ref } from '@hcengineering/core'
import notification, { DocUpdates } from '@hcengineering/notification'
import { createQuery } from '@hcengineering/presentation'
import { ActionContext, createQuery } from '@hcengineering/presentation'
import { ListView, Loading, Scroller } from '@hcengineering/ui'
import { ActionContext, ListSelectionProvider, SelectDirection } from '@hcengineering/view-resources'
import { ListSelectionProvider, SelectDirection } from '@hcengineering/view-resources'
import PeopleNotificationView from './PeopleNotificationsView.svelte'
export let filter: 'all' | 'read' | 'unread' = 'all'

View File

@ -26,7 +26,7 @@
} from '@hcengineering/core'
import { Item, Kanban as KanbanUI } from '@hcengineering/kanban'
import { getResource } from '@hcengineering/platform'
import { createQuery, getClient, statusStore } from '@hcengineering/presentation'
import { createQuery, getClient, statusStore, ActionContext } from '@hcengineering/presentation'
import { Kanban, SpaceWithStates, Task, TaskGrouping, TaskOrdering } from '@hcengineering/task'
import {
getEventPositionElement,
@ -46,7 +46,6 @@
ViewQueryOption
} from '@hcengineering/view'
import {
ActionContext,
focusStore,
getCategories,
getCategorySpaces,

View File

@ -29,7 +29,7 @@
import { Item, Kanban } from '@hcengineering/kanban'
import notification from '@hcengineering/notification'
import { getResource } from '@hcengineering/platform'
import { createQuery, getClient, statusStore } from '@hcengineering/presentation'
import { createQuery, getClient, statusStore, ActionContext } from '@hcengineering/presentation'
import tags from '@hcengineering/tags'
import { Issue, IssuesGrouping, IssuesOrdering, Project } from '@hcengineering/tracker'
import {
@ -56,7 +56,6 @@
ViewQueryOption
} from '@hcengineering/view'
import {
ActionContext,
focusStore,
getCategories,
getCategorySpaces,

View File

@ -18,7 +18,7 @@
import notification from '@hcengineering/notification'
import { Panel } from '@hcengineering/panel'
import { getResource } from '@hcengineering/platform'
import presentation, { createQuery, getClient } from '@hcengineering/presentation'
import presentation, { createQuery, getClient, ActionContext, contextStore } from '@hcengineering/presentation'
import setting, { settingId } from '@hcengineering/setting'
import { Issue, Project } from '@hcengineering/tracker'
import {
@ -34,14 +34,7 @@
navigate,
showPopup
} from '@hcengineering/ui'
import {
ActionContext,
ContextMenu,
DocNavLink,
ParentsNavigator,
UpDownNavigator,
contextStore
} from '@hcengineering/view-resources'
import { ContextMenu, DocNavLink, ParentsNavigator, UpDownNavigator } from '@hcengineering/view-resources'
import { createEventDispatcher, onDestroy } from 'svelte'
import { generateIssueShortLink, getIssueId } from '../../../issues'
import tracker from '../../../plugin'

View File

@ -17,14 +17,9 @@
import { Issue, Project } from '@hcengineering/tracker'
import { registerFocus } from '@hcengineering/ui'
import { ViewOptions, Viewlet } from '@hcengineering/view'
import {
ActionContext,
List,
ListSelectionProvider,
SelectDirection,
selectionStore
} from '@hcengineering/view-resources'
import { List, ListSelectionProvider, SelectDirection, selectionStore } from '@hcengineering/view-resources'
import tracker from '../../../plugin'
import { ActionContext } from '@hcengineering/presentation'
export let query: DocumentQuery<Issue> | undefined = undefined
export let issues: Issue[] | undefined = undefined

View File

@ -16,12 +16,13 @@
import { SortingOrder } from '@hcengineering/core'
import { Scrum, ScrumRecord } from '@hcengineering/tracker'
import { Button, Icon, IconDetails, IconDetailsFilled } from '@hcengineering/ui'
import { ActionContext, List } from '@hcengineering/view-resources'
import { List } from '@hcengineering/view-resources'
import tracker from '../../plugin'
import RecordScrumButton from './RecordScrumButton.svelte'
import ScrumEditor from './ScrumEditor.svelte'
import ScrumHeader from './ScrumHeader.svelte'
import ScrumRecordPresenter from './ScrumRecordPresenter.svelte'
import { ActionContext } from '@hcengineering/presentation'
export let scrum: Scrum
export let activeScrumRecord: ScrumRecord | undefined

View File

@ -17,12 +17,13 @@
import { Ref, SortingOrder } from '@hcengineering/core'
import { ScrumRecord, Project, Scrum } from '@hcengineering/tracker'
import { Button, Icon, IconAdd, Label, showPopup } from '@hcengineering/ui'
import { ActionContext, List } from '@hcengineering/view-resources'
import { List } from '@hcengineering/view-resources'
import tracker from '../../plugin'
import NewScrum from './NewScrum.svelte'
import RecordScrumPresenter from './RecordScrumPresenter.svelte'
import ScrumDatePresenter from './ScrumDatePresenter.svelte'
import ScrumPresenter from './ScrumPresenter.svelte'
import { ActionContext } from '@hcengineering/presentation'
export let currentSpace: Ref<Project>
export let activeScrumRecord: ScrumRecord | undefined

View File

@ -14,10 +14,10 @@
-->
<script lang="ts">
import { Ref } from '@hcengineering/core'
import { createQuery } from '@hcengineering/presentation'
import { createQuery, ActionContext } from '@hcengineering/presentation'
import tracker, { Component, IssueDraft, Project, Milestone } from '@hcengineering/tracker'
import { eventToHTMLElement, IconCircles, showPopup } from '@hcengineering/ui'
import { ActionContext, FixedColumn } from '@hcengineering/view-resources'
import { FixedColumn } from '@hcengineering/view-resources'
import { createEventDispatcher } from 'svelte'
import { flip } from 'svelte/animate'
import AssigneeEditor from '../issues/AssigneeEditor.svelte'

View File

@ -14,10 +14,10 @@
-->
<script lang="ts">
import { Ref } from '@hcengineering/core'
import { createQuery } from '@hcengineering/presentation'
import { createQuery, ActionContext } from '@hcengineering/presentation'
import tracker, { Component, Issue, IssueTemplateChild, Project, Milestone } from '@hcengineering/tracker'
import { IconCircles, eventToHTMLElement, showPopup } from '@hcengineering/ui'
import { ActionContext, FixedColumn } from '@hcengineering/view-resources'
import { FixedColumn } from '@hcengineering/view-resources'
import { createEventDispatcher } from 'svelte'
import { flip } from 'svelte/animate'
import AssigneeEditor from '../issues/AssigneeEditor.svelte'

View File

@ -1,6 +1,6 @@
import { Class, Doc, DocumentQuery, Hierarchy, Ref, Space, TxResult } from '@hcengineering/core'
import { Asset, IntlString, Resource, getResource } from '@hcengineering/platform'
import { MessageBox, getClient, updateAttribute } from '@hcengineering/presentation'
import { MessageBox, getClient, updateAttribute, ContextStore, contextStore } from '@hcengineering/presentation'
import {
AnyComponent,
AnySvelteComponent,
@ -13,7 +13,6 @@ import {
showPopup
} from '@hcengineering/ui'
import MoveView from './components/Move.svelte'
import { ContextStore, contextStore } from './context'
import view from './plugin'
import { FocusSelection, SelectDirection, focusStore, previewDocument, selectionStore } from './selection'
import { deleteObjects, getObjectLinkFragment } from './utils'

View File

@ -15,12 +15,11 @@
<script lang="ts">
import core, { Doc, Hierarchy, Ref, TxRemoveDoc } from '@hcengineering/core'
import { getResource } from '@hcengineering/platform'
import { addTxListener, getClient } from '@hcengineering/presentation'
import { addTxListener, getClient, contextStore } from '@hcengineering/presentation'
import { AnyComponent, Component } from '@hcengineering/ui'
import { Action, ViewContextType } from '@hcengineering/view'
import { fly } from 'svelte/transition'
import { getContextActions, getSelection } from '../actions'
import { contextStore } from '../context'
import { focusStore, previewDocument, selectionStore } from '../selection'
import { getObjectPreview } from '../utils'

View File

@ -15,14 +15,13 @@
<script lang="ts">
import { WithLookup, Doc } from '@hcengineering/core'
import { getResource, translate } from '@hcengineering/platform'
import { createQuery, getClient } from '@hcengineering/presentation'
import { createQuery, getClient, ActionContext } from '@hcengineering/presentation'
import ui, { Button, closePopup, Component, Icon, IconArrowLeft, Label } from '@hcengineering/ui'
import { Action, ViewContext } from '@hcengineering/view'
import { onMount } from 'svelte'
import { filterActions, getSelection } from '../actions'
import view from '../plugin'
import { focusStore, selectionStore } from '../selection'
import ActionContext from './ActionContext.svelte'
import { ListView, resizeObserver } from '@hcengineering/ui'
import ObjectPresenter from './ObjectPresenter.svelte'
import { tick } from 'svelte'

View File

@ -24,6 +24,7 @@
AttributeCategoryOrder,
AttributesBar,
KeyedAttribute,
ActionContext,
createQuery,
getAttributePresenterClass,
getClient,
@ -34,7 +35,6 @@
import { createEventDispatcher, onDestroy } from 'svelte'
import { ContextMenu, ParentsNavigator } from '..'
import { categorizeFields, getCollectionCounter, getFiltredKeys } from '../utils'
import ActionContext from './ActionContext.svelte'
import DocAttributeBar from './DocAttributeBar.svelte'
import UpDownNavigator from './UpDownNavigator.svelte'

View File

@ -18,11 +18,11 @@
import { Scroller, tableSP, FadeOptions } from '@hcengineering/ui'
import { BuildModelKey } from '@hcengineering/view'
import { onMount } from 'svelte'
import { ActionContext } from '..'
import { focusStore, ListSelectionProvider, SelectDirection, selectionStore } from '../selection'
import { LoadingProps } from '../utils'
import SourcePresenter from './inference/SourcePresenter.svelte'
import Table from './Table.svelte'
import { ActionContext } from '@hcengineering/presentation'
export let _class: Ref<Class<Doc>>
export let query: DocumentQuery<Doc>

View File

@ -16,7 +16,7 @@
<script lang="ts">
import type { Class, Doc, DocumentQuery, FindOptions, Ref, Space } from '@hcengineering/core'
import { TableBrowser } from '..'
import ActionContext from './ActionContext.svelte'
import { ActionContext } from '@hcengineering/presentation'
export let _class: Ref<Class<Doc>>
export let space: Ref<Space> | undefined = undefined

View File

@ -4,7 +4,8 @@
import { AnyComponent, Scroller } from '@hcengineering/ui'
import { BuildModelKey, ViewOptions, Viewlet } from '@hcengineering/view'
import { onMount } from 'svelte'
import { ActionContext, ListSelectionProvider, SelectDirection, focusStore, selectionStore } from '../..'
import { ActionContext } from '@hcengineering/presentation'
import { ListSelectionProvider, SelectDirection, focusStore, selectionStore } from '../..'
import List from './List.svelte'

View File

@ -102,7 +102,6 @@ import { IndexedDocumentPreview } from '@hcengineering/presentation'
import { statusSort } from './utils'
import { showEmptyGroups } from './viewOptions'
export { getActions, invokeAction } from './actions'
export { default as ActionContext } from './components/ActionContext.svelte'
export { default as ActionHandler } from './components/ActionHandler.svelte'
export { default as AddSavedView } from './components/filter/AddSavedView.svelte'
export { default as FilterButton } from './components/filter/FilterButton.svelte'
@ -124,7 +123,6 @@ export { default as TableBrowser } from './components/TableBrowser.svelte'
export { default as ValueSelector } from './components/ValueSelector.svelte'
export { default as FilterRemovedNotification } from './components/filter/FilterRemovedNotification.svelte'
export { default as ParentsNavigator } from './components/ParentsNavigator.svelte'
export * from './context'
export * from './filter'
export * from './selection'
export * from './utils'

View File

@ -20,7 +20,7 @@
import notification, { notificationId } from '@hcengineering/notification'
import { BrowserNotificatator, NotificationClientImpl } from '@hcengineering/notification-resources'
import { IntlString, getMetadata, getResource } from '@hcengineering/platform'
import { configurationStore, createQuery, getClient } from '@hcengineering/presentation'
import { configurationStore, createQuery, getClient, ActionContext } from '@hcengineering/presentation'
import {
AnyComponent,
CompAndProps,
@ -51,7 +51,6 @@
import view from '@hcengineering/view'
import setting from '@hcengineering/setting'
import {
ActionContext,
ActionHandler,
ListSelectionProvider,
NavLink,