refactor(web): consolidate routing and expose auth handler
- Add `*.log` to `.gitignore` to exclude log files from version control. - Change `auth_handler` to `pub` in `src/auth/mod.rs` to make the endpoint publicly accessible. - Remove unused `bot_index` import and route; replace direct service registration with `web_server::configure_app` in `src/main.rs`. - Refactor `src/web_server/mod.rs`: - Remove the `bot_index` handler. - Introduce `serve_html` helper for loading HTML pages. - Simplify static file serving by configuring separate routes for JS and CSS assets. - Centralize all route and static file configuration in `configure_app`. - Clean up related imports and improve error handling for missing pages.
This commit is contained in:
parent
737f934d68
commit
f9a1e3a8c0
7 changed files with 772 additions and 774 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
|
@ -1,3 +1,4 @@
|
||||||
|
*.log
|
||||||
target*
|
target*
|
||||||
.env
|
.env
|
||||||
*.env
|
*.env
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,7 @@ impl AuthService {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#[actix_web::get("/api/auth")]
|
#[actix_web::get("/api/auth")]
|
||||||
async fn auth_handler(
|
pub async fn auth_handler(
|
||||||
_req: HttpRequest,
|
_req: HttpRequest,
|
||||||
data: web::Data<AppState>,
|
data: web::Data<AppState>,
|
||||||
web::Query(params): web::Query<HashMap<String, String>>,
|
web::Query(params): web::Query<HashMap<String, String>>,
|
||||||
|
|
|
||||||
|
|
@ -46,7 +46,6 @@ use crate::session::{create_session, get_session_history, get_sessions, start_se
|
||||||
use crate::shared::state::AppState;
|
use crate::shared::state::AppState;
|
||||||
use crate::shared::utils::create_conn;
|
use crate::shared::utils::create_conn;
|
||||||
use crate::shared::utils::create_s3_operator;
|
use crate::shared::utils::create_s3_operator;
|
||||||
use crate::web_server::{bot_index};
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub enum BootstrapProgress {
|
pub enum BootstrapProgress {
|
||||||
StartingBootstrap,
|
StartingBootstrap,
|
||||||
|
|
@ -306,7 +305,6 @@ async fn main() -> std::io::Result<()> {
|
||||||
.wrap(Logger::default())
|
.wrap(Logger::default())
|
||||||
.wrap(Logger::new("HTTP REQUEST: %a %{User-Agent}i"))
|
.wrap(Logger::new("HTTP REQUEST: %a %{User-Agent}i"))
|
||||||
.app_data(web::Data::from(app_state_clone))
|
.app_data(web::Data::from(app_state_clone))
|
||||||
.configure(web_server::configure_app)
|
|
||||||
.service(auth_handler)
|
.service(auth_handler)
|
||||||
.service(create_session)
|
.service(create_session)
|
||||||
.service(get_session_history)
|
.service(get_session_history)
|
||||||
|
|
@ -332,7 +330,8 @@ async fn main() -> std::io::Result<()> {
|
||||||
.service(save_draft)
|
.service(save_draft)
|
||||||
.service(save_click);
|
.service(save_click);
|
||||||
}
|
}
|
||||||
app = app.service(bot_index);
|
app = app.configure(web_server::configure_app);
|
||||||
|
|
||||||
app
|
app
|
||||||
})
|
})
|
||||||
.workers(worker_count)
|
.workers(worker_count)
|
||||||
|
|
|
||||||
|
|
@ -14,15 +14,12 @@ async fn index() -> Result<HttpResponse> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[actix_web::get("/{botname}")]
|
async fn serve_html(path: &str) -> Result<HttpResponse> {
|
||||||
async fn bot_index(req: HttpRequest) -> Result<HttpResponse> {
|
match fs::read_to_string(format!("web/desktop/{}", path)) {
|
||||||
let botname = req.match_info().query("botname");
|
|
||||||
debug!("Serving bot interface for: {}", botname);
|
|
||||||
match fs::read_to_string("web/desktop/index.html") {
|
|
||||||
Ok(html) => Ok(HttpResponse::Ok().content_type("text/html").body(html)),
|
Ok(html) => Ok(HttpResponse::Ok().content_type("text/html").body(html)),
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
error!("Failed to load index page for bot {}: {}", botname, e);
|
error!("Failed to load page {}: {}", path, e);
|
||||||
Ok(HttpResponse::InternalServerError().body("Failed to load index page"))
|
Ok(HttpResponse::InternalServerError().body("Failed to load page"))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -30,16 +27,6 @@ async fn bot_index(req: HttpRequest) -> Result<HttpResponse> {
|
||||||
pub fn configure_app(cfg: &mut actix_web::web::ServiceConfig) {
|
pub fn configure_app(cfg: &mut actix_web::web::ServiceConfig) {
|
||||||
let static_path = Path::new("./web/desktop");
|
let static_path = Path::new("./web/desktop");
|
||||||
|
|
||||||
// Serve all static files from desktop directory
|
|
||||||
cfg.service(
|
|
||||||
Files::new("/", static_path)
|
|
||||||
.index_file("index.html")
|
|
||||||
.prefer_utf8(true)
|
|
||||||
.use_last_modified(true)
|
|
||||||
.use_etag(true)
|
|
||||||
.show_files_listing()
|
|
||||||
);
|
|
||||||
|
|
||||||
// Serve all JS files
|
// Serve all JS files
|
||||||
cfg.service(
|
cfg.service(
|
||||||
Files::new("/js", static_path.join("js"))
|
Files::new("/js", static_path.join("js"))
|
||||||
|
|
@ -48,17 +35,42 @@ pub fn configure_app(cfg: &mut actix_web::web::ServiceConfig) {
|
||||||
.use_etag(true)
|
.use_etag(true)
|
||||||
);
|
);
|
||||||
|
|
||||||
// Serve all component directories
|
// Serve CSS files
|
||||||
["drive", "tasks", "mail"].iter().for_each(|dir| {
|
cfg.service(
|
||||||
cfg.service(
|
Files::new("/css", static_path.join("css"))
|
||||||
Files::new(&format!("/{}", dir), static_path.join(dir))
|
.prefer_utf8(true)
|
||||||
.prefer_utf8(true)
|
.use_last_modified(true)
|
||||||
.use_last_modified(true)
|
.use_etag(true)
|
||||||
.use_etag(true)
|
);
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
// Serve index routes
|
cfg.service(
|
||||||
|
Files::new("/drive", static_path.join("drive"))
|
||||||
|
.prefer_utf8(true)
|
||||||
|
.use_last_modified(true)
|
||||||
|
.use_etag(true)
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
cfg.service(
|
||||||
|
Files::new("/chat", static_path.join("chat"))
|
||||||
|
.prefer_utf8(true)
|
||||||
|
.use_last_modified(true)
|
||||||
|
.use_etag(true)
|
||||||
|
);
|
||||||
|
|
||||||
|
cfg.service(
|
||||||
|
Files::new("/mail", static_path.join("mail"))
|
||||||
|
.prefer_utf8(true)
|
||||||
|
.use_last_modified(true)
|
||||||
|
.use_etag(true)
|
||||||
|
);
|
||||||
|
|
||||||
|
cfg.service(
|
||||||
|
Files::new("/tasks", static_path.join("tasks"))
|
||||||
|
.prefer_utf8(true)
|
||||||
|
.use_last_modified(true)
|
||||||
|
.use_etag(true)
|
||||||
|
);
|
||||||
cfg.service(index);
|
cfg.service(index);
|
||||||
cfg.service(bot_index);
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,111 +1,23 @@
|
||||||
<!doctype html>
|
|
||||||
<html lang="pt-br">
|
|
||||||
<head>
|
|
||||||
<meta charset="utf-8"/>
|
|
||||||
<title>General Bots Chat</title>
|
|
||||||
<meta name="viewport" content="width=device-width,initial-scale=1.0"/>
|
|
||||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/3.12.2/gsap.min.js"></script>
|
|
||||||
<script src="https://cdn.jsdelivr.net/npm/livekit-client/dist/livekit-client.umd.min.js"></script>
|
|
||||||
<script src="https://cdn.jsdelivr.net/npm/marked/marked.min.js"></script>
|
|
||||||
<link rel="stylesheet" href="chat.css">
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<div class="connection-status connecting" id="connectionStatus"></div>
|
|
||||||
<div class="flash-overlay" id="flashOverlay"></div>
|
|
||||||
<div class="float-menu">
|
|
||||||
<div class="float-logo" id="floatLogo" title="Menu"></div>
|
|
||||||
<div class="menu-button" id="themeBtn" title="Theme">⚙</div>
|
|
||||||
</div>
|
|
||||||
<div class="sidebar" id="sidebar">
|
|
||||||
<div class="sidebar-header">
|
|
||||||
<div class="sidebar-logo"></div>
|
|
||||||
<div class="sidebar-title" id="sidebarTitle">General Bots Chat</div>
|
|
||||||
</div>
|
|
||||||
<button class="sidebar-button" id="voiceToggle" onclick="toggleVoiceMode()">🎤 Voice Mode</button>
|
|
||||||
<div class="history-section">
|
|
||||||
<div class="history-title">History</div>
|
|
||||||
<div id="history"></div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- Chat layout analogous to Drive layout -->
|
|
||||||
<div class="chat-layout" x-data="chatApp()" x-cloak>
|
<div class="chat-layout" x-data="chatApp()" x-cloak>
|
||||||
<div class="panel chat-sidebar">
|
|
||||||
<div style="padding: 1rem; border-bottom: 1px solid #334155;">
|
|
||||||
<h3>General Bots Chat</h3>
|
|
||||||
</div>
|
|
||||||
<template x-for="item in navItems" :key="item.name">
|
|
||||||
<div class="nav-item"
|
|
||||||
:class="{ active: current === item.name }"
|
|
||||||
@click="current = item.name">
|
|
||||||
<span x-text="item.icon"></span>
|
|
||||||
<span x-text="item.name"></span>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="panel chat-main">
|
<div id="connectionStatus" class="connection-status disconnected"></div>
|
||||||
<div style="padding: 1rem; border-bottom: 1px solid #334155;">
|
<main id="messages"></main>
|
||||||
<h2 x-text="current"></h2>
|
|
||||||
<input type="text" x-model="search" placeholder="Search chats..."
|
|
||||||
style="width: 100%; margin-top: 0.5rem; padding: 0.5rem; background: #0f172a; border: 1px solid #334155; border-radius: 0.375rem; color: #e2e8f0;">
|
|
||||||
</div>
|
|
||||||
<div class="chat-list">
|
|
||||||
<template x-for="chat in filteredChats" :key="chat.id">
|
|
||||||
<div class="chat-item"
|
|
||||||
:class="{ selected: selectedChat?.id === chat.id }"
|
|
||||||
@click="selectedChat = chat">
|
|
||||||
<span class="chat-icon" x-text="chat.icon"></span>
|
|
||||||
<div style="flex: 1;">
|
|
||||||
<div style="font-weight: 600;" x-text="chat.name"></div>
|
|
||||||
<div class="text-xs text-gray" x-text="chat.lastMessage"></div>
|
|
||||||
</div>
|
|
||||||
<div class="text-sm text-gray" x-text="chat.time"></div>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="panel chat-details">
|
<footer>
|
||||||
<template x-if="selectedChat">
|
<div class="suggestions-container" id="suggestions"></div>
|
||||||
<div style="padding: 2rem;">
|
<div class="input-container">
|
||||||
<div style="text-align: center; margin-bottom: 2rem;">
|
<input id="messageInput" type="text" placeholder="Message..." autofocus />
|
||||||
<div style="font-size: 4rem; margin-bottom: 1rem;" x-text="selectedChat.icon"></div>
|
<button id="voiceBtn" title="Voice">🎤</button>
|
||||||
<h3 x-text="selectedChat.name"></h3>
|
<button id="sendBtn" title="Send">↑</button>
|
||||||
<p class="text-sm text-gray" x-text="selectedChat.status"></p>
|
|
||||||
</div>
|
</div>
|
||||||
<div style="margin-bottom: 1rem;">
|
</footer>
|
||||||
<div class="text-sm" style="margin-bottom: 0.5rem;">Last Message</div>
|
<button class="scroll-to-bottom" id="scrollToBottom">↓</button>
|
||||||
<div class="text-gray" x-text="selectedChat.lastMessage"></div>
|
<div class="context-indicator" id="contextIndicator">
|
||||||
|
<div>Context</div>
|
||||||
|
<div id="contextPercentage">0%</div>
|
||||||
|
<div class="context-progress">
|
||||||
|
<div class="context-progress-bar" id="contextProgressBar" style="width:0%"></div>
|
||||||
</div>
|
</div>
|
||||||
<div style="margin-bottom: 1rem;">
|
</div>
|
||||||
<div class="text-sm" style="margin-bottom: 0.5rem;">Time</div>
|
|
||||||
<div class="text-gray" x-text="selectedChat.time"></div>
|
|
||||||
</div>
|
|
||||||
<div style="display: flex; gap: 0.5rem; margin-top: 2rem;">
|
|
||||||
<button style="flex: 1; padding: 0.75rem; background: #3b82f6; color: white; border: none; border-radius: 0.375rem; cursor: pointer;">Reply</button>
|
|
||||||
<button style="flex: 1; padding: 0.75rem; background: #10b981; color: white; border: none; border-radius: 0.375rem; cursor: pointer;">Close</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
<template x-if="!selectedChat">
|
|
||||||
<div style="padding: 2rem; text-align: center; color: #64748b;">
|
|
||||||
<div style="font-size: 4rem; margin-bottom: 1rem;">💬</div>
|
|
||||||
<p>Select a chat to view details</p>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<footer>
|
|
||||||
<div class="suggestions-container" id="suggestions"></div>
|
|
||||||
<div class="input-container">
|
|
||||||
<input id="messageInput" type="text" placeholder="Message..." autofocus/>
|
|
||||||
<button id="voiceBtn" title="Voice">🎤</button>
|
|
||||||
<button id="sendBtn" title="Send">↑</button>
|
|
||||||
</div>
|
|
||||||
</footer>
|
|
||||||
|
|
||||||
<script src="chat.js"></script>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
|
|
|
||||||
File diff suppressed because it is too large
Load diff
|
|
@ -1,42 +1,43 @@
|
||||||
<!doctype html>
|
<!doctype html>
|
||||||
<html lang="en">
|
<html lang="en">
|
||||||
|
|
||||||
<head>
|
<head>
|
||||||
<meta charset="utf-8" />
|
<meta charset="utf-8" />
|
||||||
<title>General Bots Desktop</title>
|
<title>General Bots</title>
|
||||||
<meta name="viewport" content="width=device-width,initial-scale=1.0" />
|
<meta name="viewport" content="width=device-width,initial-scale=1.0" />
|
||||||
<link rel="stylesheet" href="css/app.css" />
|
<link rel="stylesheet" href="css/app.css" />
|
||||||
<script defer src="js/alpine.js"></script>
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/3.12.2/gsap.min.js"></script>
|
||||||
|
<script src="https://cdn.jsdelivr.net/npm/livekit-client/dist/livekit-client.umd.min.js"></script>
|
||||||
|
<script src="https://cdn.jsdelivr.net/npm/marked/marked.min.js"></script>
|
||||||
|
|
||||||
|
<script defer src="js/alpine.js"></script>
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body>
|
<body>
|
||||||
<nav x-data="{ current: 'drive' }">
|
<nav x-data="{ current: 'drive' }">
|
||||||
<div class="logo">⚡ General Bots</div>
|
<div class="logo">⚡ General Bots</div>
|
||||||
<a href="#chat" @click.prevent="current = 'chat'; window.switchSection('chat')"
|
<a href="#chat" @click.prevent="current = 'chat'; window.switchSection('chat')"
|
||||||
:class="{ active: current === 'chat' }">💬 Chat</a>
|
:class="{ active: current === 'chat' }">💬 Chat</a>
|
||||||
|
|
||||||
<a href="#drive" @click.prevent="current = 'drive'; window.switchSection('drive')"
|
<a href="#drive" @click.prevent="current = 'drive'; window.switchSection('drive')"
|
||||||
:class="{ active: current === 'drive' }">📁 Drive</a>
|
:class="{ active: current === 'drive' }">📁 Drive</a>
|
||||||
<a href="#tasks" @click.prevent="current = 'tasks'; window.switchSection('tasks')"
|
<a href="#tasks" @click.prevent="current = 'tasks'; window.switchSection('tasks')"
|
||||||
:class="{ active: current === 'tasks' }">✓ Tasks</a>
|
:class="{ active: current === 'tasks' }">✓ Tasks</a>
|
||||||
<a href="#mail" @click.prevent="current = 'mail'; window.switchSection('mail')"
|
<a href="#mail" @click.prevent="current = 'mail'; window.switchSection('mail')"
|
||||||
:class="{ active: current === 'mail' }">✉ Mail</a>
|
:class="{ active: current === 'mail' }">✉ Mail</a>
|
||||||
</nav>
|
</nav>
|
||||||
|
|
||||||
<div id="main-content">
|
<div id="main-content">
|
||||||
<!-- Sections will be loaded dynamically -->
|
<!-- Sections will be loaded dynamically -->
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Load Module Scripts -->
|
<!-- Load Module Scripts -->
|
||||||
<script src="js/layout.js"></script>
|
<script src="js/layout.js"></script>
|
||||||
<script src="drive/drive.js"></script>
|
<script src="chat/chat.js"></script>
|
||||||
<script src="tasks/tasks.js"></script>
|
<script src="drive/drive.js"></script>
|
||||||
<script src="mail/mail.js"></script>
|
<script src="tasks/tasks.js"></script>
|
||||||
<script src="dashboard/dashboard.js"></script>
|
<script src="mail/mail.js"></script>
|
||||||
<script src="editor/editor.js"></script>
|
|
||||||
<script src="player/player.js"></script>
|
|
||||||
<script src="paper/paper.js"></script>
|
|
||||||
<script src="settings/settings.js"></script>
|
|
||||||
<script src="tables/tables.js"></script>
|
|
||||||
<script src="news/news.js"></script>
|
|
||||||
|
|
||||||
</body>
|
</body>
|
||||||
|
|
||||||
</html>
|
</html>
|
||||||
Loading…
Add table
Reference in a new issue