diff --git a/src/js/components/Track.js b/src/js/components/Track.js
index 6079c2f7..ceeea19d 100755
--- a/src/js/components/Track.js
+++ b/src/js/components/Track.js
@@ -11,7 +11,7 @@ import {
isTouchDevice,
uriType,
} from '../util/helpers';
-import { I18n } from '../locale';
+import { I18n, i18n } from '../locale';
const MiddleColumn = ({
track_context,
@@ -333,6 +333,7 @@ const Track = ({
if (item.type !== undefined) className += ` list__item--${item.type}`;
if (item.playing) className += ' list__item--playing';
if (item.loading) className += ' list__item--loading';
+ if (item.is_playable === false) className += ' list__item--disabled';
if (hover) className += ' list__item--hover';
if (track_middle_column) className += ' list__item--has-middle-column';
if (track_details.length > 0) className += ' list__item--has-details';
@@ -365,7 +366,8 @@ const Track = ({
{track_middle_column}
{drag_zone}
- {item.is_explicit && EXPLICIT}
+ {item.is_explicit && {i18n('track.explicit').toUpperCase()}}
+ {item.is_playable === false && {i18n('track.unplayable').toUpperCase()}}
{(track_context === 'album' || track_context === 'artist') && item.track_number && (
diff --git a/src/js/locale/en.yaml b/src/js/locale/en.yaml
index e5ef04d4..b89d14c4 100755
--- a/src/js/locale/en.yaml
+++ b/src/js/locale/en.yaml
@@ -340,6 +340,7 @@ track:
title_window: '%{name} by %{artists} (track)'
lyrics_origin: 'Origin: '
explicit: Explicit
+ unplayable: Unplayable
disc_number: 'Disc %{number}'
track_number: 'Track %{number}'
unknown_album: Unknown album
diff --git a/src/js/services/mopidy/middleware.js b/src/js/services/mopidy/middleware.js
index 29d7369f..50627396 100755
--- a/src/js/services/mopidy/middleware.js
+++ b/src/js/services/mopidy/middleware.js
@@ -818,7 +818,14 @@ const MopidyMiddleware = (function () {
if (playlist && playlist.tracks) {
store.dispatch(
mopidyActions.playURIs(
- arrayOf('uri', sortItems(playlist.tracks, sortField, sortReverse)),
+ arrayOf(
+ 'uri',
+ sortItems(
+ playlist.tracks.filter((t) => t?.is_playable !== false),
+ sortField,
+ sortReverse,
+ ),
+ ),
action.uri,
action.shuffle,
),
diff --git a/src/js/util/format.js b/src/js/util/format.js
index 12ccd9dc..b21b8317 100755
--- a/src/js/util/format.js
+++ b/src/js/util/format.js
@@ -592,6 +592,7 @@ const formatTrack = function (data) {
'loading',
'uri',
'in_library',
+ 'is_playable',
'tlid',
'provider',
'name',
diff --git a/src/scss/components/_lists.scss b/src/scss/components/_lists.scss
index e0a21721..ab80f953 100755
--- a/src/scss/components/_lists.scss
+++ b/src/scss/components/_lists.scss
@@ -106,6 +106,10 @@
word-break: break-all;
}
+ &--disabled {
+ opacity: 0.5;
+ }
+
&--selected {
background: rgba(125, 125, 125, 0.15) !important;