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

Convert tournament from useRef to useState #2577

Merged

Conversation

dexonsmith
Copy link
Contributor

In the Tournament component, convert from a ref:

const tournament_ref = useRef<TournamentInterface>(...);

to a state:

const tournament = useState<TournamentInterface>(...);

This enabled the following additional changes:

  • Remove refresh().
  • Removing redundant state, switching to useMemo for sorted_players and
    raw_rounds and local variables for others.
  • Reset non-tournament state when tournament_id changes.

Depends on #2575 (builds on top of it). The diff here will be hard to read until that lands.

In the Tournament component, convert from a ref:

    const tournament_ref = useRef<TournamentInterface>(...);

to a state:

    const tournament = useState<TournamentInterface>(...);

This enabled the following additional changes:

- Remove `refresh()`.
- Removing redundant state, switching to `useMemo` for `sorted_players` and
  `raw_rounds` and local variables for others.
- Reset non-tournament state when `tournament_id` changes.

Depends on online-go#2575 (builds on top of it).
Copy link

github-actions bot commented Feb 11, 2024

Uffizzi Preview deployment-46324 was deleted.

@dexonsmith
Copy link
Contributor Author

Depends on #2575 (builds on top of it). The diff here will be hard to read until that lands.

Here's a link to incremental diff with just the changes from this PR: dexonsmith/online-go.com@fix-elimination-graph-to-update-on-changes...dexonsmith:online-go.com:convert-tournament-from-useref-to-usestate.

I think the riskiest part of this is that all the editing things had to change to call setTournament instead of modifying tournament_ref.current directly. This was tedious and I could have made a mistake. But, I manually tested all the variations of the inputs I could think of and everything still seems to function.

As partial motivation, here are screenshots of how it used to work.

  1. If you're in edit mode on a not-yet-started tournament and navigate to one that's completed using OGS search like this:
Image 4
  1. You used to wind up in edit mode for the completed tournament:
Image 5

...

But now, you just see the tournament.

Copy link
Contributor

@benjaminpjones benjaminpjones left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I really like the changes in this PR - reactive state is a lot easier to process. Moving some functions out of the giant Tournament component looks good too.

I tested on this tournament - it's the one that would reveal any performance issues, and AFAICT everything still works as intended.

refresh();
return t;
});
void get(`tournaments/${tournament_id}`)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What's the purpose of void before the promises?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Relic. I think I was trying to satisfy the type checker (or something) I didn't understand why it was complaining. The problem was that I had not yet added .catch(...).

Cleaned up in af4783d.

const [sorted_players, setSortedPlayers] = React.useState<any[]>([]);
const [players, setPlayers] = React.useState<{ [id: string]: TournamentPlayer }>({});
const [is_joined, setIsJoined] = React.useState(false);
const [clicked_round_idx, setClickedRoundIdx] = React.useState<
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm having trouble understanding the name change here. The term "Selected" is input-independent, whereas "clicked" refers to an input (replaced by touches or taps on mobile).

Further down, I see:

    const setSelectedRound = (idx: number | "standings" | "roster") => {
        setClickedRoundIdx(idx);
    };

Which makes me think this should still be called "selected". And then maybe use "validated"/"sanitized" to distinguish the one down here.

Copy link
Contributor Author

@dexonsmith dexonsmith Feb 11, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Okay. This one's a bit weird, I admit, and there's a behaviour change (which I think is mostly good, but maybe it's debatable).

Previously there was selected_round_idx as state and a forwarding function that was used for setting it:

const [selected_round_idx, setSelectedRoundIdx] = React.useState(...);
const setSelectedRound = (idx: number) => setSelectedRoundIdx(idx);

(I left behind this forwarding function, it just points to setClickedRoundIdx now. Maybe shouldn't have?)

The reason I've added an extra layer, "clicked", is to distinguish between:

  • "is this selected because the user clicked on it?"
  • "is this selected because we don't have any rounds loaded yet?"

Say a user opens a tournament that's currently in round 2 of 5. Here is the behaviour we we'll get right now:

  1. User opens the tournament. No rounds are displayed (but selected_round_idx will be 0).
  2. Once the rounds load, round 2 (active round) is selected automatically.
  3. Round 2 finishes and round 3 starts. User automatically switched to round 3 (not having made a manual selection by clicking).
  4. User clicks on round 1, which selects round 1.
  5. Round 3 finishes and round 4 starts. User still has round 1 selected (having clicked on it).
  6. User clicks on round 4, which selects round 4.
  7. Round 4 finishes and round 5 starts. User still has round 4 selected (having clicked on it).
  8. User switches to a different tournament that's in round 1 via OGS search navigation. User gets reverted to (1).

Comments:

  • (2) is important. It used to be accomplished by calling setSelectedRoundIdx any time rounds were loaded. Now the "default" round selection is just part of the assignment of selected_round_idx, and loading rounds doesn't change the state of what the user clicked on.
  • (3) is a behaviour I'm not sure if we want, but it's not a change. Comes naturally from (2). ("User can follow along a tournament as it's going")
  • (5) is new behaviour. I think we want it. Accomplished by having clicked_round_idx start out as null (did they pick this round? or are they just following along?).
  • (7) is new behaviour. Maybe we don't want it. Maybe, instead, if they manually click on the active round, we should revert back to (3) by something like:
    const setSelectedRound = (idx: number) => {
        setClickedRoundIdx(idx == default_round_idx ? null : idx);
    };
    

WDYT? Given that walkthrough, any other thoughts on naming? Should we change (7)? (Would this be clearer/easier to follow if we introduced a default_round_idx computed value?)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Made some changes: af4783d...856dd68. I think the code is more clear now, and it takes the change I suggested in my comment about (7) above.

Let me know what you think!

Copy link
Contributor

@benjaminpjones benjaminpjones Feb 11, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh cool, thanks for the detailed explanation!

I think the behavior you specified sounds reasonable, and "explicitly selected" is a good name for that variable according to this description 🙂

Remove `void`s from promises.  These were a relic from before I'd added the
`.catch(...)` and I didn't understand why the type-checker was mad.
When a user selects an earlier round, it seems rude to force them forward
if/when a new round comes in.  But if they later click on the currently active
round, revert them back to following along, so they don't get "stuck".
@dexonsmith
Copy link
Contributor Author

The same incremental diff should still work, since I merged from the branch for #2575. Here's the link again in case it's helpful: fix-elimination-graph-to-update-on-changes...convert-tournament-from-useref-to-usestate.

@anoek
Copy link
Member

anoek commented Feb 12, 2024

Awesome, thanks!

@anoek anoek closed this Feb 12, 2024
@anoek anoek reopened this Feb 12, 2024
@anoek anoek merged commit e851a3a into online-go:devel Feb 12, 2024
10 checks passed
@dexonsmith dexonsmith deleted the convert-tournament-from-useref-to-usestate branch February 12, 2024 16:33
Copy link

sentry-io bot commented Feb 13, 2024

Suspect Issues

This pull request was deployed and Sentry observed the following issues:

  • ‼️ TypeError: Cannot read properties of undefined (reading 'groupify') linkPlayersToRoundMatches(src/views/Tournament/... View Issue
  • ‼️ TypeError: Cannot read properties of undefined (reading 'id') groupify(src/views/Tournament/Tournament) View Issue
  • ‼️ TypeError: undefined is not an object (evaluating 'a.groupify') linkPlayersToRoundMatches(src/views/Tournament/... View Issue
  • ‼️ TypeError: undefined is not an object (evaluating 'u[e].player.id') groupify(src/views/Tournament/Tournament) View Issue

Did you find this useful? React with a 👍 or 👎

@dexonsmith
Copy link
Contributor Author

Suspect Issues

This pull request was deployed and Sentry observed the following issues:

  • ‼️ TypeError: Cannot read properties of undefined (reading 'groupify') linkPlayersToRoundMatches(src/views/Tournament/... View Issue
  • ‼️ TypeError: Cannot read properties of undefined (reading 'id') groupify(src/views/Tournament/Tournament) View Issue

Did you find this useful? React with a 👍 or 👎

@anoek, not sure what to do with this one; I don't have access to the target of the "View Issue" links.

dexonsmith added a commit to dexonsmith/online-go.com that referenced this pull request Feb 13, 2024
Fix [sentry
issues](online-go#2577 (comment))
by delaying computation of rounds until everything is loaded.
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.

3 participants