Something went wrong. Try again.
Monorepo for Tangled tangled.org
Something went wrong. Try again.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161use bobbin_edge_index::{EdgeStore, TicketStateKind};use bobbin_types::{ edges::{REPO_SOURCE_EDGE_KIND, TICKET_ISSUE_KIND, TICKET_PULL_KIND}, ids::{EdgeKey, SubjectRef, nsid_static}, org_tangled::{ feed::star::StarRecord, git::refs::RefsRecord, graph::follow::FollowRecord, repo::manifest::{Manifest, ManifestRecord}, }, sh_tangled::{actor, repo},};use jacquard_common::{ DefaultStr, types::{aturi::AtUri, did::Did, string::Handle}, xrpc::XrpcResp as _,};use tracing::error;
use crate::{AppState, XrpcError, fetch};
pub(crate) async fn build_profile_basic( state: &AppState, viewer: Option<&Did>, did: &Did,) -> actor::ProfileViewBasic { let handle = resolve_handle(state, did); let avatar = None; // state.avatar.as_ref().and_then(|s| s.url(did)); let viewer_state = viewer .filter(|viewer| *viewer != did) .map(|viewer| build_actor_viewer_state(&state.edges, viewer, did)); actor::ProfileViewBasic::new() .did(did.clone()) .handle(handle) .maybe_avatar(avatar) .maybe_viewer(viewer_state) .build()}
pub(crate) async fn build_profile_detailed( state: &AppState, viewer: Option<&Did>, did: &Did,) -> actor::ProfileViewDetailed { let basic = build_profile_basic(state, viewer, did).await; let followers = state.edges.count(&EdgeKey::new( nsid_static(FollowRecord::NSID), SubjectRef::Did(did.clone()), )) as i64; let follows = state.edges.count(&EdgeKey::new( nsid_static("org.tangled.graph.follow.by"), SubjectRef::Did(did.clone()), )) as i64; actor::ProfileViewDetailed::new() .did(basic.did) .handle(basic.handle) .followers_count(followers) .follows_count(follows) .maybe_avatar(basic.avatar) .maybe_viewer(basic.viewer) .build()}
fn build_actor_viewer_state(edges: &EdgeStore, viewer: &Did, subject: &Did) -> actor::ViewerState { let following = edges.viewer_source( &EdgeKey::new( nsid_static(FollowRecord::NSID), SubjectRef::Did(subject.clone()), ), viewer.as_str(), ); let followed_by = edges.viewer_source( &EdgeKey::new( nsid_static(FollowRecord::NSID), SubjectRef::Did(viewer.clone()), ), subject.as_str(), ); actor::ViewerState { following, followed_by, ..Default::default() }}
pub(crate) fn manifest_uri(repo_did: &Did) -> AtUri<DefaultStr> { AtUri::from_parts_owned(repo_did.as_str(), ManifestRecord::NSID, "self") .expect("a did and a literal rkey always assemble")}
pub(crate) fn refs_uri(repo_did: &Did) -> AtUri<DefaultStr> { AtUri::from_parts_owned(repo_did.as_str(), RefsRecord::NSID, "self") .expect("a did and a literal rkey always assemble")}
pub(crate) async fn build_repo_view_basic( state: &AppState, viewer: Option<&Did>, did: &Did,) -> Result<repo::RepoViewBasic, XrpcError> { let (_, repo) = fetch::<ManifestRecord, Manifest<DefaultStr>>(state, &manifest_uri(did)).await?; build_repo_view_basic_from_record(state, viewer, &repo, did.clone()).await}
pub(crate) async fn build_repo_view_basic_from_record( state: &AppState, viewer: Option<&Did>, repo_record: &Manifest, repo_did: Did,) -> Result<repo::RepoViewBasic, XrpcError> { let owner = build_profile_basic(state, viewer, &repo_record.declaration.owner).await; let slug = DefaultStr::from(repo_record.declaration.name.0.to_lowercase()); let subject = SubjectRef::Did(repo_did.clone()); let star_key = EdgeKey::new(nsid_static(StarRecord::NSID), subject.clone()); let star_count = state.edges.count(&star_key) as i64; let fork_count = state.edges.count(&EdgeKey::new( nsid_static(REPO_SOURCE_EDGE_KIND), subject.clone(), )) as i64; let open_count = |kind| { state .edges .count_ticket_state( &EdgeKey::new(nsid_static(kind), subject.clone()), TicketStateKind::Open, ) .count .get() as i64 }; let open_issue_count = open_count(TICKET_ISSUE_KIND); let open_pull_count = open_count(TICKET_PULL_KIND); let viewer = viewer.map(|v| { let mut viewer = repo::ViewerState::default(); viewer.star = state.edges.viewer_source(&star_key, v.as_str()); viewer }); Ok(repo::RepoViewBasic::new() .did(repo_did) .owner(owner) .slug(slug) .created_at(repo_record.created_at.clone()) .description(repo_record.description.clone()) .star_count(star_count) .fork_count(fork_count) .open_issue_count(open_issue_count) .open_pull_count(open_pull_count) .viewer(viewer) .build())}
fn resolve_handle(state: &AppState, did: &Did) -> Handle { match state.identity.get_by_did(did) { Ok(doc) => doc.handle, Err(err) => { error!(error = %err, did = %did, "failed to resolve did"); Handle::new_static("handle.invalid").expect("handle.invalid is a valid handle") } }}