Chunter: Download file action (#1570)

Signed-off-by: Denis Bunakalya <denis.bunakalya@xored.com>
This commit is contained in:
Denis Bunakalya 2022-04-28 06:23:46 +03:00 committed by GitHub
parent 5fb0565aee
commit fec4d180ed
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 132 additions and 73 deletions

View File

@ -0,0 +1,73 @@
<!--
// Copyright © 2022 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.
-->
<script lang="ts">
import type { Attachment } from '@anticrm/attachment'
import { getResource } from '@anticrm/platform'
import { showPopup, ActionIcon, IconMoreH, Menu, Icon } from '@anticrm/ui'
import { Action } from '@anticrm/view'
import { getFileUrl } from '@anticrm/presentation'
import attachmentPlugin from '../plugin'
import FileDownload from './icons/FileDownload.svelte'
export let attachment: Attachment
export let isSaved = false
$: saveAttachmentAction = isSaved
? ({
label: attachmentPlugin.string.RemoveAttachmentFromSaved,
action: attachmentPlugin.actionImpl.DeleteAttachmentFromSaved
} as Action)
: ({
label: attachmentPlugin.string.AddAttachmentToSaved,
action: attachmentPlugin.actionImpl.AddAttachmentToSaved
} as Action)
const showMenu = (ev: Event) => {
showPopup(
Menu,
{
actions: [
{
label: saveAttachmentAction.label,
icon: saveAttachmentAction.icon,
action: async (evt: MouseEvent) => {
const impl = await getResource(saveAttachmentAction.action)
await impl(attachment, evt)
}
}
]
},
ev.target as HTMLElement
)
}
</script>
<div class="actions">
<a class="downloadButton" href={getFileUrl(attachment.file)} download={attachment.name} on:click|stopPropagation>
<Icon icon={FileDownload} size={'small'} />
</a>
<ActionIcon icon={IconMoreH} size={'small'} action={showMenu} />
</div>
<style lang="scss">
.actions {
display: flex;
}
.downloadButton {
margin-right: 0.2rem;
}
</style>

View File

@ -15,48 +15,17 @@
-->
<script lang="ts">
import type { Attachment } from '@anticrm/attachment'
import { getResource } from '@anticrm/platform'
import { getFileUrl, PDFViewer } from '@anticrm/presentation'
import { showPopup, closeTooltip, ActionIcon, IconMoreH, Menu } from '@anticrm/ui'
import { Action } from '@anticrm/view'
import { showPopup, closeTooltip } from '@anticrm/ui'
import { getType } from '../utils'
import AttachmentPresenter from './AttachmentPresenter.svelte'
import AttachmentActions from './AttachmentActions.svelte'
import AudioPlayer from './AudioPlayer.svelte'
import attachment from '../plugin'
export let value: Attachment
export let isSaved: boolean = false
$: type = getType(value.type)
$: saveAttachmentAction = isSaved
? ({
label: attachment.string.RemoveAttachmentFromSaved,
action: attachment.actionImpl.DeleteAttachmentFromSaved
} as Action)
: ({
label: attachment.string.AddAttachmentToSaved,
action: attachment.actionImpl.AddAttachmentToSaved
} as Action)
const showMenu = (ev: Event) => {
showPopup(
Menu,
{
actions: [
{
label: saveAttachmentAction.label,
icon: saveAttachmentAction.icon,
action: async (evt: MouseEvent) => {
const impl = await getResource(saveAttachmentAction.action)
await impl(value, evt)
}
}
]
},
ev.target as HTMLElement
)
}
</script>
<div class="flex-row-center">
@ -69,27 +38,15 @@
}}
>
<img src={getFileUrl(value.file)} alt={value.name} />
<div class="more">
<ActionIcon
icon={IconMoreH}
size={'small'}
action={(e) => {
showMenu(e)
}}
/>
<div class="actions">
<AttachmentActions attachment={value} {isSaved} />
</div>
</div>
{:else if type === 'audio'}
<div class="buttonContainer">
<AudioPlayer {value} />
<div class="more">
<ActionIcon
icon={IconMoreH}
size={'small'}
action={(e) => {
showMenu(e)
}}
/>
<div class="actions">
<AttachmentActions attachment={value} {isSaved} />
</div>
</div>
{:else if type === 'video'}
@ -101,27 +58,15 @@
<AttachmentPresenter {value} />
</div>
</video>
<div class="more">
<ActionIcon
icon={IconMoreH}
size={'small'}
action={(e) => {
showMenu(e)
}}
/>
<div class="actions">
<AttachmentActions attachment={value} {isSaved} />
</div>
</div>
{:else}
<div class="flex container buttonContainer">
<AttachmentPresenter {value} />
<div class="more">
<ActionIcon
icon={IconMoreH}
size={'small'}
action={(e) => {
showMenu(e)
}}
/>
<div class="actions">
<AttachmentActions attachment={value} {isSaved} />
</div>
</div>
{/if}
@ -137,14 +82,14 @@
.buttonContainer {
align-items: flex-start;
.more {
.actions {
margin-left: 0.5rem;
visibility: hidden;
}
}
.buttonContainer:hover {
.more {
.actions {
visibility: visible;
}
}

View File

@ -17,7 +17,7 @@
import contact, { Employee } from '@anticrm/contact'
import { EmployeeAccount } from '@anticrm/contact'
import core, { Class, Doc, getCurrentAccount, Ref, Space } from '@anticrm/core'
import { getClient } from '@anticrm/presentation'
import { getClient, getFileUrl } from '@anticrm/presentation'
import ui, {
getCurrentLocation,
location,
@ -27,7 +27,8 @@
showPopup,
navigate,
EditWithIcon,
Spinner
Spinner,
Icon
} from '@anticrm/ui'
import { Menu } from '@anticrm/view-resources'
import { onDestroy } from 'svelte'
@ -39,6 +40,7 @@
sortModeToOptionObject
} from '..'
import attachment from '../plugin'
import FileDownload from './icons/FileDownload.svelte'
import FileBrowserFilters from './FileBrowserFilters.svelte'
import FileBrowserSortMenu from './FileBrowserSortMenu.svelte'
@ -156,6 +158,9 @@
<AttachmentPresenter value={attachment} />
</div>
<div class="eAttachmentRowActions" class:fixed={i === selectedFileNumber}>
<a href={getFileUrl(attachment.file)} download={attachment.name}>
<Icon icon={FileDownload} size={'small'} />
</a>
<div id="context-menu" class="eAttachmentRowMenu" on:click={(event) => showFileMenu(event, attachment, i)}>
<IconMoreV size={'small'} />
</div>
@ -195,6 +200,7 @@
padding: 0.25rem 0;
.eAttachmentRowActions {
display: flex;
visibility: hidden;
border: 1px solid var(--theme-bg-focused-border);
padding: 0.2rem;
@ -202,6 +208,7 @@
}
.eAttachmentRowMenu {
margin-left: 0.2rem;
visibility: hidden;
opacity: 0.6;
cursor: pointer;

View File

@ -0,0 +1,27 @@
<!--
// Copyright © 2022 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.
-->
<script lang="ts">
export let size: 'small' | 'medium' | 'large'
const fill: string = 'currentColor'
</script>
<svg class="svg-{size}" {fill} xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16">
<path
d="M11.2 0H5.8c-.1 0-.3.1-.4.2L1.3 4.5c-.1.1-.1.2-.1.3v7.5c0 2 1.5 3.6 3.5 3.7h6.6c2 0 3.6-1.7 3.5-3.7V3.5c0-1.9-1.6-3.5-3.6-3.5zM5.5 1.4V3c0 1-.7 1.8-1.6 1.8H2.2l3.3-3.4zm8.4 11c0 1.5-1.1 2.7-2.7 2.7H4.7c-1.5-.1-2.6-1.2-2.6-2.7V5.8h1.8c1.4 0 2.6-1.2 2.6-2.8V1h4.8c1.4 0 2.6 1.2 2.7 2.6v8.8h-.1z"
/>
<path
d="M7.7 11.9s.1.1.2.1H8.2c.1 0 .1-.1.2-.1l2-2.1c.2-.2.2-.5 0-.7-.2-.2-.5-.2-.7 0l-1.3 1.3V6.2c.1-.3-.1-.5-.4-.5-.3 0-.5.2-.5.5v4.2L6.2 9.1C6.1 9 6 9 5.9 9s-.2 0-.3.1c-.2.2-.2.5 0 .7l2.1 2.1z"
/>
</svg>

View File

@ -24,6 +24,7 @@ import TxAttachmentCreate from './components/activity/TxAttachmentCreate.svelte'
import Attachments from './components/Attachments.svelte'
import FileBrowser from './components/FileBrowser.svelte'
import Photos from './components/Photos.svelte'
import FileDownload from './components/icons/FileDownload.svelte'
import { uploadFile, deleteFile } from './utils'
import attachment, { Attachment } from '@anticrm/attachment'
import { SortingOrder, SortingQuery } from '@anticrm/core'
@ -39,7 +40,8 @@ export {
AttachmentPresenter,
AttachmentRefInput,
AttachmentList,
AttachmentDocList
AttachmentDocList,
FileDownload
}
export enum FileBrowserSortMode {

View File

@ -15,12 +15,12 @@
-->
<script lang="ts">
import attachment, { Attachment } from '@anticrm/attachment'
import { AttachmentPresenter } from '@anticrm/attachment-resources'
import { AttachmentPresenter, FileDownload } from '@anticrm/attachment-resources'
import { ChunterSpace } from '@anticrm/chunter'
import { Doc, SortingOrder } from '@anticrm/core'
import { createQuery } from '@anticrm/presentation'
import { createQuery, getFileUrl } from '@anticrm/presentation'
import { Menu } from '@anticrm/view-resources'
import { getCurrentLocation, showPopup, IconMoreV, Label, navigate } from '@anticrm/ui'
import { getCurrentLocation, showPopup, IconMoreV, Label, navigate, Icon } from '@anticrm/ui'
export let channel: ChunterSpace | undefined
@ -65,6 +65,9 @@
<AttachmentPresenter value={attachment} />
</div>
<div class="eAttachmentRowActions" class:fixed={i === selectedRowNumber}>
<a href={getFileUrl(attachment.file)} download={attachment.name}>
<Icon icon={FileDownload} size={'small'} />
</a>
<div id="context-menu" class="eAttachmentRowMenu" on:click={(event) => showMenu(event, attachment, i)}>
<IconMoreV size={'small'} />
</div>
@ -126,6 +129,7 @@
padding: 5px 0;
.eAttachmentRowActions {
display: flex;
visibility: hidden;
border: 1px solid var(--theme-bg-focused-border);
padding: 0.2rem;
@ -133,6 +137,7 @@
}
.eAttachmentRowMenu {
margin-left: 0.2rem;
visibility: hidden;
opacity: 0.6;
cursor: pointer;