feat: add drawer

This commit is contained in:
2024-11-12 04:43:59 +07:00
parent 38e81049a1
commit 8159b65605
10 changed files with 168 additions and 23 deletions
+88
View File
@@ -0,0 +1,88 @@
import React from "react";
import {
DrawerContentComponentProps,
DrawerContentScrollView,
} from "@react-navigation/drawer";
import { Button, View } from "tamagui";
import {
CommonActions,
DrawerActions,
useLinkBuilder,
} from "@react-navigation/native";
import { Link } from "expo-router";
import Icons from "../ui/icons";
import { logout } from "@/stores/auth";
const Drawer = (props: DrawerContentComponentProps) => {
return (
<>
<DrawerContentScrollView
contentContainerStyle={{ padding: 18 }}
{...props}
>
<DrawerItemList {...props} />
</DrawerContentScrollView>
<View p="$4">
<Button
justifyContent="flex-start"
icon={<Icons name="logout" size={16} />}
onPress={() => logout()}
>
Logout
</Button>
</View>
</>
);
};
const DrawerItemList = ({
state,
navigation,
descriptors,
}: DrawerContentComponentProps) => {
const { buildHref } = useLinkBuilder();
return state.routes.map((route, i) => {
const focused = i === state.index;
const onPress = () => {
const event = navigation.emit({
type: "drawerItemPress",
target: route.key,
canPreventDefault: true,
});
if (!event.defaultPrevented) {
navigation.dispatch({
...(focused
? DrawerActions.closeDrawer()
: CommonActions.navigate(route)),
target: state.key,
});
}
};
const { title, drawerLabel, drawerIcon } = descriptors[route.key].options;
return (
<Link key={route.key} href={buildHref(route.name, route.params) as never}>
<Button
w="100%"
justifyContent="flex-start"
bg={focused ? "$background" : "$colorTransparent"}
onPress={onPress}
icon={drawerIcon?.({ size: 16, color: "$color", focused }) as never}
>
{drawerLabel !== undefined
? drawerLabel
: title !== undefined
? title
: route.name}
</Button>
</Link>
);
}) as React.ReactNode as React.ReactElement;
};
export default Drawer;
@@ -1,8 +1,8 @@
import React from "react";
import Terminal from "./terminal";
import { BASE_WS_URL } from "@/lib/api";
import VNCViewer from "./vncviewer";
import { useAuthStore } from "@/stores/auth";
import { AppServer, useServer } from "@/stores/app";
type SSHSessionProps = {
type: "ssh";
@@ -30,8 +30,9 @@ export type InteractiveSessionProps = {
const InteractiveSession = ({ type, params }: InteractiveSessionProps) => {
const { token } = useAuthStore();
const server = useServer();
const query = new URLSearchParams({ ...params, sid: token || "" });
const url = `${BASE_WS_URL}/ws/term?${query}`;
const url = `${getBaseUrl(server)}/ws/term?${query}`;
switch (type) {
case "ssh":
@@ -50,4 +51,8 @@ const InteractiveSession = ({ type, params }: InteractiveSessionProps) => {
}
};
function getBaseUrl(server?: AppServer | null) {
return server?.url.replace("http://", "ws://") || "";
}
export default InteractiveSession;