GitFOSS
.ts
TypeScript
(application/typescript)
// 1st-party
import type { ReactView } from "@ethicdevs/react-monolith";
// 3rd-party
import React from "react";
// generated via script[prisma:generate]
import type { Organization, User } from "@prisma/client";
// app
import type {
  CommonProps,
  LinguistFileInfos,
  RepositoryFileContent,
  RepositoryLog,
  RepositoryWithForkedFromRepo,
} from "../../types";
import { buildRouteLink } from "../../utils/shared";
import { AppRoute } from "../../routes.defs";
import { Const } from "../../const";
import { NamedColors } from "../../utils/style";
import {
  Card,
  Grid,
  IslandWrapper,
  Layout,
  PageWrapper,
  Select,
  TextEllipsis,
} from "../../components";
// app islands
import Code, { getThemedCodeCss } from "../../islands/Code";
import RepositoryCommitSummaryLine from "../../islands/RepositoryCommitSummaryLine";
import RepositoryHero from "../../islands/RepositoryHero";

export interface RepositoryBrowserViewProps extends CommonProps {
  branches: string[];
  currentRef: string;
  currentUser: null | User;
  fileContent: RepositoryFileContent;
  lastCommit: null | RepositoryLog;
  linguistInfos: LinguistFileInfos;
  parentOrg: Organization;
  path: string;
  repo: RepositoryWithForkedFromRepo;
}

const RepositoryBrowserView: ReactView<RepositoryBrowserViewProps> = ({
  branches,
  commonProps,
  currentRef,
  fileContent,
  lastCommit,
  linguistInfos,
  parentOrg,
  path,
  repo,
}) => {
  const currPathParts = path.split("/");
  const shouldShowRootPath = path !== "/";

  return (
    <Layout
      {...commonProps}
      showDrawerPrimary
      orgSlug={parentOrg.slug}
      repoSlug={repo.slug}
      currentRef={currentRef}
    >
      <PageWrapper>
        <IslandWrapper data-islandid={`${RepositoryHero.name}$$0`}>
          <RepositoryHero
            forkedFromRepo={repo.forkedFromRepo}
            forksCount={repo.forks.length}
            parentOrg={parentOrg}
            repo={repo}
          />
        </IslandWrapper>
        <Grid.Col fluid style={{ marginTop: 32 }}>
          {lastCommit && (
            <Card
              data-islandid={`${RepositoryCommitSummaryLine.name}$$0`}
              style={{ width: "100%", padding: 8 }}
              themeScheme={commonProps.themeScheme}
            >
              <RepositoryCommitSummaryLine
                commit={lastCommit}
                currentRef={currentRef}
                orgSlug={parentOrg.slug}
                repoSlug={repo.slug}
              />
            </Card>
          )}
          <Card
            style={{
              width: "100%",
              marginTop: lastCommit != null ? 8 : 0,
              padding: 8,
              backdropFilter: "blur(8px)",
              backgroundColor:
                NamedColors.CARD_ALPHA_01[commonProps.themeScheme],
              position: "sticky",
              top: 80,
              zIndex: 9000,
              borderRadius: 8,
            }}
            themeScheme={commonProps.themeScheme}
          >
            <Grid.Row fluid nowrap alignItems={"center"} gap={8}>
              <Select
                themeScheme={commonProps.themeScheme}
                title={"Branch"}
                onChange={(e) => {
                  console.log("branch changed to: ", e.currentTarget.value);
                  window.location.href = buildRouteLink(
                    AppRoute.REPOSITORY_BROWSER_WITH_PATH,
                    {
                      orgSlug: parentOrg.slug,
                      repoSlug: repo.slug,
                      currentRef: e.currentTarget.value,
                      "*": path,
                    },
                  );
                }}
                style={{
                  height: 32,
                  width: "auto",
                  minWidth: 80,
                  padding: "0 8px",
                }}
              >
                {branches.map(
                  (branch, idx) =>
                    branch.trim() != "" && (
                      <option
                        key={branch}
                        value={branch}
                        selected={
                          branches.findIndex((b) => b === currentRef) === idx ||
                          (currentRef === Const.DEFAULT_HEAD_REF &&
                            branch === Const.PRIMARY_BRANCH_REF)
                            ? true
                            : undefined
                        }
                      >
                        {branch}
                      </option>
                    ),
                )}
              </Select>
              {shouldShowRootPath && (
                <a
                  title={`Go to root`}
                  href={buildRouteLink(AppRoute.REPOSITORY_DETAILS, {
                    orgSlug: parentOrg.slug,
                    repoSlug: repo.slug,
                  })}
                >
                  ~
                </a>
              )}
              {currPathParts.map(
                (pathPart, idx, self) =>
                  pathPart.trim() !== "" &&
                  pathPart !== "/" && (
                    <a
                      key={[idx, pathPart].join(":")}
                      title={`Go to "${currPathParts
                        .slice(0, idx + 1)
                        .join("/")}${
                        idx === self.length - 1 && path.endsWith("/") === false
                          ? '" file'
                          : '/" folder'
                      }`}
                      href={buildRouteLink(
                        AppRoute.REPOSITORY_BROWSER_WITH_PATH,
                        {
                          orgSlug: parentOrg.slug,
                          repoSlug: repo.slug,
                          currentRef,
                          "*": `${currPathParts.slice(0, idx + 1).join("/")}${
                            idx === self.length - 1 &&
                            path.endsWith("/") === false
                              ? ""
                              : "/"
                          }`,
                        },
                      )}
                    >
                      <TextEllipsis>
                        {pathPart}
                        {idx === self.length - 1 && path.endsWith("/") === false
                          ? ""
                          : "/"}
                      </TextEllipsis>
                    </a>
                  ),
              )}
            </Grid.Row>
            <div
              style={{
                height: 1,
                margin: "8px 0",
                background: NamedColors.BORDER_CARD[commonProps.themeScheme],
              }}
            />
            <Grid.Row
              nowrap
              gap={12}
              alignItems={"center"}
              style={{ width: "100%" }}
            >
              <div
                style={{
                  display: "flex",
                  alignItems: "center",
                  justifyContent: "center",
                  height: 24,
                  width: 24,
                  background: linguistInfos.color,
                  borderRadius: 4,
                  color: "white",
                  fontSize:
                    linguistInfos.extensions.length > 0 &&
                    linguistInfos.extensions[0].slice(1).length <= 4
                      ? linguistInfos.extensions[0].slice(1).length <= 2
                        ? 12
                        : 9
                      : 6,
                }}
              >
                {linguistInfos.extensions.length > 0
                  ? linguistInfos.extensions[0]
                  : ""}
              </div>
              <div>
                <strong>
                  {linguistInfos.languageDisplayName ||
                    `lang: ${linguistInfos.language}`}
                </strong>
              </div>
              <div>
                <span>({linguistInfos.mimeType})</span>
              </div>
            </Grid.Row>
          </Card>
          {linguistInfos.type === "image" ? (
            <Card
              style={{ width: "100%", marginTop: 8 }}
              themeScheme={commonProps.themeScheme}
            >
              <img
                src={fileContent.content}
                style={{ width: "100%", height: "auto" }}
              />
            </Card>
          ) : (
            <>
              {getThemedCodeCss(commonProps.themeScheme)}
              <Card
                data-islandid={`${Code.name}$$0`}
                style={{
                  width: "100%",
                  marginTop: 8,
                  padding: 0,
                  border: "none",
                }}
                themeScheme={commonProps.themeScheme}
              >
                <Code
                  code={fileContent.content}
                  language={linguistInfos.language}
                  themeScheme={commonProps.themeScheme}
                />
              </Card>
            </>
          )}
        </Grid.Col>
      </PageWrapper>
    </Layout>
  );
};

RepositoryBrowserView.displayName = "RepositoryBrowserView";
export default RepositoryBrowserView;