Enable search by wallet address
This commit is contained in:
parent
4797bacf32
commit
7e5917a821
3 changed files with 48 additions and 4 deletions
|
@ -10,13 +10,18 @@ use crate::errors::{ValidationError, HttpError};
|
|||
use crate::mastodon_api::accounts::types::Account;
|
||||
use crate::mastodon_api::statuses::types::Status;
|
||||
use crate::models::posts::types::Post;
|
||||
use crate::models::profiles::queries::search_profile;
|
||||
use crate::models::profiles::queries::{
|
||||
search_profile,
|
||||
search_profile_by_wallet_address,
|
||||
};
|
||||
use crate::models::profiles::types::DbActorProfile;
|
||||
use crate::models::users::types::validate_wallet_address;
|
||||
use super::types::SearchResults;
|
||||
|
||||
enum SearchQuery {
|
||||
ProfileQuery(String, Option<String>),
|
||||
Url(String),
|
||||
WalletAddress(String),
|
||||
Unknown,
|
||||
}
|
||||
|
||||
|
@ -39,6 +44,9 @@ fn parse_search_query(search_query: &str) -> SearchQuery {
|
|||
if Url::parse(search_query).is_ok() {
|
||||
return SearchQuery::Url(search_query.to_string());
|
||||
};
|
||||
if validate_wallet_address(&search_query.to_lowercase()).is_ok() {
|
||||
return SearchQuery::WalletAddress(search_query.to_string());
|
||||
};
|
||||
match parse_profile_query(search_query) {
|
||||
Ok((username, instance)) => {
|
||||
return SearchQuery::ProfileQuery(username, instance);
|
||||
|
@ -122,6 +130,10 @@ pub async fn search(
|
|||
posts = vec![post];
|
||||
};
|
||||
},
|
||||
SearchQuery::WalletAddress(address) => {
|
||||
// Search is case insensitive
|
||||
profiles = search_profile_by_wallet_address(db_client, "ETH", &address).await?;
|
||||
},
|
||||
SearchQuery::Unknown => (), // ignore
|
||||
};
|
||||
let accounts: Vec<Account> = profiles.into_iter()
|
||||
|
|
|
@ -10,6 +10,7 @@ use crate::models::cleanup::{
|
|||
};
|
||||
use crate::utils::id::new_uuid;
|
||||
use super::types::{
|
||||
get_currency_field_name,
|
||||
ExtraFields,
|
||||
DbActorProfile,
|
||||
ProfileCreateData,
|
||||
|
@ -303,12 +304,11 @@ pub async fn search_profile(
|
|||
) -> Result<Vec<DbActorProfile>, DatabaseError> {
|
||||
let db_search_query = match instance {
|
||||
Some(instance) => {
|
||||
// Search for exact profile name.
|
||||
// Fetch from remote server if not found
|
||||
// Search for exact actor address
|
||||
format!("{}@{}", username, instance)
|
||||
},
|
||||
None => {
|
||||
// Search for username
|
||||
// Fuzzy search for username
|
||||
format!("%{}%", username)
|
||||
},
|
||||
};
|
||||
|
@ -326,6 +326,34 @@ pub async fn search_profile(
|
|||
Ok(profiles)
|
||||
}
|
||||
|
||||
pub async fn search_profile_by_wallet_address(
|
||||
db_client: &impl GenericClient,
|
||||
currency_code: &str,
|
||||
wallet_address: &str,
|
||||
) -> Result<Vec<DbActorProfile>, DatabaseError> {
|
||||
let field_name = get_currency_field_name(currency_code);
|
||||
let rows = db_client.query(
|
||||
"
|
||||
SELECT actor_profile
|
||||
FROM actor_profile LEFT JOIN user_account USING (id)
|
||||
WHERE
|
||||
user_account.wallet_address ILIKE $2
|
||||
OR EXISTS (
|
||||
SELECT 1
|
||||
FROM jsonb_array_elements(actor_profile.extra_fields) AS field
|
||||
WHERE
|
||||
field ->> 'name' ILIKE $1
|
||||
AND field ->> 'value' ILIKE $2
|
||||
)
|
||||
",
|
||||
&[&field_name, &wallet_address],
|
||||
).await?;
|
||||
let profiles: Vec<DbActorProfile> = rows.iter()
|
||||
.map(|row| row.try_get("actor_profile"))
|
||||
.collect::<Result<_, _>>()?;
|
||||
Ok(profiles)
|
||||
}
|
||||
|
||||
pub async fn update_follower_count(
|
||||
db_client: &impl GenericClient,
|
||||
profile_id: &Uuid,
|
||||
|
|
|
@ -34,6 +34,10 @@ impl ExtraFields {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn get_currency_field_name(currency_code: &str) -> String {
|
||||
format!("${}", currency_code.to_uppercase())
|
||||
}
|
||||
|
||||
type SqlError = Box<dyn std::error::Error + Sync + Send>;
|
||||
|
||||
impl<'a> FromSql<'a> for ExtraFields {
|
||||
|
|
Loading…
Reference in a new issue