r/learnjavascript 4d ago

Third update for learning progress (learn typescript/javascript with me)

For the second update, you can go here: Second Progress Update

To repeat context, I began building my own politics learning app without vibecoding a month ago today, and I will post semi regularly with what I have learned, roadblocks and ideas.

I think this update marks the point were I have firmly exited the hell of being a new developer in any form (UI and backend) where you need to rely on assistance / tutorials etc.

Main things I have implemented (in order of interesting-ness) :
- Progress Bar which animates how far you are through the lesson widgets. Deceptively simple given the way my lesson runner works. Will explain code below.
- A much smoother animation and UI for my True / False card widget, including a second "explanation/feedback" card sliding in after confirmation. This bit involves some pretty fundamental UI design principles which I think can be cleanly illustrated here.
-Colour palette overhaul and addition of shadows to widgets to make things "pop out" of the screen more. This is a pretty simple way of improving the quality of your UI.

Firstly, the progress bar:

import { styles } from "@/content/theme";
import Animated, {
  useAnimatedStyle,
  withTiming,
} from "react-native-reanimated";

type ProgressMeterProps = {
  stepNumber: number;
  lessonLength: number;
};

const animationDuration = 600;

export default function ProgressMeter(props: ProgressMeterProps) {
  const valueAnimatingTo = ((props.stepNumber + 1) * 100) / props.lessonLength;
  const barWidthStyle = useAnimatedStyle(() => ({
    width: withTiming(`${valueAnimatingTo}%`, { duration: animationDuration }),
  }));
  return (
    <Animated.View style={styles.progressBarContainer}>
      <Animated.View style={[styles.progressBarCompletion, barWidthStyle]} />
    </Animated.View>
  );
}

This is the whole component file - if you want to see the call in my lesson runner or the styles referenced you can comment.

Essentially, all you need for a "progress bar" is the value you are trying to turn into the progress - here, it is how far through the lesson the user is, so we take the number of "steps" in the lesson as a ratio of the lesson length as input in the props. (look at the type defined)

Note we add 1 to the stepNumber as it is 0 indexed.

The animation itself is also quite simple. The withTiming function from the Reanimated library takes the value you are animating to reach, and you can set the duration you want this to take in milliseconds (here, 600). Thats it. It does all of the work in changing the width.

There is a dilemma over whether to adjust width or scaleX - in this case, width is clearly preferable. The reason why is slightly convoluted but I'm happy to clarify if anyone wants.

Then, we apply the animated style to my empty progress bar - and that's it.

Finally, the True/False UI overhaul, and what you can learn from it:
(I won't use code here as it isn't helpful to my point).
- The ways a card/element in anything you build can be interacted with should be obvious to any user in multiple ways.

My widget is simple. It has a card with a statement, and the card is swipeable right/left.

To SHOW this interactivity, the card oscillates side to side when idle, which signals "I can be moved", AND a small, sleek muted subtitle is included above saying "Swipe card or press buttons" - I also added buttons on the card which can be pressed and trigger the card to swipe away on its own. This is the key thing here; there are many reasons a swipe may be hard for the user:
- disability (e.g. only have 1 arm, broken wrist, etc.)
- may not immediately notice the swipeability
- phone screen cracked on one side
- just tired or can't be bothered then

Always remember, when developing, you are in an "ideal scenario". Everything is probably in optimum conditions for your app to work. You must consider that in many cases this will not be the case for users, so you should make adjustments that fit the style and serve as multi-purpose tools.

In this case, my "True" and "False" buttons do this multipurpose bit by ALSO adding as additional INDICATORS of which direction swipe gives true and which gives false.

Hopefully this helps, these posts personally help me to think through what I'm doing and maybe they can give you some tips.

1 Upvotes

0 comments sorted by