Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

V2 posture monitor #359

Merged
merged 46 commits into from
Aug 26, 2017
Merged

V2 posture monitor #359

merged 46 commits into from
Aug 26, 2017

Conversation

miguelc1221
Copy link
Contributor

@miguelc1221 miguelc1221 commented Aug 22, 2017

Posture Monitor

I refactor the monitor to reflect the new design. The monitor scene currently doesn't have a title on the title bar. I am thinking we going to pass a title prop to the titlebar when navigating to the posture monitor? I used https://github.com/bgryszko/react-native-circular-progress for the arc of the monitor. Though I had to fork it and merge some PRs in order to get some functionality we needed, similar to how we did with the video-player. I also updated the react-native-slider, since it fixed an issue that we were manually fixing ourselves (thumb was not inline with the slider).

Make sure to add "react-addons-shallow-compare" to your dependencies. I wasn't sure if to add it to this PR

Testing

  • make sure your backbone is disconnected from any previous device and reroute your app to the postureCalibrate or postureMonitor scene. The time is all messed up because we are not passing in a session time yet.
  • make sure the rating (poor-good) change appropriately and that it vibrates when the rating is poor.

This change is Reviewable

@kevhuang
Copy link
Contributor

Reviewed 4 of 20 files at r1.
Review status: 4 of 20 files reviewed at latest revision, 4 unresolved discussions.


app/components/Button.js, line 55 at r1 (raw file):

    const defaultStyles = [buttonStyles, styles.defaultBtn];
    const defaultActive = [buttonStyles, styles.secondaryActive];
    const defaultTextActive = [styles._text, styles._secondaryTextStyles];

Rename those style properties so they're consistent with the variable names


app/components/posture/PostureMonitor.js, line 67 at r1 (raw file):

 */
const normalizeCurrentDistance = distance => {
  const newRange = -25 - 210;

How come this is -25?


app/components/posture/PostureMonitor.js, line 87 at r1 (raw file):

const normalizePostureThreshold = distance => {
  const newRange = 100 - 0;
  const normalizedDistance = (((distance - MIN_POSTURE_THRESHOLD) * newRange) / currentRange) + 0;

I assume the + 0 at the end is to indicate as part of the formula for normalizing the range, you have to add the min range value. To avoid confusion, perhaps make a reusable function for normalizing.

const normalizeValue = (value, min, max) => (((value - MIN_POSTURE_THRESHOLD) / currentRange) * (max - min)) + min;

app/components/posture/postureMonitor/CircularProgress.js, line 6 at r1 (raw file):

const { Surface, Shape, Path, Group } = ART;

export default class CircularProgress extends Component {

Can this be a stateless component instead of a full-blown React Component?


Comments from Reviewable

@miguelc1221
Copy link
Contributor Author

Reviewed 3 of 20 files at r1.
Review status: 6 of 20 files reviewed at latest revision, 4 unresolved discussions.


app/components/Button.js, line 55 at r1 (raw file):

Previously, kevhuang (Kevin Huang) wrote…

Rename those style properties so they're consistent with the variable names

Done.


app/components/posture/PostureMonitor.js, line 67 at r1 (raw file):

Previously, kevhuang (Kevin Huang) wrote…

How come this is -25?

  • 25 is same as 335deg but since we want to go counter clock wise, setting it to -25 and going up to 210 made it easier.

app/components/posture/postureMonitor/CircularProgress.js, line 6 at r1 (raw file):

Previously, kevhuang (Kevin Huang) wrote…

Can this be a stateless component instead of a full-blown React Component?

can't pass functional components to Animated.createAnimatedComponent
facebook/react-native#15019


Comments from Reviewable

@kevhuang
Copy link
Contributor

Reviewed 1 of 2 files at r2.
Review status: 5 of 20 files reviewed at latest revision, 3 unresolved discussions.


app/components/posture/PostureMonitor.js, line 67 at r1 (raw file):

Previously, miguelc1221 (Miguel Correa) wrote…
  • 25 is same as 335deg but since we want to go counter clock wise, setting it to -25 and going up to 210 made it easier.

But why is it -25 and not -30 like the comments and other lines?


app/components/posture/postureMonitor/CircularProgress.js, line 6 at r1 (raw file):

Previously, miguelc1221 (Miguel Correa) wrote…

can't pass functional components to Animated.createAnimatedComponent
facebook/react-native#15019

Thanks


Comments from Reviewable

@miguelc1221
Copy link
Contributor Author

Reviewed 16 of 20 files at r1, 2 of 2 files at r2.
Review status: all files reviewed at latest revision, 2 unresolved discussions.


app/components/posture/PostureMonitor.js, line 67 at r1 (raw file):

Previously, kevhuang (Kevin Huang) wrote…

But why is it -25 and not -30 like the comments and other lines?

ah my bad, didn't notice. yea it should be -30. Fixed


app/components/posture/PostureMonitor.js, line 87 at r1 (raw file):

Previously, kevhuang (Kevin Huang) wrote…

I assume the + 0 at the end is to indicate as part of the formula for normalizing the range, you have to add the min range value. To avoid confusion, perhaps make a reusable function for normalizing.

const normalizeValue = (value, min, max) => (((value - MIN_POSTURE_THRESHOLD) / currentRange) * (max - min)) + min;

Done.


Comments from Reviewable

@kevhuang
Copy link
Contributor

Reviewed 13 of 20 files at r1, 1 of 2 files at r2, 1 of 1 files at r3.
Review status: all files reviewed at latest revision, 21 unresolved discussions.


app/components/posture/PostureMonitor.js, line 76 at r3 (raw file):

 * @return {Number}          Distance value scaled in a range of -30-210
 */
const normalizeCurrentDistance = distance => {

Please rename to getPointerPosition


app/components/posture/PostureMonitor.js, line 92 at r3 (raw file):

 * @return {Number}          Distance value scaled in a range of 0-100
 */
const normalizePostureThreshold = distance => {

Please rename to getSlouchPosition


app/components/posture/PostureMonitor.js, line 94 at r3 (raw file):

const normalizePostureThreshold = distance => {
  const normalizedDistance = Math.floor(normalizeValue(distance, 0, 100));
  return 100 - normalizedDistance;

Can we just return Math.floor(normalizeValue(distance, 100, 0))?


app/components/posture/PostureMonitor.js, line 1104 at r3 (raw file):

    ) : (
      <View style={styles.container}>
        <BodyText size={1} style={styles._timer}>

Remove the size prop from all the BodyText components


app/components/posture/postureMonitor/Monitor.js, line 20 at r3 (raw file):

      width={applyWidthDifference(6)}
      fill={slouchPosition}
      tintColor={theme.primaryColor}

Set tension to 100 so it animates as fast as the slider when moving the slider quickly.


app/components/posture/postureMonitor/Monitor.js, line 27 at r3 (raw file):

        <View
          style={[
            { transform: [{ rotate: `${pointerPosition}deg` }] },

Swap the array members. We should use the convention of defining defaults (i.e., styles.pointerContainer) first followed by overrides or additional styles.


app/components/posture/postureMonitor/Monitor.js, line 44 at r3 (raw file):

              }
          </BodyText>
          <TouchableOpacity

Let's remove the recalibration button for now. We probably won't have the firmware updated in time to support this. Sorry.


app/styles/button.js, line 31 at r3 (raw file):

    width: applyWidthDifference(150),
    height: applyWidthDifference(50),
    borderRadius: 3,

Should we add buttonShadow for all button types? Take a look at PostureCalibrate when the countdown is running. The pause button isn't noticeable.


app/styles/monitorButton.js, line 19 at r3 (raw file):

    alignItems: 'center',
    justifyContent: 'center',
    borderRadius: 100,

applyWidthDiffernce(75 / 2)


app/styles/theme.js, line 25 at r3 (raw file):

const bannerColor = '#EEE';
const warningColor = '#D32F2F';
const greenColor = '#16d03d';

Use #4CAF50 (Material green 500)


app/styles/posture/postureMonitor.js, line 1 at r3 (raw file):

import { Platform } from 'react-native';

This is how it looks on my Pixel:

✂-1

The dots are mispositioned (see my comments about that) and the button text are not in view. For the button text to be in view, you may need to set the container's justifyContent to be space-between. Then you will probably need to remove or play around with the top/bottom margin settings between each of the components.


app/styles/posture/postureMonitor.js, line 6 at r3 (raw file):

const { applyWidthDifference, fixedResponsiveFontSize } = relativeDimensions;
const totalPointerLength = applyWidthDifference(88);

Since totalPointerLength is only being referenced for the pointerContainer, there's not much value to defining this constant. Instead, define a constant for the inner monitor container size.

const innerMonitorSize = applyWidthDifference(190);

app/styles/posture/postureMonitor.js, line 43 at r3 (raw file):

  },
  innerMonitorContainer: {
    height: applyWidthDifference(190),

innerMonitorSize


app/styles/posture/postureMonitor.js, line 44 at r3 (raw file):

  innerMonitorContainer: {
    height: applyWidthDifference(190),
    width: applyWidthDifference(190),

innerMonitorSize


app/styles/posture/postureMonitor.js, line 46 at r3 (raw file):

    width: applyWidthDifference(190),
    backgroundColor: 'white',
    borderRadius: 100,

innerMonitorSize / 2


app/styles/posture/postureMonitor.js, line 67 at r3 (raw file):

  },
  pointerContainer: {
    width: (totalPointerLength * 2) - applyWidthDifference(8),

innerMonitorSize - applyWidthDifference(20)


app/styles/posture/postureMonitor.js, line 72 at r3 (raw file):

    height: applyWidthDifference(5),
    width: applyWidthDifference(20),
    borderRadius: 20,

applyWidthDifference(20)


app/styles/posture/postureMonitor.js, line 78 at r3 (raw file):

    width: applyWidthDifference(15),
    height: applyWidthDifference(15),
    borderRadius: 100,

applyWidthDifference(15 / 2)

Apply to rightCircle as well


app/styles/posture/postureMonitor.js, line 80 at r3 (raw file):

    borderRadius: 100,
    position: 'absolute',
    ...Platform.select({

Try applying the following across both iOS and Android:

bottom: applyWidthDifference(40),
left: '25%',

app/styles/posture/postureMonitor.js, line 98 at r3 (raw file):

    borderRadius: 100,
    position: 'absolute',
    ...Platform.select({

Try applying the following across both iOS and Android:

bottom: applyWidthDifference(40),
right: '25%',

Comments from Reviewable

@miguelc1221
Copy link
Contributor Author

Review status: all files reviewed at latest revision, 21 unresolved discussions.


app/components/posture/PostureMonitor.js, line 94 at r3 (raw file):

Previously, kevhuang (Kevin Huang) wrote…

Can we just return Math.floor(normalizeValue(distance, 100, 0))?

yup


app/styles/button.js, line 31 at r3 (raw file):

Previously, kevhuang (Kevin Huang) wrote…

Should we add buttonShadow for all button types? Take a look at PostureCalibrate when the countdown is running. The pause button isn't noticeable.

sure


app/styles/posture/postureMonitor.js, line 80 at r3 (raw file):

Previously, kevhuang (Kevin Huang) wrote…

Try applying the following across both iOS and Android:

bottom: applyWidthDifference(40),
left: '25%',

40 and 25% didn't work for iphone 6 and 6+ and my android device. I used instead,

bottom: applyWidthDifference(44),
left: '24%',

app/styles/posture/postureMonitor.js, line 98 at r3 (raw file):

Previously, kevhuang (Kevin Huang) wrote…

Try applying the following across both iOS and Android:

bottom: applyWidthDifference(40),
right: '25%',

used 44 and 24%


Comments from Reviewable

@kevhuang
Copy link
Contributor

Reviewed 1 of 20 files at r1, 6 of 7 files at r4.
Review status: 19 of 20 files reviewed at latest revision, 9 unresolved discussions, some commit checks failed.


app/components/posture/PostureMonitor.js, line 1104 at r3 (raw file):

Previously, kevhuang (Kevin Huang) wrote…

Remove the size prop from all the BodyText components

There's another BodyText below with a size prop


app/styles/monitorButton.js, line 1 at r4 (raw file):

import { Platform } from 'react-native';

Please move this file under app/styles/posture


app/styles/monitorButton.js, line 8 at r4 (raw file):

export default EStyleSheet.create({
  btnContainer: {

btnContainer isn't used anywhere


app/styles/posture/postureMonitor.js, line 80 at r3 (raw file):

Previously, miguelc1221 (Miguel Correa) wrote…

40 and 25% didn't work for iphone 6 and 6+ and my android device. I used instead,

bottom: applyWidthDifference(44),
left: '24%',

Let's try to move away from the arbitrary percentages for left and right and try to use good 'ol trigonometry. Since we already know the size of the outer circle, we know its radius. And since we know the outer arc spans 30 degrees past 180 on each end, that leaves us with 60 degrees in each of the two lower quadrants.

Now that we have the radius (hypotenuse) and the angle (60 degrees), we can calculate the length of the side opposite of the angle. See http://www.mathportal.org/calculators/plane-geometry-calculators/right-triangle-calculator.php for an example.

Can you try the following for the two circles?

left: (Dimensions.get('window').width * 0.5) - (applyWidthDifference(220 / 2) * Math.sin((60 * Math.PI) / 180)) - applyWidthDifference(15 / 8) // left circle
right: (Dimensions.get('window').width * 0.5) - (applyWidthDifference(220 / 2) * Math.sin((60 * Math.PI) / 180)) - applyWidthDifference(15 / 8) // right circle

I'm not too sure about subtracting 1/8th of the circle's width (the 15 / 8 part) at the end. When I didn't subtract the 1/8th, there was a minor gap between the arc and the dot.


Comments from Reviewable

@kevhuang
Copy link
Contributor

Reviewed 1 of 7 files at r4.
Review status: all files reviewed at latest revision, 11 unresolved discussions, some commit checks failed.


app/styles/monitorButton.js, line 37 at r4 (raw file):

  btnText: {
    textAlign: 'center',
    marginTop: applyWidthDifference(14),

Would 8 be okay? 14 seems too far apart.


app/styles/monitorButton.js, line 38 at r4 (raw file):

    textAlign: 'center',
    marginTop: applyWidthDifference(14),
    fontSize: fixedResponsiveFontSize(14),

Let's remove this font size override and just use the default font size from SecondaryText


app/styles/posture/postureMonitor.js, line 114 at r4 (raw file):

  sliderTitle: {
    textAlign: 'center',
    marginBottom: applyWidthDifference(10),

Instead of applying these vertical margins, how about wrapping the MonitorSlider and SecondaryText components in PostureMonitor in a View and also removing the slider.height style?

<View>
  <MonitorSlider />
  <SecondaryText ...>SLOUCH DETECTION</SecondaryText>
</View>

Comments from Reviewable

@kevhuang
Copy link
Contributor

a discussion (no related file):
Please also resolve merge conflicts


Comments from Reviewable

@miguelc1221
Copy link
Contributor Author

Reviewed 6 of 7 files at r4.
Review status: all files reviewed at latest revision, 9 unresolved discussions, some commit checks failed.


app/styles/monitorButton.js, line 37 at r4 (raw file):

Previously, kevhuang (Kevin Huang) wrote…

Would 8 be okay? 14 seems too far apart.

sure looks fine to me


app/styles/posture/postureMonitor.js, line 80 at r3 (raw file):

Previously, kevhuang (Kevin Huang) wrote…

Let's try to move away from the arbitrary percentages for left and right and try to use good 'ol trigonometry. Since we already know the size of the outer circle, we know its radius. And since we know the outer arc spans 30 degrees past 180 on each end, that leaves us with 60 degrees in each of the two lower quadrants.

Now that we have the radius (hypotenuse) and the angle (60 degrees), we can calculate the length of the side opposite of the angle. See http://www.mathportal.org/calculators/plane-geometry-calculators/right-triangle-calculator.php for an example.

Can you try the following for the two circles?

left: (Dimensions.get('window').width * 0.5) - (applyWidthDifference(220 / 2) * Math.sin((60 * Math.PI) / 180)) - applyWidthDifference(15 / 8) // left circle
right: (Dimensions.get('window').width * 0.5) - (applyWidthDifference(220 / 2) * Math.sin((60 * Math.PI) / 180)) - applyWidthDifference(15 / 8) // right circle

I'm not too sure about subtracting 1/8th of the circle's width (the 15 / 8 part) at the end. When I didn't subtract the 1/8th, there was a minor gap between the arc and the dot.

damn, schooling me right now lol. The above code works fine on my end.


Comments from Reviewable

@kevhuang
Copy link
Contributor

Reviewed 1 of 21 files at r1, 10 of 13 files at r5.
Review status: all files reviewed at latest revision, 4 unresolved discussions.


app/styles/posture/postureMonitor.js, line 80 at r3 (raw file):

Previously, miguelc1221 (Miguel Correa) wrote…

damn, schooling me right now lol. The above code works fine on my end.

Nice! I'm glad that worked on your end too. I checked on an Android tablet, and it looks fine too.


Comments from Reviewable

@kevhuang kevhuang merged commit 80fd4b1 into v2 Aug 26, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants