Skip to content

Commit

Permalink
Merge pull request #7066 from nextcloud/enhancement/viewer-attachments
Browse files Browse the repository at this point in the history
Open image, video, audio and PDF attachments with viewer
  • Loading branch information
ChristophWurst authored Sep 2, 2022
2 parents d2fb77d + a786e4b commit fd37f6b
Show file tree
Hide file tree
Showing 8 changed files with 85 additions and 66 deletions.
12 changes: 11 additions & 1 deletion lib/Controller/PageController.php
Original file line number Diff line number Diff line change
Expand Up @@ -33,17 +33,20 @@
use OCA\Mail\Db\TagMapper;
use OCA\Mail\Service\AccountService;
use OCA\Mail\Service\AliasesService;
use OCA\Viewer\Event\LoadViewer;
use OCP\AppFramework\Controller;
use OCP\AppFramework\Http\ContentSecurityPolicy;
use OCP\AppFramework\Http\RedirectResponse;
use OCP\AppFramework\Http\TemplateResponse;
use OCP\AppFramework\Services\IInitialState;
use OCP\EventDispatcher\IEventDispatcher;
use OCP\IConfig;
use OCP\IRequest;
use OCP\IURLGenerator;
use OCP\IUserSession;
use Psr\Log\LoggerInterface;
use Throwable;
use function class_exists;
use function json_decode;

class PageController extends Controller {
Expand Down Expand Up @@ -83,6 +86,7 @@ class PageController extends Controller {

/** @var OutboxService */
private $outboxService;
private IEventDispatcher $dispatcher;

public function __construct(string $appName,
IRequest $request,
Expand All @@ -97,7 +101,8 @@ public function __construct(string $appName,
TagMapper $tagMapper,
IInitialState $initialStateService,
LoggerInterface $logger,
OutboxService $outboxService) {
OutboxService $outboxService,
IEventDispatcher $dispatcher) {
parent::__construct($appName, $request);

$this->urlGenerator = $urlGenerator;
Expand All @@ -112,6 +117,7 @@ public function __construct(string $appName,
$this->initialStateService = $initialStateService;
$this->logger = $logger;
$this->outboxService = $outboxService;
$this->dispatcher = $dispatcher;
}

/**
Expand All @@ -121,6 +127,10 @@ public function __construct(string $appName,
* @return TemplateResponse renders the index page
*/
public function index(): TemplateResponse {
if (class_exists(LoadViewer::class)) {
$this->dispatcher->dispatchTyped(new LoadViewer());
}

$this->initialStateService->provideInitialState(
'debug',
$this->config->getSystemValue('debug', false)
Expand Down
7 changes: 4 additions & 3 deletions lib/Db/MessageMapper.php
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@
use function array_udiff;
use function get_class;
use function ltrim;
use function mb_convert_encoding;
use function mb_strcut;
use function OCA\Mail\array_flat_map;

Expand Down Expand Up @@ -496,9 +497,9 @@ public function updatePreviewDataBulk(Message ...$messages): array {
$query->setParameter('uid', $message->getUid(), IQueryBuilder::PARAM_INT);
$query->setParameter('mailbox_id', $message->getMailboxId(), IQueryBuilder::PARAM_INT);
$query->setParameter('flag_attachments', $message->getFlagAttachments(), $message->getFlagAttachments() === null ? IQueryBuilder::PARAM_NULL : IQueryBuilder::PARAM_BOOL);
$previewText = $message->getPreviewText();
if ($previewText !== null) {
$previewText = mb_strcut(mb_convert_encoding($previewText, 'UTF-8', 'UTF-8'), 0, 255);
$previewText = null;
if ($message->getPreviewText() !== null) {
$previewText = mb_strcut(mb_convert_encoding($message->getPreviewText(), 'UTF-8', 'UTF-8'), 0, 255);
}
$query->setParameter(
'preview_text',
Expand Down
17 changes: 17 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@
"@nextcloud/l10n": "^1.6.0",
"@nextcloud/logger": "^2.3.0",
"@nextcloud/moment": "^1.2.1",
"@nextcloud/paths": "^2.1.0",
"@nextcloud/router": "^2.0.0",
"@nextcloud/vue": "^7.0.0-beta.0",
"@nextcloud/vue-dashboard": "^2",
Expand Down
44 changes: 0 additions & 44 deletions src/components/AttachmentImageViewer.vue

This file was deleted.

15 changes: 10 additions & 5 deletions src/components/MessageAttachment.vue
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,10 @@
-->

<template>
<div class="attachment">
<div class="attachment" :class="{'message-attachment--can-preview': canPreview }" @click="$emit('click', $event)">
<img v-if="isImage"
class="mail-attached-image"
:src="url"
@click="$emit('click', $event)">
:src="url">
<img class="attachment-icon" :src="mimeUrl">
<span class="attachment-name"
:title="label">{{ name }}
Expand Down Expand Up @@ -140,6 +139,10 @@ export default {
type: Boolean,
default: false,
},
canPreview: {
type: Boolean,
default: false,
},
},
data() {
return {
Expand Down Expand Up @@ -240,14 +243,16 @@ export default {
.attachment:hover,
.attachment span:hover {
background-color: var(--color-background-hover);
cursor: pointer;
&.message-attachment--can-preview * {
cursor: pointer;
}
}
.mail-attached-image {
display: block;
max-width: 100%;
border-radius: var(--border-radius);
cursor: pointer;
}
.attachment-import-popover {
right: 32px;
Expand Down
47 changes: 35 additions & 12 deletions src/components/MessageAttachments.vue
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
<div class="mail-message-attachments">
<div class="attachments">
<MessageAttachment
v-for="attachment in attachments"
v-for="(attachment, idx) in attachments"
:id="attachment.id"
:key="attachment.id"
:file-name="attachment.fileName"
Expand All @@ -33,10 +33,8 @@
:is-calendar-event="attachment.isCalendarEvent"
:mime="attachment.mime"
:mime-url="attachment.mimeUrl"
@click="showViewer(attachment)" />
<AttachmentImageViewer v-if="attachmentImageURL && showPreview"
:url="attachmentImageURL"
@close="showPreview = false" />
:can-preview="canPreview(fileInfos[idx])"
@click="showViewer(fileInfos[idx])" />
</div>
<p v-if="moreThanOne" class="attachments-button-wrapper">
<ButtonVue
Expand Down Expand Up @@ -64,6 +62,7 @@
</template>

<script>
import { basename } from '@nextcloud/paths'
import ButtonVue from '@nextcloud/vue/dist/Components/NcButton'
import IconLoading from '@nextcloud/vue/dist/Components/NcLoadingIcon'
import IconFolder from 'vue-material-design-icons/Folder'
Expand All @@ -73,12 +72,10 @@ import { saveAttachmentsToFiles } from '../service/AttachmentService'
import MessageAttachment from './MessageAttachment'
import Logger from '../logger'
import AttachmentImageViewer from './AttachmentImageViewer'
export default {
name: 'MessageAttachments',
components: {
AttachmentImageViewer,
MessageAttachment,
ButtonVue,
IconLoading,
Expand All @@ -98,10 +95,27 @@ export default {
return {
savingToCloud: false,
showPreview: false,
attachmentImageURL: '',
}
},
computed: {
fileInfos() {
return this.attachments.map(attachment => ({
filename: attachment.downloadUrl,
source: attachment.downloadUrl,
basename: basename(attachment.downloadUrl),
mime: attachment.mime,
etag: 'fixme',
hasPreview: false,
fileid: parseInt(attachment.id, 10),
}))
},
previewableFileInfos() {
return this.fileInfos.filter(fileInfo => (fileInfo.mime.startsWith('image/')
|| fileInfo.mime.startsWith('video/')
|| fileInfo.mime.startsWith('audio/')
|| fileInfo.mime === 'application/pdf')
&& OCA.Viewer.mimetypes.includes(fileInfo.mime))
},
moreThanOne() {
return this.attachments.length > 1
},
Expand All @@ -112,6 +126,9 @@ export default {
},
},
methods: {
canPreview(fileInfo) {
return this.previewableFileInfos.includes(fileInfo)
},
saveAll() {
const picker = getFilePickerBuilder(t('mail', 'Choose a folder to store the attachments in'))
.setMultiSelect(false)
Expand Down Expand Up @@ -140,10 +157,16 @@ export default {
downloadZip() {
window.location = this.zipUrl
},
showViewer(attachment) {
if (attachment.isImage) {
this.showPreview = true
this.attachmentImageURL = attachment.downloadUrl
showViewer(fileInfo) {
if (!this.canPreview(fileInfo)) {
return
}
if (this.previewableFileInfos.includes(fileInfo)) {
OCA.Viewer.open({
fileInfo,
list: this.previewableFileInfos,
})
}
},
},
Expand Down
8 changes: 7 additions & 1 deletion tests/Unit/Controller/PageControllerTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
use OCP\AppFramework\Http\RedirectResponse;
use OCP\AppFramework\Http\TemplateResponse;
use OCP\AppFramework\Services\IInitialState;
use OCP\EventDispatcher\IEventDispatcher;
use OCP\IConfig;
use OCP\IRequest;
use OCP\IURLGenerator;
Expand Down Expand Up @@ -89,6 +90,9 @@ class PageControllerTest extends TestCase {
/** @var OutboxService|MockObject */
private $outboxService;

/** @var IEventDispatcher|MockObject */
private $eventDispatcher;

/** @var PageController */
private $controller;

Expand All @@ -109,6 +113,7 @@ protected function setUp(): void {
$this->initialState = $this->createMock(IInitialState::class);
$this->logger = $this->createMock(LoggerInterface::class);
$this->outboxService = $this->createMock(OutboxService::class);
$this->eventDispatcher = $this->createMock(IEventDispatcher::class);

$this->controller = new PageController(
$this->appName,
Expand All @@ -124,7 +129,8 @@ protected function setUp(): void {
$this->tagMapper,
$this->initialState,
$this->logger,
$this->outboxService
$this->outboxService,
$this->eventDispatcher,
);
}

Expand Down

0 comments on commit fd37f6b

Please sign in to comment.