Skip to content

Commit

Permalink
image sharing options
Browse files Browse the repository at this point in the history
  • Loading branch information
gkasdorf committed Oct 21, 2023
1 parent 9df8ad0 commit c661489
Show file tree
Hide file tree
Showing 14 changed files with 205 additions and 49 deletions.
2 changes: 1 addition & 1 deletion assets/license.html

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,9 @@ export default function CommentContextMenu({
case 'edit':
commentContextMenu.edit();
break;
case 'share':
commentContextMenu.share();
break;
}
},
[commentContextMenu],
Expand Down
14 changes: 13 additions & 1 deletion src/components/Common/ContextMenu/components/PostContextMenu.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import React, { useCallback, useMemo } from 'react';
import { usePostContextMenu } from '@components/Common/ContextMenu/hooks';
import { usePostIsOwn, usePostModerates } from '@src/state';
import { usePostIsOwn, usePostLinkType, usePostModerates } from '@src/state';
import { createPostContextMenuOptions } from '@helpers/contextMenu/createPostContextMenuOptions';
import { OnPressMenuItemEventObject } from 'react-native-ios-context-menu';
import { AppContextMenuButton } from '@components/Common/ContextMenu/AppContextMenuButton';
Expand All @@ -15,6 +15,8 @@ export default function PostContextMenu({
children,
}: IProps): React.JSX.Element {
const postContextMenu = usePostContextMenu(itemId);

const postLinkType = usePostLinkType(itemId);
const moderates = usePostModerates(itemId);
const isOwn = usePostIsOwn(itemId);

Expand All @@ -23,6 +25,7 @@ export default function PostContextMenu({
createPostContextMenuOptions({
moderates,
isOwnPost: isOwn,
isImage: postLinkType === 'image',
}),
[itemId],
);
Expand Down Expand Up @@ -51,6 +54,15 @@ export default function PostContextMenu({
case 'report':
postContextMenu.report();
break;
case 'share':
postContextMenu.share();
break;
case 'shareImage':
postContextMenu.shareImage();
break;
case 'saveImage':
postContextMenu.savePostImage();
break;
}
},
[postContextMenu],
Expand Down
21 changes: 21 additions & 0 deletions src/components/Common/ContextMenu/hooks/useCommentContextMenu.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,12 @@ import { useNavigation } from '@react-navigation/core';
import { NativeStackNavigationProp } from '@react-navigation/native-stack';
import { Alert } from 'react-native';
import { useThemeColorScheme } from '@src/hooks';
import {
useCommentCreatorActorId,
useCommentPostId,
usePostTitle,
} from '@src/state';
import { shareLink } from '@helpers/share/shareLink';

interface UseCommentContextMenu {
reply: () => void;
Expand All @@ -13,6 +19,7 @@ interface UseCommentContextMenu {
delet: () => void;
remove: () => void;
report: () => void;
share: () => void;
}

export const useCommentContextMenu = (
Expand All @@ -21,6 +28,19 @@ export const useCommentContextMenu = (
const navigation = useNavigation<NativeStackNavigationProp<any>>();
const colorScheme = useThemeColorScheme();

const postId = useCommentPostId(itemId);
const postTitle = usePostTitle(postId ?? 0);
const commentLink = useCommentCreatorActorId(itemId);

const share = (): void => {
if (postTitle == null || commentLink == null) return;

void shareLink({
title: postTitle ?? 'Comment',
link: commentLink,
});
};

const reply = (): void => {
navigation.push('Reply', {
commentId: itemId,
Expand Down Expand Up @@ -130,6 +150,7 @@ export const useCommentContextMenu = (
};

return {
share,
reply,
upvote,
downvote,
Expand Down
48 changes: 47 additions & 1 deletion src/components/Common/ContextMenu/hooks/usePostContextMenu.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,17 @@ import { useNavigation } from '@react-navigation/core';
import { NativeStackNavigationProp } from '@react-navigation/native-stack';
import { useThemeColorScheme } from '@src/hooks';
import instance from '@src/Instance';
import { setToast, usePostCommunityId } from '@src/state';
import {
setToast,
usePostActorId,
usePostCommunityId,
usePostLink,
usePostTitle,
} from '@src/state';
import { Alert } from 'react-native';
import { CheckCircle } from '@tamagui/lucide-icons';
import { shareLink } from '@helpers/share/shareLink';
import { saveImage } from '@helpers/image';

interface UsePostContextMenu {
reply: () => void;
Expand All @@ -15,13 +23,48 @@ interface UsePostContextMenu {
delet: () => void;
remove: () => void;
report: () => void;
share: () => void;
savePostImage: () => void;
shareImage: () => void;
}

export const usePostContextMenu = (itemId: number): UsePostContextMenu => {
const navigation = useNavigation<NativeStackNavigationProp<any>>();

const communityId = usePostCommunityId(itemId);
const postTitle = usePostTitle(itemId);
const postActorId = usePostActorId(itemId);
const postLink = usePostLink(itemId);

const colorScheme = useThemeColorScheme();

const share = (): void => {
if (postTitle == null || postActorId == null) {
return;
}

void shareLink({
title: postTitle,
link: postActorId,
});
};

const savePostImage = (): void => {
if (postLink == null) return;

void saveImage(postLink);
};

const shareImage = (): void => {
if (postTitle == null || postLink == null) return;

void shareLink({
title: postTitle,
link: postLink,
isImage: true,
});
};

const reply = (): void => {
navigation.push('Reply', {
postId: itemId,
Expand Down Expand Up @@ -139,6 +182,9 @@ export const usePostContextMenu = (itemId: number): UsePostContextMenu => {
};

return {
share,
shareImage,
savePostImage,
reply,
upvote,
downvote,
Expand Down
42 changes: 16 additions & 26 deletions src/components/Common/ImageViewer/ImageViewer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ import {
GestureUpdateEvent,
PanGestureHandlerEventPayload,
PinchGestureHandlerEventPayload,
TapGestureHandlerEventPayload,
} from 'react-native-gesture-handler';
import Animated, {
cancelAnimation,
Expand Down Expand Up @@ -139,26 +138,23 @@ function ImageViewer(): React.JSX.Element {
);

// <editor-fold desc="Double Tap Zomo">
const onDoubleTap = useCallback(
(event: GestureUpdateEvent<TapGestureHandlerEventPayload>): void => {
'worklet';
const onDoubleTap = useCallback((): void => {
'worklet';

runOnJS(setAccessoriesVisible)(false);
runOnJS(setAccessoriesVisible)(false);

// If the image is already zoomed, let's just reset it
if (zoomScale.value !== 1) {
centerImage();
zoomScale.value = withTiming(1, { duration: 200 });
lastScale.value = 1;
return;
}
// If the image is already zoomed, let's just reset it
if (zoomScale.value !== 1) {
centerImage();
zoomScale.value = withTiming(1, { duration: 200 });
lastScale.value = 1;
return;
}

// Zoom to the max scale
zoomScale.value = withTiming(1.75, { duration: 200 });
lastScale.value = 1.75;
},
[],
);
// Zoom to the max scale
zoomScale.value = withTiming(1.75, { duration: 200 });
lastScale.value = 1.75;
}, []);

// Create the double tap gesture
const doubleTapGesture = useMemo(
Expand Down Expand Up @@ -315,10 +311,7 @@ function ImageViewer(): React.JSX.Element {
return (
<View flex={1}>
<AppToast />
<ImageViewerHeader
title={imageViewer.params?.title ?? 'Image'}
visible={accessoriesVisible}
/>
<ImageViewerHeader visible={accessoriesVisible} />
<GestureDetector gesture={allGestures}>
<YStack zIndex={-1} flex={1}>
<Animated.View style={[styles.imageModal, backgroundStyle]}>
Expand All @@ -333,10 +326,7 @@ function ImageViewer(): React.JSX.Element {
</YStack>
</GestureDetector>

<ImageViewerFooter
source={imageViewer.params?.source}
visible={accessoriesVisible}
/>
<ImageViewerFooter visible={accessoriesVisible} />
</View>
);
}
Expand Down
29 changes: 21 additions & 8 deletions src/components/Common/ImageViewer/ImageViewerFooter.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,21 +4,29 @@ import AnimatedIconButton from '@components/Common/Button/AnimatedIconButton';
import { Save, Share } from '@tamagui/lucide-icons';
import { XStack, YStack } from 'tamagui';
import { saveImage } from '@helpers/image';
import { shareLink } from '@helpers/share/shareLink';
import { useImageViewer } from '@components/Common/ImageViewer/ImageViewerProvider';

interface IProps {
visible: boolean;
source: string | undefined;
}

function ImageViewerFooter({
visible,
source,
}: IProps): React.JSX.Element | null {
function ImageViewerFooter({ visible }: IProps): React.JSX.Element | null {
const imageViewer = useImageViewer();

if (!visible) return null;

const onImageSave = useCallback(() => {
void saveImage(source!);
}, [source]);
void saveImage(imageViewer.params!.source!);
}, [imageViewer.params?.source]);

const onSharePress = useCallback(() => {
void shareLink({
title: imageViewer.params?.title ?? 'Image',
link: imageViewer.params!.source!,
isImage: true,
});
}, [imageViewer.params?.source]);

return (
<Animated.View entering={FadeIn} exiting={FadeOut}>
Expand All @@ -37,7 +45,12 @@ function ImageViewerFooter({
iconSize={24}
onPress={onImageSave}
/>
<AnimatedIconButton icon={Share} color="white" iconSize={24} />
<AnimatedIconButton
icon={Share}
color="white"
iconSize={24}
onPress={onSharePress}
/>
</XStack>
</YStack>
</Animated.View>
Expand Down
8 changes: 2 additions & 6 deletions src/components/Common/ImageViewer/ImageViewerHeader.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,9 @@ import { useImageViewer } from '@components/Common/ImageViewer/ImageViewerProvid

interface IProps {
visible: boolean;
title: string;
}

function ImageViewerHeader({
visible,
title,
}: IProps): React.JSX.Element | null {
function ImageViewerHeader({ visible }: IProps): React.JSX.Element | null {
const imageViewer = useImageViewer();

const onExitPress = useCallback(() => {
Expand All @@ -33,7 +29,7 @@ function ImageViewerHeader({
>
<XStack top={80} flex={1} px="$3">
<Text fontSize="$6" fontWeight="bold" numberOfLines={1} color="white">
{title}
{imageViewer.params?.title ?? 'Image'}
</Text>
</XStack>
</YStack>
Expand Down
2 changes: 0 additions & 2 deletions src/components/Reply/hooks/useReplyScreen.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -50,8 +50,6 @@ export const useReplyScreen = (isEdit = false): UseReplyScreen => {

const { postId, commentId, replyId, mentionId } = route.params;

console.log(route.params);

const commentPostId = useCommentPostId(commentId);
const account = useCurrentAccount();

Expand Down
21 changes: 21 additions & 0 deletions src/helpers/contextMenu/createPostContextMenuOptions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { PostContextMenuOption } from '@src/types/contextMenu';
interface CreatePostContextMenuOptionsParams {
moderates: boolean;
isOwnPost: boolean;
isImage: boolean;
}

export const createPostContextMenuOptions = (
Expand All @@ -20,6 +21,26 @@ export const createPostContextMenuOptions = (
title: 'Share',
icon: 'square.and.arrow.up',
},
];

if (params.isImage) {
arr = [
...arr,
{
key: 'shareImage',
title: 'Share Image',
icon: 'photo',
},
{
key: 'saveImage',
title: 'Save Image',
icon: 'square.and.arrow.down',
},
];
}

arr = [
...arr,
{
key: 'upvote',
title: 'Upvote',
Expand Down
Loading

0 comments on commit c661489

Please sign in to comment.