Attachment preview (#1134)

Signed-off-by: Denis Bykhov <80476319+BykhovDenis@users.noreply.github.com>
This commit is contained in:
Denis Bykhov 2022-03-12 18:24:30 +06:00 committed by GitHub
parent 6c63a19677
commit b81f4ae28d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 229 additions and 23 deletions

View File

@ -14,18 +14,29 @@
-->
<script lang="ts">
import { getPlatformColor } from '../colors'
export let value: number
export let min: number = 0
export let max: number = 100
export let color: string = '#50BCF9'
export let color: number = 5
export let editable = false
const proc: number = (max - min) / 100
$: proc = (max - min) / 100
if (value > max) value = max
if (value < min) value = min
function click (e: MouseEvent) {
const rect = (e.target as HTMLElement).getBoundingClientRect()
const x = e.clientX - rect.left
const pos = x / rect.width
value = (max - min) * pos
console.log(`set value to ${value}`)
console.log(`max value ${max}`)
}
</script>
<div class="container">
<div class="bar" style="background-color: {color}; width: calc(100% * {Math.round((value - min) / proc)} / 100);"/>
<div class="container" on:click={click} class:cursor-pointer={editable}>
<div class="bar" style="background-color: {getPlatformColor(color)}; width: calc(100% * {Math.round((value - min) / proc)} / 100);"/>
</div>
<style lang="scss">
@ -33,7 +44,7 @@
position: relative;
width: 100%;
height: .25rem;
background-color: var(--theme-button-bg-hovered);
background-color: var(--theme-bg-accent-hover);
border-radius: .125rem;
.bar {

View File

@ -15,7 +15,7 @@
<script lang="ts">
import { Attachment } from '@anticrm/attachment'
import AttachmentPresenter from './AttachmentPresenter.svelte'
import AttachmentPreview from './AttachmentPreview.svelte'
export let attachments: Attachment[] = []
</script>
@ -24,24 +24,14 @@
<div class='container'>
{#each attachments as attachment}
<div class='item'>
<AttachmentPresenter value={attachment} />
<AttachmentPreview value={attachment} />
</div>
{/each}
</div>
{/if}
<style lang="scss">
.container {
background-color: var(--theme-bg-accent-color);
border: 1px solid var(--theme-bg-accent-color);
border-radius: 0.75rem;
.item {
padding: 1rem;
}
.item + .item {
border-top: 1px solid var(--theme-bg-accent-color);
}
.item {
padding: 0.5rem;
}
</style>

View File

@ -0,0 +1,77 @@
<!--
// Copyright © 2020, 2021 Anticrm Platform Contributors.
// Copyright © 2021 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 { getFileUrl, PDFViewer } from '@anticrm/presentation'
import { getType } from '../utils'
import { showPopup, closeTooltip } from '@anticrm/ui'
import AttachmentPresenter from './AttachmentPresenter.svelte'
import AudioPlayer from './AudioPlayer.svelte'
export let value: Attachment
$: type = getType(value.type)
</script>
<div class="flex-row-center">
{#if type === 'image'}
<div class='content flex-center cursor-pointer' on:click={() => {
closeTooltip()
showPopup(PDFViewer, { file: value.file, name: value.name, contentType: value.type }, 'right')
}}>
<img src={getFileUrl(value.file)} alt={value.name} />
</div>
{:else if type === 'audio'}
<AudioPlayer {value} />
{:else if type === 'video'}
<div class='content flex-center'>
<video controls>
<source src={getFileUrl(value.file)} type={value.type}>
<track kind="captions" label={value.name} />
<div class='container'>
<AttachmentPresenter {value} />
</div>
</video>
</div>
{:else}
<div class='container'>
<AttachmentPresenter {value} />
</div>
{/if}
</div>
<style lang="scss">
.container {
background-color: var(--theme-bg-accent-color);
border: 1px solid var(--theme-bg-accent-color);
border-radius: 0.75rem;
padding: 0.5rem
}
.content {
max-width: 20rem;
max-height: 20rem;
img, video {
max-width: 20rem;
max-height: 20rem;
border-radius: 0.75rem;
width: 100%;
height: 100%;
}
}
</style>

View File

@ -0,0 +1,56 @@
<!--
// 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 { getFileUrl } from '@anticrm/presentation'
import { CircleButton, Progress } from '@anticrm/ui'
import Play from './icons/Play.svelte'
import Pause from './icons/Pause.svelte'
export let value: Attachment
let time = 0
let duration = Number.POSITIVE_INFINITY
let paused = true
function buttonClick () {
paused = !paused
}
$: icon = !paused ? Pause : Play
</script>
<div class='container flex-between'>
<div>
<CircleButton size='x-large' on:click={buttonClick} {icon} />
</div>
<div class='w-full ml-4'>
<Progress bind:value={time} max={Number.isFinite(duration) ? duration : 100} editable />
</div>
</div>
<audio bind:duration bind:currentTime={time} bind:paused>
<source src={getFileUrl(value.file)} type={value.type}>
</audio>
<style lang="scss">
.container {
background-color: var(--theme-bg-accent-color);
border: 1px solid var(--theme-bg-accent-color);
border-radius: 0.75rem;
width: 20rem;
padding: 0.5rem;
}
</style>

View File

@ -87,7 +87,7 @@
const el: HTMLElement = ev.currentTarget as HTMLElement
el.scrollIntoView({ behavior: 'smooth', block: 'nearest', inline: 'center' })
if (item !== undefined) {
showPopup(PDFViewer, { file: item.file, name: item.name }, 'right')
showPopup(PDFViewer, { file: item.file, name: item.name, contentType: item.type }, 'right')
} else {
inputFile.click()
}
@ -134,7 +134,7 @@
>
{#each images as image (image._id)}
<div
class="item"
class="item flex-center"
on:click={(ev) => {
click(ev, image)
}}
@ -178,8 +178,8 @@
cursor: pointer;
img {
width: 5rem;
height: 5rem;
min-width: 5rem;
min-height: 5rem;
}
}

View File

@ -0,0 +1,29 @@
<!--
// 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}" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100">
<g {fill}>
<path d="M39.806,72.858h-8.915c-2.176,0-3.94-1.764-3.94-3.94V31.119c0-2.176,1.764-3.94,3.94-3.94h8.915 c2.176,0,3.94,1.764,3.94,3.94v37.799C43.746,71.094,41.982,72.858,39.806,72.858z"/>
<path d="M68.109,72.821h-8.915c-2.176,0-3.94-1.764-3.94-3.94V31.082c0-2.176,1.764-3.94,3.94-3.94h8.915 c2.176,0,3.94,1.764,3.94,3.94v37.799C72.049,71.057,70.285,72.821,68.109,72.821z"/>
<path d="M40.489,27.248c0.769,0.719,1.257,1.735,1.257,2.871v37.799c0,2.176-1.764,3.94-3.94,3.94h-8.915 c-0.234,0-0.46-0.03-0.683-0.069c0.704,0.658,1.643,1.069,2.683,1.069h8.915c2.176,0,3.94-1.764,3.94-3.94V31.119 C43.746,29.177,42.338,27.573,40.489,27.248z"/>
<path d="M68.792,27.211c0.769,0.719,1.257,1.735,1.257,2.871v37.799c0,2.176-1.764,3.94-3.94,3.94h-8.915 c-0.234,0-0.46-0.03-0.683-0.069c0.704,0.658,1.643,1.069,2.683,1.069h8.915c2.176,0,3.94-1.764,3.94-3.94V31.082 C72.049,29.14,70.641,27.535,68.792,27.211z"/>
<path d="M39.806,72.858h-8.915c-2.176,0-3.94-1.764-3.94-3.94V31.119 c0-2.176,1.764-3.94,3.94-3.94h8.915c2.176,0,3.94,1.764,3.94,3.94v37.799C43.746,71.094,41.982,72.858,39.806,72.858z" style="fill:none;stroke:#000000;stroke-miterlimit:10;"/>
<path d="M68.109,72.821h-8.915c-2.176,0-3.94-1.764-3.94-3.94V31.082 c0-2.176,1.764-3.94,3.94-3.94h8.915c2.176,0,3.94,1.764,3.94,3.94v37.799C72.049,71.057,70.285,72.821,68.109,72.821z" style="fill:none;stroke:#000000;stroke-miterlimit:10;"/>
</g>
</svg>

View File

@ -0,0 +1,26 @@
<!--
// 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}" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100">
<g {fill}>
<path d="M31.356,25.677l38.625,22.3c1.557,0.899,1.557,3.147,0,4.046l-38.625,22.3c-1.557,0.899-3.504-0.225-3.504-2.023V27.7 C27.852,25.902,29.798,24.778,31.356,25.677z"/>
<path d="M69.981,47.977l-38.625-22.3c-0.233-0.134-0.474-0.21-0.716-0.259l37.341,21.559c1.557,0.899,1.557,3.147,0,4.046 l-38.625,22.3c-0.349,0.201-0.716,0.288-1.078,0.301c0.656,0.938,1.961,1.343,3.078,0.699l38.625-22.3 C71.538,51.124,71.538,48.876,69.981,47.977z"/>
<path d="M31.356,25.677l38.625,22.3c1.557,0.899,1.557,3.147,0,4.046 l-38.625,22.3c-1.557,0.899-3.504-0.225-3.504-2.023V27.7C27.852,25.902,29.798,24.778,31.356,25.677z" style="fill:none;stroke:#000000;stroke-miterlimit:10;"/>
</g>
</svg>

View File

@ -67,3 +67,20 @@ export async function deleteFile (id: string): Promise<void> {
throw new Error('Failed to delete file')
}
}
export function getType (type: string): 'image' | 'video' | 'audio' | 'pdf' | 'other' {
if (type.startsWith('image/')) {
return 'image'
}
if (type.startsWith('audio/')) {
return 'audio'
}
if (type.startsWith('video/')) {
return 'video'
}
if (type.includes('application/pdf')) {
return 'pdf'
}
return 'other'
}