mirror of
https://github.com/tooot-app/app
synced 2025-06-05 22:19:13 +02:00
Merge branch 'main' into release
This commit is contained in:
1
fastlane/metadata/android/it-IT/full_description.txt
Symbolic link
1
fastlane/metadata/android/it-IT/full_description.txt
Symbolic link
@ -0,0 +1 @@
|
|||||||
|
../../it/description.txt
|
1
fastlane/metadata/android/it-IT/short_description.txt
Symbolic link
1
fastlane/metadata/android/it-IT/short_description.txt
Symbolic link
@ -0,0 +1 @@
|
|||||||
|
../../it/subtitle.txt
|
@ -1,5 +1,10 @@
|
|||||||
tooot is an open source, simple yet elegant Mastodon mobile client.
|
tooot is an open source, simple yet elegant Mastodon mobile client. A Mastodon (https://joinmastodon.org/) account is required to use this app.
|
||||||
|
|
||||||
A Mastodon (https://joinmastodon.org/) account is required to use this app.
|
tooot supports:
|
||||||
|
- Cross platform, including iPadOS and MacOS
|
||||||
|
- Multiple accounts
|
||||||
|
- Dark mode or adapt to system
|
||||||
|
- Adjustable toot font size
|
||||||
|
- Push notification
|
||||||
|
|
||||||
If you have suggestions, please reach out to @tooot@xmflsct.com or support@tooot.ap.
|
If you have suggestions, please reach out to @tooot@xmflsct.com or support@tooot.app.
|
||||||
|
@ -1,10 +1,5 @@
|
|||||||
Enjoy toooting! This version includes following improvements and fixes:
|
Enjoy toooting! This version includes following improvements and fixes:
|
||||||
- Added Ukrainian (Slava Ukraini)
|
- Align filter experience with v4.0 and above
|
||||||
- Automatic setting detected language when tooting
|
- Supports enlarging user's avatar and banner
|
||||||
- Remember public timeline type selection
|
- Fix iPad weird sizing (not optimisation)
|
||||||
- Show diffing of edit history
|
- Experiment (!) support of Pleroma
|
||||||
- Allow hiding boosts and replies in home timeline
|
|
||||||
- Support toot in RTL languages
|
|
||||||
- Added notification for admins
|
|
||||||
- Fix whole word filter matching
|
|
||||||
- Fix tablet cannot delete toot drafts
|
|
||||||
|
10
fastlane/metadata/it/description.txt
Normal file
10
fastlane/metadata/it/description.txt
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
tooot è un client Mastodon semplice e open source. Per utilizzare questo client, devi disporre di un account Mastodon. (https://joinmastodon.org/).
|
||||||
|
|
||||||
|
Tooot supporta:
|
||||||
|
- Multipiattaforma, inclusi iPadOS e MacOS
|
||||||
|
- Accesso a più account
|
||||||
|
- Modalità scura o adattiva
|
||||||
|
- Dimensione del carattere del testo regolabile
|
||||||
|
- Notifiche push e altre funzioni
|
||||||
|
|
||||||
|
Per suggerimenti o commenti sull'utilizzo, contattare @tooot@xmflsct.com o support@tooot.app.
|
1
fastlane/metadata/it/subtitle.txt
Normal file
1
fastlane/metadata/it/subtitle.txt
Normal file
@ -0,0 +1 @@
|
|||||||
|
Client open source per Mastodon
|
@ -1,11 +1,10 @@
|
|||||||
tooot是一个专门为中文用户社区所打造的开源、简洁长毛象客户端。使用此客户端需要已经拥有一个长毛象(https://joinmastodon.org/)账号。
|
tooot起始于专注中文社区的简洁、开源长毛象手机客户端。使用此客户端需要已经拥有一个长毛象(https://joinmastodon.org/)账号。
|
||||||
|
|
||||||
tooot支持:
|
tooot支持:
|
||||||
- iPad
|
- 跨平台,及iPadOS、MacOS
|
||||||
- 多账号登录
|
- 多账号登录
|
||||||
- 黑暗或自适应模式
|
- 黑暗或自适应模式
|
||||||
- 可调整正文字体大小
|
- 可调正文字体尺寸
|
||||||
- 消息推送
|
- 消息推送
|
||||||
等功能。
|
|
||||||
|
|
||||||
如有使用建议或意见,请联系@tooot@xmflsct.com或者support@tooot.app。
|
如有使用建议或意见,请联系@tooot@xmflsct.com或者support@tooot.app。
|
@ -1,10 +1,5 @@
|
|||||||
toooting愉快!此版本包括以下改进和修复:
|
toooting愉快!此版本包括以下改进和修复:
|
||||||
- 增加乌克兰语(Slava Ukraini)
|
- 改进过滤体验,与v4.0以上版本一致
|
||||||
- 自动识别发嘟语言
|
- 支持查看用户的头像和横幅图片
|
||||||
- 记住上次公共时间轴选项
|
- 修复iPad部分尺寸问题(非优化)
|
||||||
- 显示编辑历史的差异
|
- 试验性(!)支持Pleroma
|
||||||
- 关注列表可隐藏转嘟和回复
|
|
||||||
- 新增管理员推送通知
|
|
||||||
- 支持嘟文右到左文字
|
|
||||||
- 修复过滤整词功能
|
|
||||||
- 修复平板不能删除草稿
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "tooot",
|
"name": "tooot",
|
||||||
"version": "4.7.0",
|
"version": "4.7.1",
|
||||||
"description": "tooot for Mastodon",
|
"description": "tooot for Mastodon",
|
||||||
"author": "xmflsct <me@xmflsct.com>",
|
"author": "xmflsct <me@xmflsct.com>",
|
||||||
"license": "GPL-3.0-or-later",
|
"license": "GPL-3.0-or-later",
|
||||||
|
29
src/@types/mastodon.d.ts
vendored
29
src/@types/mastodon.d.ts
vendored
@ -263,7 +263,8 @@ declare namespace Mastodon {
|
|||||||
verified_at: string | null
|
verified_at: string | null
|
||||||
}
|
}
|
||||||
|
|
||||||
type Filter = {
|
type Filter<T extends 'v1' | 'v2'> = T extends 'v2' ? Filter_V2 : Filter_V1
|
||||||
|
type Filter_V1 = {
|
||||||
id: string
|
id: string
|
||||||
phrase: string
|
phrase: string
|
||||||
context: ('home' | 'notifications' | 'public' | 'thread' | 'account')[]
|
context: ('home' | 'notifications' | 'public' | 'thread' | 'account')[]
|
||||||
@ -271,6 +272,25 @@ declare namespace Mastodon {
|
|||||||
irreversible: boolean
|
irreversible: boolean
|
||||||
whole_word: boolean
|
whole_word: boolean
|
||||||
}
|
}
|
||||||
|
type Filter_V2 = {
|
||||||
|
id: string
|
||||||
|
title: string
|
||||||
|
context: ('home' | 'notifications' | 'public' | 'thread' | 'account')[]
|
||||||
|
expires_at?: string
|
||||||
|
filter_action: 'warn' | 'hide'
|
||||||
|
keywords: FilterKeyword[]
|
||||||
|
statuses: FilterStatus[]
|
||||||
|
}
|
||||||
|
|
||||||
|
type FilterKeyword = { id: string; keyword: string; whole_word: boolean }
|
||||||
|
|
||||||
|
type FilterStatus = { id: string; status_id: string }
|
||||||
|
|
||||||
|
type FilterResult = {
|
||||||
|
filter: Filter<'v2'>
|
||||||
|
keyword_matches?: FilterKeyword['keyword'][]
|
||||||
|
status_matches?: FilterStatus['id'][]
|
||||||
|
}
|
||||||
|
|
||||||
type List = {
|
type List = {
|
||||||
id: string
|
id: string
|
||||||
@ -406,6 +426,8 @@ declare namespace Mastodon {
|
|||||||
id: string
|
id: string
|
||||||
following: boolean
|
following: boolean
|
||||||
showing_reblogs: boolean
|
showing_reblogs: boolean
|
||||||
|
notifying?: boolean
|
||||||
|
languages?: string[]
|
||||||
followed_by: boolean
|
followed_by: boolean
|
||||||
blocking: boolean
|
blocking: boolean
|
||||||
blocked_by: boolean
|
blocked_by: boolean
|
||||||
@ -459,7 +481,7 @@ declare namespace Mastodon {
|
|||||||
sensitive: boolean
|
sensitive: boolean
|
||||||
spoiler_text?: string
|
spoiler_text?: string
|
||||||
media_attachments: Attachment[]
|
media_attachments: Attachment[]
|
||||||
application: Application
|
application?: Application
|
||||||
|
|
||||||
// Attributes
|
// Attributes
|
||||||
mentions: Mention[]
|
mentions: Mention[]
|
||||||
@ -470,7 +492,7 @@ declare namespace Mastodon {
|
|||||||
reblogs_count: number
|
reblogs_count: number
|
||||||
favourites_count: number
|
favourites_count: number
|
||||||
replies_count: number
|
replies_count: number
|
||||||
edited_at?: string // FEATURE edit_post
|
edited_at?: string
|
||||||
favourited: boolean
|
favourited: boolean
|
||||||
reblogged: boolean
|
reblogged: boolean
|
||||||
muted: boolean
|
muted: boolean
|
||||||
@ -486,6 +508,7 @@ declare namespace Mastodon {
|
|||||||
card?: Card
|
card?: Card
|
||||||
language?: string
|
language?: string
|
||||||
text?: string
|
text?: string
|
||||||
|
filtered?: FilterResult[]
|
||||||
}
|
}
|
||||||
|
|
||||||
type StatusHistory = {
|
type StatusHistory = {
|
||||||
|
@ -56,7 +56,7 @@ const Screens: React.FC<Props> = ({ localCorrupt }) => {
|
|||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const screenshotListener = addScreenshotListener(() =>
|
const screenshotListener = addScreenshotListener(() =>
|
||||||
Alert.alert(t('screenshot.title'), t('screenshot.message'), [
|
Alert.alert(t('screenshot.title'), t('screenshot.message'), [
|
||||||
{ text: t('screenshot.button'), style: 'destructive' }
|
{ text: t('common:buttons.confirm'), style: 'destructive' }
|
||||||
])
|
])
|
||||||
)
|
)
|
||||||
Platform.select({ ios: screenshotListener })
|
Platform.select({ ios: screenshotListener })
|
||||||
|
@ -53,7 +53,7 @@ const ComponentHashtag: React.FC<PropsWithChildren & Props> = ({
|
|||||||
#{hashtag.name}
|
#{hashtag.name}
|
||||||
</CustomText>
|
</CustomText>
|
||||||
<View
|
<View
|
||||||
style={{ flexDirection: 'row', alignItems: 'center' }}
|
style={{ flexDirection: 'row', alignItems: 'center', alignSelf: 'stretch' }}
|
||||||
onLayout={({
|
onLayout={({
|
||||||
nativeEvent: {
|
nativeEvent: {
|
||||||
layout: { height }
|
layout: { height }
|
||||||
@ -61,7 +61,7 @@ const ComponentHashtag: React.FC<PropsWithChildren & Props> = ({
|
|||||||
}) => setHeight(height)}
|
}) => setHeight(height)}
|
||||||
>
|
>
|
||||||
<Sparkline
|
<Sparkline
|
||||||
data={hashtag.history.map(h => parseInt(h.uses)).reverse()}
|
data={hashtag.history?.map(h => parseInt(h.uses)).reverse()}
|
||||||
width={width}
|
width={width}
|
||||||
height={height}
|
height={height}
|
||||||
margin={children ? StyleConstants.Spacing.S : undefined}
|
margin={children ? StyleConstants.Spacing.S : undefined}
|
||||||
|
@ -15,6 +15,7 @@ import { Alert, Image, KeyboardAvoidingView, Platform, TextInput, View } from 'r
|
|||||||
import { ScrollView } from 'react-native-gesture-handler'
|
import { ScrollView } from 'react-native-gesture-handler'
|
||||||
import { useSelector } from 'react-redux'
|
import { useSelector } from 'react-redux'
|
||||||
import { Placeholder } from 'rn-placeholder'
|
import { Placeholder } from 'rn-placeholder'
|
||||||
|
import validUrl from 'valid-url'
|
||||||
import InstanceInfo from './Info'
|
import InstanceInfo from './Info'
|
||||||
import CustomText from '../Text'
|
import CustomText from '../Text'
|
||||||
import { useNavigation } from '@react-navigation/native'
|
import { useNavigation } from '@react-navigation/native'
|
||||||
@ -39,12 +40,26 @@ const ComponentInstance: React.FC<Props> = ({
|
|||||||
const navigation = useNavigation<TabMeStackNavigationProp<'Tab-Me-Root' | 'Tab-Me-Switch'>>()
|
const navigation = useNavigation<TabMeStackNavigationProp<'Tab-Me-Root' | 'Tab-Me-Switch'>>()
|
||||||
|
|
||||||
const [domain, setDomain] = useState<string>('')
|
const [domain, setDomain] = useState<string>('')
|
||||||
|
const [errorCode, setErrorCode] = useState<number | null>(null)
|
||||||
|
const whitelisted: boolean =
|
||||||
|
!!domain.length &&
|
||||||
|
!!errorCode &&
|
||||||
|
!!validUrl.isHttpsUri(`https://${domain}`) &&
|
||||||
|
errorCode === 401
|
||||||
|
|
||||||
const dispatch = useAppDispatch()
|
const dispatch = useAppDispatch()
|
||||||
const instances = useSelector(getInstances, () => true)
|
const instances = useSelector(getInstances, () => true)
|
||||||
const instanceQuery = useInstanceQuery({
|
const instanceQuery = useInstanceQuery({
|
||||||
domain,
|
domain,
|
||||||
options: { enabled: !!domain, retry: false }
|
options: {
|
||||||
|
enabled: !!domain,
|
||||||
|
retry: false,
|
||||||
|
onError: err => {
|
||||||
|
if (err.status) {
|
||||||
|
setErrorCode(err.status)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
const deprecateAuthFollow = useSelector(checkInstanceFeature('deprecate_auth_follow'))
|
const deprecateAuthFollow = useSelector(checkInstanceFeature('deprecate_auth_follow'))
|
||||||
@ -146,7 +161,11 @@ const ComponentInstance: React.FC<Props> = ({
|
|||||||
borderBottomWidth: 1,
|
borderBottomWidth: 1,
|
||||||
...StyleConstants.FontStyle.M,
|
...StyleConstants.FontStyle.M,
|
||||||
color: colors.primaryDefault,
|
color: colors.primaryDefault,
|
||||||
borderBottomColor: instanceQuery.isError ? colors.red : colors.border,
|
borderBottomColor: instanceQuery.isError
|
||||||
|
? whitelisted
|
||||||
|
? colors.yellow
|
||||||
|
: colors.red
|
||||||
|
: colors.border,
|
||||||
...(Platform.OS === 'android' && { paddingRight: 0 })
|
...(Platform.OS === 'android' && { paddingRight: 0 })
|
||||||
}}
|
}}
|
||||||
editable={false}
|
editable={false}
|
||||||
@ -159,12 +178,23 @@ const ComponentInstance: React.FC<Props> = ({
|
|||||||
...StyleConstants.FontStyle.M,
|
...StyleConstants.FontStyle.M,
|
||||||
marginRight: StyleConstants.Spacing.M,
|
marginRight: StyleConstants.Spacing.M,
|
||||||
color: colors.primaryDefault,
|
color: colors.primaryDefault,
|
||||||
borderBottomColor: instanceQuery.isError ? colors.red : colors.border,
|
borderBottomColor: instanceQuery.isError
|
||||||
|
? whitelisted
|
||||||
|
? colors.yellow
|
||||||
|
: colors.red
|
||||||
|
: colors.border,
|
||||||
...(Platform.OS === 'android' && { paddingLeft: 0 })
|
...(Platform.OS === 'android' && { paddingLeft: 0 })
|
||||||
}}
|
}}
|
||||||
onChangeText={debounce(text => setDomain(text.replace(/^http(s)?\:\/\//i, '')), 1000, {
|
onChangeText={debounce(
|
||||||
|
text => {
|
||||||
|
setDomain(text.replace(/^http(s)?\:\/\//i, ''))
|
||||||
|
setErrorCode(null)
|
||||||
|
},
|
||||||
|
1000,
|
||||||
|
{
|
||||||
trailing: true
|
trailing: true
|
||||||
})}
|
}
|
||||||
|
)}
|
||||||
autoCapitalize='none'
|
autoCapitalize='none'
|
||||||
clearButtonMode='never'
|
clearButtonMode='never'
|
||||||
keyboardType='url'
|
keyboardType='url'
|
||||||
@ -194,12 +224,24 @@ const ComponentInstance: React.FC<Props> = ({
|
|||||||
type='text'
|
type='text'
|
||||||
content={t('server.button')}
|
content={t('server.button')}
|
||||||
onPress={processUpdate}
|
onPress={processUpdate}
|
||||||
disabled={!instanceQuery.data?.uri}
|
disabled={!instanceQuery.data?.uri && !whitelisted}
|
||||||
loading={instanceQuery.isFetching || appsMutation.isLoading}
|
loading={instanceQuery.isFetching || appsMutation.isLoading}
|
||||||
/>
|
/>
|
||||||
</View>
|
</View>
|
||||||
|
|
||||||
<View>
|
<View>
|
||||||
|
{whitelisted ? (
|
||||||
|
<CustomText
|
||||||
|
fontStyle='S'
|
||||||
|
style={{
|
||||||
|
color: colors.yellow,
|
||||||
|
paddingHorizontal: StyleConstants.Spacing.Global.PagePadding,
|
||||||
|
paddingTop: StyleConstants.Spacing.XS
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{t('server.whitelisted')}
|
||||||
|
</CustomText>
|
||||||
|
) : (
|
||||||
<Placeholder>
|
<Placeholder>
|
||||||
<InstanceInfo
|
<InstanceInfo
|
||||||
header={t('server.information.name')}
|
header={t('server.information.name')}
|
||||||
@ -227,6 +269,7 @@ const ComponentInstance: React.FC<Props> = ({
|
|||||||
/>
|
/>
|
||||||
</View>
|
</View>
|
||||||
</Placeholder>
|
</Placeholder>
|
||||||
|
)}
|
||||||
<View
|
<View
|
||||||
style={{
|
style={{
|
||||||
flexDirection: 'row',
|
flexDirection: 'row',
|
||||||
|
@ -4,8 +4,8 @@ import { getSettingsFontsize } from '@utils/slices/settingsSlice'
|
|||||||
import { StyleConstants } from '@utils/styles/constants'
|
import { StyleConstants } from '@utils/styles/constants'
|
||||||
import { adaptiveScale } from '@utils/styles/scaling'
|
import { adaptiveScale } from '@utils/styles/scaling'
|
||||||
import { useTheme } from '@utils/styles/ThemeManager'
|
import { useTheme } from '@utils/styles/ThemeManager'
|
||||||
import React, { useMemo } from 'react'
|
import React from 'react'
|
||||||
import { Platform, StyleSheet, TextStyle } from 'react-native'
|
import { Platform, TextStyle } from 'react-native'
|
||||||
import FastImage from 'react-native-fast-image'
|
import FastImage from 'react-native-fast-image'
|
||||||
import { useSelector } from 'react-redux'
|
import { useSelector } from 'react-redux'
|
||||||
import validUrl from 'valid-url'
|
import validUrl from 'valid-url'
|
||||||
@ -36,23 +36,19 @@ const ParseEmojis = React.memo(
|
|||||||
)
|
)
|
||||||
|
|
||||||
const { colors, theme } = useTheme()
|
const { colors, theme } = useTheme()
|
||||||
const styles = useMemo(() => {
|
|
||||||
return StyleSheet.create({
|
return (
|
||||||
text: {
|
<CustomText
|
||||||
|
style={[
|
||||||
|
{
|
||||||
color: colors.primaryDefault,
|
color: colors.primaryDefault,
|
||||||
fontSize: adaptedFontsize,
|
fontSize: adaptedFontsize,
|
||||||
lineHeight: adaptedLineheight
|
lineHeight: adaptedLineheight
|
||||||
},
|
},
|
||||||
image: {
|
style
|
||||||
width: adaptedFontsize,
|
]}
|
||||||
height: adaptedFontsize,
|
fontWeight={fontBold ? 'Bold' : undefined}
|
||||||
...(Platform.OS === 'android' && { transform: [{ translateY: 2 }] })
|
>
|
||||||
}
|
|
||||||
})
|
|
||||||
}, [theme, adaptiveFontsize])
|
|
||||||
|
|
||||||
return (
|
|
||||||
<CustomText style={[styles.text, style]} fontWeight={fontBold ? 'Bold' : undefined}>
|
|
||||||
{emojis ? (
|
{emojis ? (
|
||||||
content
|
content
|
||||||
.split(regexEmoji)
|
.split(regexEmoji)
|
||||||
@ -73,7 +69,14 @@ const ParseEmojis = React.memo(
|
|||||||
return (
|
return (
|
||||||
<CustomText key={emojiShortcode + i}>
|
<CustomText key={emojiShortcode + i}>
|
||||||
{i === 0 ? ' ' : undefined}
|
{i === 0 ? ' ' : undefined}
|
||||||
<FastImage source={{ uri }} style={styles.image} />
|
<FastImage
|
||||||
|
source={{ uri }}
|
||||||
|
style={{
|
||||||
|
width: adaptedFontsize,
|
||||||
|
height: adaptedFontsize,
|
||||||
|
transform: [{ translateY: Platform.OS === 'ios' ? -1 : 2 }]
|
||||||
|
}}
|
||||||
|
/>
|
||||||
</CustomText>
|
</CustomText>
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
|
@ -102,7 +102,7 @@ const renderNode = ({
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
const domain = href?.split(new RegExp(/:\/\/(.[^\/]+)/))
|
const domain = href?.split(new RegExp(/:\/\/(.[^\/]+\/.{3})/))
|
||||||
// Need example here
|
// Need example here
|
||||||
const content = node.children && node.children[0] && node.children[0].data
|
const content = node.children && node.children[0] && node.children[0].data
|
||||||
const shouldBeTag = tags && tags.filter(tag => `#${tag.name}` === content).length > 0
|
const shouldBeTag = tags && tags.filter(tag => `#${tag.name}` === content).length > 0
|
||||||
@ -128,17 +128,7 @@ const renderNode = ({
|
|||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{content && content !== href ? content : showFullLink ? href : domain?.[1]}
|
{content && content !== href ? content : showFullLink ? href : domain?.[1]}
|
||||||
{!shouldBeTag ? (
|
{!shouldBeTag ? '...' : null}
|
||||||
<Icon
|
|
||||||
color={colors.blue}
|
|
||||||
name='ExternalLink'
|
|
||||||
size={adaptedFontsize}
|
|
||||||
style={{
|
|
||||||
marginLeft: StyleConstants.Spacing.XS,
|
|
||||||
...(Platform.OS === 'android' && { transform: [{ translateY: 2 }] })
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
) : null}
|
|
||||||
</CustomText>
|
</CustomText>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -6,21 +6,24 @@ import {
|
|||||||
useRelationshipMutation,
|
useRelationshipMutation,
|
||||||
useRelationshipQuery
|
useRelationshipQuery
|
||||||
} from '@utils/queryHooks/relationship'
|
} from '@utils/queryHooks/relationship'
|
||||||
import { QueryKeyTimeline } from '@utils/queryHooks/timeline'
|
|
||||||
import { useTheme } from '@utils/styles/ThemeManager'
|
import { useTheme } from '@utils/styles/ThemeManager'
|
||||||
import React from 'react'
|
import React from 'react'
|
||||||
import { useTranslation } from 'react-i18next'
|
import { useTranslation } from 'react-i18next'
|
||||||
import { useQueryClient } from '@tanstack/react-query'
|
import { useQueryClient } from '@tanstack/react-query'
|
||||||
|
import { useSelector } from 'react-redux'
|
||||||
|
import { checkInstanceFeature } from '@utils/slices/instancesSlice'
|
||||||
|
import { StyleConstants } from '@utils/styles/constants'
|
||||||
|
|
||||||
export interface Props {
|
export interface Props {
|
||||||
id: Mastodon.Account['id']
|
id: Mastodon.Account['id']
|
||||||
}
|
}
|
||||||
|
|
||||||
const RelationshipOutgoing = React.memo(
|
const RelationshipOutgoing: React.FC<Props> = ({ id }: Props) => {
|
||||||
({ id }: Props) => {
|
|
||||||
const { theme } = useTheme()
|
const { theme } = useTheme()
|
||||||
const { t } = useTranslation('componentRelationship')
|
const { t } = useTranslation('componentRelationship')
|
||||||
|
|
||||||
|
const canFollowNotify = useSelector(checkInstanceFeature('account_follow_notify'))
|
||||||
|
|
||||||
const query = useRelationshipQuery({ id })
|
const query = useRelationshipQuery({ id })
|
||||||
|
|
||||||
const queryKeyRelationship: QueryKeyRelationship = ['Relationship', { id }]
|
const queryKeyRelationship: QueryKeyRelationship = ['Relationship', { id }]
|
||||||
@ -120,6 +123,27 @@ const RelationshipOutgoing = React.memo(
|
|||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
<>
|
||||||
|
{canFollowNotify && query.data?.following ? (
|
||||||
|
<Button
|
||||||
|
type='icon'
|
||||||
|
content={query.data.notifying ? 'BellOff' : 'Bell'}
|
||||||
|
round
|
||||||
|
onPress={() =>
|
||||||
|
mutation.mutate({
|
||||||
|
id,
|
||||||
|
type: 'outgoing',
|
||||||
|
payload: {
|
||||||
|
action: 'follow',
|
||||||
|
state: false,
|
||||||
|
notify: !query.data.notifying
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
loading={query.isLoading || mutation.isLoading}
|
||||||
|
style={{ marginRight: StyleConstants.Spacing.S }}
|
||||||
|
/>
|
||||||
|
) : null}
|
||||||
<Button
|
<Button
|
||||||
type='text'
|
type='text'
|
||||||
content={content}
|
content={content}
|
||||||
@ -127,9 +151,8 @@ const RelationshipOutgoing = React.memo(
|
|||||||
loading={query.isLoading || mutation.isLoading}
|
loading={query.isLoading || mutation.isLoading}
|
||||||
disabled={query.isError || query.data?.blocked_by}
|
disabled={query.isError || query.data?.blocked_by}
|
||||||
/>
|
/>
|
||||||
|
</>
|
||||||
)
|
)
|
||||||
},
|
}
|
||||||
() => true
|
|
||||||
)
|
|
||||||
|
|
||||||
export default RelationshipOutgoing
|
export default RelationshipOutgoing
|
||||||
|
@ -98,7 +98,6 @@ const TimelineConversation: React.FC<Props> = ({ conversation, queryKey, highlig
|
|||||||
</View>
|
</View>
|
||||||
|
|
||||||
{conversation.last_status ? (
|
{conversation.last_status ? (
|
||||||
<>
|
|
||||||
<View
|
<View
|
||||||
style={{
|
style={{
|
||||||
paddingTop: highlighted ? StyleConstants.Spacing.S : 0,
|
paddingTop: highlighted ? StyleConstants.Spacing.S : 0,
|
||||||
@ -107,10 +106,9 @@ const TimelineConversation: React.FC<Props> = ({ conversation, queryKey, highlig
|
|||||||
>
|
>
|
||||||
<TimelineContent />
|
<TimelineContent />
|
||||||
<TimelinePoll />
|
<TimelinePoll />
|
||||||
</View>
|
|
||||||
|
|
||||||
<TimelineActions />
|
<TimelineActions />
|
||||||
</>
|
</View>
|
||||||
) : null}
|
) : null}
|
||||||
</Pressable>
|
</Pressable>
|
||||||
</StatusContext.Provider>
|
</StatusContext.Provider>
|
||||||
|
@ -9,11 +9,12 @@ import TimelineCard from '@components/Timeline/Shared/Card'
|
|||||||
import TimelineContent from '@components/Timeline/Shared/Content'
|
import TimelineContent from '@components/Timeline/Shared/Content'
|
||||||
import TimelineHeaderDefault from '@components/Timeline/Shared/HeaderDefault'
|
import TimelineHeaderDefault from '@components/Timeline/Shared/HeaderDefault'
|
||||||
import TimelinePoll from '@components/Timeline/Shared/Poll'
|
import TimelinePoll from '@components/Timeline/Shared/Poll'
|
||||||
|
import removeHTML from '@helpers/removeHTML'
|
||||||
import { useNavigation } from '@react-navigation/native'
|
import { useNavigation } from '@react-navigation/native'
|
||||||
import { StackNavigationProp } from '@react-navigation/stack'
|
import { StackNavigationProp } from '@react-navigation/stack'
|
||||||
import { TabLocalStackParamList } from '@utils/navigation/navigators'
|
import { TabLocalStackParamList } from '@utils/navigation/navigators'
|
||||||
import { QueryKeyTimeline } from '@utils/queryHooks/timeline'
|
import { QueryKeyTimeline } from '@utils/queryHooks/timeline'
|
||||||
import { getInstanceAccount } from '@utils/slices/instancesSlice'
|
import { checkInstanceFeature, getInstanceAccount } from '@utils/slices/instancesSlice'
|
||||||
import { StyleConstants } from '@utils/styles/constants'
|
import { StyleConstants } from '@utils/styles/constants'
|
||||||
import { useTheme } from '@utils/styles/ThemeManager'
|
import { useTheme } from '@utils/styles/ThemeManager'
|
||||||
import React, { useRef, useState } from 'react'
|
import React, { useRef, useState } from 'react'
|
||||||
@ -22,7 +23,7 @@ import { useSelector } from 'react-redux'
|
|||||||
import * as ContextMenu from 'zeego/context-menu'
|
import * as ContextMenu from 'zeego/context-menu'
|
||||||
import StatusContext from './Shared/Context'
|
import StatusContext from './Shared/Context'
|
||||||
import TimelineFeedback from './Shared/Feedback'
|
import TimelineFeedback from './Shared/Feedback'
|
||||||
import TimelineFiltered, { shouldFilter } from './Shared/Filtered'
|
import TimelineFiltered, { FilteredProps, shouldFilter } from './Shared/Filtered'
|
||||||
import TimelineFullConversation from './Shared/FullConversation'
|
import TimelineFullConversation from './Shared/FullConversation'
|
||||||
import TimelineHeaderAndroid from './Shared/HeaderAndroid'
|
import TimelineHeaderAndroid from './Shared/HeaderAndroid'
|
||||||
import TimelineTranslate from './Shared/Translate'
|
import TimelineTranslate from './Shared/Translate'
|
||||||
@ -47,12 +48,20 @@ const TimelineDefault: React.FC<Props> = ({
|
|||||||
disableOnPress = false,
|
disableOnPress = false,
|
||||||
isConversation = false
|
isConversation = false
|
||||||
}) => {
|
}) => {
|
||||||
|
const status = item.reblog ? item.reblog : item
|
||||||
|
const rawContent = useRef<string[]>([])
|
||||||
|
if (highlighted) {
|
||||||
|
rawContent.current = [
|
||||||
|
removeHTML(status.content),
|
||||||
|
status.spoiler_text ? removeHTML(status.spoiler_text) : ''
|
||||||
|
].filter(c => c.length)
|
||||||
|
}
|
||||||
|
|
||||||
const { colors } = useTheme()
|
const { colors } = useTheme()
|
||||||
const navigation = useNavigation<StackNavigationProp<TabLocalStackParamList>>()
|
const navigation = useNavigation<StackNavigationProp<TabLocalStackParamList>>()
|
||||||
|
|
||||||
const instanceAccount = useSelector(getInstanceAccount, () => true)
|
const instanceAccount = useSelector(getInstanceAccount, () => true)
|
||||||
|
|
||||||
const status = item.reblog ? item.reblog : item
|
|
||||||
const ownAccount = status.account?.id === instanceAccount?.id
|
const ownAccount = status.account?.id === instanceAccount?.id
|
||||||
const [spoilerExpanded, setSpoilerExpanded] = useState(
|
const [spoilerExpanded, setSpoilerExpanded] = useState(
|
||||||
instanceAccount?.preferences?.['reading:expand:spoilers'] || false
|
instanceAccount?.preferences?.['reading:expand:spoilers'] || false
|
||||||
@ -60,15 +69,7 @@ const TimelineDefault: React.FC<Props> = ({
|
|||||||
const spoilerHidden = status.spoiler_text?.length
|
const spoilerHidden = status.spoiler_text?.length
|
||||||
? !instanceAccount?.preferences?.['reading:expand:spoilers'] && !spoilerExpanded
|
? !instanceAccount?.preferences?.['reading:expand:spoilers'] && !spoilerExpanded
|
||||||
: false
|
: false
|
||||||
const copiableContent = useRef<{ content: string; complete: boolean }>({
|
const detectedLanguage = useRef<string>(status.language || '')
|
||||||
content: '',
|
|
||||||
complete: false
|
|
||||||
})
|
|
||||||
|
|
||||||
const filtered = queryKey && shouldFilter({ copiableContent, status, queryKey })
|
|
||||||
if (queryKey && filtered && !highlighted) {
|
|
||||||
return <TimelineFiltered phrase={filtered} />
|
|
||||||
}
|
|
||||||
|
|
||||||
const mainStyle: StyleProp<ViewStyle> = {
|
const mainStyle: StyleProp<ViewStyle> = {
|
||||||
flex: 1,
|
flex: 1,
|
||||||
@ -102,8 +103,9 @@ const TimelineDefault: React.FC<Props> = ({
|
|||||||
paddingTop: highlighted ? StyleConstants.Spacing.S : 0,
|
paddingTop: highlighted ? StyleConstants.Spacing.S : 0,
|
||||||
paddingLeft: highlighted
|
paddingLeft: highlighted
|
||||||
? 0
|
? 0
|
||||||
: (disableDetails ? StyleConstants.Avatar.XS : StyleConstants.Avatar.M) +
|
: (disableDetails || isConversation
|
||||||
StyleConstants.Spacing.S,
|
? StyleConstants.Avatar.XS
|
||||||
|
: StyleConstants.Avatar.M) + StyleConstants.Spacing.S,
|
||||||
...(disableDetails && { marginTop: -StyleConstants.Spacing.S })
|
...(disableDetails && { marginTop: -StyleConstants.Spacing.S })
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
@ -114,9 +116,9 @@ const TimelineDefault: React.FC<Props> = ({
|
|||||||
<TimelineFullConversation />
|
<TimelineFullConversation />
|
||||||
<TimelineTranslate />
|
<TimelineTranslate />
|
||||||
<TimelineFeedback />
|
<TimelineFeedback />
|
||||||
</View>
|
|
||||||
|
|
||||||
<TimelineActions />
|
<TimelineActions />
|
||||||
|
</View>
|
||||||
</>
|
</>
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -124,11 +126,36 @@ const TimelineDefault: React.FC<Props> = ({
|
|||||||
visibility: status.visibility,
|
visibility: status.visibility,
|
||||||
type: 'status',
|
type: 'status',
|
||||||
url: status.url || status.uri,
|
url: status.url || status.uri,
|
||||||
copiableContent
|
rawContent
|
||||||
})
|
})
|
||||||
const mStatus = menuStatus({ status, queryKey, rootQueryKey })
|
const mStatus = menuStatus({ status, queryKey, rootQueryKey })
|
||||||
const mInstance = menuInstance({ status, queryKey, rootQueryKey })
|
const mInstance = menuInstance({ status, queryKey, rootQueryKey })
|
||||||
|
|
||||||
|
if (!ownAccount) {
|
||||||
|
let filterResults: FilteredProps['filterResults'] = []
|
||||||
|
const [filterRevealed, setFilterRevealed] = useState(false)
|
||||||
|
const hasFilterServerSide = useSelector(checkInstanceFeature('filter_server_side'))
|
||||||
|
if (hasFilterServerSide) {
|
||||||
|
if (status.filtered?.length) {
|
||||||
|
filterResults = status.filtered?.map(filter => filter.filter)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (queryKey) {
|
||||||
|
const checkFilter = shouldFilter({ queryKey, status })
|
||||||
|
if (checkFilter?.length) {
|
||||||
|
filterResults = checkFilter
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (queryKey && !highlighted && filterResults?.length && !filterRevealed) {
|
||||||
|
return !filterResults.filter(result => result.filter_action === 'hide').length ? (
|
||||||
|
<Pressable onPress={() => setFilterRevealed(!filterRevealed)}>
|
||||||
|
<TimelineFiltered filterResults={filterResults} />
|
||||||
|
</Pressable>
|
||||||
|
) : null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<StatusContext.Provider
|
<StatusContext.Provider
|
||||||
value={{
|
value={{
|
||||||
@ -138,7 +165,8 @@ const TimelineDefault: React.FC<Props> = ({
|
|||||||
reblogStatus: item.reblog ? item : undefined,
|
reblogStatus: item.reblog ? item : undefined,
|
||||||
ownAccount,
|
ownAccount,
|
||||||
spoilerHidden,
|
spoilerHidden,
|
||||||
copiableContent,
|
rawContent,
|
||||||
|
detectedLanguage,
|
||||||
highlighted,
|
highlighted,
|
||||||
inThread: queryKey?.[1].page === 'Toot',
|
inThread: queryKey?.[1].page === 'Toot',
|
||||||
disableDetails,
|
disableDetails,
|
||||||
|
@ -13,7 +13,7 @@ import { useNavigation } from '@react-navigation/native'
|
|||||||
import { StackNavigationProp } from '@react-navigation/stack'
|
import { StackNavigationProp } from '@react-navigation/stack'
|
||||||
import { TabLocalStackParamList } from '@utils/navigation/navigators'
|
import { TabLocalStackParamList } from '@utils/navigation/navigators'
|
||||||
import { QueryKeyTimeline } from '@utils/queryHooks/timeline'
|
import { QueryKeyTimeline } from '@utils/queryHooks/timeline'
|
||||||
import { getInstanceAccount } from '@utils/slices/instancesSlice'
|
import { checkInstanceFeature, getInstanceAccount } from '@utils/slices/instancesSlice'
|
||||||
import { StyleConstants } from '@utils/styles/constants'
|
import { StyleConstants } from '@utils/styles/constants'
|
||||||
import { useTheme } from '@utils/styles/ThemeManager'
|
import { useTheme } from '@utils/styles/ThemeManager'
|
||||||
import React, { useCallback, useRef, useState } from 'react'
|
import React, { useCallback, useRef, useState } from 'react'
|
||||||
@ -21,7 +21,7 @@ import { Pressable, View } from 'react-native'
|
|||||||
import { useSelector } from 'react-redux'
|
import { useSelector } from 'react-redux'
|
||||||
import * as ContextMenu from 'zeego/context-menu'
|
import * as ContextMenu from 'zeego/context-menu'
|
||||||
import StatusContext from './Shared/Context'
|
import StatusContext from './Shared/Context'
|
||||||
import TimelineFiltered, { shouldFilter } from './Shared/Filtered'
|
import TimelineFiltered, { FilteredProps, shouldFilter } from './Shared/Filtered'
|
||||||
import TimelineFullConversation from './Shared/FullConversation'
|
import TimelineFullConversation from './Shared/FullConversation'
|
||||||
import TimelineHeaderAndroid from './Shared/HeaderAndroid'
|
import TimelineHeaderAndroid from './Shared/HeaderAndroid'
|
||||||
|
|
||||||
@ -47,21 +47,6 @@ const TimelineNotifications: React.FC<Props> = ({ notification, queryKey }) => {
|
|||||||
const spoilerHidden = notification.status?.spoiler_text?.length
|
const spoilerHidden = notification.status?.spoiler_text?.length
|
||||||
? !instanceAccount.preferences?.['reading:expand:spoilers'] && !spoilerExpanded
|
? !instanceAccount.preferences?.['reading:expand:spoilers'] && !spoilerExpanded
|
||||||
: false
|
: false
|
||||||
const copiableContent = useRef<{ content: string; complete: boolean }>({
|
|
||||||
content: '',
|
|
||||||
complete: false
|
|
||||||
})
|
|
||||||
|
|
||||||
const filtered =
|
|
||||||
notification.status &&
|
|
||||||
shouldFilter({
|
|
||||||
copiableContent,
|
|
||||||
status: notification.status,
|
|
||||||
queryKey
|
|
||||||
})
|
|
||||||
if (notification.status && filtered) {
|
|
||||||
return <TimelineFiltered phrase={filtered} />
|
|
||||||
}
|
|
||||||
|
|
||||||
const { colors } = useTheme()
|
const { colors } = useTheme()
|
||||||
const navigation = useNavigation<StackNavigationProp<TabLocalStackParamList>>()
|
const navigation = useNavigation<StackNavigationProp<TabLocalStackParamList>>()
|
||||||
@ -112,11 +97,11 @@ const TimelineNotifications: React.FC<Props> = ({ notification, queryKey }) => {
|
|||||||
<TimelineAttachment />
|
<TimelineAttachment />
|
||||||
<TimelineCard />
|
<TimelineCard />
|
||||||
<TimelineFullConversation />
|
<TimelineFullConversation />
|
||||||
|
|
||||||
|
<TimelineActions />
|
||||||
</View>
|
</View>
|
||||||
) : null}
|
) : null}
|
||||||
</View>
|
</View>
|
||||||
|
|
||||||
<TimelineActions />
|
|
||||||
</>
|
</>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@ -124,20 +109,44 @@ const TimelineNotifications: React.FC<Props> = ({ notification, queryKey }) => {
|
|||||||
const mShare = menuShare({
|
const mShare = menuShare({
|
||||||
visibility: notification.status?.visibility,
|
visibility: notification.status?.visibility,
|
||||||
type: 'status',
|
type: 'status',
|
||||||
url: notification.status?.url || notification.status?.uri,
|
url: notification.status?.url || notification.status?.uri
|
||||||
copiableContent
|
|
||||||
})
|
})
|
||||||
const mStatus = menuStatus({ status: notification.status, queryKey })
|
const mStatus = menuStatus({ status: notification.status, queryKey })
|
||||||
const mInstance = menuInstance({ status: notification.status, queryKey })
|
const mInstance = menuInstance({ status: notification.status, queryKey })
|
||||||
|
|
||||||
|
if (!ownAccount) {
|
||||||
|
let filterResults: FilteredProps['filterResults'] = []
|
||||||
|
const [filterRevealed, setFilterRevealed] = useState(false)
|
||||||
|
const hasFilterServerSide = useSelector(checkInstanceFeature('filter_server_side'))
|
||||||
|
if (notification.status) {
|
||||||
|
if (hasFilterServerSide) {
|
||||||
|
if (notification.status.filtered?.length) {
|
||||||
|
filterResults = notification.status.filtered.map(filter => filter.filter)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
const checkFilter = shouldFilter({ queryKey, status: notification.status })
|
||||||
|
if (checkFilter?.length) {
|
||||||
|
filterResults = checkFilter
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (filterResults?.length && !filterRevealed) {
|
||||||
|
return !filterResults.filter(result => result.filter_action === 'hide').length ? (
|
||||||
|
<Pressable onPress={() => setFilterRevealed(!filterRevealed)}>
|
||||||
|
<TimelineFiltered filterResults={filterResults} />
|
||||||
|
</Pressable>
|
||||||
|
) : null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<StatusContext.Provider
|
<StatusContext.Provider
|
||||||
value={{
|
value={{
|
||||||
queryKey,
|
queryKey,
|
||||||
status,
|
status,
|
||||||
ownAccount,
|
ownAccount,
|
||||||
spoilerHidden,
|
spoilerHidden
|
||||||
copiableContent
|
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<ContextMenu.Root>
|
<ContextMenu.Root>
|
||||||
|
@ -55,7 +55,7 @@ const TimelineRefresh: React.FC<Props> = ({
|
|||||||
firstPage?.links?.prev && {
|
firstPage?.links?.prev && {
|
||||||
...(firstPage.links.prev.isOffset
|
...(firstPage.links.prev.isOffset
|
||||||
? { offset: firstPage.links.prev.id }
|
? { offset: firstPage.links.prev.id }
|
||||||
: { max_id: firstPage.links.prev.id }),
|
: { min_id: firstPage.links.prev.id }),
|
||||||
// https://github.com/facebook/react-native/issues/25239#issuecomment-731100372
|
// https://github.com/facebook/react-native/issues/25239#issuecomment-731100372
|
||||||
limit: '3'
|
limit: '3'
|
||||||
},
|
},
|
||||||
|
@ -2,6 +2,7 @@ import Icon from '@components/Icon'
|
|||||||
import { displayMessage } from '@components/Message'
|
import { displayMessage } from '@components/Message'
|
||||||
import CustomText from '@components/Text'
|
import CustomText from '@components/Text'
|
||||||
import { useActionSheet } from '@expo/react-native-action-sheet'
|
import { useActionSheet } from '@expo/react-native-action-sheet'
|
||||||
|
import { androidActionSheetStyles } from '@helpers/androidActionSheetStyles'
|
||||||
import { useNavigation } from '@react-navigation/native'
|
import { useNavigation } from '@react-navigation/native'
|
||||||
import { StackNavigationProp } from '@react-navigation/stack'
|
import { StackNavigationProp } from '@react-navigation/stack'
|
||||||
import { RootStackParamList } from '@utils/navigation/navigators'
|
import { RootStackParamList } from '@utils/navigation/navigators'
|
||||||
@ -99,7 +100,8 @@ const TimelineActions: React.FC = () => {
|
|||||||
t('shared.actions.reblogged.options.unlisted'),
|
t('shared.actions.reblogged.options.unlisted'),
|
||||||
t('common:buttons.cancel')
|
t('common:buttons.cancel')
|
||||||
],
|
],
|
||||||
cancelButtonIndex: 2
|
cancelButtonIndex: 2,
|
||||||
|
...androidActionSheetStyles(colors)
|
||||||
},
|
},
|
||||||
(selectedIndex: number) => {
|
(selectedIndex: number) => {
|
||||||
switch (selectedIndex) {
|
switch (selectedIndex) {
|
||||||
@ -263,11 +265,6 @@ const TimelineActions: React.FC = () => {
|
|||||||
}, [status.bookmarked])
|
}, [status.bookmarked])
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<View
|
|
||||||
style={{
|
|
||||||
paddingLeft: highlighted ? 0 : StyleConstants.Avatar.M + StyleConstants.Spacing.S
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<View style={{ flexDirection: 'row' }}>
|
<View style={{ flexDirection: 'row' }}>
|
||||||
<Pressable
|
<Pressable
|
||||||
{...(highlighted
|
{...(highlighted
|
||||||
@ -320,7 +317,6 @@ const TimelineActions: React.FC = () => {
|
|||||||
children={childrenBookmark}
|
children={childrenBookmark}
|
||||||
/>
|
/>
|
||||||
</View>
|
</View>
|
||||||
</View>
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -70,7 +70,6 @@ const TimelineAttachment = () => {
|
|||||||
preview_url: attachment.preview_url,
|
preview_url: attachment.preview_url,
|
||||||
url: attachment.url,
|
url: attachment.url,
|
||||||
remote_url: attachment.remote_url,
|
remote_url: attachment.remote_url,
|
||||||
blurhash: attachment.blurhash,
|
|
||||||
width: attachment.meta?.original?.width,
|
width: attachment.meta?.original?.width,
|
||||||
height: attachment.meta?.original?.height
|
height: attachment.meta?.original?.height
|
||||||
}
|
}
|
||||||
@ -90,7 +89,6 @@ const TimelineAttachment = () => {
|
|||||||
preview_url: attachment.preview_url,
|
preview_url: attachment.preview_url,
|
||||||
url: attachment.url,
|
url: attachment.url,
|
||||||
remote_url: attachment.remote_url,
|
remote_url: attachment.remote_url,
|
||||||
blurhash: attachment.blurhash,
|
|
||||||
width: attachment.meta?.original?.width,
|
width: attachment.meta?.original?.width,
|
||||||
height: attachment.meta?.original?.height
|
height: attachment.meta?.original?.height
|
||||||
}
|
}
|
||||||
|
@ -48,8 +48,7 @@ const TimelineAvatar: React.FC<Props> = ({ account }) => {
|
|||||||
style={{
|
style={{
|
||||||
borderRadius: StyleConstants.Avatar.M,
|
borderRadius: StyleConstants.Avatar.M,
|
||||||
overflow: 'hidden',
|
overflow: 'hidden',
|
||||||
marginRight: StyleConstants.Spacing.S,
|
marginRight: StyleConstants.Spacing.S
|
||||||
marginLeft: isConversation ? StyleConstants.Avatar.M - StyleConstants.Avatar.XS : undefined
|
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
)
|
)
|
||||||
|
@ -145,6 +145,7 @@ const TimelineCard: React.FC = () => {
|
|||||||
/>
|
/>
|
||||||
) : null}
|
) : null}
|
||||||
<View style={{ flex: 1, padding: StyleConstants.Spacing.S }}>
|
<View style={{ flex: 1, padding: StyleConstants.Spacing.S }}>
|
||||||
|
{status.card?.title.length ? (
|
||||||
<CustomText
|
<CustomText
|
||||||
fontStyle='S'
|
fontStyle='S'
|
||||||
numberOfLines={2}
|
numberOfLines={2}
|
||||||
@ -155,9 +156,10 @@ const TimelineCard: React.FC = () => {
|
|||||||
fontWeight='Bold'
|
fontWeight='Bold'
|
||||||
testID='title'
|
testID='title'
|
||||||
>
|
>
|
||||||
{status.card?.title}
|
{status.card.title}
|
||||||
</CustomText>
|
</CustomText>
|
||||||
{status.card?.description ? (
|
) : null}
|
||||||
|
{status.card?.description.length ? (
|
||||||
<CustomText
|
<CustomText
|
||||||
fontStyle='S'
|
fontStyle='S'
|
||||||
numberOfLines={1}
|
numberOfLines={1}
|
||||||
@ -170,9 +172,11 @@ const TimelineCard: React.FC = () => {
|
|||||||
{status.card.description}
|
{status.card.description}
|
||||||
</CustomText>
|
</CustomText>
|
||||||
) : null}
|
) : null}
|
||||||
|
{status.card?.url.length ? (
|
||||||
<CustomText fontStyle='S' numberOfLines={1} style={{ color: colors.secondary }}>
|
<CustomText fontStyle='S' numberOfLines={1} style={{ color: colors.secondary }}>
|
||||||
{status.card?.url}
|
{status.card.url}
|
||||||
</CustomText>
|
</CustomText>
|
||||||
|
) : null}
|
||||||
</View>
|
</View>
|
||||||
</>
|
</>
|
||||||
)
|
)
|
||||||
@ -187,10 +191,6 @@ const TimelineCard: React.FC = () => {
|
|||||||
style={{
|
style={{
|
||||||
flex: 1,
|
flex: 1,
|
||||||
flexDirection: 'row',
|
flexDirection: 'row',
|
||||||
minHeight:
|
|
||||||
(isStatus && foundStatus) || (isAccount && foundAccount)
|
|
||||||
? undefined
|
|
||||||
: StyleConstants.Font.LineHeight.M * 5,
|
|
||||||
marginTop: StyleConstants.Spacing.M,
|
marginTop: StyleConstants.Spacing.M,
|
||||||
borderWidth: StyleSheet.hairlineWidth,
|
borderWidth: StyleSheet.hairlineWidth,
|
||||||
borderRadius: StyleConstants.Spacing.S,
|
borderRadius: StyleConstants.Spacing.S,
|
||||||
|
@ -1,8 +1,12 @@
|
|||||||
import { ParseHTML } from '@components/Parse'
|
import { ParseHTML } from '@components/Parse'
|
||||||
|
import CustomText from '@components/Text'
|
||||||
import { getInstanceAccount } from '@utils/slices/instancesSlice'
|
import { getInstanceAccount } from '@utils/slices/instancesSlice'
|
||||||
|
import { StyleConstants } from '@utils/styles/constants'
|
||||||
|
import { useTheme } from '@utils/styles/ThemeManager'
|
||||||
import React, { useContext } from 'react'
|
import React, { useContext } from 'react'
|
||||||
import { useTranslation } from 'react-i18next'
|
import { useTranslation } from 'react-i18next'
|
||||||
import { Platform } from 'react-native'
|
import { Platform, StyleSheet, View } from 'react-native'
|
||||||
|
import { Path, Svg } from 'react-native-svg'
|
||||||
import { useSelector } from 'react-redux'
|
import { useSelector } from 'react-redux'
|
||||||
import { isRtlLang } from 'rtl-detect'
|
import { isRtlLang } from 'rtl-detect'
|
||||||
import StatusContext from './Context'
|
import StatusContext from './Context'
|
||||||
@ -16,6 +20,7 @@ const TimelineContent: React.FC<Props> = ({ notificationOwnToot = false, setSpoi
|
|||||||
const { status, highlighted, inThread, disableDetails } = useContext(StatusContext)
|
const { status, highlighted, inThread, disableDetails } = useContext(StatusContext)
|
||||||
if (!status || typeof status.content !== 'string' || !status.content.length) return null
|
if (!status || typeof status.content !== 'string' || !status.content.length) return null
|
||||||
|
|
||||||
|
const { colors } = useTheme()
|
||||||
const { t } = useTranslation('componentTimeline')
|
const { t } = useTranslation('componentTimeline')
|
||||||
const instanceAccount = useSelector(getInstanceAccount, () => true)
|
const instanceAccount = useSelector(getInstanceAccount, () => true)
|
||||||
|
|
||||||
@ -39,6 +44,11 @@ const TimelineContent: React.FC<Props> = ({ notificationOwnToot = false, setSpoi
|
|||||||
: undefined
|
: undefined
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
|
{inThread ? (
|
||||||
|
<CustomText fontStyle='S' style={{ textAlign: 'center', color: colors.secondary, paddingVertical: StyleConstants.Spacing.XS }}>
|
||||||
|
{t('shared.content.expandHint')}
|
||||||
|
</CustomText>
|
||||||
|
) : null}
|
||||||
<ParseHTML
|
<ParseHTML
|
||||||
content={status.content}
|
content={status.content}
|
||||||
size={highlighted ? 'L' : 'M'}
|
size={highlighted ? 'L' : 'M'}
|
||||||
|
@ -1,7 +1,9 @@
|
|||||||
import { QueryKeyTimeline } from '@utils/queryHooks/timeline'
|
import { QueryKeyTimeline } from '@utils/queryHooks/timeline'
|
||||||
import { createContext } from 'react'
|
import { createContext } from 'react'
|
||||||
|
|
||||||
type ContextType = {
|
export type HighlightedStatusContextType = {}
|
||||||
|
|
||||||
|
type StatusContextType = {
|
||||||
queryKey?: QueryKeyTimeline
|
queryKey?: QueryKeyTimeline
|
||||||
rootQueryKey?: QueryKeyTimeline
|
rootQueryKey?: QueryKeyTimeline
|
||||||
|
|
||||||
@ -10,10 +12,8 @@ type ContextType = {
|
|||||||
reblogStatus?: Mastodon.Status // When it is a reblog, pass the root status
|
reblogStatus?: Mastodon.Status // When it is a reblog, pass the root status
|
||||||
ownAccount?: boolean
|
ownAccount?: boolean
|
||||||
spoilerHidden?: boolean
|
spoilerHidden?: boolean
|
||||||
copiableContent?: React.MutableRefObject<{
|
rawContent?: React.MutableRefObject<string[]> // When highlighted, for translate, edit history
|
||||||
content: string
|
detectedLanguage?: React.MutableRefObject<string>
|
||||||
complete: boolean
|
|
||||||
}>
|
|
||||||
|
|
||||||
highlighted?: boolean
|
highlighted?: boolean
|
||||||
inThread?: boolean
|
inThread?: boolean
|
||||||
@ -21,6 +21,6 @@ type ContextType = {
|
|||||||
disableOnPress?: boolean
|
disableOnPress?: boolean
|
||||||
isConversation?: boolean
|
isConversation?: boolean
|
||||||
}
|
}
|
||||||
const StatusContext = createContext<ContextType>({} as ContextType)
|
const StatusContext = createContext<StatusContextType>({} as StatusContextType)
|
||||||
|
|
||||||
export default StatusContext
|
export default StatusContext
|
||||||
|
@ -11,7 +11,7 @@ import { StyleSheet, View } from 'react-native'
|
|||||||
import StatusContext from './Context'
|
import StatusContext from './Context'
|
||||||
|
|
||||||
const TimelineFeedback = () => {
|
const TimelineFeedback = () => {
|
||||||
const { status, highlighted } = useContext(StatusContext)
|
const { status, highlighted, detectedLanguage } = useContext(StatusContext)
|
||||||
if (!status || !highlighted) return null
|
if (!status || !highlighted) return null
|
||||||
|
|
||||||
const { t } = useTranslation('componentTimeline')
|
const { t } = useTranslation('componentTimeline')
|
||||||
@ -80,7 +80,12 @@ const TimelineFeedback = () => {
|
|||||||
accessibilityHint={t('shared.actionsUsers.history.accessibilityHint')}
|
accessibilityHint={t('shared.actionsUsers.history.accessibilityHint')}
|
||||||
accessibilityRole='button'
|
accessibilityRole='button'
|
||||||
style={[styles.text, { marginRight: 0, color: colors.blue }]}
|
style={[styles.text, { marginRight: 0, color: colors.blue }]}
|
||||||
onPress={() => navigation.push('Tab-Shared-History', { id: status.id })}
|
onPress={() =>
|
||||||
|
navigation.push('Tab-Shared-History', {
|
||||||
|
id: status.id,
|
||||||
|
detectedLanguage: detectedLanguage?.current || status.language || ''
|
||||||
|
})
|
||||||
|
}
|
||||||
>
|
>
|
||||||
{t('shared.actionsUsers.history.text', {
|
{t('shared.actionsUsers.history.text', {
|
||||||
count: data.length - 1
|
count: data.length - 1
|
||||||
|
@ -1,19 +1,46 @@
|
|||||||
import CustomText from '@components/Text'
|
import CustomText from '@components/Text'
|
||||||
|
import removeHTML from '@helpers/removeHTML'
|
||||||
import { store } from '@root/store'
|
import { store } from '@root/store'
|
||||||
import { QueryKeyTimeline } from '@utils/queryHooks/timeline'
|
import { QueryKeyTimeline } from '@utils/queryHooks/timeline'
|
||||||
import { getInstance, getInstanceAccount } from '@utils/slices/instancesSlice'
|
import { getInstance } from '@utils/slices/instancesSlice'
|
||||||
import { StyleConstants } from '@utils/styles/constants'
|
import { StyleConstants } from '@utils/styles/constants'
|
||||||
import { useTheme } from '@utils/styles/ThemeManager'
|
import { useTheme } from '@utils/styles/ThemeManager'
|
||||||
import htmlparser2 from 'htmlparser2-without-node-native'
|
|
||||||
import React from 'react'
|
import React from 'react'
|
||||||
import { useTranslation } from 'react-i18next'
|
import { useTranslation } from 'react-i18next'
|
||||||
import { View } from 'react-native'
|
import { View } from 'react-native'
|
||||||
|
|
||||||
const TimelineFiltered = React.memo(
|
export interface FilteredProps {
|
||||||
({ phrase }: { phrase: string }) => {
|
filterResults: { title: string; filter_action: Mastodon.Filter<'v2'>['filter_action'] }[]
|
||||||
|
}
|
||||||
|
|
||||||
|
const TimelineFiltered: React.FC<FilteredProps> = ({ filterResults }) => {
|
||||||
const { colors } = useTheme()
|
const { colors } = useTheme()
|
||||||
const { t } = useTranslation('componentTimeline')
|
const { t } = useTranslation('componentTimeline')
|
||||||
|
|
||||||
|
const main = () => {
|
||||||
|
if (!filterResults?.length) {
|
||||||
|
return <></>
|
||||||
|
}
|
||||||
|
switch (typeof filterResults[0]) {
|
||||||
|
case 'string': // v1 filter
|
||||||
|
return <>{t('shared.filtered.match', { context: 'v1', phrase: filterResults[0] })}</>
|
||||||
|
default:
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
{t('shared.filtered.match', {
|
||||||
|
context: 'v2',
|
||||||
|
count: filterResults.length,
|
||||||
|
filters: filterResults.map(result => result.title).join(t('common:separator'))
|
||||||
|
})}
|
||||||
|
<CustomText
|
||||||
|
style={{ color: colors.blue }}
|
||||||
|
children={`\n${t('shared.filtered.reveal')}`}
|
||||||
|
/>
|
||||||
|
</>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<View style={{ backgroundColor: colors.backgroundDefault }}>
|
<View style={{ backgroundColor: colors.backgroundDefault }}>
|
||||||
<CustomText
|
<CustomText
|
||||||
@ -25,67 +52,47 @@ const TimelineFiltered = React.memo(
|
|||||||
paddingLeft: StyleConstants.Avatar.M + StyleConstants.Spacing.S
|
paddingLeft: StyleConstants.Avatar.M + StyleConstants.Spacing.S
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{t('shared.filtered', { phrase })}
|
{main()}
|
||||||
</CustomText>
|
</CustomText>
|
||||||
</View>
|
</View>
|
||||||
)
|
)
|
||||||
},
|
}
|
||||||
() => true
|
|
||||||
)
|
|
||||||
|
|
||||||
export const shouldFilter = ({
|
export const shouldFilter = ({
|
||||||
copiableContent,
|
queryKey,
|
||||||
status,
|
status
|
||||||
queryKey
|
|
||||||
}: {
|
}: {
|
||||||
copiableContent: React.MutableRefObject<{
|
|
||||||
content: string
|
|
||||||
complete: boolean
|
|
||||||
}>
|
|
||||||
status: Mastodon.Status
|
|
||||||
queryKey: QueryKeyTimeline
|
queryKey: QueryKeyTimeline
|
||||||
}): string | null => {
|
status: Pick<Mastodon.Status, 'content' | 'spoiler_text'>
|
||||||
|
}): FilteredProps['filterResults'] | undefined => {
|
||||||
const page = queryKey[1]
|
const page = queryKey[1]
|
||||||
const instance = getInstance(store.getState())
|
const instance = getInstance(store.getState())
|
||||||
const ownAccount = getInstanceAccount(store.getState())?.id === status.account?.id
|
|
||||||
|
|
||||||
let shouldFilter: string | null = null
|
let returnFilter: FilteredProps['filterResults'] | undefined
|
||||||
|
|
||||||
if (!ownAccount) {
|
const rawContentCombined = [
|
||||||
let rawContent = ''
|
removeHTML(status.content),
|
||||||
const parser = new htmlparser2.Parser({
|
status.spoiler_text ? removeHTML(status.spoiler_text) : ''
|
||||||
ontext: (text: string) => {
|
]
|
||||||
if (!copiableContent.current.complete) {
|
.filter(c => c.length)
|
||||||
copiableContent.current.content = copiableContent.current.content + text
|
.join(`\n`)
|
||||||
}
|
const checkFilter = (filter: Mastodon.Filter<'v1'>) => {
|
||||||
|
|
||||||
rawContent = rawContent + text
|
|
||||||
}
|
|
||||||
})
|
|
||||||
if (status.spoiler_text) {
|
|
||||||
parser.write(status.spoiler_text)
|
|
||||||
rawContent = rawContent + `\n\n`
|
|
||||||
}
|
|
||||||
parser.write(status.content)
|
|
||||||
parser.end()
|
|
||||||
|
|
||||||
const checkFilter = (filter: Mastodon.Filter) => {
|
|
||||||
const escapedPhrase = filter.phrase.replace(/[.*+?^${}()|[\]\\]/g, '\\$&') // $& means the whole matched string
|
const escapedPhrase = filter.phrase.replace(/[.*+?^${}()|[\]\\]/g, '\\$&') // $& means the whole matched string
|
||||||
switch (filter.whole_word) {
|
switch (filter.whole_word) {
|
||||||
case true:
|
case true:
|
||||||
if (new RegExp(`\\b${escapedPhrase}\\b`, 'i').test(rawContent)) {
|
if (new RegExp(`\\b${escapedPhrase}\\b`, 'i').test(rawContentCombined)) {
|
||||||
shouldFilter = filter.phrase
|
returnFilter = [{ title: filter.phrase, filter_action: 'warn' }]
|
||||||
}
|
}
|
||||||
break
|
break
|
||||||
case false:
|
case false:
|
||||||
if (new RegExp(escapedPhrase, 'i').test(rawContent)) {
|
if (new RegExp(escapedPhrase, 'i').test(rawContentCombined)) {
|
||||||
shouldFilter = filter.phrase
|
returnFilter = [{ title: filter.phrase, filter_action: 'warn' }]
|
||||||
}
|
}
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
instance?.filters?.forEach(filter => {
|
instance?.filters?.forEach(filter => {
|
||||||
if (shouldFilter) {
|
if (returnFilter) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if (filter.expires_at) {
|
if (filter.expires_at) {
|
||||||
@ -100,30 +107,27 @@ export const shouldFilter = ({
|
|||||||
case 'List':
|
case 'List':
|
||||||
case 'Account':
|
case 'Account':
|
||||||
if (filter.context.includes('home')) {
|
if (filter.context.includes('home')) {
|
||||||
checkFilter(filter)
|
checkFilter(filter as Mastodon.Filter<'v1'>)
|
||||||
}
|
}
|
||||||
break
|
break
|
||||||
case 'Notifications':
|
case 'Notifications':
|
||||||
if (filter.context.includes('notifications')) {
|
if (filter.context.includes('notifications')) {
|
||||||
checkFilter(filter)
|
checkFilter(filter as Mastodon.Filter<'v1'>)
|
||||||
}
|
}
|
||||||
break
|
break
|
||||||
case 'LocalPublic':
|
case 'LocalPublic':
|
||||||
if (filter.context.includes('public')) {
|
if (filter.context.includes('public')) {
|
||||||
checkFilter(filter)
|
checkFilter(filter as Mastodon.Filter<'v1'>)
|
||||||
}
|
}
|
||||||
break
|
break
|
||||||
case 'Toot':
|
case 'Toot':
|
||||||
if (filter.context.includes('thread')) {
|
if (filter.context.includes('thread')) {
|
||||||
checkFilter(filter)
|
checkFilter(filter as Mastodon.Filter<'v1'>)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
copiableContent.current.complete = true
|
return returnFilter
|
||||||
}
|
|
||||||
|
|
||||||
return shouldFilter
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export default TimelineFiltered
|
export default TimelineFiltered
|
||||||
|
@ -10,7 +10,7 @@ import * as DropdownMenu from 'zeego/dropdown-menu'
|
|||||||
import StatusContext from './Context'
|
import StatusContext from './Context'
|
||||||
|
|
||||||
const TimelineHeaderAndroid: React.FC = () => {
|
const TimelineHeaderAndroid: React.FC = () => {
|
||||||
const { queryKey, rootQueryKey, status, disableDetails, disableOnPress } =
|
const { queryKey, rootQueryKey, status, disableDetails, disableOnPress, rawContent } =
|
||||||
useContext(StatusContext)
|
useContext(StatusContext)
|
||||||
|
|
||||||
if (Platform.OS !== 'android' || !status || disableDetails || disableOnPress) return null
|
if (Platform.OS !== 'android' || !status || disableDetails || disableOnPress) return null
|
||||||
@ -21,7 +21,8 @@ const TimelineHeaderAndroid: React.FC = () => {
|
|||||||
const mShare = menuShare({
|
const mShare = menuShare({
|
||||||
visibility: status.visibility,
|
visibility: status.visibility,
|
||||||
type: 'status',
|
type: 'status',
|
||||||
url: status.url || status.uri
|
url: status.url || status.uri,
|
||||||
|
rawContent
|
||||||
})
|
})
|
||||||
const mAccount = menuAccount({
|
const mAccount = menuAccount({
|
||||||
type: 'status',
|
type: 'status',
|
||||||
|
@ -16,7 +16,7 @@ import HeaderSharedMuted from './HeaderShared/Muted'
|
|||||||
import HeaderSharedVisibility from './HeaderShared/Visibility'
|
import HeaderSharedVisibility from './HeaderShared/Visibility'
|
||||||
|
|
||||||
const TimelineHeaderDefault: React.FC = () => {
|
const TimelineHeaderDefault: React.FC = () => {
|
||||||
const { queryKey, rootQueryKey, status, copiableContent, highlighted, disableDetails } =
|
const { queryKey, rootQueryKey, status, highlighted, disableDetails, rawContent } =
|
||||||
useContext(StatusContext)
|
useContext(StatusContext)
|
||||||
if (!status) return null
|
if (!status) return null
|
||||||
|
|
||||||
@ -28,7 +28,7 @@ const TimelineHeaderDefault: React.FC = () => {
|
|||||||
visibility: status.visibility,
|
visibility: status.visibility,
|
||||||
type: 'status',
|
type: 'status',
|
||||||
url: status.url || status.uri,
|
url: status.url || status.uri,
|
||||||
copiableContent
|
rawContent
|
||||||
})
|
})
|
||||||
const mAccount = menuAccount({
|
const mAccount = menuAccount({
|
||||||
type: 'status',
|
type: 'status',
|
||||||
|
@ -13,39 +13,25 @@ import { Circle } from 'react-native-animated-spinkit'
|
|||||||
import StatusContext from './Context'
|
import StatusContext from './Context'
|
||||||
|
|
||||||
const TimelineTranslate = () => {
|
const TimelineTranslate = () => {
|
||||||
const { status, highlighted, copiableContent } = useContext(StatusContext)
|
const { status, highlighted, rawContent, detectedLanguage } = useContext(StatusContext)
|
||||||
if (!status || !highlighted) return null
|
if (!status || !highlighted || !rawContent?.current.length) return null
|
||||||
|
|
||||||
const { t } = useTranslation('componentTimeline')
|
const { t } = useTranslation('componentTimeline')
|
||||||
const { colors } = useTheme()
|
const { colors } = useTheme()
|
||||||
|
|
||||||
const backupTextProcessing = (): string[] => {
|
const [detected, setDetected] = useState<{
|
||||||
const text = status.spoiler_text ? [status.spoiler_text, status.content] : [status.content]
|
|
||||||
|
|
||||||
for (const i in text) {
|
|
||||||
for (const emoji of status.emojis) {
|
|
||||||
text[i] = text[i].replaceAll(`:${emoji.shortcode}:`, ' ')
|
|
||||||
}
|
|
||||||
text[i] = text[i]
|
|
||||||
.replace(/(<([^>]+)>)/gi, ' ')
|
|
||||||
.replace(/@.*? /gi, ' ')
|
|
||||||
.replace(/#.*? /gi, ' ')
|
|
||||||
.replace(/http(s):\/\/.*? /gi, ' ')
|
|
||||||
}
|
|
||||||
return text
|
|
||||||
}
|
|
||||||
const text = copiableContent?.current.content
|
|
||||||
? [copiableContent?.current.content]
|
|
||||||
: backupTextProcessing()
|
|
||||||
|
|
||||||
const [detectedLanguage, setDetectedLanguage] = useState<{
|
|
||||||
language: string
|
language: string
|
||||||
confidence: number
|
confidence: number
|
||||||
}>({ language: status.language || '', confidence: 0 })
|
}>({ language: status.language || '', confidence: 0 })
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const detect = async () => {
|
const detect = async () => {
|
||||||
const result = await detectLanguage(text.join('\n\n'))
|
const result = await detectLanguage(rawContent.current.join('\n\n'))
|
||||||
result && setDetectedLanguage(result)
|
if (result) {
|
||||||
|
setDetected(result)
|
||||||
|
if (detectedLanguage) {
|
||||||
|
detectedLanguage.current = result.language
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
detect()
|
detect()
|
||||||
}, [])
|
}, [])
|
||||||
@ -57,18 +43,18 @@ const TimelineTranslate = () => {
|
|||||||
|
|
||||||
const [enabled, setEnabled] = useState(false)
|
const [enabled, setEnabled] = useState(false)
|
||||||
const { refetch, data, isFetching, isSuccess, isError } = useTranslateQuery({
|
const { refetch, data, isFetching, isSuccess, isError } = useTranslateQuery({
|
||||||
source: detectedLanguage.language,
|
source: detected.language,
|
||||||
target: targetLanguage,
|
target: targetLanguage,
|
||||||
text,
|
text: rawContent.current,
|
||||||
options: { enabled }
|
options: { enabled }
|
||||||
})
|
})
|
||||||
|
|
||||||
const devView = () => {
|
const devView = () => {
|
||||||
return __DEV__ ? (
|
return __DEV__ ? (
|
||||||
<CustomText fontStyle='S' style={{ color: colors.secondary }}>{` Source: ${
|
<CustomText fontStyle='S' style={{ color: colors.secondary }}>{` Source: ${
|
||||||
detectedLanguage?.language
|
detected?.language
|
||||||
}; Confidence: ${
|
}; Confidence: ${
|
||||||
detectedLanguage?.confidence.toString().slice(0, 5) || 'null'
|
detected?.confidence.toString().slice(0, 5) || 'null'
|
||||||
}; Target: ${targetLanguage}`}</CustomText>
|
}; Target: ${targetLanguage}`}</CustomText>
|
||||||
) : null
|
) : null
|
||||||
}
|
}
|
||||||
@ -78,13 +64,13 @@ const TimelineTranslate = () => {
|
|||||||
}
|
}
|
||||||
if (
|
if (
|
||||||
Platform.OS === 'ios' &&
|
Platform.OS === 'ios' &&
|
||||||
Localization.locale.slice(0, 2).includes(detectedLanguage.language.slice(0, 2))
|
Localization.locale.slice(0, 2).includes(detected.language.slice(0, 2))
|
||||||
) {
|
) {
|
||||||
return devView()
|
return devView()
|
||||||
}
|
}
|
||||||
if (
|
if (
|
||||||
Platform.OS === 'android' &&
|
Platform.OS === 'android' &&
|
||||||
settingsLanguage?.slice(0, 2).includes(detectedLanguage.language.slice(0, 2))
|
settingsLanguage?.slice(0, 2).includes(detected.language.slice(0, 2))
|
||||||
) {
|
) {
|
||||||
return devView()
|
return devView()
|
||||||
}
|
}
|
||||||
|
@ -16,7 +16,7 @@ import {
|
|||||||
import { getInstanceAccount } from '@utils/slices/instancesSlice'
|
import { getInstanceAccount } from '@utils/slices/instancesSlice'
|
||||||
import { useEffect, useState } from 'react'
|
import { useEffect, useState } from 'react'
|
||||||
import { useTranslation } from 'react-i18next'
|
import { useTranslation } from 'react-i18next'
|
||||||
import { Platform } from 'react-native'
|
import { Alert, Platform } from 'react-native'
|
||||||
import { useQueryClient } from '@tanstack/react-query'
|
import { useQueryClient } from '@tanstack/react-query'
|
||||||
import { useSelector } from 'react-redux'
|
import { useSelector } from 'react-redux'
|
||||||
|
|
||||||
@ -186,12 +186,22 @@ const menuAccount = ({
|
|||||||
key: 'account-block',
|
key: 'account-block',
|
||||||
item: {
|
item: {
|
||||||
onSelect: () =>
|
onSelect: () =>
|
||||||
|
Alert.alert(t('account.block.alert.title', { username: account.username }), undefined, [
|
||||||
|
{
|
||||||
|
text: t('common:buttons.confirm'),
|
||||||
|
style: 'destructive',
|
||||||
|
onPress: () =>
|
||||||
timelineMutation.mutate({
|
timelineMutation.mutate({
|
||||||
type: 'updateAccountProperty',
|
type: 'updateAccountProperty',
|
||||||
queryKey,
|
queryKey,
|
||||||
id: account.id,
|
id: account.id,
|
||||||
payload: { property: 'block', currentValue: data?.blocking }
|
payload: { property: 'block', currentValue: data?.blocking }
|
||||||
}),
|
})
|
||||||
|
},
|
||||||
|
{
|
||||||
|
text: t('common:buttons.cancel')
|
||||||
|
}
|
||||||
|
]),
|
||||||
disabled: Platform.OS !== 'android' ? !data || !isFetched : false,
|
disabled: Platform.OS !== 'android' ? !data || !isFetched : false,
|
||||||
destructive: !data?.blocking,
|
destructive: !data?.blocking,
|
||||||
hidden: false
|
hidden: false
|
||||||
@ -204,7 +214,15 @@ const menuAccount = ({
|
|||||||
{
|
{
|
||||||
key: 'account-reports',
|
key: 'account-reports',
|
||||||
item: {
|
item: {
|
||||||
onSelect: () => {
|
onSelect: () =>
|
||||||
|
Alert.alert(
|
||||||
|
t('account.reports.alert.title', { username: account.username }),
|
||||||
|
undefined,
|
||||||
|
[
|
||||||
|
{
|
||||||
|
text: t('common:buttons.confirm'),
|
||||||
|
style: 'destructive',
|
||||||
|
onPress: () => {
|
||||||
timelineMutation.mutate({
|
timelineMutation.mutate({
|
||||||
type: 'updateAccountProperty',
|
type: 'updateAccountProperty',
|
||||||
queryKey,
|
queryKey,
|
||||||
@ -217,7 +235,13 @@ const menuAccount = ({
|
|||||||
id: account.id,
|
id: account.id,
|
||||||
payload: { property: 'block', currentValue: false }
|
payload: { property: 'block', currentValue: false }
|
||||||
})
|
})
|
||||||
|
}
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
text: t('common:buttons.cancel')
|
||||||
|
}
|
||||||
|
]
|
||||||
|
),
|
||||||
disabled: false,
|
disabled: false,
|
||||||
destructive: true,
|
destructive: true,
|
||||||
hidden: false
|
hidden: false
|
||||||
|
@ -49,7 +49,7 @@ const menuInstance = ({
|
|||||||
t('instance.block.alert.message'),
|
t('instance.block.alert.message'),
|
||||||
[
|
[
|
||||||
{
|
{
|
||||||
text: t('instance.block.alert.buttons.confirm'),
|
text: t('common:buttons.confirm'),
|
||||||
style: 'destructive',
|
style: 'destructive',
|
||||||
onPress: () => {
|
onPress: () => {
|
||||||
mutation.mutate({
|
mutation.mutate({
|
||||||
|
@ -7,10 +7,7 @@ const menuShare = (
|
|||||||
params:
|
params:
|
||||||
| {
|
| {
|
||||||
visibility?: Mastodon.Status['visibility']
|
visibility?: Mastodon.Status['visibility']
|
||||||
copiableContent?: React.MutableRefObject<{
|
rawContent?: React.MutableRefObject<string[]>
|
||||||
content?: string | undefined
|
|
||||||
complete: boolean
|
|
||||||
}>
|
|
||||||
type: 'status'
|
type: 'status'
|
||||||
url?: string
|
url?: string
|
||||||
}
|
}
|
||||||
@ -48,17 +45,17 @@ const menuShare = (
|
|||||||
icon: 'square.and.arrow.up'
|
icon: 'square.and.arrow.up'
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
if (params.type === 'status' && Platform.OS === 'ios')
|
if (params.type === 'status')
|
||||||
menus[0].push({
|
menus[0].push({
|
||||||
key: 'copy',
|
key: 'copy',
|
||||||
item: {
|
item: {
|
||||||
onSelect: () => {
|
onSelect: () => {
|
||||||
Clipboard.setString(params.copiableContent?.current.content || '')
|
Clipboard.setString(params.rawContent?.current.join(`\n\n`) || '')
|
||||||
displayMessage({ type: 'success', message: t(`copy.succeed`) })
|
displayMessage({ type: 'success', message: t(`copy.succeed`) })
|
||||||
},
|
},
|
||||||
disabled: false,
|
disabled: false,
|
||||||
destructive: false,
|
destructive: false,
|
||||||
hidden: !params.copiableContent?.current.content?.length
|
hidden: !params.rawContent?.current.length
|
||||||
},
|
},
|
||||||
title: t('copy.action'),
|
title: t('copy.action'),
|
||||||
icon: 'doc.on.doc'
|
icon: 'doc.on.doc'
|
||||||
|
@ -109,7 +109,7 @@ const menuStatus = ({
|
|||||||
onSelect: () =>
|
onSelect: () =>
|
||||||
Alert.alert(t('status.deleteEdit.alert.title'), t('status.deleteEdit.alert.message'), [
|
Alert.alert(t('status.deleteEdit.alert.title'), t('status.deleteEdit.alert.message'), [
|
||||||
{
|
{
|
||||||
text: t('status.deleteEdit.alert.buttons.confirm'),
|
text: t('common:buttons.confirm'),
|
||||||
style: 'destructive',
|
style: 'destructive',
|
||||||
onPress: async () => {
|
onPress: async () => {
|
||||||
let replyToStatus: Mastodon.Status | undefined = undefined
|
let replyToStatus: Mastodon.Status | undefined = undefined
|
||||||
@ -153,7 +153,7 @@ const menuStatus = ({
|
|||||||
onSelect: () =>
|
onSelect: () =>
|
||||||
Alert.alert(t('status.delete.alert.title'), t('status.delete.alert.message'), [
|
Alert.alert(t('status.delete.alert.title'), t('status.delete.alert.message'), [
|
||||||
{
|
{
|
||||||
text: t('status.delete.alert.buttons.confirm'),
|
text: t('common:buttons.confirm'),
|
||||||
style: 'destructive',
|
style: 'destructive',
|
||||||
onPress: async () => {
|
onPress: async () => {
|
||||||
mutation.mutate({
|
mutation.mutate({
|
||||||
|
5
src/helpers/androidActionSheetStyles.ts
Normal file
5
src/helpers/androidActionSheetStyles.ts
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
export const androidActionSheetStyles = (colors: any) => ({
|
||||||
|
containerStyle: { backgroundColor: colors.backgroundDefault },
|
||||||
|
textStyle: { color: colors.primaryDefault },
|
||||||
|
titleTextStyle: { color: colors.secondary }
|
||||||
|
})
|
@ -1,4 +1,8 @@
|
|||||||
[
|
[
|
||||||
|
{
|
||||||
|
"feature": "account_follow_notify",
|
||||||
|
"version": 3.3
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"feature": "notification_type_status",
|
"feature": "notification_type_status",
|
||||||
"version": 3.3
|
"version": 3.3
|
||||||
@ -38,5 +42,9 @@
|
|||||||
{
|
{
|
||||||
"feature": "notification_type_admin_report",
|
"feature": "notification_type_admin_report",
|
||||||
"version": 4.0
|
"version": 4.0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"feature": "filter_server_side",
|
||||||
|
"version": 4.0
|
||||||
}
|
}
|
||||||
]
|
]
|
@ -1,5 +1,21 @@
|
|||||||
import { QueryClient } from '@tanstack/react-query'
|
import { QueryClient } from '@tanstack/react-query'
|
||||||
|
|
||||||
const queryClient = new QueryClient({ defaultOptions: { queries: { staleTime: 1000 * 60 * 5 } } })
|
const queryClient = new QueryClient({
|
||||||
|
defaultOptions: {
|
||||||
|
queries: {
|
||||||
|
staleTime: 1000 * 60 * 5,
|
||||||
|
retry: (failureCount, error: any) => {
|
||||||
|
if (error?.status === 404) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
if (failureCount <= 3) {
|
||||||
|
return true
|
||||||
|
} else {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
export default queryClient
|
export default queryClient
|
||||||
|
@ -6,6 +6,9 @@ const removeHTML = (text: string): string => {
|
|||||||
const parser = new htmlparser2.Parser({
|
const parser = new htmlparser2.Parser({
|
||||||
ontext: (text: string) => {
|
ontext: (text: string) => {
|
||||||
raw = raw + text
|
raw = raw + text
|
||||||
|
},
|
||||||
|
onclosetag: (tag: string) => {
|
||||||
|
if (['p', 'br'].includes(tag)) raw = raw + `\n`
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -7,7 +7,8 @@
|
|||||||
"continue": "Continua",
|
"continue": "Continua",
|
||||||
"create": "Crea",
|
"create": "Crea",
|
||||||
"delete": "Esborra",
|
"delete": "Esborra",
|
||||||
"done": "Fet"
|
"done": "Fet",
|
||||||
|
"confirm": "Confirma"
|
||||||
},
|
},
|
||||||
"customEmoji": {
|
"customEmoji": {
|
||||||
"accessibilityLabel": "Emoji personalitzat {{emoji}}"
|
"accessibilityLabel": "Emoji personalitzat {{emoji}}"
|
||||||
|
@ -13,10 +13,16 @@
|
|||||||
},
|
},
|
||||||
"block": {
|
"block": {
|
||||||
"action_false": "Bloqueja l'usuari",
|
"action_false": "Bloqueja l'usuari",
|
||||||
"action_true": "Deixa de bloquejar l'usuari"
|
"action_true": "Deixa de bloquejar l'usuari",
|
||||||
|
"alert": {
|
||||||
|
"title": ""
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"reports": {
|
"reports": {
|
||||||
"action": "Denuncia i bloqueja l'usuari"
|
"action": "Denuncia i bloqueja l'usuari",
|
||||||
|
"alert": {
|
||||||
|
"title": ""
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"at": {
|
"at": {
|
||||||
@ -32,11 +38,8 @@
|
|||||||
"block": {
|
"block": {
|
||||||
"action": "Bloquejar la instància {{instance}}",
|
"action": "Bloquejar la instància {{instance}}",
|
||||||
"alert": {
|
"alert": {
|
||||||
"title": "Confirma el bloqueig de la instància {{instance}}?",
|
"title": "Vols bloquejar la instància {{instance}}?",
|
||||||
"message": "Pots silenciar o bloquejar a un usuari.\n\nDesprés de bloquejar una instància, tot el seu contingut, amb els seus seguidors, seran esborrats!",
|
"message": "Pots silenciar o bloquejar a un usuari.\n\nDesprés de bloquejar una instància, tot el seu contingut, amb els seus seguidors, seran esborrats!"
|
||||||
"buttons": {
|
|
||||||
"confirm": "Confirma"
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -56,21 +59,15 @@
|
|||||||
"delete": {
|
"delete": {
|
||||||
"action": "Elimina la publicació",
|
"action": "Elimina la publicació",
|
||||||
"alert": {
|
"alert": {
|
||||||
"title": "Confirma l'eliminació?",
|
"title": "Vols eliminar-ho?",
|
||||||
"message": "Tots els impulsos i favorits s'esborraran, incloses totes les respostes.",
|
"message": "Tots els impulsos i favorits s'esborraran, incloses totes les respostes."
|
||||||
"buttons": {
|
|
||||||
"confirm": "Confirma"
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"deleteEdit": {
|
"deleteEdit": {
|
||||||
"action": "Elimina la publicació i torna a publicar",
|
"action": "Elimina i torna-ho a publicar",
|
||||||
"alert": {
|
"alert": {
|
||||||
"title": "Confirma l'eliminació i tornar a publicar?",
|
"title": "Vols eliminar i tornar-ho a publicar?",
|
||||||
"message": "Tots els impulsos i favorits s'esborraran, incloses totes les respostes.",
|
"message": "Tots els impulsos i favorits s'esborraran, incloses totes les respostes."
|
||||||
"buttons": {
|
|
||||||
"confirm": "Confirma"
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"mute": {
|
"mute": {
|
||||||
|
@ -1,8 +1,9 @@
|
|||||||
{
|
{
|
||||||
"server": {
|
"server": {
|
||||||
"textInput": {
|
"textInput": {
|
||||||
"placeholder": ""
|
"placeholder": "Domini de la instància"
|
||||||
},
|
},
|
||||||
|
"whitelisted": "Pot ser una instància que estigui a la llista blanca de la qual tooot no pot obtenir les dades abans d'iniciar la sessió.",
|
||||||
"button": "Inicia la sessió",
|
"button": "Inicia la sessió",
|
||||||
"information": {
|
"information": {
|
||||||
"name": "Nom",
|
"name": "Nom",
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"title": "Selecciona origen multimèdia",
|
"title": "Selecciona origen multimèdia",
|
||||||
"message": "Les dades multimèdia EXIF no s'han penjat",
|
"message": "Les dades multimèdia EXIF no es penjen",
|
||||||
"options": {
|
"options": {
|
||||||
"image": "Penja fotos",
|
"image": "Penja fotos",
|
||||||
"image_max": "Penja fotos (màx. {{max}})",
|
"image_max": "Penja fotos (màx. {{max}})",
|
||||||
|
@ -31,7 +31,7 @@
|
|||||||
"notification": "{{name}} ha impulsat la teva publicació"
|
"notification": "{{name}} ha impulsat la teva publicació"
|
||||||
},
|
},
|
||||||
"update": "L'impuls ha sigut editat",
|
"update": "L'impuls ha sigut editat",
|
||||||
"admin.sign_up": "",
|
"admin.sign_up": "{{name}} s'ha unit a la instància",
|
||||||
"admin.report": ""
|
"admin.report": ""
|
||||||
},
|
},
|
||||||
"actions": {
|
"actions": {
|
||||||
@ -55,7 +55,7 @@
|
|||||||
"accessibilityLabel": "Afegeix aquesta publicació a marcadors",
|
"accessibilityLabel": "Afegeix aquesta publicació a marcadors",
|
||||||
"function": "Afegeix la publicació a marcadors"
|
"function": "Afegeix la publicació a marcadors"
|
||||||
},
|
},
|
||||||
"openReport": ""
|
"openReport": "Obre la denúncia"
|
||||||
},
|
},
|
||||||
"actionsUsers": {
|
"actionsUsers": {
|
||||||
"reblogged_by": {
|
"reblogged_by": {
|
||||||
@ -91,7 +91,12 @@
|
|||||||
"content": {
|
"content": {
|
||||||
"expandHint": "Contingut ocult"
|
"expandHint": "Contingut ocult"
|
||||||
},
|
},
|
||||||
"filtered": "Filtrat: {{phrase}}.",
|
"filtered": {
|
||||||
|
"reveal": "Mostra-ho de totes maneres",
|
||||||
|
"match_v1": "Filtrat: {{phrase}}.",
|
||||||
|
"match_v2_one": "Filtrat per {{filters}}.",
|
||||||
|
"match_v2_other": "Filtrat per {{count}} filtres, {{filters}}."
|
||||||
|
},
|
||||||
"fullConversation": "Llegeix conversacions",
|
"fullConversation": "Llegeix conversacions",
|
||||||
"translate": {
|
"translate": {
|
||||||
"default": "Tradueix",
|
"default": "Tradueix",
|
||||||
|
@ -1,8 +1,7 @@
|
|||||||
{
|
{
|
||||||
"screenshot": {
|
"screenshot": {
|
||||||
"title": "Protecció de la privacitat",
|
"title": "Protecció de la privacitat",
|
||||||
"message": "Si us plau, no revelis la identitat d'altres usuaris, així com el nom d'usuari, avatar, etc. Gràcies!",
|
"message": "Si us plau, no revelis la identitat d'altres usuaris, així com el nom d'usuari, avatar, etc. Gràcies!"
|
||||||
"button": "Confirma"
|
|
||||||
},
|
},
|
||||||
"localCorrupt": {
|
"localCorrupt": {
|
||||||
"message": "La sessió ha sigut expirada. Si us plau, torna a iniciar la sessió"
|
"message": "La sessió ha sigut expirada. Si us plau, torna a iniciar la sessió"
|
||||||
|
@ -11,11 +11,11 @@
|
|||||||
},
|
},
|
||||||
"right": {
|
"right": {
|
||||||
"button": {
|
"button": {
|
||||||
"default": "Publicació",
|
"default": "Publica",
|
||||||
"conversation": "Envia un missatge directe",
|
"conversation": "Envia un missatge directe",
|
||||||
"reply": "Resposta de la publicació",
|
"reply": "Publica la resposta",
|
||||||
"deleteEdit": "Publicació",
|
"deleteEdit": "Publicació",
|
||||||
"edit": "Publicació",
|
"edit": "Publica l'edició",
|
||||||
"share": "Publicació"
|
"share": "Publicació"
|
||||||
},
|
},
|
||||||
"alert": {
|
"alert": {
|
||||||
|
@ -3,15 +3,15 @@
|
|||||||
"local": {
|
"local": {
|
||||||
"name": "Seguint",
|
"name": "Seguint",
|
||||||
"options": {
|
"options": {
|
||||||
"showBoosts": "",
|
"showBoosts": "Mostra les publicacions",
|
||||||
"showReplies": ""
|
"showReplies": "Mostra les respostes"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"public": {
|
"public": {
|
||||||
"segments": {
|
"segments": {
|
||||||
"federated": "Federat",
|
"federated": "Federat",
|
||||||
"local": "Local",
|
"local": "Local",
|
||||||
"trending": "En tendència"
|
"trending": "Tendència"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"notifications": {
|
"notifications": {
|
||||||
@ -31,13 +31,13 @@
|
|||||||
"title": "Mostra les notificacions",
|
"title": "Mostra les notificacions",
|
||||||
"options": {
|
"options": {
|
||||||
"follow": "$t(screenTabs:me.push.follow.heading)",
|
"follow": "$t(screenTabs:me.push.follow.heading)",
|
||||||
"follow_request": "Sol·licitud de seguiment",
|
"follow_request": "Sol·licituds de seguiment",
|
||||||
"favourite": "$t(screenTabs:me.push.favourite.heading)",
|
"favourite": "$t(screenTabs:me.push.favourite.heading)",
|
||||||
"reblog": "$t(screenTabs:me.push.reblog.heading)",
|
"reblog": "$t(screenTabs:me.push.reblog.heading)",
|
||||||
"mention": "$t(screenTabs:me.push.mention.heading)",
|
"mention": "$t(screenTabs:me.push.mention.heading)",
|
||||||
"poll": "$t(screenTabs:me.push.poll.heading)",
|
"poll": "$t(screenTabs:me.push.poll.heading)",
|
||||||
"status": "Publicació d'usuaris subscrits",
|
"status": "Publicacions d'usuaris subscrits",
|
||||||
"update": "L'impuls ha sigut editat",
|
"update": "Edicions d'impulsos",
|
||||||
"admin.sign_up": "$t(screenTabs:me.push.admin.sign_up.heading)",
|
"admin.sign_up": "$t(screenTabs:me.push.admin.sign_up.heading)",
|
||||||
"admin.report": "$t(screenTabs:me.push.admin.report.heading)"
|
"admin.report": "$t(screenTabs:me.push.admin.report.heading)"
|
||||||
}
|
}
|
||||||
@ -163,7 +163,7 @@
|
|||||||
"total_other": "{{count}} camps"
|
"total_other": "{{count}} camps"
|
||||||
},
|
},
|
||||||
"visibility": {
|
"visibility": {
|
||||||
"title": "Visibilitat de la publicació",
|
"title": "Visibilitat",
|
||||||
"options": {
|
"options": {
|
||||||
"public": "Públic",
|
"public": "Públic",
|
||||||
"unlisted": "Sense llistar",
|
"unlisted": "Sense llistar",
|
||||||
@ -171,7 +171,7 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"sensitive": {
|
"sensitive": {
|
||||||
"title": "Publica contingut multimèdia sensible"
|
"title": "Continguts multimèdia sensibles"
|
||||||
},
|
},
|
||||||
"lock": {
|
"lock": {
|
||||||
"title": "Fes el compte privat",
|
"title": "Fes el compte privat",
|
||||||
@ -211,28 +211,28 @@
|
|||||||
"heading": "Per defecte"
|
"heading": "Per defecte"
|
||||||
},
|
},
|
||||||
"follow": {
|
"follow": {
|
||||||
"heading": "Nou seguidor"
|
"heading": "Seguidors nous"
|
||||||
},
|
},
|
||||||
"follow_request": {
|
"follow_request": {
|
||||||
"heading": "Sol·licitud de seguiment"
|
"heading": "Sol·licituds de seguiment"
|
||||||
},
|
},
|
||||||
"favourite": {
|
"favourite": {
|
||||||
"heading": "Favorits"
|
"heading": "Favorits"
|
||||||
},
|
},
|
||||||
"reblog": {
|
"reblog": {
|
||||||
"heading": "Impulsat"
|
"heading": "Impulsos"
|
||||||
},
|
},
|
||||||
"mention": {
|
"mention": {
|
||||||
"heading": "T'ha mencionat"
|
"heading": "Mencions"
|
||||||
},
|
},
|
||||||
"poll": {
|
"poll": {
|
||||||
"heading": "Actualització d'una votació"
|
"heading": "Actualitzacions d'una votació"
|
||||||
},
|
},
|
||||||
"status": {
|
"status": {
|
||||||
"heading": "Publicació d'usuaris subscrits"
|
"heading": "Publicacions d'usuaris subscrits"
|
||||||
},
|
},
|
||||||
"update": {
|
"update": {
|
||||||
"heading": "L'impuls ha sigut editat"
|
"heading": "Edicions d'impulsos"
|
||||||
},
|
},
|
||||||
"admin.sign_up": {
|
"admin.sign_up": {
|
||||||
"heading": "Administració: Registra"
|
"heading": "Administració: Registra"
|
||||||
@ -399,7 +399,7 @@
|
|||||||
"reblogged_by": "{{count}} impulsats",
|
"reblogged_by": "{{count}} impulsats",
|
||||||
"favourited_by": "{{count}} favorits"
|
"favourited_by": "{{count}} favorits"
|
||||||
},
|
},
|
||||||
"resultIncomplete": ""
|
"resultIncomplete": "Els resultats d'una instància remota són incomplets"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -7,7 +7,8 @@
|
|||||||
"continue": "",
|
"continue": "",
|
||||||
"create": "",
|
"create": "",
|
||||||
"delete": "",
|
"delete": "",
|
||||||
"done": ""
|
"done": "",
|
||||||
|
"confirm": ""
|
||||||
},
|
},
|
||||||
"customEmoji": {
|
"customEmoji": {
|
||||||
"accessibilityLabel": ""
|
"accessibilityLabel": ""
|
||||||
|
@ -13,10 +13,16 @@
|
|||||||
},
|
},
|
||||||
"block": {
|
"block": {
|
||||||
"action_false": "",
|
"action_false": "",
|
||||||
"action_true": ""
|
"action_true": "",
|
||||||
|
"alert": {
|
||||||
|
"title": ""
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"reports": {
|
"reports": {
|
||||||
"action": ""
|
"action": "",
|
||||||
|
"alert": {
|
||||||
|
"title": ""
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"at": {
|
"at": {
|
||||||
@ -33,10 +39,7 @@
|
|||||||
"action": "",
|
"action": "",
|
||||||
"alert": {
|
"alert": {
|
||||||
"title": "",
|
"title": "",
|
||||||
"message": "",
|
"message": ""
|
||||||
"buttons": {
|
|
||||||
"confirm": ""
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -57,20 +60,14 @@
|
|||||||
"action": "",
|
"action": "",
|
||||||
"alert": {
|
"alert": {
|
||||||
"title": "",
|
"title": "",
|
||||||
"message": "",
|
"message": ""
|
||||||
"buttons": {
|
|
||||||
"confirm": ""
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"deleteEdit": {
|
"deleteEdit": {
|
||||||
"action": "",
|
"action": "",
|
||||||
"alert": {
|
"alert": {
|
||||||
"title": "",
|
"title": "",
|
||||||
"message": "",
|
"message": ""
|
||||||
"buttons": {
|
|
||||||
"confirm": ""
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"mute": {
|
"mute": {
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
"textInput": {
|
"textInput": {
|
||||||
"placeholder": ""
|
"placeholder": ""
|
||||||
},
|
},
|
||||||
|
"whitelisted": "",
|
||||||
"button": "",
|
"button": "",
|
||||||
"information": {
|
"information": {
|
||||||
"name": "",
|
"name": "",
|
||||||
|
@ -91,7 +91,12 @@
|
|||||||
"content": {
|
"content": {
|
||||||
"expandHint": ""
|
"expandHint": ""
|
||||||
},
|
},
|
||||||
"filtered": "",
|
"filtered": {
|
||||||
|
"reveal": "",
|
||||||
|
"match_v1": "",
|
||||||
|
"match_v2_one": "",
|
||||||
|
"match_v2_other": ""
|
||||||
|
},
|
||||||
"fullConversation": "",
|
"fullConversation": "",
|
||||||
"translate": {
|
"translate": {
|
||||||
"default": "",
|
"default": "",
|
||||||
|
@ -1,8 +1,7 @@
|
|||||||
{
|
{
|
||||||
"screenshot": {
|
"screenshot": {
|
||||||
"title": "",
|
"title": "",
|
||||||
"message": "",
|
"message": ""
|
||||||
"button": ""
|
|
||||||
},
|
},
|
||||||
"localCorrupt": {
|
"localCorrupt": {
|
||||||
"message": ""
|
"message": ""
|
||||||
|
@ -7,7 +7,8 @@
|
|||||||
"continue": "Weiter",
|
"continue": "Weiter",
|
||||||
"create": "Erstellen",
|
"create": "Erstellen",
|
||||||
"delete": "Löschen",
|
"delete": "Löschen",
|
||||||
"done": "Fertig"
|
"done": "Fertig",
|
||||||
|
"confirm": "Bestätigen"
|
||||||
},
|
},
|
||||||
"customEmoji": {
|
"customEmoji": {
|
||||||
"accessibilityLabel": "Eigenes Emoji {{emoji}}"
|
"accessibilityLabel": "Eigenes Emoji {{emoji}}"
|
||||||
|
@ -13,10 +13,16 @@
|
|||||||
},
|
},
|
||||||
"block": {
|
"block": {
|
||||||
"action_false": "Nutzer blockieren",
|
"action_false": "Nutzer blockieren",
|
||||||
"action_true": "User entblocken"
|
"action_true": "User entblocken",
|
||||||
|
"alert": {
|
||||||
|
"title": ""
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"reports": {
|
"reports": {
|
||||||
"action": "Nutzer melden und blockieren"
|
"action": "Nutzer melden und blockieren",
|
||||||
|
"alert": {
|
||||||
|
"title": ""
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"at": {
|
"at": {
|
||||||
@ -33,10 +39,7 @@
|
|||||||
"action": "Instanz {{instance}} blockieren",
|
"action": "Instanz {{instance}} blockieren",
|
||||||
"alert": {
|
"alert": {
|
||||||
"title": "{{instance}} wirklich blockieren?",
|
"title": "{{instance}} wirklich blockieren?",
|
||||||
"message": "Üblicherweise kannst du einen User stummschalten oder blockieren.\nBlockierst du hingegegen eine Instanz, wird deren gesamter Inhalt samt Usern, die dir von dieser Instanz folgen, entfernt!",
|
"message": "Üblicherweise kannst du einen User stummschalten oder blockieren.\nBlockierst du hingegegen eine Instanz, wird deren gesamter Inhalt samt Usern, die dir von dieser Instanz folgen, entfernt!"
|
||||||
"buttons": {
|
|
||||||
"confirm": "Bestätigen"
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -57,20 +60,14 @@
|
|||||||
"action": "Tröt löschen",
|
"action": "Tröt löschen",
|
||||||
"alert": {
|
"alert": {
|
||||||
"title": "Löschen bestätigen?",
|
"title": "Löschen bestätigen?",
|
||||||
"message": "Alle Boosts, Sterne und Antworten werden entfernt.",
|
"message": "Alle Boosts, Sterne und Antworten werden entfernt."
|
||||||
"buttons": {
|
|
||||||
"confirm": "Bestätigen"
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"deleteEdit": {
|
"deleteEdit": {
|
||||||
"action": "Tröt neu entwerfen",
|
"action": "Tröt neu entwerfen",
|
||||||
"alert": {
|
"alert": {
|
||||||
"title": "Beitrag wirklich entfernen?",
|
"title": "Beitrag wirklich entfernen?",
|
||||||
"message": "Alle Boosts und Likes inklusive der Antworten werden gelöscht.",
|
"message": "Alle Boosts und Likes inklusive der Antworten werden gelöscht."
|
||||||
"buttons": {
|
|
||||||
"confirm": "Bestätigen"
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"mute": {
|
"mute": {
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
"textInput": {
|
"textInput": {
|
||||||
"placeholder": "Domain der Instanz"
|
"placeholder": "Domain der Instanz"
|
||||||
},
|
},
|
||||||
|
"whitelisted": "",
|
||||||
"button": "Login",
|
"button": "Login",
|
||||||
"information": {
|
"information": {
|
||||||
"name": "Name",
|
"name": "Name",
|
||||||
|
@ -91,7 +91,12 @@
|
|||||||
"content": {
|
"content": {
|
||||||
"expandHint": "Ausgeblendeter Inhalt"
|
"expandHint": "Ausgeblendeter Inhalt"
|
||||||
},
|
},
|
||||||
"filtered": "Gefiltert: {{phrase}}.",
|
"filtered": {
|
||||||
|
"reveal": "Trotzdem anzeigen",
|
||||||
|
"match_v1": "Gefiltert: {{phrase}}.",
|
||||||
|
"match_v2_one": "Gefiltert durch {{filters}}.",
|
||||||
|
"match_v2_other": "Gefiltert durch {{count}} Filter, {{filters}}."
|
||||||
|
},
|
||||||
"fullConversation": "Unterhaltung anzeigen",
|
"fullConversation": "Unterhaltung anzeigen",
|
||||||
"translate": {
|
"translate": {
|
||||||
"default": "Übersetzen",
|
"default": "Übersetzen",
|
||||||
|
@ -1,8 +1,7 @@
|
|||||||
{
|
{
|
||||||
"screenshot": {
|
"screenshot": {
|
||||||
"title": "Datenschutz",
|
"title": "Datenschutz",
|
||||||
"message": "Bitte geben Sie nicht die Identität anderer Nutzer preis, wie z. B. Benutzername, Avatar, etc. Vielen Dank!",
|
"message": "Bitte geben Sie nicht die Identität anderer Nutzer preis, wie z. B. Benutzername, Avatar, etc. Vielen Dank!"
|
||||||
"button": "Bestätigen"
|
|
||||||
},
|
},
|
||||||
"localCorrupt": {
|
"localCorrupt": {
|
||||||
"message": "Login abgelaufen, bitte erneut anmelden"
|
"message": "Login abgelaufen, bitte erneut anmelden"
|
||||||
|
@ -7,7 +7,8 @@
|
|||||||
"continue": "Continue",
|
"continue": "Continue",
|
||||||
"create": "Create",
|
"create": "Create",
|
||||||
"delete": "Delete",
|
"delete": "Delete",
|
||||||
"done": "Done"
|
"done": "Done",
|
||||||
|
"confirm": "Confirm"
|
||||||
},
|
},
|
||||||
"customEmoji": {
|
"customEmoji": {
|
||||||
"accessibilityLabel": "Custom emoji {{emoji}}"
|
"accessibilityLabel": "Custom emoji {{emoji}}"
|
||||||
|
@ -13,10 +13,16 @@
|
|||||||
},
|
},
|
||||||
"block": {
|
"block": {
|
||||||
"action_false": "Block user",
|
"action_false": "Block user",
|
||||||
"action_true": "Unblock user"
|
"action_true": "Unblock user",
|
||||||
|
"alert": {
|
||||||
|
"title": "Confirm blocking user @{{username}} ?"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"reports": {
|
"reports": {
|
||||||
"action": "Report and block user"
|
"action": "Report and block user",
|
||||||
|
"alert": {
|
||||||
|
"title": "Confirm report and blocking user @{{username}} ?"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"at": {
|
"at": {
|
||||||
@ -33,10 +39,7 @@
|
|||||||
"action": "Block instance {{instance}}",
|
"action": "Block instance {{instance}}",
|
||||||
"alert": {
|
"alert": {
|
||||||
"title": "Confirm blocking instance {{instance}} ?",
|
"title": "Confirm blocking instance {{instance}} ?",
|
||||||
"message": "Mostly you can mute or block certain user.\n\nAfter blocking instance, all its content including followers from this instance will be removed!",
|
"message": "Mostly you can mute or block certain user.\n\nAfter blocking instance, all its content including followers from this instance will be removed!"
|
||||||
"buttons": {
|
|
||||||
"confirm": "Confirm"
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -57,20 +60,14 @@
|
|||||||
"action": "Delete toot",
|
"action": "Delete toot",
|
||||||
"alert": {
|
"alert": {
|
||||||
"title": "Confirm deleting?",
|
"title": "Confirm deleting?",
|
||||||
"message": "All boosts and favourites will be cleared, including all replies.",
|
"message": "All boosts and favourites will be cleared, including all replies."
|
||||||
"buttons": {
|
|
||||||
"confirm": "Confirm"
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"deleteEdit": {
|
"deleteEdit": {
|
||||||
"action": "Delete toot and repost",
|
"action": "Delete toot and repost",
|
||||||
"alert": {
|
"alert": {
|
||||||
"title": "Confirm deleting and repost?",
|
"title": "Confirm deleting and repost?",
|
||||||
"message": "All boosts and favourites will be cleared, including all replies.",
|
"message": "All boosts and favourites will be cleared, including all replies."
|
||||||
"buttons": {
|
|
||||||
"confirm": "Confirm"
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"mute": {
|
"mute": {
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
"textInput": {
|
"textInput": {
|
||||||
"placeholder": "Instance's domain"
|
"placeholder": "Instance's domain"
|
||||||
},
|
},
|
||||||
|
"whitelisted": "This may be a whitelisted instance that tooot cannot retrieve data from before logging in.",
|
||||||
"button": "Login",
|
"button": "Login",
|
||||||
"information": {
|
"information": {
|
||||||
"name": "Name",
|
"name": "Name",
|
||||||
|
@ -91,7 +91,12 @@
|
|||||||
"content": {
|
"content": {
|
||||||
"expandHint": "Hidden content"
|
"expandHint": "Hidden content"
|
||||||
},
|
},
|
||||||
"filtered": "Filtered: {{phrase}}.",
|
"filtered": {
|
||||||
|
"reveal": "Show anyway",
|
||||||
|
"match_v1": "Filtered: {{phrase}}.",
|
||||||
|
"match_v2_one": "Filtered by {{filters}}.",
|
||||||
|
"match_v2_other": "Filtered by {{count}} filters, {{filters}}."
|
||||||
|
},
|
||||||
"fullConversation": "Read conversations",
|
"fullConversation": "Read conversations",
|
||||||
"translate": {
|
"translate": {
|
||||||
"default": "Translate",
|
"default": "Translate",
|
||||||
|
@ -1,8 +1,7 @@
|
|||||||
{
|
{
|
||||||
"screenshot": {
|
"screenshot": {
|
||||||
"title": "Privacy Protection",
|
"title": "Privacy Protection",
|
||||||
"message": "Please do not disclose other user's identity, such as username, avatar, etc. Thank you!",
|
"message": "Please do not disclose other user's identity, such as username, avatar, etc. Thank you!"
|
||||||
"button": "Confirm"
|
|
||||||
},
|
},
|
||||||
"localCorrupt": {
|
"localCorrupt": {
|
||||||
"message": "Login expired, please login again"
|
"message": "Login expired, please login again"
|
||||||
|
@ -7,7 +7,8 @@
|
|||||||
"continue": "Continuar",
|
"continue": "Continuar",
|
||||||
"create": "Crear",
|
"create": "Crear",
|
||||||
"delete": "Borrar",
|
"delete": "Borrar",
|
||||||
"done": "Hecho"
|
"done": "Hecho",
|
||||||
|
"confirm": "Confirmar"
|
||||||
},
|
},
|
||||||
"customEmoji": {
|
"customEmoji": {
|
||||||
"accessibilityLabel": "Emoji personalizado {{emoji}}"
|
"accessibilityLabel": "Emoji personalizado {{emoji}}"
|
||||||
|
@ -13,10 +13,16 @@
|
|||||||
},
|
},
|
||||||
"block": {
|
"block": {
|
||||||
"action_false": "Bloquear usuario",
|
"action_false": "Bloquear usuario",
|
||||||
"action_true": "Desbloquear usuario"
|
"action_true": "Desbloquear usuario",
|
||||||
|
"alert": {
|
||||||
|
"title": ""
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"reports": {
|
"reports": {
|
||||||
"action": "Reportar y bloquear usuario"
|
"action": "Reportar y bloquear usuario",
|
||||||
|
"alert": {
|
||||||
|
"title": ""
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"at": {
|
"at": {
|
||||||
@ -33,10 +39,7 @@
|
|||||||
"action": "Bloquear instancia {{instance}}",
|
"action": "Bloquear instancia {{instance}}",
|
||||||
"alert": {
|
"alert": {
|
||||||
"title": "¿Confirmar bloqueo de la instancia {{instance}}?",
|
"title": "¿Confirmar bloqueo de la instancia {{instance}}?",
|
||||||
"message": "Puedes silenciar o bloquear a un usuario.\n\nTras bloquear una instancia, todo su contenido junto con sus seguidores se eliminarán.",
|
"message": "Puedes silenciar o bloquear a un usuario.\n\nTras bloquear una instancia, todo su contenido junto con sus seguidores se eliminarán."
|
||||||
"buttons": {
|
|
||||||
"confirm": "Confirmar"
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -57,20 +60,14 @@
|
|||||||
"action": "Eliminar toot",
|
"action": "Eliminar toot",
|
||||||
"alert": {
|
"alert": {
|
||||||
"title": "¿Confirmar eliminación?",
|
"title": "¿Confirmar eliminación?",
|
||||||
"message": "Todos los boosts y favoritos se eliminarán, incluidas todas las respuestas.",
|
"message": "Todos los boosts y favoritos se eliminarán, incluidas todas las respuestas."
|
||||||
"buttons": {
|
|
||||||
"confirm": "Confirmar"
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"deleteEdit": {
|
"deleteEdit": {
|
||||||
"action": "Eliminar toot y volver a publicar",
|
"action": "Eliminar toot y volver a publicar",
|
||||||
"alert": {
|
"alert": {
|
||||||
"title": "¿Confirmar eliminación y volver a publicar?",
|
"title": "¿Confirmar eliminación y volver a publicar?",
|
||||||
"message": "Todos los boosts y favoritos se eliminarán, incluidas todas las respuestas.",
|
"message": "Todos los boosts y favoritos se eliminarán, incluidas todas las respuestas."
|
||||||
"buttons": {
|
|
||||||
"confirm": "Confirmar"
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"mute": {
|
"mute": {
|
||||||
|
@ -1,8 +1,9 @@
|
|||||||
{
|
{
|
||||||
"server": {
|
"server": {
|
||||||
"textInput": {
|
"textInput": {
|
||||||
"placeholder": ""
|
"placeholder": "Dominio de la instancia"
|
||||||
},
|
},
|
||||||
|
"whitelisted": "Puede ser que la instancia esté en una lista blanca por la que tooot no pueda obtener los datos antes de iniciar la sesión.",
|
||||||
"button": "Iniciar sesión",
|
"button": "Iniciar sesión",
|
||||||
"information": {
|
"information": {
|
||||||
"name": "Nombre",
|
"name": "Nombre",
|
||||||
|
@ -31,7 +31,7 @@
|
|||||||
"notification": "{{name}} ha impulsado tu toot"
|
"notification": "{{name}} ha impulsado tu toot"
|
||||||
},
|
},
|
||||||
"update": "El impulso ha sido editado",
|
"update": "El impulso ha sido editado",
|
||||||
"admin.sign_up": "",
|
"admin.sign_up": "{{name}} se unió a la instancia",
|
||||||
"admin.report": ""
|
"admin.report": ""
|
||||||
},
|
},
|
||||||
"actions": {
|
"actions": {
|
||||||
@ -55,7 +55,7 @@
|
|||||||
"accessibilityLabel": "Añadir este toot en marcadores",
|
"accessibilityLabel": "Añadir este toot en marcadores",
|
||||||
"function": "Añadir toot a marcadores"
|
"function": "Añadir toot a marcadores"
|
||||||
},
|
},
|
||||||
"openReport": ""
|
"openReport": "Abrir denuncia"
|
||||||
},
|
},
|
||||||
"actionsUsers": {
|
"actionsUsers": {
|
||||||
"reblogged_by": {
|
"reblogged_by": {
|
||||||
@ -91,7 +91,12 @@
|
|||||||
"content": {
|
"content": {
|
||||||
"expandHint": "Contenido oculto"
|
"expandHint": "Contenido oculto"
|
||||||
},
|
},
|
||||||
"filtered": "Filtrado: {{phrase}}.",
|
"filtered": {
|
||||||
|
"reveal": "Mostrar de todos modos",
|
||||||
|
"match_v1": "Filtrado: {{phrase}}.",
|
||||||
|
"match_v2_one": "Filtrado por {{filters}}.",
|
||||||
|
"match_v2_other": "Filtrado por {{count}} filtros, {{filters}}."
|
||||||
|
},
|
||||||
"fullConversation": "Leer conversaciones",
|
"fullConversation": "Leer conversaciones",
|
||||||
"translate": {
|
"translate": {
|
||||||
"default": "Traducir",
|
"default": "Traducir",
|
||||||
|
@ -1,8 +1,7 @@
|
|||||||
{
|
{
|
||||||
"screenshot": {
|
"screenshot": {
|
||||||
"title": "Protección de la privacidad",
|
"title": "Protección de la privacidad",
|
||||||
"message": "Por favor, no revele la identidad de otros usuarios, como el nombre de usuario, avatar, etc. ¡Gracias!",
|
"message": "Por favor, no revele la identidad de otros usuarios, como el nombre de usuario, avatar, etc. ¡Gracias!"
|
||||||
"button": "Confirmar"
|
|
||||||
},
|
},
|
||||||
"localCorrupt": {
|
"localCorrupt": {
|
||||||
"message": "La sesión se ha expirado. Por favor, vuelve a iniciar sesión"
|
"message": "La sesión se ha expirado. Por favor, vuelve a iniciar sesión"
|
||||||
|
@ -15,7 +15,7 @@
|
|||||||
"conversation": "Mensaje privado",
|
"conversation": "Mensaje privado",
|
||||||
"reply": "Respuesta al toot",
|
"reply": "Respuesta al toot",
|
||||||
"deleteEdit": "Toot",
|
"deleteEdit": "Toot",
|
||||||
"edit": "Toot",
|
"edit": "Edita el toot",
|
||||||
"share": "Toot"
|
"share": "Toot"
|
||||||
},
|
},
|
||||||
"alert": {
|
"alert": {
|
||||||
|
@ -399,7 +399,7 @@
|
|||||||
"reblogged_by": "{{count}} impulsados",
|
"reblogged_by": "{{count}} impulsados",
|
||||||
"favourited_by": "{{count}} favoritos"
|
"favourited_by": "{{count}} favoritos"
|
||||||
},
|
},
|
||||||
"resultIncomplete": ""
|
"resultIncomplete": "Los resultados de una instancia remota están incompletos"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -3,11 +3,12 @@
|
|||||||
"OK": "Ok",
|
"OK": "Ok",
|
||||||
"apply": "Confirmer",
|
"apply": "Confirmer",
|
||||||
"cancel": "Annuler",
|
"cancel": "Annuler",
|
||||||
"discard": "Ne pas tenir compte",
|
"discard": "Abandonner",
|
||||||
"continue": "Continuer",
|
"continue": "Continuer",
|
||||||
"create": "",
|
"create": "Créer",
|
||||||
"delete": "",
|
"delete": "Supprimer",
|
||||||
"done": ""
|
"done": "Fait",
|
||||||
|
"confirm": "Confirmer"
|
||||||
},
|
},
|
||||||
"customEmoji": {
|
"customEmoji": {
|
||||||
"accessibilityLabel": "Émoji personnalisé {{emoji}}"
|
"accessibilityLabel": "Émoji personnalisé {{emoji}}"
|
||||||
@ -20,12 +21,12 @@
|
|||||||
"message": ""
|
"message": ""
|
||||||
},
|
},
|
||||||
"error": {
|
"error": {
|
||||||
"message": "Échec de la connexion, veuillez réessayer"
|
"message": "{{function}} a échoué, veuillez réessayer"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"separator": ", ",
|
"separator": ", ",
|
||||||
"discard": {
|
"discard": {
|
||||||
"title": "Modifications non sauvegardées",
|
"title": "Modifications non sauvegardées",
|
||||||
"message": "Votre modification n'a pas été enregistrée. Voulez-vous annuler l'enregistrement des modifications ?"
|
"message": "Votre modification n'a pas été enregistrée. Voulez-vous renoncer à enregistrer les modifications ?"
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -4,24 +4,30 @@
|
|||||||
"title": "Actions de l'utilisateur",
|
"title": "Actions de l'utilisateur",
|
||||||
"following": {
|
"following": {
|
||||||
"action_false": "Suivre l'utilisateur",
|
"action_false": "Suivre l'utilisateur",
|
||||||
"action_true": ""
|
"action_true": "Ne plus suivre l'utilisateur"
|
||||||
},
|
},
|
||||||
"inLists": "",
|
"inLists": "Gérer l'utilisateur des listes",
|
||||||
"mute": {
|
"mute": {
|
||||||
"action_false": "Rendre muet l'utilisateur",
|
"action_false": "Rendre muet l'utilisateur",
|
||||||
"action_true": "Rendre la parole"
|
"action_true": "Rendre la parole"
|
||||||
},
|
},
|
||||||
"block": {
|
"block": {
|
||||||
"action_false": "Bloquer l'utilisateur",
|
"action_false": "Bloquer l'utilisateur",
|
||||||
"action_true": "Débloquer l'utilisateur"
|
"action_true": "Débloquer l'utilisateur",
|
||||||
|
"alert": {
|
||||||
|
"title": ""
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"reports": {
|
"reports": {
|
||||||
"action": ""
|
"action": "Signaler et bloquer un utilisateur",
|
||||||
|
"alert": {
|
||||||
|
"title": ""
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"at": {
|
"at": {
|
||||||
"direct": "Message direct",
|
"direct": "Message direct",
|
||||||
"public": ""
|
"public": "Message public"
|
||||||
},
|
},
|
||||||
"copy": {
|
"copy": {
|
||||||
"action": "Copier le Pouet",
|
"action": "Copier le Pouet",
|
||||||
@ -33,10 +39,7 @@
|
|||||||
"action": "Bloquer l'instance {{instance}}",
|
"action": "Bloquer l'instance {{instance}}",
|
||||||
"alert": {
|
"alert": {
|
||||||
"title": "Confirmer le blocage de l'instance {{instance}}?",
|
"title": "Confirmer le blocage de l'instance {{instance}}?",
|
||||||
"message": "Vous pouvez masquer ou bloquer certains utilisateurs.\n\nAprès avoir bloqué l'instance, tout son contenu, y compris les followers de cette instance, sera supprimé !",
|
"message": "Vous pouvez masquer ou bloquer certains utilisateurs.\n\nAprès avoir bloqué l'instance, tout son contenu, y compris les followers de cette instance, sera supprimé !"
|
||||||
"buttons": {
|
|
||||||
"confirm": "Confirmer"
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -57,20 +60,14 @@
|
|||||||
"action": "Supprimer le pouet",
|
"action": "Supprimer le pouet",
|
||||||
"alert": {
|
"alert": {
|
||||||
"title": "Confirmer la suppression ?",
|
"title": "Confirmer la suppression ?",
|
||||||
"message": "Tous les boosts et favoris seront effacés, y compris toutes les réponses.",
|
"message": "Tous les boosts et favoris seront effacés, y compris toutes les réponses."
|
||||||
"buttons": {
|
|
||||||
"confirm": "Confirmer"
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"deleteEdit": {
|
"deleteEdit": {
|
||||||
"action": "Supprimer le pouet et le republié",
|
"action": "Supprimer le pouet et le republié",
|
||||||
"alert": {
|
"alert": {
|
||||||
"title": "Confirmer la suppression et le repost ?",
|
"title": "Confirmer la suppression et le repost ?",
|
||||||
"message": "Tous les boosts et favoris seront effacés, y compris toutes les réponses.",
|
"message": "Tous les boosts et favoris seront effacés, y compris toutes les réponses."
|
||||||
"buttons": {
|
|
||||||
"confirm": "Confirmer"
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"mute": {
|
"mute": {
|
||||||
|
@ -1,8 +1,9 @@
|
|||||||
{
|
{
|
||||||
"server": {
|
"server": {
|
||||||
"textInput": {
|
"textInput": {
|
||||||
"placeholder": ""
|
"placeholder": "URL de l’instance"
|
||||||
},
|
},
|
||||||
|
"whitelisted": "Il peut s’agir d’une instance sur liste blanche à partir de laquelle tooot ne peut pas récupérer de données avant de se connecter.",
|
||||||
"button": "Connexion",
|
"button": "Connexion",
|
||||||
"information": {
|
"information": {
|
||||||
"name": "Nom",
|
"name": "Nom",
|
||||||
@ -20,7 +21,7 @@
|
|||||||
"update": {
|
"update": {
|
||||||
"alert": {
|
"alert": {
|
||||||
"title": "Connecté à cette instance",
|
"title": "Connecté à cette instance",
|
||||||
"message": "Vous pouvez vous connecter à un autre compte, en maintenant un compte connecté existant"
|
"message": "Vous pouvez vous connecter à un autre compte, en conservant le compte connecté existant"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"HTML": {
|
"HTML": {
|
||||||
"accessibilityHint": "Appuyez pour agrandir ou réduire le contenu",
|
"accessibilityHint": "Touchez pour développer ou réduire le contenu",
|
||||||
"expanded": "{{hint}}{{moreLines}}",
|
"expanded": "{{hint}}{{moreLines}}",
|
||||||
"moreLines": " ({{count}} lignes en plus)",
|
"moreLines": " ({{count}} lignes en plus)",
|
||||||
"defaultHint": "Pouet long"
|
"defaultHint": "Pouet long"
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
"button": "Réessayer"
|
"button": "Réessayer"
|
||||||
},
|
},
|
||||||
"success": {
|
"success": {
|
||||||
"message": "La chronologie est vide"
|
"message": "Le fil est vide"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"end": {
|
"end": {
|
||||||
@ -31,8 +31,8 @@
|
|||||||
"notification": "{{name}} a partagé votre message"
|
"notification": "{{name}} a partagé votre message"
|
||||||
},
|
},
|
||||||
"update": "Le reblog a été modifié",
|
"update": "Le reblog a été modifié",
|
||||||
"admin.sign_up": "",
|
"admin.sign_up": "{{name}} a rejoint l'instance",
|
||||||
"admin.report": ""
|
"admin.report": "{{name}} a signalé:"
|
||||||
},
|
},
|
||||||
"actions": {
|
"actions": {
|
||||||
"reply": {
|
"reply": {
|
||||||
@ -40,7 +40,7 @@
|
|||||||
},
|
},
|
||||||
"reblogged": {
|
"reblogged": {
|
||||||
"accessibilityLabel": "Partager ce pouet",
|
"accessibilityLabel": "Partager ce pouet",
|
||||||
"function": "Pouet de Boost",
|
"function": "Pouet de boost",
|
||||||
"options": {
|
"options": {
|
||||||
"title": "Choisir la visibilité du boost",
|
"title": "Choisir la visibilité du boost",
|
||||||
"public": "Boost public",
|
"public": "Boost public",
|
||||||
@ -49,13 +49,13 @@
|
|||||||
},
|
},
|
||||||
"favourited": {
|
"favourited": {
|
||||||
"accessibilityLabel": "Ajouter ce pouet aux favoris",
|
"accessibilityLabel": "Ajouter ce pouet aux favoris",
|
||||||
"function": "Mettre le pouet en favori"
|
"function": "Pouet en favoris"
|
||||||
},
|
},
|
||||||
"bookmarked": {
|
"bookmarked": {
|
||||||
"accessibilityLabel": "Ajouter ce pouet aux signets",
|
"accessibilityLabel": "Ajouter ce pouet aux marque-pages",
|
||||||
"function": "Pouet de signet"
|
"function": "Pouet en marque-pages"
|
||||||
},
|
},
|
||||||
"openReport": ""
|
"openReport": "Ouvrir un rapport"
|
||||||
},
|
},
|
||||||
"actionsUsers": {
|
"actionsUsers": {
|
||||||
"reblogged_by": {
|
"reblogged_by": {
|
||||||
@ -91,7 +91,12 @@
|
|||||||
"content": {
|
"content": {
|
||||||
"expandHint": "Contenu masqué"
|
"expandHint": "Contenu masqué"
|
||||||
},
|
},
|
||||||
"filtered": "Filtré: {{phrase}}.",
|
"filtered": {
|
||||||
|
"reveal": "Montrer quand même",
|
||||||
|
"match_v1": "Filtré : {{phrase}}.",
|
||||||
|
"match_v2_one": "Filtré par {{filters}}.",
|
||||||
|
"match_v2_other": "Filtré par {{count}} filtres, {{filters}}."
|
||||||
|
},
|
||||||
"fullConversation": "Conversations lues",
|
"fullConversation": "Conversations lues",
|
||||||
"translate": {
|
"translate": {
|
||||||
"default": "Traduire",
|
"default": "Traduire",
|
||||||
@ -104,7 +109,7 @@
|
|||||||
"shared": {
|
"shared": {
|
||||||
"account": {
|
"account": {
|
||||||
"name": {
|
"name": {
|
||||||
"accessibilityHint": "Nom de l'utilisateur"
|
"accessibilityHint": "Nom d'affichage de l'utilisateur"
|
||||||
},
|
},
|
||||||
"account": {
|
"account": {
|
||||||
"accessibilityHint": "Compte de l'utilisateur"
|
"accessibilityHint": "Compte de l'utilisateur"
|
||||||
@ -119,7 +124,7 @@
|
|||||||
},
|
},
|
||||||
"visibility": {
|
"visibility": {
|
||||||
"direct": {
|
"direct": {
|
||||||
"accessibilityLabel": "Envoyer un message direct"
|
"accessibilityLabel": "Envoyer un message privé"
|
||||||
},
|
},
|
||||||
"private": {
|
"private": {
|
||||||
"accessibilityLabel": "Visible uniquement pour les abonné·e·s"
|
"accessibilityLabel": "Visible uniquement pour les abonné·e·s"
|
||||||
|
@ -1,8 +1,7 @@
|
|||||||
{
|
{
|
||||||
"screenshot": {
|
"screenshot": {
|
||||||
"title": "Protection de la confidentialité",
|
"title": "Protection de la confidentialité",
|
||||||
"message": "Veuillez ne pas divulguer l'identité d'un autre utilisateur, tel que le nom d'utilisateur, l'avatar, etc. Merci!",
|
"message": "Veuillez ne pas divulguer l'identité d'un autre utilisateur, tel que le nom d'utilisateur, l'avatar, etc. Merci!"
|
||||||
"button": "Confirmer"
|
|
||||||
},
|
},
|
||||||
"localCorrupt": {
|
"localCorrupt": {
|
||||||
"message": "Session expirée, veuillez ré-essayer"
|
"message": "Session expirée, veuillez ré-essayer"
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
"heading": {
|
"heading": {
|
||||||
"left": {
|
"left": {
|
||||||
"alert": {
|
"alert": {
|
||||||
"title": "Annuler l’édition?",
|
"title": "Annuler l’édition ?",
|
||||||
"buttons": {
|
"buttons": {
|
||||||
"save": "Enregistrer comme brouillon",
|
"save": "Enregistrer comme brouillon",
|
||||||
"delete": "Supprimer le brouillon"
|
"delete": "Supprimer le brouillon"
|
||||||
@ -12,7 +12,7 @@
|
|||||||
"right": {
|
"right": {
|
||||||
"button": {
|
"button": {
|
||||||
"default": "Pouet",
|
"default": "Pouet",
|
||||||
"conversation": "Pouet DM",
|
"conversation": "Pouet MP",
|
||||||
"reply": "Réponse de pouet",
|
"reply": "Réponse de pouet",
|
||||||
"deleteEdit": "Pouet",
|
"deleteEdit": "Pouet",
|
||||||
"edit": "Pouet",
|
"edit": "Pouet",
|
||||||
@ -24,8 +24,8 @@
|
|||||||
"button": "Réessayer"
|
"button": "Réessayer"
|
||||||
},
|
},
|
||||||
"removeReply": {
|
"removeReply": {
|
||||||
"title": "Le pouet répondu est introuvable",
|
"title": "Le pouet réponse est introuvable",
|
||||||
"description": "Le pouet répondu a peut-être été supprimé. Voulez-vous le supprimer de votre référence ?",
|
"description": "Le pouet réponse a peut-être été supprimé. Voulez-vous le supprimer de votre référence ?",
|
||||||
"confirm": "Supprimer la référence"
|
"confirm": "Supprimer la référence"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -62,7 +62,7 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"emojis": {
|
"emojis": {
|
||||||
"accessibilityHint": "Tapotez pour ajouter des émojis au pouet"
|
"accessibilityHint": "Appuyez pour ajouter des émojis au pouet"
|
||||||
},
|
},
|
||||||
"poll": {
|
"poll": {
|
||||||
"option": {
|
"option": {
|
||||||
@ -90,7 +90,7 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"expiration": {
|
"expiration": {
|
||||||
"heading": "Validité",
|
"heading": "Durée",
|
||||||
"options": {
|
"options": {
|
||||||
"300": "5 minutes",
|
"300": "5 minutes",
|
||||||
"1800": "30 minutes",
|
"1800": "30 minutes",
|
||||||
@ -106,7 +106,7 @@
|
|||||||
"actions": {
|
"actions": {
|
||||||
"attachment": {
|
"attachment": {
|
||||||
"accessibilityLabel": "Téléchargez une pièce-jointe",
|
"accessibilityLabel": "Téléchargez une pièce-jointe",
|
||||||
"accessibilityHint": "La fonction de sondage sera désactivée lorsqu'il y a une pièce jointe",
|
"accessibilityHint": "La fonction de sondage sera désactivée s'il y a une pièce jointe",
|
||||||
"failed": {
|
"failed": {
|
||||||
"alert": {
|
"alert": {
|
||||||
"title": "Le téléchargement a échoué",
|
"title": "Le téléchargement a échoué",
|
||||||
|
@ -3,15 +3,15 @@
|
|||||||
"local": {
|
"local": {
|
||||||
"name": "Suit",
|
"name": "Suit",
|
||||||
"options": {
|
"options": {
|
||||||
"showBoosts": "",
|
"showBoosts": "Afficher les boosts",
|
||||||
"showReplies": ""
|
"showReplies": "Afficher les réponses"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"public": {
|
"public": {
|
||||||
"segments": {
|
"segments": {
|
||||||
"federated": "Fédéré",
|
"federated": "Fédéré",
|
||||||
"local": "Local",
|
"local": "Local",
|
||||||
"trending": ""
|
"trending": "Tendance"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"notifications": {
|
"notifications": {
|
||||||
@ -28,7 +28,7 @@
|
|||||||
"filters": {
|
"filters": {
|
||||||
"accessibilityLabel": "Filtrer",
|
"accessibilityLabel": "Filtrer",
|
||||||
"accessibilityHint": "Filtrer les types de notifications affichés",
|
"accessibilityHint": "Filtrer les types de notifications affichés",
|
||||||
"title": "",
|
"title": "Afficher les notifications",
|
||||||
"options": {
|
"options": {
|
||||||
"follow": "$t(screenTabs:me.push.follow.heading)",
|
"follow": "$t(screenTabs:me.push.follow.heading)",
|
||||||
"follow_request": "Demande d'abonnement",
|
"follow_request": "Demande d'abonnement",
|
||||||
@ -55,7 +55,7 @@
|
|||||||
"name": "Favoris"
|
"name": "Favoris"
|
||||||
},
|
},
|
||||||
"followedTags": {
|
"followedTags": {
|
||||||
"name": ""
|
"name": "Hashtags suivis"
|
||||||
},
|
},
|
||||||
"fontSize": {
|
"fontSize": {
|
||||||
"name": "Taille de la police de Pouet"
|
"name": "Taille de la police de Pouet"
|
||||||
@ -67,25 +67,25 @@
|
|||||||
"name": "Liste : {{list}}"
|
"name": "Liste : {{list}}"
|
||||||
},
|
},
|
||||||
"listAccounts": {
|
"listAccounts": {
|
||||||
"name": ""
|
"name": "Utilisateurs dans la liste : {{list}}"
|
||||||
},
|
},
|
||||||
"listAdd": {
|
"listAdd": {
|
||||||
"name": ""
|
"name": "Créer une liste"
|
||||||
},
|
},
|
||||||
"listEdit": {
|
"listEdit": {
|
||||||
"name": ""
|
"name": "Modifier les détails de la liste"
|
||||||
},
|
},
|
||||||
"lists": {
|
"lists": {
|
||||||
"name": "Listes"
|
"name": "Listes"
|
||||||
},
|
},
|
||||||
"push": {
|
"push": {
|
||||||
"name": "Push de Notification"
|
"name": "Push de notification"
|
||||||
},
|
},
|
||||||
"profile": {
|
"profile": {
|
||||||
"name": "Modifier le profil"
|
"name": "Modifier le profil"
|
||||||
},
|
},
|
||||||
"profileName": {
|
"profileName": {
|
||||||
"name": "Editer le nom d'affichage"
|
"name": "Éditer le nom d'affichage"
|
||||||
},
|
},
|
||||||
"profileNote": {
|
"profileNote": {
|
||||||
"name": "Éditer la description"
|
"name": "Éditer la description"
|
||||||
@ -114,33 +114,33 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"listAccounts": {
|
"listAccounts": {
|
||||||
"heading": "",
|
"heading": "Gérer les utilisateurs",
|
||||||
"error": "",
|
"error": "Supprimer l'utilisateur de la liste",
|
||||||
"empty": ""
|
"empty": "Aucun utilisateur ajouté dans cette liste"
|
||||||
},
|
},
|
||||||
"listEdit": {
|
"listEdit": {
|
||||||
"heading": "",
|
"heading": "Modifier les détails de la liste",
|
||||||
"title": "",
|
"title": "Titre",
|
||||||
"repliesPolicy": {
|
"repliesPolicy": {
|
||||||
"heading": "",
|
"heading": "Montrer les réponses à :",
|
||||||
"options": {
|
"options": {
|
||||||
"none": "",
|
"none": "Personne",
|
||||||
"list": "",
|
"list": "Un membre de la liste",
|
||||||
"followed": ""
|
"followed": "N'importe quel utilisateur suivi"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"listDelete": {
|
"listDelete": {
|
||||||
"heading": "",
|
"heading": "Supprimer la liste",
|
||||||
"confirm": {
|
"confirm": {
|
||||||
"title": "",
|
"title": "Supprimer la liste \"{{list}}\" ?",
|
||||||
"message": ""
|
"message": "Cette action ne peut être annulé."
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"profile": {
|
"profile": {
|
||||||
"feedback": {
|
"feedback": {
|
||||||
"succeed": "{{type}} mis à jour",
|
"succeed": "{{type}} mis à jour",
|
||||||
"failed": "{{type}} Échec de la mise à jour, veuillez ré-essayer"
|
"failed": "La mise à jour de {{type}} a échoué, veuillez réessayer"
|
||||||
},
|
},
|
||||||
"root": {
|
"root": {
|
||||||
"name": {
|
"name": {
|
||||||
@ -178,13 +178,13 @@
|
|||||||
"description": "Nécessite que vous approuviez manuellement chaque abonné·e"
|
"description": "Nécessite que vous approuviez manuellement chaque abonné·e"
|
||||||
},
|
},
|
||||||
"bot": {
|
"bot": {
|
||||||
"title": "Compte Bot",
|
"title": "Compte bot",
|
||||||
"description": "Ce compte effectue principalement des actions automatisées et peut ne pas être surveillé"
|
"description": "Ce compte effectue principalement des actions automatisées et peut ne pas être surveillé"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"fields": {
|
"fields": {
|
||||||
"group": "Groupe {{index}}",
|
"group": "Groupe {{index}}",
|
||||||
"label": "Étiquette",
|
"label": "Libellé",
|
||||||
"content": "Contenu"
|
"content": "Contenu"
|
||||||
},
|
},
|
||||||
"mediaSelectionFailed": "Le traitement de l'image a échoué. Veuillez réessayer."
|
"mediaSelectionFailed": "Le traitement de l'image a échoué. Veuillez réessayer."
|
||||||
@ -196,8 +196,8 @@
|
|||||||
"settings": "Activer dans les paramètres"
|
"settings": "Activer dans les paramètres"
|
||||||
},
|
},
|
||||||
"missingServerKey": {
|
"missingServerKey": {
|
||||||
"message": "",
|
"message": "Le serveur n'est pas configuré pour le push",
|
||||||
"description": ""
|
"description": "Veuillez contacter l'administrateur de votre serveur pour configurer le support push"
|
||||||
},
|
},
|
||||||
"global": {
|
"global": {
|
||||||
"heading": "Activer pour {{acct}}",
|
"heading": "Activer pour {{acct}}",
|
||||||
@ -205,13 +205,13 @@
|
|||||||
},
|
},
|
||||||
"decode": {
|
"decode": {
|
||||||
"heading": "Détails du message",
|
"heading": "Détails du message",
|
||||||
"description": "Les messages acheminés par le serveur de tooot sont chiffrés, mais vous pouvez choisir de décoder le message sur le serveur. Le code source de notre serveur est open source et aucune politique de log."
|
"description": "Les messages acheminés par le serveur de tooot sont chiffrés, mais vous pouvez choisir de décoder le message sur le serveur. Le code source de notre serveur est open source et il n'y a aucune politique de log."
|
||||||
},
|
},
|
||||||
"default": {
|
"default": {
|
||||||
"heading": "Par défaut"
|
"heading": "Par défaut"
|
||||||
},
|
},
|
||||||
"follow": {
|
"follow": {
|
||||||
"heading": "Nouvel abonné"
|
"heading": "Nouveau⋅elle abonné⋅e"
|
||||||
},
|
},
|
||||||
"follow_request": {
|
"follow_request": {
|
||||||
"heading": "Demande d'abonnement"
|
"heading": "Demande d'abonnement"
|
||||||
@ -229,16 +229,16 @@
|
|||||||
"heading": "Mise à jour du sondage"
|
"heading": "Mise à jour du sondage"
|
||||||
},
|
},
|
||||||
"status": {
|
"status": {
|
||||||
"heading": "Pouet des utilisateurs inscrits"
|
"heading": "Pouet des utilisateurs auxquels vous êtes abonnés"
|
||||||
},
|
},
|
||||||
"update": {
|
"update": {
|
||||||
"heading": ""
|
"heading": "Le reblog a été édité"
|
||||||
},
|
},
|
||||||
"admin.sign_up": {
|
"admin.sign_up": {
|
||||||
"heading": ""
|
"heading": "Admin : s'inscrire"
|
||||||
},
|
},
|
||||||
"admin.report": {
|
"admin.report": {
|
||||||
"heading": ""
|
"heading": "Admin : signalement"
|
||||||
},
|
},
|
||||||
"howitworks": "Apprenez comment cela fonctionne"
|
"howitworks": "Apprenez comment cela fonctionne"
|
||||||
},
|
},
|
||||||
@ -261,7 +261,7 @@
|
|||||||
"button": "Se déconnecter",
|
"button": "Se déconnecter",
|
||||||
"alert": {
|
"alert": {
|
||||||
"title": "Déconnexion?",
|
"title": "Déconnexion?",
|
||||||
"message": "Après vous être déconnecté, vous devez vous reconnecter",
|
"message": "Après vous être déconnecté, vous devrez vous reconnecter",
|
||||||
"buttons": {
|
"buttons": {
|
||||||
"logout": "Déconnexion"
|
"logout": "Déconnexion"
|
||||||
}
|
}
|
||||||
@ -317,7 +317,7 @@
|
|||||||
"contact": {
|
"contact": {
|
||||||
"heading": "Contacter tooot"
|
"heading": "Contacter tooot"
|
||||||
},
|
},
|
||||||
"version": "Version {{version}}",
|
"version": "Version v{{version}}",
|
||||||
"instanceVersion": "Version de Mastodon v{{version}}"
|
"instanceVersion": "Version de Mastodon v{{version}}"
|
||||||
},
|
},
|
||||||
"switch": {
|
"switch": {
|
||||||
@ -346,12 +346,12 @@
|
|||||||
"suspended": "Compte suspendu par les modérateurs de votre serveur"
|
"suspended": "Compte suspendu par les modérateurs de votre serveur"
|
||||||
},
|
},
|
||||||
"accountInLists": {
|
"accountInLists": {
|
||||||
"name": "",
|
"name": "Listes de @{{username}}",
|
||||||
"inLists": "",
|
"inLists": "Dans les listes",
|
||||||
"notInLists": ""
|
"notInLists": "Autres listes"
|
||||||
},
|
},
|
||||||
"attachments": {
|
"attachments": {
|
||||||
"name": ""
|
"name": "Média de <0 /><1></1>"
|
||||||
},
|
},
|
||||||
"hashtag": {
|
"hashtag": {
|
||||||
"follow": "Suivre",
|
"follow": "Suivre",
|
||||||
@ -377,7 +377,7 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"trending": {
|
"trending": {
|
||||||
"tags": ""
|
"tags": "Tags tendance"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"sections": {
|
"sections": {
|
||||||
@ -399,7 +399,7 @@
|
|||||||
"reblogged_by": "{{count}} boosté",
|
"reblogged_by": "{{count}} boosté",
|
||||||
"favourited_by": "{{count}} mis en favori"
|
"favourited_by": "{{count}} mis en favori"
|
||||||
},
|
},
|
||||||
"resultIncomplete": ""
|
"resultIncomplete": "Les résultats d'une instance distante sont incomplets"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -7,7 +7,8 @@
|
|||||||
"continue": "Continua",
|
"continue": "Continua",
|
||||||
"create": "",
|
"create": "",
|
||||||
"delete": "",
|
"delete": "",
|
||||||
"done": ""
|
"done": "",
|
||||||
|
"confirm": "Ho capito"
|
||||||
},
|
},
|
||||||
"customEmoji": {
|
"customEmoji": {
|
||||||
"accessibilityLabel": "Emoji personalizzata {{emoji}}"
|
"accessibilityLabel": "Emoji personalizzata {{emoji}}"
|
||||||
|
@ -13,10 +13,16 @@
|
|||||||
},
|
},
|
||||||
"block": {
|
"block": {
|
||||||
"action_false": "Blocca utente",
|
"action_false": "Blocca utente",
|
||||||
"action_true": "Sblocca utente"
|
"action_true": "Sblocca utente",
|
||||||
|
"alert": {
|
||||||
|
"title": ""
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"reports": {
|
"reports": {
|
||||||
"action": ""
|
"action": "",
|
||||||
|
"alert": {
|
||||||
|
"title": ""
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"at": {
|
"at": {
|
||||||
@ -33,10 +39,7 @@
|
|||||||
"action": "Blocca istanza {{instance}}",
|
"action": "Blocca istanza {{instance}}",
|
||||||
"alert": {
|
"alert": {
|
||||||
"title": "Confermi di voler bloccare l'istanza {{instance}}?",
|
"title": "Confermi di voler bloccare l'istanza {{instance}}?",
|
||||||
"message": "Sarebbe meglio mutare o bloccare singoli utenti.\n\nSe blocchi un'istanza, tutti i suoi contenuti a te relativi, inclusi tutti i tuoi seguaci da questa, saranno rimossi.",
|
"message": "Sarebbe meglio mutare o bloccare singoli utenti.\n\nSe blocchi un'istanza, tutti i suoi contenuti a te relativi, inclusi tutti i tuoi seguaci da questa, saranno rimossi."
|
||||||
"buttons": {
|
|
||||||
"confirm": "Ho capito"
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -57,20 +60,14 @@
|
|||||||
"action": "Cancella toot",
|
"action": "Cancella toot",
|
||||||
"alert": {
|
"alert": {
|
||||||
"title": "Conferma?",
|
"title": "Conferma?",
|
||||||
"message": "Tutti i retoot, gli apprezzamenti, e le risposte, saranno cancellati.",
|
"message": "Tutti i retoot, gli apprezzamenti, e le risposte, saranno cancellati."
|
||||||
"buttons": {
|
|
||||||
"confirm": "Ho capito"
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"deleteEdit": {
|
"deleteEdit": {
|
||||||
"action": "Cancella e ripubblica toot",
|
"action": "Cancella e ripubblica toot",
|
||||||
"alert": {
|
"alert": {
|
||||||
"title": "Confermi cancellazione e ripubblicazione?",
|
"title": "Confermi cancellazione e ripubblicazione?",
|
||||||
"message": "Tutti i retoot, gli apprezzamenti, e le risposte, saranno cancellati.",
|
"message": "Tutti i retoot, gli apprezzamenti, e le risposte, saranno cancellati."
|
||||||
"buttons": {
|
|
||||||
"confirm": "Ho capito"
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"mute": {
|
"mute": {
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
"textInput": {
|
"textInput": {
|
||||||
"placeholder": ""
|
"placeholder": ""
|
||||||
},
|
},
|
||||||
|
"whitelisted": "",
|
||||||
"button": "Accedi",
|
"button": "Accedi",
|
||||||
"information": {
|
"information": {
|
||||||
"name": "Nome",
|
"name": "Nome",
|
||||||
|
@ -91,7 +91,12 @@
|
|||||||
"content": {
|
"content": {
|
||||||
"expandHint": "Contenuto nascosto"
|
"expandHint": "Contenuto nascosto"
|
||||||
},
|
},
|
||||||
"filtered": "Filtrato: {{phrase}}.",
|
"filtered": {
|
||||||
|
"reveal": "",
|
||||||
|
"match_v1": "",
|
||||||
|
"match_v2_one": "",
|
||||||
|
"match_v2_other": ""
|
||||||
|
},
|
||||||
"fullConversation": "Leggi la conversazione",
|
"fullConversation": "Leggi la conversazione",
|
||||||
"translate": {
|
"translate": {
|
||||||
"default": "Traduci",
|
"default": "Traduci",
|
||||||
|
@ -1,8 +1,7 @@
|
|||||||
{
|
{
|
||||||
"screenshot": {
|
"screenshot": {
|
||||||
"title": "Tutela della privacy",
|
"title": "Tutela della privacy",
|
||||||
"message": "Per favore, non rivelare l'identità degli altri utenti (nome, foto profilo, ecc..). Grazie!",
|
"message": "Per favore, non rivelare l'identità degli altri utenti (nome, foto profilo, ecc..). Grazie!"
|
||||||
"button": "Ho capito"
|
|
||||||
},
|
},
|
||||||
"localCorrupt": {
|
"localCorrupt": {
|
||||||
"message": "La sessione è scaduta, devi riaccedere"
|
"message": "La sessione è scaduta, devi riaccedere"
|
||||||
|
@ -5,9 +5,10 @@
|
|||||||
"cancel": "キャンセル",
|
"cancel": "キャンセル",
|
||||||
"discard": "変更を破棄",
|
"discard": "変更を破棄",
|
||||||
"continue": "続ける",
|
"continue": "続ける",
|
||||||
"create": "",
|
"create": "作成",
|
||||||
"delete": "削除",
|
"delete": "削除",
|
||||||
"done": "完了"
|
"done": "完了",
|
||||||
|
"confirm": "確認"
|
||||||
},
|
},
|
||||||
"customEmoji": {
|
"customEmoji": {
|
||||||
"accessibilityLabel": "カスタム絵文字 {{emoji}}"
|
"accessibilityLabel": "カスタム絵文字 {{emoji}}"
|
||||||
|
@ -13,10 +13,16 @@
|
|||||||
},
|
},
|
||||||
"block": {
|
"block": {
|
||||||
"action_false": "ユーザーをブロック",
|
"action_false": "ユーザーをブロック",
|
||||||
"action_true": "ユーザーのブロックを解除"
|
"action_true": "ユーザーのブロックを解除",
|
||||||
|
"alert": {
|
||||||
|
"title": ""
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"reports": {
|
"reports": {
|
||||||
"action": "ユーザーの報告とブロック"
|
"action": "ユーザーの報告とブロック",
|
||||||
|
"alert": {
|
||||||
|
"title": ""
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"at": {
|
"at": {
|
||||||
@ -33,10 +39,7 @@
|
|||||||
"action": "インスタンスをブロック {{instance}}",
|
"action": "インスタンスをブロック {{instance}}",
|
||||||
"alert": {
|
"alert": {
|
||||||
"title": "インスタンス {{instance}} をブロックしますか?",
|
"title": "インスタンス {{instance}} をブロックしますか?",
|
||||||
"message": "ほとんどの場合、特定のユーザーをミュートまたはブロックすることができます。\n\nインスタンスをブロックすると、このインスタンスからフォロワーを含むすべてのコンテンツが削除されます!",
|
"message": "ほとんどの場合、特定のユーザーをミュートまたはブロックすることができます。\n\nインスタンスをブロックすると、このインスタンスからフォロワーを含むすべてのコンテンツが削除されます!"
|
||||||
"buttons": {
|
|
||||||
"confirm": "確定"
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -57,20 +60,14 @@
|
|||||||
"action": "トゥートを削除",
|
"action": "トゥートを削除",
|
||||||
"alert": {
|
"alert": {
|
||||||
"title": "削除しますか?",
|
"title": "削除しますか?",
|
||||||
"message": "この投稿へのすべてのお気に入り登録やブーストは消去され、すべての返信は孤立することになります。",
|
"message": "この投稿へのすべてのお気に入り登録やブーストは消去され、すべての返信は孤立することになります。"
|
||||||
"buttons": {
|
|
||||||
"confirm": "確定"
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"deleteEdit": {
|
"deleteEdit": {
|
||||||
"action": "トゥートを削除し、再投稿する",
|
"action": "トゥートを削除し、再投稿する",
|
||||||
"alert": {
|
"alert": {
|
||||||
"title": "削除して再投稿しますか?",
|
"title": "削除して再投稿しますか?",
|
||||||
"message": "この投稿へのすべてのお気に入り登録やブーストは消去され、すべての返信は孤立することになります。",
|
"message": "この投稿へのすべてのお気に入り登録やブーストは消去され、すべての返信は孤立することになります。"
|
||||||
"buttons": {
|
|
||||||
"confirm": "確定"
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"mute": {
|
"mute": {
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
"textInput": {
|
"textInput": {
|
||||||
"placeholder": "インスタンスのドメイン"
|
"placeholder": "インスタンスのドメイン"
|
||||||
},
|
},
|
||||||
|
"whitelisted": "",
|
||||||
"button": "ログイン",
|
"button": "ログイン",
|
||||||
"information": {
|
"information": {
|
||||||
"name": "名前",
|
"name": "名前",
|
||||||
|
@ -91,7 +91,12 @@
|
|||||||
"content": {
|
"content": {
|
||||||
"expandHint": "内容を非表示にする"
|
"expandHint": "内容を非表示にする"
|
||||||
},
|
},
|
||||||
"filtered": "フィルター: {{phrase}}.",
|
"filtered": {
|
||||||
|
"reveal": "",
|
||||||
|
"match_v1": "",
|
||||||
|
"match_v2_one": "",
|
||||||
|
"match_v2_other": ""
|
||||||
|
},
|
||||||
"fullConversation": "スレッドを読む",
|
"fullConversation": "スレッドを読む",
|
||||||
"translate": {
|
"translate": {
|
||||||
"default": "翻訳",
|
"default": "翻訳",
|
||||||
|
@ -1,8 +1,7 @@
|
|||||||
{
|
{
|
||||||
"screenshot": {
|
"screenshot": {
|
||||||
"title": "プライバシー保護",
|
"title": "プライバシー保護",
|
||||||
"message": "ユーザー名やアバターなど、他のユーザーを特定する情報は公開しないでください。",
|
"message": "ユーザー名やアバターなど、他のユーザーを特定する情報は公開しないでください。"
|
||||||
"button": "確認"
|
|
||||||
},
|
},
|
||||||
"localCorrupt": {
|
"localCorrupt": {
|
||||||
"message": "ログインの有効期限が切れました。もう一度ログインしてください。"
|
"message": "ログインの有効期限が切れました。もう一度ログインしてください。"
|
||||||
|
@ -5,9 +5,10 @@
|
|||||||
"cancel": "취소",
|
"cancel": "취소",
|
||||||
"discard": "취소",
|
"discard": "취소",
|
||||||
"continue": "계속",
|
"continue": "계속",
|
||||||
"create": "",
|
"create": "생성",
|
||||||
"delete": "삭제",
|
"delete": "삭제",
|
||||||
"done": "완료"
|
"done": "완료",
|
||||||
|
"confirm": "확인"
|
||||||
},
|
},
|
||||||
"customEmoji": {
|
"customEmoji": {
|
||||||
"accessibilityLabel": "커스텀 에모지 {{emoji}}"
|
"accessibilityLabel": "커스텀 에모지 {{emoji}}"
|
||||||
|
@ -13,10 +13,16 @@
|
|||||||
},
|
},
|
||||||
"block": {
|
"block": {
|
||||||
"action_false": "사용자 차단",
|
"action_false": "사용자 차단",
|
||||||
"action_true": "사용자 차단 해제"
|
"action_true": "사용자 차단 해제",
|
||||||
|
"alert": {
|
||||||
|
"title": ""
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"reports": {
|
"reports": {
|
||||||
"action": "사용자 신고 및 차단"
|
"action": "사용자 신고 및 차단",
|
||||||
|
"alert": {
|
||||||
|
"title": ""
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"at": {
|
"at": {
|
||||||
@ -33,10 +39,7 @@
|
|||||||
"action": "{{instance}} 인스턴스 차단",
|
"action": "{{instance}} 인스턴스 차단",
|
||||||
"alert": {
|
"alert": {
|
||||||
"title": "정말 {{instance}} 인스턴스를 차단할까요?",
|
"title": "정말 {{instance}} 인스턴스를 차단할까요?",
|
||||||
"message": "보통은 사용자 뮤트나 차단으로 충분해요.\n\n인스턴스를 차단하면, 팔로워를 포함한 인스턴스의 모든 콘텐츠가 삭제됩니다!",
|
"message": "보통은 사용자 뮤트나 차단으로 충분해요.\n\n인스턴스를 차단하면, 팔로워를 포함한 인스턴스의 모든 콘텐츠가 삭제됩니다!"
|
||||||
"buttons": {
|
|
||||||
"confirm": "확인"
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -57,20 +60,14 @@
|
|||||||
"action": "툿 삭제",
|
"action": "툿 삭제",
|
||||||
"alert": {
|
"alert": {
|
||||||
"title": "정말 삭제할까요?",
|
"title": "정말 삭제할까요?",
|
||||||
"message": "답장을 포함한 모든 부스트와 즐겨찾기가 지워져요.",
|
"message": "답장을 포함한 모든 부스트와 즐겨찾기가 지워져요."
|
||||||
"buttons": {
|
|
||||||
"confirm": "확인"
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"deleteEdit": {
|
"deleteEdit": {
|
||||||
"action": "툿 삭제 후 다시 게시",
|
"action": "툿 삭제 후 다시 게시",
|
||||||
"alert": {
|
"alert": {
|
||||||
"title": "툿을 정말 삭제하고 다시 게시할까요?",
|
"title": "툿을 정말 삭제하고 다시 게시할까요?",
|
||||||
"message": "답장을 포함한 모든 부스트와 즐겨찾기가 지워져요.",
|
"message": "답장을 포함한 모든 부스트와 즐겨찾기가 지워져요."
|
||||||
"buttons": {
|
|
||||||
"confirm": "확인"
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"mute": {
|
"mute": {
|
||||||
|
@ -1,8 +1,9 @@
|
|||||||
{
|
{
|
||||||
"server": {
|
"server": {
|
||||||
"textInput": {
|
"textInput": {
|
||||||
"placeholder": ""
|
"placeholder": "인스턴스 도메인"
|
||||||
},
|
},
|
||||||
|
"whitelisted": "화이트리스트 등록이 필요한 인스턴스에서 tooot이 정보를 읽어올 수 없는 문제일 수 있습니다.",
|
||||||
"button": "로그인",
|
"button": "로그인",
|
||||||
"information": {
|
"information": {
|
||||||
"name": "이름",
|
"name": "이름",
|
||||||
|
@ -31,8 +31,8 @@
|
|||||||
"notification": "{{name}} 님이 내 툿을 부스트했어요"
|
"notification": "{{name}} 님이 내 툿을 부스트했어요"
|
||||||
},
|
},
|
||||||
"update": "부스트한 툿이 수정됨",
|
"update": "부스트한 툿이 수정됨",
|
||||||
"admin.sign_up": "",
|
"admin.sign_up": "{{name}} 님이 인스턴스에 가입함",
|
||||||
"admin.report": ""
|
"admin.report": "{{name}} 님의 신고:"
|
||||||
},
|
},
|
||||||
"actions": {
|
"actions": {
|
||||||
"reply": {
|
"reply": {
|
||||||
@ -55,7 +55,7 @@
|
|||||||
"accessibilityLabel": "툿 북마크에 추가",
|
"accessibilityLabel": "툿 북마크에 추가",
|
||||||
"function": "툿 북마크"
|
"function": "툿 북마크"
|
||||||
},
|
},
|
||||||
"openReport": ""
|
"openReport": "신고 열기"
|
||||||
},
|
},
|
||||||
"actionsUsers": {
|
"actionsUsers": {
|
||||||
"reblogged_by": {
|
"reblogged_by": {
|
||||||
@ -91,7 +91,12 @@
|
|||||||
"content": {
|
"content": {
|
||||||
"expandHint": "숨겨진 콘텐츠"
|
"expandHint": "숨겨진 콘텐츠"
|
||||||
},
|
},
|
||||||
"filtered": "필터: {{phrase}}.",
|
"filtered": {
|
||||||
|
"reveal": "무시하고 보기",
|
||||||
|
"match_v1": "필터됨: {{phrase}}.",
|
||||||
|
"match_v2_one": "{{filters}}에 의해 필터됨.",
|
||||||
|
"match_v2_other": "{{count}}개의 필터 {{filters}}에 의해 필터됨."
|
||||||
|
},
|
||||||
"fullConversation": "대화 보기",
|
"fullConversation": "대화 보기",
|
||||||
"translate": {
|
"translate": {
|
||||||
"default": "번역",
|
"default": "번역",
|
||||||
|
@ -1,8 +1,7 @@
|
|||||||
{
|
{
|
||||||
"screenshot": {
|
"screenshot": {
|
||||||
"title": "개인정보 보호",
|
"title": "개인정보 보호",
|
||||||
"message": "다른 사용자의 이름이나, 프로필 사진 등의 정보를 유출하지 말아주세요. 고마워요!",
|
"message": "다른 사용자의 이름이나, 프로필 사진 등의 정보를 유출하지 말아주세요. 고마워요!"
|
||||||
"button": "확인"
|
|
||||||
},
|
},
|
||||||
"localCorrupt": {
|
"localCorrupt": {
|
||||||
"message": "로그인이 만료되었어요. 다시 로그인해주세요"
|
"message": "로그인이 만료되었어요. 다시 로그인해주세요"
|
||||||
|
@ -3,15 +3,15 @@
|
|||||||
"local": {
|
"local": {
|
||||||
"name": "팔로우 중",
|
"name": "팔로우 중",
|
||||||
"options": {
|
"options": {
|
||||||
"showBoosts": "",
|
"showBoosts": "부스트 표시",
|
||||||
"showReplies": ""
|
"showReplies": "답글 표시"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"public": {
|
"public": {
|
||||||
"segments": {
|
"segments": {
|
||||||
"federated": "연합",
|
"federated": "연합",
|
||||||
"local": "로컬",
|
"local": "로컬",
|
||||||
"trending": ""
|
"trending": "유행"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"notifications": {
|
"notifications": {
|
||||||
@ -28,7 +28,7 @@
|
|||||||
"filters": {
|
"filters": {
|
||||||
"accessibilityLabel": "필터",
|
"accessibilityLabel": "필터",
|
||||||
"accessibilityHint": "받는 알림 종류 선택",
|
"accessibilityHint": "받는 알림 종류 선택",
|
||||||
"title": "",
|
"title": "알림 표시",
|
||||||
"options": {
|
"options": {
|
||||||
"follow": "$t(screenTabs:me.push.follow.heading)",
|
"follow": "$t(screenTabs:me.push.follow.heading)",
|
||||||
"follow_request": "팔로우 요청",
|
"follow_request": "팔로우 요청",
|
||||||
@ -55,7 +55,7 @@
|
|||||||
"name": "즐겨찾기"
|
"name": "즐겨찾기"
|
||||||
},
|
},
|
||||||
"followedTags": {
|
"followedTags": {
|
||||||
"name": ""
|
"name": "팔로우 중인 해시태그"
|
||||||
},
|
},
|
||||||
"fontSize": {
|
"fontSize": {
|
||||||
"name": "툿 폰트 크기"
|
"name": "툿 폰트 크기"
|
||||||
@ -235,10 +235,10 @@
|
|||||||
"heading": "부스트한 툿이 수정됨"
|
"heading": "부스트한 툿이 수정됨"
|
||||||
},
|
},
|
||||||
"admin.sign_up": {
|
"admin.sign_up": {
|
||||||
"heading": ""
|
"heading": "관리자: 신규 가입"
|
||||||
},
|
},
|
||||||
"admin.report": {
|
"admin.report": {
|
||||||
"heading": ""
|
"heading": "관리자: 신고 요청"
|
||||||
},
|
},
|
||||||
"howitworks": "메시지 라우팅 방식 더 알아보기"
|
"howitworks": "메시지 라우팅 방식 더 알아보기"
|
||||||
},
|
},
|
||||||
@ -399,7 +399,7 @@
|
|||||||
"reblogged_by": "{{count}} 부스트",
|
"reblogged_by": "{{count}} 부스트",
|
||||||
"favourited_by": "{{count}} 즐겨찾기"
|
"favourited_by": "{{count}} 즐겨찾기"
|
||||||
},
|
},
|
||||||
"resultIncomplete": ""
|
"resultIncomplete": "원격 인스턴스의 응답 형태가 올바르지 않아요"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -7,7 +7,8 @@
|
|||||||
"continue": "Ga verder",
|
"continue": "Ga verder",
|
||||||
"create": "Maak",
|
"create": "Maak",
|
||||||
"delete": "Verwijder",
|
"delete": "Verwijder",
|
||||||
"done": "Gereed"
|
"done": "Gereed",
|
||||||
|
"confirm": "Bevestig"
|
||||||
},
|
},
|
||||||
"customEmoji": {
|
"customEmoji": {
|
||||||
"accessibilityLabel": "Aangepaste emoji {{emoji}}"
|
"accessibilityLabel": "Aangepaste emoji {{emoji}}"
|
||||||
|
@ -13,10 +13,16 @@
|
|||||||
},
|
},
|
||||||
"block": {
|
"block": {
|
||||||
"action_false": "Gebruiker blokkeren",
|
"action_false": "Gebruiker blokkeren",
|
||||||
"action_true": "Gebruiker deblokkeren"
|
"action_true": "Gebruiker deblokkeren",
|
||||||
|
"alert": {
|
||||||
|
"title": "Bevestig blokkeren van @{{username}} ?"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"reports": {
|
"reports": {
|
||||||
"action": "Rapporteren en blokkeren"
|
"action": "Rapporteren en blokkeren",
|
||||||
|
"alert": {
|
||||||
|
"title": "Bevestig rapporteren en blokkeren van @{{username}} ?"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"at": {
|
"at": {
|
||||||
@ -33,10 +39,7 @@
|
|||||||
"action": "Blokkeer instantie {{instance}}",
|
"action": "Blokkeer instantie {{instance}}",
|
||||||
"alert": {
|
"alert": {
|
||||||
"title": "Bevestig blokkeren van {{instance}} ?",
|
"title": "Bevestig blokkeren van {{instance}} ?",
|
||||||
"message": "Meestal kunt u bepaalde gebruiker dempen of blokkeren.\n\nNa het blokkeren van de instantie, wordt alle inhoud inclusief volgers van deze instantie verwijderd!",
|
"message": "Meestal kunt u bepaalde gebruiker dempen of blokkeren.\n\nNa het blokkeren van de instantie, wordt alle inhoud inclusief volgers van deze instantie verwijderd!"
|
||||||
"buttons": {
|
|
||||||
"confirm": "Bevestig"
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -57,20 +60,14 @@
|
|||||||
"action": "Toot verwijderen",
|
"action": "Toot verwijderen",
|
||||||
"alert": {
|
"alert": {
|
||||||
"title": "Verwijderen bevestigen?",
|
"title": "Verwijderen bevestigen?",
|
||||||
"message": "Alle boosts en favorieten zullen worden gewist, inclusief alle antwoorden.",
|
"message": "Alle boosts en favorieten zullen worden gewist, inclusief alle antwoorden."
|
||||||
"buttons": {
|
|
||||||
"confirm": "Bevestig"
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"deleteEdit": {
|
"deleteEdit": {
|
||||||
"action": "Toot verwijderen en opnieuw plaatsen",
|
"action": "Toot verwijderen en opnieuw plaatsen",
|
||||||
"alert": {
|
"alert": {
|
||||||
"title": "Bevestig verwijderen en opnieuw plaatsen?",
|
"title": "Bevestig verwijderen en opnieuw plaatsen?",
|
||||||
"message": "Alle boosts en favorieten zullen worden gewist, inclusief alle antwoorden.",
|
"message": "Alle boosts en favorieten zullen worden gewist, inclusief alle antwoorden."
|
||||||
"buttons": {
|
|
||||||
"confirm": "Bevestig"
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"mute": {
|
"mute": {
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
"textInput": {
|
"textInput": {
|
||||||
"placeholder": "Domeinnaam van instantie"
|
"placeholder": "Domeinnaam van instantie"
|
||||||
},
|
},
|
||||||
|
"whitelisted": "Dit kan een gewhiteliste instantie zijn waarvan tooot geen gegevens kan ophalen voordat er ingelogd is.",
|
||||||
"button": "Inloggen",
|
"button": "Inloggen",
|
||||||
"information": {
|
"information": {
|
||||||
"name": "Naam",
|
"name": "Naam",
|
||||||
|
@ -91,7 +91,12 @@
|
|||||||
"content": {
|
"content": {
|
||||||
"expandHint": "Verborgen inhoud"
|
"expandHint": "Verborgen inhoud"
|
||||||
},
|
},
|
||||||
"filtered": "Gefilterd: {{phrase}}.",
|
"filtered": {
|
||||||
|
"reveal": "Toch weergeven",
|
||||||
|
"match_v1": "Gefilterd: {{phrase}}.",
|
||||||
|
"match_v2_one": "Gefilterd door {{filters}}.",
|
||||||
|
"match_v2_other": "Gefilterd door {{count}} filters, {{filters}}."
|
||||||
|
},
|
||||||
"fullConversation": "Gesprekken lezen",
|
"fullConversation": "Gesprekken lezen",
|
||||||
"translate": {
|
"translate": {
|
||||||
"default": "Vertaal",
|
"default": "Vertaal",
|
||||||
|
@ -1,8 +1,7 @@
|
|||||||
{
|
{
|
||||||
"screenshot": {
|
"screenshot": {
|
||||||
"title": "Privacy Bescherming",
|
"title": "Privacy Bescherming",
|
||||||
"message": "Gelieve de identiteit van een andere gebruiker niet openbaar te maken, zoals gebruikersnaam of avatar en meer. Bedankt!",
|
"message": "Gelieve de identiteit van een andere gebruiker niet openbaar te maken, zoals gebruikersnaam of avatar en meer. Bedankt!"
|
||||||
"button": "Bevestig"
|
|
||||||
},
|
},
|
||||||
"localCorrupt": {
|
"localCorrupt": {
|
||||||
"message": "Sessie verlopen. Log opnieuw in"
|
"message": "Sessie verlopen. Log opnieuw in"
|
||||||
|
@ -7,7 +7,8 @@
|
|||||||
"continue": "Dalej",
|
"continue": "Dalej",
|
||||||
"create": "",
|
"create": "",
|
||||||
"delete": "Usuń",
|
"delete": "Usuń",
|
||||||
"done": ""
|
"done": "",
|
||||||
|
"confirm": ""
|
||||||
},
|
},
|
||||||
"customEmoji": {
|
"customEmoji": {
|
||||||
"accessibilityLabel": "Własne emoji {{emoji}}"
|
"accessibilityLabel": "Własne emoji {{emoji}}"
|
||||||
|
@ -13,10 +13,16 @@
|
|||||||
},
|
},
|
||||||
"block": {
|
"block": {
|
||||||
"action_false": "Zablokuj użytkownika",
|
"action_false": "Zablokuj użytkownika",
|
||||||
"action_true": "Odblokuj użytkownika"
|
"action_true": "Odblokuj użytkownika",
|
||||||
|
"alert": {
|
||||||
|
"title": ""
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"reports": {
|
"reports": {
|
||||||
"action": "Zgłoś i zablokuj"
|
"action": "Zgłoś i zablokuj",
|
||||||
|
"alert": {
|
||||||
|
"title": ""
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"at": {
|
"at": {
|
||||||
@ -33,10 +39,7 @@
|
|||||||
"action": "Zablokuj instancję {{instance}}",
|
"action": "Zablokuj instancję {{instance}}",
|
||||||
"alert": {
|
"alert": {
|
||||||
"title": "Na pewno zablokować {{instance}}?",
|
"title": "Na pewno zablokować {{instance}}?",
|
||||||
"message": "Zazwyczaj wycisza się (albo blokuje) konkretnych użytkowników. \n\nGdy zablokujesz instancję, cała jej zawartość (włączając np. obserwujące Cię osoby, które do niej należą) zostanie usunięta!",
|
"message": "Zazwyczaj wycisza się (albo blokuje) konkretnych użytkowników. \n\nGdy zablokujesz instancję, cała jej zawartość (włączając np. obserwujące Cię osoby, które do niej należą) zostanie usunięta!"
|
||||||
"buttons": {
|
|
||||||
"confirm": "Na pewno?"
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -57,20 +60,14 @@
|
|||||||
"action": "Usuń wpis",
|
"action": "Usuń wpis",
|
||||||
"alert": {
|
"alert": {
|
||||||
"title": "Na pewno usunąć?",
|
"title": "Na pewno usunąć?",
|
||||||
"message": "Wszystkie podbite i polubione wpisy zostaną wyczyszczone - wraz z odpowiedziami.",
|
"message": "Wszystkie podbite i polubione wpisy zostaną wyczyszczone - wraz z odpowiedziami."
|
||||||
"buttons": {
|
|
||||||
"confirm": "Na pewno?"
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"deleteEdit": {
|
"deleteEdit": {
|
||||||
"action": "",
|
"action": "",
|
||||||
"alert": {
|
"alert": {
|
||||||
"title": "",
|
"title": "",
|
||||||
"message": "",
|
"message": ""
|
||||||
"buttons": {
|
|
||||||
"confirm": ""
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"mute": {
|
"mute": {
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user