Repository: TabbyML/tabby
File: clients/vscode/src/chat/ChatViewProvider.ts (TypeScript)

Code before:
      this.client?.showError({ content: error });
      return;
    }

    this.pendingRelevantContexts.forEach((ctx) => this.addRelevantContext(ctx));
    this.pendingMessages.forEach((message) => this.sendMessageToChatPanel(message));
    if (serverInfo.config.token) {
      this.client?.cleanError();
      // Duplicate init won't break or reload the current chat page
      const focusKey = contributes.keybindings.find((cmd) => cmd.command === "tabby.chatView.focus");
      let focusKeybinding;
      if (focusKey) {
        focusKeybinding = parseKeybinding(this.isMac && focusKey.mac ? focusKey.mac : focusKey.key);
      }
      getLogger().info("focus key binding: ", focusKeybinding);
      this.client?.init({
        fetcherOptions: {
          authorization: serverInfo.config.token,
        },
        focusKey: focusKeybinding
          ? focusKeybinding
          : {
              key: "l",
              altKey: false,
              metaKey: true,
              ctrlKey: true,
              shiftKey: false,
            },
      });
    }
  }

  private async displayChatPage(endpoint: string, opts?: { force: boolean }) {
    if (!endpoint) return;
    if (this.isChatPageDisplayed && !opts?.force) return;

    if (this.webview) {
      this.isChatPageDisplayed = true;
      const styleUri = this.webview?.webview.asWebviewUri(
        Uri.joinPath(this.context.extensionUri, "assets", "chat-panel.css"),
      );

      const logoUri = this.webview?.webview.asWebviewUri(
        Uri.joinPath(this.context.extensionUri, "assets", "tabby.png"),
      );

      this.webview.webview.html = `
        <!DOCTYPE html>
        <html lang="en">
          <!--hash: ${hashObject({ renderDate: new Date().toString() })}-->
          <head>

Review comment (suggestion):
```suggestion
              metaKey: isMac,
              ctrlKey: !isMac,
```

Code after:
    if (error) {
      this.client?.showError({ content: error });
      return;
    }

    this.pendingRelevantContexts.forEach((ctx) => this.addRelevantContext(ctx));
    this.pendingMessages.forEach((message) => this.sendMessageToChatPanel(message));

    if (serverInfo.config.token) {
      this.client?.cleanError();

      const focusKeybinding = await this.getFocusKeybinding();
      getLogger().info("focus key binding: ", focusKeybinding);

      this.client?.init({
        fetcherOptions: {
          authorization: serverInfo.config.token,
        },
        focusKey: focusKeybinding,
      });
    }
  }

  private async getFocusKeybinding(): Promise<FocusKeybinding | undefined> {
    const focusCommand = "tabby.chatView.focus";
    const defaultFocusKey = contributes.keybindings.find((cmd) => cmd.command === focusCommand);
    const defaultKeybinding = defaultFocusKey
      ? parseKeybinding(this.isMac && defaultFocusKey.mac ? defaultFocusKey.mac : defaultFocusKey.key)
      : undefined;

    const allKeybindings = await readUserKeybindingsConfig();
    const userShortcut = allKeybindings?.find((keybinding) => keybinding.command === focusCommand);

    return userShortcut ? parseKeybinding(userShortcut.key) : defaultKeybinding;
  }

  private async displayChatPage(endpoint: string, opts?: { force: boolean }) {
    if (!endpoint) return;
    if (this.isChatPageDisplayed && !opts?.force) return;

    if (this.webview) {
      this.isChatPageDisplayed = true;
      const styleUri = this.webview?.webview.asWebviewUri(
        Uri.joinPath(this.context.extensionUri, "assets", "chat-panel.css"),
      );

      const logoUri = this.webview?.webview.asWebviewUri(
        Uri.joinPath(this.context.extensionUri, "assets", "tabby.png"),
      );

      this.webview.webview.html = `