From 31c43836f40baa15d78cdb2d710d9dc2833c4568 Mon Sep 17 00:00:00 2001
From: Khairul Hidayat <me@khairul.my.id>
Date: Sat, 9 Nov 2024 03:38:27 +0700
Subject: [PATCH] feat: update ui, test release mode

---
 frontend/.gitignore                         |  2 +
 frontend/app.config.ts                      | 13 +++++--
 frontend/app/(drawer)/_layout.tsx           |  2 +-
 frontend/components/containers/terminal.tsx |  3 ++
 frontend/components/containers/xtermjs.tsx  | 43 ++++++++++++++++++---
 frontend/components/ui/pager-view.tsx       |  4 +-
 frontend/eas.json                           | 24 ++++++++++++
 frontend/package.json                       |  4 +-
 8 files changed, 82 insertions(+), 13 deletions(-)
 create mode 100644 frontend/eas.json

diff --git a/frontend/.gitignore b/frontend/.gitignore
index 574ca7f..451f25f 100644
--- a/frontend/.gitignore
+++ b/frontend/.gitignore
@@ -20,3 +20,5 @@ expo-env.d.ts
 # @end expo-cli
 .env*
 !.env.example
+*.apk
+*.aab
diff --git a/frontend/app.config.ts b/frontend/app.config.ts
index 188f6e7..73cc29f 100644
--- a/frontend/app.config.ts
+++ b/frontend/app.config.ts
@@ -2,12 +2,12 @@ import { ExpoConfig, ConfigContext } from "expo/config";
 
 export default ({ config }: ConfigContext): ExpoConfig => ({
   ...config,
-  name: "frontend",
-  slug: "frontend",
+  name: "Vaulterm",
+  slug: "vaulterm",
   version: "1.0.0",
   orientation: "portrait",
   icon: "./assets/images/icon.png",
-  scheme: "myapp",
+  scheme: "vaulterm",
   userInterfaceStyle: "automatic",
   newArchEnabled: true,
   splash: {
@@ -19,6 +19,7 @@ export default ({ config }: ConfigContext): ExpoConfig => ({
     supportsTablet: true,
   },
   android: {
+    package: "sh.rul.vaulterm",
     adaptiveIcon: {
       foregroundImage: "./assets/images/adaptive-icon.png",
       backgroundColor: "#ffffff",
@@ -33,4 +34,10 @@ export default ({ config }: ConfigContext): ExpoConfig => ({
   experiments: {
     typedRoutes: true,
   },
+  owner: "khairul169",
+  extra: {
+    eas: {
+      projectId: "3e0112c1-f0ed-423c-b5cf-95633f23f6dc",
+    },
+  },
 });
diff --git a/frontend/app/(drawer)/_layout.tsx b/frontend/app/(drawer)/_layout.tsx
index 935daab..b67685b 100644
--- a/frontend/app/(drawer)/_layout.tsx
+++ b/frontend/app/(drawer)/_layout.tsx
@@ -18,7 +18,7 @@ export default function Layout() {
         <Drawer.Screen name="hosts" options={{ title: "Hosts" }} />
         <Drawer.Screen
           name="terminal"
-          options={{ title: "Terminal", headerShown: true }}
+          options={{ title: "Terminal", headerShown: media.sm }}
         />
       </Drawer>
     </GestureHandlerRootView>
diff --git a/frontend/components/containers/terminal.tsx b/frontend/components/containers/terminal.tsx
index 84a9082..f77fc30 100644
--- a/frontend/components/containers/terminal.tsx
+++ b/frontend/components/containers/terminal.tsx
@@ -4,6 +4,7 @@ import Ionicons from "@expo/vector-icons/Ionicons";
 import { ScrollView, Text, TextStyle, View } from "tamagui";
 import Pressable from "../ui/pressable";
 import Icons from "../ui/icons";
+import useThemeStore from "@/stores/theme";
 
 const Keys = {
   ArrowLeft: "\x1b[D",
@@ -29,6 +30,7 @@ type TerminalProps = ComponentPropsWithoutRef<typeof View> & XTermJsProps;
 
 const Terminal = ({ client = "xtermjs", style, ...props }: TerminalProps) => {
   const xtermRef = React.useRef<XTermRef>(null);
+  const theme = useThemeStore((i) => i.theme);
 
   const send = (data: string) => {
     switch (client) {
@@ -45,6 +47,7 @@ const Terminal = ({ client = "xtermjs", style, ...props }: TerminalProps) => {
           ref={xtermRef}
           dom={{ scrollEnabled: false }}
           wsUrl={props.url}
+          colorScheme={theme}
         />
       )}
 
diff --git a/frontend/components/containers/xtermjs.tsx b/frontend/components/containers/xtermjs.tsx
index 94d09f4..353788f 100644
--- a/frontend/components/containers/xtermjs.tsx
+++ b/frontend/components/containers/xtermjs.tsx
@@ -18,10 +18,11 @@ type XTermJsProps = {
   dom?: DOMProps;
   style?: CSSProperties;
   wsUrl: string;
+  colorScheme?: "light" | "dark";
 };
 
 // vscode-snazzy https://github.com/Tyriar/vscode-snazzy
-const snazzyTheme = {
+const darkTheme = {
   foreground: "#eff0eb",
   background: "#282a36",
   selection: "#97979b33",
@@ -43,6 +44,28 @@ const snazzyTheme = {
   brightWhite: "#eff0eb",
 };
 
+const lightTheme = {
+  foreground: "#282a36",
+  background: "#e5f2ff",
+  selection: "#97979b33",
+  black: "#eff0eb",
+  brightBlack: "#686868",
+  red: "#d32f2f",
+  brightRed: "#ff5c57",
+  green: "#388e3c",
+  brightGreen: "#5af78e",
+  yellow: "#fbc02d",
+  brightYellow: "#f3f99d",
+  blue: "#1976d2",
+  brightBlue: "#57c7ff",
+  magenta: "#ab47bc",
+  brightMagenta: "#ff6ac1",
+  cyan: "#00acc1",
+  brightCyan: "#9aedfe",
+  white: "#282a36",
+  brightWhite: "#686868",
+};
+
 export interface XTermRef extends DOMImperativeFactory {
   send: (...args: JSONValue[]) => void;
 }
@@ -50,7 +73,9 @@ export interface XTermRef extends DOMImperativeFactory {
 const XTermJs = forwardRef<XTermRef, XTermJsProps>((props, ref) => {
   const containerRef = useRef<HTMLDivElement | null>(null);
   const wsRef = useRef<WebSocket | null>(null);
-  const { wsUrl, onLoad, style = {} } = props;
+  const xtermRef = useRef<XTerm | null>(null);
+  const { wsUrl, onLoad, style = {}, colorScheme } = props;
+  const theme = colorScheme === "dark" ? darkTheme : lightTheme;
 
   useEffect(() => {
     const container = containerRef.current;
@@ -60,10 +85,11 @@ const XTermJs = forwardRef<XTermRef, XTermJsProps>((props, ref) => {
 
     const xterm = new XTerm({
       fontFamily: '"Cascadia Code", Menlo, monospace',
-      theme: snazzyTheme,
+      theme: theme,
       cursorBlink: true,
     });
     xterm.open(container);
+    xtermRef.current = xterm;
 
     const fitAddon = new FitAddon();
     xterm.loadAddon(fitAddon);
@@ -101,8 +127,6 @@ const XTermJs = forwardRef<XTermRef, XTermJsProps>((props, ref) => {
     }
 
     function onClose(e: CloseEvent) {
-      console.log("WS Closed", e.reason, e.code);
-
       // Check if the close event was abnormal
       if (!e.wasClean) {
         const reason = e.reason || `Code: ${e.code}`;
@@ -129,6 +153,7 @@ const XTermJs = forwardRef<XTermRef, XTermJsProps>((props, ref) => {
 
     return () => {
       xterm.dispose();
+      xtermRef.current = null;
       wsRef.current = null;
       containerRef.current = null;
 
@@ -154,11 +179,17 @@ const XTermJs = forwardRef<XTermRef, XTermJsProps>((props, ref) => {
     []
   );
 
+  useEffect(() => {
+    if (xtermRef.current) {
+      xtermRef.current.options.theme = theme;
+    }
+  }, [theme]);
+
   return (
     <div
       ref={containerRef}
       style={{
-        background: snazzyTheme.background,
+        background: theme.background,
         padding: 12,
         flex: !IS_DOM ? 1 : undefined,
         width: "100%",
diff --git a/frontend/components/ui/pager-view.tsx b/frontend/components/ui/pager-view.tsx
index d2a54f6..50efba4 100644
--- a/frontend/components/ui/pager-view.tsx
+++ b/frontend/components/ui/pager-view.tsx
@@ -19,13 +19,13 @@ const PagerView = ({
 
   const [onPageSelect, clearPageSelectDebounce] = useDebounceCallback(
     (page) => onChangePage?.(page),
-    100
+    300
   );
 
   const [setPage] = useDebounceCallback((page) => {
     ref.current?.setPage(page);
     clearPageSelectDebounce();
-  }, 300);
+  }, 100);
 
   useEffect(() => {
     if (page != null) {
diff --git a/frontend/eas.json b/frontend/eas.json
new file mode 100644
index 0000000..8679de5
--- /dev/null
+++ b/frontend/eas.json
@@ -0,0 +1,24 @@
+{
+  "cli": {
+    "version": ">= 10.2.2"
+  },
+  "build": {
+    "development": {
+      "developmentClient": true,
+      "distribution": "internal"
+    },
+    "preview": {
+      "distribution": "internal",
+      "android": {
+        "buildType": "apk"
+      },
+      "env": {
+        "EXPO_PUBLIC_API_URL": "https://vaulterm-dev.rul.sh"
+      }
+    },
+    "production": {}
+  },
+  "submit": {
+    "production": {}
+  }
+}
\ No newline at end of file
diff --git a/frontend/package.json b/frontend/package.json
index 469f27e..9df1ab5 100644
--- a/frontend/package.json
+++ b/frontend/package.json
@@ -10,7 +10,9 @@
     "ios": "expo start --ios",
     "web": "expo start --web",
     "test": "jest --watchAll",
-    "lint": "expo lint"
+    "lint": "expo lint",
+    "build:preview": "eas build -p android --profile preview --local",
+    "build:android": "eas build -p android --local"
   },
   "jest": {
     "preset": "jest-expo"