Skip to content
This repository has been archived by the owner on Oct 23, 2021. It is now read-only.

Commit

Permalink
fix: preget albums covers before rendering them (#192)
Browse files Browse the repository at this point in the history
  • Loading branch information
negamaxi committed Aug 4, 2018
1 parent 3798738 commit f7d5ac9
Show file tree
Hide file tree
Showing 20 changed files with 215 additions and 110 deletions.
4 changes: 2 additions & 2 deletions src/main/methods/startCommunication/startIpfsBridge.js
Expand Up @@ -30,7 +30,7 @@ const startIpfsBridge = ({ ipfsProcessPromise }) => {
return ipfsProcess.call({ type: IPC_IPFS_CACHE_CIDS, payload: cids })
}

const handleOpenCachedCIDsStream = async event => {
const handleopenCachedIPFSFilesStream = async event => {
const ipfsProcess = await ipfsProcessPromise
const handleMessage = ({ type, ...rest }) => {
switch (type) {
Expand All @@ -54,7 +54,7 @@ const startIpfsBridge = ({ ipfsProcessPromise }) => {
ipcMainTake(IPC_IPFS_SHARE_OBJECT, handleShareObject),
ipcMainTake(IPC_IPFS_SHARE_FS_FILE, handleShareFsFile),
ipcMainTake(IPC_IPFS_CACHE_CIDS, handleCacheFilesByCIDs),
ipcMainTake(IPC_IPFS_OPEN_CACHED_CIDS_STREAM, handleOpenCachedCIDsStream),
ipcMainTake(IPC_IPFS_OPEN_CACHED_CIDS_STREAM, handleopenCachedIPFSFilesStream),
ipcMainTake(IPC_IPFS_GET_STATS, handleGetStats)
]
return () => {
Expand Down
8 changes: 4 additions & 4 deletions src/renderer/sagas/startApp/getApis/getCustomIpfsApi.js
Expand Up @@ -34,10 +34,10 @@ function * getCustomIpfsApi () {
const cacheIPFSFilesByCIDs = cids => {
return rendererCalls(IPC_IPFS_CACHE_CIDS, cids)
}
const openCachedCIDsStream = () => {
const openCachedIPFSFilesStream = () => {
return rendererCalls(IPC_IPFS_OPEN_CACHED_CIDS_STREAM)
}
const getCachedCIDsChannel = () => {
const getCachedIPFSFilesChannel = () => {
return eventChannel(emit => {
const handleMessage = (e, arg) => {
emit(arg)
Expand All @@ -58,8 +58,8 @@ function * getCustomIpfsApi () {
shareFsFileToIpfs,
shareObjectToIpfs,
cacheIPFSFilesByCIDs,
openCachedCIDsStream,
getCachedCIDsChannel,
openCachedIPFSFilesStream,
getCachedIPFSFilesChannel,
getIPFSStats
}
}
Expand Down
4 changes: 2 additions & 2 deletions src/renderer/sagas/startApp/startServices.js
Expand Up @@ -8,10 +8,10 @@ import startAlbumsReciever from './startServices/startAblumsReciever'
import startAlbumsPublisher from './startServices/startAlbumsPublisher'
import startAlbumsSharingService from './startServices/startAlbumsSharingService'
import startDiscoverPageService from './startServices/startDiscoverPageService'
import startTracksCache from './startServices/startTracksCache'
import startNotificationsService from './startServices/startNotificationsService'
import startAlbumsCollectionInfo from './startServices/startAlbumsCollectionInfo'
import startNewReleaseChecker from './startServices/startNewReleaseChecker'
import startIPFSCachingService from './startServices/startIPFSCachingService'
import startIndicatorsBarService from './startServices/startIndicatorsBarService'

function * startServices (apis) {
Expand All @@ -21,7 +21,7 @@ function * startServices (apis) {
spawn(startAlbumsPublisher, apis),
spawn(startAlbumsSharingService, apis),
spawn(startDiscoverPageService, apis),
spawn(startTracksCache, apis),
spawn(startIPFSCachingService, apis),
spawn(startAlbumsCollectionInfo, apis),
spawn(startNotificationsService, apis),
spawn(startNewReleaseChecker, apis),
Expand Down
@@ -0,0 +1,14 @@
import { fork } from 'redux-saga/effects'
import startCachedIPFSFilesReciever from './startIPFSCachingService/startCachedIPFSFilesReciever'
import startIPFSFilesCatch from './startIPFSCachingService/startIPFSFilesCatch'

function * startIPFSCachingService (api) {
try {
yield fork(startCachedIPFSFilesReciever, api)
yield fork(startIPFSFilesCatch, api)
} catch (e) {
console.error(e)
}
}

export default startIPFSCachingService
@@ -0,0 +1,18 @@
import { call, put, take } from 'redux-saga/effects'
import { systemIPFSFileCached } from '~actions/system'

function * startCachedIPFSFilesReciever (api) {
const { getCachedIPFSFilesChannel, openCachedIPFSFilesStream } = api
yield call(openCachedIPFSFilesStream)
const channel = yield call(getCachedIPFSFilesChannel)
while (true) {
const { errorMessage, payload } = yield take(channel)
if (!errorMessage) {
yield put(systemIPFSFileCached(payload))
} else {
console.error(new Error(errorMessage))
}
}
}

export default startCachedIPFSFilesReciever
@@ -0,0 +1,16 @@
import { call, takeEvery } from 'redux-saga/effects'
import { systemPlayedTracksRecieved, systemQueuedTracksRecieved, systemDiscoverAlbumsFetchSucceed } from '~actions/system'
import cachePlaylistTracks from './startIPFSFilesCatch/cachePlaylistTracks'
import cacheDiscoverAlbumsCovers from './startIPFSFilesCatch/cacheDiscoverAlbumsCovers'

function * startIPFSFilesCatch (api) {
yield call(cachePlaylistTracks, api)
yield takeEvery(
[ systemPlayedTracksRecieved, systemQueuedTracksRecieved ], cachePlaylistTracks, api
)
yield takeEvery(
systemDiscoverAlbumsFetchSucceed, cacheDiscoverAlbumsCovers, api
)
}

export default startIPFSFilesCatch
@@ -0,0 +1,19 @@
import { call } from 'redux-saga/effects'

const handleMap = ({ albumCoverCid }) => albumCoverCid

const getAlbumsCoversCIDs = (albums) => {
return albums.map(handleMap)
}

function * cacheDiscoverAlbumsCovers (api, { payload }) {
const { cacheIPFSFilesByCIDs } = api
const uncachedCIDs = getAlbumsCoversCIDs(payload)
try {
yield call(cacheIPFSFilesByCIDs, uncachedCIDs)
} catch (e) {
console.error(e)
}
}

export default cacheDiscoverAlbumsCovers
Expand Up @@ -3,9 +3,9 @@ import { getPlaylistUncachedTracksCIDs } from '#selectors'

function * cachePlaylistTracks (api) {
const { cacheIPFSFilesByCIDs } = api
const uncachedTracks = yield select(getPlaylistUncachedTracksCIDs)
const uncachedCIDs = yield select(getPlaylistUncachedTracksCIDs)
try {
yield call(cacheIPFSFilesByCIDs, uncachedTracks)
yield call(cacheIPFSFilesByCIDs, uncachedCIDs)
} catch (e) {
console.error(e)
}
Expand Down

This file was deleted.

3 changes: 1 addition & 2 deletions src/renderer/state/actions/system.js
Expand Up @@ -49,8 +49,7 @@ export const systemPlaylistCleared = c('PLAYLIST_CLEARED')
export const systemPlayedTracksRecieved = c('PLAYED_TRACKS_RECIEVED')
export const systemQueuedTracksRecieved = c('QUEUED_TRACKS_RECIEVED')

export const systemCacheTracks = c('CACHE_TRACKS')
export const systemCacheTrackSucceed = c('CACHE_TRACK_SUCCEED')
export const systemIPFSFileCached = c('IPFS_FILE_CACHED')

export const systemRepeatedPlaylistEnded = c('REPEATED_PLAYLIST_ENDED')

Expand Down
16 changes: 9 additions & 7 deletions src/renderer/state/domains/cachedCIDs.js
@@ -1,5 +1,7 @@
import { systemCacheTrackSucceed, systemPlayedTracksRecieved } from '~actions/system'
import { uiPlaylistCleared } from '~actions/ui'

import {
systemIPFSFileCached
} from '~actions/system'

const DOMAIN = 'cachedCIDs'

Expand All @@ -10,11 +12,11 @@ export const getCachedCIDs = state => state[DOMAIN]
const reducer = (state = initialState, action) => {
const { type, payload } = action
switch (type) {
case systemCacheTrackSucceed.toString():
return { ...state, [payload]: true }
case uiPlaylistCleared.toString():
case systemPlayedTracksRecieved.toString():
return {}
case systemIPFSFileCached.toString():
return {
...state,
[payload]: true
}
default:
return state
}
Expand Down
38 changes: 38 additions & 0 deletions src/renderer/state/domains/localAudiosCIDs.js
@@ -0,0 +1,38 @@
import { systemPlayedTracksRecieved, systemIPFSFileCached, systemQueuedTracksRecieved } from '~actions/system'
import { uiPlaylistCleared } from '~actions/ui'

const DOMAIN = 'localAudiosCIDs'

const initialState = {}

export const getLocalAudiosCIDs = state => state[DOMAIN]

const handleReduceTracks = (acc, track) => {
acc[track.audio] = false
return acc
}

const reducer = (state = initialState, action) => {
const { type, payload } = action
switch (type) {
case systemIPFSFileCached.toString():
if (state[payload] === false) {
return { ...state, [payload]: true }
}
return state
case systemPlayedTracksRecieved.toString():
return payload.reduce(handleReduceTracks, {})
case systemQueuedTracksRecieved.toString():
const newCids = payload.reduce(handleReduceTracks, {})
return {
...newCids,
...state
}
case uiPlaylistCleared.toString():
return {}
default:
return state
}
}

export default reducer
36 changes: 36 additions & 0 deletions src/renderer/state/domains/localCoversCIDs.js
@@ -0,0 +1,36 @@
import {
systemIPFSFileCached, systemDiscoverAlbumsFetchSucceed
} from '~actions/system'
import {
uiDiscoverPageClosed
} from '~actions/ui'

const DOMAIN = 'localCoversCIDs'

const initialState = {}

export const getLocalCoversCIDs = state => state[DOMAIN]

const handleReduce = (acc, album) => {
acc[album.albumCoverCid] = false
return acc
}

const reducer = (state = initialState, action) => {
const { type, payload } = action
switch (type) {
case systemIPFSFileCached.toString():
if (state[payload] === false) {
return { ...state, [payload]: true }
}
return state
case systemDiscoverAlbumsFetchSucceed.toString():
return payload.reduce(handleReduce, {})
case uiDiscoverPageClosed.toString():
return {}
default:
return state
}
}

export default reducer
8 changes: 4 additions & 4 deletions src/renderer/state/selectors/derived.js
Expand Up @@ -10,10 +10,10 @@ import {
getPlaylistTracksByIndex,
getShareCandidates,
getNotifications,
getIpfsGateway,
getCachedCIDs
getIpfsGateway
} from '#selectors'
import { getIpfsApiEndpoint } from '../domains/ipfsInfo'
import { getCachedCIDs } from '../domains/cachedCIDs'

export const isAppReady = state => getAppStartProgress(state) === 100

Expand Down Expand Up @@ -45,15 +45,15 @@ export const getPlaylistTracksIndexes = createSelector(

export const getPlaylistTracksCount = state => getPlaylistTracksIndexes(state).length

export const getPlaylistTracksCids = createSelector(
export const getPlaylistTracksCIDs = createSelector(
getPlaylistTracksByIndex,
tracks => {
return Object.values(tracks).map(({ audio }) => audio)
}
)

export const getPlaylistUncachedTracksCIDs = createSelector(
[ getPlaylistTracksCids, getCachedCIDs ],
[ getPlaylistTracksCIDs, getCachedCIDs ],
(tracksCIDs, cachedCIDs) => {
return tracksCIDs.filter(cid => !cachedCIDs[cid])
}
Expand Down
Expand Up @@ -49,4 +49,24 @@
.album__actions-button:active {
background-color: var(--accent-color);
color: white;
}

.album__cover-image {
position: absolute;
left: 0;
top: 0;
width: 100%;
height: 100%;
padding: 0.25em;
object-fit: contain;
}

.album__cover-image {
position: absolute;
left: 0;
top: 0;
width: 100%;
height: 100%;
padding: 0.25em;
object-fit: contain;
}
Expand Up @@ -3,15 +3,15 @@ import propTypes from 'prop-types'
import MdPlay from 'react-icons/lib/md/play-arrow'
import MdAdd from 'react-icons/lib/md/playlist-add'

import NoCover from '~components/DiskIcon.jsx'

import {
E2E_DISCOVER_ALBUM_QUEUE_BUTTON,
E2E_DISCOVER_ALBUM_PLAY_BUTTON,
E2E_DISCOVER_ALBUM_TITLE,
E2E_DISCOVER_ALBUM_ARTIST
} from '~data/e2eConstants'

import CoverImage from './Album/CoverImage.jsx'

import './Album.css'

class Album extends React.Component {
Expand Down Expand Up @@ -41,7 +41,8 @@ class Album extends React.Component {
hasSelectedView,
albumTitle,
albumArtist,
albumCoverURL
albumCoverURL,
isCoverCached
} = this.props

return (
Expand All @@ -51,7 +52,17 @@ class Album extends React.Component {
onClick={this.handleAlbumClick}
className='album__cover'
>
<CoverImage src={albumCoverURL} />
{
isCoverCached ? (
<img
className='album__cover-image'
src={albumCoverURL}
onLoad={this.handleImageLoad}
/>
) : (
<NoCover />
)
}
</button>
{
!hasSelectedView && (
Expand Down Expand Up @@ -100,7 +111,8 @@ Album.propTypes = {
albumCid: propTypes.string.isRequired,
albumArtist: propTypes.string.isRequired,
albumTitle: propTypes.string.isRequired,
albumCoverURL: propTypes.string.isRequired
albumCoverURL: propTypes.string.isRequired,
isCoverCached: propTypes.bool.isRequired
}

export default Album

0 comments on commit f7d5ac9

Please sign in to comment.