benjstorlie / sudoku-shuffle

Play sudoku
https://mighty-ridge-19238-3e456d2c37f3.herokuapp.com/
MIT License
0 stars 0 forks source link

Message Box Component for Errors or other messages to player #32

Open benjstorlie opened 1 year ago

benjstorlie commented 1 year ago

This is how Sudoku Slam does its error messages, without obstructing the screen or anything.

I was writing the autoSolve function and it makes the most sense to do it where it throws an Error if it finds a cell with no candidates (which means the user has a mistake somewhere). And have most of it in a try-catch block. In Sudoku Slam, their Messages box would flash and show "Autofill has detected an incorrect solution; stopping."

But there are many other reasons to have errors or messages to users. Maybe there's a setting where it doesn't allow you enter a digit if there's already that same digit in the row, col, or box. You could have both digits show up red, which is what Cracking the Cryptic does. Or, you could actually not allow a digit to be entered there, and instead have the message box flash "There's already a 2 in this row, so it can't go here", like Sudoku Slam does.

But maybe there's benign messages to show too.

benjstorlie commented 1 year ago

So, you can add to GameContext.js

const [ message, setMessage ] = useState('');

To eliminate the need to setMessage('') at the beginning of every move, just in case there used to be an error, do useEffect to remove the error if the user clicks or types anywhere, or add conditions to make it more specific. The flashing can be done with css.

import React, { useState, useEffect } from 'react';
import { gameContext } from '../../utils/GameContext';

export default function MessageBox() {
  const { message, setMessage } = useGameContext();
  const [showMessage, setShowMessage] = useState(false);

  useEffect(() => {
    if (message) {
      setShowMessage(true);

      // Event listener to clear message when the mouse is clicked
      const handleClick = () => {
        setMessage('');
        setShowMessage(false);
      };

      // Event listener to clear message when a key is pressed
      const handleKeyPress = (event) => {
        if (event.key === 'Enter' || event.key === 'Escape') {
          setMessage('');
          setShowMessage(false);
        }
      };

      window.addEventListener('click', handleClick);
      window.addEventListener('keydown', handleKeyPress);

      return () => {
        window.removeEventListener('click', handleClick);
        window.removeEventListener('keydown', handleKeyPress);
      };
    }
  }, [message setMessage]);

  return (
    <div className={`message-box ${showMessage ? 'show' : 'hide'}`}>
      {message}
    </div>
  );
}