diff --git a/app/assets/stylesheets/components/_list.scss b/app/assets/stylesheets/components/_list.scss index 3d230a2f..c4b386ce 100644 --- a/app/assets/stylesheets/components/_list.scss +++ b/app/assets/stylesheets/components/_list.scss @@ -19,6 +19,12 @@ border-bottom: 1px solid var(--list-border-color); } +.c-list__item--divider { + margin-top: spacing("small"); + font-weight: bold; + text-transform: uppercase; +} + .c-list--border-none .c-list__item { border-bottom: none; } diff --git a/app/controllers/albums_controller.rb b/app/controllers/albums_controller.rb index 09bedb71..12297419 100644 --- a/app/controllers/albums_controller.rb +++ b/app/controllers/albums_controller.rb @@ -14,7 +14,7 @@ def index end def show - @songs = @album.songs.includes(:artist) + @groped_songs = @album.songs.includes(:artist).group_by(&:discnum) @album.attach_image_from_discogs end diff --git a/app/models/album.rb b/app/models/album.rb index d07cc4f8..139b4596 100644 --- a/app/models/album.rb +++ b/app/models/album.rb @@ -8,7 +8,7 @@ class Album < ApplicationRecord validates :name, uniqueness: {scope: :artist} - has_many :songs, -> { order(:tracknum) }, inverse_of: :album, dependent: :destroy + has_many :songs, -> { order(:discnum, :tracknum) }, inverse_of: :album, dependent: :destroy belongs_to :artist, touch: true search_by :name, associations: {artist: :name} diff --git a/app/models/media.rb b/app/models/media.rb index 360665e1..834b2784 100644 --- a/app/models/media.rb +++ b/app/models/media.rb @@ -76,7 +76,7 @@ def attach(file_info) end def song_info(file_info) - file_info.slice(:name, :tracknum, :duration, :file_path, :file_path_hash, :bit_depth).compact + file_info.slice(:name, :tracknum, :discnum, :duration, :file_path, :file_path_hash, :bit_depth).compact end def album_info(file_info) diff --git a/app/models/media_file.rb b/app/models/media_file.rb index 023506ba..c9f9eaf4 100644 --- a/app/models/media_file.rb +++ b/app/models/media_file.rb @@ -55,6 +55,7 @@ def get_tag_info(file_path) albumartist_name: tag.albumartist.presence, genre: tag.genre.presence, tracknum: tag.track, + discnum: tag.disc, duration: tag.duration.round, bit_depth: tag.bit_depth, image: extract_image_from(tag) diff --git a/app/views/albums/show.html.erb b/app/views/albums/show.html.erb index bd1f01ff..18703dae 100644 --- a/app/views/albums/show.html.erb +++ b/app/views/albums/show.html.erb @@ -7,9 +7,9 @@

<%= @album.title %>

<%= @album.artist.title %>

- <%= @songs.load.size %> <%= t("label.tracks") %> + <%= @album.songs.count %> <%= t("label.tracks") %> , - <%= format_duration(@songs.sum(:duration)) %> + <%= format_duration(@album.songs.sum(:duration)) %>
<%= button_to( @@ -35,69 +35,75 @@
diff --git a/config/locales/en.yml b/config/locales/en.yml index 488b372c..e5352774 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -108,6 +108,7 @@ en: play_next: 'Play Next' play_last: 'Play Last' search_results: 'Search Results' + disc: 'Disc %{number}' error: login: 'Wrong email or password' forbidden: "Sorry, you do not have permission to visit that" diff --git a/db/migrate/20231207020650_add_discnum_to_songs.rb b/db/migrate/20231207020650_add_discnum_to_songs.rb new file mode 100644 index 00000000..fba957b8 --- /dev/null +++ b/db/migrate/20231207020650_add_discnum_to_songs.rb @@ -0,0 +1,5 @@ +class AddDiscnumToSongs < ActiveRecord::Migration[7.1] + def change + add_column :songs, :discnum, :integer + end +end diff --git a/db/schema.rb b/db/schema.rb index e5c8a9b6..5032edd1 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -10,7 +10,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema[7.1].define(version: 2023_11_02_065319) do +ActiveRecord::Schema[7.1].define(version: 2023_12_07_020650) do create_table "albums", force: :cascade do |t| t.string "name" t.string "image" @@ -77,6 +77,7 @@ t.integer "artist_id" t.string "file_path_hash" t.integer "bit_depth" + t.integer "discnum" t.index ["album_id"], name: "index_songs_on_album_id" t.index ["artist_id"], name: "index_songs_on_artist_id" t.index ["file_path_hash"], name: "index_songs_on_file_path_hash" diff --git a/test/models/album_test.rb b/test/models/album_test.rb index bc7c640e..e5d125c1 100644 --- a/test/models/album_test.rb +++ b/test/models/album_test.rb @@ -12,19 +12,19 @@ class AlbumTest < ActiveSupport::TestCase assert_equal "Unknown Album", Album.create(name: nil).title end - test "should order by tracknum for associated songs" do + test "should order by discnum and tracknum for associated songs" do artist = artists(:artist1) album = artist.albums.create album.songs.create!( [ - {name: "test_song_1", file_path: "fake_path", file_path_hash: "fake_path_hash", md5_hash: "fake_md5", tracknum: 2, artist: artist}, - {name: "test_song_2", file_path: "fake_path", file_path_hash: "fake_path_hash", md5_hash: "fake_md5", tracknum: 3, artist: artist}, - {name: "test_song_3", file_path: "fake_path", file_path_hash: "fake_path_hash", md5_hash: "fake_md5", tracknum: 1, artist: artist} + {name: "test_song_1", file_path: "fake_path", file_path_hash: "fake_path_hash", md5_hash: "fake_md5", tracknum: 2, discnum: 2, artist: artist}, + {name: "test_song_2", file_path: "fake_path", file_path_hash: "fake_path_hash", md5_hash: "fake_md5", tracknum: 3, discnum: 1, artist: artist}, + {name: "test_song_3", file_path: "fake_path", file_path_hash: "fake_path_hash", md5_hash: "fake_md5", tracknum: 1, discnum: 1, artist: artist} ] ) - assert_equal %w[test_song_3 test_song_1 test_song_2], album.songs.pluck(:name) + assert_equal %w[test_song_3 test_song_2 test_song_1], album.songs.pluck(:name) end test "should filter by genre" do diff --git a/test/models/media_file_test.rb b/test/models/media_file_test.rb index 8545db09..74db24d0 100644 --- a/test/models/media_file_test.rb +++ b/test/models/media_file_test.rb @@ -70,6 +70,7 @@ class MediaFileTest < ActiveSupport::TestCase assert_equal 1984, tag_info[:year] assert_equal "Rock", tag_info[:genre] assert_equal cover_image_binary, tag_image_binary + assert_equal 0, tag_info[:discnum] end test "should get tag info from flac file" do @@ -86,6 +87,7 @@ class MediaFileTest < ActiveSupport::TestCase assert_equal 1984, tag_info[:year] assert_equal "Rock", tag_info[:genre] assert_equal cover_image_binary, tag_image_binary + assert_equal 0, tag_info[:discnum] end test "should get tag info from ogg file" do @@ -99,6 +101,7 @@ class MediaFileTest < ActiveSupport::TestCase assert_equal 8, tag_info[:duration] assert_equal 1984, tag_info[:year] assert_equal "Rock", tag_info[:genre] + assert_nil tag_info[:discnum] end test "should get tag info from wav file" do @@ -115,6 +118,7 @@ class MediaFileTest < ActiveSupport::TestCase assert_equal 1984, tag_info[:year] assert_equal "Rock", tag_info[:genre] assert_equal cover_image_binary, tag_image_binary + assert_equal 0, tag_info[:discnum] end test "should get tag info from opus file" do @@ -128,6 +132,7 @@ class MediaFileTest < ActiveSupport::TestCase assert_equal 8, tag_info[:duration] assert_equal 1984, tag_info[:year] assert_equal "Rock", tag_info[:genre] + assert_nil tag_info[:discnum] end test "should get tag info from m4a file" do @@ -144,6 +149,7 @@ class MediaFileTest < ActiveSupport::TestCase assert_equal 1984, tag_info[:year] assert_equal "Rock", tag_info[:genre] assert_equal cover_image_binary, tag_image_binary + assert_nil tag_info[:discnum] end test "should get tag info from oga file" do @@ -157,6 +163,7 @@ class MediaFileTest < ActiveSupport::TestCase assert_equal 8, tag_info[:duration] assert_equal 1984, tag_info[:year] assert_equal "Rock", tag_info[:genre] + assert_nil tag_info[:discnum] end test "should get tag info from wma file" do @@ -170,6 +177,7 @@ class MediaFileTest < ActiveSupport::TestCase assert_equal 8, tag_info[:duration] assert_nil tag_info[:year] assert_nil tag_info[:genre] + assert_nil tag_info[:discnum] end test "should get md5 hash from file" do