-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
move around some things, add code for pfps
- Loading branch information
Showing
4 changed files
with
192 additions
and
87 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
use crate::error::Error; | ||
use crate::Target; | ||
use nostr_sdk::nips::nip19::Nip19; | ||
use nostr_sdk::prelude::*; | ||
|
||
pub fn to_target(nip19: &Nip19) -> Option<Target> { | ||
match nip19 { | ||
Nip19::Event(ev) => Some(Target::Event(ev.event_id)), | ||
Nip19::EventId(evid) => Some(Target::Event(*evid)), | ||
Nip19::Profile(prof) => Some(Target::Profile(prof.public_key)), | ||
Nip19::Pubkey(pk) => Some(Target::Profile(*pk)), | ||
Nip19::Secret(_) => None, | ||
} | ||
} | ||
|
||
pub fn to_filters(nip19: &Nip19) -> Result<Vec<Filter>, Error> { | ||
match nip19 { | ||
Nip19::Event(ev) => { | ||
let mut filters = vec![Filter::new().id(ev.event_id).limit(1)]; | ||
if let Some(author) = ev.author { | ||
filters.push(Filter::new().author(author).kind(Kind::Metadata).limit(1)) | ||
} | ||
Ok(filters) | ||
} | ||
Nip19::EventId(evid) => Ok(vec![Filter::new().id(*evid).limit(1)]), | ||
Nip19::Profile(prof) => Ok(vec![Filter::new() | ||
.author(prof.public_key) | ||
.kind(Kind::Metadata) | ||
.limit(1)]), | ||
Nip19::Pubkey(pk) => Ok(vec![Filter::new() | ||
.author(*pk) | ||
.kind(Kind::Metadata) | ||
.limit(1)]), | ||
Nip19::Secret(_sec) => Err(Error::InvalidNip19), | ||
} | ||
} | ||
|
||
pub fn to_relays(nip19: &Nip19) -> Vec<String> { | ||
let mut relays: Vec<String> = vec![]; | ||
match nip19 { | ||
Nip19::Event(ev) => relays.extend(ev.relays.clone()), | ||
Nip19::Profile(p) => relays.extend(p.relays.clone()), | ||
_ => (), | ||
} | ||
relays | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,77 @@ | ||
use egui::{Color32, ColorImage}; | ||
use image::imageops::FilterType; | ||
|
||
// Thank to gossip for this one! | ||
pub fn round_image(image: &mut ColorImage) { | ||
#[cfg(feature = "profiling")] | ||
puffin::profile_function!(); | ||
|
||
// The radius to the edge of of the avatar circle | ||
let edge_radius = image.size[0] as f32 / 2.0; | ||
let edge_radius_squared = edge_radius * edge_radius; | ||
|
||
for (pixnum, pixel) in image.pixels.iter_mut().enumerate() { | ||
// y coordinate | ||
let uy = pixnum / image.size[0]; | ||
let y = uy as f32; | ||
let y_offset = edge_radius - y; | ||
|
||
// x coordinate | ||
let ux = pixnum % image.size[0]; | ||
let x = ux as f32; | ||
let x_offset = edge_radius - x; | ||
|
||
// The radius to this pixel (may be inside or outside the circle) | ||
let pixel_radius_squared: f32 = x_offset * x_offset + y_offset * y_offset; | ||
|
||
// If inside of the avatar circle | ||
if pixel_radius_squared <= edge_radius_squared { | ||
// squareroot to find how many pixels we are from the edge | ||
let pixel_radius: f32 = pixel_radius_squared.sqrt(); | ||
let distance = edge_radius - pixel_radius; | ||
|
||
// If we are within 1 pixel of the edge, we should fade, to | ||
// antialias the edge of the circle. 1 pixel from the edge should | ||
// be 100% of the original color, and right on the edge should be | ||
// 0% of the original color. | ||
if distance <= 1.0 { | ||
*pixel = Color32::from_rgba_premultiplied( | ||
(pixel.r() as f32 * distance) as u8, | ||
(pixel.g() as f32 * distance) as u8, | ||
(pixel.b() as f32 * distance) as u8, | ||
(pixel.a() as f32 * distance) as u8, | ||
); | ||
} | ||
} else { | ||
// Outside of the avatar circle | ||
*pixel = Color32::TRANSPARENT; | ||
} | ||
} | ||
} | ||
|
||
fn process_pfp_bitmap(size: u32, image: &mut image::DynamicImage) -> ColorImage { | ||
#[cfg(features = "profiling")] | ||
puffin::profile_function!(); | ||
|
||
// Crop square | ||
let smaller = image.width().min(image.height()); | ||
|
||
if image.width() > smaller { | ||
let excess = image.width() - smaller; | ||
*image = image.crop_imm(excess / 2, 0, image.width() - excess, image.height()); | ||
} else if image.height() > smaller { | ||
let excess = image.height() - smaller; | ||
*image = image.crop_imm(0, excess / 2, image.width(), image.height() - excess); | ||
} | ||
let image = image.resize(size, size, FilterType::CatmullRom); // DynamicImage | ||
let image_buffer = image.into_rgba8(); // RgbaImage (ImageBuffer) | ||
let mut color_image = ColorImage::from_rgba_unmultiplied( | ||
[ | ||
image_buffer.width() as usize, | ||
image_buffer.height() as usize, | ||
], | ||
image_buffer.as_flat_samples().as_slice(), | ||
); | ||
round_image(&mut color_image); | ||
color_image | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
struct ProfileRenderData {} | ||
|
||
use crate::Notecrumbs; | ||
|
||
struct NoteRenderData { | ||
content: String, | ||
profile: ProfileRenderData, | ||
} | ||
|
||
enum RenderData { | ||
Note(NoteRenderData), | ||
} | ||
|
||
fn note_ui(app: &Notecrumbs, ctx: &egui::Context, content: &str) { | ||
use egui::{FontId, RichText}; | ||
|
||
egui::CentralPanel::default().show(&ctx, |ui| { | ||
ui.horizontal(|ui| { | ||
ui.label(RichText::new("✏").font(FontId::proportional(120.0))); | ||
ui.vertical(|ui| { | ||
ui.label(RichText::new(content).font(FontId::proportional(40.0))); | ||
}); | ||
}) | ||
}); | ||
} | ||
|
||
pub fn render_note(app: &Notecrumbs, content: &str) -> Vec<u8> { | ||
use egui_skia::{rasterize, RasterizeOptions}; | ||
use skia_safe::EncodedImageFormat; | ||
|
||
let options = RasterizeOptions { | ||
pixels_per_point: 1.0, | ||
frames_before_screenshot: 1, | ||
}; | ||
|
||
let mut surface = rasterize((1200, 630), |ctx| note_ui(app, ctx, content), Some(options)); | ||
|
||
surface | ||
.image_snapshot() | ||
.encode_to_data(EncodedImageFormat::PNG) | ||
.expect("expected image") | ||
.as_bytes() | ||
.into() | ||
} |