Merge branch 'fix-ordinal-suffix' into 'rebased-redesign'
Fix ordinal suffix for numbers greater than 10 See merge request bloodyhealth/drip!306
This commit is contained in:
@@ -1,32 +1,34 @@
|
|||||||
import React from 'react'
|
import React from 'react'
|
||||||
import PropTypes from 'prop-types'
|
import PropTypes from 'prop-types'
|
||||||
import { StyleSheet, View } from 'react-native'
|
import { StyleSheet, View } from 'react-native'
|
||||||
import { LocalDate } from 'js-joda'
|
|
||||||
import moment from 'moment'
|
import moment from 'moment'
|
||||||
|
|
||||||
import AppText from '../common/app-text'
|
import AppText from '../common/app-text'
|
||||||
|
|
||||||
import cycleModule from '../../lib/cycle'
|
import cycleModule from '../../lib/cycle'
|
||||||
import { dateEnding } from '../helpers/home'
|
import { getOrdinalSuffix } from '../helpers/home'
|
||||||
import { Containers, Typography } from '../../styles'
|
import { Containers, Typography } from '../../styles'
|
||||||
|
|
||||||
const CycleDayLabel = ({ height, date }) => {
|
const CycleDayLabel = ({ height, date }) => {
|
||||||
const dayDate = LocalDate.parse(date)
|
|
||||||
const cycleDayNumber = cycleModule().getCycleDayNumber(date)
|
const cycleDayNumber = cycleModule().getCycleDayNumber(date)
|
||||||
|
|
||||||
const isFirstDayOfMonth = dayDate.dayOfMonth() === 1
|
|
||||||
const dateFormatting = isFirstDayOfMonth ? 'MMM' : 'D'
|
|
||||||
const shortDate = moment(date, "YYYY-MM-DD").format(dateFormatting)
|
|
||||||
const ending = isFirstDayOfMonth ?
|
|
||||||
'' : dateEnding[this.cycleDayNumber] || dateEnding['default']
|
|
||||||
const cycleDayLabel = cycleDayNumber ? cycleDayNumber : ' '
|
const cycleDayLabel = cycleDayNumber ? cycleDayNumber : ' '
|
||||||
|
|
||||||
|
const momentDate = moment(date)
|
||||||
|
const dayOfMonth = momentDate.date()
|
||||||
|
const isFirstDayOfMonth = dayOfMonth === 1
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<View style={[styles.container, { height }]}>
|
<View style={[styles.container, { height }]}>
|
||||||
<AppText style={styles.textBold}>{cycleDayLabel}</AppText>
|
<AppText style={styles.textBold}>{cycleDayLabel}</AppText>
|
||||||
<View style={{flexDirection: 'row', justifyContent: 'space-around', alignItems: 'center'}}>
|
<View style={styles.dateLabel}>
|
||||||
<AppText style={styles.text}>{shortDate}</AppText>
|
<AppText style={styles.text}>
|
||||||
<AppText style={styles.textLight}>{ending}</AppText>
|
{isFirstDayOfMonth ? momentDate.format('MMM') : dayOfMonth}
|
||||||
|
</AppText>
|
||||||
|
{!isFirstDayOfMonth &&
|
||||||
|
<AppText style={styles.textLight}>
|
||||||
|
{getOrdinalSuffix(dayOfMonth)}
|
||||||
|
</AppText>
|
||||||
|
}
|
||||||
</View>
|
</View>
|
||||||
</View>
|
</View>
|
||||||
)
|
)
|
||||||
@@ -47,13 +49,19 @@ const styles = StyleSheet.create({
|
|||||||
...Containers.rowContainer
|
...Containers.rowContainer
|
||||||
},
|
},
|
||||||
text: {
|
text: {
|
||||||
...Typography.label
|
...Typography.label,
|
||||||
|
fontSize: 12
|
||||||
},
|
},
|
||||||
textBold: {
|
textBold: {
|
||||||
...Typography.labelBold
|
...Typography.labelBold
|
||||||
},
|
},
|
||||||
textLight: {
|
textLight: {
|
||||||
...Typography.labelLight
|
...Typography.labelLight,
|
||||||
|
},
|
||||||
|
dateLabel: {
|
||||||
|
flexDirection: 'row',
|
||||||
|
justifyContent: 'space-around',
|
||||||
|
alignItems: 'center',
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ function getTimes(prediction) {
|
|||||||
const predictedBleedingStart = LocalDate.parse(prediction[0][0])
|
const predictedBleedingStart = LocalDate.parse(prediction[0][0])
|
||||||
/* the range of predicted bleeding days can be either 3 or 5 */
|
/* the range of predicted bleeding days can be either 3 or 5 */
|
||||||
const predictedBleedingEnd =
|
const predictedBleedingEnd =
|
||||||
LocalDate.parse(prediction[0][ prediction[0].length - 1 ])
|
LocalDate.parse(prediction[0][prediction[0].length - 1])
|
||||||
const daysToEnd = todayDate.until(predictedBleedingEnd, ChronoUnit.DAYS)
|
const daysToEnd = todayDate.until(predictedBleedingEnd, ChronoUnit.DAYS)
|
||||||
return { todayDate, predictedBleedingStart, predictedBleedingEnd, daysToEnd }
|
return { todayDate, predictedBleedingStart, predictedBleedingEnd, daysToEnd }
|
||||||
}
|
}
|
||||||
@@ -63,9 +63,25 @@ export function getBleedingPredictionRange(prediction) {
|
|||||||
return (daysToEnd === 0 ? '0' : `0 - ${daysToEnd}`)
|
return (daysToEnd === 0 ? '0' : `0 - ${daysToEnd}`)
|
||||||
}
|
}
|
||||||
|
|
||||||
export const dateEnding = {
|
export function getOrdinalSuffix(num) {
|
||||||
'1': 'st',
|
const j = num % 10
|
||||||
'2': 'nd',
|
const k = num % 100
|
||||||
'3': 'rd',
|
|
||||||
'default': 'th'
|
if (j === 1 && k !== 11) {
|
||||||
|
return 'st'
|
||||||
|
}
|
||||||
|
|
||||||
|
if (j === 2 && k !== 12) {
|
||||||
|
return 'nd'
|
||||||
|
}
|
||||||
|
|
||||||
|
if (j === 3 && k !== 13) {
|
||||||
|
return 'rd'
|
||||||
|
}
|
||||||
|
|
||||||
|
return 'th'
|
||||||
|
}
|
||||||
|
|
||||||
|
export function formatWithOrdinalSuffix(num) {
|
||||||
|
return num + getOrdinalSuffix(num)
|
||||||
}
|
}
|
||||||
|
|||||||
+6
-7
@@ -13,7 +13,7 @@ import Button from './common/button'
|
|||||||
|
|
||||||
import cycleModule from '../lib/cycle'
|
import cycleModule from '../lib/cycle'
|
||||||
import { getFertilityStatusForDay } from '../lib/sympto-adapter'
|
import { getFertilityStatusForDay } from '../lib/sympto-adapter'
|
||||||
import { determinePredictionText, dateEnding } from './helpers/home'
|
import { determinePredictionText, formatWithOrdinalSuffix } from './helpers/home'
|
||||||
|
|
||||||
import { Colors, Fonts, Sizes, Spacing } from '../styles'
|
import { Colors, Fonts, Sizes, Spacing } from '../styles'
|
||||||
import { home as labels } from '../i18n/en/labels'
|
import { home as labels } from '../i18n/en/labels'
|
||||||
@@ -32,15 +32,14 @@ class Home extends Component {
|
|||||||
this.todayDateString = today.toString()
|
this.todayDateString = today.toString()
|
||||||
const { getCycleDayNumber, getPredictedMenses } = cycleModule()
|
const { getCycleDayNumber, getPredictedMenses } = cycleModule()
|
||||||
this.cycleDayNumber = getCycleDayNumber(this.todayDateString)
|
this.cycleDayNumber = getCycleDayNumber(this.todayDateString)
|
||||||
const {status, phase, statusText} =
|
const { status, phase, statusText } =
|
||||||
getFertilityStatusForDay(this.todayDateString)
|
getFertilityStatusForDay(this.todayDateString)
|
||||||
const prediction = getPredictedMenses()
|
const prediction = getPredictedMenses()
|
||||||
|
|
||||||
this.cycleDayText = !this.cycleDayNumber ? labels.cycleDayNotEnoughInfo
|
this.cycleDayText = !this.cycleDayNumber ? labels.cycleDayNotEnoughInfo
|
||||||
: `${this.cycleDayNumber}${dateEnding[this.cycleDayNumber] || dateEnding['default']}`
|
: formatWithOrdinalSuffix(this.cycleDayNumber)
|
||||||
this.phase = phase
|
this.phase = phase
|
||||||
this.phaseText = !phase ? statusText
|
this.phaseText = !phase ? statusText : formatWithOrdinalSuffix(phase)
|
||||||
: `${phase}${dateEnding[phase] || dateEnding['default']}`
|
|
||||||
this.prediction = determinePredictionText(prediction)
|
this.prediction = determinePredictionText(prediction)
|
||||||
this.status = status
|
this.status = status
|
||||||
this.statusText = statusText
|
this.statusText = statusText
|
||||||
@@ -149,13 +148,13 @@ const styles = StyleSheet.create({
|
|||||||
})
|
})
|
||||||
|
|
||||||
const mapStateToProps = (state) => {
|
const mapStateToProps = (state) => {
|
||||||
return({
|
return ({
|
||||||
date: getDate(state),
|
date: getDate(state),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
const mapDispatchToProps = (dispatch) => {
|
const mapDispatchToProps = (dispatch) => {
|
||||||
return({
|
return ({
|
||||||
navigate: (page) => dispatch(navigate(page)),
|
navigate: (page) => dispatch(navigate(page)),
|
||||||
setDate: (date) => dispatch(setDate(date)),
|
setDate: (date) => dispatch(setDate(date)),
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -0,0 +1,25 @@
|
|||||||
|
import { expect } from 'chai'
|
||||||
|
|
||||||
|
import {getOrdinalSuffix } from '../components/helpers/home'
|
||||||
|
|
||||||
|
describe('Home helper: getOrdinalSuffix', () => {
|
||||||
|
it('For 1, it returns suffix \'st\'', () => {
|
||||||
|
expect(getOrdinalSuffix(1)).to.eql('st')
|
||||||
|
})
|
||||||
|
|
||||||
|
it('For 2, it returns suffix \'nd\'', () => {
|
||||||
|
expect(getOrdinalSuffix(2)).to.eql('nd')
|
||||||
|
})
|
||||||
|
|
||||||
|
it('For 3, it returns suffix \'rd\'', () => {
|
||||||
|
expect(getOrdinalSuffix(3)).to.eql('rd')
|
||||||
|
})
|
||||||
|
|
||||||
|
it('For 11, it returns suffix \'th\'', () => {
|
||||||
|
expect(getOrdinalSuffix(11)).to.eql('th')
|
||||||
|
})
|
||||||
|
|
||||||
|
it('For 23, it returns suffix \'rd\'', () => {
|
||||||
|
expect(getOrdinalSuffix(23)).to.eql('rd')
|
||||||
|
})
|
||||||
|
})
|
||||||
Reference in New Issue
Block a user