|
| 1 | +use crate::components::footer::Footer; |
| 2 | +use crate::components::header::Header; |
| 3 | +use leptos::prelude::Effect; |
| 4 | +use leptos::prelude::*; |
| 5 | +use leptos_router::hooks::{use_location, use_navigate}; |
| 6 | + |
| 7 | +// Welcome Patina Press Release |
| 8 | +fn patina_press_release() -> impl IntoView { |
| 9 | + view! { |
| 10 | + <div> |
| 11 | + <p class="mb-4"> |
| 12 | + <strong>"October 7, 2025 – Redmond, WA"</strong> " – The " <strong>"Open Device Partnership (ODP)"</strong> " is announcing " <strong>"Patina"</strong>", a new open-source firmware project is public, and details will be shared at the upcoming " |
| 13 | + <a href="https://uefi.org/events/uefi-2025-developers-conference-and-plugfest" class="underline hover:text-blue-600 transition-colors duration-150"> |
| 14 | + "UEFI 2025 Developer Conference & Plugfest" |
| 15 | + </a> |
| 16 | + ", October 7–10 in Sunnyvale, California. Patina is a Rust-based, UEFI-compatible firmware designed for memory safety and to address long standing challenges in the PC firmware ecosystem. It reimagines system firmware development to meet the evolving needs of modern hardware, software development lifecycles, supply chains, and industry collaboration. Patina joins a growing portfolio of ODP projects aimed at building a secure, modern foundation for device enablement. To learn more about Patina, please visit the project page and documentation here: " |
| 17 | + <a href="https://opendevicepartnership.github.io/patina" class="underline hover:text-blue-600 transition-colors duration-150"> |
| 18 | + "Patina Documentation" |
| 19 | + </a> |
| 20 | + "." |
| 21 | + </p> |
| 22 | + |
| 23 | + <p class="mb-4"> |
| 24 | + "ODP is an industry-wide, open-source initiative focused on advancing " <strong>"security, fundamentals, and standardization"</strong> " in device software. The partnership's work addresses long-standing challenges in firmware and system design by leveraging " <strong>"memory-safe programming languages like Rust"</strong> " and " <strong>"hardware-rooted security features"</strong> " and doing so based on standards that will work across a partner's entire device product line. This approach reduces exposure to common vulnerabilities while providing manufacturers with a sustainable, consistent foundation that lowers engineering costs across product lines." |
| 25 | + </p> |
| 26 | + |
| 27 | + <p class="mb-4"> |
| 28 | + "In addition to Patina, ODP is currently focused on three other major projects:" |
| 29 | + </p> |
| 30 | + <ul class="list-disc pl-12 mb-4"> |
| 31 | + <li class="mb-2"> |
| 32 | + <strong>"Secure EC firmware"</strong>", providing a modern, security-focused embedded controller implementation designed to eliminate classes of bugs prevalent in legacy EC codebases." |
| 33 | + </li> |
| 34 | + <li class="mb-2"> |
| 35 | + <strong>"Unified OS-EC service interface"</strong>", ensuring that operating systems can interact with embedded controllers in a consistent, well-defined way across devices." |
| 36 | + </li> |
| 37 | + <li class="mb-2"> |
| 38 | + <strong>"MPTF"</strong>", extending recent advancements in the Windows power-thermal framework to meet partner needs." |
| 39 | + </li> |
| 40 | + </ul> |
| 41 | + <p class="mb-4"> |
| 42 | + "Together, these efforts give hardware makers the ability to standardize firmware and device software across their entire portfolios—improving reliability, accelerating time-to-market, and reducing redundant engineering work." |
| 43 | + </p> |
| 44 | + |
| 45 | + <p class="mb-4"> |
| 46 | + "The Open Device Partnership is about building trust at the foundation. By focusing on memory safety, hardware-rooted security, and clear standards, we're making it easier for partners to deliver secure, consistent solutions while also reducing long-term development costs." |
| 47 | + </p> |
| 48 | + |
| 49 | + <p class="mb-4"> |
| 50 | + "With Patina's public launch and the ongoing progress of ODP's other projects, the initiative is now seeking broader industry participation. ODP invites partners, contributors, and stakeholders to join in shaping the future of secure, open device enablement." |
| 51 | + </p> |
| 52 | + |
| 53 | + <p class="mb-4"> |
| 54 | + "👉 Learn more and get involved at " |
| 55 | + <a href="https://opendevicepartnership.org/" class="underline hover:text-blue-600 transition-colors duration-150"> |
| 56 | + "opendevicepartnership.org" |
| 57 | + </a>"." |
| 58 | + </p> |
| 59 | + </div> |
| 60 | + } |
| 61 | +} |
| 62 | + |
| 63 | +#[component] |
| 64 | +pub fn AnnouncementsPage() -> impl IntoView { |
| 65 | + let location = use_location(); |
| 66 | + let navigate = use_navigate(); |
| 67 | + |
| 68 | + // List of announcement links and their content (display_text, title, slug) |
| 69 | + let announcements = vec![( |
| 70 | + "Oct-7-2025 Welcome Patina!", |
| 71 | + "Patina Project to Launch at UEFI 2025 Developer Conference & Plugfest", |
| 72 | + "welcome-patina-announcement", |
| 73 | + )]; |
| 74 | + |
| 75 | + let (selected, set_selected) = signal(0); |
| 76 | + |
| 77 | + // Set selected from query param if present |
| 78 | + { |
| 79 | + let location = location.clone(); |
| 80 | + let set_selected = set_selected.clone(); |
| 81 | + let announcements_clone = announcements.clone(); |
| 82 | + Effect::new(move |_| { |
| 83 | + let search = location.search.get(); |
| 84 | + |
| 85 | + // Check for new slug-based format: ?id=slug |
| 86 | + if search.contains("id=") { |
| 87 | + // Try to extract the id value more flexibly |
| 88 | + if let Some(id_start) = search.find("id=") { |
| 89 | + let slug = &search[id_start + 3..]; |
| 90 | + // Remove any trailing parameters |
| 91 | + let slug = if let Some(amp_pos) = slug.find('&') { |
| 92 | + &slug[..amp_pos] |
| 93 | + } else { |
| 94 | + slug |
| 95 | + }; |
| 96 | + if let Some(idx) = announcements_clone.iter().position(|(_, _, s)| *s == slug) { |
| 97 | + set_selected.set(idx); |
| 98 | + } |
| 99 | + } |
| 100 | + } |
| 101 | + }); |
| 102 | + } |
| 103 | + |
| 104 | + view! { |
| 105 | + <div class="flex flex-col w-full min-h-screen background_quaternary"> |
| 106 | + <Header background_class="background_quaternary" /> |
| 107 | + <div class="h2_mobile md:h1 px-4 md:px-10 pt-4 md:pt-20 pb-4 md:pb-20">Announcements</div> |
| 108 | + <div class="flex flex-col md:flex-row w-full flex-1 relative"> |
| 109 | + <div class="w-full md:w-[450px] h-[300px] md:h-[700px] overflow-y-auto background_tertiary z-10 p-2 md:p-6 mb-4 md:mb-0"> |
| 110 | + <ul class="space-y-2 md:space-y-4"> |
| 111 | + {announcements.iter().enumerate().map(|(i, (link, _, slug))| { |
| 112 | + let navigate = navigate.clone(); |
| 113 | + let slug = *slug; |
| 114 | + view! { |
| 115 | + <li> |
| 116 | + <button |
| 117 | + class="link_mobile md:link w-full text-left p-2 md:p-3" |
| 118 | + on:click=move |_| { |
| 119 | + set_selected.set(i); |
| 120 | + navigate(&format!("/announcements?id={}", slug), Default::default()); |
| 121 | + } |
| 122 | + > |
| 123 | + {*link} |
| 124 | + </button> |
| 125 | + </li> |
| 126 | + } |
| 127 | + }).collect::<Vec<_>>()} |
| 128 | + </ul> |
| 129 | + </div> |
| 130 | + <div class="flex-1 h-[300px] md:h-[700px] background_primary rounded-tl-[30px] md:rounded-tl-[50px] -ml-0 md:-ml-16 z-20 overflow-y-auto p-4 md:p-10"> |
| 131 | + {move || { |
| 132 | + let (title, content): (String, AnyView) = if let Some((_, title, slug)) = announcements.get(selected.get()) { |
| 133 | + let content = match *slug { |
| 134 | + "welcome-patina-announcement" => patina_press_release().into_any(), |
| 135 | + _ => view! { <p>"Content not found"</p> }.into_any(), |
| 136 | + }; |
| 137 | + (title.to_string(), content) |
| 138 | + } else { |
| 139 | + ("No announcement selected".to_string(), view! { <p>{""}</p> }.into_any()) |
| 140 | + }; |
| 141 | + view! { |
| 142 | + <div class="p_mobile md:p"> |
| 143 | + <div class="h2_mobile md:h2 pb-4 md:pb-6">{title}</div> |
| 144 | + <div class="p2_mobile md:p2"> |
| 145 | + {content} |
| 146 | + </div> |
| 147 | + </div> |
| 148 | + } |
| 149 | + }} |
| 150 | + </div> |
| 151 | + </div> |
| 152 | + <Footer /> |
| 153 | + </div> |
| 154 | + } |
| 155 | +} |
0 commit comments