Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add subscribed icon #1573

Merged
merged 3 commits into from
Aug 10, 2024
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
52 changes: 48 additions & 4 deletions src/features/labels/links/CommunityLink.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,17 @@ import { Community, SubscribedType } from "lemmy-js-client";
import { renderHandle } from "../Handle";
import { LinkContainer, StyledLink, hideCss } from "./shared";
import ItemIcon from "../img/ItemIcon";
import { useIonActionSheet } from "@ionic/react";
import { IonIcon, useIonActionSheet } from "@ionic/react";
import { LongPressOptions, useLongPress } from "use-long-press";
import {
heart,
heartDislikeOutline,
heartOutline,
removeCircleOutline,
tabletPortraitOutline,
} from "ionicons/icons";
import useCommunityActions from "../../community/useCommunityActions";
import { useCallback, useContext } from "react";
import { createContext, useCallback, useContext } from "react";
import { ShareImageContext } from "../../share/asImage/ShareAsImage";
import {
preventOnClickNavigationBug,
Expand All @@ -22,12 +23,28 @@ import {
import { styled } from "@linaria/react";
import { cx } from "@linaria/core";
import { useAppSelector } from "../../../store";
import { OShowSubscribedIcon } from "../../../services/db";

const StyledItemIcon = styled(ItemIcon)`
margin-right: 0.4rem;
vertical-align: middle;
`;

const SubscribedIcon = styled(IonIcon)`
color: var(--ion-color-danger);
vertical-align: middle;
font-size: 0.85em;

margin-bottom: 1px;
margin-left: 2px;

opacity: 0.4;

.ion-palette-dark & {
opacity: 0.5;
}
`;

interface CommunityLinkProps {
community: Community;
showInstanceWhenRemote?: boolean;
Expand Down Expand Up @@ -55,6 +72,7 @@ export default function CommunityLink({
const showCommunityIcons = useAppSelector(
(state) => state.settings.appearance.posts.showCommunityIcons,
);
const showSubscribed = useShowSubscribedIcon();

const { isSubscribed, isBlocked, subscribe, block, sidebar } =
useCommunityActions(community, subscribed);
Expand Down Expand Up @@ -106,6 +124,13 @@ export default function CommunityLink({
showInstanceWhenRemote,
});

const end = (
<>
{instance}
{showSubscribed && isSubscribed && <SubscribedIcon icon={heart} />}
</>
);

return (
<LinkContainer
{...bind()}
Expand All @@ -117,19 +142,38 @@ export default function CommunityLink({
e.stopPropagation();
preventOnClickNavigationBug(e);
}}
draggable={false}
>
{showCommunityIcons && !hideCommunity && !hideIcon && (
<StyledItemIcon item={community} size={tinyIcon ? 16 : 24} />
)}

{name}
{!disableInstanceClick && instance}
{!disableInstanceClick && end}
</StyledLink>
{disableInstanceClick && instance}
{disableInstanceClick && end}
</LinkContainer>
);
}

const onStart: LongPressOptions["onStart"] = (e) => {
e.stopPropagation();
};

function useShowSubscribedIcon() {
const feedEnabled = useContext(ShowSubscribedIconContext);
const subscribedIcon = useAppSelector(
(state) => state.settings.general.subscribedIcon,
);

switch (subscribedIcon) {
case OShowSubscribedIcon.OnlyAllLocal:
return feedEnabled;
case OShowSubscribedIcon.Never:
return false;
case OShowSubscribedIcon.Everywhere:
return true;
}
}

export const ShowSubscribedIconContext = createContext(false);
1 change: 1 addition & 0 deletions src/features/labels/links/PersonLink.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,7 @@ export default function PersonLink({
e.stopPropagation();
preventOnClickNavigationBug(e);
}}
draggable={false}
>
{prefix ? (
<>
Expand Down
2 changes: 2 additions & 0 deletions src/features/settings/general/other/Other.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import OpenNativeApps from "./OpenNativeApps";
import ClearCache from "./ClearCache";
import BackupSettings from "./backup/BackupSettings";
import Thumbnailinator from "./Thumbnailinator";
import SubscribedIcon from "./SubscribedIcon";

export default function Other() {
return (
Expand All @@ -24,6 +25,7 @@ export default function Other() {
<Haptics />
<NoSubscribedInFeed />
<Thumbnailinator />
<SubscribedIcon />
<ClearCache />
<BackupSettings />
</IonList>
Expand Down
24 changes: 24 additions & 0 deletions src/features/settings/general/other/SubscribedIcon.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import { startCase } from "lodash";
import { OShowSubscribedIcon } from "../../../../services/db";
import { useAppSelector } from "../../../../store";
import { setSubscribedIcon } from "../../settingsSlice";
import SettingSelector from "../../shared/SettingSelector";

export default function SubscribedIcon() {
const subscribedIcon = useAppSelector(
(state) => state.settings.general.subscribedIcon,
);

return (
<SettingSelector
title="Show Subscribed Icon"
selected={subscribedIcon}
setSelected={setSubscribedIcon}
options={OShowSubscribedIcon}
getOptionLabel={(option) => {
if (option === OShowSubscribedIcon.OnlyAllLocal) return "All/Local";
return startCase(option);
}}
/>
);
}
13 changes: 13 additions & 0 deletions src/features/settings/settingsSlice.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,8 @@ import {
OAutoplayMediaType,
CommentsThemeType,
VotesThemeType,
ShowSubscribedIcon,
OShowSubscribedIcon,
} from "../../services/db";
import { LOCALSTORAGE_KEYS, get, set } from "./syncStorage";
import { Mode } from "@ionic/core";
Expand Down Expand Up @@ -136,6 +138,7 @@ interface SettingsState {
defaultFeed: DefaultFeedType | undefined;
noSubscribedInFeed: boolean;
thumbnailinatorEnabled: boolean;
subscribedIcon: ShowSubscribedIcon;
};
blocks: {
keywords: string[];
Expand Down Expand Up @@ -222,6 +225,7 @@ export const initialState: SettingsState = {
defaultFeed: undefined,
noSubscribedInFeed: false,
thumbnailinatorEnabled: true,
subscribedIcon: OShowSubscribedIcon.Never,
},
blocks: {
keywords: [],
Expand Down Expand Up @@ -532,6 +536,11 @@ export const appearanceSlice = createSlice({

db.setSetting("prefer_native_apps", action.payload);
},
setSubscribedIcon(state, action: PayloadAction<ShowSubscribedIcon>) {
state.general.subscribedIcon = action.payload;

db.setSetting("subscribed_icon", action.payload);
},

resetSettings: () => ({
...initialState,
Expand Down Expand Up @@ -722,6 +731,7 @@ export const fetchSettingsFromDatabase = createAsyncThunk<SettingsState>(
const quick_switch_dark_mode = await db.getSetting(
"quick_switch_dark_mode",
);
const subscribed_icon = await db.getSetting("subscribed_icon");

return {
...state.settings,
Expand Down Expand Up @@ -864,6 +874,8 @@ export const fetchSettingsFromDatabase = createAsyncThunk<SettingsState>(
thumbnailinatorEnabled:
thumbnailinator_enabled ??
initialState.general.thumbnailinatorEnabled,
subscribedIcon:
subscribed_icon ?? initialState.general.subscribedIcon,
},
blocks: {
keywords: filtered_keywords ?? initialState.blocks.keywords,
Expand Down Expand Up @@ -944,6 +956,7 @@ export const {
setAlwaysUseReaderMode,
setShowCollapsedComment,
setQuickSwitchDarkMode,
setSubscribedIcon,
} = appearanceSlice.actions;

export default appearanceSlice.reducer;
1 change: 1 addition & 0 deletions src/features/settings/shared/SettingSelector.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@ export default function SettingSelector<
<IonLabel className="ion-text-nowrap">{title}</IonLabel>
<IonLabel slot="end" color="medium" className="ion-no-margin">
{getSelectedLabel?.(selected) ??
getOptionLabel?.(selected) ??
(typeof selected === "string" ? startCase(selected) : selected)}
</IonLabel>
<IonActionSheet
Expand Down
21 changes: 12 additions & 9 deletions src/routes/pages/shared/SpecialFeedPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ import PostAppearanceProvider, {
} from "../../../features/post/appearance/PostAppearanceProvider";
import { CenteredSpinner } from "../../../features/shared/CenteredSpinner";
import useFeedUpdate from "../../../features/feed/useFeedUpdate";
import { ShowSubscribedIconContext } from "../../../features/labels/links/CommunityLink";

interface SpecialFeedProps {
type: ListingType;
Expand Down Expand Up @@ -93,15 +94,17 @@ export default function SpecialFeedPage({ type }: SpecialFeedProps) {
if (!sort) return <CenteredSpinner />;

return (
<PageTypeContext.Provider value="special-feed">
<WaitUntilPostAppearanceResolved>
<PostCommentFeed
fetchFn={fetchFn}
sortDuration={getSortDuration(sort)}
filterOnRxFn={filterSubscribed ? filterSubscribedFn : undefined}
/>
</WaitUntilPostAppearanceResolved>
</PageTypeContext.Provider>
<ShowSubscribedIconContext.Provider value={type !== "Subscribed"}>
<PageTypeContext.Provider value="special-feed">
<WaitUntilPostAppearanceResolved>
<PostCommentFeed
fetchFn={fetchFn}
sortDuration={getSortDuration(sort)}
filterOnRxFn={filterSubscribed ? filterSubscribedFn : undefined}
/>
</WaitUntilPostAppearanceResolved>
</PageTypeContext.Provider>
</ShowSubscribedIconContext.Provider>
);
})();

Expand Down
10 changes: 10 additions & 0 deletions src/services/db.ts
Original file line number Diff line number Diff line change
Expand Up @@ -172,6 +172,15 @@ export const OLinkHandlerType = {
InApp: "in-app",
} as const;

export type ShowSubscribedIcon =
(typeof OShowSubscribedIcon)[keyof typeof OShowSubscribedIcon];

export const OShowSubscribedIcon = {
Never: "never",
OnlyAllLocal: "all-local",
Everywhere: "everywhere",
} as const;

export type DefaultFeedType =
| {
type:
Expand Down Expand Up @@ -351,6 +360,7 @@ export type SettingValueTypes = {
autoplay_media: AutoplayMediaType;
show_collapsed_comment: boolean;
quick_switch_dark_mode: boolean;
subscribed_icon: ShowSubscribedIcon;
};

export interface ISettingItem<T extends keyof SettingValueTypes> {
Expand Down