Compare commits

...

7 Commits

8 changed files with 93 additions and 28 deletions

View File

@ -15,6 +15,7 @@
"stylelint-config-standard-scss"
],
"rules": {
"no-descending-specificity": null,
"string-quotes": "single"
}
}

View File

@ -8,10 +8,10 @@ use {
use crate::group_data::GroupDataModel;
const BACKGROUND_1: RGBColor = RGBColor(17, 17, 17);
const BACKGROUND_2: RGBColor = RGBColor(0, 0, 0);
const FOREGROUND: RGBColor = RGBColor(255, 255, 255);
const ACCENT_1: RGBColor = RGBColor(255, 0, 255);
const BACKGROUND_1: RGBColor = RGBColor(31, 23, 49);
const BACKGROUND_2: RGBColor = RGBColor(42, 32, 65);
const FOREGROUND: RGBColor = RGBColor(242, 239, 255);
const ACCENT_1: RGBColor = RGBColor(210, 184, 58);
/// The chart for the user count.
#[derive(Debug)]
@ -46,7 +46,7 @@ impl UserCountChart {
let path = parent.join("user-count.svg");
let chart_root = SVGBackend::new(&path, (1280, 720)).into_drawing_area();
chart_root.fill(&BACKGROUND_1)?;
chart_root.fill(&BACKGROUND_2)?;
let text_style =
|font_size: i32| ("sans-serif", font_size).into_font().color(&FOREGROUND);
@ -55,15 +55,15 @@ impl UserCountChart {
.margin(20, 20, 20, 20)
.titled("Tildes User Count", text_style(30))?;
chart_root.fill(&BACKGROUND_1)?;
chart_root.fill(&BACKGROUND_2)?;
let mut chart = ChartBuilder::on(&chart_root)
.caption(
format!("Using the {group_name} subscriber count."),
text_style(20),
)
.x_label_area_size(40)
.y_label_area_size(40)
.x_label_area_size(50)
.y_label_area_size(50)
.margin(10)
.build_cartesian_2d(0..(datapoints_len + 1), min_count..max_count)?;
@ -75,9 +75,9 @@ impl UserCountChart {
.y_labels(5)
.y_label_formatter(&|y| format!("{y:0}"))
.label_style(text_style(20))
.axis_style(&BACKGROUND_2)
.light_line_style(&BACKGROUND_2)
.bold_line_style(&BACKGROUND_1)
.axis_style(&BACKGROUND_1)
.light_line_style(&BACKGROUND_1)
.bold_line_style(&BACKGROUND_2)
.draw()?;
chart

View File

@ -85,15 +85,19 @@ pub async fn run() -> Result<()> {
command: web_command,
} => match web_command {
WebSubcommands::Build { output } => {
let user_count_group =
let (groups, user_count_group) =
if let Some(snapshot) = SnapshotModel::get_most_recent(&db).await? {
GroupDataModel::get_highest_subscribers(&db, &snapshot).await?
(
GroupDataModel::get_all_by_snapshot(&db, &snapshot).await?,
GroupDataModel::get_highest_subscribers(&db, &snapshot).await?,
)
} else {
None
(vec![], None)
};
create_dir_all(&output).await?;
HomeTemplate::new(
groups,
user_count_group.as_ref().map(|group| group.subscribers),
)
.render_to_file(&output)

View File

@ -19,7 +19,12 @@ impl GroupDataModel {
db: &DatabaseConnection,
snapshot: &SnapshotModel,
) -> Result<Vec<Self>> {
let groups = snapshot.find_related(GroupDataEntity).all(db).await?;
let groups = snapshot
.find_related(GroupDataEntity)
.order_by_asc(GroupDataColumn::Name)
.all(db)
.await?;
Ok(groups)
}
@ -44,7 +49,7 @@ impl GroupDataModel {
name: &str,
) -> Result<Vec<Self>> {
let groups = GroupDataEntity::find()
.order_by_desc(GroupDataColumn::SnapshotId)
.order_by_asc(GroupDataColumn::SnapshotId)
.filter(GroupDataColumn::Name.eq(name))
.limit(amount)
.all(db)

View File

@ -6,11 +6,11 @@ body {
--small-spacing: 4px;
--medium-spacing: 8px;
--large-spacing: 16px;
--background-1: #222;
--background-2: #111;
--foreground-1: #fff;
--anchor-1: #f0f;
--anchor-2: #000;
--background-1: #1f1731;
--background-2: #2a2041;
--foreground-1: #f2efff;
--anchor-1: #d2b83a;
--anchor-2: var(--foreground-1);
background-color: var(--background-1);
color: var(--foreground-1);
@ -20,10 +20,8 @@ body {
a,
a:visited {
color: var(--anchor-1);
text-decoration: none;
&:hover {
background-color: var(--anchor-1);
color: var(--anchor-2);
}
}

View File

@ -24,13 +24,41 @@
.page-main {
h2,
img,
p {
p,
table {
margin-bottom: var(--medium-spacing);
&:last-child {
margin-bottom: 0;
}
}
table {
border: 2px solid var(--background-2);
border-collapse: collapse;
width: 100%;
}
thead {
background-color: var(--background-2);
border-bottom: 2px solid var(--background-2);
text-align: left;
}
tr {
border: 2px solid var(--background-2);
}
td,
th {
padding: var(--medium-spacing);
}
tbody {
> tr:nth-of-type(2n) {
background-color: var(--background-2);
}
}
}
.page-footer {

View File

@ -13,13 +13,38 @@
<h2>General</h2>
<p>
There are currently an
<abbr title="Based on the group with the highest subscriber count.">estimated</abbr>
There are currently an estimated
<span class="underline">{{ user_count }}</span>
registered users on Tildes.
</p>
<img src="/charts/user-count.svg" alt="User Count Chart">
<table>
<thead>
<tr>
<th>Group</th>
<th>Subscribers</th>
<th>Description</th>
</tr>
</thead>
<tbody>
{% for group in groups %}
<tr>
<td>
<a href="https://tildes.net/{{ group.name }}">{{ group.name }}</a>
</td>
<td>{{ group.subscribers }}</td>
<td>
{% if let Some(description) = group.description %}
{{ description }}
{% endif %}
</td>
</tr>
{% endfor %}
</tbody>
</table>
</main>
<footer class="page-footer">

View File

@ -7,12 +7,15 @@ use {
color_eyre::Result,
};
use crate::utilities::today;
use crate::{group_data::GroupDataModel, utilities::today};
/// The template for the home page.
#[derive(Template)]
#[template(path = "index.html")]
pub struct HomeTemplate {
/// The groups to create the table with.
pub groups: Vec<GroupDataModel>,
/// The string for the `<title>` element.
pub page_title: String,
@ -25,8 +28,9 @@ pub struct HomeTemplate {
impl HomeTemplate {
/// Create a new [`HomeTemplate`].
pub fn new(user_count: Option<i64>) -> Self {
pub fn new(groups: Vec<GroupDataModel>, user_count: Option<i64>) -> Self {
Self {
groups,
page_title: "Tildes Statistics".to_string(),
today: today(),
user_count: user_count