From 7c4aca51dcd9d326afcf80f748361d93d03822fe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?marcin=20miko=C5=82ajczak?= Date: Mon, 12 Dec 2022 23:36:56 +0100 Subject: [PATCH] some basic groups ui MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: marcin mikołajczak --- app/soapbox/actions/compose.ts | 14 +- app/soapbox/actions/importer/index.ts | 12 ++ app/soapbox/components/status.tsx | 25 ++- .../compose/components/compose-form.tsx | 13 +- .../group/components/group-header.tsx | 166 ++++++++++++++++++ .../group/components/group-info-panel.tsx | 27 +++ app/soapbox/features/group/group-timeline.tsx | 62 +++++++ app/soapbox/features/ui/index.tsx | 4 + .../features/ui/util/async-components.ts | 8 + app/soapbox/pages/group-page.tsx | 80 +++++++++ app/soapbox/reducers/compose.ts | 9 + app/soapbox/reducers/statuses.ts | 1 + app/soapbox/selectors/index.ts | 13 ++ 13 files changed, 425 insertions(+), 9 deletions(-) create mode 100644 app/soapbox/features/group/components/group-header.tsx create mode 100644 app/soapbox/features/group/components/group-info-panel.tsx create mode 100644 app/soapbox/features/group/group-timeline.tsx create mode 100644 app/soapbox/pages/group-page.tsx diff --git a/app/soapbox/actions/compose.ts b/app/soapbox/actions/compose.ts index 519cc89948..98c369bb99 100644 --- a/app/soapbox/actions/compose.ts +++ b/app/soapbox/actions/compose.ts @@ -47,6 +47,7 @@ const COMPOSE_UPLOAD_SUCCESS = 'COMPOSE_UPLOAD_SUCCESS'; const COMPOSE_UPLOAD_FAIL = 'COMPOSE_UPLOAD_FAIL'; const COMPOSE_UPLOAD_PROGRESS = 'COMPOSE_UPLOAD_PROGRESS'; const COMPOSE_UPLOAD_UNDO = 'COMPOSE_UPLOAD_UNDO'; +const COMPOSE_GROUP_POST = 'COMPOSE_GROUP_POST'; const COMPOSE_SUGGESTIONS_CLEAR = 'COMPOSE_SUGGESTIONS_CLEAR'; const COMPOSE_SUGGESTIONS_READY = 'COMPOSE_SUGGESTIONS_READY'; @@ -469,6 +470,15 @@ const undoUploadCompose = (composeId: string, media_id: string) => ({ media_id: media_id, }); +const groupCompose = (composeId: string, groupId: string) => + (dispatch: AppDispatch, getState: () => RootState) => { + dispatch({ + type: COMPOSE_GROUP_POST, + id: composeId, + group_id: groupId, + }); + }; + const clearComposeSuggestions = (composeId: string) => { if (cancelFetchComposeSuggestionsAccounts) { cancelFetchComposeSuggestionsAccounts(); @@ -721,7 +731,7 @@ const eventDiscussionCompose = (composeId: string, status: Status) => const instance = state.instance; const { explicitAddressing } = getFeatures(instance); - dispatch({ + return dispatch({ type: COMPOSE_EVENT_REPLY, id: composeId, status: status, @@ -748,6 +758,7 @@ export { COMPOSE_UPLOAD_FAIL, COMPOSE_UPLOAD_PROGRESS, COMPOSE_UPLOAD_UNDO, + COMPOSE_GROUP_POST, COMPOSE_SUGGESTIONS_CLEAR, COMPOSE_SUGGESTIONS_READY, COMPOSE_SUGGESTION_SELECT, @@ -800,6 +811,7 @@ export { uploadComposeSuccess, uploadComposeFail, undoUploadCompose, + groupCompose, clearComposeSuggestions, fetchComposeSuggestions, readyComposeSuggestionsEmojis, diff --git a/app/soapbox/actions/importer/index.ts b/app/soapbox/actions/importer/index.ts index d284f4f741..8750a5d61f 100644 --- a/app/soapbox/actions/importer/index.ts +++ b/app/soapbox/actions/importer/index.ts @@ -65,6 +65,9 @@ const importFetchedAccounts = (accounts: APIEntity[], args = { should_refetch: f return importAccounts(normalAccounts); }; +const importFetchedGroup = (group: APIEntity) => + importFetchedGroups([group]); + const importFetchedGroups = (groups: APIEntity[]) => { const normalGroups: APIEntity[] = []; @@ -112,6 +115,10 @@ const importFetchedStatus = (status: APIEntity, idempotencyKey?: string) => dispatch(importFetchedPoll(status.poll)); } + if (status.group?.id) { + dispatch(importFetchedGroup(status.group)); + } + dispatch(importFetchedAccount(status.account)); dispatch(importStatus(status, idempotencyKey)); }; @@ -161,6 +168,10 @@ const importFetchedStatuses = (statuses: APIEntity[]) => if (status.poll?.id) { polls.push(status.poll); } + + if (status.group?.id) { + dispatch(importFetchedGroup(status.group)); + } } statuses.forEach(processStatus); @@ -196,6 +207,7 @@ export { importPolls, importFetchedAccount, importFetchedAccounts, + importFetchedGroup, importFetchedGroups, importFetchedStatus, importFetchedStatuses, diff --git a/app/soapbox/components/status.tsx b/app/soapbox/components/status.tsx index f24adaefb5..935ad8b7ee 100644 --- a/app/soapbox/components/status.tsx +++ b/app/soapbox/components/status.tsx @@ -2,7 +2,7 @@ import classNames from 'clsx'; import React, { useEffect, useRef, useState } from 'react'; import { HotKeys } from 'react-hotkeys'; import { useIntl, FormattedMessage, defineMessages } from 'react-intl'; -import { NavLink, useHistory } from 'react-router-dom'; +import { Link, NavLink, useHistory } from 'react-router-dom'; import { mentionCompose, replyCompose } from 'soapbox/actions/compose'; import { toggleFavourite, toggleReblog } from 'soapbox/actions/interactions'; @@ -26,6 +26,7 @@ import { Card, HStack, Stack, Text } from './ui'; import type { Map as ImmutableMap } from 'immutable'; import type { Account as AccountEntity, + Group as GroupEntity, Status as StatusEntity, } from 'soapbox/types/entities'; @@ -299,6 +300,8 @@ const Status: React.FC = (props) => { } } + const group = actualStatus.group as GroupEntity | null; + const handlers = muted ? undefined : { reply: handleHotkeyReply, favourite: handleHotkeyFavourite, @@ -342,6 +345,26 @@ const Status: React.FC = (props) => { )} + {group && ( +
+ + + + + e.stopPropagation()}> + + + ) }} + /> + + +
+ )} + { autoFocus?: boolean, clickableAreaRef?: React.RefObject, event?: string, + group?: string, } -const ComposeForm = ({ id, shouldCondense, autoFocus, clickableAreaRef, event }: IComposeForm) => { +const ComposeForm = ({ id, shouldCondense, autoFocus, clickableAreaRef, event, group }: IComposeForm) => { const history = useHistory(); const intl = useIntl(); const dispatch = useAppDispatch(); @@ -228,7 +229,7 @@ const ComposeForm = ({ id, shouldCondense, autoFocus, clickab {features.media && } {features.polls && } - {features.privacyScopes && } + {features.privacyScopes && !group && } {features.scheduledStatuses && } {features.spoilers && } {features.richText && } @@ -278,7 +279,7 @@ const ComposeForm = ({ id, shouldCondense, autoFocus, clickab return ( - {scheduledStatusCount > 0 && !event && ( + {scheduledStatusCount > 0 && !event && !group && ( ({ id, shouldCondense, autoFocus, clickab - {!shouldCondense && !event && } + {!shouldCondense && !event && !group && } - {!shouldCondense && !event && } + {!shouldCondense && !event && !group && } ({ id, shouldCondense, autoFocus, clickab