mirror of
https://codeberg.org/demostf/frontend.git
synced 2026-06-03 10:14:13 +02:00
prepare for private demos
This commit is contained in:
parent
0c7e51f94b
commit
ffb230045c
6 changed files with 58 additions and 14 deletions
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"db_name": "PostgreSQL",
|
"db_name": "PostgreSQL",
|
||||||
"query": "SELECT\n demos.id, demos.name, url, map, red, blu, uploader, duration, demos.created_at,\n \"scoreRed\" as score_red, \"scoreBlue\" as score_blue, server, nick,\n \"playerCount\" as player_count,\n users_named.name as uploader_name_preferred,\n users.steamid as \"uploader_steam_id?: SteamId\",\n users.name as \"uploader_name?\"\n FROM demos\n LEFT JOIN users_named ON uploader = users_named.id\n LEFT JOIN users ON uploader = users.id\n WHERE deleted_at IS NULL AND demos.id = $1",
|
"query": "SELECT\n demos.id, demos.name, url, map, red, blu, uploader, duration, demos.created_at,\n \"scoreRed\" as score_red, \"scoreBlue\" as score_blue, server, nick,\n \"playerCount\" as player_count,\n users_named.name as uploader_name_preferred,\n users.steamid as \"uploader_steam_id?: SteamId\",\n users.name as \"uploader_name?\",\n demos.private_until\n FROM demos\n LEFT JOIN users_named ON uploader = users_named.id\n LEFT JOIN users ON uploader = users.id\n WHERE deleted_at IS NULL AND demos.id = $1",
|
||||||
"describe": {
|
"describe": {
|
||||||
"columns": [
|
"columns": [
|
||||||
{
|
{
|
||||||
|
|
@ -87,6 +87,11 @@
|
||||||
"ordinal": 16,
|
"ordinal": 16,
|
||||||
"name": "uploader_name?",
|
"name": "uploader_name?",
|
||||||
"type_info": "Varchar"
|
"type_info": "Varchar"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ordinal": 17,
|
||||||
|
"name": "private_until",
|
||||||
|
"type_info": "Timestamptz"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"parameters": {
|
"parameters": {
|
||||||
|
|
@ -109,8 +114,9 @@
|
||||||
false,
|
false,
|
||||||
true,
|
true,
|
||||||
false,
|
false,
|
||||||
false
|
false,
|
||||||
|
true
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"hash": "68e8265e13596ad6de3e3d346b6d2fb62a68eda3e98f690e7e8d954627d8025c"
|
"hash": "7ea7c5f61e8c77898d8b816fce80f066026822e03d6f74bd4ae19d7c9d914426"
|
||||||
}
|
}
|
||||||
|
|
@ -10,10 +10,7 @@
|
||||||
inputs.flakelight.follows = "flakelight";
|
inputs.flakelight.follows = "flakelight";
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
outputs = {
|
outputs = {mill-scale, ...}:
|
||||||
mill-scale,
|
|
||||||
...
|
|
||||||
}:
|
|
||||||
mill-scale ./. {
|
mill-scale ./. {
|
||||||
packageOpts = {demostf-frontend-node-modules, ...}: {
|
packageOpts = {demostf-frontend-node-modules, ...}: {
|
||||||
preBuild = ''
|
preBuild = ''
|
||||||
|
|
|
||||||
|
|
@ -40,6 +40,7 @@ pub struct Demo {
|
||||||
pub player_count: i32,
|
pub player_count: i32,
|
||||||
pub players: Vec<Player>,
|
pub players: Vec<Player>,
|
||||||
pub chat: Vec<Chat>,
|
pub chat: Vec<Chat>,
|
||||||
|
pub private_until: Option<OffsetDateTime>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Debug for Demo {
|
impl Debug for Demo {
|
||||||
|
|
@ -74,6 +75,7 @@ impl Demo {
|
||||||
pub server: String,
|
pub server: String,
|
||||||
pub nick: String,
|
pub nick: String,
|
||||||
pub player_count: i32,
|
pub player_count: i32,
|
||||||
|
pub private_until: Option<OffsetDateTime>,
|
||||||
}
|
}
|
||||||
|
|
||||||
let Some(raw) = query_as!(
|
let Some(raw) = query_as!(
|
||||||
|
|
@ -84,7 +86,8 @@ impl Demo {
|
||||||
"playerCount" as player_count,
|
"playerCount" as player_count,
|
||||||
users_named.name as uploader_name_preferred,
|
users_named.name as uploader_name_preferred,
|
||||||
users.steamid as "uploader_steam_id?: SteamId",
|
users.steamid as "uploader_steam_id?: SteamId",
|
||||||
users.name as "uploader_name?"
|
users.name as "uploader_name?",
|
||||||
|
demos.private_until
|
||||||
FROM demos
|
FROM demos
|
||||||
LEFT JOIN users_named ON uploader = users_named.id
|
LEFT JOIN users_named ON uploader = users_named.id
|
||||||
LEFT JOIN users ON uploader = users.id
|
LEFT JOIN users ON uploader = users.id
|
||||||
|
|
@ -120,6 +123,7 @@ impl Demo {
|
||||||
player_count: raw.player_count,
|
player_count: raw.player_count,
|
||||||
players,
|
players,
|
||||||
chat,
|
chat,
|
||||||
|
private_until: raw.private_until,
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -149,6 +153,37 @@ impl Demo {
|
||||||
pub fn viewer_url(&self) -> ViewerUrl {
|
pub fn viewer_url(&self) -> ViewerUrl {
|
||||||
ViewerUrl(self.id)
|
ViewerUrl(self.id)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn is_private(&self) -> bool {
|
||||||
|
if let Some(private_until) = self.private_until {
|
||||||
|
let now = OffsetDateTime::now_utc();
|
||||||
|
now < private_until
|
||||||
|
} else {
|
||||||
|
false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn url(&self) -> &str {
|
||||||
|
if self.is_private() {
|
||||||
|
""
|
||||||
|
} else {
|
||||||
|
self.url.as_str()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn private_until_text(&self) -> Cow<'static, str> {
|
||||||
|
if let Some(private_until) = self.private_until {
|
||||||
|
let now = OffsetDateTime::now_utc();
|
||||||
|
let days = (private_until - now).whole_days();
|
||||||
|
if days <= 1 {
|
||||||
|
"by tomorrow".into()
|
||||||
|
} else {
|
||||||
|
format!("in {days} days").into()
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
"".into()
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct ViewerUrl(i32);
|
pub struct ViewerUrl(i32);
|
||||||
|
|
|
||||||
|
|
@ -23,7 +23,9 @@ impl Page for DemoPage {
|
||||||
fn render(&self) -> Markup {
|
fn render(&self) -> Markup {
|
||||||
let style_url = ClassIconsStyle::url();
|
let style_url = ClassIconsStyle::url();
|
||||||
html! {
|
html! {
|
||||||
@if self.demo.url.is_empty() {
|
@if self.demo.is_private() {
|
||||||
|
h3.warning { "This demo is private, it will be available for download " (self.demo.private_until_text()) }
|
||||||
|
} @else if self.demo.url.is_empty() {
|
||||||
h3.warning { "This demo has been deleted and is no longer available for download." }
|
h3.warning { "This demo has been deleted and is no longer available for download." }
|
||||||
}
|
}
|
||||||
h2 { (self.demo.server) " - " (self.demo.red) " vs " (self.demo.blu) }
|
h2 { (self.demo.server) " - " (self.demo.red) " vs " (self.demo.blu) }
|
||||||
|
|
@ -104,8 +106,8 @@ impl Page for DemoPage {
|
||||||
span.time { (self.demo.duration()) }
|
span.time { (self.demo.duration()) }
|
||||||
}
|
}
|
||||||
p.demo-download {
|
p.demo-download {
|
||||||
@if !self.demo.url.is_empty() {
|
@if !self.demo.url().is_empty() {
|
||||||
a.button.button-primary href = (self.demo.url) download = (self.demo.name) rel = "nofollow" { "Download" }
|
a.button.button-primary href = (self.demo.url()) download = (self.demo.name) rel = "nofollow" { "Download" }
|
||||||
a.button href = (self.demo.viewer_url()) rel = "nofollow" { "View" }
|
a.button href = (self.demo.viewer_url()) rel = "nofollow" { "View" }
|
||||||
}
|
}
|
||||||
@if !self.demo.chat.is_empty() {
|
@if !self.demo.chat.is_empty() {
|
||||||
|
|
|
||||||
|
|
@ -53,8 +53,12 @@ impl Page for ViewerPage<'_> {
|
||||||
html! {
|
html! {
|
||||||
.viewer-page data-maps = (maps) data-sync = (sync) {
|
.viewer-page data-maps = (maps) data-sync = (sync) {
|
||||||
@if let Some(demo) = self.demo.as_ref() {
|
@if let Some(demo) = self.demo.as_ref() {
|
||||||
|
@if demo.is_private() {
|
||||||
|
h3.warning { "This demo is private, it will be available for download " (demo.private_until_text()) }
|
||||||
|
} @else {
|
||||||
input type = "hidden" name = "url" value = (demo.url) {}
|
input type = "hidden" name = "url" value = (demo.url) {}
|
||||||
progress.download min = "0" max = "100" value = "0" {}
|
progress.download min = "0" max = "100" value = "0" {}
|
||||||
|
}
|
||||||
} @else {
|
} @else {
|
||||||
.dropzone role = "button" {
|
.dropzone role = "button" {
|
||||||
noscript {
|
noscript {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue