diff --git a/src/database/indexer.rs b/src/database/indexer.rs
@@ -1,5 +1,4 @@
use std::{
- borrow::Cow,
collections::HashSet,
ffi::OsStr,
fmt::Debug,
diff --git a/src/methods/filters.rs b/src/methods/filters.rs
@@ -24,6 +24,14 @@ pub fn format_time(s: impl Into<Timestamp>) -> Result<String, askama::Error> {
.map_err(askama::Error::Custom)
}
+pub fn branch_query(branch: Option<&str>) -> String {
+ if let Some(b) = branch {
+ format!("?h={b}")
+ } else {
+ String::new()
+ }
+}
+
pub fn timeago(s: impl Into<Timestamp>) -> Result<String, askama::Error> {
Ok(timeago::Formatter::new()
.convert((OffsetDateTime::now_utc() - s.into().0).try_into().unwrap()))
diff --git a/src/methods/repo/tree.rs b/src/methods/repo/tree.rs
@@ -1,12 +1,12 @@
-use std::{
- fmt::{Display, Formatter},
- sync::Arc,
-};
-
use askama::Template;
use axum::{extract::Query, response::IntoResponse, Extension};
use itertools::Itertools;
use serde::Deserialize;
+use std::path::PathBuf;
+use std::{
+ fmt::{Display, Formatter},
+ sync::Arc,
+};
use crate::{
git::{FileWithContent, PathDestination, TreeItem},
@@ -51,6 +51,7 @@ pub struct TreeView {
pub repo: Repository,
pub items: Vec<TreeItem>,
pub query: UriQuery,
+ pub repo_path: PathBuf,
pub branch: Option<Arc<str>>,
}
@@ -58,6 +59,7 @@ pub struct TreeView {
#[template(path = "repo/file.html")]
pub struct FileView {
pub repo: Repository,
+ pub repo_path: PathBuf,
pub file: FileWithContent,
pub branch: Option<Arc<str>>,
}
@@ -73,7 +75,7 @@ pub async fn handle(
Ok(
match open_repo
- .path(child_path, query.id.as_deref(), !query.raw)
+ .path(child_path.clone(), query.id.as_deref(), !query.raw)
.await?
{
PathDestination::Tree(items) => {
@@ -82,6 +84,7 @@ pub async fn handle(
items,
branch: query.branch.clone(),
query,
+ repo_path: child_path.unwrap_or_default(),
})))
}
PathDestination::File(file) if query.raw => ResponseEither::Right(file.content),
@@ -90,6 +93,7 @@ pub async fn handle(
repo,
file,
branch: query.branch,
+ repo_path: child_path.unwrap_or_default(),
})))
}
},
diff --git a/statics/sass/style.scss b/statics/sass/style.scss
@@ -58,6 +58,15 @@ nav {
}
}
+aside {
+ background: #f7f7f7;
+ padding: 0.3rem 2rem;
+
+ @media (prefers-color-scheme: dark) {
+ background: #111;
+ }
+}
+
main {
padding: 2rem;
margin: 0;
diff --git a/templates/base.html b/templates/base.html
@@ -30,6 +30,10 @@
</nav>
{%- endblock -%}
+<aside>
+ {%- block subnav %}{% endblock %}
+</aside>
+
<main>
{%- block content %}{% endblock -%}
</main>
diff --git a/templates/repo/file.html b/templates/repo/file.html
@@ -1,4 +1,5 @@
{% import "macros/link.html" as link %}
+{% import "macros/breadcrumbs.html" as breadcrumbs %}
{% extends "repo/base.html" %}
{% block head %}
@@ -8,6 +9,10 @@
{% block tree_nav_class %}active{% endblock %}
+{% block subnav %}
+ {% call breadcrumbs::breadcrumbs(repo_path, filters::branch_query(branch.as_deref())) %}
+{% endblock %}
+
{% block extra_nav_links %}
<a href="?raw=true{% call link::maybe_branch_suffix(branch) %}">plain</a>
{% endblock %}
diff --git a/templates/repo/macros/breadcrumbs.html b/templates/repo/macros/breadcrumbs.html
@@ -0,0 +1,11 @@
+{%- macro breadcrumbs(repo_path, query) -%}
+ path:
+ <a href="/{{ repo.display() }}/tree/{{ query }}">{{ repo.display() }}</a>
+ {%- for child in repo_path.ancestors().collect_vec().into_iter().rev() -%}
+ {%- if let Some(file_name) = child.file_name() -%}
+ /<a href="/{{ repo.display() }}/tree/{{ child.display() }}{{ query }}">
+ {{- file_name.to_string_lossy() -}}
+ </a>
+ {%- endif -%}
+ {%- endfor -%}
+{%- endmacro -%}
\ No newline at end of file
diff --git a/templates/repo/tree.html b/templates/repo/tree.html
@@ -1,7 +1,12 @@
+{% import "macros/breadcrumbs.html" as breadcrumbs %}
{% extends "repo/base.html" %}
{% block tree_nav_class %}active{% endblock %}
+{% block subnav %}
+ {% call breadcrumbs::breadcrumbs(repo_path, query) %}
+{% endblock %}
+
{% block content %}
<div class="table-responsive">
<table class="repositories">