Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,14 @@ import { useAuthContext } from '../../../../contexts/AuthContext';
import { ColorName } from '../../../../styles/colors';
import useProfileForm from '../../../../hooks/useProfileForm';
import { FeedType } from '../../../../graphql/feed';
import { usePlusSubscription } from '../../../../hooks';
import { usePlusSubscription, useToastNotification } from '../../../../hooks';
import { Tooltip } from '../../../tooltip/Tooltip';
import { Switch } from '../../../fields/Switch';
import { useSettingsContext } from '../../../../contexts/SettingsContext';
import { SidebarSettingsFlags } from '../../../../graphql/settings';
import { useLogContext } from '../../../../contexts/LogContext';
import { LogEvent, Origin, TargetId } from '../../../../lib/log';
import { labels } from '../../../../lib';

export const FeedSettingsGeneralSection = (): ReactElement => {
const { setData, data, feed, onDelete, editFeedSettings } = useContext(
Expand All @@ -31,6 +37,9 @@ export const FeedSettingsGeneralSection = (): ReactElement => {
const isMainFeed = feed?.type === FeedType.Main;
const isCustomFeed = feed?.type === FeedType.Custom;
const { isPlus } = usePlusSubscription();
const { flags, updateFlag } = useSettingsContext();
const { displayToast } = useToastNotification();
const { logEvent } = useLogContext();

const isDefaultFeed = isMainFeed
? user.defaultFeedId === null
Expand Down Expand Up @@ -167,6 +176,48 @@ export const FeedSettingsGeneralSection = (): ReactElement => {
</Tooltip>
)}
</div>
<Divider className="my-1 bg-border-subtlest-tertiary" />
<div className="flex flex-col gap-4">
<div className="flex flex-col gap-1">
<Typography bold type={TypographyType.Body}>
Pin highlights to top
</Typography>
<Typography
type={TypographyType.Callout}
color={TypographyColor.Tertiary}
>
When highlights appear in your feed, show them in the first
position. Otherwise they&apos;re placed somewhere near the top.
</Typography>
</div>
<Switch
inputId="highlights-first-switch"
name="highlights_first"
compact={false}
checked={flags?.highlightsFirstEnabled ?? false}
onClick={async () => {
const newState = !(flags?.highlightsFirstEnabled ?? false);
await updateFlag(
SidebarSettingsFlags.HighlightsFirstEnabled,
newState,
);

displayToast(
labels.feed.settings.globalPreferenceNotice.highlightsFirst,
);

logEvent({
event_name: LogEvent.ToggleHighlightsFirst,
target_id: newState ? TargetId.On : TargetId.Off,
extra: JSON.stringify({
origin: Origin.Settings,
}),
});
}}
>
Pin highlights to first position
</Switch>
</div>
{isCustomFeed && (
<>
<Divider className="my-1 bg-border-subtlest-tertiary" />
Expand Down
2 changes: 2 additions & 0 deletions packages/shared/src/graphql/settings.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ export type SettingsFlags = {
sidebarResourcesExpanded: boolean;
sidebarBookmarksExpanded: boolean;
clickbaitShieldEnabled: boolean;
highlightsFirstEnabled?: boolean;
timezoneMismatchIgnore?: string;
prompt?: Record<string, boolean>;
defaultWriteTab?: WriteFormTab;
Expand All @@ -65,6 +66,7 @@ export enum SidebarSettingsFlags {
ResourcesExpanded = 'sidebarResourcesExpanded',
BookmarksExpanded = 'sidebarBookmarksExpanded',
ClickbaitShieldEnabled = 'clickbaitShieldEnabled',
HighlightsFirstEnabled = 'highlightsFirstEnabled',
}

export type RemoteSettings = {
Expand Down
2 changes: 2 additions & 0 deletions packages/shared/src/lib/labels.ts
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,8 @@ export const labels = {
globalPreferenceNotice: {
clickbaitShield: 'Clickbait shield has been applied for all feeds',
contentLanguage: 'New language preferences set for all feeds',
highlightsFirst:
'Highlights pinning preference applied to all your feeds',
},
},
},
Expand Down
1 change: 1 addition & 0 deletions packages/shared/src/lib/log.ts
Original file line number Diff line number Diff line change
Expand Up @@ -339,6 +339,7 @@ export enum LogEvent {
ToggleClickbaitShield = 'toggle clickbait shield',
ClickbaitShieldTitle = 'clickbait shield title',
// End Clickbait Shield
ToggleHighlightsFirst = 'toggle highlights first',
InstallPWA = 'install pwa',
// Start Share
ShareProfile = 'share profile',
Expand Down
6 changes: 6 additions & 0 deletions scripts/typecheck-strict-changed.js
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,12 @@ const strictSkipList = new Set([
// path; pre-existing strict violations (queryResult.data optionality,
// NotificationItem reduce typing) are unrelated to the rename.
'packages/webapp/pages/notifications.tsx',
// Highlights-first toggle — touched only to add a new Switch subsection
// for the highlightsFirstEnabled flag. Pre-existing strict violations
// (auth user / feed optionality, Button prop mismatches, defaultFeedId
// null vs undefined) live on unrelated lines and should be addressed in
// a dedicated cleanup PR.
'packages/shared/src/components/feeds/FeedSettings/sections/FeedSettingsGeneralSection.tsx',
]);

const changedFiles = getChangedTypescriptFiles().filter(
Expand Down
Loading