241 lines
8.8 KiB
Rust
241 lines
8.8 KiB
Rust
use magnetar_calckey_model::ck;
|
|
use magnetar_calckey_model::ck::sea_orm_active_enums::UserProfileFfvisibilityEnum;
|
|
use magnetar_sdk::types::drive::PackDriveFileBase;
|
|
use magnetar_sdk::types::emoji::{EmojiContext, PackEmojiBase};
|
|
use magnetar_sdk::types::instance::InstanceTicker;
|
|
use magnetar_sdk::types::note::PackNoteMaybeFull;
|
|
use magnetar_sdk::types::user::{
|
|
AvatarDecoration, PackSecurityKeyBase, ProfileField, SecurityKeyBase, SpeechTransform,
|
|
UserBase, UserDetailExt, UserProfileExt, UserProfilePinsEx, UserRelationExt, UserSecretsExt,
|
|
};
|
|
use magnetar_sdk::types::MmXml;
|
|
use url::Url;
|
|
|
|
use crate::model::{PackType, PackingContext};
|
|
|
|
impl PackType<&[PackEmojiBase]> for EmojiContext {
|
|
fn extract(_context: &PackingContext, data: &[PackEmojiBase]) -> Self {
|
|
EmojiContext(data.to_owned())
|
|
}
|
|
}
|
|
|
|
pub struct UserBaseSource<'a> {
|
|
pub user: &'a ck::user::Model,
|
|
pub username_mm: Option<&'a MmXml>,
|
|
pub avatar_url: &'a Url,
|
|
pub avatar: Option<&'a PackDriveFileBase>,
|
|
pub emoji_context: &'a EmojiContext,
|
|
pub instance: Option<&'a InstanceTicker>,
|
|
}
|
|
|
|
impl PackType<UserBaseSource<'_>> for UserBase {
|
|
fn extract(
|
|
_context: &PackingContext,
|
|
UserBaseSource {
|
|
user,
|
|
username_mm,
|
|
avatar_url,
|
|
avatar,
|
|
emoji_context,
|
|
instance,
|
|
}: UserBaseSource,
|
|
) -> Self {
|
|
UserBase {
|
|
acct: user
|
|
.host
|
|
.as_ref()
|
|
.map(|host| format!("@{}@{}", user.username, host))
|
|
.unwrap_or_else(|| format!("@{}", user.username)),
|
|
username: user.username.clone(),
|
|
display_name: user.name.clone().unwrap_or_else(|| user.username.clone()),
|
|
display_name_mm: username_mm.cloned(),
|
|
host: user.host.clone(),
|
|
speech_transform: if user.is_cat && user.speak_as_cat {
|
|
SpeechTransform::Cat
|
|
} else {
|
|
SpeechTransform::None
|
|
},
|
|
created_at: user.created_at.into(),
|
|
avatar_url: avatar_url.to_string(),
|
|
avatar_blurhash: avatar.and_then(|v| v.file.0.blurhash.clone()),
|
|
avatar_decoration: if user.is_cat {
|
|
AvatarDecoration::CatEars
|
|
} else {
|
|
AvatarDecoration::None
|
|
},
|
|
is_admin: user.is_admin,
|
|
is_moderator: user.is_moderator,
|
|
is_bot: user.is_bot,
|
|
emojis: emoji_context.clone(),
|
|
instance: instance.map(|i| i.clone()),
|
|
}
|
|
}
|
|
}
|
|
|
|
pub struct UserProfileExtSource<'a> {
|
|
pub user: &'a ck::user::Model,
|
|
pub profile: &'a ck::user_profile::Model,
|
|
pub profile_fields: &'a Vec<ProfileField>,
|
|
pub banner_url: Option<&'a Url>,
|
|
pub banner: Option<&'a ck::drive_file::Model>,
|
|
pub description_mm: Option<&'a MmXml>,
|
|
pub relation: Option<&'a UserRelationExt>,
|
|
}
|
|
|
|
impl PackType<UserProfileExtSource<'_>> for UserProfileExt {
|
|
fn extract(
|
|
context: &PackingContext,
|
|
UserProfileExtSource {
|
|
user,
|
|
profile,
|
|
profile_fields,
|
|
banner_url,
|
|
banner,
|
|
description_mm,
|
|
relation,
|
|
}: UserProfileExtSource,
|
|
) -> Self {
|
|
let follow_visibility = match profile.ff_visibility {
|
|
UserProfileFfvisibilityEnum::Public => true,
|
|
UserProfileFfvisibilityEnum::Followers => relation.is_some_and(|r| r.follows_you),
|
|
UserProfileFfvisibilityEnum::Private => false,
|
|
} || context.is_self(user);
|
|
|
|
UserProfileExt {
|
|
is_locked: user.is_locked,
|
|
is_silenced: user.is_silenced,
|
|
is_suspended: user.is_suspended,
|
|
description: profile.description.clone(),
|
|
description_mm: description_mm.cloned(),
|
|
location: profile.location.clone(),
|
|
birthday: profile
|
|
.birthday
|
|
.clone()
|
|
.and_then(|b| b.parse().map_or_else(|_| None, Some)),
|
|
fields: profile_fields.clone(),
|
|
follower_count: follow_visibility.then_some(user.followers_count as u64),
|
|
following_count: follow_visibility.then_some(user.following_count as u64),
|
|
note_count: Some(user.notes_count as u64),
|
|
url: profile.url.clone(),
|
|
moved_to_uri: user.moved_to_uri.clone(),
|
|
also_known_as: user.also_known_as.clone(),
|
|
banner_url: banner_url.map(Url::to_string),
|
|
banner_blurhash: banner.and_then(|b| b.blurhash.clone()),
|
|
has_public_reactions: profile.public_reactions,
|
|
}
|
|
}
|
|
}
|
|
|
|
impl PackType<&ck::user::Model> for UserDetailExt {
|
|
fn extract(_context: &PackingContext, user: &ck::user::Model) -> Self {
|
|
UserDetailExt {
|
|
last_fetched_at: user.last_fetched_at.map(Into::into),
|
|
uri: user.uri.clone(),
|
|
updated_at: user.updated_at.map(Into::into),
|
|
}
|
|
}
|
|
}
|
|
|
|
struct UserRelationExtSource<'a> {
|
|
pub follow_out: Option<&'a ck::following::Model>,
|
|
pub follow_in: Option<&'a ck::following::Model>,
|
|
pub block_out: Option<&'a ck::blocking::Model>,
|
|
pub block_in: Option<&'a ck::blocking::Model>,
|
|
pub mute: Option<&'a ck::muting::Model>,
|
|
pub renote_mute: Option<&'a ck::renote_muting::Model>,
|
|
pub follow_request_out: Option<&'a ck::follow_request::Model>,
|
|
pub follow_request_in: Option<&'a ck::follow_request::Model>,
|
|
}
|
|
|
|
impl PackType<UserRelationExtSource<'_>> for UserRelationExt {
|
|
fn extract(
|
|
context: &PackingContext,
|
|
UserRelationExtSource {
|
|
follow_out,
|
|
follow_in,
|
|
block_out,
|
|
block_in,
|
|
mute,
|
|
renote_mute,
|
|
follow_request_in,
|
|
follow_request_out,
|
|
}: UserRelationExtSource,
|
|
) -> Self {
|
|
let self_user = context.self_user();
|
|
|
|
UserRelationExt {
|
|
follows_you: self_user.is_some_and(|self_user| {
|
|
follow_in.is_some_and(|follow_in| {
|
|
self_user.id == follow_in.followee_id && self_user.id != follow_in.follower_id
|
|
})
|
|
}),
|
|
you_follow: self_user.is_some_and(|self_user| {
|
|
follow_out.is_some_and(|follow_out| {
|
|
self_user.id == follow_out.follower_id && self_user.id != follow_out.followee_id
|
|
})
|
|
}),
|
|
blocks_you: self_user.is_some_and(|self_user| {
|
|
block_in.is_some_and(|block_in| {
|
|
self_user.id == block_in.blockee_id && self_user.id != block_in.blocker_id
|
|
})
|
|
}),
|
|
you_block: self_user.is_some_and(|self_user| {
|
|
block_out.is_some_and(|block_out| {
|
|
self_user.id == block_out.blocker_id && self_user.id != block_out.blockee_id
|
|
})
|
|
}),
|
|
mute: self_user.is_some_and(|self_user| {
|
|
mute.is_some_and(|mute| {
|
|
self_user.id == mute.muter_id && self_user.id != mute.mutee_id
|
|
})
|
|
}),
|
|
mute_renotes: self_user.is_some_and(|self_user| {
|
|
renote_mute.is_some_and(|renote_mute| {
|
|
self_user.id == renote_mute.muter_id && self_user.id != renote_mute.mutee_id
|
|
})
|
|
}),
|
|
you_request_follow: self_user.is_some_and(|self_user| {
|
|
follow_request_in.is_some_and(|follow_req_in| {
|
|
self_user.id == follow_req_in.followee_id
|
|
&& self_user.id != follow_req_in.follower_id
|
|
})
|
|
}),
|
|
they_request_follow: self_user.is_some_and(|self_user| {
|
|
follow_request_out.is_some_and(|follow_req_out| {
|
|
self_user.id == follow_req_out.follower_id
|
|
&& self_user.id != follow_req_out.followee_id
|
|
})
|
|
}),
|
|
}
|
|
}
|
|
}
|
|
|
|
impl PackType<&[PackNoteMaybeFull]> for UserProfilePinsEx {
|
|
fn extract(_context: &PackingContext, pinned_notes: &[PackNoteMaybeFull]) -> Self {
|
|
UserProfilePinsEx {
|
|
pinned_notes: pinned_notes.to_owned(),
|
|
}
|
|
}
|
|
}
|
|
|
|
impl PackType<ck::user_security_key::Model> for SecurityKeyBase {
|
|
fn extract(_context: &PackingContext, key: ck::user_security_key::Model) -> Self {
|
|
SecurityKeyBase {
|
|
name: key.name.clone(),
|
|
last_used_at: Some(key.last_used.into()),
|
|
}
|
|
}
|
|
}
|
|
|
|
type UserSecretsExtSource<'a> = (&'a ck::user_profile::Model, &'a [PackSecurityKeyBase]);
|
|
|
|
impl PackType<UserSecretsExtSource<'_>> for UserSecretsExt {
|
|
fn extract(_context: &PackingContext, (profile, keys): UserSecretsExtSource) -> Self {
|
|
UserSecretsExt {
|
|
email: profile.email.clone(),
|
|
email_verified: profile.email_verified,
|
|
security_keys: keys.to_owned(),
|
|
}
|
|
}
|
|
}
|