Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Image, video and other binary file handling (Assets) #22

Closed
michaelbromley opened this issue Sep 12, 2018 · 2 comments
Closed

Image, video and other binary file handling (Assets) #22

michaelbromley opened this issue Sep 12, 2018 · 2 comments
Labels
design 📐 This issue deals with high-level design of a feature

Comments

@michaelbromley
Copy link
Member

Overview

  • A typical web shop has one or more images for each product. Each individual variant may also have one or more images (e.g. a paint range, where each variant is a colour with its own colour-swatch image).
  • Videos are also a common requirement, and might be hosted on the server itself, or linked from a dedicated video server or video service like YouTube.
  • Other binaries might be used, such as pdfs with spec sheets or instruction manuals.
  • An administrator should be able to easily create new media objects by uploading or supplying a link.
  • There should be some means to browse existing media objects in the admin-ui, so that existing objects can be re-used.

Design

A Media entity would represent all types of binary files. It would have a type discriminator whose value would be a MediaType (image, video, etc).

Physical storage

The Media entity would have a pointer to the actual binary file somewhere on a disk. The physical storage location should be configurable - it should not have to reside on the same machine as the Vendure API server. (look into existing Node libs which abstract away the file system).

Previews / thumbnails

There should be a built-in way to generate different sizes of image whilst preserving the original. This could be generalized into a "preview" (or better name) property which would be a collection of one or more MediaPreview entities. This would also then handle the case for preview images of videos, pdfs and other file types.

Another way would be to have a single "preview" image which can be resized on-the-fly with query parameters. These generated previews would then be cached so that the re-sampling only need take place for the initial call. This is much simpler but has performance implications.

Maybe the way to go would be to automatically generate a default set of previews (according to some config), and then further permutations can be generated on the fly.

It would be good to abstract the actual image-manipulation lib away so that the image processing capabilities can be extended by the developer, so in essence we pass through the query string to the configured "image plugin" which can then pass off the work to some library. For example, a developer may want to use ImageMagick rather than a JavaScript-based lib for improved performance.

Linking with other entities

The Product and ProductVariant entities would have the existing image string property replaced by a media property which would be a collection of Media entities.

Additionally, the custom fields API should be extended to allow Media fields with optional type filter.

Where there is more than 1 Media entity, there must be a way to choose the "default" one, i.e. the image to show in a list view of Products, for example.

This could be done by:

  • adding an additional defaultMedia property which stores the id of one of the linked Media entities.
  • using the order of the collection, so that the 0th element is considered the default.

I would tend to favour the first solution, since it is more explicit.

Media browser

A media browser is a UI component which is used in the admin-ui to select an existing Media entity. As a first implementation this would be akin to the media browser in WordPress - essentially a flat (no folders), filterable list of all Media entities.

For large shops this might become unwieldy - our reference shop has over 6,000 individual images. Therefore a future extension will have to address the issue of organizing large media collections, with folders or tags or something like that.

References

@michaelbromley michaelbromley added the design 📐 This issue deals with high-level design of a feature label Sep 12, 2018
@michaelbromley
Copy link
Member Author

michaelbromley commented Sep 12, 2018

Configurable preview function

Use case I just came across:

Developer is building a shop selling audio clips (e.g. samples for musicians). Wants to attach an audio file to a Product, but wants the preview image to be a waveform of that audio file.

To allow this, we need to have a configurable generatePreview function which takes the file as an argument and outputs an image.

The default function would be simple - it would resize the source image to some maximum-allowed resolution and for non-image files it would do something sensible like outputting a "file" image with the filename overlaid.

In the above use-case, the developer would be free to write his or her own generatePreview function which is able to use whatever logic is needed for generating a waveform image.

@michaelbromley
Copy link
Member Author

Naming

What to call the entity which can represent and image, video, or any other kind of file?

  • Media
    ✅ It fits for the most common use-case (images)
    👎 Not all files may be considered "media" files.
    👎 Grammatically unsatisfactory
  • Resource
    ✅ General enough to encompass every type of file
    👎 Perhaps over-general, since the term is sometimes applied to entities in the data model.
  • File
    ✅ They are files after all.
    👎 But actually the entity is a pointer to or representation of the file, rather than the file itself.
  • Asset
    ✅ General enough to cover all types of file
    ✅ Familiar term for developers to describe such files

Let's go with Asset

@michaelbromley michaelbromley changed the title Image, video and other binary file handling (media objects) Image, video and other binary file handling (Assets) Sep 12, 2018
michaelbromley added a commit that referenced this issue Sep 13, 2018
Relates to #22. The basic mechanism is there, but more work needs to be done on:

1. figuring out how to properly modularize the asset server
2. transforming asset identifiers into absolute urls at the API layer
3. handling other file types (video & default previews)
4. providing url-based image manipulation for the default asset server
michaelbromley added a commit that referenced this issue Sep 14, 2018
Relates to #22 and also prototypes the implementation of #24.
michaelbromley added a commit that referenced this issue Sep 14, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
design 📐 This issue deals with high-level design of a feature
Projects
None yet
Development

No branches or pull requests

1 participant