(1) Use absolute imports
(2) Allow queue tracks to be played when touched (3) Store refresh dates as numbers
This commit is contained in:
@@ -1,3 +1,18 @@
|
|||||||
module.exports = {
|
module.exports = {
|
||||||
presets: ['module:metro-react-native-babel-preset'],
|
presets: ['module:metro-react-native-babel-preset'],
|
||||||
|
plugins: [
|
||||||
|
[
|
||||||
|
'module-resolver',
|
||||||
|
{
|
||||||
|
// root: ['./src'],
|
||||||
|
alias: {
|
||||||
|
store: './src/store',
|
||||||
|
components: './src/components',
|
||||||
|
utility: './src/utility',
|
||||||
|
screens: './src/screens',
|
||||||
|
CONSTANTS: './src/CONSTANTS',
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
]
|
||||||
};
|
};
|
||||||
|
|||||||
82
package-lock.json
generated
82
package-lock.json
generated
@@ -2432,6 +2432,19 @@
|
|||||||
"@types/babel__traverse": "^7.0.6"
|
"@types/babel__traverse": "^7.0.6"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"babel-plugin-module-resolver": {
|
||||||
|
"version": "4.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/babel-plugin-module-resolver/-/babel-plugin-module-resolver-4.0.0.tgz",
|
||||||
|
"integrity": "sha512-3pdEq3PXALilSJ6dnC4wMWr0AZixHRM4utpdpBR9g5QG7B7JwWyukQv7a9hVxkbGFl+nQbrHDqqQOIBtTXTP/Q==",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"find-babel-config": "^1.2.0",
|
||||||
|
"glob": "^7.1.6",
|
||||||
|
"pkg-up": "^3.1.0",
|
||||||
|
"reselect": "^4.0.0",
|
||||||
|
"resolve": "^1.13.1"
|
||||||
|
}
|
||||||
|
},
|
||||||
"babel-plugin-styled-components": {
|
"babel-plugin-styled-components": {
|
||||||
"version": "1.10.7",
|
"version": "1.10.7",
|
||||||
"resolved": "https://registry.npmjs.org/babel-plugin-styled-components/-/babel-plugin-styled-components-1.10.7.tgz",
|
"resolved": "https://registry.npmjs.org/babel-plugin-styled-components/-/babel-plugin-styled-components-1.10.7.tgz",
|
||||||
@@ -4424,6 +4437,30 @@
|
|||||||
"unpipe": "~1.0.0"
|
"unpipe": "~1.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"find-babel-config": {
|
||||||
|
"version": "1.2.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/find-babel-config/-/find-babel-config-1.2.0.tgz",
|
||||||
|
"integrity": "sha512-jB2CHJeqy6a820ssiqwrKMeyC6nNdmrcgkKWJWmpoxpE8RKciYJXCcXRq1h2AzCo5I5BJeN2tkGEO3hLTuePRA==",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"json5": "^0.5.1",
|
||||||
|
"path-exists": "^3.0.0"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"json5": {
|
||||||
|
"version": "0.5.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/json5/-/json5-0.5.1.tgz",
|
||||||
|
"integrity": "sha1-Hq3nrMASA0rYTiOWdn6tn6VJWCE=",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
|
"path-exists": {
|
||||||
|
"version": "3.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz",
|
||||||
|
"integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=",
|
||||||
|
"dev": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"find-cache-dir": {
|
"find-cache-dir": {
|
||||||
"version": "2.1.0",
|
"version": "2.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-2.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-2.1.0.tgz",
|
||||||
@@ -8334,6 +8371,51 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"pkg-up": {
|
||||||
|
"version": "3.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/pkg-up/-/pkg-up-3.1.0.tgz",
|
||||||
|
"integrity": "sha512-nDywThFk1i4BQK4twPQ6TA4RT8bDY96yeuCVBWL3ePARCiEKDRSrNGbFIgUJpLp+XeIR65v8ra7WuJOFUBtkMA==",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"find-up": "^3.0.0"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"find-up": {
|
||||||
|
"version": "3.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz",
|
||||||
|
"integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"locate-path": "^3.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"locate-path": {
|
||||||
|
"version": "3.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz",
|
||||||
|
"integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"p-locate": "^3.0.0",
|
||||||
|
"path-exists": "^3.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"p-locate": {
|
||||||
|
"version": "3.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz",
|
||||||
|
"integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"p-limit": "^2.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"path-exists": {
|
||||||
|
"version": "3.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz",
|
||||||
|
"integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=",
|
||||||
|
"dev": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"plist": {
|
"plist": {
|
||||||
"version": "3.0.1",
|
"version": "3.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/plist/-/plist-3.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/plist/-/plist-3.0.1.tgz",
|
||||||
|
|||||||
@@ -55,6 +55,7 @@
|
|||||||
"@typescript-eslint/eslint-plugin": "^2.27.0",
|
"@typescript-eslint/eslint-plugin": "^2.27.0",
|
||||||
"@typescript-eslint/parser": "^2.27.0",
|
"@typescript-eslint/parser": "^2.27.0",
|
||||||
"babel-jest": "^24.9.0",
|
"babel-jest": "^24.9.0",
|
||||||
|
"babel-plugin-module-resolver": "^4.0.0",
|
||||||
"eslint": "^6.5.1",
|
"eslint": "^6.5.1",
|
||||||
"jest": "^24.9.0",
|
"jest": "^24.9.0",
|
||||||
"metro-react-native-babel-preset": "^0.58.0",
|
"metro-react-native-babel-preset": "^0.58.0",
|
||||||
|
|||||||
@@ -51,7 +51,7 @@ const Album: React.FC = () => {
|
|||||||
|
|
||||||
// Retrieve album tracks on load
|
// Retrieve album tracks on load
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!album?.lastRefreshed || differenceInDays(album.lastRefreshed, new Date()) > ALBUM_CACHE_AMOUNT_OF_DAYS) {
|
if (!album?.lastRefreshed || differenceInDays(album?.lastRefreshed, new Date()) > ALBUM_CACHE_AMOUNT_OF_DAYS) {
|
||||||
refresh();
|
refresh();
|
||||||
}
|
}
|
||||||
}, []);
|
}, []);
|
||||||
|
|||||||
@@ -3,6 +3,8 @@ import useQueue from 'utility/useQueue';
|
|||||||
import { View, Text } from 'react-native';
|
import { View, Text } from 'react-native';
|
||||||
import styled, { css } from 'styled-components/native';
|
import styled, { css } from 'styled-components/native';
|
||||||
import useCurrentTrack from 'utility/useCurrentTrack';
|
import useCurrentTrack from 'utility/useCurrentTrack';
|
||||||
|
import TouchableHandler from 'components/TouchableHandler';
|
||||||
|
import usePlayTrack from 'utility/usePlayTrack';
|
||||||
|
|
||||||
const QueueItem = styled.View<{ active?: boolean, alreadyPlayed?: boolean }>`
|
const QueueItem = styled.View<{ active?: boolean, alreadyPlayed?: boolean }>`
|
||||||
padding: 10px;
|
padding: 10px;
|
||||||
@@ -24,16 +26,19 @@ const QueueItem = styled.View<{ active?: boolean, alreadyPlayed?: boolean }>`
|
|||||||
export default function Queue() {
|
export default function Queue() {
|
||||||
const queue = useQueue();
|
const queue = useQueue();
|
||||||
const currentTrack = useCurrentTrack();
|
const currentTrack = useCurrentTrack();
|
||||||
const currentIndex = queue?.findIndex(d => d.id === currentTrack?.id);
|
const currentIndex = queue.findIndex(d => d.id === currentTrack?.id);
|
||||||
|
const playTrack = usePlayTrack();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<View>
|
<View>
|
||||||
<Text style={{ marginTop: 20, marginBottom: 20 }}>Queue</Text>
|
<Text style={{ marginTop: 20, marginBottom: 20 }}>Queue</Text>
|
||||||
{queue?.map((track, i) => (
|
{queue.map((track, i) => (
|
||||||
|
<TouchableHandler id={track.id} onPress={playTrack} key={track.id}>
|
||||||
<QueueItem active={currentTrack?.id === track.id} key={i} alreadyPlayed={i < currentIndex}>
|
<QueueItem active={currentTrack?.id === track.id} key={i} alreadyPlayed={i < currentIndex}>
|
||||||
<Text style={{marginBottom: 2}}>{track.title}</Text>
|
<Text style={{marginBottom: 2}}>{track.title}</Text>
|
||||||
<Text style={{ opacity: 0.5 }}>{track.artist}</Text>
|
<Text style={{ opacity: 0.5 }}>{track.artist}</Text>
|
||||||
</QueueItem>
|
</QueueItem>
|
||||||
|
</TouchableHandler>
|
||||||
))}
|
))}
|
||||||
</View>
|
</View>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ export interface State {
|
|||||||
entities: Dictionary<AlbumTrack>;
|
entities: Dictionary<AlbumTrack>;
|
||||||
ids: EntityId[];
|
ids: EntityId[];
|
||||||
},
|
},
|
||||||
lastRefreshed?: Date,
|
lastRefreshed?: number,
|
||||||
}
|
}
|
||||||
|
|
||||||
const initialState: State = {
|
const initialState: State = {
|
||||||
@@ -35,7 +35,7 @@ const music = createSlice({
|
|||||||
builder.addCase(fetchAllAlbums.fulfilled, (state, { payload }) => {
|
builder.addCase(fetchAllAlbums.fulfilled, (state, { payload }) => {
|
||||||
albumAdapter.setAll(state.albums, payload);
|
albumAdapter.setAll(state.albums, payload);
|
||||||
state.albums.isLoading = false;
|
state.albums.isLoading = false;
|
||||||
state.lastRefreshed = new Date();
|
state.lastRefreshed = new Date().getTime();
|
||||||
});
|
});
|
||||||
builder.addCase(fetchAllAlbums.pending, (state) => { state.albums.isLoading = true; });
|
builder.addCase(fetchAllAlbums.pending, (state) => { state.albums.isLoading = true; });
|
||||||
builder.addCase(fetchAllAlbums.rejected, (state) => { state.albums.isLoading = false; });
|
builder.addCase(fetchAllAlbums.rejected, (state) => { state.albums.isLoading = false; });
|
||||||
@@ -46,7 +46,7 @@ const music = createSlice({
|
|||||||
const album = state.albums.entities[payload[0].AlbumId];
|
const album = state.albums.entities[payload[0].AlbumId];
|
||||||
if (album) {
|
if (album) {
|
||||||
album.Tracks = payload.map(d => d.Id);
|
album.Tracks = payload.map(d => d.Id);
|
||||||
album.lastRefreshed = new Date();
|
album.lastRefreshed = new Date().getTime();
|
||||||
}
|
}
|
||||||
state.tracks.isLoading = false;
|
state.tracks.isLoading = false;
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -41,7 +41,7 @@ export interface Album {
|
|||||||
BackdropImageTags: any[];
|
BackdropImageTags: any[];
|
||||||
LocationType: string;
|
LocationType: string;
|
||||||
Tracks?: string[];
|
Tracks?: string[];
|
||||||
lastRefreshed?: Date;
|
lastRefreshed?: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface AlbumTrack {
|
export interface AlbumTrack {
|
||||||
|
|||||||
@@ -4,9 +4,9 @@ import TrackPlayer, { usePlaybackState, Track } from 'react-native-track-player'
|
|||||||
/**
|
/**
|
||||||
* This hook retrieves the current playing track from TrackPlayer
|
* This hook retrieves the current playing track from TrackPlayer
|
||||||
*/
|
*/
|
||||||
export default function useQueue(): Track[] | undefined {
|
export default function useQueue(): Track[] {
|
||||||
const state = usePlaybackState();
|
const state = usePlaybackState();
|
||||||
const [queue, setQueue] = useState<Track[]>();
|
const [queue, setQueue] = useState<Track[]>([]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
TrackPlayer.getQueue().then(setQueue);
|
TrackPlayer.getQueue().then(setQueue);
|
||||||
|
|||||||
Reference in New Issue
Block a user