├── .watchmanconfig ├── .gitattributes ├── .eslintrc ├── .babelrc ├── .eslintignore ├── player.jpg ├── app.json ├── android ├── app │ ├── src │ │ └── main │ │ │ ├── res │ │ │ ├── values │ │ │ │ ├── strings.xml │ │ │ │ └── styles.xml │ │ │ ├── mipmap-hdpi │ │ │ │ └── ic_launcher.png │ │ │ ├── mipmap-mdpi │ │ │ │ └── ic_launcher.png │ │ │ ├── mipmap-xhdpi │ │ │ │ └── ic_launcher.png │ │ │ └── mipmap-xxhdpi │ │ │ │ └── ic_launcher.png │ │ │ ├── assets │ │ │ └── fonts │ │ │ │ ├── Entypo.ttf │ │ │ │ ├── Zocial.ttf │ │ │ │ ├── EvilIcons.ttf │ │ │ │ ├── Feather.ttf │ │ │ │ ├── Ionicons.ttf │ │ │ │ ├── Octicons.ttf │ │ │ │ ├── FontAwesome.ttf │ │ │ │ ├── Foundation.ttf │ │ │ │ ├── MaterialIcons.ttf │ │ │ │ ├── SimpleLineIcons.ttf │ │ │ │ └── MaterialCommunityIcons.ttf │ │ │ ├── java │ │ │ └── com │ │ │ │ └── reactnativespotifystreamer │ │ │ │ ├── MainActivity.java │ │ │ │ └── MainApplication.java │ │ │ └── AndroidManifest.xml │ ├── BUCK │ ├── proguard-rules.pro │ └── build.gradle ├── gradle │ └── wrapper │ │ ├── gradle-wrapper.jar │ │ └── gradle-wrapper.properties ├── keystores │ ├── debug.keystore.properties │ └── BUCK ├── settings.gradle ├── build.gradle ├── gradle.properties ├── gradlew.bat └── gradlew ├── ios ├── ReactNativeSpotifyStreamer │ ├── Images.xcassets │ │ ├── Contents.json │ │ └── AppIcon.appiconset │ │ │ └── Contents.json │ ├── AppDelegate.h │ ├── main.m │ ├── AppDelegate.m │ ├── Info.plist │ └── Base.lproj │ │ └── LaunchScreen.xib ├── ReactNativeSpotifyStreamer-Bridging-Header.h ├── dummy.swift ├── ReactNativeSpotifyStreamerTests │ ├── Info.plist │ └── ReactNativeSpotifyStreamerTests.m ├── ReactNativeSpotifyStreamer-tvOSTests │ └── Info.plist ├── ReactNativeSpotifyStreamer-tvOS │ └── Info.plist └── ReactNativeSpotifyStreamer.xcodeproj │ └── xcshareddata │ └── xcschemes │ ├── ReactNativeSpotifyStreamer.xcscheme │ └── ReactNativeSpotifyStreamer-tvOS.xcscheme ├── .buckconfig ├── src ├── redux │ ├── types.js │ ├── store.js │ └── ducks │ │ ├── index.js │ │ └── player.js ├── __tests__ │ └── Root.test.js ├── utils.js ├── root.js ├── api │ ├── api.js │ └── types.js ├── theme.js ├── components │ ├── TouchableIcon.js │ └── ProgressBar.js ├── TrackList.js ├── TrackItem.js ├── Player.js ├── PlayerControls.js └── App.js ├── rn-cli.config.js ├── ReactotronConfig.js ├── README.md ├── index.js ├── .gitignore ├── package.json ├── player-handler.js ├── .flowconfig └── flow-typed └── npm ├── jest_v22.x.x.js └── rxjs_v5.0.x.js /.watchmanconfig: -------------------------------------------------------------------------------- 1 | {} -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | *.pbxproj -text 2 | -------------------------------------------------------------------------------- /.eslintrc: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "callstack-io" 3 | } -------------------------------------------------------------------------------- /.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": ["react-native"] 3 | } 4 | -------------------------------------------------------------------------------- /.eslintignore: -------------------------------------------------------------------------------- 1 | /node_modules/** 2 | /android/** 3 | /ios/** 4 | /flow-typed/** -------------------------------------------------------------------------------- /player.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ferrannp/react-native-spotify-streamer/HEAD/player.jpg -------------------------------------------------------------------------------- /app.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "ReactNativeSpotifyStreamer", 3 | "displayName": "ReactNativeSpotifyStreamer" 4 | } -------------------------------------------------------------------------------- /android/app/src/main/res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | ReactNativeSpotifyStreamer 3 | 4 | -------------------------------------------------------------------------------- /ios/ReactNativeSpotifyStreamer/Images.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /.buckconfig: -------------------------------------------------------------------------------- 1 | 2 | [android] 3 | target = Google Inc.:Google APIs:23 4 | 5 | [maven_repositories] 6 | central = https://repo1.maven.org/maven2 7 | -------------------------------------------------------------------------------- /android/gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ferrannp/react-native-spotify-streamer/HEAD/android/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /android/app/src/main/assets/fonts/Entypo.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ferrannp/react-native-spotify-streamer/HEAD/android/app/src/main/assets/fonts/Entypo.ttf -------------------------------------------------------------------------------- /android/app/src/main/assets/fonts/Zocial.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ferrannp/react-native-spotify-streamer/HEAD/android/app/src/main/assets/fonts/Zocial.ttf -------------------------------------------------------------------------------- /android/app/src/main/assets/fonts/EvilIcons.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ferrannp/react-native-spotify-streamer/HEAD/android/app/src/main/assets/fonts/EvilIcons.ttf -------------------------------------------------------------------------------- /android/app/src/main/assets/fonts/Feather.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ferrannp/react-native-spotify-streamer/HEAD/android/app/src/main/assets/fonts/Feather.ttf -------------------------------------------------------------------------------- /android/app/src/main/assets/fonts/Ionicons.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ferrannp/react-native-spotify-streamer/HEAD/android/app/src/main/assets/fonts/Ionicons.ttf -------------------------------------------------------------------------------- /android/app/src/main/assets/fonts/Octicons.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ferrannp/react-native-spotify-streamer/HEAD/android/app/src/main/assets/fonts/Octicons.ttf -------------------------------------------------------------------------------- /android/keystores/debug.keystore.properties: -------------------------------------------------------------------------------- 1 | key.store=debug.keystore 2 | key.alias=androiddebugkey 3 | key.store.password=android 4 | key.alias.password=android 5 | -------------------------------------------------------------------------------- /ios/ReactNativeSpotifyStreamer-Bridging-Header.h: -------------------------------------------------------------------------------- 1 | // 2 | // Use this file to import your target's public headers that you would like to expose to Swift. 3 | // 4 | 5 | -------------------------------------------------------------------------------- /android/app/src/main/assets/fonts/FontAwesome.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ferrannp/react-native-spotify-streamer/HEAD/android/app/src/main/assets/fonts/FontAwesome.ttf -------------------------------------------------------------------------------- /android/app/src/main/assets/fonts/Foundation.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ferrannp/react-native-spotify-streamer/HEAD/android/app/src/main/assets/fonts/Foundation.ttf -------------------------------------------------------------------------------- /android/app/src/main/assets/fonts/MaterialIcons.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ferrannp/react-native-spotify-streamer/HEAD/android/app/src/main/assets/fonts/MaterialIcons.ttf -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ferrannp/react-native-spotify-streamer/HEAD/android/app/src/main/res/mipmap-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ferrannp/react-native-spotify-streamer/HEAD/android/app/src/main/res/mipmap-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /android/app/src/main/assets/fonts/SimpleLineIcons.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ferrannp/react-native-spotify-streamer/HEAD/android/app/src/main/assets/fonts/SimpleLineIcons.ttf -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ferrannp/react-native-spotify-streamer/HEAD/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ferrannp/react-native-spotify-streamer/HEAD/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /src/redux/types.js: -------------------------------------------------------------------------------- 1 | /* @flow */ 2 | 3 | export type ActionType = { 4 | type: string, 5 | payload: *, 6 | }; 7 | 8 | export type DispatchType = (action: ActionType) => void; 9 | -------------------------------------------------------------------------------- /src/redux/store.js: -------------------------------------------------------------------------------- 1 | /* @flow */ 2 | 3 | import { createStore } from 'redux'; 4 | import reducers from './ducks'; 5 | 6 | const store = createStore(reducers); 7 | 8 | export default store; 9 | -------------------------------------------------------------------------------- /android/app/src/main/assets/fonts/MaterialCommunityIcons.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ferrannp/react-native-spotify-streamer/HEAD/android/app/src/main/assets/fonts/MaterialCommunityIcons.ttf -------------------------------------------------------------------------------- /android/keystores/BUCK: -------------------------------------------------------------------------------- 1 | keystore( 2 | name = "debug", 3 | properties = "debug.keystore.properties", 4 | store = "debug.keystore", 5 | visibility = [ 6 | "PUBLIC", 7 | ], 8 | ) 9 | -------------------------------------------------------------------------------- /src/redux/ducks/index.js: -------------------------------------------------------------------------------- 1 | /* @flow */ 2 | 3 | import { combineReducers } from 'redux'; 4 | 5 | import player from './player'; 6 | 7 | export default combineReducers({ 8 | player, 9 | }); 10 | -------------------------------------------------------------------------------- /ios/dummy.swift: -------------------------------------------------------------------------------- 1 | // 2 | // dummy.swift 3 | // ReactNativeSpotifyStreamer 4 | // 5 | // Created by Ferran Negre Pizarro on 21/02/2018. 6 | // Copyright © 2018 Facebook. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | -------------------------------------------------------------------------------- /android/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | zipStoreBase=GRADLE_USER_HOME 4 | zipStorePath=wrapper/dists 5 | distributionUrl=https\://services.gradle.org/distributions/gradle-2.14.1-all.zip 6 | -------------------------------------------------------------------------------- /android/app/src/main/res/values/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /src/__tests__/Root.test.js: -------------------------------------------------------------------------------- 1 | /* @flow */ 2 | 3 | import 'react-native'; 4 | import React from 'react'; 5 | import renderer from 'react-test-renderer'; 6 | 7 | import Root from '../root'; 8 | 9 | it('renders correctly', () => { 10 | const tree = renderer.create(); 11 | expect(tree).toBeTruthy(); 12 | }); 13 | -------------------------------------------------------------------------------- /rn-cli.config.js: -------------------------------------------------------------------------------- 1 | // See https://github.com/oblador/react-native-vector-icons/issues/626 2 | const blacklist = require('metro/src/blacklist'); // eslint-disable-line import/no-extraneous-dependencies 3 | 4 | module.exports = { 5 | getBlacklistRE() { 6 | return blacklist([/react-native\/local-cli\/core\/__fixtures__.*/]); 7 | }, 8 | }; 9 | -------------------------------------------------------------------------------- /ReactotronConfig.js: -------------------------------------------------------------------------------- 1 | /* @flow */ 2 | 3 | if (global.__DEV__) { 4 | // eslint-disable-next-line global-require, import/no-extraneous-dependencies 5 | const Reactotron = require('reactotron-react-native').default; 6 | Reactotron.configure() 7 | .useReactNative() 8 | .connect(); 9 | 10 | global.log = Reactotron.log; 11 | } 12 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # react-native-spotify-streamer 2 | 3 | This repo was created as part of the conference talk: **The dark side of Background tasks in React Native**. You can watch it from [React Native Camp 2018](https://www.youtube.com/watch?v=ZlkEimenw9E) or from [React Alicante 2018](https://www.youtube.com/watch?v=8MBQr9cSdHc). 4 | 5 | ![Player](player.jpg) 6 | Design credits to Katrina (krempel) - https://dribbble.com/shots/2725561-Music-Player-UI 7 | -------------------------------------------------------------------------------- /android/settings.gradle: -------------------------------------------------------------------------------- 1 | rootProject.name = 'ReactNativeSpotifyStreamer' 2 | include ':react-native-track-player' 3 | project(':react-native-track-player').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-track-player/android') 4 | include ':react-native-vector-icons' 5 | project(':react-native-vector-icons').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-vector-icons/android') 6 | 7 | include ':app' 8 | -------------------------------------------------------------------------------- /src/utils.js: -------------------------------------------------------------------------------- 1 | /* @flow */ 2 | 3 | import type { TrackType } from './api/types'; 4 | 5 | export const getTrackStructure = (track: TrackType) => ({ 6 | id: track.id, 7 | url: track.preview_url, 8 | title: track.name, 9 | artist: track.artists[0].name, 10 | album: track.album.name, 11 | artwork: track.album.images[0].url, 12 | }); 13 | 14 | export const leftPad = (num: number, size: number) => { 15 | let s = `${num}`; 16 | while (s.length < size) s = `0${s}`; 17 | return s; 18 | }; 19 | -------------------------------------------------------------------------------- /android/app/src/main/java/com/reactnativespotifystreamer/MainActivity.java: -------------------------------------------------------------------------------- 1 | package com.reactnativespotifystreamer; 2 | 3 | import com.facebook.react.ReactActivity; 4 | 5 | public class MainActivity extends ReactActivity { 6 | 7 | /** 8 | * Returns the name of the main component registered from JavaScript. 9 | * This is used to schedule rendering of the component. 10 | */ 11 | @Override 12 | protected String getMainComponentName() { 13 | return "ReactNativeSpotifyStreamer"; 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/root.js: -------------------------------------------------------------------------------- 1 | /* @flow */ 2 | 3 | import * as React from 'react'; 4 | import { Provider as PaperProvider } from 'react-native-paper'; 5 | import { Provider as ReduxProvider } from 'react-redux'; 6 | 7 | import App from './App'; 8 | import theme from './theme'; 9 | import store from './redux/store'; 10 | 11 | function Root() { 12 | return ( 13 | 14 | 15 | 16 | 17 | 18 | ); 19 | } 20 | 21 | export default Root; 22 | -------------------------------------------------------------------------------- /ios/ReactNativeSpotifyStreamer/AppDelegate.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2015-present, Facebook, Inc. 3 | * All rights reserved. 4 | * 5 | * This source code is licensed under the BSD-style license found in the 6 | * LICENSE file in the root directory of this source tree. An additional grant 7 | * of patent rights can be found in the PATENTS file in the same directory. 8 | */ 9 | 10 | #import 11 | 12 | @interface AppDelegate : UIResponder 13 | 14 | @property (nonatomic, strong) UIWindow *window; 15 | 16 | @end 17 | -------------------------------------------------------------------------------- /ios/ReactNativeSpotifyStreamer/main.m: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2015-present, Facebook, Inc. 3 | * All rights reserved. 4 | * 5 | * This source code is licensed under the BSD-style license found in the 6 | * LICENSE file in the root directory of this source tree. An additional grant 7 | * of patent rights can be found in the PATENTS file in the same directory. 8 | */ 9 | 10 | #import 11 | 12 | #import "AppDelegate.h" 13 | 14 | int main(int argc, char * argv[]) { 15 | @autoreleasepool { 16 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/api/api.js: -------------------------------------------------------------------------------- 1 | /* @flow */ 2 | 3 | import { CLIENT_ID, CLIENT_SECRET } from '../../secrets'; 4 | 5 | const Buffer = require('buffer/').Buffer; 6 | 7 | const BASE_URL = 'https://api.spotify.com/v1'; 8 | 9 | export const authHeaders = (token: string) => ({ 10 | Authorization: `Bearer ${token}`, 11 | }); 12 | 13 | export const tokenHeaders = { 14 | Authorization: `Basic ${new Buffer(`${CLIENT_ID}:${CLIENT_SECRET}`).toString( 15 | 'base64' 16 | )}`, 17 | }; 18 | 19 | export const getToken = () => 'https://accounts.spotify.com/api/token'; 20 | 21 | export const fetchSearch = (query: string) => 22 | `${BASE_URL}/search?q=${query}&type=track`; 23 | -------------------------------------------------------------------------------- /src/api/types.js: -------------------------------------------------------------------------------- 1 | /* @flow */ 2 | 3 | export type TrackResult = { 4 | tracks: { 5 | items: Array, 6 | }, 7 | }; 8 | 9 | export type TokenResult = { 10 | response: { 11 | access_token: string, 12 | }, 13 | }; 14 | 15 | export type AlbumType = { 16 | name: string, 17 | images: Array<{ 18 | height: number, 19 | url: string, 20 | width: number, 21 | }>, 22 | }; 23 | 24 | export type ArtistType = { 25 | name: string, 26 | }; 27 | 28 | export type TrackType = { 29 | album: AlbumType, 30 | artists: Array, 31 | duration_ms: number, 32 | id: string, 33 | name: string, 34 | preview_url: string, 35 | }; 36 | -------------------------------------------------------------------------------- /src/theme.js: -------------------------------------------------------------------------------- 1 | /* @flow */ 2 | 3 | import type { Theme } from 'react-native-paper/src/types'; 4 | import { DarkTheme } from 'react-native-paper'; 5 | 6 | type ThemeColors = { 7 | colors: { 8 | icon: string, 9 | divider: string, 10 | ripple: string, 11 | }, 12 | }; 13 | 14 | export type ThemeType = Theme & ThemeColors; 15 | 16 | const theme = { 17 | ...DarkTheme, 18 | colors: { 19 | ...DarkTheme.colors, 20 | background: '#373C3F', 21 | divider: '#95898E', 22 | icon: '#FFFFFF', 23 | primary: '#18D1A8', 24 | ripple: 'rgba(255, 255, 255, .20)', 25 | secondaryText: '#D9D7DA', 26 | }, 27 | }; 28 | 29 | export default theme; 30 | -------------------------------------------------------------------------------- /src/redux/ducks/player.js: -------------------------------------------------------------------------------- 1 | /* @flow */ 2 | 3 | import type { ActionType } from '../types'; 4 | 5 | export const PLAYBACK_STATE = 'PLAYBACK_STATE'; 6 | 7 | type State = { 8 | playerState: ?string, 9 | }; 10 | 11 | const initialState = { 12 | playerState: null, 13 | }; 14 | 15 | export default function reducer( 16 | state: State = initialState, 17 | action: ActionType 18 | ) { 19 | switch (action.type) { 20 | case PLAYBACK_STATE: 21 | return { ...state, ...{ playerState: action.payload } }; 22 | default: 23 | return state; 24 | } 25 | } 26 | 27 | export const playbackState = (payload: string) => ({ 28 | type: PLAYBACK_STATE, 29 | payload, 30 | }); 31 | -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | /* @flow */ 2 | 3 | import { AppRegistry } from 'react-native'; 4 | import TrackPlayer from 'react-native-track-player'; 5 | 6 | import './ReactotronConfig'; 7 | import Root from './src/root'; 8 | import playerHandler from './player-handler'; 9 | import store from './src/redux/store'; 10 | 11 | if (global.__DEV__) { 12 | // $FlowFixMe this property is on RN 13 | console.ignoredYellowBox = ['Remote debugger']; // eslint-disable-line no-console 14 | } 15 | 16 | AppRegistry.registerComponent('ReactNativeSpotifyStreamer', () => Root); 17 | // AppRegistry.registerHeadlessTask('TrackPlayer', () => 18 | // playerHandler(store.dispatch) 19 | // ); 20 | TrackPlayer.registerEventHandler(playerHandler(store.dispatch)); 21 | -------------------------------------------------------------------------------- /android/build.gradle: -------------------------------------------------------------------------------- 1 | // Top-level build file where you can add configuration options common to all sub-projects/modules. 2 | 3 | buildscript { 4 | repositories { 5 | jcenter() 6 | } 7 | dependencies { 8 | classpath 'com.android.tools.build:gradle:2.2.3' 9 | 10 | // NOTE: Do not place your application dependencies here; they belong 11 | // in the individual module build.gradle files 12 | } 13 | } 14 | 15 | allprojects { 16 | repositories { 17 | mavenLocal() 18 | jcenter() 19 | maven { 20 | // All of React Native (JS, Obj-C sources, Android binaries) is installed from npm 21 | url "$rootDir/../node_modules/react-native/android" 22 | } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /ios/ReactNativeSpotifyStreamerTests/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | org.reactjs.native.example.$(PRODUCT_NAME:rfc1034identifier) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | BNDL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1 23 | 24 | 25 | -------------------------------------------------------------------------------- /ios/ReactNativeSpotifyStreamer-tvOSTests/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | org.reactjs.native.example.$(PRODUCT_NAME:rfc1034identifier) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | BNDL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1 23 | 24 | 25 | -------------------------------------------------------------------------------- /android/gradle.properties: -------------------------------------------------------------------------------- 1 | # Project-wide Gradle settings. 2 | 3 | # IDE (e.g. Android Studio) users: 4 | # Gradle settings configured through the IDE *will override* 5 | # any settings specified in this file. 6 | 7 | # For more details on how to configure your build environment visit 8 | # http://www.gradle.org/docs/current/userguide/build_environment.html 9 | 10 | # Specifies the JVM arguments used for the daemon process. 11 | # The setting is particularly useful for tweaking memory settings. 12 | # Default value: -Xmx10248m -XX:MaxPermSize=256m 13 | # org.gradle.jvmargs=-Xmx2048m -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8 14 | 15 | # When configured, Gradle will run in incubating parallel mode. 16 | # This option should only be used with decoupled projects. More details, visit 17 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects 18 | # org.gradle.parallel=true 19 | 20 | android.useDeprecatedNdk=true 21 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # OSX 2 | # 3 | .DS_Store 4 | 5 | # Xcode 6 | # 7 | build/ 8 | *.pbxuser 9 | !default.pbxuser 10 | *.mode1v3 11 | !default.mode1v3 12 | *.mode2v3 13 | !default.mode2v3 14 | *.perspectivev3 15 | !default.perspectivev3 16 | xcuserdata 17 | *.xccheckout 18 | *.moved-aside 19 | DerivedData 20 | *.hmap 21 | *.ipa 22 | *.xcuserstate 23 | project.xcworkspace 24 | 25 | # Android/IntelliJ 26 | # 27 | build/ 28 | .idea 29 | .gradle 30 | local.properties 31 | *.iml 32 | 33 | # node.js 34 | # 35 | node_modules/ 36 | npm-debug.log 37 | yarn-error.log 38 | 39 | # BUCK 40 | buck-out/ 41 | \.buckd/ 42 | *.keystore 43 | 44 | # fastlane 45 | # 46 | # It is recommended to not store the screenshots in the git repo. Instead, use fastlane to re-generate the 47 | # screenshots whenever they are needed. 48 | # For more information about the recommended setup visit: 49 | # https://docs.fastlane.tools/best-practices/source-control/ 50 | 51 | */fastlane/report.xml 52 | */fastlane/Preview.html 53 | */fastlane/screenshots 54 | 55 | secrets.js -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "ReactNativeSpotifyStreamer", 3 | "version": "0.0.1", 4 | "private": true, 5 | "scripts": { 6 | "start": "node node_modules/react-native/local-cli/cli.js start", 7 | "test": "jest", 8 | "flow": "flow", 9 | "lint": "eslint ." 10 | }, 11 | "dependencies": { 12 | "buffer": "^5.0.8", 13 | "react": "16.2.0", 14 | "react-native": "0.52.2", 15 | "react-native-paper": "^0.0.8", 16 | "react-native-track-player": "^0.2.2", 17 | "react-native-vector-icons": "^4.5.0", 18 | "react-redux": "^5.0.7", 19 | "redux": "^3.7.2", 20 | "rxjs": "^5.5.6" 21 | }, 22 | "devDependencies": { 23 | "babel-jest": "22.1.0", 24 | "babel-preset-react-native": "4.0.0", 25 | "eslint": "^4.16.0", 26 | "eslint-config-callstack-io": "^1.1.1", 27 | "flow-bin": "0.61.0", 28 | "jest": "22.1.4", 29 | "react-test-renderer": "16.2.0", 30 | "reactotron-react-native": "^1.14.0" 31 | }, 32 | "jest": { 33 | "preset": "react-native" 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /src/components/TouchableIcon.js: -------------------------------------------------------------------------------- 1 | /* @flow */ 2 | 3 | import * as React from 'react'; 4 | import { TouchableRipple, withTheme } from 'react-native-paper'; 5 | import Icon from 'react-native-vector-icons/MaterialIcons'; 6 | 7 | import type { ThemeType } from '../theme'; 8 | 9 | type Props = { 10 | borderless?: boolean, 11 | disabled?: boolean, 12 | name: string, 13 | iconStyle?: any, // eslint-disable-line flowtype/no-weak-types 14 | style?: any, // eslint-disable-line flowtype/no-weak-types 15 | onPress: () => void, 16 | theme: ThemeType, 17 | }; 18 | 19 | const TouchableIcon = ({ 20 | borderless = true, 21 | disabled = false, 22 | name, 23 | iconStyle, 24 | style, 25 | onPress, 26 | theme, 27 | }: Props) => ( 28 | 34 | 39 | 40 | ); 41 | 42 | export default withTheme(TouchableIcon); 43 | -------------------------------------------------------------------------------- /ios/ReactNativeSpotifyStreamer/Images.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "iphone", 5 | "size" : "20x20", 6 | "scale" : "2x" 7 | }, 8 | { 9 | "idiom" : "iphone", 10 | "size" : "20x20", 11 | "scale" : "3x" 12 | }, 13 | { 14 | "idiom" : "iphone", 15 | "size" : "29x29", 16 | "scale" : "2x" 17 | }, 18 | { 19 | "idiom" : "iphone", 20 | "size" : "29x29", 21 | "scale" : "3x" 22 | }, 23 | { 24 | "idiom" : "iphone", 25 | "size" : "40x40", 26 | "scale" : "2x" 27 | }, 28 | { 29 | "idiom" : "iphone", 30 | "size" : "40x40", 31 | "scale" : "3x" 32 | }, 33 | { 34 | "idiom" : "iphone", 35 | "size" : "60x60", 36 | "scale" : "2x" 37 | }, 38 | { 39 | "idiom" : "iphone", 40 | "size" : "60x60", 41 | "scale" : "3x" 42 | }, 43 | { 44 | "idiom" : "ios-marketing", 45 | "size" : "1024x1024", 46 | "scale" : "1x" 47 | } 48 | ], 49 | "info" : { 50 | "version" : 1, 51 | "author" : "xcode" 52 | } 53 | } -------------------------------------------------------------------------------- /src/components/ProgressBar.js: -------------------------------------------------------------------------------- 1 | /* @flow */ 2 | 3 | import React, { Fragment } from 'react'; 4 | import { 5 | ProgressBar as PaperProgressBar, 6 | Text, 7 | withTheme, 8 | } from 'react-native-paper'; 9 | import { ProgressComponent } from 'react-native-track-player'; 10 | import { StyleSheet } from 'react-native'; 11 | 12 | import { leftPad } from '../utils'; 13 | 14 | class ProgressBar extends ProgressComponent<> { 15 | render() { 16 | const { theme } = this.props; 17 | const { duration, position } = this.state; 18 | 19 | return ( 20 | 21 | 22 | 0:{leftPad(Math.floor(position), 2)} 23 | 24 | {' '} 25 | / 0:{leftPad(Math.round(duration), 2)} 26 | 27 | 28 | 32 | 33 | ); 34 | } 35 | } 36 | 37 | const styles = StyleSheet.create({ 38 | progressBar: { 39 | paddingVertical: 0, 40 | }, 41 | }); 42 | 43 | export default withTheme(ProgressBar); 44 | -------------------------------------------------------------------------------- /android/app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 5 | 6 | 7 | 8 | 9 | 12 | 13 | 19 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /android/app/src/main/java/com/reactnativespotifystreamer/MainApplication.java: -------------------------------------------------------------------------------- 1 | package com.reactnativespotifystreamer; 2 | 3 | import android.app.Application; 4 | 5 | import com.facebook.react.ReactApplication; 6 | import guichaguri.trackplayer.TrackPlayer; 7 | import com.oblador.vectoricons.VectorIconsPackage; 8 | import com.facebook.react.ReactNativeHost; 9 | import com.facebook.react.ReactPackage; 10 | import com.facebook.react.shell.MainReactPackage; 11 | import com.facebook.soloader.SoLoader; 12 | 13 | import java.util.Arrays; 14 | import java.util.List; 15 | 16 | public class MainApplication extends Application implements ReactApplication { 17 | 18 | private final ReactNativeHost mReactNativeHost = new ReactNativeHost(this) { 19 | @Override 20 | public boolean getUseDeveloperSupport() { 21 | return BuildConfig.DEBUG; 22 | } 23 | 24 | @Override 25 | protected List getPackages() { 26 | return Arrays.asList( 27 | new MainReactPackage(), 28 | new TrackPlayer(), 29 | new VectorIconsPackage() 30 | ); 31 | } 32 | 33 | @Override 34 | protected String getJSMainModuleName() { 35 | return "index"; 36 | } 37 | }; 38 | 39 | @Override 40 | public ReactNativeHost getReactNativeHost() { 41 | return mReactNativeHost; 42 | } 43 | 44 | @Override 45 | public void onCreate() { 46 | super.onCreate(); 47 | SoLoader.init(this, /* native exopackage */ false); 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /ios/ReactNativeSpotifyStreamer/AppDelegate.m: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2015-present, Facebook, Inc. 3 | * All rights reserved. 4 | * 5 | * This source code is licensed under the BSD-style license found in the 6 | * LICENSE file in the root directory of this source tree. An additional grant 7 | * of patent rights can be found in the PATENTS file in the same directory. 8 | */ 9 | 10 | #import "AppDelegate.h" 11 | 12 | #import 13 | #import 14 | 15 | @implementation AppDelegate 16 | 17 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions 18 | { 19 | NSURL *jsCodeLocation; 20 | 21 | jsCodeLocation = [[RCTBundleURLProvider sharedSettings] jsBundleURLForBundleRoot:@"index" fallbackResource:nil]; 22 | 23 | RCTRootView *rootView = [[RCTRootView alloc] initWithBundleURL:jsCodeLocation 24 | moduleName:@"ReactNativeSpotifyStreamer" 25 | initialProperties:nil 26 | launchOptions:launchOptions]; 27 | rootView.backgroundColor = [[UIColor alloc] initWithRed:1.0f green:1.0f blue:1.0f alpha:1]; 28 | 29 | self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds]; 30 | UIViewController *rootViewController = [UIViewController new]; 31 | rootViewController.view = rootView; 32 | self.window.rootViewController = rootViewController; 33 | [self.window makeKeyAndVisible]; 34 | return YES; 35 | } 36 | 37 | @end 38 | -------------------------------------------------------------------------------- /src/TrackList.js: -------------------------------------------------------------------------------- 1 | /* @flow */ 2 | 3 | import React, { Component, Fragment } from 'react'; 4 | import { Keyboard, FlatList, StyleSheet } from 'react-native'; 5 | 6 | import type { TrackType } from './api/types'; 7 | import TrackItem from './TrackItem'; 8 | import Player from './Player'; 9 | 10 | type Props = { 11 | tracks: Array, 12 | }; 13 | 14 | type State = { 15 | selectedTrack: ?TrackType, 16 | }; 17 | 18 | class TrackList extends Component { 19 | state = { 20 | selectedTrack: null, 21 | }; 22 | 23 | onTrackSelected = (track: TrackType) => { 24 | this.setState({ selectedTrack: track }, () => Keyboard.dismiss()); 25 | }; 26 | 27 | render() { 28 | const { tracks } = this.props; 29 | const { selectedTrack } = this.state; 30 | 31 | return ( 32 | 33 | item.id} 35 | data={tracks} 36 | keyboardShouldPersistTaps="always" 37 | extraData={this.state.selectedTrack} 38 | renderItem={({ item }) => ( 39 | 44 | )} 45 | contentContainerStyle={styles.listContainer} 46 | /> 47 | 48 | 49 | ); 50 | } 51 | } 52 | 53 | const styles = StyleSheet.create({ 54 | listContainer: { 55 | paddingTop: 8, 56 | paddingBottom: 16, 57 | }, 58 | }); 59 | 60 | export default TrackList; 61 | -------------------------------------------------------------------------------- /player-handler.js: -------------------------------------------------------------------------------- 1 | /* @flow */ 2 | 3 | import { Alert } from 'react-native'; 4 | import TrackPlayer from 'react-native-track-player'; 5 | import { playbackState } from './src/redux/ducks/player'; 6 | import type { DispatchType } from './src/redux/types'; 7 | 8 | type Data = { 9 | type: string, 10 | position: number, 11 | ducking: number, 12 | error: string, 13 | state: string, 14 | }; 15 | 16 | async function playerHandler(dispatch: DispatchType, data: Data) { 17 | switch (data.type) { 18 | // Forward remote events to the player 19 | case 'remote-play': 20 | TrackPlayer.play(); 21 | break; 22 | case 'remote-pause': 23 | TrackPlayer.pause(); 24 | break; 25 | case 'remote-stop': 26 | TrackPlayer.stop(); 27 | break; 28 | case 'remote-next': 29 | TrackPlayer.skipToNext(); 30 | break; 31 | case 'remote-previous': 32 | TrackPlayer.skipToPrevious(); 33 | break; 34 | case 'remote-seek': 35 | TrackPlayer.seekTo(data.position); 36 | break; 37 | // You can make ducking smoother by adding a fade in/out 38 | case 'remote-duck': 39 | TrackPlayer.setVolume(data.ducking ? 0.5 : 1); 40 | break; 41 | // Playback updates 42 | case 'playback-state': { 43 | dispatch(playbackState(data.state)); 44 | break; 45 | } 46 | case 'playback-track-changed': 47 | break; 48 | case 'playback-error': 49 | Alert.alert('An error occurred', data.error); 50 | break; 51 | default: 52 | break; 53 | } 54 | } 55 | 56 | export default function(dispatch: DispatchType) { 57 | return playerHandler.bind(null, dispatch); 58 | } 59 | -------------------------------------------------------------------------------- /.flowconfig: -------------------------------------------------------------------------------- 1 | [ignore] 2 | ; We fork some components by platform 3 | .*/*[.]android.js 4 | 5 | ; Ignore "BUCK" generated dirs 6 | /\.buckd/ 7 | 8 | ; Ignore unexpected extra "@providesModule" 9 | .*/node_modules/.*/node_modules/fbjs/.* 10 | 11 | ; Ignore duplicate module providers 12 | ; For RN Apps installed via npm, "Libraries" folder is inside 13 | ; "node_modules/react-native" but in the source repo it is in the root 14 | .*/Libraries/react-native/React.js 15 | 16 | ; Ignore polyfills 17 | .*/Libraries/polyfills/.* 18 | 19 | ; Ignore metro 20 | .*/node_modules/metro/.* 21 | 22 | [include] 23 | 24 | [libs] 25 | node_modules/react-native/Libraries/react-native/react-native-interface.js 26 | node_modules/react-native/flow/ 27 | node_modules/react-native/flow-github/ 28 | flow-typed/ 29 | 30 | [options] 31 | emoji=true 32 | 33 | module.system=haste 34 | 35 | munge_underscores=true 36 | 37 | module.name_mapper='^[./a-zA-Z0-9$_-]+\.\(bmp\|gif\|jpg\|jpeg\|png\|psd\|svg\|webp\|m4v\|mov\|mp4\|mpeg\|mpg\|webm\|aac\|aiff\|caf\|m4a\|mp3\|wav\|html\|pdf\)$' -> 'RelativeImageStub' 38 | 39 | module.file_ext=.js 40 | module.file_ext=.jsx 41 | module.file_ext=.json 42 | module.file_ext=.native.js 43 | 44 | suppress_type=$FlowIssue 45 | suppress_type=$FlowFixMe 46 | suppress_type=$FlowFixMeProps 47 | suppress_type=$FlowFixMeState 48 | 49 | suppress_comment=\\(.\\|\n\\)*\\$FlowFixMe\\($\\|[^(]\\|(\\(\\)? *\\(site=[a-z,_]*react_native[a-z,_]*\\)?)\\) 50 | suppress_comment=\\(.\\|\n\\)*\\$FlowIssue\\((\\(\\)? *\\(site=[a-z,_]*react_native[a-z,_]*\\)?)\\)?:? #[0-9]+ 51 | suppress_comment=\\(.\\|\n\\)*\\$FlowFixedInNextDeploy 52 | suppress_comment=\\(.\\|\n\\)*\\$FlowExpectedError 53 | 54 | unsafe.enable_getters_and_setters=true 55 | 56 | [version] 57 | ^0.61.0 58 | -------------------------------------------------------------------------------- /ios/ReactNativeSpotifyStreamer-tvOS/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | org.reactjs.native.example.$(PRODUCT_NAME:rfc1034identifier) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | APPL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1 23 | LSRequiresIPhoneOS 24 | 25 | UILaunchStoryboardName 26 | LaunchScreen 27 | UIRequiredDeviceCapabilities 28 | 29 | armv7 30 | 31 | UISupportedInterfaceOrientations 32 | 33 | UIInterfaceOrientationPortrait 34 | UIInterfaceOrientationLandscapeLeft 35 | UIInterfaceOrientationLandscapeRight 36 | 37 | UIViewControllerBasedStatusBarAppearance 38 | 39 | NSLocationWhenInUseUsageDescription 40 | 41 | NSAppTransportSecurity 42 | 43 | 44 | NSExceptionDomains 45 | 46 | localhost 47 | 48 | NSExceptionAllowsInsecureHTTPLoads 49 | 50 | 51 | 52 | 53 | 54 | 55 | -------------------------------------------------------------------------------- /android/app/BUCK: -------------------------------------------------------------------------------- 1 | # To learn about Buck see [Docs](https://buckbuild.com/). 2 | # To run your application with Buck: 3 | # - install Buck 4 | # - `npm start` - to start the packager 5 | # - `cd android` 6 | # - `keytool -genkey -v -keystore keystores/debug.keystore -storepass android -alias androiddebugkey -keypass android -dname "CN=Android Debug,O=Android,C=US"` 7 | # - `./gradlew :app:copyDownloadableDepsToLibs` - make all Gradle compile dependencies available to Buck 8 | # - `buck install -r android/app` - compile, install and run application 9 | # 10 | 11 | lib_deps = [] 12 | 13 | for jarfile in glob(['libs/*.jar']): 14 | name = 'jars__' + jarfile[jarfile.rindex('/') + 1: jarfile.rindex('.jar')] 15 | lib_deps.append(':' + name) 16 | prebuilt_jar( 17 | name = name, 18 | binary_jar = jarfile, 19 | ) 20 | 21 | for aarfile in glob(['libs/*.aar']): 22 | name = 'aars__' + aarfile[aarfile.rindex('/') + 1: aarfile.rindex('.aar')] 23 | lib_deps.append(':' + name) 24 | android_prebuilt_aar( 25 | name = name, 26 | aar = aarfile, 27 | ) 28 | 29 | android_library( 30 | name = "all-libs", 31 | exported_deps = lib_deps, 32 | ) 33 | 34 | android_library( 35 | name = "app-code", 36 | srcs = glob([ 37 | "src/main/java/**/*.java", 38 | ]), 39 | deps = [ 40 | ":all-libs", 41 | ":build_config", 42 | ":res", 43 | ], 44 | ) 45 | 46 | android_build_config( 47 | name = "build_config", 48 | package = "com.reactnativespotifystreamer", 49 | ) 50 | 51 | android_resource( 52 | name = "res", 53 | package = "com.reactnativespotifystreamer", 54 | res = "src/main/res", 55 | ) 56 | 57 | android_binary( 58 | name = "app", 59 | keystore = "//android/keystores:debug", 60 | manifest = "src/main/AndroidManifest.xml", 61 | package_type = "debug", 62 | deps = [ 63 | ":app-code", 64 | ], 65 | ) 66 | -------------------------------------------------------------------------------- /src/TrackItem.js: -------------------------------------------------------------------------------- 1 | /* @flow */ 2 | 3 | import React, { PureComponent } from 'react'; 4 | import { StyleSheet, View } from 'react-native'; 5 | import { Text, TouchableRipple, withTheme } from 'react-native-paper'; 6 | 7 | import type { TrackType } from './api/types'; 8 | import type { ThemeType } from './theme'; 9 | 10 | type Props = { 11 | selectedId: string, 12 | theme: ThemeType, 13 | track: TrackType, 14 | onTrackSelected: (track: TrackType) => void, 15 | }; 16 | 17 | class TrackItem extends PureComponent { 18 | onTrackSelected = () => { 19 | this.props.onTrackSelected(this.props.track); 20 | }; 21 | 22 | render() { 23 | const { selectedId, theme, track } = this.props; 24 | const { artists, name } = track; 25 | const artist = artists[0]; 26 | 27 | return ( 28 | 32 | 33 | 41 | 42 | 46 | {name} 47 | 48 | 58 | {artist.name.toUpperCase()} 59 | 60 | 61 | 62 | 63 | ); 64 | } 65 | } 66 | 67 | const styles = StyleSheet.create({ 68 | container: { 69 | flexDirection: 'row', 70 | paddingRight: 16, 71 | }, 72 | content: { 73 | paddingLeft: 24, 74 | paddingVertical: 12, 75 | }, 76 | title: { 77 | fontSize: 15, 78 | paddingBottom: 2, 79 | }, 80 | artist: { 81 | fontSize: 13, 82 | paddingTop: 2, 83 | }, 84 | selected: { 85 | width: 5, 86 | }, 87 | }); 88 | 89 | export default withTheme(TrackItem); 90 | -------------------------------------------------------------------------------- /ios/ReactNativeSpotifyStreamer/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleDisplayName 8 | ReactNativeSpotifyStreamer 9 | CFBundleExecutable 10 | $(EXECUTABLE_NAME) 11 | CFBundleIdentifier 12 | org.reactjs.native.example.$(PRODUCT_NAME:rfc1034identifier) 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | $(PRODUCT_NAME) 17 | CFBundlePackageType 18 | APPL 19 | CFBundleShortVersionString 20 | 1.0 21 | CFBundleSignature 22 | ???? 23 | CFBundleVersion 24 | 1 25 | LSRequiresIPhoneOS 26 | 27 | NSAppTransportSecurity 28 | 29 | NSExceptionDomains 30 | 31 | localhost 32 | 33 | NSExceptionAllowsInsecureHTTPLoads 34 | 35 | 36 | 37 | 38 | NSLocationWhenInUseUsageDescription 39 | 40 | UIAppFonts 41 | 42 | Entypo.ttf 43 | EvilIcons.ttf 44 | Feather.ttf 45 | FontAwesome.ttf 46 | Foundation.ttf 47 | Ionicons.ttf 48 | MaterialCommunityIcons.ttf 49 | MaterialIcons.ttf 50 | Octicons.ttf 51 | SimpleLineIcons.ttf 52 | Zocial.ttf 53 | 54 | UIBackgroundModes 55 | 56 | audio 57 | 58 | UILaunchStoryboardName 59 | LaunchScreen 60 | UIRequiredDeviceCapabilities 61 | 62 | armv7 63 | 64 | UISupportedInterfaceOrientations 65 | 66 | UIInterfaceOrientationPortrait 67 | UIInterfaceOrientationLandscapeLeft 68 | UIInterfaceOrientationLandscapeRight 69 | 70 | UIViewControllerBasedStatusBarAppearance 71 | 72 | 73 | 74 | -------------------------------------------------------------------------------- /ios/ReactNativeSpotifyStreamerTests/ReactNativeSpotifyStreamerTests.m: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2015-present, Facebook, Inc. 3 | * All rights reserved. 4 | * 5 | * This source code is licensed under the BSD-style license found in the 6 | * LICENSE file in the root directory of this source tree. An additional grant 7 | * of patent rights can be found in the PATENTS file in the same directory. 8 | */ 9 | 10 | #import 11 | #import 12 | 13 | #import 14 | #import 15 | 16 | #define TIMEOUT_SECONDS 600 17 | #define TEXT_TO_LOOK_FOR @"Welcome to React Native!" 18 | 19 | @interface ReactNativeSpotifyStreamerTests : XCTestCase 20 | 21 | @end 22 | 23 | @implementation ReactNativeSpotifyStreamerTests 24 | 25 | - (BOOL)findSubviewInView:(UIView *)view matching:(BOOL(^)(UIView *view))test 26 | { 27 | if (test(view)) { 28 | return YES; 29 | } 30 | for (UIView *subview in [view subviews]) { 31 | if ([self findSubviewInView:subview matching:test]) { 32 | return YES; 33 | } 34 | } 35 | return NO; 36 | } 37 | 38 | - (void)testRendersWelcomeScreen 39 | { 40 | UIViewController *vc = [[[RCTSharedApplication() delegate] window] rootViewController]; 41 | NSDate *date = [NSDate dateWithTimeIntervalSinceNow:TIMEOUT_SECONDS]; 42 | BOOL foundElement = NO; 43 | 44 | __block NSString *redboxError = nil; 45 | RCTSetLogFunction(^(RCTLogLevel level, RCTLogSource source, NSString *fileName, NSNumber *lineNumber, NSString *message) { 46 | if (level >= RCTLogLevelError) { 47 | redboxError = message; 48 | } 49 | }); 50 | 51 | while ([date timeIntervalSinceNow] > 0 && !foundElement && !redboxError) { 52 | [[NSRunLoop mainRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate dateWithTimeIntervalSinceNow:0.1]]; 53 | [[NSRunLoop mainRunLoop] runMode:NSRunLoopCommonModes beforeDate:[NSDate dateWithTimeIntervalSinceNow:0.1]]; 54 | 55 | foundElement = [self findSubviewInView:vc.view matching:^BOOL(UIView *view) { 56 | if ([view.accessibilityLabel isEqualToString:TEXT_TO_LOOK_FOR]) { 57 | return YES; 58 | } 59 | return NO; 60 | }]; 61 | } 62 | 63 | RCTSetLogFunction(RCTDefaultLogFunction); 64 | 65 | XCTAssertNil(redboxError, @"RedBox error: %@", redboxError); 66 | XCTAssertTrue(foundElement, @"Couldn't find element with text '%@' in %d seconds", TEXT_TO_LOOK_FOR, TIMEOUT_SECONDS); 67 | } 68 | 69 | 70 | @end 71 | -------------------------------------------------------------------------------- /android/gradlew.bat: -------------------------------------------------------------------------------- 1 | @if "%DEBUG%" == "" @echo off 2 | @rem ########################################################################## 3 | @rem 4 | @rem Gradle startup script for Windows 5 | @rem 6 | @rem ########################################################################## 7 | 8 | @rem Set local scope for the variables with windows NT shell 9 | if "%OS%"=="Windows_NT" setlocal 10 | 11 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 12 | set DEFAULT_JVM_OPTS= 13 | 14 | set DIRNAME=%~dp0 15 | if "%DIRNAME%" == "" set DIRNAME=. 16 | set APP_BASE_NAME=%~n0 17 | set APP_HOME=%DIRNAME% 18 | 19 | @rem Find java.exe 20 | if defined JAVA_HOME goto findJavaFromJavaHome 21 | 22 | set JAVA_EXE=java.exe 23 | %JAVA_EXE% -version >NUL 2>&1 24 | if "%ERRORLEVEL%" == "0" goto init 25 | 26 | echo. 27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 28 | echo. 29 | echo Please set the JAVA_HOME variable in your environment to match the 30 | echo location of your Java installation. 31 | 32 | goto fail 33 | 34 | :findJavaFromJavaHome 35 | set JAVA_HOME=%JAVA_HOME:"=% 36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe 37 | 38 | if exist "%JAVA_EXE%" goto init 39 | 40 | echo. 41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 42 | echo. 43 | echo Please set the JAVA_HOME variable in your environment to match the 44 | echo location of your Java installation. 45 | 46 | goto fail 47 | 48 | :init 49 | @rem Get command-line arguments, handling Windowz variants 50 | 51 | if not "%OS%" == "Windows_NT" goto win9xME_args 52 | if "%@eval[2+2]" == "4" goto 4NT_args 53 | 54 | :win9xME_args 55 | @rem Slurp the command line arguments. 56 | set CMD_LINE_ARGS= 57 | set _SKIP=2 58 | 59 | :win9xME_args_slurp 60 | if "x%~1" == "x" goto execute 61 | 62 | set CMD_LINE_ARGS=%* 63 | goto execute 64 | 65 | :4NT_args 66 | @rem Get arguments from the 4NT Shell from JP Software 67 | set CMD_LINE_ARGS=%$ 68 | 69 | :execute 70 | @rem Setup the command line 71 | 72 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar 73 | 74 | @rem Execute Gradle 75 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% 76 | 77 | :end 78 | @rem End local scope for the variables with windows NT shell 79 | if "%ERRORLEVEL%"=="0" goto mainEnd 80 | 81 | :fail 82 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 83 | rem the _cmd.exe /c_ return code! 84 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 85 | exit /b 1 86 | 87 | :mainEnd 88 | if "%OS%"=="Windows_NT" endlocal 89 | 90 | :omega 91 | -------------------------------------------------------------------------------- /android/app/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # By default, the flags in this file are appended to flags specified 3 | # in /usr/local/Cellar/android-sdk/24.3.3/tools/proguard/proguard-android.txt 4 | # You can edit the include path and order by changing the proguardFiles 5 | # directive in build.gradle. 6 | # 7 | # For more details, see 8 | # http://developer.android.com/guide/developing/tools/proguard.html 9 | 10 | # Add any project specific keep options here: 11 | 12 | # If your project uses WebView with JS, uncomment the following 13 | # and specify the fully qualified class name to the JavaScript interface 14 | # class: 15 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 16 | # public *; 17 | #} 18 | 19 | # Disabling obfuscation is useful if you collect stack traces from production crashes 20 | # (unless you are using a system that supports de-obfuscate the stack traces). 21 | -dontobfuscate 22 | 23 | # React Native 24 | 25 | # Keep our interfaces so they can be used by other ProGuard rules. 26 | # See http://sourceforge.net/p/proguard/bugs/466/ 27 | -keep,allowobfuscation @interface com.facebook.proguard.annotations.DoNotStrip 28 | -keep,allowobfuscation @interface com.facebook.proguard.annotations.KeepGettersAndSetters 29 | -keep,allowobfuscation @interface com.facebook.common.internal.DoNotStrip 30 | 31 | # Do not strip any method/class that is annotated with @DoNotStrip 32 | -keep @com.facebook.proguard.annotations.DoNotStrip class * 33 | -keep @com.facebook.common.internal.DoNotStrip class * 34 | -keepclassmembers class * { 35 | @com.facebook.proguard.annotations.DoNotStrip *; 36 | @com.facebook.common.internal.DoNotStrip *; 37 | } 38 | 39 | -keepclassmembers @com.facebook.proguard.annotations.KeepGettersAndSetters class * { 40 | void set*(***); 41 | *** get*(); 42 | } 43 | 44 | -keep class * extends com.facebook.react.bridge.JavaScriptModule { *; } 45 | -keep class * extends com.facebook.react.bridge.NativeModule { *; } 46 | -keepclassmembers,includedescriptorclasses class * { native ; } 47 | -keepclassmembers class * { @com.facebook.react.uimanager.UIProp ; } 48 | -keepclassmembers class * { @com.facebook.react.uimanager.annotations.ReactProp ; } 49 | -keepclassmembers class * { @com.facebook.react.uimanager.annotations.ReactPropGroup ; } 50 | 51 | -dontwarn com.facebook.react.** 52 | 53 | # TextLayoutBuilder uses a non-public Android constructor within StaticLayout. 54 | # See libs/proxy/src/main/java/com/facebook/fbui/textlayoutbuilder/proxy for details. 55 | -dontwarn android.text.StaticLayout 56 | 57 | # okhttp 58 | 59 | -keepattributes Signature 60 | -keepattributes *Annotation* 61 | -keep class okhttp3.** { *; } 62 | -keep interface okhttp3.** { *; } 63 | -dontwarn okhttp3.** 64 | 65 | # okio 66 | 67 | -keep class sun.misc.Unsafe { *; } 68 | -dontwarn java.nio.file.* 69 | -dontwarn org.codehaus.mojo.animal_sniffer.IgnoreJRERequirement 70 | -dontwarn okio.** 71 | -------------------------------------------------------------------------------- /src/Player.js: -------------------------------------------------------------------------------- 1 | /* @flow */ 2 | 3 | import React, { Component, Fragment } from 'react'; 4 | import { Image, StyleSheet, View } from 'react-native'; 5 | import { Divider, Text, withTheme } from 'react-native-paper'; 6 | 7 | import type { ThemeType } from './theme'; 8 | import type { TrackType } from './api/types'; 9 | import PlayerControls from './PlayerControls'; 10 | import ProgressBar from './components/ProgressBar'; 11 | 12 | type Props = { 13 | theme: ThemeType, 14 | track: ?TrackType, 15 | }; 16 | 17 | class Player extends Component { 18 | renderTrackPlaceHolder() { 19 | const { theme } = this.props; 20 | return ( 21 | 22 | 25 | No track selected 26 | 27 | 28 | ); 29 | } 30 | 31 | render() { 32 | const { theme, track } = this.props; 33 | 34 | return ( 35 | 36 | 37 | 38 | {!track ? ( 39 | this.renderTrackPlaceHolder() 40 | ) : ( 41 | 42 | 48 | 49 | 50 | 54 | {track.name} 55 | 56 | 66 | {track.artists[0].name.toUpperCase()} 67 | 68 | 69 | 70 | 71 | 72 | )} 73 | 74 | 75 | 76 | ); 77 | } 78 | } 79 | 80 | const styles = StyleSheet.create({ 81 | container: { 82 | height: 220, 83 | }, 84 | trackContainer: { 85 | height: 140, 86 | paddingHorizontal: 16, 87 | flexDirection: 'row', 88 | alignItems: 'center', 89 | }, 90 | albumCover: { 91 | height: 100, 92 | width: 100, 93 | }, 94 | trackInfo: { 95 | flex: 1, 96 | height: 100, 97 | justifyContent: 'space-between', 98 | paddingLeft: 16, 99 | paddingVertical: 4, 100 | }, 101 | title: { 102 | fontSize: 20, 103 | paddingBottom: 2, 104 | }, 105 | artist: { 106 | fontSize: 14, 107 | paddingTop: 2, 108 | paddingBottom: 10, 109 | }, 110 | trackPlaceHolder: { 111 | flex: 1, 112 | alignItems: 'center', 113 | }, 114 | placeHolderText: { 115 | fontSize: 18, 116 | }, 117 | }); 118 | 119 | export default withTheme(Player); 120 | -------------------------------------------------------------------------------- /src/PlayerControls.js: -------------------------------------------------------------------------------- 1 | /* @flow */ 2 | 3 | import React, { PureComponent } from 'react'; 4 | import { Platform, StyleSheet, View } from 'react-native'; 5 | import { withTheme } from 'react-native-paper'; 6 | import TrackPlayer from 'react-native-track-player'; 7 | import { connect } from 'react-redux'; 8 | 9 | import type { ThemeType } from './theme'; 10 | import TouchableIcon from './components/TouchableIcon'; 11 | import type { TrackType } from './api/types'; 12 | import { getTrackStructure } from './utils'; 13 | 14 | type Props = { 15 | playerState: string, 16 | theme: ThemeType, 17 | track: TrackType, 18 | }; 19 | 20 | // The constant TrackPlayer.STATE_PLAYING is not consistent across platforms 21 | // https://github.com/react-native-kit/react-native-track-player/issues/141 22 | const STATE_PLAYING = Platform.OS === 'android' ? 3 : 'STATE_PLAYING'; 23 | const STATE_PAUSED = Platform.OS === 'android' ? 2 : 'STATE_PAUSED'; 24 | 25 | class PlayerControls extends PureComponent { 26 | componentWillReceiveProps(nextProps: Props) { 27 | if (nextProps.track && this.props.track !== nextProps.track) { 28 | this._checkChangeSelectedTrack(); 29 | } 30 | } 31 | 32 | _checkChangeSelectedTrack = async () => { 33 | let isCurrentTrack; 34 | isCurrentTrack = await !!TrackPlayer.getCurrentTrack().catch(() => { 35 | // If nothing is playing, it rejects the promise 36 | isCurrentTrack = false; 37 | }); 38 | if (isCurrentTrack) { 39 | this._playNewTrack(); 40 | } 41 | }; 42 | 43 | _onPlayPause = async () => { 44 | const state = this.props.playerState; 45 | 46 | if (state === STATE_PLAYING) { 47 | await TrackPlayer.pause(); 48 | } else if (state === STATE_PAUSED) { 49 | const position = Math.round(await TrackPlayer.getPosition()); 50 | const duration = Math.round(await TrackPlayer.getDuration()); 51 | if (position === duration) { 52 | // It's finished 53 | this._playNewTrack(); 54 | } else { 55 | await TrackPlayer.play(); 56 | } 57 | } else { 58 | this._playNewTrack(); 59 | } 60 | }; 61 | 62 | _playNewTrack = async () => { 63 | const { track } = this.props; 64 | 65 | await TrackPlayer.reset(); 66 | await TrackPlayer.add(getTrackStructure(track)); 67 | await TrackPlayer.play(); 68 | }; 69 | 70 | render() { 71 | const { playerState, theme, track } = this.props; 72 | 73 | return ( 74 | 80 | {}} 84 | disabled={!track} 85 | /> 86 | 92 | {}} 96 | disabled={!track} 97 | /> 98 | 99 | ); 100 | } 101 | } 102 | 103 | const styles = StyleSheet.create({ 104 | playerContainer: { 105 | flexDirection: 'row', 106 | height: 80, 107 | }, 108 | iconButton: { 109 | flex: 1, 110 | justifyContent: 'center', 111 | alignItems: 'center', 112 | }, 113 | }); 114 | 115 | export default connect( 116 | state => ({ 117 | playerState: state.player.playerState, 118 | }), 119 | null 120 | )(withTheme(PlayerControls)); 121 | -------------------------------------------------------------------------------- /ios/ReactNativeSpotifyStreamer/Base.lproj/LaunchScreen.xib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 21 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | -------------------------------------------------------------------------------- /src/App.js: -------------------------------------------------------------------------------- 1 | /* @flow */ 2 | 3 | import React, { Component, Fragment } from 'react'; 4 | import { 5 | AsyncStorage, 6 | Platform, 7 | StatusBar, 8 | StyleSheet, 9 | View, 10 | } from 'react-native'; 11 | import { SearchBar, withTheme } from 'react-native-paper'; 12 | import Rx from 'rxjs/Rx'; 13 | import TrackPlayer from 'react-native-track-player'; 14 | import type { Theme } from 'react-native-paper/src/types'; 15 | 16 | import { authHeaders, fetchSearch, getToken, tokenHeaders } from './api/api'; 17 | import type { TokenResult, TrackResult, TrackType } from './api/types'; 18 | import TrackList from './TrackList'; 19 | 20 | type Props = { 21 | theme: Theme, 22 | }; 23 | 24 | type State = { 25 | accessToken: string, 26 | query: string, 27 | tracks: Array, 28 | }; 29 | 30 | class App extends Component { 31 | token$ = null; 32 | searchInput$ = null; 33 | 34 | state = { 35 | accessToken: '', 36 | query: '', 37 | tracks: [], 38 | }; 39 | 40 | componentDidMount() { 41 | this.initAccessToken(); 42 | this.initSearchInput(); 43 | this.initPlayer(); 44 | } 45 | 46 | componentWillUnmount() { 47 | // $FlowFixMe 48 | this.searchInput$.unsubscribe(); 49 | if (this.token$) { 50 | this.token$.unsubscribe(); 51 | } 52 | } 53 | 54 | initAccessToken = async () => { 55 | const accessToken = await AsyncStorage.getItem('@AccessToken'); 56 | if (accessToken) { 57 | this.setState({ accessToken }); 58 | } else { 59 | this.token$ = this.getAccessToken(); 60 | } 61 | }; 62 | 63 | getAccessToken = () => { 64 | const token$ = new Rx.Subject(); 65 | token$ 66 | .take(1) 67 | .switchMap(() => 68 | Rx.Observable.ajax 69 | .post(getToken(), { grant_type: 'client_credentials' }, tokenHeaders) 70 | .map(result => result) 71 | .catch(() => Rx.Observable.empty()) 72 | ) 73 | .subscribe((result: TokenResult) => { 74 | const accessToken = result.response.access_token; 75 | this.setState({ accessToken }, async () => { 76 | // Ready to retry the query 77 | await AsyncStorage.setItem('@AccessToken', accessToken); 78 | // $FlowFixMe 79 | this.searchInput$.next(this.state.query); 80 | }); 81 | }); 82 | token$.next(); 83 | return token$; 84 | }; 85 | 86 | initSearchInput = () => { 87 | this.searchInput$ = new Rx.Subject(); 88 | this.searchInput$ 89 | .debounceTime(300) 90 | .switchMap(query => 91 | Rx.Observable.ajax 92 | .getJSON(fetchSearch(query), authHeaders(this.state.accessToken)) 93 | .map((result: TrackResult) => result) 94 | .catch((e: { status: number }) => { 95 | if (e.status === 401) { 96 | // Handle token expiration 97 | this.token$ = this.getAccessToken(); 98 | } 99 | return Rx.Observable.empty(); 100 | }) 101 | ) 102 | .subscribe((result: TrackResult) => { 103 | this.setState({ tracks: result.tracks.items }); 104 | }); 105 | }; 106 | 107 | initPlayer = async () => { 108 | await TrackPlayer.setupPlayer(); 109 | }; 110 | 111 | onArtistChange = query => { 112 | this.setState({ query, tracks: !query ? [] : this.state.tracks }, () => { 113 | if (query) { 114 | // $FlowFixMe 115 | this.searchInput$.next(query); 116 | } 117 | }); 118 | }; 119 | 120 | renderBody = () => { 121 | const { query, tracks } = this.state; 122 | 123 | return ( 124 | 125 | 131 | 132 | 133 | ); 134 | }; 135 | 136 | render() { 137 | const { theme } = this.props; 138 | const { accessToken } = this.state; 139 | 140 | return ( 141 | 144 | 145 | {!!accessToken && this.renderBody()} 146 | 147 | ); 148 | } 149 | } 150 | 151 | const styles = StyleSheet.create({ 152 | container: { 153 | flex: 1, 154 | paddingTop: Platform.OS === 'ios' ? 24 : 0, 155 | }, 156 | }); 157 | 158 | export default withTheme(App); 159 | -------------------------------------------------------------------------------- /android/gradlew: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | ############################################################################## 4 | ## 5 | ## Gradle start up script for UN*X 6 | ## 7 | ############################################################################## 8 | 9 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 10 | DEFAULT_JVM_OPTS="" 11 | 12 | APP_NAME="Gradle" 13 | APP_BASE_NAME=`basename "$0"` 14 | 15 | # Use the maximum available, or set MAX_FD != -1 to use that value. 16 | MAX_FD="maximum" 17 | 18 | warn ( ) { 19 | echo "$*" 20 | } 21 | 22 | die ( ) { 23 | echo 24 | echo "$*" 25 | echo 26 | exit 1 27 | } 28 | 29 | # OS specific support (must be 'true' or 'false'). 30 | cygwin=false 31 | msys=false 32 | darwin=false 33 | case "`uname`" in 34 | CYGWIN* ) 35 | cygwin=true 36 | ;; 37 | Darwin* ) 38 | darwin=true 39 | ;; 40 | MINGW* ) 41 | msys=true 42 | ;; 43 | esac 44 | 45 | # For Cygwin, ensure paths are in UNIX format before anything is touched. 46 | if $cygwin ; then 47 | [ -n "$JAVA_HOME" ] && JAVA_HOME=`cygpath --unix "$JAVA_HOME"` 48 | fi 49 | 50 | # Attempt to set APP_HOME 51 | # Resolve links: $0 may be a link 52 | PRG="$0" 53 | # Need this for relative symlinks. 54 | while [ -h "$PRG" ] ; do 55 | ls=`ls -ld "$PRG"` 56 | link=`expr "$ls" : '.*-> \(.*\)$'` 57 | if expr "$link" : '/.*' > /dev/null; then 58 | PRG="$link" 59 | else 60 | PRG=`dirname "$PRG"`"/$link" 61 | fi 62 | done 63 | SAVED="`pwd`" 64 | cd "`dirname \"$PRG\"`/" >&- 65 | APP_HOME="`pwd -P`" 66 | cd "$SAVED" >&- 67 | 68 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar 69 | 70 | # Determine the Java command to use to start the JVM. 71 | if [ -n "$JAVA_HOME" ] ; then 72 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then 73 | # IBM's JDK on AIX uses strange locations for the executables 74 | JAVACMD="$JAVA_HOME/jre/sh/java" 75 | else 76 | JAVACMD="$JAVA_HOME/bin/java" 77 | fi 78 | if [ ! -x "$JAVACMD" ] ; then 79 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME 80 | 81 | Please set the JAVA_HOME variable in your environment to match the 82 | location of your Java installation." 83 | fi 84 | else 85 | JAVACMD="java" 86 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 87 | 88 | Please set the JAVA_HOME variable in your environment to match the 89 | location of your Java installation." 90 | fi 91 | 92 | # Increase the maximum file descriptors if we can. 93 | if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then 94 | MAX_FD_LIMIT=`ulimit -H -n` 95 | if [ $? -eq 0 ] ; then 96 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then 97 | MAX_FD="$MAX_FD_LIMIT" 98 | fi 99 | ulimit -n $MAX_FD 100 | if [ $? -ne 0 ] ; then 101 | warn "Could not set maximum file descriptor limit: $MAX_FD" 102 | fi 103 | else 104 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" 105 | fi 106 | fi 107 | 108 | # For Darwin, add options to specify how the application appears in the dock 109 | if $darwin; then 110 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" 111 | fi 112 | 113 | # For Cygwin, switch paths to Windows format before running java 114 | if $cygwin ; then 115 | APP_HOME=`cygpath --path --mixed "$APP_HOME"` 116 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` 117 | 118 | # We build the pattern for arguments to be converted via cygpath 119 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` 120 | SEP="" 121 | for dir in $ROOTDIRSRAW ; do 122 | ROOTDIRS="$ROOTDIRS$SEP$dir" 123 | SEP="|" 124 | done 125 | OURCYGPATTERN="(^($ROOTDIRS))" 126 | # Add a user-defined pattern to the cygpath arguments 127 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then 128 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" 129 | fi 130 | # Now convert the arguments - kludge to limit ourselves to /bin/sh 131 | i=0 132 | for arg in "$@" ; do 133 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` 134 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option 135 | 136 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition 137 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` 138 | else 139 | eval `echo args$i`="\"$arg\"" 140 | fi 141 | i=$((i+1)) 142 | done 143 | case $i in 144 | (0) set -- ;; 145 | (1) set -- "$args0" ;; 146 | (2) set -- "$args0" "$args1" ;; 147 | (3) set -- "$args0" "$args1" "$args2" ;; 148 | (4) set -- "$args0" "$args1" "$args2" "$args3" ;; 149 | (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; 150 | (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; 151 | (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; 152 | (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; 153 | (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; 154 | esac 155 | fi 156 | 157 | # Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules 158 | function splitJvmOpts() { 159 | JVM_OPTS=("$@") 160 | } 161 | eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS 162 | JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME" 163 | 164 | exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@" 165 | -------------------------------------------------------------------------------- /ios/ReactNativeSpotifyStreamer.xcodeproj/xcshareddata/xcschemes/ReactNativeSpotifyStreamer.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 29 | 35 | 36 | 37 | 43 | 49 | 50 | 51 | 52 | 53 | 58 | 59 | 61 | 67 | 68 | 69 | 70 | 71 | 77 | 78 | 79 | 80 | 81 | 82 | 92 | 94 | 100 | 101 | 102 | 103 | 104 | 105 | 111 | 113 | 119 | 120 | 121 | 122 | 124 | 125 | 128 | 129 | 130 | -------------------------------------------------------------------------------- /ios/ReactNativeSpotifyStreamer.xcodeproj/xcshareddata/xcschemes/ReactNativeSpotifyStreamer-tvOS.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 29 | 35 | 36 | 37 | 43 | 49 | 50 | 51 | 52 | 53 | 58 | 59 | 61 | 67 | 68 | 69 | 70 | 71 | 77 | 78 | 79 | 80 | 81 | 82 | 92 | 94 | 100 | 101 | 102 | 103 | 104 | 105 | 111 | 113 | 119 | 120 | 121 | 122 | 124 | 125 | 128 | 129 | 130 | -------------------------------------------------------------------------------- /android/app/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: "com.android.application" 2 | 3 | import com.android.build.OutputFile 4 | 5 | /** 6 | * The react.gradle file registers a task for each build variant (e.g. bundleDebugJsAndAssets 7 | * and bundleReleaseJsAndAssets). 8 | * These basically call `react-native bundle` with the correct arguments during the Android build 9 | * cycle. By default, bundleDebugJsAndAssets is skipped, as in debug/dev mode we prefer to load the 10 | * bundle directly from the development server. Below you can see all the possible configurations 11 | * and their defaults. If you decide to add a configuration block, make sure to add it before the 12 | * `apply from: "../../node_modules/react-native/react.gradle"` line. 13 | * 14 | * project.ext.react = [ 15 | * // the name of the generated asset file containing your JS bundle 16 | * bundleAssetName: "index.android.bundle", 17 | * 18 | * // the entry file for bundle generation 19 | * entryFile: "index.android.js", 20 | * 21 | * // whether to bundle JS and assets in debug mode 22 | * bundleInDebug: false, 23 | * 24 | * // whether to bundle JS and assets in release mode 25 | * bundleInRelease: true, 26 | * 27 | * // whether to bundle JS and assets in another build variant (if configured). 28 | * // See http://tools.android.com/tech-docs/new-build-system/user-guide#TOC-Build-Variants 29 | * // The configuration property can be in the following formats 30 | * // 'bundleIn${productFlavor}${buildType}' 31 | * // 'bundleIn${buildType}' 32 | * // bundleInFreeDebug: true, 33 | * // bundleInPaidRelease: true, 34 | * // bundleInBeta: true, 35 | * 36 | * // whether to disable dev mode in custom build variants (by default only disabled in release) 37 | * // for example: to disable dev mode in the staging build type (if configured) 38 | * devDisabledInStaging: true, 39 | * // The configuration property can be in the following formats 40 | * // 'devDisabledIn${productFlavor}${buildType}' 41 | * // 'devDisabledIn${buildType}' 42 | * 43 | * // the root of your project, i.e. where "package.json" lives 44 | * root: "../../", 45 | * 46 | * // where to put the JS bundle asset in debug mode 47 | * jsBundleDirDebug: "$buildDir/intermediates/assets/debug", 48 | * 49 | * // where to put the JS bundle asset in release mode 50 | * jsBundleDirRelease: "$buildDir/intermediates/assets/release", 51 | * 52 | * // where to put drawable resources / React Native assets, e.g. the ones you use via 53 | * // require('./image.png')), in debug mode 54 | * resourcesDirDebug: "$buildDir/intermediates/res/merged/debug", 55 | * 56 | * // where to put drawable resources / React Native assets, e.g. the ones you use via 57 | * // require('./image.png')), in release mode 58 | * resourcesDirRelease: "$buildDir/intermediates/res/merged/release", 59 | * 60 | * // by default the gradle tasks are skipped if none of the JS files or assets change; this means 61 | * // that we don't look at files in android/ or ios/ to determine whether the tasks are up to 62 | * // date; if you have any other folders that you want to ignore for performance reasons (gradle 63 | * // indexes the entire tree), add them here. Alternatively, if you have JS files in android/ 64 | * // for example, you might want to remove it from here. 65 | * inputExcludes: ["android/**", "ios/**"], 66 | * 67 | * // override which node gets called and with what additional arguments 68 | * nodeExecutableAndArgs: ["node"], 69 | * 70 | * // supply additional arguments to the packager 71 | * extraPackagerArgs: [] 72 | * ] 73 | */ 74 | 75 | project.ext.react = [ 76 | entryFile: "index.js" 77 | ] 78 | 79 | apply from: "../../node_modules/react-native/react.gradle" 80 | 81 | /** 82 | * Set this to true to create two separate APKs instead of one: 83 | * - An APK that only works on ARM devices 84 | * - An APK that only works on x86 devices 85 | * The advantage is the size of the APK is reduced by about 4MB. 86 | * Upload all the APKs to the Play Store and people will download 87 | * the correct one based on the CPU architecture of their device. 88 | */ 89 | def enableSeparateBuildPerCPUArchitecture = false 90 | 91 | /** 92 | * Run Proguard to shrink the Java bytecode in release builds. 93 | */ 94 | def enableProguardInReleaseBuilds = false 95 | 96 | android { 97 | compileSdkVersion 23 98 | buildToolsVersion "23.0.1" 99 | 100 | defaultConfig { 101 | applicationId "com.reactnativespotifystreamer" 102 | minSdkVersion 16 103 | targetSdkVersion 22 104 | versionCode 1 105 | versionName "1.0" 106 | ndk { 107 | abiFilters "armeabi-v7a", "x86" 108 | } 109 | } 110 | splits { 111 | abi { 112 | reset() 113 | enable enableSeparateBuildPerCPUArchitecture 114 | universalApk false // If true, also generate a universal APK 115 | include "armeabi-v7a", "x86" 116 | } 117 | } 118 | buildTypes { 119 | release { 120 | minifyEnabled enableProguardInReleaseBuilds 121 | proguardFiles getDefaultProguardFile("proguard-android.txt"), "proguard-rules.pro" 122 | } 123 | } 124 | // applicationVariants are e.g. debug, release 125 | applicationVariants.all { variant -> 126 | variant.outputs.each { output -> 127 | // For each separate APK per architecture, set a unique version code as described here: 128 | // http://tools.android.com/tech-docs/new-build-system/user-guide/apk-splits 129 | def versionCodes = ["armeabi-v7a":1, "x86":2] 130 | def abi = output.getFilter(OutputFile.ABI) 131 | if (abi != null) { // null for the universal-debug, universal-release variants 132 | output.versionCodeOverride = 133 | versionCodes.get(abi) * 1048576 + defaultConfig.versionCode 134 | } 135 | } 136 | } 137 | } 138 | 139 | dependencies { 140 | compile project(':react-native-track-player') 141 | compile project(':react-native-vector-icons') 142 | compile fileTree(dir: "libs", include: ["*.jar"]) 143 | compile "com.android.support:appcompat-v7:23.0.1" 144 | compile "com.facebook.react:react-native:+" // From node_modules 145 | } 146 | 147 | // Run this once to be able to run the application with BUCK 148 | // puts all compile dependencies into folder libs for BUCK to use 149 | task copyDownloadableDepsToLibs(type: Copy) { 150 | from configurations.compile 151 | into 'libs' 152 | } 153 | -------------------------------------------------------------------------------- /flow-typed/npm/jest_v22.x.x.js: -------------------------------------------------------------------------------- 1 | // flow-typed signature: 6e1fc0a644aa956f79029fec0709e597 2 | // flow-typed version: 07ebad4796/jest_v22.x.x/flow_>=v0.39.x 3 | 4 | type JestMockFn, TReturn> = { 5 | (...args: TArguments): TReturn, 6 | /** 7 | * An object for introspecting mock calls 8 | */ 9 | mock: { 10 | /** 11 | * An array that represents all calls that have been made into this mock 12 | * function. Each call is represented by an array of arguments that were 13 | * passed during the call. 14 | */ 15 | calls: Array, 16 | /** 17 | * An array that contains all the object instances that have been 18 | * instantiated from this mock function. 19 | */ 20 | instances: Array 21 | }, 22 | /** 23 | * Resets all information stored in the mockFn.mock.calls and 24 | * mockFn.mock.instances arrays. Often this is useful when you want to clean 25 | * up a mock's usage data between two assertions. 26 | */ 27 | mockClear(): void, 28 | /** 29 | * Resets all information stored in the mock. This is useful when you want to 30 | * completely restore a mock back to its initial state. 31 | */ 32 | mockReset(): void, 33 | /** 34 | * Removes the mock and restores the initial implementation. This is useful 35 | * when you want to mock functions in certain test cases and restore the 36 | * original implementation in others. Beware that mockFn.mockRestore only 37 | * works when mock was created with jest.spyOn. Thus you have to take care of 38 | * restoration yourself when manually assigning jest.fn(). 39 | */ 40 | mockRestore(): void, 41 | /** 42 | * Accepts a function that should be used as the implementation of the mock. 43 | * The mock itself will still record all calls that go into and instances 44 | * that come from itself -- the only difference is that the implementation 45 | * will also be executed when the mock is called. 46 | */ 47 | mockImplementation( 48 | fn: (...args: TArguments) => TReturn 49 | ): JestMockFn, 50 | /** 51 | * Accepts a function that will be used as an implementation of the mock for 52 | * one call to the mocked function. Can be chained so that multiple function 53 | * calls produce different results. 54 | */ 55 | mockImplementationOnce( 56 | fn: (...args: TArguments) => TReturn 57 | ): JestMockFn, 58 | /** 59 | * Just a simple sugar function for returning `this` 60 | */ 61 | mockReturnThis(): void, 62 | /** 63 | * Deprecated: use jest.fn(() => value) instead 64 | */ 65 | mockReturnValue(value: TReturn): JestMockFn, 66 | /** 67 | * Sugar for only returning a value once inside your mock 68 | */ 69 | mockReturnValueOnce(value: TReturn): JestMockFn 70 | }; 71 | 72 | type JestAsymmetricEqualityType = { 73 | /** 74 | * A custom Jasmine equality tester 75 | */ 76 | asymmetricMatch(value: mixed): boolean 77 | }; 78 | 79 | type JestCallsType = { 80 | allArgs(): mixed, 81 | all(): mixed, 82 | any(): boolean, 83 | count(): number, 84 | first(): mixed, 85 | mostRecent(): mixed, 86 | reset(): void 87 | }; 88 | 89 | type JestClockType = { 90 | install(): void, 91 | mockDate(date: Date): void, 92 | tick(milliseconds?: number): void, 93 | uninstall(): void 94 | }; 95 | 96 | type JestMatcherResult = { 97 | message?: string | (() => string), 98 | pass: boolean 99 | }; 100 | 101 | type JestMatcher = (actual: any, expected: any) => JestMatcherResult; 102 | 103 | type JestPromiseType = { 104 | /** 105 | * Use rejects to unwrap the reason of a rejected promise so any other 106 | * matcher can be chained. If the promise is fulfilled the assertion fails. 107 | */ 108 | rejects: JestExpectType, 109 | /** 110 | * Use resolves to unwrap the value of a fulfilled promise so any other 111 | * matcher can be chained. If the promise is rejected the assertion fails. 112 | */ 113 | resolves: JestExpectType 114 | }; 115 | 116 | /** 117 | * Plugin: jest-enzyme 118 | */ 119 | type EnzymeMatchersType = { 120 | toBeChecked(): void, 121 | toBeDisabled(): void, 122 | toBeEmpty(): void, 123 | toBePresent(): void, 124 | toContainReact(element: React$Element): void, 125 | toHaveClassName(className: string): void, 126 | toHaveHTML(html: string): void, 127 | toHaveProp(propKey: string, propValue?: any): void, 128 | toHaveRef(refName: string): void, 129 | toHaveState(stateKey: string, stateValue?: any): void, 130 | toHaveStyle(styleKey: string, styleValue?: any): void, 131 | toHaveTagName(tagName: string): void, 132 | toHaveText(text: string): void, 133 | toIncludeText(text: string): void, 134 | toHaveValue(value: any): void, 135 | toMatchElement(element: React$Element): void, 136 | toMatchSelector(selector: string): void 137 | }; 138 | 139 | type JestExpectType = { 140 | not: JestExpectType & EnzymeMatchersType, 141 | /** 142 | * If you have a mock function, you can use .lastCalledWith to test what 143 | * arguments it was last called with. 144 | */ 145 | lastCalledWith(...args: Array): void, 146 | /** 147 | * toBe just checks that a value is what you expect. It uses === to check 148 | * strict equality. 149 | */ 150 | toBe(value: any): void, 151 | /** 152 | * Use .toHaveBeenCalled to ensure that a mock function got called. 153 | */ 154 | toBeCalled(): void, 155 | /** 156 | * Use .toBeCalledWith to ensure that a mock function was called with 157 | * specific arguments. 158 | */ 159 | toBeCalledWith(...args: Array): void, 160 | /** 161 | * Using exact equality with floating point numbers is a bad idea. Rounding 162 | * means that intuitive things fail. 163 | */ 164 | toBeCloseTo(num: number, delta: any): void, 165 | /** 166 | * Use .toBeDefined to check that a variable is not undefined. 167 | */ 168 | toBeDefined(): void, 169 | /** 170 | * Use .toBeFalsy when you don't care what a value is, you just want to 171 | * ensure a value is false in a boolean context. 172 | */ 173 | toBeFalsy(): void, 174 | /** 175 | * To compare floating point numbers, you can use toBeGreaterThan. 176 | */ 177 | toBeGreaterThan(number: number): void, 178 | /** 179 | * To compare floating point numbers, you can use toBeGreaterThanOrEqual. 180 | */ 181 | toBeGreaterThanOrEqual(number: number): void, 182 | /** 183 | * To compare floating point numbers, you can use toBeLessThan. 184 | */ 185 | toBeLessThan(number: number): void, 186 | /** 187 | * To compare floating point numbers, you can use toBeLessThanOrEqual. 188 | */ 189 | toBeLessThanOrEqual(number: number): void, 190 | /** 191 | * Use .toBeInstanceOf(Class) to check that an object is an instance of a 192 | * class. 193 | */ 194 | toBeInstanceOf(cls: Class<*>): void, 195 | /** 196 | * .toBeNull() is the same as .toBe(null) but the error messages are a bit 197 | * nicer. 198 | */ 199 | toBeNull(): void, 200 | /** 201 | * Use .toBeTruthy when you don't care what a value is, you just want to 202 | * ensure a value is true in a boolean context. 203 | */ 204 | toBeTruthy(): void, 205 | /** 206 | * Use .toBeUndefined to check that a variable is undefined. 207 | */ 208 | toBeUndefined(): void, 209 | /** 210 | * Use .toContain when you want to check that an item is in a list. For 211 | * testing the items in the list, this uses ===, a strict equality check. 212 | */ 213 | toContain(item: any): void, 214 | /** 215 | * Use .toContainEqual when you want to check that an item is in a list. For 216 | * testing the items in the list, this matcher recursively checks the 217 | * equality of all fields, rather than checking for object identity. 218 | */ 219 | toContainEqual(item: any): void, 220 | /** 221 | * Use .toEqual when you want to check that two objects have the same value. 222 | * This matcher recursively checks the equality of all fields, rather than 223 | * checking for object identity. 224 | */ 225 | toEqual(value: any): void, 226 | /** 227 | * Use .toHaveBeenCalled to ensure that a mock function got called. 228 | */ 229 | toHaveBeenCalled(): void, 230 | /** 231 | * Use .toHaveBeenCalledTimes to ensure that a mock function got called exact 232 | * number of times. 233 | */ 234 | toHaveBeenCalledTimes(number: number): void, 235 | /** 236 | * Use .toHaveBeenCalledWith to ensure that a mock function was called with 237 | * specific arguments. 238 | */ 239 | toHaveBeenCalledWith(...args: Array): void, 240 | /** 241 | * Use .toHaveBeenLastCalledWith to ensure that a mock function was last called 242 | * with specific arguments. 243 | */ 244 | toHaveBeenLastCalledWith(...args: Array): void, 245 | /** 246 | * Check that an object has a .length property and it is set to a certain 247 | * numeric value. 248 | */ 249 | toHaveLength(number: number): void, 250 | /** 251 | * 252 | */ 253 | toHaveProperty(propPath: string, value?: any): void, 254 | /** 255 | * Use .toMatch to check that a string matches a regular expression or string. 256 | */ 257 | toMatch(regexpOrString: RegExp | string): void, 258 | /** 259 | * Use .toMatchObject to check that a javascript object matches a subset of the properties of an object. 260 | */ 261 | toMatchObject(object: Object | Array): void, 262 | /** 263 | * This ensures that a React component matches the most recent snapshot. 264 | */ 265 | toMatchSnapshot(name?: string): void, 266 | /** 267 | * Use .toThrow to test that a function throws when it is called. 268 | * If you want to test that a specific error gets thrown, you can provide an 269 | * argument to toThrow. The argument can be a string for the error message, 270 | * a class for the error, or a regex that should match the error. 271 | * 272 | * Alias: .toThrowError 273 | */ 274 | toThrow(message?: string | Error | Class | RegExp): void, 275 | toThrowError(message?: string | Error | Class | RegExp): void, 276 | /** 277 | * Use .toThrowErrorMatchingSnapshot to test that a function throws a error 278 | * matching the most recent snapshot when it is called. 279 | */ 280 | toThrowErrorMatchingSnapshot(): void 281 | }; 282 | 283 | type JestObjectType = { 284 | /** 285 | * Disables automatic mocking in the module loader. 286 | * 287 | * After this method is called, all `require()`s will return the real 288 | * versions of each module (rather than a mocked version). 289 | */ 290 | disableAutomock(): JestObjectType, 291 | /** 292 | * An un-hoisted version of disableAutomock 293 | */ 294 | autoMockOff(): JestObjectType, 295 | /** 296 | * Enables automatic mocking in the module loader. 297 | */ 298 | enableAutomock(): JestObjectType, 299 | /** 300 | * An un-hoisted version of enableAutomock 301 | */ 302 | autoMockOn(): JestObjectType, 303 | /** 304 | * Clears the mock.calls and mock.instances properties of all mocks. 305 | * Equivalent to calling .mockClear() on every mocked function. 306 | */ 307 | clearAllMocks(): JestObjectType, 308 | /** 309 | * Resets the state of all mocks. Equivalent to calling .mockReset() on every 310 | * mocked function. 311 | */ 312 | resetAllMocks(): JestObjectType, 313 | /** 314 | * Restores all mocks back to their original value. 315 | */ 316 | restoreAllMocks(): JestObjectType, 317 | /** 318 | * Removes any pending timers from the timer system. 319 | */ 320 | clearAllTimers(): void, 321 | /** 322 | * The same as `mock` but not moved to the top of the expectation by 323 | * babel-jest. 324 | */ 325 | doMock(moduleName: string, moduleFactory?: any): JestObjectType, 326 | /** 327 | * The same as `unmock` but not moved to the top of the expectation by 328 | * babel-jest. 329 | */ 330 | dontMock(moduleName: string): JestObjectType, 331 | /** 332 | * Returns a new, unused mock function. Optionally takes a mock 333 | * implementation. 334 | */ 335 | fn, TReturn>( 336 | implementation?: (...args: TArguments) => TReturn 337 | ): JestMockFn, 338 | /** 339 | * Determines if the given function is a mocked function. 340 | */ 341 | isMockFunction(fn: Function): boolean, 342 | /** 343 | * Given the name of a module, use the automatic mocking system to generate a 344 | * mocked version of the module for you. 345 | */ 346 | genMockFromModule(moduleName: string): any, 347 | /** 348 | * Mocks a module with an auto-mocked version when it is being required. 349 | * 350 | * The second argument can be used to specify an explicit module factory that 351 | * is being run instead of using Jest's automocking feature. 352 | * 353 | * The third argument can be used to create virtual mocks -- mocks of modules 354 | * that don't exist anywhere in the system. 355 | */ 356 | mock( 357 | moduleName: string, 358 | moduleFactory?: any, 359 | options?: Object 360 | ): JestObjectType, 361 | /** 362 | * Returns the actual module instead of a mock, bypassing all checks on 363 | * whether the module should receive a mock implementation or not. 364 | */ 365 | requireActual(moduleName: string): any, 366 | /** 367 | * Returns a mock module instead of the actual module, bypassing all checks 368 | * on whether the module should be required normally or not. 369 | */ 370 | requireMock(moduleName: string): any, 371 | /** 372 | * Resets the module registry - the cache of all required modules. This is 373 | * useful to isolate modules where local state might conflict between tests. 374 | */ 375 | resetModules(): JestObjectType, 376 | /** 377 | * Exhausts the micro-task queue (usually interfaced in node via 378 | * process.nextTick). 379 | */ 380 | runAllTicks(): void, 381 | /** 382 | * Exhausts the macro-task queue (i.e., all tasks queued by setTimeout(), 383 | * setInterval(), and setImmediate()). 384 | */ 385 | runAllTimers(): void, 386 | /** 387 | * Exhausts all tasks queued by setImmediate(). 388 | */ 389 | runAllImmediates(): void, 390 | /** 391 | * Executes only the macro task queue (i.e. all tasks queued by setTimeout() 392 | * or setInterval() and setImmediate()). 393 | */ 394 | runTimersToTime(msToRun: number): void, 395 | /** 396 | * Executes only the macro-tasks that are currently pending (i.e., only the 397 | * tasks that have been queued by setTimeout() or setInterval() up to this 398 | * point) 399 | */ 400 | runOnlyPendingTimers(): void, 401 | /** 402 | * Explicitly supplies the mock object that the module system should return 403 | * for the specified module. Note: It is recommended to use jest.mock() 404 | * instead. 405 | */ 406 | setMock(moduleName: string, moduleExports: any): JestObjectType, 407 | /** 408 | * Indicates that the module system should never return a mocked version of 409 | * the specified module from require() (e.g. that it should always return the 410 | * real module). 411 | */ 412 | unmock(moduleName: string): JestObjectType, 413 | /** 414 | * Instructs Jest to use fake versions of the standard timer functions 415 | * (setTimeout, setInterval, clearTimeout, clearInterval, nextTick, 416 | * setImmediate and clearImmediate). 417 | */ 418 | useFakeTimers(): JestObjectType, 419 | /** 420 | * Instructs Jest to use the real versions of the standard timer functions. 421 | */ 422 | useRealTimers(): JestObjectType, 423 | /** 424 | * Creates a mock function similar to jest.fn but also tracks calls to 425 | * object[methodName]. 426 | */ 427 | spyOn(object: Object, methodName: string): JestMockFn, 428 | /** 429 | * Set the default timeout interval for tests and before/after hooks in milliseconds. 430 | * Note: The default timeout interval is 5 seconds if this method is not called. 431 | */ 432 | setTimeout(timeout: number): JestObjectType 433 | }; 434 | 435 | type JestSpyType = { 436 | calls: JestCallsType 437 | }; 438 | 439 | /** Runs this function after every test inside this context */ 440 | declare function afterEach( 441 | fn: (done: () => void) => ?Promise, 442 | timeout?: number 443 | ): void; 444 | /** Runs this function before every test inside this context */ 445 | declare function beforeEach( 446 | fn: (done: () => void) => ?Promise, 447 | timeout?: number 448 | ): void; 449 | /** Runs this function after all tests have finished inside this context */ 450 | declare function afterAll( 451 | fn: (done: () => void) => ?Promise, 452 | timeout?: number 453 | ): void; 454 | /** Runs this function before any tests have started inside this context */ 455 | declare function beforeAll( 456 | fn: (done: () => void) => ?Promise, 457 | timeout?: number 458 | ): void; 459 | 460 | /** A context for grouping tests together */ 461 | declare var describe: { 462 | /** 463 | * Creates a block that groups together several related tests in one "test suite" 464 | */ 465 | (name: string, fn: () => void): void, 466 | 467 | /** 468 | * Only run this describe block 469 | */ 470 | only(name: string, fn: () => void): void, 471 | 472 | /** 473 | * Skip running this describe block 474 | */ 475 | skip(name: string, fn: () => void): void 476 | }; 477 | 478 | /** An individual test unit */ 479 | declare var it: { 480 | /** 481 | * An individual test unit 482 | * 483 | * @param {string} Name of Test 484 | * @param {Function} Test 485 | * @param {number} Timeout for the test, in milliseconds. 486 | */ 487 | ( 488 | name: string, 489 | fn?: (done: () => void) => ?Promise, 490 | timeout?: number 491 | ): void, 492 | /** 493 | * Only run this test 494 | * 495 | * @param {string} Name of Test 496 | * @param {Function} Test 497 | * @param {number} Timeout for the test, in milliseconds. 498 | */ 499 | only( 500 | name: string, 501 | fn?: (done: () => void) => ?Promise, 502 | timeout?: number 503 | ): void, 504 | /** 505 | * Skip running this test 506 | * 507 | * @param {string} Name of Test 508 | * @param {Function} Test 509 | * @param {number} Timeout for the test, in milliseconds. 510 | */ 511 | skip( 512 | name: string, 513 | fn?: (done: () => void) => ?Promise, 514 | timeout?: number 515 | ): void, 516 | /** 517 | * Run the test concurrently 518 | * 519 | * @param {string} Name of Test 520 | * @param {Function} Test 521 | * @param {number} Timeout for the test, in milliseconds. 522 | */ 523 | concurrent( 524 | name: string, 525 | fn?: (done: () => void) => ?Promise, 526 | timeout?: number 527 | ): void 528 | }; 529 | declare function fit( 530 | name: string, 531 | fn: (done: () => void) => ?Promise, 532 | timeout?: number 533 | ): void; 534 | /** An individual test unit */ 535 | declare var test: typeof it; 536 | /** A disabled group of tests */ 537 | declare var xdescribe: typeof describe; 538 | /** A focused group of tests */ 539 | declare var fdescribe: typeof describe; 540 | /** A disabled individual test */ 541 | declare var xit: typeof it; 542 | /** A disabled individual test */ 543 | declare var xtest: typeof it; 544 | 545 | /** The expect function is used every time you want to test a value */ 546 | declare var expect: { 547 | /** The object that you want to make assertions against */ 548 | (value: any): JestExpectType & JestPromiseType & EnzymeMatchersType, 549 | /** Add additional Jasmine matchers to Jest's roster */ 550 | extend(matchers: { [name: string]: JestMatcher }): void, 551 | /** Add a module that formats application-specific data structures. */ 552 | addSnapshotSerializer(serializer: (input: Object) => string): void, 553 | assertions(expectedAssertions: number): void, 554 | hasAssertions(): void, 555 | any(value: mixed): JestAsymmetricEqualityType, 556 | anything(): void, 557 | arrayContaining(value: Array): void, 558 | objectContaining(value: Object): void, 559 | /** Matches any received string that contains the exact expected string. */ 560 | stringContaining(value: string): void, 561 | stringMatching(value: string | RegExp): void 562 | }; 563 | 564 | // TODO handle return type 565 | // http://jasmine.github.io/2.4/introduction.html#section-Spies 566 | declare function spyOn(value: mixed, method: string): Object; 567 | 568 | /** Holds all functions related to manipulating test runner */ 569 | declare var jest: JestObjectType; 570 | 571 | /** 572 | * The global Jasmine object, this is generally not exposed as the public API, 573 | * using features inside here could break in later versions of Jest. 574 | */ 575 | declare var jasmine: { 576 | DEFAULT_TIMEOUT_INTERVAL: number, 577 | any(value: mixed): JestAsymmetricEqualityType, 578 | anything(): void, 579 | arrayContaining(value: Array): void, 580 | clock(): JestClockType, 581 | createSpy(name: string): JestSpyType, 582 | createSpyObj( 583 | baseName: string, 584 | methodNames: Array 585 | ): { [methodName: string]: JestSpyType }, 586 | objectContaining(value: Object): void, 587 | stringMatching(value: string): void 588 | }; 589 | -------------------------------------------------------------------------------- /flow-typed/npm/rxjs_v5.0.x.js: -------------------------------------------------------------------------------- 1 | // flow-typed signature: 40d60f46fb115f551b496c572b577cfe 2 | // flow-typed version: 55b9091816/rxjs_v5.0.x/flow_>=v0.34.x 3 | 4 | // FIXME(samgoldman) Remove top-level interface once Babel supports 5 | // `declare interface` syntax. 6 | // FIXME(samgoldman) Remove this once rxjs$Subject can mixin rxjs$Observer 7 | interface rxjs$IObserver<-T> { 8 | closed?: boolean; 9 | next(value: T): mixed; 10 | error(error: any): mixed; 11 | complete(): mixed; 12 | } 13 | 14 | type rxjs$PartialObserver<-T> = 15 | | { 16 | +next: (value: T) => mixed, 17 | +error?: (error: any) => mixed, 18 | +complete?: () => mixed 19 | } 20 | | { 21 | +next?: (value: T) => mixed, 22 | +error: (error: any) => mixed, 23 | +complete?: () => mixed 24 | } 25 | | { 26 | +next?: (value: T) => mixed, 27 | +error?: (error: any) => mixed, 28 | +complete: () => mixed 29 | }; 30 | 31 | interface rxjs$ISubscription { 32 | unsubscribe(): void; 33 | } 34 | 35 | type rxjs$TeardownLogic = rxjs$ISubscription | (() => void); 36 | 37 | type rxjs$EventListenerOptions = 38 | | { 39 | capture?: boolean, 40 | passive?: boolean, 41 | once?: boolean 42 | } 43 | | boolean; 44 | 45 | type rxjs$ObservableInput = rxjs$Observable | Promise | Iterable; 46 | 47 | type rxjs$OperatorFunction = (rxjs$Observable) => rxjs$Observable; 48 | type rxjs$OperatorFunctionLast> = ( 49 | rxjs$Observable 50 | ) => R; 51 | 52 | declare class rxjs$Observable<+T> { 53 | static bindCallback( 54 | callbackFunc: (callback: (_: void) => any) => any, 55 | selector?: void, 56 | scheduler?: rxjs$SchedulerClass 57 | ): () => rxjs$Observable; 58 | static bindCallback( 59 | callbackFunc: (callback: (result: U) => any) => any, 60 | selector?: void, 61 | scheduler?: rxjs$SchedulerClass 62 | ): () => rxjs$Observable; 63 | static bindCallback( 64 | callbackFunc: (v1: T, callback: (result: U) => any) => any, 65 | selector?: void, 66 | scheduler?: rxjs$SchedulerClass 67 | ): (v1: T) => rxjs$Observable; 68 | static bindCallback( 69 | callbackFunc: (v1: T, v2: T2, callback: (result: U) => any) => any, 70 | selector?: void, 71 | scheduler?: rxjs$SchedulerClass 72 | ): (v1: T, v2: T2) => rxjs$Observable; 73 | static bindCallback( 74 | callbackFunc: (v1: T, v2: T2, v3: T3, callback: (result: U) => any) => any, 75 | selector?: void, 76 | scheduler?: rxjs$SchedulerClass 77 | ): (v1: T, v2: T2, v3: T3) => rxjs$Observable; 78 | static bindCallback( 79 | callbackFunc: ( 80 | v1: T, 81 | v2: T2, 82 | v3: T3, 83 | v4: T4, 84 | callback: (result: U) => any 85 | ) => any, 86 | selector?: void, 87 | scheduler?: rxjs$SchedulerClass 88 | ): (v1: T, v2: T2, v3: T3, v4: T4) => rxjs$Observable; 89 | static bindCallback( 90 | callbackFunc: ( 91 | v1: T, 92 | v2: T2, 93 | v3: T3, 94 | v4: T4, 95 | v5: T5, 96 | callback: (result: U) => any 97 | ) => any, 98 | selector?: void, 99 | scheduler?: rxjs$SchedulerClass 100 | ): (v1: T, v2: T2, v3: T3, v4: T4, v5: T5) => rxjs$Observable; 101 | static bindCallback( 102 | callbackFunc: ( 103 | v1: T, 104 | v2: T2, 105 | v3: T3, 106 | v4: T4, 107 | v5: T5, 108 | v6: T6, 109 | callback: (result: U) => any 110 | ) => any, 111 | selector?: void, 112 | scheduler?: rxjs$SchedulerClass 113 | ): (v1: T, v2: T2, v3: T3, v4: T4, v5: T5, v6: T6) => rxjs$Observable; 114 | static bindCallback( 115 | callbackFunc: (callback: (...args: Array) => any) => any, 116 | selector: (...args: Array) => U, 117 | scheduler?: rxjs$SchedulerClass 118 | ): () => rxjs$Observable; 119 | static bindCallback( 120 | callbackFunc: (v1: T, callback: (...args: Array) => any) => any, 121 | selector: (...args: Array) => U, 122 | scheduler?: rxjs$SchedulerClass 123 | ): (v1: T) => rxjs$Observable; 124 | static bindCallback( 125 | callbackFunc: ( 126 | v1: T, 127 | v2: T2, 128 | callback: (...args: Array) => any 129 | ) => any, 130 | selector: (...args: Array) => U, 131 | scheduler?: rxjs$SchedulerClass 132 | ): (v1: T, v2: T2) => rxjs$Observable; 133 | static bindCallback( 134 | callbackFunc: ( 135 | v1: T, 136 | v2: T2, 137 | v3: T3, 138 | callback: (...args: Array) => any 139 | ) => any, 140 | selector: (...args: Array) => U, 141 | scheduler?: rxjs$SchedulerClass 142 | ): (v1: T, v2: T2, v3: T3) => rxjs$Observable; 143 | static bindCallback( 144 | callbackFunc: ( 145 | v1: T, 146 | v2: T2, 147 | v3: T3, 148 | v4: T4, 149 | callback: (...args: Array) => any 150 | ) => any, 151 | selector: (...args: Array) => U, 152 | scheduler?: rxjs$SchedulerClass 153 | ): (v1: T, v2: T2, v3: T3, v4: T4) => rxjs$Observable; 154 | static bindCallback( 155 | callbackFunc: ( 156 | v1: T, 157 | v2: T2, 158 | v3: T3, 159 | v4: T4, 160 | v5: T5, 161 | callback: (...args: Array) => any 162 | ) => any, 163 | selector: (...args: Array) => U, 164 | scheduler?: rxjs$SchedulerClass 165 | ): (v1: T, v2: T2, v3: T3, v4: T4, v5: T5) => rxjs$Observable; 166 | static bindCallback( 167 | callbackFunc: ( 168 | v1: T, 169 | v2: T2, 170 | v3: T3, 171 | v4: T4, 172 | v5: T5, 173 | v6: T6, 174 | callback: (...args: Array) => any 175 | ) => any, 176 | selector: (...args: Array) => U, 177 | scheduler?: rxjs$SchedulerClass 178 | ): (v1: T, v2: T2, v3: T3, v4: T4, v5: T5, v6: T6) => rxjs$Observable; 179 | static bindCallback( 180 | callbackFunc: Function, 181 | selector?: void, 182 | scheduler?: rxjs$SchedulerClass 183 | ): (...args: Array) => rxjs$Observable; 184 | static bindCallback( 185 | callbackFunc: Function, 186 | selector?: (...args: Array) => T, 187 | scheduler?: rxjs$SchedulerClass 188 | ): (...args: Array) => rxjs$Observable; 189 | 190 | static bindNodeCallback( 191 | callbackFunc: (callback: (err: any, result: U) => any) => any, 192 | selector?: void, 193 | scheduler?: rxjs$SchedulerClass 194 | ): () => rxjs$Observable; 195 | static bindNodeCallback( 196 | callbackFunc: (v1: T, callback: (err: any, result: U) => any) => any, 197 | selector?: void, 198 | scheduler?: rxjs$SchedulerClass 199 | ): (v1: T) => rxjs$Observable; 200 | static bindNodeCallback( 201 | callbackFunc: ( 202 | v1: T, 203 | v2: T2, 204 | callback: (err: any, result: U) => any 205 | ) => any, 206 | selector?: void, 207 | scheduler?: rxjs$SchedulerClass 208 | ): (v1: T, v2: T2) => rxjs$Observable; 209 | static bindNodeCallback( 210 | callbackFunc: ( 211 | v1: T, 212 | v2: T2, 213 | v3: T3, 214 | callback: (err: any, result: U) => any 215 | ) => any, 216 | selector?: void, 217 | scheduler?: rxjs$SchedulerClass 218 | ): (v1: T, v2: T2, v3: T3) => rxjs$Observable; 219 | static bindNodeCallback( 220 | callbackFunc: ( 221 | v1: T, 222 | v2: T2, 223 | v3: T3, 224 | v4: T4, 225 | callback: (err: any, result: U) => any 226 | ) => any, 227 | selector?: void, 228 | scheduler?: rxjs$SchedulerClass 229 | ): (v1: T, v2: T2, v3: T3, v4: T4) => rxjs$Observable; 230 | static bindNodeCallback( 231 | callbackFunc: ( 232 | v1: T, 233 | v2: T2, 234 | v3: T3, 235 | v4: T4, 236 | v5: T5, 237 | callback: (err: any, result: U) => any 238 | ) => any, 239 | selector?: void, 240 | scheduler?: rxjs$SchedulerClass 241 | ): (v1: T, v2: T2, v3: T3, v4: T4, v5: T5) => rxjs$Observable; 242 | static bindNodeCallback( 243 | callbackFunc: ( 244 | v1: T, 245 | v2: T2, 246 | v3: T3, 247 | v4: T4, 248 | v5: T5, 249 | v6: T6, 250 | callback: (err: any, result: U) => any 251 | ) => any, 252 | selector?: void, 253 | scheduler?: rxjs$SchedulerClass 254 | ): (v1: T, v2: T2, v3: T3, v4: T4, v5: T5, v6: T6) => rxjs$Observable; 255 | static bindNodeCallback( 256 | callbackFunc: Function, 257 | selector?: void, 258 | scheduler?: rxjs$SchedulerClass 259 | ): (...args: Array) => rxjs$Observable; 260 | static bindNodeCallback( 261 | callbackFunc: Function, 262 | selector?: (...args: Array) => T, 263 | scheduler?: rxjs$SchedulerClass 264 | ): (...args: Array) => rxjs$Observable; 265 | 266 | static concat(...sources: rxjs$Observable[]): rxjs$Observable; 267 | 268 | static create( 269 | subscribe: ( 270 | observer: rxjs$Observer 271 | ) => rxjs$ISubscription | Function | void 272 | ): rxjs$Observable; 273 | 274 | static defer( 275 | observableFactory: () => rxjs$Observable | Promise 276 | ): rxjs$Observable; 277 | 278 | static from( 279 | input: rxjs$ObservableInput, 280 | scheduler?: rxjs$SchedulerClass 281 | ): rxjs$Observable; 282 | 283 | static fromEvent( 284 | element: any, 285 | eventName: string, 286 | ...none: Array 287 | ): rxjs$Observable; 288 | static fromEvent( 289 | element: any, 290 | eventName: string, 291 | options: rxjs$EventListenerOptions, 292 | ...none: Array 293 | ): rxjs$Observable; 294 | static fromEvent( 295 | element: any, 296 | eventName: string, 297 | selector: () => T, 298 | ...none: Array 299 | ): rxjs$Observable; 300 | static fromEvent( 301 | element: any, 302 | eventName: string, 303 | options: rxjs$EventListenerOptions, 304 | selector: () => T 305 | ): rxjs$Observable; 306 | 307 | static fromEventPattern( 308 | addHandler: (handler: (item: T) => void) => void, 309 | removeHandler: (handler: (item: T) => void) => void, 310 | selector?: () => T 311 | ): rxjs$Observable; 312 | 313 | static fromPromise(promise: Promise): rxjs$Observable; 314 | 315 | static empty(): rxjs$Observable; 316 | 317 | static interval(period: number): rxjs$Observable; 318 | 319 | static timer( 320 | initialDelay: number | Date, 321 | period?: number, 322 | scheduler?: rxjs$SchedulerClass 323 | ): rxjs$Observable; 324 | 325 | static merge( 326 | source0: rxjs$Observable, 327 | source1: rxjs$Observable 328 | ): rxjs$Observable; 329 | static merge( 330 | source0: rxjs$Observable, 331 | source1: rxjs$Observable, 332 | source2: rxjs$Observable 333 | ): rxjs$Observable; 334 | static merge(...sources: rxjs$Observable[]): rxjs$Observable; 335 | 336 | static never(): rxjs$Observable; 337 | 338 | static of(...values: T[]): rxjs$Observable; 339 | 340 | static range( 341 | start?: number, 342 | count?: number, 343 | scheduler?: rxjs$SchedulerClass 344 | ): rxjs$Observable; 345 | 346 | static throw(error: any): rxjs$Observable; 347 | 348 | audit( 349 | durationSelector: (value: T) => rxjs$Observable | Promise 350 | ): rxjs$Observable; 351 | 352 | auditTime( 353 | duration: number, 354 | scheduler?: rxjs$SchedulerClass 355 | ): rxjs$Observable; 356 | 357 | race(other: rxjs$Observable): rxjs$Observable; 358 | 359 | repeat(count?: number): rxjs$Observable; 360 | 361 | buffer(bufferBoundaries: rxjs$Observable): rxjs$Observable>; 362 | 363 | bufferCount( 364 | bufferSize: number, 365 | startBufferEvery?: number 366 | ): rxjs$Observable>; 367 | 368 | bufferTime( 369 | bufferTimeSpan: number, 370 | bufferCreationInterval?: number, 371 | maxBufferSize?: number, 372 | scheduler?: rxjs$SchedulerClass 373 | ): rxjs$Observable>; 374 | 375 | bufferToggle( 376 | openings: rxjs$Observable | Promise, 377 | closingSelector: (value: U) => rxjs$Observable | Promise 378 | ): rxjs$Observable>; 379 | 380 | bufferWhen( 381 | closingSelector: () => rxjs$Observable 382 | ): rxjs$Observable>; 383 | 384 | catch( 385 | selector: (err: any, caught: rxjs$Observable) => rxjs$Observable 386 | ): rxjs$Observable; 387 | 388 | concat(...sources: rxjs$Observable[]): rxjs$Observable; 389 | 390 | concatAll(): rxjs$Observable; 391 | 392 | concatMap( 393 | f: (value: T, index: number) => rxjs$ObservableInput, 394 | _: void 395 | ): rxjs$Observable; 396 | concatMap( 397 | f: (value: T, index: number) => rxjs$ObservableInput, 398 | resultSelector: ( 399 | outerValue: T, 400 | innerValue: U, 401 | outerIndex: number, 402 | innerIndex: number 403 | ) => V 404 | ): rxjs$Observable; 405 | 406 | debounceTime( 407 | dueTime: number, 408 | scheduler?: rxjs$SchedulerClass 409 | ): rxjs$Observable; 410 | 411 | defaultIfEmpty(defaultValue: U): rxjs$Observable; 412 | 413 | delay(dueTime: number, scheduler?: rxjs$SchedulerClass): rxjs$Observable; 414 | 415 | delayWhen( 416 | delayDurationSelector: (value: T) => rxjs$Observable, 417 | subscriptionDelay?: rxjs$Observable 418 | ): rxjs$Observable; 419 | 420 | distinctUntilChanged(compare?: (x: T, y: T) => boolean): rxjs$Observable; 421 | 422 | distinct( 423 | keySelector?: (value: T) => U, 424 | flushes?: rxjs$Observable 425 | ): rxjs$Observable; 426 | 427 | distinctUntilKeyChanged( 428 | key: string, 429 | compare?: (x: mixed, y: mixed) => boolean 430 | ): rxjs$Observable; 431 | 432 | elementAt(index: number, defaultValue?: T): rxjs$Observable; 433 | 434 | exhaustMap( 435 | project: (value: T, index: number) => rxjs$ObservableInput, 436 | _: void 437 | ): rxjs$Observable; 438 | exhaustMap( 439 | project: (value: T, index: number) => rxjs$ObservableInput, 440 | resultSelector: ( 441 | outerValue: T, 442 | innerValue: U, 443 | outerIndex: number, 444 | innerIndex: number 445 | ) => V 446 | ): rxjs$Observable; 447 | 448 | expand( 449 | project: (value: T, index: number) => rxjs$Observable, 450 | concurrent?: number, 451 | scheduler?: rxjs$SchedulerClass 452 | ): rxjs$Observable; 453 | 454 | filter( 455 | predicate: (value: T, index: number) => boolean, 456 | thisArg?: any 457 | ): rxjs$Observable; 458 | 459 | finally(f: () => mixed): rxjs$Observable; 460 | 461 | first( 462 | predicate?: (value: T, index: number, source: rxjs$Observable) => boolean 463 | ): rxjs$Observable; 464 | first( 465 | predicate: ?( 466 | value: T, 467 | index: number, 468 | source: rxjs$Observable 469 | ) => boolean, 470 | resultSelector: (value: T, index: number) => U 471 | ): rxjs$Observable; 472 | first( 473 | predicate: ?( 474 | value: T, 475 | index: number, 476 | source: rxjs$Observable 477 | ) => boolean, 478 | resultSelector: ?(value: T, index: number) => U, 479 | defaultValue: U 480 | ): rxjs$Observable; 481 | 482 | groupBy( 483 | keySelector: (value: T) => K, 484 | _: void 485 | ): rxjs$Observable>; 486 | groupBy( 487 | keySelector: (value: T) => K, 488 | elementSelector: (value: T) => V, 489 | durationSelector?: ( 490 | grouped: rxjs$GroupedObservable 491 | ) => rxjs$Observable 492 | ): rxjs$Observable>; 493 | 494 | ignoreElements(): rxjs$Observable; 495 | 496 | last( 497 | predicate?: (value: T, index: number, source: rxjs$Observable) => boolean 498 | ): rxjs$Observable; 499 | last( 500 | predicate: ?( 501 | value: T, 502 | index: number, 503 | source: rxjs$Observable 504 | ) => boolean, 505 | resultSelector: (value: T, index: number) => U 506 | ): rxjs$Observable; 507 | last( 508 | predicate: ?( 509 | value: T, 510 | index: number, 511 | source: rxjs$Observable 512 | ) => boolean, 513 | resultSelector: ?(value: T, index: number) => U, 514 | defaultValue: U 515 | ): rxjs$Observable; 516 | 517 | let( 518 | project: (self: rxjs$Observable) => rxjs$Observable 519 | ): rxjs$Observable; 520 | 521 | // Alias for `let` 522 | letBind( 523 | project: (self: rxjs$Observable) => rxjs$Observable 524 | ): rxjs$Observable; 525 | 526 | switch(): T; // assumption: T is Observable 527 | 528 | // Alias for `mergeMap` 529 | flatMap( 530 | project: (value: T, index: number) => rxjs$ObservableInput, 531 | concurrency?: number 532 | ): rxjs$Observable; 533 | flatMap( 534 | project: (value: T, index: number) => rxjs$ObservableInput, 535 | resultSelector: ( 536 | outerValue: T, 537 | innerValue: U, 538 | outerIndex: number, 539 | innerIndex: number 540 | ) => V, 541 | concurrency?: number 542 | ): rxjs$Observable; 543 | 544 | flatMapTo(innerObservable: rxjs$Observable): rxjs$Observable; 545 | 546 | flatMapTo( 547 | innerObservable: rxjs$Observable, 548 | resultSelector: ( 549 | outerValue: T, 550 | innerValue: U, 551 | outerIndex: number, 552 | innerIndex: number 553 | ) => V, 554 | concurrent?: number 555 | ): rxjs$Observable; 556 | 557 | switchMap( 558 | project: (value: T, index: number) => rxjs$ObservableInput, 559 | _: void 560 | ): rxjs$Observable; 561 | switchMap( 562 | project: (value: T, index: number) => rxjs$ObservableInput, 563 | resultSelector: ( 564 | outerValue: T, 565 | innerValue: U, 566 | outerIndex: number, 567 | innerIndex: number 568 | ) => V 569 | ): rxjs$Observable; 570 | 571 | switchMapTo(innerObservable: rxjs$Observable): rxjs$Observable; 572 | 573 | map(f: (value: T, index: number) => U, thisArg?: any): rxjs$Observable; 574 | 575 | mapTo(value: U): rxjs$Observable; 576 | 577 | merge(other: rxjs$Observable): rxjs$Observable; 578 | 579 | mergeAll(): rxjs$Observable; 580 | 581 | mergeMap( 582 | project: (value: T, index: number) => rxjs$ObservableInput, 583 | concurrency?: number 584 | ): rxjs$Observable; 585 | mergeMap( 586 | project: (value: T, index: number) => rxjs$ObservableInput, 587 | resultSelector: ( 588 | outerValue: T, 589 | innerValue: U, 590 | outerIndex: number, 591 | innerIndex: number 592 | ) => V, 593 | concurrency?: number 594 | ): rxjs$Observable; 595 | 596 | mergeMapTo(innerObservable: rxjs$Observable): rxjs$Observable; 597 | 598 | mergeMapTo( 599 | innerObservable: rxjs$Observable, 600 | resultSelector: ( 601 | outerValue: T, 602 | innerValue: U, 603 | outerIndex: number, 604 | innerIndex: number 605 | ) => V, 606 | concurrent?: number 607 | ): rxjs$Observable; 608 | 609 | multicast( 610 | subjectOrSubjectFactory: rxjs$Subject | (() => rxjs$Subject) 611 | ): rxjs$ConnectableObservable; 612 | 613 | observeOn(scheduler: rxjs$SchedulerClass): rxjs$Observable; 614 | 615 | pairwise(): rxjs$Observable<[T, T]>; 616 | 617 | partition( 618 | predicate: (value: T, index: number) => boolean, 619 | thisArg: any 620 | ): [rxjs$Observable, rxjs$Observable]; 621 | 622 | pipe(): rxjs$Observable; 623 | 624 | pipe(op1: rxjs$OperatorFunctionLast): A; 625 | 626 | pipe( 627 | op1: rxjs$OperatorFunction, 628 | op2: rxjs$OperatorFunctionLast 629 | ): B; 630 | 631 | pipe( 632 | op1: rxjs$OperatorFunction, 633 | op2: rxjs$OperatorFunction, 634 | op3: rxjs$OperatorFunctionLast 635 | ): C; 636 | 637 | pipe( 638 | op1: rxjs$OperatorFunction, 639 | op2: rxjs$OperatorFunction, 640 | op3: rxjs$OperatorFunction, 641 | op4: rxjs$OperatorFunctionLast 642 | ): D; 643 | 644 | pipe( 645 | op1: rxjs$OperatorFunction, 646 | op2: rxjs$OperatorFunction, 647 | op3: rxjs$OperatorFunction, 648 | op4: rxjs$OperatorFunction, 649 | op5: rxjs$OperatorFunctionLast 650 | ): E; 651 | 652 | publish(): rxjs$ConnectableObservable; 653 | 654 | publishLast(): rxjs$ConnectableObservable; 655 | 656 | reduce( 657 | accumulator: ( 658 | acc: U, 659 | currentValue: T, 660 | index: number, 661 | source: rxjs$Observable 662 | ) => U, 663 | seed: U 664 | ): rxjs$Observable; 665 | 666 | sample(notifier: rxjs$Observable): rxjs$Observable; 667 | 668 | sampleTime( 669 | delay: number, 670 | scheduler?: rxjs$SchedulerClass 671 | ): rxjs$Observable; 672 | 673 | publishReplay( 674 | bufferSize?: number, 675 | windowTime?: number, 676 | scheduler?: rxjs$SchedulerClass 677 | ): rxjs$ConnectableObservable; 678 | 679 | retry(retryCount: ?number): rxjs$Observable; 680 | 681 | retryWhen( 682 | notifier: (errors: rxjs$Observable) => rxjs$Observable 683 | ): rxjs$Observable; 684 | 685 | scan(f: (acc: U, value: T) => U, initialValue: U): rxjs$Observable; 686 | 687 | share(): rxjs$Observable; 688 | 689 | skip(count: number): rxjs$Observable; 690 | 691 | skipUntil(other: rxjs$Observable | Promise): rxjs$Observable; 692 | 693 | skipWhile( 694 | predicate: (value: T, index: number) => boolean 695 | ): rxjs$Observable; 696 | 697 | startWith(...values: Array): rxjs$Observable; 698 | 699 | subscribeOn(scheduler: rxjs$SchedulerClass): rxjs$Observable; 700 | 701 | take(count: number): rxjs$Observable; 702 | 703 | takeUntil(other: rxjs$Observable): rxjs$Observable; 704 | 705 | takeWhile( 706 | predicate: (value: T, index: number) => boolean 707 | ): rxjs$Observable; 708 | 709 | do( 710 | onNext?: (value: T) => mixed, 711 | onError?: (error: any) => mixed, 712 | onCompleted?: () => mixed 713 | ): rxjs$Observable; 714 | do(observer: { 715 | next?: (value: T) => mixed, 716 | error?: (error: any) => mixed, 717 | complete?: () => mixed 718 | }): rxjs$Observable; 719 | 720 | throttleTime(duration: number): rxjs$Observable; 721 | 722 | timeout(due: number | Date, _: void): rxjs$Observable; 723 | 724 | timeoutWith( 725 | due: number | Date, 726 | withObservable: rxjs$Observable, 727 | scheduler?: rxjs$SchedulerClass 728 | ): rxjs$Observable; 729 | 730 | toArray(): rxjs$Observable; 731 | 732 | toPromise(): Promise; 733 | 734 | subscribe(observer: rxjs$PartialObserver): rxjs$Subscription; 735 | subscribe( 736 | onNext: ?(value: T) => mixed, 737 | onError: ?(error: any) => mixed, 738 | onCompleted: ?() => mixed 739 | ): rxjs$Subscription; 740 | 741 | static combineLatest( 742 | a: rxjs$Observable, 743 | resultSelector: (a: A) => B 744 | ): rxjs$Observable; 745 | 746 | static combineLatest( 747 | a: rxjs$Observable, 748 | b: rxjs$Observable, 749 | resultSelector: (a: A, b: B) => C 750 | ): rxjs$Observable; 751 | 752 | static combineLatest( 753 | a: rxjs$Observable, 754 | b: rxjs$Observable, 755 | c: rxjs$Observable, 756 | resultSelector: (a: A, b: B, c: C) => D 757 | ): rxjs$Observable; 758 | 759 | static combineLatest( 760 | a: rxjs$Observable, 761 | b: rxjs$Observable, 762 | c: rxjs$Observable, 763 | d: rxjs$Observable, 764 | resultSelector: (a: A, b: B, c: C, d: D) => E 765 | ): rxjs$Observable; 766 | 767 | static combineLatest( 768 | a: rxjs$Observable, 769 | b: rxjs$Observable, 770 | c: rxjs$Observable, 771 | d: rxjs$Observable, 772 | e: rxjs$Observable, 773 | resultSelector: (a: A, b: B, c: C, d: D, e: E) => F 774 | ): rxjs$Observable; 775 | 776 | static combineLatest( 777 | a: rxjs$Observable, 778 | b: rxjs$Observable, 779 | c: rxjs$Observable, 780 | d: rxjs$Observable, 781 | e: rxjs$Observable, 782 | f: rxjs$Observable, 783 | resultSelector: (a: A, b: B, c: C, d: D, e: E, f: F) => G 784 | ): rxjs$Observable; 785 | 786 | static combineLatest( 787 | a: rxjs$Observable, 788 | b: rxjs$Observable, 789 | c: rxjs$Observable, 790 | d: rxjs$Observable, 791 | e: rxjs$Observable, 792 | f: rxjs$Observable, 793 | g: rxjs$Observable, 794 | resultSelector: (a: A, b: B, c: C, d: D, e: E, f: F, g: G) => H 795 | ): rxjs$Observable; 796 | 797 | static combineLatest(a: rxjs$Observable, _: void): rxjs$Observable<[A]>; 798 | 799 | static combineLatest( 800 | a: rxjs$Observable, 801 | b: rxjs$Observable, 802 | _: void 803 | ): rxjs$Observable<[A, B]>; 804 | 805 | static combineLatest( 806 | a: rxjs$Observable, 807 | b: rxjs$Observable, 808 | c: rxjs$Observable, 809 | _: void 810 | ): rxjs$Observable<[A, B, C]>; 811 | 812 | static combineLatest( 813 | a: rxjs$Observable, 814 | b: rxjs$Observable, 815 | c: rxjs$Observable, 816 | d: rxjs$Observable, 817 | _: void 818 | ): rxjs$Observable<[A, B, C, D]>; 819 | 820 | static combineLatest( 821 | a: rxjs$Observable, 822 | b: rxjs$Observable, 823 | c: rxjs$Observable, 824 | d: rxjs$Observable, 825 | e: rxjs$Observable, 826 | _: void 827 | ): rxjs$Observable<[A, B, C, D, E]>; 828 | 829 | static combineLatest( 830 | a: rxjs$Observable, 831 | b: rxjs$Observable, 832 | c: rxjs$Observable, 833 | d: rxjs$Observable, 834 | e: rxjs$Observable, 835 | f: rxjs$Observable, 836 | _: void 837 | ): rxjs$Observable<[A, B, C, D, E, F]>; 838 | 839 | static combineLatest( 840 | a: rxjs$Observable, 841 | b: rxjs$Observable, 842 | c: rxjs$Observable, 843 | d: rxjs$Observable, 844 | e: rxjs$Observable, 845 | f: rxjs$Observable, 846 | g: rxjs$Observable, 847 | _: void 848 | ): rxjs$Observable<[A, B, C, D, E, F, G]>; 849 | 850 | static combineLatest( 851 | a: rxjs$Observable, 852 | b: rxjs$Observable, 853 | c: rxjs$Observable, 854 | d: rxjs$Observable, 855 | e: rxjs$Observable, 856 | f: rxjs$Observable, 857 | g: rxjs$Observable, 858 | h: rxjs$Observable, 859 | _: void 860 | ): rxjs$Observable<[A, B, C, D, E, F, G, H]>; 861 | 862 | combineLatest( 863 | a: rxjs$Observable, 864 | b: rxjs$Observable, 865 | c: rxjs$Observable, 866 | d: rxjs$Observable, 867 | e: rxjs$Observable, 868 | f: rxjs$Observable, 869 | g: rxjs$Observable, 870 | resultSelector: (t: T, a: A, b: B, c: C, d: D, e: E, f: F, g: G) => H 871 | ): rxjs$Observable; 872 | 873 | combineLatest( 874 | a: rxjs$Observable, 875 | b: rxjs$Observable, 876 | c: rxjs$Observable, 877 | d: rxjs$Observable, 878 | e: rxjs$Observable, 879 | f: rxjs$Observable, 880 | resultSelector: (t: T, a: A, b: B, c: C, d: D, e: E, f: F) => G 881 | ): rxjs$Observable; 882 | 883 | combineLatest( 884 | a: rxjs$Observable, 885 | b: rxjs$Observable, 886 | c: rxjs$Observable, 887 | d: rxjs$Observable, 888 | e: rxjs$Observable, 889 | resultSelector: (t: T, a: A, b: B, c: C, d: D, e: E) => F 890 | ): rxjs$Observable; 891 | 892 | combineLatest( 893 | a: rxjs$Observable, 894 | b: rxjs$Observable, 895 | c: rxjs$Observable, 896 | d: rxjs$Observable, 897 | resultSelector: (t: T, a: A, b: B, c: C, d: D) => E 898 | ): rxjs$Observable; 899 | 900 | combineLatest( 901 | a: rxjs$Observable, 902 | b: rxjs$Observable, 903 | c: rxjs$Observable, 904 | resultSelector: (t: T, a: A, b: B, c: C) => D 905 | ): rxjs$Observable; 906 | 907 | combineLatest( 908 | a: rxjs$Observable, 909 | b: rxjs$Observable, 910 | resultSelector: (t: T, a: A, b: B) => C 911 | ): rxjs$Observable; 912 | 913 | combineLatest( 914 | a: rxjs$Observable, 915 | resultSelector: (t: T, a: A) => B 916 | ): rxjs$Observable; 917 | 918 | combineLatest( 919 | a: rxjs$Observable, 920 | b: rxjs$Observable, 921 | c: rxjs$Observable, 922 | d: rxjs$Observable, 923 | e: rxjs$Observable, 924 | f: rxjs$Observable, 925 | g: rxjs$Observable, 926 | _: void 927 | ): rxjs$Observable<[T, A, B, C, D, E, E, F, G]>; 928 | 929 | combineLatest( 930 | a: rxjs$Observable, 931 | b: rxjs$Observable, 932 | c: rxjs$Observable, 933 | d: rxjs$Observable, 934 | e: rxjs$Observable, 935 | f: rxjs$Observable, 936 | _: void 937 | ): rxjs$Observable<[T, A, B, C, D, E, F]>; 938 | 939 | combineLatest( 940 | a: rxjs$Observable, 941 | b: rxjs$Observable, 942 | c: rxjs$Observable, 943 | d: rxjs$Observable, 944 | e: rxjs$Observable, 945 | _: void 946 | ): rxjs$Observable<[T, A, B, C, D, E]>; 947 | 948 | combineLatest( 949 | a: rxjs$Observable, 950 | b: rxjs$Observable, 951 | c: rxjs$Observable, 952 | d: rxjs$Observable, 953 | _: void 954 | ): rxjs$Observable<[T, A, B, C, D]>; 955 | 956 | combineLatest( 957 | a: rxjs$Observable, 958 | b: rxjs$Observable, 959 | c: rxjs$Observable, 960 | _: void 961 | ): rxjs$Observable<[T, A, B, C]>; 962 | 963 | combineLatest( 964 | a: rxjs$Observable, 965 | b: rxjs$Observable, 966 | _: void 967 | ): rxjs$Observable<[T, A, B]>; 968 | 969 | combineLatest(a: rxjs$Observable, _: void): rxjs$Observable<[T, A]>; 970 | 971 | static zip( 972 | a: rxjs$Observable, 973 | resultSelector: (a: A) => B 974 | ): rxjs$Observable; 975 | 976 | static zip( 977 | a: rxjs$Observable, 978 | b: rxjs$Observable, 979 | resultSelector: (a: A, b: B) => C 980 | ): rxjs$Observable; 981 | 982 | static zip( 983 | a: rxjs$Observable, 984 | b: rxjs$Observable, 985 | c: rxjs$Observable, 986 | resultSelector: (a: A, b: B, c: C) => D 987 | ): rxjs$Observable; 988 | 989 | static zip( 990 | a: rxjs$Observable, 991 | b: rxjs$Observable, 992 | c: rxjs$Observable, 993 | d: rxjs$Observable, 994 | resultSelector: (a: A, b: B, c: C, d: D) => E 995 | ): rxjs$Observable; 996 | 997 | static zip( 998 | a: rxjs$Observable, 999 | b: rxjs$Observable, 1000 | c: rxjs$Observable, 1001 | d: rxjs$Observable, 1002 | e: rxjs$Observable, 1003 | resultSelector: (a: A, b: B, c: C, d: D, e: E) => F 1004 | ): rxjs$Observable; 1005 | 1006 | static zip( 1007 | a: rxjs$Observable, 1008 | b: rxjs$Observable, 1009 | c: rxjs$Observable, 1010 | d: rxjs$Observable, 1011 | e: rxjs$Observable, 1012 | f: rxjs$Observable, 1013 | resultSelector: (a: A, b: B, c: C, d: D, e: E, f: F) => G 1014 | ): rxjs$Observable; 1015 | 1016 | static zip( 1017 | a: rxjs$Observable, 1018 | b: rxjs$Observable, 1019 | c: rxjs$Observable, 1020 | d: rxjs$Observable, 1021 | e: rxjs$Observable, 1022 | f: rxjs$Observable, 1023 | g: rxjs$Observable, 1024 | resultSelector: (a: A, b: B, c: C, d: D, e: E, f: F, g: G) => H 1025 | ): rxjs$Observable; 1026 | 1027 | static zip(a: rxjs$Observable, _: void): rxjs$Observable<[A]>; 1028 | 1029 | static zip( 1030 | a: rxjs$Observable, 1031 | b: rxjs$Observable, 1032 | _: void 1033 | ): rxjs$Observable<[A, B]>; 1034 | 1035 | static zip( 1036 | a: rxjs$Observable, 1037 | b: rxjs$Observable, 1038 | c: rxjs$Observable, 1039 | _: void 1040 | ): rxjs$Observable<[A, B, C]>; 1041 | 1042 | static zip( 1043 | a: rxjs$Observable, 1044 | b: rxjs$Observable, 1045 | c: rxjs$Observable, 1046 | d: rxjs$Observable, 1047 | _: void 1048 | ): rxjs$Observable<[A, B, C, D]>; 1049 | 1050 | static zip( 1051 | a: rxjs$Observable, 1052 | b: rxjs$Observable, 1053 | c: rxjs$Observable, 1054 | d: rxjs$Observable, 1055 | e: rxjs$Observable, 1056 | _: void 1057 | ): rxjs$Observable<[A, B, C, D, E]>; 1058 | 1059 | static zip( 1060 | a: rxjs$Observable, 1061 | b: rxjs$Observable, 1062 | c: rxjs$Observable, 1063 | d: rxjs$Observable, 1064 | e: rxjs$Observable, 1065 | f: rxjs$Observable, 1066 | _: void 1067 | ): rxjs$Observable<[A, B, C, D, E, F]>; 1068 | 1069 | static zip( 1070 | a: rxjs$Observable, 1071 | b: rxjs$Observable, 1072 | c: rxjs$Observable, 1073 | d: rxjs$Observable, 1074 | e: rxjs$Observable, 1075 | f: rxjs$Observable, 1076 | g: rxjs$Observable, 1077 | _: void 1078 | ): rxjs$Observable<[A, B, C, D, E, F, G]>; 1079 | 1080 | static zip( 1081 | a: rxjs$Observable, 1082 | b: rxjs$Observable, 1083 | c: rxjs$Observable, 1084 | d: rxjs$Observable, 1085 | e: rxjs$Observable, 1086 | f: rxjs$Observable, 1087 | g: rxjs$Observable, 1088 | h: rxjs$Observable, 1089 | _: void 1090 | ): rxjs$Observable<[A, B, C, D, E, F, G, H]>; 1091 | 1092 | zip( 1093 | a: rxjs$Observable, 1094 | b: rxjs$Observable, 1095 | c: rxjs$Observable, 1096 | d: rxjs$Observable, 1097 | e: rxjs$Observable, 1098 | f: rxjs$Observable, 1099 | g: rxjs$Observable, 1100 | resultSelector: (t: T, a: A, b: B, c: C, d: D, e: E, f: F, g: G) => H 1101 | ): rxjs$Observable; 1102 | 1103 | zip( 1104 | a: rxjs$Observable, 1105 | b: rxjs$Observable, 1106 | c: rxjs$Observable, 1107 | d: rxjs$Observable, 1108 | e: rxjs$Observable, 1109 | f: rxjs$Observable, 1110 | resultSelector: (t: T, a: A, b: B, c: C, d: D, e: E, f: F) => G 1111 | ): rxjs$Observable; 1112 | 1113 | zip( 1114 | a: rxjs$Observable, 1115 | b: rxjs$Observable, 1116 | c: rxjs$Observable, 1117 | d: rxjs$Observable, 1118 | e: rxjs$Observable, 1119 | resultSelector: (t: T, a: A, b: B, c: C, d: D, e: E) => F 1120 | ): rxjs$Observable; 1121 | 1122 | zip( 1123 | a: rxjs$Observable, 1124 | b: rxjs$Observable, 1125 | c: rxjs$Observable, 1126 | d: rxjs$Observable, 1127 | resultSelector: (t: T, a: A, b: B, c: C, d: D) => E 1128 | ): rxjs$Observable; 1129 | 1130 | zip( 1131 | a: rxjs$Observable, 1132 | b: rxjs$Observable, 1133 | c: rxjs$Observable, 1134 | resultSelector: (t: T, a: A, b: B, c: C) => D 1135 | ): rxjs$Observable; 1136 | 1137 | zip( 1138 | a: rxjs$Observable, 1139 | b: rxjs$Observable, 1140 | resultSelector: (t: T, a: A, b: B) => C 1141 | ): rxjs$Observable; 1142 | 1143 | zip( 1144 | a: rxjs$Observable, 1145 | resultSelector: (t: T, a: A) => B 1146 | ): rxjs$Observable; 1147 | 1148 | zip( 1149 | a: rxjs$Observable, 1150 | b: rxjs$Observable, 1151 | c: rxjs$Observable, 1152 | d: rxjs$Observable, 1153 | e: rxjs$Observable, 1154 | f: rxjs$Observable, 1155 | g: rxjs$Observable, 1156 | _: void 1157 | ): rxjs$Observable<[T, A, B, C, D, E, E, F, G]>; 1158 | 1159 | zip( 1160 | a: rxjs$Observable, 1161 | b: rxjs$Observable, 1162 | c: rxjs$Observable, 1163 | d: rxjs$Observable, 1164 | e: rxjs$Observable, 1165 | f: rxjs$Observable, 1166 | _: void 1167 | ): rxjs$Observable<[T, A, B, C, D, E, F]>; 1168 | 1169 | zip( 1170 | a: rxjs$Observable, 1171 | b: rxjs$Observable, 1172 | c: rxjs$Observable, 1173 | d: rxjs$Observable, 1174 | e: rxjs$Observable, 1175 | _: void 1176 | ): rxjs$Observable<[T, A, B, C, D, E]>; 1177 | 1178 | zip( 1179 | a: rxjs$Observable, 1180 | b: rxjs$Observable, 1181 | c: rxjs$Observable, 1182 | d: rxjs$Observable, 1183 | _: void 1184 | ): rxjs$Observable<[T, A, B, C, D]>; 1185 | 1186 | zip( 1187 | a: rxjs$Observable, 1188 | b: rxjs$Observable, 1189 | c: rxjs$Observable, 1190 | _: void 1191 | ): rxjs$Observable<[T, A, B, C]>; 1192 | 1193 | zip( 1194 | a: rxjs$Observable, 1195 | b: rxjs$Observable, 1196 | _: void 1197 | ): rxjs$Observable<[T, A, B]>; 1198 | 1199 | zip(a: rxjs$Observable, _: void): rxjs$Observable<[T, A]>; 1200 | 1201 | static forkJoin( 1202 | a: rxjs$Observable, 1203 | resultSelector: (a: A) => B 1204 | ): rxjs$Observable; 1205 | 1206 | static forkJoin( 1207 | a: rxjs$Observable, 1208 | b: rxjs$Observable, 1209 | resultSelector: (a: A, b: B) => C 1210 | ): rxjs$Observable; 1211 | 1212 | static forkJoin( 1213 | a: rxjs$Observable, 1214 | b: rxjs$Observable, 1215 | c: rxjs$Observable, 1216 | resultSelector: (a: A, b: B, c: C) => D 1217 | ): rxjs$Observable; 1218 | 1219 | static forkJoin( 1220 | a: rxjs$Observable, 1221 | b: rxjs$Observable, 1222 | c: rxjs$Observable, 1223 | d: rxjs$Observable, 1224 | resultSelector: (a: A, b: B, c: C, d: D) => E 1225 | ): rxjs$Observable; 1226 | 1227 | static forkJoin( 1228 | a: rxjs$Observable, 1229 | b: rxjs$Observable, 1230 | c: rxjs$Observable, 1231 | d: rxjs$Observable, 1232 | e: rxjs$Observable, 1233 | resultSelector: (a: A, b: B, c: C, d: D, e: E) => F 1234 | ): rxjs$Observable; 1235 | 1236 | static forkJoin( 1237 | a: rxjs$Observable, 1238 | b: rxjs$Observable, 1239 | c: rxjs$Observable, 1240 | d: rxjs$Observable, 1241 | e: rxjs$Observable, 1242 | f: rxjs$Observable, 1243 | resultSelector: (a: A, b: B, c: C, d: D, e: E, f: F) => G 1244 | ): rxjs$Observable; 1245 | 1246 | static forkJoin( 1247 | a: rxjs$Observable, 1248 | b: rxjs$Observable, 1249 | c: rxjs$Observable, 1250 | d: rxjs$Observable, 1251 | e: rxjs$Observable, 1252 | f: rxjs$Observable, 1253 | g: rxjs$Observable, 1254 | resultSelector: (a: A, b: B, c: C, d: D, e: E, f: F, g: G) => H 1255 | ): rxjs$Observable; 1256 | 1257 | static forkJoin( 1258 | a: rxjs$Observable, 1259 | b: rxjs$Observable, 1260 | _: void 1261 | ): rxjs$Observable<[A, B]>; 1262 | 1263 | static forkJoin( 1264 | a: rxjs$Observable, 1265 | b: rxjs$Observable, 1266 | c: rxjs$Observable, 1267 | _: void 1268 | ): rxjs$Observable<[A, B, C]>; 1269 | 1270 | static forkJoin( 1271 | a: rxjs$Observable, 1272 | b: rxjs$Observable, 1273 | c: rxjs$Observable, 1274 | d: rxjs$Observable, 1275 | _: void 1276 | ): rxjs$Observable<[A, B, C, D]>; 1277 | 1278 | static forkJoin( 1279 | a: rxjs$Observable, 1280 | b: rxjs$Observable, 1281 | c: rxjs$Observable, 1282 | d: rxjs$Observable, 1283 | e: rxjs$Observable, 1284 | _: void 1285 | ): rxjs$Observable<[A, B, C, D, E]>; 1286 | 1287 | static forkJoin( 1288 | a: rxjs$Observable, 1289 | b: rxjs$Observable, 1290 | c: rxjs$Observable, 1291 | d: rxjs$Observable, 1292 | e: rxjs$Observable, 1293 | f: rxjs$Observable, 1294 | _: void 1295 | ): rxjs$Observable<[A, B, C, D, E, F]>; 1296 | 1297 | static forkJoin( 1298 | a: rxjs$Observable, 1299 | b: rxjs$Observable, 1300 | c: rxjs$Observable, 1301 | d: rxjs$Observable, 1302 | e: rxjs$Observable, 1303 | f: rxjs$Observable, 1304 | g: rxjs$Observable, 1305 | _: void 1306 | ): rxjs$Observable<[A, B, C, D, E, F, G]>; 1307 | 1308 | static forkJoin( 1309 | a: rxjs$Observable, 1310 | b: rxjs$Observable, 1311 | c: rxjs$Observable, 1312 | d: rxjs$Observable, 1313 | e: rxjs$Observable, 1314 | f: rxjs$Observable, 1315 | g: rxjs$Observable, 1316 | h: rxjs$Observable, 1317 | _: void 1318 | ): rxjs$Observable<[A, B, C, D, E, F, G, H]>; 1319 | 1320 | static forkJoin( 1321 | a: Array>, 1322 | _: void 1323 | ): rxjs$Observable>; 1324 | 1325 | static forkJoin( 1326 | a: Array>, 1327 | _: void 1328 | ): rxjs$Observable; 1329 | 1330 | static forkJoin( 1331 | a: Array>, 1332 | resultSelector: (...values: Array) => B 1333 | ): rxjs$Observable; 1334 | 1335 | static forkJoin( 1336 | a: Array>, 1337 | resultSelector: (...values: Array) => A 1338 | ): rxjs$Observable; 1339 | 1340 | window( 1341 | windowBoundaries: rxjs$Observable 1342 | ): rxjs$Observable>; 1343 | windowCount( 1344 | windowSize: number, 1345 | startWindowEvery?: number 1346 | ): rxjs$Observable>; 1347 | windowToggle( 1348 | openings: rxjs$Observable, 1349 | closingSelector: (value: A) => rxjs$Observable 1350 | ): rxjs$Observable>; 1351 | windowWhen( 1352 | closingSelector: () => rxjs$Observable 1353 | ): rxjs$Observable>; 1354 | 1355 | withLatestFrom( 1356 | a: rxjs$Observable, 1357 | b: rxjs$Observable, 1358 | c: rxjs$Observable, 1359 | d: rxjs$Observable, 1360 | e: rxjs$Observable, 1361 | f: rxjs$Observable, 1362 | g: rxjs$Observable, 1363 | resultSelector: (t: T, a: A, b: B, c: C, d: D, e: E, f: F, g: G) => H 1364 | ): rxjs$Observable; 1365 | 1366 | withLatestFrom( 1367 | a: rxjs$Observable, 1368 | b: rxjs$Observable, 1369 | c: rxjs$Observable, 1370 | d: rxjs$Observable, 1371 | e: rxjs$Observable, 1372 | f: rxjs$Observable, 1373 | resultSelector: (t: T, a: A, b: B, c: C, d: D, e: E, f: F) => G 1374 | ): rxjs$Observable; 1375 | 1376 | withLatestFrom( 1377 | a: rxjs$Observable, 1378 | b: rxjs$Observable, 1379 | c: rxjs$Observable, 1380 | d: rxjs$Observable, 1381 | e: rxjs$Observable, 1382 | resultSelector: (t: T, a: A, b: B, c: C, d: D, e: E) => F 1383 | ): rxjs$Observable; 1384 | 1385 | withLatestFrom( 1386 | a: rxjs$Observable, 1387 | b: rxjs$Observable, 1388 | c: rxjs$Observable, 1389 | d: rxjs$Observable, 1390 | resultSelector: (t: T, a: A, b: B, c: C, d: D) => E 1391 | ): rxjs$Observable; 1392 | 1393 | withLatestFrom( 1394 | a: rxjs$Observable, 1395 | b: rxjs$Observable, 1396 | c: rxjs$Observable, 1397 | resultSelector: (t: T, a: A, b: B, c: C) => D 1398 | ): rxjs$Observable; 1399 | 1400 | withLatestFrom( 1401 | a: rxjs$Observable, 1402 | b: rxjs$Observable, 1403 | resultSelector: (t: T, a: A, b: B) => C 1404 | ): rxjs$Observable; 1405 | 1406 | withLatestFrom( 1407 | a: rxjs$Observable, 1408 | resultSelector: (t: T, a: A) => B 1409 | ): rxjs$Observable; 1410 | 1411 | withLatestFrom( 1412 | a: rxjs$Observable, 1413 | b: rxjs$Observable, 1414 | c: rxjs$Observable, 1415 | d: rxjs$Observable, 1416 | e: rxjs$Observable, 1417 | f: rxjs$Observable, 1418 | g: rxjs$Observable, 1419 | _: void 1420 | ): rxjs$Observable<[T, A, B, C, D, E, E, F, G]>; 1421 | 1422 | withLatestFrom( 1423 | a: rxjs$Observable, 1424 | b: rxjs$Observable, 1425 | c: rxjs$Observable, 1426 | d: rxjs$Observable, 1427 | e: rxjs$Observable, 1428 | f: rxjs$Observable, 1429 | _: void 1430 | ): rxjs$Observable<[T, A, B, C, D, E, F]>; 1431 | 1432 | withLatestFrom( 1433 | a: rxjs$Observable, 1434 | b: rxjs$Observable, 1435 | c: rxjs$Observable, 1436 | d: rxjs$Observable, 1437 | e: rxjs$Observable, 1438 | _: void 1439 | ): rxjs$Observable<[T, A, B, C, D, E]>; 1440 | 1441 | withLatestFrom( 1442 | a: rxjs$Observable, 1443 | b: rxjs$Observable, 1444 | c: rxjs$Observable, 1445 | d: rxjs$Observable, 1446 | _: void 1447 | ): rxjs$Observable<[T, A, B, C, D]>; 1448 | 1449 | withLatestFrom( 1450 | a: rxjs$Observable, 1451 | b: rxjs$Observable, 1452 | c: rxjs$Observable, 1453 | _: void 1454 | ): rxjs$Observable<[T, A, B, C]>; 1455 | 1456 | withLatestFrom( 1457 | a: rxjs$Observable, 1458 | b: rxjs$Observable, 1459 | _: void 1460 | ): rxjs$Observable<[T, A, B]>; 1461 | 1462 | withLatestFrom(a: rxjs$Observable, _: void): rxjs$Observable<[T, A]>; 1463 | 1464 | static using( 1465 | resourceFactory: () => ?R, 1466 | observableFactory: (resource: R) => rxjs$Observable | Promise | void 1467 | ): rxjs$Observable; 1468 | 1469 | _subscribe(observer: rxjs$Subscriber): rxjs$Subscription; 1470 | 1471 | _isScalar: boolean; 1472 | source: ?rxjs$Observable; 1473 | operator: ?rxjs$Operator; 1474 | } 1475 | 1476 | declare class rxjs$ConnectableObservable extends rxjs$Observable { 1477 | connect(): rxjs$Subscription; 1478 | refCount(): rxjs$Observable; 1479 | } 1480 | 1481 | declare class rxjs$GroupedObservable extends rxjs$Observable { 1482 | key: K; 1483 | } 1484 | 1485 | declare class rxjs$Observer { 1486 | next(value: T): mixed; 1487 | 1488 | error(error: any): mixed; 1489 | 1490 | complete(): mixed; 1491 | } 1492 | 1493 | declare interface rxjs$Operator { 1494 | call(subscriber: rxjs$Subscriber, source: any): rxjs$TeardownLogic; 1495 | } 1496 | 1497 | // FIXME(samgoldman) should be `mixins rxjs$Observable, rxjs$Observer` 1498 | // once Babel parsing support exists: https://phabricator.babeljs.io/T6821 1499 | declare class rxjs$Subject extends rxjs$Observable { 1500 | asObservable(): rxjs$Observable; 1501 | 1502 | observers: Array>; 1503 | 1504 | unsubscribe(): void; 1505 | 1506 | // Copied from rxjs$Observer 1507 | next(value: T): mixed; 1508 | error(error: any): mixed; 1509 | complete(): mixed; 1510 | 1511 | // For use in subclasses only: 1512 | _next(value: T): void; 1513 | } 1514 | 1515 | declare class rxjs$AnonymousSubject extends rxjs$Subject { 1516 | source: ?rxjs$Observable; 1517 | destination: ?rxjs$Observer; 1518 | 1519 | constructor( 1520 | destination?: rxjs$IObserver, 1521 | source?: rxjs$Observable 1522 | ): void; 1523 | next(value: T): void; 1524 | error(err: any): void; 1525 | complete(): void; 1526 | } 1527 | 1528 | declare class rxjs$BehaviorSubject extends rxjs$Subject { 1529 | constructor(initialValue: T): void; 1530 | 1531 | getValue(): T; 1532 | } 1533 | 1534 | declare class rxjs$ReplaySubject extends rxjs$Subject { 1535 | constructor( 1536 | bufferSize?: number, 1537 | windowTime?: number, 1538 | scheduler?: rxjs$SchedulerClass 1539 | ): void; 1540 | } 1541 | 1542 | declare class rxjs$Subscription { 1543 | unsubscribe(): void; 1544 | add(teardown: rxjs$TeardownLogic): rxjs$Subscription; 1545 | } 1546 | 1547 | declare class rxjs$Subscriber extends rxjs$Subscription { 1548 | static create( 1549 | next?: (x?: T) => void, 1550 | error?: (e?: any) => void, 1551 | complete?: () => void 1552 | ): rxjs$Subscriber; 1553 | 1554 | constructor( 1555 | destinationOrNext?: rxjs$PartialObserver | ((value: T) => void), 1556 | error?: (e?: any) => void, 1557 | complete?: () => void 1558 | ): void; 1559 | next(value?: T): void; 1560 | error(err?: any): void; 1561 | complete(): void; 1562 | unsubscribe(): void; 1563 | } 1564 | 1565 | declare class rxjs$SchedulerClass { 1566 | schedule( 1567 | work: (state?: T) => void, 1568 | delay?: number, 1569 | state?: T 1570 | ): rxjs$Subscription; 1571 | } 1572 | 1573 | declare class rxjs$TimeoutError extends Error {} 1574 | 1575 | declare module "rxjs" { 1576 | declare module.exports: { 1577 | Observable: typeof rxjs$Observable, 1578 | Observer: typeof rxjs$Observer, 1579 | ConnectableObservable: typeof rxjs$ConnectableObservable, 1580 | Subject: typeof rxjs$Subject, 1581 | Subscriber: typeof rxjs$Subscriber, 1582 | AnonymousSubject: typeof rxjs$AnonymousSubject, 1583 | BehaviorSubject: typeof rxjs$BehaviorSubject, 1584 | ReplaySubject: typeof rxjs$ReplaySubject, 1585 | Scheduler: { 1586 | asap: rxjs$SchedulerClass, 1587 | queue: rxjs$SchedulerClass, 1588 | animationFrame: rxjs$SchedulerClass, 1589 | async: rxjs$SchedulerClass 1590 | }, 1591 | Subscription: typeof rxjs$Subscription, 1592 | TimeoutError: typeof rxjs$TimeoutError 1593 | }; 1594 | } 1595 | 1596 | declare module "rxjs/Observable" { 1597 | declare module.exports: { 1598 | Observable: typeof rxjs$Observable 1599 | }; 1600 | } 1601 | 1602 | declare module "rxjs/Observer" { 1603 | declare module.exports: { 1604 | Observer: typeof rxjs$Observer 1605 | }; 1606 | } 1607 | 1608 | declare module "rxjs/BehaviorSubject" { 1609 | declare module.exports: { 1610 | BehaviorSubject: typeof rxjs$BehaviorSubject 1611 | }; 1612 | } 1613 | 1614 | declare module "rxjs/ReplaySubject" { 1615 | declare module.exports: { 1616 | ReplaySubject: typeof rxjs$ReplaySubject 1617 | }; 1618 | } 1619 | 1620 | declare module "rxjs/Subject" { 1621 | declare module.exports: { 1622 | Subject: typeof rxjs$Subject, 1623 | AnonymousSubject: typeof rxjs$AnonymousSubject 1624 | }; 1625 | } 1626 | 1627 | declare module "rxjs/Subscriber" { 1628 | declare module.exports: { 1629 | Subscriber: typeof rxjs$Subscriber 1630 | }; 1631 | } 1632 | 1633 | declare module "rxjs/Subscription" { 1634 | declare module.exports: { 1635 | Subscription: typeof rxjs$Subscription 1636 | }; 1637 | } 1638 | 1639 | declare module "rxjs/testing/TestScheduler" { 1640 | declare module.exports: { 1641 | TestScheduler: typeof rxjs$SchedulerClass 1642 | }; 1643 | } 1644 | --------------------------------------------------------------------------------