diff --git a/.github/home-bottom.png b/.github/home-bottom.png
new file mode 100644
index 0000000..6621c9c
Binary files /dev/null and b/.github/home-bottom.png differ
diff --git a/.github/home.png b/.github/home.png
index bb88926..5e9834d 100644
Binary files a/.github/home.png and b/.github/home.png differ
diff --git a/.github/movies.png b/.github/movies.png
index b4b78df..d6c925f 100644
Binary files a/.github/movies.png and b/.github/movies.png differ
diff --git a/.github/my-list.png b/.github/my-list.png
new file mode 100644
index 0000000..5f45861
Binary files /dev/null and b/.github/my-list.png differ
diff --git a/.github/show.png b/.github/show.png
index 9c0cce9..e7aa03b 100644
Binary files a/.github/show.png and b/.github/show.png differ
diff --git a/.github/shows.png b/.github/shows.png
index 72245e7..72231ae 100644
Binary files a/.github/shows.png and b/.github/shows.png differ
diff --git a/README.md b/README.md
index 1270b81..f2a9f30 100644
--- a/README.md
+++ b/README.md
@@ -55,9 +55,13 @@ Please see the [contributing guide](https://github.com/tripss/popcorn-native/blo
## Screenshots
-Home Screen | Movies Screen
+Home Screen | Home Screen
:-------------------------:|:-------------------------:
-![Home Screen](./.github/home.png) | ![Movies Screen](./.github/movies.png)
+![Home Screen](./.github/home.png) | ![Home Screen](./.github/home-bottom.png)
+
+My List Screen | Movies Screen
+:-------------------------:|:-------------------------:
+![My List Screen](./.github/my-list.png) |![Show Screen](./.github/movies.png)
Shows Screen | Show Screen
:-------------------------:|:-------------------------:
diff --git a/android/app/build.gradle b/android/app/build.gradle
index 8a1cdd1..bd92b66 100644
--- a/android/app/build.gradle
+++ b/android/app/build.gradle
@@ -107,8 +107,8 @@ android {
applicationId "com.popcorn"
minSdkVersion 16
targetSdkVersion 26
- versionCode 9
- versionName "v0.6.3"
+ versionCode 10
+ versionName "v0.7.0"
ndk {
abiFilters "armeabi-v7a", "x86"
}
diff --git a/app/components/Card/Card.js b/app/components/Card/Card.js
index b0b5897..238a281 100644
--- a/app/components/Card/Card.js
+++ b/app/components/Card/Card.js
@@ -10,7 +10,7 @@ const styles = StyleSheet.create({
root: {
height : 190,
- width : 120,
+ width : 121,
marginLeft : 8,
marginRight: 8,
alignSelf : 'stretch',
@@ -24,33 +24,56 @@ const styles = StyleSheet.create({
})
-export const Card = ({ item, empty, ...rest }) => (
- console.warn(item.title)}
- // onPress={() => this.openItem(item)}
- {...rest}>
-
-
-
-
-)
-
-Card.propTypes = {
- item : PropTypes.object,
- empty: PropTypes.bool,
-}
+export default class Card extends React.Component {
-Card.defaultProps = {
- item : null,
- empty: false,
-}
+ static propTypes = {
+ item : PropTypes.object,
+ empty: PropTypes.bool,
+ }
+
+ static defaultProps = {
+ item : null,
+ empty: false,
+ }
+
+ constructor(props) {
+ super(props)
+
+ const { item, empty } = props
-export default Card
+ this.state = {
+ showPlaceholder: empty || !item.images.poster.thumb,
+ }
+ }
+
+ handleImageError = () => {
+ this.setState({
+ showPlaceholder: true,
+ })
+ }
+
+ render() {
+ const { item, empty, ...rest } = this.props
+ const { showPlaceholder } = this.state
+
+ return (
+ console.warn(item.title)}
+ // onPress={() => this.openItem(item)}
+ {...rest}>
+
+
+
+
+ )
+ }
+}
diff --git a/app/components/Disclaimer/Disclaimer.js b/app/components/Disclaimer/Disclaimer.js
index c3c4ca6..b3e1a1e 100644
--- a/app/components/Disclaimer/Disclaimer.js
+++ b/app/components/Disclaimer/Disclaimer.js
@@ -82,17 +82,19 @@ export default class CheckForUpdates extends React.Component {
children: PropTypes.node.isRequired,
}
- state = {
- accepted : false,
- animating: false,
- loading : true,
+ constructor(props, context) {
+ super(props, context)
+
+ this.state = {
+ accepted : false,
+ animating: false,
+ }
}
componentWillMount() {
Settings.getItem(Settings.DISCLAIMER_ACCEPTED).then((accepted) => {
this.setState({
accepted: accepted && accepted === 'y',
- loading : false,
}, () => {
if (!accepted) {
SplashScreen.hide()
@@ -122,7 +124,7 @@ export default class CheckForUpdates extends React.Component {
render() {
const { children } = this.props
- const { animating, accepted, loading } = this.state
+ const { animating, accepted } = this.state
return (
diff --git a/app/modules/BookmarkAdapter/BookmarkAdapter.js b/app/modules/BookmarkAdapter/BookmarkAdapter.js
new file mode 100644
index 0000000..8e784c8
--- /dev/null
+++ b/app/modules/BookmarkAdapter/BookmarkAdapter.js
@@ -0,0 +1,31 @@
+import DefaultBookmarkAdapter from 'popcorn-sdk/BookmarkAdapter'
+
+import Bookmarks from '../db/Bookmarks'
+
+export default new (class BookmarkAdapter extends DefaultBookmarkAdapter {
+
+ getAll = Bookmarks.getAll
+
+ checkMovie = movie => new Promise(async(resolve) => {
+ const bookmarks = await Bookmarks.getAllMovies()
+
+ resolve({
+ ...movie,
+ bookmarked: bookmarks.filter(bookmark => bookmark.id === movie.id).length === 1,
+ })
+ })
+
+ checkShow = show => new Promise(async(resolve) => {
+ const bookmarks = await Bookmarks.getAllShows()
+
+ resolve({
+ ...show,
+ bookmarked: bookmarks.filter(bookmark => bookmark.id === show.id).length === 1,
+ })
+ })
+
+ addItem = Bookmarks.addItem
+
+ removeItem = Bookmarks.removeItem
+
+})()
diff --git a/app/modules/BookmarkAdapter/index.js b/app/modules/BookmarkAdapter/index.js
new file mode 100644
index 0000000..fb9afa6
--- /dev/null
+++ b/app/modules/BookmarkAdapter/index.js
@@ -0,0 +1 @@
+export { default } from './BookmarkAdapter'
diff --git a/app/modules/PopcornSDK.js b/app/modules/PopcornSDK.js
new file mode 100644
index 0000000..5a8ea29
--- /dev/null
+++ b/app/modules/PopcornSDK.js
@@ -0,0 +1,8 @@
+import Popcorn from 'popcorn-sdk'
+
+import BookmarkAdapter from './BookmarkAdapter'
+
+const SDK = Popcorn
+SDK.setBookmarkAdapter(BookmarkAdapter)
+
+export default SDK
diff --git a/app/modules/db/Bookmarks.js b/app/modules/db/Bookmarks.js
new file mode 100644
index 0000000..cc9434f
--- /dev/null
+++ b/app/modules/db/Bookmarks.js
@@ -0,0 +1,55 @@
+import { Constants } from 'popcorn-sdk'
+import Base from './Base'
+
+export default new (class BookmarksDB extends Base {
+
+ KEY_BOOKMARKS = '@Popcorn:Bookmarks'
+
+ bookmarks = []
+
+ getAll = async() => {
+ if (this.bookmarks.length > 0) {
+ return this.bookmarks
+ }
+
+ const bookmarks = await this.getItem(this.KEY_BOOKMARKS)
+
+ if (bookmarks) {
+ this.bookmarks = JSON.parse(bookmarks)
+ console.log('this.bookmarks', this.bookmarks)
+ return this.bookmarks
+ }
+
+ return this.bookmarks
+ }
+
+ getAllMovies = async() => {
+ await this.getAll()
+
+ return this.bookmarks.filter(bookmark => bookmark.type === Constants.TYPE_MOVIE)
+ }
+
+ getAllShows = async() => {
+ await this.getAll()
+
+ return this.bookmarks.filter(bookmark => bookmark.type === Constants.TYPE_SHOW)
+ }
+
+ addItem = ({ id, title, type, images }) => {
+ this.bookmarks.push({
+ id,
+ title,
+ type,
+ images,
+ })
+
+ this.setItem(this.KEY_BOOKMARKS, JSON.stringify(this.bookmarks))
+ }
+
+ removeItem = ({ id }) => {
+ this.bookmarks = this.bookmarks.filter(bookmark => bookmark.id !== id)
+
+ this.setItem(this.KEY_BOOKMARKS, JSON.stringify(this.bookmarks))
+ }
+
+})()
diff --git a/app/modules/db/Settings.js b/app/modules/db/Settings.js
index 28bf559..e55b727 100644
--- a/app/modules/db/Settings.js
+++ b/app/modules/db/Settings.js
@@ -2,6 +2,6 @@ import Base from './Base'
export default new (class SettingsDB extends Base {
- DISCLAIMER_ACCEPTED = 'Settings.DISCLAIMER_ACCEPTED'
+ DISCLAIMER_ACCEPTED = '@Popcorn:Settings:DISCLAIMER_ACCEPTED'
})()
diff --git a/app/modules/i18n/translations/en.json b/app/modules/i18n/translations/en.json
index 2cc7491..f2d861a 100644
--- a/app/modules/i18n/translations/en.json
+++ b/app/modules/i18n/translations/en.json
@@ -1,5 +1,6 @@
{
"Home": "Home",
+ "My List": "My List",
"Movies": "Movies",
"Shows": "Shows",
"Season {{number}}": "Season {{number}}",
diff --git a/app/modules/i18n/translations/nl.json b/app/modules/i18n/translations/nl.json
index 78e00e6..dd30b93 100644
--- a/app/modules/i18n/translations/nl.json
+++ b/app/modules/i18n/translations/nl.json
@@ -1,5 +1,6 @@
{
"Home": "Home",
+ "My List": "Mijn Lijst",
"Movies": "Films",
"Shows": "Series",
"Season {{number}}": "Seizoen {{number}}",
diff --git a/app/screens/Home/HomeActions.js b/app/screens/Home/HomeActions.js
index e70604c..d4bbecd 100644
--- a/app/screens/Home/HomeActions.js
+++ b/app/screens/Home/HomeActions.js
@@ -1,4 +1,5 @@
-import Popcorn, { Constants } from 'popcorn-sdk'
+import { Constants } from 'popcorn-sdk'
+import Popcorn from 'modules/PopcornSDK'
import * as HomeConstants from './HomeConstants'
import * as HomeSelectors from './HomeSelectors'
@@ -42,9 +43,32 @@ export const getItems = (mode, page = 1, givenFilters = {}) => (dispatch, getSta
case Constants.TYPE_MOVIE:
return Popcorn.getMovies(page, filters).then(movies => dispatch(fetchedItems(movies, mode))).catch(catchNoCon)
+ case 'movieSearch':
+ // Clear the items
+ dispatch(clearItems(mode))
+
+ return Popcorn.getMovies(page, filters).then(movies => dispatch(fetchedItems(movies, mode))).catch(catchNoCon)
+
case Constants.TYPE_SHOW:
return Popcorn.getShows(page, filters).then(shows => dispatch(fetchedItems(shows, mode))).catch(catchNoCon)
+ case 'showSearch':
+ // Clear the items
+ dispatch(clearItems(mode))
+
+ return Popcorn.getShows(page, filters).then(shows => dispatch(fetchedItems(shows, mode))).catch(catchNoCon)
+
+ case Constants.TYPE_BOOKMARK:
+ return Popcorn.bookmarks.getAll().then(bookmarks => dispatch(fetchedItems(bookmarks, mode)))
+
+ case 'bookmarkSearch':
+ return Popcorn.bookmarks.getAll().then(bookmarks => dispatch(
+ fetchedItems(
+ bookmarks.filter(bookmark => bookmark.title.toLowerCase().indexOf(filters.keywords.toLowerCase()) > -1),
+ mode,
+ ),
+ ))
+
default:
return null
}
diff --git a/app/screens/Home/HomeConstants.js b/app/screens/Home/HomeConstants.js
index dfc9372..28ca94f 100644
--- a/app/screens/Home/HomeConstants.js
+++ b/app/screens/Home/HomeConstants.js
@@ -4,10 +4,14 @@ export const INITIAL_STATE = {
isLoading : true,
hasInternet: true,
modes : {
- bookmark: { page: 1, items: [], filters: {} },
- movie : { page: 1, items: [], filters: { limit: 50, sort: 'trending' } },
- show : { page: 1, items: [], filters: { limit: 50, sort: 'trending' } },
- search : { page: 1, items: [], filters: {} },
+ bookmark : { items: [] },
+ bookmarkSearch: { items: [] },
+
+ movie : { page: 1, items: [], filters: { limit: 50, sort: 'trending' } },
+ movieSearch : { page: 1, items: [], filters: {} },
+
+ show : { page: 1, items: [], filters: { limit: 50, sort: 'trending' } },
+ showSearch : { page: 1, items: [], filters: {} },
},
}
diff --git a/app/screens/Home/HomeReducer.js b/app/screens/Home/HomeReducer.js
index a16db2f..e38a8c0 100644
--- a/app/screens/Home/HomeReducer.js
+++ b/app/screens/Home/HomeReducer.js
@@ -1,4 +1,5 @@
import * as HomeConstants from './HomeConstants'
+import * as ItemConstants from '../Item/ItemConstants'
export default (state = HomeConstants.INITIAL_STATE, action) => {
switch (action.type) {
@@ -40,6 +41,33 @@ export default (state = HomeConstants.INITIAL_STATE, action) => {
},
}
+ case ItemConstants.ADD_TO_BOOKMARKS:
+ return {
+ ...state,
+ modes: {
+ ...state.modes,
+ bookmark: {
+ ...state.modes.bookmark,
+ items: [
+ ...state.modes.bookmark.items,
+ action.payload,
+ ],
+ },
+ },
+ }
+
+ case ItemConstants.REMOVE_FROM_BOOKMARKS:
+ return {
+ ...state,
+ modes: {
+ ...state.modes,
+ bookmark: {
+ ...state.modes.bookmark,
+ items: state.modes.bookmark.items.filter(bookmark => bookmark.id !== action.payload.id),
+ },
+ },
+ }
+
default:
return state
}
diff --git a/app/screens/Home/HomeScreen.js b/app/screens/Home/HomeScreen.js
index d457d0e..e5989f0 100644
--- a/app/screens/Home/HomeScreen.js
+++ b/app/screens/Home/HomeScreen.js
@@ -43,6 +43,7 @@ export default class Home extends React.PureComponent {
getItems(Constants.TYPE_MOVIE)
getItems(Constants.TYPE_SHOW)
+ getItems(Constants.TYPE_BOOKMARK)
}
componentWillUnmount() {
@@ -69,7 +70,11 @@ export default class Home extends React.PureComponent {
return null
}
- getMyList = () => []
+ getMyList = () => {
+ const { modes } = this.props
+
+ return modes[Constants.TYPE_BOOKMARK].items.slice(0, 10)
+ }
getMovies = (withSlice = true) => {
const { modes } = this.props
@@ -92,6 +97,8 @@ export default class Home extends React.PureComponent {
render() {
const { isLoading, hasInternet } = this.props
+ const myList = this.getMyList()
+
return (
@@ -104,8 +111,20 @@ export default class Home extends React.PureComponent {
onLoad={this.handleCoverLoaded}
item={this.getMainCover()} />
+ {myList && myList.length > 0 && (
+
+ )}
+
0 ? 0 : -20,
+ marginBottom: 8,
+ }}
onPress={this.handleItemOpen}
loading={isLoading}
title={i18n.t('Movies')}
diff --git a/app/screens/Item/ItemActions.js b/app/screens/Item/ItemActions.js
index 7b6e183..aa1287c 100644
--- a/app/screens/Item/ItemActions.js
+++ b/app/screens/Item/ItemActions.js
@@ -1,4 +1,5 @@
-import Popcorn, { Constants } from 'popcorn-sdk'
+import { Constants } from 'popcorn-sdk'
+import Popcorn from 'modules/PopcornSDK'
import * as ItemConstants from './ItemConstants'
import * as HomeSelectors from '../Home/HomeSelectors'
@@ -21,21 +22,8 @@ export function partlyFetchedItem(item) {
}
}
-export function fetchEpisodeTorrents() {
- return {
- type: ItemConstants.FETCH_EPISODE_TORRENTS,
- }
-}
-
-export function fetchedEpisodeTorrents(item) {
- return {
- type : ItemConstants.FETCHED_EPISODE_TORRENTS,
- payload: item,
- }
-}
-
export function getItem(type, itemId) {
- return (dispatch, getState) => new Promise((resolve) => {
+ return (dispatch, getState) => new Promise(async(resolve) => {
dispatch({
type: ItemConstants.FETCH_ITEM,
})
@@ -44,7 +32,9 @@ export function getItem(type, itemId) {
if (type === Constants.TYPE_MOVIE) {
if (item) {
- resolve(dispatch(fetchedItem(item)))
+ resolve(dispatch(fetchedItem(
+ await Popcorn.bookmarks.checkMovie(item),
+ )))
} else {
resolve(Popcorn.getMovie(itemId).then(movie => dispatch(fetchedItem(movie))))
@@ -52,16 +42,36 @@ export function getItem(type, itemId) {
} else if (type === Constants.TYPE_SHOW) {
if (item) {
- dispatch(partlyFetchedItem(item))
+ resolve(dispatch(partlyFetchedItem(
+ await Popcorn.bookmarks.checkMovie(item),
+ )))
}
return Popcorn.getShowBasic(itemId).then((basicShow) => {
dispatch(partlyFetchedItem(basicShow))
- return resolve(Popcorn.getShowMeta(basicShow).then(show => dispatch(fetchedItem(show))))
+ Popcorn.getShowMeta(basicShow).then(show => dispatch(fetchedItem(show)))
})
}
return null
})
}
+
+export const addToBookmarks = (item) => (dispatch) => {
+ Popcorn.bookmarks.addItem(item)
+
+ dispatch({
+ type : ItemConstants.ADD_TO_BOOKMARKS,
+ payload: item,
+ })
+}
+
+export const removeFromBookmarks = (item) => (dispatch) => {
+ Popcorn.bookmarks.removeItem(item)
+
+ dispatch({
+ type : ItemConstants.REMOVE_FROM_BOOKMARKS,
+ payload: item,
+ })
+}
diff --git a/app/screens/Item/ItemConstants.js b/app/screens/Item/ItemConstants.js
index 61c33fe..dd55e2e 100644
--- a/app/screens/Item/ItemConstants.js
+++ b/app/screens/Item/ItemConstants.js
@@ -12,8 +12,6 @@ export const INITIAL_STATE = {
export const FETCH_ITEM = `${REDUCER_NAME}.fetch.item`
export const PARTLY_FETCH_ITEM = `${REDUCER_NAME}.partly.fetch.item`
export const FETCHED_ITEM = `${REDUCER_NAME}.fetched.item`
-export const UPDATE_ITEM = `${REDUCER_NAME}.update.item`
-export const SELECT_SEASON_EPISODE = `${REDUCER_NAME}.select.season.episode`
-export const FETCH_EPISODE_TORRENTS = `${REDUCER_NAME}.fetch.episode.torrents`
-export const FETCHED_EPISODE_TORRENTS = `${REDUCER_NAME}.fetched.episode.torrents`
+export const ADD_TO_BOOKMARKS = `${REDUCER_NAME}.add.to.bookmarks`
+export const REMOVE_FROM_BOOKMARKS = `${REDUCER_NAME}.remove.from.bookmarks`
diff --git a/app/screens/Item/ItemReducer.js b/app/screens/Item/ItemReducer.js
index 4f1585a..835bc8d 100644
--- a/app/screens/Item/ItemReducer.js
+++ b/app/screens/Item/ItemReducer.js
@@ -23,23 +23,22 @@ export default (state = ItemConstants.INITIAL_STATE, action) => {
item : action.payload,
}
- case ItemConstants.FETCH_EPISODE_TORRENTS:
+ case ItemConstants.ADD_TO_BOOKMARKS:
return {
...state,
- fetchingEpisodeTorrents: true,
+ item: {
+ ...state.item,
+ bookmarked: true,
+ },
}
- case ItemConstants.FETCHED_EPISODE_TORRENTS:
+ case ItemConstants.REMOVE_FROM_BOOKMARKS:
return {
...state,
- fetchingEpisodeTorrents: false,
- item : action.payload,
- }
-
- case ItemConstants.SELECT_SEASON_EPISODE:
- return {
- ...state,
- ...action.payload,
+ item: {
+ ...state.item,
+ bookmarked: false,
+ },
}
default:
diff --git a/app/screens/Item/ItemScreen.js b/app/screens/Item/ItemScreen.js
index d193cf9..069661b 100644
--- a/app/screens/Item/ItemScreen.js
+++ b/app/screens/Item/ItemScreen.js
@@ -7,6 +7,7 @@ import i18n from 'modules/i18n'
import ScrollViewWithStatusBar from 'components/ScrollViewWithStatusBar'
import Typography from 'components/Typography'
+import IconButton from 'components/IconButton'
import colors from 'modules/colors'
@@ -36,8 +37,22 @@ const styles = StyleSheet.create({
export default class Item extends React.Component {
+ static getDerivedStateFromProps(nextProps, state) {
+ const { item: nextItem } = nextProps
+ const { activeSeason } = state
+
+ // If we retrieve more season then update to the latest one
+ if (nextItem && nextItem.seasons && nextItem.seasons.length > activeSeason) {
+ return {
+ activeSeason: nextItem.seasons[nextItem.seasons.length - 1].number,
+ }
+ }
+
+ return null
+ }
+
state = {
- activeSeason: 0,
+ activeSeason: null,
}
componentDidMount() {
@@ -54,6 +69,17 @@ export default class Item extends React.Component {
})
}
+ handleToggleBookmarks = () => {
+ const { item, addToBookmarks, removeFromBookmarks } = this.props
+
+ if (item.bookmarked) {
+ removeFromBookmarks(item)
+
+ } else {
+ addToBookmarks(item)
+ }
+ }
+
playItem = (torrents, episode = {}) => {
const { navigation: { navigate, state: { params: item } } } = this.props
@@ -66,24 +92,15 @@ export default class Item extends React.Component {
})
}
- getSelectedSeason = () => {
- const { item } = this.props
-
- const { activeSeason } = this.state
-
- return item.seasons.find(season => season.number === activeSeason)
- }
-
getAiredEpisodes = () => {
- const { item, isLoading } = this.props
+ const { activeSeason } = this.state
+ const today = Date.now()
- if (isLoading || !item || !item.seasons) {
+ if (!activeSeason) {
return []
}
- const today = Date.now()
-
- const season = this.getSelectedSeason()
+ const season = this.getSeasons(activeSeason)
if (!season) {
return []
@@ -92,13 +109,21 @@ export default class Item extends React.Component {
return season.episodes.filter(episode => episode.aired < today)
}
- getSeasonsForPicker = () => {
- const { item, isLoading } = this.props
+ getSeasons = (seasonNr = null) => {
+ const { item } = this.props
+
+ if (!item || !item.seasons || item.seasons.length === 0) {
+ if (seasonNr) {
+ return null
+ }
- if (isLoading) {
return []
}
+ if (seasonNr) {
+ return item.seasons.find(season => season.number === seasonNr)
+ }
+
return item.seasons
}
@@ -119,14 +144,25 @@ export default class Item extends React.Component {
)}
+ {item && (
+
+
+
+ )}
+
{item && item.type === Constants.TYPE_SHOW && (
this.setState({ activeSeason: itemValue })}>
+ onValueChange={(itemValue) => this.setState({ activeSeason: itemValue })}>
- {this.getSeasonsForPicker().map(season => (
+ {this.getSeasons().map(season => (
(
))
diff --git a/app/screens/Mode/ModeScreen.js b/app/screens/Mode/ModeScreen.js
index 33a0ebe..19fb0a7 100644
--- a/app/screens/Mode/ModeScreen.js
+++ b/app/screens/Mode/ModeScreen.js
@@ -1,11 +1,15 @@
import React from 'react'
import PropTypes from 'prop-types'
-import { StyleSheet, Text, View, FlatList, StatusBar } from 'react-native'
+import { StyleSheet, Text, View, FlatList, StatusBar, TextInput } from 'react-native'
import Orientation from 'react-native-orientation'
+import * as Animatable from 'react-native-animatable'
+import Icon from 'react-native-vector-icons/MaterialIcons'
+import { Constants } from 'popcorn-sdk'
import colors from 'modules/colors'
import Card from 'components/Card'
+import IconButton from 'components/IconButton'
import FullScreenLoading from 'components/FullScreenLoading'
const styles = StyleSheet.create({
@@ -20,14 +24,44 @@ const styles = StyleSheet.create({
flexDirection: 'column',
},
- list: {
- marginTop: 32,
- },
-
listItem: {
marginTop: 16,
},
+ searchRoot: {
+ width : '100%',
+ height : 50,
+ marginTop : 40,
+ display : 'flex',
+ justifyContent: 'center',
+ alignItems : 'center',
+ },
+
+ searchContainer: {
+ backgroundColor: colors.BACKGROUND_LIGHTER,
+ width : '90%',
+ height : '100%',
+ },
+
+ input: {
+ height : '100%',
+ width : '80%',
+ color : '#FFF',
+ marginLeft: 40,
+ },
+
+ cancelSearch: {
+ position: 'absolute',
+ right : 8,
+ top : 8,
+ },
+
+ searchIcon: {
+ position: 'absolute',
+ left : 8,
+ top : 8,
+ },
+
})
export default class Mode extends React.Component {
@@ -48,7 +82,10 @@ export default class Mode extends React.Component {
}
state = {
- page: 1,
+ page : 1,
+ firstSearch: true,
+ searching : false,
+ searchText : '',
}
componentDidMount() {
@@ -61,6 +98,11 @@ export default class Mode extends React.Component {
getItems = () => {
const { modes, mode } = this.props
+ const { searching } = this.state
+
+ if (searching) {
+ return modes[`${mode}Search`].items
+ }
return modes[mode].items
}
@@ -71,10 +113,36 @@ export default class Mode extends React.Component {
navigation.navigate('Item', item)
}
+ handleSearch = () => {
+ const { isLoading, getItems, mode } = this.props
+ const { searchText } = this.state
+
+ if (!isLoading && searchText.trim().length > 0) {
+ getItems(`${mode}Search`, 1, { keywords: searchText }).then(() => {
+ this.setState({
+ searching: true,
+ })
+ })
+ }
+ }
+
+ handleCancelSearch = () => {
+ this.setState({
+ searchText: '',
+ searching : false,
+ })
+ }
+
+ handleTextChange = text => this.setState({ searchText: text, firstSearch: false })
+
handleEndReached = () => {
const { isLoading, getItems, mode } = this.props
const { page } = this.state
+ if (mode === Constants.TYPE_BOOKMARK) {
+ return
+ }
+
const nPage = page + 1
this.setState({
@@ -93,6 +161,48 @@ export default class Mode extends React.Component {
/>
)
+ renderSearchBar = () => {
+ const { searchText, firstSearch } = this.state
+
+ return (
+
+
+
+
+ 0 ? 'zoomIn' : 'zoomOut'}
+ duration={firstSearch ? 1 : 300}
+ useNativeDriver>
+
+
+
+
+
+
+
+
+
+
+ )
+ }
+
render() {
const { isLoading, hasInternet } = this.props
@@ -106,18 +216,22 @@ export default class Mode extends React.Component {
{hasInternet && (
- `${item.id}-${index}`}
- onEndReachedThreshold={100}
- onEndReached={this.handleEndReached}
- ListHeaderComponent={() => }
- ListFooterComponent={() => }
- />
+
+
+ `${item.id}-${index}`}
+ onEndReachedThreshold={100}
+ onEndReached={this.handleEndReached}
+ ListHeaderComponent={this.renderSearchBar}
+ ListFooterComponent={() => }
+ />
+
+
)}
{!hasInternet && (
diff --git a/app/screens/index.js b/app/screens/index.js
index 2b7f1ea..63fc557 100644
--- a/app/screens/index.js
+++ b/app/screens/index.js
@@ -30,6 +30,21 @@ export default createStackNavigator({
},
},
+ MyList: {
+ screen: ({ ...props }) => ,
+
+ navigationOptions: {
+ tabBarLabel: i18n.t('My List'),
+ tabBarIcon : ({ tintColor }) => (
+
+ ),
+ },
+ },
+
Movies: {
screen: ({ ...props }) => ,
diff --git a/package.json b/package.json
index 1670f58..8707196 100644
--- a/package.json
+++ b/package.json
@@ -15,7 +15,7 @@
},
"dependencies": {
"i18n-js": "^3.0.11",
- "popcorn-sdk": "0.5.0",
+ "popcorn-sdk": "1.1.0",
"prop-types": "^15.6.2",
"react": "16.3.1",
"react-native": "~0.55.2",
diff --git a/yarn.lock b/yarn.lock
index 2467a87..86ec092 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -4781,9 +4781,9 @@ pn@^1.1.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/pn/-/pn-1.1.0.tgz#e2f4cef0e219f463c179ab37463e4e1ecdccbafb"
-popcorn-sdk@0.5.0:
- version "0.5.0"
- resolved "https://registry.yarnpkg.com/popcorn-sdk/-/popcorn-sdk-0.5.0.tgz#7b08bd1d1d7ed202cd42f780921fd25a1a300e47"
+popcorn-sdk@1.1.0:
+ version "1.1.0"
+ resolved "https://registry.yarnpkg.com/popcorn-sdk/-/popcorn-sdk-1.1.0.tgz#f7dc79c79a48fea764991327dceb9596449b6563"
dependencies:
axios "^0.18.0"