Compare commits

...

34 Commits

Author SHA1 Message Date
Lei Nelissen
6440c1ac7b Bump version 2021-10-25 23:50:33 +02:00
Lei Nelissen
6c0a277397 Update dependencies 2021-10-25 23:36:14 +02:00
Lei Nelissen
080a664d4f Merge pull request #58 from Sjord/nl-locale-fixes
Dutch translation fixes
2021-10-25 22:25:22 +02:00
Sjoerd Langkemper
ae6a99ce6d Dutch translation fixes
achtergrond = background
instellen, stel ... in = to configure
2021-10-12 21:26:02 +02:00
Lei Nelissen
b14f546525 Add Japanese as a locale 2021-05-12 22:18:23 +02:00
Lei Nelissen
2b8e78a076 Merge pull request #46 from leinelissen/translations_src-localisation-lang-en-locale-json--master_ja
Translate '/src/localisation/lang/en/locale.json' in 'ja'
2021-05-12 22:14:56 +02:00
Lei Nelissen
4a345699a8 Fix search box (fix #47) 2021-05-12 22:13:44 +02:00
Lei Nelissen
eaef9be7db Update dependencies 2021-05-12 22:03:29 +02:00
transifex-integration[bot]
8049a25cce Apply translations in ja
translation completed for the source file '/src/localisation/lang/en/locale.json'
on the 'ja' language.
2021-05-12 14:42:54 +00:00
Lei Nelissen
7403ab986b Release build 16 2021-04-25 23:45:20 +02:00
Lei Nelissen
d8e9f8f4c6 Allow arbitrary loads (ie HTTP) on iOS
Fixes #42
2021-04-25 23:16:27 +02:00
Lei Nelissen
fa05935017 Release build 15 2021-04-24 23:18:01 +02:00
Lei Nelissen
2de5cc8e6c Polish search engine UX 2021-04-24 15:30:07 +02:00
Lei Nelissen
24d484ca25 Add track results to search queries 2021-04-24 14:50:43 +02:00
Lei Nelissen
a7b24cf4eb Fix XMLDom issue 2021-04-24 12:21:02 +02:00
Lei Nelissen
eaa1402173 Update packages 2021-04-24 12:18:56 +02:00
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
Lei Nelissen
645f1307f3 Add OGG Support
Fixes #12
2021-03-21 23:01:07 +01:00
Lei Nelissen
3f16bd6465 Show Album art instead of Track art if an AlbumId is available
Fixes #13
2021-03-21 22:55:35 +01:00
Lei Nelissen
5c15d730b3 Add AirPlay casting button 2021-03-21 22:42:04 +01:00
Lei Nelissen
603bf10154 Switch back to regular react-native-track-player version as patch was merged 2021-03-21 22:12:36 +01:00
Lei Nelissen
57f9e0e08e Upgrade Android build for React Native 0.64 2021-03-21 21:50:35 +01:00
Lei Nelissen
597a348eab Release build 12 2021-03-21 21:50:15 +01:00
Lei Nelissen
8860581450 Upgrade to React Native 0.64 2021-03-21 20:16:26 +01:00
Lei Nelissen
a92ff581ae Merge pull request #38 from yisiliang/master
add Chinese language support
2021-03-21 18:51:04 +01:00
YiSiliang
cd2e333caa add Chinese language support 2021-03-14 21:07:50 +08:00
Lei Nelissen
4ba83b8efc Release build 11 2021-03-09 22:42:34 +01:00
Lei Nelissen
e4daccfe5e Update packages 2021-03-09 22:25:43 +01:00
Lei Nelissen
76c45623a0 Fix launch crash on devices without fallback languages 2021-03-09 22:21:41 +01:00
Lei Nelissen
e4b93ec8c8 Release build 10 2021-02-13 22:16:04 +01:00
44 changed files with 7501 additions and 17598 deletions

3
.editorconfig Normal file
View File

@@ -0,0 +1,3 @@
# Windows files
[*.bat]
end_of_line = crlf

4
.gitattributes vendored
View File

@@ -1 +1,3 @@
*.pbxproj -text
# Windows files should use crlf line endings
# https://help.github.com/articles/dealing-with-line-endings/
*.bat text eol=crlf

View File

@@ -2,61 +2,74 @@ GEM
remote: https://rubygems.org/
specs:
CFPropertyList (3.0.3)
addressable (2.7.0)
addressable (2.8.0)
public_suffix (>= 2.0.2, < 5.0)
artifactory (3.0.15)
atomos (0.1.3)
aws-eventstream (1.1.0)
aws-partitions (1.426.0)
aws-sdk-core (3.112.0)
aws-eventstream (1.1.1)
aws-partitions (1.488.0)
aws-sdk-core (3.119.0)
aws-eventstream (~> 1, >= 1.0.2)
aws-partitions (~> 1, >= 1.239.0)
aws-sigv4 (~> 1.1)
jmespath (~> 1.0)
aws-sdk-kms (1.42.0)
aws-sdk-core (~> 3, >= 3.112.0)
aws-sdk-kms (1.46.0)
aws-sdk-core (~> 3, >= 3.119.0)
aws-sigv4 (~> 1.1)
aws-sdk-s3 (1.88.0)
aws-sdk-core (~> 3, >= 3.112.0)
aws-sdk-s3 (1.99.0)
aws-sdk-core (~> 3, >= 3.119.0)
aws-sdk-kms (~> 1)
aws-sigv4 (~> 1.1)
aws-sigv4 (1.2.2)
aws-sigv4 (1.2.4)
aws-eventstream (~> 1, >= 1.0.2)
babosa (1.0.4)
claide (1.0.3)
colored (1.2)
colored2 (3.1.2)
commander-fastlane (4.4.6)
highline (~> 1.7.2)
commander (4.6.0)
highline (~> 2.0.0)
declarative (0.0.20)
declarative-option (0.1.0)
digest-crc (0.6.3)
digest-crc (0.6.4)
rake (>= 12.0.0, < 14.0.0)
domain_name (0.5.20190701)
unf (>= 0.0.5, < 1.0.0)
dotenv (2.7.6)
emoji_regex (3.2.1)
excon (0.79.0)
faraday (1.3.0)
emoji_regex (3.2.2)
excon (0.85.0)
faraday (1.7.0)
faraday-em_http (~> 1.0)
faraday-em_synchrony (~> 1.0)
faraday-excon (~> 1.1)
faraday-httpclient (~> 1.0.1)
faraday-net_http (~> 1.0)
faraday-net_http_persistent (~> 1.1)
faraday-patron (~> 1.0)
faraday-rack (~> 1.0)
multipart-post (>= 1.2, < 3)
ruby2_keywords
ruby2_keywords (>= 0.0.4)
faraday-cookie_jar (0.0.7)
faraday (>= 0.8.0)
http-cookie (~> 1.0.0)
faraday-em_http (1.0.0)
faraday-em_synchrony (1.0.0)
faraday-excon (1.1.0)
faraday-httpclient (1.0.1)
faraday-net_http (1.0.1)
faraday_middleware (1.0.0)
faraday-net_http_persistent (1.2.0)
faraday-patron (1.0.0)
faraday-rack (1.0.0)
faraday_middleware (1.1.0)
faraday (~> 1.0)
fastimage (2.2.2)
fastlane (2.174.0)
fastimage (2.2.5)
fastlane (2.191.0)
CFPropertyList (>= 2.3, < 4.0.0)
addressable (>= 2.3, < 3.0.0)
addressable (>= 2.8, < 3.0.0)
artifactory (~> 3.0)
aws-sdk-s3 (~> 1.0)
babosa (>= 1.0.3, < 2.0.0)
bundler (>= 1.12.0, < 3.0.0)
colored
commander-fastlane (>= 4.4.6, < 5.0.0)
commander (~> 4.6)
dotenv (>= 2.1.1, < 3.0.0)
emoji_regex (>= 0.1, < 4.0)
excon (>= 0.71.0, < 1.0.0)
@@ -65,18 +78,19 @@ GEM
faraday_middleware (~> 1.0)
fastimage (>= 2.1.0, < 3.0.0)
gh_inspector (>= 1.1.2, < 2.0.0)
google-api-client (>= 0.37.0, < 0.39.0)
google-cloud-storage (>= 1.15.0, < 2.0.0)
highline (>= 1.7.2, < 2.0.0)
google-apis-androidpublisher_v3 (~> 0.3)
google-apis-playcustomapp_v1 (~> 0.1)
google-cloud-storage (~> 1.31)
highline (~> 2.0)
json (< 3.0.0)
jwt (>= 2.1.0, < 3)
mini_magick (>= 4.9.4, < 5.0.0)
multipart-post (~> 2.0.0)
naturally (~> 2.2)
plist (>= 3.1.0, < 4.0.0)
rubyzip (>= 2.0.0, < 3.0.0)
security (= 0.1.3)
simctl (~> 1.6.3)
slack-notifier (>= 2.0.0, < 3.0.0)
terminal-notifier (>= 2.0.0, < 3.0.0)
terminal-table (>= 1.4.5, < 2.0.0)
tty-screen (>= 0.6.3, < 1.0.0)
@@ -85,61 +99,56 @@ GEM
xcodeproj (>= 1.13.0, < 2.0.0)
xcpretty (~> 0.3.0)
xcpretty-travis-formatter (>= 0.0.3)
fastlane-plugin-sentry (1.8.0)
fastlane-plugin-sentry (1.8.1)
gh_inspector (1.1.3)
google-api-client (0.38.0)
google-apis-androidpublisher_v3 (0.10.0)
google-apis-core (>= 0.4, < 2.a)
google-apis-core (0.4.1)
addressable (~> 2.5, >= 2.5.1)
googleauth (~> 0.9)
httpclient (>= 2.8.1, < 3.0)
googleauth (>= 0.16.2, < 2.a)
httpclient (>= 2.8.1, < 3.a)
mini_mime (~> 1.0)
representable (~> 3.0)
retriable (>= 2.0, < 4.0)
signet (~> 0.12)
google-apis-core (0.2.1)
addressable (~> 2.5, >= 2.5.1)
googleauth (~> 0.14)
httpclient (>= 2.8.1, < 3.0)
mini_mime (~> 1.0)
representable (~> 3.0)
retriable (>= 2.0, < 4.0)
retriable (>= 2.0, < 4.a)
rexml
signet (~> 0.14)
webrick
google-apis-iamcredentials_v1 (0.1.0)
google-apis-core (~> 0.1)
google-apis-storage_v1 (0.2.0)
google-apis-core (~> 0.1)
google-cloud-core (1.5.0)
google-apis-iamcredentials_v1 (0.6.0)
google-apis-core (>= 0.4, < 2.a)
google-apis-playcustomapp_v1 (0.5.0)
google-apis-core (>= 0.4, < 2.a)
google-apis-storage_v1 (0.6.0)
google-apis-core (>= 0.4, < 2.a)
google-cloud-core (1.6.0)
google-cloud-env (~> 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)
google-cloud-errors (1.0.1)
google-cloud-storage (1.30.0)
google-cloud-errors (1.1.0)
google-cloud-storage (1.34.1)
addressable (~> 2.5)
digest-crc (~> 0.4)
google-apis-iamcredentials_v1 (~> 0.1)
google-apis-storage_v1 (~> 0.1)
google-cloud-core (~> 1.2)
googleauth (~> 0.9)
google-cloud-core (~> 1.6)
googleauth (>= 0.16.2, < 2.a)
mini_mime (~> 1.0)
googleauth (0.15.1)
googleauth (0.17.0)
faraday (>= 0.17.3, < 2.0)
jwt (>= 1.4, < 3.0)
memoist (~> 0.16)
multi_json (~> 1.11)
os (>= 0.9, < 2.0)
signet (~> 0.14)
highline (1.7.10)
http-cookie (1.0.3)
highline (2.0.3)
http-cookie (1.0.4)
domain_name (~> 0.5)
httpclient (2.8.3)
jmespath (1.4.0)
json (2.5.1)
jwt (2.2.2)
jwt (2.2.3)
memoist (0.16.2)
mini_magick (4.11.0)
mini_mime (1.0.2)
mini_mime (1.1.0)
multi_json (1.15.0)
multipart-post (2.0.0)
nanaimo (0.3.0)
@@ -147,18 +156,18 @@ GEM
os (1.1.1)
plist (3.6.0)
public_suffix (4.0.6)
rake (13.0.3)
representable (3.0.4)
rake (13.0.6)
representable (3.1.1)
declarative (< 0.1.0)
declarative-option (< 0.2.0)
trailblazer-option (>= 0.1.1, < 0.2.0)
uber (< 0.2.0)
retriable (3.1.2)
rexml (3.2.4)
rexml (3.2.5)
rouge (2.0.7)
ruby2_keywords (0.0.4)
rubyzip (2.3.0)
ruby2_keywords (0.0.5)
rubyzip (2.3.2)
security (0.1.3)
signet (0.14.1)
signet (0.15.0)
addressable (~> 2.3)
faraday (>= 0.17.3, < 2.0)
jwt (>= 1.5, < 3.0)
@@ -166,10 +175,10 @@ GEM
simctl (1.6.8)
CFPropertyList
naturally
slack-notifier (2.3.2)
terminal-notifier (2.0.0)
terminal-table (1.8.0)
unicode-display_width (~> 1.1, >= 1.1.1)
trailblazer-option (0.1.1)
tty-cursor (0.7.1)
tty-screen (0.8.1)
tty-spinner (0.9.3)
@@ -181,12 +190,13 @@ GEM
unicode-display_width (1.7.0)
webrick (1.7.0)
word_wrap (1.0.0)
xcodeproj (1.19.0)
xcodeproj (1.21.0)
CFPropertyList (>= 2.3.3, < 4.0)
atomos (~> 0.1.3)
claide (>= 1.0.2, < 2.0)
colored2 (~> 3.1)
nanaimo (~> 0.3.0)
rexml (~> 3.2.4)
xcpretty (0.3.0)
rouge (~> 2.0.7)
xcpretty-travis-formatter (1.0.1)

View File

@@ -122,13 +122,15 @@ def jscFlavor = 'org.webkit:android-jsc:+'
*/
def enableHermes = project.ext.react.get("enableHermes", false);
android {
compileSdkVersion rootProject.ext.compileSdkVersion
/**
* Architectures to build native code for in debug.
*/
def nativeArchitectures = project.getProperties().get("reactNativeDebugArchitectures")
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
android {
ndkVersion rootProject.ext.ndkVersion
compileSdkVersion rootProject.ext.compileSdkVersion
defaultConfig {
applicationId "com.jellyfinaudioplayer"
@@ -157,6 +159,11 @@ android {
buildTypes {
debug {
signingConfig signingConfigs.debug
if (nativeArchitectures) {
ndk {
abiFilters nativeArchitectures.split(',')
}
}
}
release {
// Caution! In production, you need to generate your own keystore file.
@@ -172,11 +179,12 @@ android {
variant.outputs.each { output ->
// For each separate APK per architecture, set a unique version code as described here:
// https://developer.android.com/studio/build/configure-apk-splits.html
// Example: versionCode 1 will generate 1001 for armeabi-v7a, 1002 for x86, etc.
def versionCodes = ["armeabi-v7a": 1, "x86": 2, "arm64-v8a": 3, "x86_64": 4]
def abi = output.getFilter(OutputFile.ABI)
if (abi != null) { // null for the universal-debug, universal-release variants
output.versionCodeOverride =
versionCodes.get(abi) * 1048576 + defaultConfig.versionCode
defaultConfig.versionCode * 1000 + versionCodes.get(abi)
}
}
@@ -214,7 +222,7 @@ dependencies {
// Run this once to be able to run the application with BUCK
// puts all compile dependencies into folder libs for BUCK to use
task copyDownloadableDepsToLibs(type: Copy) {
from configurations.compile
from configurations.implementation
into 'libs'
}

View File

@@ -4,5 +4,10 @@
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/>
<application android:usesCleartextTraffic="true" tools:targetApi="28" tools:ignore="GoogleAppIndexingWarning" />
<application
android:usesCleartextTraffic="true"
tools:targetApi="28"
tools:ignore="GoogleAppIndexingWarning">
<activity android:name="com.facebook.react.devsupport.DevSettingsActivity" />
</application>
</manifest>

View File

@@ -22,7 +22,5 @@
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity android:name="com.facebook.react.devsupport.DevSettingsActivity" />
</application>
</manifest>

View File

@@ -1,6 +1,7 @@
package com.jellyfinaudioplayer;
import com.facebook.react.ReactActivity;
import android.os.Bundle;
public class MainActivity extends ReactActivity {
@@ -12,4 +13,9 @@ public class MainActivity extends ReactActivity {
protected String getMainComponentName() {
return "JellyfinAudioPlayer";
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(null);
}
}

View File

@@ -2,17 +2,18 @@
buildscript {
ext {
buildToolsVersion = "28.0.3"
minSdkVersion = 16
compileSdkVersion = 28
targetSdkVersion = 28
buildToolsVersion = "30.0.2"
minSdkVersion = 21
compileSdkVersion = 30
targetSdkVersion = 30
ndkVersion = "21.4.7075529"
}
repositories {
google()
jcenter()
mavenCentral()
}
dependencies {
classpath("com.android.tools.build:gradle:3.5.2")
classpath("com.android.tools.build:gradle:4.2.2")
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
@@ -21,6 +22,7 @@ buildscript {
allprojects {
repositories {
mavenCentral()
mavenLocal()
maven {
// All of React Native (JS, Obj-C sources, Android binaries) is installed from npm

View File

@@ -25,4 +25,4 @@ android.useAndroidX=true
android.enableJetifier=true
# Version of flipper SDK to use with React Native
FLIPPER_VERSION=0.54.0
FLIPPER_VERSION=0.99.0

View File

@@ -1,5 +1,5 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-6.5-all.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-6.9-all.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists

2
android/gradlew vendored
View File

@@ -82,6 +82,7 @@ esac
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
# Determine the Java command to use to start the JVM.
if [ -n "$JAVA_HOME" ] ; then
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
@@ -129,6 +130,7 @@ fi
if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then
APP_HOME=`cygpath --path --mixed "$APP_HOME"`
CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
JAVACMD=`cygpath --unix "$JAVACMD"`
# We build the pattern for arguments to be converted via cygpath

View File

@@ -38,6 +38,6 @@ Generate beta build
----
This README.md is auto-generated and will be re-generated every time [fastlane](https://fastlane.tools) is run.
This README.md is auto-generated and will be re-generated every time [_fastlane_](https://fastlane.tools) is run.
More information about fastlane can be found on [fastlane.tools](https://fastlane.tools).
The documentation of fastlane can be found on [docs.fastlane.tools](https://docs.fastlane.tools).

View File

@@ -5,7 +5,9 @@ import App from './src/components/App';
import { name as appName } from './app.json';
import PlaybackService from './src/utility/PlaybackService';
import { setupSentry } from 'utility/Sentry';
import { enableScreens } from 'react-native-screens';
setupSentry();
enableScreens();
AppRegistry.registerComponent(appName, () => App);
TrackPlayer.registerPlaybackService(() => PlaybackService);

View File

@@ -179,6 +179,7 @@
00E356EB1AD99517003FC87E /* Frameworks */,
00E356EC1AD99517003FC87E /* Resources */,
BDE784ECF29EF861DBFF49D7 /* [CP] Copy Pods Resources */,
476A07969B11CA4E09819AC0 /* [CP] Embed Pods Frameworks */,
);
buildRules = (
);
@@ -202,6 +203,7 @@
00DD1BFF1BD5951E006B06BC /* Bundle React Native code and images */,
B9FB8FC65CEFF9AFAC71127E /* [CP] Copy Pods Resources */,
1DC46C84C90B4D84A18AC142 /* Upload Debug Symbols to Sentry */,
E8FF56077B675D4D92D5CC25 /* [CP] Embed Pods Frameworks */,
);
buildRules = (
);
@@ -303,6 +305,26 @@
shellPath = /bin/sh;
shellScript = "export SENTRY_PROPERTIES=sentry.properties\n../node_modules/@sentry/cli/bin/sentry-cli upload-dsym";
};
476A07969B11CA4E09819AC0 /* [CP] Embed Pods Frameworks */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputPaths = (
"${PODS_ROOT}/Target Support Files/Pods-JellyfinAudioPlayer-JellyfinAudioPlayerTests/Pods-JellyfinAudioPlayer-JellyfinAudioPlayerTests-frameworks.sh",
"${PODS_XCFRAMEWORKS_BUILD_DIR}/Flipper-DoubleConversion/double-conversion.framework/double-conversion",
"${PODS_XCFRAMEWORKS_BUILD_DIR}/OpenSSL-Universal/OpenSSL.framework/OpenSSL",
);
name = "[CP] Embed Pods Frameworks";
outputPaths = (
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/double-conversion.framework",
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/OpenSSL.framework",
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-JellyfinAudioPlayer-JellyfinAudioPlayerTests/Pods-JellyfinAudioPlayer-JellyfinAudioPlayerTests-frameworks.sh\"\n";
showEnvVarsInLog = 0;
};
B9FB8FC65CEFF9AFAC71127E /* [CP] Copy Pods Resources */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
@@ -383,6 +405,26 @@
shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n";
showEnvVarsInLog = 0;
};
E8FF56077B675D4D92D5CC25 /* [CP] Embed Pods Frameworks */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputPaths = (
"${PODS_ROOT}/Target Support Files/Pods-JellyfinAudioPlayer/Pods-JellyfinAudioPlayer-frameworks.sh",
"${PODS_XCFRAMEWORKS_BUILD_DIR}/Flipper-DoubleConversion/double-conversion.framework/double-conversion",
"${PODS_XCFRAMEWORKS_BUILD_DIR}/OpenSSL-Universal/OpenSSL.framework/OpenSSL",
);
name = "[CP] Embed Pods Frameworks";
outputPaths = (
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/double-conversion.framework",
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/OpenSSL.framework",
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-JellyfinAudioPlayer/Pods-JellyfinAudioPlayer-frameworks.sh\"\n";
showEnvVarsInLog = 0;
};
FD10A7F022414F080027D42C /* Start Packager */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
@@ -504,7 +546,7 @@
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CLANG_ENABLE_MODULES = YES;
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 9;
CURRENT_PROJECT_VERSION = 19;
DEVELOPMENT_TEAM = 238P3C58WC;
ENABLE_BITCODE = NO;
GCC_PREPROCESSOR_DEFINITIONS = (
@@ -535,7 +577,7 @@
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CLANG_ENABLE_MODULES = YES;
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 9;
CURRENT_PROJECT_VERSION = 19;
DEVELOPMENT_TEAM = 238P3C58WC;
INFOPLIST_FILE = JellyfinAudioPlayer/Info.plist;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
@@ -603,7 +645,7 @@
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 10.0;
IPHONEOS_DEPLOYMENT_TARGET = 11.0;
LD_RUNPATH_SEARCH_PATHS = "/usr/lib/swift $(inherited)";
LIBRARY_SEARCH_PATHS = (
"\"$(TOOLCHAIN_DIR)/usr/lib/swift/$(PLATFORM_NAME)\"",
@@ -659,7 +701,7 @@
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 10.0;
IPHONEOS_DEPLOYMENT_TARGET = 11.0;
LD_RUNPATH_SEARCH_PATHS = "/usr/lib/swift $(inherited)";
LIBRARY_SEARCH_PATHS = (
"\"$(TOOLCHAIN_DIR)/usr/lib/swift/$(PLATFORM_NAME)\"",

View File

@@ -21,21 +21,13 @@
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string>9</string>
<string>19</string>
<key>LSRequiresIPhoneOS</key>
<true/>
<key>NSAppTransportSecurity</key>
<dict>
<key>NSAllowsArbitraryLoads</key>
<true/>
<key>NSExceptionDomains</key>
<dict>
<key>localhost</key>
<dict>
<key>NSExceptionAllowsInsecureHTTPLoads</key>
<true/>
</dict>
</dict>
</dict>
<key>NSLocationWhenInUseUsageDescription</key>
<string></string>

View File

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

View File

@@ -1,4 +1,4 @@
platform :ios, '10.0'
platform :ios, '11.0'
require_relative '../node_modules/@react-native-community/cli-platform-ios/native_modules'
require_relative '../node_modules/react-native/scripts/react_native_pods'

View File

@@ -1,379 +1,453 @@
PODS:
- boost-for-react-native (1.63.0)
- CocoaAsyncSocket (7.6.4)
- CocoaLibEvent (1.0.0)
- boost (1.76.0)
- CocoaAsyncSocket (7.6.5)
- DoubleConversion (1.1.6)
- FBLazyVector (0.63.4)
- FBReactNativeSpec (0.63.4):
- Folly (= 2020.01.13.00)
- RCTRequired (= 0.63.4)
- RCTTypeSafety (= 0.63.4)
- React-Core (= 0.63.4)
- React-jsi (= 0.63.4)
- ReactCommon/turbomodule/core (= 0.63.4)
- Flipper (0.54.0):
- Flipper-Folly (~> 2.2)
- Flipper-RSocket (~> 1.1)
- Flipper-DoubleConversion (1.1.7)
- Flipper-Folly (2.3.0):
- boost-for-react-native
- CocoaLibEvent (~> 1.0)
- FBLazyVector (0.66.1)
- FBReactNativeSpec (0.66.1):
- RCT-Folly (= 2021.06.28.00-v2)
- RCTRequired (= 0.66.1)
- RCTTypeSafety (= 0.66.1)
- React-Core (= 0.66.1)
- React-jsi (= 0.66.1)
- ReactCommon/turbomodule/core (= 0.66.1)
- Flipper (0.99.0):
- Flipper-Folly (~> 2.6)
- Flipper-RSocket (~> 1.4)
- Flipper-Boost-iOSX (1.76.0.1.11)
- Flipper-DoubleConversion (3.1.7)
- Flipper-Fmt (7.1.7)
- Flipper-Folly (2.6.7):
- Flipper-Boost-iOSX
- Flipper-DoubleConversion
- Flipper-Fmt (= 7.1.7)
- Flipper-Glog
- OpenSSL-Universal (= 1.0.2.20)
- libevent (~> 2.1.12)
- OpenSSL-Universal (= 1.1.180)
- Flipper-Glog (0.3.6)
- Flipper-PeerTalk (0.0.4)
- Flipper-RSocket (1.1.0):
- Flipper-Folly (~> 2.2)
- FlipperKit (0.54.0):
- FlipperKit/Core (= 0.54.0)
- FlipperKit/Core (0.54.0):
- Flipper (~> 0.54.0)
- Flipper-RSocket (1.4.3):
- Flipper-Folly (~> 2.6)
- FlipperKit (0.99.0):
- FlipperKit/Core (= 0.99.0)
- FlipperKit/Core (0.99.0):
- Flipper (~> 0.99.0)
- FlipperKit/CppBridge
- FlipperKit/FBCxxFollyDynamicConvert
- FlipperKit/FBDefines
- FlipperKit/FKPortForwarding
- FlipperKit/CppBridge (0.54.0):
- Flipper (~> 0.54.0)
- FlipperKit/FBCxxFollyDynamicConvert (0.54.0):
- Flipper-Folly (~> 2.2)
- FlipperKit/FBDefines (0.54.0)
- FlipperKit/FKPortForwarding (0.54.0):
- FlipperKit/CppBridge (0.99.0):
- Flipper (~> 0.99.0)
- FlipperKit/FBCxxFollyDynamicConvert (0.99.0):
- Flipper-Folly (~> 2.6)
- FlipperKit/FBDefines (0.99.0)
- FlipperKit/FKPortForwarding (0.99.0):
- CocoaAsyncSocket (~> 7.6)
- Flipper-PeerTalk (~> 0.0.4)
- FlipperKit/FlipperKitHighlightOverlay (0.54.0)
- FlipperKit/FlipperKitLayoutPlugin (0.54.0):
- FlipperKit/FlipperKitHighlightOverlay (0.99.0)
- FlipperKit/FlipperKitLayoutHelpers (0.99.0):
- FlipperKit/Core
- FlipperKit/FlipperKitHighlightOverlay
- FlipperKit/FlipperKitLayoutTextSearchable
- FlipperKit/FlipperKitLayoutIOSDescriptors (0.99.0):
- FlipperKit/Core
- FlipperKit/FlipperKitHighlightOverlay
- FlipperKit/FlipperKitLayoutHelpers
- YogaKit (~> 1.18)
- FlipperKit/FlipperKitLayoutTextSearchable (0.54.0)
- FlipperKit/FlipperKitNetworkPlugin (0.54.0):
- FlipperKit/FlipperKitLayoutPlugin (0.99.0):
- FlipperKit/Core
- FlipperKit/FlipperKitReactPlugin (0.54.0):
- FlipperKit/FlipperKitHighlightOverlay
- FlipperKit/FlipperKitLayoutHelpers
- FlipperKit/FlipperKitLayoutIOSDescriptors
- FlipperKit/FlipperKitLayoutTextSearchable
- YogaKit (~> 1.18)
- FlipperKit/FlipperKitLayoutTextSearchable (0.99.0)
- FlipperKit/FlipperKitNetworkPlugin (0.99.0):
- FlipperKit/Core
- FlipperKit/FlipperKitUserDefaultsPlugin (0.54.0):
- FlipperKit/FlipperKitReactPlugin (0.99.0):
- FlipperKit/Core
- FlipperKit/SKIOSNetworkPlugin (0.54.0):
- FlipperKit/FlipperKitUserDefaultsPlugin (0.99.0):
- FlipperKit/Core
- FlipperKit/SKIOSNetworkPlugin (0.99.0):
- FlipperKit/Core
- FlipperKit/FlipperKitNetworkPlugin
- Folly (2020.01.13.00):
- boost-for-react-native
- DoubleConversion
- Folly/Default (= 2020.01.13.00)
- glog
- Folly/Default (2020.01.13.00):
- boost-for-react-native
- DoubleConversion
- glog
- fmt (6.2.1)
- glog (0.3.5)
- libwebp (1.1.0):
- libwebp/demux (= 1.1.0)
- libwebp/mux (= 1.1.0)
- libwebp/webp (= 1.1.0)
- libwebp/demux (1.1.0):
- libevent (2.1.12)
- libwebp (1.2.1):
- libwebp/demux (= 1.2.1)
- libwebp/mux (= 1.2.1)
- libwebp/webp (= 1.2.1)
- libwebp/demux (1.2.1):
- libwebp/webp
- libwebp/mux (1.1.0):
- libwebp/mux (1.2.1):
- libwebp/demux
- libwebp/webp (1.1.0)
- OpenSSL-Universal (1.0.2.20):
- OpenSSL-Universal/Static (= 1.0.2.20)
- OpenSSL-Universal/Static (1.0.2.20)
- RCTRequired (0.63.4)
- RCTTypeSafety (0.63.4):
- FBLazyVector (= 0.63.4)
- Folly (= 2020.01.13.00)
- RCTRequired (= 0.63.4)
- React-Core (= 0.63.4)
- React (0.63.4):
- React-Core (= 0.63.4)
- React-Core/DevSupport (= 0.63.4)
- React-Core/RCTWebSocket (= 0.63.4)
- React-RCTActionSheet (= 0.63.4)
- React-RCTAnimation (= 0.63.4)
- React-RCTBlob (= 0.63.4)
- React-RCTImage (= 0.63.4)
- React-RCTLinking (= 0.63.4)
- React-RCTNetwork (= 0.63.4)
- React-RCTSettings (= 0.63.4)
- React-RCTText (= 0.63.4)
- React-RCTVibration (= 0.63.4)
- React-callinvoker (0.63.4)
- React-Core (0.63.4):
- Folly (= 2020.01.13.00)
- glog
- React-Core/Default (= 0.63.4)
- React-cxxreact (= 0.63.4)
- React-jsi (= 0.63.4)
- React-jsiexecutor (= 0.63.4)
- Yoga
- React-Core/CoreModulesHeaders (0.63.4):
- Folly (= 2020.01.13.00)
- glog
- React-Core/Default
- React-cxxreact (= 0.63.4)
- React-jsi (= 0.63.4)
- React-jsiexecutor (= 0.63.4)
- Yoga
- React-Core/Default (0.63.4):
- Folly (= 2020.01.13.00)
- glog
- React-cxxreact (= 0.63.4)
- React-jsi (= 0.63.4)
- React-jsiexecutor (= 0.63.4)
- Yoga
- React-Core/DevSupport (0.63.4):
- Folly (= 2020.01.13.00)
- glog
- React-Core/Default (= 0.63.4)
- React-Core/RCTWebSocket (= 0.63.4)
- React-cxxreact (= 0.63.4)
- React-jsi (= 0.63.4)
- React-jsiexecutor (= 0.63.4)
- React-jsinspector (= 0.63.4)
- Yoga
- React-Core/RCTActionSheetHeaders (0.63.4):
- Folly (= 2020.01.13.00)
- glog
- React-Core/Default
- React-cxxreact (= 0.63.4)
- React-jsi (= 0.63.4)
- React-jsiexecutor (= 0.63.4)
- Yoga
- React-Core/RCTAnimationHeaders (0.63.4):
- Folly (= 2020.01.13.00)
- glog
- React-Core/Default
- React-cxxreact (= 0.63.4)
- React-jsi (= 0.63.4)
- React-jsiexecutor (= 0.63.4)
- Yoga
- React-Core/RCTBlobHeaders (0.63.4):
- Folly (= 2020.01.13.00)
- glog
- React-Core/Default
- React-cxxreact (= 0.63.4)
- React-jsi (= 0.63.4)
- React-jsiexecutor (= 0.63.4)
- Yoga
- React-Core/RCTImageHeaders (0.63.4):
- Folly (= 2020.01.13.00)
- glog
- React-Core/Default
- React-cxxreact (= 0.63.4)
- React-jsi (= 0.63.4)
- React-jsiexecutor (= 0.63.4)
- Yoga
- React-Core/RCTLinkingHeaders (0.63.4):
- Folly (= 2020.01.13.00)
- glog
- React-Core/Default
- React-cxxreact (= 0.63.4)
- React-jsi (= 0.63.4)
- React-jsiexecutor (= 0.63.4)
- Yoga
- React-Core/RCTNetworkHeaders (0.63.4):
- Folly (= 2020.01.13.00)
- glog
- React-Core/Default
- React-cxxreact (= 0.63.4)
- React-jsi (= 0.63.4)
- React-jsiexecutor (= 0.63.4)
- Yoga
- React-Core/RCTSettingsHeaders (0.63.4):
- Folly (= 2020.01.13.00)
- glog
- React-Core/Default
- React-cxxreact (= 0.63.4)
- React-jsi (= 0.63.4)
- React-jsiexecutor (= 0.63.4)
- Yoga
- React-Core/RCTTextHeaders (0.63.4):
- Folly (= 2020.01.13.00)
- glog
- React-Core/Default
- React-cxxreact (= 0.63.4)
- React-jsi (= 0.63.4)
- React-jsiexecutor (= 0.63.4)
- Yoga
- React-Core/RCTVibrationHeaders (0.63.4):
- Folly (= 2020.01.13.00)
- glog
- React-Core/Default
- React-cxxreact (= 0.63.4)
- React-jsi (= 0.63.4)
- React-jsiexecutor (= 0.63.4)
- Yoga
- React-Core/RCTWebSocket (0.63.4):
- Folly (= 2020.01.13.00)
- glog
- React-Core/Default (= 0.63.4)
- React-cxxreact (= 0.63.4)
- React-jsi (= 0.63.4)
- React-jsiexecutor (= 0.63.4)
- Yoga
- React-CoreModules (0.63.4):
- FBReactNativeSpec (= 0.63.4)
- Folly (= 2020.01.13.00)
- RCTTypeSafety (= 0.63.4)
- React-Core/CoreModulesHeaders (= 0.63.4)
- React-jsi (= 0.63.4)
- React-RCTImage (= 0.63.4)
- ReactCommon/turbomodule/core (= 0.63.4)
- React-cxxreact (0.63.4):
- boost-for-react-native (= 1.63.0)
- libwebp/webp (1.2.1)
- OpenSSL-Universal (1.1.180)
- RCT-Folly (2021.06.28.00-v2):
- boost
- DoubleConversion
- Folly (= 2020.01.13.00)
- fmt (~> 6.2.1)
- glog
- React-callinvoker (= 0.63.4)
- React-jsinspector (= 0.63.4)
- React-jsi (0.63.4):
- boost-for-react-native (= 1.63.0)
- RCT-Folly/Default (= 2021.06.28.00-v2)
- RCT-Folly/Default (2021.06.28.00-v2):
- boost
- DoubleConversion
- Folly (= 2020.01.13.00)
- fmt (~> 6.2.1)
- glog
- React-jsi/Default (= 0.63.4)
- React-jsi/Default (0.63.4):
- boost-for-react-native (= 1.63.0)
- RCTRequired (0.66.1)
- RCTTypeSafety (0.66.1):
- FBLazyVector (= 0.66.1)
- RCT-Folly (= 2021.06.28.00-v2)
- RCTRequired (= 0.66.1)
- React-Core (= 0.66.1)
- React (0.66.1):
- React-Core (= 0.66.1)
- React-Core/DevSupport (= 0.66.1)
- React-Core/RCTWebSocket (= 0.66.1)
- React-RCTActionSheet (= 0.66.1)
- React-RCTAnimation (= 0.66.1)
- React-RCTBlob (= 0.66.1)
- React-RCTImage (= 0.66.1)
- React-RCTLinking (= 0.66.1)
- React-RCTNetwork (= 0.66.1)
- React-RCTSettings (= 0.66.1)
- React-RCTText (= 0.66.1)
- React-RCTVibration (= 0.66.1)
- React-callinvoker (0.66.1)
- React-Core (0.66.1):
- glog
- RCT-Folly (= 2021.06.28.00-v2)
- React-Core/Default (= 0.66.1)
- React-cxxreact (= 0.66.1)
- React-jsi (= 0.66.1)
- React-jsiexecutor (= 0.66.1)
- React-perflogger (= 0.66.1)
- Yoga
- React-Core/CoreModulesHeaders (0.66.1):
- glog
- RCT-Folly (= 2021.06.28.00-v2)
- React-Core/Default
- React-cxxreact (= 0.66.1)
- React-jsi (= 0.66.1)
- React-jsiexecutor (= 0.66.1)
- React-perflogger (= 0.66.1)
- Yoga
- React-Core/Default (0.66.1):
- glog
- RCT-Folly (= 2021.06.28.00-v2)
- React-cxxreact (= 0.66.1)
- React-jsi (= 0.66.1)
- React-jsiexecutor (= 0.66.1)
- React-perflogger (= 0.66.1)
- Yoga
- React-Core/DevSupport (0.66.1):
- glog
- RCT-Folly (= 2021.06.28.00-v2)
- React-Core/Default (= 0.66.1)
- React-Core/RCTWebSocket (= 0.66.1)
- React-cxxreact (= 0.66.1)
- React-jsi (= 0.66.1)
- React-jsiexecutor (= 0.66.1)
- React-jsinspector (= 0.66.1)
- React-perflogger (= 0.66.1)
- Yoga
- React-Core/RCTActionSheetHeaders (0.66.1):
- glog
- RCT-Folly (= 2021.06.28.00-v2)
- React-Core/Default
- React-cxxreact (= 0.66.1)
- React-jsi (= 0.66.1)
- React-jsiexecutor (= 0.66.1)
- React-perflogger (= 0.66.1)
- Yoga
- React-Core/RCTAnimationHeaders (0.66.1):
- glog
- RCT-Folly (= 2021.06.28.00-v2)
- React-Core/Default
- React-cxxreact (= 0.66.1)
- React-jsi (= 0.66.1)
- React-jsiexecutor (= 0.66.1)
- React-perflogger (= 0.66.1)
- Yoga
- React-Core/RCTBlobHeaders (0.66.1):
- glog
- RCT-Folly (= 2021.06.28.00-v2)
- React-Core/Default
- React-cxxreact (= 0.66.1)
- React-jsi (= 0.66.1)
- React-jsiexecutor (= 0.66.1)
- React-perflogger (= 0.66.1)
- Yoga
- React-Core/RCTImageHeaders (0.66.1):
- glog
- RCT-Folly (= 2021.06.28.00-v2)
- React-Core/Default
- React-cxxreact (= 0.66.1)
- React-jsi (= 0.66.1)
- React-jsiexecutor (= 0.66.1)
- React-perflogger (= 0.66.1)
- Yoga
- React-Core/RCTLinkingHeaders (0.66.1):
- glog
- RCT-Folly (= 2021.06.28.00-v2)
- React-Core/Default
- React-cxxreact (= 0.66.1)
- React-jsi (= 0.66.1)
- React-jsiexecutor (= 0.66.1)
- React-perflogger (= 0.66.1)
- Yoga
- React-Core/RCTNetworkHeaders (0.66.1):
- glog
- RCT-Folly (= 2021.06.28.00-v2)
- React-Core/Default
- React-cxxreact (= 0.66.1)
- React-jsi (= 0.66.1)
- React-jsiexecutor (= 0.66.1)
- React-perflogger (= 0.66.1)
- Yoga
- React-Core/RCTSettingsHeaders (0.66.1):
- glog
- RCT-Folly (= 2021.06.28.00-v2)
- React-Core/Default
- React-cxxreact (= 0.66.1)
- React-jsi (= 0.66.1)
- React-jsiexecutor (= 0.66.1)
- React-perflogger (= 0.66.1)
- Yoga
- React-Core/RCTTextHeaders (0.66.1):
- glog
- RCT-Folly (= 2021.06.28.00-v2)
- React-Core/Default
- React-cxxreact (= 0.66.1)
- React-jsi (= 0.66.1)
- React-jsiexecutor (= 0.66.1)
- React-perflogger (= 0.66.1)
- Yoga
- React-Core/RCTVibrationHeaders (0.66.1):
- glog
- RCT-Folly (= 2021.06.28.00-v2)
- React-Core/Default
- React-cxxreact (= 0.66.1)
- React-jsi (= 0.66.1)
- React-jsiexecutor (= 0.66.1)
- React-perflogger (= 0.66.1)
- Yoga
- React-Core/RCTWebSocket (0.66.1):
- glog
- RCT-Folly (= 2021.06.28.00-v2)
- React-Core/Default (= 0.66.1)
- React-cxxreact (= 0.66.1)
- React-jsi (= 0.66.1)
- React-jsiexecutor (= 0.66.1)
- React-perflogger (= 0.66.1)
- Yoga
- React-CoreModules (0.66.1):
- FBReactNativeSpec (= 0.66.1)
- RCT-Folly (= 2021.06.28.00-v2)
- RCTTypeSafety (= 0.66.1)
- React-Core/CoreModulesHeaders (= 0.66.1)
- React-jsi (= 0.66.1)
- React-RCTImage (= 0.66.1)
- ReactCommon/turbomodule/core (= 0.66.1)
- React-cxxreact (0.66.1):
- boost (= 1.76.0)
- DoubleConversion
- Folly (= 2020.01.13.00)
- glog
- React-jsiexecutor (0.63.4):
- RCT-Folly (= 2021.06.28.00-v2)
- React-callinvoker (= 0.66.1)
- React-jsi (= 0.66.1)
- React-jsinspector (= 0.66.1)
- React-logger (= 0.66.1)
- React-perflogger (= 0.66.1)
- React-runtimeexecutor (= 0.66.1)
- React-jsi (0.66.1):
- boost (= 1.76.0)
- DoubleConversion
- Folly (= 2020.01.13.00)
- glog
- React-cxxreact (= 0.63.4)
- React-jsi (= 0.63.4)
- React-jsinspector (0.63.4)
- react-native-safe-area-context (3.1.9):
- RCT-Folly (= 2021.06.28.00-v2)
- React-jsi/Default (= 0.66.1)
- React-jsi/Default (0.66.1):
- boost (= 1.76.0)
- DoubleConversion
- glog
- RCT-Folly (= 2021.06.28.00-v2)
- React-jsiexecutor (0.66.1):
- DoubleConversion
- glog
- RCT-Folly (= 2021.06.28.00-v2)
- React-cxxreact (= 0.66.1)
- React-jsi (= 0.66.1)
- React-perflogger (= 0.66.1)
- React-jsinspector (0.66.1)
- React-logger (0.66.1):
- glog
- react-native-airplay-button (1.1.0):
- React-Core
- react-native-safe-area-context (3.3.2):
- React-Core
- react-native-slider (3.0.3):
- React
- react-native-track-player (1.2.3):
- React
- react-native-webview (11.2.3):
- react-native-track-player (1.2.7):
- React-Core
- React-RCTActionSheet (0.63.4):
- React-Core/RCTActionSheetHeaders (= 0.63.4)
- React-RCTAnimation (0.63.4):
- FBReactNativeSpec (= 0.63.4)
- Folly (= 2020.01.13.00)
- RCTTypeSafety (= 0.63.4)
- React-Core/RCTAnimationHeaders (= 0.63.4)
- React-jsi (= 0.63.4)
- ReactCommon/turbomodule/core (= 0.63.4)
- React-RCTBlob (0.63.4):
- FBReactNativeSpec (= 0.63.4)
- Folly (= 2020.01.13.00)
- React-Core/RCTBlobHeaders (= 0.63.4)
- React-Core/RCTWebSocket (= 0.63.4)
- React-jsi (= 0.63.4)
- React-RCTNetwork (= 0.63.4)
- ReactCommon/turbomodule/core (= 0.63.4)
- React-RCTImage (0.63.4):
- FBReactNativeSpec (= 0.63.4)
- Folly (= 2020.01.13.00)
- RCTTypeSafety (= 0.63.4)
- React-Core/RCTImageHeaders (= 0.63.4)
- React-jsi (= 0.63.4)
- React-RCTNetwork (= 0.63.4)
- ReactCommon/turbomodule/core (= 0.63.4)
- React-RCTLinking (0.63.4):
- FBReactNativeSpec (= 0.63.4)
- React-Core/RCTLinkingHeaders (= 0.63.4)
- React-jsi (= 0.63.4)
- ReactCommon/turbomodule/core (= 0.63.4)
- React-RCTNetwork (0.63.4):
- FBReactNativeSpec (= 0.63.4)
- Folly (= 2020.01.13.00)
- RCTTypeSafety (= 0.63.4)
- React-Core/RCTNetworkHeaders (= 0.63.4)
- React-jsi (= 0.63.4)
- ReactCommon/turbomodule/core (= 0.63.4)
- React-RCTSettings (0.63.4):
- FBReactNativeSpec (= 0.63.4)
- Folly (= 2020.01.13.00)
- RCTTypeSafety (= 0.63.4)
- React-Core/RCTSettingsHeaders (= 0.63.4)
- React-jsi (= 0.63.4)
- ReactCommon/turbomodule/core (= 0.63.4)
- React-RCTText (0.63.4):
- React-Core/RCTTextHeaders (= 0.63.4)
- React-RCTVibration (0.63.4):
- FBReactNativeSpec (= 0.63.4)
- Folly (= 2020.01.13.00)
- React-Core/RCTVibrationHeaders (= 0.63.4)
- React-jsi (= 0.63.4)
- ReactCommon/turbomodule/core (= 0.63.4)
- ReactCommon/turbomodule/core (0.63.4):
- react-native-webview (11.14.1):
- React-Core
- React-perflogger (0.66.1)
- React-RCTActionSheet (0.66.1):
- React-Core/RCTActionSheetHeaders (= 0.66.1)
- React-RCTAnimation (0.66.1):
- FBReactNativeSpec (= 0.66.1)
- RCT-Folly (= 2021.06.28.00-v2)
- RCTTypeSafety (= 0.66.1)
- React-Core/RCTAnimationHeaders (= 0.66.1)
- React-jsi (= 0.66.1)
- ReactCommon/turbomodule/core (= 0.66.1)
- React-RCTBlob (0.66.1):
- FBReactNativeSpec (= 0.66.1)
- RCT-Folly (= 2021.06.28.00-v2)
- React-Core/RCTBlobHeaders (= 0.66.1)
- React-Core/RCTWebSocket (= 0.66.1)
- React-jsi (= 0.66.1)
- React-RCTNetwork (= 0.66.1)
- ReactCommon/turbomodule/core (= 0.66.1)
- React-RCTImage (0.66.1):
- FBReactNativeSpec (= 0.66.1)
- RCT-Folly (= 2021.06.28.00-v2)
- RCTTypeSafety (= 0.66.1)
- React-Core/RCTImageHeaders (= 0.66.1)
- React-jsi (= 0.66.1)
- React-RCTNetwork (= 0.66.1)
- ReactCommon/turbomodule/core (= 0.66.1)
- React-RCTLinking (0.66.1):
- FBReactNativeSpec (= 0.66.1)
- React-Core/RCTLinkingHeaders (= 0.66.1)
- React-jsi (= 0.66.1)
- ReactCommon/turbomodule/core (= 0.66.1)
- React-RCTNetwork (0.66.1):
- FBReactNativeSpec (= 0.66.1)
- RCT-Folly (= 2021.06.28.00-v2)
- RCTTypeSafety (= 0.66.1)
- React-Core/RCTNetworkHeaders (= 0.66.1)
- React-jsi (= 0.66.1)
- ReactCommon/turbomodule/core (= 0.66.1)
- React-RCTSettings (0.66.1):
- FBReactNativeSpec (= 0.66.1)
- RCT-Folly (= 2021.06.28.00-v2)
- RCTTypeSafety (= 0.66.1)
- React-Core/RCTSettingsHeaders (= 0.66.1)
- React-jsi (= 0.66.1)
- ReactCommon/turbomodule/core (= 0.66.1)
- React-RCTText (0.66.1):
- React-Core/RCTTextHeaders (= 0.66.1)
- React-RCTVibration (0.66.1):
- FBReactNativeSpec (= 0.66.1)
- RCT-Folly (= 2021.06.28.00-v2)
- React-Core/RCTVibrationHeaders (= 0.66.1)
- React-jsi (= 0.66.1)
- ReactCommon/turbomodule/core (= 0.66.1)
- React-runtimeexecutor (0.66.1):
- React-jsi (= 0.66.1)
- ReactCommon/turbomodule/core (0.66.1):
- DoubleConversion
- Folly (= 2020.01.13.00)
- glog
- React-callinvoker (= 0.63.4)
- React-Core (= 0.63.4)
- React-cxxreact (= 0.63.4)
- React-jsi (= 0.63.4)
- RCT-Folly (= 2021.06.28.00-v2)
- React-callinvoker (= 0.66.1)
- React-Core (= 0.66.1)
- React-cxxreact (= 0.66.1)
- React-jsi (= 0.66.1)
- React-logger (= 0.66.1)
- React-perflogger (= 0.66.1)
- RNCAsyncStorage (1.12.1):
- React-Core
- RNCMaskedView (0.1.10):
- RNCMaskedView (0.1.11):
- React
- RNCPicker (1.8.1):
- React-Core
- RNFastImage (8.3.4):
- RNFastImage (8.5.11):
- React-Core
- SDWebImage (~> 5.8)
- SDWebImageWebPCoder (~> 0.6.1)
- RNGestureHandler (1.10.0):
- SDWebImage (~> 5.11.1)
- SDWebImageWebPCoder (~> 0.8.4)
- RNGestureHandler (1.10.3):
- React-Core
- RNLocalize (2.0.1):
- RNLocalize (2.1.5):
- React-Core
- RNReanimated (1.13.2):
- React-Core
- RNScreens (2.17.1):
- React-Core
- RNSentry (2.2.0):
- React-Core
- Sentry (= 6.1.4)
- RNSVG (12.1.0):
- RNReanimated (2.2.3):
- DoubleConversion
- FBLazyVector
- FBReactNativeSpec
- glog
- RCT-Folly
- RCTRequired
- RCTTypeSafety
- React
- SDWebImage (5.10.4):
- SDWebImage/Core (= 5.10.4)
- SDWebImage/Core (5.10.4)
- SDWebImageWebPCoder (0.6.1):
- React-callinvoker
- React-Core
- React-Core/DevSupport
- React-Core/RCTWebSocket
- React-CoreModules
- React-cxxreact
- React-jsi
- React-jsiexecutor
- React-jsinspector
- React-RCTActionSheet
- React-RCTAnimation
- React-RCTBlob
- React-RCTImage
- React-RCTLinking
- React-RCTNetwork
- React-RCTSettings
- React-RCTText
- React-RCTVibration
- ReactCommon/turbomodule/core
- Yoga
- RNScreens (3.8.0):
- React-Core
- React-RCTImage
- RNSentry (2.6.2):
- React-Core
- Sentry (= 7.1.4)
- RNSVG (12.2.0):
- React-Core
- SDWebImage (5.11.1):
- SDWebImage/Core (= 5.11.1)
- SDWebImage/Core (5.11.1)
- SDWebImageWebPCoder (0.8.4):
- libwebp (~> 1.0)
- SDWebImage/Core (~> 5.7)
- Sentry (6.1.4):
- Sentry/Core (= 6.1.4)
- Sentry/Core (6.1.4)
- SDWebImage/Core (~> 5.10)
- Sentry (7.1.4):
- Sentry/Core (= 7.1.4)
- Sentry/Core (7.1.4)
- Yoga (1.14.0)
- YogaKit (1.18.1):
- Yoga (~> 1.14)
DEPENDENCIES:
- boost (from `../node_modules/react-native/third-party-podspecs/boost.podspec`)
- DoubleConversion (from `../node_modules/react-native/third-party-podspecs/DoubleConversion.podspec`)
- FBLazyVector (from `../node_modules/react-native/Libraries/FBLazyVector`)
- FBReactNativeSpec (from `../node_modules/react-native/Libraries/FBReactNativeSpec`)
- Flipper (~> 0.54.0)
- Flipper-DoubleConversion (= 1.1.7)
- Flipper-Folly (~> 2.2)
- FBReactNativeSpec (from `../node_modules/react-native/React/FBReactNativeSpec`)
- Flipper (= 0.99.0)
- Flipper-Boost-iOSX (= 1.76.0.1.11)
- Flipper-DoubleConversion (= 3.1.7)
- Flipper-Fmt (= 7.1.7)
- Flipper-Folly (= 2.6.7)
- Flipper-Glog (= 0.3.6)
- Flipper-PeerTalk (~> 0.0.4)
- Flipper-RSocket (~> 1.1)
- FlipperKit (~> 0.54.0)
- FlipperKit/Core (~> 0.54.0)
- FlipperKit/CppBridge (~> 0.54.0)
- FlipperKit/FBCxxFollyDynamicConvert (~> 0.54.0)
- FlipperKit/FBDefines (~> 0.54.0)
- FlipperKit/FKPortForwarding (~> 0.54.0)
- FlipperKit/FlipperKitHighlightOverlay (~> 0.54.0)
- FlipperKit/FlipperKitLayoutPlugin (~> 0.54.0)
- FlipperKit/FlipperKitLayoutTextSearchable (~> 0.54.0)
- FlipperKit/FlipperKitNetworkPlugin (~> 0.54.0)
- FlipperKit/FlipperKitReactPlugin (~> 0.54.0)
- FlipperKit/FlipperKitUserDefaultsPlugin (~> 0.54.0)
- FlipperKit/SKIOSNetworkPlugin (~> 0.54.0)
- Folly (from `../node_modules/react-native/third-party-podspecs/Folly.podspec`)
- Flipper-PeerTalk (= 0.0.4)
- Flipper-RSocket (= 1.4.3)
- FlipperKit (= 0.99.0)
- FlipperKit/Core (= 0.99.0)
- FlipperKit/CppBridge (= 0.99.0)
- FlipperKit/FBCxxFollyDynamicConvert (= 0.99.0)
- FlipperKit/FBDefines (= 0.99.0)
- FlipperKit/FKPortForwarding (= 0.99.0)
- FlipperKit/FlipperKitHighlightOverlay (= 0.99.0)
- FlipperKit/FlipperKitLayoutPlugin (= 0.99.0)
- FlipperKit/FlipperKitLayoutTextSearchable (= 0.99.0)
- FlipperKit/FlipperKitNetworkPlugin (= 0.99.0)
- FlipperKit/FlipperKitReactPlugin (= 0.99.0)
- FlipperKit/FlipperKitUserDefaultsPlugin (= 0.99.0)
- FlipperKit/SKIOSNetworkPlugin (= 0.99.0)
- glog (from `../node_modules/react-native/third-party-podspecs/glog.podspec`)
- RCT-Folly (from `../node_modules/react-native/third-party-podspecs/RCT-Folly.podspec`)
- RCTRequired (from `../node_modules/react-native/Libraries/RCTRequired`)
- RCTTypeSafety (from `../node_modules/react-native/Libraries/TypeSafety`)
- React (from `../node_modules/react-native/`)
@@ -386,10 +460,13 @@ DEPENDENCIES:
- React-jsi (from `../node_modules/react-native/ReactCommon/jsi`)
- React-jsiexecutor (from `../node_modules/react-native/ReactCommon/jsiexecutor`)
- React-jsinspector (from `../node_modules/react-native/ReactCommon/jsinspector`)
- React-logger (from `../node_modules/react-native/ReactCommon/logger`)
- 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-slider (from `../node_modules/@react-native-community/slider`)"
- react-native-track-player (from `../node_modules/react-native-track-player`)
- react-native-webview (from `../node_modules/react-native-webview`)
- React-perflogger (from `../node_modules/react-native/ReactCommon/reactperflogger`)
- React-RCTActionSheet (from `../node_modules/react-native/Libraries/ActionSheetIOS`)
- React-RCTAnimation (from `../node_modules/react-native/Libraries/NativeAnimation`)
- React-RCTBlob (from `../node_modules/react-native/Libraries/Blob`)
@@ -399,6 +476,7 @@ DEPENDENCIES:
- React-RCTSettings (from `../node_modules/react-native/Libraries/Settings`)
- React-RCTText (from `../node_modules/react-native/Libraries/Text`)
- React-RCTVibration (from `../node_modules/react-native/Libraries/Vibration`)
- React-runtimeexecutor (from `../node_modules/react-native/ReactCommon/runtimeexecutor`)
- ReactCommon/turbomodule/core (from `../node_modules/react-native/ReactCommon`)
- "RNCAsyncStorage (from `../node_modules/@react-native-community/async-storage`)"
- "RNCMaskedView (from `../node_modules/@react-native-community/masked-view`)"
@@ -414,16 +492,18 @@ DEPENDENCIES:
SPEC REPOS:
trunk:
- boost-for-react-native
- CocoaAsyncSocket
- CocoaLibEvent
- Flipper
- Flipper-Boost-iOSX
- Flipper-DoubleConversion
- Flipper-Fmt
- Flipper-Folly
- Flipper-Glog
- Flipper-PeerTalk
- Flipper-RSocket
- FlipperKit
- fmt
- libevent
- libwebp
- OpenSSL-Universal
- SDWebImage
@@ -432,16 +512,18 @@ SPEC REPOS:
- YogaKit
EXTERNAL SOURCES:
boost:
:podspec: "../node_modules/react-native/third-party-podspecs/boost.podspec"
DoubleConversion:
:podspec: "../node_modules/react-native/third-party-podspecs/DoubleConversion.podspec"
FBLazyVector:
:path: "../node_modules/react-native/Libraries/FBLazyVector"
FBReactNativeSpec:
:path: "../node_modules/react-native/Libraries/FBReactNativeSpec"
Folly:
:podspec: "../node_modules/react-native/third-party-podspecs/Folly.podspec"
:path: "../node_modules/react-native/React/FBReactNativeSpec"
glog:
:podspec: "../node_modules/react-native/third-party-podspecs/glog.podspec"
RCT-Folly:
:podspec: "../node_modules/react-native/third-party-podspecs/RCT-Folly.podspec"
RCTRequired:
:path: "../node_modules/react-native/Libraries/RCTRequired"
RCTTypeSafety:
@@ -462,6 +544,10 @@ EXTERNAL SOURCES:
:path: "../node_modules/react-native/ReactCommon/jsiexecutor"
React-jsinspector:
:path: "../node_modules/react-native/ReactCommon/jsinspector"
React-logger:
:path: "../node_modules/react-native/ReactCommon/logger"
react-native-airplay-button:
:path: "../node_modules/react-native-airplay-button"
react-native-safe-area-context:
:path: "../node_modules/react-native-safe-area-context"
react-native-slider:
@@ -470,6 +556,8 @@ EXTERNAL SOURCES:
:path: "../node_modules/react-native-track-player"
react-native-webview:
:path: "../node_modules/react-native-webview"
React-perflogger:
:path: "../node_modules/react-native/ReactCommon/reactperflogger"
React-RCTActionSheet:
:path: "../node_modules/react-native/Libraries/ActionSheetIOS"
React-RCTAnimation:
@@ -488,6 +576,8 @@ EXTERNAL SOURCES:
:path: "../node_modules/react-native/Libraries/Text"
React-RCTVibration:
:path: "../node_modules/react-native/Libraries/Vibration"
React-runtimeexecutor:
:path: "../node_modules/react-native/ReactCommon/runtimeexecutor"
ReactCommon:
:path: "../node_modules/react-native/ReactCommon"
RNCAsyncStorage:
@@ -514,63 +604,70 @@ EXTERNAL SOURCES:
:path: "../node_modules/react-native/ReactCommon/yoga"
SPEC CHECKSUMS:
boost-for-react-native: 39c7adb57c4e60d6c5479dd8623128eb5b3f0f2c
CocoaAsyncSocket: 694058e7c0ed05a9e217d1b3c7ded962f4180845
CocoaLibEvent: 2fab71b8bd46dd33ddb959f7928ec5909f838e3f
DoubleConversion: cde416483dac037923206447da6e1454df403714
FBLazyVector: 3bb422f41b18121b71783a905c10e58606f7dc3e
FBReactNativeSpec: f2c97f2529dd79c083355182cc158c9f98f4bd6e
Flipper: be611d4b742d8c87fbae2ca5f44603a02539e365
Flipper-DoubleConversion: 38631e41ef4f9b12861c67d17cb5518d06badc41
Flipper-Folly: e4493b013c02d9347d5e0cb4d128680239f6c78a
boost: a7c83b31436843459a1961bfd74b96033dc77234
CocoaAsyncSocket: 065fd1e645c7abab64f7a6a2007a48038fdc6a99
DoubleConversion: 831926d9b8bf8166fd87886c4abab286c2422662
FBLazyVector: 500821d196c3d1bd10e7e828bc93ce075234080f
FBReactNativeSpec: 74c869e2cffa2ffec685cd1bac6788c021da6005
Flipper: 30e8eeeed6abdc98edaf32af0cda2f198be4b733
Flipper-Boost-iOSX: fd1e2b8cbef7e662a122412d7ac5f5bea715403c
Flipper-DoubleConversion: 57ffbe81ef95306cc9e69c4aa3aeeeeb58a6a28c
Flipper-Fmt: 60cbdd92fc254826e61d669a5d87ef7015396a9b
Flipper-Folly: 83af37379faa69497529e414bd43fbfc7cae259a
Flipper-Glog: 1dfd6abf1e922806c52ceb8701a3599a79a200a6
Flipper-PeerTalk: 116d8f857dc6ef55c7a5a75ea3ceaafe878aadc9
Flipper-RSocket: 64e7431a55835eb953b0bf984ef3b90ae9fdddd7
FlipperKit: ab353d41aea8aae2ea6daaf813e67496642f3d7d
Folly: b73c3869541e86821df3c387eb0af5f65addfab4
glog: 40a13f7840415b9a77023fbcae0f1e6f43192af3
libwebp: 946cb3063cea9236285f7e9a8505d806d30e07f3
OpenSSL-Universal: ff34003318d5e1163e9529b08470708e389ffcdd
RCTRequired: 082f10cd3f905d6c124597fd1c14f6f2655ff65e
RCTTypeSafety: 8c9c544ecbf20337d069e4ae7fd9a377aadf504b
React: b0a957a2c44da4113b0c4c9853d8387f8e64e615
React-callinvoker: c3f44dd3cb195b6aa46621fff95ded79d59043fe
React-Core: d3b2a1ac9a2c13c3bcde712d9281fc1c8a5b315b
React-CoreModules: 0581ff36cb797da0943d424f69e7098e43e9be60
React-cxxreact: c1480d4fda5720086c90df537ee7d285d4c57ac3
React-jsi: a0418934cf48f25b485631deb27c64dc40fb4c31
React-jsiexecutor: 93bd528844ad21dc07aab1c67cb10abae6df6949
React-jsinspector: 58aef7155bc9a9683f5b60b35eccea8722a4f53a
react-native-safe-area-context: b6e0e284002381d2ff29fa4fff42b4d8282e3c94
react-native-slider: e99fc201cefe81270fc9d81714a7a0f5e566b168
react-native-track-player: 6ff21d21eb70ecbd2a6bad29822ecf6c8609a3aa
react-native-webview: 6520e3e7b4933de76b95ef542c8d7115cf45b68e
React-RCTActionSheet: 89a0ca9f4a06c1f93c26067af074ccdce0f40336
React-RCTAnimation: 1bde3ecc0c104c55df246eda516e0deb03c4e49b
React-RCTBlob: a97d378b527740cc667e03ebfa183a75231ab0f0
React-RCTImage: c1b1f2d3f43a4a528c8946d6092384b5c880d2f0
React-RCTLinking: 35ae4ab9dc0410d1fcbdce4d7623194a27214fb2
React-RCTNetwork: 29ec2696f8d8cfff7331fac83d3e893c95ef43ae
React-RCTSettings: 60f0691bba2074ef394f95d4c2265ec284e0a46a
React-RCTText: 5c51df3f08cb9dedc6e790161195d12bac06101c
React-RCTVibration: ae4f914cfe8de7d4de95ae1ea6cc8f6315d73d9d
ReactCommon: 73d79c7039f473b76db6ff7c6b159c478acbbb3b
RNCAsyncStorage: b03032fdbdb725bea0bd9e5ec5a7272865ae7398
RNCMaskedView: 5a8ec07677aa885546a0d98da336457e2bea557f
Flipper-RSocket: d9d9ade67cbecf6ac10730304bf5607266dd2541
FlipperKit: d8d346844eca5d9120c17d441a2f38596e8ed2b9
fmt: ff9d55029c625d3757ed641535fd4a75fedc7ce9
glog: 5337263514dd6f09803962437687240c5dc39aa4
libevent: 4049cae6c81cdb3654a443be001fb9bdceff7913
libwebp: 98a37e597e40bfdb4c911fc98f2c53d0b12d05fc
OpenSSL-Universal: 1aa4f6a6ee7256b83db99ec1ccdaa80d10f9af9b
RCT-Folly: a21c126816d8025b547704b777a2ba552f3d9fa9
RCTRequired: 3cc065b52aa18db729268b9bd78a2feffb4d0f91
RCTTypeSafety: 3c4fc37d5dea452d2ef17324db5504ec2f05083a
React: 4a00720816c52a213424442954acb7e4b724804a
React-callinvoker: 911fc6570538f3bb5c61edf9dc907c1beb4355bf
React-Core: e134d3a5d7b2a1a731589be776e20dbb14868f27
React-CoreModules: 2f8588b2aa47e7fef27125c8eaaabda963b3ac62
React-cxxreact: 8f1382538cad0cc8b8eafca6d66268828e353bea
React-jsi: 9fe1854d2c0486216acebd5db3c38b4ccb23ca0b
React-jsiexecutor: db2f6e22a534d466fc0e34e622df47d9d20bab2f
React-jsinspector: 8c0517dee5e8c70cd6c3066f20213ff7ce54f176
React-logger: bfddd3418dc1d45b77b822958f3e31422e2c179b
react-native-airplay-button: 517a0248e8d8e744a42250f67bead5175a774ece
react-native-safe-area-context: 5cf05f49df9d17261e40e518481f2e334c6cd4b5
react-native-slider: b733e17fdd31186707146debf1f04b5d94aa1a93
react-native-track-player: 878d6c66e4ae3a69f6a534c57c6c34a42e9b033f
react-native-webview: 16054e7a26009b7d5944a18e19f450e26bd4c969
React-perflogger: fcac6090a80e3d967791b4c7f1b1a017f9d4a398
React-RCTActionSheet: caf5913d9f9e605f5467206cf9d1caa6d47d7ad6
React-RCTAnimation: 6539e3bf594f6a529cd861985ba6548286ae1ead
React-RCTBlob: 6e2e999d28b15fd03ed533f164ce33e0fcde571a
React-RCTImage: c6bbb10eedb6b840c4474f2108b864173b83de15
React-RCTLinking: 8fda9bb8fdb104e78110a903a9a77754318c7d11
React-RCTNetwork: 2b26daad93830501cf14aab03eac04e304f942d3
React-RCTSettings: 89c0dcee7adb706c749383596f57c1e882a27843
React-RCTText: 71734fce8e6cb854daeb4a5eec182c303ea58473
React-RCTVibration: 6600b5eed7c0fda4a433fa1198d1cb2690151791
React-runtimeexecutor: 33a949a51bec5f8a3c9e8d8092deb259600d761e
ReactCommon: 620442811dc6f707b4bf5e3b27d4f19c12d5a821
RNCAsyncStorage: cb9a623793918c6699586281f0b51cbc38f046f9
RNCMaskedView: f127cd9652acfa31b91dcff613e07ba18b774db6
RNCPicker: 914b557e20b3b8317b084aca9ff4b4edb95f61e4
RNFastImage: d4870d58f5936111c56218dbd7fcfc18e65b58ff
RNGestureHandler: 03f587ba19a7e2d9fe48fb9aa6e33ace5fd07dd5
RNLocalize: 41026b7c14878f1a1b381bc79f668f1fbf841adb
RNReanimated: e03f7425cb7a38dcf1b644d680d1bfc91c3337ad
RNScreens: b6c9607e6fe47c1b6e2f1910d2acd46dd7ecea3a
RNSentry: 6aeba1adc242fd22a6826acae92f430697b47a9c
RNSVG: ce9d996113475209013317e48b05c21ee988d42e
SDWebImage: c666b97e1fa9c64b4909816a903322018f0a9c84
SDWebImageWebPCoder: d0dac55073088d24b2ac1b191a71a8f8d0adac21
Sentry: 9d055e2de30a77685e86b219acf02e59b82091fc
Yoga: 4bd86afe9883422a7c4028c00e34790f560923d6
RNFastImage: 1f2cab428712a4baaf78d6169eaec7f622556dd7
RNGestureHandler: a479ebd5ed4221a810967000735517df0d2db211
RNLocalize: 13a971fd888f2933504a745983f781dc52feeab6
RNReanimated: b04ef2a4f0cb61b062bbcf033f84a9e470f4f60b
RNScreens: 6e1ea5787989f92b0671049b808aef64fa1ef98c
RNSentry: 68644ef607b780551cc555f084869764f2566652
RNSVG: 4ecc2e8f38b6ebe7889909570c26f3abe8059767
SDWebImage: a7f831e1a65eb5e285e3fb046a23fcfbf08e696d
SDWebImageWebPCoder: f93010f3f6c031e2f8fb3081ca4ee6966c539815
Sentry: 1d3eb1a25f8c5333c88dd5603904a6d461cd9fcf
Yoga: 2b4a01651f42a32f82e6cef3830a3ba48088237f
YogaKit: f782866e155069a2cca2517aafea43200b01fd5a
PODFILE CHECKSUM: d99c1202f98b3f7477b6a86c9226010b36143469
PODFILE CHECKSUM: 640720093b3030dd16ab5dd407cf5fd8c4f7f7c8
COCOAPODS: 1.10.1
COCOAPODS: 1.11.2

23198
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -1,6 +1,6 @@
{
"name": "JellyfinAudioPlayer",
"version": "0.0.1",
"version": "0.1.5",
"main": "src/index.js",
"private": true,
"scripts": {
@@ -13,61 +13,63 @@
},
"dependencies": {
"@react-native-community/async-storage": "^1.12.1",
"@react-native-community/masked-view": "^0.1.10",
"@react-native-community/masked-view": "^0.1.11",
"@react-native-community/picker": "^1.8.1",
"@react-native-community/slider": "^3.0.3",
"@react-navigation/bottom-tabs": "^5.11.7",
"@react-navigation/native": "^5.9.2",
"@react-navigation/stack": "^5.14.2",
"@reduxjs/toolkit": "^1.5.0",
"@sentry/react-native": "^2.2.0",
"@types/lodash": "^4.14.168",
"@types/redux-logger": "^3.0.8",
"@types/styled-components": "^5.1.7",
"date-fns": "^2.17.0",
"@react-navigation/bottom-tabs": "^5.11.15",
"@react-navigation/native": "^5.9.8",
"@react-navigation/stack": "^5.14.9",
"@reduxjs/toolkit": "^1.6.2",
"@sentry/react-native": "^2.6.2",
"@types/lodash": "^4.14.176",
"date-fns": "^2.25.0",
"fuse.js": "^6.4.6",
"i18n-js": "^3.8.0",
"lodash": "^4.17.20",
"react": "16.13.1",
"react-native": "^0.63.4",
"react-native-collapsible": "^1.5.3",
"react-native-dotenv": "^2.5.1",
"react-native-fast-image": "^8.3.4",
"react-native-gesture-handler": "^1.9.0",
"react-native-localize": "^2.0.1",
"react-native-reanimated": "^1.13.2",
"react-native-safe-area-context": "^3.1.9",
"react-native-screens": "^2.17.1",
"react-native-svg": "^12.1.0",
"lodash": "^4.17.21",
"react": "^17.0.2",
"react-native": "^0.66.1",
"react-native-airplay-button": "^1.1.0",
"react-native-collapsible": "^1.6.0",
"react-native-dotenv": "^2.6.2",
"react-native-fast-image": "^8.5.11",
"react-native-gesture-handler": "^1.10.3",
"react-native-localize": "^2.1.5",
"react-native-reanimated": "^2.2.3",
"react-native-safe-area-context": "^3.3.2",
"react-native-screens": "^3.8.0",
"react-native-svg": "^12.2.0",
"react-native-svg-transformer": "^0.14.3",
"react-native-track-player": "github:leinelissen/react-native-track-player",
"react-native-webview": "^11.2.1",
"react-redux": "^7.2.2",
"redux": "^4.0.5",
"react-native-track-player": "^1.2.7",
"react-native-webview": "^11.14.1",
"react-redux": "^7.2.6",
"redux": "^4.1.1",
"redux-logger": "^3.0.6",
"redux-persist": "^6.0.0",
"styled-components": "^5.2.1"
"styled-components": "^5.3.3"
},
"devDependencies": {
"@babel/core": "^7.8.4",
"@babel/runtime": "^7.8.4",
"@babel/core": "^7.15.8",
"@babel/runtime": "^7.15.4",
"@react-native-community/eslint-config": "^2.0.0",
"@types/i18n-js": "^3.8.0",
"@types/jest": "^26.0.20",
"@types/react-native": "^0.63.48",
"@types/react-redux": "^7.1.16",
"@types/react-test-renderer": "^17.0.0",
"@types/styled-components-react-native": "^5.1.1",
"@typescript-eslint/eslint-plugin": "^4.14.2",
"@typescript-eslint/parser": "^4.14.2",
"@sentry/cli": "^1.70.1",
"@types/i18n-js": "^3.8.2",
"@types/jest": "^26.0.24",
"@types/react-native": "^0.66.1",
"@types/react-redux": "^7.1.20",
"@types/react-test-renderer": "^17.0.1",
"@types/redux-logger": "^3.0.9",
"@types/styled-components": "^5.1.15",
"@types/styled-components-react-native": "^5.1.2",
"@typescript-eslint/eslint-plugin": "^4.33.0",
"@typescript-eslint/parser": "^4.33.0",
"babel-jest": "^26.6.3",
"babel-plugin-module-resolver": "^4.1.0",
"eslint": "^7.19.0",
"eslint": "^7.32.0",
"eslint-plugin-react-hooks": "^4.2.0",
"jest": "^26.6.3",
"metro-react-native-babel-preset": "^0.59.0",
"react-test-renderer": "^17.0.1",
"typescript": "^4.1.3"
"metro-react-native-babel-preset": "^0.66.2",
"react-test-renderer": "^17.0.2",
"typescript": "^4.4.4"
},
"jest": {
"preset": "react-native",

View File

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

View File

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

@@ -8,14 +8,21 @@ const localeGetters: Record<string, () => object> = {
fr: () => require('./lang/fr/locale.json'),
nl: () => require('./lang/nl/locale.json'),
es: () => require('./lang/es/locale.json'),
zh: () => require('./lang/zh/locale.json'),
ja: () => require('./lang/ja/locale.json'),
};
// Have RNLocalize pick the best locale from the languages on offer
const locale = findBestAvailableLanguage(Object.keys(localeGetters));
let locale = findBestAvailableLanguage(Object.keys(localeGetters));
// Check if the locale is correctly picked
if (!locale || !locale.languageTag) {
throw new Error('Invalid locale selected');
// Some users might not list English as a fallback language, and hence might not
// be assigned a locale. In this case, we'll just default to English.
locale = {
languageTag: 'en',
isRTL: false,
};
}
// Set the key-value pairs for the different languages you want to support.

View File

@@ -38,5 +38,6 @@
"enable-error-reporting-description": "This helps improve the app experience by sending crash and error reports to us.",
"enable": "Enable",
"disable": "Disable",
"more-info": "More Info"
"more-info": "More Info",
"track": "Track"
}

View File

@@ -0,0 +1,43 @@
{
"play-next": "再生する",
"play-album": "アルバムを再生する",
"queue": "再生リスト",
"add-to-queue": "再生リストに追加",
"clear-queue": "再生リストをクリア",
"no-results": "結果なし",
"album": "アルバム",
"albums": "アルバム",
"all-albums": "すべてのアルバム",
"search": "検索",
"music": "音楽",
"now-playing": "再生中",
"onboarding-welcome": "ようこそ。",
"onboarding-intro": "Jellyfin Audio Player は、どこからでも音楽ライブラリをストリーミングすることができます。バックグラウンド・オーディオやキャスティングを完全にサポートします。",
"onboarding-cta": "始めるためには、Jellyfin サーバーが必要です。下のボタンをクリックして、Jellyfin サーバーのアドレスを入力し、ログインしてください。",
"set-jellyfin-server": "Jellyfin サーバ を設定",
"set-jellyfin-server-instruction": "Jellyfin サーバの URL を入力してください。プロトコルとポートを必ず含めてください。",
"settings": "設定",
"jellyfin-library": "Jellyfin ライブライ",
"jellyfin-server-url": "Jellyfin サーバの URL",
"jellyfin-access-token": "Jellyfin アクセストークン",
"jellyfin-user-id": "Jellyfin ユーザ ID",
"setting-cache": "キャッシュ",
"setting-cache-description": "Jellyfinライブラリをアップデートしたにもかかわらず、アプリがキャッシュされたアセットを保持している場合、このボタンを使って強制的にキャッシュをクリアすることができます。これにより、アプリはライブラリを最初から取得するようになります。",
"reset-cache": "キャッシュをリセット",
"recent-albums": "最近のアルバム",
"error-reporting": "エラー報告",
"error-reporting-description": "このアプリを使用中に、エラーの可能性があります。これらのエラーを報告することで、よりセキュアで安定したアプリ体験を実現することができます。",
"error-reporting-rationale": "エラーレポートを有効にすると、エラーが発生するたびにレポートが自動的に作成され、デバイス、バージョン、特定のエラーなど、デバッグに役立つ情報とともにサーバーに送信されます。",
"why-use-tracking": "なぜトラッキングを使うか?",
"why-use-tracking-description": "トラッキングは、奇妙なエッジケースや見落としを報告することで、このアプリの開発を促進します。これにより、アプリの安定性と堅牢性が向上し、すべての人のアプリ体験が向上します。",
"what-data-is-gathered": "どのデータが集まりますか?",
"what-data-is-gathered-description": "エラー、デバイスタイプ、OSバージョン、アプリバージョン、デバイスIDが記録されます。いかなるエラー報告においても、アプリケーションの状態は送信されません。デバイスIDは、デバイスの設定でリセット可能な一意のハッシュであり、この識別子から個人情報を推測することはできません。",
"where-is-data-stored": "データはどこに保存されていますか?",
"where-is-data-stored-description": "Sentryサービスは、私たち自身のインフラでセルフホストされています。当社以外の誰も、サーバー、データベース、アプリケーション、データログにアクセスすることはできません。このインフラはEUでホストされています。",
"enable-error-reporting": "エラー報告を有効にしますか?",
"enable-error-reporting-description": "これは、クラッシュやエラーのレポートを送信することで、アプリを改善に役立ちます。",
"enable": "有効する",
"disable": "無効する",
"more-info": "詳しくは",
"track": "追跡"
}

View File

@@ -12,9 +12,9 @@
"music": "Muziek",
"now-playing": "Nu spelend",
"onboarding-welcome": "Welkom!",
"onboarding-intro": "Jellyfin Audio Player maakt het mogelijk om van waar dan ook je muziek te streamen, met volledige support voor achtegroundaudio en casting.",
"onboarding-intro": "Jellyfin Audio Player maakt het mogelijk om van waar dan ook je muziek te streamen, met volledige support voor achtergroundaudio en casting.",
"onboarding-cta": "Om te starten moet je een Jellyfin server hebben. Klik de onderstaande knop om het adres van je Jellyfin server in te vullen en er in te loggen.",
"set-jellyfin-server": "Kies Jellyfin Server in",
"set-jellyfin-server": "Stel Jellyfin Server in",
"set-jellyfin-server-instruction": "Vul alsjeblieft je Jellyfin server URL in. Voeg ook het protocol en de poort toe",
"settings": "Instellingen",
"jellyfin-library": "Jellyfin Bibliotheek",

View File

@@ -0,0 +1,42 @@
{
"play-next": "播放下一首",
"play-album": "播放专辑",
"queue": "歌曲队列",
"add-to-queue": "加入队列",
"clear-queue": "清除队列",
"no-results": "无匹配记录",
"album": "专辑",
"albums": "专辑",
"all-albums": "所有专辑",
"search": "搜索",
"music": "歌曲",
"now-playing": "正在播放",
"onboarding-welcome": "欢迎",
"onboarding-intro": "Jellyfin Audio Player will allow you to stream your music library from anywhere, with full support for background audio and casting.",
"onboarding-cta": "In order to get started, you need a Jellyfin server. Click the button below to enter your Jellyfin server address and login to it.",
"set-jellyfin-server": "设置Jellyfin服务器",
"set-jellyfin-server-instruction": "设置Jellyfin服务器的完整网址包括HTTP/HTTS和端口。",
"settings": "设置",
"jellyfin-library": "Jellyfin库",
"jellyfin-server-url": "Jellyfin服务器网址",
"jellyfin-access-token": "Jellyfin Access Token",
"jellyfin-user-id": "Jellyfin用户ID",
"setting-cache": "缓存",
"setting-cache-description": "If you have updated your Jellyfin library, but the app is holding on to cached assets, you can forcefully clear the cache using this button. This will force the app to fetch the library from scratch.",
"reset-cache": "清除缓存",
"recent-albums": "最近专辑",
"error-reporting": "Error Reporting",
"error-reporting-description": "During use of this app, you may encounter errors. Reporting these errors helps in creating a more secure and stable app experience.",
"error-reporting-rationale": "When you enable error reporting, every time an error occurs, a report is automatically created and sent to a server, along with helpful debugging information such as devices, versions and the specific error.",
"why-use-tracking": "Why use tracking?",
"why-use-tracking-description": "Tracking helps speed up development for this app by reporting weird edge cases and oversights. This helps make the app more stable and robust, thus increasing the app experience for everyone.",
"what-data-is-gathered": "What data is gathered?",
"what-data-is-gathered-description": "We log the error, device type, OS version, app version and device id. No application state is sent in any error reporting. The device id is a unique hash that can be reset in your device settings, and we cannot deduce any personal information from this identifier.",
"where-is-data-stored": "Where is data stored?",
"where-is-data-stored-description": "The Sentry backend is self-hosted on our own infrastructure. No-one but us has access to the servers, databases, application and data logs, least of all any Sentry staff. The infrastructure is hosted in the European Union.",
"enable-error-reporting": "Do you want to enable error reporting?",
"enable-error-reporting-description": "This helps improve the app experience by sending crash and error reports to us.",
"enable": "启用",
"disable": "禁用",
"more-info": "更多信息"
}

View File

@@ -37,4 +37,5 @@ export type LocaleKeys = 'play-next'
| 'enable-error-reporting-description'
| 'enable'
| 'disable'
| 'more-info'
| 'more-info'
| 'track'

View File

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

View File

@@ -1,10 +1,10 @@
import React, { useState, useEffect, useRef, useCallback } from 'react';
import Input from 'components/Input';
import { Text, View } from 'react-native';
import { ActivityIndicator, Text, View } from 'react-native';
import styled from 'styled-components/native';
import { useTypedSelector } from 'store';
import { useAppDispatch, useTypedSelector } from 'store';
import Fuse from 'fuse.js';
import { Album } from 'store/music/types';
import { Album, AlbumTrack } from 'store/music/types';
import { FlatList } from 'react-native-gesture-handler';
import TouchableHandler from 'components/TouchableHandler';
import { useNavigation } from '@react-navigation/native';
@@ -13,9 +13,21 @@ import { NavigationProp } from '../types';
import FastImage from 'react-native-fast-image';
import { t } from '@localisation';
import useDefaultStyles from 'components/Colors';
import { searchAndFetchAlbums } from 'store/music/actions';
import { debounce } from 'lodash';
const Container = styled.View`
padding: 0 20px;
position: relative;
`;
const Loading = styled.View`
position: absolute;
right: 32px;
top: 0;
height: 100%;
flex: 1;
justify-content: center;
`;
const AlbumImage = styled(FastImage)`
@@ -46,18 +58,39 @@ const fuseOptions = {
includeScore: true,
};
type AudioResult = {
type: 'Audio',
id: string;
album: string;
name: string;
};
type AlbumResult = {
type: 'AlbumArtist',
id: string;
album: undefined;
name: undefined;
}
type CombinedResults = (AudioResult | AlbumResult)[];
export default function Search() {
const defaultStyles = useDefaultStyles();
// Prepare state
const [fuseIsReady, setFuseReady] = useState(false);
const [searchTerm, setSearchTerm] = useState('');
const albums = useTypedSelector(state => state.music.albums.entities);
const [results, setResults] = useState<Fuse.FuseResult<Album>[]>([]);
const fuse = useRef<Fuse<Album, typeof fuseOptions>>();
const [fuseResults, setFuseResults] = useState<CombinedResults>([]);
const [jellyfinResults, setJellyfinResults] = useState<CombinedResults>([]);
const [isLoading, setLoading] = useState(false);
const fuse = useRef<Fuse<Album>>();
// Prepare helpers
const navigation = useNavigation<NavigationProp>();
const getImage = useGetImage();
const dispatch = useAppDispatch();
/**
* Since it is impractical to have a global fuse variable, we need to
@@ -68,21 +101,89 @@ export default function Search() {
*/
useEffect(() => {
fuse.current = new Fuse(Object.values(albums) as Album[], fuseOptions);
}, [albums]);
setFuseReady(true);
}, [albums, setFuseReady]);
/**
* This function retrieves search results from Jellyfin. It is a seperate
* callback, so that we can make sure it is properly debounced and doesn't
* cause execessive jank in the interface.
*/
// eslint-disable-next-line react-hooks/exhaustive-deps
const fetchJellyfinResults = useCallback(debounce(async (searchTerm: string, currentResults: CombinedResults) => {
// First, query the Jellyfin API
const { payload } = await dispatch(searchAndFetchAlbums({ term: searchTerm }));
// Convert the current results to album ids
const albumIds = currentResults.map(item => item.id);
// Parse the result in correct typescript form
const results = (payload as { results: (Album | AlbumTrack)[] }).results;
// Filter any results that are already displayed
const items = results.filter(item => (
!(item.Type === 'MusicAlbum' && albumIds.includes(item.Id))
// Then convert the results to proper result form
)).map((item) => ({
type: item.Type,
id: item.Id,
album: item.Type === 'Audio'
? item.AlbumId
: undefined,
name: item.Type === 'Audio'
? item.Name
: undefined,
}));
// Lastly, we'll merge the two and assign them to the state
setJellyfinResults([...items] as CombinedResults);
// Loading is now complete
setLoading(false);
}, 50), [dispatch, setJellyfinResults]);
/**
* Whenever the search term changes, we gather results from Fuse and assign
* them to state
*/
useEffect(() => {
// GUARD: In some extraordinary cases, Fuse might not be presented since
// it is assigned via refs. In this case, we can't handle any searching.
if (!fuse.current) {
if (!searchTerm) {
return;
}
setResults(fuse.current.search(searchTerm));
}, [searchTerm, setResults, fuse]);
const retrieveResults = async () => {
// GUARD: In some extraordinary cases, Fuse might not be presented since
// it is assigned via refs. In this case, we can't handle any searching.
if (!fuse.current) {
return;
}
// First set the immediate results from fuse
const fuseResults = fuse.current.search(searchTerm);
const albums: AlbumResult[] = fuseResults
.map(({ item }) => ({
id: item.Id,
type: 'AlbumArtist',
album: undefined,
name: undefined,
}));
// Assign the preliminary results
setFuseResults(albums);
setLoading(true);
try {
// Wrap the call in a try/catch block so that we catch any
// network issues in search and just use local search if the
// network is unavailable
fetchJellyfinResults(searchTerm, albums);
} catch {
// Reset the loading indicator if the network fails
setLoading(false);
}
};
retrieveResults();
}, [searchTerm, setFuseResults, setLoading, fuse, fetchJellyfinResults]);
// Handlers
const selectAlbum = useCallback((id: string) =>
@@ -92,35 +193,59 @@ export default function Search() {
const HeaderComponent = React.useMemo(() => (
<Container>
<Input value={searchTerm} onChangeText={setSearchTerm} style={defaultStyles.input} placeholder={t('search') + '...'} />
{(searchTerm.length && !results.length) ? <Text style={{ textAlign: 'center' }}>{t('no-results')}</Text> : null}
{isLoading && <Loading><ActivityIndicator /></Loading>}
</Container>
), [searchTerm, results, setSearchTerm, defaultStyles]);
), [searchTerm, setSearchTerm, defaultStyles, isLoading]);
const FooterComponent = React.useMemo(() => (
<Container>
{(searchTerm.length && !jellyfinResults.length && !fuseResults.length && !isLoading)
? <Text style={{ textAlign: 'center' }}>{t('no-results')}</Text>
: null}
</Container>
), [searchTerm, jellyfinResults, fuseResults, isLoading]);
// GUARD: We cannot search for stuff unless Fuse is loaded with results.
// Therefore we delay rendering to when we are certain it's there.
if (!fuse.current) {
if (!fuseIsReady) {
return null;
}
return (
<FlatList
data={results}
renderItem={({ item: { item: album } }) =>(
<TouchableHandler id={album.Id} onPress={selectAlbum}>
<SearchResult style={defaultStyles.border}>
<AlbumImage source={{ uri: getImage(album.Id) }} />
<View>
<Text numberOfLines={1} ellipsizeMode="tail" style={defaultStyles.text}>
{album.Name} - {album.AlbumArtist}
</Text>
<HalfOpacity style={defaultStyles.text}>{t('album')}</HalfOpacity>
</View>
</SearchResult>
</TouchableHandler>
)}
keyExtractor={(item) => item.refIndex.toString()}
ListHeaderComponent={HeaderComponent}
extraData={searchTerm}
/>
<>
<FlatList
style={{ flex: 1 }}
data={[...jellyfinResults, ...fuseResults]}
renderItem={({ item: { id, type, album: trackAlbum, name: trackName } }: { item: AlbumResult | AudioResult }) => {
const album = albums[trackAlbum || id];
// GUARD: If the album cannot be found in the store, we
// cannot display it.
if (!album) {
return null;
}
return (
<TouchableHandler id={album.Id} onPress={selectAlbum}>
<SearchResult style={defaultStyles.border}>
<AlbumImage source={{ uri: getImage(album.Id) }} />
<View>
<Text numberOfLines={1} ellipsizeMode="tail" style={defaultStyles.text}>
{trackName || album.Name} - {album.AlbumArtist}
</Text>
<HalfOpacity style={defaultStyles.text}>
{type === 'AlbumArtist' ? t('album'): t('track')}
</HalfOpacity>
</View>
</SearchResult>
</TouchableHandler>
);
}}
keyExtractor={(item) => item.id}
ListHeaderComponent={HeaderComponent}
ListFooterComponent={FooterComponent}
extraData={[searchTerm, albums]}
/>
</>
);
}

View File

@@ -1,70 +1,5 @@
import { StackNavigationProp } from '@react-navigation/stack';
export interface UserData {
PlaybackPositionTicks: number;
PlayCount: number;
IsFavorite: boolean;
Played: boolean;
Key: string;
}
export interface ArtistItem {
Name: string;
Id: string;
}
export interface AlbumArtist {
Name: string;
Id: string;
}
export interface ImageTags {
Primary: string;
}
export interface Album {
Name: string;
ServerId: string;
Id: string;
SortName: string;
RunTimeTicks: number;
ProductionYear: number;
IsFolder: boolean;
Type: string;
UserData: UserData;
PrimaryImageAspectRatio: number;
Artists: string[];
ArtistItems: ArtistItem[];
AlbumArtist: string;
AlbumArtists: AlbumArtist[];
ImageTags: ImageTags;
BackdropImageTags: any[];
LocationType: string;
DateCreated: string;
}
export interface AlbumTrack {
Name: string;
ServerId: string;
Id: string;
RunTimeTicks: number;
ProductionYear: number;
IndexNumber: number;
IsFolder: boolean;
Type: string;
UserData: UserData;
Artists: string[];
ArtistItems: ArtistItem[];
Album: string;
AlbumId: string;
AlbumPrimaryImageTag: string;
AlbumArtist: string;
AlbumArtists: AlbumArtist[];
ImageTags: ImageTags;
BackdropImageTags: any[];
LocationType: string;
MediaType: string;
}
import { Album } from 'store/music/types';
export type StackParams = {
Albums: undefined;

View File

@@ -0,0 +1,14 @@
import React from 'react';
import styled from 'styled-components/native';
const Button = styled.View`
margin: 20px 40px;
`;
function Casting() {
return (
<Button />
);
}
export default Casting;

View File

@@ -0,0 +1,9 @@
import React from 'react';
export interface CastingProps {
fill?: string;
}
declare const CastingComponent: React.FC<CastingProps>;
export default CastingComponent;

View File

@@ -0,0 +1,25 @@
import { THEME_COLOR } from 'CONSTANTS';
import React from 'react';
import AirPlayButton from 'react-native-airplay-button';
import styled from 'styled-components/native';
import { CastingProps } from './Casting';
const Button = styled.View`
margin: 20px 40px;
`;
function Casting({ fill }: CastingProps) {
return (
<>
<Button>
<AirPlayButton
activeTintColor={THEME_COLOR}
tintColor={fill}
style={{ width: 40, height: 40 }}
/>
</Button>
</>
);
}
export default Casting;

View File

@@ -10,6 +10,7 @@ import PauseIcon from 'assets/pause.svg';
import RepeatIcon from 'assets/repeat.svg';
// import ShuffleIcon from 'assets/shuffle.svg';
import { THEME_COLOR } from 'CONSTANTS';
import Casting from './Casting';
const BUTTON_SIZE = 40;
const BUTTON_SIZE_SMALL = 25;
@@ -54,9 +55,7 @@ export default function MediaControls() {
<Button>
<RepeatButton fill={fill} />
</Button>
<Button>
{/* <ShuffleButton fill={fill} /> */}
</Button>
<Casting fill={fill} />
</Buttons>
</Container>
);

View File

@@ -1,5 +1,5 @@
import { configureStore, getDefaultMiddleware, combineReducers } from '@reduxjs/toolkit';
import { useSelector, TypedUseSelectorHook } from 'react-redux';
import { useSelector, TypedUseSelectorHook, useDispatch } from 'react-redux';
import AsyncStorage from '@react-native-community/async-storage';
import { persistStore, persistReducer, PersistConfig } from 'redux-persist';
import autoMergeLevel2 from 'redux-persist/es/stateReconciler/autoMergeLevel2';
@@ -34,6 +34,7 @@ export type AppState = ReturnType<typeof reducers>;
export type AppDispatch = typeof store.dispatch;
export type AsyncThunkAPI = { state: AppState, dispatch: AppDispatch };
export const useTypedSelector: TypedUseSelectorHook<AppState> = useSelector;
export const useAppDispatch = () => useDispatch<AppDispatch>();
export const persistedStore = persistStore(store);

View File

@@ -1,7 +1,7 @@
import { createAsyncThunk, createEntityAdapter } from '@reduxjs/toolkit';
import { Album, AlbumTrack } from './types';
import { AsyncThunkAPI } from '..';
import { retrieveAlbums, retrieveAlbumTracks, retrieveRecentAlbums } from 'utility/JellyfinApi';
import { retrieveAllAlbums, retrieveAlbumTracks, retrieveRecentAlbums, searchItem, retrieveAlbum } from 'utility/JellyfinApi';
export const albumAdapter = createEntityAdapter<Album>({
selectId: album => album.Id,
@@ -15,7 +15,7 @@ export const fetchAllAlbums = createAsyncThunk<Album[], undefined, AsyncThunkAPI
'/albums/all',
async (empty, thunkAPI) => {
const credentials = thunkAPI.getState().settings.jellyfin;
return retrieveAlbums(credentials) as Promise<Album[]>;
return retrieveAllAlbums(credentials) as Promise<Album[]>;
}
);
@@ -44,4 +44,36 @@ export const fetchTracksByAlbum = createAsyncThunk<AlbumTrack[], string, AsyncTh
const credentials = thunkAPI.getState().settings.jellyfin;
return retrieveAlbumTracks(ItemId, credentials) as Promise<AlbumTrack[]>;
}
);
type SearchAndFetchResults = {
albums: Album[];
results: (Album | AlbumTrack)[];
};
export const searchAndFetchAlbums = createAsyncThunk<
SearchAndFetchResults,
{ term: string, limit?: number },
AsyncThunkAPI
>(
'/search',
async ({ term, limit = 24 }, thunkAPI) => {
const state = thunkAPI.getState();
const results = await searchItem(state.settings.jellyfin, term, limit);
const albums = await Promise.all(results.filter((item) => (
!state.music.albums.ids.includes(item.Type === 'MusicAlbum' ? item.Id : item.AlbumId)
)).map(async (item) => {
if (item.Type === 'MusicAlbum') {
return item;
}
return retrieveAlbum(state.settings.jellyfin, item.AlbumId);
}));
return {
albums,
results
};
}
);

View File

@@ -1,4 +1,4 @@
import { fetchAllAlbums, albumAdapter, fetchTracksByAlbum, trackAdapter, fetchRecentAlbums } from './actions';
import { fetchAllAlbums, albumAdapter, fetchTracksByAlbum, trackAdapter, fetchRecentAlbums, searchAndFetchAlbums } from './actions';
import { createSlice, Dictionary, EntityId } from '@reduxjs/toolkit';
import { Album, AlbumTrack } from './types';
import { setJellyfinCredentials } from 'store/settings/actions';
@@ -77,6 +77,12 @@ const music = createSlice({
builder.addCase(fetchTracksByAlbum.pending, (state) => { state.tracks.isLoading = true; });
builder.addCase(fetchTracksByAlbum.rejected, (state) => { state.tracks.isLoading = false; });
builder.addCase(searchAndFetchAlbums.pending, (state) => { state.albums.isLoading = true; });
builder.addCase(searchAndFetchAlbums.fulfilled, (state, { payload }) => {
albumAdapter.upsertMany(state.albums, payload.albums);
state.albums.isLoading = false;
});
// Reset any caches we have when a new server is set
builder.addCase(setJellyfinCredentials, () => initialState);
}

View File

@@ -30,7 +30,7 @@ export interface Album {
RunTimeTicks: number;
ProductionYear: number;
IsFolder: boolean;
Type: string;
Type: 'MusicAlbum';
UserData: UserData;
PrimaryImageAspectRatio: number;
Artists: string[];
@@ -53,7 +53,7 @@ export interface AlbumTrack {
ProductionYear: number;
IndexNumber: number;
IsFolder: boolean;
Type: string;
Type: 'Audio';
UserData: UserData;
Artists: string[];
ArtistItems: ArtistItem[];

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({
name: 'player',
initialState: 0,
initialState,
reducers: {
addNewTrackToPlayer: (state) => state + 1,
addNewTrackToPlayer: (state) => {
state.addedTrackCount += 1;
},
setCurrentTrack: (state, action: PayloadAction<Track | undefined>) => {
state.currentTrack = action.payload;
},
}
});

View File

@@ -1,6 +1,6 @@
import { Track } from 'react-native-track-player';
import { AppState, useTypedSelector } from 'store';
import { AlbumTrack } from 'store/music/types';
import { Album, AlbumTrack } from 'store/music/types';
type Credentials = AppState['settings']['jellyfin'];
@@ -22,11 +22,7 @@ const baseTrackOptions: Record<string, string> = {
// This must be set to support client seeking
TranscodingProtocol: 'hls',
TranscodingContainer: 'ts',
// NOTE: We cannot send a comma-delimited list yet due to an issue with
// react-native-track-player. This is set to be merged and released very
// soon: https://github.com/react-native-kit/react-native-track-player/pull/950
// Container: 'mp3',
Container: 'mp3,aac,m4a,m4b|aac,alac,m4a,m4b|alac,flac',
Container: 'mp3,aac,m4a,m4b|aac,alac,m4a,m4b|alac,flac|ogg',
AudioCodec: 'aac',
static: 'true',
};
@@ -53,7 +49,9 @@ export function generateTrack(track: AlbumTrack, credentials: Credentials): Trac
title: track.Name,
artist: track.Artists.join(', '),
album: track.Album,
artwork: getImage(track.Id, credentials),
artwork: track.AlbumId
? getImage(track.AlbumId, credentials)
: getImage(track.Id, credentials),
};
}
@@ -72,7 +70,7 @@ const albumParams = new URLSearchParams(albumOptions).toString();
/**
* Retrieve all albums that are available on the Jellyfin server
*/
export async function retrieveAlbums(credentials: Credentials) {
export async function retrieveAllAlbums(credentials: Credentials) {
const config = generateConfig(credentials);
const albums = await fetch(`${credentials?.uri}/Users/${credentials?.user_id}/Items?${albumParams}`, config)
.then(response => response.json());
@@ -80,6 +78,15 @@ export async function retrieveAlbums(credentials: Credentials) {
return albums.Items;
}
/**
* Retrieve a single album
*/
export async function retrieveAlbum(credentials: Credentials, id: string): Promise<Album> {
const config = generateConfig(credentials);
return fetch(`${credentials?.uri}/Users/${credentials?.user_id}/Items/${id}`, config)
.then(response => response.json());
}
const latestAlbumsOptions = {
IncludeItemTypes: 'MusicAlbum',
Fields: 'DateCreated',
@@ -124,11 +131,66 @@ export async function retrieveAlbumTracks(ItemId: string, credentials: Credentia
return album.Items;
}
/**
* Retrieve an image URL for a given ItemId
*/
export function getImage(ItemId: string, credentials: Credentials): string {
return encodeURI(`${credentials?.uri}/Items/${ItemId}/Images/Primary?format=jpeg`);
}
/**
* Create a hook that can convert ItemIds to image URLs
*/
export function useGetImage() {
const credentials = useTypedSelector((state) => state.settings.jellyfin);
return (ItemId: string) => getImage(ItemId, credentials);
}
}
const trackParams = {
SortBy: 'AlbumArtist,SortName',
SortOrder: 'Ascending',
IncludeItemTypes: 'Audio',
Recursive: 'true',
Fields: 'PrimaryImageAspectRatio,SortName,BasicSyncInfo,DateCreated',
};
/**
* Retrieve all possible tracks that can be found in Jellyfin
*/
export async function retrieveAllTracks(credentials: Credentials) {
const config = generateConfig(credentials);
const tracks = await fetch(`${credentials?.uri}/Users/${credentials?.user_id}/Items?${trackParams}`, config)
.then(response => response.json());
return tracks.Items;
}
const searchParams = {
IncludeItemTypes: 'Audio,MusicAlbum',
SortBy: 'Album,SortName',
SortOrder: 'Ascending',
Recursive: 'true',
};
/**
* Remotely search the Jellyfin library for a particular search term
*/
export async function searchItem(
credentials: Credentials,
term: string, limit = 24
): Promise<(Album | AlbumTrack)[]> {
const config = generateConfig(credentials);
const params = new URLSearchParams({
...searchParams,
SearchTerm: term,
Limit: limit.toString(),
}).toString();
const results = await fetch(`${credentials?.uri}/Users/${credentials?.user_id}/Items?${params}`, config)
.then(response => response.json());
return results.Items;
}

View File

@@ -1,42 +1,15 @@
import { useEffect, useState } from 'react';
import TrackPlayer, { usePlaybackState, Track } from 'react-native-track-player';
import { 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
*/
export default function useCurrentTrack(): Track | undefined {
const state = usePlaybackState();
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]);
const track = useTypedSelector(state => state.player.currentTrack, idEqual);
return track;
}

View File

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