Page MenuHomePhabricator

D5829.id19373.diff
No OneTemporary

D5829.id19373.diff

diff --git a/web/modals/modal.css b/web/modals/modal.css
--- a/web/modals/modal.css
+++ b/web/modals/modal.css
@@ -30,6 +30,10 @@
padding: 32px 32px 0 32px;
}
+div.modalHeaderCentered {
+ justify-content: center;
+}
+
h2.title {
font-size: 20px;
font-weight: 500;
diff --git a/web/modals/modal.react.js b/web/modals/modal.react.js
--- a/web/modals/modal.react.js
+++ b/web/modals/modal.react.js
@@ -17,6 +17,7 @@
+onClose: () => void,
+withCloseButton?: boolean,
+size?: ModalSize,
+ +modalHeaderCentered?: boolean,
};
type ModalProps = {
@@ -32,6 +33,7 @@
name,
icon,
withCloseButton = true,
+ modalHeaderCentered = false,
} = props;
const modalContainerClasses = classNames(css.modalContainer, {
@@ -39,6 +41,11 @@
[css.modalContainerSmall]: size === 'small',
});
+ const modalHeader = classNames({
+ [css.modalHeader]: true,
+ [css.modalHeaderCentered]: modalHeaderCentered,
+ });
+
const cornerCloseButton = React.useMemo(() => {
if (!withCloseButton) {
return null;
@@ -60,7 +67,7 @@
return (
<ModalOverlay onClose={onClose}>
<div className={modalContainerClasses}>
- <div className={css.modalHeader}>
+ <div className={modalHeader}>
<h2 className={css.title}>
{headerIcon}
{name}
diff --git a/web/modals/terms-and-privacy-modal.css b/web/modals/terms-and-privacy-modal.css
new file mode 100644
--- /dev/null
+++ b/web/modals/terms-and-privacy-modal.css
@@ -0,0 +1,31 @@
+.container {
+ color: var(--modal-fg);
+ padding: 20px 32px;
+ text-align: center;
+ line-height: var(--line-height-text);
+}
+
+.button {
+ display: flex;
+ flex-direction: column;
+ width: 110px;
+ padding: 5px 0 16px;
+ margin: auto;
+ justify-content: space-around;
+}
+
+.link {
+ color: var(--purple-link);
+}
+
+.error {
+ margin-top: 16px;
+ font-size: var(--s-font-14);
+ color: var(--error);
+ font-style: italic;
+ text-align: center;
+}
+
+.buttonContent {
+ height: 20px;
+}
diff --git a/web/modals/terms-and-privacy-modal.react.js b/web/modals/terms-and-privacy-modal.react.js
new file mode 100644
--- /dev/null
+++ b/web/modals/terms-and-privacy-modal.react.js
@@ -0,0 +1,96 @@
+// @flow
+
+import * as React from 'react';
+
+import {
+ policyAcknowledgment,
+ policyAcknowledgmentActionTypes,
+} from 'lib/actions/user-actions.js';
+import { policyTypes } from 'lib/facts/policies.js';
+import { createLoadingStatusSelector } from 'lib/selectors/loading-selectors.js';
+import {
+ useDispatchActionPromise,
+ useServerCall,
+} from 'lib/utils/action-utils.js';
+import { acknowledgePolicy } from 'lib/utils/policy-acknowledge-utlis.js';
+
+import Button, { buttonThemes } from '../components/button.react.js';
+import LoadingIndicator from '../loading-indicator.react.js';
+import { useSelector } from '../redux/redux-utils.js';
+import Modal from './modal.react';
+import css from './terms-and-privacy-modal.css';
+
+const loadingStatusSelector = createLoadingStatusSelector(
+ policyAcknowledgmentActionTypes,
+);
+
+const disabledOnClose = () => undefined;
+
+function TermsAndPrivacyModal(): React.Node {
+ const loading = useSelector(loadingStatusSelector);
+ const [acknowledgmentError, setAcknowledgmentError] = React.useState('');
+ const sendAcknowledgmentRequest = useServerCall(policyAcknowledgment);
+ const dispatchActionPromise = useDispatchActionPromise();
+
+ const onAccept = React.useCallback(() => {
+ acknowledgePolicy(
+ policyTypes.tosAndPrivacyPolicy,
+ dispatchActionPromise,
+ sendAcknowledgmentRequest,
+ setAcknowledgmentError,
+ );
+ }, [dispatchActionPromise, sendAcknowledgmentRequest]);
+
+ const buttonContent = React.useMemo(() => {
+ if (loading === 'loading') {
+ return <LoadingIndicator status="loading" size="medium" />;
+ }
+ return 'I accept';
+ }, [loading]);
+
+ return (
+ <Modal
+ withCloseButton={false}
+ modalHeaderCentered={true}
+ onClose={disabledOnClose}
+ name="Terms of Service and Privacy Policy"
+ size="large"
+ >
+ <div className={css.container}>
+ We recently updated our{' '}
+ <a
+ href="https://comm.app/privacy"
+ target="_blank"
+ rel="noreferrer"
+ className={css.link}
+ >
+ Terms of Service
+ </a>
+ {' & '}
+ <a
+ href="https://comm.app/terms"
+ target="_blank"
+ rel="noreferrer"
+ className={css.link}
+ >
+ Privacy Policy
+ </a>
+ . In order to continue using Comm, we&apos;re asking you to read
+ through, acknowledge, and accept the updated policies.
+ </div>
+
+ <div className={css.button}>
+ <Button
+ variant="filled"
+ buttonColor={buttonThemes.standard}
+ onClick={onAccept}
+ >
+ <div className={css.buttonContent}>{buttonContent}</div>
+ </Button>
+ <div className={css.error}>{acknowledgmentError}</div>
+ </div>
+ </Modal>
+ );
+}
+
+export default TermsAndPrivacyModal;
diff --git a/web/theme.css b/web/theme.css
--- a/web/theme.css
+++ b/web/theme.css
@@ -190,4 +190,5 @@
--typeahead-overlay-shadow-secondary: rgba(0, 0, 0, 0.4);
--spoiler-text-color: #33332c;
--spoiler-background-color: #33332c;
+ --purple-link: var(--violet-light-100);
}

File Metadata

Mime Type
text/plain
Expires
Thu, Dec 19, 3:45 PM (25 s)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
2677860
Default Alt Text
D5829.id19373.diff (5 KB)

Event Timeline