Skip to content

Commit

Permalink
Platform-agnostic curated playlists (WIP)
Browse files Browse the repository at this point in the history
  • Loading branch information
jaedb committed May 21, 2022
1 parent 520645d commit b60e2ee
Show file tree
Hide file tree
Showing 30 changed files with 1,722 additions and 364 deletions.
4 changes: 1 addition & 3 deletions Dockerfile
Expand Up @@ -53,9 +53,7 @@ RUN python3 -m pip install --no-cache \
tox \
mopidy-mpd \
mopidy-local \
dbus-python \
# pip not up-to-date for Mopidy-Tidal (https://github.com/tehkillerbee/mopidy-tidal/issues/14)
git+https://github.com/tehkillerbee/mopidy-tidal.git@master
dbus-python

# Start helper script.
COPY docker/entrypoint.sh /entrypoint.sh
Expand Down
2 changes: 1 addition & 1 deletion docker-compose.example.yml
Expand Up @@ -12,7 +12,7 @@ services:
mopidy:
image: jaedb/iris
environment:
- PIP_PACKAGES="Mopidy-SoundCloud Mopidy-MusicBox-Webclient"
- PIP_PACKAGES=Mopidy-YTMusic Mopidy-Tidal Mopidy-SoundCloud Mopidy-MusicBox-Webclient
build:
context: .
depends_on:
Expand Down
2 changes: 1 addition & 1 deletion mopidy_iris/__init__.py
Expand Up @@ -3,7 +3,7 @@

from mopidy import config, ext

__version__ = "3.62.0"
__version__ = "3.63.0"

logger = logging.getLogger(__name__)

Expand Down
16 changes: 13 additions & 3 deletions mopidy_iris/static/app.css

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion mopidy_iris/static/app.css.map

Large diffs are not rendered by default.

1,135 changes: 1,025 additions & 110 deletions mopidy_iris/static/app.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion mopidy_iris/static/app.js.map

Large diffs are not rendered by default.

85 changes: 0 additions & 85 deletions mopidy_iris/static/app.min.css

This file was deleted.

141 changes: 0 additions & 141 deletions mopidy_iris/static/app.min.js

This file was deleted.

4 changes: 2 additions & 2 deletions mopidy_iris/static/index.html
Expand Up @@ -140,8 +140,8 @@

// Release details
// These are automatically injected to built HTML
var build = "1652000473";
var version = "3.62.0";
var build = "1653096655";
var version = "3.63.0";

// Construct the script tag
var js = document.createElement("script");
Expand Down
2 changes: 1 addition & 1 deletion mopidy_iris/static/manifest.json
@@ -1,5 +1,5 @@
{
"manifest_version": "3.62.0",
"manifest_version": "3.63.0",
"short_name": "Iris",
"name": "Iris",
"icons": [
Expand Down
2 changes: 1 addition & 1 deletion package.json
@@ -1,6 +1,6 @@
{
"name": "mopidy-iris",
"version": "3.62.0",
"version": "3.63.0",
"description": "Mopidy HTTP interface",
"repository": "https://github.com/jaedb/iris",
"author": "James Barnsley <james@barnsley.nz>",
Expand Down
2 changes: 1 addition & 1 deletion setup.cfg
@@ -1,6 +1,6 @@
[metadata]
name = Mopidy-Iris
version = 3.62.0
version = 3.63.0
url = https://github.com/jaedb/iris
author = James Barnsley
author_email = james@barnsley.nz
Expand Down
11 changes: 8 additions & 3 deletions src/js/components/Grid.js
Expand Up @@ -5,18 +5,23 @@ import { GridItem } from './GridItem';
const Grid = memo(({
items,
className = '',
mini = false,
mini,
tile,
getLink,
sourceIcon,
}) => {
if (!items || !items.length) return null;

return (
<SmartList
className={`grid grid--${items[0].type}s ${className} ${mini ? 'grid--mini' : ''}`}
className={`grid grid--${items[0].type}s ${className} ${mini ? 'grid--mini' : ''} ${tile ? 'grid--tile' : ''}`}
items={items}
itemComponent={GridItem}
itemProps={{ getLink, sourceIcon }}
itemProps={{
getLink,
sourceIcon,
tile,
}}
/>
);
});
Expand Down
5 changes: 5 additions & 0 deletions src/js/components/GridItem.js
Expand Up @@ -22,6 +22,7 @@ const SecondaryLine = ({
tracks = [],
followers,
albums_uris = [],
playlists_uris = [],
artists,
} = {},
}) => {
Expand All @@ -31,6 +32,9 @@ const SecondaryLine = ({

const items = () => {
switch (type) {
case 'mood':
case 'playlist_group':
return null;
case 'playlist':
return <li><I18n path="specs.tracks" count={trackCount} /></li>;
case 'artist':
Expand Down Expand Up @@ -97,6 +101,7 @@ const GridItem = ({
}
break;
case 'album':
case 'playlist':
dispatch(mopidyActions.getImages([item.uri]));
break;
default:
Expand Down
7 changes: 7 additions & 0 deletions src/js/components/ListItem.js
Expand Up @@ -30,6 +30,13 @@ const getValue = (item = {}, name = '') => {
if (!total && !value) return null;
return <I18n path="specs.tracks" count={nice_number(total || value.length)} />;
}
case 'playlists': {
const {
playlists_uris: array = [],
} = item;
if (!array.length) return null;
return <I18n path="specs.playlists" count={nice_number(array.length)} />;
}
case 'artists': {
const {
artists_total: total,
Expand Down
4 changes: 4 additions & 0 deletions src/js/components/Sidebar.js
Expand Up @@ -94,6 +94,10 @@ const Sidebar = () => {
<Icon name="explore" type="material" />
<I18n path="sidebar.discover" />
</Link>
<Link to="/discover/moods" className="sidebar__menu__item" activeClassName="sidebar__menu__item--active">
<Icon name="mood" type="material" />
<I18n path="sidebar.moods" />
</Link>
<Link to="/discover/categories" className="sidebar__menu__item" activeClassName="sidebar__menu__item--active">
<Icon name="mood" type="material" />
<I18n path="sidebar.genre" />
Expand Down
7 changes: 2 additions & 5 deletions src/js/locale/en.yaml
Expand Up @@ -166,7 +166,7 @@ sidebar:
now_playing: Now playing
search: Search
discover: Discover
genre: Genre / Mood
moods: Genre / Mood
featured_playlists: Featured playlists
new_releases: New releases
my_music: My music
Expand Down Expand Up @@ -482,11 +482,8 @@ user:
you: You
discover:
title: Discover
categories:
moods:
title: 'Genre / Mood'
category:
title: 'Genre / Mood'
category: Category
featured:
title: Featured playlists
new_releases:
Expand Down
8 changes: 8 additions & 0 deletions src/js/services/core/actions.js
Expand Up @@ -174,6 +174,14 @@ export function loadPlaylist(uri, options = {}) {
};
}

export function loadPlaylistGroup(uri, options = {}) {
return {
type: 'LOAD_PLAYLIST_GROUP',
uri,
options,
};
}

export function loadUser(uri, options = {}) {
return {
type: 'LOAD_USER',
Expand Down
23 changes: 23 additions & 0 deletions src/js/services/core/middleware.js
Expand Up @@ -500,6 +500,29 @@ const CoreMiddleware = (function () {
break;
}

case 'LOAD_PLAYLIST_GROUP': {
const fetch = () => {
console.debug('fetching', action)
switch (uriSource(action.uri)) {
case 'spotify':
store.dispatch(spotifyActions.getCategory(action.uri, action.options));
break;
default:
store.dispatch(mopidyActions.getPlaylistGroup(action.uri, action.options));
break;
}
};
ensureLoaded({
store,
action,
fetch,
dependents: ['playlist_uris', 'playlists'],
type: 'playlist_group',
});
next(action);
break;
}

case 'LOAD_USER': {
const fetch = () => {
switch (uriSource(action.uri)) {
Expand Down
15 changes: 15 additions & 0 deletions src/js/services/mopidy/actions.js
Expand Up @@ -477,13 +477,28 @@ export function deletePlaylist(uri) {
};
}

export function getLibraryMoods(uri) {
return {
type: 'MOPIDY_GET_LIBRARY_MOODS',
uri,
};
}

export function getLibraryPlaylists(uri) {
return {
type: 'MOPIDY_GET_LIBRARY_PLAYLISTS',
uri,
};
}

export function getPlaylistGroup(uri, options) {
return {
type: 'MOPIDY_GET_PLAYLIST_GROUP',
uri,
options,
};
}

export function getPlaylist(uri, options) {
return {
type: 'MOPIDY_GET_PLAYLIST',
Expand Down
58 changes: 57 additions & 1 deletion src/js/services/mopidy/middleware.js
Expand Up @@ -15,12 +15,15 @@ import {
formatAlbum,
formatTrack,
formatTracks,
formatSimpleObject,
formatPlaylists,
formatPlaylistGroup,
formatPlaylistGroups,
getTrackIcon,
formatArtists,
formatArtist,
formatPlaylist,
injectSortId,
formatSimpleObject,
} from '../../util/format';
import {
arrayOf,
Expand Down Expand Up @@ -1769,6 +1772,8 @@ const MopidyMiddleware = (function () {
Object.keys(response).forEach((uri) => {
const images = response[uri];

console.debug({ images })

if (images) {
itemsWithImages.push({
uri,
Expand Down Expand Up @@ -1950,6 +1955,57 @@ const MopidyMiddleware = (function () {
});
break;

case 'MOPIDY_GET_LIBRARY_MOODS': {
store.dispatch(uiActions.startProcess(action.type, { notification: false }));

request(store, 'library.browse', { uri: action.uri })
.then((response) => {
const moods = response.map((mood) => ({
...formatSimpleObject(mood),
type: 'mood',
}));

store.dispatch(
uiActions.updateProcess(
action.type,
{
total: moods.length,
remaining: moods.length,
},
),
);

store.dispatch(coreActions.libraryLoaded({
uri: action.uri,
type: 'moods',
items_uris: arrayOf('uri', moods),
}));
store.dispatch(coreActions.itemsLoaded(moods));
store.dispatch(uiActions.stopLoading(action.uri));
store.dispatch(uiActions.processFinished(action.type));
});
break;
}

case 'MOPIDY_GET_PLAYLIST_GROUP': {
const decodedUri = action.uri ? decodeURIComponent(action.uri) : null;
store.dispatch(coreActions.itemLoaded({
uri: decodedUri,
loading: true,
}));
request(store, 'library.browse', { uri: action.uri })
.then((browse) => {
const playlists = formatPlaylists(browse);
const playlists_uris = arrayOf('uri', playlists);
store.dispatch(coreActions.itemsLoaded(playlists));
store.dispatch(coreActions.itemLoaded({
uri: decodedUri,
loading: false,
playlists_uris,
}));
})
break;
}
case 'MOPIDY_GET_LIBRARY_PLAYLISTS': {
store.dispatch(uiActions.startProcess(action.type, { notification: false }));

Expand Down
4 changes: 2 additions & 2 deletions src/js/services/spotify/actions.js
Expand Up @@ -421,10 +421,10 @@ export function getFeaturedPlaylists(forceRefetch = false) {
};
}

export function getCategories() {
export function getLibraryMoods() {
return (dispatch, getState) => {
const loaderId = generateGuid();
dispatch(uiActions.startLoading(loaderId, 'spotify_categories'));
dispatch(uiActions.startLoading(loaderId, 'spotify_moods'));

let endpoint = 'browse/categories';
endpoint += '?limit=50';
Expand Down

0 comments on commit b60e2ee

Please sign in to comment.