Make thumbnails optional
to prevent app from crashing when in the middle of scanning
This commit is contained in:
parent
254765a5d4
commit
54a83a4dc6
|
@ -1593,7 +1593,7 @@ type Media {
|
||||||
"Local filepath for the media"
|
"Local filepath for the media"
|
||||||
path: String!
|
path: String!
|
||||||
"URL to display the media in a smaller resolution"
|
"URL to display the media in a smaller resolution"
|
||||||
thumbnail: MediaURL!
|
thumbnail: MediaURL
|
||||||
"URL to display the photo in full resolution, will be null for videos"
|
"URL to display the photo in full resolution, will be null for videos"
|
||||||
highRes: MediaURL
|
highRes: MediaURL
|
||||||
"URL to get the video in a web format that can be played in the browser, will be null for photos"
|
"URL to get the video in a web format that can be played in the browser, will be null for photos"
|
||||||
|
@ -2928,14 +2928,11 @@ func (ec *executionContext) _Media_thumbnail(ctx context.Context, field graphql.
|
||||||
return graphql.Null
|
return graphql.Null
|
||||||
}
|
}
|
||||||
if resTmp == nil {
|
if resTmp == nil {
|
||||||
if !graphql.HasFieldError(ctx, fc) {
|
|
||||||
ec.Errorf(ctx, "must not be null")
|
|
||||||
}
|
|
||||||
return graphql.Null
|
return graphql.Null
|
||||||
}
|
}
|
||||||
res := resTmp.(*models.MediaURL)
|
res := resTmp.(*models.MediaURL)
|
||||||
fc.Result = res
|
fc.Result = res
|
||||||
return ec.marshalNMediaURL2ᚖgithubᚗcomᚋphotoviewᚋphotoviewᚋapiᚋgraphqlᚋmodelsᚐMediaURL(ctx, field.Selections, res)
|
return ec.marshalOMediaURL2ᚖgithubᚗcomᚋphotoviewᚋphotoviewᚋapiᚋgraphqlᚋmodelsᚐMediaURL(ctx, field.Selections, res)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ec *executionContext) _Media_highRes(ctx context.Context, field graphql.CollectedField, obj *models.Media) (ret graphql.Marshaler) {
|
func (ec *executionContext) _Media_highRes(ctx context.Context, field graphql.CollectedField, obj *models.Media) (ret graphql.Marshaler) {
|
||||||
|
@ -8195,9 +8192,6 @@ func (ec *executionContext) _Media(ctx context.Context, sel ast.SelectionSet, ob
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
res = ec._Media_thumbnail(ctx, field, obj)
|
res = ec._Media_thumbnail(ctx, field, obj)
|
||||||
if res == graphql.Null {
|
|
||||||
atomic.AddUint32(&invalids, 1)
|
|
||||||
}
|
|
||||||
return res
|
return res
|
||||||
})
|
})
|
||||||
case "highRes":
|
case "highRes":
|
||||||
|
@ -9671,10 +9665,6 @@ func (ec *executionContext) marshalNMediaType2githubᚗcomᚋphotoviewᚋphotovi
|
||||||
return v
|
return v
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ec *executionContext) marshalNMediaURL2githubᚗcomᚋphotoviewᚋphotoviewᚋapiᚋgraphqlᚋmodelsᚐMediaURL(ctx context.Context, sel ast.SelectionSet, v models.MediaURL) graphql.Marshaler {
|
|
||||||
return ec._MediaURL(ctx, sel, &v)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (ec *executionContext) marshalNMediaURL2ᚖgithubᚗcomᚋphotoviewᚋphotoviewᚋapiᚋgraphqlᚋmodelsᚐMediaURL(ctx context.Context, sel ast.SelectionSet, v *models.MediaURL) graphql.Marshaler {
|
func (ec *executionContext) marshalNMediaURL2ᚖgithubᚗcomᚋphotoviewᚋphotoviewᚋapiᚋgraphqlᚋmodelsᚐMediaURL(ctx context.Context, sel ast.SelectionSet, v *models.MediaURL) graphql.Marshaler {
|
||||||
if v == nil {
|
if v == nil {
|
||||||
if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) {
|
if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) {
|
||||||
|
|
|
@ -163,17 +163,21 @@ func (r *mediaResolver) HighRes(ctx context.Context, media *models.Media) (*mode
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *mediaResolver) Thumbnail(ctx context.Context, media *models.Media) (*models.MediaURL, error) {
|
func (r *mediaResolver) Thumbnail(ctx context.Context, media *models.Media) (*models.MediaURL, error) {
|
||||||
var url models.MediaURL
|
var url []*models.MediaURL
|
||||||
err := r.Database.
|
err := r.Database.
|
||||||
Where("media_id = ?", media.ID).
|
Where("media_id = ?", media.ID).
|
||||||
Where("purpose = ? OR purpose = ?", models.PhotoThumbnail, models.VideoThumbnail).
|
Where("purpose = ? OR purpose = ?", models.PhotoThumbnail, models.VideoThumbnail).
|
||||||
First(&url).Error
|
Find(&url).Error
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, errors.Wrapf(err, "could not query thumbnail (%s)", media.Path)
|
return nil, errors.Wrapf(err, "could not query thumbnail (%s)", media.Path)
|
||||||
}
|
}
|
||||||
|
|
||||||
return &url, nil
|
if len(url) == 0 {
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
return url[0], nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *mediaResolver) VideoWeb(ctx context.Context, media *models.Media) (*models.MediaURL, error) {
|
func (r *mediaResolver) VideoWeb(ctx context.Context, media *models.Media) (*models.MediaURL, error) {
|
||||||
|
|
|
@ -237,7 +237,7 @@ type Media {
|
||||||
"Local filepath for the media"
|
"Local filepath for the media"
|
||||||
path: String!
|
path: String!
|
||||||
"URL to display the media in a smaller resolution"
|
"URL to display the media in a smaller resolution"
|
||||||
thumbnail: MediaURL!
|
thumbnail: MediaURL
|
||||||
"URL to display the photo in full resolution, will be null for videos"
|
"URL to display the photo in full resolution, will be null for videos"
|
||||||
highRes: MediaURL
|
highRes: MediaURL
|
||||||
"URL to get the video in a web format that can be played in the browser, will be null for photos"
|
"URL to get the video in a web format that can be played in the browser, will be null for photos"
|
||||||
|
|
|
@ -75,7 +75,7 @@ export const AlbumBox = ({ album, customLink, ...props }) => {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
let thumbnail = album.thumbnail && album.thumbnail.thumbnail.url
|
let thumbnail = album.thumbnail?.thumbnail?.url
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<AlbumBoxLink {...props} to={customLink || `/album/${album.id}`}>
|
<AlbumBoxLink {...props} to={customLink || `/album/${album.id}`}>
|
||||||
|
|
|
@ -2,6 +2,8 @@ import React from 'react'
|
||||||
import PropTypes from 'prop-types'
|
import PropTypes from 'prop-types'
|
||||||
|
|
||||||
const getProtectedUrl = url => {
|
const getProtectedUrl = url => {
|
||||||
|
if (url == null) return null
|
||||||
|
|
||||||
const imgUrl = new URL(url)
|
const imgUrl = new URL(url)
|
||||||
|
|
||||||
const tokenRegex = location.pathname.match(/^\/share\/([\d\w]+)(\/?.*)$/)
|
const tokenRegex = location.pathname.match(/^\/share\/([\d\w]+)(\/?.*)$/)
|
||||||
|
@ -26,7 +28,7 @@ export const ProtectedImage = ({ src, ...props }) => (
|
||||||
)
|
)
|
||||||
|
|
||||||
ProtectedImage.propTypes = {
|
ProtectedImage.propTypes = {
|
||||||
src: PropTypes.string.isRequired,
|
src: PropTypes.string,
|
||||||
}
|
}
|
||||||
|
|
||||||
export const ProtectedVideo = ({ media, ...props }) => (
|
export const ProtectedVideo = ({ media, ...props }) => (
|
||||||
|
@ -35,7 +37,7 @@ export const ProtectedVideo = ({ media, ...props }) => (
|
||||||
controls
|
controls
|
||||||
key={media.id}
|
key={media.id}
|
||||||
crossOrigin="use-credentials"
|
crossOrigin="use-credentials"
|
||||||
poster={getProtectedUrl(media.thumbnail.url)}
|
poster={getProtectedUrl(media.thumbnail?.url)}
|
||||||
>
|
>
|
||||||
<source src={getProtectedUrl(media.videoWeb.url)} type="video/mp4" />
|
<source src={getProtectedUrl(media.videoWeb.url)} type="video/mp4" />
|
||||||
</video>
|
</video>
|
||||||
|
|
|
@ -25,10 +25,10 @@ const PresentMedia = ({ media, imageLoaded, ...otherProps }) => {
|
||||||
if (media.type == 'photo') {
|
if (media.type == 'photo') {
|
||||||
return (
|
return (
|
||||||
<div {...otherProps}>
|
<div {...otherProps}>
|
||||||
<StyledPhoto src={media.thumbnail.url} />
|
<StyledPhoto src={media.thumbnail?.url} />
|
||||||
<StyledPhoto
|
<StyledPhoto
|
||||||
style={{ display: 'none' }}
|
style={{ display: 'none' }}
|
||||||
src={media.highRes.url}
|
src={media.highRes?.url}
|
||||||
onLoad={e => {
|
onLoad={e => {
|
||||||
e.target.style.display = 'initial'
|
e.target.style.display = 'initial'
|
||||||
imageLoaded && imageLoaded()
|
imageLoaded && imageLoaded()
|
||||||
|
|
|
@ -82,7 +82,7 @@ const PreviewVideo = styled(ProtectedVideo)`
|
||||||
|
|
||||||
const PreviewMedia = ({ media, previewImage }) => {
|
const PreviewMedia = ({ media, previewImage }) => {
|
||||||
if (media.type == null || media.type == 'photo') {
|
if (media.type == null || media.type == 'photo') {
|
||||||
return <PreviewImage src={previewImage.url} />
|
return <PreviewImage src={previewImage?.url} />
|
||||||
}
|
}
|
||||||
|
|
||||||
if (media.type == 'video') {
|
if (media.type == 'video') {
|
||||||
|
@ -94,7 +94,7 @@ const PreviewMedia = ({ media, previewImage }) => {
|
||||||
|
|
||||||
PreviewMedia.propTypes = {
|
PreviewMedia.propTypes = {
|
||||||
media: PropTypes.object.isRequired,
|
media: PropTypes.object.isRequired,
|
||||||
previewImage: PropTypes.object.isRequired,
|
previewImage: PropTypes.object,
|
||||||
}
|
}
|
||||||
|
|
||||||
const Name = styled.div`
|
const Name = styled.div`
|
||||||
|
@ -194,12 +194,14 @@ const SidebarContent = ({ media, hidePreview }) => {
|
||||||
else if (media.thumbnail) previewImage = media.thumbnail
|
else if (media.thumbnail) previewImage = media.thumbnail
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const imageAspect = previewImage
|
||||||
|
? previewImage.height / previewImage.width
|
||||||
|
: 3 / 2
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
{!hidePreview && (
|
{!hidePreview && (
|
||||||
<PreviewImageWrapper
|
<PreviewImageWrapper imageAspect={imageAspect}>
|
||||||
imageAspect={previewImage.height / previewImage.width}
|
|
||||||
>
|
|
||||||
<PreviewMedia previewImage={previewImage} media={media} />
|
<PreviewMedia previewImage={previewImage} media={media} />
|
||||||
</PreviewImageWrapper>
|
</PreviewImageWrapper>
|
||||||
)}
|
)}
|
||||||
|
|
Loading…
Reference in New Issue