Fixed #554
3
.vscode/settings.json
vendored
@ -1,3 +0,0 @@
|
||||
{
|
||||
"javascript.inlayHints.functionLikeReturnTypes.enabled": false
|
||||
}
|
BIN
demo/screenshots/Component-Instance.png
Normal file
After Width: | Height: | Size: 382 KiB |
BIN
demo/screenshots/Component-MediaSelector.png
Normal file
After Width: | Height: | Size: 311 KiB |
BIN
demo/screenshots/Logout-Confirmation.png
Normal file
After Width: | Height: | Size: 317 KiB |
BIN
demo/screenshots/Screen-AccountSelection.png
Normal file
After Width: | Height: | Size: 116 KiB |
BIN
demo/screenshots/Tab-Local.png
Normal file
After Width: | Height: | Size: 312 KiB |
BIN
demo/screenshots/Tab-Me-List-Edit.png
Normal file
After Width: | Height: | Size: 113 KiB |
BIN
demo/screenshots/Tab-Me-ListAccounts_Empty.png
Normal file
After Width: | Height: | Size: 97 KiB |
BIN
demo/screenshots/Tab-Me-ListAccounts_Error.png
Normal file
After Width: | Height: | Size: 109 KiB |
BIN
demo/screenshots/Tab-Me-List_Delete.png
Normal file
After Width: | Height: | Size: 214 KiB |
BIN
demo/screenshots/Tab-Me-List_Menu.png
Normal file
After Width: | Height: | Size: 271 KiB |
BIN
demo/screenshots/Tab-Me-Profile-Fields.png
Normal file
After Width: | Height: | Size: 177 KiB |
BIN
demo/screenshots/Tab-Me-Profile.png
Normal file
After Width: | Height: | Size: 199 KiB |
BIN
demo/screenshots/Tab-Me-Profile_Feedback.png
Normal file
After Width: | Height: | Size: 211 KiB |
BIN
demo/screenshots/Tab-Me-Push_Bottom.png
Normal file
After Width: | Height: | Size: 236 KiB |
BIN
demo/screenshots/Tab-Me-Push_MissingServerKey.png
Normal file
After Width: | Height: | Size: 113 KiB |
BIN
demo/screenshots/Tab-Me-Push_NotAvailable.png
Normal file
After Width: | Height: | Size: 103 KiB |
BIN
demo/screenshots/Tab-Me-Push_ReEnable.png
Normal file
After Width: | Height: | Size: 248 KiB |
BIN
demo/screenshots/Tab-Me-Push_Top.png
Normal file
After Width: | Height: | Size: 249 KiB |
BIN
demo/screenshots/Tab-Me-Settings-Appearance.png
Normal file
After Width: | Height: | Size: 403 KiB |
BIN
demo/screenshots/Tab-Me-Settings-DarkTheme.png
Normal file
After Width: | Height: | Size: 344 KiB |
BIN
demo/screenshots/Tab-Me-Settings-FontSize.png
Normal file
After Width: | Height: | Size: 164 KiB |
BIN
demo/screenshots/Tab-Me-Settings-OpeningLink.png
Normal file
After Width: | Height: | Size: 356 KiB |
BIN
demo/screenshots/Tab-Me-Settings.png
Normal file
After Width: | Height: | Size: 188 KiB |
BIN
demo/screenshots/Tab-Me-Switch.png
Normal file
After Width: | Height: | Size: 169 KiB |
BIN
demo/screenshots/Tab-Me.png
Normal file
After Width: | Height: | Size: 187 KiB |
BIN
demo/screenshots/Tab-Notifications-Filter.png
Normal file
After Width: | Height: | Size: 174 KiB |
BIN
demo/screenshots/Tab-Notifications.png
Normal file
After Width: | Height: | Size: 274 KiB |
BIN
demo/screenshots/Tab-Public.png
Normal file
After Width: | Height: | Size: 293 KiB |
BIN
demo/screenshots/Tab-Shared-Account.png
Normal file
After Width: | Height: | Size: 609 KiB |
BIN
demo/screenshots/Tab-Shared-AccountInLists.png
Normal file
After Width: | Height: | Size: 104 KiB |
BIN
demo/screenshots/Tab-Shared-Attachments.png
Normal file
After Width: | Height: | Size: 402 KiB |
BIN
demo/screenshots/Tab-Shared-Hashtag.png
Normal file
After Width: | Height: | Size: 339 KiB |
BIN
demo/screenshots/Tab-Shared-History.png
Normal file
After Width: | Height: | Size: 109 KiB |
BIN
demo/screenshots/Tab-Shared-Search.png
Normal file
After Width: | Height: | Size: 198 KiB |
BIN
demo/screenshots/Tab-Shared-Toot.png
Normal file
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(
|
||||
|