From 4d8419a6e0b4de2b0de57c0255a2a96fe91b8ab9 Mon Sep 17 00:00:00 2001 From: Grace Date: Sat, 30 May 2020 01:14:03 -0400 Subject: [PATCH 1/7] Redesign notifications modal --- app/screens/Headlines.js | 4 +- app/screens/Post.js | 2 +- app/screens/SettingsPage.js | 98 ++++++++++++++++++++----------------- 3 files changed, 55 insertions(+), 49 deletions(-) diff --git a/app/screens/Headlines.js b/app/screens/Headlines.js index bf2e6849..621422ef 100644 --- a/app/screens/Headlines.js +++ b/app/screens/Headlines.js @@ -144,10 +144,10 @@ export default (props) => { onCloseStart={() => StatusBar.setHidden(false)} > - {/* setModalVisible(!modalVisible)} - />*/} + />
this.toggleNotificationSetting(receiverGroup) } + onToggle={ () => {this.toggleNotificationSetting(receiverGroup); console.log(receiverGroup)} } /> } @@ -89,24 +106,25 @@ export default class SettingsPage extends Component { {/* Header */} Notifications How often do you want to hear from The Daily? - - - + + - - Breaking News - Important stories, as they happen + + Breaking News + Important stories, as they happen - - - + + - - Every day - Daily news roundup + + Every day + Daily news roundup - - - + + - - Every week - Weekend roundup + + Every week + Weekend roundup - @@ -175,22 +184,19 @@ export default class SettingsPage extends Component { {this.props.setModalVisible(!this.props.modalVisible); - }}> Close From f9499a3f8847a9a03b21b6329b1f88a4022738e8 Mon Sep 17 00:00:00 2001 From: Grace Date: Sat, 30 May 2020 01:27:06 -0400 Subject: [PATCH 2/7] Change ToggleSwitch to RN Switch --- app/screens/SettingsPage.js | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/app/screens/SettingsPage.js b/app/screens/SettingsPage.js index 43cd057d..065904d9 100644 --- a/app/screens/SettingsPage.js +++ b/app/screens/SettingsPage.js @@ -17,6 +17,7 @@ import { FlatList, TouchableOpacity, TouchableHighlight, + Switch, SectionList } from 'react-native'; import _ from 'lodash'; @@ -86,13 +87,19 @@ export default class SettingsPage extends Component { } ToggleSwitch = ({receiverGroup}) => { - return {this.toggleNotificationSetting(receiverGroup);} } + /> + + {/* {this.toggleNotificationSetting(receiverGroup); console.log(receiverGroup)} } - /> + />*/} } render() { From 0030bb542dc08b18d4eabc0257ac23bc7a33ea13 Mon Sep 17 00:00:00 2001 From: Grace Date: Sat, 30 May 2020 01:50:30 -0400 Subject: [PATCH 3/7] Increase settings header height --- app/HTML.js | 2 +- app/screens/SettingsPage.js | 5 +++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/app/HTML.js b/app/HTML.js index 78e057dc..8f52d0ca 100644 --- a/app/HTML.js +++ b/app/HTML.js @@ -33,7 +33,7 @@ const renderers = { else if (typeof htmlAttribs.class !== 'undefined' && htmlAttribs.class.includes("wp-block-embed__wrapper") && typeof passProps.rawChildren[0].attribs.title !== 'undefined' && passProps.rawChildren[0].attribs.title.includes("Spotify Embed")) { // hacky way of displaying Spotify players for podcasts let uri = passProps.rawChildren[0].attribs.src; return ( - + ) } else { diff --git a/app/screens/SettingsPage.js b/app/screens/SettingsPage.js index 065904d9..5aebdf09 100644 --- a/app/screens/SettingsPage.js +++ b/app/screens/SettingsPage.js @@ -35,7 +35,7 @@ var selectedCategory = STRINGS.FEATURED_HEADLINES; //The currently selected cate const styles = { listItem: { flex: 1, - maxHeight: 64, + maxHeight: 72, flexDirection: 'row', alignItems: 'center', borderBottomWidth: 1, @@ -91,6 +91,7 @@ export default class SettingsPage extends Component { value={this.state.isOn[receiverGroup]} ios_backgroundColor={COLORS.LIGHT_GRAY} onValueChange={ () => {this.toggleNotificationSetting(receiverGroup);} } + style={{ transform: [{ scaleX: .8 }, { scaleY: .8 }] }} /> {/* Date: Sat, 30 May 2020 02:07:17 -0400 Subject: [PATCH 4/7] Change header font to PT Serif --- app/screens/Headlines.js | 2 +- app/screens/styles/header.js | 2 +- app/screens/styles/headlines.js | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/app/screens/Headlines.js b/app/screens/Headlines.js index 621422ef..b302f4a7 100644 --- a/app/screens/Headlines.js +++ b/app/screens/Headlines.js @@ -97,7 +97,7 @@ export default (props) => { color: COLORS.BLACK, marginLeft: MARGINS.ARTICLE_SIDES }}> - Settings + Notification Settings diff --git a/app/screens/styles/header.js b/app/screens/styles/header.js index 60fd678b..5832ff56 100755 --- a/app/screens/styles/header.js +++ b/app/screens/styles/header.js @@ -28,7 +28,7 @@ const styles = StyleSheet.create({ }, wordsTitle: { color: COLORS.BLACK, - fontFamily: FONTS.OPEN_SANS_BOLD, + fontFamily: FONTS.PT_SERIF_BOLD, fontSize: FONT_SIZES.DEFAULT_SMALL_MEDIUM, textAlign: ALIGNMENTS.CENTER }, diff --git a/app/screens/styles/headlines.js b/app/screens/styles/headlines.js index c3ea26a1..b024689c 100755 --- a/app/screens/styles/headlines.js +++ b/app/screens/styles/headlines.js @@ -32,7 +32,7 @@ const styles= StyleSheet.create({ }, sideBarTitleText: { color: COLORS.BLACK, - fontFamily: FONTS.OPEN_SANS_BOLD, + fontFamily: FONTS.PT_SERIF_BOLD, fontSize: FONT_SIZES.DEFAULT_SMALL_MEDIUM, //textAlign: 'center', flex: 1, From de965aeee813e7af0c1fd39000aee90cdff45946 Mon Sep 17 00:00:00 2001 From: Grace Date: Thu, 4 Jun 2020 15:52:44 -0400 Subject: [PATCH 5/7] Add alert for push notifs, update version numbers --- app.json | 6 ++--- app/helper/PushNotification.js | 2 +- app/screens/FollowInfoStorage.js | 43 ++++++++++++++++++++++---------- app/screens/SettingsPage.js | 10 ++++---- 4 files changed, 39 insertions(+), 22 deletions(-) diff --git a/app.json b/app.json index c15f0bb4..2da1417b 100644 --- a/app.json +++ b/app.json @@ -4,7 +4,7 @@ "description": "The Stanford Daily Mobile App", "slug": "StanfordDaily", "privacy": "public", - "version": "1.3.2", + "version": "1.4.0", "platforms": [ "ios", "android" @@ -31,14 +31,14 @@ ], "ios": { "bundleIdentifier": "com.Stanford.Daily.App", - "buildNumber": "14", + "buildNumber": "15", "appStoreUrl": "https://itunes.apple.com/app/stanford-daily/id1341270063", "supportsTablet": true }, "android": { "package": "com.Stanford.Daily.App", "googleServicesFile": "./google-services.json", - "versionCode": 14, + "versionCode": 15, "playStoreUrl": "https://play.google.com/store/apps/details?id=com.Stanford.Daily.App", "permissions": [ "ACCESS_COARSE_LOCATION", diff --git a/app/helper/PushNotification.js b/app/helper/PushNotification.js index 46112df7..22c63105 100644 --- a/app/helper/PushNotification.js +++ b/app/helper/PushNotification.js @@ -7,7 +7,7 @@ export async function registerForPushNotificationsAsync() { Permissions.NOTIFICATIONS ); let finalStatus = existingStatus; - + // only ask if permissions have not already been determined, because // iOS won't necessarily prompt the user a second time. if (existingStatus !== 'granted') { diff --git a/app/screens/FollowInfoStorage.js b/app/screens/FollowInfoStorage.js index 97904cc0..785406af 100644 --- a/app/screens/FollowInfoStorage.js +++ b/app/screens/FollowInfoStorage.js @@ -1,8 +1,25 @@ -import {AsyncStorage} from "react-native" +import { AsyncStorage, Linking, Alert } from "react-native" import { STRINGS } from '../assets/constants.js' import { Notifications } from "expo"; +import * as Permissions from 'expo-permissions'; export async function getToken() { + const { status: existingStatus } = await Permissions.getAsync( + Permissions.NOTIFICATIONS + ); + // if push notifications aren't on, alert user and give them the option to turn them on + if (existingStatus !== 'granted') { // code adapted from https://stackoverflow.com/questions/59980039/permissions-askasync-not-working-as-expected + Alert.alert( + "Please turn on notifications for this app in settings", + "", + [ + { text: "Cancel" }, + { text: "Settings", onPress: () => Linking.openURL("app-settings:") }, + ], + { cancelable: false } + ); + } + let token = await Notifications.getExpoPushTokenAsync(); if (__DEV__) { console.log(token); @@ -34,7 +51,7 @@ export async function followCategory(category_id) { } export async function unfollowCategory(category_id) { - let categories_followed = await getCategoriesFollowed(); + let categories_followed = await getCategoriesFollowed(); var index = categories_followed.indexOf(category_id); if (index !== -1) categories_followed.splice(index, 1); // remove category_id from list await updateBackend(); @@ -42,14 +59,14 @@ export async function unfollowCategory(category_id) { } export async function followAuthor(author_id) { - let authors_followed = await getAuthorsFollowed(); + let authors_followed = await getAuthorsFollowed(); authors_followed.push(author_id); // add author_id to authors_followed await updateBackend(); return await AsyncStorage.setItem('authors_followed', JSON.stringify(authors_followed)); } export async function unfollowAuthor(author_id) { - let authors_followed = await getAuthorsFollowed(); + let authors_followed = await getAuthorsFollowed(); var index = authors_followed.indexOf(author_id); if (index !== -1) authors_followed.splice(index, 1); // remove author_id from list await updateBackend(); @@ -57,16 +74,16 @@ export async function unfollowAuthor(author_id) { } export async function followLocation(location_id) { - let locations_followed = await getLocationsFollowed(); - locations_followed.push(location_id); + let locations_followed = await getLocationsFollowed(); + locations_followed.push(location_id); await updateBackend(); return await AsyncStorage.setItem('locations_followed', JSON.stringify(locations_followed)); } export async function unfollowLocation(location_id) { - let locations_followed = await getLocationsFollowed(); + let locations_followed = await getLocationsFollowed(); var index = locations_followed.indexOf(location_id); - if (index !== -1) locations_followed.splice(index, 1); + if (index !== -1) locations_followed.splice(index, 1); await updateBackend(); return await AsyncStorage.setItem('locations_followed', JSON.stringify(locations_followed)); } @@ -93,14 +110,14 @@ export async function isFollowingLocation(location_id) { } export async function addNotificationSetting(notification_id) { - let notification_settings = await getNotificationSettings(); - notification_settings.push(notification_id); + let notification_settings = await getNotificationSettings(); + notification_settings.push(notification_id); await updateBackend(); return await AsyncStorage.setItem('notification_settings', JSON.stringify(notification_settings)); } export async function removeNotificationSetting(notification_id) { - let notification_settings = await getNotificationSettings(); + let notification_settings = await getNotificationSettings(); var index = notification_settings.indexOf(notification_id); if (index !== -1) notification_settings.splice(index, 1); // remove notification option from list await updateBackend(); @@ -118,8 +135,8 @@ async function updateBackend() { let response = await fetch(STRINGS.DAILY_URL + 'wp-json/tsd/v1/push-notification/users/' + await getToken(), { method: 'PUT', headers: { - Accept: 'application/json', - 'Content-Type': 'application/json', + Accept: 'application/json', + 'Content-Type': 'application/json', }, body: JSON.stringify({ subscribing: { diff --git a/app/screens/SettingsPage.js b/app/screens/SettingsPage.js index 5aebdf09..d23a0f39 100644 --- a/app/screens/SettingsPage.js +++ b/app/screens/SettingsPage.js @@ -87,20 +87,20 @@ export default class SettingsPage extends Component { } ToggleSwitch = ({receiverGroup}) => { - return {this.toggleNotificationSetting(receiverGroup);} } style={{ transform: [{ scaleX: .8 }, { scaleY: .8 }] }} /> - - {/* {this.toggleNotificationSetting(receiverGroup); console.log(receiverGroup)} } - />*/} + onToggle={ () => {this.toggleNotificationSetting(receiverGroup)} } + />*/} + } render() { From 691c548da94cbc53f7a5791ae06a72d58f2b0447 Mon Sep 17 00:00:00 2001 From: Grace Date: Fri, 12 Jun 2020 00:05:11 -0400 Subject: [PATCH 6/7] Keyboard hide bottom tab bar --- app/config/router.js | 3 ++- app/screens/FollowInfoStorage.js | 2 +- app/screens/SettingsPage.js | 2 +- 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/app/config/router.js b/app/config/router.js index e3e514a4..21553705 100644 --- a/app/config/router.js +++ b/app/config/router.js @@ -85,6 +85,7 @@ export const Tabs = createBottomTabNavigator({ inactiveTintColor: '#000000', inactiveBackgroundColor: 'white', activeBackgroundColor: 'white', + keyboardHidesTabBar: true, labelStyle: { fontFamily: "Open Sans", // FONTS.PT_SERIF marginBottom: labelBottomMargin @@ -98,7 +99,7 @@ export const Tabs = createBottomTabNavigator({ marginBottom: iphone_x ? -34 : 0 } }, - lazy: true + lazy: true, }); const Root = createStackNavigator({ diff --git a/app/screens/FollowInfoStorage.js b/app/screens/FollowInfoStorage.js index 785406af..958ba4d5 100644 --- a/app/screens/FollowInfoStorage.js +++ b/app/screens/FollowInfoStorage.js @@ -132,7 +132,7 @@ export async function isBeingNotified(notification_id) { } async function updateBackend() { - let response = await fetch(STRINGS.DAILY_URL + 'wp-json/tsd/v1/push-notification/users/' + await getToken(), { + let response = await fetch(STRINGS.DAILY_URL + 'wp-json/tsd/v1/push-notification/users/' + await getToken(), { // test notifications at "http://stanforddaily2.staging.wpengine.com/"" method: 'PUT', headers: { Accept: 'application/json', diff --git a/app/screens/SettingsPage.js b/app/screens/SettingsPage.js index d23a0f39..6a8f7263 100644 --- a/app/screens/SettingsPage.js +++ b/app/screens/SettingsPage.js @@ -90,7 +90,7 @@ export default class SettingsPage extends Component { return {this.toggleNotificationSetting(receiverGroup);} } + onValueChange={ () => {this.toggleNotificationSetting(receiverGroup)} } style={{ transform: [{ scaleX: .8 }, { scaleY: .8 }] }} /> {/* Date: Fri, 12 Jun 2020 01:08:50 -0400 Subject: [PATCH 7/7] Add loading indicator --- app/screens/Headlines.js | 7 +- app/screens/SettingsPage.js | 315 +++++++++++++++-------------- app/screens/styles/newsfeeditem.js | 1 + 3 files changed, 164 insertions(+), 159 deletions(-) diff --git a/app/screens/Headlines.js b/app/screens/Headlines.js index b302f4a7..adcf2bbf 100644 --- a/app/screens/Headlines.js +++ b/app/screens/Headlines.js @@ -127,8 +127,9 @@ export default (props) => { const {posts} = await getCategoryAsync([category.slug], pageNumber); setArticles(posts); } + setRefreshing(false); })(); - }, [pageNumber, category]); + }, [pageNumber, category, refreshing]); return ( { ref={listRef} removeClippedSubviews={false} disableVirtualization={true} - // refreshing={refreshing} + refreshing={refreshing} keyExtractor={item => `list-key-${item.id}`} - // onRefresh={() => setRefreshing(true)} + onRefresh={() => setRefreshing(true)} // onEndReached={() => setPageNumber(pageNumber + 1)} sections={[{ data: articles, key: `category-list-${pageNumber}-${category}` }]} renderItem={_renderRow} diff --git a/app/screens/SettingsPage.js b/app/screens/SettingsPage.js index 6a8f7263..36f8f3d0 100644 --- a/app/screens/SettingsPage.js +++ b/app/screens/SettingsPage.js @@ -4,21 +4,21 @@ import { Ionicons } from '@expo/vector-icons'; import Modal from "react-native-modal" import ToggleSwitch from 'toggle-switch-react-native' import { - Alert, - Image, - Platform, - View, - Text, - Dimensions, - RefreshControl, - StatusBar, - ActivityIndicator, - NetInfo, - FlatList, - TouchableOpacity, - TouchableHighlight, - Switch, - SectionList + Alert, + Image, + Platform, + View, + Text, + Dimensions, + RefreshControl, + StatusBar, + ActivityIndicator, + NetInfo, + FlatList, + TouchableOpacity, + TouchableHighlight, + Switch, + SectionList } from 'react-native'; import _ from 'lodash'; @@ -28,187 +28,190 @@ import { isBeingNotified, addNotificationSetting, removeNotificationSetting } fr const amplitude = Amplitude.initialize(KEYS.AMPLITUDE_API); //A map between categories names and their codes -const {width, height} = Dimensions.get('window'); +const { width, height } = Dimensions.get('window'); var selectedCategory = STRINGS.FEATURED_HEADLINES; //The currently selected category const styles = { - listItem: { - flex: 1, - maxHeight: 72, - flexDirection: 'row', + listItem: { + flex: 1, + maxHeight: 72, + flexDirection: 'row', alignItems: 'center', - borderBottomWidth: 1, + borderBottomWidth: 1, borderBottomColor: COLORS.LIGHT_GRAY }, notifHeader: { - fontSize: FONT_SIZES.DEFAULT_MEDIUM, + fontSize: FONT_SIZES.DEFAULT_MEDIUM, fontFamily: FONTS.OPEN_SANS_BOLD }, notifText: { - fontSize: 13, + fontSize: 13, fontFamily: FONTS.OPEN_SANS } } export default class SettingsPage extends Component { - constructor(props) { - super(props); - this.state = { - isOn: { - [PN_RECEIVER_GROUPS.BREAKING]: false, - [PN_RECEIVER_GROUPS.DAILY]: false, - [PN_RECEIVER_GROUPS.WEEKLY]: false - } - }; - } - - async componentDidMount() { - this.updateNotificationSettings(); - } + constructor(props) { + super(props); + this.state = { + isOn: { + [PN_RECEIVER_GROUPS.BREAKING]: false, + [PN_RECEIVER_GROUPS.DAILY]: false, + [PN_RECEIVER_GROUPS.WEEKLY]: false + } + }; + } - async updateNotificationSettings() { - this.setState({ - isOn: { - [PN_RECEIVER_GROUPS.BREAKING]: await isBeingNotified(PN_RECEIVER_GROUPS.BREAKING), - [PN_RECEIVER_GROUPS.DAILY]: await isBeingNotified(PN_RECEIVER_GROUPS.DAILY), - [PN_RECEIVER_GROUPS.WEEKLY]: await isBeingNotified(PN_RECEIVER_GROUPS.WEEKLY) - } - }); - } + async componentDidMount() { + this.updateNotificationSettings(); + } - async toggleNotificationSetting(name) { - if (this.state.isOn[name]) { - await removeNotificationSetting(name); - } - else { - await addNotificationSetting(name); + async updateNotificationSettings() { + this.setState({ + isOn: { + [PN_RECEIVER_GROUPS.BREAKING]: await isBeingNotified(PN_RECEIVER_GROUPS.BREAKING), + [PN_RECEIVER_GROUPS.DAILY]: await isBeingNotified(PN_RECEIVER_GROUPS.DAILY), + [PN_RECEIVER_GROUPS.WEEKLY]: await isBeingNotified(PN_RECEIVER_GROUPS.WEEKLY) } - await this.updateNotificationSettings(); + }); + } + + async toggleNotificationSetting(name) { + if (this.state.isOn[name]) { + await removeNotificationSetting(name); } + else { + await addNotificationSetting(name); + } + await this.updateNotificationSettings(); + } - ToggleSwitch = ({receiverGroup}) => { - return {this.toggleNotificationSetting(receiverGroup)} } - style={{ transform: [{ scaleX: .8 }, { scaleY: .8 }] }} - /> - {/* { + return { this.toggleNotificationSetting(receiverGroup) }} + style={{ transform: [{ scaleX: .8 }, { scaleY: .8 }] }} + /> + {/* {this.toggleNotificationSetting(receiverGroup)} } />*/} - - } - - render() { - return ( - - - {/* Header */} - - - Notifications - - How often do you want to hear from The Daily? - - - - - - - + } - - Breaking News - Important stories, as they happen - + render() { + return ( + + + {/* Header */} + + + Notifications + + How often do you want to hear from The Daily? + + + + + + + + - - - + + Breaking News + Important stories, as they happen - - - - + + + + - - Every day - Daily news roundup - + + + + - - - + + Every day + Daily news roundup - - - - + + + + - - Every week - Weekend roundup - + + + + - - - + + Every week + Weekend roundup + + + + - - {this.props.setModalVisible(!this.props.modalVisible); - }}> - Close - - - - ) - } + + + { + this.props.setModalVisible(!this.props.modalVisible); + }}> + Close + + + + ) + } } diff --git a/app/screens/styles/newsfeeditem.js b/app/screens/styles/newsfeeditem.js index 4ab17b64..54c58542 100755 --- a/app/screens/styles/newsfeeditem.js +++ b/app/screens/styles/newsfeeditem.js @@ -12,6 +12,7 @@ const styles = ({ }, dateAndAuthor: { flexDirection: ALIGNMENTS.ROW, + flexWrap: 'wrap', justifyContent: ALIGNMENTS.SPACE_BETWEEN, marginTop: MARGINS.DEFAULT_MARGIN, marginHorizontal: MARGINS.ARTICLE_SIDES,