No description
Find a file
Nextcloud bot 11389bc0fb
fix(l10n): Update translations from Transifex
Signed-off-by: Nextcloud bot <bot@nextcloud.com>
2025-10-21 01:47:10 +00:00
.github feat(deps): Add Nextcloud 33 support on master 2025-09-04 12:21:04 +02:00
.tx [tx-robot] Update transifex configuration 2022-10-01 03:06:13 +00:00
appinfo feat(deps): Add Nextcloud 33 support on master 2025-09-04 12:21:04 +02:00
composer Add composer autoloader 2023-02-20 11:22:35 +01:00
css chore(assets): Recompile assets 2025-10-14 10:44:47 +02:00
cypress chore(deps): cypress snapshot update 2025-09-07 02:01:25 +00:00
img chore: Add SPDX header 2024-09-19 11:09:27 +02:00
js chore(assets): Recompile assets 2025-10-14 10:44:47 +02:00
l10n fix(l10n): Update translations from Transifex 2025-10-21 01:47:10 +00:00
lib Chore(deps-dev): Bump nextcloud/coding-standard from 1.2.3 to 1.3.2 2024-12-14 11:33:58 +01:00
LICENSES feat: only provide fonts which are available (shipped by us) 2025-09-02 12:09:33 +02:00
src fix: added the dirPath to the node.path to file comparisons for use in subfolders in a file share. Previously, node.path for files ina a shaer were /${file.basename} 2025-10-14 10:35:46 +02:00
tests Chore(deps-dev): Bump vimeo/psalm from 4.30.0 to 5.15.0 2023-08-27 11:05:44 +02:00
.editorconfig chore: Add SPDX header 2024-09-19 11:09:27 +02:00
.eslintrc.json fix(cypress): wait for ressource load 2024-09-06 08:49:47 +02:00
.gitattributes chore: Add SPDX header 2024-09-19 11:09:27 +02:00
.gitignore chore: Add SPDX header 2024-09-19 11:09:27 +02:00
.l10nignore chore: Add SPDX header 2024-09-19 11:09:27 +02:00
.npmignore chore: Add SPDX header 2024-09-19 11:09:27 +02:00
.php-cs-fixer.dist.php chore: Add SPDX header 2024-09-19 11:09:27 +02:00
.stylelintignore chore: Add SPDX header 2024-09-19 11:09:27 +02:00
AUTHORS.md chore: Add SPDX header 2024-09-19 11:09:27 +02:00
composer.json build(dep): bump PHP requirement to 8.2 2025-10-08 12:34:53 +02:00
composer.lock build(dep): bump PHP requirement to 8.2 2025-10-08 12:34:53 +02:00
COPYING Viewer first commit 2019-02-21 21:45:35 +01:00
cypress.config.ts test: Allow running cypress on different instance 2025-01-07 18:51:38 +01:00
package-lock.json Chore(deps): Bump tar-fs from 2.1.3 to 2.1.4 2025-09-26 19:45:58 +00:00
package.json chore(deps): update cypress 2025-09-14 08:05:47 +00:00
psalm.xml build(dep): bump PHP requirement to 8.2 2025-10-08 12:34:53 +02:00
README.md feat: add API package to register handlers in init scripts 2025-09-01 16:12:55 +02:00
renovate.json feat(deps): Add Nextcloud 33 support on master 2025-09-04 12:21:04 +02:00
REUSE.toml chore: Add SPDX header 2024-09-19 11:09:27 +02:00
stylelint.config.js feat: add API package to register handlers in init scripts 2025-09-01 16:12:55 +02:00
tsconfig.json chore: Adjust Typescript configs 2024-09-07 15:38:35 +02:00
vite.config.ts feat: only provide fonts which are available (shipped by us) 2025-09-02 12:09:33 +02:00

Files viewer for nextcloud

REUSE status

Show your latest holiday photos and videos like in the movies. Show a glimpse of your latest novel directly from your nextcloud. Choose the best GIF of your collection thanks to the direct view of your favorites files!

viewer

📋 Current support

  • Images
  • Videos

🏗 Development setup

  1. ☁ Clone this app into the apps folder of your Nextcloud: git clone https://github.com/nextcloud/viewer.git
  2. 👩‍💻 In the folder of the app, install dependencies with npm ci and build the Javascript with npm run build.
  3. 🎉 Partytime!

🧙 Advanced development stuff

To build the Javascript whenever you make changes, you can also run npm run dev for development builds.

📷 Running cypress tests

To run e2e cypress tests, execute npm run cypress.

The visual-regression tests require additional care as they depend on installation of fonts in the application. To achieve repeatable results run the tests using npm run cypress:visual-regression. This will build the app with the required fonts and run the tests.

If changes are required to the reference (base) screenshots used by the visual-regression tests, run cypress:update-snapshots and commit the updated screenshots.

API

Add the viewer to your app

In php, on your page, emit the LoadViewer event. Check the documentation/tutorial for more info on this type of page controller sample.

use OCA\Viewer\Event\LoadViewer;
use OCP\AppFramework\Controller;
use OCP\AppFramework\Http\TemplateResponse;
use OCP\EventDispatcher\IEventDispatcher;
use OCP\IRequest;

class PageController extends Controller {
	protected $appName;

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

	public function __construct($appName,
								IRequest $request,
								IEventDispatcher $eventDispatcher) {
		parent::__construct($appName, $request);

		$this->appName = $appName;
		$this->eventDispatcher = $eventDispatcher;
	}

	/**
	 * @NoAdminRequired
	 * @NoCSRFRequired
	 * Render default index template
	 *
	 * @return TemplateResponse
	 */
	public function index(): TemplateResponse {
		$this->eventDispatcher->dispatch(LoadViewer::class, new LoadViewer());
		$response = new TemplateResponse($this->appName, 'main');
		return $response;
	}
}

This will load all the necessary scripts and make the Viewer accessible trough javascript at OCA.Viewer

Open a file

  1. Open a file on WebDAV and let the viewer fetch the folder data
OCA.Viewer.open({path: '/path/to/file.jpg'})
  1. Open a file on WebDAV and provide a list of files
OCA.Viewer.open({
  	path: '/path/to/file.jpg',
  	list: [
  		{
  			basename: 'file.jpg',
  			filename: '/path/to/file.jpg',
  			...
  		},
  		...
  	],
})
// Alternative: pass known file info so it doesn't need to be fetched
const fileInfo = {
  filename: '/path/to/file.jpg',
  basename: 'file.jpg',
  mime: 'image/jpeg',
  etag: 'xyz987',
  hasPreview: true,
  fileid: 13579,
}
OCA.Viewer.open({
  fileinfo: fileInfo,
  list: [fileInfo],
})

The list parameter requires an array of fileinfo. You can check how we generate a fileinfo object here from a dav PROPFIND request data. There is currently no dedicated package for it, but this is coming. You can check the photos repository where we also use it.

  1. Open a file from an app's route
const fileInfo1 = {
  filename: 'https://next.cloud/apps/pizza/topping/pineapple.jpg',
  basename: 'pineapple.jpg',
  source: 'https://next.cloud/apps/pizza/topping/pineapple.jpg',
  mime: 'image/jpeg',
  etag: 'abc123',
  hasPreview: false,
  fileid: 12345,
}
const fileInfo2 = {
  filename: 'https://next.cloud/apps/pizza/topping/garlic.jpg',
  basename: 'garlic.jpg',
  source: 'https://next.cloud/apps/pizza/topping/garlic.jpg',
  mime: 'image/jpeg',
  etag: 'def456',
  hasPreview: false,
  fileid: 67890,
}
OCA.Viewer.open({
  fileInfo: fileInfo1,
  list: [fileInfo1, fileInfo2],
})

In order to open a shared file you will need to provide the share token so the Viewer can use it to authenticate the requests to the server. See the files_sharing app controller and template for an example.

Close the viewer

OCA.Viewer.close()

🔍 Add you own file view

If you want to make your app compatible with this app, you can use the methods provided by the @nextcloud/viewer npm.js package:

  1. Create a vue component which use the path and mime props (they will be automatically passed by the viewer)
  2. Register your mime viewer with the following:
     import { registerHandler } from '@nextcloud/viewer'
     import VideoView from 'VideoView.vue'
    
     registerHandler({
         // unique id
         id: 'video',
    
        // optional, it will group every view of this group and
        // use the proper view when building the file list
        // of the slideshow.
        // e.g. you open an image/jpeg that have the `media` group
        // you will be able to see the video/mpeg from the `video` handler
        // files that also have the `media` group set.
        group: 'media',
    
        // the list of mimes your component is able to display
        mimes: [
             'video/mpeg',
             'video/ogg',
             'video/webm',
             'video/mp4'
         ],
    
         // your vue component view
         component: VideoView
     })
    
  3. Make sure your script is loaded with \OCP\Util::addInitScript so that the handler is registered before the viewer is loaded.
  4. if you feel like your mime should be integrated on this repo, you can also create a pull request with your object on the models directory and the view on the components directory. Please have a look at what's already here and take example of it. 🙇‍♀️

Legacy handler registration

Caution

Using OCA.Viewer for registering your handlers is not recommended as this might break depending on the script loading order

If you want to make your app compatible with this app, you can use the OCA.Viewer methods

  1. Create a vue component which use the path and mime props (they will be automatically passed by the viewer)
  2. Register your mime viewer with the following:
     import VideoView from 'VideoView.vue'
    
     OCA.Viewer.registerHandler({
         // unique id
         id: 'video',
    
        // optional, it will group every view of this group and
        // use the proper view when building the file list
        // of the slideshow.
        // e.g. you open an image/jpeg that have the `media` group
        // you will be able to see the video/mpeg from the `video` handler
        // files that also have the `media` group set.
        group: 'media',
    
        // the list of mimes your component is able to display
        mimes: [
             'video/mpeg',
             'video/ogg',
             'video/webm',
             'video/mp4'
         ],
    
         // your vue component view
         component: VideoView
     })
    
  3. Make sure your script is loaded with \OCP\Util::addScript (in contrast to using the API package)!