feat: ixvd/hub integration
This commit is contained in:
parent
7c44053eae
commit
d692c61590
7 changed files with 177 additions and 16 deletions
|
@ -6,19 +6,26 @@
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
<title>IXVD - Home</title>
|
<title>IXVD - Home</title>
|
||||||
<link rel="stylesheet" href="/obj/css/main.css">
|
<link rel="stylesheet" href="/obj/css/main.css">
|
||||||
|
<script src="obj/js/updateLoop.js" defer></script>
|
||||||
<script src="obj/js/services.js" defer></script>
|
<script src="obj/js/services.js" defer></script>
|
||||||
|
<script src="obj/js/issues.js" defer></script>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<main>
|
<div id="issues" hidden>
|
||||||
<h1>IXVD</h1>
|
<h1>Maintenance / Issues</h1>
|
||||||
<p>Home of people that love software, games and developing!</p>
|
<hr>
|
||||||
<div id="services">
|
<div id="issues-holder"></div>
|
||||||
<h2>Services</h2>
|
</div>
|
||||||
<div id="service-holder">
|
<main>
|
||||||
Nothing (yet)!
|
<h1>IXVD</h1>
|
||||||
</div>
|
<p>Home of people that love software, games and developing!</p>
|
||||||
|
<div id="services">
|
||||||
|
<h2>Services</h2>
|
||||||
|
<div id="service-holder">
|
||||||
|
Nothing (yet)!
|
||||||
</div>
|
</div>
|
||||||
<br/>
|
</div>
|
||||||
</main>
|
<br/>
|
||||||
|
</main>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
|
@ -11,15 +11,19 @@ body {
|
||||||
padding: 0;
|
padding: 0;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
display: flex;
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
background-color: #f0f0f0;
|
background-color: #f0f0f0;
|
||||||
}
|
}
|
||||||
|
|
||||||
main {
|
body > * {
|
||||||
|
width: 50%;
|
||||||
padding: 1rem 2rem;
|
padding: 1rem 2rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
main {
|
||||||
border: 1px solid #ddd;
|
border: 1px solid #ddd;
|
||||||
border-radius: 4px;
|
|
||||||
background-color: #fff;
|
background-color: #fff;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -37,6 +41,62 @@ main {
|
||||||
text-align: right;
|
text-align: right;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#issues {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
background: #555555;
|
||||||
|
color: #fff;
|
||||||
|
transition: all .3s ease-in-out;
|
||||||
|
/*box-shadow: inset 0 -10px 10px rgba(0,0,0,.3);*/
|
||||||
|
}
|
||||||
|
|
||||||
|
#issues > * {
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#issues-holder {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
|
||||||
|
#issues-holder .issue {
|
||||||
|
display: grid;
|
||||||
|
grid-template-areas: "issue-details issue-data";
|
||||||
|
grid-template-columns: 8fr 2fr;
|
||||||
|
padding: 5px 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#issues-holder .issue + .issue {
|
||||||
|
border-top: 1px solid #777777;
|
||||||
|
}
|
||||||
|
|
||||||
|
#issues-holder .issue .issue-details {
|
||||||
|
grid-area: issue-details;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
|
||||||
|
#issues-holder .issue .issue-details .issue-title {
|
||||||
|
font-size: 1.2em;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
#issues-holder .issue .issue-data {
|
||||||
|
grid-area: issue-data;
|
||||||
|
display: grid;
|
||||||
|
align-content: start;
|
||||||
|
}
|
||||||
|
|
||||||
|
#issues-holder .issue .issue-data > span {
|
||||||
|
display: flex;
|
||||||
|
justify-content: right;
|
||||||
|
}
|
||||||
|
|
||||||
|
#issues-holder .issue .issue-data .issue-status {
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
a {
|
a {
|
||||||
color: #000;
|
color: #000;
|
||||||
transition: 0.5s all;
|
transition: 0.5s all;
|
||||||
|
@ -73,4 +133,8 @@ a:hover {
|
||||||
|
|
||||||
#links a {
|
#links a {
|
||||||
margin-bottom: 0.5rem;
|
margin-bottom: 0.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
[hidden] {
|
||||||
|
display: none !important;
|
||||||
}
|
}
|
62
public/obj/js/issues.js
Normal file
62
public/obj/js/issues.js
Normal file
|
@ -0,0 +1,62 @@
|
||||||
|
const issuesDiv = document.querySelector("#issues");
|
||||||
|
const issuesHolderDiv = document.querySelector("#issues-holder");
|
||||||
|
|
||||||
|
async function updateIssues() {
|
||||||
|
let fetchResult = await (await fetch('/relay/hub_issues')).json()
|
||||||
|
if (fetchResult.length > 0) {
|
||||||
|
issuesDiv.removeAttribute("hidden");
|
||||||
|
issuesHolderDiv.innerHTML = '';
|
||||||
|
fetchResult.forEach((issue) => {
|
||||||
|
let issueDiv = document.createElement("div");
|
||||||
|
issueDiv.classList.add("issue");
|
||||||
|
let detailsDiv = document.createElement("div");
|
||||||
|
detailsDiv.classList.add("issue-details");
|
||||||
|
issueDiv.append(detailsDiv);
|
||||||
|
|
||||||
|
let titleSpan = document.createElement("span");
|
||||||
|
titleSpan.classList.add("issue-title");
|
||||||
|
detailsDiv.append(titleSpan);
|
||||||
|
titleSpan.innerText = issue.title;
|
||||||
|
|
||||||
|
|
||||||
|
let descriptionSpan = document.createElement("span");
|
||||||
|
descriptionSpan.classList.add("issue-description");
|
||||||
|
detailsDiv.append(descriptionSpan);
|
||||||
|
let desc = () => {
|
||||||
|
let body = issue.body.replaceAll("\r", "").replaceAll("\n", " ");
|
||||||
|
if (body.length > 100) {
|
||||||
|
return body.slice(0, 100) + "..."
|
||||||
|
} else {
|
||||||
|
return body
|
||||||
|
}
|
||||||
|
};
|
||||||
|
descriptionSpan.innerText = desc();
|
||||||
|
|
||||||
|
let dataDiv = document.createElement("div");
|
||||||
|
dataDiv.classList.add("issue-data");
|
||||||
|
issueDiv.append(dataDiv);
|
||||||
|
|
||||||
|
let statusSpan = document.createElement("span");
|
||||||
|
statusSpan.classList.add("issue-status");
|
||||||
|
dataDiv.append(statusSpan);
|
||||||
|
statusSpan.innerText = issue.state;
|
||||||
|
switch (issue.state) {
|
||||||
|
case 'open':
|
||||||
|
statusSpan.style.color = "#ff8f8f";
|
||||||
|
break
|
||||||
|
case 'closed':
|
||||||
|
statusSpan.style.color = "#8fff91";
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
let timeSpan = document.createElement("span");
|
||||||
|
statusSpan.classList.add("issue-time");
|
||||||
|
dataDiv.append(timeSpan);
|
||||||
|
timeSpan.innerText = issue.updated_at;
|
||||||
|
|
||||||
|
issuesHolderDiv.append(issueDiv)
|
||||||
|
})
|
||||||
|
} else issuesDiv.setAttribute("hidden", "true");
|
||||||
|
}
|
||||||
|
|
||||||
|
window.updateLoop.push(updateIssues);
|
|
@ -6,9 +6,9 @@ const SERVICE_BLACKLIST = [
|
||||||
];
|
];
|
||||||
|
|
||||||
const serviceHolderDiv = document.querySelector('#service-holder');
|
const serviceHolderDiv = document.querySelector('#service-holder');
|
||||||
|
serviceHolderDiv.innerHTML = 'Loading...';
|
||||||
|
|
||||||
async function update() {
|
async function updateServices() {
|
||||||
serviceHolderDiv.innerHTML = 'Loading...';
|
|
||||||
let fetchResult = await (await fetch('/relay/gatus')).json()
|
let fetchResult = await (await fetch('/relay/gatus')).json()
|
||||||
serviceHolderDiv.innerHTML = '';
|
serviceHolderDiv.innerHTML = '';
|
||||||
|
|
||||||
|
@ -27,4 +27,4 @@ async function update() {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
update();
|
window.updateLoop.push(updateServices);
|
15
public/obj/js/updateLoop.js
Normal file
15
public/obj/js/updateLoop.js
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
window.updateLoop = [];
|
||||||
|
|
||||||
|
(() => {
|
||||||
|
let updLoop = setInterval(() => {
|
||||||
|
updateLoop.forEach(f => f());
|
||||||
|
}, 15000);
|
||||||
|
|
||||||
|
let everythingLoaded = setInterval(function() {
|
||||||
|
if (/loaded|complete/.test(document.readyState)) {
|
||||||
|
clearInterval(everythingLoaded);
|
||||||
|
updateLoop.forEach(f => f());
|
||||||
|
}
|
||||||
|
}, 10);
|
||||||
|
})();
|
||||||
|
|
|
@ -2,7 +2,6 @@ use std::env;
|
||||||
|
|
||||||
use actix_files as fs;
|
use actix_files as fs;
|
||||||
use actix_web::{App, HttpServer, middleware};
|
use actix_web::{App, HttpServer, middleware};
|
||||||
use actix_web::web::Redirect;
|
|
||||||
use env_logger;
|
use env_logger;
|
||||||
|
|
||||||
mod relay;
|
mod relay;
|
||||||
|
|
14
src/relay.rs
14
src/relay.rs
|
@ -14,9 +14,23 @@ pub async fn get_gatus_services() -> HttpResponse {
|
||||||
.body(status_response.text().await.unwrap())
|
.body(status_response.text().await.unwrap())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[get("/hub_issues")]
|
||||||
|
pub async fn get_hub_issues() -> HttpResponse {
|
||||||
|
let status_response = if let Ok(res) = reqwest::get("https://git.ixvd.net/api/v1/repos/ixvd/hub/issues?state=open").await {
|
||||||
|
res
|
||||||
|
} else {
|
||||||
|
return HttpResponse::build(StatusCode::INTERNAL_SERVER_ERROR)
|
||||||
|
.body("Failed to get status from forgejo");
|
||||||
|
};
|
||||||
|
|
||||||
|
HttpResponse::build(StatusCode::OK)
|
||||||
|
.body(status_response.text().await.unwrap())
|
||||||
|
}
|
||||||
|
|
||||||
pub fn configure(cfg: &mut web::ServiceConfig) {
|
pub fn configure(cfg: &mut web::ServiceConfig) {
|
||||||
cfg.service(
|
cfg.service(
|
||||||
web::scope("/relay")
|
web::scope("/relay")
|
||||||
.service(get_gatus_services)
|
.service(get_gatus_services)
|
||||||
|
.service(get_hub_issues)
|
||||||
);
|
);
|
||||||
}
|
}
|
Loading…
Reference in a new issue