<commit_before>import React, { useCallback, useContext, useEffect, useState } from "react";

import Baskerville from "../components/Baskerville";
import Emoji from "../components/Emoji";
import Link from "../components/Link";

import Fraktio from "../components/Fraktio";
import {
  Cv,
  Email,
  GitHub,
  Linkedin,
  Npm,
  Portfolio,
  Telegram,
  Twitter
} from "../components/icons";

const staticMessages = [
  <p key="1">
    Hello there! <Emoji label="Smiling Face With Sunglasses">😎</Emoji>
  </p>,
  <p key="2">My name is <NAME></p>,
  <p key="3">
    I’m a UX <Baskerville>&</Baskerville> UI Designer
  </p>,
  <p key="4">But I also code ECMAscript and React!</p>,
  <p key="5">
    I work at <Fraktio />
  </p>,
  <p key="6">
    There I help people realise their ideas, design useful experiences and
    create beautiful interfaces and interactions.
  </p>,
  <p key="7">
    You should email me at{" "}
    <Link href="mailto:<EMAIL>">
      <Emoji label="Email">
        <Email />
      </Emoji>{" "}
      <EMAIL>
    </Link>{" "}
    or send a tweet to{" "}
    <Link href="https://twitter.com/iirojappinen">
      <Emoji label="Twitter">
        <Twitter />
      </Emoji>{" "}
      @iirojappinen
    </Link>
  </p>,
  <p key="8">
    I also have a{" "}
    <Link href="/cv/">
      <Emoji label="CV">
        <Cv />
      </Emoji>{" "}
      CV
    </Link>
    ,{" "}
    <Link href="/portfolio/">
      <Emoji label="Portfolio">
        <Portfolio />
      </Emoji>{" "}
      Portfolio
    </Link>{" "}
    and a{" "}
    <Link href="https://fi.linkedin.com/in/iiroj">
      <Emoji label="Linkedin">
        <Linkedin />
      </Emoji>{" "}
      LinkedIn
    </Link>{" "}
    profile.
  </p>,
  <p key="9">
    Check out my{" "}
    <Link href="https://github.com/iiroj">
      <Emoji label="GitHub">
        <GitHub />
      </Emoji>{" "}
      GitHub
    </Link>{" "}
    and{" "}
    <Link href="https://www.npmjs.com/~iiroj">
      <Emoji label="npmn">
        <Npm />
      </Emoji>{" "}
      npm
    </Link>{" "}
    for my open source work.
  </p>,
  <p key="10">
    Finally, feel free to send me anonymous{" "}
    <Emoji label="Telegram">
      <Telegram />
    </Emoji>{" "}
    feedback from below. Have a nice day!
  </p>
];

const sentFeedbackMessage = (
  <p key="replied">
    <Emoji label="Check Mark">✅</Emoji> Thanks for the feedback!
  </p>
);

const noScriptMessage = (
  <p key="noscript">
    <Emoji label="Warning">⚠️</Emoji> Uh-oh! It seems you don’t have Javascript
    enabled.
  </p>
);

const randomIntFromInterval = (min, max) =>
  Math.floor(Math.random() * (max - min + 1) + min);

const waitFor = ms => new Promise(resolve => setTimeout(resolve, ms));

function* messageGenerator(i = 0) {
  while (true) yield staticMessages[i++];
}

const generateMessage = messageGenerator();

const useChatService = () => {
  const [initialized, setInitialized] = useState(false);
  const [typing, setTyping] = useState(false);
  const [messages, setMessages] = useState([
    // Replace the last message on SSR, since it's about sending Feedback
    ...staticMessages.slice(0, staticMessages.length - 1),
    noScriptMessage
  ]);

  const getMessages = async () => {
    if (initialized) {
      await waitFor(1000);
      setTyping(messages.length < staticMessages.length);
    } else {
      setTyping(true);
      setInitialized(true);
    }

    await waitFor(randomIntFromInterval(20, 40) * 100);
    const message = generateMessage.next().value;
    setMessages(messages =>
      messages.length >= staticMessages.length
        ? messages
        : [...messages, message]
    );
    setTyping(false);
  };

  useEffect(() => {
    setMessages([]);
  }, []);

  useEffect(() => {
    getMessages();
  }, [messages.length]);

  const handleSkip = useCallback(() => {
    setMessages(staticMessages);
    setTyping(false);
  }, []);

  const handleSentFeedback = () => {
    setMessages(messages => [...messages, sentFeedbackMessage]);
  };

  return {
    handleSentFeedback,
    handleSkip,
    messages,
    ready: messages.length >= staticMessages.length,
    typing
  };
};

const ChatContext = React.createContext();

export const ChatProvider = ({ children }) => {
  const value = useChatService();<commit_msg>fix: use single state for typing and messages<commit_after>import React, { useCallback, useContext, useEffect, useState } from "react";

import Baskerville from "../components/Baskerville";
import Emoji from "../components/Emoji";
import Link from "../components/Link";

import Fraktio from "../components/Fraktio";
import {
  Cv,
  Email,
  GitHub,
  Linkedin,
  Npm,
  Portfolio,
  Telegram,
  Twitter
} from "../components/icons";

const staticMessages = [
  <p key="1">
    Hello there! <Emoji label="Smiling Face With Sunglasses">😎</Emoji>
  </p>,
  <p key="2">My name is <NAME></p>,
  <p key="3">
    I’m a UX <Baskerville>&</Baskerville> UI Designer
  </p>,
  <p key="4">But I also code ECMAscript and React!</p>,
  <p key="5">
    I work at <Fraktio />
  </p>,
  <p key="6">
    There I help people realise their ideas, design useful experiences and
    create beautiful interfaces and interactions.
  </p>,
  <p key="7">
    You should email me at{" "}
    <Link href="mailto:<EMAIL>">
      <Emoji label="Email">
        <Email />
      </Emoji>{" "}
      <EMAIL>
    </Link>{" "}
    or send a tweet to{" "}
    <Link href="https://twitter.com/iirojappinen">
      <Emoji label="Twitter">
        <Twitter />
      </Emoji>{" "}
      @iirojappinen
    </Link>
  </p>,
  <p key="8">
    I also have a{" "}
    <Link href="/cv/">
      <Emoji label="CV">
        <Cv />
      </Emoji>{" "}
      CV
    </Link>
    ,{" "}
    <Link href="/portfolio/">
      <Emoji label="Portfolio">
        <Portfolio />
      </Emoji>{" "}
      Portfolio
    </Link>{" "}
    and a{" "}
    <Link href="https://fi.linkedin.com/in/iiroj">
      <Emoji label="Linkedin">
        <Linkedin />
      </Emoji>{" "}
      LinkedIn
    </Link>{" "}
    profile.
  </p>,
  <p key="9">
    Check out my{" "}
    <Link href="https://github.com/iiroj">
      <Emoji label="GitHub">
        <GitHub />
      </Emoji>{" "}
      GitHub
    </Link>{" "}
    and{" "}
    <Link href="https://www.npmjs.com/~iiroj">
      <Emoji label="npmn">
        <Npm />
      </Emoji>{" "}
      npm
    </Link>{" "}
    for my open source work.
  </p>,
  <p key="10">
    Finally, feel free to send me anonymous{" "}
    <Emoji label="Telegram">
      <Telegram />
    </Emoji>{" "}
    feedback from below. Have a nice day!
  </p>
];

const sentFeedbackMessage = (
  <p key="replied">
    <Emoji label="Check Mark">✅</Emoji> Thanks for the feedback!
  </p>
);

const noScriptMessage = (
  <p key="noscript">
    <Emoji label="Warning">⚠️</Emoji> Uh-oh! It seems you don’t have Javascript
    enabled.
  </p>
);

const randomIntFromInterval = (min, max) =>
  Math.floor(Math.random() * (max - min + 1) + min);

const waitFor = ms => new Promise(resolve => setTimeout(resolve, ms));

function* messageGenerator(i = 0) {
  while (true) yield staticMessages[i++];
}

const generateMessage = messageGenerator();

const useChatService = () => {
  const [initialized, setInitialized] = useState(false);
  const [{ messages, typing }, setState] = useState({
    initialized: false,
    messages: [
      // Replace the last message on SSR, since it's about sending Feedback
      ...staticMessages.slice(0, staticMessages.length - 1),
      noScriptMessage
    ],
    typing: false
  });

  const getMessages = async () => {
    if (initialized) {
      await waitFor(1000);
    } else {
      setInitialized(true);
    }

    if (messages.length < staticMessages.length) {
      setState(state => ({ ...state, typing: true }));
      await waitFor(randomIntFromInterval(20, 40) * 100);
      const message = generateMessage.next().value;
      setState(state => ({
        ...state,
        messages:
          state.messages.length >= staticMessages.length
            ? state.messages
            : [...state.messages, message],
        typing: false
      }));
    }
  };

  useEffect(() => {
    setState(state => ({
      ...state,
      messages: [],
      typing: true
    }));
  }, []);

  useEffect(() => {
    getMessages();
  }, [messages.length]);

  const handleSkip = useCallback(() => {
    setState(state => ({
      ...state,
      messages: staticMessages,
      typing: false
    }));
  }, []);

  const handleSentFeedback = () => {
    setState(state => ({
      ...state,
      messages: [...state.messages, sentFeedbackMessage]
    }));
  };

  return {
    handleSentFeedback,
    handleSkip,
    messages,
    ready: messages.length >= staticMessages.length,
    typing
  };
};

const ChatContext = React.createContext();

export const ChatProvider = ({ children }) => {
  const value = useChatService();
{'fraction_non_alphanumeric': 0.17469811533686944, 'fraction_numerical': 0.005868412143098973, 'mean_word_length': 2.5676328502415457, 'pattern_counts': {'":': 0, '<': 153, '<?xml version=': 0, '>': 182, 'https://': 8, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '303926', 'n_tokens_mistral': 3001, 'n_tokens_neox': 3017, 'n_words': 721}