production-taskbar-client / src / renderer / features / programs / ProgramsComponent.jsx
ProgramsComponent.jsx
Raw
import { ipcRenderer } from "electron";

import React, { useEffect } from "react";
import { useDispatch, useSelector } from "react-redux";
import _ from "lodash";
import path from "path";
import ProgramButton from "./program_button/ProgramButton";
import {
  addTaskbarProgram,
  removeTaskbarProgram,
  setForeground,
} from "./programsSlice";
import "../../app/locale/i18n";
import "./ProgramsComponent.less";
import IconButton from "./icon_button/IconButton";

const isSamePaths = (path1, path2) => {
  if (path1 && path2) return path.normalize(path1) === path.normalize(path2);
  return false;
};

export default function Programs(props) {
  const { compact } = props;
  const dispatch = useDispatch();
  const programs = useSelector(
    (state) => state.database?.settings?.workplace?.workplace_type?.programs
  );

  const exclusive = useSelector(
    (state) => state.database?.settings?.workplace?.exclusive_program
  );

  const webProgramsForType = useSelector((state) => {
    const sites = state.database?.settings?.workplace?.workplace_type?.sites;
    return _.filter(sites, "is_program");
  });

  const webProgramsExclusive = useSelector((state) => {
    const sites = state.database?.settings?.workplace?.sites;
    return _.filter(sites, "is_program");
  });

  const webProgramsAll = _.union(webProgramsForType, webProgramsExclusive);
  const webPrograms = _.uniqBy(webProgramsAll, (webProgram) => webProgram.id);

  const taskbarPrograms = useSelector(
    (state) => state.programs.taskbarPrograms
  );

  const foreground = useSelector((state) => state.programs.foreground);

  useEffect(() => {
    ipcRenderer.send("winevent", "enum-foreground");
    ipcRenderer.on("winevent", (_event, message) => {
      const program = message.data;
      if (message.event === "foreground") {
        dispatch(setForeground(program));

        const isProgram = _.find(programs, (p) =>
          isSamePaths(p.executable_path, program.path)
        );
        const isExclusive = isSamePaths(
          exclusive?.executable_path,
          program.path
        );
        if (isProgram || isExclusive) return;

        dispatch(addTaskbarProgram(program));
      }
      if (message.event === "closed") dispatch(removeTaskbarProgram(program));
    });
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, []);

  return (
    <div className={compact ? "programs--compact" : "programs"}>
      {programs
        ? programs.map((p) => (
            <ProgramButton
              key={p.name}
              type="program"
              program={p}
              active={isSamePaths(foreground?.path, p.executable_path)}
            />
          ))
        : null}
      {exclusive ? (
        <ProgramButton
          key={exclusive.name}
          type="exclusive"
          program={exclusive}
          active={isSamePaths(foreground?.path, exclusive.executable_path)}
        />
      ) : null}
      {webPrograms
        ? webPrograms.map((web) => (
            <ProgramButton key={web.name} type="web" program={web} />
          ))
        : null}

      {!compact ? (
        <div className="taskbar-programs">
          {taskbarPrograms // NOSONAR
            ? Object.entries(taskbarPrograms).map(([hwnd, program]) => {
                return (
                  <IconButton
                    key={hwnd}
                    program={program}
                    active={foreground?.hwnd === program.hwnd}
                  />
                );
              })
            : null}
        </div>
      ) : null}
    </div>
  );
}