From d06784958d73159b5e4abafe5114804662114ed7 Mon Sep 17 00:00:00 2001
From: Ryan Schanzenbacher <ryan@rschanz.org>
Date: Thu, 9 Jul 2026 22:15:53 -0400
Subject: move ubersicht modules in tree

---
 .../lib/components/data/memory.jsx                 | 134 +++++++++++++++++++++
 1 file changed, 134 insertions(+)
 create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/components/data/memory.jsx

(limited to 'users/ryan/modules/simple-bar/simple-bar-source/lib/components/data/memory.jsx')

diff --git a/users/ryan/modules/simple-bar/simple-bar-source/lib/components/data/memory.jsx b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/data/memory.jsx
new file mode 100755
index 0000000..e4361db
--- /dev/null
+++ b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/data/memory.jsx
@@ -0,0 +1,134 @@
+import * as Uebersicht from "uebersicht";
+import * as DataWidget from "./data-widget.jsx";
+import * as DataWidgetLoader from "./data-widget-loader.jsx";
+import useWidgetRefresh from "../../hooks/use-widget-refresh";
+import useServerSocket from "../../hooks/use-server-socket";
+import { useSimpleBarContext } from "../simple-bar-context.jsx";
+import * as Utils from "../../utils";
+
+export { memoryStyles as styles } from "../../styles/components/data/memory";
+
+const { React } = Uebersicht;
+
+const DEFAULT_REFRESH_FREQUENCY = 4000;
+
+/**
+ * Memory Widget component
+ * @returns {JSX.Element|null} The memory widget component
+ */
+export const Widget = () => {
+  const { displayIndex, settings } = useSimpleBarContext();
+  const { widgets, memoryWidgetOptions } = settings;
+  const { memoryWidget } = widgets;
+  const {
+    refreshFrequency,
+    showOnDisplay,
+    memoryMonitorApp,
+    showIcon,
+    memoryUsageThreshold,
+  } = memoryWidgetOptions;
+
+  // Determine the refresh frequency for the widget
+  const refresh = React.useMemo(
+    () =>
+      Utils.getRefreshFrequency(refreshFrequency, DEFAULT_REFRESH_FREQUENCY),
+    [refreshFrequency],
+  );
+
+  // Determine if the widget should be visible
+  const visible =
+    Utils.isVisibleOnDisplay(displayIndex, showOnDisplay) && memoryWidget;
+
+  const [state, setState] = Uebersicht.React.useState();
+  const [loading, setLoading] = Uebersicht.React.useState(visible);
+
+  /**
+   * Reset the widget state
+   */
+  const resetWidget = () => {
+    setState(undefined);
+    setLoading(false);
+  };
+
+  /**
+   * Fetch memory usage data
+   */
+  const getMemory = React.useCallback(async () => {
+    const output = await Utils.cachedRun(
+      'vm_stat | awk \'BEGIN {page_size=4096} /page size of/ {page_size=$8} /Pages free/ {free=$3} /Pages inactive/ {inactive=$3} /Pages speculative/ {spec=$4} /Pages active/ {active=$3} /Pages wired/ {wired=$4} END {gsub(/\\./, "", free); gsub(/\\./, "", inactive); gsub(/\\./, "", spec); gsub(/\\./, "", active); gsub(/\\./, "", wired); available=free+inactive+spec; total=available+active+wired; printf "%.0f", (available/total)*100}\'',
+      refresh,
+    );
+    const free = parseInt(Utils.cleanupOutput(output), 10);
+    setState({ free });
+    setLoading(false);
+  }, [setLoading, setState, refresh]);
+
+  // Use server socket to get memory data
+  useServerSocket("memory", visible, getMemory, resetWidget, setLoading);
+  // Refresh the widget at the specified interval
+  useWidgetRefresh(visible, getMemory, refresh);
+
+  if (loading) return <DataWidgetLoader.Widget className="memory" />;
+  if (!state) return null;
+
+  const { free } = state;
+  const used = 100 - free;
+  const threshold = Number(memoryUsageThreshold) || 0;
+
+  if (threshold > 0 && used < threshold) return null;
+
+  // Handle click event to open memory usage app
+  const onClick =
+    memoryMonitorApp === "None"
+      ? undefined
+      : (e) => {
+          Utils.clickEffect(e);
+          openMemoryUsageApp(memoryMonitorApp);
+        };
+
+  /**
+   * Pie chart component for memory usage
+   * @returns {JSX.Element} The pie chart component
+   */
+  const Pie = () => {
+    return (
+      <div
+        className="memory__pie"
+        style={{
+          backgroundImage: `conic-gradient(var(--pie-color) ${used}%, var(--main-alt) ${used}% 100%)`,
+        }}
+      />
+    );
+  };
+
+  const classes = Utils.classNames("memory", {
+    "memory--low": used <= 30,
+    "memory--medium": used > 30 && used <= 70,
+    "memory--high": used > 70,
+  });
+
+  return (
+    <DataWidget.Widget
+      classes={classes}
+      Icon={showIcon ? Pie : null}
+      onClick={onClick}
+    >
+      <div className="memory__content">{used}%</div>
+    </DataWidget.Widget>
+  );
+};
+
+/**
+ * Open the specified memory usage application
+ * @param {string} app - The name of the application to open
+ */
+function openMemoryUsageApp(app) {
+  switch (app) {
+    case "Activity Monitor":
+      Uebersicht.run(`open -a "Activity Monitor"`);
+      break;
+    case "Top":
+      Utils.runInUserTerminal("top");
+      break;
+  }
+}
-- 
cgit v1.3

