Skip to content

Commit ff1613e

Browse files
authored
feat: add user setting for which default post type to use (#5365)
1 parent 1768e6b commit ff1613e

10 files changed

Lines changed: 141 additions & 26 deletions

File tree

packages/shared/src/components/fields/form/common.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
export enum WriteFormTab {
2-
Share = 'Share a link',
32
NewPost = 'New post',
3+
Share = 'Share a link',
44
Poll = 'Poll',
55
}
66

packages/shared/src/components/post/freeform/write/WriteFreeFormSkeleton.tsx

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -14,15 +14,13 @@ export function WriteFreeFormSkeleton({
1414
return (
1515
<WritePageContainer>
1616
<WritePostHeader isEdit={isEdit} />
17-
<WritePageMain className="px-6 py-5">
18-
<ElementPlaceholder className="h-24 w-40 rounded-16" />
19-
<ElementPlaceholder className="mt-6 h-12 rounded-12" />
20-
<ElementPlaceholder className="mt-4 h-60 rounded-12" />
21-
<span className="mt-8 flex flex-row items-center">
22-
<ElementPlaceholder className="hidden h-6 w-12 rounded-6 tablet:flex" />
23-
<ElementPlaceholder className="mr-20 h-6 flex-1 rounded-6 tablet:ml-4" />
24-
<ElementPlaceholder className="h-6 w-16 rounded-8 tablet:h-10 tablet:w-36 tablet:rounded-12" />
25-
</span>
17+
<WritePageMain className="gap-4 px-6 py-5">
18+
<ElementPlaceholder className="w h-12 rounded-12 laptop:max-w-70" />
19+
<ElementPlaceholder className="h-24 w-[11.5rem] rounded-16" />
20+
<ElementPlaceholder className="h-12 rounded-12" />
21+
<ElementPlaceholder className="h-[25.5rem] rounded-12" />
22+
23+
<ElementPlaceholder className="ml-auto h-6 w-16 rounded-8 tablet:h-10 tablet:w-32 tablet:rounded-12" />
2624
</WritePageMain>
2725
</WritePageContainer>
2826
);

packages/shared/src/components/post/freeform/write/WritePostHeader.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ export function WritePostHeader({
1414
const { squad } = useWritePostContext();
1515

1616
return (
17-
<header className="flex h-14 flex-row items-center border-b border-border-subtlest-tertiary px-6 py-4">
17+
<header className="flex h-16 flex-row items-center border-b border-border-subtlest-tertiary px-6 py-4">
1818
<h1 className="font-bold typo-title3">{isEdit ? 'Edit' : 'New'} post</h1>
1919

2020
{squad && squad.type === SourceType.Squad && (

packages/shared/src/components/profile/ProfileSettingsMenu.tsx

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ import {
3131
JobIcon,
3232
TerminalIcon,
3333
TourIcon,
34+
FeatherIcon,
3435
} from '../icons';
3536
import { NavDrawer } from '../drawers/NavDrawer';
3637
import {
@@ -112,6 +113,11 @@ const useAccountPageItems = () => {
112113
icon: NewTabIcon,
113114
href: `${settingsUrl}/appearance`,
114115
},
116+
composition: {
117+
title: 'Composition',
118+
icon: FeatherIcon,
119+
href: `${settingsUrl}/composition`,
120+
},
115121
notifications: {
116122
title: 'Notifications',
117123
icon: BellIcon,

packages/shared/src/components/tabs/TabContainer.tsx

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ export interface TabContainerProps<T extends string = string> {
5050
style?: CSSProperties;
5151
tabListProps?: Pick<TabListProps, 'className' | 'autoScrollActive'>;
5252
tabTag?: AllowedTabTags;
53+
extraHeaderContent?: ReactNode;
5354
}
5455

5556
export function TabContainer<T extends string = string>({
@@ -65,6 +66,7 @@ export function TabContainer<T extends string = string>({
6566
style,
6667
tabListProps = {},
6768
tabTag,
69+
extraHeaderContent,
6870
}: TabContainerProps<T>): ReactElement {
6971
const router = useRouter();
7072
const containerRef = useRef<HTMLDivElement>(null);
@@ -168,6 +170,7 @@ export function TabContainer<T extends string = string>({
168170
autoScrollActive={tabListProps?.autoScrollActive}
169171
tag={tabTag}
170172
/>
173+
{extraHeaderContent}
171174
</header>
172175
{render}
173176
</div>

packages/shared/src/contexts/SettingsContext.tsx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ import {
1717
CampaignCtaPlacement,
1818
UPDATE_USER_SETTINGS_MUTATION,
1919
} from '../graphql/settings';
20+
import { WriteFormTab } from '../components/fields/form/common';
2021
import AuthContext from './AuthContext';
2122
import { capitalize } from '../lib/strings';
2223
import { storageWrapper } from '../lib/storageWrapper';
@@ -136,6 +137,7 @@ const defaultSettings: RemoteSettings = {
136137
sidebarResourcesExpanded: true,
137138
sidebarBookmarksExpanded: true,
138139
clickbaitShieldEnabled: true,
140+
defaultWriteTab: WriteFormTab.NewPost,
139141
},
140142
};
141143

packages/shared/src/graphql/settings.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import { gql } from 'graphql-request';
22
import type { SortCommentsBy } from './comments';
3+
import type { WriteFormTab } from '../components/fields/form/common';
34

45
export type Spaciness = 'eco' | 'roomy' | 'cozy';
56
export type RemoteTheme = 'darcula' | 'bright' | 'auto';
@@ -19,6 +20,7 @@ export type SettingsFlags = {
1920
timezoneMismatchIgnore?: string;
2021
prompt?: Record<string, boolean>;
2122
lastPrompt?: string;
23+
defaultWriteTab?: WriteFormTab;
2224
};
2325

2426
export enum SidebarSettingsFlags {

packages/webapp/pages/settings/appearance.tsx

Lines changed: 13 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import {
1010
TypographyColor,
1111
TypographyType,
1212
} from '@dailydotdev/shared/src/components/typography/Typography';
13+
import type { RadioItemProps } from '@dailydotdev/shared/src/components/fields/Radio';
1314
import { Radio } from '@dailydotdev/shared/src/components/fields/Radio';
1415
import { ToggleRadio } from '@dailydotdev/shared/src/components/fields/ToggleRadio';
1516
import { useLogContext } from '@dailydotdev/shared/src/contexts/LogContext';
@@ -19,13 +20,14 @@ import {
1920
TargetType,
2021
} from '@dailydotdev/shared/src/lib/log';
2122
import classNames from 'classnames';
23+
import { FlexCol } from '@dailydotdev/shared/src/components/utilities';
2224
import { AccountPageContainer } from '../../components/layouts/SettingsLayout/AccountPageContainer';
2325
import { getSettingsLayout } from '../../components/layouts/SettingsLayout';
2426
import { defaultSeo } from '../../next-seo';
2527
import { getTemplatedTitle } from '../../components/layouts/utils';
2628
import { SettingsSwitch } from '../../components/layouts/SettingsLayout/common';
2729

28-
const densities = [
30+
const densities: RadioItemProps[] = [
2931
{ label: 'Eco', value: 'eco' },
3032
{ label: 'Roomy', value: 'roomy' },
3133
{ label: 'Cozy', value: 'cozy' },
@@ -64,11 +66,11 @@ const AccountManageSubscriptionPage = (): ReactElement => {
6466

6567
return (
6668
<AccountPageContainer title="Appearance">
67-
<div className="flex flex-col gap-6">
69+
<FlexCol className="gap-6">
6870
<ThemeSection />
6971

7072
{isLaptop && (
71-
<section className="flex flex-col gap-2">
73+
<FlexCol className="gap-2">
7274
<Typography bold type={TypographyType.Subhead}>
7375
Layout
7476
</Typography>
@@ -86,10 +88,10 @@ const AccountManageSubscriptionPage = (): ReactElement => {
8688
offLabel="Cards"
8789
onLabel="List"
8890
/>
89-
</section>
91+
</FlexCol>
9092
)}
9193

92-
<section className="flex flex-col gap-2">
94+
<FlexCol className="gap-2">
9395
<Typography bold type={TypographyType.Subhead}>
9496
Density
9597
</Typography>
@@ -119,9 +121,9 @@ const AccountManageSubscriptionPage = (): ReactElement => {
119121
}}
120122
reverse
121123
/>
122-
</section>
124+
</FlexCol>
123125

124-
<section className="flex flex-col gap-5">
126+
<FlexCol className="gap-5">
125127
<Typography bold type={TypographyType.Subhead}>
126128
Preferences
127129
</Typography>
@@ -149,9 +151,9 @@ const AccountManageSubscriptionPage = (): ReactElement => {
149151
>
150152
Show companion widget on external sites
151153
</SettingsSwitch>
152-
</section>
154+
</FlexCol>
153155

154-
<section className="flex flex-col gap-5">
156+
<FlexCol className="gap-5">
155157
<Typography bold type={TypographyType.Subhead}>
156158
Accessibility
157159
</Typography>
@@ -163,8 +165,8 @@ const AccountManageSubscriptionPage = (): ReactElement => {
163165
>
164166
Auto-hide notifications after a few seconds
165167
</SettingsSwitch>
166-
</section>
167-
</div>
168+
</FlexCol>
169+
</FlexCol>
168170
</AccountPageContainer>
169171
);
170172
};
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
import React from 'react';
2+
import type { ReactElement } from 'react';
3+
import type { NextSeoProps } from 'next-seo';
4+
5+
import { useSettingsContext } from '@dailydotdev/shared/src/contexts/SettingsContext';
6+
import {
7+
Typography,
8+
TypographyType,
9+
} from '@dailydotdev/shared/src/components/typography/Typography';
10+
import type { RadioItemProps } from '@dailydotdev/shared/src/components/fields/Radio';
11+
import { Radio } from '@dailydotdev/shared/src/components/fields/Radio';
12+
13+
import { WriteFormTab } from '@dailydotdev/shared/src/components/fields/form/common';
14+
import { FlexCol } from '@dailydotdev/shared/src/components/utilities';
15+
import { AccountPageContainer } from '../../components/layouts/SettingsLayout/AccountPageContainer';
16+
import { getSettingsLayout } from '../../components/layouts/SettingsLayout';
17+
import { defaultSeo } from '../../next-seo';
18+
import { getTemplatedTitle } from '../../components/layouts/utils';
19+
20+
const defaultWriteTabs: RadioItemProps[] = Object.keys(WriteFormTab).map(
21+
(key) => ({
22+
label: WriteFormTab[key],
23+
value: key,
24+
}),
25+
);
26+
27+
const AccountManageSubscriptionPage = (): ReactElement => {
28+
const { updateFlag, flags } = useSettingsContext();
29+
30+
return (
31+
<AccountPageContainer title="Composition">
32+
<div id="compose" aria-hidden />
33+
<FlexCol className="gap-2">
34+
<Typography bold type={TypographyType.Subhead}>
35+
Default post type
36+
</Typography>
37+
38+
<Radio
39+
name="default-write-tab"
40+
options={defaultWriteTabs}
41+
value={flags.defaultWriteTab}
42+
onChange={(value) => {
43+
updateFlag('defaultWriteTab', value);
44+
}}
45+
className={{
46+
content: 'w-full justify-between !pr-0',
47+
container: '!gap-0',
48+
label: 'font-normal text-text-secondary typo-callout',
49+
}}
50+
reverse
51+
/>
52+
</FlexCol>
53+
</AccountPageContainer>
54+
);
55+
};
56+
57+
const seo: NextSeoProps = {
58+
...defaultSeo,
59+
title: getTemplatedTitle('Appearance'),
60+
};
61+
62+
AccountManageSubscriptionPage.getLayout = getSettingsLayout;
63+
AccountManageSubscriptionPage.layoutProps = { seo };
64+
65+
export default AccountManageSubscriptionPage;

packages/webapp/pages/squads/create.tsx

Lines changed: 41 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -36,11 +36,19 @@ import { useQueryClient } from '@tanstack/react-query';
3636
import CreatePoll from '@dailydotdev/shared/src/components/post/poll/CreatePoll';
3737
import { Pill, PillSize } from '@dailydotdev/shared/src/components/Pill';
3838
import { useMultipleSourcePost } from '@dailydotdev/shared/src/features/squads/hooks/useMultipleSourcePost';
39-
import { webappUrl } from '@dailydotdev/shared/src/lib/constants';
39+
import { settingsUrl, webappUrl } from '@dailydotdev/shared/src/lib/constants';
4040
import type { WriteForm } from '@dailydotdev/shared/src/contexts';
41-
import { getLayout as getMainLayout } from '../../components/layouts/MainLayout';
42-
import { defaultOpenGraph, defaultSeo } from '../../next-seo';
41+
import { useSettingsContext } from '@dailydotdev/shared/src/contexts/SettingsContext';
42+
43+
import {
44+
Button,
45+
ButtonSize,
46+
} from '@dailydotdev/shared/src/components/buttons/Button';
47+
import { SettingsIcon } from '@dailydotdev/shared/src/components/icons';
48+
import { LinkWithTooltip } from '@dailydotdev/shared/src/components/tooltips/LinkWithTooltip';
4349
import { getTemplatedTitle } from '../../components/layouts/utils';
50+
import { defaultOpenGraph, defaultSeo } from '../../next-seo';
51+
import { getLayout as getMainLayout } from '../../components/layouts/MainLayout';
4452

4553
const seo: NextSeoProps = {
4654
title: getTemplatedTitle('Create post'),
@@ -59,6 +67,10 @@ function CreatePost(): ReactElement {
5967
);
6068
const { push, isReady: isRouteReady, query } = useRouter();
6169
const { squads, user, isAuthReady, isFetched } = useAuthContext();
70+
const {
71+
flags: { defaultWriteTab },
72+
loadedSettings,
73+
} = useSettingsContext();
6274
const [selectedSourceIds, setSelectedSourceIds] = useState<string[]>([]);
6375
const activeSquads = useMemo(() => {
6476
const collator = new Intl.Collator('en');
@@ -191,6 +203,8 @@ function CreatePost(): ReactElement {
191203
setDisplay(WriteFormTab.Share);
192204
} else if (isInitialPoll) {
193205
setDisplay(WriteFormTab.Poll);
206+
} else if (defaultWriteTab in WriteFormTab) {
207+
setDisplay(WriteFormTab[defaultWriteTab]);
194208
}
195209

196210
const preselectedSquad =
@@ -220,6 +234,7 @@ function CreatePost(): ReactElement {
220234
activeSquads,
221235
selectedSourceIds.length,
222236
query,
237+
defaultWriteTab,
223238
]);
224239

225240
useEffect(() => {
@@ -228,7 +243,7 @@ function CreatePost(): ReactElement {
228243
}
229244
}, [display, hasCheckedPollTab, completeAction]);
230245

231-
if (!isFetched || !isAuthReady || !isRouteReady) {
246+
if (!isFetched || !isAuthReady || !isRouteReady || !loadedSettings) {
232247
return <WriteFreeFormSkeleton />;
233248
}
234249

@@ -255,6 +270,28 @@ function CreatePost(): ReactElement {
255270
shouldMountInactive
256271
className={{ header: 'px-1' }}
257272
showHeader={isTablet}
273+
extraHeaderContent={
274+
!isMobile && (
275+
<LinkWithTooltip
276+
tooltip={{
277+
content: (
278+
<div className="max-w-48">
279+
You can change the default post type settings
280+
</div>
281+
),
282+
placement: 'left',
283+
}}
284+
href={`${settingsUrl}/composition`}
285+
passHref
286+
>
287+
<Button
288+
icon={<SettingsIcon />}
289+
size={ButtonSize.Small}
290+
className="ml-auto mr-3 self-center text-text-quaternary"
291+
/>
292+
</LinkWithTooltip>
293+
)
294+
}
258295
>
259296
<Tab
260297
label={WriteFormTab.NewPost}

0 commit comments

Comments
 (0)