mirror of
https://github.com/khairul169/vaulterm.git
synced 2025-04-28 16:49:39 +07:00
feat: update ui, test release mode
This commit is contained in:
parent
334d90e691
commit
31c43836f4
2
frontend/.gitignore
vendored
2
frontend/.gitignore
vendored
@ -20,3 +20,5 @@ expo-env.d.ts
|
|||||||
# @end expo-cli
|
# @end expo-cli
|
||||||
.env*
|
.env*
|
||||||
!.env.example
|
!.env.example
|
||||||
|
*.apk
|
||||||
|
*.aab
|
||||||
|
@ -2,12 +2,12 @@ import { ExpoConfig, ConfigContext } from "expo/config";
|
|||||||
|
|
||||||
export default ({ config }: ConfigContext): ExpoConfig => ({
|
export default ({ config }: ConfigContext): ExpoConfig => ({
|
||||||
...config,
|
...config,
|
||||||
name: "frontend",
|
name: "Vaulterm",
|
||||||
slug: "frontend",
|
slug: "vaulterm",
|
||||||
version: "1.0.0",
|
version: "1.0.0",
|
||||||
orientation: "portrait",
|
orientation: "portrait",
|
||||||
icon: "./assets/images/icon.png",
|
icon: "./assets/images/icon.png",
|
||||||
scheme: "myapp",
|
scheme: "vaulterm",
|
||||||
userInterfaceStyle: "automatic",
|
userInterfaceStyle: "automatic",
|
||||||
newArchEnabled: true,
|
newArchEnabled: true,
|
||||||
splash: {
|
splash: {
|
||||||
@ -19,6 +19,7 @@ export default ({ config }: ConfigContext): ExpoConfig => ({
|
|||||||
supportsTablet: true,
|
supportsTablet: true,
|
||||||
},
|
},
|
||||||
android: {
|
android: {
|
||||||
|
package: "sh.rul.vaulterm",
|
||||||
adaptiveIcon: {
|
adaptiveIcon: {
|
||||||
foregroundImage: "./assets/images/adaptive-icon.png",
|
foregroundImage: "./assets/images/adaptive-icon.png",
|
||||||
backgroundColor: "#ffffff",
|
backgroundColor: "#ffffff",
|
||||||
@ -33,4 +34,10 @@ export default ({ config }: ConfigContext): ExpoConfig => ({
|
|||||||
experiments: {
|
experiments: {
|
||||||
typedRoutes: true,
|
typedRoutes: true,
|
||||||
},
|
},
|
||||||
|
owner: "khairul169",
|
||||||
|
extra: {
|
||||||
|
eas: {
|
||||||
|
projectId: "3e0112c1-f0ed-423c-b5cf-95633f23f6dc",
|
||||||
|
},
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
@ -18,7 +18,7 @@ export default function Layout() {
|
|||||||
<Drawer.Screen name="hosts" options={{ title: "Hosts" }} />
|
<Drawer.Screen name="hosts" options={{ title: "Hosts" }} />
|
||||||
<Drawer.Screen
|
<Drawer.Screen
|
||||||
name="terminal"
|
name="terminal"
|
||||||
options={{ title: "Terminal", headerShown: true }}
|
options={{ title: "Terminal", headerShown: media.sm }}
|
||||||
/>
|
/>
|
||||||
</Drawer>
|
</Drawer>
|
||||||
</GestureHandlerRootView>
|
</GestureHandlerRootView>
|
||||||
|
@ -4,6 +4,7 @@ import Ionicons from "@expo/vector-icons/Ionicons";
|
|||||||
import { ScrollView, Text, TextStyle, View } from "tamagui";
|
import { ScrollView, Text, TextStyle, View } from "tamagui";
|
||||||
import Pressable from "../ui/pressable";
|
import Pressable from "../ui/pressable";
|
||||||
import Icons from "../ui/icons";
|
import Icons from "../ui/icons";
|
||||||
|
import useThemeStore from "@/stores/theme";
|
||||||
|
|
||||||
const Keys = {
|
const Keys = {
|
||||||
ArrowLeft: "\x1b[D",
|
ArrowLeft: "\x1b[D",
|
||||||
@ -29,6 +30,7 @@ type TerminalProps = ComponentPropsWithoutRef<typeof View> & XTermJsProps;
|
|||||||
|
|
||||||
const Terminal = ({ client = "xtermjs", style, ...props }: TerminalProps) => {
|
const Terminal = ({ client = "xtermjs", style, ...props }: TerminalProps) => {
|
||||||
const xtermRef = React.useRef<XTermRef>(null);
|
const xtermRef = React.useRef<XTermRef>(null);
|
||||||
|
const theme = useThemeStore((i) => i.theme);
|
||||||
|
|
||||||
const send = (data: string) => {
|
const send = (data: string) => {
|
||||||
switch (client) {
|
switch (client) {
|
||||||
@ -45,6 +47,7 @@ const Terminal = ({ client = "xtermjs", style, ...props }: TerminalProps) => {
|
|||||||
ref={xtermRef}
|
ref={xtermRef}
|
||||||
dom={{ scrollEnabled: false }}
|
dom={{ scrollEnabled: false }}
|
||||||
wsUrl={props.url}
|
wsUrl={props.url}
|
||||||
|
colorScheme={theme}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
|
@ -18,10 +18,11 @@ type XTermJsProps = {
|
|||||||
dom?: DOMProps;
|
dom?: DOMProps;
|
||||||
style?: CSSProperties;
|
style?: CSSProperties;
|
||||||
wsUrl: string;
|
wsUrl: string;
|
||||||
|
colorScheme?: "light" | "dark";
|
||||||
};
|
};
|
||||||
|
|
||||||
// vscode-snazzy https://github.com/Tyriar/vscode-snazzy
|
// vscode-snazzy https://github.com/Tyriar/vscode-snazzy
|
||||||
const snazzyTheme = {
|
const darkTheme = {
|
||||||
foreground: "#eff0eb",
|
foreground: "#eff0eb",
|
||||||
background: "#282a36",
|
background: "#282a36",
|
||||||
selection: "#97979b33",
|
selection: "#97979b33",
|
||||||
@ -43,6 +44,28 @@ const snazzyTheme = {
|
|||||||
brightWhite: "#eff0eb",
|
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 {
|
export interface XTermRef extends DOMImperativeFactory {
|
||||||
send: (...args: JSONValue[]) => void;
|
send: (...args: JSONValue[]) => void;
|
||||||
}
|
}
|
||||||
@ -50,7 +73,9 @@ export interface XTermRef extends DOMImperativeFactory {
|
|||||||
const XTermJs = forwardRef<XTermRef, XTermJsProps>((props, ref) => {
|
const XTermJs = forwardRef<XTermRef, XTermJsProps>((props, ref) => {
|
||||||
const containerRef = useRef<HTMLDivElement | null>(null);
|
const containerRef = useRef<HTMLDivElement | null>(null);
|
||||||
const wsRef = useRef<WebSocket | 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(() => {
|
useEffect(() => {
|
||||||
const container = containerRef.current;
|
const container = containerRef.current;
|
||||||
@ -60,10 +85,11 @@ const XTermJs = forwardRef<XTermRef, XTermJsProps>((props, ref) => {
|
|||||||
|
|
||||||
const xterm = new XTerm({
|
const xterm = new XTerm({
|
||||||
fontFamily: '"Cascadia Code", Menlo, monospace',
|
fontFamily: '"Cascadia Code", Menlo, monospace',
|
||||||
theme: snazzyTheme,
|
theme: theme,
|
||||||
cursorBlink: true,
|
cursorBlink: true,
|
||||||
});
|
});
|
||||||
xterm.open(container);
|
xterm.open(container);
|
||||||
|
xtermRef.current = xterm;
|
||||||
|
|
||||||
const fitAddon = new FitAddon();
|
const fitAddon = new FitAddon();
|
||||||
xterm.loadAddon(fitAddon);
|
xterm.loadAddon(fitAddon);
|
||||||
@ -101,8 +127,6 @@ const XTermJs = forwardRef<XTermRef, XTermJsProps>((props, ref) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function onClose(e: CloseEvent) {
|
function onClose(e: CloseEvent) {
|
||||||
console.log("WS Closed", e.reason, e.code);
|
|
||||||
|
|
||||||
// Check if the close event was abnormal
|
// Check if the close event was abnormal
|
||||||
if (!e.wasClean) {
|
if (!e.wasClean) {
|
||||||
const reason = e.reason || `Code: ${e.code}`;
|
const reason = e.reason || `Code: ${e.code}`;
|
||||||
@ -129,6 +153,7 @@ const XTermJs = forwardRef<XTermRef, XTermJsProps>((props, ref) => {
|
|||||||
|
|
||||||
return () => {
|
return () => {
|
||||||
xterm.dispose();
|
xterm.dispose();
|
||||||
|
xtermRef.current = null;
|
||||||
wsRef.current = null;
|
wsRef.current = null;
|
||||||
containerRef.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 (
|
return (
|
||||||
<div
|
<div
|
||||||
ref={containerRef}
|
ref={containerRef}
|
||||||
style={{
|
style={{
|
||||||
background: snazzyTheme.background,
|
background: theme.background,
|
||||||
padding: 12,
|
padding: 12,
|
||||||
flex: !IS_DOM ? 1 : undefined,
|
flex: !IS_DOM ? 1 : undefined,
|
||||||
width: "100%",
|
width: "100%",
|
||||||
|
@ -19,13 +19,13 @@ const PagerView = ({
|
|||||||
|
|
||||||
const [onPageSelect, clearPageSelectDebounce] = useDebounceCallback(
|
const [onPageSelect, clearPageSelectDebounce] = useDebounceCallback(
|
||||||
(page) => onChangePage?.(page),
|
(page) => onChangePage?.(page),
|
||||||
100
|
300
|
||||||
);
|
);
|
||||||
|
|
||||||
const [setPage] = useDebounceCallback((page) => {
|
const [setPage] = useDebounceCallback((page) => {
|
||||||
ref.current?.setPage(page);
|
ref.current?.setPage(page);
|
||||||
clearPageSelectDebounce();
|
clearPageSelectDebounce();
|
||||||
}, 300);
|
}, 100);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (page != null) {
|
if (page != null) {
|
||||||
|
24
frontend/eas.json
Normal file
24
frontend/eas.json
Normal file
@ -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": {}
|
||||||
|
}
|
||||||
|
}
|
@ -10,7 +10,9 @@
|
|||||||
"ios": "expo start --ios",
|
"ios": "expo start --ios",
|
||||||
"web": "expo start --web",
|
"web": "expo start --web",
|
||||||
"test": "jest --watchAll",
|
"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": {
|
"jest": {
|
||||||
"preset": "jest-expo"
|
"preset": "jest-expo"
|
||||||
|
Loading…
x
Reference in New Issue
Block a user