diff --git a/assets/license.html b/assets/license.html index 7678ceda7..0671d836d 100644 --- a/assets/license.html +++ b/assets/license.html @@ -45,6 +45,6 @@ padding: 15px; } -
namelicense typelinkinstalled versionauthor
@react-native-async-storage/async-storageMITgit+https://github.com/react-native-async-storage/async-storage.git1.19.3Krzysztof Borowy
@react-native/metro-configMITgit+https://github.com/facebook/react-native.git0.74.0n/a
@react-navigation/bottom-tabsMITgit+https://github.com/react-navigation/react-navigation.git7.0.0-alpha.5n/a
@react-navigation/material-top-tabsMITgit+https://github.com/react-navigation/react-navigation.git7.0.0-alpha.4n/a
@react-navigation/nativeMITgit+https://github.com/react-navigation/react-navigation.git7.0.0-alpha.4n/a
@react-navigation/native-stackMITgit+https://github.com/react-navigation/react-navigation.git7.0.0-alpha.5n/a
@shopify/flash-listMITgit+https://github.com/Shopify/flash-list.git1.6.1shopify
@tamagui/confign/ahttps://registry.npmjs.org/@tamagui/config/-/config-1.74.17.tgz1.74.15n/a
@tamagui/lucide-iconsMIThttps://registry.npmjs.org/@tamagui/lucide-icons/-/lucide-icons-1.74.17.tgz1.74.15n/a
@tamagui/theme-buildern/ahttps://registry.npmjs.org/@tamagui/theme-builder/-/theme-builder-1.74.17.tgz1.74.15n/a
@types/lodashMIThttps://github.com/DefinitelyTyped/DefinitelyTyped.git4.14.199n/a
@types/markdown-itMIThttps://github.com/DefinitelyTyped/DefinitelyTyped.git13.0.2n/a
@types/reactMIThttps://github.com/DefinitelyTyped/DefinitelyTyped.git18.2.28n/a
axiosMITgit+https://github.com/axios/axios.git1.5.1Matt Zabriskie
babel-plugin-module-resolverMITgit+https://github.com/tleunen/babel-plugin-module-resolver.git5.0.0Tommy Leunen tommy.leunen@gmail.com http://tommyleunen.com
dayjsMITgit+https://github.com/iamkun/dayjs.git1.11.10iamkun
expoMITgit+https://github.com/expo/expo.git49.0.13Expo
expo-blurMITgit+https://github.com/expo/expo.git12.6.0650 Industries, Inc.
expo-build-propertiesMITgit+https://github.com/expo/expo.git0.8.3650 Industries, Inc.
expo-clipboardMITgit+https://github.com/expo/expo.git4.5.0650 Industries, Inc.
expo-dev-clientMITgit+https://github.com/expo/expo.git2.4.11650 Industries, Inc.
expo-file-systemMITgit+https://github.com/expo/expo.git15.6.0650 Industries, Inc.
expo-imageMITgit+https://github.com/expo/expo.git1.5.1650 Industries, Inc.
expo-image-pickerMITgit+https://github.com/expo/expo.git14.5.0650 Industries, Inc.
expo-linear-gradientMITgit+https://github.com/expo/expo.git12.3.0650 Industries, Inc.
expo-linkingMITgit+https://github.com/expo/expo.git6.0.0650 Industries, Inc.
expo-localizationMITgit+https://github.com/expo/expo.git14.5.0650 Industries, Inc.
expo-mail-composerMITgit+https://github.com/expo/expo.git12.5.0650 Industries, Inc.
expo-media-libraryMITgit+https://github.com/expo/expo.git15.6.0650 Industries, Inc.
expo-permissionsMITgit+https://github.com/expo/expo.git14.4.0650 Industries, Inc.
expo-splash-screenMITgit+https://github.com/expo/expo.git0.22.0650 Industries, Inc.
expo-status-barMITgit+https://github.com/expo/expo.git1.7.1650 Industries, Inc.
expo-system-uiMITgit+https://github.com/expo/expo.git2.6.0650 Industries, Inc.
expo-web-browserMITgit+https://github.com/expo/expo.git12.5.0650 Industries, Inc.
fuse.jsApache-2.0git+https://github.com/krisk/Fuse.git6.6.2Kiro Risk kirollos@gmail.com http://kiro.me
i18nextMITgit+https://github.com/i18next/i18next.git23.5.1Jan Mühlemann (https://github.com/jamuhl)
immerMITgit+https://github.com/immerjs/immer.git10.0.3Michel Weststrate
lemmy-js-clientAGPL-3.0git+https://github.com/LemmyNet/lemmy-js-client.git0.18.1Dessalines
lodashMITgit+https://github.com/lodash/lodash.git4.17.21John-David Dalton
markdown-itMITgit+https://github.com/markdown-it/markdown-it.git13.0.2n/a
motiMITgit+https://github.com/nandorojo/moti.git0.27.0n/a
reactMITgit+https://github.com/facebook/react.git18.2.0n/a
react-domMITgit+https://github.com/facebook/react.git18.2.0n/a
react-error-boundaryMITgit+https://github.com/bvaughn/react-error-boundary.git4.0.11Brian Vaughn
react-i18nextMITgit+https://github.com/i18next/react-i18next.git13.2.2Jan Mühlemann (https://github.com/jamuhl)
react-nativeMITgit+https://github.com/facebook/react-native.git0.72.5n/a
react-native-change-iconMITgit+https://github.com/skb1129/react-native-change-icon.git5.0.0Surya Kant Bansal (https://github.com/skb1129)
react-native-device-infoMITgit+https://github.com/react-native-device-info/react-native-device-info.git10.11.0Rebecca Hughes (https://github.com/rebeccahughes)
react-native-fsMITgit+ssh://git@github.com/itinance/react-native-fs.git2.20.0Johannes Lumpe (https://github.com/johanneslumpe)
react-native-gesture-handlerMITgit+https://github.com/software-mansion/react-native-gesture-handler.git2.13.2Krzysztof Magiera krzys.magiera@gmail.com
react-native-haptic-feedbackMITgit+https://github.com/mkuczera/react-native-haptic-feedback.git2.2.0Michael Kuczera
react-native-ios-context-menuMITgit+https://github.com/indominicstop/react-native-ios-context-menu.git1.15.3Dominic Go <18517029+dominicstop@users.noreply.github.com> (https://github.com/dominicstop)
react-native-keyboard-aware-scroll-viewMITgit+https://github.com/APSL/react-native-keyboard-aware-scroll-view.git0.9.5Alvaro Medina Ballester
react-native-linear-gradientMITgit+https://github.com/react-native-linear-gradient/react-native-linear-gradient.git2.8.3Brent Vatne (https://github.com/brentvatne)
react-native-material-tabsMITgit+https://github.com/iRoachie/react-native-material-tabs.git4.2.0Kyle Roach kroach.work@gmail.com
react-native-pager-viewMITgit+https://github.com/callstack/react-native-pager-view.git7.0.0-rc.0troZee (https://github.com/callstack)
react-native-reanimatedMITgit+https://github.com/software-mansion/react-native-reanimated.git3.3.0Krzysztof Magiera krzys.magiera@gmail.com
react-native-safe-area-contextMITgit+https://github.com/th3rdwave/react-native-safe-area-context.git4.7.2Janic Duplessis
react-native-screensMITgit+https://github.com/software-mansion/react-native-screens.git3.25.0Krzysztof Magiera krzys.magiera@gmail.com
react-native-shareMITgit+https://github.com/react-native-community/react-native-share.git9.4.1Esteban Fuentealba efuentealba@json.cl
react-native-svgMITgit+https://github.com/react-native-community/react-native-svg.git13.14.0n/a
react-native-webMITgit://github.com/necolas/react-native-web.git0.19.9Nicolas Gallagher
react-native-webviewMITgit+https://github.com/react-native-webview/react-native-webview.git13.6.2Jamon Holmgren
react-navigation-header-buttonsMITgit+https://github.com/vonovak/react-navigation-header-buttons.git11.1.0Vojtech Novak (https://github.com/vonovak)
reactotron-plugin-zustandMITgit+https://github.com/joalisonpereira/reactotron-plugin-zustand.git1.0.3joalisonpereira
tamaguin/ahttps://registry.npmjs.org/tamagui/-/tamagui-1.74.17.tgz1.74.15n/a
zustandMITgit+https://github.com/pmndrs/zustand.git4.4.3Paul Henschel
@babel/coreMIThttps://github.com/babel/babel.git7.23.2The Babel Team (https://babel.dev/team)
@typescript-eslint/eslint-pluginMITgit+https://github.com/typescript-eslint/typescript-eslint.git6.7.5n/a
eslintMITgit+https://github.com/eslint/eslint.git8.51.0Nicholas C. Zakas
eslint-config-prettierMITgit+https://github.com/prettier/eslint-config-prettier.git9.0.0Simon Lydell
eslint-config-standard-with-typescriptMITgit+https://github.com/standard/eslint-config-standard-with-typescript.git39.1.1Shahar Or (mightyiam)
eslint-plugin-importMITgit+https://github.com/import-js/eslint-plugin-import.git2.28.1Ben Mosher
eslint-plugin-nMITgit+https://github.com/eslint-community/eslint-plugin-n.git16.2.0Toru Nagashima
eslint-plugin-prettierMITgit+https://github.com/prettier/eslint-plugin-prettier.git5.0.1Teddy Katz
eslint-plugin-promiseISCgit+https://github.com/eslint-community/eslint-plugin-promise.git6.1.1jden
eslint-plugin-reactMITgit+https://github.com/jsx-eslint/eslint-plugin-react.git7.33.2Yannick Croissant
prettierMITgit+https://github.com/prettier/prettier.git3.0.3James Long
reactotron-react-nativeMITgit+https://github.com/infinitered/reactotron-react-native.git5.0.3Infinite Red
typescriptApache-2.0git+https://github.com/Microsoft/TypeScript.git5.2.2Microsoft Corp.
+
namelicense typelinkinstalled versionauthor
@react-native-async-storage/async-storageMITgit+https://github.com/react-native-async-storage/async-storage.git1.19.3Krzysztof Borowy
@react-native-community/sliderMITgit+https://github.com/callstack/react-native-slider.git4.4.3react-native-community
@react-native-picker/pickerMITgit+https://github.com/react-native-picker/picker.git2.5.1
@react-native/metro-configMITgit+https://github.com/facebook/react-native.git0.74.0n/a
@react-navigation/bottom-tabsMITgit+https://github.com/react-navigation/react-navigation.git7.0.0-alpha.5n/a
@react-navigation/material-top-tabsMITgit+https://github.com/react-navigation/react-navigation.git7.0.0-alpha.4n/a
@react-navigation/nativeMITgit+https://github.com/react-navigation/react-navigation.git7.0.0-alpha.4n/a
@react-navigation/native-stackMITgit+https://github.com/react-navigation/react-navigation.git7.0.0-alpha.5n/a
@shopify/flash-listMITgit+https://github.com/Shopify/flash-list.git1.6.1shopify
@tamagui/animations-react-nativeMIThttps://registry.npmjs.org/@tamagui/animations-react-native/-/animations-react-native-1.74.21.tgz1.74.19n/a
@tamagui/confign/ahttps://registry.npmjs.org/@tamagui/config/-/config-1.74.21.tgz1.74.19n/a
@tamagui/lucide-iconsMIThttps://registry.npmjs.org/@tamagui/lucide-icons/-/lucide-icons-1.74.21.tgz1.74.19n/a
@tamagui/theme-buildern/ahttps://registry.npmjs.org/@tamagui/theme-builder/-/theme-builder-1.74.21.tgz1.74.19n/a
@tamagui/themesn/ahttps://registry.npmjs.org/@tamagui/themes/-/themes-1.74.21.tgz1.74.21n/a
@types/lodashMIThttps://github.com/DefinitelyTyped/DefinitelyTyped.git4.14.199n/a
@types/markdown-itMIThttps://github.com/DefinitelyTyped/DefinitelyTyped.git13.0.2n/a
@types/reactMIThttps://github.com/DefinitelyTyped/DefinitelyTyped.git18.2.28n/a
axiosMITgit+https://github.com/axios/axios.git1.5.1Matt Zabriskie
babel-plugin-module-resolverMITgit+https://github.com/tleunen/babel-plugin-module-resolver.git5.0.0Tommy Leunen tommy.leunen@gmail.com http://tommyleunen.com
dayjsMITgit+https://github.com/iamkun/dayjs.git1.11.10iamkun
expoMITgit+https://github.com/expo/expo.git49.0.13Expo
expo-assetMITgit+https://github.com/expo/expo.git8.10.1650 Industries, Inc.
expo-blurMITgit+https://github.com/expo/expo.git12.6.0650 Industries, Inc.
expo-build-propertiesMITgit+https://github.com/expo/expo.git0.8.3650 Industries, Inc.
expo-clipboardMITgit+https://github.com/expo/expo.git4.5.0650 Industries, Inc.
expo-dev-clientMITgit+https://github.com/expo/expo.git2.4.11650 Industries, Inc.
expo-file-systemMITgit+https://github.com/expo/expo.git15.6.0650 Industries, Inc.
expo-imageMITgit+https://github.com/expo/expo.git1.5.1650 Industries, Inc.
expo-image-pickerMITgit+https://github.com/expo/expo.git14.5.0650 Industries, Inc.
expo-linear-gradientMITgit+https://github.com/expo/expo.git12.3.0650 Industries, Inc.
expo-linkingMITgit+https://github.com/expo/expo.git6.0.0650 Industries, Inc.
expo-localizationMITgit+https://github.com/expo/expo.git14.5.0650 Industries, Inc.
expo-mail-composerMITgit+https://github.com/expo/expo.git12.5.0650 Industries, Inc.
expo-media-libraryMITgit+https://github.com/expo/expo.git15.6.0650 Industries, Inc.
expo-permissionsMITgit+https://github.com/expo/expo.git14.4.0650 Industries, Inc.
expo-splash-screenMITgit+https://github.com/expo/expo.git0.22.0650 Industries, Inc.
expo-status-barMITgit+https://github.com/expo/expo.git1.7.1650 Industries, Inc.
expo-system-uiMITgit+https://github.com/expo/expo.git2.6.0650 Industries, Inc.
expo-web-browserMITgit+https://github.com/expo/expo.git12.5.0650 Industries, Inc.
fuse.jsApache-2.0git+https://github.com/krisk/Fuse.git6.6.2Kiro Risk kirollos@gmail.com http://kiro.me
i18nextMITgit+https://github.com/i18next/i18next.git23.5.1Jan Mühlemann (https://github.com/jamuhl)
immerMITgit+https://github.com/immerjs/immer.git10.0.3Michel Weststrate
lemmy-js-clientAGPL-3.0git+https://github.com/LemmyNet/lemmy-js-client.git0.18.1Dessalines
lodashMITgit+https://github.com/lodash/lodash.git4.17.21John-David Dalton
markdown-itMITgit+https://github.com/markdown-it/markdown-it.git13.0.2n/a
motiMITgit+https://github.com/nandorojo/moti.git0.27.0n/a
reactMITgit+https://github.com/facebook/react.git18.2.0n/a
react-domMITgit+https://github.com/facebook/react.git18.2.0n/a
react-error-boundaryMITgit+https://github.com/bvaughn/react-error-boundary.git4.0.11Brian Vaughn
react-i18nextMITgit+https://github.com/i18next/react-i18next.git13.2.2Jan Mühlemann (https://github.com/jamuhl)
react-nativeMITgit+https://github.com/facebook/react-native.git0.72.5n/a
react-native-change-iconMITgit+https://github.com/skb1129/react-native-change-icon.git5.0.0Surya Kant Bansal (https://github.com/skb1129)
react-native-device-infoMITgit+https://github.com/react-native-device-info/react-native-device-info.git10.11.0Rebecca Hughes (https://github.com/rebeccahughes)
react-native-drawer-layoutMITgit+https://github.com/react-navigation/react-navigation.git4.0.0-alpha.1n/a
react-native-fsMITgit+ssh://git@github.com/itinance/react-native-fs.git2.20.0Johannes Lumpe (https://github.com/johanneslumpe)
react-native-gesture-handlerMITgit+https://github.com/software-mansion/react-native-gesture-handler.git2.13.2Krzysztof Magiera krzys.magiera@gmail.com
react-native-haptic-feedbackMITgit+https://github.com/mkuczera/react-native-haptic-feedback.git2.2.0Michael Kuczera
react-native-ios-context-menuMITgit+https://github.com/indominicstop/react-native-ios-context-menu.git1.15.3Dominic Go <18517029+dominicstop@users.noreply.github.com> (https://github.com/dominicstop)
react-native-keyboard-aware-scroll-viewMITgit+https://github.com/APSL/react-native-keyboard-aware-scroll-view.git0.9.5Alvaro Medina Ballester
react-native-linear-gradientMITgit+https://github.com/react-native-linear-gradient/react-native-linear-gradient.git2.8.3Brent Vatne (https://github.com/brentvatne)
react-native-material-tabsMITgit+https://github.com/iRoachie/react-native-material-tabs.git4.2.0Kyle Roach kroach.work@gmail.com
react-native-pager-viewMITgit+https://github.com/callstack/react-native-pager-view.git7.0.0-rc.0troZee (https://github.com/callstack)
react-native-reanimatedMITgit+https://github.com/software-mansion/react-native-reanimated.git3.3.0Krzysztof Magiera krzys.magiera@gmail.com
react-native-safe-area-contextMITgit+https://github.com/th3rdwave/react-native-safe-area-context.git4.7.2Janic Duplessis
react-native-screensMITgit+https://github.com/software-mansion/react-native-screens.git3.25.0Krzysztof Magiera krzys.magiera@gmail.com
react-native-shareMITgit+https://github.com/react-native-community/react-native-share.git9.4.1Esteban Fuentealba efuentealba@json.cl
react-native-svgMITgit+https://github.com/react-native-community/react-native-svg.git13.14.0n/a
react-native-webMITgit://github.com/necolas/react-native-web.git0.19.9Nicolas Gallagher
react-native-webviewMITgit+https://github.com/react-native-webview/react-native-webview.git13.6.2Jamon Holmgren
react-navigation-header-buttonsMITgit+https://github.com/vonovak/react-navigation-header-buttons.git11.1.0Vojtech Novak (https://github.com/vonovak)
reactotron-plugin-zustandMITgit+https://github.com/joalisonpereira/reactotron-plugin-zustand.git1.0.3joalisonpereira
reanimated-color-pickerMITgit+https://github.com/alabsi91/reanimated-color-picker.git2.4.0Ahmed Alabsi (https://github.com/alabsi91)
tamaguin/ahttps://registry.npmjs.org/tamagui/-/tamagui-1.74.21.tgz1.74.19n/a
zustandMITgit+https://github.com/pmndrs/zustand.git4.4.3Paul Henschel
@babel/coreMIThttps://github.com/babel/babel.git7.23.2The Babel Team (https://babel.dev/team)
@tamagui/babel-pluginMIThttps://registry.npmjs.org/@tamagui/babel-plugin/-/babel-plugin-1.74.21.tgz1.74.21n/a
@typescript-eslint/eslint-pluginMITgit+https://github.com/typescript-eslint/typescript-eslint.git6.7.5n/a
eslintMITgit+https://github.com/eslint/eslint.git8.51.0Nicholas C. Zakas
eslint-config-prettierMITgit+https://github.com/prettier/eslint-config-prettier.git9.0.0Simon Lydell
eslint-config-standard-with-typescriptMITgit+https://github.com/standard/eslint-config-standard-with-typescript.git39.1.1Shahar Or (mightyiam)
eslint-plugin-importMITgit+https://github.com/import-js/eslint-plugin-import.git2.28.1Ben Mosher
eslint-plugin-nMITgit+https://github.com/eslint-community/eslint-plugin-n.git16.2.0Toru Nagashima
eslint-plugin-prettierMITgit+https://github.com/prettier/eslint-plugin-prettier.git5.0.1Teddy Katz
eslint-plugin-promiseISCgit+https://github.com/eslint-community/eslint-plugin-promise.git6.1.1jden
eslint-plugin-reactMITgit+https://github.com/jsx-eslint/eslint-plugin-react.git7.33.2Yannick Croissant
patch-packageMITgit+https://github.com/ds300/patch-package.git8.0.0David Sheldrick
postinstall-postinstallMIThttps://github.com/ds300/postinstall-postinstall2.1.0David Sheldrick
prettierMITgit+https://github.com/prettier/prettier.git3.0.3James Long
reactotron-react-nativeMITgit+https://github.com/infinitered/reactotron-react-native.git5.0.3Infinite Red
typescriptApache-2.0git+https://github.com/Microsoft/TypeScript.git5.2.2Microsoft Corp.
diff --git a/src/components/Common/ContextMenu/components/CommentContextMenu.tsx b/src/components/Common/ContextMenu/components/CommentContextMenu.tsx index a31134ff4..a0a6f2add 100644 --- a/src/components/Common/ContextMenu/components/CommentContextMenu.tsx +++ b/src/components/Common/ContextMenu/components/CommentContextMenu.tsx @@ -48,6 +48,9 @@ export default function CommentContextMenu({ case 'edit': commentContextMenu.edit(); break; + case 'share': + commentContextMenu.share(); + break; } }, [commentContextMenu], diff --git a/src/components/Common/ContextMenu/components/PostContextMenu.tsx b/src/components/Common/ContextMenu/components/PostContextMenu.tsx index a1ad04026..b7dd3d846 100644 --- a/src/components/Common/ContextMenu/components/PostContextMenu.tsx +++ b/src/components/Common/ContextMenu/components/PostContextMenu.tsx @@ -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'; @@ -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); @@ -23,6 +25,7 @@ export default function PostContextMenu({ createPostContextMenuOptions({ moderates, isOwnPost: isOwn, + isImage: postLinkType === 'image', }), [itemId], ); @@ -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], diff --git a/src/components/Common/ContextMenu/hooks/useCommentContextMenu.ts b/src/components/Common/ContextMenu/hooks/useCommentContextMenu.ts index 676ce9ab4..9dd052a78 100644 --- a/src/components/Common/ContextMenu/hooks/useCommentContextMenu.ts +++ b/src/components/Common/ContextMenu/hooks/useCommentContextMenu.ts @@ -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; @@ -13,6 +19,7 @@ interface UseCommentContextMenu { delet: () => void; remove: () => void; report: () => void; + share: () => void; } export const useCommentContextMenu = ( @@ -21,6 +28,19 @@ export const useCommentContextMenu = ( const navigation = useNavigation>(); 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, @@ -130,6 +150,7 @@ export const useCommentContextMenu = ( }; return { + share, reply, upvote, downvote, diff --git a/src/components/Common/ContextMenu/hooks/usePostContextMenu.ts b/src/components/Common/ContextMenu/hooks/usePostContextMenu.ts index 1f019e1b9..9db16d09d 100644 --- a/src/components/Common/ContextMenu/hooks/usePostContextMenu.ts +++ b/src/components/Common/ContextMenu/hooks/usePostContextMenu.ts @@ -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; @@ -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>(); + 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, @@ -139,6 +182,9 @@ export const usePostContextMenu = (itemId: number): UsePostContextMenu => { }; return { + share, + shareImage, + savePostImage, reply, upvote, downvote, diff --git a/src/components/Common/ImageViewer/ImageViewer.tsx b/src/components/Common/ImageViewer/ImageViewer.tsx index 8e42896b1..395698749 100644 --- a/src/components/Common/ImageViewer/ImageViewer.tsx +++ b/src/components/Common/ImageViewer/ImageViewer.tsx @@ -7,7 +7,6 @@ import { GestureUpdateEvent, PanGestureHandlerEventPayload, PinchGestureHandlerEventPayload, - TapGestureHandlerEventPayload, } from 'react-native-gesture-handler'; import Animated, { cancelAnimation, @@ -139,26 +138,23 @@ function ImageViewer(): React.JSX.Element { ); // - const onDoubleTap = useCallback( - (event: GestureUpdateEvent): 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( @@ -315,10 +311,7 @@ function ImageViewer(): React.JSX.Element { return ( - + @@ -333,10 +326,7 @@ function ImageViewer(): React.JSX.Element { - + ); } diff --git a/src/components/Common/ImageViewer/ImageViewerFooter.tsx b/src/components/Common/ImageViewer/ImageViewerFooter.tsx index 941478763..a30699bb3 100644 --- a/src/components/Common/ImageViewer/ImageViewerFooter.tsx +++ b/src/components/Common/ImageViewer/ImageViewerFooter.tsx @@ -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 ( @@ -37,7 +45,12 @@ function ImageViewerFooter({ iconSize={24} onPress={onImageSave} /> - + diff --git a/src/components/Common/ImageViewer/ImageViewerHeader.tsx b/src/components/Common/ImageViewer/ImageViewerHeader.tsx index a1d663e53..770d48bf7 100644 --- a/src/components/Common/ImageViewer/ImageViewerHeader.tsx +++ b/src/components/Common/ImageViewer/ImageViewerHeader.tsx @@ -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(() => { @@ -33,7 +29,7 @@ function ImageViewerHeader({ > - {title} + {imageViewer.params?.title ?? 'Image'} diff --git a/src/components/Reply/hooks/useReplyScreen.tsx b/src/components/Reply/hooks/useReplyScreen.tsx index cee6af53a..ece75d292 100644 --- a/src/components/Reply/hooks/useReplyScreen.tsx +++ b/src/components/Reply/hooks/useReplyScreen.tsx @@ -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(); diff --git a/src/helpers/contextMenu/createPostContextMenuOptions.ts b/src/helpers/contextMenu/createPostContextMenuOptions.ts index 164d0fcd6..62f007b22 100644 --- a/src/helpers/contextMenu/createPostContextMenuOptions.ts +++ b/src/helpers/contextMenu/createPostContextMenuOptions.ts @@ -4,6 +4,7 @@ import { PostContextMenuOption } from '@src/types/contextMenu'; interface CreatePostContextMenuOptionsParams { moderates: boolean; isOwnPost: boolean; + isImage: boolean; } export const createPostContextMenuOptions = ( @@ -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', diff --git a/src/helpers/share/shareLink.ts b/src/helpers/share/shareLink.ts new file mode 100644 index 000000000..704515726 --- /dev/null +++ b/src/helpers/share/shareLink.ts @@ -0,0 +1,55 @@ +import RNShare, { ShareOptions } from 'react-native-share'; +import { getCachePath } from '@root/modules/expo-image-cache-path'; +import { setToast } from '@src/state'; + +interface ShareLinkOptions { + title?: string; + link: string; + isImage?: boolean; + callback?: () => unknown; +} + +export const shareLink = async ({ + title, + link, + isImage, + callback, +}: ShareLinkOptions): Promise => { + let options: ShareOptions = { + url: link, + title, + }; + + if (isImage === true) { + const uri = getCachePath(link); + + if (uri == null) return; + + options = { + filename: uri.split('/').pop(), + type: `image/${uri.split('.').pop()}`, + activityItemSources: [ + { + placeholderItem: { type: 'url', content: 'url' }, + item: { + default: { + type: 'url', + content: uri, + }, + }, + dataTypeIdentifier: { + saveToCameraRoll: `image/${uri.split('.').pop()}`, + }, + }, + ], + }; + } + + try { + void RNShare.open(options).then(() => callback?.()); + } catch (e: any) { + setToast({ + text: 'Error sharing content.', + }); + } +}; diff --git a/src/state/account/actions/setCurrentAccount.ts b/src/state/account/actions/setCurrentAccount.ts index 99aca8a2a..5d6a1f65c 100644 --- a/src/state/account/actions/setCurrentAccount.ts +++ b/src/state/account/actions/setCurrentAccount.ts @@ -2,12 +2,9 @@ import { useAccountStore } from '@src/state'; export const setCurrentAccount = (fullName: string): void => { useAccountStore.setState((state) => { - console.log(fullName); - const currentAccount = state.accounts.find((c) => c.isCurrentAccount); if (currentAccount != null) { - console.log('switchedAccount'); currentAccount.isCurrentAccount = false; } const newCurrentAccount = state.accounts.find( @@ -15,7 +12,6 @@ export const setCurrentAccount = (fullName: string): void => { ); if (newCurrentAccount != null) { - console.log('setAccount'); newCurrentAccount.isCurrentAccount = true; state.currentAccount = newCurrentAccount; } diff --git a/src/state/comment/commentStore.ts b/src/state/comment/commentStore.ts index 4360a4ba7..7155ea9e2 100644 --- a/src/state/comment/commentStore.ts +++ b/src/state/comment/commentStore.ts @@ -77,3 +77,6 @@ export const useCommentRemoved = (id: number): boolean => useCommentStore( (state) => state.comments.get(id)?.view.comment.removed ?? false, ); + +export const useCommentActorId = (id: number): string | undefined => + useCommentStore((state) => state.comments.get(id)?.view.comment.ap_id); diff --git a/src/types/contextMenu/PostContextMenuOption.ts b/src/types/contextMenu/PostContextMenuOption.ts index 8a9babbaa..407e68d91 100644 --- a/src/types/contextMenu/PostContextMenuOption.ts +++ b/src/types/contextMenu/PostContextMenuOption.ts @@ -1,6 +1,8 @@ export type PostContextMenuOption = | 'reply' | 'share' + | 'shareImage' + | 'saveImage' | 'edit' | 'delete' | 'remove'