Compare commits

...

4 Commits

Author SHA1 Message Date
Kevin Yue
4191e9a19f feat: support drag and remove title bar on KDE 2023-06-25 13:46:35 +08:00
Kevin Yue
5bc3da99ac doc: improve doc 2023-06-25 09:32:10 +08:00
Kevin Yue
e8db014336 refactor: refine the error message 2023-06-25 09:30:13 +08:00
Kevin Yue
e5fd2ba280 doc: update the dev doc 2023-06-25 01:26:25 +08:00
12 changed files with 68 additions and 18 deletions

View File

@ -6,6 +6,7 @@
"clientgpversion",
"clientos",
"gpcommon",
"gpgui",
"gpservice",
"Immer",
"jnlp",

View File

@ -1,9 +1,29 @@
## Development
### Build the service
```sh
# Build the client first
cargo build -p gpclient
# Build the service
cargo build -p gpservice
```
### Start the service
```sh
sudo ./target/debug/gpservice
```
### Start the GUI
```
```sh
cd gpgui
pnpm install
pnpm tauri dev
```
### Open the DevTools
Right-click on the GUI window and select "Inspect Element".

View File

@ -3,10 +3,15 @@
<head>
<meta charset="UTF-8" />
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=0" />
<title>Vite + React + TS</title>
</head>
<body>
<body data-tauri-drag-region>
<script>
var htmlFontSize = getComputedStyle(document.documentElement).fontSize;
var ratio = parseInt(htmlFontSize) / 16;
document.documentElement.style.fontSize = (16 / ratio) + 'px';
</script>
<div id="root"></div>
<script type="module" src="/src/main.tsx"></script>
</body>

View File

@ -44,6 +44,18 @@ fn setup(app: &mut tauri::App) -> Result<(), Box<dyn std::error::Error>> {
});
app.manage(client);
match std::env::var("XDG_CURRENT_DESKTOP") {
Ok(desktop) => {
if desktop == "KDE" {
if let Some(main_window) = app.get_window("main") {
let _ = main_window.set_decorations(false);
}
}
}
Err(_) => (),
}
Ok(())
}

View File

@ -68,11 +68,13 @@
},
"windows": [
{
"title": "GlobalProtect",
"label": "main",
"fullscreen": false,
"width": 260,
"height": 360,
"resizable": false,
"title": "GlobalProtect",
"width": 260
"fileDropEnabled": false
}
]
}

View File

@ -41,7 +41,7 @@ export default function App() {
const ready = useAtomValue(statusReadyAtom);
return (
<Box padding={2} paddingBottom={0}>
<Box data-tauri-drag-region padding={2} paddingBottom={0}>
{ready ? <MainContent /> : <Loading />}
<Notification />
</Box>

View File

@ -93,11 +93,17 @@ function InnerStatusIcon() {
return <DisconnectedIcon />;
}
const DragRegion = styled(Box)(({ theme }) => ({
position: "absolute",
inset: 0,
}));
export default function StatusIcon() {
return (
<IconContainer>
<BackgroundIcon />
<InnerStatusIcon />
<DragRegion data-tauri-drag-region />
</IconContainer>
);
}

View File

@ -7,6 +7,7 @@ export default function StatusText() {
return (
<Typography
data-tauri-drag-region
textAlign="center"
mt={1.5}
variant="subtitle1"

View File

@ -4,7 +4,7 @@ import StatusText from "./StatusText";
export default function ConnectionStatus() {
return (
<Box>
<Box data-tauri-drag-region>
<StatusIcon />
<StatusText />
</Box>

View File

@ -1,4 +1,4 @@
import { Alert, AlertTitle, Slide, SlideProps, Snackbar } from "@mui/material";
import { Alert, AlertTitle, Box, Slide, SlideProps, Snackbar } from "@mui/material";
import { useAtom, useAtomValue } from "jotai";
import {
closeNotificationAtom,
@ -35,6 +35,7 @@ export default function Notification() {
}}
>
<Alert
data-tauri-drag-region
severity={severity}
icon={false}
sx={{
@ -42,8 +43,8 @@ export default function Notification() {
borderRadius: 0,
}}
>
{title && <AlertTitle>{title}</AlertTitle>}
{message}
{title && <AlertTitle data-tauri-drag-region>{title}</AlertTitle>}
{message && <Box data-tauri-drag-region>{message}</Box>}
</Alert>
</Snackbar>
);

View File

@ -45,7 +45,7 @@ class GatewayService {
});
if (!response.ok) {
throw new Error("Login failed");
throw new Error(`Gateway login failed: ${response.status}`);
}
return this.parseLoginResponse(response.data);

View File

@ -36,8 +36,9 @@ export type PortalCredential = {
class PortalService {
async prelogin(portal: string): Promise<Prelogin> {
const preloginUrl = `https://${portal}/global-protect/prelogin.esp`;
let response;
try {
const response = await fetch<string>(preloginUrl, {
response = await fetch<string>(preloginUrl, {
method: "POST",
headers: {
"User-Agent": "PAN GlobalProtect",
@ -57,14 +58,15 @@ class PortalService {
// "host-id": "TODO, mac address?",
}),
});
} catch (err) {
console.error("Failed to prelogin: Network error", err);
throw new Error("Failed to prelogin: Network error");
}
if (!response.ok) {
throw new Error(`Failed to prelogin: ${response.status}`);
}
return this.parsePrelogin(response.data);
} catch (err) {
throw new Error(`Failed to prelogin: Network error`);
}
}
private parsePrelogin(response: string): Prelogin {