diff --git a/ios/kitsu_mobile/Images.xcassets/AppIcon.appiconset/Icon-1024.png b/ios/kitsu_mobile/Images.xcassets/AppIcon.appiconset/Icon-1024.png index b9e7d699f..0646d767c 100644 Binary files a/ios/kitsu_mobile/Images.xcassets/AppIcon.appiconset/Icon-1024.png and b/ios/kitsu_mobile/Images.xcassets/AppIcon.appiconset/Icon-1024.png differ diff --git a/ios/kitsu_mobile/Images.xcassets/AppIcon.appiconset/Icon-120.png b/ios/kitsu_mobile/Images.xcassets/AppIcon.appiconset/Icon-120.png index ff6db1703..64ef4642e 100644 Binary files a/ios/kitsu_mobile/Images.xcassets/AppIcon.appiconset/Icon-120.png and b/ios/kitsu_mobile/Images.xcassets/AppIcon.appiconset/Icon-120.png differ diff --git a/ios/kitsu_mobile/Images.xcassets/AppIcon.appiconset/Icon-121.png b/ios/kitsu_mobile/Images.xcassets/AppIcon.appiconset/Icon-121.png index ff6db1703..64ef4642e 100644 Binary files a/ios/kitsu_mobile/Images.xcassets/AppIcon.appiconset/Icon-121.png and b/ios/kitsu_mobile/Images.xcassets/AppIcon.appiconset/Icon-121.png differ diff --git a/ios/kitsu_mobile/Images.xcassets/AppIcon.appiconset/Icon-152.png b/ios/kitsu_mobile/Images.xcassets/AppIcon.appiconset/Icon-152.png index 109b8f82c..2630e61ac 100644 Binary files a/ios/kitsu_mobile/Images.xcassets/AppIcon.appiconset/Icon-152.png and b/ios/kitsu_mobile/Images.xcassets/AppIcon.appiconset/Icon-152.png differ diff --git a/ios/kitsu_mobile/Images.xcassets/AppIcon.appiconset/Icon-167.png b/ios/kitsu_mobile/Images.xcassets/AppIcon.appiconset/Icon-167.png index 77c3f9c42..1d785fd28 100644 Binary files a/ios/kitsu_mobile/Images.xcassets/AppIcon.appiconset/Icon-167.png and b/ios/kitsu_mobile/Images.xcassets/AppIcon.appiconset/Icon-167.png differ diff --git a/ios/kitsu_mobile/Images.xcassets/AppIcon.appiconset/Icon-180.png b/ios/kitsu_mobile/Images.xcassets/AppIcon.appiconset/Icon-180.png index a3a2e0def..1639d49ef 100644 Binary files a/ios/kitsu_mobile/Images.xcassets/AppIcon.appiconset/Icon-180.png and b/ios/kitsu_mobile/Images.xcassets/AppIcon.appiconset/Icon-180.png differ diff --git a/ios/kitsu_mobile/Images.xcassets/AppIcon.appiconset/Icon-20.png b/ios/kitsu_mobile/Images.xcassets/AppIcon.appiconset/Icon-20.png index 62366c594..d2fb56487 100644 Binary files a/ios/kitsu_mobile/Images.xcassets/AppIcon.appiconset/Icon-20.png and b/ios/kitsu_mobile/Images.xcassets/AppIcon.appiconset/Icon-20.png differ diff --git a/ios/kitsu_mobile/Images.xcassets/AppIcon.appiconset/Icon-29.png b/ios/kitsu_mobile/Images.xcassets/AppIcon.appiconset/Icon-29.png index 7a8accb1d..cc4b0c871 100644 Binary files a/ios/kitsu_mobile/Images.xcassets/AppIcon.appiconset/Icon-29.png and b/ios/kitsu_mobile/Images.xcassets/AppIcon.appiconset/Icon-29.png differ diff --git a/ios/kitsu_mobile/Images.xcassets/AppIcon.appiconset/Icon-40.png b/ios/kitsu_mobile/Images.xcassets/AppIcon.appiconset/Icon-40.png index 8796ddac4..6607c38e8 100644 Binary files a/ios/kitsu_mobile/Images.xcassets/AppIcon.appiconset/Icon-40.png and b/ios/kitsu_mobile/Images.xcassets/AppIcon.appiconset/Icon-40.png differ diff --git a/ios/kitsu_mobile/Images.xcassets/AppIcon.appiconset/Icon-41.png b/ios/kitsu_mobile/Images.xcassets/AppIcon.appiconset/Icon-41.png index 8796ddac4..6607c38e8 100644 Binary files a/ios/kitsu_mobile/Images.xcassets/AppIcon.appiconset/Icon-41.png and b/ios/kitsu_mobile/Images.xcassets/AppIcon.appiconset/Icon-41.png differ diff --git a/ios/kitsu_mobile/Images.xcassets/AppIcon.appiconset/Icon-42.png b/ios/kitsu_mobile/Images.xcassets/AppIcon.appiconset/Icon-42.png index 8796ddac4..6607c38e8 100644 Binary files a/ios/kitsu_mobile/Images.xcassets/AppIcon.appiconset/Icon-42.png and b/ios/kitsu_mobile/Images.xcassets/AppIcon.appiconset/Icon-42.png differ diff --git a/ios/kitsu_mobile/Images.xcassets/AppIcon.appiconset/Icon-58.png b/ios/kitsu_mobile/Images.xcassets/AppIcon.appiconset/Icon-58.png index 7858c9387..1e841baa6 100644 Binary files a/ios/kitsu_mobile/Images.xcassets/AppIcon.appiconset/Icon-58.png and b/ios/kitsu_mobile/Images.xcassets/AppIcon.appiconset/Icon-58.png differ diff --git a/ios/kitsu_mobile/Images.xcassets/AppIcon.appiconset/Icon-59.png b/ios/kitsu_mobile/Images.xcassets/AppIcon.appiconset/Icon-59.png index 7858c9387..1e841baa6 100644 Binary files a/ios/kitsu_mobile/Images.xcassets/AppIcon.appiconset/Icon-59.png and b/ios/kitsu_mobile/Images.xcassets/AppIcon.appiconset/Icon-59.png differ diff --git a/ios/kitsu_mobile/Images.xcassets/AppIcon.appiconset/Icon-60.png b/ios/kitsu_mobile/Images.xcassets/AppIcon.appiconset/Icon-60.png index e41c155dd..2065f58a8 100644 Binary files a/ios/kitsu_mobile/Images.xcassets/AppIcon.appiconset/Icon-60.png and b/ios/kitsu_mobile/Images.xcassets/AppIcon.appiconset/Icon-60.png differ diff --git a/ios/kitsu_mobile/Images.xcassets/AppIcon.appiconset/Icon-76.png b/ios/kitsu_mobile/Images.xcassets/AppIcon.appiconset/Icon-76.png index 47ad7e8c3..0ad57b775 100644 Binary files a/ios/kitsu_mobile/Images.xcassets/AppIcon.appiconset/Icon-76.png and b/ios/kitsu_mobile/Images.xcassets/AppIcon.appiconset/Icon-76.png differ diff --git a/ios/kitsu_mobile/Images.xcassets/AppIcon.appiconset/Icon-80.png b/ios/kitsu_mobile/Images.xcassets/AppIcon.appiconset/Icon-80.png index 31861d6fb..9bcfa1b0d 100644 Binary files a/ios/kitsu_mobile/Images.xcassets/AppIcon.appiconset/Icon-80.png and b/ios/kitsu_mobile/Images.xcassets/AppIcon.appiconset/Icon-80.png differ diff --git a/ios/kitsu_mobile/Images.xcassets/AppIcon.appiconset/Icon-81.png b/ios/kitsu_mobile/Images.xcassets/AppIcon.appiconset/Icon-81.png index 31861d6fb..9bcfa1b0d 100644 Binary files a/ios/kitsu_mobile/Images.xcassets/AppIcon.appiconset/Icon-81.png and b/ios/kitsu_mobile/Images.xcassets/AppIcon.appiconset/Icon-81.png differ diff --git a/ios/kitsu_mobile/Images.xcassets/AppIcon.appiconset/Icon-87.png b/ios/kitsu_mobile/Images.xcassets/AppIcon.appiconset/Icon-87.png index 454a0a767..d92b4e8dc 100644 Binary files a/ios/kitsu_mobile/Images.xcassets/AppIcon.appiconset/Icon-87.png and b/ios/kitsu_mobile/Images.xcassets/AppIcon.appiconset/Icon-87.png differ diff --git a/src/routes/library.js b/src/routes/library.js index 0ee933969..1ead39ea2 100644 --- a/src/routes/library.js +++ b/src/routes/library.js @@ -4,7 +4,6 @@ import { StackNavigator } from 'react-navigation'; import library from 'kitsu/assets/img/tabbar_icons/library.png'; import { LibraryScreen } from 'kitsu/screens/Library/LibraryScreen'; import { navigationBarHeight, statusBarHeight } from 'kitsu/constants/app'; -import { LibrarySettings } from 'kitsu/screens/Library/LibrarySettings'; import navigationOptions from './navigationOptions'; import { commonRoutes } from './common'; @@ -12,9 +11,6 @@ const LibraryStack = StackNavigator({ LibraryScreen: { screen: LibraryScreen, }, - LibrarySettings: { - screen: LibrarySettings, - }, ...commonRoutes, }, { diff --git a/src/routes/sidebar.js b/src/routes/sidebar.js index f7d7602bf..8605dab12 100644 --- a/src/routes/sidebar.js +++ b/src/routes/sidebar.js @@ -3,7 +3,7 @@ import { SettingsScreen, GeneralSettings, PrivacySettings, - LibraryScreen, + LibrarySettings, Blocking, LinkedAccounts, ImportLibrary, @@ -23,7 +23,7 @@ export const sidebarRoutes = { screen: PrivacySettings, }, LibrarySettings: { - screen: LibraryScreen, + screen: LibrarySettings, }, Blocking: { screen: Blocking, diff --git a/src/screens/Auth/AuthScreen.js b/src/screens/Auth/AuthScreen.js index 218c04050..f34f841f8 100644 --- a/src/screens/Auth/AuthScreen.js +++ b/src/screens/Auth/AuthScreen.js @@ -22,6 +22,7 @@ import { createUser } from 'kitsu/store/user/actions'; import { TERMS_URL } from 'kitsu/constants/app'; import isEmpty from 'lodash/isEmpty'; import moment from 'moment'; +import { Sentry } from 'react-native-sentry'; import AuthWrapper from './AuthWrapper'; import styles from './styles'; @@ -109,6 +110,11 @@ class AuthScreen extends React.Component { } }, (error) => { + Sentry.captureMessage('FBSDK - Facebook Login Failed', { + extra: { + error, + }, + }); console.log(`Login fail with error: ${error}`); }, ); diff --git a/src/screens/Intro/RegistrationScreen.js b/src/screens/Intro/RegistrationScreen.js index db3e63154..99464520f 100644 --- a/src/screens/Intro/RegistrationScreen.js +++ b/src/screens/Intro/RegistrationScreen.js @@ -8,6 +8,7 @@ import { loginUser } from 'kitsu/store/auth/actions'; import * as colors from 'kitsu/constants/colors'; import { placeholderImage } from 'kitsu/assets/img/intro'; import { kitsuConfig } from 'kitsu/config/env'; +import { Sentry } from 'react-native-sentry'; import { IntroHeader } from './common/'; import styles from './styles'; @@ -77,6 +78,11 @@ class RegistrationScreen extends React.Component { }, (error) => { this.setState({ loggingUser: false }); + Sentry.captureMessage('FBSDK - Facebook Login Failed', { + extra: { + error, + }, + }); console.log(`Login fail with error: ${error}`); }, ); diff --git a/src/screens/Library/LibraryScreen/component.js b/src/screens/Library/LibraryScreen/component.js index 87547a89d..9701d4962 100644 --- a/src/screens/Library/LibraryScreen/component.js +++ b/src/screens/Library/LibraryScreen/component.js @@ -58,7 +58,9 @@ export class LibraryScreenComponent extends PureComponent { onOptionPress = () => { const { navigation } = this.props; if (navigation) { - navigation.navigate('LibrarySettings'); + navigation.navigate('LibrarySettings', { + navigateBackOnSave: true, + }); } } diff --git a/src/screens/Onboarding/Aozora/WelcomeScreen.js b/src/screens/Onboarding/Aozora/WelcomeScreen.js index a69e84671..7d2d29cdd 100644 --- a/src/screens/Onboarding/Aozora/WelcomeScreen.js +++ b/src/screens/Onboarding/Aozora/WelcomeScreen.js @@ -1,5 +1,5 @@ import React from 'react'; -import { View, Text, ImageBackground } from 'react-native'; +import { View, Text, ImageBackground, ScrollView } from 'react-native'; import FastImage from 'react-native-fast-image'; import { Button } from 'kitsu/components/Button'; import { NavigationActions } from 'react-navigation'; @@ -43,7 +43,10 @@ class WelcomeScreen extends React.Component { return ( - + {title} @@ -63,7 +66,7 @@ class WelcomeScreen extends React.Component { title={"Let's get started!"} titleStyle={commonStyles.buttonTitleStyle} /> - + ); } diff --git a/src/screens/Onboarding/common/RatingSystemScreen.js b/src/screens/Onboarding/common/RatingSystemScreen.js index 8c165b082..aba476241 100644 --- a/src/screens/Onboarding/common/RatingSystemScreen.js +++ b/src/screens/Onboarding/common/RatingSystemScreen.js @@ -1,5 +1,5 @@ import React from 'react'; -import { View, Text, TouchableOpacity } from 'react-native'; +import { View, Text, TouchableOpacity, ScrollView } from 'react-native'; import FastImage from 'react-native-fast-image'; import { connect } from 'react-redux'; import { upperFirst, toLower } from 'lodash'; @@ -91,7 +91,7 @@ class RatingSystemScreen extends React.Component { const { loading } = this.props; return ( - + How would you prefer to rate the things you’ve seen and read? @@ -118,7 +118,7 @@ class RatingSystemScreen extends React.Component { title={`Use ${upperFirst(toLower(ratingSystem))} Ratings`} titleStyle={styles.buttonTitleStyle} /> - + { - const mapper = { - romanized: 'Romanized', - canonical: 'Most Common Usage', - english: 'English', - }; - return mapper[key]; -}; - -const mediaPreferenceTitleToKey = (title) => { - switch (title) { - case 'Romanized': return 'romanized'; - case 'Most Common Usage': return 'canonical'; - case 'English': return 'english'; - default: return null; - } -}; - -class LibraryScreen extends React.Component { - static navigationOptions = ({ navigation }) => navigationOptions(navigation, 'Library'); - - // No mapping needed for Rating System, since API uses it as it is. - // We just need to translate Canonical to Most Common Usage. - state = { - modified: false, - titleLanguagePreference: mediaPreferenceKeyToTitle(this.props.titleLanguagePreference), - ratingSystem: this.props.ratingSystem, - }; - - titleLanguagePreference = ['Romanized', 'Most Common Usage', 'English', 'cancel']; - ratingSystem = ['simple', 'regular', 'advanced', 'cancel']; - - onUpdateLibrarySettings = () => { - const { titleLanguagePreference, ratingSystem } = this.state; - this.props.updateLibrarySettings({ - titleLanguagePreference: mediaPreferenceTitleToKey(titleLanguagePreference), - ratingSystem, - }); - }; - - render() { - const { navigation, loading } = this.props; - const { modified, titleLanguagePreference, ratingSystem } = this.state; - return ( - - - this.setState({ modified: true, titleLanguagePreference: t })} - cancelButtonIndex={this.titleLanguagePreference.length - 1} - options={this.titleLanguagePreference} - > - - - Title Display - - - { titleLanguagePreference } - - - - - this.setState({ modified: true, ratingSystem: t })} - cancelButtonIndex={this.ratingSystem.length - 1} - options={this.ratingSystem} - > - - - Rating Type - - - { startCase(ratingSystem) } - - - - - - item.title} - renderItem={({ item }) => ( - navigation.navigate(item.target)} - /> - )} - ItemSeparatorComponent={() => } - removeClippedSubviews={false} - scrollEnabled={false} - /> - - - - ); - } -} - -const mapStateToProps = ({ user }) => ({ - titleLanguagePreference: user.currentUser.titleLanguagePreference, - ratingSystem: user.currentUser.ratingSystem, - loading: user.loading, -}); - -LibraryScreen.propTypes = { - ratingSystem: PropTypes.string, - titleLanguagePreference: PropTypes.string, - updateLibrarySettings: PropTypes.func, - loading: PropTypes.bool, -}; - -LibraryScreen.defaultProps = { - ratingSystem: 'Simple', - titleLanguagePreference: 'Canonical', - updateLibrarySettings: null, - loading: false, -}; - -export default connect(mapStateToProps, { updateLibrarySettings })(LibraryScreen); diff --git a/src/screens/Library/LibrarySettings/component.js b/src/screens/Sidebar/Library/LibrarySettings/component.js similarity index 63% rename from src/screens/Library/LibrarySettings/component.js rename to src/screens/Sidebar/Library/LibrarySettings/component.js index 343fb522b..92b921b81 100644 --- a/src/screens/Library/LibrarySettings/component.js +++ b/src/screens/Sidebar/Library/LibrarySettings/component.js @@ -1,16 +1,34 @@ import React, { PureComponent } from 'react'; import { View, ScrollView, Text } from 'react-native'; import { PropTypes } from 'prop-types'; -import { CustomHeader } from 'kitsu/screens/Profiles/components/CustomHeader'; import Icon from 'react-native-vector-icons/Ionicons'; import { libraryImport, libraryExport } from 'kitsu/assets/img/sidebar_icons/'; -import { SidebarListItem } from 'kitsu/screens/Sidebar/common/'; import * as colors from 'kitsu/constants/colors'; import { SelectMenu } from 'kitsu/components/SelectMenu'; -import { capitalize } from 'lodash'; +import { capitalize, lowerCase, isEmpty } from 'lodash'; import { Kitsu } from 'kitsu/config/api'; +import { navigationOptions, SidebarListItem, SidebarTitle, SidebarButton } from 'kitsu/screens/Sidebar/common/'; import { styles } from './styles'; import { SORT_OPTIONS } from './sortOptions'; +import SidebarHeader from '../../common/SidebarHeader'; + +const mediaPreferenceKeyToTitle = (key) => { + const mapper = { + romanized: 'Romanized', + canonical: 'Most Common Usage', + english: 'English', + }; + return mapper[key] || '-'; +}; + +const mediaPreferenceTitleToKey = (title) => { + switch (title) { + case 'Romanized': return 'romanized'; + case 'Most Common Usage': return 'canonical'; + case 'English': return 'english'; + default: return null; + } +}; export class LibrarySettingsComponent extends PureComponent { static navigationOptions = () => ({ @@ -23,8 +41,13 @@ export class LibrarySettingsComponent extends PureComponent { navigation: PropTypes.object.isRequired, fetchUserLibrary: PropTypes.func.isRequired, setLibrarySort: PropTypes.func.isRequired, + navigateBackOnSave: PropTypes.bool, }; + static defaultProps = { + navigateBackOnSave: false, + } + constructor(props) { super(props); @@ -34,13 +57,21 @@ export class LibrarySettingsComponent extends PureComponent { sortBy: (sort && sort.by) || 'updated_at', ascending: !!(sort && sort.ascending), ratingSystem: (currentUser && currentUser.ratingSystem) || 'simple', + titleLanguagePreference: (currentUser && lowerCase(currentUser.titleLanguagePreference)) || 'canonical', saving: false, }; } save = async () => { - const { fetchUserLibrary, navigation, currentUser, setLibrarySort, fetchCurrentUser } = this.props; - const { sortBy, ascending, saving, ratingSystem } = this.state; + const { + fetchUserLibrary, + navigation, + currentUser, + setLibrarySort, + fetchCurrentUser, + navigateBackOnSave, + } = this.props; + const { sortBy, ascending, saving, ratingSystem, titleLanguagePreference } = this.state; // Only save if we're not already saving if (saving) return; @@ -50,31 +81,38 @@ export class LibrarySettingsComponent extends PureComponent { // Save the sort setLibrarySort(sortBy, ascending); - // Check if rating needs to be changed - if (currentUser && currentUser.ratingSystem !== ratingSystem) { - // Update the rating system - await Kitsu.update('users', { id: currentUser.id, ratingSystem }); + // See if any changes need to be made + if (currentUser) { + const changes = {}; - // Fetch the new user object - await fetchCurrentUser(); - } + // Rating + if (currentUser.ratingSystem !== ratingSystem) { + changes.ratingSystem = ratingSystem; + } - // Update the user library - if (currentUser) { + // Media title preferences + if (lowerCase(currentUser.titleLanguagePreference) !== titleLanguagePreference) { + changes.titleLanguagePreference = titleLanguagePreference; + } + + // Only update user if we have changes + if (!isEmpty(changes)) { + // Update the rating system + await Kitsu.update('users', { id: currentUser.id, ...changes }); + + // Fetch the new user object + await fetchCurrentUser(); + } + + // Update the user library fetchUserLibrary({ userId: currentUser.id, refresh: true }); } this.setState({ saving: false }); - if (navigation) navigation.goBack(); + if (navigation && navigateBackOnSave) navigation.goBack(); }; - goBack = () => { - if (!this.state.saving) { - this.props.navigation.goBack(); - } - } - librarySorting() { const { sortBy, ascending } = this.state; const filteredOption = SORT_OPTIONS.filter(e => e.key === sortBy); @@ -108,13 +146,26 @@ export class LibrarySettingsComponent extends PureComponent { } mediaPreferences() { - const { ratingSystem } = this.state; + const { ratingSystem, titleLanguagePreference } = this.state; return { heading: 'Media Preferences', rows: [ { - title: 'Rating System', + title: 'Title Display', + value: mediaPreferenceKeyToTitle(titleLanguagePreference), + options: ['Romanized', 'Most Common Usage', 'English', 'Nevermind'], + onOptionSelected: (value) => { + const newValue = mediaPreferenceTitleToKey(value); + if (newValue) { + this.setState({ + titleLanguagePreference: newValue, + }); + } + }, + }, + { + title: 'Rating Type', value: capitalize(ratingSystem), options: ['Simple', 'Regular', 'Advanced', 'Nevermind'], onOptionSelected: (value) => { @@ -147,6 +198,12 @@ export class LibrarySettingsComponent extends PureComponent { }; } + goBack = () => { + if (!this.state.saving) { + this.props.navigation.goBack(); + } + } + renderSideBarRow = (row) => { const { navigation } = this.props; return ( @@ -186,14 +243,15 @@ export class LibrarySettingsComponent extends PureComponent { renderSettings(settings) { return settings.map(setting => ( - - {setting.heading} + + {setting.rows.map(row => this.renderSettingRow(row))} )); } render() { + const { navigation } = this.props; const { saving } = this.state; const settings = [this.librarySorting(), this.mediaPreferences(), this.manageLibrary()]; @@ -201,16 +259,20 @@ export class LibrarySettingsComponent extends PureComponent { return ( - {this.renderSettings(settings)} + ); diff --git a/src/screens/Library/LibrarySettings/index.js b/src/screens/Sidebar/Library/LibrarySettings/index.js similarity index 70% rename from src/screens/Library/LibrarySettings/index.js rename to src/screens/Sidebar/Library/LibrarySettings/index.js index 8425427ea..81b0eb8fb 100644 --- a/src/screens/Library/LibrarySettings/index.js +++ b/src/screens/Sidebar/Library/LibrarySettings/index.js @@ -3,13 +3,16 @@ import { fetchUserLibrary, setLibrarySort } from 'kitsu/store/profile/actions'; import { fetchCurrentUser } from 'kitsu/store/user/actions'; import { LibrarySettingsComponent } from './component'; -const mapStateToProps = ({ user, profile }) => { +const mapStateToProps = ({ user, profile }, ownProps) => { const { currentUser } = user; const { librarySort: sort } = profile; + const navigateBackOnSave = (ownProps.navigation.state.params && + ownProps.navigation.state.params.navigateBackOnSave); return { currentUser, sort, + navigateBackOnSave, }; }; diff --git a/src/screens/Library/LibrarySettings/sortOptions.js b/src/screens/Sidebar/Library/LibrarySettings/sortOptions.js similarity index 100% rename from src/screens/Library/LibrarySettings/sortOptions.js rename to src/screens/Sidebar/Library/LibrarySettings/sortOptions.js diff --git a/src/screens/Library/LibrarySettings/styles.js b/src/screens/Sidebar/Library/LibrarySettings/styles.js similarity index 92% rename from src/screens/Library/LibrarySettings/styles.js rename to src/screens/Sidebar/Library/LibrarySettings/styles.js index c50afce80..0cb06583d 100644 --- a/src/screens/Library/LibrarySettings/styles.js +++ b/src/screens/Sidebar/Library/LibrarySettings/styles.js @@ -1,4 +1,4 @@ -import { StyleSheet } from 'react-native'; +import { StyleSheet, Platform } from 'react-native'; import * as colors from 'kitsu/constants/colors'; export const styles = StyleSheet.create({ @@ -7,6 +7,7 @@ export const styles = StyleSheet.create({ flex: 1, }, headerContainer: { + height: Platform.select({ ios: 77, android: 72 }), backgroundColor: colors.listBackPurple, shadowColor: 'rgba(0,0,0,0.2)', shadowOffset: { diff --git a/src/screens/Sidebar/Library/index.js b/src/screens/Sidebar/Library/index.js index ad8cd7b23..4a10a8a4a 100644 --- a/src/screens/Sidebar/Library/index.js +++ b/src/screens/Sidebar/Library/index.js @@ -1,11 +1,11 @@ import ImportDetail from './ImportDetail'; import ImportLibrary from './ImportLibrary'; import ExportLibrary from './ExportLibrary'; -import LibraryScreen from './LibraryScreen'; +import { LibrarySettings } from './LibrarySettings'; export { ImportDetail, ImportLibrary, ExportLibrary, - LibraryScreen, + LibrarySettings, }; diff --git a/src/screens/Sidebar/LinkedAccounts.js b/src/screens/Sidebar/LinkedAccounts.js index 818b9b2ad..2c11e5959 100644 --- a/src/screens/Sidebar/LinkedAccounts.js +++ b/src/screens/Sidebar/LinkedAccounts.js @@ -5,6 +5,7 @@ import { connect } from 'react-redux'; import { LoginManager } from 'react-native-fbsdk'; import * as colors from 'kitsu/constants/colors'; import fblogo from 'kitsu/assets/img/fblogo.png'; +import { Sentry } from 'react-native-sentry'; import { connectFBUser, disconnectFBUser } from 'kitsu/store/user/actions'; import { navigationOptions, SidebarTitle, ItemSeparator } from './common/'; import { styles } from './styles'; @@ -23,6 +24,11 @@ class LinkedAccounts extends React.Component { } }, (error) => { + Sentry.captureMessage('FBSDK - Facebook Login Failed', { + extra: { + error, + }, + }); console.log(`Login fail with error: ${error}`); }); } diff --git a/src/screens/Sidebar/common/SidebarHeader.js b/src/screens/Sidebar/common/SidebarHeader.js index 8a2beeb39..eb91e44df 100644 --- a/src/screens/Sidebar/common/SidebarHeader.js +++ b/src/screens/Sidebar/common/SidebarHeader.js @@ -9,37 +9,45 @@ import { isX, paddingX } from 'kitsu/utils/isX'; import PropTypes from 'prop-types'; import { getImgixCoverImage } from 'kitsu/utils/coverImage'; -const SidebarHeader = ({ navigation, headerTitle, coverImage }) => ( - - - - - navigation.goBack()}> - - +const SidebarHeader = ({ navigation, headerTitle, coverImage, onBackPress }) => { + const goBack = onBackPress || navigation.goBack; + return ( + + + + + goBack()} + > + + + + {headerTitle} + + + - {headerTitle} - - - - - - -); + + + ); +}; SidebarHeader.propTypes = { headerTitle: PropTypes.string.isRequired, navigation: PropTypes.object.isRequired, coverImage: PropTypes.object, + onBackPress: PropTypes.func, }; SidebarHeader.defaultProps = { headerTitle: 'Settings', coverImage: null, + onBackPress: null, }; const styles = { diff --git a/src/screens/Sidebar/index.js b/src/screens/Sidebar/index.js index bc7a29c0b..4f47ae200 100644 --- a/src/screens/Sidebar/index.js +++ b/src/screens/Sidebar/index.js @@ -1,6 +1,6 @@ import Blocking from './Blocking'; import GeneralSettings from './GeneralSettings'; -import { LibraryScreen, ExportLibrary, ImportLibrary, ImportDetail } from './Library'; +import { LibrarySettings, ExportLibrary, ImportLibrary, ImportDetail } from './Library'; import LinkedAccounts from './LinkedAccounts'; import PrivacySettings from './PrivacySettings'; import SettingsScreen from './SettingsScreen'; @@ -13,7 +13,7 @@ export { ImportDetail, ImportLibrary, ExportLibrary, - LibraryScreen, + LibrarySettings, LinkedAccounts, PrivacySettings, SettingsScreen, diff --git a/src/store/profile/actions.js b/src/store/profile/actions.js index dfe175766..a541ac211 100644 --- a/src/store/profile/actions.js +++ b/src/store/profile/actions.js @@ -1,9 +1,8 @@ -import capitalize from 'lodash/capitalize'; -import map from 'lodash/map'; +import { capitalize, map, lowerCase } from 'lodash'; import * as types from 'kitsu/store/types'; import { Kitsu } from 'kitsu/config/api'; import { KitsuLibrary, KitsuLibraryEventSource, KitsuLibrarySort } from 'kitsu/utils/kitsuLibrary'; -import { getState } from '../user/actions'; +import { getTitleField } from 'kitsu/utils/getTitleField'; export const fetchProfile = userId => async (dispatch) => { dispatch({ type: types.FETCH_USER }); @@ -116,10 +115,15 @@ const defaultFetchUserLibraryOptions = { * * @param {any} sort An object with the format { by: , ascending: } * @param {string} kind 'anime' or 'manga' + * @param {any} user The current user or null. * @returns The sort string. */ -function getSortString(sort, kind) { - const titleSort = `${kind}.titles.canonical`; +function getSortString(sort, kind, user) { + // Get the user preference + const preference = (user && lowerCase(user.titleLanguagePreference)); + const key = (preference && getTitleField(preference)) || 'canonical'; + + const titleSort = `${kind}.titles.${key}`; if (!sort || !sort.by) return titleSort; const ascending = sort.ascending ? '' : '-'; @@ -162,6 +166,7 @@ export const fetchUserLibraryByType = fetchOptions => async (dispatch, getState) }; const { userLibrary, librarySort } = getState().profile; + const { currentUser } = getState().user; let data = userLibrary[options.userId][options.library][options.status].data; @@ -186,7 +191,7 @@ export const fetchUserLibraryByType = fetchOptions => async (dispatch, getState) limit: options.limit, offset: options.refresh ? 0 : data.length, }, - sort: getSortString(librarySort, options.library), + sort: getSortString(librarySort, options.library, currentUser), }); if (options.refresh) { diff --git a/src/store/user/actions.js b/src/store/user/actions.js index 50d4d70cb..1d5616dcb 100644 --- a/src/store/user/actions.js +++ b/src/store/user/actions.js @@ -175,8 +175,10 @@ export const updateLibrarySettings = data => async (dispatch, getState) => { dispatch({ type: types.UPDATE_LIBRARY_SETTINGS }); const { user, auth } = getState(); const { id } = user.currentUser; - const token = auth.tokens.access_token; - setToken(token); + const token = auth.tokens && auth.tokens.access_token; + if (token) { + setToken(token); + } try { await Kitsu.update('users', { id, ...data }); dispatch({ type: types.UPDATE_LIBRARY_SETTINGS_SUCCESS, payload: data });