1
0
mirror of https://github.com/ascribe/onion.git synced 2024-12-23 01:39:36 +01:00
onion/js/components/ascribe_buttons/s3_download_button.js

100 lines
3.1 KiB
JavaScript
Raw Normal View History

2016-02-17 11:38:01 +01:00
'use strict';
import React from 'react';
import S3Fetcher from '../../fetchers/s3_fetcher';
import Glyphicon from 'react-bootstrap/lib/Glyphicon';
import AppConstants from '../../constants/application_constants';
import { getLangText } from '../../utils/lang_utils';
import { queryParamsToArgs } from '../../utils/url_utils';
const { string } = React.PropTypes;
const S3DownloadButton = React.createClass({
propTypes: {
url: string,
title: string,
artistName: string,
fileExtension: string
},
getInitialState() {
return {
2016-02-22 17:38:02 +01:00
downloadUrl: null,
signatureExpiryTimerId: null
2016-02-17 11:38:01 +01:00
};
},
componentDidMount() {
// Initially, we request a signed url from the backend
2016-02-17 11:38:01 +01:00
this.signUrl();
},
2016-02-22 17:38:02 +01:00
componentWillUnmount() {
window.clearTimeout(this.state.signatureExpiryTimerId);
2016-02-22 17:38:02 +01:00
},
2016-02-17 11:38:01 +01:00
transformS3UrlToS3Key(url) {
return url.replace(`https://${AppConstants.cloudfrontDomain}/`, '');
},
2016-03-01 12:55:27 +01:00
signUrl() {
2016-02-17 11:38:01 +01:00
const { url, title, artistName } = this.props;
S3Fetcher
.signUrl(this.transformS3UrlToS3Key(url), title, artistName)
2016-03-01 12:55:27 +01:00
.then(({ signed_url: downloadUrl }) => {
const { signatureExpiryTimerId } = this.state;
// The signed url, however can expire, which is why we need to set up a timer to
// renew it when it expires.
const expires = parseInt(queryParamsToArgs(downloadUrl.split('?')[1]).expires, 10);
const now = new Date().getTime() / 1000;
// Amazon uses seconds as their signature unix timestamp while `setTimeout` uses
// milliseconds. Therefore we need to multiply with 1000.
const interval = (expires - now) * 1000;
// Make sure to clear the previous timeout just in case it was not the one that
// invoked the refetching
if (signatureExpiryTimerId) {
window.clearTimeout(signatureExpiryTimerId);
2016-03-01 12:55:27 +01:00
}
this.setState({
downloadUrl,
// Substract 5s to make sure there is a big enough window to sign again before
// expiration
signatureExpiryTimerId: window.setTimeout(this.signUrl, interval - 5000)
});
2016-03-01 12:55:27 +01:00
})
2016-02-17 11:38:01 +01:00
.catch(console.logGlobal);
},
render() {
const { fileExtension, url } = this.props;
const { downloadUrl } = this.state;
return (
2016-02-22 12:18:40 +01:00
<a
ref="downloadButton"
download
className="btn btn-xs btn-default ascribe-margin-1px"
target="_blank"
href={downloadUrl || url}>
{/*
If it turns out that `fileExtension` is an empty string, we're just
using the label 'file'.
*/}
{getLangText('Download')} .{fileExtension || 'file'} <Glyphicon glyph="cloud-download" />
</a>
2016-02-17 11:38:01 +01:00
);
}
});
2016-02-22 12:18:40 +01:00
export default S3DownloadButton;