perf, pedantic, nursery, and unwrap_used clippy fixes
This commit is contained in:
parent
a186d3bec4
commit
3fe77c93e2
15 changed files with 195 additions and 207 deletions
|
@ -17,7 +17,7 @@ use std::path::PathBuf;
|
||||||
use tracing::error;
|
use tracing::error;
|
||||||
|
|
||||||
#[derive(
|
#[derive(
|
||||||
Clone, Debug, Default, PartialEq, Serialize, Deserialize,
|
Clone, Debug, Default, PartialEq, Eq, Serialize, Deserialize,
|
||||||
)]
|
)]
|
||||||
pub struct Image {
|
pub struct Image {
|
||||||
pub id: i32,
|
pub id: i32,
|
||||||
|
@ -52,8 +52,7 @@ impl Content for Image {
|
||||||
if self.path.exists() {
|
if self.path.exists() {
|
||||||
self.path
|
self.path
|
||||||
.file_name()
|
.file_name()
|
||||||
.map(|f| f.to_string_lossy().to_string())
|
.map_or("Missing image".into(), |f| f.to_string_lossy().to_string())
|
||||||
.unwrap_or("Missing image".into())
|
|
||||||
} else {
|
} else {
|
||||||
"Missing image".into()
|
"Missing image".into()
|
||||||
}
|
}
|
||||||
|
@ -85,7 +84,7 @@ impl From<&Value> for Image {
|
||||||
let path =
|
let path =
|
||||||
p.to_str().unwrap_or_default().to_string();
|
p.to_str().unwrap_or_default().to_string();
|
||||||
let title =
|
let title =
|
||||||
path.rsplit_once("/").unwrap_or_default().1;
|
path.rsplit_once('/').unwrap_or_default().1;
|
||||||
title.to_string()
|
title.to_string()
|
||||||
});
|
});
|
||||||
Self {
|
Self {
|
||||||
|
@ -154,14 +153,14 @@ impl Model<Image> {
|
||||||
.await;
|
.await;
|
||||||
match result {
|
match result {
|
||||||
Ok(v) => {
|
Ok(v) => {
|
||||||
for image in v.into_iter() {
|
for image in v {
|
||||||
let _ = self.add_item(image);
|
let _ = self.add_item(image);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
error!("There was an error in converting images: {e}")
|
error!("There was an error in converting images: {e}");
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -172,7 +171,7 @@ pub async fn update_image_in_db(
|
||||||
let path = image
|
let path = image
|
||||||
.path
|
.path
|
||||||
.to_str()
|
.to_str()
|
||||||
.map(|s| s.to_string())
|
.map(std::string::ToString::to_string)
|
||||||
.unwrap_or_default();
|
.unwrap_or_default();
|
||||||
query!(
|
query!(
|
||||||
r#"UPDATE images SET title = $2, file_path = $3 WHERE id = $1"#,
|
r#"UPDATE images SET title = $2, file_path = $3 WHERE id = $1"#,
|
||||||
|
|
|
@ -50,7 +50,7 @@ impl std::fmt::Display for ServiceItemKind {
|
||||||
// }
|
// }
|
||||||
|
|
||||||
impl From<ServiceItemKind> for String {
|
impl From<ServiceItemKind> for String {
|
||||||
fn from(val: ServiceItemKind) -> String {
|
fn from(val: ServiceItemKind) -> Self {
|
||||||
match val {
|
match val {
|
||||||
ServiceItemKind::Song(_) => "song".to_owned(),
|
ServiceItemKind::Song(_) => "song".to_owned(),
|
||||||
ServiceItemKind::Video(_) => "video".to_owned(),
|
ServiceItemKind::Video(_) => "video".to_owned(),
|
||||||
|
|
|
@ -10,7 +10,7 @@ pub struct Model<T> {
|
||||||
pub kind: LibraryKind,
|
pub kind: LibraryKind,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq, Copy)]
|
#[derive(Debug, Clone, PartialEq, Eq, Copy)]
|
||||||
pub enum LibraryKind {
|
pub enum LibraryKind {
|
||||||
Song,
|
Song,
|
||||||
Video,
|
Video,
|
||||||
|
@ -46,7 +46,7 @@ impl<T> Model<T> {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_item(&self, index: i32) -> Option<&T> {
|
#[must_use] pub fn get_item(&self, index: i32) -> Option<&T> {
|
||||||
self.items.get(index as usize)
|
self.items.get(index as usize)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -75,8 +75,7 @@ impl Content for Presentation {
|
||||||
if self.path.exists() {
|
if self.path.exists() {
|
||||||
self.path
|
self.path
|
||||||
.file_name()
|
.file_name()
|
||||||
.map(|f| f.to_string_lossy().to_string())
|
.map_or("Missing presentation".into(), |f| f.to_string_lossy().to_string())
|
||||||
.unwrap_or("Missing presentation".into())
|
|
||||||
} else {
|
} else {
|
||||||
"Missing presentation".into()
|
"Missing presentation".into()
|
||||||
}
|
}
|
||||||
|
@ -190,14 +189,14 @@ impl ServiceTrait for Presentation {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Presentation {
|
impl Presentation {
|
||||||
pub fn new() -> Self {
|
#[must_use] pub fn new() -> Self {
|
||||||
Self {
|
Self {
|
||||||
title: "".to_string(),
|
title: String::new(),
|
||||||
..Default::default()
|
..Default::default()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_kind(&self) -> &PresKind {
|
#[must_use] pub const fn get_kind(&self) -> &PresKind {
|
||||||
&self.kind
|
&self.kind
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -240,7 +239,7 @@ impl Model<Presentation> {
|
||||||
.await;
|
.await;
|
||||||
match result {
|
match result {
|
||||||
Ok(v) => {
|
Ok(v) => {
|
||||||
for presentation in v.into_iter() {
|
for presentation in v {
|
||||||
let _ = self.add_item(Presentation {
|
let _ = self.add_item(Presentation {
|
||||||
id: presentation.id,
|
id: presentation.id,
|
||||||
title: presentation.title,
|
title: presentation.title,
|
||||||
|
@ -267,7 +266,7 @@ pub async fn update_presentation_in_db(
|
||||||
let path = presentation
|
let path = presentation
|
||||||
.path
|
.path
|
||||||
.to_str()
|
.to_str()
|
||||||
.map(|s| s.to_string())
|
.map(std::string::ToString::to_string)
|
||||||
.unwrap_or_default();
|
.unwrap_or_default();
|
||||||
let html = presentation.kind == PresKind::Html;
|
let html = presentation.kind == PresKind::Html;
|
||||||
query!(
|
query!(
|
||||||
|
|
|
@ -79,13 +79,13 @@ impl AsMimeTypes for ServiceItem {
|
||||||
impl From<&ServiceItem> for Value {
|
impl From<&ServiceItem> for Value {
|
||||||
fn from(value: &ServiceItem) -> Self {
|
fn from(value: &ServiceItem) -> Self {
|
||||||
match &value.kind {
|
match &value.kind {
|
||||||
ServiceItemKind::Song(song) => Value::from(song),
|
ServiceItemKind::Song(song) => Self::from(song),
|
||||||
ServiceItemKind::Video(video) => Value::from(video),
|
ServiceItemKind::Video(video) => Self::from(video),
|
||||||
ServiceItemKind::Image(image) => Value::from(image),
|
ServiceItemKind::Image(image) => Self::from(image),
|
||||||
ServiceItemKind::Presentation(presentation) => {
|
ServiceItemKind::Presentation(presentation) => {
|
||||||
Value::from(presentation)
|
Self::from(presentation)
|
||||||
}
|
}
|
||||||
ServiceItemKind::Content(slide) => Value::from(slide),
|
ServiceItemKind::Content(slide) => Self::from(slide),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -172,54 +172,51 @@ impl From<&Value> for ServiceItem {
|
||||||
} else if let Some(background) =
|
} else if let Some(background) =
|
||||||
list.get(background_pos)
|
list.get(background_pos)
|
||||||
{
|
{
|
||||||
match background {
|
if let Value::List(item) = background { match &item[0] {
|
||||||
Value::List(item) => match &item[0] {
|
Value::Symbol(Symbol(s))
|
||||||
Value::Symbol(Symbol(s))
|
if s == "image" =>
|
||||||
if s == "image" =>
|
{
|
||||||
{
|
Self::from(&Image::from(
|
||||||
Self::from(&Image::from(
|
background,
|
||||||
background,
|
))
|
||||||
))
|
|
||||||
}
|
|
||||||
Value::Symbol(Symbol(s))
|
|
||||||
if s == "video" =>
|
|
||||||
{
|
|
||||||
Self::from(&Video::from(
|
|
||||||
background,
|
|
||||||
))
|
|
||||||
}
|
|
||||||
Value::Symbol(Symbol(s))
|
|
||||||
if s == "presentation" =>
|
|
||||||
{
|
|
||||||
Self::from(&Presentation::from(
|
|
||||||
background,
|
|
||||||
))
|
|
||||||
}
|
|
||||||
_ => todo!(),
|
|
||||||
},
|
|
||||||
_ => {
|
|
||||||
error!(
|
|
||||||
"There is no background here: {:?}",
|
|
||||||
background
|
|
||||||
);
|
|
||||||
ServiceItem::default()
|
|
||||||
}
|
}
|
||||||
|
Value::Symbol(Symbol(s))
|
||||||
|
if s == "video" =>
|
||||||
|
{
|
||||||
|
Self::from(&Video::from(
|
||||||
|
background,
|
||||||
|
))
|
||||||
|
}
|
||||||
|
Value::Symbol(Symbol(s))
|
||||||
|
if s == "presentation" =>
|
||||||
|
{
|
||||||
|
Self::from(&Presentation::from(
|
||||||
|
background,
|
||||||
|
))
|
||||||
|
}
|
||||||
|
_ => todo!(),
|
||||||
|
} } else {
|
||||||
|
error!(
|
||||||
|
"There is no background here: {:?}",
|
||||||
|
background
|
||||||
|
);
|
||||||
|
Self::default()
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
error!(
|
error!(
|
||||||
"There is no background here: {:?}",
|
"There is no background here: {:?}",
|
||||||
background_pos
|
background_pos
|
||||||
);
|
);
|
||||||
ServiceItem::default()
|
Self::default()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Value::Symbol(Symbol(s)) if s == "song" => {
|
Value::Symbol(Symbol(s)) if s == "song" => {
|
||||||
let song = lisp_to_song(list.clone());
|
let song = lisp_to_song(list.clone());
|
||||||
Self::from(&song)
|
Self::from(&song)
|
||||||
}
|
}
|
||||||
_ => ServiceItem::default(),
|
_ => Self::default(),
|
||||||
},
|
},
|
||||||
_ => ServiceItem::default(),
|
_ => Self::default(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -107,9 +107,9 @@ impl TryFrom<&Background> for Video {
|
||||||
fn try_from(
|
fn try_from(
|
||||||
value: &Background,
|
value: &Background,
|
||||||
) -> std::result::Result<Self, Self::Error> {
|
) -> std::result::Result<Self, Self::Error> {
|
||||||
Video::new(
|
Self::new(
|
||||||
&url::Url::from_file_path(value.path.clone())
|
&url::Url::from_file_path(value.path.clone())
|
||||||
.map_err(|_| ParseError::BackgroundNotVideo)?,
|
.map_err(|()| ParseError::BackgroundNotVideo)?,
|
||||||
)
|
)
|
||||||
.map_err(|_| ParseError::BackgroundNotVideo)
|
.map_err(|_| ParseError::BackgroundNotVideo)
|
||||||
}
|
}
|
||||||
|
@ -121,9 +121,9 @@ impl TryFrom<Background> for Video {
|
||||||
fn try_from(
|
fn try_from(
|
||||||
value: Background,
|
value: Background,
|
||||||
) -> std::result::Result<Self, Self::Error> {
|
) -> std::result::Result<Self, Self::Error> {
|
||||||
Video::new(
|
Self::new(
|
||||||
&url::Url::from_file_path(value.path)
|
&url::Url::from_file_path(value.path)
|
||||||
.map_err(|_| ParseError::BackgroundNotVideo)?,
|
.map_err(|()| ParseError::BackgroundNotVideo)?,
|
||||||
)
|
)
|
||||||
.map_err(|_| ParseError::BackgroundNotVideo)
|
.map_err(|_| ParseError::BackgroundNotVideo)
|
||||||
}
|
}
|
||||||
|
@ -132,7 +132,7 @@ impl TryFrom<Background> for Video {
|
||||||
impl TryFrom<String> for Background {
|
impl TryFrom<String> for Background {
|
||||||
type Error = ParseError;
|
type Error = ParseError;
|
||||||
fn try_from(value: String) -> Result<Self, Self::Error> {
|
fn try_from(value: String) -> Result<Self, Self::Error> {
|
||||||
Background::try_from(value.as_str())
|
Self::try_from(value.as_str())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -147,7 +147,7 @@ impl TryFrom<PathBuf> for Background {
|
||||||
.to_str()
|
.to_str()
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.to_string();
|
.to_string();
|
||||||
let path = path.replace("~", &home);
|
let path = path.replace('~', &home);
|
||||||
PathBuf::from(path)
|
PathBuf::from(path)
|
||||||
} else {
|
} else {
|
||||||
path
|
path
|
||||||
|
@ -192,10 +192,10 @@ impl TryFrom<&str> for Background {
|
||||||
type Error = ParseError;
|
type Error = ParseError;
|
||||||
fn try_from(value: &str) -> Result<Self, Self::Error> {
|
fn try_from(value: &str) -> Result<Self, Self::Error> {
|
||||||
let value = value.trim_start_matches("file://");
|
let value = value.trim_start_matches("file://");
|
||||||
if value.starts_with("~") {
|
if value.starts_with('~') {
|
||||||
if let Some(home) = dirs::home_dir() {
|
if let Some(home) = dirs::home_dir() {
|
||||||
if let Some(home) = home.to_str() {
|
if let Some(home) = home.to_str() {
|
||||||
let value = value.replace("~", home);
|
let value = value.replace('~', home);
|
||||||
Self::try_from(PathBuf::from(value))
|
Self::try_from(PathBuf::from(value))
|
||||||
} else {
|
} else {
|
||||||
Self::try_from(PathBuf::from(value))
|
Self::try_from(PathBuf::from(value))
|
||||||
|
@ -252,9 +252,9 @@ impl Display for ParseError {
|
||||||
impl From<String> for BackgroundKind {
|
impl From<String> for BackgroundKind {
|
||||||
fn from(value: String) -> Self {
|
fn from(value: String) -> Self {
|
||||||
if value == "image" {
|
if value == "image" {
|
||||||
BackgroundKind::Image
|
Self::Image
|
||||||
} else {
|
} else {
|
||||||
BackgroundKind::Video
|
Self::Video
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -281,7 +281,7 @@ impl Slide {
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_font_size(mut self, font_size: i32) -> Self {
|
pub const fn set_font_size(mut self, font_size: i32) -> Self {
|
||||||
self.font_size = font_size;
|
self.font_size = font_size;
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
@ -291,12 +291,12 @@ impl Slide {
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_pdf_index(mut self, pdf_index: u32) -> Self {
|
pub const fn set_pdf_index(mut self, pdf_index: u32) -> Self {
|
||||||
self.pdf_index = pdf_index;
|
self.pdf_index = pdf_index;
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn background(&self) -> &Background {
|
pub const fn background(&self) -> &Background {
|
||||||
&self.background
|
&self.background
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -304,11 +304,11 @@ impl Slide {
|
||||||
self.text.clone()
|
self.text.clone()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn text_alignment(&self) -> TextAlignment {
|
pub const fn text_alignment(&self) -> TextAlignment {
|
||||||
self.text_alignment
|
self.text_alignment
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn font_size(&self) -> i32 {
|
pub const fn font_size(&self) -> i32 {
|
||||||
self.font_size
|
self.font_size
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -316,7 +316,7 @@ impl Slide {
|
||||||
self.font.clone()
|
self.font.clone()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn video_loop(&self) -> bool {
|
pub const fn video_loop(&self) -> bool {
|
||||||
self.video_loop
|
self.video_loop
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -328,13 +328,13 @@ impl Slide {
|
||||||
self.pdf_page.clone()
|
self.pdf_page.clone()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn pdf_index(&self) -> u32 {
|
pub const fn pdf_index(&self) -> u32 {
|
||||||
self.pdf_index
|
self.pdf_index
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn song_slides(song: &Song) -> Result<Vec<Self>> {
|
pub fn song_slides(song: &Song) -> Result<Vec<Self>> {
|
||||||
let lyrics = song.get_lyrics()?;
|
let lyrics = song.get_lyrics()?;
|
||||||
let slides: Vec<Slide> = lyrics
|
let slides: Vec<Self> = lyrics
|
||||||
.iter()
|
.iter()
|
||||||
.map(|l| {
|
.map(|l| {
|
||||||
let song = song.clone();
|
let song = song.clone();
|
||||||
|
@ -358,7 +358,7 @@ impl Slide {
|
||||||
Ok(slides)
|
Ok(slides)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn set_index(&mut self, index: i32) {
|
pub(crate) const fn set_index(&mut self, index: i32) {
|
||||||
self.id = index;
|
self.id = index;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -381,7 +381,7 @@ impl From<&Value> for Slide {
|
||||||
fn from(value: &Value) -> Self {
|
fn from(value: &Value) -> Self {
|
||||||
match value {
|
match value {
|
||||||
Value::List(list) => lisp_to_slide(list),
|
Value::List(list) => lisp_to_slide(list),
|
||||||
_ => Slide::default(),
|
_ => Self::default(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -404,7 +404,7 @@ fn lisp_to_slide(lisp: &Vec<Value>) -> Slide {
|
||||||
slide = slide.background(lisp_to_background(background));
|
slide = slide.background(lisp_to_background(background));
|
||||||
} else {
|
} else {
|
||||||
slide = slide.background(Background::default());
|
slide = slide.background(Background::default());
|
||||||
};
|
}
|
||||||
|
|
||||||
let text_position = lisp.iter().position(|v| match v {
|
let text_position = lisp.iter().position(|v| match v {
|
||||||
Value::List(vec) => {
|
Value::List(vec) => {
|
||||||
|
@ -691,9 +691,7 @@ impl SlideBuilder {
|
||||||
|
|
||||||
impl Image {
|
impl Image {
|
||||||
fn new() -> Self {
|
fn new() -> Self {
|
||||||
Self {
|
Default::default()
|
||||||
..Default::default()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -128,7 +128,7 @@ impl FromRow<'_, SqliteRow> for Song {
|
||||||
})),
|
})),
|
||||||
verse_order: Some({
|
verse_order: Some({
|
||||||
let str: &str = row.try_get(0)?;
|
let str: &str = row.try_get(0)?;
|
||||||
str.split(' ').map(|s| s.to_string()).collect()
|
str.split(' ').map(std::string::ToString::to_string).collect()
|
||||||
}),
|
}),
|
||||||
background: {
|
background: {
|
||||||
let string: String = row.try_get(7)?;
|
let string: String = row.try_get(7)?;
|
||||||
|
@ -251,8 +251,7 @@ pub fn lisp_to_song(list: Vec<Value>) -> Song {
|
||||||
{
|
{
|
||||||
let pos = key_pos + 1;
|
let pos = key_pos + 1;
|
||||||
list.get(pos)
|
list.get(pos)
|
||||||
.map(String::from)
|
.map_or(String::from("song"), String::from)
|
||||||
.unwrap_or(String::from("song"))
|
|
||||||
} else {
|
} else {
|
||||||
String::from("song")
|
String::from("song")
|
||||||
};
|
};
|
||||||
|
@ -319,30 +318,30 @@ pub fn lisp_to_song(list: Vec<Value>) -> Song {
|
||||||
let lyric = String::from(&lyric[1]);
|
let lyric = String::from(&lyric[1]);
|
||||||
|
|
||||||
let verse_title = match lyric_verse.as_str() {
|
let verse_title = match lyric_verse.as_str() {
|
||||||
"i1" => r#"\n\nIntro 1\n"#,
|
"i1" => r"\n\nIntro 1\n",
|
||||||
"i2" => r#"\n\nIntro 1\n"#,
|
"i2" => r"\n\nIntro 1\n",
|
||||||
"v1" => r#"\n\nVerse 1\n"#,
|
"v1" => r"\n\nVerse 1\n",
|
||||||
"v2" => r#"\n\nVerse 2\n"#,
|
"v2" => r"\n\nVerse 2\n",
|
||||||
"v3" => r#"\n\nVerse 3\n"#,
|
"v3" => r"\n\nVerse 3\n",
|
||||||
"v4" => r#"\n\nVerse 4\n"#,
|
"v4" => r"\n\nVerse 4\n",
|
||||||
"v5" => r#"\n\nVerse 5\n"#,
|
"v5" => r"\n\nVerse 5\n",
|
||||||
"c1" => r#"\n\nChorus 1\n"#,
|
"c1" => r"\n\nChorus 1\n",
|
||||||
"c2" => r#"\n\nChorus 2\n"#,
|
"c2" => r"\n\nChorus 2\n",
|
||||||
"c3" => r#"\n\nChorus 3\n"#,
|
"c3" => r"\n\nChorus 3\n",
|
||||||
"c4" => r#"\n\nChorus 4\n"#,
|
"c4" => r"\n\nChorus 4\n",
|
||||||
"b1" => r#"\n\nBridge 1\n"#,
|
"b1" => r"\n\nBridge 1\n",
|
||||||
"b2" => r#"\n\nBridge 2\n"#,
|
"b2" => r"\n\nBridge 2\n",
|
||||||
"e1" => r#"\n\nEnding 1\n"#,
|
"e1" => r"\n\nEnding 1\n",
|
||||||
"e2" => r#"\n\nEnding 2\n"#,
|
"e2" => r"\n\nEnding 2\n",
|
||||||
"o1" => r#"\n\nOther 1\n"#,
|
"o1" => r"\n\nOther 1\n",
|
||||||
"o2" => r#"\n\nOther 2\n"#,
|
"o2" => r"\n\nOther 2\n",
|
||||||
_ => "",
|
_ => "",
|
||||||
};
|
};
|
||||||
|
|
||||||
let lyric = format!("{verse_title}{lyric}");
|
let lyric = format!("{verse_title}{lyric}");
|
||||||
let lyric = lyric.replace(
|
let lyric = lyric.replace(
|
||||||
"\\n", r#"
|
"\\n", r"
|
||||||
"#,
|
",
|
||||||
);
|
);
|
||||||
lyrics.push(lyric);
|
lyrics.push(lyric);
|
||||||
}
|
}
|
||||||
|
@ -392,15 +391,15 @@ impl Model<Song> {
|
||||||
let result = query(r#"SELECT verse_order as "verse_order!", font_size as "font_size!: i32", background_type as "background_type!", horizontal_text_alignment as "horizontal_text_alignment!", vertical_text_alignment as "vertical_text_alignment!", title as "title!", font as "font!", background as "background!", lyrics as "lyrics!", ccli as "ccli!", author as "author!", audio as "audio!", id as "id: i32" from songs"#).fetch_all(db).await;
|
let result = query(r#"SELECT verse_order as "verse_order!", font_size as "font_size!: i32", background_type as "background_type!", horizontal_text_alignment as "horizontal_text_alignment!", vertical_text_alignment as "vertical_text_alignment!", title as "title!", font as "font!", background as "background!", lyrics as "lyrics!", ccli as "ccli!", author as "author!", audio as "audio!", id as "id: i32" from songs"#).fetch_all(db).await;
|
||||||
match result {
|
match result {
|
||||||
Ok(s) => {
|
Ok(s) => {
|
||||||
for song in s.into_iter() {
|
for song in s {
|
||||||
match Song::from_row(&song) {
|
match Song::from_row(&song) {
|
||||||
Ok(song) => {
|
Ok(song) => {
|
||||||
let _ = self.add_item(song);
|
let _ = self.add_item(song);
|
||||||
}
|
}
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
error!("Could not convert song: {e}")
|
error!("Could not convert song: {e}");
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
|
@ -425,7 +424,7 @@ pub async fn update_song_in_db(
|
||||||
})
|
})
|
||||||
.collect::<String>()
|
.collect::<String>()
|
||||||
} else {
|
} else {
|
||||||
String::from("")
|
String::new()
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -488,13 +487,13 @@ impl Song {
|
||||||
let verse_order = self.verse_order.clone();
|
let verse_order = self.verse_order.clone();
|
||||||
|
|
||||||
let mut lyric_map = HashMap::new();
|
let mut lyric_map = HashMap::new();
|
||||||
let mut verse_title = String::from("");
|
let mut verse_title = String::new();
|
||||||
let mut lyric = String::from("");
|
let mut lyric = String::new();
|
||||||
for (i, line) in raw_lyrics.split('\n').enumerate() {
|
for (i, line) in raw_lyrics.split('\n').enumerate() {
|
||||||
if VERSE_KEYWORDS.contains(&line) {
|
if VERSE_KEYWORDS.contains(&line) {
|
||||||
if i != 0 {
|
if i != 0 {
|
||||||
lyric_map.insert(verse_title, lyric);
|
lyric_map.insert(verse_title, lyric);
|
||||||
lyric = String::from("");
|
lyric = String::new();
|
||||||
verse_title = line.to_string();
|
verse_title = line.to_string();
|
||||||
} else {
|
} else {
|
||||||
verse_title = line.to_string();
|
verse_title = line.to_string();
|
||||||
|
@ -535,7 +534,7 @@ impl Song {
|
||||||
lyric_list.push(lyric.to_string());
|
lyric_list.push(lyric.to_string());
|
||||||
} else {
|
} else {
|
||||||
// error!("NOT WORKING!");
|
// error!("NOT WORKING!");
|
||||||
};
|
}
|
||||||
}
|
}
|
||||||
// for lyric in lyric_list.iter() {
|
// for lyric in lyric_list.iter() {
|
||||||
// debug!(lyric = ?lyric)
|
// debug!(lyric = ?lyric)
|
||||||
|
|
|
@ -11,7 +11,9 @@ pub fn bg_from_video(
|
||||||
video: &Path,
|
video: &Path,
|
||||||
screenshot: &Path,
|
screenshot: &Path,
|
||||||
) -> Result<(), Box<dyn Error>> {
|
) -> Result<(), Box<dyn Error>> {
|
||||||
if !screenshot.exists() {
|
if screenshot.exists() {
|
||||||
|
debug!("Screenshot already exists");
|
||||||
|
} else {
|
||||||
let output_duration = Command::new("ffprobe")
|
let output_duration = Command::new("ffprobe")
|
||||||
.args(["-i", &video.to_string_lossy()])
|
.args(["-i", &video.to_string_lossy()])
|
||||||
.output()
|
.output()
|
||||||
|
@ -26,9 +28,9 @@ pub fn bg_from_video(
|
||||||
let mut duration = log.split_off(duration_index + 10);
|
let mut duration = log.split_off(duration_index + 10);
|
||||||
duration.truncate(11);
|
duration.truncate(11);
|
||||||
// debug!("rust-duration-is: {duration}");
|
// debug!("rust-duration-is: {duration}");
|
||||||
let mut hours = String::from("");
|
let mut hours = String::new();
|
||||||
let mut minutes = String::from("");
|
let mut minutes = String::new();
|
||||||
let mut seconds = String::from("");
|
let mut seconds = String::new();
|
||||||
for (i, c) in duration.chars().enumerate() {
|
for (i, c) in duration.chars().enumerate() {
|
||||||
if i <= 1 {
|
if i <= 1 {
|
||||||
hours.push(c);
|
hours.push(c);
|
||||||
|
@ -63,8 +65,6 @@ pub fn bg_from_video(
|
||||||
.expect("failed to execute ffmpeg");
|
.expect("failed to execute ffmpeg");
|
||||||
// io::stdout().write_all(&output.stdout).unwrap();
|
// io::stdout().write_all(&output.stdout).unwrap();
|
||||||
// io::stderr().write_all(&output.stderr).unwrap();
|
// io::stderr().write_all(&output.stderr).unwrap();
|
||||||
} else {
|
|
||||||
debug!("Screenshot already exists");
|
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
|
@ -57,8 +57,7 @@ impl Content for Video {
|
||||||
if self.path.exists() {
|
if self.path.exists() {
|
||||||
self.path
|
self.path
|
||||||
.file_name()
|
.file_name()
|
||||||
.map(|f| f.to_string_lossy().to_string())
|
.map_or("Missing video".into(), |f| f.to_string_lossy().to_string())
|
||||||
.unwrap_or("Missing video".into())
|
|
||||||
} else {
|
} else {
|
||||||
"Missing video".into()
|
"Missing video".into()
|
||||||
}
|
}
|
||||||
|
@ -90,7 +89,7 @@ impl From<&Value> for Video {
|
||||||
let path =
|
let path =
|
||||||
p.to_str().unwrap_or_default().to_string();
|
p.to_str().unwrap_or_default().to_string();
|
||||||
let title =
|
let title =
|
||||||
path.rsplit_once("/").unwrap_or_default().1;
|
path.rsplit_once('/').unwrap_or_default().1;
|
||||||
title.to_string()
|
title.to_string()
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -124,8 +123,7 @@ impl From<&Value> for Video {
|
||||||
}) {
|
}) {
|
||||||
let pos = loop_pos + 1;
|
let pos = loop_pos + 1;
|
||||||
list.get(pos)
|
list.get(pos)
|
||||||
.map(|l| String::from(l) == *"true")
|
.is_some_and(|l| String::from(l) == *"true")
|
||||||
.unwrap_or_default()
|
|
||||||
} else {
|
} else {
|
||||||
false
|
false
|
||||||
};
|
};
|
||||||
|
@ -193,14 +191,14 @@ impl Model<Video> {
|
||||||
let result = query_as!(Video, r#"SELECT title as "title!", file_path as "path!", start_time as "start_time!: f32", end_time as "end_time!: f32", loop as "looping!", id as "id: i32" from videos"#).fetch_all(db).await;
|
let result = query_as!(Video, r#"SELECT title as "title!", file_path as "path!", start_time as "start_time!: f32", end_time as "end_time!: f32", loop as "looping!", id as "id: i32" from videos"#).fetch_all(db).await;
|
||||||
match result {
|
match result {
|
||||||
Ok(v) => {
|
Ok(v) => {
|
||||||
for video in v.into_iter() {
|
for video in v {
|
||||||
let _ = self.add_item(video);
|
let _ = self.add_item(video);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
error!("There was an error in converting videos: {e}")
|
error!("There was an error in converting videos: {e}");
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -211,7 +209,7 @@ pub async fn update_video_in_db(
|
||||||
let path = video
|
let path = video
|
||||||
.path
|
.path
|
||||||
.to_str()
|
.to_str()
|
||||||
.map(|s| s.to_string())
|
.map(std::string::ToString::to_string)
|
||||||
.unwrap_or_default();
|
.unwrap_or_default();
|
||||||
query!(
|
query!(
|
||||||
r#"UPDATE videos SET title = $2, file_path = $3, start_time = $4, end_time = $5, loop = $6 WHERE id = $1"#,
|
r#"UPDATE videos SET title = $2, file_path = $3, start_time = $4, end_time = $5, loop = $6 WHERE id = $1"#,
|
||||||
|
|
28
src/main.rs
28
src/main.rs
|
@ -1,6 +1,6 @@
|
||||||
use clap::{command, Parser};
|
use clap::{command, Parser};
|
||||||
use core::service_items::ServiceItem;
|
use core::service_items::ServiceItem;
|
||||||
use core::slide::*;
|
use core::slide::{Background, Slide, SlideBuilder, TextAlignment, BackgroundKind};
|
||||||
use core::songs::Song;
|
use core::songs::Song;
|
||||||
use cosmic::app::context_drawer::ContextDrawer;
|
use cosmic::app::context_drawer::ContextDrawer;
|
||||||
use cosmic::app::{Core, Settings, Task};
|
use cosmic::app::{Core, Settings, Task};
|
||||||
|
@ -233,11 +233,11 @@ impl cosmic::Application for App {
|
||||||
// }
|
// }
|
||||||
|
|
||||||
// nav_model.activate_position(0);
|
// nav_model.activate_position(0);
|
||||||
let mut app = App {
|
let mut app = Self {
|
||||||
presenter,
|
presenter,
|
||||||
core,
|
core,
|
||||||
nav_model,
|
nav_model,
|
||||||
service: items.clone(),
|
service: items,
|
||||||
file: PathBuf::default(),
|
file: PathBuf::default(),
|
||||||
windows,
|
windows,
|
||||||
presentation_open: false,
|
presentation_open: false,
|
||||||
|
@ -248,7 +248,7 @@ impl cosmic::Application for App {
|
||||||
song_editor,
|
song_editor,
|
||||||
searching: false,
|
searching: false,
|
||||||
search_results: vec![],
|
search_results: vec![],
|
||||||
search_query: "".into(),
|
search_query: String::new(),
|
||||||
search_id: cosmic::widget::Id::unique(),
|
search_id: cosmic::widget::Id::unique(),
|
||||||
current_item: (0, 0),
|
current_item: (0, 0),
|
||||||
library_dragged_item: None,
|
library_dragged_item: None,
|
||||||
|
@ -259,11 +259,11 @@ impl cosmic::Application for App {
|
||||||
|
|
||||||
if input.ui {
|
if input.ui {
|
||||||
debug!("main view");
|
debug!("main view");
|
||||||
batch.push(app.update_title())
|
batch.push(app.update_title());
|
||||||
} else {
|
} else {
|
||||||
debug!("window view");
|
debug!("window view");
|
||||||
batch.push(app.show_window())
|
batch.push(app.show_window());
|
||||||
};
|
}
|
||||||
|
|
||||||
batch.push(app.add_library());
|
batch.push(app.add_library());
|
||||||
// batch.push(app.add_service(items, Arc::clone(&fontdb)));
|
// batch.push(app.add_service(items, Arc::clone(&fontdb)));
|
||||||
|
@ -403,7 +403,7 @@ impl cosmic::Application for App {
|
||||||
.fold(0, |a, item| a + item.slides.len());
|
.fold(0, |a, item| a + item.slides.len());
|
||||||
|
|
||||||
let total_slides_text =
|
let total_slides_text =
|
||||||
format!("Total Slides: {}", total_slides);
|
format!("Total Slides: {total_slides}");
|
||||||
let row = row![
|
let row = row![
|
||||||
text::body(total_items_text),
|
text::body(total_items_text),
|
||||||
text::body(total_slides_text)
|
text::body(total_slides_text)
|
||||||
|
@ -635,7 +635,7 @@ impl cosmic::Application for App {
|
||||||
cosmic::Action::App(
|
cosmic::Action::App(
|
||||||
Message::Present(m),
|
Message::Present(m),
|
||||||
)
|
)
|
||||||
}))
|
}));
|
||||||
}
|
}
|
||||||
_ => todo!(),
|
_ => todo!(),
|
||||||
}
|
}
|
||||||
|
@ -661,7 +661,7 @@ impl cosmic::Application for App {
|
||||||
m,
|
m,
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
}))
|
}));
|
||||||
}
|
}
|
||||||
_ => todo!(),
|
_ => todo!(),
|
||||||
}
|
}
|
||||||
|
@ -694,7 +694,7 @@ impl cosmic::Application for App {
|
||||||
cosmic::Action::App(
|
cosmic::Action::App(
|
||||||
Message::Present(m),
|
Message::Present(m),
|
||||||
)
|
)
|
||||||
}))
|
}));
|
||||||
}
|
}
|
||||||
_ => todo!(),
|
_ => todo!(),
|
||||||
}
|
}
|
||||||
|
@ -735,7 +735,7 @@ impl cosmic::Application for App {
|
||||||
m,
|
m,
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
}))
|
}));
|
||||||
}
|
}
|
||||||
_ => todo!(),
|
_ => todo!(),
|
||||||
}
|
}
|
||||||
|
@ -817,7 +817,7 @@ impl cosmic::Application for App {
|
||||||
|
|
||||||
self.windows.push(id);
|
self.windows.push(id);
|
||||||
_ = self.set_window_title(
|
_ = self.set_window_title(
|
||||||
format!("window_{}", count),
|
format!("window_{count}"),
|
||||||
id,
|
id,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -992,7 +992,7 @@ impl cosmic::Application for App {
|
||||||
Task::none()
|
Task::none()
|
||||||
}
|
}
|
||||||
Message::CloseSearch => {
|
Message::CloseSearch => {
|
||||||
self.search_query = "".into();
|
self.search_query = String::new();
|
||||||
self.search_results = vec![];
|
self.search_results = vec![];
|
||||||
self.searching = false;
|
self.searching = false;
|
||||||
Task::none()
|
Task::none()
|
||||||
|
|
|
@ -133,13 +133,13 @@ impl<'a> Library {
|
||||||
if kind != LibraryKind::Song {
|
if kind != LibraryKind::Song {
|
||||||
error!("Not editing a song item");
|
error!("Not editing a song item");
|
||||||
return Action::None;
|
return Action::None;
|
||||||
};
|
}
|
||||||
|
|
||||||
match self
|
match self
|
||||||
.song_library
|
.song_library
|
||||||
.update_item(song.clone(), index)
|
.update_item(song.clone(), index)
|
||||||
{
|
{
|
||||||
Ok(_) => {
|
Ok(()) => {
|
||||||
return Action::Task(
|
return Action::Task(
|
||||||
Task::future(self.db.acquire()).and_then(
|
Task::future(self.db.acquire()).and_then(
|
||||||
move |conn| update_in_db(&song, conn),
|
move |conn| update_in_db(&song, conn),
|
||||||
|
@ -162,13 +162,13 @@ impl<'a> Library {
|
||||||
if kind != LibraryKind::Image {
|
if kind != LibraryKind::Image {
|
||||||
error!("Not editing a image item");
|
error!("Not editing a image item");
|
||||||
return Action::None;
|
return Action::None;
|
||||||
};
|
}
|
||||||
|
|
||||||
match self
|
match self
|
||||||
.image_library
|
.image_library
|
||||||
.update_item(image.clone(), index)
|
.update_item(image.clone(), index)
|
||||||
{
|
{
|
||||||
Ok(_) => {
|
Ok(()) => {
|
||||||
return Action::Task(
|
return Action::Task(
|
||||||
Task::future(self.db.acquire()).and_then(
|
Task::future(self.db.acquire()).and_then(
|
||||||
move |conn| {
|
move |conn| {
|
||||||
|
@ -196,13 +196,13 @@ impl<'a> Library {
|
||||||
if kind != LibraryKind::Video {
|
if kind != LibraryKind::Video {
|
||||||
error!("Not editing a video item");
|
error!("Not editing a video item");
|
||||||
return Action::None;
|
return Action::None;
|
||||||
};
|
}
|
||||||
|
|
||||||
match self
|
match self
|
||||||
.video_library
|
.video_library
|
||||||
.update_item(video.clone(), index)
|
.update_item(video.clone(), index)
|
||||||
{
|
{
|
||||||
Ok(_) => {
|
Ok(()) => {
|
||||||
return Action::Task(
|
return Action::Task(
|
||||||
Task::future(self.db.acquire()).and_then(
|
Task::future(self.db.acquire()).and_then(
|
||||||
move |conn| {
|
move |conn| {
|
||||||
|
@ -230,13 +230,13 @@ impl<'a> Library {
|
||||||
if kind != LibraryKind::Presentation {
|
if kind != LibraryKind::Presentation {
|
||||||
error!("Not editing a presentation item");
|
error!("Not editing a presentation item");
|
||||||
return Action::None;
|
return Action::None;
|
||||||
};
|
}
|
||||||
|
|
||||||
match self
|
match self
|
||||||
.presentation_library
|
.presentation_library
|
||||||
.update_item(presentation.clone(), index)
|
.update_item(presentation.clone(), index)
|
||||||
{
|
{
|
||||||
Ok(_) => return Action::Task(
|
Ok(()) => return Action::Task(
|
||||||
Task::future(self.db.acquire()).and_then(
|
Task::future(self.db.acquire()).and_then(
|
||||||
move |conn| {
|
move |conn| {
|
||||||
Task::perform(
|
Task::perform(
|
||||||
|
@ -254,7 +254,7 @@ impl<'a> Library {
|
||||||
}
|
}
|
||||||
Message::PresentationChanged => (),
|
Message::PresentationChanged => (),
|
||||||
Message::Error(_) => (),
|
Message::Error(_) => (),
|
||||||
};
|
}
|
||||||
Action::None
|
Action::None
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -315,7 +315,7 @@ impl<'a> Library {
|
||||||
textm!("Presentations").align_y(Vertical::Center),
|
textm!("Presentations").align_y(Vertical::Center),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
let item_count = model.items.len();
|
let item_count = model.items.len();
|
||||||
row = row.push(horizontal_space());
|
row = row.push(horizontal_space());
|
||||||
row = row
|
row = row
|
||||||
|
@ -373,7 +373,7 @@ impl<'a> Library {
|
||||||
let service_item = item.to_service_item();
|
let service_item = item.to_service_item();
|
||||||
let visual_item = self
|
let visual_item = self
|
||||||
.single_item(index, item, model)
|
.single_item(index, item, model)
|
||||||
.map(|_| Message::None);
|
.map(|()| Message::None);
|
||||||
DndSource::<Message, ServiceItem>::new(
|
DndSource::<Message, ServiceItem>::new(
|
||||||
mouse_area(visual_item)
|
mouse_area(visual_item)
|
||||||
.on_drag(Message::DragItem(service_item.clone()))
|
.on_drag(Message::DragItem(service_item.clone()))
|
||||||
|
@ -418,7 +418,7 @@ impl<'a> Library {
|
||||||
)
|
)
|
||||||
}})
|
}})
|
||||||
.drag_content(move || {
|
.drag_content(move || {
|
||||||
service_item.to_owned()
|
service_item.clone()
|
||||||
})
|
})
|
||||||
.into()
|
.into()
|
||||||
},
|
},
|
||||||
|
@ -573,14 +573,14 @@ impl<'a> Library {
|
||||||
.items
|
.items
|
||||||
.iter()
|
.iter()
|
||||||
.filter(|song| song.title.to_lowercase().contains(&query))
|
.filter(|song| song.title.to_lowercase().contains(&query))
|
||||||
.map(|song| song.to_service_item())
|
.map(super::super::core::content::Content::to_service_item)
|
||||||
.collect();
|
.collect();
|
||||||
let videos: Vec<ServiceItem> = self
|
let videos: Vec<ServiceItem> = self
|
||||||
.video_library
|
.video_library
|
||||||
.items
|
.items
|
||||||
.iter()
|
.iter()
|
||||||
.filter(|vid| vid.title.to_lowercase().contains(&query))
|
.filter(|vid| vid.title.to_lowercase().contains(&query))
|
||||||
.map(|vid| vid.to_service_item())
|
.map(super::super::core::content::Content::to_service_item)
|
||||||
.collect();
|
.collect();
|
||||||
let images: Vec<ServiceItem> = self
|
let images: Vec<ServiceItem> = self
|
||||||
.image_library
|
.image_library
|
||||||
|
@ -589,14 +589,14 @@ impl<'a> Library {
|
||||||
.filter(|image| {
|
.filter(|image| {
|
||||||
image.title.to_lowercase().contains(&query)
|
image.title.to_lowercase().contains(&query)
|
||||||
})
|
})
|
||||||
.map(|image| image.to_service_item())
|
.map(super::super::core::content::Content::to_service_item)
|
||||||
.collect();
|
.collect();
|
||||||
let presentations: Vec<ServiceItem> = self
|
let presentations: Vec<ServiceItem> = self
|
||||||
.presentation_library
|
.presentation_library
|
||||||
.items
|
.items
|
||||||
.iter()
|
.iter()
|
||||||
.filter(|pres| pres.title.to_lowercase().contains(&query))
|
.filter(|pres| pres.title.to_lowercase().contains(&query))
|
||||||
.map(|pres| pres.to_service_item())
|
.map(super::super::core::content::Content::to_service_item)
|
||||||
.collect();
|
.collect();
|
||||||
items.extend(videos);
|
items.extend(videos);
|
||||||
items.extend(images);
|
items.extend(images);
|
||||||
|
@ -656,7 +656,7 @@ fn update_in_db(
|
||||||
Task::perform(
|
Task::perform(
|
||||||
update_song_in_db(song.to_owned(), conn).map(
|
update_song_in_db(song.to_owned(), conn).map(
|
||||||
move |r| match r {
|
move |r| match r {
|
||||||
Ok(_) => {
|
Ok(()) => {
|
||||||
warn!(
|
warn!(
|
||||||
"Should have updated song: {:?}",
|
"Should have updated song: {:?}",
|
||||||
song_title
|
song_title
|
||||||
|
@ -667,7 +667,7 @@ fn update_in_db(
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
|_| Message::SongChanged,
|
|()| Message::SongChanged,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -154,7 +154,7 @@ impl Presenter {
|
||||||
absolute_slide_index: 0,
|
absolute_slide_index: 0,
|
||||||
total_slides,
|
total_slides,
|
||||||
video,
|
video,
|
||||||
audio: items[0].slides[0].audio().clone(),
|
audio: items[0].slides[0].audio(),
|
||||||
service: items,
|
service: items,
|
||||||
video_position: 0.0,
|
video_position: 0.0,
|
||||||
hovered_slide: None,
|
hovered_slide: None,
|
||||||
|
@ -221,8 +221,7 @@ impl Presenter {
|
||||||
let offset = AbsoluteOffset {
|
let offset = AbsoluteOffset {
|
||||||
x: {
|
x: {
|
||||||
if self.current_slide_index > 2 {
|
if self.current_slide_index > 2 {
|
||||||
self.current_slide_index as f32 * 187.5
|
(self.current_slide_index as f32).mul_add(187.5, -187.5)
|
||||||
- 187.5
|
|
||||||
} else {
|
} else {
|
||||||
0.0
|
0.0
|
||||||
}
|
}
|
||||||
|
@ -256,7 +255,7 @@ impl Presenter {
|
||||||
?current_audio,
|
?current_audio,
|
||||||
"audio needs to change"
|
"audio needs to change"
|
||||||
);
|
);
|
||||||
self.audio = Some(new_audio.clone());
|
self.audio = Some(new_audio);
|
||||||
tasks.push(self.start_audio());
|
tasks.push(self.start_audio());
|
||||||
}
|
}
|
||||||
Some(current_audio) => {
|
Some(current_audio) => {
|
||||||
|
@ -271,10 +270,10 @@ impl Presenter {
|
||||||
?new_audio,
|
?new_audio,
|
||||||
"could not find audio, need to change"
|
"could not find audio, need to change"
|
||||||
);
|
);
|
||||||
self.audio = Some(new_audio.clone());
|
self.audio = Some(new_audio);
|
||||||
tasks.push(self.start_audio());
|
tasks.push(self.start_audio());
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
} else {
|
} else {
|
||||||
self.audio = None;
|
self.audio = None;
|
||||||
self.update(Message::EndAudio);
|
self.update(Message::EndAudio);
|
||||||
|
@ -326,7 +325,7 @@ impl Presenter {
|
||||||
std::time::Duration::from_secs_f32(position),
|
std::time::Duration::from_secs_f32(position),
|
||||||
);
|
);
|
||||||
match video.seek(position, false) {
|
match video.seek(position, false) {
|
||||||
Ok(_) => debug!(
|
Ok(()) => debug!(
|
||||||
"Video position changed: {:?}",
|
"Video position changed: {:?}",
|
||||||
position
|
position
|
||||||
),
|
),
|
||||||
|
@ -355,7 +354,7 @@ impl Presenter {
|
||||||
install_ctx
|
install_ctx
|
||||||
.set_desktop_id(&format!("{}.desktop", "org.chriscochrun.lumina"));
|
.set_desktop_id(&format!("{}.desktop", "org.chriscochrun.lumina"));
|
||||||
let install_detail = missing_plugin.installer_detail();
|
let install_detail = missing_plugin.installer_detail();
|
||||||
println!("installing plugins: {}", install_detail);
|
println!("installing plugins: {install_detail}");
|
||||||
let status = gst_pbutils::missing_plugins::install_plugins_sync(
|
let status = gst_pbutils::missing_plugins::install_plugins_sync(
|
||||||
&[&install_detail],
|
&[&install_detail],
|
||||||
Some(&install_ctx),
|
Some(&install_ctx),
|
||||||
|
@ -391,7 +390,7 @@ impl Presenter {
|
||||||
Message::Error(error) => {
|
Message::Error(error) => {
|
||||||
error!(error);
|
error!(error);
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
Action::None
|
Action::None
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -641,7 +640,7 @@ impl Presenter {
|
||||||
v.set_looping(
|
v.set_looping(
|
||||||
self.current_slide.video_loop(),
|
self.current_slide.video_loop(),
|
||||||
);
|
);
|
||||||
self.video = Some(v)
|
self.video = Some(v);
|
||||||
}
|
}
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
error!(
|
error!(
|
||||||
|
@ -664,7 +663,7 @@ impl Presenter {
|
||||||
let audio = audio.clone();
|
let audio = audio.clone();
|
||||||
Task::perform(
|
Task::perform(
|
||||||
start_audio(Arc::clone(&self.sink.1), audio),
|
start_audio(Arc::clone(&self.sink.1), audio),
|
||||||
|_| Message::None,
|
|()| Message::None,
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
debug!(?self.audio, "Apparently this doesn't exist");
|
debug!(?self.audio, "Apparently this doesn't exist");
|
||||||
|
|
|
@ -54,10 +54,10 @@ struct EditorProgram {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl SlideEditor {
|
impl SlideEditor {
|
||||||
pub fn view<'a>(
|
pub fn view(
|
||||||
&'a self,
|
&self,
|
||||||
font: Font,
|
font: Font,
|
||||||
) -> cosmic::Element<'a, SlideWidget> {
|
) -> cosmic::Element<'_, SlideWidget> {
|
||||||
container(
|
container(
|
||||||
widget::canvas(&self.program)
|
widget::canvas(&self.program)
|
||||||
.height(Length::Fill)
|
.height(Length::Fill)
|
||||||
|
@ -122,10 +122,10 @@ impl<'a> Program<SlideWidget, cosmic::Theme, cosmic::Renderer>
|
||||||
match event {
|
match event {
|
||||||
canvas::Event::Mouse(event) => match event {
|
canvas::Event::Mouse(event) => match event {
|
||||||
cosmic::iced::mouse::Event::CursorEntered => {
|
cosmic::iced::mouse::Event::CursorEntered => {
|
||||||
debug!("cursor entered")
|
debug!("cursor entered");
|
||||||
}
|
}
|
||||||
cosmic::iced::mouse::Event::CursorLeft => {
|
cosmic::iced::mouse::Event::CursorLeft => {
|
||||||
debug!("cursor left")
|
debug!("cursor left");
|
||||||
}
|
}
|
||||||
cosmic::iced::mouse::Event::CursorMoved {
|
cosmic::iced::mouse::Event::CursorMoved {
|
||||||
position,
|
position,
|
||||||
|
@ -140,7 +140,7 @@ impl<'a> Program<SlideWidget, cosmic::Theme, cosmic::Renderer>
|
||||||
}
|
}
|
||||||
cosmic::iced::mouse::Event::ButtonPressed(button) => {
|
cosmic::iced::mouse::Event::ButtonPressed(button) => {
|
||||||
// self.mouse_button_pressed = Some(button);
|
// self.mouse_button_pressed = Some(button);
|
||||||
debug!(?button, "mouse button pressed")
|
debug!(?button, "mouse button pressed");
|
||||||
}
|
}
|
||||||
cosmic::iced::mouse::Event::ButtonReleased(
|
cosmic::iced::mouse::Event::ButtonReleased(
|
||||||
button,
|
button,
|
||||||
|
|
|
@ -140,11 +140,11 @@ impl SongEditor {
|
||||||
self.song = Some(song.clone());
|
self.song = Some(song.clone());
|
||||||
self.title = song.title;
|
self.title = song.title;
|
||||||
if let Some(font) = song.font {
|
if let Some(font) = song.font {
|
||||||
self.font = font
|
self.font = font;
|
||||||
};
|
}
|
||||||
if let Some(font_size) = song.font_size {
|
if let Some(font_size) = song.font_size {
|
||||||
self.font_size = font_size as usize
|
self.font_size = font_size as usize;
|
||||||
};
|
}
|
||||||
if let Some(verse_order) = song.verse_order {
|
if let Some(verse_order) = song.verse_order {
|
||||||
self.verse_order = verse_order
|
self.verse_order = verse_order
|
||||||
.into_iter()
|
.into_iter()
|
||||||
|
@ -155,18 +155,18 @@ impl SongEditor {
|
||||||
.collect();
|
.collect();
|
||||||
}
|
}
|
||||||
if let Some(author) = song.author {
|
if let Some(author) = song.author {
|
||||||
self.author = author
|
self.author = author;
|
||||||
};
|
}
|
||||||
if let Some(audio) = song.audio {
|
if let Some(audio) = song.audio {
|
||||||
self.audio = audio
|
self.audio = audio;
|
||||||
};
|
}
|
||||||
if let Some(ccli) = song.ccli {
|
if let Some(ccli) = song.ccli {
|
||||||
self.ccli = ccli
|
self.ccli = ccli;
|
||||||
};
|
}
|
||||||
if let Some(lyrics) = song.lyrics {
|
if let Some(lyrics) = song.lyrics {
|
||||||
self.lyrics =
|
self.lyrics =
|
||||||
text_editor::Content::with_text(&lyrics)
|
text_editor::Content::with_text(&lyrics);
|
||||||
};
|
}
|
||||||
self.background_video(&song.background);
|
self.background_video(&song.background);
|
||||||
self.background = song.background;
|
self.background = song.background;
|
||||||
}
|
}
|
||||||
|
@ -212,8 +212,8 @@ impl SongEditor {
|
||||||
self.verse_order = verse_order.clone();
|
self.verse_order = verse_order.clone();
|
||||||
if let Some(mut song) = self.song.clone() {
|
if let Some(mut song) = self.song.clone() {
|
||||||
let verse_order = verse_order
|
let verse_order = verse_order
|
||||||
.split(" ")
|
.split(' ')
|
||||||
.map(|s| s.to_owned())
|
.map(std::borrow::ToOwned::to_owned)
|
||||||
.collect();
|
.collect();
|
||||||
song.verse_order = Some(verse_order);
|
song.verse_order = Some(verse_order);
|
||||||
return self.update_song(song);
|
return self.update_song(song);
|
||||||
|
@ -245,7 +245,7 @@ impl SongEditor {
|
||||||
debug!(?path);
|
debug!(?path);
|
||||||
if let Some(mut song) = self.song.clone() {
|
if let Some(mut song) = self.song.clone() {
|
||||||
let background =
|
let background =
|
||||||
Background::try_from(path.clone()).ok();
|
Background::try_from(path).ok();
|
||||||
self.background_video(&background);
|
self.background_video(&background);
|
||||||
song.background = background;
|
song.background = background;
|
||||||
return self.update_song(song);
|
return self.update_song(song);
|
||||||
|
@ -416,7 +416,7 @@ order",
|
||||||
.into()
|
.into()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn editing(&self) -> bool {
|
pub const fn editing(&self) -> bool {
|
||||||
self.editing
|
self.editing
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -121,15 +121,15 @@ impl From<&str> for Font {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Font {
|
impl Font {
|
||||||
pub fn get_name(&self) -> String {
|
#[must_use] pub fn get_name(&self) -> String {
|
||||||
self.name.clone()
|
self.name.clone()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_weight(&self) -> Weight {
|
#[must_use] pub const fn get_weight(&self) -> Weight {
|
||||||
self.weight
|
self.weight
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_style(&self) -> Style {
|
#[must_use] pub const fn get_style(&self) -> Style {
|
||||||
self.style
|
self.style
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -148,7 +148,7 @@ impl Font {
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn size(mut self, size: u8) -> Self {
|
#[must_use] pub const fn size(mut self, size: u8) -> Self {
|
||||||
self.size = size;
|
self.size = size;
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
@ -161,12 +161,12 @@ impl Hash for Color {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Color {
|
impl Color {
|
||||||
pub fn from_hex_str(color: impl AsRef<str>) -> Color {
|
pub fn from_hex_str(color: impl AsRef<str>) -> Self {
|
||||||
match Rgb::from_hex_str(color.as_ref()) {
|
match Rgb::from_hex_str(color.as_ref()) {
|
||||||
Ok(rgb) => Color(rgb),
|
Ok(rgb) => Self(rgb),
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
error!("error in making color from hex_str: {:?}", e);
|
error!("error in making color from hex_str: {:?}", e);
|
||||||
Color::default()
|
Self::default()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -236,7 +236,7 @@ impl TextSvg {
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn alignment(mut self, alignment: TextAlignment) -> Self {
|
pub const fn alignment(mut self, alignment: TextAlignment) -> Self {
|
||||||
self.alignment = alignment;
|
self.alignment = alignment;
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
@ -255,7 +255,7 @@ impl TextSvg {
|
||||||
shadow.spread,
|
shadow.spread,
|
||||||
shadow.color)
|
shadow.color)
|
||||||
} else {
|
} else {
|
||||||
"".into()
|
String::new()
|
||||||
};
|
};
|
||||||
let stroke = if let Some(stroke) = &self.stroke {
|
let stroke = if let Some(stroke) = &self.stroke {
|
||||||
format!(
|
format!(
|
||||||
|
@ -263,17 +263,17 @@ impl TextSvg {
|
||||||
stroke.color, stroke.size
|
stroke.color, stroke.size
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
"".into()
|
String::new()
|
||||||
};
|
};
|
||||||
let size = Size::new(1920.0, 1080.0);
|
let size = Size::new(1920.0, 1080.0);
|
||||||
let font_size = self.font.size as f32;
|
let font_size = f32::from(self.font.size);
|
||||||
let total_lines = self.text.lines().count();
|
let total_lines = self.text.lines().count();
|
||||||
let half_lines = (total_lines / 2) as f32;
|
let half_lines = (total_lines / 2) as f32;
|
||||||
let middle_position = size.height / 2.0;
|
let middle_position = size.height / 2.0;
|
||||||
let line_spacing = 10.0;
|
let line_spacing = 10.0;
|
||||||
let text_and_line_spacing = font_size + line_spacing;
|
let text_and_line_spacing = font_size + line_spacing;
|
||||||
let starting_y_position =
|
let starting_y_position =
|
||||||
middle_position - (half_lines * text_and_line_spacing);
|
half_lines.mul_add(-text_and_line_spacing, middle_position);
|
||||||
|
|
||||||
let text_pieces: Vec<String> = self
|
let text_pieces: Vec<String> = self
|
||||||
.text
|
.text
|
||||||
|
@ -282,8 +282,7 @@ impl TextSvg {
|
||||||
.map(|(index, text)| {
|
.map(|(index, text)| {
|
||||||
format!(
|
format!(
|
||||||
"<tspan x=\"50%\" y=\"{}\">{}</tspan>",
|
"<tspan x=\"50%\" y=\"{}\">{}</tspan>",
|
||||||
starting_y_position
|
(index as f32).mul_add(text_and_line_spacing, starting_y_position),
|
||||||
+ (index as f32 * text_and_line_spacing),
|
|
||||||
text
|
text
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
|
@ -350,7 +349,7 @@ impl TextSvg {
|
||||||
self.text
|
self.text
|
||||||
.lines()
|
.lines()
|
||||||
.enumerate()
|
.enumerate()
|
||||||
.map(|(i, t)| format!("<tspan x=\"50%\">{}</tspan>", t))
|
.map(|(i, t)| format!("<tspan x=\"50%\">{t}</tspan>"))
|
||||||
.collect()
|
.collect()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -391,7 +390,7 @@ pub fn text_svg_generator(
|
||||||
.shadow(shadow(2, 2, 5, "#000000"))
|
.shadow(shadow(2, 2, 5, "#000000"))
|
||||||
.stroke(stroke(3, "#000"))
|
.stroke(stroke(3, "#000"))
|
||||||
.font(
|
.font(
|
||||||
Font::from(slide.font().clone())
|
Font::from(slide.font())
|
||||||
.size(slide.font_size().try_into().unwrap()),
|
.size(slide.font_size().try_into().unwrap()),
|
||||||
)
|
)
|
||||||
.fontdb(Arc::clone(&fontdb))
|
.fontdb(Arc::clone(&fontdb))
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue