<commit_before>import React from "react-native";
import Icon from "./icon";
import GrowingTextInput from "./growing-text-input";
import TouchFeedback from "./touch-feedback";
import ChatSuggestionsController from "../controllers/chat-suggestions-controller";
import ImageUploadController from "../controllers/image-upload-controller";
import ImageUploadChat from "./image-upload-chat";
import ImageChooser from "../../modules/image-chooser";
import textUtils from "../../lib/text-utils";

const {
	StyleSheet,
	View,
	PixelRatio
} = React;

const styles = StyleSheet.create({
	container: {
		flexDirection: "row",
		alignItems: "stretch",
		backgroundColor: "#fff",
		borderColor: "rgba(0, 0, 0, .12)",
		borderTopWidth: 1 / PixelRatio.get()
	},
	inputContainer: {
		flex: 1,
		paddingHorizontal: 16
	},
	input: {
		color: "#000",
		backgroundColor: "transparent",
		paddingVertical: 16,
		margin: 0
	},
	iconContainer: {
		alignItems: "center",
		justifyContent: "center"
	},
	icon: {
		color: "#000",
		fontSize: 24,
		opacity: 0.5,
		margin: 17
	}
});

export default class ChatInput extends React.Component {
	constructor(props) {
		super(props);

		this.state = {
			text: "",
			query: "",
			imageData: null
		};
	}

	set quotedText(text) {
		this._computedAndSetText({
			replyTo: text.from,
			quotedText: text.text
		});
	}

	set replyTo(text) {
		this._computedAndSetText({
			replyTo: text.from
		});
	}

	_sendMessage() {
		this.props.sendMessage(this.state.text);

		this.setState({
			text: ""
		});
	}

	_uploadImage() {
		ImageChooser.pickImage(result => {
			if (result.type === "success") {
				this.setState({
					imageData: result
				});
			}
		});
	}

	_onUploadFinish(result) {
		const { height, width, name } = this.state.imageData;

		const aspectRatio = height / width;

		this.props.sendMessage(textUtils.getTextFromMetadata({
			type: "image",
			caption: name,
			height: 160 * aspectRatio,
			width: 160,
			thumbnailUrl: result.thumbnailUrl,
			originalUrl: result.originalUrl
		}), result.textId);

		setTimeout(() => this._onUploadClose(), 500);
	}

	_onUploadClose() {
		this.setState({
			imageData: ""
		});
	}

	_onSuggestionSelect(nick) {
		this.setState({
			text: "@" + nick + " ",
			query: ""
		});
	}

	_onChangeText(text) {
		const query = /^@[a-z0-9]*$/.test(text) ? text : "";

		this.setState({
			text,
			query
		});
	}

	_computedAndSetText(opts) {
		let newValue = this.state.text;

		if (opts.quotedText) {
			if (newValue) {
				newValue += "\n\n";
			}

			newValue += "> " + (opts.replyTo ? "@" + opts.replyTo + " - " : "") + opts.quotedText + "\n\n";
		} else if (opts.replyTo) {<commit_msg>Add space before nick when replying<commit_after>import React from "react-native";
import Icon from "./icon";
import GrowingTextInput from "./growing-text-input";
import TouchFeedback from "./touch-feedback";
import ChatSuggestionsController from "../controllers/chat-suggestions-controller";
import ImageUploadController from "../controllers/image-upload-controller";
import ImageUploadChat from "./image-upload-chat";
import ImageChooser from "../../modules/image-chooser";
import textUtils from "../../lib/text-utils";

const {
	StyleSheet,
	View,
	PixelRatio
} = React;

const styles = StyleSheet.create({
	container: {
		flexDirection: "row",
		alignItems: "stretch",
		backgroundColor: "#fff",
		borderColor: "rgba(0, 0, 0, .12)",
		borderTopWidth: 1 / PixelRatio.get()
	},
	inputContainer: {
		flex: 1,
		paddingHorizontal: 16
	},
	input: {
		color: "#000",
		backgroundColor: "transparent",
		paddingVertical: 16,
		margin: 0
	},
	iconContainer: {
		alignItems: "center",
		justifyContent: "center"
	},
	icon: {
		color: "#000",
		fontSize: 24,
		opacity: 0.5,
		margin: 17
	}
});

export default class ChatInput extends React.Component {
	constructor(props) {
		super(props);

		this.state = {
			text: "",
			query: "",
			imageData: null
		};
	}

	set quotedText(text) {
		this._computedAndSetText({
			replyTo: text.from,
			quotedText: text.text
		});
	}

	set replyTo(text) {
		this._computedAndSetText({
			replyTo: text.from
		});
	}

	_sendMessage() {
		this.props.sendMessage(this.state.text);

		this.setState({
			text: ""
		});
	}

	_uploadImage() {
		ImageChooser.pickImage(result => {
			if (result.type === "success") {
				this.setState({
					imageData: result
				});
			}
		});
	}

	_onUploadFinish(result) {
		const { height, width, name } = this.state.imageData;

		const aspectRatio = height / width;

		this.props.sendMessage(textUtils.getTextFromMetadata({
			type: "image",
			caption: name,
			height: 160 * aspectRatio,
			width: 160,
			thumbnailUrl: result.thumbnailUrl,
			originalUrl: result.originalUrl
		}), result.textId);

		setTimeout(() => this._onUploadClose(), 500);
	}

	_onUploadClose() {
		this.setState({
			imageData: ""
		});
	}

	_onSuggestionSelect(nick) {
		this.setState({
			text: "@" + nick + " ",
			query: ""
		});
	}

	_onChangeText(text) {
		const query = /^@[a-z0-9]*$/.test(text) ? text : "";

		this.setState({
			text,
			query
		});
	}

	_computedAndSetText(opts) {
		let newValue = this.state.text;

		if (opts.quotedText) {
			if (newValue) {
				newValue += "\n\n";
			}

			newValue += "> " + (opts.replyTo ? "@" + opts.replyTo + " - " : "") + opts.quotedText + "\n\n";
		} else if (opts.replyTo) {
			if (newValue) {
				newValue += " ";
			}

{'fraction_non_alphanumeric': 0.16567275437942602, 'fraction_numerical': 0.013045098770033545, 'mean_word_length': 3.3883892068683563, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 9, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7564907', 'n_tokens_mistral': 2181, 'n_tokens_neox': 1871, 'n_words': 380}