diff --git a/app/javascript/flavours/glitch/features/compose/components/quoted_post.tsx b/app/javascript/flavours/glitch/features/compose/components/quoted_post.tsx
new file mode 100644
index 0000000000..c63cd77d54
--- /dev/null
+++ b/app/javascript/flavours/glitch/features/compose/components/quoted_post.tsx
@@ -0,0 +1,27 @@
+import { useMemo } from 'react';
+import type { FC } from 'react';
+
+import { Map } from 'immutable';
+
+import { QuotedStatus } from '@/flavours/glitch/components/status_quoted';
+import { useAppSelector } from '@/flavours/glitch/store';
+
+export const ComposeQuotedStatus: FC = () => {
+ const quotedStatusId = useAppSelector(
+ (state) => state.compose.get('quoted_status_id') as string | null,
+ );
+ const quote = useMemo(
+ () =>
+ quotedStatusId
+ ? Map<'state' | 'quoted_status', string>([
+ ['state', 'accepted'],
+ ['quoted_status', quotedStatusId],
+ ])
+ : null,
+ [quotedStatusId],
+ );
+ if (!quote) {
+ return null;
+ }
+ return
;
+};
diff --git a/app/javascript/flavours/glitch/features/compose/containers/poll_button_container.js b/app/javascript/flavours/glitch/features/compose/containers/poll_button_container.js
index 9de388f64a..e8fa9798c5 100644
--- a/app/javascript/flavours/glitch/features/compose/containers/poll_button_container.js
+++ b/app/javascript/flavours/glitch/features/compose/containers/poll_button_container.js
@@ -3,10 +3,16 @@ import { connect } from 'react-redux';
import { addPoll, removePoll } from '../../../actions/compose';
import PollButton from '../components/poll_button';
-const mapStateToProps = state => ({
- disabled: state.getIn(['compose', 'is_uploading']) || (state.getIn(['compose', 'media_attachments']).size > 0),
- active: state.getIn(['compose', 'poll']) !== null,
-});
+const mapStateToProps = state => {
+ const readyAttachmentsSize = state.compose.get('media_attachments').size ?? 0;
+ const hasAttachments = readyAttachmentsSize > 0 || !!state.compose.get('is_uploading');
+ const hasQuote = !!state.compose.get('quoted_status_id');
+
+ return ({
+ disabled: hasAttachments || hasQuote,
+ active: state.getIn(['compose', 'poll']) !== null,
+ });
+};
const mapDispatchToProps = dispatch => ({
diff --git a/app/javascript/flavours/glitch/features/compose/containers/upload_button_container.js b/app/javascript/flavours/glitch/features/compose/containers/upload_button_container.js
index 39cc12078c..8ce36fd19c 100644
--- a/app/javascript/flavours/glitch/features/compose/containers/upload_button_container.js
+++ b/app/javascript/flavours/glitch/features/compose/containers/upload_button_container.js
@@ -12,9 +12,10 @@ const mapStateToProps = state => {
const attachmentsSize = readyAttachmentsSize + pendingAttachmentsSize;
const isOverLimit = attachmentsSize > state.getIn(['server', 'server', 'configuration', 'statuses', 'max_media_attachments'])-1;
const hasVideoOrAudio = state.getIn(['compose', 'media_attachments']).some(m => ['video', 'audio'].includes(m.get('type')));
+ const hasQuote = !!state.compose.get('quoted_status_id');
return {
- disabled: isPoll || isUploading || isOverLimit || hasVideoOrAudio,
+ disabled: isPoll || isUploading || isOverLimit || hasVideoOrAudio || hasQuote,
resetFileKey: state.getIn(['compose', 'resetFileKey']),
};
};
diff --git a/app/javascript/flavours/glitch/reducers/compose.js b/app/javascript/flavours/glitch/reducers/compose.js
index 077c80db3f..32cef7a256 100644
--- a/app/javascript/flavours/glitch/reducers/compose.js
+++ b/app/javascript/flavours/glitch/reducers/compose.js
@@ -407,8 +407,16 @@ export const composeReducer = (state = initialState, action) => {
return state.set('is_changing_upload', false);
} else if (quoteComposeByStatus.match(action)) {
const status = action.payload;
- if (status.getIn(['quote_approval', 'current_user']) === 'automatic') {
- return state.set('quoted_status_id', status.get('id'));
+ if (
+ status.getIn(['quote_approval', 'current_user']) === 'automatic' &&
+ state.get('media_attachments').size === 0 &&
+ !state.get('is_uploading') &&
+ !state.get('poll')
+ ) {
+ return state
+ .set('quoted_status_id', status.get('id'))
+ .set('spoiler', status.get('sensitive'))
+ .set('spoiler_text', status.get('spoiler_text'));
}
} else if (quoteComposeCancel.match(action)) {
return state.set('quoted_status_id', null);
diff --git a/app/javascript/flavours/glitch/selectors/filters.ts b/app/javascript/flavours/glitch/selectors/filters.ts
index 5d7bfcbdc7..376d626619 100644
--- a/app/javascript/flavours/glitch/selectors/filters.ts
+++ b/app/javascript/flavours/glitch/selectors/filters.ts
@@ -15,7 +15,7 @@ export const getFilters = createSelector(
(_, { contextType }: { contextType: string }) => contextType,
],
(filters, contextType) => {
- if (!contextType) {
+ if (!contextType || contextType === 'compose') {
return null;
}
diff --git a/app/javascript/flavours/glitch/store/typed_functions.ts b/app/javascript/flavours/glitch/store/typed_functions.ts
index 3204d13ee4..4d7341b0c8 100644
--- a/app/javascript/flavours/glitch/store/typed_functions.ts
+++ b/app/javascript/flavours/glitch/store/typed_functions.ts
@@ -129,7 +129,7 @@ export function createAppThunk
(
},
}));
- return Object.assign({}, action, actionCreator);
+ return Object.assign(actionCreator, action);
}
const createBaseAsyncThunk = rtkCreateAsyncThunk.withTypes();
diff --git a/app/javascript/flavours/glitch/styles/components.scss b/app/javascript/flavours/glitch/styles/components.scss
index 5e1c1e9d6f..a591656805 100644
--- a/app/javascript/flavours/glitch/styles/components.scss
+++ b/app/javascript/flavours/glitch/styles/components.scss
@@ -999,6 +999,24 @@ body > [data-popper-placement] {
}
}
}
+
+ .status__quote {
+ margin: 0 8px;
+ max-height: 220px;
+ overflow: hidden;
+
+ // Override .status__content .status__content__text.status__content__text--visible
+ .status__content__text.status__content__text {
+ display: -webkit-box;
+ }
+
+ .status__content__text {
+ -webkit-line-clamp: 4;
+ line-clamp: 4;
+ -webkit-box-orient: vertical;
+ overflow: hidden;
+ }
+ }
}
.dropdown-button {
@@ -1633,6 +1651,7 @@ body > [data-popper-placement] {
align-items: center;
gap: 10px;
overflow: hidden;
+ flex-grow: 1;
.display-name {
bdi {
@@ -1649,6 +1668,11 @@ body > [data-popper-placement] {
}
}
+.status__quote-cancel {
+ align-self: self-start;
+ order: 5;
+}
+
.status__info {
font-size: 15px;
padding-bottom: 10px;