89109d2
use axum::extract::{Path, State};
use axum::response::Response;
use maud::html;
use crate::handler::html::{HtmlRepoPath, archived_class, resolve, response_html};
use crate::service::GitService;
use crate::share::access::BasicAuth;
#[utoipa::path(
get,
path = "/repos/{space_name}/{repo_name}/html/star-button",
tag = "html",
description = "渲染当前用户视角的加星按钮与星数片段。",
operation_id = "render_star_button",
params(HtmlRepoPath),
responses(
(status = 200, description = "star button html fragment", content_type = "text/html"),
(status = 404, description = "repo not found")
)
)]
pub async fn render_star_button(
State(service): State<GitService>,
Path(path): Path<HtmlRepoPath>,
auth: BasicAuth,
) -> Response {
let ctx = match resolve(service.clone(), path, auth).await {
Ok(c) => c,
Err(resp) => return resp,
};
let is_starred = match ctx.uid {
Some(uid) => service.is_starred(&ctx.ctx, uid).await.unwrap_or(false),
None => false,
};
let base = "git-star-button inline-flex items-center rounded-md border border-zinc-200 bg-white text-xs text-zinc-700 shadow-sm";
let cls = archived_class(&ctx.dto, base);
let space = ctx.space_name.clone();
let repo = ctx.repo_name.clone();
let star_count = ctx.dto.stars_count;
let markup = html! {
div class=(cls)
data-component="git-star-button"
data-space=(space)
data-repo=(repo)
data-starred=(if is_starred { "true" } else { "false" })
data-count=(star_count)
data-archived=(if ctx.dto.is_archived { "true" } else { "false" }) {
button class="flex items-center gap-1.5 px-2.5 py-1 font-medium hover:bg-zinc-50 border-r border-zinc-200 transition-colors"
type="button"
data-action="toggle-star" {
@if is_starred {
svg class="h-3.5 w-3.5 text-amber-500 fill-amber-500" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg" {
path d="M8 .25a.75.75 0 01.673.418l1.882 3.815 4.21.612a.75.75 0 01.416 1.279l-3.046 2.97.719 4.192a.75.75 0 01-1.088.791L8 12.347l-3.766 1.98a.75.75 0 01-1.088-.79l.72-4.194L.818 6.374a.75.75 0 01.416-1.28l4.21-.611L7.327.668A.75.75 0 018 .25z" {}
}
span { "Starred" }
} @else {
svg class="h-3.5 w-3.5 text-zinc-500" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg" {
path d="M8 .25a.75.75 0 01.673.418l1.882 3.815 4.21.612a.75.75 0 01.416 1.279l-3.046 2.97.719 4.192a.75.75 0 01-1.088.791L8 12.347l-3.766 1.98a.75.75 0 01-1.088-.79l.72-4.194L.818 6.374a.75.75 0 01.416-1.28l4.21-.611L7.327.668A.75.75 0 018 .25z" {}
}
span { "Star" }
}
}
a class="px-2.5 py-1 font-mono text-[11px] text-zinc-600 hover:text-zinc-900 hover:bg-zinc-50 transition-colors"
href=(format!("/{space}/{repo}/stargazers"))
title=(format!("{star_count} stargazers")) {
(star_count)
}
}
};
response_html(markup, 30)
}