From 1143552e1690f8b96b3d95381f7f06cbb46ead59 Mon Sep 17 00:00:00 2001 From: Maximilian Hils Date: Sun, 22 Mar 2015 00:21:38 +0100 Subject: web: add content views --- web/src/js/components/flowview/contentview.js | 158 ++++++++++++++++++++++++++ 1 file changed, 158 insertions(+) create mode 100644 web/src/js/components/flowview/contentview.js (limited to 'web/src/js/components/flowview/contentview.js') diff --git a/web/src/js/components/flowview/contentview.js b/web/src/js/components/flowview/contentview.js new file mode 100644 index 00000000..09a64bb2 --- /dev/null +++ b/web/src/js/components/flowview/contentview.js @@ -0,0 +1,158 @@ +var React = require("react"); +var _ = require("lodash"); + +var MessageUtils = require("../../flow/utils.js").MessageUtils; +var utils = require("../../utils.js"); + +var image_regex = /^image\/(png|jpe?g|gif|vnc.microsoft.icon|x-icon)$/i; +var Image = React.createClass({ + statics: { + matches: function (message) { + return image_regex.test(MessageUtils.getContentType(message)); + } + }, + render: function () { + var message_name = this.props.flow.request === this.props.message ? "request" : "response"; + var url = "/flows/" + this.props.flow.id + "/" + message_name + "/content"; + return
+ preview +
; + } +}); + +var Raw = React.createClass({ + statics: { + matches: function (message) { + return true; + } + }, + render: function () { + //FIXME + return
raw
; + } +}); + + +var Auto = React.createClass({ + statics: { + matches: function () { + return false; // don't match itself + }, + findView: function (message) { + for (var i = 0; i < all.length; i++) { + if (all[i].matches(message)) { + return all[i]; + } + } + return all[all.length - 1]; + } + }, + render: function () { + var View = Auto.findView(this.props.message); + return ; + } +}); + +var all = [Auto, Image, Raw]; + + +var ContentEmpty = React.createClass({ + render: function () { + var message_name = this.props.flow.request === this.props.message ? "request" : "response"; + return
No {message_name} content.
; + } +}); + +var ContentMissing = React.createClass({ + render: function () { + var message_name = this.props.flow.request === this.props.message ? "Request" : "Response"; + return
{message_name} content missing.
; + } +}); + +var TooLarge = React.createClass({ + render: function () { + var size = utils.formatSize(this.props.message.contentLength); + return
+ + {size} content size. +
; + } +}); + +var ViewSelector = React.createClass({ + render: function () { + var views = []; + for (var i = 0; i < all.length; i++) { + var view = all[i]; + var className = "btn btn-default"; + if (view === this.props.active) { + className += " active"; + } + var text; + if (view === Auto) { + text = "auto: " + Auto.findView(this.props.message).displayName.toLowerCase(); + } else { + text = view.displayName.toLowerCase(); + } + views.push( + + ); + } + + return
{views}
; + } +}); + +var ContentView = React.createClass({ + getInitialState: function () { + return { + displayLarge: false, + View: Auto + }; + }, + propTypes: { + // It may seem a bit weird at the first glance: + // Every view takes the flow and the message as props, e.g. + // + flow: React.PropTypes.object.isRequired, + message: React.PropTypes.object.isRequired, + }, + selectView: function (view) { + this.setState({ + View: view + }); + }, + displayLarge: function () { + this.setState({displayLarge: true}); + }, + componentWillReceiveProps: function (nextProps) { + if (nextProps.message !== this.props.message) { + this.setState(this.getInitialState()); + } + }, + render: function () { + var message = this.props.message; + if (message.contentLength === 0) { + return ; + } else if (message.contentLength === null) { + return ; + } else if (message.contentLength > 1024 * 1024 * 3 && !this.state.displayLarge) { + return ; + } + + return
+ +
+ +
+
; + } +}); + +module.exports = ContentView; \ No newline at end of file -- cgit v1.2.3