@atlaskit/editor-core
Version:
A package contains Atlassian editor core functionality
296 lines • 13.3 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var tslib_1 = require("tslib");
var React = require("react");
var styled_components_1 = require("styled-components");
var util_shared_styles_1 = require("@atlaskit/util-shared-styles");
var media_core_1 = require("@atlaskit/media-core");
var media_1 = require("../../plugins/media");
// Maybe it's better to ask media to export these as constant because
// we do something similar in src/schema/nodes/media.tsx:82
exports.MEDIA_HEIGHT = 125;
exports.FILE_WIDTH = 156;
exports.LINK_WIDTH = 343;
// tslint:disable-next-line
var FilePlaceholder = (_a = ["\n background: ", ";\n width: ", "px;\n min-height: ", "px;\n"], _a.raw = ["\n background: ", ";\n width: ", "px;\n min-height: ", "px;\n"], styled_components_1.default.div(_a, util_shared_styles_1.akColorN30, function (_a) {
var _b = _a.dimensions, _c = (_b === void 0 ? {} : _b).width, width = _c === void 0 ? exports.FILE_WIDTH : _c;
return width;
}, function (_a) {
var _b = _a.dimensions, _c = (_b === void 0 ? {} : _b).height, height = _c === void 0 ? exports.MEDIA_HEIGHT : _c;
return height;
}));
// tslint:disable-next-line
var LinkPlaceholder = (_b = ["\n background: ", ";\n width: ", "px;\n min-height: ", "px;\n"], _b.raw = ["\n background: ", ";\n width: ", "px;\n min-height: ", "px;\n"], styled_components_1.default.div(_b, util_shared_styles_1.akColorN30, function (_a) {
var _b = _a.dimensions, _c = (_b === void 0 ? {} : _b).width, width = _c === void 0 ? exports.LINK_WIDTH : _c;
return width;
}, function (_a) {
var _b = _a.dimensions, _c = (_b === void 0 ? {} : _b).height, height = _c === void 0 ? exports.MEDIA_HEIGHT : _c;
return height;
}));
/**
* Map media state status into CardView processing status
* Media state status is more broad than CardView API so we need to reduce it
*/
function mapMediaStatusIntoCardStatus(state) {
switch (state.status) {
case 'ready':
case 'unknown':
case 'unfinalized':
return 'complete';
case 'processing':
return 'processing';
case 'uploading':
return 'uploading';
// default case is to let TypeScript know that this function always returns a string
case 'error':
default:
return 'error';
}
}
var MediaComponent = (function (_super) {
tslib_1.__extends(MediaComponent, _super);
function MediaComponent(props) {
var _this = _super.call(this, props) || this;
_this.thumbnailWm = new WeakMap();
_this.destroyed = false;
_this.state = {
id: '',
status: 'unknown'
};
_this.handleMediaStateChange = function (mediaState) {
if (_this.destroyed) {
return;
}
var newState = tslib_1.__assign({}, mediaState);
_this.setState(newState);
};
_this.handleMediaProvider = function (mediaProvider) { return tslib_1.__awaiter(_this, void 0, void 0, function () {
var id, stateManager, mediaState;
return tslib_1.__generator(this, function (_a) {
switch (_a.label) {
case 0:
id = this.props.id;
if (this.destroyed) {
return [2 /*return*/];
}
stateManager = mediaProvider.stateManager || this.getStateManagerFromEditorPlugin();
this.setState({ mediaProvider: mediaProvider });
if (stateManager) {
mediaState = stateManager.getState(id);
stateManager.subscribe(id, this.handleMediaStateChange);
this.setState(tslib_1.__assign({ id: id }, mediaState));
}
return [4 /*yield*/, this.setContext('viewContext', mediaProvider)];
case 1:
_a.sent();
return [4 /*yield*/, this.setContext('linkCreateContext', mediaProvider)];
case 2:
_a.sent();
return [2 /*return*/];
}
});
}); };
_this.setContext = function (contextName, mediaProvider) { return tslib_1.__awaiter(_this, void 0, void 0, function () {
var context, _a;
return tslib_1.__generator(this, function (_b) {
switch (_b.label) {
case 0: return [4 /*yield*/, mediaProvider[contextName]];
case 1:
context = _b.sent();
if (this.destroyed || !context) {
return [2 /*return*/];
}
if ('clientId' in context) {
context = media_core_1.ContextFactory.create(context);
}
this.setState((_a = {}, _a[contextName] = context, _a));
return [2 /*return*/];
}
});
}); };
return _this;
}
MediaComponent.prototype.componentWillMount = function () {
var _this = this;
var mediaProvider = this.props.mediaProvider;
if (mediaProvider) {
mediaProvider.then(this.handleMediaProvider);
}
require.ensure([], function (require) {
var _a = require('@atlaskit/media-card'), Card = _a.Card, CardView = _a.CardView;
_this.setState({ Card: Card, CardView: CardView });
});
};
MediaComponent.prototype.componentWillReceiveProps = function (nextProps) {
var mediaProvider = nextProps.mediaProvider;
if (this.props.mediaProvider !== mediaProvider) {
if (mediaProvider) {
mediaProvider.then(this.handleMediaProvider);
}
else {
this.setState({ mediaProvider: mediaProvider });
}
}
};
MediaComponent.prototype.componentWillUnmount = function () {
this.destroyed = true;
var id = this.props.id;
var mediaProvider = this.state.mediaProvider;
if (mediaProvider) {
var stateManager_1 = mediaProvider.stateManager;
if (stateManager_1) {
stateManager_1.unsubscribe(id, this.handleMediaStateChange);
}
}
var stateManager = this.getStateManagerFromEditorPlugin();
if (stateManager) {
stateManager.unsubscribe(id, this.handleMediaStateChange);
}
};
MediaComponent.prototype.render = function () {
switch (this.props.type) {
case 'file':
return this.renderFile();
case 'link':
return this.renderLink();
default:
return null;
}
};
MediaComponent.prototype.renderLoadingCard = function (url, mediaItemType) {
if (mediaItemType === void 0) { mediaItemType = 'link'; }
var CardView = this.state.CardView;
var cardDimensions = this.props.cardDimensions;
if (CardView) {
return (React.createElement(CardView, { metadata: { type: mediaItemType, url: url, title: '' }, status: "loading", mediaItemType: mediaItemType, dimensions: cardDimensions }));
}
if (mediaItemType === 'link') {
return React.createElement(LinkPlaceholder, { dimensions: cardDimensions });
}
else if (mediaItemType === 'file') {
return React.createElement(FilePlaceholder, { dimensions: cardDimensions });
}
return null;
};
MediaComponent.prototype.renderLink = function () {
var _a = this.state, mediaProvider = _a.mediaProvider, linkCreateContext = _a.linkCreateContext, Card = _a.Card;
var _b = this.props, id = _b.id, collection = _b.collection, cardDimensions = _b.cardDimensions, onDelete = _b.onDelete, appearance = _b.appearance, otherProps = tslib_1.__rest(_b, ["id", "collection", "cardDimensions", "onDelete", "appearance"]);
var hasProviders = mediaProvider && linkCreateContext;
if (!hasProviders || !Card) {
return this.renderLoadingCard();
}
var identifier = {
mediaItemType: 'link',
collectionName: collection,
id: id,
};
if (id.substr(0, 10) === 'temporary:') {
var url = id.substr(id.indexOf(':', 11) + 1);
return this.renderLoadingCard(url);
}
if (onDelete) {
otherProps.actions = [media_core_1.CardDelete(onDelete)];
}
return (React.createElement(Card, tslib_1.__assign({ context: linkCreateContext, dimensions: cardDimensions, identifier: identifier, appearance: appearance || 'horizontal', resizeMode: this.resizeMode }, otherProps)));
};
MediaComponent.prototype.renderFile = function () {
var _a = this.state, mediaProvider = _a.mediaProvider, viewContext = _a.viewContext, CardView = _a.CardView;
var _b = this.props, id = _b.id, cardDimensions = _b.cardDimensions;
if (!mediaProvider || !viewContext) {
if (!CardView) {
return React.createElement(FilePlaceholder, { dimensions: cardDimensions });
}
return (React.createElement(CardView, { status: "loading", mediaItemType: "file", dimensions: cardDimensions }));
}
if (id.substr(0, 10) === 'temporary:') {
return this.renderTemporaryFile();
}
else {
return this.renderPublicFile();
}
};
MediaComponent.prototype.renderPublicFile = function () {
var _a = this.state, viewContext = _a.viewContext, Card = _a.Card;
var _b = this.props, cardDimensions = _b.cardDimensions, collection = _b.collection, id = _b.id, onDelete = _b.onDelete, onClick = _b.onClick;
var otherProps = {};
if (onDelete) {
otherProps.actions = [media_core_1.CardDelete(onDelete)];
}
if (onClick) {
otherProps.onClick = onClick;
}
if (!Card) {
return React.createElement(FilePlaceholder, { dimensions: cardDimensions });
}
return (React.createElement(Card, tslib_1.__assign({ context: viewContext, dimensions: cardDimensions, identifier: {
id: id,
mediaItemType: 'file',
collectionName: collection
}, selectable: false, resizeMode: this.resizeMode }, otherProps)));
};
MediaComponent.prototype.renderTemporaryFile = function () {
var state = this.state;
var thumbnail = state.thumbnail, fileName = state.fileName, fileSize = state.fileSize, fileType = state.fileType, CardView = state.CardView;
var _a = this.props, onDelete = _a.onDelete, cardDimensions = _a.cardDimensions;
// Cache the data url for thumbnail, so it's not regenerated on each re-render (prevents flicker)
var dataURI;
if (thumbnail) {
if (this.thumbnailWm.has(thumbnail)) {
dataURI = this.thumbnailWm.get(thumbnail);
}
else {
dataURI = URL.createObjectURL(thumbnail);
this.thumbnailWm.set(thumbnail, dataURI);
}
}
// Make sure that we always display progress bar when the file is uploading (prevents flicker)
var progress = state.progress;
if (!progress && state.status === 'uploading') {
progress = .0;
}
// Construct file details object
var fileDetails = {
name: fileName,
size: fileSize,
mimeType: fileType,
mediaType: (thumbnail || (fileType && fileType.indexOf('image/') > -1) ? 'image' : 'unknown')
};
var otherProps = {};
if (onDelete) {
otherProps.actions = [media_core_1.CardDelete(onDelete)];
}
if (!CardView) {
return React.createElement(FilePlaceholder, { dimensions: cardDimensions });
}
return React.createElement(CardView
// CardViewProps
, tslib_1.__assign({
// CardViewProps
status: mapMediaStatusIntoCardStatus(state), mediaItemType: "file", metadata: fileDetails,
// FileCardProps
dataURI: dataURI, progress: progress }, otherProps));
};
MediaComponent.prototype.getStateManagerFromEditorPlugin = function () {
var editorView = this.props.editorView;
if (!editorView) {
return;
}
var pluginState = media_1.stateKey.getState(editorView.state);
if (!pluginState) {
return;
}
return pluginState.stateManager;
};
Object.defineProperty(MediaComponent.prototype, "resizeMode", {
get: function () {
var resizeMode = this.props.resizeMode;
return resizeMode || 'full-fit';
},
enumerable: true,
configurable: true
});
return MediaComponent;
}(React.PureComponent));
exports.default = MediaComponent;
var _a, _b;
//# sourceMappingURL=MediaComponent.js.map