react-avatar
Version:
Universal React avatar component makes it possible to generate avatars based on user information.
162 lines (158 loc) • 5.82 kB
JavaScript
;
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
Object.defineProperty(exports, "__esModule", {
value: true
});
Object.defineProperty(exports, "Cache", {
enumerable: true,
get: function () {
return _cache.Cache;
}
});
Object.defineProperty(exports, "ConfigProvider", {
enumerable: true,
get: function () {
return _context.ConfigProvider;
}
});
exports.default = createAvatarDataProvider;
Object.defineProperty(exports, "getRandomColor", {
enumerable: true,
get: function () {
return _utils.getRandomColor;
}
});
var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
var _react = _interopRequireWildcard(require("react"));
var _propTypes = _interopRequireDefault(require("prop-types"));
var _cache = require("./cache");
var _context = require("./context");
var _internalState = _interopRequireDefault(require("./internal-state"));
var _utils = require("./utils");
function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function (e) { return e ? t : r; })(e); }
function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != typeof e && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && {}.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; }
function matchSource(Source, props, cb) {
const {
cache
} = props;
const instance = new Source(props);
if (!instance.isCompatible(props)) return cb();
instance.get(state => {
const failedBefore = state && state.src && cache.hasSourceFailedBefore(state.src);
if (!failedBefore && state) {
cb(state);
} else {
cb();
}
});
}
function createAvatarDataProvider(_ref) {
let {
sources = []
} = _ref;
// Collect propTypes for each individual source
const sourcePropTypes = sources.reduce((r, s) => Object.assign(r, s.propTypes), {});
class AvatarDataProvider extends _react.PureComponent {
constructor(props) {
super(props);
(0, _defineProperty2.default)(this, "_createFetcher", internal => errEvent => {
const {
cache
} = this.props;
if (!internal.isActive(this.state)) return;
// Mark img source as failed for future reference
if (errEvent && errEvent.type === 'error') cache.sourceFailed(errEvent.target.src);
const pointer = internal.sourcePointer;
if (sources.length === pointer) return;
const source = sources[pointer];
internal.sourcePointer++;
matchSource(source, this.props, nextState => {
if (!nextState) return setTimeout(internal.fetch, 0);
if (!internal.isActive(this.state)) return;
// Reset other values to prevent them from sticking (#51)
nextState = {
src: null,
value: null,
color: null,
...nextState
};
this.setState(state => {
// Internal state has been reset => we received new props
return internal.isActive(state) ? nextState : {};
});
});
});
(0, _defineProperty2.default)(this, "fetch", () => {
const internal = new _internalState.default();
internal.fetch = this._createFetcher(internal);
this.setState({
internal
}, internal.fetch);
});
this.state = {
internal: null,
src: null,
value: null,
color: props.color
};
}
componentDidMount() {
this.fetch();
}
componentDidUpdate(prevProps) {
let needsUpdate = false;
// This seems redundant
//
// Props that need to be in `state` are
// `value`, `src` and `color`
for (const prop in sourcePropTypes) needsUpdate = needsUpdate || prevProps[prop] !== this.props[prop];
if (needsUpdate) setTimeout(this.fetch, 0);
}
componentWillUnmount() {
if (this.state.internal) {
this.state.internal.active = false;
}
}
render() {
const {
children,
propertyName
} = this.props;
const {
src,
value,
color,
sourceName,
internal
} = this.state;
const avatarData = {
src,
value,
color,
sourceName,
onRenderFailed: () => internal && internal.fetch() // eslint-disable-line
};
if (typeof children === 'function') return children(avatarData);
const child = _react.default.Children.only(children);
return /*#__PURE__*/_react.default.cloneElement(child, {
[propertyName]: avatarData
});
}
}
(0, _defineProperty2.default)(AvatarDataProvider, "displayName", 'AvatarDataProvider');
(0, _defineProperty2.default)(AvatarDataProvider, "propTypes", {
// PropTypes defined on sources
...sourcePropTypes,
cache: _propTypes.default.object,
propertyName: _propTypes.default.string
});
(0, _defineProperty2.default)(AvatarDataProvider, "defaultProps", {
propertyName: 'avatar'
});
(0, _defineProperty2.default)(AvatarDataProvider, "Cache", _cache.Cache);
(0, _defineProperty2.default)(AvatarDataProvider, "ConfigProvider", _context.ConfigProvider);
return Object.assign((0, _context.withConfig)(AvatarDataProvider), {
ConfigProvider: _context.ConfigProvider,
Cache: _cache.Cache
});
}