//@flow import React from "react"; import { Hunk, Diff as DiffComponent, getChangeKey, Change, DiffObjectProps, File } from "react-diff-view"; import injectSheets from "react-jss"; import classNames from "classnames"; import { translate } from "react-i18next"; import { Button } from "../buttons"; const styles = { panel: { fontSize: "1rem" }, /* breaks into a second row * when buttons and title become too long */ level: { flexWrap: "wrap" }, titleHeader: { display: "flex", maxWidth: "100%", cursor: "pointer" }, title: { marginLeft: ".25rem", fontSize: "1rem" }, /* align child to right */ buttonHeader: { display: "flex", marginLeft: "auto" }, hunkDivider: { margin: ".5rem 0" }, changeType: { marginLeft: ".75rem" } }; type Props = DiffObjectProps & { file: File, // context props classes: any, t: string => string }; type State = { collapsed: boolean, sideBySide: boolean }; class DiffFile extends React.Component { constructor(props: Props) { super(props); this.state = { collapsed: false, sideBySide: false }; } toggleCollapse = () => { this.setState(state => ({ collapsed: !state.collapsed })); }; toggleSideBySide = () => { this.setState(state => ({ sideBySide: !state.sideBySide })); }; setCollapse = (collapsed: boolean) => { this.setState({ collapsed }); }; createHunkHeader = (hunk: Hunk, i: number) => { const { classes } = this.props; if (i > 0) { return
; } return null; }; collectHunkAnnotations = (hunk: Hunk) => { const { annotationFactory, file } = this.props; if (annotationFactory) { return annotationFactory({ hunk, file }); } }; handleClickEvent = (change: Change, hunk: Hunk) => { const { file, onClick } = this.props; const context = { changeId: getChangeKey(change), change, hunk, file }; if (onClick) { onClick(context); } }; createCustomEvents = (hunk: Hunk) => { const { onClick } = this.props; if (onClick) { return { gutter: { onClick: (change: Change) => { this.handleClickEvent(change, hunk); } } }; } }; renderHunk = (hunk: Hunk, i: number) => { return ( ); }; renderFileTitle = (file: any) => { if ( file.oldPath !== file.newPath && (file.type === "copy" || file.type === "rename") ) { return ( <> {file.oldPath} {file.newPath} ); } else if (file.type === "delete") { return file.oldPath; } return file.newPath; }; hoverFileTitle = (file: any) => { if ( file.oldPath !== file.newPath && (file.type === "copy" || file.type === "rename") ) { return ( <> {file.oldPath} > {file.newPath} ); } else if (file.type === "delete") { return file.oldPath; } return file.newPath; }; renderChangeTag = (file: any) => { const { t, classes } = this.props; const key = "diff.changes." + file.type; let value = t(key); if (key === value) { value = file.type; } return ( {value} ); }; render() { const { file, fileControlFactory, fileAnnotationFactory, classes, t } = this.props; const { collapsed, sideBySide } = this.state; const viewType = sideBySide ? "split" : "unified"; let body = null; let icon = "fa fa-angle-right"; if (!collapsed) { const fileAnnotations = fileAnnotationFactory ? fileAnnotationFactory(file) : null; icon = "fa fa-angle-down"; body = (
{fileAnnotations} {file.hunks.map(this.renderHunk)}
); } const fileControls = fileControlFactory ? fileControlFactory(file, this.setCollapse) : null; return (
{this.renderFileTitle(file)} {this.renderChangeTag(file)}
{fileControls}
{body}
); } } export default injectSheets(styles)(translate("repos")(DiffFile));