<commit_before>/*
 *  This file is part of CoCalc: Copyright © 2020 Sagemath, Inc.
 *  License: AGPLv3 s.t. "Commons Clause" – see LICENSE.md for details
 */

import { React, useState } from "../../../app-framework";
import memoizeOne from "memoize-one";

import { ProjectActions } from "../../../project_actions";
import { CopyButton } from "./copy-button";
import { PublicButton } from "./public-button";
import { FileCheckbox } from "./file-checkbox";
import { generate_click_for } from "./utils";
import { COLORS, TimeAgo, Tip, Icon } from "../../../r_misc";
const { Button, Row, Col } = require("react-bootstrap");
const misc = require("smc-util/misc");
import { url_href } from "../../utils";

interface Props {
  isdir: boolean;
  name: string;
  display_name: string; // if given, will display this, and will show true filename in popover
  size: number; // sometimes is NOT known!
  time: number;
  issymlink: boolean;
  checked: boolean;
  bordered: boolean;
  color: string;
  mask: boolean;
  public_data: object;
  is_public: boolean;
  current_path: string;
  actions: ProjectActions;
  no_select: boolean;
  public_view: boolean;
  link_target?: string;
}

export const FileRow: React.FC<Props> = React.memo((props) => {
  const [
    selection_at_last_mouse_down,
    set_selection_at_last_mouse_down,
  ] = useState<string | undefined>(undefined);

  function render_icon() {
    const style: React.CSSProperties = {
      color: props.mask ? "#bbbbbb" : undefined,
      verticalAlign: "sub",
    } as const;
    let body: JSX.Element;
    if (props.isdir) {
      body = (
        <>
          <Icon
            name="folder-open-o"
            style={{ fontSize: "14pt", verticalAlign: "sub" }}
          />
          <Icon
            name="caret-right"
            style={{
              marginLeft: "3px",
              fontSize: "14pt",
              verticalAlign: "sub",
            }}
          />
        </>
      );
    } else {
      // get the file_associations[ext] just like it is defined in the editor
      let name: string;
      const { file_options } = require("../../../editor");
      const info = file_options(props.name);
      if (info != undefined) {
        name = info.icon;
      } else {
        name = "file";
      }

      body = <Icon name={name} style={{ fontSize: "14pt" }} />;
    }

    return <a style={style}>{body}</a>;
  }

  function render_link_target() {
    if (props.link_target == null || props.link_target == props.name) return;
    return (
      <>
        {" "}
        <Icon name="arrow-right" style={{ margin: "0 10px" }} />{" "}
        {props.link_target}{" "}
      </>
    );
  }

  function render_name_link(styles, name, ext) {
    return (
      <a style={styles} cocalc-test="file-line">
        <span style={{ fontWeight: props.mask ? "normal" : "bold" }}>
          {misc.trunc_middle(name, 50)}
        </span>
        <span style={{ color: !props.mask ? "#999" : undefined }}>
          {ext === "" ? "" : `.${ext}`}
        </span>
        {render_link_target()}
      </a>
    );
  }

  function render_name() {
    let name = props.display_name ?? props.name;
    const name_and_ext = misc.separate_file_extension(name);
    ({ name } = name_and_ext);
    const { ext } = name_and_ext;

    const show_tip =
      (props.display_name != undefined && props.name !== props.display_name) ||
      name.length > 50;

    const styles = {
      whiteSpace: "pre-wrap",
      wordWrap: "break-word",
      overflowWrap: "break-word",
      verticalAlign: "middle",
      color: props.mask ? "#bbbbbb" : undefined,
    };

    if (show_tip) {
      return (
        <Tip
          title={
            props.display_name
              ? "Displayed filename is an alias. The actual name is:"
              : "Full name"<commit_msg>fix #4761 -- files: don't treat directories like filenames<commit_after>/*
 *  This file is part of CoCalc: Copyright © 2020 Sagemath, Inc.
 *  License: AGPLv3 s.t. "Commons Clause" – see LICENSE.md for details
 */

import { React, useState } from "../../../app-framework";
import memoizeOne from "memoize-one";

import { ProjectActions } from "../../../project_actions";
import { CopyButton } from "./copy-button";
import { PublicButton } from "./public-button";
import { FileCheckbox } from "./file-checkbox";
import { generate_click_for } from "./utils";
import { COLORS, TimeAgo, Tip, Icon } from "../../../r_misc";
const { Button, Row, Col } = require("react-bootstrap");
const misc = require("smc-util/misc");
import { url_href } from "../../utils";

interface Props {
  isdir: boolean;
  name: string;
  display_name: string; // if given, will display this, and will show true filename in popover
  size: number; // sometimes is NOT known!
  time: number;
  issymlink: boolean;
  checked: boolean;
  bordered: boolean;
  color: string;
  mask: boolean;
  public_data: object;
  is_public: boolean;
  current_path: string;
  actions: ProjectActions;
  no_select: boolean;
  public_view: boolean;
  link_target?: string;
}

export const FileRow: React.FC<Props> = React.memo((props) => {
  const [
    selection_at_last_mouse_down,
    set_selection_at_last_mouse_down,
  ] = useState<string | undefined>(undefined);

  function render_icon() {
    const style: React.CSSProperties = {
      color: props.mask ? "#bbbbbb" : undefined,
      verticalAlign: "sub",
    } as const;
    let body: JSX.Element;
    if (props.isdir) {
      body = (
        <>
          <Icon
            name="folder-open-o"
            style={{ fontSize: "14pt", verticalAlign: "sub" }}
          />
          <Icon
            name="caret-right"
            style={{
              marginLeft: "3px",
              fontSize: "14pt",
              verticalAlign: "sub",
            }}
          />
        </>
      );
    } else {
      // get the file_associations[ext] just like it is defined in the editor
      let name: string;
      const { file_options } = require("../../../editor");
      const info = file_options(props.name);
      if (info != undefined) {
        name = info.icon;
      } else {
        name = "file";
      }

      body = <Icon name={name} style={{ fontSize: "14pt" }} />;
    }

    return <a style={style}>{body}</a>;
  }

  function render_link_target() {
    if (props.link_target == null || props.link_target == props.name) return;
    return (
      <>
        {" "}
        <Icon name="arrow-right" style={{ margin: "0 10px" }} />{" "}
        {props.link_target}{" "}
      </>
    );
  }

  function render_name_link(styles, name, ext) {
    return (
      <a style={styles} cocalc-test="file-line">
        <span style={{ fontWeight: props.mask ? "normal" : "bold" }}>
          {misc.trunc_middle(name, 50)}
        </span>
        <span style={{ color: !props.mask ? "#999" : undefined }}>
          {ext === "" ? "" : `.${ext}`}
        </span>
        {render_link_target()}
      </a>
    );
  }

  function render_name() {
    let name = props.display_name ?? props.name;
    let ext: string;
    if (props.isdir) {
      ext = "";
    } else {
      const name_and_ext = misc.separate_file_extension(name);
      ({ name, ext } = name_and_ext);
    }

    const show_tip =
      (props.display_name != undefined && props.name !== props.display_name) ||
      name.length > 50;

    const styles = {
      whiteSpace: "pre-wrap",
      wordWrap: "break-word",
      overflowWrap: "break-word",
      verticalAlign: "middle",
      color: props.mask ? "#bbbbbb" : undefined,
    };

    if (show_tip) {
      return (
        <Tip
          title={
            props.display_name
              ? "Displayed filename is an alias. The actual name is:"
              : "Full name"
{'fraction_non_alphanumeric': 0.1527399922269724, 'fraction_numerical': 0.006218422075398368, 'mean_word_length': 2.273960983884648, 'pattern_counts': {'":': 0, '<': 41, '<?xml version=': 0, '>': 43, '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': '2765892', 'n_tokens_mistral': 2458, 'n_tokens_neox': 2415, 'n_words': 615}