mirror of
https://github.com/johrpan/musicus.git
synced 2025-10-26 11:47:25 +01:00
Show albums on home screen
This commit is contained in:
parent
3ab0332475
commit
38613c0063
7 changed files with 172 additions and 3 deletions
25
data/ui/album_tile.blp
Normal file
25
data/ui/album_tile.blp
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
using Gtk 4.0;
|
||||
using Adw 1;
|
||||
|
||||
template $MusicusAlbumTile: Gtk.FlowBoxChild {
|
||||
styles [
|
||||
"card",
|
||||
"activatable",
|
||||
"tile"
|
||||
]
|
||||
|
||||
Gtk.Box {
|
||||
valign: center;
|
||||
|
||||
Gtk.Label title_label {
|
||||
styles [
|
||||
"title"
|
||||
]
|
||||
|
||||
valign: center;
|
||||
halign: start;
|
||||
lines: 1;
|
||||
ellipsize: end;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -127,6 +127,23 @@ template $MusicusHomePage : Adw.NavigationPage {
|
|||
selection-mode: none;
|
||||
child-activated => $recording_selected() swapped;
|
||||
}
|
||||
|
||||
Gtk.Label {
|
||||
styles ["heading"]
|
||||
visible: bind albums_flow_box.visible;
|
||||
halign: start;
|
||||
label: _("Albums");
|
||||
}
|
||||
|
||||
Gtk.FlowBox albums_flow_box {
|
||||
margin-top: 12;
|
||||
margin-bottom: 24;
|
||||
column-spacing: 12;
|
||||
row-spacing: 12;
|
||||
homogeneous: true;
|
||||
selection-mode: none;
|
||||
child-activated => $album_selected() swapped;
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
|
|
|||
56
src/album_tile.rs
Normal file
56
src/album_tile.rs
Normal file
|
|
@ -0,0 +1,56 @@
|
|||
use gtk::{glib, subclass::prelude::*};
|
||||
use std::cell::OnceCell;
|
||||
|
||||
use crate::db::models::Album;
|
||||
|
||||
mod imp {
|
||||
use super::*;
|
||||
|
||||
#[derive(Debug, Default, gtk::CompositeTemplate)]
|
||||
#[template(file = "data/ui/album_tile.blp")]
|
||||
pub struct MusicusAlbumTile {
|
||||
pub album: OnceCell<Album>,
|
||||
|
||||
#[template_child]
|
||||
pub title_label: TemplateChild<gtk::Label>,
|
||||
}
|
||||
|
||||
#[glib::object_subclass]
|
||||
impl ObjectSubclass for MusicusAlbumTile {
|
||||
const NAME: &'static str = "MusicusAlbumTile";
|
||||
type Type = super::MusicusAlbumTile;
|
||||
type ParentType = gtk::FlowBoxChild;
|
||||
|
||||
fn class_init(klass: &mut Self::Class) {
|
||||
klass.bind_template();
|
||||
}
|
||||
|
||||
fn instance_init(obj: &glib::subclass::InitializingObject<Self>) {
|
||||
obj.init_template();
|
||||
}
|
||||
}
|
||||
|
||||
impl ObjectImpl for MusicusAlbumTile {}
|
||||
impl WidgetImpl for MusicusAlbumTile {}
|
||||
impl FlowBoxChildImpl for MusicusAlbumTile {}
|
||||
}
|
||||
|
||||
glib::wrapper! {
|
||||
pub struct MusicusAlbumTile(ObjectSubclass<imp::MusicusAlbumTile>)
|
||||
@extends gtk::Widget, gtk::FlowBoxChild;
|
||||
}
|
||||
|
||||
impl MusicusAlbumTile {
|
||||
pub fn new(album: &Album) -> Self {
|
||||
let obj: Self = glib::Object::new();
|
||||
|
||||
obj.imp().title_label.set_label(&album.name.get());
|
||||
obj.imp().album.set(album.clone()).unwrap();
|
||||
|
||||
obj
|
||||
}
|
||||
|
||||
pub fn album(&self) -> &Album {
|
||||
self.imp().album.get().unwrap()
|
||||
}
|
||||
}
|
||||
|
|
@ -9,7 +9,7 @@ use diesel::prelude::*;
|
|||
use super::{schema::*, tables, TranslatedString};
|
||||
|
||||
// Re-exports for tables that don't need additional information.
|
||||
pub use tables::{Instrument, Person, Role};
|
||||
pub use tables::{Album, Instrument, Person, Role};
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct Work {
|
||||
|
|
@ -371,3 +371,10 @@ impl Track {
|
|||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl Eq for Album {}
|
||||
impl PartialEq for Album {
|
||||
fn eq(&self, other: &Self) -> bool {
|
||||
self.album_id == other.album_id
|
||||
}
|
||||
}
|
||||
|
|
@ -1,4 +1,5 @@
|
|||
use crate::{
|
||||
album_tile::MusicusAlbumTile,
|
||||
db::models::*,
|
||||
library::{LibraryQuery, MusicusLibrary},
|
||||
player::MusicusPlayer,
|
||||
|
|
@ -8,11 +9,13 @@ use crate::{
|
|||
search_tag::Tag,
|
||||
tag_tile::MusicusTagTile,
|
||||
};
|
||||
|
||||
use adw::subclass::{navigation_page::NavigationPageImpl, prelude::*};
|
||||
use gtk::{
|
||||
glib::{self, clone, Properties},
|
||||
prelude::*,
|
||||
};
|
||||
|
||||
use std::cell::{OnceCell, RefCell};
|
||||
|
||||
mod imp {
|
||||
|
|
@ -33,6 +36,7 @@ mod imp {
|
|||
pub ensembles: RefCell<Vec<Ensemble>>,
|
||||
pub works: RefCell<Vec<Work>>,
|
||||
pub recordings: RefCell<Vec<Recording>>,
|
||||
pub albums: RefCell<Vec<Album>>,
|
||||
|
||||
#[template_child]
|
||||
pub search_entry: TemplateChild<MusicusSearchEntry>,
|
||||
|
|
@ -49,6 +53,8 @@ mod imp {
|
|||
#[template_child]
|
||||
pub recordings_flow_box: TemplateChild<gtk::FlowBox>,
|
||||
#[template_child]
|
||||
pub albums_flow_box: TemplateChild<gtk::FlowBox>,
|
||||
#[template_child]
|
||||
pub play_button: TemplateChild<gtk::Button>,
|
||||
}
|
||||
|
||||
|
|
@ -120,13 +126,14 @@ impl MusicusHomePage {
|
|||
fn select(&self, search_entry: &MusicusSearchEntry) {
|
||||
let imp = self.imp();
|
||||
|
||||
let (composer, performer, ensemble, work, recording) = {
|
||||
let (composer, performer, ensemble, work, recording, album) = {
|
||||
(
|
||||
imp.composers.borrow().first().cloned(),
|
||||
imp.performers.borrow().first().cloned(),
|
||||
imp.ensembles.borrow().first().cloned(),
|
||||
imp.works.borrow().first().cloned(),
|
||||
imp.recordings.borrow().first().cloned(),
|
||||
imp.albums.borrow().first().cloned(),
|
||||
)
|
||||
};
|
||||
|
||||
|
|
@ -140,6 +147,8 @@ impl MusicusHomePage {
|
|||
search_entry.add_tag(Tag::Work(work));
|
||||
} else if let Some(recording) = recording {
|
||||
self.play_recording(&recording);
|
||||
} else if let Some(album) = album {
|
||||
self.show_album(&album);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -159,6 +168,11 @@ impl MusicusHomePage {
|
|||
);
|
||||
}
|
||||
|
||||
#[template_callback]
|
||||
fn album_selected(&self, tile: >k::FlowBoxChild, _: >k::FlowBox) {
|
||||
self.show_album(tile.downcast_ref::<MusicusAlbumTile>().unwrap().album());
|
||||
}
|
||||
|
||||
fn play_recording(&self, recording: &Recording) {
|
||||
let tracks = &recording.tracks;
|
||||
|
||||
|
|
@ -227,6 +241,10 @@ impl MusicusHomePage {
|
|||
self.player().append(items);
|
||||
}
|
||||
|
||||
fn show_album(&self, _album: &Album) {
|
||||
todo!("Show album");
|
||||
}
|
||||
|
||||
fn query(&self, query: &LibraryQuery) {
|
||||
let imp = self.imp();
|
||||
let results = self.library().query(query).unwrap();
|
||||
|
|
@ -237,6 +255,7 @@ impl MusicusHomePage {
|
|||
&imp.ensembles_flow_box,
|
||||
&imp.works_flow_box,
|
||||
&imp.recordings_flow_box,
|
||||
&imp.albums_flow_box,
|
||||
] {
|
||||
while let Some(widget) = flowbox.first_child() {
|
||||
flowbox.remove(&widget);
|
||||
|
|
@ -257,6 +276,7 @@ impl MusicusHomePage {
|
|||
imp.works_flow_box.set_visible(!results.works.is_empty());
|
||||
imp.recordings_flow_box
|
||||
.set_visible(!results.recordings.is_empty());
|
||||
imp.albums_flow_box.set_visible(!results.albums.is_empty());
|
||||
|
||||
for composer in &results.composers {
|
||||
imp.composers_flow_box
|
||||
|
|
@ -283,11 +303,16 @@ impl MusicusHomePage {
|
|||
.append(&MusicusRecordingTile::new(recording));
|
||||
}
|
||||
|
||||
for album in &results.albums {
|
||||
imp.albums_flow_box.append(&MusicusAlbumTile::new(album));
|
||||
}
|
||||
|
||||
imp.composers.replace(results.composers);
|
||||
imp.performers.replace(results.performers);
|
||||
imp.ensembles.replace(results.ensembles);
|
||||
imp.works.replace(results.works);
|
||||
imp.recordings.replace(results.recordings);
|
||||
imp.albums.replace(results.albums);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -109,11 +109,17 @@ impl MusicusLibrary {
|
|||
.map(|w| Work::from_table(w, connection))
|
||||
.collect::<Result<Vec<Work>>>()?;
|
||||
|
||||
let albums: Vec<Album> = albums::table
|
||||
.filter(albums::name.like(&search))
|
||||
.limit(9)
|
||||
.load(connection)?;
|
||||
|
||||
LibraryResults {
|
||||
composers,
|
||||
performers,
|
||||
ensembles,
|
||||
works,
|
||||
albums,
|
||||
..Default::default()
|
||||
}
|
||||
}
|
||||
|
|
@ -219,9 +225,24 @@ impl MusicusLibrary {
|
|||
.map(|r| Recording::from_table(r, &&self.folder(), connection))
|
||||
.collect::<Result<Vec<Recording>>>()?;
|
||||
|
||||
let albums = albums::table
|
||||
.inner_join(
|
||||
album_recordings::table
|
||||
.inner_join(recordings::table.inner_join(recording_ensembles::table)),
|
||||
)
|
||||
.filter(
|
||||
recording_ensembles::ensemble_id
|
||||
.eq(&ensemble.ensemble_id)
|
||||
.and(albums::name.like(&search)),
|
||||
)
|
||||
.select(albums::all_columns)
|
||||
.distinct()
|
||||
.load(connection)?;
|
||||
|
||||
LibraryResults {
|
||||
composers,
|
||||
recordings,
|
||||
albums,
|
||||
..Default::default()
|
||||
}
|
||||
}
|
||||
|
|
@ -265,9 +286,24 @@ impl MusicusLibrary {
|
|||
.map(|r| Recording::from_table(r, &self.folder(), connection))
|
||||
.collect::<Result<Vec<Recording>>>()?;
|
||||
|
||||
let albums = albums::table
|
||||
.inner_join(
|
||||
album_recordings::table
|
||||
.inner_join(recordings::table.inner_join(recording_persons::table)),
|
||||
)
|
||||
.filter(
|
||||
recording_persons::person_id
|
||||
.eq(&performer.person_id)
|
||||
.and(albums::name.like(&search)),
|
||||
)
|
||||
.select(albums::all_columns)
|
||||
.distinct()
|
||||
.load(connection)?;
|
||||
|
||||
LibraryResults {
|
||||
composers,
|
||||
recordings,
|
||||
albums,
|
||||
..Default::default()
|
||||
}
|
||||
}
|
||||
|
|
@ -426,6 +462,7 @@ pub struct LibraryResults {
|
|||
pub ensembles: Vec<Ensemble>,
|
||||
pub works: Vec<Work>,
|
||||
pub recordings: Vec<Recording>,
|
||||
pub albums: Vec<Album>,
|
||||
}
|
||||
|
||||
impl LibraryResults {
|
||||
|
|
@ -435,5 +472,6 @@ impl LibraryResults {
|
|||
&& self.ensembles.is_empty()
|
||||
&& self.works.is_empty()
|
||||
&& self.recordings.is_empty()
|
||||
&& self.albums.is_empty()
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,10 +1,11 @@
|
|||
mod album_tile;
|
||||
mod application;
|
||||
mod config;
|
||||
mod db;
|
||||
mod editor;
|
||||
mod home_page;
|
||||
mod library_manager;
|
||||
mod library;
|
||||
mod library_manager;
|
||||
mod player;
|
||||
mod player_bar;
|
||||
mod playlist_item;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue