Compare commits

..

5 Commits

Author SHA1 Message Date
Lei Nelissen
1edeb00631 Fix active button color on Android 2021-04-03 15:19:38 +02:00
Lei Nelissen
d422c1ff1e Pull current track from Redux store
Fixes #40
2021-04-03 14:49:49 +02:00
Lei Nelissen
28b330ad4c Update all dependencies 2021-04-03 14:49:01 +02:00
Lei Nelissen
a867513212 Update Fastlane Sentry plugin 2021-03-22 09:49:33 +01:00
Lei Nelissen
14a6341fae Release build 13 2021-03-22 09:24:36 +01:00
14 changed files with 668 additions and 401 deletions

View File

@@ -6,21 +6,21 @@ GEM
public_suffix (>= 2.0.2, < 5.0) public_suffix (>= 2.0.2, < 5.0)
artifactory (3.0.15) artifactory (3.0.15)
atomos (0.1.3) atomos (0.1.3)
aws-eventstream (1.1.0) aws-eventstream (1.1.1)
aws-partitions (1.426.0) aws-partitions (1.434.0)
aws-sdk-core (3.112.0) aws-sdk-core (3.113.0)
aws-eventstream (~> 1, >= 1.0.2) aws-eventstream (~> 1, >= 1.0.2)
aws-partitions (~> 1, >= 1.239.0) aws-partitions (~> 1, >= 1.239.0)
aws-sigv4 (~> 1.1) aws-sigv4 (~> 1.1)
jmespath (~> 1.0) jmespath (~> 1.0)
aws-sdk-kms (1.42.0) aws-sdk-kms (1.43.0)
aws-sdk-core (~> 3, >= 3.112.0) aws-sdk-core (~> 3, >= 3.112.0)
aws-sigv4 (~> 1.1) aws-sigv4 (~> 1.1)
aws-sdk-s3 (1.88.0) aws-sdk-s3 (1.92.0)
aws-sdk-core (~> 3, >= 3.112.0) aws-sdk-core (~> 3, >= 3.112.0)
aws-sdk-kms (~> 1) aws-sdk-kms (~> 1)
aws-sigv4 (~> 1.1) aws-sigv4 (~> 1.1)
aws-sigv4 (1.2.2) aws-sigv4 (1.2.3)
aws-eventstream (~> 1, >= 1.0.2) aws-eventstream (~> 1, >= 1.0.2)
babosa (1.0.4) babosa (1.0.4)
claide (1.0.3) claide (1.0.3)
@@ -35,7 +35,7 @@ GEM
domain_name (0.5.20190701) domain_name (0.5.20190701)
unf (>= 0.0.5, < 1.0.0) unf (>= 0.0.5, < 1.0.0)
dotenv (2.7.6) dotenv (2.7.6)
emoji_regex (3.2.1) emoji_regex (3.2.2)
excon (0.79.0) excon (0.79.0)
faraday (1.3.0) faraday (1.3.0)
faraday-net_http (~> 1.0) faraday-net_http (~> 1.0)
@@ -47,8 +47,8 @@ GEM
faraday-net_http (1.0.1) faraday-net_http (1.0.1)
faraday_middleware (1.0.0) faraday_middleware (1.0.0)
faraday (~> 1.0) faraday (~> 1.0)
fastimage (2.2.2) fastimage (2.2.3)
fastlane (2.174.0) fastlane (2.178.0)
CFPropertyList (>= 2.3, < 4.0.0) CFPropertyList (>= 2.3, < 4.0.0)
addressable (>= 2.3, < 3.0.0) addressable (>= 2.3, < 3.0.0)
artifactory (~> 3.0) artifactory (~> 3.0)
@@ -72,6 +72,7 @@ GEM
jwt (>= 2.1.0, < 3) jwt (>= 2.1.0, < 3)
mini_magick (>= 4.9.4, < 5.0.0) mini_magick (>= 4.9.4, < 5.0.0)
multipart-post (~> 2.0.0) multipart-post (~> 2.0.0)
naturally (~> 2.2)
plist (>= 3.1.0, < 4.0.0) plist (>= 3.1.0, < 4.0.0)
rubyzip (>= 2.0.0, < 3.0.0) rubyzip (>= 2.0.0, < 3.0.0)
security (= 0.1.3) security (= 0.1.3)
@@ -85,7 +86,7 @@ GEM
xcodeproj (>= 1.13.0, < 2.0.0) xcodeproj (>= 1.13.0, < 2.0.0)
xcpretty (~> 0.3.0) xcpretty (~> 0.3.0)
xcpretty-travis-formatter (>= 0.0.3) xcpretty-travis-formatter (>= 0.0.3)
fastlane-plugin-sentry (1.8.0) fastlane-plugin-sentry (1.8.1)
gh_inspector (1.1.3) gh_inspector (1.1.3)
google-api-client (0.38.0) google-api-client (0.38.0)
addressable (~> 2.5, >= 2.5.1) addressable (~> 2.5, >= 2.5.1)
@@ -95,7 +96,7 @@ GEM
representable (~> 3.0) representable (~> 3.0)
retriable (>= 2.0, < 4.0) retriable (>= 2.0, < 4.0)
signet (~> 0.12) signet (~> 0.12)
google-apis-core (0.2.1) google-apis-core (0.3.0)
addressable (~> 2.5, >= 2.5.1) addressable (~> 2.5, >= 2.5.1)
googleauth (~> 0.14) googleauth (~> 0.14)
httpclient (>= 2.8.1, < 3.0) httpclient (>= 2.8.1, < 3.0)
@@ -105,17 +106,17 @@ GEM
rexml rexml
signet (~> 0.14) signet (~> 0.14)
webrick webrick
google-apis-iamcredentials_v1 (0.1.0) google-apis-iamcredentials_v1 (0.2.0)
google-apis-core (~> 0.1) google-apis-core (~> 0.1)
google-apis-storage_v1 (0.2.0) google-apis-storage_v1 (0.3.0)
google-apis-core (~> 0.1) google-apis-core (~> 0.1)
google-cloud-core (1.5.0) google-cloud-core (1.6.0)
google-cloud-env (~> 1.0) google-cloud-env (~> 1.0)
google-cloud-errors (~> 1.0) google-cloud-errors (~> 1.0)
google-cloud-env (1.4.0) google-cloud-env (1.5.0)
faraday (>= 0.17.3, < 2.0) faraday (>= 0.17.3, < 2.0)
google-cloud-errors (1.0.1) google-cloud-errors (1.1.0)
google-cloud-storage (1.30.0) google-cloud-storage (1.31.0)
addressable (~> 2.5) addressable (~> 2.5)
digest-crc (~> 0.4) digest-crc (~> 0.4)
google-apis-iamcredentials_v1 (~> 0.1) google-apis-iamcredentials_v1 (~> 0.1)
@@ -123,7 +124,7 @@ GEM
google-cloud-core (~> 1.2) google-cloud-core (~> 1.2)
googleauth (~> 0.9) googleauth (~> 0.9)
mini_mime (~> 1.0) mini_mime (~> 1.0)
googleauth (0.15.1) googleauth (0.16.0)
faraday (>= 0.17.3, < 2.0) faraday (>= 0.17.3, < 2.0)
jwt (>= 1.4, < 3.0) jwt (>= 1.4, < 3.0)
memoist (~> 0.16) memoist (~> 0.16)
@@ -158,7 +159,7 @@ GEM
ruby2_keywords (0.0.4) ruby2_keywords (0.0.4)
rubyzip (2.3.0) rubyzip (2.3.0)
security (0.1.3) security (0.1.3)
signet (0.14.1) signet (0.15.0)
addressable (~> 2.3) addressable (~> 2.3)
faraday (>= 0.17.3, < 2.0) faraday (>= 0.17.3, < 2.0)
jwt (>= 1.5, < 3.0) jwt (>= 1.5, < 3.0)

View File

@@ -542,7 +542,7 @@
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_MODULES = YES;
CODE_SIGN_STYLE = Automatic; CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 12; CURRENT_PROJECT_VERSION = 13;
DEVELOPMENT_TEAM = 238P3C58WC; DEVELOPMENT_TEAM = 238P3C58WC;
ENABLE_BITCODE = NO; ENABLE_BITCODE = NO;
GCC_PREPROCESSOR_DEFINITIONS = ( GCC_PREPROCESSOR_DEFINITIONS = (
@@ -573,7 +573,7 @@
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_MODULES = YES;
CODE_SIGN_STYLE = Automatic; CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 12; CURRENT_PROJECT_VERSION = 13;
DEVELOPMENT_TEAM = 238P3C58WC; DEVELOPMENT_TEAM = 238P3C58WC;
INFOPLIST_FILE = JellyfinAudioPlayer/Info.plist; INFOPLIST_FILE = JellyfinAudioPlayer/Info.plist;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";

View File

@@ -21,7 +21,7 @@
<key>CFBundleSignature</key> <key>CFBundleSignature</key>
<string>????</string> <string>????</string>
<key>CFBundleVersion</key> <key>CFBundleVersion</key>
<string>12</string> <string>13</string>
<key>LSRequiresIPhoneOS</key> <key>LSRequiresIPhoneOS</key>
<true/> <true/>
<key>NSAppTransportSecurity</key> <key>NSAppTransportSecurity</key>

View File

@@ -19,6 +19,6 @@
<key>CFBundleSignature</key> <key>CFBundleSignature</key>
<string>????</string> <string>????</string>
<key>CFBundleVersion</key> <key>CFBundleVersion</key>
<string>12</string> <string>13</string>
</dict> </dict>
</plist> </plist>

View File

@@ -261,13 +261,15 @@ PODS:
- React-jsi (= 0.64.0) - React-jsi (= 0.64.0)
- React-perflogger (= 0.64.0) - React-perflogger (= 0.64.0)
- React-jsinspector (0.64.0) - React-jsinspector (0.64.0)
- react-native-airplay-button (1.0.4):
- React-Core
- react-native-safe-area-context (3.2.0): - react-native-safe-area-context (3.2.0):
- React-Core - React-Core
- react-native-slider (3.0.3): - react-native-slider (3.0.3):
- React - React
- react-native-track-player (1.2.3): - react-native-track-player (1.2.6):
- React - React
- react-native-webview (11.2.3): - react-native-webview (11.3.1):
- React-Core - React-Core
- React-perflogger (0.64.0) - React-perflogger (0.64.0)
- React-RCTActionSheet (0.64.0): - React-RCTActionSheet (0.64.0):
@@ -433,6 +435,7 @@ DEPENDENCIES:
- React-jsi (from `../node_modules/react-native/ReactCommon/jsi`) - React-jsi (from `../node_modules/react-native/ReactCommon/jsi`)
- React-jsiexecutor (from `../node_modules/react-native/ReactCommon/jsiexecutor`) - React-jsiexecutor (from `../node_modules/react-native/ReactCommon/jsiexecutor`)
- React-jsinspector (from `../node_modules/react-native/ReactCommon/jsinspector`) - React-jsinspector (from `../node_modules/react-native/ReactCommon/jsinspector`)
- react-native-airplay-button (from `../node_modules/react-native-airplay-button`)
- react-native-safe-area-context (from `../node_modules/react-native-safe-area-context`) - react-native-safe-area-context (from `../node_modules/react-native-safe-area-context`)
- "react-native-slider (from `../node_modules/@react-native-community/slider`)" - "react-native-slider (from `../node_modules/@react-native-community/slider`)"
- react-native-track-player (from `../node_modules/react-native-track-player`) - react-native-track-player (from `../node_modules/react-native-track-player`)
@@ -511,6 +514,8 @@ EXTERNAL SOURCES:
:path: "../node_modules/react-native/ReactCommon/jsiexecutor" :path: "../node_modules/react-native/ReactCommon/jsiexecutor"
React-jsinspector: React-jsinspector:
:path: "../node_modules/react-native/ReactCommon/jsinspector" :path: "../node_modules/react-native/ReactCommon/jsinspector"
react-native-airplay-button:
:path: "../node_modules/react-native-airplay-button"
react-native-safe-area-context: react-native-safe-area-context:
:path: "../node_modules/react-native-safe-area-context" :path: "../node_modules/react-native-safe-area-context"
react-native-slider: react-native-slider:
@@ -594,10 +599,11 @@ SPEC CHECKSUMS:
React-jsi: 74341196d9547cbcbcfa4b3bbbf03af56431d5a1 React-jsi: 74341196d9547cbcbcfa4b3bbbf03af56431d5a1
React-jsiexecutor: 06a9c77b56902ae7ffcdd7a4905f664adc5d237b React-jsiexecutor: 06a9c77b56902ae7ffcdd7a4905f664adc5d237b
React-jsinspector: 0ae35a37b20d5e031eb020a69cc5afdbd6406301 React-jsinspector: 0ae35a37b20d5e031eb020a69cc5afdbd6406301
react-native-airplay-button: 6899e488bff6b4d87b33c1def54c919dad2e3803
react-native-safe-area-context: e471852c5ed67eea4b10c5d9d43c1cebae3b231d react-native-safe-area-context: e471852c5ed67eea4b10c5d9d43c1cebae3b231d
react-native-slider: b733e17fdd31186707146debf1f04b5d94aa1a93 react-native-slider: b733e17fdd31186707146debf1f04b5d94aa1a93
react-native-track-player: ba2416753b58f3cdf9db5a07daa65876d659f925 react-native-track-player: 92eaa90aeb24ce1a7149f983c75128075004e7a2
react-native-webview: 36561eaf7508e67f72d8c959b713bac841f3652e react-native-webview: 30f048378c6cee522ed9bbbedbc34acb21e58188
React-perflogger: 9c547d8f06b9bf00cb447f2b75e8d7f19b7e02af React-perflogger: 9c547d8f06b9bf00cb447f2b75e8d7f19b7e02af
React-RCTActionSheet: 3080b6e12e0e1a5b313c8c0050699b5c794a1b11 React-RCTActionSheet: 3080b6e12e0e1a5b313c8c0050699b5c794a1b11
React-RCTAnimation: 3f96f21a497ae7dabf4d2f150ee43f906aaf516f React-RCTAnimation: 3f96f21a497ae7dabf4d2f150ee43f906aaf516f

836
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -19,8 +19,8 @@
"@react-navigation/bottom-tabs": "^5.11.8", "@react-navigation/bottom-tabs": "^5.11.8",
"@react-navigation/native": "^5.9.3", "@react-navigation/native": "^5.9.3",
"@react-navigation/stack": "^5.14.3", "@react-navigation/stack": "^5.14.3",
"@reduxjs/toolkit": "^1.5.0", "@reduxjs/toolkit": "^1.5.1",
"@sentry/react-native": "^2.3.0", "@sentry/react-native": "^2.4.0",
"@types/lodash": "^4.14.168", "@types/lodash": "^4.14.168",
"date-fns": "^2.19.0", "date-fns": "^2.19.0",
"fuse.js": "^6.4.6", "fuse.js": "^6.4.6",
@@ -34,41 +34,41 @@
"react-native-fast-image": "^8.3.4", "react-native-fast-image": "^8.3.4",
"react-native-gesture-handler": "^1.10.3", "react-native-gesture-handler": "^1.10.3",
"react-native-localize": "^2.0.2", "react-native-localize": "^2.0.2",
"react-native-reanimated": "^2.0.0", "react-native-reanimated": "^2.1.0",
"react-native-safe-area-context": "^3.2.0", "react-native-safe-area-context": "^3.2.0",
"react-native-screens": "^2.18.1", "react-native-screens": "^2.18.1",
"react-native-svg": "^12.1.0", "react-native-svg": "^12.1.0",
"react-native-svg-transformer": "^0.14.3", "react-native-svg-transformer": "^0.14.3",
"react-native-track-player": "^1.2.6", "react-native-track-player": "^1.2.7",
"react-native-webview": "^11.3.1", "react-native-webview": "^11.3.2",
"react-redux": "^7.2.2", "react-redux": "^7.2.3",
"redux": "^4.0.5", "redux": "^4.0.5",
"redux-logger": "^3.0.6", "redux-logger": "^3.0.6",
"redux-persist": "^6.0.0", "redux-persist": "^6.0.0",
"styled-components": "^5.2.1" "styled-components": "^5.2.3"
}, },
"devDependencies": { "devDependencies": {
"@babel/core": "^7.13.10", "@babel/core": "^7.13.14",
"@babel/runtime": "^7.13.10", "@babel/runtime": "^7.13.10",
"@react-native-community/eslint-config": "^2.0.0", "@react-native-community/eslint-config": "^2.0.0",
"@sentry/cli": "^1.63.1", "@sentry/cli": "^1.63.2",
"@types/i18n-js": "^3.8.0", "@types/i18n-js": "^3.8.0",
"@types/jest": "^26.0.21", "@types/jest": "^26.0.22",
"@types/react-native": "^0.64.0", "@types/react-native": "^0.64.2",
"@types/react-redux": "^7.1.16", "@types/react-redux": "^7.1.16",
"@types/react-test-renderer": "^17.0.1", "@types/react-test-renderer": "^17.0.1",
"@types/redux-logger": "^3.0.8", "@types/redux-logger": "^3.0.8",
"@types/styled-components": "^5.1.9", "@types/styled-components": "^5.1.9",
"@types/styled-components-react-native": "^5.1.1", "@types/styled-components-react-native": "^5.1.1",
"@typescript-eslint/eslint-plugin": "^4.18.0", "@typescript-eslint/eslint-plugin": "^4.20.0",
"@typescript-eslint/parser": "^4.18.0", "@typescript-eslint/parser": "^4.20.0",
"babel-jest": "^26.6.3", "babel-jest": "^26.6.3",
"babel-plugin-module-resolver": "^4.1.0", "babel-plugin-module-resolver": "^4.1.0",
"eslint": "^7.22.0", "eslint": "^7.23.0",
"eslint-plugin-react-hooks": "^4.2.0", "eslint-plugin-react-hooks": "^4.2.0",
"jest": "^26.6.3", "jest": "^26.6.3",
"metro-react-native-babel-preset": "^0.65.2", "metro-react-native-babel-preset": "^0.65.2",
"react-test-renderer": "^17.0.1", "react-test-renderer": "^17.0.2",
"typescript": "^4.2.3" "typescript": "^4.2.3"
}, },
"jest": { "jest": {

View File

@@ -11,7 +11,8 @@ import {
} from '@react-navigation/native'; } from '@react-navigation/native';
import { useColorScheme } from 'react-native'; import { useColorScheme } from 'react-native';
import { ColorSchemeContext, themes } from './Colors'; import { ColorSchemeContext, themes } from './Colors';
import ErrorReportingAlert from 'utility/ErrorReportingAlert'; // import ErrorReportingAlert from 'utility/ErrorReportingAlert';
import PlayerStateUpdater from './PlayerStateUpdater';
export default function App(): JSX.Element { export default function App(): JSX.Element {
const colorScheme = useColorScheme(); const colorScheme = useColorScheme();
@@ -41,6 +42,7 @@ export default function App(): JSX.Element {
<ColorSchemeContext.Provider value={theme}> <ColorSchemeContext.Provider value={theme}>
<NavigationContainer theme={colorScheme === 'dark' ? DarkTheme : DefaultTheme}> <NavigationContainer theme={colorScheme === 'dark' ? DarkTheme : DefaultTheme}>
<Routes /> <Routes />
<PlayerStateUpdater />
</NavigationContainer> </NavigationContainer>
</ColorSchemeContext.Provider> </ColorSchemeContext.Provider>
</PersistGate> </PersistGate>

View File

@@ -13,21 +13,14 @@ interface ButtonProps extends PressableProps {
style?: ViewProps['style']; style?: ViewProps['style'];
} }
interface PressableStyleProps {
active: boolean;
}
const BaseButton = styled.Pressable<PressableStyleProps>` const BaseButton = styled.Pressable`
padding: 16px; padding: 16px;
border-radius: 8px; border-radius: 8px;
flex-direction: row; flex-direction: row;
align-items: center; align-items: center;
justify-content: center; justify-content: center;
flex-grow: 1; flex-grow: 1;
${props => props.active && css`
background-color: ${THEME_COLOR};
`}
`; `;
const ButtonText = styled.Text<{ active?: boolean }>` const ButtonText = styled.Text<{ active?: boolean }>`
@@ -51,8 +44,10 @@ export default function Button(props: ButtonProps) {
{...rest} {...rest}
onPressIn={handlePressIn} onPressIn={handlePressIn}
onPressOut={handlePressOut} onPressOut={handlePressOut}
active={isPressed} style={[
style={[ defaultStyles.button, props.style ]} props.style,
{ backgroundColor: isPressed ? THEME_COLOR : defaultStyles.button.backgroundColor }
]}
> >
{Icon && {Icon &&
<Icon <Icon

View File

@@ -0,0 +1,54 @@
import { useCallback, useEffect } from 'react';
import TrackPlayer, { TrackPlayerEvents } from 'react-native-track-player';
import { shallowEqual, useDispatch } from 'react-redux';
import { useTypedSelector } from 'store';
import player from 'store/player';
function PlayerStateUpdater() {
const dispatch = useDispatch();
const trackId = useTypedSelector(state => state.player.currentTrack?.id, shallowEqual);
const handleUpdate = useCallback(async () => {
const currentTrackId = await TrackPlayer.getCurrentTrack();
// GUARD: Only retrieve new track if it is different from the one we
// have currently in state.
if (currentTrackId === trackId){
return;
}
// GUARD: Only fetch current track if there is a current track
if (!currentTrackId) {
dispatch(player.actions.setCurrentTrack(undefined));
}
// If it is different, retrieve the track and save it
try {
const currentTrack = await TrackPlayer.getTrack(currentTrackId);
dispatch(player.actions.setCurrentTrack(currentTrack));
} catch {
// Due to the async nature, a track might be removed at the
// point when we try to retrieve it. If this happens, we'll just
// smother the error and wait for a new track update to
// finish.
}
}, [trackId, dispatch]);
useEffect(() => {
function handler() {
handleUpdate();
}
handler();
const subscription = TrackPlayer.addEventListener(TrackPlayerEvents.PLAYBACK_TRACK_CHANGED, handler);
return () => {
subscription.remove();
};
}, []);
return null;
}
export default PlayerStateUpdater;

View File

@@ -80,7 +80,7 @@ const Album: React.FC = () => {
const refresh = useCallback(() => { dispatch(fetchTracksByAlbum(id)); }, [id, dispatch]); const refresh = useCallback(() => { dispatch(fetchTracksByAlbum(id)); }, [id, dispatch]);
const selectTrack = useCallback(async (trackId) => { const selectTrack = useCallback(async (trackId) => {
const tracks = await playAlbum(id, false); const tracks = await playAlbum(id, false);
if (tracks) { if (tracks) {
const track = tracks.find((t) => t.id.startsWith(trackId)); const track = tracks.find((t) => t.id.startsWith(trackId));

View File

@@ -1,10 +1,26 @@
import { createSlice } from '@reduxjs/toolkit'; import { createSlice, PayloadAction } from '@reduxjs/toolkit';
import { Track } from 'react-native-track-player';
interface State {
addedTrackCount: number,
currentTrack: Track | undefined,
}
const initialState: State = {
addedTrackCount: 0,
currentTrack: undefined,
};
const player = createSlice({ const player = createSlice({
name: 'player', name: 'player',
initialState: 0, initialState,
reducers: { reducers: {
addNewTrackToPlayer: (state) => state + 1, addNewTrackToPlayer: (state) => {
state.addedTrackCount += 1;
},
setCurrentTrack: (state, action: PayloadAction<Track | undefined>) => {
state.currentTrack = action.payload;
},
} }
}); });

View File

@@ -1,42 +1,15 @@
import { useEffect, useState } from 'react'; import { Track } from 'react-native-track-player';
import TrackPlayer, { usePlaybackState, Track } from 'react-native-track-player'; import { useTypedSelector } from 'store';
const idEqual = (left: Track | undefined, right: Track | undefined) => {
return left?.id === right?.id;
};
/** /**
* This hook retrieves the current playing track from TrackPlayer * This hook retrieves the current playing track from TrackPlayer
*/ */
export default function useCurrentTrack(): Track | undefined { export default function useCurrentTrack(): Track | undefined {
const state = usePlaybackState(); const track = useTypedSelector(state => state.player.currentTrack, idEqual);
const [track, setTrack] = useState<Track>();
useEffect(() => {
const fetchTrack = async () => {
const currentTrackId = await TrackPlayer.getCurrentTrack();
// GUARD: Only fetch current track if there is a current track
if (!currentTrackId) {
setTrack(undefined);
}
// GUARD: Only retrieve new track if it is different from the one we
// have currently in state.
if (currentTrackId === track?.id){
return;
}
// If it is different, retrieve the track and save it
try {
const currentTrack = await TrackPlayer.getTrack(currentTrackId);
setTrack(currentTrack);
} catch {
// Due to the async nature, a track might be removed at the
// point when we try to retrieve it. If this happens, we'll just
// smother the error and wait for a new track update to
// finish.
}
};
fetchTrack();
}, [state, track, setTrack]);
return track; return track;
} }

View File

@@ -8,7 +8,7 @@ import { useTypedSelector } from 'store';
export default function useQueue(): Track[] { export default function useQueue(): Track[] {
const state = usePlaybackState(); const state = usePlaybackState();
const [queue, setQueue] = useState<Track[]>([]); const [queue, setQueue] = useState<Track[]>([]);
const addedTrackCount = useTypedSelector(state => state.player); const addedTrackCount = useTypedSelector(state => state.player.addedTrackCount);
useEffect(() => { useEffect(() => {
TrackPlayer.getQueue().then(setQueue); TrackPlayer.getQueue().then(setQueue);