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

[size] fix relative size breaking some external image requests #197

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions demo/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -227,6 +227,13 @@ class Demo extends React.Component {
<Avatar value="100%" size="100%" />
</div>
</div>
<div style={{ fontSize: 15, padding: 10 }}>
<Avatar facebookId="100008343750912" size="10em" />
<Avatar md5Email="8c5d4c4b9ef6c68c4ff91c319d4c56be" size="10em" />
<ConfigProvider avatarRedirectUrl="https://avatar-redirect.appspot.com">
<Avatar googleId="116933859726289749306" size="10em" />
</ConfigProvider>
</div>
</section>

<section>
Expand Down
6 changes: 4 additions & 2 deletions src/sources/AvatarRedirect.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
'use strict';
import PropTypes from 'prop-types';
import { getImageSize } from '../utils';

export default
function createRedirectSource(network, property) {
Expand All @@ -23,12 +24,13 @@ function createRedirectSource(network, property) {
}

get = (setState) => {
const { size, avatarRedirectUrl } = this.props;
const { avatarRedirectUrl } = this.props;
const size = getImageSize(this.props.size);

const baseUrl = avatarRedirectUrl.replace(/\/*$/, '/');
const id = this.props[property];

const query = size ? '' : `size=${size}`;
const query = size ? `size=${size}` : '';
const src = `${baseUrl}${network}/${id}?${query}`;

setState({ source: 'network', src });
Expand Down
11 changes: 8 additions & 3 deletions src/sources/Facebook.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
'use strict';
import PropTypes from 'prop-types';
import { getImageSize } from '../utils';

export default
class FacebookSource {
Expand All @@ -17,9 +18,13 @@ class FacebookSource {
isCompatible = () => !!this.props.facebookId

get = (setState) => {
const { size, facebookId } = this.props;
const url = 'https://graph.facebook.com/' +
`${facebookId}/picture?width=${size}&height=${size}`;
const { facebookId } = this.props;
const size = getImageSize(this.props.size);

let url = `https://graph.facebook.com/${facebookId}/picture`;

if (size)
url += `?width=${size}&height=${size}`;

setState({
sourceName: 'facebook',
Expand Down
10 changes: 8 additions & 2 deletions src/sources/Github.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
'use strict';
import PropTypes from 'prop-types';
import { getImageSize } from '../utils';

export default
class GithubSource {
Expand All @@ -17,8 +18,13 @@ class GithubSource {
isCompatible = () => !!this.props.githubHandle

get = (setState) => {
const { size, githubHandle } = this.props;
const url = `https://avatars.githubusercontent.com/${githubHandle}?v=4&s=${size}`;
const { githubHandle } = this.props;
const size = getImageSize(this.props.size);

let url = `https://avatars.githubusercontent.com/${githubHandle}?v=4`;

if (size)
url += `&s=${size}`;

setState({
sourceName: 'github',
Expand Down
12 changes: 8 additions & 4 deletions src/sources/Gravatar.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
'use strict';

import PropTypes from 'prop-types';
import retina from 'is-retina';
import md5 from 'md5';

const IS_RETINA = retina();
import { getImageSize } from '../utils';


export default
class GravatarSource {
Expand All @@ -27,8 +27,12 @@ class GravatarSource {
get = (setState) => {
const { props } = this;
const email = props.md5Email || md5(props.email);
const size = IS_RETINA ? props.size * 2 : props.size;
const url = `https://secure.gravatar.com/avatar/${email}?s=${size}&d=404`;
const size = getImageSize(props.size);

let url = `https://secure.gravatar.com/avatar/${email}?d=404`;

if (size)
url += `&s=${size}`;

setState({
sourceName: 'gravatar',
Expand Down
28 changes: 28 additions & 0 deletions src/utils.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
'use strict';

import retina from 'is-retina';

const IS_RETINA = retina();

export
function fetch(url, successCb, errorCb) {
const request = new XMLHttpRequest();
Expand Down Expand Up @@ -104,6 +108,30 @@ function parseSize(size) {
};
}

/**
* Calculate absolute size in pixels we want for the images
* that get requested from the various sources. They don't
* understand relative sizes like `em` or `vww`. We select
* a fixed size of 512px when we can't detect the true pixel size.
*/
export function getImageSize(size) {
size = parseSize(size);

if (isNaN(size.value)) // invalid size, use fallback
size = 512;
else if (size.unit === 'px') // px are good, use them
size = size.value;
else if (size.value === 0) // relative 0 === absolute 0
size = 0;
else // anything else is unknown, use fallback
size = 512;

if (IS_RETINA)
size = size * 2;

return size;
}

export
function defaultInitials(name, { maxInitials }) {
return name.split(/\s/)
Expand Down