ronantakizawa/codereview-bench huggingface dataset:
Repository: freeCodeCamp/freeCodeCamp
File: client/src/templates/Challenges/exam-download/show.tsx (TypeScript)

Code before:
import React, { useEffect, useState } from 'react';
import { graphql } from 'gatsby';
import Helmet from 'react-helmet';
import {
  Button,
  Callout,
  Dropdown,
  MenuItem,
  Spacer,
  Container,
  Row,
  Col
} from '@freecodecamp/ui';
import { Trans, useTranslation, withTranslation } from 'react-i18next';
import { createSelector } from 'reselect';
import { connect } from 'react-redux';
import Spinner from 'react-spinkit';

import LearnLayout from '../../../components/layouts/learn';
import ChallengeTitle from '../components/challenge-title';
import useDetectOS, { type UserOSState } from '../utils/use-detect-os';
import type {
  ChallengeNode,
  CompletedChallenge,
  User
} from '../../../redux/prop-types';
import {
  completedChallengesSelector,
  isSignedInSelector,
  userSelector
} from '../../../redux/selectors';
import { examAttempts } from '../../../utils/ajax';
import MissingPrerequisites from '../exam/components/missing-prerequisites';
import { isChallengeCompletedSelector } from '../redux/selectors';
import envData from '../../../../config/env.json';
import { Attempts } from './attempts';
import ExamTokenControls from './exam-token-controls';

import './show.css';
import { Link } from '../../../components/helpers';
import { SuperBlocks } from '@freecodecamp/shared/config/curriculum';


Review comment (suggestion):
```suggestion
```
I'd use a `Loader` for consistency.

Code after:
import React, { useEffect, useState } from 'react';
import { graphql } from 'gatsby';
import Helmet from 'react-helmet';
import {
  Button,
  Callout,
  Dropdown,
  MenuItem,
  Spacer,
  Container,
  Row,
  Col
} from '@freecodecamp/ui';
import { Trans, useTranslation, withTranslation } from 'react-i18next';
import { createSelector } from 'reselect';
import { connect } from 'react-redux';

import LearnLayout from '../../../components/layouts/learn';
import ChallengeTitle from '../components/challenge-title';
import useDetectOS, { type UserOSState } from '../utils/use-detect-os';
import type {
  ChallengeNode,
  CompletedChallenge,
  User
} from '../../../redux/prop-types';
import {
  completedChallengesSelector,
  isSignedInSelector,
  userSelector
} from '../../../redux/selectors';
import { examAttempts } from '../../../utils/ajax';
import MissingPrerequisites from '../exam/components/missing-prerequisites';
import { isChallengeCompletedSelector } from '../redux/selectors';
import envData from '../../../../config/env.json';
import { Attempts } from './attempts';
import ExamTokenControls from './exam-token-controls';

import './show.css';
import { Link, Loader } from '../../../components/helpers';
import { SuperBlocks } from '@freecodecamp/shared/config/curriculum';

const { deploymentEnv } = envData;
Repository: freeCodeCamp/freeCodeCamp
File: client/src/templates/Challenges/exam-download/show.tsx (TypeScript)

Code before:
      completedChallenges={completedChallenges}
      nodes={nodes}
      examSuperBlock={examSuperBlock}
    />
  );
}

interface ExamPrerequisitesProps {
  id: string;
  completedChallenges: CompletedChallenge[];
  nodes: ChallengeNode[];
  examSuperBlock: SuperBlocks;
}

function ExamPrerequisites({
  id,
  completedChallenges,
  nodes,
  examSuperBlock
}: ExamPrerequisitesProps) {
  const { t } = useTranslation();
  const getExamsQuery = examAttempts.useGetExamsQuery();
  const examIdsQuery = examAttempts.useGetExamIdsByChallengeIdQuery(id);

  if (getExamsQuery.isFetching || examIdsQuery.isFetching) {
    return <Spinner />;
  }

  if (getExamsQuery.isError || examIdsQuery.isError) {
    console.error(getExamsQuery.error);
    console.error(examIdsQuery.error);
    return null;
  }

  if (!getExamsQuery.isSuccess || !examIdsQuery.isSuccess) {
    return null;
  }

  const examId = examIdsQuery.data.at(0)?.examId;
  const exam = getExamsQuery.data.find(examItem => examItem.id === examId);

  if (!exam) {
    // This should never happen
    return null;
  }

  const unmetPrerequisites = exam.prerequisites.filter(
    prereq => !completedChallenges.some(challenge => challenge.id === prereq)
  );
  const challenges = nodes.filter(
    ({ challenge }) =>

Review comment (suggestion):
```suggestion
    return <Loader />;
```
Also, the page realigns a bit because `Loader`/`Spinkit` is bigger than the button.

Code after:
      challenges={challenges}
      examSuperBlock={examSuperBlock}
    />
  );
}

interface ExamPrerequisitesProps {
  id: string;
  completedChallenges: CompletedChallenge[];
  challenges: ChallengeNode['challenge'][];
  examSuperBlock: SuperBlocks;
}

function ExamPrerequisites({
  id,
  completedChallenges,
  challenges,
  examSuperBlock
}: ExamPrerequisitesProps) {
  const { t } = useTranslation();
  const getExamsQuery = examAttempts.useGetExamsQuery();
  const examIdsQuery = examAttempts.useGetExamIdsByChallengeIdQuery(id);

  if (getExamsQuery.isFetching || examIdsQuery.isFetching) {
    return <Loader />;
  }

  if (getExamsQuery.isError || examIdsQuery.isError) {
    console.error(getExamsQuery.error);
    console.error(examIdsQuery.error);
    return null;
  }

  if (!getExamsQuery.isSuccess || !examIdsQuery.isSuccess) {
    return null;
  }

  const examId = examIdsQuery.data.at(0)?.examId;
  const exam = getExamsQuery.data.find(examItem => examItem.id === examId);

  if (!exam) {
    // This should never happen
    return null;
  }

  const unmetPrerequisites = exam.prerequisites.filter(
    prereq => !completedChallenges.some(challenge => challenge.id === prereq)
  );
  const unmetChallenges = challenges.filter(
    challenge =>
      unmetPrerequisites?.includes(challenge.id) &&
Repository: freeCodeCamp/freeCodeCamp
File: client/src/templates/Challenges/exam-download/show.tsx (TypeScript)

Code before:
  );
}

interface ExamPrerequisitesProps {
  id: string;
  completedChallenges: CompletedChallenge[];
  nodes: ChallengeNode[];
  examSuperBlock: SuperBlocks;
}

function ExamPrerequisites({
  id,
  completedChallenges,
  nodes,
  examSuperBlock
}: ExamPrerequisitesProps) {
  const { t } = useTranslation();
  const getExamsQuery = examAttempts.useGetExamsQuery();
  const examIdsQuery = examAttempts.useGetExamIdsByChallengeIdQuery(id);

  if (getExamsQuery.isFetching || examIdsQuery.isFetching) {
    return <Spinner />;
  }

  if (getExamsQuery.isError || examIdsQuery.isError) {
    console.error(getExamsQuery.error);
    console.error(examIdsQuery.error);
    return null;
  }

  if (!getExamsQuery.isSuccess || !examIdsQuery.isSuccess) {
    return null;
  }

  const examId = examIdsQuery.data.at(0)?.examId;
  const exam = getExamsQuery.data.find(examItem => examItem.id === examId);

  if (!exam) {
    // This should never happen
    return null;
  }

  const unmetPrerequisites = exam.prerequisites.filter(
    prereq => !completedChallenges.some(challenge => challenge.id === prereq)
  );
  const challenges = nodes.filter(
    ({ challenge }) =>
      unmetPrerequisites?.includes(challenge.id) &&
      challenge.superBlock === examSuperBlock
  );
  const missingPrerequisites = challenges.map(({ challenge }) => {

Review comment (suggestion):
```suggestion
```
Unless the idea is to get users to report these errors as a kind of budget Sentry, I'd get rid of these. Ideally show a flash message, but that's not vital.

Code after:
}

interface ExamPrerequisitesProps {
  id: string;
  completedChallenges: CompletedChallenge[];
  challenges: ChallengeNode['challenge'][];
  examSuperBlock: SuperBlocks;
}

function ExamPrerequisites({
  id,
  completedChallenges,
  challenges,
  examSuperBlock
}: ExamPrerequisitesProps) {
  const { t } = useTranslation();
  const getExamsQuery = examAttempts.useGetExamsQuery();
  const examIdsQuery = examAttempts.useGetExamIdsByChallengeIdQuery(id);

  if (getExamsQuery.isFetching || examIdsQuery.isFetching) {
    return <Loader />;
  }

  if (getExamsQuery.isError || examIdsQuery.isError) {
    console.error(getExamsQuery.error);
    console.error(examIdsQuery.error);
    return null;
  }

  if (!getExamsQuery.isSuccess || !examIdsQuery.isSuccess) {
    return null;
  }

  const examId = examIdsQuery.data.at(0)?.examId;
  const exam = getExamsQuery.data.find(examItem => examItem.id === examId);

  if (!exam) {
    // This should never happen
    return null;
  }

  const unmetPrerequisites = exam.prerequisites.filter(
    prereq => !completedChallenges.some(challenge => challenge.id === prereq)
  );
  const unmetChallenges = challenges.filter(
    challenge =>
      unmetPrerequisites?.includes(challenge.id) &&
      challenge.superBlock === examSuperBlock
  );
  const missingPrerequisites = unmetChallenges.map(challenge => {
    return {
Repository: freeCodeCamp/freeCodeCamp
File: client/src/templates/Challenges/exam-download/show.tsx (TypeScript)

Code before:
        </p>
      </Callout>
    );
  }

  return (
    <ExamPrerequisites
      id={id}
      completedChallenges={completedChallenges}
      nodes={nodes}
      examSuperBlock={examSuperBlock}
    />
  );
}

interface ExamPrerequisitesProps {
  id: string;
  completedChallenges: CompletedChallenge[];
  nodes: ChallengeNode[];
  examSuperBlock: SuperBlocks;
}

function ExamPrerequisites({
  id,
  completedChallenges,
  nodes,
  examSuperBlock
}: ExamPrerequisitesProps) {
  const { t } = useTranslation();
  const getExamsQuery = examAttempts.useGetExamsQuery();
  const examIdsQuery = examAttempts.useGetExamIdsByChallengeIdQuery(id);

  if (getExamsQuery.isFetching || examIdsQuery.isFetching) {
    return <Spinner />;
  }

  if (getExamsQuery.isError || examIdsQuery.isError) {
    console.error(getExamsQuery.error);
    console.error(examIdsQuery.error);
    return null;
  }

  if (!getExamsQuery.isSuccess || !examIdsQuery.isSuccess) {
    return null;
  }

  const examId = examIdsQuery.data.at(0)?.examId;
  const exam = getExamsQuery.data.find(examItem => examItem.id === examId);

  if (!exam) {
    // This should never happen

Review comment (suggestion):
```suggestion
  allChallenges,
```
I would `nodes.map(({ challenge }) => challenge` and pass that around, since Node is a Gatsby concept that the components don't need to care about.

Code after:
      </Callout>
    );
  }

  return (
    <ExamPrerequisites
      id={id}
      completedChallenges={completedChallenges}
      challenges={challenges}
      examSuperBlock={examSuperBlock}
    />
  );
}

interface ExamPrerequisitesProps {
  id: string;
  completedChallenges: CompletedChallenge[];
  challenges: ChallengeNode['challenge'][];
  examSuperBlock: SuperBlocks;
}

function ExamPrerequisites({
  id,
  completedChallenges,
  challenges,
  examSuperBlock
}: ExamPrerequisitesProps) {
  const { t } = useTranslation();
  const getExamsQuery = examAttempts.useGetExamsQuery();
  const examIdsQuery = examAttempts.useGetExamIdsByChallengeIdQuery(id);

  if (getExamsQuery.isFetching || examIdsQuery.isFetching) {
    return <Loader />;
  }

  if (getExamsQuery.isError || examIdsQuery.isError) {
    console.error(getExamsQuery.error);
    console.error(examIdsQuery.error);
    return null;
  }

  if (!getExamsQuery.isSuccess || !examIdsQuery.isSuccess) {
    return null;
  }

  const examId = examIdsQuery.data.at(0)?.examId;
  const exam = getExamsQuery.data.find(examItem => examItem.id === examId);

  if (!exam) {
    // This should never happen
    return null;
Repository: freeCodeCamp/freeCodeCamp
File: client/src/components/Flash/index.tsx (TypeScript)

Code before:

type FlashProps = {
  flashMessage: FlashState['message'];
  removeFlashMessage: typeof removeFlashMessage;
};

function Flash({ flashMessage, removeFlashMessage }: FlashProps): JSX.Element {
  const { type, message, id, variables = {} } = flashMessage;
  const { t } = useTranslation();

  // Some APIs are returning 'error' as a flash type, and it needs to be mapped to 'danger'.
  // TODO: Standardize the value of `type`.
  // Tracking issue: https://github.com/freeCodeCamp/freeCodeCamp/issues/50184
  const flashStyle =
    type === 'error' ? 'danger' : (type as AlertProps['variant']);

  function handleClose() {
    removeFlashMessage();
  }

  return (
    <Alert
      key={id}
      variant={flashStyle}
      className='flash-container'
      data-playwright-test-label='flash-container'
    >
      <Container>
        <Row>
          <Col
            md={8}
            mdOffset={2}
            sm={10}
            smOffset={1}
            xs={12}
            className='flash-message'
            data-testid='flash-message'
          >
            {t(message, variables)}
            <CloseButton
              onClick={handleClose}
              label={t('buttons.close')}
              className='close'
            />
          </Col>
        </Row>
      </Container>
    </Alert>
  );
}


Review comment (suggestion):
```suggestion
      data-playwright-test-label='flash-message'
```

Code after:

type FlashProps = {
  flashMessage: FlashState['message'];
  removeFlashMessage: typeof removeFlashMessage;
};

function Flash({ flashMessage, removeFlashMessage }: FlashProps): JSX.Element {
  const { type, message, id, variables = {} } = flashMessage;
  const { t } = useTranslation();

  // Some APIs are returning 'error' as a flash type, and it needs to be mapped to 'danger'.
  // TODO: Standardize the value of `type`.
  // Tracking issue: https://github.com/freeCodeCamp/freeCodeCamp/issues/50184
  const flashStyle =
    type === 'error' ? 'danger' : (type as AlertProps['variant']);

  function handleClose() {
    removeFlashMessage();
  }

  return (
    <Alert
      key={id}
      variant={flashStyle}
      className='flash-container'
      data-playwright-test-label='flash-message'
    >
      <Container>
        <Row>
          <Col
            md={8}
            mdOffset={2}
            sm={10}
            smOffset={1}
            xs={12}
            className='flash-message'
            data-testid='flash-message-content'
          >
            {t(message, variables)}
            <CloseButton
              onClick={handleClose}
              label={t('buttons.close')}
              className='close'
            />
          </Col>
        </Row>
      </Container>
    </Alert>
  );
}
Repository: freeCodeCamp/freeCodeCamp
File: client/src/components/Flash/index.tsx (TypeScript)

Code before:
  // TODO: Standardize the value of `type`.
  // Tracking issue: https://github.com/freeCodeCamp/freeCodeCamp/issues/50184
  const flashStyle =
    type === 'error' ? 'danger' : (type as AlertProps['variant']);

  function handleClose() {
    removeFlashMessage();
  }

  return (
    <Alert
      key={id}
      variant={flashStyle}
      className='flash-container'
      data-playwright-test-label='flash-container'
    >
      <Container>
        <Row>
          <Col
            md={8}
            mdOffset={2}
            sm={10}
            smOffset={1}
            xs={12}
            className='flash-message'
            data-testid='flash-message'
          >
            {t(message, variables)}
            <CloseButton
              onClick={handleClose}
              label={t('buttons.close')}
              className='close'
            />
          </Col>
        </Row>
      </Container>
    </Alert>
  );
}

Flash.displayName = 'FlashMessages';

export default Flash;


Review comment (suggestion):
```suggestion
            data-testid='flash-message-content'
```

Code after:
  // TODO: Standardize the value of `type`.
  // Tracking issue: https://github.com/freeCodeCamp/freeCodeCamp/issues/50184
  const flashStyle =
    type === 'error' ? 'danger' : (type as AlertProps['variant']);

  function handleClose() {
    removeFlashMessage();
  }

  return (
    <Alert
      key={id}
      variant={flashStyle}
      className='flash-container'
      data-playwright-test-label='flash-message'
    >
      <Container>
        <Row>
          <Col
            md={8}
            mdOffset={2}
            sm={10}
            smOffset={1}
            xs={12}
            className='flash-message'
            data-testid='flash-message-content'
          >
            {t(message, variables)}
            <CloseButton
              onClick={handleClose}
              label={t('buttons.close')}
              className='close'
            />
          </Col>
        </Row>
      </Container>
    </Alert>
  );
}

Flash.displayName = 'FlashMessages';

export default Flash;
Repository: fyne-io/fyne
File: internal/driver/common/canvas.go (Go)

Code before:
}

// SetContentTreeAndFocusMgr sets content tree and focus manager.
//
// This function does not use the canvas lock.
func (c *Canvas) SetContentTreeAndFocusMgr(content fyne.CanvasObject) {
	c.contentTree = &renderCacheTree{root: &RenderCacheNode{obj: content}}
	var focused fyne.Focusable
	if c.contentFocusMgr != nil {
		focused = c.contentFocusMgr.Focused() // keep old focus if possible
	}
	c.contentFocusMgr = app.NewFocusManager(content)
	if focused != nil {
		c.contentFocusMgr.Focus(focused)
	}
}

// CheckDirtyAndClear returns true if the canvas is dirty and
// clears the dirty state atomically.
func (c *Canvas) CheckDirtyAndClear() bool {
	return atomic.SwapUint32(&c.dirty, 0) != 0
}

// SetDirty sets canvas dirty flag atomically.
func (c *Canvas) SetDirty() {
	atomic.AddUint32(&c.dirty, 1)
}

// SetMenuTreeAndFocusMgr sets menu tree and focus manager.
//
// This function does not use the canvas lock.
func (c *Canvas) SetMenuTreeAndFocusMgr(menu fyne.CanvasObject) {
	c.menuTree = &renderCacheTree{root: &RenderCacheNode{obj: menu}}
	if menu != nil {
		c.menuFocusMgr = app.NewFocusManager(menu)
	} else {
		c.menuFocusMgr = nil
	}
}

// SetMobileWindowHeadTree sets window head tree.
//
// This function does not use the canvas lock.
func (c *Canvas) SetMobileWindowHeadTree(head fyne.CanvasObject) {
	c.mWindowHeadTree = &renderCacheTree{root: &RenderCacheNode{obj: head}}
}

// SetPainter sets the canvas painter.
func (c *Canvas) SetPainter(p gl.Painter) {
	c.painter = p
}

Review comment (performance):
If we are serializing the refresh call, do we need a benchmark to indicate performance changes here?

Code after:
}

// Painter returns the canvas painter.
func (c *Canvas) Painter() gl.Painter {
	return c.painter
}

// Refresh refreshes a canvas object.
func (c *Canvas) Refresh(obj fyne.CanvasObject) {
	walkNeeded := false
	switch obj.(type) {
	case *fyne.Container:
		walkNeeded = true
	case fyne.Widget:
		walkNeeded = true
	}

	if walkNeeded {
		c.serializeRefresh.Lock()
		driver.WalkCompleteObjectTree(obj, func(co fyne.CanvasObject, p1, p2 fyne.Position, s fyne.Size) bool {
			if i, ok := co.(*canvas.Image); ok {
				i.Refresh()
			}
			return false
		}, nil)
		c.serializeRefresh.Unlock()
	}

	c.refreshQueue.In(obj)
	c.SetDirty()
}

// RemoveShortcut removes a shortcut from the canvas.
func (c *Canvas) RemoveShortcut(shortcut fyne.Shortcut) {
	c.shortcut.RemoveShortcut(shortcut)
}

// SetContentTreeAndFocusMgr sets content tree and focus manager.
//
// This function does not use the canvas lock.
func (c *Canvas) SetContentTreeAndFocusMgr(content fyne.CanvasObject) {
	c.contentTree = &renderCacheTree{root: &RenderCacheNode{obj: content}}
	var focused fyne.Focusable
	if c.contentFocusMgr != nil {
		focused = c.contentFocusMgr.Focused() // keep old focus if possible
	}
	c.contentFocusMgr = app.NewFocusManager(content)
	if focused != nil {
		c.contentFocusMgr.Focus(focused)
	}
}
Repository: fyne-io/fyne
File: internal/painter/image.go (Go)

Code before:
package painter

import (
	"image"
	_ "image/jpeg" // avoid users having to import when using image widget
	_ "image/png"  // avoid the same for PNG images

	"golang.org/x/image/draw"

	"fyne.io/fyne/v2"
	"fyne.io/fyne/v2/canvas"
)

// PaintImage renders a given fyne Image to a Go standard image
// If a fyne.Canvas is given and the image’s fill mode is “fill original” the image’s min size has
// to fit its original size. If it doesn’t, PaintImage does not paint the image but adjusts its min size.
// The image will then be painted on the next frame because of the min size change.
func PaintImage(img *canvas.Image, c fyne.Canvas, width, height int) image.Image {
	if img.Size().IsZero() && width != 0 && height != 0 { // if the image has not been realised for some reason, set it up
		img.Resize(fyne.NewSize(float32(width), float32(height)))
	}
	dst, err := paintImage(img, width, height)
	if err != nil {
		fyne.LogError("failed to paint image", err)
	}

	return dst
}

func paintImage(img *canvas.Image, width, height int) (dst image.Image, err error) {
	if width <= 0 || height <= 0 {
		return
	}

	dst = img.Image
	if dst == nil {
		dst = image.NewNRGBA(image.Rect(0, 0, width, height))
	}

	size := dst.Bounds().Size()
	if width != size.X || height != size.Y {
		dst = scaleImage(dst, width, height, img.ScaleMode)
	}
	return
}

Review comment (suggestion):
I have slight concern here. When using the software painter, this code path could be triggered which would then happen in the render thread. Is it possible to either make drawImage in the software painter call paintImage directly or pass an additional information that says "this is not in the render thread"/something along that line.

Code after:
package painter

import (
	"image"
	_ "image/jpeg" // avoid users having to import when using image widget
	_ "image/png"  // avoid the same for PNG images

	"golang.org/x/image/draw"

	"fyne.io/fyne/v2"
	"fyne.io/fyne/v2/canvas"
)

// PaintImage renders a given fyne Image to a Go standard image
// If a fyne.Canvas is given and the image’s fill mode is “fill original” the image’s min size has
// to fit its original size. If it doesn’t, PaintImage does not paint the image but adjusts its min size.
// The image will then be painted on the next frame because of the min size change.
func PaintImage(img *canvas.Image, c fyne.Canvas, width, height int) image.Image {
	if img.Size().IsZero() && c == nil { // an image without size or canvas won't get rendered unless we setup
		img.Resize(fyne.NewSize(float32(width), float32(height)))
	}
	dst, err := paintImage(img, width, height)
	if err != nil {
		fyne.LogError("failed to paint image", err)
	}

	return dst
}

func paintImage(img *canvas.Image, width, height int) (dst image.Image, err error) {
	if width <= 0 || height <= 0 {
		return
	}

	dst = img.Image
	if dst == nil {
		dst = image.NewNRGBA(image.Rect(0, 0, width, height))
	}

	size := dst.Bounds().Size()
	if width != size.X || height != size.Y {
		dst = scaleImage(dst, width, height, img.ScaleMode)
	}
	return
}