I created a new app called IronTrack

IronTrack is my new mobile app for anyone who wants a simple, motivating way to plan gym sessions and track every workout. I built it to remove the friction between "I should train" and "I did train" by making plans easy to create and logging fast and reliable.## Why I built IronTrackI wanted one place to plan workouts, stick to them, and see progress without a dozen taps. IronTrack focuses on the essentials: smart plans, manual control, streaks, and precise tracking for every set.## Key features### AI plan generatorTell IronTrack your height, weight, age, and goal, and it builds a plan for you. This is great if you want a quick, reasonable starting point without spending hours researching routines.### Manual plan builderPrefer full control? Build a plan by hand. Add exercises, customize sets and reps, and tweak things anytime.### StreaksConsistency matters. IronTrack shows your streaks so you can keep the momentum and see your habits build over time.### Detailed workout trackingLog every workout with time, reps, weight, and exercise name. IronTrack keeps it clean and fast, so you can stay focused on training.## Screenshots Dashboard IronTrack Plans Tracking workout Exercise details Finish screen History screen AI plan builder Chinese version Workout history Exercise library## How to get started1. Create a plan with AI or build one manually. 2. Start your workout and log time, reps, and weight as you go. 3. Keep your streak alive and watch your history grow.## ShoutoutsBig thanks to Cloudflare, GitHub, and Neon for their generous free tiers. They made it much easier to ship IronTrack and keep costs low while I built and tested the app.If you want a clean, focused gym tracker that still feels smart, IronTrack is for you. I would love feedback and feature requests as I keep improving it.

Read More

Mendix: how to set entity association in Java Action

In Mendix, you can set an entity association in a microflow by simply set the association attribute of the entity. But how to do this in a Java Action?Let's say you have two entities, `EntityA` and `EntityB`, and EntityA has a one to many association with EntityB. The association attribute in EntityB is `EntityB_EntityA`. Well its quite straight forward.Here is the code snippet:```java import com.mendix.core.Core; import com.mendix.systemwideinterfaces.core.IContext; import com.mendix.systemwideinterfaces.core.IMendixObject; import com.mendix.systemwideinterfaces.core.IMendixObjectMember; import module.name.proxies.EntityA; import module.name.proxies.EntityB;//... your other action codeEntityB entityB = new EntityB(context); EntityA entityA = new EntityA(context); entityB.setEntityB_EntityA(entityA); // when everything is done, you might also want to commit it entityB.commit() ```

Read More

The differences between React.memo, useCallback and useMemo

In React, `React.memo`, `useCallback` and `useMemo` are three hooks that can help you optimize your React application. They are similar in some ways, but they are used for different purposes. In this article, I will explain the differences between them.## React.memo`React.memo` is a higher-order component that can be used to prevent unnecessary re-renders of a functional component. It is similar to `PureComponent` in class components. When you wrap a functional component with `React.memo`, React will only re-render the component if the props have changed.Here is an example:```javascript import React from 'react';const MyComponent = React.memo(({ name }) => { return {name}; }); ``` In the example above, `MyComponent` will only re-render if the `name` prop has changed.## useCallback`useCallback` is a hook that returns a memoized version of a callback function. It is useful when you need to pass a callback function to a child component, and you want to prevent the child component from re-rendering unnecessarily.Here is an example:```javascript import React, { useCallback } from 'react';const MyComponent = ({ onClick }) => { return Click me; };const ParentComponent = () => { const handleClick = useCallback(() => { console.log('Button clicked'); }, []); return ; }; ```In the example above, `MyComponent` will only re-render if the `onClick` prop has changed.## useMemo`useMemo` is a hook that returns a memoized value. It is useful when you need to calculate a value that is expensive to compute, and you want to prevent the value from being recalculated unnecessarily.Here is an example:```javascript import React, { useMemo } from 'react';const MyComponent = ({ a, b }) => { const result = useMemo(() => { return a + b; }, [a, b]); return {result}; }; ```In the example above, `result` will only be recalculated if the `a` or `b` props have changed.## Summary- `React.memo` is used to prevent unnecessary re-renders of a functional component. - `useCallback` is used to return a memoized version of a callback function. - `useMemo` is used to return a memoized value. - `useCallback` is actually a special case of `useMemo`, where the memoized value is a function.

Read More

How to shuffle an array

In a small talk, one of my friends asked me, without searching or using AI, can you figure out how to shuffle an array in JavaScript? Surprisingly, I couldn't answer him immediately. I was thinking about the `sort` method, but I couldn't remember the exact implementation, and I even thought about using timestamp as seed to generate a random number.After the talk, I figured out the answer in a very short time. Here is the code:```javascriptconst shuffle = (arr) => arr.sort(() => Math.random() - 0.5); ``` Fine, this code is written by AI and its so simple and obvious. And here is the code that I want to write:```javascript const shuffle = (arr) => { const len = arr.length; for (let i = 0; i { for (let i = arr.length - 1; i > 0; i--) { const randomIdx = Math.floor(Math.random() * (i + 1)); [arr[i], arr[randomIdx]] = [arr[randomIdx], arr[i]]; } return arr; } ```why it is more effective? Because - compare with using sort function, it only needs to iterate through the array once, while the sort method may iterate multiple times - compare with my implementation, mine always generates a random number which from 0 to the length of the array, while Fisher-Yates shuffle algorithm only generates a random number which from 0 to the current index of the array. - compare with my implementation, mine always swaps the element with itself, while Fisher-Yates shuffle algorithm only swaps the element with the element that has not been swapped.-EOF-

Read More

A Simple bash script to modify macOS DNS by detecting SSID

I believe most of us have different DNS settings for different networks. For example, in my case, I use Google's public DNS `8.8.8.8` and Cloudflare's `1.1.1.1` at home, but at work, I have to clearthe DNS reacord and let my Mac use the default DNS provided by the company.It's a bit annoying to change the DNS settings manually every time I switch networks. So I wrote a simple bash script to automatically change the DNS settings based on the SSID of the network I'm connected to.Here is the script:```bash #!/bin/bash # clear or set dns function set_or_clear_dns() { local current_ssid=$(networksetup -getairportnetwork en0 | cut -d ':' -f 2 | xargs) if [[ "$current_ssid" == "YOUR_COMPANY_WIFI_SSID" ]]; then # Clear DNS to Automatic (Empty) sudo networksetup -setdnsservers Wi-Fi empty else # Set DNS to 1.1.1.1 and 8.8.8.8 sudo networksetup -setdnsservers Wi-Fi 1.1.1.1 8.8.8.8 fi } set_or_clear_dns ```You can replace `YOUR_COMPANY_WIFI_SSID` with your company's Wi-Fi SSID. Ofcause, you can add more SSID conditions and DNS settings as needed. And in the code I just simply clear the DNS settings to automatic when connected to the company's Wi-Fi, you can also set it to other DNS servers, by replacing `empty` with the DNS servers you want to use.

Read More