updating db to allow for changing the style and weight of the font
Also, fixed a bug in showing the stroke and shadow size if set to 0
This commit is contained in:
parent
d77205cdec
commit
c6ae2a0fbd
5 changed files with 84 additions and 51 deletions
6
migrations/20260217193356_add_text_weight_and_style.sql
Normal file
6
migrations/20260217193356_add_text_weight_and_style.sql
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
-- Add migration script here
|
||||
ALTER TABLE songs
|
||||
ADD COLUMN weight TEXT;
|
||||
|
||||
ALTER TABLE songs
|
||||
ADD COLUMN style TEXT;
|
||||
|
|
@ -436,6 +436,18 @@ impl FromRow<'_, SqliteRow> for Song {
|
|||
_ => None,
|
||||
};
|
||||
|
||||
let style_string: String = row.try_get("style")?;
|
||||
let font_style =
|
||||
ron::de::from_str::<Option<Style>>(&style_string)
|
||||
.ok()
|
||||
.flatten();
|
||||
|
||||
let weight_string: String = row.try_get("weight")?;
|
||||
let font_weight =
|
||||
ron::de::from_str::<Option<Weight>>(&weight_string)
|
||||
.ok()
|
||||
.flatten();
|
||||
|
||||
Ok(Self {
|
||||
id: row.try_get("id")?,
|
||||
title: row.try_get("title")?,
|
||||
|
|
@ -479,6 +491,8 @@ impl FromRow<'_, SqliteRow> for Song {
|
|||
}),
|
||||
font: row.try_get("font")?,
|
||||
font_size: row.try_get("font_size")?,
|
||||
font_style,
|
||||
font_weight,
|
||||
stroke_size,
|
||||
stroke_color,
|
||||
shadow_size,
|
||||
|
|
@ -698,7 +712,7 @@ pub async fn get_song_from_db(
|
|||
index: i32,
|
||||
db: &mut SqliteConnection,
|
||||
) -> Result<Song> {
|
||||
let row = query("SELECT verse_order, font_size, background_type, horizontal_text_alignment, vertical_text_alignment, title, font, background, lyrics, ccli, author, audio, stroke_size, stroke_color, shadow_color, shadow_size, shadow_offset_x, shadow_offset_y, id from songs where id = $1").bind(index).fetch_one(db).await.into_diagnostic()?;
|
||||
let row = query("SELECT verse_order, font_size, background_type, horizontal_text_alignment, vertical_text_alignment, title, font, background, lyrics, ccli, author, audio, stroke_size, stroke_color, shadow_color, shadow_size, shadow_offset_x, shadow_offset_y, style, weight, id from songs where id = $1").bind(index).fetch_one(db).await.into_diagnostic()?;
|
||||
Song::from_row(&row).into_diagnostic()
|
||||
}
|
||||
|
||||
|
|
@ -716,7 +730,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.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;
|
||||
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, style, weight, id from songs").fetch_all(&mut db1.detach()).await;
|
||||
match result {
|
||||
Ok(s) => {
|
||||
for song in s {
|
||||
|
|
@ -854,6 +868,11 @@ pub async fn update_song_in_db(
|
|||
let shadow_color =
|
||||
ron::ser::to_string(&item.shadow_color).into_diagnostic()?;
|
||||
|
||||
let style =
|
||||
ron::ser::to_string(&item.font_style).into_diagnostic()?;
|
||||
let weight =
|
||||
ron::ser::to_string(&item.font_weight).into_diagnostic()?;
|
||||
|
||||
// debug!(
|
||||
// ?stroke_size,
|
||||
// ?stroke_color,
|
||||
|
|
@ -864,7 +883,7 @@ pub async fn update_song_in_db(
|
|||
// );
|
||||
|
||||
let result = query!(
|
||||
r#"UPDATE songs SET title = $2, lyrics = $3, author = $4, ccli = $5, verse_order = $6, audio = $7, font = $8, font_size = $9, background = $10, horizontal_text_alignment = $11, vertical_text_alignment = $12, stroke_color = $13, shadow_color = $14, stroke_size = $15, shadow_size = $16, shadow_offset_x = $17, shadow_offset_y = $18 WHERE id = $1"#,
|
||||
r#"UPDATE songs SET title = $2, lyrics = $3, author = $4, ccli = $5, verse_order = $6, audio = $7, font = $8, font_size = $9, background = $10, horizontal_text_alignment = $11, vertical_text_alignment = $12, stroke_color = $13, shadow_color = $14, stroke_size = $15, shadow_size = $16, shadow_offset_x = $17, shadow_offset_y = $18, style = $19, weight = $20 WHERE id = $1"#,
|
||||
item.id,
|
||||
item.title,
|
||||
lyrics,
|
||||
|
|
@ -882,7 +901,9 @@ pub async fn update_song_in_db(
|
|||
stroke_size,
|
||||
shadow_size,
|
||||
shadow_offset_x,
|
||||
shadow_offset_y
|
||||
shadow_offset_y,
|
||||
style,
|
||||
weight
|
||||
)
|
||||
.execute(&mut db.detach())
|
||||
.await
|
||||
|
|
|
|||
|
|
@ -447,7 +447,7 @@ impl SongEditor {
|
|||
if let Some(song) = &mut self.song {
|
||||
song.font = Some(font.0.families[0].0.clone());
|
||||
let song = song.to_owned();
|
||||
return Action::Task(self.update_song(song));
|
||||
return Action::Task(self.update_song(&song));
|
||||
}
|
||||
}
|
||||
Message::ChangeFontStyle => {
|
||||
|
|
@ -466,7 +466,7 @@ impl SongEditor {
|
|||
song.font_style = Some(Style::Italic);
|
||||
}
|
||||
let song = song.clone();
|
||||
return Action::Task(self.update_song(song));
|
||||
return Action::Task(self.update_song(&song));
|
||||
}
|
||||
}
|
||||
Message::ChangeFontWeight => {
|
||||
|
|
@ -485,7 +485,7 @@ impl SongEditor {
|
|||
song.font_weight = Some(Weight::Bold);
|
||||
}
|
||||
let song = song.clone();
|
||||
return Action::Task(self.update_song(song));
|
||||
return Action::Task(self.update_song(&song));
|
||||
}
|
||||
}
|
||||
Message::ChangeFontSize(size) => {
|
||||
|
|
@ -494,7 +494,7 @@ impl SongEditor {
|
|||
if let Some(song) = &mut self.song {
|
||||
song.font_size = i32::try_from(size).ok();
|
||||
let song = song.to_owned();
|
||||
return Action::Task(self.update_song(song));
|
||||
return Action::Task(self.update_song(&song));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -503,7 +503,7 @@ impl SongEditor {
|
|||
if let Some(song) = &mut self.song {
|
||||
song.title = title;
|
||||
let song = song.to_owned();
|
||||
return Action::Task(self.update_song(song));
|
||||
return Action::Task(self.update_song(&song));
|
||||
}
|
||||
}
|
||||
Message::ChangeVerseOrder(verse_order) => {
|
||||
|
|
@ -514,7 +514,7 @@ impl SongEditor {
|
|||
.map(std::borrow::ToOwned::to_owned)
|
||||
.collect();
|
||||
song.verse_order = Some(verse_order);
|
||||
return Action::Task(self.update_song(song));
|
||||
return Action::Task(self.update_song(&song));
|
||||
}
|
||||
}
|
||||
Message::ChangeLyrics(action) => {
|
||||
|
|
@ -524,7 +524,7 @@ impl SongEditor {
|
|||
|
||||
if let Some(mut song) = self.song.clone() {
|
||||
song.lyrics = Some(lyrics);
|
||||
return Action::Task(self.update_song(song));
|
||||
return Action::Task(self.update_song(&song));
|
||||
}
|
||||
}
|
||||
Message::Edit(edit) => {
|
||||
|
|
@ -536,7 +536,7 @@ impl SongEditor {
|
|||
self.author.clone_from(&author);
|
||||
if let Some(mut song) = self.song.clone() {
|
||||
song.author = Some(author);
|
||||
return Action::Task(self.update_song(song));
|
||||
return Action::Task(self.update_song(&song));
|
||||
}
|
||||
}
|
||||
Message::ChangeBackground(Ok(path)) => {
|
||||
|
|
@ -545,7 +545,7 @@ impl SongEditor {
|
|||
let background = Background::try_from(path).ok();
|
||||
self.background_video(background.as_ref());
|
||||
song.background = background;
|
||||
return Action::Task(self.update_song(song));
|
||||
return Action::Task(self.update_song(&song));
|
||||
}
|
||||
}
|
||||
Message::ChangeBackground(Err(error)) => {
|
||||
|
|
@ -571,7 +571,7 @@ impl SongEditor {
|
|||
song.stroke_size =
|
||||
if size == 0 { None } else { Some(size) };
|
||||
let song = song.to_owned();
|
||||
return Action::Task(self.update_song(song));
|
||||
return Action::Task(self.update_song(&song));
|
||||
}
|
||||
}
|
||||
Message::UpdateStrokeColor(update) => {
|
||||
|
|
@ -583,7 +583,7 @@ impl SongEditor {
|
|||
{
|
||||
debug!(?color);
|
||||
song.stroke_color = Some(color.into());
|
||||
tasks.push(self.update_song(song));
|
||||
tasks.push(self.update_song(&song));
|
||||
}
|
||||
return Action::Task(Task::batch(tasks));
|
||||
}
|
||||
|
|
@ -657,7 +657,7 @@ impl SongEditor {
|
|||
);
|
||||
|
||||
return Action::Task(
|
||||
self.update_song(song),
|
||||
self.update_song(&song),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
@ -672,7 +672,7 @@ impl SongEditor {
|
|||
// index, verse, lyric,
|
||||
// );
|
||||
return Action::Task(
|
||||
self.update_song(song),
|
||||
self.update_song(&song),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
@ -692,7 +692,7 @@ impl SongEditor {
|
|||
verses.remove(verse);
|
||||
}
|
||||
return Action::Task(
|
||||
self.update_song(song),
|
||||
self.update_song(&song),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
@ -716,7 +716,7 @@ impl SongEditor {
|
|||
}
|
||||
if let Some(mut song) = self.song.clone() {
|
||||
song.add_verse(verse, lyric);
|
||||
return Action::Task(self.update_song(song));
|
||||
return Action::Task(self.update_song(&song));
|
||||
}
|
||||
}
|
||||
Message::RemoveVerse(index) => {
|
||||
|
|
@ -727,7 +727,7 @@ impl SongEditor {
|
|||
verses.remove(index);
|
||||
},
|
||||
);
|
||||
return Action::Task(self.update_song(song));
|
||||
return Action::Task(self.update_song(&song));
|
||||
}
|
||||
}
|
||||
Message::ChipHovered(index) => {
|
||||
|
|
@ -746,7 +746,7 @@ impl SongEditor {
|
|||
verses.insert(index, verse);
|
||||
let song = song.clone();
|
||||
return Action::Task(
|
||||
self.update_song(song),
|
||||
self.update_song(&song),
|
||||
);
|
||||
}
|
||||
error!("No verses in this song?");
|
||||
|
|
@ -769,7 +769,7 @@ impl SongEditor {
|
|||
verses.push(verse);
|
||||
let song = song.clone();
|
||||
return Action::Task(
|
||||
self.update_song(song),
|
||||
self.update_song(&song),
|
||||
);
|
||||
}
|
||||
error!(
|
||||
|
|
@ -793,7 +793,7 @@ impl SongEditor {
|
|||
let verse = verses.remove(index);
|
||||
verses.insert(target_index, verse);
|
||||
debug!(?verses);
|
||||
return Action::Task(self.update_song(song));
|
||||
return Action::Task(self.update_song(&song));
|
||||
}
|
||||
}
|
||||
draggable::DragEvent::Picked { .. }
|
||||
|
|
@ -808,7 +808,7 @@ impl SongEditor {
|
|||
Message::SetTextAlignment(alignment) => {
|
||||
if let Some(mut song) = self.song.clone() {
|
||||
song.text_alignment = Some(alignment);
|
||||
return Action::Task(self.update_song(song));
|
||||
return Action::Task(self.update_song(&song));
|
||||
}
|
||||
}
|
||||
Message::UpdateShadowSize(index) => {
|
||||
|
|
@ -820,7 +820,7 @@ impl SongEditor {
|
|||
song.shadow_size =
|
||||
if size == 0 { None } else { Some(size) };
|
||||
let song = song.to_owned();
|
||||
return Action::Task(self.update_song(song));
|
||||
return Action::Task(self.update_song(&song));
|
||||
}
|
||||
}
|
||||
Message::UpdateShadowOffsetX(index) => {
|
||||
|
|
@ -837,7 +837,7 @@ impl SongEditor {
|
|||
} else {
|
||||
song.shadow_offset = Some((x, 0));
|
||||
}
|
||||
return Action::Task(self.update_song(song));
|
||||
return Action::Task(self.update_song(&song));
|
||||
}
|
||||
}
|
||||
Message::UpdateShadowOffsetY(index) => {
|
||||
|
|
@ -854,7 +854,7 @@ impl SongEditor {
|
|||
} else {
|
||||
song.shadow_offset = Some((0, y));
|
||||
}
|
||||
return Action::Task(self.update_song(song));
|
||||
return Action::Task(self.update_song(&song));
|
||||
}
|
||||
}
|
||||
Message::UpdateShadowColor(update) => {
|
||||
|
|
@ -866,7 +866,7 @@ impl SongEditor {
|
|||
{
|
||||
debug!(?color);
|
||||
song.shadow_color = Some(color.into());
|
||||
tasks.push(self.update_song(song));
|
||||
tasks.push(self.update_song(&song));
|
||||
}
|
||||
return Action::Task(Task::batch(tasks));
|
||||
}
|
||||
|
|
@ -1419,16 +1419,18 @@ impl SongEditor {
|
|||
dropdown(
|
||||
&self.stroke_sizes,
|
||||
self.song.as_ref().and_then(|song| {
|
||||
song.stroke_size.and_then(|size| {
|
||||
self.stroke_sizes.iter().position(
|
||||
|size_string| {
|
||||
size_string
|
||||
.parse::<u16>()
|
||||
.expect("these are fine")
|
||||
== size
|
||||
},
|
||||
)
|
||||
})
|
||||
song.stroke_size
|
||||
.and_then(|size| {
|
||||
self.stroke_sizes.iter().position(
|
||||
|size_string| {
|
||||
size_string
|
||||
.parse::<u16>()
|
||||
.expect("these are fine")
|
||||
== size
|
||||
},
|
||||
)
|
||||
})
|
||||
.map_or(Some(0), Some)
|
||||
}),
|
||||
Message::UpdateStrokeSize,
|
||||
)
|
||||
|
|
@ -1499,14 +1501,18 @@ impl SongEditor {
|
|||
let shadow_size_dropdown = dropdown(
|
||||
&self.shadow_sizes,
|
||||
self.song.as_ref().and_then(|song| {
|
||||
song.shadow_size.and_then(|size| {
|
||||
self.shadow_sizes.iter().position(|size_string| {
|
||||
size_string
|
||||
.parse::<u16>()
|
||||
.expect("these are fine")
|
||||
== size
|
||||
song.shadow_size
|
||||
.and_then(|size| {
|
||||
self.shadow_sizes.iter().position(
|
||||
|size_string| {
|
||||
size_string
|
||||
.parse::<u16>()
|
||||
.expect("these are fine")
|
||||
== size
|
||||
},
|
||||
)
|
||||
})
|
||||
})
|
||||
.map_or(Some(0), Some)
|
||||
}),
|
||||
Message::UpdateShadowSize,
|
||||
)
|
||||
|
|
@ -1533,7 +1539,7 @@ impl SongEditor {
|
|||
let shadow_offset_y_dropdown = dropdown(
|
||||
&self.shadow_offset_sizes,
|
||||
self.song.as_ref().and_then(|song| {
|
||||
song.shadow_offset.and_then(|(offset_y, _)| {
|
||||
song.shadow_offset.and_then(|(_, offset_y)| {
|
||||
self.shadow_offset_sizes.iter().position(
|
||||
|y_string| {
|
||||
y_string
|
||||
|
|
@ -1801,7 +1807,7 @@ impl SongEditor {
|
|||
|
||||
// fn update_verse_slide_subscription(&self)
|
||||
|
||||
fn update_song(&mut self, song: Song) -> Task<Message> {
|
||||
fn update_song(&mut self, song: &Song) -> Task<Message> {
|
||||
// use cosmic::iced_futures::futures::stream;
|
||||
// use cosmic::iced_futures::futures::{Stream, StreamExt};
|
||||
// use cosmic::iced_futures::stream::channel;
|
||||
|
|
@ -1873,7 +1879,7 @@ impl SongEditor {
|
|||
self.update_slide_handle = Some(handle);
|
||||
tasks.push(task);
|
||||
}
|
||||
tasks.push(Task::done(Message::UpdateSong(song)));
|
||||
tasks.push(Task::done(Message::UpdateSong(song.clone())));
|
||||
|
||||
Task::batch(tasks)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@ use resvg::{
|
|||
usvg::{Tree, fontdb},
|
||||
};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use tracing::{debug, error};
|
||||
use tracing::error;
|
||||
|
||||
use crate::TextAlignment;
|
||||
|
||||
|
|
@ -580,7 +580,7 @@ pub fn text_svg_generator_with_cache(
|
|||
text_svg
|
||||
};
|
||||
let text_svg = text_svg.font(font).fontdb(Arc::clone(fontdb));
|
||||
debug!(fill = ?text_svg.fill, font = ?text_svg.font, stroke = ?text_svg.stroke, shadow = ?text_svg.shadow, text = ?text_svg.text);
|
||||
// debug!(fill = ?text_svg.fill, font = ?text_svg.font, stroke = ?text_svg.stroke, shadow = ?text_svg.shadow, text = ?text_svg.text);
|
||||
let text_svg =
|
||||
text_svg.build(Size::new(1280.0, 720.0), cache);
|
||||
slide.text_svg = Some(text_svg);
|
||||
|
|
@ -598,7 +598,7 @@ mod tests {
|
|||
#[test]
|
||||
fn test_generator() {
|
||||
let slide = Slide::default();
|
||||
|
||||
debug!("test");
|
||||
let mut fontdb = Database::new();
|
||||
fontdb.load_system_fonts();
|
||||
let fontdb = Arc::new(fontdb);
|
||||
|
|
|
|||
BIN
test.db
BIN
test.db
Binary file not shown.
Loading…
Add table
Add a link
Reference in a new issue