diff --git a/src/web4/handler.rs b/src/web4/handler.rs index 1b7a1d3..380a81b 100644 --- a/src/web4/handler.rs +++ b/src/web4/handler.rs @@ -37,21 +37,19 @@ pub fn web4_get(contract: &Contract, request: Web4Request) -> Web4Response { return Web4Response::PreloadUrls { preload_urls: [metadata_preload_url.clone()].to_vec() }; }; - if let Some(Web4Response::Body { content_type: _, body }) = preloads.get(&metadata_preload_url) { - if let Ok(body_value) = serde_json::from_slice::( - &BASE64_ENGINE.decode(body).unwrap() - ) { - if let Some(app_name_str) = body_value[¤t_account_id] - ["widget"]["app"]["metadata"]["name"] - .as_str() + if let Some(Web4Response::Body { content_type: _, body }) = preloads.get(&metadata_preload_url) + { + if let Ok(body_value) = + serde_json::from_slice::(&BASE64_ENGINE.decode(body).unwrap()) + { + if let Some(app_name_str) = + body_value[¤t_account_id]["widget"]["app"]["metadata"]["name"].as_str() { app_name = app_name_str.to_string(); } - if let Some(description_str) = body_value - [¤t_account_id]["widget"]["app"]["metadata"] - ["description"] - .as_str() + if let Some(description_str) = + body_value[¤t_account_id]["widget"]["app"]["metadata"]["description"].as_str() { description = description_str.to_string(); } @@ -62,11 +60,33 @@ pub fn web4_get(contract: &Contract, request: Web4Request) -> Web4Response { "https://i.near.social/magic/large/https://near.social/magic/img/account/{}", ¤t_account_id ); - let redirect_path; - let initial_props_json; + let mut redirect_path; + let mut initial_props_json; + + // Directly check the `c` and `s` query parameters and map them manually. + let campaign_name = match request.query.get("c").and_then(|vec| vec.get(0).map(|s| s.as_str())) + { + Some("1") => Some("x_ros_announcement"), + Some("2") => Some("wuasm"), + Some("3") => Some("redacted"), + _ => None, + }; + + let social_platform = + match request.query.get("s").and_then(|vec| vec.get(0).map(|s| s.as_str())) { + Some("i") => Some("instagram"), + Some("x") => Some("twitter"), + Some("f") => Some("facebook"), + Some("t") => Some("telegram"), + Some("y") => Some("youtube"), + Some("d") => Some("discord"), + Some("tt") => Some("tiktok"), + Some("l") => Some("linkedin"), + _ => None, + }; - match (page, path_parts.get(2)) { - ("community", Some(handle)) => { + match (page, path_parts.get(2), path_parts.get(3)) { + ("community", Some(handle), _) => { if let Some(community) = contract.get_community(handle.to_string()) { title = format!(" - Community - {}", community.name); description = community.description; @@ -78,7 +98,7 @@ pub fn web4_get(contract: &Contract, request: Web4Request) -> Web4Response { format!("{}/widget/app?page={}&handle={}", ¤t_account_id, page, handle); initial_props_json = json!({"page": page, "handle": handle}); } - ("proposal", Some(id)) => { + ("proposal", Some(id), _) => { if let Ok(id) = id.parse::() { if let Some(versioned_proposal) = contract.proposals.get(id.into()) { let proposal_body = @@ -91,16 +111,47 @@ pub fn web4_get(contract: &Contract, request: Web4Request) -> Web4Response { } else { title = " - Proposals".to_string(); } - redirect_path = - format!("{}/widget/app?page={}&id={}", ¤t_account_id, page, id); + redirect_path = format!("{}/widget/app?page={}&id={}", ¤t_account_id, page, id); initial_props_json = json!({"page": page, "id": id}); } + // Handle blog route with community and blog title + ("blog", Some(community), Some(blog_title)) => { + redirect_path = format!( + "{}/widget/app?page=blogv2&community={}&id={}", + ¤t_account_id, community, blog_title + ); + initial_props_json = json!({ + "page": "blogv2", + "community": community, + "id": blog_title + }); + title = format!(" - Blog - {} - {}", community, blog_title); + description = + format!("Read the latest blog from the {} community: {}", community, blog_title); + } _ => { redirect_path = format!("{}/widget/app", ¤t_account_id); initial_props_json = json!({"page": page}); } } + if let Some(campaign_value) = &campaign_name { + redirect_path = format!("{}&campaign={}", redirect_path, campaign_value); + // Modify initial_props_json to add the campaign field + if let Some(obj) = initial_props_json.as_object_mut() { + obj.insert("campaign".to_string(), json!(campaign_value)); + } + } + + if let Some(social_value) = &social_platform { + redirect_path = format!("{}&social={}", redirect_path, social_value); + + // Modify initial_props_json to add the social field + if let Some(obj) = initial_props_json.as_object_mut() { + obj.insert("social".to_string(), json!(social_value)); + } + } + let app_name = html_escape::encode_text(&app_name).to_string(); let title = html_escape::encode_text(&title).to_string(); let description = html_escape::encode_text(&description).to_string(); @@ -108,56 +159,56 @@ pub fn web4_get(contract: &Contract, request: Web4Request) -> Web4Response { let scroll_comment_into_view_js = include_str!("./scroll_comment_into_view.js"); let body = format!( r#" - - - {title} - - - - - - - - - - - - - - - - - - - - - -"#, + + + {title} + + + + + + + + + + + + + + + + + + + + + + "#, url = redirect_path ); @@ -288,8 +339,9 @@ mod tests { assert!(body_string.contains( "" )); - assert!(body_string - .contains("")); + assert!( + body_string.contains("") + ); } _ => { panic!("Should return Web4Response::Body"); @@ -378,6 +430,33 @@ mod tests { } } + #[test] + pub fn test_blog_page_response() { + view_test_env(); + let contract = Contract::new(); + + let response = web4_get( + &contract, + serde_json::from_value(serde_json::json!({ + "path": "/blog/dev-dao/blog-title?c=1&s=i", + "preloads": create_preload_result(String::from("near/dev/hub"), String::from("The decentralized home base for NEAR builders")), + })) + .unwrap(), + ); + match response { + Web4Response::Body { content_type, body } => { + assert_eq!("text/html; charset=UTF-8", content_type); + + let body_string = String::from_utf8(BASE64_ENGINE.decode(body).unwrap()).unwrap(); + assert!(body_string.contains(" - Blog - dev-dao - blog-title")); + assert!(body_string.contains("")); + } + _ => { + panic!("Should return Web4Response::Body"); + } + } + } + #[test] pub fn test_web4_unknown_path() { view_test_env(); @@ -650,9 +729,9 @@ mod tests { let body_string = String::from_utf8(BASE64_ENGINE.decode(body).unwrap()).unwrap(); assert!(body_string.contains("")); - assert!( - body_string.contains("") - ); + assert!(body_string.contains( + "" + )); assert!(body_string.contains("https://near.social/not-only-devhub.near/widget/app")); let expected_initial_props_string = json!({"page": "proposal", "id": "1"}).to_string();