Add translate link to post menu (#261)
* Add a google translate menu item to posts * Fix: make sure the dropdown menu is always visible (when low on the screen)
This commit is contained in:
parent
c2bfa111ac
commit
a9920d9630
6 changed files with 44 additions and 3 deletions
|
@ -1,6 +1,6 @@
|
||||||
import React from 'react'
|
import React from 'react'
|
||||||
import {observer} from 'mobx-react-lite'
|
import {observer} from 'mobx-react-lite'
|
||||||
import {StyleSheet, View} from 'react-native'
|
import {Linking, StyleSheet, View} from 'react-native'
|
||||||
import Clipboard from '@react-native-clipboard/clipboard'
|
import Clipboard from '@react-native-clipboard/clipboard'
|
||||||
import {AtUri} from '../../../third-party/uri'
|
import {AtUri} from '../../../third-party/uri'
|
||||||
import {
|
import {
|
||||||
|
@ -89,6 +89,11 @@ export const PostThreadItem = observer(function PostThreadItem({
|
||||||
Clipboard.setString(record?.text || '')
|
Clipboard.setString(record?.text || '')
|
||||||
Toast.show('Copied to clipboard')
|
Toast.show('Copied to clipboard')
|
||||||
}, [record])
|
}, [record])
|
||||||
|
const onOpenTranslate = React.useCallback(() => {
|
||||||
|
Linking.openURL(
|
||||||
|
encodeURI(`https://translate.google.com/#auto|en|${record?.text || ''}`),
|
||||||
|
)
|
||||||
|
}, [record])
|
||||||
const onDeletePost = React.useCallback(() => {
|
const onDeletePost = React.useCallback(() => {
|
||||||
item.delete().then(
|
item.delete().then(
|
||||||
() => {
|
() => {
|
||||||
|
@ -167,6 +172,7 @@ export const PostThreadItem = observer(function PostThreadItem({
|
||||||
itemTitle={itemTitle}
|
itemTitle={itemTitle}
|
||||||
isAuthor={item.post.author.did === store.me.did}
|
isAuthor={item.post.author.did === store.me.did}
|
||||||
onCopyPostText={onCopyPostText}
|
onCopyPostText={onCopyPostText}
|
||||||
|
onOpenTranslate={onOpenTranslate}
|
||||||
onDeletePost={onDeletePost}>
|
onDeletePost={onDeletePost}>
|
||||||
<FontAwesomeIcon
|
<FontAwesomeIcon
|
||||||
icon="ellipsis-h"
|
icon="ellipsis-h"
|
||||||
|
@ -259,6 +265,7 @@ export const PostThreadItem = observer(function PostThreadItem({
|
||||||
onPressToggleRepost={onPressToggleRepost}
|
onPressToggleRepost={onPressToggleRepost}
|
||||||
onPressToggleUpvote={onPressToggleUpvote}
|
onPressToggleUpvote={onPressToggleUpvote}
|
||||||
onCopyPostText={onCopyPostText}
|
onCopyPostText={onCopyPostText}
|
||||||
|
onOpenTranslate={onOpenTranslate}
|
||||||
onDeletePost={onDeletePost}
|
onDeletePost={onDeletePost}
|
||||||
/>
|
/>
|
||||||
</View>
|
</View>
|
||||||
|
@ -353,6 +360,7 @@ export const PostThreadItem = observer(function PostThreadItem({
|
||||||
onPressToggleRepost={onPressToggleRepost}
|
onPressToggleRepost={onPressToggleRepost}
|
||||||
onPressToggleUpvote={onPressToggleUpvote}
|
onPressToggleUpvote={onPressToggleUpvote}
|
||||||
onCopyPostText={onCopyPostText}
|
onCopyPostText={onCopyPostText}
|
||||||
|
onOpenTranslate={onOpenTranslate}
|
||||||
onDeletePost={onDeletePost}
|
onDeletePost={onDeletePost}
|
||||||
/>
|
/>
|
||||||
</View>
|
</View>
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
import React, {useState, useEffect} from 'react'
|
import React, {useState, useEffect} from 'react'
|
||||||
import {
|
import {
|
||||||
ActivityIndicator,
|
ActivityIndicator,
|
||||||
|
Linking,
|
||||||
StyleProp,
|
StyleProp,
|
||||||
StyleSheet,
|
StyleSheet,
|
||||||
View,
|
View,
|
||||||
|
@ -120,6 +121,11 @@ export const Post = observer(function Post({
|
||||||
Clipboard.setString(record.text)
|
Clipboard.setString(record.text)
|
||||||
Toast.show('Copied to clipboard')
|
Toast.show('Copied to clipboard')
|
||||||
}
|
}
|
||||||
|
const onOpenTranslate = () => {
|
||||||
|
Linking.openURL(
|
||||||
|
encodeURI(`https://translate.google.com/#auto|en|${record?.text || ''}`),
|
||||||
|
)
|
||||||
|
}
|
||||||
const onDeletePost = () => {
|
const onDeletePost = () => {
|
||||||
item.delete().then(
|
item.delete().then(
|
||||||
() => {
|
() => {
|
||||||
|
@ -214,6 +220,7 @@ export const Post = observer(function Post({
|
||||||
onPressToggleRepost={onPressToggleRepost}
|
onPressToggleRepost={onPressToggleRepost}
|
||||||
onPressToggleUpvote={onPressToggleUpvote}
|
onPressToggleUpvote={onPressToggleUpvote}
|
||||||
onCopyPostText={onCopyPostText}
|
onCopyPostText={onCopyPostText}
|
||||||
|
onOpenTranslate={onOpenTranslate}
|
||||||
onDeletePost={onDeletePost}
|
onDeletePost={onDeletePost}
|
||||||
/>
|
/>
|
||||||
</View>
|
</View>
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import React, {useMemo, useState} from 'react'
|
import React, {useMemo, useState} from 'react'
|
||||||
import {observer} from 'mobx-react-lite'
|
import {observer} from 'mobx-react-lite'
|
||||||
import {StyleSheet, View} from 'react-native'
|
import {Linking, StyleSheet, View} from 'react-native'
|
||||||
import Clipboard from '@react-native-clipboard/clipboard'
|
import Clipboard from '@react-native-clipboard/clipboard'
|
||||||
import Svg, {Circle, Line} from 'react-native-svg'
|
import Svg, {Circle, Line} from 'react-native-svg'
|
||||||
import {AtUri} from '../../../third-party/uri'
|
import {AtUri} from '../../../third-party/uri'
|
||||||
|
@ -86,6 +86,11 @@ export const FeedItem = observer(function ({
|
||||||
Clipboard.setString(record?.text || '')
|
Clipboard.setString(record?.text || '')
|
||||||
Toast.show('Copied to clipboard')
|
Toast.show('Copied to clipboard')
|
||||||
}
|
}
|
||||||
|
const onOpenTranslate = React.useCallback(() => {
|
||||||
|
Linking.openURL(
|
||||||
|
encodeURI(`https://translate.google.com/#auto|en|${record?.text || ''}`),
|
||||||
|
)
|
||||||
|
}, [record])
|
||||||
const onDeletePost = () => {
|
const onDeletePost = () => {
|
||||||
track('FeedItem:PostDelete')
|
track('FeedItem:PostDelete')
|
||||||
item.delete().then(
|
item.delete().then(
|
||||||
|
@ -243,6 +248,7 @@ export const FeedItem = observer(function ({
|
||||||
onPressToggleRepost={onPressToggleRepost}
|
onPressToggleRepost={onPressToggleRepost}
|
||||||
onPressToggleUpvote={onPressToggleUpvote}
|
onPressToggleUpvote={onPressToggleUpvote}
|
||||||
onCopyPostText={onCopyPostText}
|
onCopyPostText={onCopyPostText}
|
||||||
|
onOpenTranslate={onOpenTranslate}
|
||||||
onDeletePost={onDeletePost}
|
onDeletePost={onDeletePost}
|
||||||
/>
|
/>
|
||||||
</View>
|
</View>
|
||||||
|
|
|
@ -52,6 +52,7 @@ interface PostCtrlsOpts {
|
||||||
onPressToggleRepost: () => Promise<void>
|
onPressToggleRepost: () => Promise<void>
|
||||||
onPressToggleUpvote: () => Promise<void>
|
onPressToggleUpvote: () => Promise<void>
|
||||||
onCopyPostText: () => void
|
onCopyPostText: () => void
|
||||||
|
onOpenTranslate: () => void
|
||||||
onDeletePost: () => void
|
onDeletePost: () => void
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -297,6 +298,7 @@ export function PostCtrls(opts: PostCtrlsOpts) {
|
||||||
itemTitle={opts.itemTitle}
|
itemTitle={opts.itemTitle}
|
||||||
isAuthor={opts.isAuthor}
|
isAuthor={opts.isAuthor}
|
||||||
onCopyPostText={opts.onCopyPostText}
|
onCopyPostText={opts.onCopyPostText}
|
||||||
|
onOpenTranslate={opts.onOpenTranslate}
|
||||||
onDeletePost={opts.onDeletePost}>
|
onDeletePost={opts.onDeletePost}>
|
||||||
<FontAwesomeIcon
|
<FontAwesomeIcon
|
||||||
icon="ellipsis-h"
|
icon="ellipsis-h"
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
import React, {useRef} from 'react'
|
import React, {useRef} from 'react'
|
||||||
import {
|
import {
|
||||||
|
Dimensions,
|
||||||
Share,
|
Share,
|
||||||
StyleProp,
|
StyleProp,
|
||||||
StyleSheet,
|
StyleSheet,
|
||||||
|
@ -21,6 +22,7 @@ import {usePalette} from 'lib/hooks/usePalette'
|
||||||
import {useTheme} from 'lib/ThemeContext'
|
import {useTheme} from 'lib/ThemeContext'
|
||||||
|
|
||||||
const HITSLOP = {left: 10, top: 10, right: 10, bottom: 10}
|
const HITSLOP = {left: 10, top: 10, right: 10, bottom: 10}
|
||||||
|
const ESTIMATED_MENU_ITEM_HEIGHT = 52
|
||||||
|
|
||||||
export interface DropdownItem {
|
export interface DropdownItem {
|
||||||
icon?: IconProp
|
icon?: IconProp
|
||||||
|
@ -67,10 +69,15 @@ export function DropdownButton({
|
||||||
if (!menuWidth) {
|
if (!menuWidth) {
|
||||||
menuWidth = 200
|
menuWidth = 200
|
||||||
}
|
}
|
||||||
|
const winHeight = Dimensions.get('window').height
|
||||||
|
const estimatedMenuHeight = items.length * ESTIMATED_MENU_ITEM_HEIGHT
|
||||||
const newX = openToRight
|
const newX = openToRight
|
||||||
? pageX + width + rightOffset
|
? pageX + width + rightOffset
|
||||||
: pageX + width - menuWidth
|
: pageX + width - menuWidth
|
||||||
const newY = pageY + height + bottomOffset
|
let newY = pageY + height + bottomOffset
|
||||||
|
if (newY + estimatedMenuHeight > winHeight) {
|
||||||
|
newY -= estimatedMenuHeight
|
||||||
|
}
|
||||||
createDropdownMenu(
|
createDropdownMenu(
|
||||||
newX,
|
newX,
|
||||||
newY,
|
newY,
|
||||||
|
@ -114,6 +121,7 @@ export function PostDropdownBtn({
|
||||||
itemHref,
|
itemHref,
|
||||||
isAuthor,
|
isAuthor,
|
||||||
onCopyPostText,
|
onCopyPostText,
|
||||||
|
onOpenTranslate,
|
||||||
onDeletePost,
|
onDeletePost,
|
||||||
}: {
|
}: {
|
||||||
style?: StyleProp<ViewStyle>
|
style?: StyleProp<ViewStyle>
|
||||||
|
@ -124,6 +132,7 @@ export function PostDropdownBtn({
|
||||||
itemTitle: string
|
itemTitle: string
|
||||||
isAuthor: boolean
|
isAuthor: boolean
|
||||||
onCopyPostText: () => void
|
onCopyPostText: () => void
|
||||||
|
onOpenTranslate: () => void
|
||||||
onDeletePost: () => void
|
onDeletePost: () => void
|
||||||
}) {
|
}) {
|
||||||
const store = useStores()
|
const store = useStores()
|
||||||
|
@ -152,6 +161,13 @@ export function PostDropdownBtn({
|
||||||
Share.share({url: toShareUrl(itemHref)})
|
Share.share({url: toShareUrl(itemHref)})
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
icon: 'language',
|
||||||
|
label: 'Translate...',
|
||||||
|
onPress() {
|
||||||
|
onOpenTranslate()
|
||||||
|
},
|
||||||
|
},
|
||||||
{
|
{
|
||||||
icon: 'circle-exclamation',
|
icon: 'circle-exclamation',
|
||||||
label: 'Report post',
|
label: 'Report post',
|
||||||
|
|
|
@ -42,6 +42,7 @@ import {faHouse} from '@fortawesome/free-solid-svg-icons/faHouse'
|
||||||
import {faImage as farImage} from '@fortawesome/free-regular-svg-icons/faImage'
|
import {faImage as farImage} from '@fortawesome/free-regular-svg-icons/faImage'
|
||||||
import {faImage} from '@fortawesome/free-solid-svg-icons/faImage'
|
import {faImage} from '@fortawesome/free-solid-svg-icons/faImage'
|
||||||
import {faInfo} from '@fortawesome/free-solid-svg-icons/faInfo'
|
import {faInfo} from '@fortawesome/free-solid-svg-icons/faInfo'
|
||||||
|
import {faLanguage} from '@fortawesome/free-solid-svg-icons/faLanguage'
|
||||||
import {faLink} from '@fortawesome/free-solid-svg-icons/faLink'
|
import {faLink} from '@fortawesome/free-solid-svg-icons/faLink'
|
||||||
import {faLock} from '@fortawesome/free-solid-svg-icons/faLock'
|
import {faLock} from '@fortawesome/free-solid-svg-icons/faLock'
|
||||||
import {faMagnifyingGlass} from '@fortawesome/free-solid-svg-icons/faMagnifyingGlass'
|
import {faMagnifyingGlass} from '@fortawesome/free-solid-svg-icons/faMagnifyingGlass'
|
||||||
|
@ -113,6 +114,7 @@ export function setup() {
|
||||||
faImage,
|
faImage,
|
||||||
farImage,
|
farImage,
|
||||||
faInfo,
|
faInfo,
|
||||||
|
faLanguage,
|
||||||
faLink,
|
faLink,
|
||||||
faLock,
|
faLock,
|
||||||
faMagnifyingGlass,
|
faMagnifyingGlass,
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue