File size: 1,971 Bytes
7e3630c
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
import { useMemo } from "react";
import type { Position } from "./usePosition.js";

export type Visibility = "full" | "partial" | "hidden";

export interface VisibilityInfo {
  position: Position;
  terminalWidth: number;
  terminalHeight: number;
  defaultVisibility: Visibility;
}

export type GetVisibility = (info: VisibilityInfo) => Visibility;

export function defaultVisibility(
  position: Position,
  terminalHeight: number,
  terminalWidth: number,
): Visibility {
  const viewportStartRow = terminalHeight - position.appHeight + position.row;
  const viewportEndRow = viewportStartRow + position.height;
  const inAppStartRow = position.row;
  const inAppEndRow = inAppStartRow + position.height;

  if (
    viewportEndRow <= 0 ||
    inAppEndRow <= 0 ||
    viewportStartRow >= terminalHeight ||
    inAppStartRow >= position.appHeight
  ) {
    return "hidden";
  }

  const viewportEndCol = position.col + position.width;
  if (
    viewportEndCol <= 0 ||
    position.col >= terminalWidth ||
    position.col >= position.appWidth
  ) {
    return "hidden";
  }

  if (
    viewportStartRow < 0 ||
    inAppStartRow < 0 ||
    viewportEndRow > terminalHeight ||
    inAppEndRow > position.appHeight ||
    position.col < 0 ||
    viewportEndCol > terminalWidth ||
    viewportEndCol > position.appWidth
  ) {
    return "partial";
  }

  return "full";
}

export function useVisibility(
  position: Position | undefined,
  terminalHeight: number,
  terminalWidth: number,
  getVisibility?: GetVisibility,
): Visibility {
  return useMemo(() => {
    if (!position) return "hidden";

    const visibility = defaultVisibility(
      position,
      terminalHeight,
      terminalWidth,
    );

    if (getVisibility) {
      return getVisibility({
        position,
        terminalWidth,
        terminalHeight,
        defaultVisibility: visibility,
      });
    }

    return visibility;
  }, [position, terminalHeight, terminalWidth, getVisibility]);
}