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鈥檒l occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix thumbs for new uploads to private repos #994

Merged
merged 1 commit into from
Mar 27, 2018

Conversation

Quicksaver
Copy link
Contributor

Closes #993.

- Summary

When working on a private repo, new image uploads don't show the thumbnail until you reload the page, leading the user sometimes to think the upload failed because they see a broken thumbnail icon. The src url of new images don't have the token query parameter that is applied when the page loads.

This fix reloads the file list of the upload directory from the git API (as if it was first loading the media library), and fetches the url of the newly uploaded file from that list. I left the previous built-in-the-method url as a fallback, just in case.

Note: my fix seems the "simplest" in terms of what I could already find in the code, but if you think there's a better way to do it, I'm all up for it. 馃槃

- Test plan

Tested uploading an image, to a private repository, through the media library. The thumbnail appeared immediately as expected. Also tested in a public repo, all fine as before as well.

- Description for the changelog

(Media Library) Fix broken thumbnail when uploading an image to a private repository

- A picture of a cute animal (not mandatory but encouraged)
img_20171126_123023

@verythorough
Copy link
Contributor

verythorough commented Jan 8, 2018

Deploy preview for cms-demo ready!

Built with commit 0d14076

https://deploy-preview-994--cms-demo.netlify.com

@tech4him1
Copy link
Contributor

@Quicksaver Do the download_urls automatically have the tokens added to them?

@Quicksaver
Copy link
Contributor Author

@tech4him1 it seems they do, they also come directly from the git API on load at least.

@Quicksaver
Copy link
Contributor Author

Quicksaver commented Jan 8, 2018

PS not really sure why the build is failing, I can't tell locally as running lint on master also fails, but it builds just fine. Please let me know if there's something I can do on my end to fix that.

@verythorough
Copy link
Contributor

verythorough commented Jan 8, 2018

Deploy preview for netlify-cms-www ready!

Built with commit 0d14076

https://deploy-preview-994--netlify-cms-www.netlify.com

@tech4him1
Copy link
Contributor

@Quicksaver Looks like the build just had a connection issue, should be fixed now.

let url = `https://raw.githubusercontent.com/${repo}/${this.branch}${path}`;

// Assets uploaded to private repos will need valid access tokens.
const files = await this.api.listFiles(this.config.get('media_folder'));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we should only get the file that we are actually wanting, not the entire media_folder again. This could be accomplished by making a function essentially like listFiles, except for requesting a single file instead of a directory.

Copy link
Contributor

@tech4him1 tech4him1 Jan 9, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also, I do think double-checking the SHA here is a good idea, as we don't want to run into caching issues. When we were constructing the URL manually before, though, we definitely weren't worrying about caching, so maybe it's not really necessary.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@tech4him1

I think we should only get the file that we are actually wanting

I wanted to do that, but I couldn't find any API in the docs that could be used for that. The Contents API being used now, if pointed at a file rather than at a directory, will also retrieve the contents of that file. So we'd be transferring the whole image file twice, once just to get the metadata containing its download_url, and again later on to show the thumbnail (as it's a different url so it's not cached).

That API also has a 1 Mb limit, so it won't work for larger files, we'd need the Blobs API to retrieve those files, but that doesn't include the download_url.

As far as I can tell, this really seems to be the most direct way to get the tokenized download_url currently used to show the thumbnails. Those alternatives are probably useful for #990 though.

Copy link
Contributor

@erquhart erquhart Jan 20, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The only other option I can think of is super hacky - parse the token from the download_url of another image. 99.9% sure we just shouldn't.

So that aside, we should:

  1. only take the approach provided here for private repos (check with repos/get)
  2. hurry up and get thumbnail creation in place (Media library needs rendered thumbnails聽#946), and ensure thumbnails are well below 1mb, so we can stop doing this

@erquhart
Copy link
Contributor

@Quicksaver this is better than nothing for private repos, we can still merge it if it's updated to only apply for those.

@Quicksaver
Copy link
Contributor Author

@erquhart I've been wanting to do that but haven't had a chance to work on it at all since back then. 馃槶

@erquhart
Copy link
Contributor

erquhart commented Mar 2, 2018

No problem! I'll leave it open for now in case you or someone else finds time to get it in.

@robertgonzales
Copy link

I'm seeing this issue, but not just for new uploads. No thumbnails load even with the token param.

@erquhart
Copy link
Contributor

@robertgonzales that would qualify as a separate issue, can you open one with a repro case?

@Quicksaver
Copy link
Contributor Author

@erquhart @tech4him1 re-fixed for private repositories only (finally!) 馃槃 I couldn't find anywhere else that was already checking if the repo is private, so I created a new method in the API script just for that, could be useful for other features down the line as well I guess.

const isPrivateRepo = await this.api.isPrivateRepo();
if (isPrivateRepo) {
const files = await this.api.listFiles(this.config.get('media_folder'));
for (let file of files) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we could make this code a bit simpler by using find() instead of looping:

const file = files.find(f => (f.sha === mediaFile.sha));
if (file) {
  url = file.download_url;
}

isPrivateRepo() {
return this.request(this.repoURL)
.then(repo => repo.private)
.catch(error => {
Copy link
Contributor

@tech4him1 tech4him1 Mar 16, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

request() should catch itself on an API error -- we don't need to catch here unless there is a good reason.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I copied this from the hasWriteAccess() method above. Without knowing more about why that one is written like that, I couldn't tell you if it needs the catch or not, although yeah request() should probably catch it by itself. What do you think, should I keep it or remove it?

Copy link
Contributor

@tech4him1 tech4him1 Mar 16, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's go ahead and remove it, Benaiah agreed as well.

@Quicksaver
Copy link
Contributor Author

@tech4him1 removed the catch().

@Quicksaver
Copy link
Contributor Author

@tech4him1 and changed the loop into a .find() as well (almost forgot to mention).

@tech4him1 tech4him1 requested review from Benaiah, erquhart and tech4him1 and removed request for erquhart March 21, 2018 22:54
}
}

return { id: mediaFile.sha, name: value, size: fileObj.size, url, path: trimStart(path, '/') };
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It looks like we're returning the file SHA now, instead of the response (commit) SHA. Maybe I just missed the reason for this, can you explain? 馃槃

Copy link
Contributor Author

@Quicksaver Quicksaver Mar 22, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@tech4him1 response.sha is undefined (yep, it was setting an undefined id before), at most it should have been response.object.sha. I set it to the file's sha instead to be more consistent with the other ids from when the media library initializes: https://github.com/netlify/netlify-cms/blob/master/src/backends/github/implementation.js#L94-L104

It's not really part of the original issue, true. But I thought since I was already in that very same line of code, I'd throw that in. 馃槄

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@Quicksaver Sounds good, maybe it should be split into a seperate commit? (same PR is fine)

Copy link
Contributor Author

@Quicksaver Quicksaver Mar 23, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@tech4him1 makes sense, I split it into a separate commit.

@Quicksaver
Copy link
Contributor Author

@tech4him1 Also, I just stumbled upon a redundant file.filter call in getMedia() in implementation.js (listFiles() in API.js already has an exact same one) so I went ahead and created a commit for it as well. Let me know if I'm filling this PR too much with non-relevant commits. 馃榿

@tech4him1
Copy link
Contributor

tech4him1 commented Mar 23, 2018

@Quicksaver Thank you! I think that the filter change should be in a seperate PR, since it's not really related (although it think it is pretty obvious 馃槃). It's up to you on the sha one, it could be lumped with either one, or seperate.

@Quicksaver
Copy link
Contributor Author

@tech4him1 left this PR with only the thumb url fix, moved the other two fixes to #1189.

Copy link
Contributor

@tech4him1 tech4him1 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

馃帀

Copy link
Contributor

@erquhart erquhart left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks!

@buzzlightyear182
Copy link

Hello! I'm following the Quick Start Guide from the site so I'm using v 1.0.0 (https://unpkg.com/netlify-cms@^1.0.0) and I have the same issue with uploading images and thumbnails. I saw the PR was merged, but I'm not really sure how that works, is it there already in CDN?

@tech4him1
Copy link
Contributor

@buzzlightyear182 Make sure you have the caret in the link ^1.0.0, so that it automatically upgrades to the latest CMS version (v1.4.0). You can also try ^1.4.0 (still with the caret) to force the version. If you are are still having the problem, you can file a new issue with steps to reproduce.

@buzzlightyear182
Copy link

Thanks @tech4him1 I've always had the caret in my file and did the ^1.4.0 too. I opened an issue with a screenshot of the error I got from console: #1220

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Need to reload page after uploading image to show the thumbnail
6 participants