Skip to content

Commit 6fd6aec

Browse files
committed
feat: embed default web redict to git repo
1 parent b4413c5 commit 6fd6aec

3 files changed

Lines changed: 206 additions & 0 deletions

File tree

core/public/public.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,3 +9,6 @@ import (
99
var dist embed.FS
1010

1111
var Public, _ = fs.Sub(dist, "dist")
12+
13+
//go:embed all:templates
14+
var Templates embed.FS

core/public/templates/index.tmpl

Lines changed: 193 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,193 @@
1+
<!DOCTYPE html>
2+
<html lang="en">
3+
<head>
4+
<title>AIProxy</title>
5+
<meta charset="UTF-8" />
6+
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
7+
<style>
8+
* {
9+
box-sizing: border-box;
10+
}
11+
12+
body {
13+
font-family: "Segoe UI", Tahoma, Geneva, Verdana, sans-serif;
14+
text-align: center;
15+
margin: 0;
16+
padding: 20px;
17+
min-height: 100vh;
18+
display: flex;
19+
align-items: center;
20+
justify-content: center;
21+
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
22+
}
23+
24+
.container {
25+
background: white;
26+
padding: 40px;
27+
border-radius: 15px;
28+
box-shadow: 0 10px 30px rgba(0, 0, 0, 0.2);
29+
max-width: 500px;
30+
width: 100%;
31+
animation: fadeIn 0.5s ease-in;
32+
}
33+
34+
@keyframes fadeIn {
35+
from {
36+
opacity: 0;
37+
transform: translateY(20px);
38+
}
39+
to {
40+
opacity: 1;
41+
transform: translateY(0);
42+
}
43+
}
44+
45+
h1 {
46+
color: #333;
47+
margin-bottom: 20px;
48+
font-size: 2rem;
49+
}
50+
51+
.status-icon {
52+
font-size: 3rem;
53+
color: #28a745;
54+
margin-bottom: 20px;
55+
}
56+
57+
.countdown {
58+
font-size: 2rem;
59+
font-weight: bold;
60+
color: #007bff;
61+
margin: 20px 0;
62+
padding: 10px;
63+
background: #f8f9fa;
64+
border-radius: 8px;
65+
transition: all 0.3s ease;
66+
}
67+
68+
.countdown.warning {
69+
color: #dc3545;
70+
background: #fff5f5;
71+
}
72+
73+
.redirect-info {
74+
margin: 20px 0;
75+
color: #666;
76+
}
77+
78+
.btn {
79+
display: inline-block;
80+
padding: 12px 24px;
81+
background: #007bff;
82+
color: white;
83+
text-decoration: none;
84+
border-radius: 25px;
85+
transition: all 0.3s ease;
86+
margin: 10px;
87+
font-weight: 500;
88+
}
89+
90+
.btn:hover {
91+
background: #0056b3;
92+
transform: translateY(-2px);
93+
box-shadow: 0 5px 15px rgba(0, 123, 255, 0.3);
94+
}
95+
96+
.btn-secondary {
97+
background: #6c757d;
98+
}
99+
100+
.btn-secondary:hover {
101+
background: #545b62;
102+
}
103+
104+
.progress-bar {
105+
width: 100%;
106+
height: 4px;
107+
background: #e9ecef;
108+
border-radius: 2px;
109+
margin: 20px 0;
110+
overflow: hidden;
111+
}
112+
113+
.progress-fill {
114+
height: 100%;
115+
background: linear-gradient(90deg, #007bff, #0056b3);
116+
border-radius: 2px;
117+
transition: width 1s linear;
118+
}
119+
120+
@media (max-width: 480px) {
121+
.container {
122+
padding: 20px;
123+
margin: 10px;
124+
}
125+
126+
h1 {
127+
font-size: 1.5rem;
128+
}
129+
130+
.countdown {
131+
font-size: 1.5rem;
132+
}
133+
}
134+
</style>
135+
</head>
136+
<body>
137+
<div class="container">
138+
<div class="status-icon">✅</div>
139+
<h1>AIProxy is Running!</h1>
140+
141+
<div class="redirect-info">
142+
<p>Redirecting to:</p>
143+
<a href="{{.URL}}" class="url-display" target="_self">{{.URL}}</a>
144+
</div>
145+
146+
<div class="countdown" id="countdown">{{.INITIAL_COUNTDOWN}}</div>
147+
<div class="progress-bar">
148+
<div class="progress-fill" id="progressBar"></div>
149+
</div>
150+
151+
<div>
152+
<a href="{{.URL}}" class="btn" target="_self">Go Now</a>
153+
</div>
154+
</div>
155+
156+
<script>
157+
const INITIAL_COUNTDOWN = {{.INITIAL_COUNTDOWN}};
158+
159+
let countdown = INITIAL_COUNTDOWN;
160+
let isActive = true;
161+
162+
const countdownElement = document.getElementById("countdown");
163+
const progressBar = document.getElementById("progressBar");
164+
const cancelBtn = document.getElementById("cancelBtn");
165+
166+
progressBar.style.width = "100%";
167+
168+
const timer = setInterval(() => {
169+
if (!isActive) return;
170+
171+
countdown--;
172+
countdownElement.textContent = countdown;
173+
174+
const progress = (countdown / INITIAL_COUNTDOWN) * 100;
175+
progressBar.style.width = progress + "%";
176+
177+
if (countdown <= 3) {
178+
countdownElement.classList.add("warning");
179+
}
180+
181+
if (countdown <= 0) {
182+
clearInterval(timer);
183+
countdownElement.textContent = "Redirecting...";
184+
progressBar.style.width = "0%";
185+
186+
setTimeout(() => {
187+
window.location.href = "{{.URL}}";
188+
}, 500);
189+
}
190+
}, 1000);
191+
</script>
192+
</body>
193+
</html>

core/router/static.go

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package router
22

33
import (
4+
"html/template"
45
"io/fs"
56
"net/http"
67
"net/url"
@@ -15,9 +16,18 @@ import (
1516
)
1617

1718
func SetStaticFileRouter(router *gin.Engine) {
19+
router.SetHTMLTemplate(template.Must(template.New("").Funcs(router.FuncMap).ParseFS(public.Templates, "templates/*")))
20+
1821
if config.DisableWeb {
22+
router.GET("/", func(ctx *gin.Context) {
23+
ctx.HTML(http.StatusOK, "index.tmpl", gin.H{
24+
"URL": "https://github.com/labring/aiproxy",
25+
"INITIAL_COUNTDOWN": 15,
26+
})
27+
})
1928
return
2029
}
30+
2131
if config.WebPath == "" {
2232
err := initFSRouter(router, public.Public.(fs.ReadDirFS), ".")
2333
if err != nil {

0 commit comments

Comments
 (0)