Add quality survey at the end of the call (#1084)
Signed-off-by: Timo K <toger5@hotmail.de> Co-authored-by: Robin <robin@robin.town>
This commit is contained in:
		
					parent
					
						
							
								eff8847586
							
						
					
				
			
			
				commit
				
					
						2a6981c58d
					
				
			
		
					 12 changed files with 338 additions and 30 deletions
				
			
		| 
						 | 
				
			
			@ -29,6 +29,7 @@ import {
 | 
			
		|||
  MuteCameraTracker,
 | 
			
		||||
  MuteMicrophoneTracker,
 | 
			
		||||
  UndecryptableToDeviceEventTracker,
 | 
			
		||||
  QualitySurveyEventTracker,
 | 
			
		||||
} from "./PosthogEvents";
 | 
			
		||||
import { Config } from "../config/Config";
 | 
			
		||||
import { getUrlParams } from "../UrlParams";
 | 
			
		||||
| 
						 | 
				
			
			@ -431,4 +432,5 @@ export class PosthogAnalytics {
 | 
			
		|||
  public eventMuteMicrophone = new MuteMicrophoneTracker();
 | 
			
		||||
  public eventMuteCamera = new MuteCameraTracker();
 | 
			
		||||
  public eventUndecryptableToDevice = new UndecryptableToDeviceEventTracker();
 | 
			
		||||
  public eventQualitySurvey = new QualitySurveyEventTracker();
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -163,3 +163,21 @@ export class UndecryptableToDeviceEventTracker {
 | 
			
		|||
    });
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
interface QualitySurveyEvent {
 | 
			
		||||
  eventName: "QualitySurvey";
 | 
			
		||||
  callId: string;
 | 
			
		||||
  feedbackText: string;
 | 
			
		||||
  stars: number;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export class QualitySurveyEventTracker {
 | 
			
		||||
  track(callId: string, feedbackText: string, stars: number) {
 | 
			
		||||
    PosthogAnalytics.instance.trackEvent<QualitySurveyEvent>({
 | 
			
		||||
      eventName: "QualitySurvey",
 | 
			
		||||
      callId,
 | 
			
		||||
      feedbackText,
 | 
			
		||||
      stars,
 | 
			
		||||
    });
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										3
									
								
								src/icons/StarSelected.svg
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								src/icons/StarSelected.svg
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,3 @@
 | 
			
		|||
<svg width="28" height="26" viewBox="0 0 28 26" fill="none" xmlns="http://www.w3.org/2000/svg">
 | 
			
		||||
<path d="M14 21.0267L22.24 26.0001L20.0533 16.6267L27.3333 10.3201L17.7466 9.50675L14 0.666748L10.2533 9.50675L0.666626 10.3201L7.94663 16.6267L5.75996 26.0001L14 21.0267Z" fill="white"/>
 | 
			
		||||
</svg>
 | 
			
		||||
| 
		 After Width: | Height: | Size: 290 B  | 
							
								
								
									
										4
									
								
								src/icons/StarUnselected.svg
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										4
									
								
								src/icons/StarUnselected.svg
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,4 @@
 | 
			
		|||
<svg width="28" height="26" viewBox="0 0 28 26" fill="none" xmlns="http://www.w3.org/2000/svg">
 | 
			
		||||
  <path id="Vector" d="M14 7.50675L15.2933 10.5601L15.92 12.0401L17.52 12.1734L20.8133 12.4534L18.3066 14.6267L17.0933 15.6801L17.4533 17.2534L18.2 20.4667L15.3733 18.7601L14 17.9067L12.6266 18.7334L9.79996 20.4401L10.5466 17.2267L10.9066 15.6534L9.69329 14.6001L7.18663 12.4267L10.48 12.1467L12.08 12.0134L12.7066 10.5334L14 7.50675M14 0.666748L10.2533 9.50675L0.666626 10.3201L7.94663 16.6267L5.75996 26.0001L14 21.0267L22.24 26.0001L20.0533 16.6267L27.3333 10.3201L17.7466 9.50675L14 0.666748Z" fill="white"/>
 | 
			
		||||
  </svg>
 | 
			
		||||
  
 | 
			
		||||
| 
		 After Width: | Height: | Size: 620 B  | 
							
								
								
									
										23
									
								
								src/input/FeedbackInput.module.css
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										23
									
								
								src/input/FeedbackInput.module.css
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,23 @@
 | 
			
		|||
/*
 | 
			
		||||
Copyright 2023 New Vector Ltd
 | 
			
		||||
 | 
			
		||||
Licensed under the Apache License, Version 2.0 (the "License");
 | 
			
		||||
you may not use this file except in compliance with the License.
 | 
			
		||||
You may obtain a copy of the License at
 | 
			
		||||
 | 
			
		||||
http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
 | 
			
		||||
Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
See the License for the specific language governing permissions and
 | 
			
		||||
limitations under the License.
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
.feedback textarea {
 | 
			
		||||
  height: 75px;
 | 
			
		||||
  border-radius: 8px;
 | 
			
		||||
}
 | 
			
		||||
.feedback {
 | 
			
		||||
  border-radius: 8px;
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										41
									
								
								src/input/StarRatingInput.module.css
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										41
									
								
								src/input/StarRatingInput.module.css
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,41 @@
 | 
			
		|||
/*
 | 
			
		||||
Copyright 2023 New Vector Ltd
 | 
			
		||||
 | 
			
		||||
Licensed under the Apache License, Version 2.0 (the "License");
 | 
			
		||||
you may not use this file except in compliance with the License.
 | 
			
		||||
You may obtain a copy of the License at
 | 
			
		||||
 | 
			
		||||
http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
 | 
			
		||||
Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
See the License for the specific language governing permissions and
 | 
			
		||||
limitations under the License.
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
.starIcon {
 | 
			
		||||
  cursor: pointer;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.starRating {
 | 
			
		||||
  display: flex;
 | 
			
		||||
  justify-content: center;
 | 
			
		||||
  flex: 1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.inputContainer {
 | 
			
		||||
  display: inline-block;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.hideElement {
 | 
			
		||||
  border: 0;
 | 
			
		||||
  clip-path: content-box;
 | 
			
		||||
  height: 0px;
 | 
			
		||||
  width: 0px;
 | 
			
		||||
  margin: -1px;
 | 
			
		||||
  overflow: hidden;
 | 
			
		||||
  padding: 0;
 | 
			
		||||
  width: 1px;
 | 
			
		||||
  display: inline-block;
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										85
									
								
								src/input/StarRatingInput.tsx
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										85
									
								
								src/input/StarRatingInput.tsx
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,85 @@
 | 
			
		|||
/*
 | 
			
		||||
Copyright 2023 New Vector Ltd
 | 
			
		||||
 | 
			
		||||
Licensed under the Apache License, Version 2.0 (the "License");
 | 
			
		||||
you may not use this file except in compliance with the License.
 | 
			
		||||
You may obtain a copy of the License at
 | 
			
		||||
 | 
			
		||||
    http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
 | 
			
		||||
Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
See the License for the specific language governing permissions and
 | 
			
		||||
limitations under the License.
 | 
			
		||||
*/
 | 
			
		||||
import React, { useState } from "react";
 | 
			
		||||
import { useTranslation } from "react-i18next";
 | 
			
		||||
 | 
			
		||||
import styles from "./StarRatingInput.module.css";
 | 
			
		||||
import { ReactComponent as StarSelected } from "../icons/StarSelected.svg";
 | 
			
		||||
import { ReactComponent as StarUnselected } from "../icons/StarUnselected.svg";
 | 
			
		||||
 | 
			
		||||
interface Props {
 | 
			
		||||
  starCount: number;
 | 
			
		||||
  onChange: (stars: number) => void;
 | 
			
		||||
  required?: boolean;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export function StarRatingInput({
 | 
			
		||||
  starCount,
 | 
			
		||||
  onChange,
 | 
			
		||||
  required,
 | 
			
		||||
}: Props): JSX.Element {
 | 
			
		||||
  const [rating, setRating] = useState(0);
 | 
			
		||||
  const [hover, setHover] = useState(0);
 | 
			
		||||
  const { t } = useTranslation();
 | 
			
		||||
  return (
 | 
			
		||||
    <div className={styles.starRating}>
 | 
			
		||||
      {[...Array(starCount)].map((_star, index) => {
 | 
			
		||||
        index += 1;
 | 
			
		||||
        return (
 | 
			
		||||
          <div
 | 
			
		||||
            className={styles.inputContainer}
 | 
			
		||||
            onMouseEnter={() => setHover(index)}
 | 
			
		||||
            onMouseLeave={() => setHover(rating)}
 | 
			
		||||
            key={index}
 | 
			
		||||
          >
 | 
			
		||||
            <input
 | 
			
		||||
              className={styles.hideElement}
 | 
			
		||||
              type="radio"
 | 
			
		||||
              id={"starInput" + String(index)}
 | 
			
		||||
              value={String(index) + "Star"}
 | 
			
		||||
              name="star rating"
 | 
			
		||||
              onChange={(_ev) => {
 | 
			
		||||
                setRating(index);
 | 
			
		||||
                onChange(index);
 | 
			
		||||
              }}
 | 
			
		||||
              required
 | 
			
		||||
            />
 | 
			
		||||
            <label
 | 
			
		||||
              className={styles.hideElement}
 | 
			
		||||
              id={"starInvisibleLabel" + String(index)}
 | 
			
		||||
              htmlFor={String(index)}
 | 
			
		||||
            >
 | 
			
		||||
              {t("{{count}} stars", {
 | 
			
		||||
                count: index,
 | 
			
		||||
              })}
 | 
			
		||||
            </label>
 | 
			
		||||
            <label
 | 
			
		||||
              className={styles.starIcon}
 | 
			
		||||
              id={"starIcon" + String(index)}
 | 
			
		||||
              htmlFor={String(index)}
 | 
			
		||||
            >
 | 
			
		||||
              {index <= (hover || rating) ? (
 | 
			
		||||
                <StarSelected />
 | 
			
		||||
              ) : (
 | 
			
		||||
                <StarUnselected />
 | 
			
		||||
              )}
 | 
			
		||||
            </label>
 | 
			
		||||
          </div>
 | 
			
		||||
        );
 | 
			
		||||
      })}
 | 
			
		||||
    </div>
 | 
			
		||||
  );
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -17,20 +17,31 @@ limitations under the License.
 | 
			
		|||
.headline {
 | 
			
		||||
  text-align: center;
 | 
			
		||||
  margin-bottom: 60px;
 | 
			
		||||
  white-space: pre;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.callEndedContent {
 | 
			
		||||
  text-align: center;
 | 
			
		||||
  max-width: 360px;
 | 
			
		||||
  max-width: 450px;
 | 
			
		||||
}
 | 
			
		||||
.callEndedContent p {
 | 
			
		||||
  font-size: var(--font-size-subtitle);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.callEndedContent h3 {
 | 
			
		||||
  margin-bottom: 32px;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.callEndedButton {
 | 
			
		||||
  margin-top: 54px;
 | 
			
		||||
  margin-left: 30px;
 | 
			
		||||
  margin-right: 30px !important;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.submitButton {
 | 
			
		||||
  width: 100%;
 | 
			
		||||
  margin-top: 54px;
 | 
			
		||||
  margin-left: 30px;
 | 
			
		||||
  margin-right: 30px !important;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.container {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -14,19 +14,130 @@ See the License for the specific language governing permissions and
 | 
			
		|||
limitations under the License.
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
import React from "react";
 | 
			
		||||
import React, { FormEventHandler, useCallback, useState } from "react";
 | 
			
		||||
import { MatrixClient } from "matrix-js-sdk/src/client";
 | 
			
		||||
import { Trans, useTranslation } from "react-i18next";
 | 
			
		||||
import { useHistory } from "react-router-dom";
 | 
			
		||||
 | 
			
		||||
import styles from "./CallEndedView.module.css";
 | 
			
		||||
import { LinkButton } from "../button";
 | 
			
		||||
import feedbackStyle from "../input/FeedbackInput.module.css";
 | 
			
		||||
import { Button, LinkButton } from "../button";
 | 
			
		||||
import { useProfile } from "../profile/useProfile";
 | 
			
		||||
import { Subtitle, Body, Link, Headline } from "../typography/Typography";
 | 
			
		||||
import { Body, Link, Headline } from "../typography/Typography";
 | 
			
		||||
import { Header, HeaderLogo, LeftNav, RightNav } from "../Header";
 | 
			
		||||
import { PosthogAnalytics } from "../analytics/PosthogAnalytics";
 | 
			
		||||
import { FieldRow, InputField } from "../input/Input";
 | 
			
		||||
import { StarRatingInput } from "../input/StarRatingInput";
 | 
			
		||||
 | 
			
		||||
export function CallEndedView({ client }: { client: MatrixClient }) {
 | 
			
		||||
export function CallEndedView({
 | 
			
		||||
  client,
 | 
			
		||||
  isPasswordlessUser,
 | 
			
		||||
  endedCallId,
 | 
			
		||||
}: {
 | 
			
		||||
  client: MatrixClient;
 | 
			
		||||
  isPasswordlessUser: boolean;
 | 
			
		||||
  endedCallId: string;
 | 
			
		||||
}) {
 | 
			
		||||
  const { t } = useTranslation();
 | 
			
		||||
  const history = useHistory();
 | 
			
		||||
 | 
			
		||||
  const { displayName } = useProfile(client);
 | 
			
		||||
  const [surveySubmitted, setSurverySubmitted] = useState(false);
 | 
			
		||||
  const [starRating, setStarRating] = useState(0);
 | 
			
		||||
  const [submitting, setSubmitting] = useState(false);
 | 
			
		||||
  const [submitDone, setSubmitDone] = useState(false);
 | 
			
		||||
  const submitSurvery: FormEventHandler<HTMLFormElement> = useCallback(
 | 
			
		||||
    (e) => {
 | 
			
		||||
      e.preventDefault();
 | 
			
		||||
      const data = new FormData(e.target as HTMLFormElement);
 | 
			
		||||
      const feedbackText = data.get("feedbackText") as string;
 | 
			
		||||
 | 
			
		||||
      PosthogAnalytics.instance.eventQualitySurvey.track(
 | 
			
		||||
        endedCallId,
 | 
			
		||||
        feedbackText,
 | 
			
		||||
        starRating
 | 
			
		||||
      );
 | 
			
		||||
 | 
			
		||||
      setSubmitting(true);
 | 
			
		||||
 | 
			
		||||
      setTimeout(() => {
 | 
			
		||||
        setSubmitDone(true);
 | 
			
		||||
 | 
			
		||||
        setTimeout(() => {
 | 
			
		||||
          if (isPasswordlessUser) {
 | 
			
		||||
            // setting this renders the callEndedView with the invitation to create an account
 | 
			
		||||
            setSurverySubmitted(true);
 | 
			
		||||
          } else {
 | 
			
		||||
            // if the user already has an account immediately go back to the home screen
 | 
			
		||||
            history.push("/");
 | 
			
		||||
          }
 | 
			
		||||
        }, 1000);
 | 
			
		||||
      }, 1000);
 | 
			
		||||
    },
 | 
			
		||||
    [endedCallId, history, isPasswordlessUser, starRating]
 | 
			
		||||
  );
 | 
			
		||||
  const createAccountDialog = isPasswordlessUser && (
 | 
			
		||||
    <div className={styles.callEndedContent}>
 | 
			
		||||
      <Trans>
 | 
			
		||||
        <p>Why not finish by setting up a password to keep your account?</p>
 | 
			
		||||
        <p>
 | 
			
		||||
          You'll be able to keep your name and set an avatar for use on future
 | 
			
		||||
          calls
 | 
			
		||||
        </p>
 | 
			
		||||
      </Trans>
 | 
			
		||||
      <LinkButton
 | 
			
		||||
        className={styles.callEndedButton}
 | 
			
		||||
        size="lg"
 | 
			
		||||
        variant="default"
 | 
			
		||||
        to="/register"
 | 
			
		||||
      >
 | 
			
		||||
        {t("Create account")}
 | 
			
		||||
      </LinkButton>
 | 
			
		||||
    </div>
 | 
			
		||||
  );
 | 
			
		||||
 | 
			
		||||
  const qualitySurveyDialog = (
 | 
			
		||||
    <div className={styles.callEndedContent}>
 | 
			
		||||
      <Trans>
 | 
			
		||||
        <p>
 | 
			
		||||
          We'd love to hear your feedback so we can improve your experience.
 | 
			
		||||
        </p>
 | 
			
		||||
      </Trans>
 | 
			
		||||
      <form onSubmit={submitSurvery}>
 | 
			
		||||
        <FieldRow>
 | 
			
		||||
          <StarRatingInput starCount={5} onChange={setStarRating} required />
 | 
			
		||||
        </FieldRow>
 | 
			
		||||
        <FieldRow>
 | 
			
		||||
          <InputField
 | 
			
		||||
            className={feedbackStyle.feedback}
 | 
			
		||||
            id="feedbackText"
 | 
			
		||||
            name="feedbackText"
 | 
			
		||||
            label={t("Your feedback")}
 | 
			
		||||
            placeholder={t("Your feedback")}
 | 
			
		||||
            type="textarea"
 | 
			
		||||
            required
 | 
			
		||||
          />
 | 
			
		||||
        </FieldRow>{" "}
 | 
			
		||||
        <FieldRow>
 | 
			
		||||
          {submitDone ? (
 | 
			
		||||
            <Trans>
 | 
			
		||||
              <p>Thanks for your feedback!</p>
 | 
			
		||||
            </Trans>
 | 
			
		||||
          ) : (
 | 
			
		||||
            <Button
 | 
			
		||||
              type="submit"
 | 
			
		||||
              className={styles.submitButton}
 | 
			
		||||
              size="lg"
 | 
			
		||||
              variant="default"
 | 
			
		||||
              data-testid="home_go"
 | 
			
		||||
            >
 | 
			
		||||
              {submitting ? t("Submitting…") : t("Submit")}
 | 
			
		||||
            </Button>
 | 
			
		||||
          )}
 | 
			
		||||
        </FieldRow>
 | 
			
		||||
      </form>
 | 
			
		||||
    </div>
 | 
			
		||||
  );
 | 
			
		||||
 | 
			
		||||
  return (
 | 
			
		||||
    <>
 | 
			
		||||
| 
						 | 
				
			
			@ -39,27 +150,19 @@ export function CallEndedView({ client }: { client: MatrixClient }) {
 | 
			
		|||
      <div className={styles.container}>
 | 
			
		||||
        <main className={styles.main}>
 | 
			
		||||
          <Headline className={styles.headline}>
 | 
			
		||||
            {t("{{displayName}}, your call is now ended", { displayName })}
 | 
			
		||||
            {surveySubmitted
 | 
			
		||||
              ? t("{{displayName}}, your call has ended.", {
 | 
			
		||||
                  displayName,
 | 
			
		||||
                })
 | 
			
		||||
              : t("{{displayName}}, your call has ended.", {
 | 
			
		||||
                  displayName,
 | 
			
		||||
                }) +
 | 
			
		||||
                "\n" +
 | 
			
		||||
                t("How did it go?")}
 | 
			
		||||
          </Headline>
 | 
			
		||||
          <div className={styles.callEndedContent}>
 | 
			
		||||
            <Trans>
 | 
			
		||||
              <Subtitle>
 | 
			
		||||
                Why not finish by setting up a password to keep your account?
 | 
			
		||||
              </Subtitle>
 | 
			
		||||
              <Subtitle>
 | 
			
		||||
                You'll be able to keep your name and set an avatar for use on
 | 
			
		||||
                future calls
 | 
			
		||||
              </Subtitle>
 | 
			
		||||
            </Trans>
 | 
			
		||||
            <LinkButton
 | 
			
		||||
              className={styles.callEndedButton}
 | 
			
		||||
              size="lg"
 | 
			
		||||
              variant="default"
 | 
			
		||||
              to="/register"
 | 
			
		||||
            >
 | 
			
		||||
              {t("Create account")}
 | 
			
		||||
            </LinkButton>
 | 
			
		||||
          </div>
 | 
			
		||||
          {!surveySubmitted && PosthogAnalytics.instance.isEnabled()
 | 
			
		||||
            ? qualitySurveyDialog
 | 
			
		||||
            : createAccountDialog}
 | 
			
		||||
        </main>
 | 
			
		||||
        <Body className={styles.footer}>
 | 
			
		||||
          <Link color="primary" to="/">
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -203,7 +203,11 @@ export function GroupCallView({
 | 
			
		|||
      widget.api.transport.send(ElementWidgetActions.HangupCall, {});
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (!isPasswordlessUser && !isEmbedded) {
 | 
			
		||||
    if (
 | 
			
		||||
      !isPasswordlessUser &&
 | 
			
		||||
      !isEmbedded &&
 | 
			
		||||
      !PosthogAnalytics.instance.isEnabled()
 | 
			
		||||
    ) {
 | 
			
		||||
      history.push("/");
 | 
			
		||||
    }
 | 
			
		||||
  }, [groupCall, leave, isPasswordlessUser, isEmbedded, history]);
 | 
			
		||||
| 
						 | 
				
			
			@ -268,8 +272,14 @@ export function GroupCallView({
 | 
			
		|||
      );
 | 
			
		||||
    }
 | 
			
		||||
  } else if (left) {
 | 
			
		||||
    if (isPasswordlessUser) {
 | 
			
		||||
      return <CallEndedView client={client} />;
 | 
			
		||||
    if (isPasswordlessUser || PosthogAnalytics.instance.isEnabled()) {
 | 
			
		||||
      return (
 | 
			
		||||
        <CallEndedView
 | 
			
		||||
          endedCallId={groupCall.groupCallId}
 | 
			
		||||
          client={client}
 | 
			
		||||
          isPasswordlessUser={isPasswordlessUser}
 | 
			
		||||
        />
 | 
			
		||||
      );
 | 
			
		||||
    } else {
 | 
			
		||||
      // If the user is a regular user, we'll have sent them back to the homepage,
 | 
			
		||||
      // so just sit here & do nothing: otherwise we would (briefly) mount the
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -23,6 +23,7 @@ import { FieldRow, InputField, ErrorMessage } from "../input/Input";
 | 
			
		|||
import { useSubmitRageshake, useRageshakeRequest } from "./submit-rageshake";
 | 
			
		||||
import { Body } from "../typography/Typography";
 | 
			
		||||
import styles from "../input/SelectInput.module.css";
 | 
			
		||||
import feedbackStyles from "../input/FeedbackInput.module.css";
 | 
			
		||||
 | 
			
		||||
interface Props {
 | 
			
		||||
  roomId?: string;
 | 
			
		||||
| 
						 | 
				
			
			@ -68,9 +69,11 @@ export function FeedbackSettingsTab({ roomId }: Props) {
 | 
			
		|||
      <form onSubmit={onSubmitFeedback}>
 | 
			
		||||
        <FieldRow>
 | 
			
		||||
          <InputField
 | 
			
		||||
            className={feedbackStyles.feedback}
 | 
			
		||||
            id="description"
 | 
			
		||||
            name="description"
 | 
			
		||||
            label={t("Your feedback")}
 | 
			
		||||
            placeholder={t("Your feedback")}
 | 
			
		||||
            type="textarea"
 | 
			
		||||
            disabled={sending || sent}
 | 
			
		||||
          />
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue