Compare commits

..

31 Commits

Author SHA1 Message Date
Lei Nelissen
9138946ba9 Release TestFlight URL 2020-08-25 10:51:11 +02:00
Lei Nelissen
ea11a7d317 Resolve dark mode styling issues 2020-08-25 10:39:21 +02:00
Lei Nelissen
91344300c8 Update fastlane to support signing and TestFlight 2020-08-25 10:39:02 +02:00
Lei Nelissen
52146a6e12 Disable codec/bitrate settings
Appearently neither Jellyfin nor Emby support user-defined bitrates (see https://emby.media/community/index.php?/topic/65896-change-audio-bitrate-of-transcoder/ and https://github.com/jellyfin/jellyfin/issues/1124. These issues must be fixed first before any attempt at user control over bitrate and codecs can be considered.
2020-08-09 18:29:17 +02:00
Lei Nelissen
0712e6b8ca Add onboarding component 2020-08-09 17:49:36 +02:00
Lei Nelissen
2155320f6b Add fastlane to README and simplify structure 2020-08-09 13:32:20 +02:00
Lei Nelissen
4ff1e173ba Get short hash in separate step 2020-07-28 12:09:15 +02:00
Lei Nelissen
c1f6a2984a Fix variable name in artifact upload 2020-07-28 12:03:37 +02:00
Lei Nelissen
8ba3080734 Fix entry file for good
(Famous last words)
2020-07-28 11:52:09 +02:00
Lei Nelissen
fe22661036 Add commit hash to Android APK filename 2020-07-28 11:43:06 +02:00
Lei Nelissen
3762d9166b Update fastlane syntax 2020-07-28 11:42:43 +02:00
Lei Nelissen
48dd8c23aa Change entrypoint file so iOS bundle is automatically generated 2020-07-28 11:42:08 +02:00
Lei Nelissen
86a4d11f67 Fix small dark mode issues 2020-07-26 17:18:15 +02:00
Lei Nelissen
57b79bf4e2 Implement dark mode for Android 2020-07-26 17:02:18 +02:00
Lei Nelissen
9c24dede18 Make sure dark mode updates are propagated 2020-07-26 14:55:13 +02:00
Lei Nelissen
6978a4dfea Add iOS Dark Mode 2020-07-26 14:45:32 +02:00
Lei Nelissen
ea91b083c3 Adjust slider color on Android 2020-07-26 12:55:02 +02:00
Lei Nelissen
715e9e3580 Adjust podfile for RN 0.63 2020-07-26 12:54:52 +02:00
Lei Nelissen
f1a084bc1e Fix ScrollView padding issues 2020-07-26 12:34:00 +02:00
Lei Nelissen
425b19734c Give artifact a name 2020-07-26 12:30:07 +02:00
Lei Nelissen
60bbbc7193 Update dependencies 2020-07-26 12:29:27 +02:00
Lei Nelissen
8aafd3f0d6 Install and setup bundler correctly 2020-07-26 12:14:42 +02:00
Lei Nelissen
fde4d7ecb3 Speed up fastlane install and upload correct artifact 2020-07-26 12:11:47 +02:00
Lei Nelissen
db2801d77d Add android APK workflow 2020-07-26 11:56:04 +02:00
Lei Nelissen
218c72d9e8 Setup fastlane for both iOS and Android 2020-07-26 11:55:46 +02:00
Lei Nelissen
4d3f6f30d1 Fix Android compilation issues and icon 2020-07-26 11:31:56 +02:00
Lei Nelissen
90a61f258d Use correct lane 2020-07-25 21:26:37 +02:00
Lei Nelissen
3a1fcd4594 Fix syntax 2020-07-25 21:19:50 +02:00
Lei Nelissen
b9501265f9 Cocoapods is already installed, so we don't need to explicitly install it 2020-07-25 21:18:14 +02:00
Lei Nelissen
3680cad5fc Setup Github action generating IPA file 2020-07-25 21:10:40 +02:00
Lei Nelissen
0690aae374 Implement fastlane 2020-07-25 21:10:28 +02:00
65 changed files with 6351 additions and 3925 deletions

49
.github/workflows/fastlane.yml vendored Normal file
View File

@@ -0,0 +1,49 @@
name: Fastlane
on: [push]
jobs:
# build-ios:
# runs-on: macos-latest
# steps:
# - uses: actions/checkout@v1
# - name: Install Node dependencies
# run: npm install
# - name: Install CocoaPods dependencies
# run: pod install --project-directory=./ios
# - name: Run fastlane setup
# env:
# APPLE_ACCOUNT: ${{ secrets.APPLE_ACCOUNT }}
# TEAM_ID: ${{ secrets.TEAM_ID }}
# run: |
# cd ios
# fastlane beta --verbose
# - name: Upload artifact
# uses: actions/upload-artifact@v2
# with:
# name: my-artifact
# path: output/*.ipa
build-android:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v1
- name: Set outputs
id: vars
run: echo "::set-output name=sha_short::$(git rev-parse --short HEAD)"
- name: Set up Ruby 2.6
uses: actions/setup-ruby@v1
with:
ruby-version: 2.6.x
- name: Install fastlane
run: |
gem install bundler
bundle install -j 6
- name: Install Node dependencies
run: npm install
- name: Generate APK
run: fastlane android beta
- name: Upload artifact
uses: actions/upload-artifact@v2
with:
name: jellyfin-audio-player-android-${{ steps.vars.outputs.sha_short }}.apk
path: android/app/build/outputs/**/*.apk

5
.gitignore vendored
View File

@@ -61,3 +61,8 @@ buck-out/
# CocoaPods
/ios/Pods/
build/
fastlane/report.xml
fastlane/Appfile
certificates/

9
Gemfile Normal file
View File

@@ -0,0 +1,9 @@
# frozen_string_literal: true
source "https://rubygems.org"
git_source(:github) {|repo_name| "https://github.com/#{repo_name}" }
# gem "rails"
gem "fastlane", "~> 2.153"

178
Gemfile.lock Normal file
View File

@@ -0,0 +1,178 @@
GEM
remote: https://rubygems.org/
specs:
CFPropertyList (3.0.2)
addressable (2.7.0)
public_suffix (>= 2.0.2, < 5.0)
atomos (0.1.3)
aws-eventstream (1.1.0)
aws-partitions (1.355.0)
aws-sdk-core (3.104.3)
aws-eventstream (~> 1, >= 1.0.2)
aws-partitions (~> 1, >= 1.239.0)
aws-sigv4 (~> 1.1)
jmespath (~> 1.0)
aws-sdk-kms (1.36.0)
aws-sdk-core (~> 3, >= 3.99.0)
aws-sigv4 (~> 1.1)
aws-sdk-s3 (1.78.0)
aws-sdk-core (~> 3, >= 3.104.3)
aws-sdk-kms (~> 1)
aws-sigv4 (~> 1.1)
aws-sigv4 (1.2.2)
aws-eventstream (~> 1, >= 1.0.2)
babosa (1.0.3)
claide (1.0.3)
colored (1.2)
colored2 (3.1.2)
commander-fastlane (4.4.6)
highline (~> 1.7.2)
declarative (0.0.20)
declarative-option (0.1.0)
digest-crc (0.6.1)
rake (~> 13.0)
domain_name (0.5.20190701)
unf (>= 0.0.5, < 1.0.0)
dotenv (2.7.6)
emoji_regex (3.0.0)
excon (0.76.0)
faraday (1.0.1)
multipart-post (>= 1.2, < 3)
faraday-cookie_jar (0.0.6)
faraday (>= 0.7.4)
http-cookie (~> 1.0.0)
faraday_middleware (1.0.0)
faraday (~> 1.0)
fastimage (2.2.0)
fastlane (2.156.1)
CFPropertyList (>= 2.3, < 4.0.0)
addressable (>= 2.3, < 3.0.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)
dotenv (>= 2.1.1, < 3.0.0)
emoji_regex (>= 0.1, < 4.0)
excon (>= 0.71.0, < 1.0.0)
faraday (~> 1.0)
faraday-cookie_jar (~> 0.0.6)
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)
json (< 3.0.0)
jwt (>= 2.1.0, < 3)
mini_magick (>= 4.9.4, < 5.0.0)
multipart-post (~> 2.0.0)
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)
tty-spinner (>= 0.8.0, < 1.0.0)
word_wrap (~> 1.0.0)
xcodeproj (>= 1.13.0, < 2.0.0)
xcpretty (~> 0.3.0)
xcpretty-travis-formatter (>= 0.0.3)
gh_inspector (1.1.3)
google-api-client (0.38.0)
addressable (~> 2.5, >= 2.5.1)
googleauth (~> 0.9)
httpclient (>= 2.8.1, < 3.0)
mini_mime (~> 1.0)
representable (~> 3.0)
retriable (>= 2.0, < 4.0)
signet (~> 0.12)
google-cloud-core (1.5.0)
google-cloud-env (~> 1.0)
google-cloud-errors (~> 1.0)
google-cloud-env (1.3.3)
faraday (>= 0.17.3, < 2.0)
google-cloud-errors (1.0.1)
google-cloud-storage (1.27.0)
addressable (~> 2.5)
digest-crc (~> 0.4)
google-api-client (~> 0.33)
google-cloud-core (~> 1.2)
googleauth (~> 0.9)
mini_mime (~> 1.0)
googleauth (0.13.1)
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)
domain_name (~> 0.5)
httpclient (2.8.3)
jmespath (1.4.0)
json (2.3.1)
jwt (2.2.1)
memoist (0.16.2)
mini_magick (4.10.1)
mini_mime (1.0.2)
multi_json (1.15.0)
multipart-post (2.0.0)
nanaimo (0.3.0)
naturally (2.2.0)
os (1.1.1)
plist (3.5.0)
public_suffix (4.0.5)
rake (13.0.1)
representable (3.0.4)
declarative (< 0.1.0)
declarative-option (< 0.2.0)
uber (< 0.2.0)
retriable (3.1.2)
rouge (2.0.7)
rubyzip (2.3.0)
security (0.1.3)
signet (0.14.0)
addressable (~> 2.3)
faraday (>= 0.17.3, < 2.0)
jwt (>= 1.5, < 3.0)
multi_json (~> 1.10)
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)
tty-cursor (0.7.1)
tty-screen (0.8.1)
tty-spinner (0.9.3)
tty-cursor (~> 0.7)
uber (0.1.0)
unf (0.1.4)
unf_ext
unf_ext (0.0.7.7)
unicode-display_width (1.7.0)
word_wrap (1.0.0)
xcodeproj (1.18.0)
CFPropertyList (>= 2.3.3, < 4.0)
atomos (~> 0.1.3)
claide (>= 1.0.2, < 2.0)
colored2 (~> 3.1)
nanaimo (~> 0.3.0)
xcpretty (0.3.0)
rouge (~> 2.0.7)
xcpretty-travis-formatter (1.0.0)
xcpretty (~> 0.2, >= 0.0.7)
PLATFORMS
ruby
DEPENDENCIES
fastlane (~> 2.153)
BUNDLED WITH
1.17.2

View File

@@ -1,25 +1,63 @@
# Jellyfin Audio Player
This is a React Native-based audio streaming app for Jellyfin.
![Fastlane](https://github.com/leinelissen/jellyfin-audio-player/workflows/Fastlane/badge.svg)
![MIT License](https://img.shields.io/github/license/leinelissen/jellyfin-audio-player)
This is a [React Native](https://reactnative.dev/)-based audio streaming app for [Jellyfin](https://jellyfin.org/). Jellyfin is a community-based piece of software that allows you to stream your media library over the internet. By means of React Native, Jellyfin Audio Player allows you to stream your Jellyfin Music library, with full support for background audio and casting (ie. Airplay and Chromecast).
## ❗Now open for beta testing on iOS
Please follow this link to enroll for the TestFlight beta release of Jellyfin Audio Player: https://testflight.apple.com/join/cf2AMDpx.
|![](./docs/images/now-playing.png)|![](./docs/images/recent-albums.png)|![](./docs/images/album-list.png)|![](./docs/images/search.png)|
|-|-|-|-|
## Features
* Sorting by recent albums
* Browsing through all available albums
* Searching based on album and artist names
* Queuing tracks and albums
* AirPlay and Chromecast support
* Background audio
* Native Dark Mode
### Features being considered
* Downloading music for offline playback
* Searching based on track names
* Looping and shuffling queue
## Getting Started
What you want get started on depends on your intentions. As there is no build for general availability yet, you will need to build this project yourself.
This piece of software is in alpha. I am working on getting this app in ~~TestFlight and~~ Google Play Developer Console, but this is contingent on keys being available. In the meantime, IPAs and APK are intermittenly released on the [Releases page](https://github.com/leinelissen/jellyfin-audio-player/releases). Alternatively, you can build this app from source using the build instructions.
### Using the app
You will need to setup your Jellyfin account for the application to be able to pull in all your audio. To do this, go over to the "Settings" tab and click the "Set Jellyfin server"-button. A modal will pop up in which you will enter your Jellyfin server url, after which you enter your credentials in the provided browser view. When the app detects your credentials, they will automatically be remembered by the app.
You will need to setup your Jellyfin account for the application to be able to pull in all your audio. To do this, go over to the "Settings" tab and click the "Set Jellyfin server"-button. A modal will pop up in which you will enter your Jellyfin server url, after which you enter your credentials in the provided browser view. When the app detects your credentials, they will automatically be remembered for the future.
## Building from source
### Prerequisites
This project is built on React Native, and first of all requires [NodeJS](https://nodejs.org/en/) to be installed. After installing it and cloning this repository, don't forget ton run `npm install` on your command line, so that all Node dependencies are installed.
#### iOS Prerequisites
[XCode](https://developer.apple.com/download/) is required to build the iOS application. It also comes bundles with iOS simulators which make development exceedingly easy. This does mean that iOS development is limited to macs.
#### Android prerequisites
[Android Studio](https://developer.android.com/studio/install) is recommended for development as it includes the Android SDK as well as Android Simulators for devleopment. At the very least, installing the Android SDK is neccessary for building any version of the app.
### Development Build
This app has been mainly developed for iOS, but should mostly function on Android as well. To get started, do the following:
1. Clone this repository
2. Install [NodeJS](https://nodejs.org/en/) and [XCode](https://developer.apple.com/download/)
3. `npm install`
4. `npm run ios`
As soon as all prerequisites are covered, you can start development in either iOS or Android simulators by running the following
```
npm run ios
npm run android
```
### Production Build
Follow step 1-3 from the development build, then do the following:
This project is configured using [Fastlane](https://docs.fastlane.tools/), which allows for easy IPA and APK generation. To get started with this, make sure you install Fastlane first either using bundler (see below), or alternatively via e.g. Homebrew ([see supported methods](https://docs.fastlane.tools/getting-started/ios/setup/)).
```
npm run build:ios
gem install bundler
bundle install -j 6
```
Then open `ios/JellyfinAudioPlayer.xcworkspace` and build the project in XCode.
When fastlane is setup, you can run either commands for generating IPA (iOS) or APK (Android) bundles.
```
fastlane ios beta
fastlane android beta
```
## Licensing and Credits
This work is licensed under the MIT license and was built by Lei Nelissen.

View File

@@ -79,6 +79,7 @@ import com.android.build.OutputFile
project.ext.react = [
enableHermes: false, // clean and rebuild if changing
entryFile: 'index.js'
]
apply from: "../../node_modules/react-native/react.gradle"
@@ -134,6 +135,7 @@ android {
targetSdkVersion rootProject.ext.targetSdkVersion
versionCode 1
versionName "1.0"
multiDexEnabled true
}
splits {
abi {
@@ -164,13 +166,6 @@ android {
}
}
packagingOptions {
pickFirst "lib/armeabi-v7a/libc++_shared.so"
pickFirst "lib/arm64-v8a/libc++_shared.so"
pickFirst "lib/x86/libc++_shared.so"
pickFirst "lib/x86_64/libc++_shared.so"
}
// applicationVariants are e.g. debug, release
applicationVariants.all { variant ->
variant.outputs.each { output ->

View File

@@ -0,0 +1,30 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:aapt="http://schemas.android.com/aapt"
android:width="108dp"
android:height="108dp"
android:viewportWidth="108"
android:viewportHeight="108">
<path android:pathData="M31,63.928c0,0 6.4,-11 12.1,-13.1c7.2,-2.6 26,-1.4 26,-1.4l38.1,38.1L107,108.928l-32,-1L31,63.928z">
<aapt:attr name="android:fillColor">
<gradient
android:endX="85.84757"
android:endY="92.4963"
android:startX="42.9492"
android:startY="49.59793"
android:type="linear">
<item
android:color="#44000000"
android:offset="0.0" />
<item
android:color="#00000000"
android:offset="1.0" />
</gradient>
</aapt:attr>
</path>
<path
android:fillColor="#FFFFFF"
android:fillType="nonZero"
android:pathData="M65.3,45.828l3.8,-6.6c0.2,-0.4 0.1,-0.9 -0.3,-1.1c-0.4,-0.2 -0.9,-0.1 -1.1,0.3l-3.9,6.7c-6.3,-2.8 -13.4,-2.8 -19.7,0l-3.9,-6.7c-0.2,-0.4 -0.7,-0.5 -1.1,-0.3C38.8,38.328 38.7,38.828 38.9,39.228l3.8,6.6C36.2,49.428 31.7,56.028 31,63.928h46C76.3,56.028 71.8,49.428 65.3,45.828zM43.4,57.328c-0.8,0 -1.5,-0.5 -1.8,-1.2c-0.3,-0.7 -0.1,-1.5 0.4,-2.1c0.5,-0.5 1.4,-0.7 2.1,-0.4c0.7,0.3 1.2,1 1.2,1.8C45.3,56.528 44.5,57.328 43.4,57.328L43.4,57.328zM64.6,57.328c-0.8,0 -1.5,-0.5 -1.8,-1.2s-0.1,-1.5 0.4,-2.1c0.5,-0.5 1.4,-0.7 2.1,-0.4c0.7,0.3 1.2,1 1.2,1.8C66.5,56.528 65.6,57.328 64.6,57.328L64.6,57.328z"
android:strokeWidth="1"
android:strokeColor="#00000000" />
</vector>

View File

@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
<background android:drawable="@color/ic_launcher_background"/>
<foreground android:drawable="@mipmap/ic_launcher_foreground"/>
</adaptive-icon>

View File

@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
<background android:drawable="@color/ic_launcher_background"/>
<foreground android:drawable="@mipmap/ic_launcher_foreground"/>
</adaptive-icon>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.2 KiB

After

Width:  |  Height:  |  Size: 2.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.1 KiB

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.5 KiB

After

Width:  |  Height:  |  Size: 3.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

After

Width:  |  Height:  |  Size: 5.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 18 KiB

After

Width:  |  Height:  |  Size: 8.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

View File

@@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<color name="ic_launcher_background">#FFFFFF</color>
</resources>

View File

@@ -1,9 +1,8 @@
<resources>
<!-- Base application theme. -->
<style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
<style name="AppTheme" parent="Theme.MaterialComponents.DayNight.NoActionBar">
<!-- Customize your theme here. -->
<item name="android:textColor">#000000</item>
<!-- <item name="android:textColor">#000000</item> -->
</style>
</resources>

View File

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

4
fastlane/Appfile Normal file
View File

@@ -0,0 +1,4 @@
package_name("nl.moeilijkedingen.jellyfinaudioplayer")
app_identifier("nl.moeilijkedingen.jellyfinaudioplayer")
apple_id("lei@moeilijkedingen.nl")
team_id("238P3C58WC")

50
fastlane/Fastfile Normal file
View File

@@ -0,0 +1,50 @@
default_platform(:ios)
platform :ios do
lane :alpha do
get_certificates(
development: true,
output_path: 'certificates/'
)
build_app(
scheme: "JellyfinAudioPlayer",
export_method: "development",
output_directory: "build",
workspace: "ios/JellyfinAudioPlayer.xcworkspace"
)
end
lane :beta do
get_certificates(
output_path: 'certificates/'
)
get_provisioning_profile(
output_path: 'certificates/',
filename: "provisioning.mobileprovision",
fail_on_name_taken: true,
)
update_code_signing_settings(
use_automatic_signing: true,
path: "ios/JellyfinAudioPlayer.xcodeproj"
)
increment_build_number(
xcodeproj: "ios/JellyfinAudioPlayer.xcodeproj"
)
build_app(
scheme: "JellyfinAudioPlayer",
output_directory: "build",
workspace: "ios/JellyfinAudioPlayer.xcworkspace",
export_method: "app-store",
)
upload_to_testflight
end
end
platform :android do
desc "Generate beta build"
lane :beta do
gradle(
task: "clean assembleRelease",
project_dir: "android"
)
end
end

43
fastlane/README.md Normal file
View File

@@ -0,0 +1,43 @@
fastlane documentation
================
# Installation
Make sure you have the latest version of the Xcode command line tools installed:
```
xcode-select --install
```
Install _fastlane_ using
```
[sudo] gem install fastlane -NV
```
or alternatively using `brew install fastlane`
# Available Actions
## iOS
### ios alpha
```
fastlane ios alpha
```
### ios beta
```
fastlane ios beta
```
----
## Android
### android beta
```
fastlane android beta
```
Generate beta build
----
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

View File

@@ -12,15 +12,8 @@
13B07FBD1A68108700A75B9A /* LaunchScreen.xib in Resources */ = {isa = PBXBuildFile; fileRef = 13B07FB11A68108700A75B9A /* LaunchScreen.xib */; };
13B07FBF1A68108700A75B9A /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 13B07FB51A68108700A75B9A /* Images.xcassets */; };
13B07FC11A68108700A75B9A /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 13B07FB71A68108700A75B9A /* main.m */; };
2D02E4BC1E0B4A80006451C7 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 13B07FB01A68108700A75B9A /* AppDelegate.m */; };
2D02E4BD1E0B4A84006451C7 /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 13B07FB51A68108700A75B9A /* Images.xcassets */; };
2D02E4BF1E0B4AB3006451C7 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 13B07FB71A68108700A75B9A /* main.m */; };
2DCD954D1E0B4F2C00145EB5 /* JellyfinAudioPlayerTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 00E356F21AD99517003FC87E /* JellyfinAudioPlayerTests.m */; };
463612208457EBB4B723000A /* libPods-JellyfinAudioPlayer-JellyfinAudioPlayerTests.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 842AB597D56E84A4ACDC4735 /* libPods-JellyfinAudioPlayer-JellyfinAudioPlayerTests.a */; };
4F46F441249A56FF00308470 /* main.jsbundle in Resources */ = {isa = PBXBuildFile; fileRef = 008F07F21AC5B25A0029DE68 /* main.jsbundle */; };
9C3FCC29E5AD02738E8E3F28 /* libPods-JellyfinAudioPlayer-tvOSTests.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 7D43C7610851B9666193E3F6 /* libPods-JellyfinAudioPlayer-tvOSTests.a */; };
A807E2BB233D6F9347D8A95C /* libPods-JellyfinAudioPlayer.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 71370E61E2CC6BD9372ADCF3 /* libPods-JellyfinAudioPlayer.a */; };
A9112B4690DCDB63E46B6C30 /* libPods-JellyfinAudioPlayer-tvOS.a in Frameworks */ = {isa = PBXBuildFile; fileRef = E35451F7979C52C1692C4C9F /* libPods-JellyfinAudioPlayer-tvOS.a */; };
/* End PBXBuildFile section */
/* Begin PBXContainerItemProxy section */
@@ -31,17 +24,9 @@
remoteGlobalIDString = 13B07F861A680F5B00A75B9A;
remoteInfo = JellyfinAudioPlayer;
};
2D02E4911E0B4A5D006451C7 /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 83CBB9F71A601CBA00E9B192 /* Project object */;
proxyType = 1;
remoteGlobalIDString = 2D02E47A1E0B4A5D006451C7;
remoteInfo = "JellyfinAudioPlayer-tvOS";
};
/* End PBXContainerItemProxy section */
/* Begin PBXFileReference section */
008F07F21AC5B25A0029DE68 /* main.jsbundle */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = main.jsbundle; sourceTree = "<group>"; };
00E356EE1AD99517003FC87E /* JellyfinAudioPlayerTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = JellyfinAudioPlayerTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
00E356F11AD99517003FC87E /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
00E356F21AD99517003FC87E /* JellyfinAudioPlayerTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = JellyfinAudioPlayerTests.m; sourceTree = "<group>"; };
@@ -53,8 +38,6 @@
13B07FB61A68108700A75B9A /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = Info.plist; path = JellyfinAudioPlayer/Info.plist; sourceTree = "<group>"; };
13B07FB71A68108700A75B9A /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = main.m; path = JellyfinAudioPlayer/main.m; sourceTree = "<group>"; };
2710519FCC41B05FDE6738DF /* Pods-JellyfinAudioPlayer.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-JellyfinAudioPlayer.release.xcconfig"; path = "Target Support Files/Pods-JellyfinAudioPlayer/Pods-JellyfinAudioPlayer.release.xcconfig"; sourceTree = "<group>"; };
2D02E47B1E0B4A5D006451C7 /* JellyfinAudioPlayer-tvOS.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "JellyfinAudioPlayer-tvOS.app"; sourceTree = BUILT_PRODUCTS_DIR; };
2D02E4901E0B4A5D006451C7 /* JellyfinAudioPlayer-tvOSTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = "JellyfinAudioPlayer-tvOSTests.xctest"; sourceTree = BUILT_PRODUCTS_DIR; };
39572B38534BBDBB596C8C95 /* Pods-JellyfinAudioPlayer-JellyfinAudioPlayerTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-JellyfinAudioPlayer-JellyfinAudioPlayerTests.release.xcconfig"; path = "Target Support Files/Pods-JellyfinAudioPlayer-JellyfinAudioPlayerTests/Pods-JellyfinAudioPlayer-JellyfinAudioPlayerTests.release.xcconfig"; sourceTree = "<group>"; };
590BEA7DE65819C5B5FDAD06 /* Pods-JellyfinAudioPlayer-tvOSTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-JellyfinAudioPlayer-tvOSTests.release.xcconfig"; path = "Target Support Files/Pods-JellyfinAudioPlayer-tvOSTests/Pods-JellyfinAudioPlayer-tvOSTests.release.xcconfig"; sourceTree = "<group>"; };
71370E61E2CC6BD9372ADCF3 /* libPods-JellyfinAudioPlayer.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-JellyfinAudioPlayer.a"; sourceTree = BUILT_PRODUCTS_DIR; };
@@ -87,22 +70,6 @@
);
runOnlyForDeploymentPostprocessing = 0;
};
2D02E4781E0B4A5D006451C7 /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
A9112B4690DCDB63E46B6C30 /* libPods-JellyfinAudioPlayer-tvOS.a in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
2D02E48D1E0B4A5D006451C7 /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
9C3FCC29E5AD02738E8E3F28 /* libPods-JellyfinAudioPlayer-tvOSTests.a in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXFrameworksBuildPhase section */
/* Begin PBXGroup section */
@@ -126,7 +93,6 @@
13B07FAE1A68108700A75B9A /* JellyfinAudioPlayer */ = {
isa = PBXGroup;
children = (
008F07F21AC5B25A0029DE68 /* main.jsbundle */,
13B07FAF1A68108700A75B9A /* AppDelegate.h */,
13B07FB01A68108700A75B9A /* AppDelegate.m */,
13B07FB51A68108700A75B9A /* Images.xcassets */,
@@ -192,8 +158,6 @@
children = (
13B07F961A680F5B00A75B9A /* Jellyfin Player.app */,
00E356EE1AD99517003FC87E /* JellyfinAudioPlayerTests.xctest */,
2D02E47B1E0B4A5D006451C7 /* JellyfinAudioPlayer-tvOS.app */,
2D02E4901E0B4A5D006451C7 /* JellyfinAudioPlayer-tvOSTests.xctest */,
);
name = Products;
sourceTree = "<group>";
@@ -209,6 +173,7 @@
00E356EA1AD99517003FC87E /* Sources */,
00E356EB1AD99517003FC87E /* Frameworks */,
00E356EC1AD99517003FC87E /* Resources */,
BDE784ECF29EF861DBFF49D7 /* [CP] Copy Pods Resources */,
);
buildRules = (
);
@@ -230,6 +195,7 @@
13B07F8C1A680F5B00A75B9A /* Frameworks */,
13B07F8E1A680F5B00A75B9A /* Resources */,
00DD1BFF1BD5951E006B06BC /* Bundle React Native code and images */,
B9FB8FC65CEFF9AFAC71127E /* [CP] Copy Pods Resources */,
);
buildRules = (
);
@@ -240,45 +206,6 @@
productReference = 13B07F961A680F5B00A75B9A /* Jellyfin Player.app */;
productType = "com.apple.product-type.application";
};
2D02E47A1E0B4A5D006451C7 /* JellyfinAudioPlayer-tvOS */ = {
isa = PBXNativeTarget;
buildConfigurationList = 2D02E4BA1E0B4A5E006451C7 /* Build configuration list for PBXNativeTarget "JellyfinAudioPlayer-tvOS" */;
buildPhases = (
05D2621E5320B14963E6BA49 /* [CP] Check Pods Manifest.lock */,
FD10A7F122414F3F0027D42C /* Start Packager */,
2D02E4771E0B4A5D006451C7 /* Sources */,
2D02E4781E0B4A5D006451C7 /* Frameworks */,
2D02E4791E0B4A5D006451C7 /* Resources */,
2D02E4CB1E0B4B27006451C7 /* Bundle React Native Code And Images */,
);
buildRules = (
);
dependencies = (
);
name = "JellyfinAudioPlayer-tvOS";
productName = "JellyfinAudioPlayer-tvOS";
productReference = 2D02E47B1E0B4A5D006451C7 /* JellyfinAudioPlayer-tvOS.app */;
productType = "com.apple.product-type.application";
};
2D02E48F1E0B4A5D006451C7 /* JellyfinAudioPlayer-tvOSTests */ = {
isa = PBXNativeTarget;
buildConfigurationList = 2D02E4BB1E0B4A5E006451C7 /* Build configuration list for PBXNativeTarget "JellyfinAudioPlayer-tvOSTests" */;
buildPhases = (
BFD53620BC35198B520DBD0A /* [CP] Check Pods Manifest.lock */,
2D02E48C1E0B4A5D006451C7 /* Sources */,
2D02E48D1E0B4A5D006451C7 /* Frameworks */,
2D02E48E1E0B4A5D006451C7 /* Resources */,
);
buildRules = (
);
dependencies = (
2D02E4921E0B4A5D006451C7 /* PBXTargetDependency */,
);
name = "JellyfinAudioPlayer-tvOSTests";
productName = "JellyfinAudioPlayer-tvOSTests";
productReference = 2D02E4901E0B4A5D006451C7 /* JellyfinAudioPlayer-tvOSTests.xctest */;
productType = "com.apple.product-type.bundle.unit-test";
};
/* End PBXNativeTarget section */
/* Begin PBXProject section */
@@ -289,24 +216,15 @@
TargetAttributes = {
00E356ED1AD99517003FC87E = {
CreatedOnToolsVersion = 6.2;
DevelopmentTeam = HD2D35G9Y4;
DevelopmentTeam = 238P3C58WC;
ProvisioningStyle = Automatic;
TestTargetID = 13B07F861A680F5B00A75B9A;
};
13B07F861A680F5B00A75B9A = {
DevelopmentTeam = HD2D35G9Y4;
DevelopmentTeam = 238P3C58WC;
LastSwiftMigration = 1120;
};
2D02E47A1E0B4A5D006451C7 = {
CreatedOnToolsVersion = 8.2.1;
DevelopmentTeam = HD2D35G9Y4;
ProvisioningStyle = Automatic;
};
2D02E48F1E0B4A5D006451C7 = {
CreatedOnToolsVersion = 8.2.1;
DevelopmentTeam = HD2D35G9Y4;
ProvisioningStyle = Automatic;
TestTargetID = 2D02E47A1E0B4A5D006451C7;
};
};
};
buildConfigurationList = 83CBB9FA1A601CBA00E9B192 /* Build configuration list for PBXProject "JellyfinAudioPlayer" */;
@@ -324,8 +242,6 @@
targets = (
13B07F861A680F5B00A75B9A /* JellyfinAudioPlayer */,
00E356ED1AD99517003FC87E /* JellyfinAudioPlayerTests */,
2D02E47A1E0B4A5D006451C7 /* JellyfinAudioPlayer-tvOS */,
2D02E48F1E0B4A5D006451C7 /* JellyfinAudioPlayer-tvOSTests */,
);
};
/* End PBXProject section */
@@ -342,27 +258,11 @@
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
4F46F441249A56FF00308470 /* main.jsbundle in Resources */,
13B07FBF1A68108700A75B9A /* Images.xcassets in Resources */,
13B07FBD1A68108700A75B9A /* LaunchScreen.xib in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
2D02E4791E0B4A5D006451C7 /* Resources */ = {
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
2D02E4BD1E0B4A84006451C7 /* Images.xcassets in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
2D02E48E1E0B4A5D006451C7 /* Resources */ = {
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXResourcesBuildPhase section */
/* Begin PBXShellScriptBuildPhase section */
@@ -371,51 +271,36 @@
buildActionMask = 2147483647;
files = (
);
inputFileListPaths = (
);
inputPaths = (
);
name = "Bundle React Native code and images";
outputPaths = (
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/main.jsbundle",
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "export NODE_BINARY=node\n../node_modules/react-native/scripts/react-native-xcode.sh\n";
shellScript = "export NODE_BINARY=$(which node)\n../node_modules/react-native/scripts/react-native-xcode.sh\n";
};
05D2621E5320B14963E6BA49 /* [CP] Check Pods Manifest.lock */ = {
B9FB8FC65CEFF9AFAC71127E /* [CP] Copy Pods Resources */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputFileListPaths = (
);
inputPaths = (
"${PODS_PODFILE_DIR_PATH}/Podfile.lock",
"${PODS_ROOT}/Manifest.lock",
);
name = "[CP] Check Pods Manifest.lock";
outputFileListPaths = (
"${PODS_ROOT}/Target Support Files/Pods-JellyfinAudioPlayer/Pods-JellyfinAudioPlayer-resources.sh",
"${PODS_CONFIGURATION_BUILD_DIR}/React-Core/AccessibilityResources.bundle",
);
name = "[CP] Copy Pods Resources";
outputPaths = (
"$(DERIVED_FILE_DIR)/Pods-JellyfinAudioPlayer-tvOS-checkManifestLockResult.txt",
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/AccessibilityResources.bundle",
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
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";
shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-JellyfinAudioPlayer/Pods-JellyfinAudioPlayer-resources.sh\"\n";
showEnvVarsInLog = 0;
};
2D02E4CB1E0B4B27006451C7 /* Bundle React Native Code And Images */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputPaths = (
);
name = "Bundle React Native Code And Images";
outputPaths = (
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "export NODE_BINARY=node\n../node_modules/react-native/scripts/react-native-xcode.sh";
};
BBD71961640F29097BE9932A /* [CP] Check Pods Manifest.lock */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
@@ -438,26 +323,22 @@
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;
};
BFD53620BC35198B520DBD0A /* [CP] Check Pods Manifest.lock */ = {
BDE784ECF29EF861DBFF49D7 /* [CP] Copy Pods Resources */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputFileListPaths = (
);
inputPaths = (
"${PODS_PODFILE_DIR_PATH}/Podfile.lock",
"${PODS_ROOT}/Manifest.lock",
);
name = "[CP] Check Pods Manifest.lock";
outputFileListPaths = (
"${PODS_ROOT}/Target Support Files/Pods-JellyfinAudioPlayer-JellyfinAudioPlayerTests/Pods-JellyfinAudioPlayer-JellyfinAudioPlayerTests-resources.sh",
"${PODS_CONFIGURATION_BUILD_DIR}/React-Core/AccessibilityResources.bundle",
);
name = "[CP] Copy Pods Resources";
outputPaths = (
"$(DERIVED_FILE_DIR)/Pods-JellyfinAudioPlayer-tvOSTests-checkManifestLockResult.txt",
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/AccessibilityResources.bundle",
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
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";
shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-JellyfinAudioPlayer-JellyfinAudioPlayerTests/Pods-JellyfinAudioPlayer-JellyfinAudioPlayerTests-resources.sh\"\n";
showEnvVarsInLog = 0;
};
E68FAF43791AC236CF4BF8CB /* [CP] Check Pods Manifest.lock */ = {
@@ -501,25 +382,6 @@
shellScript = "export RCT_METRO_PORT=\"${RCT_METRO_PORT:=8081}\"\necho \"export RCT_METRO_PORT=${RCT_METRO_PORT}\" > \"${SRCROOT}/../node_modules/react-native/scripts/.packager.env\"\nif [ -z \"${RCT_NO_LAUNCH_PACKAGER+xxx}\" ] ; then\n if nc -w 5 -z localhost ${RCT_METRO_PORT} ; then\n if ! curl -s \"http://localhost:${RCT_METRO_PORT}/status\" | grep -q \"packager-status:running\" ; then\n echo \"Port ${RCT_METRO_PORT} already in use, packager is either not running or not running correctly\"\n exit 2\n fi\n else\n open \"$SRCROOT/../node_modules/react-native/scripts/launchPackager.command\" || echo \"Can't start packager automatically\"\n fi\nfi\n";
showEnvVarsInLog = 0;
};
FD10A7F122414F3F0027D42C /* Start Packager */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputFileListPaths = (
);
inputPaths = (
);
name = "Start Packager";
outputFileListPaths = (
);
outputPaths = (
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "export RCT_METRO_PORT=\"${RCT_METRO_PORT:=8081}\"\necho \"export RCT_METRO_PORT=${RCT_METRO_PORT}\" > \"${SRCROOT}/../node_modules/react-native/scripts/.packager.env\"\nif [ -z \"${RCT_NO_LAUNCH_PACKAGER+xxx}\" ] ; then\n if nc -w 5 -z localhost ${RCT_METRO_PORT} ; then\n if ! curl -s \"http://localhost:${RCT_METRO_PORT}/status\" | grep -q \"packager-status:running\" ; then\n echo \"Port ${RCT_METRO_PORT} already in use, packager is either not running or not running correctly\"\n exit 2\n fi\n else\n open \"$SRCROOT/../node_modules/react-native/scripts/launchPackager.command\" || echo \"Can't start packager automatically\"\n fi\nfi\n";
showEnvVarsInLog = 0;
};
/* End PBXShellScriptBuildPhase section */
/* Begin PBXSourcesBuildPhase section */
@@ -540,23 +402,6 @@
);
runOnlyForDeploymentPostprocessing = 0;
};
2D02E4771E0B4A5D006451C7 /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
2D02E4BF1E0B4AB3006451C7 /* main.m in Sources */,
2D02E4BC1E0B4A80006451C7 /* AppDelegate.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
2D02E48C1E0B4A5D006451C7 /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
2DCD954D1E0B4F2C00145EB5 /* JellyfinAudioPlayerTests.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXSourcesBuildPhase section */
/* Begin PBXTargetDependency section */
@@ -565,11 +410,6 @@
target = 13B07F861A680F5B00A75B9A /* JellyfinAudioPlayer */;
targetProxy = 00E356F41AD99517003FC87E /* PBXContainerItemProxy */;
};
2D02E4921E0B4A5D006451C7 /* PBXTargetDependency */ = {
isa = PBXTargetDependency;
target = 2D02E47A1E0B4A5D006451C7 /* JellyfinAudioPlayer-tvOS */;
targetProxy = 2D02E4911E0B4A5D006451C7 /* PBXContainerItemProxy */;
};
/* End PBXTargetDependency section */
/* Begin PBXVariantGroup section */
@@ -590,7 +430,8 @@
baseConfigurationReference = 8DAD3DCD6450C4255A20940E /* Pods-JellyfinAudioPlayer-JellyfinAudioPlayerTests.debug.xcconfig */;
buildSettings = {
BUNDLE_LOADER = "$(TEST_HOST)";
DEVELOPMENT_TEAM = HD2D35G9Y4;
CODE_SIGN_STYLE = Automatic;
DEVELOPMENT_TEAM = 238P3C58WC;
GCC_PREPROCESSOR_DEFINITIONS = (
"DEBUG=1",
"$(inherited)",
@@ -614,8 +455,9 @@
baseConfigurationReference = 39572B38534BBDBB596C8C95 /* Pods-JellyfinAudioPlayer-JellyfinAudioPlayerTests.release.xcconfig */;
buildSettings = {
BUNDLE_LOADER = "$(TEST_HOST)";
CODE_SIGN_STYLE = Automatic;
COPY_PHASE_STRIP = NO;
DEVELOPMENT_TEAM = HD2D35G9Y4;
DEVELOPMENT_TEAM = 238P3C58WC;
INFOPLIST_FILE = JellyfinAudioPlayerTests/Info.plist;
IPHONEOS_DEPLOYMENT_TARGET = 9.0;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
@@ -626,6 +468,8 @@
);
PRODUCT_BUNDLE_IDENTIFIER = "org.reactjs.native.example.$(PRODUCT_NAME:rfc1034identifier)";
PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE = "915c5213-22f6-4f9d-8065-2a06300f9bfb";
PROVISIONING_PROFILE_SPECIFIER = "";
TEST_HOST = "$(BUILT_PRODUCTS_DIR)/JellyfinAudioPlayer.app/JellyfinAudioPlayer";
};
name = Release;
@@ -636,8 +480,9 @@
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CLANG_ENABLE_MODULES = YES;
CURRENT_PROJECT_VERSION = 1;
DEVELOPMENT_TEAM = HD2D35G9Y4;
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 3;
DEVELOPMENT_TEAM = 238P3C58WC;
ENABLE_BITCODE = NO;
GCC_PREPROCESSOR_DEFINITIONS = (
"$(inherited)",
@@ -650,8 +495,9 @@
"-ObjC",
"-lc++",
);
PRODUCT_BUNDLE_IDENTIFIER = "org.reactjs.native.example.$(PRODUCT_NAME:rfc1034identifier)";
PRODUCT_BUNDLE_IDENTIFIER = nl.moeilijkedingen.jellyfinaudioplayer;
PRODUCT_NAME = "Jellyfin Player";
PROVISIONING_PROFILE_SPECIFIER = "";
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
SWIFT_VERSION = 5.0;
VERSIONING_SYSTEM = "apple-generic";
@@ -664,8 +510,9 @@
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CLANG_ENABLE_MODULES = YES;
CURRENT_PROJECT_VERSION = 1;
DEVELOPMENT_TEAM = HD2D35G9Y4;
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 3;
DEVELOPMENT_TEAM = 238P3C58WC;
INFOPLIST_FILE = JellyfinAudioPlayer/Info.plist;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
OTHER_LDFLAGS = (
@@ -673,127 +520,15 @@
"-ObjC",
"-lc++",
);
PRODUCT_BUNDLE_IDENTIFIER = "org.reactjs.native.example.$(PRODUCT_NAME:rfc1034identifier)";
PRODUCT_BUNDLE_IDENTIFIER = nl.moeilijkedingen.jellyfinaudioplayer;
PRODUCT_NAME = "Jellyfin Player";
PROVISIONING_PROFILE = "915c5213-22f6-4f9d-8065-2a06300f9bfb";
PROVISIONING_PROFILE_SPECIFIER = "";
SWIFT_VERSION = 5.0;
VERSIONING_SYSTEM = "apple-generic";
};
name = Release;
};
2D02E4971E0B4A5E006451C7 /* Debug */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = DEB1E90737138C4BD6E5323D /* Pods-JellyfinAudioPlayer-tvOS.debug.xcconfig */;
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = "App Icon & Top Shelf Image";
ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage;
CLANG_ANALYZER_NONNULL = YES;
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
DEBUG_INFORMATION_FORMAT = dwarf;
DEVELOPMENT_TEAM = HD2D35G9Y4;
ENABLE_TESTABILITY = YES;
GCC_NO_COMMON_BLOCKS = YES;
INFOPLIST_FILE = "JellyfinAudioPlayer-tvOS/Info.plist";
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
OTHER_LDFLAGS = (
"$(inherited)",
"-ObjC",
"-lc++",
);
PRODUCT_BUNDLE_IDENTIFIER = "org.reactjs.native.example.JellyfinAudioPlayer-tvOS";
PRODUCT_NAME = "$(TARGET_NAME)";
SDKROOT = appletvos;
TARGETED_DEVICE_FAMILY = 3;
TVOS_DEPLOYMENT_TARGET = 9.2;
};
name = Debug;
};
2D02E4981E0B4A5E006451C7 /* Release */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = B179EFCC51AF0F281E73F0B8 /* Pods-JellyfinAudioPlayer-tvOS.release.xcconfig */;
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = "App Icon & Top Shelf Image";
ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage;
CLANG_ANALYZER_NONNULL = YES;
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
COPY_PHASE_STRIP = NO;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
DEVELOPMENT_TEAM = HD2D35G9Y4;
GCC_NO_COMMON_BLOCKS = YES;
INFOPLIST_FILE = "JellyfinAudioPlayer-tvOS/Info.plist";
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
OTHER_LDFLAGS = (
"$(inherited)",
"-ObjC",
"-lc++",
);
PRODUCT_BUNDLE_IDENTIFIER = "org.reactjs.native.example.JellyfinAudioPlayer-tvOS";
PRODUCT_NAME = "$(TARGET_NAME)";
SDKROOT = appletvos;
TARGETED_DEVICE_FAMILY = 3;
TVOS_DEPLOYMENT_TARGET = 9.2;
};
name = Release;
};
2D02E4991E0B4A5E006451C7 /* Debug */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = 86AD8F7165272727927424B9 /* Pods-JellyfinAudioPlayer-tvOSTests.debug.xcconfig */;
buildSettings = {
BUNDLE_LOADER = "$(TEST_HOST)";
CLANG_ANALYZER_NONNULL = YES;
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
DEBUG_INFORMATION_FORMAT = dwarf;
DEVELOPMENT_TEAM = HD2D35G9Y4;
ENABLE_TESTABILITY = YES;
GCC_NO_COMMON_BLOCKS = YES;
INFOPLIST_FILE = "JellyfinAudioPlayer-tvOSTests/Info.plist";
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
OTHER_LDFLAGS = (
"$(inherited)",
"-ObjC",
"-lc++",
);
PRODUCT_BUNDLE_IDENTIFIER = "org.reactjs.native.example.JellyfinAudioPlayer-tvOSTests";
PRODUCT_NAME = "$(TARGET_NAME)";
SDKROOT = appletvos;
TEST_HOST = "$(BUILT_PRODUCTS_DIR)/JellyfinAudioPlayer-tvOS.app/JellyfinAudioPlayer-tvOS";
TVOS_DEPLOYMENT_TARGET = 10.1;
};
name = Debug;
};
2D02E49A1E0B4A5E006451C7 /* Release */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = 590BEA7DE65819C5B5FDAD06 /* Pods-JellyfinAudioPlayer-tvOSTests.release.xcconfig */;
buildSettings = {
BUNDLE_LOADER = "$(TEST_HOST)";
CLANG_ANALYZER_NONNULL = YES;
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
COPY_PHASE_STRIP = NO;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
DEVELOPMENT_TEAM = HD2D35G9Y4;
GCC_NO_COMMON_BLOCKS = YES;
INFOPLIST_FILE = "JellyfinAudioPlayer-tvOSTests/Info.plist";
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
OTHER_LDFLAGS = (
"$(inherited)",
"-ObjC",
"-lc++",
);
PRODUCT_BUNDLE_IDENTIFIER = "org.reactjs.native.example.JellyfinAudioPlayer-tvOSTests";
PRODUCT_NAME = "$(TARGET_NAME)";
SDKROOT = appletvos;
TEST_HOST = "$(BUILT_PRODUCTS_DIR)/JellyfinAudioPlayer-tvOS.app/JellyfinAudioPlayer-tvOS";
TVOS_DEPLOYMENT_TARGET = 10.1;
};
name = Release;
};
83CBBA201A601CBA00E9B192 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
@@ -822,7 +557,8 @@
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
CODE_SIGN_IDENTITY = "Apple Development";
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "Apple Development";
COPY_PHASE_STRIP = NO;
ENABLE_STRICT_OBJC_MSGSEND = YES;
ENABLE_TESTABILITY = YES;
@@ -882,7 +618,8 @@
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
CODE_SIGN_IDENTITY = "Apple Development";
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "Apple Development";
COPY_PHASE_STRIP = YES;
ENABLE_NS_ASSERTIONS = NO;
ENABLE_STRICT_OBJC_MSGSEND = YES;
@@ -928,24 +665,6 @@
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
2D02E4BA1E0B4A5E006451C7 /* Build configuration list for PBXNativeTarget "JellyfinAudioPlayer-tvOS" */ = {
isa = XCConfigurationList;
buildConfigurations = (
2D02E4971E0B4A5E006451C7 /* Debug */,
2D02E4981E0B4A5E006451C7 /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
2D02E4BB1E0B4A5E006451C7 /* Build configuration list for PBXNativeTarget "JellyfinAudioPlayer-tvOSTests" */ = {
isa = XCConfigurationList;
buildConfigurations = (
2D02E4991E0B4A5E006451C7 /* Debug */,
2D02E49A1E0B4A5E006451C7 /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
83CBB9FA1A601CBA00E9B192 /* Build configuration list for PBXProject "JellyfinAudioPlayer" */ = {
isa = XCConfigurationList;
buildConfigurations = (

View File

@@ -36,7 +36,11 @@ static void InitializeFlipper(UIApplication *application) {
moduleName:@"JellyfinAudioPlayer"
initialProperties:nil];
rootView.backgroundColor = [[UIColor alloc] initWithRed:1.0f green:1.0f blue:1.0f alpha:1];
if (@available(iOS 13.0, *)) {
rootView.backgroundColor = [UIColor systemBackgroundColor];
} else {
rootView.backgroundColor = [UIColor whiteColor];
}
self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
UIViewController *rootViewController = [UIViewController new];

View File

@@ -21,7 +21,7 @@
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string>1</string>
<string>3</string>
<key>LSRequiresIPhoneOS</key>
<true/>
<key>NSAppTransportSecurity</key>
@@ -42,7 +42,7 @@
<key>UIBackgroundModes</key>
<array>
<string>audio</string>
<string>processing</string>
<string>fetch</string>
</array>
<key>UILaunchStoryboardName</key>
<string>LaunchScreen</string>

View File

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

View File

@@ -1,104 +1,21 @@
platform :ios, '10.0'
require_relative '../node_modules/@react-native-community/cli-platform-ios/native_modules'
def add_flipper_pods!(versions = {})
versions['Flipper'] ||= '~> 0.33.1'
versions['DoubleConversion'] ||= '1.1.7'
versions['Flipper-Folly'] ||= '~> 2.1'
versions['Flipper-Glog'] ||= '0.3.6'
versions['Flipper-PeerTalk'] ||= '~> 0.0.4'
versions['Flipper-RSocket'] ||= '~> 1.0'
pod 'FlipperKit', versions['Flipper'], :configuration => 'Debug'
pod 'FlipperKit/FlipperKitLayoutPlugin', versions['Flipper'], :configuration => 'Debug'
pod 'FlipperKit/SKIOSNetworkPlugin', versions['Flipper'], :configuration => 'Debug'
pod 'FlipperKit/FlipperKitUserDefaultsPlugin', versions['Flipper'], :configuration => 'Debug'
pod 'FlipperKit/FlipperKitReactPlugin', versions['Flipper'], :configuration => 'Debug'
# List all transitive dependencies for FlipperKit pods
# to avoid them being linked in Release builds
pod 'Flipper', versions['Flipper'], :configuration => 'Debug'
pod 'Flipper-DoubleConversion', versions['DoubleConversion'], :configuration => 'Debug'
pod 'Flipper-Folly', versions['Flipper-Folly'], :configuration => 'Debug'
pod 'Flipper-Glog', versions['Flipper-Glog'], :configuration => 'Debug'
pod 'Flipper-PeerTalk', versions['Flipper-PeerTalk'], :configuration => 'Debug'
pod 'Flipper-RSocket', versions['Flipper-RSocket'], :configuration => 'Debug'
pod 'FlipperKit/Core', versions['Flipper'], :configuration => 'Debug'
pod 'FlipperKit/CppBridge', versions['Flipper'], :configuration => 'Debug'
pod 'FlipperKit/FBCxxFollyDynamicConvert', versions['Flipper'], :configuration => 'Debug'
pod 'FlipperKit/FBDefines', versions['Flipper'], :configuration => 'Debug'
pod 'FlipperKit/FKPortForwarding', versions['Flipper'], :configuration => 'Debug'
pod 'FlipperKit/FlipperKitHighlightOverlay', versions['Flipper'], :configuration => 'Debug'
pod 'FlipperKit/FlipperKitLayoutTextSearchable', versions['Flipper'], :configuration => 'Debug'
pod 'FlipperKit/FlipperKitNetworkPlugin', versions['Flipper'], :configuration => 'Debug'
end
# Post Install processing for Flipper
def flipper_post_install(installer)
installer.pods_project.targets.each do |target|
if target.name == 'YogaKit'
target.build_configurations.each do |config|
config.build_settings['SWIFT_VERSION'] = '4.1'
end
end
end
end
require_relative '../node_modules/react-native/scripts/react_native_pods'
target 'JellyfinAudioPlayer' do
# Pods for JellyfinAudioPlayer
pod 'FBLazyVector', :path => "../node_modules/react-native/Libraries/FBLazyVector"
pod 'FBReactNativeSpec', :path => "../node_modules/react-native/Libraries/FBReactNativeSpec"
pod 'RCTRequired', :path => "../node_modules/react-native/Libraries/RCTRequired"
pod 'RCTTypeSafety', :path => "../node_modules/react-native/Libraries/TypeSafety"
pod 'React', :path => '../node_modules/react-native/'
pod 'React-Core', :path => '../node_modules/react-native/'
pod 'React-CoreModules', :path => '../node_modules/react-native/React/CoreModules'
pod 'React-Core/DevSupport', :path => '../node_modules/react-native/'
pod 'React-RCTActionSheet', :path => '../node_modules/react-native/Libraries/ActionSheetIOS'
pod 'React-RCTAnimation', :path => '../node_modules/react-native/Libraries/NativeAnimation'
pod 'React-RCTBlob', :path => '../node_modules/react-native/Libraries/Blob'
pod 'React-RCTImage', :path => '../node_modules/react-native/Libraries/Image'
pod 'React-RCTLinking', :path => '../node_modules/react-native/Libraries/LinkingIOS'
pod 'React-RCTNetwork', :path => '../node_modules/react-native/Libraries/Network'
pod 'React-RCTSettings', :path => '../node_modules/react-native/Libraries/Settings'
pod 'React-RCTText', :path => '../node_modules/react-native/Libraries/Text'
pod 'React-RCTVibration', :path => '../node_modules/react-native/Libraries/Vibration'
pod 'React-Core/RCTWebSocket', :path => '../node_modules/react-native/'
pod 'React-cxxreact', :path => '../node_modules/react-native/ReactCommon/cxxreact'
pod 'React-jsi', :path => '../node_modules/react-native/ReactCommon/jsi'
pod 'React-jsiexecutor', :path => '../node_modules/react-native/ReactCommon/jsiexecutor'
pod 'React-jsinspector', :path => '../node_modules/react-native/ReactCommon/jsinspector'
pod 'ReactCommon/callinvoker', :path => "../node_modules/react-native/ReactCommon"
pod 'ReactCommon/turbomodule/core', :path => "../node_modules/react-native/ReactCommon"
pod 'Yoga', :path => '../node_modules/react-native/ReactCommon/yoga', :modular_headers => true
pod 'DoubleConversion', :podspec => '../node_modules/react-native/third-party-podspecs/DoubleConversion.podspec'
pod 'glog', :podspec => '../node_modules/react-native/third-party-podspecs/glog.podspec'
pod 'Folly', :podspec => '../node_modules/react-native/third-party-podspecs/Folly.podspec'
config = use_native_modules!
use_react_native!(:path => config["reactNativePath"])
target 'JellyfinAudioPlayerTests' do
inherit! :complete
# Pods for testing
end
use_native_modules!
# Enables Flipper.
#
# Note that if you have use_frameworks! enabled, Flipper will not work and
# you should disable these next few lines.
add_flipper_pods!
use_flipper!
post_install do |installer|
flipper_post_install(installer)
end
end
target 'JellyfinAudioPlayer-tvOS' do
# Pods for JellyfinAudioPlayer-tvOS
target 'JellyfinAudioPlayer-tvOSTests' do
inherit! :search_paths
# Pods for testing
end
end

View File

@@ -3,17 +3,17 @@ PODS:
- CocoaAsyncSocket (7.6.4)
- CocoaLibEvent (1.0.0)
- DoubleConversion (1.1.6)
- FBLazyVector (0.62.2)
- FBReactNativeSpec (0.62.2):
- Folly (= 2018.10.22.00)
- RCTRequired (= 0.62.2)
- RCTTypeSafety (= 0.62.2)
- React-Core (= 0.62.2)
- React-jsi (= 0.62.2)
- ReactCommon/turbomodule/core (= 0.62.2)
- Flipper (0.33.1):
- Flipper-Folly (~> 2.1)
- Flipper-RSocket (~> 1.0)
- FBLazyVector (0.63.2)
- FBReactNativeSpec (0.63.2):
- Folly (= 2020.01.13.00)
- RCTRequired (= 0.63.2)
- RCTTypeSafety (= 0.63.2)
- React-Core (= 0.63.2)
- React-jsi (= 0.63.2)
- ReactCommon/turbomodule/core (= 0.63.2)
- Flipper (0.41.5):
- Flipper-Folly (~> 2.2)
- Flipper-RSocket (~> 1.1)
- Flipper-DoubleConversion (1.1.7)
- Flipper-Folly (2.2.0):
- boost-for-react-native
@@ -25,44 +25,44 @@ PODS:
- Flipper-PeerTalk (0.0.4)
- Flipper-RSocket (1.1.0):
- Flipper-Folly (~> 2.2)
- FlipperKit (0.33.1):
- FlipperKit/Core (= 0.33.1)
- FlipperKit/Core (0.33.1):
- Flipper (~> 0.33.1)
- FlipperKit (0.41.5):
- FlipperKit/Core (= 0.41.5)
- FlipperKit/Core (0.41.5):
- Flipper (~> 0.41.5)
- FlipperKit/CppBridge
- FlipperKit/FBCxxFollyDynamicConvert
- FlipperKit/FBDefines
- FlipperKit/FKPortForwarding
- FlipperKit/CppBridge (0.33.1):
- Flipper (~> 0.33.1)
- FlipperKit/FBCxxFollyDynamicConvert (0.33.1):
- Flipper-Folly (~> 2.1)
- FlipperKit/FBDefines (0.33.1)
- FlipperKit/FKPortForwarding (0.33.1):
- FlipperKit/CppBridge (0.41.5):
- Flipper (~> 0.41.5)
- FlipperKit/FBCxxFollyDynamicConvert (0.41.5):
- Flipper-Folly (~> 2.2)
- FlipperKit/FBDefines (0.41.5)
- FlipperKit/FKPortForwarding (0.41.5):
- CocoaAsyncSocket (~> 7.6)
- Flipper-PeerTalk (~> 0.0.4)
- FlipperKit/FlipperKitHighlightOverlay (0.33.1)
- FlipperKit/FlipperKitLayoutPlugin (0.33.1):
- FlipperKit/FlipperKitHighlightOverlay (0.41.5)
- FlipperKit/FlipperKitLayoutPlugin (0.41.5):
- FlipperKit/Core
- FlipperKit/FlipperKitHighlightOverlay
- FlipperKit/FlipperKitLayoutTextSearchable
- YogaKit (~> 1.18)
- FlipperKit/FlipperKitLayoutTextSearchable (0.33.1)
- FlipperKit/FlipperKitNetworkPlugin (0.33.1):
- FlipperKit/FlipperKitLayoutTextSearchable (0.41.5)
- FlipperKit/FlipperKitNetworkPlugin (0.41.5):
- FlipperKit/Core
- FlipperKit/FlipperKitReactPlugin (0.33.1):
- FlipperKit/FlipperKitReactPlugin (0.41.5):
- FlipperKit/Core
- FlipperKit/FlipperKitUserDefaultsPlugin (0.33.1):
- FlipperKit/FlipperKitUserDefaultsPlugin (0.41.5):
- FlipperKit/Core
- FlipperKit/SKIOSNetworkPlugin (0.33.1):
- FlipperKit/SKIOSNetworkPlugin (0.41.5):
- FlipperKit/Core
- FlipperKit/FlipperKitNetworkPlugin
- Folly (2018.10.22.00):
- Folly (2020.01.13.00):
- boost-for-react-native
- DoubleConversion
- Folly/Default (= 2018.10.22.00)
- Folly/Default (= 2020.01.13.00)
- glog
- Folly/Default (2018.10.22.00):
- Folly/Default (2020.01.13.00):
- boost-for-react-native
- DoubleConversion
- glog
@@ -79,249 +79,255 @@ PODS:
- OpenSSL-Universal (1.0.2.19):
- OpenSSL-Universal/Static (= 1.0.2.19)
- OpenSSL-Universal/Static (1.0.2.19)
- RCTRequired (0.62.2)
- RCTTypeSafety (0.62.2):
- FBLazyVector (= 0.62.2)
- Folly (= 2018.10.22.00)
- RCTRequired (= 0.62.2)
- React-Core (= 0.62.2)
- React (0.62.2):
- React-Core (= 0.62.2)
- React-Core/DevSupport (= 0.62.2)
- React-Core/RCTWebSocket (= 0.62.2)
- React-RCTActionSheet (= 0.62.2)
- React-RCTAnimation (= 0.62.2)
- React-RCTBlob (= 0.62.2)
- React-RCTImage (= 0.62.2)
- React-RCTLinking (= 0.62.2)
- React-RCTNetwork (= 0.62.2)
- React-RCTSettings (= 0.62.2)
- React-RCTText (= 0.62.2)
- React-RCTVibration (= 0.62.2)
- React-Core (0.62.2):
- Folly (= 2018.10.22.00)
- RCTRequired (0.63.2)
- RCTTypeSafety (0.63.2):
- FBLazyVector (= 0.63.2)
- Folly (= 2020.01.13.00)
- RCTRequired (= 0.63.2)
- React-Core (= 0.63.2)
- React (0.63.2):
- React-Core (= 0.63.2)
- React-Core/DevSupport (= 0.63.2)
- React-Core/RCTWebSocket (= 0.63.2)
- React-RCTActionSheet (= 0.63.2)
- React-RCTAnimation (= 0.63.2)
- React-RCTBlob (= 0.63.2)
- React-RCTImage (= 0.63.2)
- React-RCTLinking (= 0.63.2)
- React-RCTNetwork (= 0.63.2)
- React-RCTSettings (= 0.63.2)
- React-RCTText (= 0.63.2)
- React-RCTVibration (= 0.63.2)
- React-callinvoker (0.63.2)
- React-Core (0.63.2):
- Folly (= 2020.01.13.00)
- glog
- React-Core/Default (= 0.62.2)
- React-cxxreact (= 0.62.2)
- React-jsi (= 0.62.2)
- React-jsiexecutor (= 0.62.2)
- React-Core/Default (= 0.63.2)
- React-cxxreact (= 0.63.2)
- React-jsi (= 0.63.2)
- React-jsiexecutor (= 0.63.2)
- Yoga
- React-Core/CoreModulesHeaders (0.62.2):
- Folly (= 2018.10.22.00)
- React-Core/CoreModulesHeaders (0.63.2):
- Folly (= 2020.01.13.00)
- glog
- React-Core/Default
- React-cxxreact (= 0.62.2)
- React-jsi (= 0.62.2)
- React-jsiexecutor (= 0.62.2)
- React-cxxreact (= 0.63.2)
- React-jsi (= 0.63.2)
- React-jsiexecutor (= 0.63.2)
- Yoga
- React-Core/Default (0.62.2):
- Folly (= 2018.10.22.00)
- React-Core/Default (0.63.2):
- Folly (= 2020.01.13.00)
- glog
- React-cxxreact (= 0.62.2)
- React-jsi (= 0.62.2)
- React-jsiexecutor (= 0.62.2)
- React-cxxreact (= 0.63.2)
- React-jsi (= 0.63.2)
- React-jsiexecutor (= 0.63.2)
- Yoga
- React-Core/DevSupport (0.62.2):
- Folly (= 2018.10.22.00)
- React-Core/DevSupport (0.63.2):
- Folly (= 2020.01.13.00)
- glog
- React-Core/Default (= 0.62.2)
- React-Core/RCTWebSocket (= 0.62.2)
- React-cxxreact (= 0.62.2)
- React-jsi (= 0.62.2)
- React-jsiexecutor (= 0.62.2)
- React-jsinspector (= 0.62.2)
- React-Core/Default (= 0.63.2)
- React-Core/RCTWebSocket (= 0.63.2)
- React-cxxreact (= 0.63.2)
- React-jsi (= 0.63.2)
- React-jsiexecutor (= 0.63.2)
- React-jsinspector (= 0.63.2)
- Yoga
- React-Core/RCTActionSheetHeaders (0.62.2):
- Folly (= 2018.10.22.00)
- React-Core/RCTActionSheetHeaders (0.63.2):
- Folly (= 2020.01.13.00)
- glog
- React-Core/Default
- React-cxxreact (= 0.62.2)
- React-jsi (= 0.62.2)
- React-jsiexecutor (= 0.62.2)
- React-cxxreact (= 0.63.2)
- React-jsi (= 0.63.2)
- React-jsiexecutor (= 0.63.2)
- Yoga
- React-Core/RCTAnimationHeaders (0.62.2):
- Folly (= 2018.10.22.00)
- React-Core/RCTAnimationHeaders (0.63.2):
- Folly (= 2020.01.13.00)
- glog
- React-Core/Default
- React-cxxreact (= 0.62.2)
- React-jsi (= 0.62.2)
- React-jsiexecutor (= 0.62.2)
- React-cxxreact (= 0.63.2)
- React-jsi (= 0.63.2)
- React-jsiexecutor (= 0.63.2)
- Yoga
- React-Core/RCTBlobHeaders (0.62.2):
- Folly (= 2018.10.22.00)
- React-Core/RCTBlobHeaders (0.63.2):
- Folly (= 2020.01.13.00)
- glog
- React-Core/Default
- React-cxxreact (= 0.62.2)
- React-jsi (= 0.62.2)
- React-jsiexecutor (= 0.62.2)
- React-cxxreact (= 0.63.2)
- React-jsi (= 0.63.2)
- React-jsiexecutor (= 0.63.2)
- Yoga
- React-Core/RCTImageHeaders (0.62.2):
- Folly (= 2018.10.22.00)
- React-Core/RCTImageHeaders (0.63.2):
- Folly (= 2020.01.13.00)
- glog
- React-Core/Default
- React-cxxreact (= 0.62.2)
- React-jsi (= 0.62.2)
- React-jsiexecutor (= 0.62.2)
- React-cxxreact (= 0.63.2)
- React-jsi (= 0.63.2)
- React-jsiexecutor (= 0.63.2)
- Yoga
- React-Core/RCTLinkingHeaders (0.62.2):
- Folly (= 2018.10.22.00)
- React-Core/RCTLinkingHeaders (0.63.2):
- Folly (= 2020.01.13.00)
- glog
- React-Core/Default
- React-cxxreact (= 0.62.2)
- React-jsi (= 0.62.2)
- React-jsiexecutor (= 0.62.2)
- React-cxxreact (= 0.63.2)
- React-jsi (= 0.63.2)
- React-jsiexecutor (= 0.63.2)
- Yoga
- React-Core/RCTNetworkHeaders (0.62.2):
- Folly (= 2018.10.22.00)
- React-Core/RCTNetworkHeaders (0.63.2):
- Folly (= 2020.01.13.00)
- glog
- React-Core/Default
- React-cxxreact (= 0.62.2)
- React-jsi (= 0.62.2)
- React-jsiexecutor (= 0.62.2)
- React-cxxreact (= 0.63.2)
- React-jsi (= 0.63.2)
- React-jsiexecutor (= 0.63.2)
- Yoga
- React-Core/RCTSettingsHeaders (0.62.2):
- Folly (= 2018.10.22.00)
- React-Core/RCTSettingsHeaders (0.63.2):
- Folly (= 2020.01.13.00)
- glog
- React-Core/Default
- React-cxxreact (= 0.62.2)
- React-jsi (= 0.62.2)
- React-jsiexecutor (= 0.62.2)
- React-cxxreact (= 0.63.2)
- React-jsi (= 0.63.2)
- React-jsiexecutor (= 0.63.2)
- Yoga
- React-Core/RCTTextHeaders (0.62.2):
- Folly (= 2018.10.22.00)
- React-Core/RCTTextHeaders (0.63.2):
- Folly (= 2020.01.13.00)
- glog
- React-Core/Default
- React-cxxreact (= 0.62.2)
- React-jsi (= 0.62.2)
- React-jsiexecutor (= 0.62.2)
- React-cxxreact (= 0.63.2)
- React-jsi (= 0.63.2)
- React-jsiexecutor (= 0.63.2)
- Yoga
- React-Core/RCTVibrationHeaders (0.62.2):
- Folly (= 2018.10.22.00)
- React-Core/RCTVibrationHeaders (0.63.2):
- Folly (= 2020.01.13.00)
- glog
- React-Core/Default
- React-cxxreact (= 0.62.2)
- React-jsi (= 0.62.2)
- React-jsiexecutor (= 0.62.2)
- React-cxxreact (= 0.63.2)
- React-jsi (= 0.63.2)
- React-jsiexecutor (= 0.63.2)
- Yoga
- React-Core/RCTWebSocket (0.62.2):
- Folly (= 2018.10.22.00)
- React-Core/RCTWebSocket (0.63.2):
- Folly (= 2020.01.13.00)
- glog
- React-Core/Default (= 0.62.2)
- React-cxxreact (= 0.62.2)
- React-jsi (= 0.62.2)
- React-jsiexecutor (= 0.62.2)
- React-Core/Default (= 0.63.2)
- React-cxxreact (= 0.63.2)
- React-jsi (= 0.63.2)
- React-jsiexecutor (= 0.63.2)
- Yoga
- React-CoreModules (0.62.2):
- FBReactNativeSpec (= 0.62.2)
- Folly (= 2018.10.22.00)
- RCTTypeSafety (= 0.62.2)
- React-Core/CoreModulesHeaders (= 0.62.2)
- React-RCTImage (= 0.62.2)
- ReactCommon/turbomodule/core (= 0.62.2)
- React-cxxreact (0.62.2):
- React-CoreModules (0.63.2):
- FBReactNativeSpec (= 0.63.2)
- Folly (= 2020.01.13.00)
- RCTTypeSafety (= 0.63.2)
- React-Core/CoreModulesHeaders (= 0.63.2)
- React-jsi (= 0.63.2)
- React-RCTImage (= 0.63.2)
- ReactCommon/turbomodule/core (= 0.63.2)
- React-cxxreact (0.63.2):
- boost-for-react-native (= 1.63.0)
- DoubleConversion
- Folly (= 2018.10.22.00)
- Folly (= 2020.01.13.00)
- glog
- React-jsinspector (= 0.62.2)
- React-jsi (0.62.2):
- React-callinvoker (= 0.63.2)
- React-jsinspector (= 0.63.2)
- React-jsi (0.63.2):
- boost-for-react-native (= 1.63.0)
- DoubleConversion
- Folly (= 2018.10.22.00)
- Folly (= 2020.01.13.00)
- glog
- React-jsi/Default (= 0.62.2)
- React-jsi/Default (0.62.2):
- React-jsi/Default (= 0.63.2)
- React-jsi/Default (0.63.2):
- boost-for-react-native (= 1.63.0)
- DoubleConversion
- Folly (= 2018.10.22.00)
- Folly (= 2020.01.13.00)
- glog
- React-jsiexecutor (0.62.2):
- React-jsiexecutor (0.63.2):
- DoubleConversion
- Folly (= 2018.10.22.00)
- Folly (= 2020.01.13.00)
- glog
- React-cxxreact (= 0.62.2)
- React-jsi (= 0.62.2)
- React-jsinspector (0.62.2)
- react-native-safe-area-context (3.0.7):
- React-cxxreact (= 0.63.2)
- React-jsi (= 0.63.2)
- React-jsinspector (0.63.2)
- react-native-appearance (0.3.4):
- React
- react-native-slider (3.0.0):
- react-native-safe-area-context (3.1.1):
- React
- react-native-slider (3.0.3):
- React
- react-native-track-player (1.2.3):
- React
- react-native-webview (10.3.2):
- React
- React-RCTActionSheet (0.62.2):
- React-Core/RCTActionSheetHeaders (= 0.62.2)
- React-RCTAnimation (0.62.2):
- FBReactNativeSpec (= 0.62.2)
- Folly (= 2018.10.22.00)
- RCTTypeSafety (= 0.62.2)
- React-Core/RCTAnimationHeaders (= 0.62.2)
- ReactCommon/turbomodule/core (= 0.62.2)
- React-RCTBlob (0.62.2):
- FBReactNativeSpec (= 0.62.2)
- Folly (= 2018.10.22.00)
- React-Core/RCTBlobHeaders (= 0.62.2)
- React-Core/RCTWebSocket (= 0.62.2)
- React-jsi (= 0.62.2)
- React-RCTNetwork (= 0.62.2)
- ReactCommon/turbomodule/core (= 0.62.2)
- React-RCTImage (0.62.2):
- FBReactNativeSpec (= 0.62.2)
- Folly (= 2018.10.22.00)
- RCTTypeSafety (= 0.62.2)
- React-Core/RCTImageHeaders (= 0.62.2)
- React-RCTNetwork (= 0.62.2)
- ReactCommon/turbomodule/core (= 0.62.2)
- React-RCTLinking (0.62.2):
- FBReactNativeSpec (= 0.62.2)
- React-Core/RCTLinkingHeaders (= 0.62.2)
- ReactCommon/turbomodule/core (= 0.62.2)
- React-RCTNetwork (0.62.2):
- FBReactNativeSpec (= 0.62.2)
- Folly (= 2018.10.22.00)
- RCTTypeSafety (= 0.62.2)
- React-Core/RCTNetworkHeaders (= 0.62.2)
- ReactCommon/turbomodule/core (= 0.62.2)
- React-RCTSettings (0.62.2):
- FBReactNativeSpec (= 0.62.2)
- Folly (= 2018.10.22.00)
- RCTTypeSafety (= 0.62.2)
- React-Core/RCTSettingsHeaders (= 0.62.2)
- ReactCommon/turbomodule/core (= 0.62.2)
- React-RCTText (0.62.2):
- React-Core/RCTTextHeaders (= 0.62.2)
- React-RCTVibration (0.62.2):
- FBReactNativeSpec (= 0.62.2)
- Folly (= 2018.10.22.00)
- React-Core/RCTVibrationHeaders (= 0.62.2)
- ReactCommon/turbomodule/core (= 0.62.2)
- ReactCommon/callinvoker (0.62.2):
- React-RCTActionSheet (0.63.2):
- React-Core/RCTActionSheetHeaders (= 0.63.2)
- React-RCTAnimation (0.63.2):
- FBReactNativeSpec (= 0.63.2)
- Folly (= 2020.01.13.00)
- RCTTypeSafety (= 0.63.2)
- React-Core/RCTAnimationHeaders (= 0.63.2)
- React-jsi (= 0.63.2)
- ReactCommon/turbomodule/core (= 0.63.2)
- React-RCTBlob (0.63.2):
- FBReactNativeSpec (= 0.63.2)
- Folly (= 2020.01.13.00)
- React-Core/RCTBlobHeaders (= 0.63.2)
- React-Core/RCTWebSocket (= 0.63.2)
- React-jsi (= 0.63.2)
- React-RCTNetwork (= 0.63.2)
- ReactCommon/turbomodule/core (= 0.63.2)
- React-RCTImage (0.63.2):
- FBReactNativeSpec (= 0.63.2)
- Folly (= 2020.01.13.00)
- RCTTypeSafety (= 0.63.2)
- React-Core/RCTImageHeaders (= 0.63.2)
- React-jsi (= 0.63.2)
- React-RCTNetwork (= 0.63.2)
- ReactCommon/turbomodule/core (= 0.63.2)
- React-RCTLinking (0.63.2):
- FBReactNativeSpec (= 0.63.2)
- React-Core/RCTLinkingHeaders (= 0.63.2)
- React-jsi (= 0.63.2)
- ReactCommon/turbomodule/core (= 0.63.2)
- React-RCTNetwork (0.63.2):
- FBReactNativeSpec (= 0.63.2)
- Folly (= 2020.01.13.00)
- RCTTypeSafety (= 0.63.2)
- React-Core/RCTNetworkHeaders (= 0.63.2)
- React-jsi (= 0.63.2)
- ReactCommon/turbomodule/core (= 0.63.2)
- React-RCTSettings (0.63.2):
- FBReactNativeSpec (= 0.63.2)
- Folly (= 2020.01.13.00)
- RCTTypeSafety (= 0.63.2)
- React-Core/RCTSettingsHeaders (= 0.63.2)
- React-jsi (= 0.63.2)
- ReactCommon/turbomodule/core (= 0.63.2)
- React-RCTText (0.63.2):
- React-Core/RCTTextHeaders (= 0.63.2)
- React-RCTVibration (0.63.2):
- FBReactNativeSpec (= 0.63.2)
- Folly (= 2020.01.13.00)
- React-Core/RCTVibrationHeaders (= 0.63.2)
- React-jsi (= 0.63.2)
- ReactCommon/turbomodule/core (= 0.63.2)
- ReactCommon/turbomodule/core (0.63.2):
- DoubleConversion
- Folly (= 2018.10.22.00)
- Folly (= 2020.01.13.00)
- glog
- React-cxxreact (= 0.62.2)
- ReactCommon/turbomodule/core (0.62.2):
- DoubleConversion
- Folly (= 2018.10.22.00)
- glog
- React-Core (= 0.62.2)
- React-cxxreact (= 0.62.2)
- React-jsi (= 0.62.2)
- ReactCommon/callinvoker (= 0.62.2)
- React-callinvoker (= 0.63.2)
- React-Core (= 0.63.2)
- React-cxxreact (= 0.63.2)
- React-jsi (= 0.63.2)
- RNCAsyncStorage (1.11.0):
- React
- RNCMaskedView (0.1.10):
- React
- RNCPicker (1.6.5):
- React
- RNFastImage (8.1.5):
- RNFastImage (8.3.2):
- React
- SDWebImage (~> 5.0)
- SDWebImageWebPCoder (~> 0.4.1)
- RNGestureHandler (1.6.1):
- SDWebImage (~> 5.8)
- SDWebImageWebPCoder (~> 0.6.1)
- RNGestureHandler (1.7.0):
- React
- RNReanimated (1.9.0):
- RNReanimated (1.10.1):
- React
- RNScreens (2.9.0):
- React
@@ -330,9 +336,9 @@ PODS:
- SDWebImage (5.8.1):
- SDWebImage/Core (= 5.8.1)
- SDWebImage/Core (5.8.1)
- SDWebImageWebPCoder (0.4.1):
- SDWebImageWebPCoder (0.6.1):
- libwebp (~> 1.0)
- SDWebImage/Core (~> 5.5)
- SDWebImage/Core (~> 5.7)
- Yoga (1.14.0)
- YogaKit (1.18.1):
- Yoga (~> 1.14)
@@ -341,30 +347,31 @@ DEPENDENCIES:
- 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.33.1)
- Flipper (~> 0.41.1)
- Flipper-DoubleConversion (= 1.1.7)
- Flipper-Folly (~> 2.1)
- Flipper-Folly (~> 2.2)
- Flipper-Glog (= 0.3.6)
- Flipper-PeerTalk (~> 0.0.4)
- Flipper-RSocket (~> 1.0)
- FlipperKit (~> 0.33.1)
- FlipperKit/Core (~> 0.33.1)
- FlipperKit/CppBridge (~> 0.33.1)
- FlipperKit/FBCxxFollyDynamicConvert (~> 0.33.1)
- FlipperKit/FBDefines (~> 0.33.1)
- FlipperKit/FKPortForwarding (~> 0.33.1)
- FlipperKit/FlipperKitHighlightOverlay (~> 0.33.1)
- FlipperKit/FlipperKitLayoutPlugin (~> 0.33.1)
- FlipperKit/FlipperKitLayoutTextSearchable (~> 0.33.1)
- FlipperKit/FlipperKitNetworkPlugin (~> 0.33.1)
- FlipperKit/FlipperKitReactPlugin (~> 0.33.1)
- FlipperKit/FlipperKitUserDefaultsPlugin (~> 0.33.1)
- FlipperKit/SKIOSNetworkPlugin (~> 0.33.1)
- Flipper-RSocket (~> 1.1)
- FlipperKit (~> 0.41.1)
- FlipperKit/Core (~> 0.41.1)
- FlipperKit/CppBridge (~> 0.41.1)
- FlipperKit/FBCxxFollyDynamicConvert (~> 0.41.1)
- FlipperKit/FBDefines (~> 0.41.1)
- FlipperKit/FKPortForwarding (~> 0.41.1)
- FlipperKit/FlipperKitHighlightOverlay (~> 0.41.1)
- FlipperKit/FlipperKitLayoutPlugin (~> 0.41.1)
- FlipperKit/FlipperKitLayoutTextSearchable (~> 0.41.1)
- FlipperKit/FlipperKitNetworkPlugin (~> 0.41.1)
- FlipperKit/FlipperKitReactPlugin (~> 0.41.1)
- FlipperKit/FlipperKitUserDefaultsPlugin (~> 0.41.1)
- FlipperKit/SKIOSNetworkPlugin (~> 0.41.1)
- Folly (from `../node_modules/react-native/third-party-podspecs/Folly.podspec`)
- glog (from `../node_modules/react-native/third-party-podspecs/glog.podspec`)
- RCTRequired (from `../node_modules/react-native/Libraries/RCTRequired`)
- RCTTypeSafety (from `../node_modules/react-native/Libraries/TypeSafety`)
- React (from `../node_modules/react-native/`)
- React-callinvoker (from `../node_modules/react-native/ReactCommon/callinvoker`)
- React-Core (from `../node_modules/react-native/`)
- React-Core/DevSupport (from `../node_modules/react-native/`)
- React-Core/RCTWebSocket (from `../node_modules/react-native/`)
@@ -373,6 +380,7 @@ 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-native-appearance (from `../node_modules/react-native-appearance`)
- 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`)
@@ -386,7 +394,6 @@ 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`)
- ReactCommon/callinvoker (from `../node_modules/react-native/ReactCommon`)
- 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`)"
@@ -433,6 +440,8 @@ EXTERNAL SOURCES:
:path: "../node_modules/react-native/Libraries/TypeSafety"
React:
:path: "../node_modules/react-native/"
React-callinvoker:
:path: "../node_modules/react-native/ReactCommon/callinvoker"
React-Core:
:path: "../node_modules/react-native/"
React-CoreModules:
@@ -445,6 +454,8 @@ EXTERNAL SOURCES:
:path: "../node_modules/react-native/ReactCommon/jsiexecutor"
React-jsinspector:
:path: "../node_modules/react-native/ReactCommon/jsinspector"
react-native-appearance:
:path: "../node_modules/react-native-appearance"
react-native-safe-area-context:
:path: "../node_modules/react-native-safe-area-context"
react-native-slider:
@@ -496,56 +507,58 @@ SPEC CHECKSUMS:
boost-for-react-native: 39c7adb57c4e60d6c5479dd8623128eb5b3f0f2c
CocoaAsyncSocket: 694058e7c0ed05a9e217d1b3c7ded962f4180845
CocoaLibEvent: 2fab71b8bd46dd33ddb959f7928ec5909f838e3f
DoubleConversion: 5805e889d232975c086db112ece9ed034df7a0b2
FBLazyVector: 4aab18c93cd9546e4bfed752b4084585eca8b245
FBReactNativeSpec: 5465d51ccfeecb7faa12f9ae0024f2044ce4044e
Flipper: 6c1f484f9a88d30ab3e272800d53688439e50f69
DoubleConversion: cde416483dac037923206447da6e1454df403714
FBLazyVector: 3ef4a7f62e7db01092f9d517d2ebc0d0677c4a37
FBReactNativeSpec: dc7fa9088f0f2a998503a352b0554d69a4391c5a
Flipper: 33585e2d9810fe5528346be33bcf71b37bb7ae13
Flipper-DoubleConversion: 38631e41ef4f9b12861c67d17cb5518d06badc41
Flipper-Folly: c12092ea368353b58e992843a990a3225d4533c3
Flipper-Glog: 1dfd6abf1e922806c52ceb8701a3599a79a200a6
Flipper-PeerTalk: 116d8f857dc6ef55c7a5a75ea3ceaafe878aadc9
Flipper-RSocket: 64e7431a55835eb953b0bf984ef3b90ae9fdddd7
FlipperKit: 6dc9b8f4ef60d9e5ded7f0264db299c91f18832e
Folly: 30e7936e1c45c08d884aa59369ed951a8e68cf51
glog: 1f3da668190260b06b429bb211bfbee5cd790c28
FlipperKit: bc68102cd4952a258a23c9c1b316c7bec1fecf83
Folly: b73c3869541e86821df3c387eb0af5f65addfab4
glog: 40a13f7840415b9a77023fbcae0f1e6f43192af3
libwebp: 946cb3063cea9236285f7e9a8505d806d30e07f3
OpenSSL-Universal: 8b48cc0d10c1b2923617dfe5c178aa9ed2689355
RCTRequired: cec6a34b3ac8a9915c37e7e4ad3aa74726ce4035
RCTTypeSafety: 93006131180074cffa227a1075802c89a49dd4ce
React: 29a8b1a02bd764fb7644ef04019270849b9a7ac3
React-Core: b12bffb3f567fdf99510acb716ef1abd426e0e05
React-CoreModules: 4a9b87bbe669d6c3173c0132c3328e3b000783d0
React-cxxreact: e65f9c2ba0ac5be946f53548c1aaaee5873a8103
React-jsi: b6dc94a6a12ff98e8877287a0b7620d365201161
React-jsiexecutor: 1540d1c01bb493ae3124ed83351b1b6a155db7da
React-jsinspector: 512e560d0e985d0e8c479a54a4e5c147a9c83493
react-native-safe-area-context: c39fc20a20cd66ebf1d56c6f8b8711142fbfee98
react-native-slider: 05f11678260cb27c3d00a2dd1558b623be3ec8d2
RCTRequired: f13f25e7b12f925f1f6a6a8c69d929a03c0129fe
RCTTypeSafety: 44982c5c8e43ff4141eb519a8ddc88059acd1f3a
React: e1c65dd41cb9db13b99f24608e47dd595f28ca9a
React-callinvoker: 552a6a6bc8b3bb794cf108ad59e5a9e2e3b4fc98
React-Core: 9d341e725dc9cd2f49e4c49ad1fc4e8776aa2639
React-CoreModules: 5335e168165da7f7083ce7147768d36d3e292318
React-cxxreact: d3261ec5f7d11743fbf21e263a34ea51d1f13ebc
React-jsi: 54245e1d5f4b690dec614a73a3795964eeef13a8
React-jsiexecutor: 8ca588cc921e70590820ce72b8789b02c67cce38
React-jsinspector: b14e62ebe7a66e9231e9581279909f2fc3db6606
react-native-appearance: fc2014516054585d531e07aa0b40ab0de1d2be85
react-native-safe-area-context: 4c3249e4840225c61fcd215b136af0a737bccb79
react-native-slider: b733e17fdd31186707146debf1f04b5d94aa1a93
react-native-track-player: ba2416753b58f3cdf9db5a07daa65876d659f925
react-native-webview: e2c0bce9a1a7c7edd4eb30f0c3016fce216245ce
React-RCTActionSheet: f41ea8a811aac770e0cc6e0ad6b270c644ea8b7c
React-RCTAnimation: 49ab98b1c1ff4445148b72a3d61554138565bad0
React-RCTBlob: a332773f0ebc413a0ce85942a55b064471587a71
React-RCTImage: e70be9b9c74fe4e42d0005f42cace7981c994ac3
React-RCTLinking: c1b9739a88d56ecbec23b7f63650e44672ab2ad2
React-RCTNetwork: 73138b6f45e5a2768ad93f3d57873c2a18d14b44
React-RCTSettings: 6e3738a87e21b39a8cb08d627e68c44acf1e325a
React-RCTText: fae545b10cfdb3d247c36c56f61a94cfd6dba41d
React-RCTVibration: 4356114dbcba4ce66991096e51a66e61eda51256
ReactCommon: ed4e11d27609d571e7eee8b65548efc191116eb3
RNCAsyncStorage: d059c3ee71738c39834a627476322a5a8cd5bf36
React-RCTActionSheet: 910163b6b09685a35c4ebbc52b66d1bfbbe39fc5
React-RCTAnimation: 9a883bbe1e9d2e158d4fb53765ed64c8dc2200c6
React-RCTBlob: 39cf0ece1927996c4466510e25d2105f67010e13
React-RCTImage: de355d738727b09ad3692f2a979affbd54b5f378
React-RCTLinking: 8122f221d395a63364b2c0078ce284214bd04575
React-RCTNetwork: 8f96c7b49ea6a0f28f98258f347b6ad218bc0830
React-RCTSettings: 8a49622aff9c1925f5455fa340b6fe4853d64ab6
React-RCTText: 1b6773e776e4b33f90468c20fe3b16ca3e224bb8
React-RCTVibration: 4d2e726957f4087449739b595f107c0d4b6c2d2d
ReactCommon: a0a1edbebcac5e91338371b72ffc66aa822792ce
RNCAsyncStorage: db711e29e5e0500d9bd21aa0c2e397efa45302b1
RNCMaskedView: f5c7d14d6847b7b44853f7acb6284c1da30a3459
RNCPicker: 55b9b4240d0a9eba8733d02616775d4040de2e7d
RNFastImage: 35ae972d6727c84ee3f5c6897e07f84d0a3445e9
RNGestureHandler: 8f09cd560f8d533eb36da5a6c5a843af9f056b38
RNReanimated: b5ccb50650ba06f6e749c7c329a1bc3ae0c88b43
RNFastImage: e19ba191922e7dab9d932a4d59d62d76660aa222
RNGestureHandler: b6b359bb800ae399a9c8b27032bdbf7c18f08a08
RNReanimated: c2bb7438b57a3d987bb2e4e6e4bca94787e30b02
RNScreens: c526239bbe0e957b988dacc8d75ac94ec9cb19da
RNSVG: ce9d996113475209013317e48b05c21ee988d42e
SDWebImage: e3eae2eda88578db0685a0c88597fdadd9433f05
SDWebImageWebPCoder: 36f8f47bd9879a8aea6044765c1351120fd8e3a8
Yoga: 3ebccbdd559724312790e7742142d062476b698e
SDWebImageWebPCoder: d0dac55073088d24b2ac1b191a71a8f8d0adac21
Yoga: 7740b94929bbacbddda59bf115b5317e9a161598
YogaKit: f782866e155069a2cca2517aafea43200b01fd5a
PODFILE CHECKSUM: 34db80daea4bf9020013707ff198a8e43d5808ec
PODFILE CHECKSUM: 2d28e638928312f9630682b819df0581e381449e
COCOAPODS: 1.9.1

8276
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -1,7 +1,7 @@
{
"name": "JellyfinAudioPlayer",
"version": "0.0.1",
"main": "src/index.ts",
"main": "src/index.js",
"private": true,
"scripts": {
"android": "react-native run-android",
@@ -15,52 +15,53 @@
"@react-native-community/async-storage": "^1.11.0",
"@react-native-community/masked-view": "^0.1.10",
"@react-native-community/picker": "^1.6.5",
"@react-native-community/slider": "^3.0.0",
"@react-navigation/bottom-tabs": "^5.6.1",
"@react-navigation/native": "^5.6.1",
"@react-navigation/stack": "^5.6.2",
"@react-native-community/slider": "^3.0.3",
"@react-navigation/bottom-tabs": "^5.7.2",
"@react-navigation/native": "^5.7.1",
"@react-navigation/stack": "^5.7.1",
"@reduxjs/toolkit": "^1.4.0",
"@types/lodash": "^4.14.157",
"@types/lodash": "^4.14.158",
"@types/redux-logger": "^3.0.8",
"@types/styled-components": "^5.1.0",
"date-fns": "^2.14.0",
"@types/styled-components": "^5.1.1",
"date-fns": "^2.15.0",
"fuse.js": "^6.4.0",
"lodash": "^4.17.15",
"react": "16.11.0",
"react-native": "0.62.2",
"react-native-fast-image": "^8.1.5",
"react-native-gesture-handler": "^1.6.1",
"react-native-reanimated": "^1.9.0",
"react-native-safe-area-context": "^3.0.7",
"lodash": "^4.17.19",
"react": "^16.13.1",
"react-native": "^0.63.2",
"react-native-appearance": "^0.3.4",
"react-native-fast-image": "^8.3.2",
"react-native-gesture-handler": "^1.7.0",
"react-native-reanimated": "^1.10.1",
"react-native-safe-area-context": "^3.1.1",
"react-native-screens": "^2.9.0",
"react-native-svg": "^12.1.0",
"react-native-svg-transformer": "^0.14.3",
"react-native-track-player": "github:leinelissen/react-native-track-player",
"react-native-webview": "^10.3.2",
"react-redux": "^7.2.0",
"react-redux": "^7.2.1",
"redux": "^4.0.5",
"redux-logger": "^3.0.6",
"redux-persist": "^6.0.0",
"styled-components": "^5.1.1"
},
"devDependencies": {
"@babel/core": "^7.10.4",
"@babel/runtime": "^7.10.4",
"@react-native-community/eslint-config": "^1.0.0",
"@types/jest": "^24.0.24",
"@types/react-native": "^0.62.17",
"@babel/core": "^7.10.5",
"@babel/runtime": "^7.10.5",
"@react-native-community/eslint-config": "^2.0.0",
"@types/jest": "^26.0.7",
"@types/react-native": "^0.63.2",
"@types/react-redux": "^7.1.9",
"@types/react-test-renderer": "16.9.2",
"@typescript-eslint/eslint-plugin": "^2.27.0",
"@typescript-eslint/parser": "^2.27.0",
"babel-jest": "^24.9.0",
"@typescript-eslint/eslint-plugin": "^3.7.0",
"@typescript-eslint/parser": "^3.7.0",
"babel-jest": "^26.1.0",
"babel-plugin-module-resolver": "^4.0.0",
"eslint": "^6.5.1",
"eslint-plugin-react-hooks": "^4.0.5",
"jest": "^24.9.0",
"metro-react-native-babel-preset": "^0.58.0",
"react-test-renderer": "16.11.0",
"typescript": "^3.9.6"
"eslint": "^7.5.0",
"eslint-plugin-react-hooks": "^4.0.8",
"jest": "^26.1.0",
"metro-react-native-babel-preset": "^0.61.0",
"react-test-renderer": "^16.13.1",
"typescript": "^3.9.7"
},
"jest": {
"preset": "react-native",

Binary file not shown.

After

Width:  |  Height:  |  Size: 102 KiB

View File

@@ -2,19 +2,27 @@ import React, { Component } from 'react';
import { Provider } from 'react-redux';
import TrackPlayer from 'react-native-track-player';
import { PersistGate } from 'redux-persist/integration/react';
import { NavigationContainer } from '@react-navigation/native';
import { AppearanceProvider, Appearance, AppearanceListener } from 'react-native-appearance';
import Routes from '../screens';
import store, { persistedStore } from 'store';
import {
NavigationContainer,
DefaultTheme,
DarkTheme,
} from '@react-navigation/native';
interface State {
isReady: boolean;
colorScheme?: string;
}
export default class App extends Component<State> {
state = {
isReady: false
export default class App extends Component<{}, State> {
state: State = {
isReady: false,
};
subscription = null;
async componentDidMount() {
await TrackPlayer.setupPlayer();
await TrackPlayer.updateOptions({
@@ -27,11 +35,20 @@ export default class App extends Component<State> {
TrackPlayer.CAPABILITY_SEEK_TO,
]
});
this.setState({ isReady: true });
this.subscription = Appearance.addChangeListener(this.setScheme);
this.setState({ isReady: true, colorScheme: Appearance.getColorScheme() });
}
componentWillUnmount() {
this.subscription?.remove();
}
setScheme: AppearanceListener = ({ colorScheme }) => {
this.setState({ colorScheme });
}
render() {
const { isReady } = this.state;
const { isReady, colorScheme } = this.state;
if (!isReady) {
return null;
@@ -40,9 +57,11 @@ export default class App extends Component<State> {
return (
<Provider store={store}>
<PersistGate loading={null} persistor={persistedStore}>
<NavigationContainer>
<Routes />
</NavigationContainer>
<AppearanceProvider>
<NavigationContainer theme={colorScheme === 'dark' ? DarkTheme : DefaultTheme}>
<Routes />
</NavigationContainer>
</AppearanceProvider>
</PersistGate>
</Provider>
);

View File

@@ -0,0 +1,26 @@
import { StyleSheet, PlatformColor } from 'react-native';
import { THEME_COLOR } from 'CONSTANTS';
export const colors = StyleSheet.create({
text: {
color: PlatformColor('?attr/colorOnBackground'),
},
view: {
backgroundColor: PlatformColor('?android:colorBackground'),
},
border: {
borderColor: '#88888844'
},
activeBackground: {
backgroundColor: `${THEME_COLOR}44`,
},
imageBackground: {
backgroundColor: PlatformColor('?attr/colorBackgroundFloating'),
},
modal: {
backgroundColor: PlatformColor('?attr/colorBackgroundFloating'),
},
input: {
backgroundColor: PlatformColor('?attr/colorBackgroundFloating'),
}
});

View File

@@ -0,0 +1,27 @@
import { StyleSheet, PlatformColor, DynamicColorIOS } from 'react-native';
import { THEME_COLOR } from 'CONSTANTS';
export const colors = StyleSheet.create({
text: {
color: PlatformColor('label'),
},
view: {
backgroundColor: PlatformColor('systemBackground'),
},
border: {
borderColor: PlatformColor('systemGray5Color'),
},
activeBackground: {
backgroundColor: DynamicColorIOS({ light: `${THEME_COLOR}16`, dark: `${THEME_COLOR}66` })
},
imageBackground: {
backgroundColor: PlatformColor('systemGray5Color')
},
modal: {
backgroundColor: DynamicColorIOS({ light: '#eeeeeeee', dark: '#222222ee' })
},
input: {
backgroundColor: PlatformColor('systemGray5Color'),
color: PlatformColor('label'),
}
});

View File

@@ -2,7 +2,6 @@ import styled from 'styled-components/native';
const Input = styled.TextInput`
margin: 10px 0;
background-color: #f6f6f6;
border-radius: 5px;
padding: 15px;
`;

View File

@@ -3,20 +3,20 @@ import { TouchableOpacityProps, Text } from 'react-native';
import ChevronRight from 'assets/chevron-right.svg';
import styled from 'styled-components/native';
import { THEME_COLOR } from 'CONSTANTS';
import { colors } from './Colors';
const BUTTON_SIZE = 14;
const Container = styled.TouchableOpacity`
padding: 18px 0;
border-bottom-width: 1px;
border-bottom-color: #eee;
flex-direction: row;
justify-content: space-between;
`;
const ListButton: React.FC<TouchableOpacityProps> = ({ children, ...props }) => {
return (
<Container {...props}>
<Container {...props} style={colors.border}>
<Text style={{ color: THEME_COLOR, fontSize: 16 }}>{children}</Text>
<ChevronRight width={BUTTON_SIZE} height={BUTTON_SIZE} fill={THEME_COLOR} />
</Container>

View File

@@ -1,24 +1,23 @@
import React from 'react';
import styled from 'styled-components/native';
import { SafeAreaView } from 'react-native';
import { colors } from './Colors';
const Background = styled.View`
background-color: #eeeeeeee;
padding: 100px 25px;
flex: 1;
`;
const Container = styled.View`
background-color: white;
border-radius: 20px;
flex: 1;
`;
const Modal: React.FC = ({ children }) => {
return (
<Background>
<SafeAreaView style={{ flex: 1}}>
<Container>
<Background style={colors.modal}>
<SafeAreaView style={{ flex: 1 }}>
<Container style={colors.view}>
{children}
</Container>
</SafeAreaView>

View File

@@ -1,6 +1,6 @@
import React, { useCallback, useEffect } from 'react';
import { StackParams } from '../types';
import { Text, ScrollView, Dimensions, Button, RefreshControl } from 'react-native';
import { Text, ScrollView, Dimensions, Button, RefreshControl, StyleSheet } from 'react-native';
import { useGetImage } from 'utility/JellyfinApi';
import styled, { css } from 'styled-components/native';
import { useRoute, RouteProp } from '@react-navigation/native';
@@ -14,11 +14,32 @@ import usePlayAlbum from 'utility/usePlayAlbum';
import usePlayTrack from 'utility/usePlayTrack';
import TouchableHandler from 'components/TouchableHandler';
import useCurrentTrack from 'utility/useCurrentTrack';
import { colors } from 'components/Colors';
type Route = RouteProp<StackParams, 'Album'>;
const Screen = Dimensions.get('screen');
const styles = StyleSheet.create({
name: {
...colors.text,
fontSize: 36,
fontWeight: 'bold'
},
artist: {
...colors.text,
fontSize: 24,
opacity: 0.5,
marginBottom: 24
},
index: {
...colors.text,
width: 20,
opacity: 0.5,
marginRight: 5
}
});
const AlbumImage = styled(FastImage)`
border-radius: 10px;
width: ${Screen.width * 0.6}px;
@@ -29,7 +50,6 @@ const AlbumImage = styled(FastImage)`
const TrackContainer = styled.View<{isPlaying: boolean}>`
padding: 15px;
border-bottom-width: 1px;
border-bottom-color: #eee;
flex-direction: row;
${props => props.isPlaying && css`
@@ -71,22 +91,22 @@ const Album: React.FC = () => {
return (
<ScrollView
style={{ backgroundColor: '#f6f6f6', padding: 20, paddingBottom: 50 }}
contentContainerStyle={{ padding: 20, paddingBottom: 50 }}
refreshControl={
<RefreshControl refreshing={isLoading} onRefresh={refresh} />
}
>
<AlbumImage source={{ uri: getImage(album?.Id) }} />
<Text style={{ fontSize: 36, fontWeight: 'bold' }} >{album?.Name}</Text>
<Text style={{ fontSize: 24, opacity: 0.5, marginBottom: 24 }}>{album?.AlbumArtist}</Text>
<AlbumImage source={{ uri: getImage(album?.Id) }} style={colors.imageBackground} />
<Text style={styles.name} >{album?.Name}</Text>
<Text style={styles.artist}>{album?.AlbumArtist}</Text>
<Button title="Play Album" onPress={selectAlbum} color={THEME_COLOR} />
{album?.Tracks?.length ? album.Tracks.map((trackId) =>
<TouchableHandler key={trackId} id={trackId} onPress={selectTrack}>
<TrackContainer isPlaying={currentTrack?.id.startsWith(trackId) || false}>
<Text style={{ width: 20, opacity: 0.5, marginRight: 5 }}>
<TrackContainer isPlaying={currentTrack?.id.startsWith(trackId) || false} style={colors.border}>
<Text style={styles.index}>
{tracks[trackId]?.IndexNumber}
</Text>
<Text>{tracks[trackId]?.Name}</Text>
<Text style={colors.text}>{tracks[trackId]?.Name}</Text>
</TrackContainer>
</TouchableHandler>
) : undefined}

View File

@@ -15,6 +15,7 @@ import { selectAlbumsByAlphabet, SectionedId } from 'store/music/selectors';
import AlphabetScroller from 'components/AlphabetScroller';
import { EntityId } from '@reduxjs/toolkit';
import styled from 'styled-components/native';
import { colors } from 'components/Colors';
interface VirtualizedItemInfo {
section: SectionedId,
@@ -39,11 +40,10 @@ function generateSection({ section }: { section: SectionedId }) {
}
const SectionContainer = styled.View`
background-color: #f6f6f6;
border-bottom-color: #eee;
border-bottom-width: 1px;
height: 50px;
justify-content: center;
padding: 0 10px;
`;
const SectionText = styled.Text`
@@ -51,13 +51,15 @@ const SectionText = styled.Text`
font-weight: bold;
`;
const sectionStyles = { ...colors.view, ...colors.border };
class SectionHeading extends PureComponent<{ label: string }> {
render() {
const { label } = this.props;
return (
<SectionContainer>
<SectionText>{label}</SectionText>
<SectionContainer style={sectionStyles}>
<SectionText style={colors.text}>{label}</SectionText>
</SectionContainer>
);
}
@@ -82,9 +84,9 @@ class GeneratedAlbumItem extends PureComponent<GeneratedAlbumItemProps> {
return (
<TouchableHandler id={id as string} onPress={onPress}>
<AlbumItem>
<AlbumImage source={{ uri: imageUrl }} />
<Text numberOfLines={1}>{name}</Text>
<HalfOpacity numberOfLines={1}>{artist}</HalfOpacity>
<AlbumImage source={{ uri: imageUrl }} style={colors.imageBackground} />
<Text numberOfLines={1} style={colors.text}>{name}</Text>
<HalfOpacity style={colors.text} numberOfLines={1}>{artist}</HalfOpacity>
</AlbumItem>
</TouchableHandler>
);
@@ -153,7 +155,7 @@ const Albums: React.FC = () => {
const nextItem = section.data[index + 1];
return (
<View style={{ flexDirection: 'row' }} key={item}>
<View style={{ flexDirection: 'row', marginLeft: 10, marginRight: 10 }} key={item}>
<GeneratedAlbumItem
id={item}
imageUrl={getImage(item as string)}
@@ -184,19 +186,17 @@ const Albums: React.FC = () => {
return (
<SafeAreaView>
<ListContainer>
<AlphabetScroller onSelect={selectLetter} />
<SectionList
sections={sections}
refreshing={isLoading}
onRefresh={retrieveData}
getItemLayout={getItemLayout}
ref={listRef}
keyExtractor={(item, index) => `${item}_${index}`}
renderSectionHeader={generateSection}
renderItem={generateItem}
/>
</ListContainer>
<AlphabetScroller onSelect={selectLetter} />
<SectionList
sections={sections}
refreshing={isLoading}
onRefresh={retrieveData}
getItemLayout={getItemLayout}
ref={listRef}
keyExtractor={(item, index) => `${item}_${index}`}
renderSectionHeader={generateSection}
renderItem={generateItem}
/>
</SafeAreaView>
);
};

View File

@@ -1,7 +1,7 @@
import React, { useCallback, useEffect } from 'react';
import { useGetImage } from 'utility/JellyfinApi';
import { Album, NavigationProp } from '../types';
import { Text, SafeAreaView, FlatList } from 'react-native';
import { Text, SafeAreaView, FlatList, StyleSheet } from 'react-native';
import { useDispatch } from 'react-redux';
import { useNavigation } from '@react-navigation/native';
import { useTypedSelector } from 'store';
@@ -12,6 +12,14 @@ import AlbumImage, { AlbumItem } from './components/AlbumImage';
import { useRecentAlbums } from 'store/music/selectors';
import { Header } from 'components/Typography';
import ListButton from 'components/ListButton';
import { colors } from 'components/Colors';
const styles = StyleSheet.create({
artist: {
...colors.text,
opacity: 0.5,
}
});
const NavigationHeader: React.FC = () => {
const navigation = useNavigation();
@@ -22,7 +30,7 @@ const NavigationHeader: React.FC = () => {
<ListContainer>
<ListButton onPress={handleAllAlbumsClick}>All Albums</ListButton>
<ListButton onPress={handleSearchClick}>Search</ListButton>
<Header>Recent Albums</Header>
<Header style={colors.text}>Recent Albums</Header>
</ListContainer>
);
};
@@ -58,9 +66,9 @@ const RecentAlbums: React.FC = () => {
renderItem={({ item }) => (
<TouchableHandler id={item} onPress={selectAlbum}>
<AlbumItem>
<AlbumImage source={{ uri: getImage(item) }} />
<Text numberOfLines={1}>{albums[item]?.Name}</Text>
<Text numberOfLines={1} style={{ opacity: 0.5 }}>{albums[item]?.AlbumArtist}</Text>
<AlbumImage source={{ uri: getImage(item) }} style={colors.imageBackground} />
<Text style={colors.text} numberOfLines={1}>{albums[item]?.Name}</Text>
<Text style={styles.artist} numberOfLines={1}>{albums[item]?.AlbumArtist}</Text>
</AlbumItem>
</TouchableHandler>
)}

View File

@@ -11,6 +11,7 @@ import { useNavigation } from '@react-navigation/native';
import { useGetImage } from 'utility/JellyfinApi';
import { NavigationProp } from '../types';
import FastImage from 'react-native-fast-image';
import { colors } from 'components/Colors';
const Container = styled.View`
padding: 0 20px;
@@ -20,7 +21,6 @@ const AlbumImage = styled(FastImage)`
border-radius: 4px;
width: 25px;
height: 25px;
background-color: #fefefe;
margin-right: 10px;
`;
@@ -33,7 +33,6 @@ const HalfOpacity = styled.Text`
const SearchResult = styled.View`
flex-direction: row;
align-items: center;
border-bottom-color: #ddd;
border-bottom-width: 1px;
margin-left: 15px;
padding-right: 15px;
@@ -51,7 +50,7 @@ export default function Search() {
const [searchTerm, setSearchTerm] = useState('');
const albums = useTypedSelector(state => state.music.albums.entities);
const [results, setResults] = useState<Fuse.FuseResult<Album>[]>([]);
let fuse = useRef<Fuse<Album, typeof fuseOptions>>();
const fuse = useRef<Fuse<Album, typeof fuseOptions>>();
// Prepare helpers
const navigation = useNavigation<NavigationProp>();
@@ -89,7 +88,7 @@ export default function Search() {
const HeaderComponent = React.useMemo(() => (
<Container>
<Input value={searchTerm} onChangeText={setSearchTerm} placeholder="Search..." />
<Input value={searchTerm} onChangeText={setSearchTerm} style={colors.input} placeholder="Search..." />
{(searchTerm.length && !results.length) ? <Text>No results...</Text> : null}
</Container>
), [searchTerm, results, setSearchTerm]);
@@ -105,13 +104,13 @@ export default function Search() {
data={results}
renderItem={({ item: { item: album } }) =>(
<TouchableHandler id={album.Id} onPress={selectAlbum}>
<SearchResult>
<SearchResult style={colors.border}>
<AlbumImage source={{ uri: getImage(album.Id) }} />
<View>
<Text numberOfLines={1} ellipsizeMode="tail">
<Text numberOfLines={1} ellipsizeMode="tail" style={colors.text}>
{album.Name} - {album.AlbumArtist}
</Text>
<HalfOpacity>Album</HalfOpacity>
<HalfOpacity style={colors.text}>Album</HalfOpacity>
</View>
</SearchResult>
</TouchableHandler>

View File

@@ -14,7 +14,6 @@ const AlbumImage = styled(FastImage)`
border-radius: 10px;
width: ${Screen.width / 2 - 40}px;
height: ${Screen.width / 2 - 40}px;
background-color: #fefefe;
margin-bottom: 5px;
`;

View File

@@ -2,7 +2,6 @@ import styled from 'styled-components/native';
const ListContainer = styled.View`
padding: 10px;
background-color: #f6f6f6;
`;
export default ListContainer;

View File

@@ -0,0 +1,76 @@
import React, { useCallback, useEffect } from 'react';
import styled from 'styled-components/native';
import { THEME_COLOR } from 'CONSTANTS';
import { Button } from 'react-native';
import { useNavigation } from '@react-navigation/native';
import { NavigationProp } from 'screens';
import { useTypedSelector } from 'store';
import { useDispatch } from 'react-redux';
import { setOnboardingStatus } from 'store/settings/actions';
const Container = styled.SafeAreaView`
background-color: ${THEME_COLOR};
flex: 1;
justify-content: center;
`;
const TextContainer = styled.ScrollView`
padding: 25px;
`;
const Text = styled.Text`
text-align: center;
color: white;
margin-bottom: 10px;
`;
const ButtonContainer = styled.View`
margin-top: 50px;
`;
const Logo = styled.Image`
width: 150px;
height: 150px;
margin: 0 auto 50px auto;
`;
function Onboarding() {
// Get account from Redux and dispatcher
const account = useTypedSelector(state => state.settings.jellyfin);
const dispatch = useDispatch();
// Also retrieve the navigation handler so that we can open the modal in
// which the Jellyfin server is set
const navigation = useNavigation<NavigationProp>();
const handleClick = useCallback(() => navigation.navigate('SetJellyfinServer'), [navigation]);
// We'll also respond to any change in the account, setting the onboarding
// status to true, so that the app becomes available.
useEffect(() => {
if (account) {
dispatch(setOnboardingStatus(true));
}
}, [account, dispatch]);
return (
<Container>
<TextContainer contentContainerStyle={{ flexGrow: 1, justifyContent: 'center' }}>
<Logo source={require('../../assets/app-icon-white.png')} />
<Text >
Welcome!
</Text>
<Text>
Jellyfin Audio Player will allow you to stream your music library from anywhere, with full support for background audio and casting.
</Text>
<Text>
In order to get started, you need a Jellyfin server. Click the button below to enter your Jellyfin server address and login to it.
</Text>
<ButtonContainer>
<Button title="Set Jellyfin Server" color="#ffffff" onPress={handleClick} />
</ButtonContainer>
</TextContainer>
</Container>
);
}
export default Onboarding;

View File

@@ -7,6 +7,7 @@ import ForwardIcon from 'assets/forwards.svg';
import BackwardIcon from 'assets/backwards.svg';
import PlayIcon from 'assets/play.svg';
import PauseIcon from 'assets/pause.svg';
import { useColorScheme } from 'react-native-appearance';
const BUTTON_SIZE = 40;
@@ -32,61 +33,64 @@ const Button = styled.View`
`;
export default function MediaControls() {
const scheme = useColorScheme();
const fill = scheme === 'dark' ? '#ffffff' : '#000000';
return (
<Container>
<Buttons>
<Button>
<PreviousButton />
<PreviousButton fill={fill} />
</Button>
<MainButton />
<MainButton fill={fill} />
<Button>
<NextButton />
<NextButton fill={fill} />
</Button>
</Buttons>
</Container>
);
}
export function PreviousButton() {
export function PreviousButton({ fill }: { fill: string }) {
const hasQueue = useHasQueue();
return (
<TouchableOpacity onPress={previous} disabled={!hasQueue} style={{ opacity: hasQueue ? 1 : 0.5 }}>
<BackwardIcon width={BUTTON_SIZE} height={BUTTON_SIZE} fill="#000" />
<BackwardIcon width={BUTTON_SIZE} height={BUTTON_SIZE} fill={fill} />
</TouchableOpacity>
);
}
export function NextButton() {
export function NextButton({ fill }: { fill: string }) {
const hasQueue = useHasQueue();
return (
<TouchableOpacity onPress={next} disabled={!hasQueue} style={{ opacity: hasQueue ? 1 : 0.5 }}>
<ForwardIcon width={BUTTON_SIZE} height={BUTTON_SIZE} fill="#000" />
<ForwardIcon width={BUTTON_SIZE} height={BUTTON_SIZE} fill={fill} />
</TouchableOpacity>
);
}
export function MainButton() {
export function MainButton({ fill }: { fill: string }) {
const state = usePlaybackState();
switch (state) {
case STATE_PLAYING:
return (
<TouchableOpacity onPress={pause}>
<PauseIcon width={BUTTON_SIZE} height={BUTTON_SIZE} fill="#000" />
<PauseIcon width={BUTTON_SIZE} height={BUTTON_SIZE} fill={fill} />
</TouchableOpacity>
);
case STATE_PAUSED:
return (
<TouchableOpacity onPress={play}>
<PlayIcon width={BUTTON_SIZE} height={BUTTON_SIZE} fill="#000" />
<PlayIcon width={BUTTON_SIZE} height={BUTTON_SIZE} fill={fill} />
</TouchableOpacity>
);
default:
return (
<TouchableOpacity onPress={pause} disabled>
<PauseIcon width={BUTTON_SIZE} height={BUTTON_SIZE} fill="#000" />
<PauseIcon width={BUTTON_SIZE} height={BUTTON_SIZE} fill={fill} />
</TouchableOpacity>
);
}

View File

@@ -1,29 +1,47 @@
import React from 'react';
import { Text, Dimensions, View } from 'react-native';
import { Text, Dimensions, View, StyleSheet } from 'react-native';
import useCurrentTrack from 'utility/useCurrentTrack';
import styled from 'styled-components/native';
import FastImage from 'react-native-fast-image';
import { colors } from 'components/Colors';
const Screen = Dimensions.get('screen');
const Artwork = styled(FastImage)`
border-radius: 10px;
background-color: #fbfbfb;
width: ${Screen.width * 0.8}px;
height: ${Screen.width * 0.8}px;
margin: 25px auto;
display: flex;
flex: 1;
`;
const styles = StyleSheet.create({
artist: {
...colors.text,
fontWeight: 'bold',
fontSize: 24,
marginBottom: 12,
},
title: {
...colors.text,
fontSize: 18,
marginBottom: 12,
textAlign: 'center',
paddingLeft: 20,
paddingRight: 20,
}
});
export default function NowPlaying() {
const track = useCurrentTrack();
return (
<View style={{ alignItems: 'center' }}>
<Artwork style={{ flex: 1 }} source={{ uri: track?.artwork }} />
<Text style={{ fontWeight: 'bold', fontSize: 24, marginBottom: 12 }} >{track?.artist}</Text>
<Text style={{ fontSize: 18, marginBottom: 12, textAlign: 'center', paddingLeft: 20, paddingRight: 20 }}>{track?.title}</Text>
<Artwork style={colors.imageBackground} source={{ uri: track?.artwork }} />
<Text style={styles.artist} >{track?.artist}</Text>
<Text style={styles.title}>{track?.title}</Text>
</View>
);
}

View File

@@ -1,9 +1,10 @@
import React, { Component } from 'react';
import TrackPlayer from 'react-native-track-player';
import styled from 'styled-components/native';
import { Text } from 'react-native';
import { Text, Platform } from 'react-native';
import Slider from '@react-native-community/slider';
import { THEME_COLOR } from 'CONSTANTS';
import { colors } from 'components/Colors';
const NumberBar = styled.View`
flex-direction: row;
@@ -74,11 +75,12 @@ export default class ProgressBar extends Component<{}, State> {
onValueChange={this.handleGesture}
onSlidingComplete={this.handleEndOfGesture}
minimumTrackTintColor={THEME_COLOR}
thumbTintColor={Platform.OS === 'android' ? THEME_COLOR : undefined}
disabled={!duration}
/>
<NumberBar>
<Text>{getMinutes(gesture || position)}:{getSeconds(gesture || position)}</Text>
<Text>{getMinutes(duration)}:{getSeconds(duration)}</Text>
<Text style={colors.text}>{getMinutes(gesture || position)}:{getSeconds(gesture || position)}</Text>
<Text style={colors.text}>{getMinutes(duration)}:{getSeconds(duration)}</Text>
</NumberBar>
</>
);

View File

@@ -1,29 +1,39 @@
import React, { useCallback } from 'react';
import useQueue from 'utility/useQueue';
import { View, Text } from 'react-native';
import { View, Text, StyleSheet } from 'react-native';
import styled, { css } from 'styled-components/native';
import useCurrentTrack from 'utility/useCurrentTrack';
import TouchableHandler from 'components/TouchableHandler';
import TrackPlayer from 'react-native-track-player';
import { THEME_COLOR } from 'CONSTANTS';
import { colors } from 'components/Colors';
const QueueItem = styled.View<{ active?: boolean, alreadyPlayed?: boolean }>`
const QueueItem = styled.View<{ active?: boolean, alreadyPlayed?: boolean, isDark?: boolean }>`
padding: 10px;
border-bottom-width: 1px;
border-bottom-color: #eee;
${props => props.active && css`
font-weight: 900;
background-color: ${THEME_COLOR}16;
padding: 20px 35px;
margin: 0 -25px;
`}
${props => props.alreadyPlayed && css`
opacity: 0.25;
opacity: 0.5;
`}
`;
const styles = StyleSheet.create({
title: {
...colors.text,
marginBottom: 2,
},
artist: {
...colors.text,
opacity: 0.5,
}
});
export default function Queue() {
const queue = useQueue();
const currentTrack = useCurrentTrack();
@@ -38,9 +48,17 @@ export default function Queue() {
<Text style={{ marginTop: 20, marginBottom: 20 }}>Queue</Text>
{queue.map((track, i) => (
<TouchableHandler id={track.id} onPress={playTrack} key={i}>
<QueueItem active={currentTrack?.id === track.id} key={i} alreadyPlayed={i < currentIndex}>
<Text style={{marginBottom: 2}}>{track.title}</Text>
<Text style={{ opacity: 0.5 }}>{track.artist}</Text>
<QueueItem
active={currentTrack?.id === track.id}
key={i}
alreadyPlayed={i < currentIndex}
style={{
...colors.border,
...currentTrack?.id === track.id ? colors.activeBackground : {},
}}
>
<Text style={styles.title}>{track.title}</Text>
<Text style={styles.artist}>{track.artist}</Text>
</QueueItem>
</TouchableHandler>
))}

View File

@@ -1,22 +1,25 @@
import React from 'react';
import { StyleSheet, ScrollView } from 'react-native';
import MediaControls from './components/MediaControls';
import ProgressBar from './components/ProgressBar';
import NowPlaying from './components/NowPlaying';
import styled from 'styled-components/native';
import Queue from './components/Queue';
import { colors } from 'components/Colors';
const Container = styled.ScrollView`
background-color: #fff;
padding: 25px;
`;
const styles = StyleSheet.create({
outer: colors.view,
inner: {
padding: 25,
}
});
export default function Player() {
return (
<Container>
<ScrollView contentContainerStyle={styles.inner} style={styles.outer}>
<NowPlaying />
<MediaControls />
<ProgressBar />
<Queue />
</Container>
</ScrollView>
);
}

View File

@@ -1,6 +1,5 @@
import React, { useCallback } from 'react';
import { View, Text, SafeAreaView, Button } from 'react-native';
import { Picker } from '@react-native-community/picker';
import { View, Text, SafeAreaView, Button, StyleSheet } from 'react-native';
import { ScrollView } from 'react-native-gesture-handler';
import styled from 'styled-components/native';
import { useSelector } from 'react-redux';
@@ -8,13 +7,14 @@ import { AppState } from 'store';
import { useNavigation } from '@react-navigation/native';
import { NavigationProp } from '..';
import { THEME_COLOR } from 'CONSTANTS';
import { Header } from 'components/Typography';
import { colors } from 'components/Colors';
const InputContainer = styled.View`
margin: 10px 0;
`;
const Input = styled.TextInput`
background-color: #fbfbfb;
padding: 15px;
margin-top: 5px;
border-radius: 5px;
@@ -29,26 +29,27 @@ export default function Settings() {
<ScrollView>
<SafeAreaView>
<View style={{ padding: 20 }}>
<Text style={{ fontSize: 36, marginBottom: 24, fontWeight: 'bold' }}>Settings</Text>
<Header style={colors.text}>Settings</Header>
<InputContainer>
<Text>Jellyfin Server URL</Text>
<Input placeholder="https://jellyfin.yourserver.com/" value={jellyfin?.uri} editable={false} />
<Text style={colors.text}>Jellyfin Server URL</Text>
<Input placeholder="https://jellyfin.yourserver.com/" value={jellyfin?.uri} editable={false} style={colors.input} />
</InputContainer>
<InputContainer>
<Text>Jellyfin Access Token</Text>
<Input placeholder="deadbeefdeadbeefdeadbeef" value={jellyfin?.access_token} editable={false} />
<Text style={colors.text}>Jellyfin Access Token</Text>
<Input placeholder="deadbeefdeadbeefdeadbeef" value={jellyfin?.access_token} editable={false} style={colors.input} />
</InputContainer>
<InputContainer>
<Text>Jellyfin User ID</Text>
<Input placeholder="deadbeefdeadbeefdeadbeef" value={jellyfin?.user_id} editable={false} />
<Text style={colors.text}>Jellyfin User ID</Text>
<Input placeholder="deadbeefdeadbeefdeadbeef" value={jellyfin?.user_id} editable={false} style={colors.input} />
</InputContainer>
<Button title="Set Jellyfin server" onPress={handleClick} color={THEME_COLOR} />
<InputContainer>
<Text>Bitrate</Text>
{/* The bitrate setting is hidden for now, since Jellyfin does not appear to support custom bitrates */}
{/* <InputContainer>
<Text style={colors.text}>Bitrate</Text>
<Picker selectedValue={bitrate}>
<Picker.Item label="320kbps" value={140000000} />
</Picker>
</InputContainer>
</InputContainer> */}
</View>
</SafeAreaView>
</ScrollView>

View File

@@ -10,6 +10,8 @@ import PlayPauseIcon from 'assets/play-pause-fill.svg';
import NotesIcon from 'assets/notes.svg';
import GearIcon from 'assets/gear.svg';
import { THEME_COLOR } from 'CONSTANTS';
import { useTypedSelector } from 'store';
import Onboarding from './Onboarding';
const Stack = createStackNavigator();
const Tab = createBottomTabNavigator();
@@ -34,6 +36,14 @@ function getIcon(route: string): React.FC<any> | null {
}
function Screens() {
const isOnboardingComplete = useTypedSelector(state => state.settings.isOnboardingComplete);
// GUARD: If onboarding has not been completed, we instead render the
// onboarding component, so that the user can get setup in the app.
if (!isOnboardingComplete) {
return <Onboarding />;
}
return (
<Tab.Navigator
screenOptions={({ route }) => ({

View File

@@ -7,6 +7,7 @@ import { useDispatch } from 'react-redux';
import { useNavigation, StackActions } from '@react-navigation/native';
import CredentialGenerator from './components/CredentialGenerator';
import { THEME_COLOR } from 'CONSTANTS';
import { colors } from 'components/Colors';
export default function SetJellyfinServer() {
// State for first screen
@@ -31,8 +32,10 @@ export default function SetJellyfinServer() {
onCredentialsRetrieved={saveCredentials}
/>
) : (
<View style={{ padding: 20}}>
<Text>Please enter your Jellyfin server URL first. Make sure to include the protocol and port</Text>
<View style={{ padding: 20, flex: 1, justifyContent: 'center', alignItems: 'center' }}>
<Text style={colors.text}>
Please enter your Jellyfin server URL. Make sure to include the protocol and port
</Text>
<Input
placeholder="https://jellyfin.yourserver.io/"
onChangeText={setServerUrl}
@@ -40,6 +43,7 @@ export default function SetJellyfinServer() {
keyboardType="url"
autoCapitalize="none"
autoCorrect={false}
style={{ ...colors.input, width: '100%' }}
/>
<Button
title="Set server"

View File

@@ -1,12 +1,14 @@
import { configureStore, getDefaultMiddleware, combineReducers } from '@reduxjs/toolkit';
import { useSelector, TypedUseSelectorHook } from 'react-redux';
import AsyncStorage from '@react-native-community/async-storage';
import { persistStore, persistReducer } from 'redux-persist';
import { persistStore, persistReducer, PersistConfig } from 'redux-persist';
import autoMergeLevel2 from 'redux-persist/es/stateReconciler/autoMergeLevel2';
// import logger from 'redux-logger';
const persistConfig = {
const persistConfig: PersistConfig<AppState> = {
key: 'root',
storage: AsyncStorage,
stateReconciler: autoMergeLevel2
};
import settings from './settings';
@@ -26,7 +28,7 @@ const store = configureStore({
),
});
export type AppState = ReturnType<typeof store.getState>;
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;

View File

@@ -1,4 +1,5 @@
import { createAction } from '@reduxjs/toolkit';
export const setJellyfinCredentials = createAction<{ access_token: string, user_id: string, uri: string, deviced_id: string; }>('SET_JELLYFIN_CREDENTIALS');
export const setBitrate = createAction<number>('SET_BITRATE');
export const setBitrate = createAction<number>('SET_BITRATE');
export const setOnboardingStatus = createAction<boolean>('SET_ONBOARDING_STATUS');

View File

@@ -1,5 +1,5 @@
import { createReducer } from '@reduxjs/toolkit';
import { setBitrate, setJellyfinCredentials } from './actions';
import { setBitrate, setJellyfinCredentials, setOnboardingStatus } from './actions';
interface State {
jellyfin?: {
@@ -9,10 +9,12 @@ interface State {
device_id: string;
}
bitrate: number;
isOnboardingComplete: boolean;
}
const initialState: State = {
bitrate: 140000000
bitrate: 140000000,
isOnboardingComplete: false,
};
const settings = createReducer(initialState, {
@@ -24,6 +26,10 @@ const settings = createReducer(initialState, {
...state,
bitrate: action.payload,
}),
[setOnboardingStatus.type]: (state, action) => ({
...state,
isOnboardingComplete: action.payload,
})
});
export default settings;

View File

@@ -15,6 +15,8 @@ function generateConfig(credentials: Credentials): RequestInit {
const baseTrackOptions: Record<string, string> = {
// Not sure where this number refers to, but setting it to 140000000 appears
// to do wonders for making stuff work
// NOTE: Apparently setting a bitrate is as of yet unsupported in the
// Jellyfin core, and hence this value is not used
MaxStreamingBitrate: '140000000',
MaxSampleRate: '48000',
// This must be set to support client seeking