mirror of
https://github.com/khairul169/vaulterm.git
synced 2026-09-15 17:03:30 +07:00
feat: add drawer
This commit is contained in:
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user