Skip to content

Commit

Permalink
update
Browse files Browse the repository at this point in the history
  • Loading branch information
lerte committed Apr 11, 2024
1 parent 47966c1 commit 4bec1a0
Show file tree
Hide file tree
Showing 14 changed files with 1,628 additions and 205 deletions.
83 changes: 51 additions & 32 deletions app.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,16 @@ import (

"github.com/gofiber/fiber/v2/log"
"github.com/wailsapp/wails/v2/pkg/runtime"
"mvdan.cc/xurls/v2"
)

// App struct
type App struct {
ctx context.Context
}

var zrokCommand = "./resources/zrok.exe"


// NewApp creates a new App application struct
func NewApp() *App {
Expand Down Expand Up @@ -54,16 +57,6 @@ func (a *App) ChooseFolder() (string, error) {
return folder,nil
}

func (a *App) Invite(email string) string {
requestBody := []byte(fmt.Sprintf(`{"email": "%s"}`, email))
resp, err := http.Post("https://api.zrok.io/api/v1/invite", "application/zrok.v1+json", bytes.NewBuffer(requestBody))
if err != nil {
log.Error("发送请求时出错:", err)
}
defer resp.Body.Close()
return resp.Status
}

func writeToFile(name string, data string) error {
f, err := os.OpenFile(name, os.O_CREATE | os.O_APPEND | os.O_WRONLY, 0644)
if err != nil {
Expand All @@ -77,34 +70,60 @@ func writeToFile(name string, data string) error {
return nil
}

func (a *App) Invite(email string) string {
cmd := exec.Command(zrokCommand, "status")
cmd.SysProcAttr = &syscall.SysProcAttr{HideWindow: true}
output, _ := cmd.Output()
xurlsStrict := xurls.Strict()
find := xurlsStrict.FindAllString(string(output), -1)
apiEndpoint := find[0]

requestBody := []byte(fmt.Sprintf(`{"email": "%s"}`, email))
resp, err := http.Post(apiEndpoint+"/api/v1/invite", "application/zrok.v1+json", bytes.NewBuffer(requestBody))
if err != nil {
log.Error("发送请求时出错:", err)
}
defer resp.Body.Close()
return resp.Status
}

func (a *App) Version() string {
cmd := exec.Command(zrokCommand, "version")
cmd.SysProcAttr = &syscall.SysProcAttr{HideWindow: true}
output, _ := cmd.Output()
return string(output)
}

func (a *App) Overview() string {
cmd := exec.Command(zrokCommand, "overview")
cmd.SysProcAttr = &syscall.SysProcAttr{HideWindow: true}
output, _ := cmd.Output()
return string(output)
}

// Zrok
func (a *App) Zrok(args []string) string {
log.Info("Zrok", args)
writeToFile("./resources/logs.txt", strings.Join(args, " "))
zrokCommand := "./resources/zrok.exe"
command := args[0]
if command == "enable" {
cmd := exec.Command(zrokCommand, args...)
cmd.SysProcAttr = &syscall.SysProcAttr{HideWindow: true}
// 创建一个缓冲区来保存标准错误输出
var stderr bytes.Buffer
cmd.Stderr = &stderr
// 执行命令
err := cmd.Run()
if err != nil {
// 如果命令执行出错,则打印标准错误输出
fmt.Println("执行命令时出错:", err)
fmt.Println("标准错误输出:", stderr.String())
return stderr.String()
}

// 如果命令执行成功,则打印标准错误输出
fmt.Println("标准错误输出:", stderr.String())
}

cmd := exec.Command(zrokCommand, args...)
cmd.SysProcAttr = &syscall.SysProcAttr{HideWindow: true}
output, _ := cmd.Output()
return string(output)
// 创建一个缓冲区来保存标准错误输出
var stdout bytes.Buffer
var stderr bytes.Buffer
cmd.Stdout = &stdout
cmd.Stderr = &stderr
// 执行命令
err := cmd.Run()
if err != nil {
// 如果命令执行出错,则打印标准错误输出
log.Error("执行命令时出错:", err)
log.Error("标准错误输出:", stderr.String())
return stderr.String()
}
// 如果命令执行成功,则打印标准输出

log.Info("标准输出:", stdout.String())
return stdout.String()
}

23 changes: 23 additions & 0 deletions apps/frontend/hooks/useAutoDark.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import { useState, useEffect } from "react";

type Theme = "inherit" | "light" | "dark";

export const useAutoDark = () => {
const [theme, setTheme] = useState<Theme>("dark");
const handleThemeChange = (system: MediaQueryList) => {
if (system.matches) {
setTheme("dark");
} else {
setTheme("light");
}
};
const system = window.matchMedia("(prefers-color-scheme: dark)");
useEffect(() => {
handleThemeChange(system);
system.addEventListener("change", () => handleThemeChange(system));
return () => {
system.removeEventListener("change", () => handleThemeChange(system));
};
}, []);
return [theme, setTheme] as const;
};
7 changes: 3 additions & 4 deletions apps/frontend/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,11 @@
"preview": "vite preview"
},
"dependencies": {
"@chakra-ui/react": "^2.8.2",
"@emotion/react": "^11.11.4",
"@emotion/styled": "^11.11.5",
"framer-motion": "^11.0.25",
"@radix-ui/themes": "^3.0.2",
"lucide-react": "^0.367.0",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-hot-toast": "^2.4.1",
"react-router-dom": "^6.22.3"
},
"devDependencies": {
Expand Down
24 changes: 24 additions & 0 deletions apps/frontend/src/App.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import router from "./router";
import { Toaster } from "react-hot-toast";
import { RouterProvider } from "react-router-dom";
import { Theme, ThemePanel } from "@radix-ui/themes";
import { useAutoDark } from "./../hooks/useAutoDark";

const App = () => {
const [theme] = useAutoDark();
return (
<Theme
scaling="95%"
radius="large"
grayColor="sand"
appearance={theme}
accentColor="crimson"
>
<RouterProvider router={router} />
<Toaster />
<ThemePanel />
</Theme>
);
};

export default App;
122 changes: 83 additions & 39 deletions apps/frontend/src/Home.tsx
Original file line number Diff line number Diff line change
@@ -1,70 +1,89 @@
import { useState } from "react";
import { Invite, Zrok } from "./../wailsjs/go/main/App";
import { Input, Button, useToast } from "@chakra-ui/react";
import { Share, Environment } from "./../types/zrok";
import toast from "react-hot-toast";
import { Button, TextField } from "@radix-ui/themes";
import {
Zrok,
Invite,
Version,
Overview,
} from "../../../frontend/wailsjs/go/main/App";

function Home() {
const toast = useToast();
const [email, setEmail] = useState("");
const [command, setCommand] = useState("");
const [loading, setLoading] = useState(false);

const handleInvite = async () => {
const result = await Invite(email);
const [statusCode, ...statusText] = result.split(" ");

if (statusCode == "201") {
toast({
title: "Invited",
description: "Invite sent to " + email,
status: "success",
duration: 3000,
isClosable: true,
});
toast.success("Invite sent to " + email);
} else {
toast({
title: "Result",
description: statusText.join(" "),
status: "error",
duration: 3000,
isClosable: true,
});
toast.error(statusText.join(" "));
}
};

const handleEnable = async () => {
setLoading(true);
const commands = command.split(" ").filter((item) => item != "");
commands.shift();
const result = await Zrok(commands);
if (/^\[ERROR\]/.test(result)) {
toast({
title: "Error",
description: result,
status: "error",
duration: 3000,
isClosable: true,
});
toast.error(result);
}
if (/successfully/.test(result)) {
toast.success("the zrok environment was successfully enabled...");
}
setLoading(false);
};

const handleSharing = async () => {
setLoading(true);
const commands = command.split(" ").filter((item) => item != "");
commands.shift();
Zrok(commands);
setInterval(() => {
getOverview();
}, 2000);
};

const getVersion = async () => {
const version = await Zrok(["version"]);
toast({
title: "Version",
description: version.slice(-20),
status: "success",
duration: 3000,
isClosable: true,
});
const version = await Version();
toast.success("Version: " + version.slice(-20));
};

type Environments = {
environment: Environment[];
shares?: Share[];
};
const getOverview = async () => {
const overview = await Overview();
const { environments }: { environments: Environments[] } =
JSON.parse(overview);

console.info(environments);
const index = environments.findIndex((environment) =>
environment.shares?.filter(
(share) => share.backendProxyEndpoint == "http://localhost:300"
)
);
if (index > -1) {
setLoading(false);
}
};

return (
<div className="flex flex-col gap-2 p-8">
<div className="flex gap-4 w-full">
<Input
<TextField.Root
placeholder="Email"
value={email}
onChange={(e) => setEmail(e.target.value)}
/>
></TextField.Root>
<Button
colorScheme="green"
color="lime"
onClick={handleInvite}
>
Zrok Invite
Expand All @@ -73,20 +92,45 @@ function Home() {

<h2>Enable your zrok account</h2>
<div className="flex gap-4 w-full">
<Input
<TextField.Root
placeholder="Enable your zrok account"
value={command}
onChange={(e) => setCommand(e.target.value)}
/>
></TextField.Root>
<Button
colorScheme="red"
color="blue"
loading={loading}
onClick={handleEnable}
>
Enable
</Button>
</div>

<h2>Sharing</h2>
<div className="flex gap-4 w-full">
<TextField.Root
placeholder="Sharing"
value={command}
onChange={(e) => setCommand(e.target.value)}
></TextField.Root>
<Button
color="red"
loading={loading}
onClick={handleSharing}
>
Sharing
</Button>
</div>

<Button
color="purple"
onClick={getOverview}
>
getOverview
</Button>

<Button
colorScheme="blue"
color="blue"
onClick={getVersion}
>
获取版本号
Expand Down
9 changes: 3 additions & 6 deletions apps/frontend/src/main.tsx
Original file line number Diff line number Diff line change
@@ -1,15 +1,12 @@
import "./style.css";
import App from "./App";
import React from "react";
import router from "./router";
import "@radix-ui/themes/styles.css";
import { createRoot } from "react-dom/client";
import { ChakraProvider } from "@chakra-ui/react";
import { RouterProvider } from "react-router-dom";

const root = createRoot(document.getElementById("root")!);
root.render(
<React.StrictMode>
<ChakraProvider>
<RouterProvider router={router} />
</ChakraProvider>
<App />
</React.StrictMode>
);
20 changes: 20 additions & 0 deletions apps/frontend/types/zrok.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
export type Environment = {
address: string;
createdAt: number;
description: string;
host: string;
updatedAt: number;
zId: string;
};

export type Share = {
backendMode: "proxy" | "web" | "caddy" | "drive";
backendProxyEndpoint: string;
createdAt: number;
frontendEndpoint: string;
frontendSelection: "public" | "private";
shareMode: "public" | "private";
token: string;
updatedAt: number;
zId: string;
};
Loading

0 comments on commit 4bec1a0

Please sign in to comment.