Something went wrong. Try again.
Monorepo for Tangled
Something went wrong. Try again.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150use bobbin_edge_index::EdgeStore;use bobbin_types::{ ids::{EdgeKey, SubjectRef, nsid_static, owner_did_from_aturi}, sh_tangled::{ actor, feed::star::StarRecord, graph::follow::FollowRecord, repo::{self, Repo, RepoRecord}, },};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("sh.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) async fn build_repo_view_basic( state: &AppState, viewer: Option<&Did>, did: &Did,) -> Result<repo::RepoViewBasic, XrpcError> { let ident = state .resolver .lookup_by_repo_did(did) .await .ok_or(XrpcError::NotFound)?; let uri = AtUri::<DefaultStr>::from_parts_owned( ident.owner.as_str(), RepoRecord::NSID, ident.rkey.as_str(), ) .map_err(|e| XrpcError::InvalidRecord(format!("repo uri assembly: {e}")))?; let (_, repo) = fetch::<RepoRecord, Repo<DefaultStr>>(state, &uri).await?; build_repo_view_basic_inner(state, viewer, &uri, &repo, did.clone()).await}
async fn build_repo_view_basic_inner( state: &AppState, viewer: Option<&Did>, repo_uri: &AtUri, repo_record: &Repo, repo_did: Did,) -> Result<repo::RepoViewBasic, XrpcError> { let owner_did = owner_did_from_aturi(repo_uri) .ok_or_else(|| XrpcError::InvalidParams("repo uri authority must be a did".into()))?; let owner = build_profile_basic(state, viewer, &owner_did).await; let slug = repo_record.name.clone().unwrap_or_else(|| { repo_uri .rkey() .map(|r| DefaultStr::from(r.as_ref())) .unwrap_or_default() }); let star_key = EdgeKey::new( nsid_static(StarRecord::NSID), SubjectRef::Did(repo_did.clone()), ); let star_count = state.edges.count(&star_key) as i64; 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) .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") } }}