Merge branch 'develop' into sort-imports
Signed-off-by: Aaron Raimist <aaron@raim.ist>
This commit is contained in:
commit
7b94e13a84
642 changed files with 30052 additions and 8035 deletions
|
@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
|
|||
limitations under the License.
|
||||
*/
|
||||
|
||||
import React from "react";
|
||||
import React, { ReactNode } from "react";
|
||||
|
||||
import { _t } from "../languageHandler";
|
||||
import SdkConfig from "../SdkConfig";
|
||||
|
@ -23,16 +23,52 @@ import Analytics from "../Analytics";
|
|||
import AccessibleButton from "../components/views/elements/AccessibleButton";
|
||||
import GenericToast from "../components/views/toasts/GenericToast";
|
||||
import ToastStore from "../stores/ToastStore";
|
||||
import {
|
||||
ButtonClicked,
|
||||
showDialog as showAnalyticsLearnMoreDialog,
|
||||
} from "../components/views/dialogs/AnalyticsLearnMoreDialog";
|
||||
import { Action } from "../dispatcher/actions";
|
||||
|
||||
const onAccept = () => {
|
||||
dis.dispatch({
|
||||
action: 'accept_cookies',
|
||||
action: Action.PseudonymousAnalyticsAccept,
|
||||
});
|
||||
};
|
||||
|
||||
const onReject = () => {
|
||||
dis.dispatch({
|
||||
action: "reject_cookies",
|
||||
action: Action.PseudonymousAnalyticsReject,
|
||||
});
|
||||
};
|
||||
|
||||
const onLearnMoreNoOptIn = () => {
|
||||
showAnalyticsLearnMoreDialog({
|
||||
onFinished: (buttonClicked?: ButtonClicked) => {
|
||||
if (buttonClicked === ButtonClicked.Primary) {
|
||||
// user clicked "Enable"
|
||||
onAccept();
|
||||
}
|
||||
// otherwise, the user either clicked "Cancel", or closed the dialog without making a choice,
|
||||
// leave the toast open
|
||||
},
|
||||
primaryButton: _t("Enable"),
|
||||
});
|
||||
};
|
||||
|
||||
const onLearnMorePreviouslyOptedIn = () => {
|
||||
showAnalyticsLearnMoreDialog({
|
||||
onFinished: (buttonClicked?: ButtonClicked) => {
|
||||
if (buttonClicked === ButtonClicked.Primary) {
|
||||
// user clicked "That's fine"
|
||||
onAccept();
|
||||
} else if (buttonClicked === ButtonClicked.Cancel) {
|
||||
// user clicked "Stop"
|
||||
onReject();
|
||||
}
|
||||
// otherwise, the user closed the dialog without making a choice, leave the toast open
|
||||
},
|
||||
primaryButton: _t("That's fine"),
|
||||
cancelButton: _t("Stop"),
|
||||
});
|
||||
};
|
||||
|
||||
|
@ -42,39 +78,89 @@ const onUsageDataClicked = () => {
|
|||
|
||||
const TOAST_KEY = "analytics";
|
||||
|
||||
export const showToast = (policyUrl?: string) => {
|
||||
const getAnonymousDescription = (): ReactNode => {
|
||||
// get toast description for anonymous tracking (the previous scheme pre-posthog)
|
||||
const brand = SdkConfig.get().brand;
|
||||
const cookiePolicyUrl = SdkConfig.get().piwik?.policyUrl;
|
||||
return _t(
|
||||
"Send <UsageDataLink>anonymous usage data</UsageDataLink> which helps us improve %(brand)s. " +
|
||||
"This will use a <PolicyLink>cookie</PolicyLink>.",
|
||||
{
|
||||
brand,
|
||||
},
|
||||
{
|
||||
"UsageDataLink": (sub) => (
|
||||
<AccessibleButton kind="link" onClick={onUsageDataClicked}>{ sub }</AccessibleButton>
|
||||
),
|
||||
"PolicyLink": (sub) => cookiePolicyUrl ? (
|
||||
<a target="_blank" href={cookiePolicyUrl}>{ sub }</a>
|
||||
) : sub,
|
||||
},
|
||||
);
|
||||
};
|
||||
|
||||
const showToast = (props: Omit<React.ComponentProps<typeof GenericToast>, "toastKey">) => {
|
||||
const analyticsOwner = SdkConfig.get().analyticsOwner ?? SdkConfig.get().brand;
|
||||
ToastStore.sharedInstance().addOrReplaceToast({
|
||||
key: TOAST_KEY,
|
||||
title: _t("Help us improve %(brand)s", { brand }),
|
||||
props: {
|
||||
description: _t(
|
||||
"Send <UsageDataLink>anonymous usage data</UsageDataLink> which helps us improve %(brand)s. " +
|
||||
"This will use a <PolicyLink>cookie</PolicyLink>.",
|
||||
{
|
||||
brand,
|
||||
},
|
||||
{
|
||||
"UsageDataLink": (sub) => (
|
||||
<AccessibleButton kind="link" onClick={onUsageDataClicked}>{ sub }</AccessibleButton>
|
||||
),
|
||||
// XXX: We need to link to the page that explains our cookies
|
||||
"PolicyLink": (sub) => policyUrl ? (
|
||||
<a target="_blank" href={policyUrl}>{ sub }</a>
|
||||
) : sub,
|
||||
},
|
||||
),
|
||||
acceptLabel: _t("Yes"),
|
||||
onAccept,
|
||||
rejectLabel: _t("No"),
|
||||
onReject,
|
||||
},
|
||||
title: _t("Help improve %(analyticsOwner)s", { analyticsOwner }),
|
||||
props,
|
||||
component: GenericToast,
|
||||
className: "mx_AnalyticsToast",
|
||||
priority: 10,
|
||||
});
|
||||
};
|
||||
|
||||
export const showPseudonymousAnalyticsOptInToast = (analyticsOptIn: boolean): void => {
|
||||
let props;
|
||||
if (analyticsOptIn) {
|
||||
// The user previously opted into our old analytics system - let them know things have changed and ask
|
||||
// them to opt in again.
|
||||
props = {
|
||||
description: _t(
|
||||
"You previously consented to share anonymous usage data with us. We're updating how that works."),
|
||||
acceptLabel: _t("That's fine"),
|
||||
onAccept,
|
||||
rejectLabel: _t("Learn more"),
|
||||
onReject: onLearnMorePreviouslyOptedIn,
|
||||
};
|
||||
} else if (analyticsOptIn === null || analyticsOptIn === undefined) {
|
||||
// The user had no analytics setting previously set, so we just need to prompt to opt-in, rather than
|
||||
// explaining any change.
|
||||
const learnMoreLink = (sub) => (
|
||||
<AccessibleButton kind="link" onClick={onLearnMoreNoOptIn}>{ sub }</AccessibleButton>
|
||||
);
|
||||
props = {
|
||||
description: _t(
|
||||
"Share anonymous data to help us identify issues. Nothing personal. No third parties. " +
|
||||
"<LearnMoreLink>Learn More</LearnMoreLink>", {}, { "LearnMoreLink": learnMoreLink }),
|
||||
acceptLabel: _t("Yes"),
|
||||
onAccept,
|
||||
rejectLabel: _t("No"),
|
||||
onReject,
|
||||
};
|
||||
} else { // false
|
||||
// The user previously opted out of analytics, don't ask again
|
||||
return;
|
||||
}
|
||||
showToast(props);
|
||||
};
|
||||
|
||||
export const showAnonymousAnalyticsOptInToast = (): void => {
|
||||
const props = {
|
||||
description: getAnonymousDescription(),
|
||||
acceptLabel: _t("Yes"),
|
||||
onAccept: () => dis.dispatch({
|
||||
action: Action.AnonymousAnalyticsAccept,
|
||||
}),
|
||||
rejectLabel: _t("No"),
|
||||
onReject: () => dis.dispatch({
|
||||
action: Action.AnonymousAnalyticsReject,
|
||||
}),
|
||||
};
|
||||
showToast(props);
|
||||
};
|
||||
|
||||
export const hideToast = () => {
|
||||
ToastStore.sharedInstance().dismissToast(TOAST_KEY);
|
||||
};
|
||||
|
|
|
@ -16,10 +16,11 @@ limitations under the License.
|
|||
|
||||
import { _t } from '../languageHandler';
|
||||
import dis from "../dispatcher/dispatcher";
|
||||
import { MatrixClientPeg } from '../MatrixClientPeg';
|
||||
import DeviceListener from '../DeviceListener';
|
||||
import GenericToast from "../components/views/toasts/GenericToast";
|
||||
import ToastStore from "../stores/ToastStore";
|
||||
import { Action } from "../dispatcher/actions";
|
||||
import { UserTab } from "../components/views/dialogs/UserSettingsDialog";
|
||||
|
||||
const TOAST_KEY = "reviewsessions";
|
||||
|
||||
|
@ -28,8 +29,8 @@ export const showToast = (deviceIds: Set<string>) => {
|
|||
DeviceListener.sharedInstance().dismissUnverifiedSessions(deviceIds);
|
||||
|
||||
dis.dispatch({
|
||||
action: 'view_user_info',
|
||||
userId: MatrixClientPeg.get().getUserId(),
|
||||
action: Action.ViewUserSettings,
|
||||
initialTabId: UserTab.Security,
|
||||
});
|
||||
};
|
||||
|
||||
|
|
|
@ -23,7 +23,6 @@ import classNames from 'classnames';
|
|||
|
||||
import { replaceableComponent } from '../utils/replaceableComponent';
|
||||
import CallHandler, { CallHandlerEvent } from '../CallHandler';
|
||||
import dis from '../dispatcher/dispatcher';
|
||||
import { MatrixClientPeg } from '../MatrixClientPeg';
|
||||
import { _t } from '../languageHandler';
|
||||
import RoomAvatar from '../components/views/avatars/RoomAvatar';
|
||||
|
@ -46,49 +45,43 @@ export default class IncomingCallToast extends React.Component<IProps, IState> {
|
|||
super(props);
|
||||
|
||||
this.state = {
|
||||
silenced: CallHandler.sharedInstance().isCallSilenced(this.props.call.callId),
|
||||
silenced: CallHandler.instance.isCallSilenced(this.props.call.callId),
|
||||
};
|
||||
}
|
||||
|
||||
public componentDidMount = (): void => {
|
||||
CallHandler.sharedInstance().addListener(CallHandlerEvent.SilencedCallsChanged, this.onSilencedCallsChanged);
|
||||
CallHandler.instance.addListener(CallHandlerEvent.SilencedCallsChanged, this.onSilencedCallsChanged);
|
||||
};
|
||||
|
||||
public componentWillUnmount(): void {
|
||||
CallHandler.sharedInstance().removeListener(CallHandlerEvent.SilencedCallsChanged, this.onSilencedCallsChanged);
|
||||
CallHandler.instance.removeListener(CallHandlerEvent.SilencedCallsChanged, this.onSilencedCallsChanged);
|
||||
}
|
||||
|
||||
private onSilencedCallsChanged = (): void => {
|
||||
this.setState({ silenced: CallHandler.sharedInstance().isCallSilenced(this.props.call.callId) });
|
||||
this.setState({ silenced: CallHandler.instance.isCallSilenced(this.props.call.callId) });
|
||||
};
|
||||
|
||||
private onAnswerClick = (e: React.MouseEvent): void => {
|
||||
e.stopPropagation();
|
||||
dis.dispatch({
|
||||
action: 'answer',
|
||||
room_id: CallHandler.sharedInstance().roomIdForCall(this.props.call),
|
||||
});
|
||||
CallHandler.instance.answerCall(CallHandler.instance.roomIdForCall(this.props.call));
|
||||
};
|
||||
|
||||
private onRejectClick= (e: React.MouseEvent): void => {
|
||||
e.stopPropagation();
|
||||
dis.dispatch({
|
||||
action: 'reject',
|
||||
room_id: CallHandler.sharedInstance().roomIdForCall(this.props.call),
|
||||
});
|
||||
CallHandler.instance.hangupOrReject(CallHandler.instance.roomIdForCall(this.props.call), true);
|
||||
};
|
||||
|
||||
private onSilenceClick = (e: React.MouseEvent): void => {
|
||||
e.stopPropagation();
|
||||
const callId = this.props.call.callId;
|
||||
this.state.silenced ?
|
||||
CallHandler.sharedInstance().unSilenceCall(callId) :
|
||||
CallHandler.sharedInstance().silenceCall(callId);
|
||||
CallHandler.instance.unSilenceCall(callId) :
|
||||
CallHandler.instance.silenceCall(callId);
|
||||
};
|
||||
|
||||
public render() {
|
||||
const call = this.props.call;
|
||||
const room = MatrixClientPeg.get().getRoom(CallHandler.sharedInstance().roomIdForCall(call));
|
||||
const room = MatrixClientPeg.get().getRoom(CallHandler.instance.roomIdForCall(call));
|
||||
const isVoice = call.type === CallType.Voice;
|
||||
|
||||
const contentClass = classNames("mx_IncomingCallToast_content", {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue