ChatCraft week 14: Releasing v2.0!
Tags: chatcraft, opensource, typescript, react
Published: 2024-04-19 22:05:57

---
series: Collaborating on ChatCraft
---

Today marks the final day on the open source team working on [ChatCraft](https://chatcraft.org)! It's been an eventful week as everyone scrambles to polish up their feature code with final bug fixes.

# Meeting with Taras

This week we met with Taras, the founder of [ChatCraft](https://chatcraft.org) online to showcase our contributions and get some professional advice from him. It was very rewarding to see what we managed to get done in the span of four months with our small team of six!

Some of our notable features include but are not limited to:

- Image reading and image generation
- Custom provider support
- Text to Speech
- Google OAuth support
- Mobile support

# Coding

This week, I focused my attention on bug fixes since this is the last week and I didn't want to risk introducing any new issues. The [issue](https://github.com/tarasglek/chatcraft.org/issues/345) I worked on was something brought up to me by Rachit in the previous week - we don't want to save an api key into localStorage unless it has been validated.

It was not a problem previously to save invalid api keys, but now it has become a problem since we can now toggle between Providers by using the up arrow next to the "Ask" button:

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/p1t99p7jkmeujj91sgr3.png)

When you press the up arrow, as you can see in the screenshot above, you get to toggle between all the providers you have saved keys for. This includes any custom providers you have added! However we don't want to show any provider with an invalid key in this list, since even if a user selects it they won't be able to use it. (They will get error when they try to send a message)

To fix this issue I opened the following PR:

{% github https://github.com/tarasglek/chatcraft.org/pull/597 %}

I am no longer automatically updating localStorage when the user enters a key; instead, I store the key in the `tableProviders` array. Only when the key has been validated I will store it to `settings.providers` (localStorage). And if a key is invalid or blank, I will remove it from localStorage.

```

  const handleApiKeyChange = async (provider: ChatCraftProvider, apiKey: string) => {
    const newProvider = providerFromUrl(
      provider.apiUrl,
      apiKey,
      provider.name,
      provider.defaultModel
    );

    setFocusedProvider(newProvider);

    const newProviders = { ...settings.providers };

    // Update api key in table
    tableProviders[newProvider.name] = newProvider;

    // Api key validation
    try {
      setIsApiKeyInvalid(false);
      setIsValidating(true);

      const result = await newProvider.validateApiKey(newProvider.apiKey!);

      setIsApiKeyInvalid(!result);
      setIsValidating(false);

      if (result) {
        // Valid key, update in settings.providers
        newProviders[newProvider.name] = newProvider;
      } else {
        // Invalid key, remove from settings.providers
        delete newProviders[newProvider.name];
      }
    } catch (err: any) {
      setIsApiKeyInvalid(true);
      setIsValidating(false);

      // Invalid key, remove from settings.providers
      delete newProviders[newProvider.name];
    }

    setSettings({
      ...settings,
      ...(newProvider.name === settings.currentProvider.name && { currentProvider: newProvider }),
      providers: newProviders,
    });

    if (newProvider.name === selectedProvider?.name) {
      setSelectedProvider(newProvider);
    }

    setApiKeySaved(true);
  };
```

# Sheriff

This week I am the sheriff, meaning I am the go-to contact person whenever there is any issues with PRs blocked or needed reviews. As I result I reviewed 5 PRs this week! I also contributed code to [one PR](https://github.com/tarasglek/chatcraft.org/pull/600).

See all the PR's in this week's [2.0 release](https://github.com/tarasglek/chatcraft.org/releases/tag/v2.0.0)!