lints: Fixed the rest of the lints and some bugs along the way
This commit is contained in:
parent
452f1fc0c7
commit
02773f068f
16 changed files with 299 additions and 416 deletions
|
|
@ -13,6 +13,7 @@ use tar::Builder;
|
|||
use tracing::error;
|
||||
use zstd::Encoder;
|
||||
|
||||
#[allow(clippy::too_many_lines)]
|
||||
pub fn save(
|
||||
list: Vec<ServiceItem>,
|
||||
path: impl AsRef<Path>,
|
||||
|
|
@ -23,7 +24,7 @@ pub fn save(
|
|||
fs::remove_file(path).into_diagnostic()?;
|
||||
}
|
||||
let save_file = File::create(path).into_diagnostic()?;
|
||||
let ron = process_service_items(&list)?;
|
||||
let ron = process_service_items(&list);
|
||||
|
||||
let encoder = Encoder::new(save_file, 3)
|
||||
.expect("file encoder shouldn't fail")
|
||||
|
|
@ -58,7 +59,7 @@ pub fn save(
|
|||
}
|
||||
}
|
||||
match tar.append_file("serviceitems.ron", &mut f) {
|
||||
Ok(_) => {
|
||||
Ok(()) => {
|
||||
dbg!(
|
||||
"should have added serviceitems.ron to the file"
|
||||
);
|
||||
|
|
@ -125,7 +126,7 @@ pub fn save(
|
|||
}
|
||||
|
||||
match tar.finish() {
|
||||
Ok(_) => (),
|
||||
Ok(()) => (),
|
||||
Err(e) => {
|
||||
error!(?e);
|
||||
dbg!(&e);
|
||||
|
|
@ -135,11 +136,11 @@ pub fn save(
|
|||
fs::remove_dir_all(temp_dir).into_diagnostic()
|
||||
}
|
||||
|
||||
fn process_service_items(items: &Vec<ServiceItem>) -> Result<String> {
|
||||
Ok(items
|
||||
fn process_service_items(items: &[ServiceItem]) -> String {
|
||||
items
|
||||
.iter()
|
||||
.filter_map(|item| ron::ser::to_string(item).ok())
|
||||
.collect())
|
||||
.collect()
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
|
|
|
|||
|
|
@ -72,11 +72,10 @@ impl Content for Image {
|
|||
|
||||
fn subtext(&self) -> String {
|
||||
if self.path.exists() {
|
||||
self.path
|
||||
.file_name()
|
||||
.map_or("Missing image".into(), |f| {
|
||||
f.to_string_lossy().to_string()
|
||||
})
|
||||
self.path.file_name().map_or_else(
|
||||
|| "Missing image".into(),
|
||||
|f| f.to_string_lossy().to_string(),
|
||||
)
|
||||
} else {
|
||||
"Missing image".into()
|
||||
}
|
||||
|
|
@ -89,6 +88,7 @@ impl From<Value> for Image {
|
|||
}
|
||||
}
|
||||
|
||||
#[allow(clippy::option_if_let_else)]
|
||||
impl From<&Value> for Image {
|
||||
fn from(value: &Value) -> Self {
|
||||
match value {
|
||||
|
|
|
|||
|
|
@ -28,9 +28,11 @@ impl TryFrom<PathBuf> for ServiceItemKind {
|
|||
let ext = path
|
||||
.extension()
|
||||
.and_then(|ext| ext.to_str())
|
||||
.ok_or(miette::miette!(
|
||||
"There isn't an extension on this file"
|
||||
))?;
|
||||
.ok_or_else(|| {
|
||||
miette::miette!(
|
||||
"There isn't an extension on this file"
|
||||
)
|
||||
})?;
|
||||
match ext {
|
||||
"png" | "jpg" | "jpeg" => {
|
||||
Ok(Self::Image(Image::from(path)))
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
use std::{borrow::Cow, mem::replace, path::PathBuf};
|
||||
use std::{borrow::Cow, fs, mem::replace, path::PathBuf};
|
||||
|
||||
use cosmic::iced::clipboard::mime::{AllowedMimeTypes, AsMimeTypes};
|
||||
use miette::{IntoDiagnostic, Result, miette};
|
||||
|
|
@ -84,26 +84,36 @@ impl<T> Model<T> {
|
|||
}
|
||||
|
||||
pub fn update_item(&mut self, item: T, index: i32) -> Result<()> {
|
||||
if let Some(current_item) = self.items.get_mut(index as usize)
|
||||
{
|
||||
let _old_item = replace(current_item, item);
|
||||
Ok(())
|
||||
} else {
|
||||
Err(miette!(
|
||||
"Item doesn't exist in model. Id was {}",
|
||||
index
|
||||
))
|
||||
}
|
||||
self.items
|
||||
.get_mut(
|
||||
usize::try_from(index)
|
||||
.expect("Shouldn't be negative"),
|
||||
)
|
||||
.map_or_else(
|
||||
|| {
|
||||
Err(miette!(
|
||||
"Item doesn't exist in model. Id was {index}"
|
||||
))
|
||||
},
|
||||
|current_item| {
|
||||
let _old_item = replace(current_item, item);
|
||||
Ok(())
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
pub fn remove_item(&mut self, index: i32) -> Result<()> {
|
||||
self.items.remove(index as usize);
|
||||
self.items.remove(
|
||||
usize::try_from(index).expect("Shouldn't be negative"),
|
||||
);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub fn get_item(&self, index: i32) -> Option<&T> {
|
||||
self.items.get(index as usize)
|
||||
self.items.get(
|
||||
usize::try_from(index).expect("shouldn't be negative"),
|
||||
)
|
||||
}
|
||||
|
||||
pub fn find<P>(&self, f: P) -> Option<&T>
|
||||
|
|
@ -114,7 +124,10 @@ impl<T> Model<T> {
|
|||
}
|
||||
|
||||
pub fn insert_item(&mut self, item: T, index: i32) -> Result<()> {
|
||||
self.items.insert(index as usize, item);
|
||||
self.items.insert(
|
||||
usize::try_from(index).expect("Shouldn't be negative"),
|
||||
item,
|
||||
);
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
|
@ -131,11 +144,13 @@ impl<T> Model<T> {
|
|||
// }
|
||||
|
||||
pub async fn get_db() -> SqliteConnection {
|
||||
let mut data = dirs::data_local_dir().unwrap();
|
||||
let mut data = dirs::data_local_dir()
|
||||
.expect("Should be able to find a data dir");
|
||||
data.push("lumina");
|
||||
let _ = fs::create_dir_all(&data);
|
||||
data.push("library-db.sqlite3");
|
||||
let mut db_url = String::from("sqlite://");
|
||||
db_url.push_str(data.to_str().unwrap());
|
||||
db_url.push_str(data.to_str().expect("Should be there"));
|
||||
SqliteConnection::connect(&db_url).await.expect("problems")
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -65,27 +65,24 @@ impl From<PathBuf> for Presentation {
|
|||
.to_str()
|
||||
.unwrap_or_default()
|
||||
{
|
||||
"pdf" => {
|
||||
if let Ok(document) = Document::open(&value.as_path())
|
||||
{
|
||||
if let Ok(count) = document.page_count() {
|
||||
PresKind::Pdf {
|
||||
starting_index: 0,
|
||||
ending_index: count - 1,
|
||||
}
|
||||
} else {
|
||||
"pdf" => Document::open(&value.as_path()).map_or(
|
||||
PresKind::Pdf {
|
||||
starting_index: 0,
|
||||
ending_index: 0,
|
||||
},
|
||||
|document| {
|
||||
document.page_count().map_or(
|
||||
PresKind::Pdf {
|
||||
starting_index: 0,
|
||||
ending_index: 0,
|
||||
}
|
||||
}
|
||||
} else {
|
||||
PresKind::Pdf {
|
||||
starting_index: 0,
|
||||
ending_index: 0,
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|count| PresKind::Pdf {
|
||||
starting_index: 0,
|
||||
ending_index: count - 1,
|
||||
},
|
||||
)
|
||||
},
|
||||
),
|
||||
"html" => PresKind::Html,
|
||||
_ => PresKind::Generic,
|
||||
};
|
||||
|
|
@ -129,11 +126,10 @@ impl Content for Presentation {
|
|||
|
||||
fn subtext(&self) -> String {
|
||||
if self.path.exists() {
|
||||
self.path
|
||||
.file_name()
|
||||
.map_or("Missing presentation".into(), |f| {
|
||||
f.to_string_lossy().to_string()
|
||||
})
|
||||
self.path.file_name().map_or_else(
|
||||
|| "Missing presentation".into(),
|
||||
|f| f.to_string_lossy().to_string(),
|
||||
)
|
||||
} else {
|
||||
"Missing presentation".into()
|
||||
}
|
||||
|
|
@ -146,6 +142,7 @@ impl From<Value> for Presentation {
|
|||
}
|
||||
}
|
||||
|
||||
#[allow(clippy::option_if_let_else)]
|
||||
impl From<&Value> for Presentation {
|
||||
fn from(value: &Value) -> Self {
|
||||
match value {
|
||||
|
|
@ -206,15 +203,14 @@ impl ServiceTrait for Presentation {
|
|||
let pages: Vec<Handle> = pages
|
||||
.enumerate()
|
||||
.filter_map(|(index, page)| {
|
||||
if (index as i32) < starting_index {
|
||||
return None;
|
||||
} else if (index as i32) > ending_index {
|
||||
let index = i32::try_from(index)
|
||||
.expect("Shouldn't be that high");
|
||||
|
||||
if index < starting_index || index > ending_index {
|
||||
return None;
|
||||
}
|
||||
|
||||
let Some(page) = page.ok() else {
|
||||
return None;
|
||||
};
|
||||
let page = page.ok()?;
|
||||
let matrix = Matrix::IDENTITY;
|
||||
let colorspace = Colorspace::device_rgb();
|
||||
let Ok(pixmap) = page
|
||||
|
|
@ -248,7 +244,10 @@ impl ServiceTrait for Presentation {
|
|||
.video_loop(false)
|
||||
.video_start_time(0.0)
|
||||
.video_end_time(0.0)
|
||||
.pdf_index(index as u32)
|
||||
.pdf_index(
|
||||
u32::try_from(index)
|
||||
.expect("Shouldn't get that high"),
|
||||
)
|
||||
.pdf_page(page)
|
||||
.build()?;
|
||||
slides.push(slide);
|
||||
|
|
@ -334,32 +333,38 @@ impl Model<Presentation> {
|
|||
presentation.ending_index,
|
||||
) {
|
||||
PresKind::Pdf {
|
||||
starting_index: starting_index as i32,
|
||||
ending_index: ending_index as i32,
|
||||
starting_index: i32::try_from(
|
||||
starting_index,
|
||||
)
|
||||
.expect("Shouldn't get that high"),
|
||||
ending_index: i32::try_from(
|
||||
ending_index,
|
||||
)
|
||||
.expect("Shouldn't get that high"),
|
||||
}
|
||||
} else {
|
||||
let path =
|
||||
PathBuf::from(presentation.path);
|
||||
if let Ok(document) =
|
||||
Document::open(path.as_path())
|
||||
{
|
||||
if let Ok(count) =
|
||||
document.page_count()
|
||||
{
|
||||
let ending_index = count - 1;
|
||||
PresKind::Pdf {
|
||||
starting_index: 0,
|
||||
ending_index,
|
||||
}
|
||||
} else {
|
||||
PresKind::Pdf {
|
||||
starting_index: 0,
|
||||
ending_index: 0,
|
||||
}
|
||||
}
|
||||
} else {
|
||||
PresKind::Generic
|
||||
}
|
||||
|
||||
Document::open(path.as_path()).map_or(
|
||||
PresKind::Generic,
|
||||
|document| {
|
||||
document.page_count().map_or(
|
||||
PresKind::Pdf {
|
||||
starting_index: 0,
|
||||
ending_index: 0,
|
||||
},
|
||||
|count| {
|
||||
let ending_index =
|
||||
count - 1;
|
||||
PresKind::Pdf {
|
||||
starting_index: 0,
|
||||
ending_index,
|
||||
}
|
||||
},
|
||||
)
|
||||
},
|
||||
)
|
||||
},
|
||||
});
|
||||
}
|
||||
|
|
@ -416,16 +421,16 @@ pub async fn update_presentation_in_db(
|
|||
.unwrap_or_default();
|
||||
let html = presentation.kind == PresKind::Html;
|
||||
let mut db = db.detach();
|
||||
let mut starting_index = 0;
|
||||
let mut ending_index = 0;
|
||||
if let PresKind::Pdf {
|
||||
let (starting_index, ending_index) = if let PresKind::Pdf {
|
||||
starting_index: s_index,
|
||||
ending_index: e_index,
|
||||
} = presentation.get_kind()
|
||||
} =
|
||||
presentation.get_kind()
|
||||
{
|
||||
starting_index = *s_index;
|
||||
ending_index = *e_index;
|
||||
}
|
||||
(*s_index, *e_index)
|
||||
} else {
|
||||
(0, 0)
|
||||
};
|
||||
let id = presentation.id;
|
||||
if let Err(e) =
|
||||
query!("SELECT id FROM presentations where id = $1", id)
|
||||
|
|
|
|||
|
|
@ -32,7 +32,7 @@ impl Eq for ServiceItem {}
|
|||
|
||||
impl PartialOrd for ServiceItem {
|
||||
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
|
||||
self.id.partial_cmp(&other.id)
|
||||
Some(self.cmp(other))
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -89,9 +89,11 @@ impl TryFrom<PathBuf> for ServiceItem {
|
|||
let ext = path
|
||||
.extension()
|
||||
.and_then(|ext| ext.to_str())
|
||||
.ok_or(miette::miette!(
|
||||
"There isn't an extension on this file"
|
||||
))?;
|
||||
.ok_or_else(|| {
|
||||
miette::miette!(
|
||||
"There isn't an extension on this file"
|
||||
)
|
||||
})?;
|
||||
match ext {
|
||||
"png" | "jpg" | "jpeg" => {
|
||||
Ok(Self::from(&Image::from(path)))
|
||||
|
|
@ -157,6 +159,8 @@ impl From<Value> for ServiceItem {
|
|||
}
|
||||
}
|
||||
|
||||
#[allow(clippy::option_if_let_else)]
|
||||
#[allow(clippy::match_like_matches_macro)]
|
||||
impl From<&Value> for ServiceItem {
|
||||
fn from(value: &Value) -> Self {
|
||||
match value {
|
||||
|
|
@ -280,64 +284,61 @@ impl From<Vec<ServiceItem>> for Service {
|
|||
|
||||
impl From<&Song> for ServiceItem {
|
||||
fn from(song: &Song) -> Self {
|
||||
if let Ok(slides) = song.to_slides() {
|
||||
Self {
|
||||
song.to_slides().map_or_else(
|
||||
|_| Self {
|
||||
kind: ServiceItemKind::Song(song.clone()),
|
||||
database_id: song.id,
|
||||
title: song.title.clone(),
|
||||
..Default::default()
|
||||
},
|
||||
|slides| Self {
|
||||
kind: ServiceItemKind::Song(song.clone()),
|
||||
database_id: song.id,
|
||||
title: song.title.clone(),
|
||||
slides,
|
||||
..Default::default()
|
||||
}
|
||||
} else {
|
||||
Self {
|
||||
kind: ServiceItemKind::Song(song.clone()),
|
||||
database_id: song.id,
|
||||
title: song.title.clone(),
|
||||
..Default::default()
|
||||
}
|
||||
}
|
||||
},
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<&Video> for ServiceItem {
|
||||
fn from(video: &Video) -> Self {
|
||||
if let Ok(slides) = video.to_slides() {
|
||||
Self {
|
||||
video.to_slides().map_or_else(
|
||||
|_| Self {
|
||||
kind: ServiceItemKind::Video(video.clone()),
|
||||
database_id: video.id,
|
||||
title: video.title.clone(),
|
||||
..Default::default()
|
||||
},
|
||||
|slides| Self {
|
||||
kind: ServiceItemKind::Video(video.clone()),
|
||||
database_id: video.id,
|
||||
title: video.title.clone(),
|
||||
slides,
|
||||
..Default::default()
|
||||
}
|
||||
} else {
|
||||
Self {
|
||||
kind: ServiceItemKind::Video(video.clone()),
|
||||
database_id: video.id,
|
||||
title: video.title.clone(),
|
||||
..Default::default()
|
||||
}
|
||||
}
|
||||
},
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<&Image> for ServiceItem {
|
||||
fn from(image: &Image) -> Self {
|
||||
if let Ok(slides) = image.to_slides() {
|
||||
Self {
|
||||
image.to_slides().map_or_else(
|
||||
|_| Self {
|
||||
kind: ServiceItemKind::Image(image.clone()),
|
||||
database_id: image.id,
|
||||
title: image.title.clone(),
|
||||
..Default::default()
|
||||
},
|
||||
|slides| Self {
|
||||
kind: ServiceItemKind::Image(image.clone()),
|
||||
database_id: image.id,
|
||||
title: image.title.clone(),
|
||||
slides,
|
||||
..Default::default()
|
||||
}
|
||||
} else {
|
||||
Self {
|
||||
kind: ServiceItemKind::Image(image.clone()),
|
||||
database_id: image.id,
|
||||
title: image.title.clone(),
|
||||
..Default::default()
|
||||
}
|
||||
}
|
||||
},
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -370,13 +371,9 @@ impl From<&Presentation> for ServiceItem {
|
|||
|
||||
#[allow(unused)]
|
||||
impl Service {
|
||||
fn add_item(
|
||||
&mut self,
|
||||
item: impl Into<ServiceItem>,
|
||||
) -> Result<()> {
|
||||
fn add_item(&mut self, item: impl Into<ServiceItem>) {
|
||||
let service_item: ServiceItem = item.into();
|
||||
self.items.push(service_item);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn to_slides(&self) -> Result<Vec<Slide>> {
|
||||
|
|
@ -392,7 +389,7 @@ impl Service {
|
|||
.collect::<Vec<Slide>>();
|
||||
let mut final_slides = vec![];
|
||||
for (index, mut slide) in slides.into_iter().enumerate() {
|
||||
slide.set_index(index as i32);
|
||||
slide.set_index(i32::try_from(index).into_diagnostic()?);
|
||||
final_slides.push(slide);
|
||||
}
|
||||
Ok(final_slides)
|
||||
|
|
@ -455,19 +452,15 @@ mod test {
|
|||
let pres = test_presentation();
|
||||
let pres_item = ServiceItem::from(&pres);
|
||||
let mut service_model = Service::default();
|
||||
match service_model.add_item(&song) {
|
||||
Ok(_) => {
|
||||
assert_eq!(
|
||||
ServiceItemKind::Song(song),
|
||||
service_model.items[0].kind
|
||||
);
|
||||
assert_eq!(
|
||||
ServiceItemKind::Presentation(pres),
|
||||
pres_item.kind
|
||||
);
|
||||
assert_eq!(service_item, service_model.items[0]);
|
||||
}
|
||||
Err(e) => panic!("Problem adding item: {:?}", e),
|
||||
}
|
||||
service_model.add_item(&song);
|
||||
assert_eq!(
|
||||
ServiceItemKind::Song(song),
|
||||
service_model.items[0].kind
|
||||
);
|
||||
assert_eq!(
|
||||
ServiceItemKind::Presentation(pres),
|
||||
pres_item.kind
|
||||
);
|
||||
assert_eq!(service_item, service_model.items[0]);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -136,12 +136,15 @@ impl TryFrom<PathBuf> for Background {
|
|||
type Error = ParseError;
|
||||
fn try_from(path: PathBuf) -> Result<Self, Self::Error> {
|
||||
let path = if path.starts_with("~") {
|
||||
let path = path.to_str().unwrap().to_string();
|
||||
let path = path
|
||||
.to_str()
|
||||
.expect("Should have a string")
|
||||
.to_string();
|
||||
let path = path.trim_start_matches("file://");
|
||||
let home = dirs::home_dir()
|
||||
.unwrap()
|
||||
.expect("We should have a home directory")
|
||||
.to_str()
|
||||
.unwrap()
|
||||
.expect("Gah")
|
||||
.to_string();
|
||||
let path = path.replace('~', &home);
|
||||
PathBuf::from(path)
|
||||
|
|
@ -189,16 +192,18 @@ impl TryFrom<&str> for Background {
|
|||
fn try_from(value: &str) -> Result<Self, Self::Error> {
|
||||
let value = value.trim_start_matches("file://");
|
||||
if value.starts_with('~') {
|
||||
if let Some(home) = dirs::home_dir() {
|
||||
if let Some(home) = home.to_str() {
|
||||
let value = value.replace('~', home);
|
||||
Self::try_from(PathBuf::from(value))
|
||||
} else {
|
||||
Self::try_from(PathBuf::from(value))
|
||||
}
|
||||
} else {
|
||||
Self::try_from(PathBuf::from(value))
|
||||
}
|
||||
dirs::home_dir().map_or_else(
|
||||
|| Self::try_from(PathBuf::from(value)),
|
||||
|home| {
|
||||
home.to_str().map_or_else(
|
||||
|| Self::try_from(PathBuf::from(value)),
|
||||
|home| {
|
||||
let value = value.replace('~', home);
|
||||
Self::try_from(PathBuf::from(value))
|
||||
},
|
||||
)
|
||||
},
|
||||
)
|
||||
} else if value.starts_with("./") {
|
||||
Err(ParseError::CannotCanonicalize)
|
||||
} else {
|
||||
|
|
@ -262,95 +267,116 @@ impl From<&Slide> for Value {
|
|||
}
|
||||
|
||||
impl Slide {
|
||||
#[must_use]
|
||||
pub fn set_text(mut self, text: impl AsRef<str>) -> Self {
|
||||
self.text = text.as_ref().into();
|
||||
self
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub fn with_text_svg(mut self, text_svg: TextSvg) -> Self {
|
||||
self.text_svg = Some(text_svg);
|
||||
self
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub fn set_font(mut self, font: impl AsRef<str>) -> Self {
|
||||
self.font = Some(font.as_ref().into());
|
||||
self
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub const fn set_font_size(mut self, font_size: i32) -> Self {
|
||||
self.font_size = font_size;
|
||||
self
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub fn set_audio(mut self, audio: Option<PathBuf>) -> Self {
|
||||
self.audio = audio;
|
||||
self
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub const fn set_pdf_index(mut self, pdf_index: u32) -> Self {
|
||||
self.pdf_index = pdf_index;
|
||||
self
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub const fn set_stroke(mut self, stroke: Stroke) -> Self {
|
||||
self.stroke = Some(stroke);
|
||||
self
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub const fn set_shadow(mut self, shadow: Shadow) -> Self {
|
||||
self.shadow = Some(shadow);
|
||||
self
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub const fn set_text_color(mut self, color: Color) -> Self {
|
||||
self.text_color = Some(color);
|
||||
self
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub const fn background(&self) -> &Background {
|
||||
&self.background
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub fn text(&self) -> String {
|
||||
self.text.clone()
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub const fn text_alignment(&self) -> TextAlignment {
|
||||
self.text_alignment
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub const fn font_size(&self) -> i32 {
|
||||
self.font_size
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub fn font(&self) -> Option<Font> {
|
||||
self.font.clone()
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub const fn video_loop(&self) -> bool {
|
||||
self.video_loop
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub fn audio(&self) -> Option<PathBuf> {
|
||||
self.audio.clone()
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub fn pdf_page(&self) -> Option<Handle> {
|
||||
self.pdf_page.clone()
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub fn text_color(&self) -> Option<Color> {
|
||||
self.text_color.clone()
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub fn stroke(&self) -> Option<Stroke> {
|
||||
self.stroke.clone()
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub fn shadow(&self) -> Option<Shadow> {
|
||||
self.shadow.clone()
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub const fn pdf_index(&self) -> u32 {
|
||||
self.pdf_index
|
||||
}
|
||||
|
|
@ -405,7 +431,8 @@ impl From<&Value> for Slide {
|
|||
}
|
||||
}
|
||||
|
||||
fn lisp_to_slide(lisp: &Vec<Value>) -> Slide {
|
||||
#[allow(clippy::option_if_let_else)]
|
||||
fn lisp_to_slide(lisp: &[Value]) -> Slide {
|
||||
const DEFAULT_BACKGROUND_LOCATION: usize = 1;
|
||||
const DEFAULT_TEXT_LOCATION: usize = 0;
|
||||
|
||||
|
|
@ -469,6 +496,7 @@ fn lisp_to_slide(lisp: &Vec<Value>) -> Slide {
|
|||
}
|
||||
}
|
||||
|
||||
#[allow(clippy::option_if_let_else)]
|
||||
fn lisp_to_font_size(lisp: &Value) -> i32 {
|
||||
match lisp {
|
||||
Value::List(list) => {
|
||||
|
|
@ -501,6 +529,7 @@ fn lisp_to_text(lisp: &Value) -> impl Into<String> {
|
|||
|
||||
// Need to return a Result here so that we can propogate
|
||||
// errors and then handle them appropriately
|
||||
#[allow(clippy::option_if_let_else)]
|
||||
pub fn lisp_to_background(lisp: &Value) -> Background {
|
||||
match lisp {
|
||||
Value::List(list) => {
|
||||
|
|
|
|||
|
|
@ -35,10 +35,7 @@ pub async fn search_online_song_links(
|
|||
|
||||
Ok(document
|
||||
.select(&best_matches_selector)
|
||||
.filter_map(|best_section| {
|
||||
Some(best_section.select(&lyric_selector))
|
||||
})
|
||||
.flatten()
|
||||
.flat_map(|best_section| best_section.select(&lyric_selector))
|
||||
.map(|a| {
|
||||
a.value().attr("href").unwrap_or("").trim().to_string()
|
||||
})
|
||||
|
|
@ -52,13 +49,17 @@ pub async fn search_online_song_links(
|
|||
.collect())
|
||||
}
|
||||
|
||||
// leaving this lint unfixed because I don't know if we will need this
|
||||
// id value or not in the future and I'd like to keep the code understanding
|
||||
// of what this variable might be.
|
||||
#[allow(clippy::no_effect_underscore_binding)]
|
||||
pub async fn link_to_online_song(
|
||||
links: Vec<impl AsRef<str> + std::fmt::Display>,
|
||||
) -> Result<Vec<OnlineSong>> {
|
||||
let mut songs = vec![];
|
||||
for link in links {
|
||||
let parts = link
|
||||
.to_string()
|
||||
.as_ref()
|
||||
.split('/')
|
||||
.map(std::string::ToString::to_string)
|
||||
.collect::<Vec<String>>();
|
||||
|
|
|
|||
|
|
@ -85,8 +85,8 @@ pub enum VerseName {
|
|||
|
||||
impl VerseName {
|
||||
#[must_use]
|
||||
pub fn from_string(name: String) -> Self {
|
||||
match name.as_str() {
|
||||
pub fn from_string(name: &str) -> Self {
|
||||
match name {
|
||||
"Verse" => Self::Verse { number: 1 },
|
||||
"Pre-Chorus" => Self::PreChorus { number: 1 },
|
||||
"Chorus" => Self::Chorus { number: 1 },
|
||||
|
|
@ -96,7 +96,7 @@ impl VerseName {
|
|||
"Outro" => Self::Outro { number: 1 },
|
||||
"Instrumental" => Self::Instrumental { number: 1 },
|
||||
"Other" => Self::Other { number: 1 },
|
||||
"Blank" => Self::Blank,
|
||||
// Blank is included in wildcard
|
||||
_ => Self::Blank,
|
||||
}
|
||||
}
|
||||
|
|
@ -260,7 +260,9 @@ impl Content for Song {
|
|||
}
|
||||
|
||||
fn subtext(&self) -> String {
|
||||
self.author.clone().unwrap_or("Author missing".into())
|
||||
self.author
|
||||
.clone()
|
||||
.unwrap_or_else(|| "Author missing".into())
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -278,7 +280,9 @@ impl ServiceTrait for Song {
|
|||
let lyrics: Vec<String> = self
|
||||
.verses
|
||||
.as_ref()
|
||||
.ok_or(miette!("There are no verses assigned yet."))?
|
||||
.ok_or_else(|| {
|
||||
miette!("There are no verses assigned yet.")
|
||||
})?
|
||||
.iter()
|
||||
.filter_map(|verse| self.get_lyric(verse))
|
||||
.flat_map(|lyric| {
|
||||
|
|
@ -299,13 +303,12 @@ impl ServiceTrait for Song {
|
|||
.clone()
|
||||
.unwrap_or_else(|| "Calibri".into()),
|
||||
)
|
||||
.style(
|
||||
self.font_style.clone().unwrap_or_default(),
|
||||
)
|
||||
.weight(
|
||||
self.font_weight.clone().unwrap_or_default(),
|
||||
)
|
||||
.size(self.font_size.unwrap_or(100) as u8);
|
||||
.style(self.font_style.unwrap_or_default())
|
||||
.weight(self.font_weight.unwrap_or_default())
|
||||
.size(
|
||||
u8::try_from(self.font_size.unwrap_or(100))
|
||||
.unwrap_or(100),
|
||||
);
|
||||
let stroke_size =
|
||||
self.stroke_size.unwrap_or_default();
|
||||
let stroke: Stroke = stroke(
|
||||
|
|
@ -367,22 +370,11 @@ impl ServiceTrait for Song {
|
|||
}
|
||||
}
|
||||
|
||||
#[allow(clippy::too_many_lines)]
|
||||
impl FromRow<'_, SqliteRow> for Song {
|
||||
fn from_row(row: &SqliteRow) -> sqlx::Result<Self> {
|
||||
let lyrics: &str = row.try_get("lyrics")?;
|
||||
|
||||
// let Some((mut verses, mut verse_map)) =
|
||||
// lyrics_to_verse(lyrics.clone()).ok()
|
||||
// else {
|
||||
// return Err(sqlx::Error::ColumnDecode {
|
||||
// index: "8".into(),
|
||||
// source: miette!(
|
||||
// "Couldn't decode the song into verses"
|
||||
// )
|
||||
// .into(),
|
||||
// });
|
||||
// };
|
||||
|
||||
let Ok(verse_map) = ron::de::from_str::<
|
||||
Option<HashMap<VerseName, String>>,
|
||||
>(lyrics) else {
|
||||
|
|
@ -508,6 +500,9 @@ impl From<Value> for Song {
|
|||
}
|
||||
}
|
||||
|
||||
#[allow(clippy::option_if_let_else)]
|
||||
#[allow(clippy::needless_pass_by_value)]
|
||||
#[allow(clippy::too_many_lines)]
|
||||
pub fn lisp_to_song(list: Vec<Value>) -> Song {
|
||||
const DEFAULT_SONG_ID: i32 = 0;
|
||||
// const DEFAULT_SONG_LOCATION: usize = 0;
|
||||
|
|
@ -586,7 +581,8 @@ pub fn lisp_to_song(list: Vec<Value>) -> Song {
|
|||
.position(|v| v == &Value::Keyword(Keyword::from("title")))
|
||||
{
|
||||
let pos = key_pos + 1;
|
||||
list.get(pos).map_or(String::from("song"), String::from)
|
||||
list.get(pos)
|
||||
.map_or_else(|| String::from("song"), String::from)
|
||||
} else {
|
||||
String::from("song")
|
||||
};
|
||||
|
|
@ -629,10 +625,7 @@ pub fn lisp_to_song(list: Vec<Value>) -> Song {
|
|||
|| text.contains("i1")
|
||||
}
|
||||
_ => false,
|
||||
} && match &inner[1] {
|
||||
Value::String(_) => true,
|
||||
_ => false,
|
||||
})
|
||||
} && matches!(&inner[1], Value::String(_)))
|
||||
}
|
||||
_ => false,
|
||||
})
|
||||
|
|
@ -654,7 +647,7 @@ pub fn lisp_to_song(list: Vec<Value>) -> Song {
|
|||
|
||||
let verse_title = match lyric_verse.as_str() {
|
||||
"i1" => r"\n\nIntro 1\n",
|
||||
"i2" => r"\n\nIntro 1\n",
|
||||
"i2" => r"\n\nIntro 2\n",
|
||||
"v1" => r"\n\nVerse 1\n",
|
||||
"v2" => r"\n\nVerse 2\n",
|
||||
"v3" => r"\n\nVerse 3\n",
|
||||
|
|
@ -722,7 +715,7 @@ impl Model<Song> {
|
|||
|
||||
pub async fn load_from_db(&mut self, db: &mut SqlitePool) {
|
||||
// static DATABASE_URL: &str = "sqlite:///home/chris/.local/share/lumina/library-db.sqlite3";
|
||||
let db1 = db.acquire().await.unwrap();
|
||||
let db1 = db.acquire().await.expect("Database not found");
|
||||
let result = query("SELECT verse_order, font_size, background_type, horizontal_text_alignment, vertical_text_alignment, title, font, background, lyrics, ccli, author, audio, stroke_size, shadow_size, stroke_color, shadow_color, shadow_offset_x, shadow_offset_y, id from songs").fetch_all(&mut db1.detach()).await;
|
||||
match result {
|
||||
Ok(s) => {
|
||||
|
|
@ -766,16 +759,14 @@ pub async fn add_song_to_db(
|
|||
let mut song = Song::default();
|
||||
|
||||
let verse_order = {
|
||||
if let Some(vo) = song.verse_order.clone() {
|
||||
song.verse_order.clone().map_or_else(String::new, |vo| {
|
||||
vo.into_iter()
|
||||
.map(|mut s| {
|
||||
s.push(' ');
|
||||
s
|
||||
})
|
||||
.collect::<String>()
|
||||
} else {
|
||||
String::new()
|
||||
}
|
||||
})
|
||||
};
|
||||
|
||||
let audio = song
|
||||
|
|
@ -803,7 +794,9 @@ pub async fn add_song_to_db(
|
|||
.execute(&mut db)
|
||||
.await
|
||||
.into_diagnostic()?;
|
||||
song.id = res.last_insert_rowid() as i32;
|
||||
song.id = i32::try_from(res.last_insert_rowid()).expect(
|
||||
"Fairly confident that this number won't get that high",
|
||||
);
|
||||
Ok(song)
|
||||
}
|
||||
|
||||
|
|
@ -921,7 +914,7 @@ impl Song {
|
|||
verse_map
|
||||
.entry(*verse)
|
||||
.and_modify(|old_lyrics| {
|
||||
*old_lyrics = lyric_copy.clone();
|
||||
old_lyrics.clone_from(&lyric_copy);
|
||||
})
|
||||
.or_insert(lyric_copy);
|
||||
// debug!(?verse_map, "should be updated");
|
||||
|
|
@ -935,10 +928,6 @@ impl Song {
|
|||
}
|
||||
|
||||
pub fn get_lyrics(&self) -> Result<Vec<String>> {
|
||||
// ---------------------------------
|
||||
// new implementation
|
||||
// ---------------------------------
|
||||
|
||||
if let Some(verses) = self.verses.as_ref() {
|
||||
let mut lyrics = vec![];
|
||||
for verse in verses {
|
||||
|
|
@ -952,73 +941,7 @@ impl Song {
|
|||
}
|
||||
return Ok(lyrics);
|
||||
}
|
||||
return Err(miette!("No verses in this song yet"));
|
||||
|
||||
// ---------------------------------
|
||||
// old implementation
|
||||
// ---------------------------------
|
||||
|
||||
// let mut lyric_list = Vec::new();
|
||||
// if self.lyrics.is_none() {
|
||||
// return Err(miette!("There is no lyrics here"));
|
||||
// } else if self.verse_order.is_none() {
|
||||
// return Err(miette!("There is no verse_order here"));
|
||||
// } else if self
|
||||
// .verse_order
|
||||
// .clone()
|
||||
// .is_some_and(|v| v.is_empty())
|
||||
// {
|
||||
// return Err(miette!("There is no verse_order here"));
|
||||
// }
|
||||
// if let Some(raw_lyrics) = self.lyrics.clone() {
|
||||
// let raw_lyrics = raw_lyrics.as_str();
|
||||
// let verse_order = self.verses.clone();
|
||||
|
||||
// let mut lyric_map = HashMap::new();
|
||||
// let mut verse_title = String::new();
|
||||
// let mut lyric = String::new();
|
||||
// for (i, line) in raw_lyrics.split('\n').enumerate() {
|
||||
// if VERSE_KEYWORDS.contains(&line) {
|
||||
// if i != 0 {
|
||||
// lyric_map.insert(verse_title, lyric);
|
||||
// lyric = String::new();
|
||||
// verse_title = line.to_string();
|
||||
// } else {
|
||||
// verse_title = line.to_string();
|
||||
// }
|
||||
// } else {
|
||||
// lyric.push_str(line);
|
||||
// lyric.push('\n');
|
||||
// }
|
||||
// }
|
||||
// lyric_map.insert(verse_title, lyric);
|
||||
|
||||
// for verse in verse_order.unwrap_or_default() {
|
||||
// let verse_name = &verse.get_name();
|
||||
// if let Some(lyric) = lyric_map.get(verse_name) {
|
||||
// if lyric.contains("\n\n") {
|
||||
// let split_lyrics: Vec<&str> =
|
||||
// lyric.split("\n\n").collect();
|
||||
// for lyric in split_lyrics {
|
||||
// if lyric.is_empty() {
|
||||
// continue;
|
||||
// }
|
||||
// lyric_list.push(lyric.to_string());
|
||||
// }
|
||||
// continue;
|
||||
// }
|
||||
// lyric_list.push(lyric.clone());
|
||||
// } else {
|
||||
// // error!("NOT WORKING!");
|
||||
// }
|
||||
// }
|
||||
// // for lyric in lyric_list.iter() {
|
||||
// // debug!(lyric = ?lyric)
|
||||
// // }
|
||||
// Ok(lyric_list)
|
||||
// } else {
|
||||
// Err(miette!("There are no lyrics"))
|
||||
// }
|
||||
Err(miette!("No verses in this song yet"))
|
||||
}
|
||||
|
||||
pub fn update_verse_name(
|
||||
|
|
@ -1123,39 +1046,28 @@ impl Song {
|
|||
#[must_use]
|
||||
pub fn get_next_verse_name(&self) -> VerseName {
|
||||
if let Some(verse_names) = &self.verses {
|
||||
let verses: Vec<&VerseName> = verse_names
|
||||
let verses = verse_names
|
||||
.iter()
|
||||
.filter(|verse| match verse {
|
||||
VerseName::Verse { .. } => true,
|
||||
_ => false,
|
||||
.filter(|verse| {
|
||||
matches!(verse, VerseName::Verse { .. })
|
||||
})
|
||||
.sorted()
|
||||
.collect();
|
||||
let choruses: Vec<&VerseName> = verse_names
|
||||
.iter()
|
||||
.filter(|verse| match verse {
|
||||
VerseName::Chorus { .. } => true,
|
||||
_ => false,
|
||||
})
|
||||
.collect();
|
||||
let bridges: Vec<&VerseName> = verse_names
|
||||
.iter()
|
||||
.filter(|verse| match verse {
|
||||
VerseName::Bridge { .. } => true,
|
||||
_ => false,
|
||||
})
|
||||
.collect();
|
||||
if verses.is_empty() {
|
||||
.sorted();
|
||||
let mut choruses = verse_names.iter().filter(|verse| {
|
||||
matches!(verse, VerseName::Chorus { .. })
|
||||
});
|
||||
let mut bridges = verse_names.iter().filter(|verse| {
|
||||
matches!(verse, VerseName::Bridge { .. })
|
||||
});
|
||||
if verses.len() == 0 {
|
||||
VerseName::Verse { number: 1 }
|
||||
} else if choruses.is_empty() {
|
||||
} else if choruses.next().is_none() {
|
||||
VerseName::Chorus { number: 1 }
|
||||
} else if verses.len() == 1 {
|
||||
let verse_number =
|
||||
if let Some(last_verse) = verses.iter().last() {
|
||||
match last_verse {
|
||||
VerseName::Verse { number } => *number,
|
||||
_ => 0,
|
||||
}
|
||||
if let Some(VerseName::Verse { number }) =
|
||||
verses.last()
|
||||
{
|
||||
*number
|
||||
} else {
|
||||
0
|
||||
};
|
||||
|
|
@ -1163,10 +1075,10 @@ impl Song {
|
|||
return VerseName::Verse { number: 1 };
|
||||
}
|
||||
VerseName::Verse { number: 2 }
|
||||
} else if bridges.is_empty() {
|
||||
} else if bridges.next().is_none() {
|
||||
VerseName::Bridge { number: 1 }
|
||||
} else {
|
||||
if let Some(last_verse) = verses.iter().last()
|
||||
if let Some(last_verse) = verses.last()
|
||||
&& let VerseName::Verse { number } = last_verse
|
||||
{
|
||||
return VerseName::Verse { number: number + 1 };
|
||||
|
|
@ -1194,17 +1106,15 @@ impl Song {
|
|||
|
||||
pub(crate) fn verse_name_from_str(
|
||||
&self,
|
||||
verse_name: String, // chorus 2
|
||||
verse_name: &str, // chorus 2
|
||||
old_verse_name: VerseName, // v4
|
||||
) -> VerseName {
|
||||
if old_verse_name.get_name() == verse_name {
|
||||
return old_verse_name;
|
||||
}
|
||||
if let Some(verses) =
|
||||
self.verse_map.clone().map(|verse_map| {
|
||||
self.verse_map.clone().map(|verse_map| {
|
||||
verse_map.into_keys().collect::<Vec<VerseName>>()
|
||||
})
|
||||
{
|
||||
}).map_or_else(|| VerseName::from_string(verse_name), |verses| {
|
||||
verses
|
||||
.into_iter()
|
||||
.filter(|verse| {
|
||||
|
|
@ -1212,7 +1122,7 @@ impl Song {
|
|||
.get_name()
|
||||
.split_whitespace()
|
||||
.next()
|
||||
.unwrap()
|
||||
.expect("Shouldn't fail, the get_name() fn won't return a string that is blank or all whitespace")
|
||||
== verse_name
|
||||
})
|
||||
.sorted()
|
||||
|
|
@ -1221,9 +1131,7 @@ impl Song {
|
|||
|| VerseName::from_string(verse_name),
|
||||
|verse_name| verse_name.next(),
|
||||
)
|
||||
} else {
|
||||
VerseName::from_string(verse_name)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
pub(crate) fn delete_verse(&mut self, verse: VerseName) {
|
||||
|
|
|
|||
|
|
@ -90,6 +90,7 @@ impl From<Value> for Video {
|
|||
}
|
||||
}
|
||||
|
||||
#[allow(clippy::cast_precision_loss)]
|
||||
impl From<&Value> for Video {
|
||||
fn from(value: &Value) -> Self {
|
||||
match value {
|
||||
|
|
|
|||
|
|
@ -41,7 +41,6 @@ use miette::{IntoDiagnostic, Result, miette};
|
|||
use rayon::prelude::*;
|
||||
use resvg::usvg::fontdb;
|
||||
use std::collections::HashMap;
|
||||
use std::fs::read_to_string;
|
||||
use std::path::PathBuf;
|
||||
use std::sync::Arc;
|
||||
use tracing::{debug, level_filters::LevelFilter};
|
||||
|
|
|
|||
|
|
@ -27,6 +27,7 @@ use cosmic::{
|
|||
menu, mouse_area, responsive, scrollable, text,
|
||||
},
|
||||
};
|
||||
use derive_more::Debug;
|
||||
use iced_video_player::{Position, Video, VideoPlayer, gst_pbutils};
|
||||
use rodio::{Decoder, OutputStream, OutputStreamBuilder, Sink};
|
||||
use tracing::{debug, error, info, warn};
|
||||
|
|
@ -41,7 +42,7 @@ use crate::{
|
|||
},
|
||||
};
|
||||
|
||||
const REFERENCE_WIDTH: f32 = 1920.0;
|
||||
// const REFERENCE_WIDTH: f32 = 1920.0;
|
||||
static DEFAULT_SLIDE: LazyLock<Slide> = LazyLock::new(Slide::default);
|
||||
|
||||
// #[derive(Default, Clone, Debug)]
|
||||
|
|
@ -73,8 +74,8 @@ pub(crate) enum Action {
|
|||
None,
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
#[allow(clippy::large_enum_variant)]
|
||||
#[derive(Clone, Debug)]
|
||||
pub(crate) enum Message {
|
||||
NextSlide,
|
||||
PrevSlide,
|
||||
|
|
@ -83,7 +84,7 @@ pub(crate) enum Message {
|
|||
ClickSlide(usize, usize),
|
||||
EndVideo,
|
||||
StartVideo,
|
||||
StartAudio,
|
||||
// StartAudio,
|
||||
EndAudio,
|
||||
VideoPos(f32),
|
||||
VideoFrame,
|
||||
|
|
@ -95,80 +96,19 @@ pub(crate) enum Message {
|
|||
RightClickSlide(usize, usize),
|
||||
AssignObsScene(usize),
|
||||
UpdateObsScenes(Vec<Scene>),
|
||||
#[debug("AddObsClient")]
|
||||
AddObsClient(Arc<Client>),
|
||||
AssignSlideAction(slide_actions::Action),
|
||||
}
|
||||
|
||||
impl std::fmt::Debug for Message {
|
||||
fn fmt(
|
||||
&self,
|
||||
f: &mut std::fmt::Formatter<'_>,
|
||||
) -> std::fmt::Result {
|
||||
match self {
|
||||
Self::NextSlide => write!(f, "NextSlide"),
|
||||
Self::PrevSlide => write!(f, "PrevSlide"),
|
||||
Self::SlideChange(arg0) => {
|
||||
f.debug_tuple("SlideChange").field(arg0).finish()
|
||||
}
|
||||
Self::ActivateSlide(arg0, arg1) => f
|
||||
.debug_tuple("ActivateSlide")
|
||||
.field(arg0)
|
||||
.field(arg1)
|
||||
.finish(),
|
||||
Self::ClickSlide(arg0, arg1) => f
|
||||
.debug_tuple("ClickSlide")
|
||||
.field(arg0)
|
||||
.field(arg1)
|
||||
.finish(),
|
||||
Self::EndVideo => write!(f, "EndVideo"),
|
||||
Self::StartVideo => write!(f, "StartVideo"),
|
||||
Self::StartAudio => write!(f, "StartAudio"),
|
||||
Self::EndAudio => write!(f, "EndAudio"),
|
||||
Self::VideoPos(arg0) => {
|
||||
f.debug_tuple("VideoPos").field(arg0).finish()
|
||||
}
|
||||
Self::VideoFrame => write!(f, "VideoFrame"),
|
||||
Self::MissingPlugin(arg0) => {
|
||||
f.debug_tuple("MissingPlugin").field(arg0).finish()
|
||||
}
|
||||
Self::HoveredSlide(arg0) => {
|
||||
f.debug_tuple("HoveredSlide").field(arg0).finish()
|
||||
}
|
||||
Self::ChangeFont(arg0) => {
|
||||
f.debug_tuple("ChangeFont").field(arg0).finish()
|
||||
}
|
||||
Self::Error(arg0) => {
|
||||
f.debug_tuple("Error").field(arg0).finish()
|
||||
}
|
||||
Self::None => write!(f, "None"),
|
||||
Self::RightClickSlide(arg0, arg1) => f
|
||||
.debug_tuple("RightClickSlide")
|
||||
.field(arg0)
|
||||
.field(arg1)
|
||||
.finish(),
|
||||
Self::AssignObsScene(arg0) => {
|
||||
f.debug_tuple("ObsSceneAssign").field(arg0).finish()
|
||||
}
|
||||
Self::UpdateObsScenes(arg0) => {
|
||||
f.debug_tuple("UpdateObsScenes").field(arg0).finish()
|
||||
}
|
||||
Self::AddObsClient(_) => write!(f, "AddObsClient"),
|
||||
Self::AssignSlideAction(action) => f
|
||||
.debug_tuple("AssignSlideAction")
|
||||
.field(action)
|
||||
.finish(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[allow(clippy::enum_variant_names)]
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||
enum MenuAction {
|
||||
ObsSceneAssign(usize),
|
||||
ObsStartStream,
|
||||
ObsStopStream,
|
||||
ObsStartRecord,
|
||||
ObsStopRecord,
|
||||
// ObsStartRecord,
|
||||
// ObsStopRecord,
|
||||
}
|
||||
|
||||
impl menu::Action for MenuAction {
|
||||
|
|
@ -189,8 +129,8 @@ impl menu::Action for MenuAction {
|
|||
action: ObsAction::StopStream,
|
||||
},
|
||||
),
|
||||
Self::ObsStartRecord => todo!(),
|
||||
Self::ObsStopRecord => todo!(),
|
||||
// Self::ObsStartRecord => todo!(),
|
||||
// Self::ObsStopRecord => todo!(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -642,9 +582,9 @@ impl Presenter {
|
|||
Message::HoveredSlide(slide) => {
|
||||
self.hovered_slide = slide;
|
||||
}
|
||||
Message::StartAudio => {
|
||||
return Action::Task(self.start_audio());
|
||||
}
|
||||
// Message::StartAudio => {
|
||||
// return Action::Task(self.start_audio());
|
||||
// }
|
||||
Message::EndAudio => {
|
||||
self.sink.0.stop();
|
||||
}
|
||||
|
|
@ -1008,13 +948,13 @@ impl Presenter {
|
|||
}
|
||||
}
|
||||
|
||||
#[allow(clippy::unused_async)]
|
||||
async fn obs_scene_switch(client: Arc<Client>, scene: Scene) {
|
||||
match client.scenes().set_current_program_scene(&scene.id).await {
|
||||
Ok(()) => debug!("Set scene to: {:?}", scene),
|
||||
Err(e) => error!(?e),
|
||||
}
|
||||
}
|
||||
// #[allow(clippy::unused_async)]
|
||||
// async fn obs_scene_switch(client: Arc<Client>, scene: Scene) {
|
||||
// match client.scenes().set_current_program_scene(&scene.id).await {
|
||||
// Ok(()) => debug!("Set scene to: {:?}", scene),
|
||||
// Err(e) => error!(?e),
|
||||
// }
|
||||
// }
|
||||
|
||||
// This needs to be async so that rodio's audio will work
|
||||
#[allow(clippy::unused_async)]
|
||||
|
|
@ -1033,17 +973,6 @@ async fn start_audio(sink: Arc<Sink>, audio: PathBuf) {
|
|||
debug!(empty, paused, "Finished running");
|
||||
}
|
||||
|
||||
fn scale_font(font_size: f32, width: f32) -> f32 {
|
||||
let scale_factor = (REFERENCE_WIDTH / width).sqrt();
|
||||
// debug!(scale_factor);
|
||||
|
||||
if font_size > 0.0 {
|
||||
font_size / scale_factor
|
||||
} else {
|
||||
50.0
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn slide_view<'a>(
|
||||
slide: &'a Slide,
|
||||
video: Option<&'a Video>,
|
||||
|
|
|
|||
|
|
@ -344,7 +344,7 @@ struct State {
|
|||
hovered: bool,
|
||||
left_pressed_position: Option<Point>,
|
||||
is_dragging: bool,
|
||||
cached_bounds: Rectangle,
|
||||
_cached_bounds: Rectangle,
|
||||
}
|
||||
|
||||
impl State {
|
||||
|
|
|
|||
|
|
@ -13,13 +13,13 @@ use tracing::debug;
|
|||
|
||||
#[derive(Debug, Default)]
|
||||
struct State {
|
||||
cache: canvas::Cache,
|
||||
_cache: canvas::Cache,
|
||||
}
|
||||
|
||||
#[derive(Debug, Default)]
|
||||
pub struct SlideEditor {
|
||||
state: State,
|
||||
font: Font,
|
||||
_state: State,
|
||||
_font: Font,
|
||||
program: EditorProgram,
|
||||
}
|
||||
|
||||
|
|
@ -35,11 +35,11 @@ pub enum Message {
|
|||
}
|
||||
|
||||
pub struct Text {
|
||||
text: String,
|
||||
_text: String,
|
||||
}
|
||||
|
||||
pub struct Image {
|
||||
source: PathBuf,
|
||||
_source: PathBuf,
|
||||
}
|
||||
|
||||
pub enum SlideWidget {
|
||||
|
|
@ -55,7 +55,7 @@ pub enum SlideError {
|
|||
|
||||
#[derive(Debug, Default)]
|
||||
struct EditorProgram {
|
||||
mouse_button_pressed: Option<cosmic::iced::mouse::Button>,
|
||||
_mouse_button_pressed: Option<cosmic::iced::mouse::Button>,
|
||||
}
|
||||
|
||||
impl SlideEditor {
|
||||
|
|
|
|||
|
|
@ -85,7 +85,7 @@ pub struct SongEditor {
|
|||
video: Option<Video>,
|
||||
ccli: String,
|
||||
song_slides: Option<Vec<Slide>>,
|
||||
slide_state: SlideEditor,
|
||||
_slide_state: SlideEditor,
|
||||
stroke_sizes: [String; 16],
|
||||
shadow_sizes: [String; 16],
|
||||
shadow_offset_sizes: [String; 21],
|
||||
|
|
@ -253,7 +253,7 @@ impl SongEditor {
|
|||
background: None,
|
||||
video: None,
|
||||
ccli: String::new(),
|
||||
slide_state: SlideEditor::default(),
|
||||
_slide_state: SlideEditor::default(),
|
||||
song_slides: None,
|
||||
stroke_sizes: [
|
||||
"0".to_string(),
|
||||
|
|
@ -641,7 +641,7 @@ impl SongEditor {
|
|||
|
||||
let verse_name = song
|
||||
.verse_name_from_str(
|
||||
verse_name,
|
||||
&verse_name,
|
||||
old_verse_name,
|
||||
);
|
||||
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ use cosmic::iced_wgpu::Primitive;
|
|||
use cosmic::iced_wgpu::primitive::Renderer as PrimitiveRenderer;
|
||||
|
||||
pub struct SlideText {
|
||||
text: String,
|
||||
_text: String,
|
||||
font_size: f32,
|
||||
}
|
||||
|
||||
|
|
@ -16,7 +16,7 @@ impl SlideText {
|
|||
pub fn new(text: impl AsRef<str>) -> Self {
|
||||
let text = text.as_ref();
|
||||
Self {
|
||||
text: text.to_string(),
|
||||
_text: text.to_string(),
|
||||
font_size: 50.0,
|
||||
}
|
||||
}
|
||||
|
|
@ -88,8 +88,8 @@ where
|
|||
|
||||
#[derive(Debug, Clone)]
|
||||
pub(crate) struct TextPrimitive {
|
||||
text_id: u64,
|
||||
size: (u32, u32),
|
||||
_text_id: u64,
|
||||
_size: (u32, u32),
|
||||
}
|
||||
|
||||
impl TextPrimitive {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue