Fixed #554
|
@ -1,3 +0,0 @@
|
|||
{
|
||||
"javascript.inlayHints.functionLikeReturnTypes.enabled": false
|
||||
}
|
After Width: | Height: | Size: 382 KiB |
After Width: | Height: | Size: 311 KiB |
After Width: | Height: | Size: 317 KiB |
After Width: | Height: | Size: 116 KiB |
After Width: | Height: | Size: 312 KiB |
After Width: | Height: | Size: 113 KiB |
After Width: | Height: | Size: 97 KiB |
After Width: | Height: | Size: 109 KiB |
After Width: | Height: | Size: 214 KiB |
After Width: | Height: | Size: 271 KiB |
After Width: | Height: | Size: 177 KiB |
After Width: | Height: | Size: 199 KiB |
After Width: | Height: | Size: 211 KiB |
After Width: | Height: | Size: 236 KiB |
After Width: | Height: | Size: 113 KiB |
After Width: | Height: | Size: 103 KiB |
After Width: | Height: | Size: 248 KiB |
After Width: | Height: | Size: 249 KiB |
After Width: | Height: | Size: 403 KiB |
After Width: | Height: | Size: 344 KiB |
After Width: | Height: | Size: 164 KiB |
After Width: | Height: | Size: 356 KiB |
After Width: | Height: | Size: 188 KiB |
After Width: | Height: | Size: 169 KiB |
After Width: | Height: | Size: 187 KiB |
After Width: | Height: | Size: 174 KiB |
After Width: | Height: | Size: 274 KiB |
After Width: | Height: | Size: 293 KiB |
After Width: | Height: | Size: 609 KiB |
After Width: | Height: | Size: 104 KiB |
After Width: | Height: | Size: 402 KiB |
After Width: | Height: | Size: 339 KiB |
After Width: | Height: | Size: 109 KiB |
After Width: | Height: | Size: 198 KiB |
After Width: | Height: | Size: 334 KiB |
154
demo/statuses.ts
|
@ -1,6 +1,7 @@
|
|||
const demoStatuses = [
|
||||
const demoStatus: Mastodon.Status[] = [
|
||||
{
|
||||
id: '1',
|
||||
uri: 'https://example.com',
|
||||
created_at: new Date().toISOString(),
|
||||
sensitive: false,
|
||||
visibility: 'public',
|
||||
|
@ -13,7 +14,6 @@ const demoStatuses = [
|
|||
bookmarked: false,
|
||||
content:
|
||||
'<p>Would you like to try out this simple, beautiful and open-source mobile app for Mastodon? 😊</p>',
|
||||
reblog: null,
|
||||
application: {
|
||||
name: 'tooot',
|
||||
website: 'https://tooot.app'
|
||||
|
@ -23,19 +23,31 @@ const demoStatuses = [
|
|||
username: 'tooot📱',
|
||||
acct: 'tooot@xmflsct.com',
|
||||
display_name: 'tooot📱',
|
||||
avatar_static:
|
||||
'https://avatars.githubusercontent.com/u/77554750?s=200&v=4'
|
||||
avatar: 'https://avatars.githubusercontent.com/u/77554750?s=200&v=4',
|
||||
avatar_static: 'https://avatars.githubusercontent.com/u/77554750?s=200&v=4',
|
||||
url: '',
|
||||
header: '',
|
||||
header_static: '',
|
||||
locked: false,
|
||||
discoverable: false,
|
||||
created_at: new Date().toISOString(),
|
||||
last_status_at: new Date().toISOString(),
|
||||
statuses_count: 1,
|
||||
followers_count: 1,
|
||||
following_count: 1,
|
||||
fields: [],
|
||||
bot: false
|
||||
},
|
||||
media_attachments: [],
|
||||
poll: {
|
||||
id: '1',
|
||||
expires_at: new Date().setDate(new Date().getDate() + 5),
|
||||
expires_at: new Date().setDate(new Date().getDate() + 5).toString(),
|
||||
expired: false,
|
||||
multiple: false,
|
||||
votes_count: 10,
|
||||
voters_count: null,
|
||||
voters_count: 2,
|
||||
voted: false,
|
||||
own_votes: null,
|
||||
own_votes: undefined,
|
||||
options: [
|
||||
{
|
||||
title: 'I would love to!',
|
||||
|
@ -48,11 +60,15 @@ const demoStatuses = [
|
|||
],
|
||||
emojis: []
|
||||
},
|
||||
mentions: []
|
||||
mentions: [],
|
||||
tags: [],
|
||||
emojis: [],
|
||||
pinned: false
|
||||
},
|
||||
{
|
||||
id: '2',
|
||||
created_at: new Date().setMinutes(new Date().getMinutes() - 2),
|
||||
uri: 'https://example.com',
|
||||
created_at: new Date().setMinutes(new Date().getMinutes() - 2).toString(),
|
||||
sensitive: false,
|
||||
spoiler_text: '',
|
||||
visibility: 'public',
|
||||
|
@ -65,18 +81,26 @@ const demoStatuses = [
|
|||
bookmarked: false,
|
||||
content:
|
||||
'<p>Mastodon is a free and open-source self-hosted social networking service. It allows anyone to host their own server node in the network, and its various separately operated user bases are federated across many different servers. These nodes are referred to as "instances" by Mastodon users.</p>',
|
||||
reblog: null,
|
||||
application: {
|
||||
name: 'Web',
|
||||
website: null
|
||||
},
|
||||
application: { name: 'Web' },
|
||||
account: {
|
||||
id: '1000',
|
||||
username: 'Mastodon',
|
||||
acct: 'mastodon',
|
||||
display_name: 'Mastodon',
|
||||
avatar_static:
|
||||
'https://mastodon.social/apple-touch-icon.png'
|
||||
avatar: 'https://mastodon.social/apple-touch-icon.png',
|
||||
avatar_static: 'https://mastodon.social/apple-touch-icon.png',
|
||||
url: '',
|
||||
header: '',
|
||||
header_static: '',
|
||||
locked: false,
|
||||
discoverable: false,
|
||||
created_at: new Date().toISOString(),
|
||||
last_status_at: new Date().toISOString(),
|
||||
statuses_count: 1,
|
||||
followers_count: 1,
|
||||
following_count: 1,
|
||||
fields: [],
|
||||
bot: false
|
||||
},
|
||||
media_attachments: [],
|
||||
card: {
|
||||
|
@ -85,18 +109,31 @@ const demoStatuses = [
|
|||
description:
|
||||
'Mastodon is an open source decentralized social network - by the people for the people. Join the federation and take back control of your social media!',
|
||||
type: 'link',
|
||||
image:
|
||||
'https://mastodon.social/apple-touch-icon.png'
|
||||
image: 'https://mastodon.social/apple-touch-icon.png',
|
||||
author_name: '',
|
||||
author_url: '',
|
||||
provider_name: '',
|
||||
provider_url: '',
|
||||
html: '<p></p>',
|
||||
width: 100,
|
||||
height: 100,
|
||||
embed_url: 'https://example.com',
|
||||
blurhash: ''
|
||||
},
|
||||
mentions: []
|
||||
mentions: [],
|
||||
tags: [],
|
||||
emojis: [],
|
||||
pinned: false
|
||||
},
|
||||
{
|
||||
id: '3',
|
||||
created_at: '2021-01-24T09:50:00.901Z',
|
||||
uri: '',
|
||||
created_at: new Date().setHours(new Date().getHours() - 1).toString(),
|
||||
sensitive: false,
|
||||
spoiler_text: '',
|
||||
visibility: 'public',
|
||||
replies_count: 2,
|
||||
reblogs_count: null,
|
||||
reblogs_count: 1,
|
||||
favourites_count: 3,
|
||||
favourited: false,
|
||||
reblogged: false,
|
||||
|
@ -104,24 +141,38 @@ const demoStatuses = [
|
|||
bookmarked: true,
|
||||
content:
|
||||
'<p>These servers are connected as a federated social network, allowing users from different servers to interact with each other seamlessly. Once a Mastodon server knows another Mastodon server, it "federates" with the other Mastodon server. Mastodon is a part of the wider Fediverse, allowing its users to also interact with users on different open platforms that support the same protocol, such as PeerTube and Friendica.</p>',
|
||||
reblog: null,
|
||||
application: {
|
||||
name: 'Web',
|
||||
website: null
|
||||
},
|
||||
application: { name: 'Web' },
|
||||
account: {
|
||||
id: '1001',
|
||||
username: 'Fediverse',
|
||||
acct: 'fediverse',
|
||||
display_name: 'Fediverse',
|
||||
avatar:
|
||||
'https://e7.pngegg.com/pngimages/667/514/png-clipart-mastodon-fediverse-social-media-free-software-logo-social-media-blue-text.png',
|
||||
avatar_static:
|
||||
'https://e7.pngegg.com/pngimages/667/514/png-clipart-mastodon-fediverse-social-media-free-software-logo-social-media-blue-text.png'
|
||||
'https://e7.pngegg.com/pngimages/667/514/png-clipart-mastodon-fediverse-social-media-free-software-logo-social-media-blue-text.png',
|
||||
url: '',
|
||||
header: '',
|
||||
header_static: '',
|
||||
locked: false,
|
||||
discoverable: false,
|
||||
created_at: new Date().toISOString(),
|
||||
last_status_at: new Date().toISOString(),
|
||||
statuses_count: 1,
|
||||
followers_count: 1,
|
||||
following_count: 1,
|
||||
fields: [],
|
||||
bot: false
|
||||
},
|
||||
media_attachments: [],
|
||||
mentions: []
|
||||
mentions: [],
|
||||
tags: [],
|
||||
emojis: [],
|
||||
pinned: false
|
||||
},
|
||||
{
|
||||
id: '4',
|
||||
uri: 'https://example.com',
|
||||
created_at: '2021-01-24T08:50:00.901Z',
|
||||
sensitive: false,
|
||||
visibility: 'public',
|
||||
|
@ -134,7 +185,6 @@ const demoStatuses = [
|
|||
bookmarked: false,
|
||||
content:
|
||||
'<p>tooot is an open source, simple mobile client for Mastodon. Focusing on your connections while being able to explore the Fediverse.</p>',
|
||||
reblog: null,
|
||||
application: {
|
||||
name: 'tooot',
|
||||
website: 'https://tooot.app'
|
||||
|
@ -144,14 +194,30 @@ const demoStatuses = [
|
|||
username: 'tooot📱',
|
||||
acct: 'tooot@xmflsct.com',
|
||||
display_name: 'tooot📱',
|
||||
avatar_static:
|
||||
'https://avatars.githubusercontent.com/u/77554750?s=200&v=4'
|
||||
avatar: 'https://avatars.githubusercontent.com/u/77554750?s=200&v=4',
|
||||
avatar_static: 'https://avatars.githubusercontent.com/u/77554750?s=200&v=4',
|
||||
url: '',
|
||||
header: '',
|
||||
header_static: '',
|
||||
locked: false,
|
||||
discoverable: false,
|
||||
created_at: new Date().toISOString(),
|
||||
last_status_at: new Date().toISOString(),
|
||||
statuses_count: 1,
|
||||
followers_count: 1,
|
||||
following_count: 1,
|
||||
fields: [],
|
||||
bot: false
|
||||
},
|
||||
media_attachments: [],
|
||||
mentions: []
|
||||
mentions: [],
|
||||
tags: [],
|
||||
emojis: [],
|
||||
pinned: false
|
||||
},
|
||||
{
|
||||
id: '5',
|
||||
uri: 'https://example.com',
|
||||
created_at: '2021-01-24T07:50:00.901Z',
|
||||
sensitive: false,
|
||||
visibility: 'public',
|
||||
|
@ -164,7 +230,6 @@ const demoStatuses = [
|
|||
bookmarked: false,
|
||||
content:
|
||||
'<p>- tooot supports multiple accounts<br />- tooot supports browsing external instance<br />- tooot aims to support multiple languages</p>',
|
||||
reblog: null,
|
||||
application: {
|
||||
name: 'tooot',
|
||||
website: 'https://tooot.app'
|
||||
|
@ -174,12 +239,27 @@ const demoStatuses = [
|
|||
username: 'tooot📱',
|
||||
acct: 'tooot@xmflsct.com',
|
||||
display_name: 'tooot📱',
|
||||
avatar_static:
|
||||
'https://avatars.githubusercontent.com/u/77554750?s=200&v=4'
|
||||
avatar: 'https://avatars.githubusercontent.com/u/77554750?s=200&v=4',
|
||||
avatar_static: 'https://avatars.githubusercontent.com/u/77554750?s=200&v=4',
|
||||
url: '',
|
||||
header: '',
|
||||
header_static: '',
|
||||
locked: false,
|
||||
discoverable: false,
|
||||
created_at: new Date().toISOString(),
|
||||
last_status_at: new Date().toISOString(),
|
||||
statuses_count: 1,
|
||||
followers_count: 1,
|
||||
following_count: 1,
|
||||
fields: [],
|
||||
bot: false
|
||||
},
|
||||
media_attachments: [],
|
||||
mentions: []
|
||||
mentions: [],
|
||||
tags: [],
|
||||
emojis: [],
|
||||
pinned: false
|
||||
}
|
||||
]
|
||||
|
||||
export default demoStatuses
|
||||
export default demoStatus
|
||||
|
|
|
@ -86,9 +86,10 @@ const MenuRow: React.FC<Props> = ({
|
|||
>
|
||||
<View
|
||||
style={{
|
||||
flex: 3,
|
||||
flexGrow: 3,
|
||||
flexDirection: 'row',
|
||||
alignItems: 'center'
|
||||
alignItems: 'center',
|
||||
marginRight: StyleConstants.Spacing.M
|
||||
}}
|
||||
>
|
||||
{iconFront && (
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
{
|
||||
"server": {
|
||||
"textInput": {
|
||||
"placeholder": "Instance' domain"
|
||||
"placeholder": "Instance's domain"
|
||||
},
|
||||
"button": "Login",
|
||||
"information": {
|
||||
|
|
|
@ -1,13 +1,11 @@
|
|||
{
|
||||
"heading": {
|
||||
"left": {
|
||||
"button": "Cancel",
|
||||
"alert": {
|
||||
"title": "Cancel editing?",
|
||||
"buttons": {
|
||||
"save": "Save draft",
|
||||
"delete": "Delete draft",
|
||||
"cancel": "Cancel"
|
||||
"delete": "Delete draft"
|
||||
}
|
||||
}
|
||||
},
|
||||
|
|
|
@ -4,7 +4,6 @@
|
|||
"name": "Following"
|
||||
},
|
||||
"public": {
|
||||
"name": "",
|
||||
"segments": {
|
||||
"federated": "Federated",
|
||||
"local": "Local",
|
||||
|
@ -13,9 +12,6 @@
|
|||
},
|
||||
"notifications": {
|
||||
"name": "Notifications"
|
||||
},
|
||||
"me": {
|
||||
"name": "About me"
|
||||
}
|
||||
},
|
||||
"common": {
|
||||
|
@ -348,7 +344,7 @@
|
|||
"notInLists": "Other lists"
|
||||
},
|
||||
"attachments": {
|
||||
"name": "<0 /><1>\"s media</1>"
|
||||
"name": "<0 /><1>'s media</1>"
|
||||
},
|
||||
"hashtag": {
|
||||
"follow": "Follow",
|
||||
|
|
|
@ -206,7 +206,7 @@ const ScreenCompose: React.FC<RootStackScreenProps<'Screen-Compose'>> = ({
|
|||
() => (
|
||||
<HeaderLeft
|
||||
type='text'
|
||||
content={t('heading.left.button')}
|
||||
content={t('common:buttons.cancel')}
|
||||
onPress={() => {
|
||||
if (!composeState.dirty) {
|
||||
navigation.goBack()
|
||||
|
@ -229,7 +229,7 @@ const ScreenCompose: React.FC<RootStackScreenProps<'Screen-Compose'>> = ({
|
|||
}
|
||||
},
|
||||
{
|
||||
text: t('heading.left.alert.buttons.cancel'),
|
||||
text: t('common:buttons.cancel'),
|
||||
style: 'cancel'
|
||||
}
|
||||
])
|
||||
|
@ -342,9 +342,7 @@ const ScreenCompose: React.FC<RootStackScreenProps<'Screen-Compose'>> = ({
|
|||
)
|
||||
|
||||
const headerContent = useMemo(() => {
|
||||
return `${totalTextCount} / ${maxTootChars}${
|
||||
__DEV__ ? ` Dirty: ${composeState.dirty.toString()}` : ''
|
||||
}`
|
||||
return `${totalTextCount} / ${maxTootChars}`
|
||||
}, [totalTextCount, maxTootChars, composeState.dirty])
|
||||
|
||||
const inputProps: EmojisState['inputProps'] = [
|
||||
|
|
|
@ -32,7 +32,7 @@ export const menuListDelete = ({
|
|||
key: 'list-delete',
|
||||
onSelect: () =>
|
||||
Alert.alert(
|
||||
i18next.t('screenTabs:me.listDelete.confirm.title', { list: params.title.slice(0, 6) }),
|
||||
i18next.t('screenTabs:me.listDelete.confirm.title', { list: params.title.slice(0, 20) }),
|
||||
i18next.t('screenTabs:me.listDelete.confirm.message'),
|
||||
[
|
||||
{
|
||||
|
|
|
@ -28,10 +28,7 @@ const AccountInformation = React.memo(
|
|||
<View style={styles.base}>
|
||||
<Placeholder
|
||||
Animation={props => (
|
||||
<Fade
|
||||
{...props}
|
||||
style={{ backgroundColor: colors.shimmerHighlight }}
|
||||
/>
|
||||
<Fade {...props} style={{ backgroundColor: colors.shimmerHighlight }} />
|
||||
)}
|
||||
>
|
||||
<View style={styles.avatarAndActions}>
|
||||
|
@ -41,7 +38,7 @@ const AccountInformation = React.memo(
|
|||
|
||||
<AccountInformationName account={account} />
|
||||
|
||||
<AccountInformationAccount account={account} localInstance={myInfo} />
|
||||
<AccountInformationAccount account={account} />
|
||||
|
||||
<AccountInformationFields account={account} myInfo={myInfo} />
|
||||
|
||||
|
|
|
@ -1,10 +1,7 @@
|
|||
import Icon from '@components/Icon'
|
||||
import CustomText from '@components/Text'
|
||||
import { useRelationshipQuery } from '@utils/queryHooks/relationship'
|
||||
import {
|
||||
getInstanceAccount,
|
||||
getInstanceUri
|
||||
} from '@utils/slices/instancesSlice'
|
||||
import { getInstanceAccount, getInstanceUri } from '@utils/slices/instancesSlice'
|
||||
import { StyleConstants } from '@utils/styles/constants'
|
||||
import { useTheme } from '@utils/styles/ThemeManager'
|
||||
import React from 'react'
|
||||
|
@ -15,19 +12,12 @@ import { PlaceholderLine } from 'rn-placeholder'
|
|||
|
||||
export interface Props {
|
||||
account: Mastodon.Account | undefined
|
||||
localInstance: boolean
|
||||
}
|
||||
|
||||
const AccountInformationAccount: React.FC<Props> = ({
|
||||
account,
|
||||
localInstance
|
||||
}) => {
|
||||
const AccountInformationAccount: React.FC<Props> = ({ account }) => {
|
||||
const { t } = useTranslation('screenTabs')
|
||||
const { colors } = useTheme()
|
||||
const instanceAccount = useSelector(
|
||||
getInstanceAccount,
|
||||
(prev, next) => prev?.acct === next?.acct
|
||||
)
|
||||
const instanceAccount = useSelector(getInstanceAccount, (prev, next) => prev?.acct === next?.acct)
|
||||
const instanceUri = useSelector(getInstanceUri)
|
||||
|
||||
const { data: relationship } = useRelationshipQuery({
|
||||
|
@ -35,6 +25,10 @@ const AccountInformationAccount: React.FC<Props> = ({
|
|||
options: { enabled: account !== undefined }
|
||||
})
|
||||
|
||||
const localInstance = instanceAccount.acct.includes('@')
|
||||
? instanceAccount.acct.includes(`@${instanceUri}`)
|
||||
: true
|
||||
|
||||
if (account || (localInstance && instanceAccount)) {
|
||||
return (
|
||||
<View
|
||||
|
@ -54,7 +48,7 @@ const AccountInformationAccount: React.FC<Props> = ({
|
|||
) : null}
|
||||
<CustomText
|
||||
style={{
|
||||
textDecorationLine: (account?.moved || account?.suspended) ? 'line-through' : undefined
|
||||
textDecorationLine: account?.moved || account?.suspended ? 'line-through' : undefined
|
||||
}}
|
||||
selectable
|
||||
>
|
||||
|
@ -94,7 +88,4 @@ const AccountInformationAccount: React.FC<Props> = ({
|
|||
}
|
||||
}
|
||||
|
||||
export default React.memo(
|
||||
AccountInformationAccount,
|
||||
(_, next) => next.account === undefined
|
||||
)
|
||||
export default AccountInformationAccount
|
||||
|
|
|
@ -5,7 +5,7 @@ import { StackNavigationProp } from '@react-navigation/stack'
|
|||
import { TabLocalStackParamList } from '@utils/navigation/navigators'
|
||||
import { StyleConstants } from '@utils/styles/constants'
|
||||
import React from 'react'
|
||||
import { Pressable, StyleSheet, View } from 'react-native'
|
||||
import { Pressable, View } from 'react-native'
|
||||
|
||||
export interface Props {
|
||||
account: Mastodon.Account | undefined
|
||||
|
@ -13,24 +13,24 @@ export interface Props {
|
|||
edit?: boolean
|
||||
}
|
||||
|
||||
const AccountInformationAvatar: React.FC<Props> = ({
|
||||
account,
|
||||
myInfo,
|
||||
edit
|
||||
}) => {
|
||||
const navigation =
|
||||
useNavigation<StackNavigationProp<TabLocalStackParamList>>()
|
||||
const AccountInformationAvatar: React.FC<Props> = ({ account, myInfo, edit }) => {
|
||||
const navigation = useNavigation<StackNavigationProp<TabLocalStackParamList>>()
|
||||
return (
|
||||
<Pressable
|
||||
disabled={!myInfo}
|
||||
onPress={() => {
|
||||
myInfo && account && navigation.push('Tab-Shared-Account', { account })
|
||||
}}
|
||||
style={styles.base}
|
||||
style={{
|
||||
borderRadius: 8,
|
||||
overflow: 'hidden',
|
||||
width: StyleConstants.Avatar.L,
|
||||
height: StyleConstants.Avatar.L
|
||||
}}
|
||||
>
|
||||
<GracefullyImage
|
||||
key={account?.avatar}
|
||||
style={styles.image}
|
||||
style={{ flex: 1 }}
|
||||
uri={{ original: account?.avatar, static: account?.avatar_static }}
|
||||
/>
|
||||
{edit ? (
|
||||
|
@ -51,14 +51,4 @@ const AccountInformationAvatar: React.FC<Props> = ({
|
|||
)
|
||||
}
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
base: {
|
||||
borderRadius: 8,
|
||||
overflow: 'hidden',
|
||||
width: StyleConstants.Avatar.L,
|
||||
height: StyleConstants.Avatar.L
|
||||
},
|
||||
image: { flex: 1 }
|
||||
})
|
||||
|
||||
export default AccountInformationAvatar
|
||||
|
|
|
@ -12,59 +12,53 @@ export interface Props {
|
|||
hidden?: boolean
|
||||
}
|
||||
|
||||
const AccountInformationCreated = React.memo(
|
||||
({ account, hidden = false }: Props) => {
|
||||
if (hidden) {
|
||||
return null
|
||||
}
|
||||
const AccountInformationCreated: React.FC<Props> = ({ account, hidden = false }) => {
|
||||
if (hidden) {
|
||||
return null
|
||||
}
|
||||
|
||||
const { i18n } = useTranslation()
|
||||
const { colors } = useTheme()
|
||||
const { t } = useTranslation('screenTabs')
|
||||
const { i18n } = useTranslation()
|
||||
const { colors } = useTheme()
|
||||
const { t } = useTranslation('screenTabs')
|
||||
|
||||
if (account) {
|
||||
return (
|
||||
<View
|
||||
style={{
|
||||
flexDirection: 'row',
|
||||
alignItems: 'center',
|
||||
borderRadius: 0,
|
||||
marginBottom: StyleConstants.Spacing.M
|
||||
}}
|
||||
>
|
||||
<Icon
|
||||
name='Calendar'
|
||||
size={StyleConstants.Font.Size.S}
|
||||
color={colors.secondary}
|
||||
style={{ marginRight: StyleConstants.Spacing.XS }}
|
||||
/>
|
||||
<CustomText fontStyle='S' style={{ color: colors.secondary }}>
|
||||
{t('shared.account.created_at', {
|
||||
date: new Date(account.created_at || '').toLocaleDateString(
|
||||
i18n.language,
|
||||
{
|
||||
year: 'numeric',
|
||||
month: 'long',
|
||||
day: 'numeric'
|
||||
}
|
||||
)
|
||||
})}
|
||||
</CustomText>
|
||||
</View>
|
||||
)
|
||||
} else {
|
||||
return (
|
||||
<PlaceholderLine
|
||||
width={StyleConstants.Font.Size.S * 4}
|
||||
height={StyleConstants.Font.LineHeight.S}
|
||||
color={colors.shimmerDefault}
|
||||
noMargin
|
||||
style={{ borderRadius: 0, marginBottom: StyleConstants.Spacing.M }}
|
||||
if (account) {
|
||||
return (
|
||||
<View
|
||||
style={{
|
||||
flexDirection: 'row',
|
||||
alignItems: 'center',
|
||||
borderRadius: 0,
|
||||
marginBottom: StyleConstants.Spacing.M
|
||||
}}
|
||||
>
|
||||
<Icon
|
||||
name='Calendar'
|
||||
size={StyleConstants.Font.Size.S}
|
||||
color={colors.secondary}
|
||||
style={{ marginRight: StyleConstants.Spacing.XS }}
|
||||
/>
|
||||
)
|
||||
}
|
||||
},
|
||||
(_, next) => next.account === undefined
|
||||
)
|
||||
<CustomText fontStyle='S' style={{ color: colors.secondary }}>
|
||||
{t('shared.account.created_at', {
|
||||
date: new Date(account.created_at || '').toLocaleDateString(i18n.language, {
|
||||
year: 'numeric',
|
||||
month: 'long',
|
||||
day: 'numeric'
|
||||
})
|
||||
})}
|
||||
</CustomText>
|
||||
</View>
|
||||
)
|
||||
} else {
|
||||
return (
|
||||
<PlaceholderLine
|
||||
width={StyleConstants.Font.Size.S * 4}
|
||||
height={StyleConstants.Font.LineHeight.S}
|
||||
color={colors.shimmerDefault}
|
||||
noMargin
|
||||
style={{ borderRadius: 0, marginBottom: StyleConstants.Spacing.M }}
|
||||
/>
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
export default AccountInformationCreated
|
||||
|
|
|
@ -10,53 +10,50 @@ export interface Props {
|
|||
myInfo?: boolean
|
||||
}
|
||||
|
||||
const AccountInformationFields = React.memo(
|
||||
({ account, myInfo }: Props) => {
|
||||
if (account?.suspended || myInfo || !account?.fields || account.fields.length === 0) {
|
||||
return null
|
||||
}
|
||||
const AccountInformationFields: React.FC<Props> = ({ account, myInfo }) => {
|
||||
if (account?.suspended || myInfo || !account?.fields || account.fields.length === 0) {
|
||||
return null
|
||||
}
|
||||
|
||||
const { colors } = useTheme()
|
||||
const { colors } = useTheme()
|
||||
|
||||
return (
|
||||
<View style={[styles.fields, { borderTopColor: colors.border }]}>
|
||||
{account.fields.map((field, index) => (
|
||||
<View key={index} style={[styles.field, { borderBottomColor: colors.border }]}>
|
||||
<View style={[styles.fieldLeft, { borderRightColor: colors.border }]}>
|
||||
<ParseHTML
|
||||
content={field.name}
|
||||
size={'S'}
|
||||
emojis={account.emojis}
|
||||
showFullLink
|
||||
numberOfLines={5}
|
||||
selectable
|
||||
return (
|
||||
<View style={[styles.fields, { borderTopColor: colors.border }]}>
|
||||
{account.fields.map((field, index) => (
|
||||
<View key={index} style={[styles.field, { borderBottomColor: colors.border }]}>
|
||||
<View style={[styles.fieldLeft, { borderRightColor: colors.border }]}>
|
||||
<ParseHTML
|
||||
content={field.name}
|
||||
size={'S'}
|
||||
emojis={account.emojis}
|
||||
showFullLink
|
||||
numberOfLines={5}
|
||||
selectable
|
||||
/>
|
||||
{field.verified_at ? (
|
||||
<Icon
|
||||
name='CheckCircle'
|
||||
size={StyleConstants.Font.Size.M}
|
||||
color={colors.primaryDefault}
|
||||
style={styles.fieldCheck}
|
||||
/>
|
||||
{field.verified_at ? (
|
||||
<Icon
|
||||
name='CheckCircle'
|
||||
size={StyleConstants.Font.Size.M}
|
||||
color={colors.primaryDefault}
|
||||
style={styles.fieldCheck}
|
||||
/>
|
||||
) : null}
|
||||
</View>
|
||||
<View style={styles.fieldRight}>
|
||||
<ParseHTML
|
||||
content={field.value}
|
||||
size={'S'}
|
||||
emojis={account.emojis}
|
||||
showFullLink
|
||||
numberOfLines={5}
|
||||
selectable
|
||||
/>
|
||||
</View>
|
||||
) : null}
|
||||
</View>
|
||||
))}
|
||||
</View>
|
||||
)
|
||||
},
|
||||
(_, next) => next.account === undefined
|
||||
)
|
||||
<View style={styles.fieldRight}>
|
||||
<ParseHTML
|
||||
content={field.value}
|
||||
size={'S'}
|
||||
emojis={account.emojis}
|
||||
showFullLink
|
||||
numberOfLines={5}
|
||||
selectable
|
||||
/>
|
||||
</View>
|
||||
</View>
|
||||
))}
|
||||
</View>
|
||||
)
|
||||
}
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
fields: {
|
||||
|
|
|
@ -66,4 +66,4 @@ const AccountInformationName: React.FC<Props> = ({ account }) => {
|
|||
)
|
||||
}
|
||||
|
||||
export default React.memo(AccountInformationName, (_, next) => next.account === undefined)
|
||||
export default AccountInformationName
|
||||
|
|
|
@ -1,45 +1,35 @@
|
|||
import { ParseHTML } from '@components/Parse'
|
||||
import { StyleConstants } from '@utils/styles/constants'
|
||||
import React, { useState } from 'react'
|
||||
import { StyleSheet, View } from 'react-native'
|
||||
import React from 'react'
|
||||
import { View } from 'react-native'
|
||||
|
||||
export interface Props {
|
||||
account: Mastodon.Account | undefined
|
||||
myInfo?: boolean
|
||||
}
|
||||
|
||||
const AccountInformationNote = React.memo(
|
||||
({ account, myInfo }: Props) => {
|
||||
const [note, setNote] = useState(account?.source?.note)
|
||||
if (
|
||||
account?.suspended ||
|
||||
myInfo ||
|
||||
!account?.note ||
|
||||
account.note.length === 0 ||
|
||||
account.note === '<p></p>'
|
||||
) {
|
||||
return null
|
||||
}
|
||||
|
||||
return (
|
||||
<View style={styles.note}>
|
||||
<ParseHTML
|
||||
content={account.note!}
|
||||
size={'M'}
|
||||
emojis={account.emojis}
|
||||
selectable
|
||||
numberOfLines={999}
|
||||
/>
|
||||
</View>
|
||||
)
|
||||
},
|
||||
(_, next) => next.account === undefined
|
||||
)
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
note: {
|
||||
marginBottom: StyleConstants.Spacing.L
|
||||
const AccountInformationNote: React.FC<Props> = ({ account, myInfo }) => {
|
||||
if (
|
||||
account?.suspended ||
|
||||
myInfo ||
|
||||
!account?.note ||
|
||||
account.note.length === 0 ||
|
||||
account.note === '<p></p>'
|
||||
) {
|
||||
return null
|
||||
}
|
||||
})
|
||||
|
||||
return (
|
||||
<View style={{ marginBottom: StyleConstants.Spacing.L }}>
|
||||
<ParseHTML
|
||||
content={account.note!}
|
||||
size={'M'}
|
||||
emojis={account.emojis}
|
||||
selectable
|
||||
numberOfLines={999}
|
||||
/>
|
||||
</View>
|
||||
)
|
||||
}
|
||||
|
||||
export default AccountInformationNote
|
||||
|
|
|
@ -39,7 +39,7 @@ const TabSharedAccountInLists: React.FC<
|
|||
})
|
||||
}, [])
|
||||
|
||||
const listsQuery = useListsQuery({})
|
||||
const listsQuery = useListsQuery()
|
||||
const accountInListsQuery = useAccountInListsQuery({ id: account.id })
|
||||
|
||||
const sections = [
|
||||
|
@ -48,8 +48,10 @@ const TabSharedAccountInLists: React.FC<
|
|||
id: 'out',
|
||||
title: t('shared.accountInLists.notInLists'),
|
||||
data:
|
||||
listsQuery.data?.filter(
|
||||
({ id }) => accountInListsQuery.data?.filter(d => d.id !== id).length
|
||||
listsQuery.data?.filter(({ id }) =>
|
||||
accountInListsQuery.data?.length
|
||||
? accountInListsQuery.data.filter(d => d.id !== id).length
|
||||
: true
|
||||
) || []
|
||||
}
|
||||
]
|
||||
|
|
|
@ -54,7 +54,11 @@ const TabSharedSearch: React.FC<TabSharedStackScreenProps<'Tab-Shared-Search'>>
|
|||
fontSize: StyleConstants.Font.Size.M,
|
||||
flex: 1,
|
||||
color: colors.primaryDefault,
|
||||
paddingLeft: StyleConstants.Spacing.XS
|
||||
marginLeft: StyleConstants.Spacing.XS,
|
||||
paddingLeft: StyleConstants.Spacing.XS,
|
||||
paddingVertical: StyleConstants.Spacing.XS,
|
||||
borderBottomColor: colors.border,
|
||||
borderBottomWidth: 1
|
||||
}}
|
||||
autoFocus
|
||||
onChangeText={debounce(
|
||||
|
|