Page Menu
Home
Phorge
Search
Configure Global Search
Log In
Files
F32193721
D4618.1765099208.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Flag For Later
Award Token
Size
11 KB
Referenced Files
None
Subscribers
None
D4618.1765099208.diff
View Options
diff --git a/web/modals/threads/new-thread-modal.react.js b/web/modals/threads/new-thread-modal.react.js
deleted file mode 100644
--- a/web/modals/threads/new-thread-modal.react.js
+++ /dev/null
@@ -1,318 +0,0 @@
-// @flow
-
-import invariant from 'invariant';
-import * as React from 'react';
-
-import { newThreadActionTypes, newThread } from 'lib/actions/thread-actions';
-import { createLoadingStatusSelector } from 'lib/selectors/loading-selectors';
-import { threadInfoSelector } from 'lib/selectors/thread-selectors';
-import {
- generateRandomColor,
- threadTypeDescriptions,
-} from 'lib/shared/thread-utils';
-import type { CalendarQuery } from 'lib/types/entry-types';
-import {
- type ThreadInfo,
- threadTypes,
- assertThreadType,
- type ThreadType,
- type ClientNewThreadRequest,
- type NewThreadResult,
-} from 'lib/types/thread-types';
-import {
- type DispatchActionPromise,
- useDispatchActionPromise,
- useServerCall,
-} from 'lib/utils/action-utils';
-import { firstLine } from 'lib/utils/string-utils';
-
-import Button from '../../components/button.react';
-import { useSelector } from '../../redux/redux-utils';
-import { nonThreadCalendarQuery } from '../../selectors/nav-selectors';
-import css from '../../style.css';
-import Modal from '../modal.react';
-import ColorPicker from './color-picker.react';
-
-type BaseProps = {
- +onClose: () => void,
- +parentThreadID?: ?string,
-};
-type Props = {
- ...BaseProps,
- +inputDisabled: boolean,
- +calendarQuery: () => CalendarQuery,
- +parentThreadInfo: ?ThreadInfo,
- +dispatchActionPromise: DispatchActionPromise,
- +newThread: (request: ClientNewThreadRequest) => Promise<NewThreadResult>,
-};
-type State = {
- +threadType: ?ThreadType,
- +name: string,
- +description: string,
- +color: string,
- +errorMessage: string,
-};
-
-const { COMMUNITY_OPEN_SUBTHREAD, COMMUNITY_SECRET_SUBTHREAD } = threadTypes;
-
-class NewThreadModal extends React.PureComponent<Props, State> {
- nameInput: ?HTMLInputElement;
- openPrivacyInput: ?HTMLInputElement;
- threadPasswordInput: ?HTMLInputElement;
-
- constructor(props: Props) {
- super(props);
- this.state = {
- threadType: props.parentThreadID ? undefined : COMMUNITY_SECRET_SUBTHREAD,
- name: '',
- description: '',
- color: props.parentThreadInfo
- ? props.parentThreadInfo.color
- : generateRandomColor(),
- errorMessage: '',
- };
- }
-
- componentDidMount() {
- invariant(this.nameInput, 'nameInput ref unset');
- this.nameInput.focus();
- }
-
- render() {
- let threadTypeSection = null;
- if (this.props.parentThreadID) {
- threadTypeSection = (
- <div className={css['new-thread-privacy-container']}>
- <div className={css['modal-radio-selector']}>
- <div className={css['form-title']}>Chat type</div>
- <div className={css['form-enum-selector']}>
- <div className={css['form-enum-container']}>
- <input
- type="radio"
- name="new-thread-type"
- id="new-thread-open"
- value={COMMUNITY_OPEN_SUBTHREAD}
- checked={this.state.threadType === COMMUNITY_OPEN_SUBTHREAD}
- onChange={this.onChangeThreadType}
- disabled={this.props.inputDisabled}
- ref={this.openPrivacyInputRef}
- />
- <div className={css['form-enum-option']}>
- <label htmlFor="new-thread-open">
- Open
- <span className={css['form-enum-description']}>
- {threadTypeDescriptions[COMMUNITY_OPEN_SUBTHREAD]}
- </span>
- </label>
- </div>
- </div>
- <div className={css['form-enum-container']}>
- <input
- type="radio"
- name="new-thread-type"
- id="new-thread-closed"
- value={COMMUNITY_SECRET_SUBTHREAD}
- checked={this.state.threadType === COMMUNITY_SECRET_SUBTHREAD}
- onChange={this.onChangeThreadType}
- disabled={this.props.inputDisabled}
- />
- <div className={css['form-enum-option']}>
- <label htmlFor="new-thread-closed">
- Secret
- <span className={css['form-enum-description']}>
- {threadTypeDescriptions[COMMUNITY_SECRET_SUBTHREAD]}
- </span>
- </label>
- </div>
- </div>
- </div>
- </div>
- </div>
- );
- }
- return (
- <Modal name="New chat" onClose={this.props.onClose} size="large">
- <div className={css['modal-body']}>
- <form method="POST">
- <div>
- <div className={css['form-title']}>Chat name</div>
- <div className={css['form-content']}>
- <input
- type="text"
- value={firstLine(this.state.name)}
- placeholder="Chat name"
- onChange={this.onChangeName}
- disabled={this.props.inputDisabled}
- ref={this.nameInputRef}
- />
- </div>
- </div>
- <div className={css['form-textarea-container']}>
- <div className={css['form-title']}>Description</div>
- <div className={css['form-content']}>
- <textarea
- value={this.state.description}
- placeholder="Chat description"
- onChange={this.onChangeDescription}
- disabled={this.props.inputDisabled}
- />
- </div>
- </div>
- {threadTypeSection}
- <div>
- <div className={`${css['form-title']} ${css['color-title']}`}>
- Color
- </div>
- <div className={css['form-content']}>
- <ColorPicker
- id="new-thread-color"
- value={this.state.color}
- disabled={this.props.inputDisabled}
- onChange={this.onChangeColor}
- />
- </div>
- </div>
- <div className={css['form-footer']}>
- <Button
- onClick={this.onSubmit}
- disabled={this.props.inputDisabled}
- type="submit"
- >
- Save
- </Button>
- <div className={css['modal-form-error']}>
- {this.state.errorMessage}
- </div>
- </div>
- </form>
- </div>
- </Modal>
- );
- }
-
- nameInputRef = (nameInput: ?HTMLInputElement) => {
- this.nameInput = nameInput;
- };
-
- openPrivacyInputRef = (openPrivacyInput: ?HTMLInputElement) => {
- this.openPrivacyInput = openPrivacyInput;
- };
-
- onChangeName = (event: SyntheticEvent<HTMLInputElement>) => {
- const target = event.target;
- invariant(target instanceof HTMLInputElement, 'target not input');
- this.setState({ name: firstLine(target.value) });
- };
-
- onChangeDescription = (event: SyntheticEvent<HTMLTextAreaElement>) => {
- const target = event.target;
- invariant(target instanceof HTMLTextAreaElement, 'target not textarea');
- this.setState({ description: target.value });
- };
-
- onChangeColor = (color: string) => {
- this.setState({ color: color });
- };
-
- onChangeThreadType = (event: SyntheticEvent<HTMLInputElement>) => {
- const target = event.target;
- invariant(target instanceof HTMLInputElement, 'target not input');
- this.setState({
- threadType: assertThreadType(parseInt(target.value, 10)),
- });
- };
-
- onSubmit = (event: SyntheticEvent<HTMLElement>) => {
- event.preventDefault();
-
- const threadType = this.state.threadType;
- invariant(
- threadType !== null,
- 'threadType state should never be set to null',
- );
- if (threadType === undefined) {
- this.setState(
- {
- errorMessage: 'chat type unspecified',
- },
- () => {
- invariant(this.openPrivacyInput, 'openPrivacyInput ref unset');
- this.openPrivacyInput.focus();
- },
- );
- return;
- }
-
- this.props.dispatchActionPromise(
- newThreadActionTypes,
- this.newThreadAction(threadType),
- );
- };
-
- async newThreadAction(threadType: ThreadType) {
- const name = this.state.name.trim();
- try {
- invariant(
- threadType === 3 ||
- threadType === 4 ||
- threadType === 6 ||
- threadType === 7,
- "Sidebars and communities can't be created from the chat composer",
- );
- const query = this.props.calendarQuery();
- const response = await this.props.newThread({
- type: threadType,
- name,
- description: this.state.description,
- color: this.state.color,
- calendarQuery: query,
- });
- this.props.onClose();
- return response;
- } catch (e) {
- this.setState(
- {
- threadType: undefined,
- name: '',
- description: '',
- color: '',
- errorMessage: 'unknown error',
- },
- () => {
- invariant(this.nameInput, 'nameInput ref unset');
- this.nameInput.focus();
- },
- );
- throw e;
- }
- }
-}
-
-const loadingStatusSelector = createLoadingStatusSelector(newThreadActionTypes);
-
-const ConnectedNewThreadModal: React.ComponentType<BaseProps> = React.memo<BaseProps>(
- function ConnectedNewThreadModal(props) {
- const { parentThreadID } = props;
- const parentThreadInfo: ?ThreadInfo = useSelector(state =>
- parentThreadID ? threadInfoSelector(state)[parentThreadID] : null,
- );
- invariant(!parentThreadID || parentThreadInfo, 'parent chat should exist');
- const inputDisabled = useSelector(loadingStatusSelector) === 'loading';
- const calendarQuery = useSelector(nonThreadCalendarQuery);
- const callNewThread = useServerCall(newThread);
- const dispatchActionPromise = useDispatchActionPromise();
-
- return (
- <NewThreadModal
- {...props}
- parentThreadInfo={parentThreadInfo}
- inputDisabled={inputDisabled}
- calendarQuery={calendarQuery}
- newThread={callNewThread}
- dispatchActionPromise={dispatchActionPromise}
- />
- );
- },
-);
-
-export default ConnectedNewThreadModal;
diff --git a/web/style.css b/web/style.css
--- a/web/style.css
+++ b/web/style.css
@@ -164,35 +164,6 @@
line-height: 0;
}
-div.form-enum-selector {
- display: inline-block;
- padding-bottom: 4px;
-}
-div.form-enum-selector > div.form-enum-container {
- padding-top: 5px;
-}
-div.form-enum-selector > div.form-enum-container > input {
- vertical-align: top;
- margin-top: 4px;
-}
-div.form-enum-selector div.form-enum-option {
- display: inline-block;
- font-size: 15px;
- font-weight: 600;
- padding-left: 3px;
-}
-div.form-enum-selector span.form-enum-description {
- display: block;
- font-family: var(--font-stack);
- font-weight: normal;
- font-size: 13px;
- max-width: 260px;
- color: gray;
-}
-div.color-title {
- margin-top: 4px;
-}
-
.hidden {
display: none;
}
@@ -200,15 +171,6 @@
font-style: italic;
}
-div.form-textarea-container {
- margin-top: 1px;
-}
-
-div.new-thread-privacy-container {
- margin-bottom: 3px;
- margin-top: -6px;
-}
-
span.page-loading {
margin-top: 5px;
margin-right: 12px;
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Sun, Dec 7, 9:20 AM (11 h, 32 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
5843282
Default Alt Text
D4618.1765099208.diff (11 KB)
Attached To
Mode
D4618: [web] Remove old `NewThreadModal` component
Attached
Detach File
Event Timeline
Log In to Comment