Merge remote-tracking branch 'origin/main' into next/base

* origin/main: (39 commits)
  Revert "fix quote & feed padding not being pressable (#7694)" (#7733)
  Nightly source-language update
  Add dev mode for easy copying of at:// URIs and DIDs (#7723)
  Improved search language select (#7591)
  Improved search page (#7590)
  Animate drawer menu on mobile web (#7711)
  Special treatment for recommended starter packs (#7706)
  invert new postonboarding gate (#7695)
  Animate dropdown menus (#7704)
  Better animations for dialogs, animate web composer (#7703)
  fix quote & feed padding not being pressable (#7694)
  ungate trending (#7696)
  run prettier (#7727)
  Nightly source-language update
  Add deploy key to nightly commit (#7722)
  [APP-1031] Add new followerRule to threadgate settings (#7681)
  Fix bug in GH action nightly-update-source-languages.yaml
  More i18n process updates (#7720)
  Run intl:extract on english to see if crowdin picks up on the changes
  Refine accessibilityHint (#7554)
  ...
This commit is contained in:
Eric Bailey
2025-02-13 11:19:59 -06:00
97 changed files with 14126 additions and 4505 deletions
@@ -0,0 +1,38 @@
name: Nightly Update Source Languages
on:
schedule:
- cron: '0 2 * * *' # run at 2 AM UTC
workflow_dispatch:
jobs:
extract-languages:
name: Nightly Update Source Languages
runs-on: ubuntu-latest
permissions:
# Give the default GITHUB_TOKEN write permission to commit and push the
# added or changed files to the repository.
contents: write
steps:
- name: Check out Git repository
uses: actions/checkout@v3
with:
ssh-key: ${{secrets.GH_ACTION_DEPLOY_KEY}}
- name: Install node
uses: actions/setup-node@v4
with:
node-version-file: .nvmrc
- name: Yarn install
uses: Wandalen/wretry.action@master
with:
command: yarn --frozen-lockfile
attempt_limit: 3
attempt_delay: 2000
- name: Extract language strings
run: yarn intl:extract
- name: Create commit
uses: stefanzweifel/git-auto-commit-action@v5
with:
commit_message: Nightly source-language update
file_pattern: ./src/locale/locales/en/messages.po
+42
View File
@@ -0,0 +1,42 @@
import {IsValidHandle, validateServiceHandle} from '#/lib/strings/handles'
describe('handle validation', () => {
const valid = [
['ali', 'bsky.social'],
['alice', 'bsky.social'],
['a-lice', 'bsky.social'],
['a-----lice', 'bsky.social'],
['123', 'bsky.social'],
['123456789012345678', 'bsky.social'],
['alice', 'custom-pds.com'],
['alice', 'my-custom-pds-with-long-name.social'],
['123456789012345678', 'my-custom-pds-with-long-name.social'],
]
it.each(valid)(`should be valid: %s.%s`, (handle, service) => {
const result = validateServiceHandle(handle, service)
expect(result.overall).toEqual(true)
})
const invalid = [
['al', 'bsky.social', 'frontLength'],
['-alice', 'bsky.social', 'hyphenStartOrEnd'],
['alice-', 'bsky.social', 'hyphenStartOrEnd'],
['%%%', 'bsky.social', 'handleChars'],
['1234567890123456789', 'bsky.social', 'frontLength'],
[
'1234567890123456789',
'my-custom-pds-with-long-name.social',
'frontLength',
],
['al', 'my-custom-pds-with-long-name.social', 'frontLength'],
['a'.repeat(300), 'toolong.com', 'totalLength'],
] satisfies [string, string, keyof IsValidHandle][]
it.each(invalid)(
`should be invalid: %s.%s due to %s`,
(handle, service, expectedError) => {
const result = validateServiceHandle(handle, service)
expect(result.overall).toEqual(false)
expect(result[expectedError]).toEqual(false)
},
)
})
+1
View File
@@ -86,6 +86,7 @@ module.exports = function (config) {
'gl', 'gl',
'hi', 'hi',
'hu', 'hu',
'ia',
'id', 'id',
'it', 'it',
'ja', 'ja',
@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24"><path fill="#000" fill-rule="evenodd" d="M11.293 4.293a1 1 0 0 1 1.414 0l4 4a1 1 0 0 1-1.414 1.414L12 6.414 8.707 9.707a1 1 0 0 1-1.414-1.414l4-4Zm-4 10a1 1 0 0 1 1.414 0L12 17.586l3.293-3.293a1 1 0 0 1 1.414 1.414l-4 4a1 1 0 0 1-1.414 0l-4-4a1 1 0 0 1 0-1.414Z" clip-rule="evenodd"/></svg>

After

Width:  |  Height:  |  Size: 363 B

@@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24"><path fill="#000" fill-rule="evenodd" d="M7 2a1 1 0 0 1 1 1v2a1 1 0 0 1-2 0V3a1 1 0 0 1 1-1Zm4 0a1 1 0 0 1 1 1v2a1 1 0 1 1-2 0V3a1 1 0 0 1 1-1Zm4 0a1 1 0 0 1 1 1v2a1 1 0 1 1-2 0V3a1 1 0 0 1 1-1ZM4 9a2 2 0 0 1 2-2h10a2 2 0 0 1 2 2h.5a3.5 3.5 0 1 1 0 7H18v4a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2V9Zm12 0H6v11h10V9Zm2 5h.5a1.5 1.5 0 0 0 0-3H18v3Z" clip-rule="evenodd"/></svg>

Before

Width:  |  Height:  |  Size: 437 B

@@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24"><path fill="#000" fill-rule="evenodd" d="M6.5 4.999Zm0 0a.1.1 0 0 1-.016.024.2.2 0 0 1-.152.043q.086.014.168.032V7.5a1 1 0 0 1-.33.742c-.543.49-.917 1.176-1.23 2.036a1 1 0 0 1-.94.657H3V14h1a1 1 0 0 1 .866.5c.436.754.879 1.195 1.637 1.636A1 1 0 0 1 7 17v2h2a2 2 0 0 1 2-2h2a2 2 0 0 1 2 2h2v-2.537a1 1 0 0 1 .332-.744A4.98 4.98 0 0 0 19 11.999 5 5 0 0 0 14 7H9.474a1 1 0 0 1-.893-.55v-.001l-.001-.002-.005-.008L9.474 6l-.9.438h.001v.002l.002.001.001.003.002.003v.003a2.6 2.6 0 0 0-.443-.538c-.319-.298-.839-.648-1.637-.814V5Zm2.082 1.452ZM9.5 4.447c.211.196.379.387.508.553H14a7 7 0 0 1 6.72 8.96 1.003 1.003 0 0 0 1.146-1.46 1 1 0 1 1 1.731-1 3 3 0 0 1-3.714 4.286A7 7 0 0 1 19 16.888V19a2 2 0 0 1-2 2h-2a2 2 0 0 1-2-2h-2a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2v-1.45A5.8 5.8 0 0 1 3.448 16H3a2 2 0 0 1-2-2v-3.065a2 2 0 0 1 2-2h.324c.286-.649.657-1.291 1.176-1.852V5c0-1.047.89-2.12 2.161-1.907 1.33.223 2.248.805 2.839 1.354ZM8.25 12a1.25 1.25 0 1 0 0-2.5 1.25 1.25 0 0 0 0 2.5Z" clip-rule="evenodd"/></svg>

Before

Width:  |  Height:  |  Size: 1.0 KiB

@@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24"><path fill="#000" fill-rule="evenodd" d="M12 4c0-1.012.894-2.187 2.237-1.846a5.002 5.002 0 0 1 3.218 7.119 4 4 0 0 1 2.345 4.976A3.501 3.501 0 0 1 18.5 21h-13a3.5 3.5 0 0 1-1.3-6.75 4 4 0 0 1 2.052-4.848A4 4 0 0 1 10 4h2.001Zm-4.187 7.009A2 2 0 0 0 6 13c0 .366.098.706.271 1H12a1 1 0 1 1 0 2H5.5a1.5 1.5 0 0 0 0 3h13a1.5 1.5 0 1 0 0-3H17a1 1 0 1 1 0-2h.729A1.96 1.96 0 0 0 18 13a2 2 0 0 0-2-2h-2a1 1 0 1 1 0-2h1.236a3.002 3.002 0 0 0-1.243-4.832A2 2 0 0 1 12 6h-2a2 2 0 0 0-1.728 3.009H9a1 1 0 0 1 0 2H7.813Z" clip-rule="evenodd"/></svg>

Before

Width:  |  Height:  |  Size: 610 B

+20
View File
@@ -0,0 +1,20 @@
{
"project_id": "664276",
"base_path": ".",
"preserve_hierarchy": true,
"files": [
{
"source": "/src/locale/locales/en/messages.po",
"translation": "/src/locale/locales/%two_letters_code%/messages.po",
"languages_mapping": {
"two_letters_code": {
"pt-BR": "pt-BR",
"en-GB": "en-GB",
"zh-CN": "zh-CN",
"zh-TW": "zh-TW",
"zh-HK": "zh-HK"
}
}
}
]
}
+57 -7
View File
@@ -3,9 +3,64 @@
We want the official Bluesky app to be supported in as many languages as possible. If you want to help us translate the app, please open a PR or issue on the [Bluesky app repo on GitHub](https://github.com/bluesky-social/social-app) We want the official Bluesky app to be supported in as many languages as possible. If you want to help us translate the app, please open a PR or issue on the [Bluesky app repo on GitHub](https://github.com/bluesky-social/social-app)
## Tools ## Tools
We are using Lingui to manage translations. You can find the documentation [here](https://lingui.dev/).
- We use Lingui to implement translations. You can find the documentation [here](https://lingui.dev/).
- We use Crowdin to manage translations.
- Bluesky Crowdin: https://crowdin.com/project/bluesky-social
- Introduction to Crowdin: https://support.crowdin.com/for-translators/
## Translators
Much of the app is translated by community contributions. (We <3 our translators!) If you want to participate in the translation of the app, read this section.
### Using Crowdin
[Crowdin](https://crowdin.com/project/bluesky-social) is our primary tool for managing translations. There are two roles:
- **Proof-readers**. Can create new translations and approve submitted translations.
- **Translators**. Can create new translations.
All translations must be approved by proof-readers before they are accepted into the app.
### Using other platforms
You may contribute PRs separately from Crowdin, however we strongly recommend using Crowdin to avoid conflicts.
### Code of conduct on Crowdin
Please treat everyone with respect. Proof-readers are given final say on translations. Translators who frequently come into conflict with other translators, or who contribute noticably incorrect translations, will have their membership to the Crowdin project revoked.
### Adding a new language
Create a new [Crowdin discussion](https://crowdin.com/project/bluesky-social/discussions) or [GitHub issue](https://github.com/bluesky-social/social-app/issues) requesting the new language be added to the project.
Please only request a new language when you are certain you will be able to contribute a substantive portion of translations for the language.
## Maintainers
Install the [Crowdin CLI](https://crowdin.github.io/crowdin-cli/). You will need to [configure your API token](https://crowdin.github.io/crowdin-cli/configuration) to access the project.
### English source-file sync with Crowdin
Every night, a GitHub action will run `yarn intl:extract` to update the english `messages.po` file. This will be automatically synced with Crowdin. Crowdin should notify all subscribed users of new translations.
### Release process
1. Pull main and create a branch.
1. Run `yarn intl:pull` to fetch all translation updates from Crowdin.
1. Create a PR, ensure the translations all look correct, and merge.
1. If needed:
1. Merge all approved translation PRs (contributions from outside crowdin).
1. Run `yarn intl:push` to sync Crowdin with the state of the repo.
### Testing the translations in Crowdin
You can run `yarn intl:pull` to pull the currently-approved translations from Crowdin.
## Developers
### Adding new strings ### Adding new strings
When adding a new string, do it as follows: When adding a new string, do it as follows:
```jsx ```jsx
// Before // Before
@@ -61,6 +116,7 @@ So the workflow is as follows:
6. Enjoy translated app! 6. Enjoy translated app!
### Common pitfalls ### Common pitfalls
These pitfalls are memoization pitfalls that will cause the components to not re-render when the locale is changed -- causing stale translations to be shown. These pitfalls are memoization pitfalls that will cause the components to not re-render when the locale is changed -- causing stale translations to be shown.
```jsx ```jsx
@@ -111,9 +167,3 @@ export function Welcome() {
return <div>{welcome}</div>; return <div>{welcome}</div>;
} }
``` ```
### Credits
Please check each individual `messages.po` file for the credits of the translators. We are very grateful for their help!
If you would like to translate the Bluesky app into your language, please open a PR or issue on this repo.
+1
View File
@@ -17,6 +17,7 @@ module.exports = {
'gl', 'gl',
'hi', 'hi',
'hu', 'hu',
'ia',
'id', 'id',
'it', 'it',
'ja', 'ja',
+9
View File
@@ -70,6 +70,7 @@ import {MessagesScreen} from '#/screens/Messages/ChatList'
import {MessagesConversationScreen} from '#/screens/Messages/Conversation' import {MessagesConversationScreen} from '#/screens/Messages/Conversation'
import {MessagesSettingsScreen} from '#/screens/Messages/Settings' import {MessagesSettingsScreen} from '#/screens/Messages/Settings'
import {ModerationScreen} from '#/screens/Moderation' import {ModerationScreen} from '#/screens/Moderation'
import {Screen as ModerationInteractionSettings} from '#/screens/ModerationInteractionSettings'
import {PostLikedByScreen} from '#/screens/Post/PostLikedBy' import {PostLikedByScreen} from '#/screens/Post/PostLikedBy'
import {PostQuotesScreen} from '#/screens/Post/PostQuotes' import {PostQuotesScreen} from '#/screens/Post/PostQuotes'
import {PostRepostedByScreen} from '#/screens/Post/PostRepostedBy' import {PostRepostedByScreen} from '#/screens/Post/PostRepostedBy'
@@ -155,6 +156,14 @@ function commonScreens(Stack: typeof HomeTab, unreadCountLabel?: string) {
getComponent={() => ModerationBlockedAccounts} getComponent={() => ModerationBlockedAccounts}
options={{title: title(msg`Blocked Accounts`), requireAuth: true}} options={{title: title(msg`Blocked Accounts`), requireAuth: true}}
/> />
<Stack.Screen
name="ModerationInteractionSettings"
getComponent={() => ModerationInteractionSettings}
options={{
title: title(msg`Post Interaction Settings`),
requireAuth: true,
}}
/>
<Stack.Screen <Stack.Screen
name="Settings" name="Settings"
getComponent={() => SettingsScreen} getComponent={() => SettingsScreen}
+35 -2
View File
@@ -50,6 +50,12 @@ export const atoms = {
overflow_hidden: { overflow_hidden: {
overflow: 'hidden', overflow: 'hidden',
}, },
/**
* @platform web
*/
overflow_auto: web({
overflow: 'auto',
}),
/* /*
* Width * Width
@@ -68,7 +74,6 @@ export const atoms = {
* Used for the outermost components on screens, to ensure that they can fill * Used for the outermost components on screens, to ensure that they can fill
* the screen and extend beyond. * the screen and extend beyond.
*/ */
// @ts-ignore - web only minHeight string
util_screen_outer: [ util_screen_outer: [
web({ web({
minHeight: '100vh', minHeight: '100vh',
@@ -76,7 +81,7 @@ export const atoms = {
native({ native({
height: '100%', height: '100%',
}), }),
] as ViewStyle, ] as StyleProp<ViewStyle>,
/* /*
* Theme-independent bg colors * Theme-independent bg colors
@@ -965,6 +970,34 @@ export const atoms = {
transitionDelay: '50ms', transitionDelay: '50ms',
}), }),
/*
* Animaations
*/
fade_in: web({
animation: 'fadeIn ease-out 0.15s',
}),
fade_out: web({
animation: 'fadeOut ease-out 0.15s',
}),
zoom_in: web({
animation: 'zoomIn ease-out 0.1s',
}),
zoom_out: web({
animation: 'zoomOut ease-out 0.1s',
}),
slide_in_left: web({
// exponential easing function
animation: 'slideInLeft cubic-bezier(0.16, 1, 0.3, 1) 0.5s',
}),
slide_out_left: web({
animation: 'slideOutLeft ease-in 0.15s',
animationFillMode: 'forwards',
}),
// special composite animation for dialogs
zoom_fade_in: web({
animation: 'zoomIn ease-out 0.1s, fadeIn ease-out 0.1s',
}),
/** /**
* {@link Layout.SCROLLBAR_OFFSET} * {@link Layout.SCROLLBAR_OFFSET}
*/ */
+10 -14
View File
@@ -15,6 +15,7 @@ import {FocusScope} from '@radix-ui/react-focus-scope'
import {RemoveScrollBar} from 'react-remove-scroll-bar' import {RemoveScrollBar} from 'react-remove-scroll-bar'
import {logger} from '#/logger' import {logger} from '#/logger'
import {useA11y} from '#/state/a11y'
import {useDialogStateControlContext} from '#/state/dialogs' import {useDialogStateControlContext} from '#/state/dialogs'
import {atoms as a, flatten, useBreakpoints, useTheme, web} from '#/alf' import {atoms as a, flatten, useBreakpoints, useTheme, web} from '#/alf'
import {Button, ButtonIcon} from '#/components/Button' import {Button, ButtonIcon} from '#/components/Button'
@@ -152,6 +153,7 @@ export function Inner({
const t = useTheme() const t = useTheme()
const {close} = React.useContext(Context) const {close} = React.useContext(Context)
const {gtMobile} = useBreakpoints() const {gtMobile} = useBreakpoints()
const {reduceMotionEnabled} = useA11y()
useFocusGuards() useFocusGuards()
return ( return (
<FocusScope loop asChild trapped> <FocusScope loop asChild trapped>
@@ -161,7 +163,7 @@ export function Inner({
aria-label={label} aria-label={label}
aria-labelledby={accessibilityLabelledBy} aria-labelledby={accessibilityLabelledBy}
aria-describedby={accessibilityDescribedBy} aria-describedby={accessibilityDescribedBy}
// @ts-ignore web only -prf // @ts-expect-error web only -prf
onClick={stopPropagation} onClick={stopPropagation}
onStartShouldSetResponder={_ => true} onStartShouldSetResponder={_ => true}
onTouchEnd={stopPropagation} onTouchEnd={stopPropagation}
@@ -177,10 +179,9 @@ export function Inner({
shadowColor: t.palette.black, shadowColor: t.palette.black,
shadowOpacity: t.name === 'light' ? 0.1 : 0.4, shadowOpacity: t.name === 'light' ? 0.1 : 0.4,
shadowRadius: 30, shadowRadius: 30,
// @ts-ignore web only
animation: 'fadeIn ease-out 0.1s',
}, },
flatten(style), !reduceMotionEnabled && a.zoom_fade_in,
style,
])}> ])}>
<DismissableLayer <DismissableLayer
onInteractOutside={preventDefault} onInteractOutside={preventDefault}
@@ -216,7 +217,7 @@ export const InnerFlatList = React.forwardRef<
style={[ style={[
a.overflow_hidden, a.overflow_hidden,
a.px_0, a.px_0,
// @ts-ignore web only -sfn // @ts-expect-error web only -sfn
{maxHeight: 'calc(-36px + 100vh)'}, {maxHeight: 'calc(-36px + 100vh)'},
webInnerStyle, webInnerStyle,
]} ]}
@@ -262,20 +263,15 @@ export function Handle() {
function Backdrop() { function Backdrop() {
const t = useTheme() const t = useTheme()
const {reduceMotionEnabled} = useA11y()
return ( return (
<View <View style={{opacity: 0.8}}>
style={{
opacity: 0.8,
}}>
<View <View
style={[ style={[
a.fixed, a.fixed,
a.inset_0, a.inset_0,
{ {backgroundColor: t.palette.black},
backgroundColor: t.palette.black, !reduceMotionEnabled && a.fade_in,
// @ts-ignore web only
animation: 'fadeIn ease-out 0.15s',
},
]} ]}
/> />
</View> </View>
+2 -1
View File
@@ -1,5 +1,5 @@
import {createContext, useCallback, useContext} from 'react' import {createContext, useCallback, useContext} from 'react'
import {GestureResponderEvent, View} from 'react-native' import {GestureResponderEvent, Keyboard, View} from 'react-native'
import {msg} from '@lingui/macro' import {msg} from '@lingui/macro'
import {useLingui} from '@lingui/react' import {useLingui} from '@lingui/react'
import {useNavigation} from '@react-navigation/native' import {useNavigation} from '@react-navigation/native'
@@ -140,6 +140,7 @@ export function MenuButton() {
const {gtMobile} = useBreakpoints() const {gtMobile} = useBreakpoints()
const onPress = useCallback(() => { const onPress = useCallback(() => {
Keyboard.dismiss()
setDrawerOpen(true) setDrawerOpen(true)
}, [setDrawerOpen]) }, [setDrawerOpen])
+12 -4
View File
@@ -4,6 +4,7 @@ import {msg} from '@lingui/macro'
import {useLingui} from '@lingui/react' import {useLingui} from '@lingui/react'
import * as DropdownMenu from '@radix-ui/react-dropdown-menu' import * as DropdownMenu from '@radix-ui/react-dropdown-menu'
import {useA11y} from '#/state/a11y'
import {atoms as a, flatten, useTheme, web} from '#/alf' import {atoms as a, flatten, useTheme, web} from '#/alf'
import * as Dialog from '#/components/Dialog' import * as Dialog from '#/components/Dialog'
import {useInteractionState} from '#/components/hooks/useInteractionState' import {useInteractionState} from '#/components/hooks/useInteractionState'
@@ -177,10 +178,16 @@ export function Outer({
style?: StyleProp<ViewStyle> style?: StyleProp<ViewStyle>
}>) { }>) {
const t = useTheme() const t = useTheme()
const {reduceMotionEnabled} = useA11y()
return ( return (
<DropdownMenu.Portal> <DropdownMenu.Portal>
<DropdownMenu.Content sideOffset={5} loop aria-label="Test"> <DropdownMenu.Content
sideOffset={5}
collisionPadding={{left: 5, right: 5, bottom: 5}}
loop
aria-label="Test"
className="dropdown-menu-transform-origin">
<View <View
style={[ style={[
a.rounded_sm, a.rounded_sm,
@@ -189,6 +196,8 @@ export function Outer({
t.name === 'light' ? t.atoms.bg : t.atoms.bg_contrast_25, t.name === 'light' ? t.atoms.bg : t.atoms.bg_contrast_25,
t.atoms.shadow_md, t.atoms.shadow_md,
t.atoms.border_contrast_low, t.atoms.border_contrast_low,
a.overflow_auto,
!reduceMotionEnabled && a.zoom_fade_in,
style, style,
]}> ]}>
{children} {children}
@@ -373,9 +382,8 @@ export function Divider() {
style={flatten([ style={flatten([
a.my_xs, a.my_xs,
t.atoms.bg_contrast_100, t.atoms.bg_contrast_100,
{ a.flex_shrink_0,
height: 1, {height: 1},
},
])} ])}
/> />
) )
@@ -762,7 +762,7 @@ function SearchInput({
autoComplete="off" autoComplete="off"
autoCapitalize="none" autoCapitalize="none"
accessibilityLabel={_(msg`Search profiles`)} accessibilityLabel={_(msg`Search profiles`)}
accessibilityHint={_(msg`Search profiles`)} accessibilityHint={_(msg`Searches for profiles`)}
/> />
</View> </View>
) )
@@ -12,7 +12,7 @@ import {precacheResolvedUri} from '#/state/queries/resolve-uri'
import {precacheStarterPack} from '#/state/queries/starter-packs' import {precacheStarterPack} from '#/state/queries/starter-packs'
import {useSession} from '#/state/session' import {useSession} from '#/state/session'
import {atoms as a, useTheme} from '#/alf' import {atoms as a, useTheme} from '#/alf'
import {StarterPack} from '#/components/icons/StarterPack' import {StarterPack as StarterPackIcon} from '#/components/icons/StarterPack'
import {Link as BaseLink, LinkProps as BaseLinkProps} from '#/components/Link' import {Link as BaseLink, LinkProps as BaseLinkProps} from '#/components/Link'
import {Text} from '#/components/Typography' import {Text} from '#/components/Typography'
import * as bsky from '#/types/bsky' import * as bsky from '#/types/bsky'
@@ -70,7 +70,7 @@ export function Card({
return ( return (
<View style={[a.w_full, a.gap_md]}> <View style={[a.w_full, a.gap_md]}>
<View style={[a.flex_row, a.gap_sm, a.w_full]}> <View style={[a.flex_row, a.gap_sm, a.w_full]}>
{!noIcon ? <StarterPack width={40} gradient="sky" /> : null} {!noIcon ? <StarterPackIcon width={40} gradient="sky" /> : null}
<View style={[a.flex_1]}> <View style={[a.flex_1]}>
<Text <Text
emoji emoji
+23 -13
View File
@@ -12,6 +12,7 @@ import {PressableScale} from '#/lib/custom-animations/PressableScale'
// import {UserAvatar} from '#/view/com/util/UserAvatar' // import {UserAvatar} from '#/view/com/util/UserAvatar'
import type {TrendingTopic} from '#/state/queries/trending/useTrendingTopics' import type {TrendingTopic} from '#/state/queries/trending/useTrendingTopics'
import {atoms as a, native, useTheme, ViewStyleProp} from '#/alf' import {atoms as a, native, useTheme, ViewStyleProp} from '#/alf'
import {StarterPack as StarterPackIcon} from '#/components/icons/StarterPack'
import {Link as InternalLink, LinkProps} from '#/components/Link' import {Link as InternalLink, LinkProps} from '#/components/Link'
import {Text} from '#/components/Typography' import {Text} from '#/components/Typography'
@@ -24,9 +25,8 @@ export function TrendingTopic({
const topic = useTopic(raw) const topic = useTopic(raw)
const isSmall = size === 'small' const isSmall = size === 'small'
// const hasAvi = topic.type === 'feed' || topic.type === 'profile' const hasIcon = topic.type === 'starter-pack' && !isSmall
// const aviSize = isSmall ? 16 : 20 const iconSize = 20
// const iconSize = isSmall ? 16 : 20
return ( return (
<View <View
@@ -45,15 +45,17 @@ export function TrendingTopic({
}, },
] ]
: [a.py_sm, a.px_md], : [a.py_sm, a.px_md],
hasIcon && {gap: 6},
style, style,
/*
{
padding: 6,
gap: hasAvi ? 4 : 2,
},
a.pr_md,
*/
]}> ]}>
{hasIcon && topic.type === 'starter-pack' && (
<StarterPackIcon
gradient="sky"
width={iconSize}
style={{marginLeft: -3, marginVertical: -1}}
/>
)}
{/* {/*
<View <View
style={[ style={[
@@ -62,8 +64,8 @@ export function TrendingTopic({
a.rounded_full, a.rounded_full,
a.overflow_hidden, a.overflow_hidden,
{ {
width: aviSize, width: iconSize,
height: aviSize, height: iconSize,
}, },
]}> ]}>
{topic.type === 'tag' ? ( {topic.type === 'tag' ? (
@@ -151,7 +153,7 @@ export function TrendingTopicLink({
type ParsedTrendingTopic = type ParsedTrendingTopic =
| { | {
type: 'topic' | 'tag' | 'unknown' type: 'topic' | 'tag' | 'starter-pack' | 'unknown'
label: string label: string
displayName: string displayName: string
url: string url: string
@@ -187,6 +189,14 @@ export function useTopic(raw: TrendingTopic): ParsedTrendingTopic {
uri: undefined, uri: undefined,
url: link, url: link,
} }
} else if (link.startsWith('/starter-pack')) {
return {
type: 'starter-pack',
label: _(msg`Browse starter pack ${displayName}`),
displayName,
uri: undefined,
url: link,
}
} }
/* /*
+1 -1
View File
@@ -118,7 +118,7 @@ export function VideoPostCard({
return ( return (
<Link <Link
accessibilityHint={_(msg`Tap to view video in immersive mode.`)} accessibilityHint={_(msg`Views video in immersive mode`)}
label={_(msg`Video from ${author.handle}: ${text}`)} label={_(msg`Video from ${author.handle}: ${text}`)}
to={{ to={{
screen: 'VideoFeed', screen: 'VideoFeed',
+19 -1
View File
@@ -213,7 +213,12 @@ function Rules({
a.flex_wrap, a.flex_wrap,
t.atoms.text_contrast_medium, t.atoms.text_contrast_medium,
]}> ]}>
{settings[0].type === 'everybody' ? ( {settings.length === 0 ? (
<Trans>
This post has an unknown type of threadgate on it. Your app may be
out of date.
</Trans>
) : settings[0].type === 'everybody' ? (
<Trans>Everybody can reply to this post.</Trans> <Trans>Everybody can reply to this post.</Trans>
) : settings[0].type === 'nobody' ? ( ) : settings[0].type === 'nobody' ? (
<Trans>Replies to this post are disabled.</Trans> <Trans>Replies to this post are disabled.</Trans>
@@ -257,6 +262,19 @@ function Rule({
if (rule.type === 'mention') { if (rule.type === 'mention') {
return <Trans>mentioned users</Trans> return <Trans>mentioned users</Trans>
} }
if (rule.type === 'followers') {
return (
<Trans>
users following{' '}
<InlineLinkText
label={`@${post.author.handle}`}
to={makeProfileLink(post.author)}
style={[a.text_sm, a.leading_snug]}>
@{post.author.handle}
</InlineLinkText>
</Trans>
)
}
if (rule.type === 'following') { if (rule.type === 'following') {
return ( return (
<Trans> <Trans>
@@ -40,6 +40,7 @@ import {Loader} from '#/components/Loader'
import {Text} from '#/components/Typography' import {Text} from '#/components/Typography'
export type PostInteractionSettingsFormProps = { export type PostInteractionSettingsFormProps = {
canSave?: boolean
onSave: () => void onSave: () => void
isSaving?: boolean isSaving?: boolean
@@ -58,20 +59,53 @@ export function PostInteractionSettingsControlledDialog({
}: PostInteractionSettingsFormProps & { }: PostInteractionSettingsFormProps & {
control: Dialog.DialogControlProps control: Dialog.DialogControlProps
}) { }) {
const t = useTheme()
const {_} = useLingui() const {_} = useLingui()
return ( return (
<Dialog.Outer control={control}> <Dialog.Outer control={control}>
<Dialog.Handle /> <Dialog.Handle />
<Dialog.ScrollableInner <Dialog.ScrollableInner
label={_(msg`Edit post interaction settings`)} label={_(msg`Edit post interaction settings`)}
style={[{maxWidth: 500}, a.w_full]}> style={[{maxWidth: 500}, a.w_full]}>
<View style={[a.gap_md]}>
<Header />
<PostInteractionSettingsForm {...rest} /> <PostInteractionSettingsForm {...rest} />
<Text
style={[
a.pt_sm,
a.text_sm,
a.leading_snug,
t.atoms.text_contrast_medium,
]}>
<Trans>
You can set default interaction settings in{' '}
<Text style={[a.font_bold, t.atoms.text_contrast_medium]}>
Settings &rarr; Moderation &rarr; Interaction settings.
</Text>
</Trans>
</Text>
</View>
<Dialog.Close /> <Dialog.Close />
</Dialog.ScrollableInner> </Dialog.ScrollableInner>
</Dialog.Outer> </Dialog.Outer>
) )
} }
export function Header() {
return (
<View style={[a.gap_md, a.pb_sm]}>
<Text style={[a.text_2xl, a.font_bold]}>
<Trans>Post interaction settings</Trans>
</Text>
<Text style={[a.text_md, a.pb_xs]}>
<Trans>Customize who can interact with this post.</Trans>
</Text>
<Divider />
</View>
)
}
export type PostInteractionSettingsDialogProps = { export type PostInteractionSettingsDialogProps = {
control: Dialog.DialogControlProps control: Dialog.DialogControlProps
/** /**
@@ -203,6 +237,9 @@ export function PostInteractionSettingsDialogControlledInner(
<Dialog.ScrollableInner <Dialog.ScrollableInner
label={_(msg`Edit post interaction settings`)} label={_(msg`Edit post interaction settings`)}
style={[{maxWidth: 500}, a.w_full]}> style={[{maxWidth: 500}, a.w_full]}>
<View style={[a.gap_md]}>
<Header />
{isLoading ? ( {isLoading ? (
<View style={[a.flex_1, a.py_4xl, a.align_center, a.justify_center]}> <View style={[a.flex_1, a.py_4xl, a.align_center, a.justify_center]}>
<Loader size="xl" /> <Loader size="xl" />
@@ -218,11 +255,13 @@ export function PostInteractionSettingsDialogControlledInner(
onChangeThreadgateAllowUISettings={setEditedAllowUISettings} onChangeThreadgateAllowUISettings={setEditedAllowUISettings}
/> />
)} )}
</View>
</Dialog.ScrollableInner> </Dialog.ScrollableInner>
) )
} }
export function PostInteractionSettingsForm({ export function PostInteractionSettingsForm({
canSave = true,
onSave, onSave,
isSaving, isSaving,
postgate, postgate,
@@ -283,17 +322,7 @@ export function PostInteractionSettingsForm({
return ( return (
<View> <View>
<View style={[a.flex_1, a.gap_md]}> <View style={[a.flex_1, a.gap_md]}>
<Text style={[a.text_2xl, a.font_bold]}>
<Trans>Post interaction settings</Trans>
</Text>
<View style={[a.gap_lg]}> <View style={[a.gap_lg]}>
<Text style={[a.text_md]}>
<Trans>Customize who can interact with this post.</Trans>
</Text>
<Divider />
<View style={[a.gap_sm]}> <View style={[a.gap_sm]}>
<Text style={[a.font_bold, a.text_lg]}> <Text style={[a.font_bold, a.text_lg]}>
<Trans>Quote settings</Trans> <Trans>Quote settings</Trans>
@@ -400,7 +429,7 @@ export function PostInteractionSettingsForm({
disabled={replySettingsDisabled} disabled={replySettingsDisabled}
/> />
<Selectable <Selectable
label={_(msg`Followed users`)} label={_(msg`Users you follow`)}
isSelected={ isSelected={
!!threadgateAllowUISettings.find( !!threadgateAllowUISettings.find(
v => v.type === 'following', v => v.type === 'following',
@@ -409,6 +438,16 @@ export function PostInteractionSettingsForm({
onPress={() => onPressAudience({type: 'following'})} onPress={() => onPressAudience({type: 'following'})}
disabled={replySettingsDisabled} disabled={replySettingsDisabled}
/> />
<Selectable
label={_(msg`Your followers`)}
isSelected={
!!threadgateAllowUISettings.find(
v => v.type === 'followers',
)
}
onPress={() => onPressAudience({type: 'followers'})}
disabled={replySettingsDisabled}
/>
{lists && lists.length > 0 {lists && lists.length > 0
? lists.map(list => ( ? lists.map(list => (
<Selectable <Selectable
@@ -435,6 +474,7 @@ export function PostInteractionSettingsForm({
</View> </View>
<Button <Button
disabled={!canSave || isSaving}
label={_(msg`Save`)} label={_(msg`Save`)}
onPress={onSave} onPress={onSave}
color="primary" color="primary"
@@ -506,7 +506,7 @@ function SearchInput({
autoCapitalize="none" autoCapitalize="none"
autoFocus autoFocus
accessibilityLabel={_(msg`Search profiles`)} accessibilityLabel={_(msg`Search profiles`)}
accessibilityHint={_(msg`Search profiles`)} accessibilityHint={_(msg`Searches for profiles`)}
/> />
</View> </View>
) )
+2 -2
View File
@@ -47,7 +47,7 @@ export function HostingProvider({
</Text> </Text>
<Button <Button
label={toNiceDomain(serviceUrl)} label={toNiceDomain(serviceUrl)}
accessibilityHint={_(msg`Press to change hosting provider`)} accessibilityHint={_(msg`Changes hosting provider`)}
onPress={onPressSelectService} onPress={onPressSelectService}
variant="ghost" variant="ghost"
color="secondary" color="secondary"
@@ -63,7 +63,7 @@ export function HostingProvider({
<Button <Button
testID="selectServiceButton" testID="selectServiceButton"
label={toNiceDomain(serviceUrl)} label={toNiceDomain(serviceUrl)}
accessibilityHint={_(msg`Press to change hosting provider`)} accessibilityHint={_(msg`Changes hosting provider`)}
variant="solid" variant="solid"
color="secondary" color="secondary"
style={[ style={[
+1 -1
View File
@@ -226,6 +226,7 @@ export function createInput(Component: typeof TextInput) {
<> <>
<Component <Component
accessibilityHint={undefined} accessibilityHint={undefined}
hitSlop={HITSLOP_20}
{...rest} {...rest}
accessibilityLabel={label} accessibilityLabel={label}
ref={refs} ref={refs}
@@ -242,7 +243,6 @@ export function createInput(Component: typeof TextInput) {
placeholder={placeholder || label} placeholder={placeholder || label}
placeholderTextColor={t.palette.contrast_500} placeholderTextColor={t.palette.contrast_500}
keyboardAppearance={t.name === 'light' ? 'light' : 'dark'} keyboardAppearance={t.name === 'light' ? 'light' : 'dark'}
hitSlop={HITSLOP_20}
style={flattened} style={flattened}
/> />
+1
View File
@@ -65,6 +65,7 @@ const locales: Record<AppLanguage, Locale | undefined> = {
gl, gl,
hi, hi,
hu, hu,
ia: undefined,
id, id,
it, it,
ja, ja,
+4
View File
@@ -15,3 +15,7 @@ export const ChevronTop_Stroke2_Corner0_Rounded = createSinglePathSVG({
export const ChevronBottom_Stroke2_Corner0_Rounded = createSinglePathSVG({ export const ChevronBottom_Stroke2_Corner0_Rounded = createSinglePathSVG({
path: 'M3.293 8.293a1 1 0 0 1 1.414 0L12 15.586l7.293-7.293a1 1 0 1 1 1.414 1.414l-8 8a1 1 0 0 1-1.414 0l-8-8a1 1 0 0 1 0-1.414Z', path: 'M3.293 8.293a1 1 0 0 1 1.414 0L12 15.586l7.293-7.293a1 1 0 1 1 1.414 1.414l-8 8a1 1 0 0 1-1.414 0l-8-8a1 1 0 0 1 0-1.414Z',
}) })
export const ChevronTopBottom_Stroke2_Corner0_Rounded = createSinglePathSVG({
path: 'M11.293 4.293a1 1 0 0 1 1.414 0l4 4a1 1 0 0 1-1.414 1.414L12 6.414 8.707 9.707a1 1 0 0 1-1.414-1.414l4-4Zm-4 10a1 1 0 0 1 1.414 0L12 17.586l3.293-3.293a1 1 0 0 1 1.414 1.414l-4 4a1 1 0 0 1-1.414 0l-4-4a1 1 0 0 1 0-1.414Z',
})
-5
View File
@@ -1,5 +0,0 @@
import {createSinglePathSVG} from './TEMPLATE'
export const Coffee_Stroke2_Corner0_Rounded = createSinglePathSVG({
path: 'M7 2a1 1 0 0 1 1 1v2a1 1 0 0 1-2 0V3a1 1 0 0 1 1-1Zm4 0a1 1 0 0 1 1 1v2a1 1 0 1 1-2 0V3a1 1 0 0 1 1-1Zm4 0a1 1 0 0 1 1 1v2a1 1 0 1 1-2 0V3a1 1 0 0 1 1-1ZM4 9a2 2 0 0 1 2-2h10a2 2 0 0 1 2 2h.5a3.5 3.5 0 1 1 0 7H18v4a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2V9Zm12 0H6v11h10V9Zm2 5h.5a1.5 1.5 0 0 0 0-3H18v3Z',
})
-5
View File
@@ -1,5 +0,0 @@
import {createSinglePathSVG} from './TEMPLATE'
export const PiggyBank_Stroke2_Corner0_Rounded = createSinglePathSVG({
path: 'M6.5 4.999Zm0 0a.054.054 0 0 1-.016.024.196.196 0 0 1-.152.043c.057.01.113.02.168.032V7.5a1 1 0 0 1-.33.742c-.543.49-.917 1.176-1.23 2.036a1 1 0 0 1-.94.657H3V14h1a1 1 0 0 1 .866.5c.436.754.879 1.195 1.637 1.636A1 1 0 0 1 7 17v2h2a2 2 0 0 1 2-2h2a2 2 0 0 1 2 2h2v-2.537a1 1 0 0 1 .332-.744A4.978 4.978 0 0 0 19 11.999 5 5 0 0 0 14 7H9.474a1 1 0 0 1-.893-.55v-.001l-.001-.002-.005-.008L9.474 6l-.9.438h.001v.002l.002.001.001.003.002.003v.003a2.62 2.62 0 0 0-.443-.538c-.319-.298-.839-.648-1.637-.814V5Zm2.082 1.452ZM9.5 4.447c.211.196.379.387.508.553H14a7 7 0 0 1 6.72 8.96 1.003 1.003 0 0 0 1.146-1.46 1 1 0 1 1 1.731-1 3 3 0 0 1-3.714 4.286A7.074 7.074 0 0 1 19 16.888V19a2 2 0 0 1-2 2h-2a2 2 0 0 1-2-2h-2a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2v-1.45A5.783 5.783 0 0 1 3.448 16H3a2 2 0 0 1-2-2v-3.065a2 2 0 0 1 2-2h.324c.286-.649.657-1.291 1.176-1.852V5c0-1.047.89-2.12 2.161-1.907 1.33.223 2.248.805 2.839 1.354ZM8.25 12a1.25 1.25 0 1 0 0-2.5 1.25 1.25 0 0 0 0 2.5Z',
})
-5
View File
@@ -1,5 +0,0 @@
import {createSinglePathSVG} from './TEMPLATE'
export const Poop_Stroke2_Corner0_Rounded = createSinglePathSVG({
path: 'M12 4c0-1.012.894-2.187 2.237-1.846a5.002 5.002 0 0 1 3.218 7.119 4.001 4.001 0 0 1 2.345 4.976A3.501 3.501 0 0 1 18.5 21h-13a3.5 3.5 0 0 1-1.3-6.75 4 4 0 0 1 2.052-4.848A4 4 0 0 1 10 4h2.001Zm-4.187 7.009A2 2 0 0 0 6 13c0 .366.098.706.271 1H12a1 1 0 1 1 0 2H5.5a1.5 1.5 0 0 0 0 3h13a1.5 1.5 0 1 0 0-3H17a1 1 0 1 1 0-2h.729c.173-.294.271-.634.271-1a2 2 0 0 0-2-2h-2a1 1 0 1 1 0-2h1.236a3.002 3.002 0 0 0-1.243-4.832A2 2 0 0 1 12 6h-2a2 2 0 0 0-1.728 3.009H9a1 1 0 0 1 0 2H7.813Z',
})
+3 -3
View File
@@ -146,10 +146,10 @@ function ContentHiderActive({
label={desc.name} label={desc.name}
accessibilityHint={ accessibilityHint={
modui.noOverride modui.noOverride
? _(msg`Learn more about the moderation applied to this content.`) ? _(msg`Learn more about the moderation applied to this content`)
: override : override
? _(msg`Hide the content`) ? _(msg`Hides the content`)
: _(msg`Show the content`) : _(msg`Shows the content`)
}> }>
{state => ( {state => (
<View <View
+1 -1
View File
@@ -76,7 +76,7 @@ export function PostHider({
}} }}
accessibilityRole="button" accessibilityRole="button"
accessibilityHint={ accessibilityHint={
override ? _(msg`Hide the content`) : _(msg`Show the content`) override ? _(msg`Hides the content`) : _(msg`Shows the content`)
} }
accessibilityLabel="" accessibilityLabel=""
style={[ style={[
+1
View File
@@ -12,6 +12,7 @@ export type CommonNavigatorParams = {
ModerationModlists: undefined ModerationModlists: undefined
ModerationMutedAccounts: undefined ModerationMutedAccounts: undefined
ModerationBlockedAccounts: undefined ModerationBlockedAccounts: undefined
ModerationInteractionSettings: undefined
Settings: undefined Settings: undefined
Profile: {name: string; hideBackButton?: boolean} Profile: {name: string; hideBackButton?: boolean}
ProfileFollowers: {name: string} ProfileFollowers: {name: string}
+16
View File
@@ -25,3 +25,19 @@ export async function shareUrl(url: string) {
Toast.show(t`Copied to clipboard`, 'clipboard-check') Toast.show(t`Copied to clipboard`, 'clipboard-check')
} }
} }
/**
* This function shares a text using the native Share API if available, or copies it to the clipboard
* and displays a toast message if not (mostly on web)
*
* @param {string} text - A string representing the text that needs to be shared or copied to the
* clipboard.
*/
export async function shareText(text: string) {
if (isAndroid || isIOS) {
await Share.share({message: text})
} else {
await setStringAsync(text)
Toast.show(t`Copied to clipboard`, 'clipboard-check')
}
}
+1 -2
View File
@@ -2,9 +2,8 @@ export type Gate =
// Keep this alphabetic please. // Keep this alphabetic please.
| 'debug_show_feedcontext' | 'debug_show_feedcontext'
| 'debug_subscriptions' | 'debug_subscriptions'
| 'new_postonboarding' | 'old_postonboarding'
| 'onboarding_add_video_feed' | 'onboarding_add_video_feed'
| 'remove_show_latest_button' | 'remove_show_latest_button'
| 'test_gate_1' | 'test_gate_1'
| 'test_gate_2' | 'test_gate_2'
| 'trending_topics_beta'
+3 -4
View File
@@ -42,10 +42,9 @@ export interface IsValidHandle {
} }
// More checks from https://github.com/bluesky-social/atproto/blob/main/packages/pds/src/handle/index.ts#L72 // More checks from https://github.com/bluesky-social/atproto/blob/main/packages/pds/src/handle/index.ts#L72
export function validateHandle( export function validateServiceHandle(
str: string, str: string,
userDomain: string, userDomain: string,
isServiceHandle?: boolean,
): IsValidHandle { ): IsValidHandle {
const fullHandle = createFullHandle(str, userDomain) const fullHandle = createFullHandle(str, userDomain)
@@ -53,8 +52,8 @@ export function validateHandle(
handleChars: handleChars:
!str || (VALIDATE_REGEX.test(fullHandle) && !str.includes('.')), !str || (VALIDATE_REGEX.test(fullHandle) && !str.includes('.')),
hyphenStartOrEnd: !str.startsWith('-') && !str.endsWith('-'), hyphenStartOrEnd: !str.startsWith('-') && !str.endsWith('-'),
frontLength: str.length >= 3, frontLength: str.length >= 3 && str.length <= 18,
totalLength: fullHandle.length <= (isServiceHandle ? 30 : 253), totalLength: fullHandle.length <= 253,
} }
return { return {
+2
View File
@@ -185,6 +185,8 @@ export function sanitizeAppLanguageSetting(appLanguage: string): AppLanguage {
return AppLanguage.hi return AppLanguage.hi
case 'hu': case 'hu':
return AppLanguage.hu return AppLanguage.hu
case 'ia':
return AppLanguage.ia
case 'id': case 'id':
return AppLanguage.id return AppLanguage.id
case 'it': case 'it':
+9
View File
@@ -27,6 +27,7 @@ import {messages as messagesGa} from '#/locale/locales/ga/messages'
import {messages as messagesGl} from '#/locale/locales/gl/messages' import {messages as messagesGl} from '#/locale/locales/gl/messages'
import {messages as messagesHi} from '#/locale/locales/hi/messages' import {messages as messagesHi} from '#/locale/locales/hi/messages'
import {messages as messagesHu} from '#/locale/locales/hu/messages' import {messages as messagesHu} from '#/locale/locales/hu/messages'
import {messages as messagesIa} from '#/locale/locales/ia/messages'
import {messages as messagesId} from '#/locale/locales/id/messages' import {messages as messagesId} from '#/locale/locales/id/messages'
import {messages as messagesIt} from '#/locale/locales/it/messages' import {messages as messagesIt} from '#/locale/locales/it/messages'
import {messages as messagesJa} from '#/locale/locales/ja/messages' import {messages as messagesJa} from '#/locale/locales/ja/messages'
@@ -173,6 +174,14 @@ export async function dynamicActivate(locale: AppLanguage) {
]) ])
break break
} }
case AppLanguage.id: {
i18n.loadAndActivate({locale, messages: messagesIa})
await Promise.all([
import('@formatjs/intl-pluralrules/locale-data/ia'),
import('@formatjs/intl-numberformat/locale-data/ia'),
])
break
}
case AppLanguage.id: { case AppLanguage.id: {
i18n.loadAndActivate({locale, messages: messagesId}) i18n.loadAndActivate({locale, messages: messagesId})
await Promise.all([ await Promise.all([
+4
View File
@@ -72,6 +72,10 @@ export async function dynamicActivate(locale: AppLanguage) {
mod = await import(`./locales/hu/messages`) mod = await import(`./locales/hu/messages`)
break break
} }
case AppLanguage.ia: {
mod = await import(`./locales/ia/messages`)
break
}
case AppLanguage.id: { case AppLanguage.id: {
mod = await import(`./locales/id/messages`) mod = await import(`./locales/id/messages`)
break break
+13 -19
View File
@@ -21,6 +21,7 @@ export enum AppLanguage {
gl = 'gl', gl = 'gl',
hi = 'hi', hi = 'hi',
hu = 'hu', hu = 'hu',
ia = 'ia',
id = 'id', id = 'id',
it = 'it', it = 'it',
ja = 'ja', ja = 'ja',
@@ -64,6 +65,7 @@ export const APP_LANGUAGES: AppLanguageConfig[] = [
{code2: AppLanguage.gl, name: 'Galego – Galician'}, {code2: AppLanguage.gl, name: 'Galego – Galician'},
{code2: AppLanguage.hi, name: 'हिंदी – Hindi'}, {code2: AppLanguage.hi, name: 'हिंदी – Hindi'},
{code2: AppLanguage.hu, name: 'magyar – Hungarian'}, {code2: AppLanguage.hu, name: 'magyar – Hungarian'},
{code2: AppLanguage.ia, name: 'Interlingua'},
{code2: AppLanguage.id, name: 'Bahasa Indonesia – Indonesian'}, {code2: AppLanguage.id, name: 'Bahasa Indonesia – Indonesian'},
{code2: AppLanguage.it, name: 'Italiano – Italian'}, {code2: AppLanguage.it, name: 'Italiano – Italian'},
{code2: AppLanguage.ja, name: '日本語 – Japanese'}, {code2: AppLanguage.ja, name: '日本語 – Japanese'},
@@ -177,11 +179,7 @@ export const LANGUAGES: Language[] = [
{code3: 'cho', code2: '', name: 'Choctaw'}, {code3: 'cho', code2: '', name: 'Choctaw'},
{code3: 'chp', code2: '', name: 'Chipewyan; Dene Suline'}, {code3: 'chp', code2: '', name: 'Chipewyan; Dene Suline'},
{code3: 'chr', code2: '', name: 'Cherokee'}, {code3: 'chr', code2: '', name: 'Cherokee'},
{ {code3: 'chu', code2: 'cu', name: 'Church Slavic'},
code3: 'chu',
code2: 'cu',
name: 'Church Slavic; Old Slavonic; Church Slavonic; Old Bulgarian; Old Church Slavonic',
},
{code3: 'chv', code2: 'cv', name: 'Chuvash'}, {code3: 'chv', code2: 'cv', name: 'Chuvash'},
{code3: 'chy', code2: '', name: 'Cheyenne'}, {code3: 'chy', code2: '', name: 'Cheyenne'},
{code3: 'cmc', code2: '', name: 'Chamic languages'}, {code3: 'cmc', code2: '', name: 'Chamic languages'},
@@ -299,13 +297,9 @@ export const LANGUAGES: Language[] = [
{code3: 'iii', code2: 'ii', name: 'Sichuan Yi; Nuosu'}, {code3: 'iii', code2: 'ii', name: 'Sichuan Yi; Nuosu'},
{code3: 'ijo', code2: '', name: 'Ijo languages'}, {code3: 'ijo', code2: '', name: 'Ijo languages'},
{code3: 'iku', code2: 'iu', name: 'Inuktitut'}, {code3: 'iku', code2: 'iu', name: 'Inuktitut'},
{code3: 'ile', code2: 'ie', name: 'Interlingue; Occidental'}, {code3: 'ile', code2: 'ie', name: 'Interlingue'},
{code3: 'ilo', code2: '', name: 'Iloko'}, {code3: 'ilo', code2: '', name: 'Iloko'},
{ {code3: 'ina', code2: 'ia', name: 'Interlingua'},
code3: 'ina',
code2: 'ia',
name: 'Interlingua (International Auxiliary Language Association)',
},
{code3: 'inc', code2: '', name: 'Indic languages'}, {code3: 'inc', code2: '', name: 'Indic languages'},
{code3: 'ind', code2: 'id', name: 'Indonesian'}, {code3: 'ind', code2: 'id', name: 'Indonesian'},
{code3: 'ine', code2: '', name: 'Indo-European languages'}, {code3: 'ine', code2: '', name: 'Indo-European languages'},
@@ -323,7 +317,7 @@ export const LANGUAGES: Language[] = [
{code3: 'kaa', code2: '', name: 'Kara-Kalpak'}, {code3: 'kaa', code2: '', name: 'Kara-Kalpak'},
{code3: 'kab', code2: '', name: 'Kabyle'}, {code3: 'kab', code2: '', name: 'Kabyle'},
{code3: 'kac', code2: '', name: 'Kachin; Jingpho'}, {code3: 'kac', code2: '', name: 'Kachin; Jingpho'},
{code3: 'kal', code2: 'kl', name: 'Kalaallisut; Greenlandic'}, {code3: 'kal', code2: 'kl', name: 'Kalaallisut'},
{code3: 'kam', code2: '', name: 'Kamba'}, {code3: 'kam', code2: '', name: 'Kamba'},
{code3: 'kan', code2: 'kn', name: 'Kannada'}, {code3: 'kan', code2: 'kn', name: 'Kannada'},
{code3: 'kar', code2: '', name: 'Karen languages'}, {code3: 'kar', code2: '', name: 'Karen languages'},
@@ -362,7 +356,7 @@ export const LANGUAGES: Language[] = [
{code3: 'lat', code2: 'la', name: 'Latin'}, {code3: 'lat', code2: 'la', name: 'Latin'},
{code3: 'lav', code2: 'lv', name: 'Latvian'}, {code3: 'lav', code2: 'lv', name: 'Latvian'},
{code3: 'lez', code2: '', name: 'Lezghian'}, {code3: 'lez', code2: '', name: 'Lezghian'},
{code3: 'lim', code2: 'li', name: 'Limburgan; Limburger; Limburgish'}, {code3: 'lim', code2: 'li', name: 'Limburgish'},
{code3: 'lin', code2: 'ln', name: 'Lingala'}, {code3: 'lin', code2: 'ln', name: 'Lingala'},
{code3: 'lit', code2: 'lt', name: 'Lithuanian'}, {code3: 'lit', code2: 'lt', name: 'Lithuanian'},
{code3: 'lol', code2: '', name: 'Mongo'}, {code3: 'lol', code2: '', name: 'Mongo'},
@@ -423,9 +417,9 @@ export const LANGUAGES: Language[] = [
{code3: 'nai', code2: '', name: 'North American Indian languages'}, {code3: 'nai', code2: '', name: 'North American Indian languages'},
{code3: 'nap', code2: '', name: 'Neapolitan'}, {code3: 'nap', code2: '', name: 'Neapolitan'},
{code3: 'nau', code2: 'na', name: 'Nauru'}, {code3: 'nau', code2: 'na', name: 'Nauru'},
{code3: 'nav', code2: 'nv', name: 'Navajo; Navaho'}, {code3: 'nav', code2: 'nv', name: 'Navajo'},
{code3: 'nbl', code2: 'nr', name: 'Ndebele, South; South Ndebele'}, {code3: 'nbl', code2: 'nr', name: 'South Ndebele'},
{code3: 'nde', code2: 'nd', name: 'Ndebele, North; North Ndebele'}, {code3: 'nde', code2: 'nd', name: 'North Ndebele'},
{code3: 'ndo', code2: 'ng', name: 'Ndonga'}, {code3: 'ndo', code2: 'ng', name: 'Ndonga'},
{ {
code3: 'nds', code3: 'nds',
@@ -438,8 +432,8 @@ export const LANGUAGES: Language[] = [
{code3: 'nic', code2: '', name: 'Niger-Kordofanian languages'}, {code3: 'nic', code2: '', name: 'Niger-Kordofanian languages'},
{code3: 'niu', code2: '', name: 'Niuean'}, {code3: 'niu', code2: '', name: 'Niuean'},
{code3: 'nld', code2: 'nl', name: 'Dutch; Flemish'}, {code3: 'nld', code2: 'nl', name: 'Dutch; Flemish'},
{code3: 'nno', code2: 'nn', name: 'Norwegian Nynorsk; Nynorsk, Norwegian'}, {code3: 'nno', code2: 'nn', name: 'Norwegian Nynorsk'},
{code3: 'nob', code2: 'nb', name: 'Bokmål, Norwegian; Norwegian Bokmål'}, {code3: 'nob', code2: 'nb', name: 'Norwegian Bokmål'},
{code3: 'nog', code2: '', name: 'Nogai'}, {code3: 'nog', code2: '', name: 'Nogai'},
{code3: 'non', code2: '', name: 'Norse, Old'}, {code3: 'non', code2: '', name: 'Norse, Old'},
{code3: 'nor', code2: 'no', name: 'Norwegian'}, {code3: 'nor', code2: 'no', name: 'Norwegian'},
@@ -461,7 +455,7 @@ export const LANGUAGES: Language[] = [
{code3: 'ori', code2: 'or', name: 'Oriya'}, {code3: 'ori', code2: 'or', name: 'Oriya'},
{code3: 'orm', code2: 'om', name: 'Oromo'}, {code3: 'orm', code2: 'om', name: 'Oromo'},
{code3: 'osa', code2: '', name: 'Osage'}, {code3: 'osa', code2: '', name: 'Osage'},
{code3: 'oss', code2: 'os', name: 'Ossetian; Ossetic'}, {code3: 'oss', code2: 'os', name: 'Ossetic'},
{code3: 'ota', code2: '', name: 'Turkish, Ottoman (1500-1928)'}, {code3: 'ota', code2: '', name: 'Turkish, Ottoman (1500-1928)'},
{code3: 'oto', code2: '', name: 'Otomian languages'}, {code3: 'oto', code2: '', name: 'Otomian languages'},
{code3: 'paa', code2: '', name: 'Papuan languages'}, {code3: 'paa', code2: '', name: 'Papuan languages'},
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
+94 -94
View File
@@ -15,7 +15,7 @@ msgstr ""
#: src/components/ProgressGuide/FollowDialog.tsx:567 #: src/components/ProgressGuide/FollowDialog.tsx:567
msgid "(active)" msgid "(active)"
msgstr "" msgstr "(सक्रिय)"
#: src/screens/Messages/components/ChatListItem.tsx:130 #: src/screens/Messages/components/ChatListItem.tsx:130
msgid "(contains embedded content)" msgid "(contains embedded content)"
@@ -37,11 +37,11 @@ msgstr "{0, plural, other {# दिन}}"
#: src/screens/Profile/ProfileFollowers.tsx:40 #: src/screens/Profile/ProfileFollowers.tsx:40
msgid "{0, plural, one {# follower} other {# followers}}" msgid "{0, plural, one {# follower} other {# followers}}"
msgstr "" msgstr "{0, plural, one {# फ़ॉलोअर} other {# फ़ॉलोअर}}"
#: src/screens/Profile/ProfileFollows.tsx:40 #: src/screens/Profile/ProfileFollows.tsx:40
msgid "{0, plural, one {# following} other {# following}}" msgid "{0, plural, one {# following} other {# following}}"
msgstr "" msgstr "{0, plural, one {# फ़ॉलोइंग} other {# फ़ॉलोइंग}}"
#: src/lib/hooks/useTimeAgo.ts:146 #: src/lib/hooks/useTimeAgo.ts:146
msgid "{0, plural, one {# hour} other {# hours}}" msgid "{0, plural, one {# hour} other {# hours}}"
@@ -65,15 +65,15 @@ msgstr "{0, plural, one {# घंटा} other {# घंटे}}"
#: src/components/moderation/LabelsOnMe.tsx:53 #: src/components/moderation/LabelsOnMe.tsx:53
msgid "{0, plural, one {# label has} other {# labels have}} been placed on this account" msgid "{0, plural, one {# label has} other {# labels have}} been placed on this account"
msgstr "" msgstr "इस खाते पर {0, plural, one {# लेबल लगाया गया है।} other {# लेबल लगाए गए हैं।}}"
#: src/components/moderation/LabelsOnMe.tsx:62 #: src/components/moderation/LabelsOnMe.tsx:62
msgid "{0, plural, one {# label has} other {# labels have}} been placed on this content" msgid "{0, plural, one {# label has} other {# labels have}} been placed on this content"
msgstr "" msgstr "इस सामाग्री पर {0, plural, one {# लेबल लगाया गया है।} other {# लेबल लगाए गए हैं।}}"
#: src/screens/Post/PostLikedBy.tsx:41 #: src/screens/Post/PostLikedBy.tsx:41
msgid "{0, plural, one {# like} other {# likes}}" msgid "{0, plural, one {# like} other {# likes}}"
msgstr "" msgstr "{0, plural, one {# पसंद} other {# पसंद}}"
#: src/lib/hooks/useTimeAgo.ts:136 #: src/lib/hooks/useTimeAgo.ts:136
msgid "{0, plural, one {# minute} other {# minutes}}" msgid "{0, plural, one {# minute} other {# minutes}}"
@@ -85,7 +85,7 @@ msgstr "{0, plural, one {# महीना} other {# महीने}}"
#: src/screens/Post/PostQuotes.tsx:41 #: src/screens/Post/PostQuotes.tsx:41
msgid "{0, plural, one {# quote} other {# quotes}}" msgid "{0, plural, one {# quote} other {# quotes}}"
msgstr "" msgstr "{0, plural, one {# क्वोट} other {# क्वोट}}"
#: src/screens/Post/PostRepostedBy.tsx:41 #: src/screens/Post/PostRepostedBy.tsx:41
msgid "{0, plural, one {# repost} other {# reposts}}" msgid "{0, plural, one {# repost} other {# reposts}}"
@@ -335,7 +335,7 @@ msgstr "{handle} को संदेश भेजा नहीं जा सक
#: src/view/shell/bottom-bar/BottomBarWeb.tsx:260 #: src/view/shell/bottom-bar/BottomBarWeb.tsx:260
msgid "{notificationCount} unread items" msgid "{notificationCount} unread items"
msgstr "" msgstr "{notificationCount} अपठित चीज़ें"
#: src/view/shell/Drawer.tsx:448 #: src/view/shell/Drawer.tsx:448
msgid "{numUnreadNotifications} unread" msgid "{numUnreadNotifications} unread"
@@ -621,7 +621,7 @@ msgstr "नया पोस्ट जोड़ें"
#: src/view/screens/ProfileList.tsx:903 #: src/view/screens/ProfileList.tsx:903
#: src/view/screens/ProfileList.tsx:921 #: src/view/screens/ProfileList.tsx:921
msgid "Add people" msgid "Add people"
msgstr "" msgstr "लोगों को जोड़ें"
#: src/screens/Home/NoFeedsPinned.tsx:99 #: src/screens/Home/NoFeedsPinned.tsx:99
msgid "Add recommended feeds" msgid "Add recommended feeds"
@@ -703,7 +703,7 @@ msgstr "विकसित"
#: src/view/screens/Notifications.tsx:86 #: src/view/screens/Notifications.tsx:86
msgid "All" msgid "All"
msgstr "" msgstr "सभी"
#: src/screens/StarterPack/StarterPackScreen.tsx:381 #: src/screens/StarterPack/StarterPackScreen.tsx:381
msgid "All accounts have been followed!" msgid "All accounts have been followed!"
@@ -725,7 +725,7 @@ msgstr "इनसे नए संदेश आने की अनुमति
#: src/components/dialogs/PostInteractionSettingsDialog.tsx:314 #: src/components/dialogs/PostInteractionSettingsDialog.tsx:314
msgid "Allow quote posts" msgid "Allow quote posts"
msgstr "" msgstr "क्वोट पोस्ट की अनुमति दें"
#: src/components/dialogs/PostInteractionSettingsDialog.tsx:359 #: src/components/dialogs/PostInteractionSettingsDialog.tsx:359
msgid "Allow replies from:" msgid "Allow replies from:"
@@ -888,7 +888,7 @@ msgstr "कोई भी संपर्क कर सकता है"
#: src/screens/Settings/AppIconSettings/SettingsListItem.tsx:18 #: src/screens/Settings/AppIconSettings/SettingsListItem.tsx:18
#: src/screens/Settings/AppIconSettings/SettingsListItem.tsx:23 #: src/screens/Settings/AppIconSettings/SettingsListItem.tsx:23
msgid "App Icon" msgid "App Icon"
msgstr "" msgstr "ऐप आइकॉन"
#: src/screens/Settings/LanguageSettings.tsx:80 #: src/screens/Settings/LanguageSettings.tsx:80
msgid "App Language" msgid "App Language"
@@ -1113,7 +1113,7 @@ msgstr "अन्य उपयोगकर्ताओं को संदेश
#: src/screens/Search/components/ExploreTrendingTopics.tsx:74 #: src/screens/Search/components/ExploreTrendingTopics.tsx:74
msgid "BETA" msgid "BETA"
msgstr "" msgstr "बीटा"
#: src/components/dialogs/BirthDateSettings.tsx:106 #: src/components/dialogs/BirthDateSettings.tsx:106
#: src/screens/Settings/AccountSettings.tsx:109 #: src/screens/Settings/AccountSettings.tsx:109
@@ -1252,11 +1252,11 @@ msgstr "Bluesky लॉग आउट उपयोगकर्ताओं को
#: src/screens/Settings/AppIconSettings/index.tsx:99 #: src/screens/Settings/AppIconSettings/index.tsx:99
msgid "Bluesky+" msgid "Bluesky+"
msgstr "" msgstr "Bluesky+"
#: src/screens/Settings/AppIconSettings/index.tsx:102 #: src/screens/Settings/AppIconSettings/index.tsx:102
msgid "Bluesky+ icons" msgid "Bluesky+ icons"
msgstr "" msgstr "Bluesky+ आइकॉन"
#: src/lib/moderation/useLabelBehaviorDescription.ts:53 #: src/lib/moderation/useLabelBehaviorDescription.ts:53
msgid "Blur images" msgid "Blur images"
@@ -1298,15 +1298,15 @@ msgstr "अन्य फ़ीड देखें"
#: src/components/TrendingTopics.tsx:176 #: src/components/TrendingTopics.tsx:176
msgid "Browse posts about {displayName}" msgid "Browse posts about {displayName}"
msgstr "" msgstr "{displayName} के बारे में पोस्ट देखें"
#: src/components/TrendingTopics.tsx:184 #: src/components/TrendingTopics.tsx:184
msgid "Browse posts tagged with {displayName}" msgid "Browse posts tagged with {displayName}"
msgstr "" msgstr "{displayName} से टैग किए गए पोस्ट देखें"
#: src/components/TrendingTopics.tsx:222 #: src/components/TrendingTopics.tsx:222
msgid "Browse topic {displayName}" msgid "Browse topic {displayName}"
msgstr "" msgstr "{displayName} विषय देखें"
#: src/view/screens/Settings/index.tsx:893 #: src/view/screens/Settings/index.tsx:893
#~ msgid "Build version {0} {1}" #~ msgid "Build version {0} {1}"
@@ -1330,7 +1330,7 @@ msgstr "{0} के द्वारा"
#: src/screens/Profile/components/ProfileFeedHeader.tsx:447 #: src/screens/Profile/components/ProfileFeedHeader.tsx:447
msgid "By <0>{0}</0>" msgid "By <0>{0}</0>"
msgstr "" msgstr "<0>{0}</0> के द्वार"
#: src/screens/Signup/StepInfo/Policies.tsx:80 #: src/screens/Signup/StepInfo/Policies.tsx:80
#~ msgid "By creating an account you agree to the {els}." #~ msgid "By creating an account you agree to the {els}."
@@ -1463,12 +1463,12 @@ msgstr "बदलें"
#: src/screens/Settings/AppIconSettings/index.tsx:39 #: src/screens/Settings/AppIconSettings/index.tsx:39
msgid "Change app icon" msgid "Change app icon"
msgstr "" msgstr "ऐप आइकॉन बदलें"
#: src/screens/Settings/AppIconSettings/index.tsx:38 #: src/screens/Settings/AppIconSettings/index.tsx:38
#: src/screens/Settings/AppIconSettings/index.tsx:221 #: src/screens/Settings/AppIconSettings/index.tsx:221
msgid "Change app icon to \"{0}\"" msgid "Change app icon to \"{0}\""
msgstr "" msgstr "ऐप आइकॉन को \"{0}\" में बदलें"
#: src/screens/Settings/AccountSettings.tsx:97 #: src/screens/Settings/AccountSettings.tsx:97
#: src/screens/Settings/AccountSettings.tsx:101 #: src/screens/Settings/AccountSettings.tsx:101
@@ -1600,7 +1600,7 @@ msgstr "इस रंग को अपना अवतार के रूप
#: src/view/screens/Feeds.tsx:728 #: src/view/screens/Feeds.tsx:728
#: src/view/screens/Search/Explore.tsx:411 #: src/view/screens/Search/Explore.tsx:411
msgid "Choose your own timeline! Feeds built by the community help you find content you love." msgid "Choose your own timeline! Feeds built by the community help you find content you love."
msgstr "" msgstr "आपका अपना टाइमलाइन चुनें! समुदाय द्वारा बनाए गए फ़ीड आपको पसंदीदा सामग्री ढूँढने में सहायता करते हैं।"
#: src/screens/Signup/StepInfo/index.tsx:201 #: src/screens/Signup/StepInfo/index.tsx:201
msgid "Choose your password" msgid "Choose your password"
@@ -1696,7 +1696,7 @@ msgstr "डायलॉग बंद करें"
#: src/view/com/composer/text-input/web/EmojiPicker.web.tsx:137 #: src/view/com/composer/text-input/web/EmojiPicker.web.tsx:137
#: src/view/com/composer/text-input/web/EmojiPicker.web.tsx:173 #: src/view/com/composer/text-input/web/EmojiPicker.web.tsx:173
msgid "Close emoji picker" msgid "Close emoji picker"
msgstr "" msgstr "इमोजी चयन बंद करें"
#: src/components/dialogs/GifSelect.tsx:169 #: src/components/dialogs/GifSelect.tsx:169
msgid "Close GIF dialog" msgid "Close GIF dialog"
@@ -1859,7 +1859,7 @@ msgstr "सहायता से संपर्क करें"
#: src/screens/Settings/ContentAndMediaSettings.tsx:49 #: src/screens/Settings/ContentAndMediaSettings.tsx:49
msgid "Content & Media" msgid "Content & Media"
msgstr "" msgstr "सामाग्री और मीडिया"
#: src/screens/Settings/AccessibilitySettings.tsx:109 #: src/screens/Settings/AccessibilitySettings.tsx:109
#: src/screens/Settings/Settings.tsx:175 #: src/screens/Settings/Settings.tsx:175
@@ -2149,7 +2149,7 @@ msgstr "{0} बनाया गया"
#: src/screens/List/ListHiddenScreen.tsx:127 #: src/screens/List/ListHiddenScreen.tsx:127
msgid "Creator has been blocked" msgid "Creator has been blocked"
msgstr "" msgstr "रचयिता को अवरुद्ध किया गया"
#: src/screens/Onboarding/index.tsx:26 #: src/screens/Onboarding/index.tsx:26
#: src/screens/Onboarding/state.ts:99 #: src/screens/Onboarding/state.ts:99
@@ -2227,7 +2227,7 @@ msgstr "डिफ़ॉल्‍ट"
#: src/screens/Settings/AppIconSettings/index.tsx:75 #: src/screens/Settings/AppIconSettings/index.tsx:75
msgid "Default icons" msgid "Default icons"
msgstr "" msgstr "डिफ़ॉल्‍ट आइकॉन"
#: src/components/dms/MessageMenu.tsx:151 #: src/components/dms/MessageMenu.tsx:151
#: src/screens/Settings/AppPasswords.tsx:212 #: src/screens/Settings/AppPasswords.tsx:212
@@ -2713,7 +2713,7 @@ msgstr "शिक्षा"
#: src/screens/List/ListHiddenScreen.tsx:141 #: src/screens/List/ListHiddenScreen.tsx:141
msgid "Either the creator of this list has blocked you or you have blocked the creator." msgid "Either the creator of this list has blocked you or you have blocked the creator."
msgstr "" msgstr "इस सूची के रचयिता ने आपको अवरुद्ध किया है या आपने रचयिता को अवरुद्ध किया है।"
#: src/screens/Settings/AccountSettings.tsx:60 #: src/screens/Settings/AccountSettings.tsx:60
#: src/screens/Signup/StepInfo/index.tsx:170 #: src/screens/Signup/StepInfo/index.tsx:170
@@ -2774,7 +2774,7 @@ msgstr "इस पोस्ट को अपने वेबसाइट मे
#: src/view/com/util/post-embeds/VideoEmbedInner/VideoEmbedInnerWeb.tsx:57 #: src/view/com/util/post-embeds/VideoEmbedInner/VideoEmbedInnerWeb.tsx:57
msgid "Embedded video player" msgid "Embedded video player"
msgstr "" msgstr "एम्बेडेड वीडियो प्लेयर"
#: src/screens/Settings/components/Email2FAToggle.tsx:56 #: src/screens/Settings/components/Email2FAToggle.tsx:56
#: src/screens/Settings/components/Email2FAToggle.tsx:60 #: src/screens/Settings/components/Email2FAToggle.tsx:60
@@ -2822,7 +2822,7 @@ msgstr "केवल इस सूत्र को सक्षम करें"
#: src/screens/Settings/ContentAndMediaSettings.tsx:122 #: src/screens/Settings/ContentAndMediaSettings.tsx:122
#: src/screens/Settings/ContentAndMediaSettings.tsx:136 #: src/screens/Settings/ContentAndMediaSettings.tsx:136
msgid "Enable trending topics" msgid "Enable trending topics"
msgstr "" msgstr "रुझान सक्षम करें"
#: src/screens/Messages/Settings.tsx:130 #: src/screens/Messages/Settings.tsx:130
#: src/screens/Messages/Settings.tsx:133 #: src/screens/Messages/Settings.tsx:133
@@ -2861,7 +2861,7 @@ msgstr "पुष्टिकरण कोड दर्ज करें"
#: src/view/com/util/post-embeds/VideoEmbedInner/web-controls/VideoControls.tsx:405 #: src/view/com/util/post-embeds/VideoEmbedInner/web-controls/VideoControls.tsx:405
msgid "Enter fullscreen" msgid "Enter fullscreen"
msgstr "" msgstr "फ़ुलस्क्रीन में जाएँ"
#: src/view/com/modals/ChangePassword.tsx:154 #: src/view/com/modals/ChangePassword.tsx:154
msgid "Enter the code you received to change your password." msgid "Enter the code you received to change your password."
@@ -3166,7 +3166,7 @@ msgstr "{0} द्वारा फ़ीड"
#: src/screens/Profile/components/ProfileFeedHeader.tsx:353 #: src/screens/Profile/components/ProfileFeedHeader.tsx:353
msgid "Feed menu" msgid "Feed menu"
msgstr "" msgstr "फ़ीड मेनू"
#: src/view/screens/Feeds.tsx:709 #: src/view/screens/Feeds.tsx:709
#~ msgid "Feed offline" #~ msgid "Feed offline"
@@ -3217,7 +3217,7 @@ msgstr "फ़ीड अपडेट की गई!"
#: src/screens/Search/components/ExploreRecommendations.tsx:54 #: src/screens/Search/components/ExploreRecommendations.tsx:54
msgid "Feeds we think you might like." msgid "Feeds we think you might like."
msgstr "" msgstr "फ़ीड जो हमें लगता है आपको पसंद आए।"
#: src/view/com/modals/ChangeHandle.tsx:468 #: src/view/com/modals/ChangeHandle.tsx:468
#~ msgid "File Contents" #~ msgid "File Contents"
@@ -3245,7 +3245,7 @@ msgstr "फ़ॉलो करने के लिए खाते खोजे
#: src/components/ProgressGuide/FollowDialog.tsx:88 #: src/components/ProgressGuide/FollowDialog.tsx:88
#: src/components/ProgressGuide/FollowDialog.tsx:417 #: src/components/ProgressGuide/FollowDialog.tsx:417
msgid "Find people to follow" msgid "Find people to follow"
msgstr "" msgstr "फ़ॉलो करने के लिए लोग खोजें"
#: src/view/screens/Search/Search.tsx:595 #: src/view/screens/Search/Search.tsx:595
msgid "Find posts and users on Bluesky" msgid "Find posts and users on Bluesky"
@@ -3305,7 +3305,7 @@ msgstr "{name} को फ़ॉलो करें"
#: src/components/ProgressGuide/List.tsx:52 #: src/components/ProgressGuide/List.tsx:52
#: src/state/shell/progress-guide.tsx:229 #: src/state/shell/progress-guide.tsx:229
msgid "Follow 10 accounts" msgid "Follow 10 accounts"
msgstr "" msgstr "10 खाते फ़ॉलो करें"
#: src/components/ProgressGuide/List.tsx:69 #: src/components/ProgressGuide/List.tsx:69
msgid "Follow 7 accounts" msgid "Follow 7 accounts"
@@ -3732,13 +3732,13 @@ msgstr "यह पोस्ट छिपाएँ?"
#: src/screens/Search/components/ExploreTrendingTopics.tsx:83 #: src/screens/Search/components/ExploreTrendingTopics.tsx:83
#: src/view/shell/desktop/SidebarTrendingTopics.tsx:62 #: src/view/shell/desktop/SidebarTrendingTopics.tsx:62
msgid "Hide trending topics" msgid "Hide trending topics"
msgstr "" msgstr "रुझान छिपाएँ"
#: src/components/interstitials/Trending.tsx:99 #: src/components/interstitials/Trending.tsx:99
#: src/screens/Search/components/ExploreTrendingTopics.tsx:135 #: src/screens/Search/components/ExploreTrendingTopics.tsx:135
#: src/view/shell/desktop/SidebarTrendingTopics.tsx:108 #: src/view/shell/desktop/SidebarTrendingTopics.tsx:108
msgid "Hide trending topics?" msgid "Hide trending topics?"
msgstr "" msgstr "रुझान छिपाएँ?"
#: src/view/com/notifications/NotificationFeedItem.tsx:592 #: src/view/com/notifications/NotificationFeedItem.tsx:592
msgid "Hide user list" msgid "Hide user list"
@@ -3806,7 +3806,7 @@ msgstr "होस्टिंग प्रदाता"
#: src/view/com/post-thread/PostThread.tsx:652 #: src/view/com/post-thread/PostThread.tsx:652
#: src/view/com/post-thread/PostThread.tsx:657 #: src/view/com/post-thread/PostThread.tsx:657
msgid "Hot replies first" msgid "Hot replies first"
msgstr "" msgstr "गर्मागर्म जवाब पहले"
#: src/view/com/modals/InAppBrowserConsent.tsx:41 #: src/view/com/modals/InAppBrowserConsent.tsx:41
msgid "How should we open this link?" msgid "How should we open this link?"
@@ -3859,7 +3859,7 @@ msgstr "यदि आप इस सूची को मिटते हैं,
#: src/screens/Settings/components/ChangeHandleDialog.tsx:250 #: src/screens/Settings/components/ChangeHandleDialog.tsx:250
msgid "If you have your own domain, you can use that as your handle. This lets you self-verify your identity. <0>Learn more here.</0>" msgid "If you have your own domain, you can use that as your handle. This lets you self-verify your identity. <0>Learn more here.</0>"
msgstr "" msgstr "यदि आपका अपना डोमेन है, आप उसे अपने हैंडल के तौर पर उपयोग कर सकते हैं। इसे आप ख़ुद अपने पहचान की पुष्टि कर सकते हैं। <0>यहाँ अधिक जानें।</0>"
#: src/view/com/util/forms/PostDropdownBtnMenuItems.tsx:658 #: src/view/com/util/forms/PostDropdownBtnMenuItems.tsx:658
msgid "If you remove this post, you won't be able to recover it." msgid "If you remove this post, you won't be able to recover it."
@@ -4216,11 +4216,11 @@ msgstr "रोशन"
#: src/screens/Profile/components/ProfileFeedHeader.tsx:514 #: src/screens/Profile/components/ProfileFeedHeader.tsx:514
msgid "Like" msgid "Like"
msgstr "" msgstr "पसंद"
#: src/view/com/util/post-ctrls/PostCtrls.tsx:311 #: src/view/com/util/post-ctrls/PostCtrls.tsx:311
msgid "Like ({0, plural, one {# like} other {# likes}})" msgid "Like ({0, plural, one {# like} other {# likes}})"
msgstr "" msgstr "पसंद करें ({0, plural, one {# पसंद} other {# पसंद}})"
#: src/components/ProgressGuide/List.tsx:63 #: src/components/ProgressGuide/List.tsx:63
msgid "Like 10 posts" msgid "Like 10 posts"
@@ -4233,7 +4233,7 @@ msgstr "डिस्कवर फ़ीड को प्रशिक्षित
#: src/screens/Profile/components/ProfileFeedHeader.tsx:501 #: src/screens/Profile/components/ProfileFeedHeader.tsx:501
msgid "Like feed" msgid "Like feed"
msgstr "" msgstr "फ़ीड पसंद करें"
#: src/screens/Profile/Header/ProfileHeaderLabeler.tsx:275 #: src/screens/Profile/Header/ProfileHeaderLabeler.tsx:275
msgid "Like this feed" msgid "Like this feed"
@@ -4254,14 +4254,14 @@ msgstr "इन्होनें पसंद किया"
#: src/components/FeedCard.tsx:213 #: src/components/FeedCard.tsx:213
#: src/view/com/feeds/FeedSourceCard.tsx:303 #: src/view/com/feeds/FeedSourceCard.tsx:303
msgid "Liked by {0, plural, one {# user} other {# users}}" msgid "Liked by {0, plural, one {# user} other {# users}}"
msgstr "" msgstr "{0, plural, one {# उपयोगकर्ता} other {# उपयोगकर्ताओं}} ने पसंद किया"
#: src/components/LabelingServiceCard/index.tsx:96 #: src/components/LabelingServiceCard/index.tsx:96
#: src/screens/Profile/components/ProfileFeedHeader.tsx:489 #: src/screens/Profile/components/ProfileFeedHeader.tsx:489
#: src/screens/Profile/Header/ProfileHeaderLabeler.tsx:295 #: src/screens/Profile/Header/ProfileHeaderLabeler.tsx:295
#: src/screens/Profile/Header/ProfileHeaderLabeler.tsx:309 #: src/screens/Profile/Header/ProfileHeaderLabeler.tsx:309
msgid "Liked by {likeCount, plural, one {# user} other {# users}}" msgid "Liked by {likeCount, plural, one {# user} other {# users}}"
msgstr "" msgstr "{likeCount, plural, one {# उपयोगकर्ता} other {# उपयोगकर्ताओं}} ने पसंद किया"
#: src/view/com/notifications/FeedItem.tsx:211 #: src/view/com/notifications/FeedItem.tsx:211
#~ msgid "liked your custom feed" #~ msgid "liked your custom feed"
@@ -4282,7 +4282,7 @@ msgstr "इस पोस्ट पर पसंद"
#: src/view/com/post-thread/PostThread.tsx:626 #: src/view/com/post-thread/PostThread.tsx:626
#: src/view/com/post-thread/PostThread.tsx:631 #: src/view/com/post-thread/PostThread.tsx:631
msgid "Linear" msgid "Linear"
msgstr "" msgstr "रेखीय"
#: src/Navigation.tsx:198 #: src/Navigation.tsx:198
msgid "List" msgid "List"
@@ -4303,11 +4303,11 @@ msgstr "{0} द्वारा सूची"
#: src/view/com/profile/ProfileSubpageHeader.tsx:156 #: src/view/com/profile/ProfileSubpageHeader.tsx:156
msgid "List by <0/>" msgid "List by <0/>"
msgstr "" msgstr "<0/> द्वारा सूची"
#: src/view/com/profile/ProfileSubpageHeader.tsx:154 #: src/view/com/profile/ProfileSubpageHeader.tsx:154
msgid "List by you" msgid "List by you"
msgstr "" msgstr "आपके द्वारा सूची"
#: src/view/screens/ProfileList.tsx:455 #: src/view/screens/ProfileList.tsx:455
msgid "List deleted" msgid "List deleted"
@@ -4412,7 +4412,7 @@ msgstr "उस खाते में लॉग इन करें जो स
#: src/view/shell/desktop/RightNav.tsx:121 #: src/view/shell/desktop/RightNav.tsx:121
msgid "Logo by @sawaratsuki.bsky.social" msgid "Logo by @sawaratsuki.bsky.social"
msgstr "" msgstr "@sawaratsuki.bsky.social द्वारा लोगो"
#: src/view/shell/desktop/RightNav.tsx:103 #: src/view/shell/desktop/RightNav.tsx:103
#~ msgid "Logo by <0/>" #~ msgid "Logo by <0/>"
@@ -4483,7 +4483,7 @@ msgstr "उल्लेखित उपयोगकर्ता"
#: src/view/screens/Notifications.tsx:99 #: src/view/screens/Notifications.tsx:99
msgid "Mentions" msgid "Mentions"
msgstr "" msgstr "उल्लेख"
#: src/components/Menu/index.tsx:96 #: src/components/Menu/index.tsx:96
#: src/view/screens/Search/Search.tsx:863 #: src/view/screens/Search/Search.tsx:863
@@ -4837,7 +4837,7 @@ msgstr "नया हैंडल"
#: src/view/screens/Lists.tsx:66 #: src/view/screens/Lists.tsx:66
#: src/view/screens/ModerationModlists.tsx:66 #: src/view/screens/ModerationModlists.tsx:66
msgid "New list" msgid "New list"
msgstr "" msgstr "नई सूची"
#: src/components/dms/NewMessagesPill.tsx:92 #: src/components/dms/NewMessagesPill.tsx:92
msgid "New messages" msgid "New messages"
@@ -5241,7 +5241,7 @@ msgstr "बातचीत विकल्प खोलें"
#: src/components/Layout/Header/index.tsx:145 #: src/components/Layout/Header/index.tsx:145
msgid "Open drawer menu" msgid "Open drawer menu"
msgstr "" msgstr "ड्रॉअर मेनू खोलें"
#: src/screens/Messages/components/MessageInput.web.tsx:181 #: src/screens/Messages/components/MessageInput.web.tsx:181
#: src/view/com/composer/Composer.tsx:1228 #: src/view/com/composer/Composer.tsx:1228
@@ -5251,7 +5251,7 @@ msgstr "इमोजी चयन खोलें"
#: src/screens/Profile/components/ProfileFeedHeader.tsx:190 #: src/screens/Profile/components/ProfileFeedHeader.tsx:190
msgid "Open feed info screen" msgid "Open feed info screen"
msgstr "" msgstr "फ़ीड जानकारी स्क्रीन खोलें"
#: src/screens/Profile/components/ProfileFeedHeader.tsx:290 #: src/screens/Profile/components/ProfileFeedHeader.tsx:290
#: src/screens/Profile/components/ProfileFeedHeader.tsx:295 #: src/screens/Profile/components/ProfileFeedHeader.tsx:295
@@ -5582,7 +5582,7 @@ msgstr "वयस्कों के लिए छवि।"
#: src/screens/Profile/components/ProfileFeedHeader.tsx:519 #: src/screens/Profile/components/ProfileFeedHeader.tsx:519
#: src/screens/Profile/components/ProfileFeedHeader.tsx:526 #: src/screens/Profile/components/ProfileFeedHeader.tsx:526
msgid "Pin feed" msgid "Pin feed"
msgstr "" msgstr "फ़ीड पिन करें"
#: src/view/screens/ProfileList.tsx:685 #: src/view/screens/ProfileList.tsx:685
msgid "Pin to home" msgid "Pin to home"
@@ -5604,7 +5604,7 @@ msgstr "पिन किया गया"
#: src/screens/Profile/components/ProfileFeedHeader.tsx:162 #: src/screens/Profile/components/ProfileFeedHeader.tsx:162
#: src/screens/Profile/components/ProfileFeedHeader.tsx:174 #: src/screens/Profile/components/ProfileFeedHeader.tsx:174
msgid "Pinned {0} to Home" msgid "Pinned {0} to Home"
msgstr "" msgstr "होम में {0} पिन किया गया"
#: src/view/screens/SavedFeeds.tsx:123 #: src/view/screens/SavedFeeds.tsx:123
msgid "Pinned Feeds" msgid "Pinned Feeds"
@@ -5912,11 +5912,11 @@ msgstr "सार्वजनिक"
#: src/view/com/lists/MyLists.tsx:77 #: src/view/com/lists/MyLists.tsx:77
msgid "Public, sharable lists of users to mute or block in bulk." msgid "Public, sharable lists of users to mute or block in bulk."
msgstr "" msgstr "उपयोगकर्ताओं की सार्वजनिक, साझा योग्य सूचियाँ जिन्हें एक साथ म्यूट या अवरुद्ध किया जा सकता है।"
#: src/view/com/lists/MyLists.tsx:72 #: src/view/com/lists/MyLists.tsx:72
msgid "Public, sharable lists which can be used to drive feeds." msgid "Public, sharable lists which can be used to drive feeds."
msgstr "" msgstr "सार्वजनिक, साझा योग्य सूचियाँ जो फ़ीड चला सकती हैं।"
#: src/view/screens/ModerationModlists.tsx:75 #: src/view/screens/ModerationModlists.tsx:75
#~ msgid "Public, shareable lists of users to mute or block in bulk." #~ msgid "Public, shareable lists of users to mute or block in bulk."
@@ -6024,7 +6024,7 @@ msgstr "हाल के खोज"
#: src/screens/Search/components/ExploreRecommendations.tsx:50 #: src/screens/Search/components/ExploreRecommendations.tsx:50
msgid "Recommended" msgid "Recommended"
msgstr "" msgstr "अनुशंसित"
#: src/view/com/auth/onboarding/RecommendedFeeds.tsx:117 #: src/view/com/auth/onboarding/RecommendedFeeds.tsx:117
#~ msgid "Recommended Feeds" #~ msgid "Recommended Feeds"
@@ -6216,7 +6216,7 @@ msgstr "जवाब दें"
#: src/view/com/util/post-ctrls/PostCtrls.tsx:263 #: src/view/com/util/post-ctrls/PostCtrls.tsx:263
msgid "Reply ({0, plural, one {# reply} other {# replies}})" msgid "Reply ({0, plural, one {# reply} other {# replies}})"
msgstr "" msgstr "जवाब दें ({0, plural, one {# जवाब} other {# जवाब}})"
#: src/view/screens/PreferencesFollowingFeed.tsx:142 #: src/view/screens/PreferencesFollowingFeed.tsx:142
#~ msgid "Reply Filters" #~ msgid "Reply Filters"
@@ -6242,7 +6242,7 @@ msgstr "जवाब सेटिंग थ्रेड का लेखक च
#: src/view/com/post-thread/PostThread.tsx:648 #: src/view/com/post-thread/PostThread.tsx:648
msgid "Reply sorting" msgid "Reply sorting"
msgstr "" msgstr "जवाब क्रम"
#: src/view/com/post/Post.tsx:204 #: src/view/com/post/Post.tsx:204
#: src/view/com/posts/PostFeedItem.tsx:553 #: src/view/com/posts/PostFeedItem.tsx:553
@@ -6365,7 +6365,7 @@ msgstr "रीपोस्ट"
#: src/view/com/util/post-ctrls/RepostButton.tsx:74 #: src/view/com/util/post-ctrls/RepostButton.tsx:74
msgid "Repost ({0, plural, one {# repost} other {# reposts}})" msgid "Repost ({0, plural, one {# repost} other {# reposts}})"
msgstr "" msgstr "रीपोस्ट करें ({0, plural, one {# रीपोस्ट} other {# रीपोस्ट}})"
#: src/screens/StarterPack/StarterPackScreen.tsx:548 #: src/screens/StarterPack/StarterPackScreen.tsx:548
#: src/view/com/util/post-ctrls/RepostButton.tsx:148 #: src/view/com/util/post-ctrls/RepostButton.tsx:148
@@ -6637,15 +6637,15 @@ msgstr "खोजें"
#: src/components/ProgressGuide/FollowDialog.tsx:745 #: src/components/ProgressGuide/FollowDialog.tsx:745
msgid "Search by name or interest" msgid "Search by name or interest"
msgstr "" msgstr "नाम या दिलचस्पी से खोजें"
#: src/view/screens/Feeds.tsx:441 #: src/view/screens/Feeds.tsx:441
msgid "Search feeds" msgid "Search feeds"
msgstr "" msgstr "फ़ीड खोजें"
#: src/components/ProgressGuide/FollowDialog.tsx:575 #: src/components/ProgressGuide/FollowDialog.tsx:575
msgid "Search for \"{interestsDisplayName}\"{activeText}" msgid "Search for \"{interestsDisplayName}\"{activeText}"
msgstr "" msgstr "\"{interestsDisplayName}\"{activeText} खोजें"
#: src/view/shell/desktop/Search.tsx:201 #: src/view/shell/desktop/Search.tsx:201
msgid "Search for \"{query}\"" msgid "Search for \"{query}\""
@@ -6716,7 +6716,7 @@ msgstr "यह गाइड देखें"
#: src/view/com/util/post-embeds/VideoEmbedInner/web-controls/Scrubber.tsx:194 #: src/view/com/util/post-embeds/VideoEmbedInner/web-controls/Scrubber.tsx:194
msgid "Seek slider. Use the arrow keys to seek forwards and backwards, and space to play/pause" msgid "Seek slider. Use the arrow keys to seek forwards and backwards, and space to play/pause"
msgstr "" msgstr "सीक स्लाइडर। एरो की से आगे और पीछे सीक करें, और स्पेस से चालू/बंद करें"
#: src/view/com/util/Selector.tsx:107 #: src/view/com/util/Selector.tsx:107
#~ msgid "Select {item}" #~ msgid "Select {item}"
@@ -6909,7 +6909,7 @@ msgstr "सर्वर पता"
#: src/screens/Settings/AppIconSettings/index.tsx:178 #: src/screens/Settings/AppIconSettings/index.tsx:178
msgid "Set app icon to {0}" msgid "Set app icon to {0}"
msgstr "" msgstr "ऐप आइकॉन को {0} करें"
#: src/screens/Moderation/index.tsx:290 #: src/screens/Moderation/index.tsx:290
msgid "Set birthdate" msgid "Set birthdate"
@@ -7030,7 +7030,7 @@ msgstr "QR कोड साझा करें"
#: src/screens/Profile/components/ProfileFeedHeader.tsx:470 #: src/screens/Profile/components/ProfileFeedHeader.tsx:470
msgid "Share this feed" msgid "Share this feed"
msgstr "" msgstr "इस फ़ीड को साझा करें"
#: src/screens/StarterPack/StarterPackScreen.tsx:416 #: src/screens/StarterPack/StarterPackScreen.tsx:416
msgid "Share this starter pack" msgid "Share this starter pack"
@@ -7129,11 +7129,11 @@ msgstr "जवाब दिखाएँ"
#: src/view/com/post-thread/PostThread.tsx:622 #: src/view/com/post-thread/PostThread.tsx:622
msgid "Show replies as" msgid "Show replies as"
msgstr "" msgstr "जवाबों को ऐसे दिखाएँ"
#: src/screens/Settings/ThreadPreferences.tsx:151 #: src/screens/Settings/ThreadPreferences.tsx:151
msgid "Show replies as threaded" msgid "Show replies as threaded"
msgstr "" msgstr "जवाबों को थ्रेड में दिखाएँ"
#: src/screens/Settings/ThreadPreferences.tsx:126 #: src/screens/Settings/ThreadPreferences.tsx:126
msgid "Show replies by people you follow before all other replies" msgid "Show replies by people you follow before all other replies"
@@ -7334,7 +7334,7 @@ msgstr "कोई गड़बड़ हुई!"
#: src/screens/Profile/components/ProfileFeedHeader.tsx:538 #: src/screens/Profile/components/ProfileFeedHeader.tsx:538
msgid "Something wrong? Let us know." msgid "Something wrong? Let us know."
msgstr "" msgstr "कुछ गड़बड़ है? हमें बताएँ।"
#: src/App.native.tsx:122 #: src/App.native.tsx:122
#: src/App.web.tsx:97 #: src/App.web.tsx:97
@@ -7390,12 +7390,12 @@ msgstr "नया बातचीत शुरू करें"
#: src/view/screens/ProfileList.tsx:817 #: src/view/screens/ProfileList.tsx:817
#: src/view/screens/ProfileList.tsx:938 #: src/view/screens/ProfileList.tsx:938
msgid "Start adding people" msgid "Start adding people"
msgstr "" msgstr "लोगों को जोड़ना शुरू करें"
#: src/view/screens/ProfileList.tsx:824 #: src/view/screens/ProfileList.tsx:824
#: src/view/screens/ProfileList.tsx:945 #: src/view/screens/ProfileList.tsx:945
msgid "Start adding people!" msgid "Start adding people!"
msgstr "" msgstr "लोगों को जोड़ना शुरू करें!"
#: src/components/dms/dialogs/SearchablePeopleList.tsx:353 #: src/components/dms/dialogs/SearchablePeopleList.tsx:353
msgid "Start chat with {displayName}" msgid "Start chat with {displayName}"
@@ -7413,7 +7413,7 @@ msgstr "{0} द्वारा स्टार्टर पैक"
#: src/view/com/profile/ProfileSubpageHeader.tsx:182 #: src/view/com/profile/ProfileSubpageHeader.tsx:182
msgid "Starter pack by <0/>" msgid "Starter pack by <0/>"
msgstr "" msgstr "<0/> द्वारा स्टार्टर पैक"
#: src/components/StarterPack/StarterPackCard.tsx:80 #: src/components/StarterPack/StarterPackCard.tsx:80
#: src/view/com/profile/ProfileSubpageHeader.tsx:180 #: src/view/com/profile/ProfileSubpageHeader.tsx:180
@@ -7560,12 +7560,12 @@ msgstr "केवल टैग"
#: src/screens/Settings/AppIconSettings/index.tsx:216 #: src/screens/Settings/AppIconSettings/index.tsx:216
msgid "Tap to change app icon" msgid "Tap to change app icon"
msgstr "" msgstr "ऐप आइकॉन बदलने के लिए टैप करें"
#: src/view/com/composer/text-input/web/EmojiPicker.web.tsx:138 #: src/view/com/composer/text-input/web/EmojiPicker.web.tsx:138
#: src/view/com/composer/text-input/web/EmojiPicker.web.tsx:174 #: src/view/com/composer/text-input/web/EmojiPicker.web.tsx:174
msgid "Tap to close the emoji picker" msgid "Tap to close the emoji picker"
msgstr "" msgstr "इमोजी चयन बंद करने के लिए टैप करें"
#: src/components/ProgressGuide/Toast.tsx:156 #: src/components/ProgressGuide/Toast.tsx:156
msgid "Tap to dismiss" msgid "Tap to dismiss"
@@ -7590,7 +7590,7 @@ msgstr "पूरी छवि देखने के लिए दबाएँ"
#: src/state/shell/progress-guide.tsx:233 #: src/state/shell/progress-guide.tsx:233
msgid "Task complete - 10 follows!" msgid "Task complete - 10 follows!"
msgstr "" msgstr "कार्य समाप्त - 10 फ़ॉलो!"
#: src/state/shell/progress-guide.tsx:223 #: src/state/shell/progress-guide.tsx:223
msgid "Task complete - 10 likes!" msgid "Task complete - 10 likes!"
@@ -7693,7 +7693,7 @@ msgstr "अनअवरुद्ध करने के बाद खाता
#: src/screens/Settings/AppIconSettings/index.tsx:41 #: src/screens/Settings/AppIconSettings/index.tsx:41
#: src/screens/Settings/AppIconSettings/index.tsx:222 #: src/screens/Settings/AppIconSettings/index.tsx:222
msgid "The app will be restarted" msgid "The app will be restarted"
msgstr "" msgstr "ऐप को फिर से शुरू किया जाएगा"
#: src/components/moderation/ModerationDetailsDialog.tsx:127 #: src/components/moderation/ModerationDetailsDialog.tsx:127
#~ msgid "the author" #~ msgid "the author"
@@ -8006,7 +8006,7 @@ msgstr "<0>{0}</0> द्वारा बनाई गई इस सूची
#: src/view/screens/ProfileList.tsx:933 #: src/view/screens/ProfileList.tsx:933
msgid "This list is empty." msgid "This list is empty."
msgstr "" msgstr "यह सूची खाली है।"
#: src/screens/Profile/ErrorState.tsx:40 #: src/screens/Profile/ErrorState.tsx:40
msgid "This moderation service is unavailable. See below for more details. If this issue persists, contact us." msgid "This moderation service is unavailable. See below for more details. If this issue persists, contact us."
@@ -8105,7 +8105,7 @@ msgstr "यह आपके पोस्ट को इस क्वोट पो
#: src/view/com/post-thread/PostThread.tsx:606 #: src/view/com/post-thread/PostThread.tsx:606
#: src/view/com/post-thread/PostThread.tsx:609 #: src/view/com/post-thread/PostThread.tsx:609
msgid "Thread options" msgid "Thread options"
msgstr "" msgstr "थ्रेड विकल्प"
#: src/screens/Settings/ContentAndMediaSettings.tsx:66 #: src/screens/Settings/ContentAndMediaSettings.tsx:66
#: src/screens/Settings/ContentAndMediaSettings.tsx:69 #: src/screens/Settings/ContentAndMediaSettings.tsx:69
@@ -8119,7 +8119,7 @@ msgstr "थ्रेड प्राथमिकताएँ"
#: src/view/com/post-thread/PostThread.tsx:636 #: src/view/com/post-thread/PostThread.tsx:636
#: src/view/com/post-thread/PostThread.tsx:641 #: src/view/com/post-thread/PostThread.tsx:641
msgid "Threaded" msgid "Threaded"
msgstr "" msgstr "थ्रेड"
#: src/screens/Settings/ThreadPreferences.tsx:142 #: src/screens/Settings/ThreadPreferences.tsx:142
msgid "Threaded mode" msgid "Threaded mode"
@@ -8135,7 +8135,7 @@ msgstr "थ्रेड प्राथमिकताएँ"
#: src/view/com/util/post-embeds/VideoEmbedInner/TimeIndicator.tsx:33 #: src/view/com/util/post-embeds/VideoEmbedInner/TimeIndicator.tsx:33
msgid "Time remaining: {time} seconds" msgid "Time remaining: {time} seconds"
msgstr "" msgstr "समय बाक़ी: {time} सेकंड"
#: src/screens/Settings/components/DisableEmail2FADialog.tsx:99 #: src/screens/Settings/components/DisableEmail2FADialog.tsx:99
msgid "To disable the email 2FA method, please verify your access to the email address." msgid "To disable the email 2FA method, please verify your access to the email address."
@@ -8173,7 +8173,7 @@ msgstr "बहतरीन"
#: src/Navigation.tsx:383 #: src/Navigation.tsx:383
msgid "Topic" msgid "Topic"
msgstr "" msgstr "विषय"
#: src/view/com/modals/EditImage.tsx:272 #: src/view/com/modals/EditImage.tsx:272
#~ msgid "Transformations" #~ msgid "Transformations"
@@ -8191,7 +8191,7 @@ msgstr "अनुवाद करें"
#: src/screens/Search/components/ExploreTrendingTopics.tsx:69 #: src/screens/Search/components/ExploreTrendingTopics.tsx:69
#: src/view/shell/desktop/SidebarTrendingTopics.tsx:59 #: src/view/shell/desktop/SidebarTrendingTopics.tsx:59
msgid "Trending" msgid "Trending"
msgstr "" msgstr "रुझान"
#: src/view/com/util/error/ErrorScreen.tsx:103 #: src/view/com/util/error/ErrorScreen.tsx:103
msgctxt "action" msgctxt "action"
@@ -8285,7 +8285,7 @@ msgstr "रीपोस्ट पूर्ववत करें"
#: src/view/com/util/post-ctrls/RepostButton.tsx:68 #: src/view/com/util/post-ctrls/RepostButton.tsx:68
msgid "Undo repost ({0, plural, one {# repost} other {# reposts}})" msgid "Undo repost ({0, plural, one {# repost} other {# reposts}})"
msgstr "" msgstr "रीपोस्ट पूर्ववत करें ({0, plural, one {# रीपोस्ट} other {# रीपोस्ट}})"
#: src/view/com/profile/FollowButton.tsx:60 #: src/view/com/profile/FollowButton.tsx:60
msgctxt "action" msgctxt "action"
@@ -8307,11 +8307,11 @@ msgstr "खाता अनफ़ॉलो करें"
#: src/screens/Profile/components/ProfileFeedHeader.tsx:514 #: src/screens/Profile/components/ProfileFeedHeader.tsx:514
msgid "Unlike" msgid "Unlike"
msgstr "" msgstr "नापसंद करें"
#: src/view/com/util/post-ctrls/PostCtrls.tsx:305 #: src/view/com/util/post-ctrls/PostCtrls.tsx:305
msgid "Unlike ({0, plural, one {# like} other {# likes}})" msgid "Unlike ({0, plural, one {# like} other {# likes}})"
msgstr "" msgstr "नापसंद करें ({0, plural, one {# पसंद} other {# पसंद}})"
#: src/view/screens/ProfileFeed.tsx:576 #: src/view/screens/ProfileFeed.tsx:576
#~ msgid "Unlike this feed" #~ msgid "Unlike this feed"
@@ -8361,7 +8361,7 @@ msgstr "पिन से हटाएँ"
#: src/screens/Profile/components/ProfileFeedHeader.tsx:519 #: src/screens/Profile/components/ProfileFeedHeader.tsx:519
#: src/screens/Profile/components/ProfileFeedHeader.tsx:526 #: src/screens/Profile/components/ProfileFeedHeader.tsx:526
msgid "Unpin feed" msgid "Unpin feed"
msgstr "" msgstr "फ़ीड को पिन से हटाएँ"
#: src/screens/Profile/components/ProfileFeedHeader.tsx:309 #: src/screens/Profile/components/ProfileFeedHeader.tsx:309
#: src/screens/Profile/components/ProfileFeedHeader.tsx:311 #: src/screens/Profile/components/ProfileFeedHeader.tsx:311
@@ -8379,7 +8379,7 @@ msgstr "मॉडरेशन सूची को पिन से हटाए
#: src/screens/Profile/components/ProfileFeedHeader.tsx:164 #: src/screens/Profile/components/ProfileFeedHeader.tsx:164
msgid "Unpinned {0} from Home" msgid "Unpinned {0} from Home"
msgstr "" msgstr "{0} को होम पिन से हटाया गया"
#: src/view/screens/ProfileList.tsx:352 #: src/view/screens/ProfileList.tsx:352
msgid "Unpinned from your feeds" msgid "Unpinned from your feeds"
@@ -8404,11 +8404,11 @@ msgstr "सूची की सदस्यता छोड़ी गई"
#: src/view/com/composer/Composer.tsx:766 #: src/view/com/composer/Composer.tsx:766
msgid "Unsupported video type" msgid "Unsupported video type"
msgstr "" msgstr "असमर्थित वीडियो प्रकार"
#: src/view/com/composer/videos/SelectVideoBtn.tsx:66 #: src/view/com/composer/videos/SelectVideoBtn.tsx:66
msgid "Unsupported video type: {0}" msgid "Unsupported video type: {0}"
msgstr "" msgstr "असमर्थित वीडियो प्रकार: {0}"
#: src/view/com/composer/videos/SelectVideoBtn.tsx:72 #: src/view/com/composer/videos/SelectVideoBtn.tsx:72
#~ msgid "Unsupported video type: {mimeType}" #~ msgid "Unsupported video type: {mimeType}"
@@ -8815,7 +8815,7 @@ msgstr "साइट पर जाएँ"
#: src/view/com/util/post-embeds/VideoEmbedInner/web-controls/VolumeControl.tsx:80 #: src/view/com/util/post-embeds/VideoEmbedInner/web-controls/VolumeControl.tsx:80
msgid "Volume" msgid "Volume"
msgstr "" msgstr "वॉल्यूम"
#: src/components/moderation/LabelPreference.tsx:136 #: src/components/moderation/LabelPreference.tsx:136
#: src/lib/moderation/useLabelBehaviorDescription.ts:17 #: src/lib/moderation/useLabelBehaviorDescription.ts:17
@@ -8837,7 +8837,7 @@ msgstr "हमें इस हैशटैग के लिए कोई पर
#: src/screens/Topic.tsx:178 #: src/screens/Topic.tsx:178
msgid "We couldn't find any results for that topic." msgid "We couldn't find any results for that topic."
msgstr "" msgstr "उस विषय से जुड़े हमें कोई परिणाम नहीं मिले।"
#: src/screens/Messages/Conversation.tsx:103 #: src/screens/Messages/Conversation.tsx:103
msgid "We couldn't load this conversation" msgid "We couldn't load this conversation"
@@ -8951,7 +8951,7 @@ msgstr "आप अपने स्टार्टर पैक को क्य
#: src/screens/Search/components/ExploreTrendingTopics.tsx:79 #: src/screens/Search/components/ExploreTrendingTopics.tsx:79
msgid "What people are posting about." msgid "What people are posting about."
msgstr "" msgstr "किसके बारे में लोग पोस्ट कर रहे हैं।"
#: src/view/com/auth/SplashScreen.tsx:38 #: src/view/com/auth/SplashScreen.tsx:38
#: src/view/com/auth/SplashScreen.web.tsx:99 #: src/view/com/auth/SplashScreen.web.tsx:99
@@ -9114,7 +9114,7 @@ msgstr "आप लॉग इन जारी रखने के लिए अ
#: src/screens/Search/components/ExploreTrendingTopics.tsx:136 #: src/screens/Search/components/ExploreTrendingTopics.tsx:136
#: src/view/shell/desktop/SidebarTrendingTopics.tsx:109 #: src/view/shell/desktop/SidebarTrendingTopics.tsx:109
msgid "You can update this later from your settings." msgid "You can update this later from your settings."
msgstr "" msgstr "आप इसे बाद में अपने सेटिंग में बदल सकते हैं।"
#: src/view/com/profile/ProfileFollowers.tsx:94 #: src/view/com/profile/ProfileFollowers.tsx:94
msgid "You do not have any followers." msgid "You do not have any followers."
@@ -9348,7 +9348,7 @@ msgstr "आपने इस पोस्ट में से एक शब्द
#: src/state/shell/progress-guide.tsx:234 #: src/state/shell/progress-guide.tsx:234
msgid "You've found some people to follow" msgid "You've found some people to follow"
msgstr "" msgstr "आपने फ़ॉलो करने के लिए कुछ लोगों को ढूँढा है"
#: src/view/com/posts/FollowingEndOfFeed.tsx:44 #: src/view/com/posts/FollowingEndOfFeed.tsx:44
msgid "You've reached the end of your feed! Find some more accounts to follow." msgid "You've reached the end of your feed! Find some more accounts to follow."
@@ -9396,7 +9396,7 @@ msgstr "आपका चयन सहेजा जाएगा, पर सेट
#: src/screens/Settings/components/ChangeHandleDialog.tsx:496 #: src/screens/Settings/components/ChangeHandleDialog.tsx:496
msgid "Your current handle <0>{0}</0> will automatically remain reserved for you. You can switch back to it at any time from this account." msgid "Your current handle <0>{0}</0> will automatically remain reserved for you. You can switch back to it at any time from this account."
msgstr "" msgstr "आपका वर्तमान हैंडल <0>{0}</0> आपके लिए आरक्षित रहेगा। आप इस खाते से कभी भी उस हैंडल पर वापस जा सकते हैं।"
#: src/screens/Login/ForgotPasswordForm.tsx:51 #: src/screens/Login/ForgotPasswordForm.tsx:51
#: src/screens/Signup/state.ts:203 #: src/screens/Signup/state.ts:203
File diff suppressed because it is too large Load Diff
+152 -152
View File
@@ -8,8 +8,8 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: Italian localization\n" "Project-Id-Version: Italian localization\n"
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2025-01-24 00:43+0000\n" "POT-Creation-Date: 2025-02-04 00:43+0000\n"
"PO-Revision-Date: 2025-01-24 17:53+0000\n" "PO-Revision-Date: 2025-02-04 07:28+0000\n"
"Last-Translator: Michele Locati <michele@locati.it>, 2025\n" "Last-Translator: Michele Locati <michele@locati.it>, 2025\n"
"Language-Team: Italian (https://app.transifex.com/mlocati/teams/201833/it/)\n" "Language-Team: Italian (https://app.transifex.com/mlocati/teams/201833/it/)\n"
"Language: it\n" "Language: it\n"
@@ -23,7 +23,7 @@ msgstr ""
msgid "(active)" msgid "(active)"
msgstr "(attivo)" msgstr "(attivo)"
#: src/screens/Messages/components/ChatListItem.tsx:139 #: src/screens/Messages/components/ChatListItem.tsx:145
msgid "(contains embedded content)" msgid "(contains embedded content)"
msgstr "(contiene allegati)" msgstr "(contiene allegati)"
@@ -374,9 +374,9 @@ msgstr "7 giorni"
#: src/screens/Settings/Settings.tsx:215 #: src/screens/Settings/Settings.tsx:215
#: src/screens/Settings/Settings.tsx:218 #: src/screens/Settings/Settings.tsx:218
msgid "About" msgid "About"
msgstr "Informazioni su" msgstr "Risorse aggiuntive"
#: src/view/screens/Search/Search.tsx:858 #: src/view/screens/Search/Search.tsx:864
msgid "Access navigation links and settings" msgid "Access navigation links and settings"
msgstr "Accedi alle impostazioni di navigazione" msgstr "Accedi alle impostazioni di navigazione"
@@ -728,10 +728,10 @@ msgstr "Si è verificato un problema nell'aprire la chat"
#: src/components/hooks/useFollowMethods.ts:35 #: src/components/hooks/useFollowMethods.ts:35
#: src/components/hooks/useFollowMethods.ts:50 #: src/components/hooks/useFollowMethods.ts:50
#: src/components/ProfileCard.tsx:330 #: src/components/ProfileCard.tsx:333
#: src/components/ProfileCard.tsx:351 #: src/components/ProfileCard.tsx:354
#: src/view/com/profile/FollowButton.tsx:35 #: src/view/com/profile/FollowButton.tsx:38
#: src/view/com/profile/FollowButton.tsx:45 #: src/view/com/profile/FollowButton.tsx:48
msgid "An issue occurred, please try again." msgid "An issue occurred, please try again."
msgstr "Si è verificato un problema, riprova." msgstr "Si è verificato un problema, riprova."
@@ -928,7 +928,7 @@ msgstr "Le opzioni di riproduzione automatica sono state spostate nelle <0>impos
msgid "Autoplay videos and GIFs" msgid "Autoplay videos and GIFs"
msgstr "Riproduci automaticamente video e GIF" msgstr "Riproduci automaticamente video e GIF"
#: src/components/dms/MessagesListHeader.tsx:74 #: src/components/dms/MessagesListHeader.tsx:81
#: src/components/moderation/LabelsOnMeDialog.tsx:290 #: src/components/moderation/LabelsOnMeDialog.tsx:290
#: src/components/moderation/LabelsOnMeDialog.tsx:291 #: src/components/moderation/LabelsOnMeDialog.tsx:291
#: src/screens/Login/ChooseAccountForm.tsx:90 #: src/screens/Login/ChooseAccountForm.tsx:90
@@ -962,7 +962,7 @@ msgstr "Prima di creare uno starter pack, devi verificare la tua email."
#: src/components/dms/dialogs/NewChatDialog.tsx:79 #: src/components/dms/dialogs/NewChatDialog.tsx:79
#: src/components/dms/MessageProfileButton.tsx:89 #: src/components/dms/MessageProfileButton.tsx:89
#: src/screens/Messages/Conversation.tsx:209 #: src/screens/Messages/Conversation.tsx:204
msgid "Before you may message another user, you must first verify your email." msgid "Before you may message another user, you must first verify your email."
msgstr "Prima di poter inviare un messaggio a un altro utente, devi verificare la tua email." msgstr "Prima di poter inviare un messaggio a un altro utente, devi verificare la tua email."
@@ -971,7 +971,7 @@ msgstr "Prima di poter inviare un messaggio a un altro utente, devi verificare l
msgid "BETA" msgid "BETA"
msgstr "BETA" msgstr "BETA"
#: src/components/dialogs/BirthDateSettings.tsx:106 #: src/components/dialogs/BirthDateSettings.tsx:102
#: src/screens/Settings/AccountSettings.tsx:109 #: src/screens/Settings/AccountSettings.tsx:109
msgid "Birthday" msgid "Birthday"
msgstr "Compleanno" msgstr "Compleanno"
@@ -982,8 +982,8 @@ msgstr "Compleanno"
msgid "Block" msgid "Block"
msgstr "Blocca" msgstr "Blocca"
#: src/components/dms/ConvoMenu.tsx:191 #: src/components/dms/ConvoMenu.tsx:250
#: src/components/dms/ConvoMenu.tsx:195 #: src/components/dms/ConvoMenu.tsx:253
#: src/view/com/util/forms/PostDropdownBtnMenuItems.tsx:603 #: src/view/com/util/forms/PostDropdownBtnMenuItems.tsx:603
#: src/view/com/util/forms/PostDropdownBtnMenuItems.tsx:605 #: src/view/com/util/forms/PostDropdownBtnMenuItems.tsx:605
msgid "Block account" msgid "Block account"
@@ -1070,8 +1070,8 @@ msgstr "Il blocco non impedirà l'applicazione delle etichette al tuo account, m
msgid "Blog" msgid "Blog"
msgstr "Blog" msgstr "Blog"
#: src/view/com/auth/server-input/index.tsx:92 #: src/view/com/auth/server-input/index.tsx:132
#: src/view/com/auth/server-input/index.tsx:94 #: src/view/com/auth/server-input/index.tsx:133
msgid "Bluesky" msgid "Bluesky"
msgstr "Bluesky" msgstr "Bluesky"
@@ -1079,13 +1079,13 @@ msgstr "Bluesky"
msgid "Bluesky cannot confirm the authenticity of the claimed date." msgid "Bluesky cannot confirm the authenticity of the claimed date."
msgstr "Bluesky non può confermare l'autenticità della data dichiarata." msgstr "Bluesky non può confermare l'autenticità della data dichiarata."
#: src/view/com/auth/server-input/index.tsx:172 #: src/view/com/auth/server-input/index.tsx:208
msgid "Bluesky is an open network where you can choose your hosting provider. If you're a developer, you can host your own server." msgid "Bluesky is an open network where you can choose your hosting provider. If you're a developer, you can host your own server."
msgstr "Bluesky è una rete aperta dove puoi scegliere il fornitore che ospita i tuoi dati. Se sei uno sviluppatore, puoi utilizzare il tuo server." msgstr "Bluesky è una rete aperta dove puoi scegliere il fornitore che ospita i tuoi dati. Se sei uno sviluppatore, puoi utilizzare il tuo server."
#: src/view/com/auth/server-input/index.tsx:109 #: src/view/com/auth/server-input/index.tsx:145
msgid "Bluesky is an open network where you can choose your own provider. If you're new here, we recommend sticking with the default Bluesky Social option." msgid "Bluesky is an open network where you can choose your own provider. If you're new here, we recommend sticking with the default Bluesky Social option."
msgstr "Bluesky è una rete aperta che ti permette di scegliere il fornitore dei tuoi dati. Se sei un nuovo utente, ti consigliamo di iniziare con l'opzione predefinita Bluesky Social." msgstr "Bluesky è una rete aperta che ti permette di scegliere chi ospita i tuoi dati. Se sei un nuovo utente, ti consigliamo di iniziare con l'opzione predefinita Bluesky Social."
#: src/components/ProgressGuide/List.tsx:53 #: src/components/ProgressGuide/List.tsx:53
#: src/components/ProgressGuide/List.tsx:70 #: src/components/ProgressGuide/List.tsx:70
@@ -1094,7 +1094,7 @@ msgstr "Bluesky è meglio con gli amici!"
#: src/screens/Takendown.tsx:217 #: src/screens/Takendown.tsx:217
msgid "Bluesky Social Terms of Service" msgid "Bluesky Social Terms of Service"
msgstr "Termini di servizio di Bluesky Social" msgstr "Termini di servizio di Bluesky"
#: src/components/StarterPack/ProfileStarterPacks.tsx:299 #: src/components/StarterPack/ProfileStarterPacks.tsx:299
msgid "Bluesky will choose a set of recommended accounts from people in your network." msgid "Bluesky will choose a set of recommended accounts from people in your network."
@@ -1125,23 +1125,23 @@ msgstr "Sfoca le immagini e filtra dai feed"
msgid "Books" msgid "Books"
msgstr "Libri" msgstr "Libri"
#: src/components/FeedInterstitials.tsx:349 #: src/components/FeedInterstitials.tsx:370
msgid "Browse more accounts on the Explore page" msgid "Browse more accounts on the Explore page"
msgstr "Scopri altri account dalla Ricerca" msgstr "Scopri altri account dalla Ricerca"
#: src/components/FeedInterstitials.tsx:486 #: src/components/FeedInterstitials.tsx:507
msgid "Browse more feeds on the Explore page" msgid "Browse more feeds on the Explore page"
msgstr "Scopri nuovi feed dalla Ricerca" msgstr "Scopri nuovi feed dalla Ricerca"
#: src/components/FeedInterstitials.tsx:330 #: src/components/FeedInterstitials.tsx:351
#: src/components/FeedInterstitials.tsx:333 #: src/components/FeedInterstitials.tsx:354
#: src/components/FeedInterstitials.tsx:467 #: src/components/FeedInterstitials.tsx:488
#: src/components/FeedInterstitials.tsx:470 #: src/components/FeedInterstitials.tsx:491
msgid "Browse more suggestions" msgid "Browse more suggestions"
msgstr "Scopri nuovi suggerimenti" msgstr "Scopri nuovi suggerimenti"
#: src/components/FeedInterstitials.tsx:357 #: src/components/FeedInterstitials.tsx:378
#: src/components/FeedInterstitials.tsx:495 #: src/components/FeedInterstitials.tsx:516
msgid "Browse more suggestions on the Explore page" msgid "Browse more suggestions on the Explore page"
msgstr "Scopri nuovi suggerimenti dalla Ricerca" msgstr "Scopri nuovi suggerimenti dalla Ricerca"
@@ -1218,7 +1218,7 @@ msgstr "Fotocamera"
#: src/view/com/modals/VerifyEmail.tsx:255 #: src/view/com/modals/VerifyEmail.tsx:255
#: src/view/com/modals/VerifyEmail.tsx:261 #: src/view/com/modals/VerifyEmail.tsx:261
#: src/view/com/util/post-ctrls/RepostButton.tsx:213 #: src/view/com/util/post-ctrls/RepostButton.tsx:213
#: src/view/screens/Search/Search.tsx:887 #: src/view/screens/Search/Search.tsx:893
#: src/view/shell/desktop/LeftNav.tsx:209 #: src/view/shell/desktop/LeftNav.tsx:209
msgid "Cancel" msgid "Cancel"
msgstr "Annulla" msgstr "Annulla"
@@ -1252,7 +1252,7 @@ msgid "Cancel reactivation and log out"
msgstr "Annulla la riattivazione e disconnettiti" msgstr "Annulla la riattivazione e disconnettiti"
#: src/view/com/modals/ListAddRemoveUsers.tsx:88 #: src/view/com/modals/ListAddRemoveUsers.tsx:88
#: src/view/screens/Search/Search.tsx:879 #: src/view/screens/Search/Search.tsx:885
msgid "Cancel search" msgid "Cancel search"
msgstr "Annulla la ricerca" msgstr "Annulla la ricerca"
@@ -1331,14 +1331,14 @@ msgstr "Modifica il tuo indirizzo email"
msgid "Chat" msgid "Chat"
msgstr "Messaggi" msgstr "Messaggi"
#: src/components/dms/ConvoMenu.tsx:85 #: src/components/dms/ConvoMenu.tsx:179
msgid "Chat muted" msgid "Chat muted"
msgstr "Conversazione silenziata" msgstr "Conversazione silenziata"
#: src/components/dms/ConvoMenu.tsx:115 #: src/components/dms/ConvoMenu.tsx:78
#: src/components/dms/MessageMenu.tsx:81 #: src/components/dms/MessageMenu.tsx:81
#: src/Navigation.tsx:394 #: src/Navigation.tsx:394
#: src/screens/Messages/ChatList.tsx:254 #: src/screens/Messages/ChatList.tsx:253
msgid "Chat settings" msgid "Chat settings"
msgstr "Impostazioni chat" msgstr "Impostazioni chat"
@@ -1346,7 +1346,7 @@ msgstr "Impostazioni chat"
msgid "Chat Settings" msgid "Chat Settings"
msgstr "Impostazioni chat" msgstr "Impostazioni chat"
#: src/components/dms/ConvoMenu.tsx:87 #: src/components/dms/ConvoMenu.tsx:181
msgid "Chat unmuted" msgid "Chat unmuted"
msgstr "Conversazione riattivata" msgstr "Conversazione riattivata"
@@ -1391,12 +1391,12 @@ msgstr "Scegli gli algoritmi che compilano i tuoi feed personalizzati."
msgid "Choose this color as your avatar" msgid "Choose this color as your avatar"
msgstr "Scegli questo colore per il tuo avatar" msgstr "Scegli questo colore per il tuo avatar"
#: src/view/com/auth/server-input/index.tsx:86 #: src/view/com/auth/server-input/index.tsx:126
msgid "Choose your account provider" msgid "Choose your account provider"
msgstr "Seleziona il fornitore del tuo account" msgstr "Scegli il fornitore del tuo account"
#: src/view/screens/Feeds.tsx:728 #: src/view/screens/Feeds.tsx:728
#: src/view/screens/Search/Explore.tsx:424 #: src/view/screens/Search/Explore.tsx:427
msgid "Choose your own timeline! Feeds built by the community help you find content you love." msgid "Choose your own timeline! Feeds built by the community help you find content you love."
msgstr "Personalizza la tua cronologia! I feed creati dalla collettività ti permettono di scoprire i contenuti di tuo interesse." msgstr "Personalizza la tua cronologia! I feed creati dalla collettività ti permettono di scoprire i contenuti di tuo interesse."
@@ -1547,7 +1547,7 @@ msgstr "Linee guida della community"
#: src/screens/Onboarding/StepFinished.tsx:300 #: src/screens/Onboarding/StepFinished.tsx:300
msgid "Complete onboarding and start using your account" msgid "Complete onboarding and start using your account"
msgstr "Completa l'incorporazione e inizia a usare il tuo account" msgstr "Completa la registrazione e inizia a usare il tuo account"
#: src/screens/Signup/index.tsx:144 #: src/screens/Signup/index.tsx:144
msgid "Complete the challenge" msgid "Complete the challenge"
@@ -1700,7 +1700,7 @@ msgstr "Continua thread..."
msgid "Continue to next step" msgid "Continue to next step"
msgstr "Vai al passaggio successivo" msgstr "Vai al passaggio successivo"
#: src/screens/Messages/components/ChatListItem.tsx:173 #: src/screens/Messages/components/ChatListItem.tsx:179
msgid "Conversation deleted" msgid "Conversation deleted"
msgstr "Conversazione eliminata" msgstr "Conversazione eliminata"
@@ -1807,7 +1807,7 @@ msgstr "Non è stato possibile caricare il feed"
msgid "Could not load list" msgid "Could not load list"
msgstr "Non è stato possibile caricare la lista" msgstr "Non è stato possibile caricare la lista"
#: src/components/dms/ConvoMenu.tsx:91 #: src/components/dms/ConvoMenu.tsx:185
msgid "Could not mute chat" msgid "Could not mute chat"
msgstr "Errore nel silenziare la conversazione" msgstr "Errore nel silenziare la conversazione"
@@ -1842,7 +1842,7 @@ msgstr "Crea uno starter pack per me"
#: src/view/shell/NavSignupCard.tsx:47 #: src/view/shell/NavSignupCard.tsx:47
#: src/view/shell/NavSignupCard.tsx:52 #: src/view/shell/NavSignupCard.tsx:52
msgid "Create account" msgid "Create account"
msgstr "Crea un account" msgstr "Crea account"
#: src/screens/Signup/index.tsx:93 #: src/screens/Signup/index.tsx:93
msgid "Create Account" msgid "Create Account"
@@ -1883,8 +1883,8 @@ msgstr "L'autore è stato bloccato"
msgid "Culture" msgid "Culture"
msgstr "Cultura" msgstr "Cultura"
#: src/view/com/auth/server-input/index.tsx:100 #: src/view/com/auth/server-input/index.tsx:138
#: src/view/com/auth/server-input/index.tsx:102 #: src/view/com/auth/server-input/index.tsx:139
msgid "Custom" msgid "Custom"
msgstr "Personalizzato" msgstr "Personalizzato"
@@ -1897,7 +1897,7 @@ msgstr "Personalizza chi può interagire con questo post."
msgid "Dark" msgid "Dark"
msgstr "Scuro" msgstr "Scuro"
#: src/view/screens/Debug.tsx:70 #: src/view/screens/Debug.tsx:69
msgid "Dark mode" msgid "Dark mode"
msgstr "Aspetto scuro" msgstr "Aspetto scuro"
@@ -1919,7 +1919,7 @@ msgstr "Disattiva account"
msgid "Debug Moderation" msgid "Debug Moderation"
msgstr "Eliminare errori nella Moderazione" msgstr "Eliminare errori nella Moderazione"
#: src/view/screens/Debug.tsx:90 #: src/view/screens/Debug.tsx:89
msgid "Debug panel" msgid "Debug panel"
msgstr "Pannello per il debug" msgstr "Pannello per il debug"
@@ -2018,8 +2018,8 @@ msgstr "Eliminare questo post?"
msgid "Deleted" msgid "Deleted"
msgstr "Eliminato" msgstr "Eliminato"
#: src/components/dms/MessagesListHeader.tsx:148 #: src/components/dms/MessagesListHeader.tsx:154
#: src/screens/Messages/components/ChatListItem.tsx:107 #: src/screens/Messages/components/ChatListItem.tsx:113
msgid "Deleted Account" msgid "Deleted Account"
msgstr "Account eliminato" msgstr "Account eliminato"
@@ -2120,7 +2120,7 @@ msgstr "Scoraggia le app dal mostrare il mio account agli utenti disconnessi"
msgid "Discover new custom feeds" msgid "Discover new custom feeds"
msgstr "Scopri nuovi feed personalizzati" msgstr "Scopri nuovi feed personalizzati"
#: src/view/screens/Search/Explore.tsx:422 #: src/view/screens/Search/Explore.tsx:425
msgid "Discover new feeds" msgid "Discover new feeds"
msgstr "Scopri nuovi feed" msgstr "Scopri nuovi feed"
@@ -2189,17 +2189,17 @@ msgstr "Non inizia o termina con un trattino"
msgid "Domain verified!" msgid "Domain verified!"
msgstr "Dominio verificato!" msgstr "Dominio verificato!"
#: src/components/dialogs/BirthDateSettings.tsx:118 #: src/components/dialogs/BirthDateSettings.tsx:114
#: src/components/dialogs/BirthDateSettings.tsx:124 #: src/components/dialogs/BirthDateSettings.tsx:120
#: src/components/dms/ReportDialog.tsx:323 #: src/components/dms/ReportDialog.tsx:323
#: src/components/forms/DateField/index.tsx:77 #: src/components/forms/DateField/index.tsx:87
#: src/components/forms/DateField/index.tsx:83 #: src/components/forms/DateField/index.tsx:93
#: src/screens/Onboarding/StepProfile/index.tsx:330 #: src/screens/Onboarding/StepProfile/index.tsx:330
#: src/screens/Onboarding/StepProfile/index.tsx:333 #: src/screens/Onboarding/StepProfile/index.tsx:333
#: src/screens/Settings/components/AddAppPasswordDialog.tsx:215 #: src/screens/Settings/components/AddAppPasswordDialog.tsx:215
#: src/screens/Settings/components/AddAppPasswordDialog.tsx:222 #: src/screens/Settings/components/AddAppPasswordDialog.tsx:222
#: src/view/com/auth/server-input/index.tsx:192 #: src/view/com/auth/server-input/index.tsx:228
#: src/view/com/auth/server-input/index.tsx:193 #: src/view/com/auth/server-input/index.tsx:229
#: src/view/com/composer/labels/LabelsBtn.tsx:224 #: src/view/com/composer/labels/LabelsBtn.tsx:224
#: src/view/com/composer/labels/LabelsBtn.tsx:231 #: src/view/com/composer/labels/LabelsBtn.tsx:231
#: src/view/com/composer/videos/SubtitleDialog.tsx:169 #: src/view/com/composer/videos/SubtitleDialog.tsx:169
@@ -2226,7 +2226,7 @@ msgstr "Fatto{extraText}"
msgid "Double tap to close the dialog" msgid "Double tap to close the dialog"
msgstr "Tocca due volte per chiudere la finestra" msgstr "Tocca due volte per chiudere la finestra"
#: src/screens/VideoFeed/index.tsx:1037 #: src/screens/VideoFeed/index.tsx:1039
msgid "Double tap to like" msgid "Double tap to like"
msgstr "Tocca due volte per mettere mi piace" msgstr "Tocca due volte per mettere mi piace"
@@ -2550,7 +2550,7 @@ msgstr "Inserisci il dominio che vuoi usare"
msgid "Enter the email you used to create your account. We'll send you a \"reset code\" so you can set a new password." msgid "Enter the email you used to create your account. We'll send you a \"reset code\" so you can set a new password."
msgstr "Inserisci l'email che hai usato per creare il tuo account. Ti invieremo un codice in modo che tu possa scegliere una nuova password." msgstr "Inserisci l'email che hai usato per creare il tuo account. Ti invieremo un codice in modo che tu possa scegliere una nuova password."
#: src/components/dialogs/BirthDateSettings.tsx:107 #: src/components/dialogs/BirthDateSettings.tsx:103
msgid "Enter your birth date" msgid "Enter your birth date"
msgstr "Inserisci la tua data di nascita" msgstr "Inserisci la tua data di nascita"
@@ -2738,8 +2738,8 @@ msgstr "Non è stato possibile eliminare il post, riprovare"
msgid "Failed to delete starter pack" msgid "Failed to delete starter pack"
msgstr "Impossibile eliminare lo starter pack" msgstr "Impossibile eliminare lo starter pack"
#: src/view/screens/Search/Explore.tsx:460 #: src/view/screens/Search/Explore.tsx:463
#: src/view/screens/Search/Explore.tsx:488 #: src/view/screens/Search/Explore.tsx:491
msgid "Failed to load feeds preferences" msgid "Failed to load feeds preferences"
msgstr "Impossibile caricare preferenze feed" msgstr "Impossibile caricare preferenze feed"
@@ -2751,12 +2751,12 @@ msgstr "Impossibile caricare GIF"
msgid "Failed to load past messages" msgid "Failed to load past messages"
msgstr "Impossibile caricare messaggi vecchi" msgstr "Impossibile caricare messaggi vecchi"
#: src/view/screens/Search/Explore.tsx:453 #: src/view/screens/Search/Explore.tsx:456
#: src/view/screens/Search/Explore.tsx:481 #: src/view/screens/Search/Explore.tsx:484
msgid "Failed to load suggested feeds" msgid "Failed to load suggested feeds"
msgstr "Impossibile caricare feed consigliati" msgstr "Impossibile caricare feed consigliati"
#: src/view/screens/Search/Explore.tsx:411 #: src/view/screens/Search/Explore.tsx:414
msgid "Failed to load suggested follows" msgid "Failed to load suggested follows"
msgstr "Impossibile caricare follow consigliati" msgstr "Impossibile caricare follow consigliati"
@@ -2897,16 +2897,16 @@ msgid "Flexible"
msgstr "Flessibile" msgstr "Flessibile"
#. User is not following this account, click to follow #. User is not following this account, click to follow
#: src/components/ProfileCard.tsx:363 #: src/components/ProfileCard.tsx:366
#: src/components/ProfileHoverCard/index.web.tsx:449 #: src/components/ProfileHoverCard/index.web.tsx:449
#: src/components/ProfileHoverCard/index.web.tsx:460 #: src/components/ProfileHoverCard/index.web.tsx:460
#: src/screens/Profile/Header/ProfileHeaderStandard.tsx:234 #: src/screens/Profile/Header/ProfileHeaderStandard.tsx:234
#: src/screens/VideoFeed/index.tsx:819 #: src/screens/VideoFeed/index.tsx:821
#: src/view/com/post-thread/PostThreadFollowBtn.tsx:132 #: src/view/com/post-thread/PostThreadFollowBtn.tsx:132
msgid "Follow" msgid "Follow"
msgstr "Segui" msgstr "Segui"
#: src/view/com/profile/FollowButton.tsx:69 #: src/view/com/profile/FollowButton.tsx:72
msgctxt "action" msgctxt "action"
msgid "Follow" msgid "Follow"
msgstr "Segui" msgstr "Segui"
@@ -2916,7 +2916,7 @@ msgstr "Segui"
msgid "Follow {0}" msgid "Follow {0}"
msgstr "Segui {0}" msgstr "Segui {0}"
#: src/screens/VideoFeed/index.tsx:798 #: src/screens/VideoFeed/index.tsx:800
msgid "Follow {handle}" msgid "Follow {handle}"
msgstr "Segui {handle}" msgstr "Segui {handle}"
@@ -2948,14 +2948,14 @@ msgstr "Segui tutti"
msgid "Follow Back" msgid "Follow Back"
msgstr "Ricambia follow" msgstr "Ricambia follow"
#: src/view/com/profile/FollowButton.tsx:78 #: src/view/com/profile/FollowButton.tsx:81
msgctxt "action" msgctxt "action"
msgid "Follow Back" msgid "Follow Back"
msgstr "Segui anche tu" msgstr "Segui anche tu"
#: src/view/screens/Search/Explore.tsx:368 #: src/view/screens/Search/Explore.tsx:370
msgid "Follow more accounts to get connected to your interests and build your network." msgid "Follow more accounts to get connected to your interests and build your network."
msgstr "Segui altri account per connetterti ai tuoi interessi e crea il tuo network personale." msgstr "Segui altri account per connetterti ai tuoi interessi e creare la tua rete personale."
#: src/components/KnownFollowers.tsx:232 #: src/components/KnownFollowers.tsx:232
msgid "Followed by <0>{0}</0>" msgid "Followed by <0>{0}</0>"
@@ -2987,23 +2987,23 @@ msgid "Followers you know"
msgstr "Follower che conosci" msgstr "Follower che conosci"
#. User is following this account, click to unfollow #. User is following this account, click to unfollow
#: src/components/ProfileCard.tsx:357 #: src/components/ProfileCard.tsx:360
#: src/components/ProfileHoverCard/index.web.tsx:448 #: src/components/ProfileHoverCard/index.web.tsx:448
#: src/components/ProfileHoverCard/index.web.tsx:459 #: src/components/ProfileHoverCard/index.web.tsx:459
#: src/screens/Profile/Header/ProfileHeaderStandard.tsx:230 #: src/screens/Profile/Header/ProfileHeaderStandard.tsx:230
#: src/screens/VideoFeed/index.tsx:817 #: src/screens/VideoFeed/index.tsx:819
#: src/view/com/post-thread/PostThreadFollowBtn.tsx:135 #: src/view/com/post-thread/PostThreadFollowBtn.tsx:135
#: src/view/screens/Feeds.tsx:599 #: src/view/screens/Feeds.tsx:599
#: src/view/screens/SavedFeeds.tsx:422 #: src/view/screens/SavedFeeds.tsx:422
msgid "Following" msgid "Following"
msgstr "Following" msgstr "Following"
#: src/components/ProfileCard.tsx:321 #: src/components/ProfileCard.tsx:323
#: src/screens/Profile/Header/ProfileHeaderStandard.tsx:98 #: src/screens/Profile/Header/ProfileHeaderStandard.tsx:98
msgid "Following {0}" msgid "Following {0}"
msgstr "Stai seguendo {0}" msgstr "Stai seguendo {0}"
#: src/screens/VideoFeed/index.tsx:797 #: src/screens/VideoFeed/index.tsx:799
msgid "Following {handle}" msgid "Following {handle}"
msgstr "Stai seguendo {handle}" msgstr "Stai seguendo {handle}"
@@ -3122,8 +3122,8 @@ msgstr "Evidenti violazioni della legge o dei termini di servizio"
#: src/components/moderation/ScreenHider.tsx:163 #: src/components/moderation/ScreenHider.tsx:163
#: src/screens/Profile/ProfileFeed/index.tsx:89 #: src/screens/Profile/ProfileFeed/index.tsx:89
#: src/screens/VideoFeed/components/Header.tsx:163 #: src/screens/VideoFeed/components/Header.tsx:163
#: src/screens/VideoFeed/index.tsx:1098 #: src/screens/VideoFeed/index.tsx:1100
#: src/screens/VideoFeed/index.tsx:1102 #: src/screens/VideoFeed/index.tsx:1104
#: src/view/com/auth/LoggedOut.tsx:72 #: src/view/com/auth/LoggedOut.tsx:72
#: src/view/screens/NotFound.tsx:57 #: src/view/screens/NotFound.tsx:57
#: src/view/screens/ProfileList.tsx:1009 #: src/view/screens/ProfileList.tsx:1009
@@ -3166,7 +3166,7 @@ msgstr "Vai alla home"
msgid "Go Home" msgid "Go Home"
msgstr "Vai alla home" msgstr "Vai alla home"
#: src/screens/Messages/components/ChatListItem.tsx:274 #: src/screens/Messages/components/ChatListItem.tsx:282
msgid "Go to conversation with {0}" msgid "Go to conversation with {0}"
msgstr "Vai alla conversazione con {0}" msgstr "Vai alla conversazione con {0}"
@@ -3175,11 +3175,11 @@ msgstr "Vai alla conversazione con {0}"
msgid "Go to next" msgid "Go to next"
msgstr "Prosegui" msgstr "Prosegui"
#: src/components/dms/ConvoMenu.tsx:170 #: src/components/dms/ConvoMenu.tsx:230
msgid "Go to profile" msgid "Go to profile"
msgstr "Vai al profilo" msgstr "Vai al profilo"
#: src/components/dms/ConvoMenu.tsx:167 #: src/components/dms/ConvoMenu.tsx:227
msgid "Go to user's profile" msgid "Go to user's profile"
msgstr "Vai al profilo dell'utente" msgstr "Vai al profilo dell'utente"
@@ -3439,7 +3439,7 @@ msgstr "Se rimuovi questo post, non potrai recuperarlo."
msgid "If you want to change your password, we will send you a code to verify that this is your account." msgid "If you want to change your password, we will send you a code to verify that this is your account."
msgstr "Se vuoi modificare la password, ti invieremo un codice per verificare che questo è il tuo account." msgstr "Se vuoi modificare la password, ti invieremo un codice per verificare che questo è il tuo account."
#: src/view/com/auth/server-input/index.tsx:168 #: src/view/com/auth/server-input/index.tsx:204
msgid "If you're a developer, you can host your own server." msgid "If you're a developer, you can host your own server."
msgstr "Se sei uno sviluppatore, puoi utilizzare il tuo server." msgstr "Se sei uno sviluppatore, puoi utilizzare il tuo server."
@@ -3560,7 +3560,7 @@ msgstr "Inviti, ma personali"
msgid "It looks like you may have entered your email address incorrectly. Are you sure it's right?" msgid "It looks like you may have entered your email address incorrectly. Are you sure it's right?"
msgstr "Sembra che tu abbia inserito il tuo indirizzo email in modo errato. Sei sicuro che sia corretto?" msgstr "Sembra che tu abbia inserito il tuo indirizzo email in modo errato. Sei sicuro che sia corretto?"
#: src/screens/Signup/StepInfo/index.tsx:235 #: src/screens/Signup/StepInfo/index.tsx:236
msgid "It's correct" msgid "It's correct"
msgstr "È corretto" msgstr "È corretto"
@@ -3574,7 +3574,7 @@ msgstr "ID processo: {0}"
#: src/view/com/auth/SplashScreen.web.tsx:178 #: src/view/com/auth/SplashScreen.web.tsx:178
msgid "Jobs" msgid "Jobs"
msgstr "Lavora con noi" msgstr "Opportunità di lavoro"
#: src/screens/StarterPack/StarterPackLandingScreen.tsx:201 #: src/screens/StarterPack/StarterPackLandingScreen.tsx:201
#: src/screens/StarterPack/StarterPackLandingScreen.tsx:207 #: src/screens/StarterPack/StarterPackLandingScreen.tsx:207
@@ -3658,7 +3658,7 @@ msgstr "Ulteriori Informazioni"
msgid "Learn more about Bluesky" msgid "Learn more about Bluesky"
msgstr "Scopri di più su Bluesky" msgstr "Scopri di più su Bluesky"
#: src/view/com/auth/server-input/index.tsx:178 #: src/view/com/auth/server-input/index.tsx:214
msgid "Learn more about self hosting your PDS." msgid "Learn more about self hosting your PDS."
msgstr "Maggiori informazioni su come ospitare il tuo server." msgstr "Maggiori informazioni su come ospitare il tuo server."
@@ -3678,7 +3678,7 @@ msgid "Learn more about what is public on Bluesky."
msgstr "Scopri cosa è pubblico su Bluesky." msgstr "Scopri cosa è pubblico su Bluesky."
#: src/components/moderation/ContentHider.tsx:239 #: src/components/moderation/ContentHider.tsx:239
#: src/view/com/auth/server-input/index.tsx:180 #: src/view/com/auth/server-input/index.tsx:216
msgid "Learn more." msgid "Learn more."
msgstr "Saperne di più." msgstr "Saperne di più."
@@ -3686,15 +3686,15 @@ msgstr "Saperne di più."
msgid "Leave" msgid "Leave"
msgstr "Abbandona" msgstr "Abbandona"
#: src/components/dms/MessagesListBlockedFooter.tsx:66
#: src/components/dms/MessagesListBlockedFooter.tsx:73 #: src/components/dms/MessagesListBlockedFooter.tsx:73
#: src/components/dms/MessagesListBlockedFooter.tsx:80
msgid "Leave chat" msgid "Leave chat"
msgstr "Abbandona la chat" msgstr "Abbandona la chat"
#: src/components/dms/ConvoMenu.tsx:141 #: src/components/dms/ConvoMenu.tsx:206
#: src/components/dms/ConvoMenu.tsx:144 #: src/components/dms/ConvoMenu.tsx:209
#: src/components/dms/ConvoMenu.tsx:211 #: src/components/dms/ConvoMenu.tsx:269
#: src/components/dms/ConvoMenu.tsx:214 #: src/components/dms/ConvoMenu.tsx:272
#: src/components/dms/LeaveConvoPrompt.tsx:40 #: src/components/dms/LeaveConvoPrompt.tsx:40
msgid "Leave conversation" msgid "Leave conversation"
msgstr "Abbandona conversazione" msgstr "Abbandona conversazione"
@@ -3856,15 +3856,15 @@ msgstr "Liste"
msgid "Lists blocking this user:" msgid "Lists blocking this user:"
msgstr "Liste che bloccano questo utente:" msgstr "Liste che bloccano questo utente:"
#: src/view/screens/Search/Explore.tsx:134 #: src/view/screens/Search/Explore.tsx:135
msgid "Load more" msgid "Load more"
msgstr "Carica di più" msgstr "Carica di più"
#: src/view/screens/Search/Explore.tsx:223 #: src/view/screens/Search/Explore.tsx:224
msgid "Load more suggested feeds" msgid "Load more suggested feeds"
msgstr "Carica più feed consigliati" msgstr "Carica più feed consigliati"
#: src/view/screens/Search/Explore.tsx:221 #: src/view/screens/Search/Explore.tsx:222
msgid "Load more suggested follows" msgid "Load more suggested follows"
msgstr "Carica più utenti suggeriti" msgstr "Carica più utenti suggeriti"
@@ -3956,8 +3956,8 @@ msgstr "Gestisci i feed salvati"
msgid "Manage your muted words and tags" msgid "Manage your muted words and tags"
msgstr "Gestisci parole e tag silenziati" msgstr "Gestisci parole e tag silenziati"
#: src/components/dms/ConvoMenu.tsx:154 #: src/components/dms/ConvoMenu.tsx:218
#: src/components/dms/ConvoMenu.tsx:161 #: src/components/dms/ConvoMenu.tsx:221
msgid "Mark as read" msgid "Mark as read"
msgstr "Segna come letto" msgstr "Segna come letto"
@@ -3982,7 +3982,7 @@ msgid "Mentions"
msgstr "Menzioni" msgstr "Menzioni"
#: src/components/Menu/index.tsx:103 #: src/components/Menu/index.tsx:103
#: src/view/screens/Search/Search.tsx:856 #: src/view/screens/Search/Search.tsx:862
msgid "Menu" msgid "Menu"
msgstr "Menu" msgstr "Menu"
@@ -3991,7 +3991,7 @@ msgid "Message {0}"
msgstr "Messaggio {0}" msgstr "Messaggio {0}"
#: src/components/dms/MessageMenu.tsx:72 #: src/components/dms/MessageMenu.tsx:72
#: src/screens/Messages/components/ChatListItem.tsx:174 #: src/screens/Messages/components/ChatListItem.tsx:180
msgid "Message deleted" msgid "Message deleted"
msgstr "Messaggio eliminato" msgstr "Messaggio eliminato"
@@ -4009,8 +4009,8 @@ msgid "Message is too long"
msgstr "Il messaggio è troppo lungo" msgstr "Il messaggio è troppo lungo"
#: src/Navigation.tsx:618 #: src/Navigation.tsx:618
#: src/screens/Messages/ChatList.tsx:270 #: src/screens/Messages/ChatList.tsx:269
#: src/screens/Messages/ChatList.tsx:294 #: src/screens/Messages/ChatList.tsx:293
msgid "Messages" msgid "Messages"
msgstr "Messaggi" msgstr "Messaggi"
@@ -4133,8 +4133,8 @@ msgstr "Silenzia account"
msgid "Mute accounts" msgid "Mute accounts"
msgstr "Silenzia account" msgstr "Silenzia account"
#: src/components/dms/ConvoMenu.tsx:175 #: src/components/dms/ConvoMenu.tsx:235
#: src/components/dms/ConvoMenu.tsx:181 #: src/components/dms/ConvoMenu.tsx:241
msgid "Mute conversation" msgid "Mute conversation"
msgstr "Silenzia conversazione" msgstr "Silenzia conversazione"
@@ -4275,8 +4275,8 @@ msgid "New"
msgstr "Nuova" msgstr "Nuova"
#: src/components/dms/dialogs/NewChatDialog.tsx:65 #: src/components/dms/dialogs/NewChatDialog.tsx:65
#: src/screens/Messages/ChatList.tsx:277 #: src/screens/Messages/ChatList.tsx:276
#: src/screens/Messages/ChatList.tsx:284 #: src/screens/Messages/ChatList.tsx:283
msgid "New chat" msgid "New chat"
msgstr "Nuova chat" msgstr "Nuova chat"
@@ -4390,7 +4390,7 @@ msgstr "Nessun feed trovato. Prova a cercarne altri."
msgid "No likes yet" msgid "No likes yet"
msgstr "Ancora nessun mi piace" msgstr "Ancora nessun mi piace"
#: src/components/ProfileCard.tsx:342 #: src/components/ProfileCard.tsx:345
#: src/screens/Profile/Header/ProfileHeaderStandard.tsx:119 #: src/screens/Profile/Header/ProfileHeaderStandard.tsx:119
msgid "No longer following {0}" msgid "No longer following {0}"
msgstr "Non segui più {0}" msgstr "Non segui più {0}"
@@ -4399,7 +4399,7 @@ msgstr "Non segui più {0}"
msgid "No longer than {0} characters" msgid "No longer than {0} characters"
msgstr "Non più di {0} caratteri" msgstr "Non più di {0} caratteri"
#: src/screens/Messages/components/ChatListItem.tsx:118 #: src/screens/Messages/components/ChatListItem.tsx:124
msgid "No messages yet" msgid "No messages yet"
msgstr "Ancora nessun messaggio" msgstr "Ancora nessun messaggio"
@@ -4599,7 +4599,7 @@ msgstr "su<0><1/><2><3/></2></0>"
#: src/screens/Settings/Settings.tsx:304 #: src/screens/Settings/Settings.tsx:304
msgid "Onboarding reset" msgid "Onboarding reset"
msgstr "Reimpostazione dell'onboarding" msgstr "Reimposta account"
#: src/view/com/composer/Composer.tsx:338 #: src/view/com/composer/Composer.tsx:338
msgid "One or more GIFs is missing alt text." msgid "One or more GIFs is missing alt text."
@@ -4663,8 +4663,8 @@ msgstr "Apri il creatore di avatar"
msgid "Open change handle dialog" msgid "Open change handle dialog"
msgstr "Apri la finestra di dialogo per la modifica del nome utente" msgstr "Apri la finestra di dialogo per la modifica del nome utente"
#: src/screens/Messages/components/ChatListItem.tsx:282 #: src/screens/Messages/components/ChatListItem.tsx:290
#: src/screens/Messages/components/ChatListItem.tsx:283 #: src/screens/Messages/components/ChatListItem.tsx:291
msgid "Open conversation options" msgid "Open conversation options"
msgstr "Apri opzioni conversazione" msgstr "Apri opzioni conversazione"
@@ -4827,7 +4827,7 @@ msgstr "Altro..."
#: src/components/dms/ReportDialog.tsx:339 #: src/components/dms/ReportDialog.tsx:339
msgid "Our moderation team has received your report." msgid "Our moderation team has received your report."
msgstr "Il nostro team di moderazione ha ricevuto la segnalazione." msgstr "Il team di moderazione ha ricevuto la tua segnalazione."
#: src/screens/Messages/components/ChatDisabled.tsx:28 #: src/screens/Messages/components/ChatDisabled.tsx:28
msgid "Our moderators have reviewed reports and decided to disable your access to chats on Bluesky." msgid "Our moderators have reviewed reports and decided to disable your access to chats on Bluesky."
@@ -5326,11 +5326,11 @@ msgstr "Riattacca citazione"
msgid "Reactivate your account" msgid "Reactivate your account"
msgstr "Riattiva account" msgstr "Riattiva account"
#: src/screens/VideoFeed/index.tsx:932 #: src/screens/VideoFeed/index.tsx:934
msgid "Read less" msgid "Read less"
msgstr "Leggi di meno" msgstr "Leggi di meno"
#: src/screens/VideoFeed/index.tsx:932 #: src/screens/VideoFeed/index.tsx:934
msgid "Read more" msgid "Read more"
msgstr "Leggi di più" msgstr "Leggi di più"
@@ -5351,13 +5351,13 @@ msgstr "Leggi i termini di servizio di Bluesky"
#: src/screens/Takendown.tsx:162 #: src/screens/Takendown.tsx:162
#: src/screens/Takendown.tsx:170 #: src/screens/Takendown.tsx:170
msgid "Reason for appeal" msgid "Reason for appeal"
msgstr "Motivo della richiesta di revisione della sospensione" msgstr "Motivo del ricorso"
#: src/components/dms/ReportDialog.tsx:210 #: src/components/dms/ReportDialog.tsx:210
msgid "Reason:" msgid "Reason:"
msgstr "Motivo:" msgstr "Motivo:"
#: src/view/screens/Search/Search.tsx:1034 #: src/view/screens/Search/Search.tsx:1040
msgid "Recent Searches" msgid "Recent Searches"
msgstr "Ricerche recenti" msgstr "Ricerche recenti"
@@ -5450,11 +5450,11 @@ msgstr "Rimuovi l'immagine"
msgid "Remove mute word from your list" msgid "Remove mute word from your list"
msgstr "Rimuovi parola silenziata dalla tua lista" msgstr "Rimuovi parola silenziata dalla tua lista"
#: src/view/screens/Search/Search.tsx:1082 #: src/view/screens/Search/Search.tsx:1088
msgid "Remove profile" msgid "Remove profile"
msgstr "Rimuovi profilo" msgstr "Rimuovi profilo"
#: src/view/screens/Search/Search.tsx:1084 #: src/view/screens/Search/Search.tsx:1090
msgid "Remove profile from search history" msgid "Remove profile from search history"
msgstr "Rimuovi profilo dalla cronologia di ricerca" msgstr "Rimuovi profilo dalla cronologia di ricerca"
@@ -5465,7 +5465,7 @@ msgstr "Rimuovi citazione"
#: src/view/com/util/post-ctrls/RepostButton.tsx:155 #: src/view/com/util/post-ctrls/RepostButton.tsx:155
#: src/view/com/util/post-ctrls/RepostButton.tsx:165 #: src/view/com/util/post-ctrls/RepostButton.tsx:165
msgid "Remove repost" msgid "Remove repost"
msgstr "Rimuovi ripubblicazione" msgstr "Rimuovi repost"
#: src/view/com/composer/videos/SubtitleDialog.tsx:260 #: src/view/com/composer/videos/SubtitleDialog.tsx:260
msgid "Remove subtitle file" msgid "Remove subtitle file"
@@ -5586,8 +5586,8 @@ msgid "Reply was successfully hidden"
msgstr "Risposta nascosta con successo" msgstr "Risposta nascosta con successo"
#: src/components/dms/MessageMenu.tsx:132 #: src/components/dms/MessageMenu.tsx:132
#: src/components/dms/MessagesListBlockedFooter.tsx:77
#: src/components/dms/MessagesListBlockedFooter.tsx:84 #: src/components/dms/MessagesListBlockedFooter.tsx:84
#: src/components/dms/MessagesListBlockedFooter.tsx:91
msgid "Report" msgid "Report"
msgstr "Segnala" msgstr "Segnala"
@@ -5596,8 +5596,8 @@ msgstr "Segnala"
msgid "Report Account" msgid "Report Account"
msgstr "Segnala account" msgstr "Segnala account"
#: src/components/dms/ConvoMenu.tsx:200 #: src/components/dms/ConvoMenu.tsx:258
#: src/components/dms/ConvoMenu.tsx:203 #: src/components/dms/ConvoMenu.tsx:261
#: src/components/dms/ReportConversationPrompt.tsx:17 #: src/components/dms/ReportConversationPrompt.tsx:17
msgid "Report conversation" msgid "Report conversation"
msgstr "Segnala conversazione" msgstr "Segnala conversazione"
@@ -5759,7 +5759,7 @@ msgstr "Reimposta il codice"
#: src/screens/Settings/Settings.tsx:344 #: src/screens/Settings/Settings.tsx:344
#: src/screens/Settings/Settings.tsx:346 #: src/screens/Settings/Settings.tsx:346
msgid "Reset onboarding state" msgid "Reset onboarding state"
msgstr "Reimposta lo stato dell'incorporazione" msgstr "Ripristina lo stato di registrazione"
#: src/screens/Login/ForgotPasswordForm.tsx:80 #: src/screens/Login/ForgotPasswordForm.tsx:80
msgid "Reset password" msgid "Reset password"
@@ -5804,12 +5804,12 @@ msgid "Returns to home page"
msgstr "Ritorna alla home" msgstr "Ritorna alla home"
#: src/screens/Profile/ProfileFeed/index.tsx:90 #: src/screens/Profile/ProfileFeed/index.tsx:90
#: src/screens/VideoFeed/index.tsx:1099 #: src/screens/VideoFeed/index.tsx:1101
#: src/view/screens/NotFound.tsx:60 #: src/view/screens/NotFound.tsx:60
msgid "Returns to previous page" msgid "Returns to previous page"
msgstr "Ritorna alla pagina precedente" msgstr "Ritorna alla pagina precedente"
#: src/components/dialogs/BirthDateSettings.tsx:124 #: src/components/dialogs/BirthDateSettings.tsx:120
#: src/components/dialogs/PostInteractionSettingsDialog.tsx:438 #: src/components/dialogs/PostInteractionSettingsDialog.tsx:438
#: src/components/dialogs/PostInteractionSettingsDialog.tsx:444 #: src/components/dialogs/PostInteractionSettingsDialog.tsx:444
#: src/components/StarterPack/QrCodeDialog.tsx:185 #: src/components/StarterPack/QrCodeDialog.tsx:185
@@ -5834,7 +5834,7 @@ msgctxt "action"
msgid "Save" msgid "Save"
msgstr "Salva" msgstr "Salva"
#: src/components/dialogs/BirthDateSettings.tsx:118 #: src/components/dialogs/BirthDateSettings.tsx:114
msgid "Save birthday" msgid "Save birthday"
msgstr "Salva il compleanno" msgstr "Salva il compleanno"
@@ -5934,7 +5934,7 @@ msgstr "Cerca \"{interestsDisplayName}\"{activeText}"
msgid "Search for \"{query}\"" msgid "Search for \"{query}\""
msgstr "Cerca \"{query}\"" msgstr "Cerca \"{query}\""
#: src/view/screens/Search/Search.tsx:980 #: src/view/screens/Search/Search.tsx:986
msgid "Search for \"{searchText}\"" msgid "Search for \"{searchText}\""
msgstr "Cerca \"{searchText}\"" msgstr "Cerca \"{searchText}\""
@@ -6145,7 +6145,7 @@ msgstr "Invia tramite messaggi"
msgid "Sends email with confirmation code for account deletion" msgid "Sends email with confirmation code for account deletion"
msgstr "Invia un'email con il codice di conferma per l'eliminazione dell'account" msgstr "Invia un'email con il codice di conferma per l'eliminazione dell'account"
#: src/view/com/auth/server-input/index.tsx:127 #: src/view/com/auth/server-input/index.tsx:163
msgid "Server address" msgid "Server address"
msgstr "Indirizzo del server" msgstr "Indirizzo del server"
@@ -6420,7 +6420,7 @@ msgstr "Esci"
#: src/screens/Settings/Settings.tsx:256 #: src/screens/Settings/Settings.tsx:256
#: src/view/shell/desktop/LeftNav.tsx:205 #: src/view/shell/desktop/LeftNav.tsx:205
msgid "Sign out?" msgid "Sign out?"
msgstr "Uscire?" msgstr "Vuoi uscire?"
#: src/components/moderation/ScreenHider.tsx:91 #: src/components/moderation/ScreenHider.tsx:91
#: src/lib/moderation/useGlobalLabelStrings.ts:28 #: src/lib/moderation/useGlobalLabelStrings.ts:28
@@ -6437,7 +6437,7 @@ msgstr "Accesso effettuato come @{0}"
msgid "Signup without a starter pack" msgid "Signup without a starter pack"
msgstr "Iscriviti senza uno starter pack" msgstr "Iscriviti senza uno starter pack"
#: src/components/FeedInterstitials.tsx:314 #: src/components/FeedInterstitials.tsx:335
msgid "Similar accounts" msgid "Similar accounts"
msgstr "Account simili" msgstr "Account simili"
@@ -6459,7 +6459,7 @@ msgstr "Più piccolo"
msgid "Software Dev" msgid "Software Dev"
msgstr "Sviluppo software" msgstr "Sviluppo software"
#: src/components/FeedInterstitials.tsx:449 #: src/components/FeedInterstitials.tsx:470
msgid "Some other feeds you might like" msgid "Some other feeds you might like"
msgstr "Altri feed che potrebbero piacerti" msgstr "Altri feed che potrebbero piacerti"
@@ -6467,7 +6467,7 @@ msgstr "Altri feed che potrebbero piacerti"
msgid "Some people can reply" msgid "Some people can reply"
msgstr "Risposte limitate" msgstr "Risposte limitate"
#: src/screens/Messages/Conversation.tsx:102 #: src/screens/Messages/Conversation.tsx:112
msgid "Something went wrong" msgid "Something went wrong"
msgstr "Qualcosa è andato storto" msgstr "Qualcosa è andato storto"
@@ -6632,11 +6632,11 @@ msgstr "Iscriviti alla lista"
msgid "Success!" msgid "Success!"
msgstr "Successo!" msgstr "Successo!"
#: src/view/screens/Search/Explore.tsx:366 #: src/view/screens/Search/Explore.tsx:368
msgid "Suggested accounts" msgid "Suggested accounts"
msgstr "Account suggeriti" msgstr "Account suggeriti"
#: src/components/FeedInterstitials.tsx:316 #: src/components/FeedInterstitials.tsx:337
msgid "Suggested for you" msgid "Suggested for you"
msgstr "Suggerito per te" msgstr "Suggerito per te"
@@ -6703,7 +6703,7 @@ msgstr "Tocca per ignorare"
msgid "Tap to enter full screen" msgid "Tap to enter full screen"
msgstr "Tocca per entrare in modalità a schermo intero" msgstr "Tocca per entrare in modalità a schermo intero"
#: src/screens/VideoFeed/index.tsx:931 #: src/screens/VideoFeed/index.tsx:933
msgid "Tap to expand or collapse post text." msgid "Tap to expand or collapse post text."
msgstr "Tocca per espandere o comprimere il testo del post." msgstr "Tocca per espandere o comprimere il testo del post."
@@ -6820,7 +6820,7 @@ msgstr "Impossibile trovare starter pack."
msgid "That's all, folks!" msgid "That's all, folks!"
msgstr "Questo è tutto, gente!" msgstr "Questo è tutto, gente!"
#: src/screens/VideoFeed/index.tsx:1071 #: src/screens/VideoFeed/index.tsx:1073
msgid "That's everything!" msgid "That's everything!"
msgstr "È tutto!" msgstr "È tutto!"
@@ -7065,7 +7065,7 @@ msgstr "Questo contenuto non è disponibile perché uno degli utenti coinvolti h
msgid "This content is not viewable without a Bluesky account." msgid "This content is not viewable without a Bluesky account."
msgstr "Questo contenuto non è visualizzabile senza un account Bluesky." msgstr "Questo contenuto non è visualizzabile senza un account Bluesky."
#: src/screens/Messages/components/ChatListItem.tsx:276 #: src/screens/Messages/components/ChatListItem.tsx:284
msgid "This conversation is with a deleted or a deactivated account. Press for options." msgid "This conversation is with a deleted or a deactivated account. Press for options."
msgstr "L'utente di questa conversazione ha disattivato o eliminato l'account. Premi per le opzioni." msgstr "L'utente di questa conversazione ha disattivato o eliminato l'account. Premi per le opzioni."
@@ -7180,7 +7180,7 @@ msgstr "Questo dovrebbe creare un record di dominio in:"
msgid "This user doesn't have any followers." msgid "This user doesn't have any followers."
msgstr "Questo utente non ha follower." msgstr "Questo utente non ha follower."
#: src/components/dms/MessagesListBlockedFooter.tsx:60 #: src/components/dms/MessagesListBlockedFooter.tsx:67
msgid "This user has blocked you" msgid "This user has blocked you"
msgstr "Questo utente ti ha bloccato" msgstr "Questo utente ti ha bloccato"
@@ -7359,10 +7359,10 @@ msgstr "Impossibile contattare il servizio. Verifica la tua connessione a intern
msgid "Unable to delete" msgid "Unable to delete"
msgstr "Impossibile eliminare" msgstr "Impossibile eliminare"
#: src/components/dms/MessagesListBlockedFooter.tsx:89
#: src/components/dms/MessagesListBlockedFooter.tsx:96 #: src/components/dms/MessagesListBlockedFooter.tsx:96
#: src/components/dms/MessagesListBlockedFooter.tsx:104 #: src/components/dms/MessagesListBlockedFooter.tsx:103
#: src/components/dms/MessagesListBlockedFooter.tsx:111 #: src/components/dms/MessagesListBlockedFooter.tsx:111
#: src/components/dms/MessagesListBlockedFooter.tsx:118
#: src/screens/Profile/Header/ProfileHeaderStandard.tsx:197 #: src/screens/Profile/Header/ProfileHeaderStandard.tsx:197
#: src/screens/Profile/Header/ProfileHeaderStandard.tsx:283 #: src/screens/Profile/Header/ProfileHeaderStandard.tsx:283
#: src/view/com/profile/ProfileMenu.tsx:341 #: src/view/com/profile/ProfileMenu.tsx:341
@@ -7375,8 +7375,8 @@ msgctxt "action"
msgid "Unblock" msgid "Unblock"
msgstr "Sblocca" msgstr "Sblocca"
#: src/components/dms/ConvoMenu.tsx:191 #: src/components/dms/ConvoMenu.tsx:250
#: src/components/dms/ConvoMenu.tsx:195 #: src/components/dms/ConvoMenu.tsx:253
msgid "Unblock account" msgid "Unblock account"
msgstr "Sblocca account" msgstr "Sblocca account"
@@ -7399,7 +7399,7 @@ msgstr "Annulla ripubblicazione"
msgid "Undo repost ({0, plural, one {# repost} other {# reposts}})" msgid "Undo repost ({0, plural, one {# repost} other {# reposts}})"
msgstr "Annulla ripubblicazione ({0, plural, one {# ripubblicazione} other {# ripubblicazioni}})" msgstr "Annulla ripubblicazione ({0, plural, one {# ripubblicazione} other {# ripubblicazioni}})"
#: src/view/com/profile/FollowButton.tsx:60 #: src/view/com/profile/FollowButton.tsx:63
msgctxt "action" msgctxt "action"
msgid "Unfollow" msgid "Unfollow"
msgstr "Smetti di seguire" msgstr "Smetti di seguire"
@@ -7413,7 +7413,7 @@ msgstr "Smetti di seguire {0}"
msgid "Unfollow Account" msgid "Unfollow Account"
msgstr "Smetti di seguire questo account" msgstr "Smetti di seguire questo account"
#: src/screens/VideoFeed/index.tsx:801 #: src/screens/VideoFeed/index.tsx:803
msgid "Unfollow user" msgid "Unfollow user"
msgstr "Smetti di seguire" msgstr "Smetti di seguire"
@@ -7445,7 +7445,7 @@ msgstr "Riattiva {tag}"
msgid "Unmute Account" msgid "Unmute Account"
msgstr "Riattiva questo account" msgstr "Riattiva questo account"
#: src/components/dms/ConvoMenu.tsx:179 #: src/components/dms/ConvoMenu.tsx:239
msgid "Unmute conversation" msgid "Unmute conversation"
msgstr "Riattiva conversazione" msgstr "Riattiva conversazione"
@@ -7746,11 +7746,11 @@ msgstr "Video da {0}: {text}"
msgid "Video Games" msgid "Video Games"
msgstr "Videogiochi" msgstr "Videogiochi"
#: src/screens/VideoFeed/index.tsx:1029 #: src/screens/VideoFeed/index.tsx:1031
msgid "Video is paused" msgid "Video is paused"
msgstr "Video in pausa" msgstr "Video in pausa"
#: src/screens/VideoFeed/index.tsx:1029 #: src/screens/VideoFeed/index.tsx:1031
msgid "Video is playing" msgid "Video is playing"
msgstr "Video in riproduzione" msgstr "Video in riproduzione"
@@ -7785,12 +7785,12 @@ msgstr "Vedi l'avatar di {0}"
#: src/components/ProfileCard.tsx:110 #: src/components/ProfileCard.tsx:110
#: src/screens/Profile/components/ProfileFeedHeader.tsx:450 #: src/screens/Profile/components/ProfileFeedHeader.tsx:450
#: src/screens/VideoFeed/index.tsx:762 #: src/screens/VideoFeed/index.tsx:763
#: src/view/com/notifications/NotificationFeedItem.tsx:409 #: src/view/com/notifications/NotificationFeedItem.tsx:409
msgid "View {0}'s profile" msgid "View {0}'s profile"
msgstr "Vedi il profilo di {0}" msgstr "Vedi il profilo di {0}"
#: src/components/dms/MessagesListHeader.tsx:167 #: src/components/dms/MessagesListHeader.tsx:173
msgid "View {displayName}'s profile" msgid "View {displayName}'s profile"
msgstr "Vedi il profilo di {displayName}" msgstr "Vedi il profilo di {displayName}"
@@ -7905,7 +7905,7 @@ msgstr "Non siamo riusciti a trovare alcun risultato per quell'hashtag."
msgid "We couldn't find any results for that topic." msgid "We couldn't find any results for that topic."
msgstr "Nessun risultato per questo argomento." msgstr "Nessun risultato per questo argomento."
#: src/screens/Messages/Conversation.tsx:103 #: src/screens/Messages/Conversation.tsx:113
msgid "We couldn't load this conversation" msgid "We couldn't load this conversation"
msgstr "Non riusciamo a caricare questa conversazione" msgstr "Non riusciamo a caricare questa conversazione"
@@ -8037,7 +8037,7 @@ msgstr "Ops! Non è stato possibile caricare i video di tendenza."
#: src/screens/Takendown.tsx:173 #: src/screens/Takendown.tsx:173
msgid "Why are you appealing?" msgid "Why are you appealing?"
msgstr "Perché richiedi la revisione?" msgstr "Per quale motivo fai ricorso?"
#: src/components/ReportDialog/SelectReportOptionView.tsx:42 #: src/components/ReportDialog/SelectReportOptionView.tsx:42
msgid "Why should this content be reviewed?" msgid "Why should this content be reviewed?"
@@ -8192,7 +8192,7 @@ msgstr "Non hai salvato nessun feed."
msgid "You have blocked the author or you have been blocked by the author." msgid "You have blocked the author or you have been blocked by the author."
msgstr "Hai bloccato l'autore o sei stato bloccato dall'autore." msgstr "Hai bloccato l'autore o sei stato bloccato dall'autore."
#: src/components/dms/MessagesListBlockedFooter.tsx:58 #: src/components/dms/MessagesListBlockedFooter.tsx:65
msgid "You have blocked this user" msgid "You have blocked this user"
msgstr "Hai bloccato questo utente" msgstr "Hai bloccato questo utente"
@@ -8329,15 +8329,15 @@ msgstr "Riceverai le notifiche per questo thread"
msgid "You will receive an email with a \"reset code.\" Enter that code here, then enter your new password." msgid "You will receive an email with a \"reset code.\" Enter that code here, then enter your new password."
msgstr "Riceverai un'email con un codice di recupero. Inserisci il codice qui, poi inserisci la tua nuova password." msgstr "Riceverai un'email con un codice di recupero. Inserisci il codice qui, poi inserisci la tua nuova password."
#: src/screens/Messages/components/ChatListItem.tsx:133 #: src/screens/Messages/components/ChatListItem.tsx:139
msgid "You: {0}" msgid "You: {0}"
msgstr "Tu: {0}" msgstr "Tu: {0}"
#: src/screens/Messages/components/ChatListItem.tsx:162 #: src/screens/Messages/components/ChatListItem.tsx:168
msgid "You: {defaultEmbeddedContentMessage}" msgid "You: {defaultEmbeddedContentMessage}"
msgstr "Tu: {defaultEmbeddedContentMessage}" msgstr "Tu: {defaultEmbeddedContentMessage}"
#: src/screens/Messages/components/ChatListItem.tsx:155 #: src/screens/Messages/components/ChatListItem.tsx:161
msgid "You: {short}" msgid "You: {short}"
msgstr "Tu: {short}" msgstr "Tu: {short}"
@@ -8399,7 +8399,7 @@ msgstr "Hai raggiunto il limite giornaliero di video caricati (troppi byte)"
msgid "You've reached your daily limit for video uploads (too many videos)" msgid "You've reached your daily limit for video uploads (too many videos)"
msgstr "Hai raggiunto il limite giornaliero di video caricati (troppi video)" msgstr "Hai raggiunto il limite giornaliero di video caricati (troppi video)"
#: src/screens/VideoFeed/index.tsx:1080 #: src/screens/VideoFeed/index.tsx:1082
msgid "You've run out of videos to watch. Maybe it's a good time to take a break?" msgid "You've run out of videos to watch. Maybe it's a good time to take a break?"
msgstr "Non ci sono altri video da guardare. Forse è il momento giusto per fare una pausa?" msgstr "Non ci sono altri video da guardare. Forse è il momento giusto per fare una pausa?"
@@ -8425,11 +8425,11 @@ msgstr "L'archivio del tuo account, che contiene tutti i record di dati pubblici
#: src/screens/Takendown.tsx:214 #: src/screens/Takendown.tsx:214
msgid "Your account was found to be in violation of the <0>Bluesky Social Terms of Service</0>. You have been sent an email outlining the specific violation and suspension period, if applicable. You can appeal this decision if you believe it was made in error." msgid "Your account was found to be in violation of the <0>Bluesky Social Terms of Service</0>. You have been sent an email outlining the specific violation and suspension period, if applicable. You can appeal this decision if you believe it was made in error."
msgstr "Abbiamo riscontrato che il tuo account viola i <0>termini di servizio di Bluesky Social</0>. Ti abbiamo inviato un'email che descrive la violazione e il periodo di sospensione, se applicabile. Se ritieni che questa decisione sia stata presa per errore, puoi richiedere una revisione della sospensione." msgstr "Abbiamo riscontrato che il tuo account viola i <0>termini di servizio di Bluesky</0>. Ti abbiamo inviato un'email che descrive la violazione e il periodo di sospensione, se applicabile. Se ritieni che questa decisione sia stata presa per errore, puoi richiedere una revisione della sospensione."
#: src/screens/Takendown.tsx:154 #: src/screens/Takendown.tsx:154
msgid "Your appeal has been submitted. If your appeal succeeds, you will receive an email." msgid "Your appeal has been submitted. If your appeal succeeds, you will receive an email."
msgstr "La tua richiesta di revisione è stata inviata. Riceverai un'email se la revisione avrà esito positivo." msgstr "La richiesta di revisione è stata inviata. Se il ricorso ha esito positivo, riceverai un'email."
#: src/screens/Signup/StepInfo/index.tsx:205 #: src/screens/Signup/StepInfo/index.tsx:205
msgid "Your birth date" msgid "Your birth date"
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
+1
View File
@@ -13,6 +13,7 @@ export const router = new Router({
ModerationModlists: '/moderation/modlists', ModerationModlists: '/moderation/modlists',
ModerationMutedAccounts: '/moderation/muted-accounts', ModerationMutedAccounts: '/moderation/muted-accounts',
ModerationBlockedAccounts: '/moderation/blocked-accounts', ModerationBlockedAccounts: '/moderation/blocked-accounts',
ModerationInteractionSettings: '/moderation/interaction-settings',
// profiles, threads, lists // profiles, threads, lists
Profile: ['/profile/:name', '/profile/:name/rss'], Profile: ['/profile/:name', '/profile/:name/rss'],
ProfileFollowers: '/profile/:name/followers', ProfileFollowers: '/profile/:name/followers',
+1 -1
View File
@@ -232,7 +232,7 @@ export const LoginForm = ({
onSubmitEditing={onPressNext} onSubmitEditing={onPressNext}
blurOnSubmit={false} // HACK: https://github.com/facebook/react-native/issues/21911#issuecomment-558343069 Keyboard blur behavior is now handled in onSubmitEditing blurOnSubmit={false} // HACK: https://github.com/facebook/react-native/issues/21911#issuecomment-558343069 Keyboard blur behavior is now handled in onSubmitEditing
editable={!isProcessing} editable={!isProcessing}
accessibilityHint={_(msg`Input your password`)} accessibilityHint={_(msg`Enter your password`)}
/> />
<Button <Button
testID="forgotPasswordButton" testID="forgotPasswordButton"
@@ -281,7 +281,7 @@ function ChatListItemReady({
!isDeletedAccount !isDeletedAccount
? _(msg`Go to conversation with ${profile.handle}`) ? _(msg`Go to conversation with ${profile.handle}`)
: _( : _(
msg`This conversation is with a deleted or a deactivated account. Press for options.`, msg`This conversation is with a deleted or a deactivated account. Press for options`,
) )
} }
accessibilityActions={ accessibilityActions={
+16
View File
@@ -28,6 +28,7 @@ import * as Toggle from '#/components/forms/Toggle'
import {ChevronRight_Stroke2_Corner0_Rounded as ChevronRight} from '#/components/icons/Chevron' import {ChevronRight_Stroke2_Corner0_Rounded as ChevronRight} from '#/components/icons/Chevron'
import {CircleBanSign_Stroke2_Corner0_Rounded as CircleBanSign} from '#/components/icons/CircleBanSign' import {CircleBanSign_Stroke2_Corner0_Rounded as CircleBanSign} from '#/components/icons/CircleBanSign'
import {Props as SVGIconProps} from '#/components/icons/common' import {Props as SVGIconProps} from '#/components/icons/common'
import {EditBig_Stroke2_Corner0_Rounded as EditBig} from '#/components/icons/EditBig'
import {Filter_Stroke2_Corner0_Rounded as Filter} from '#/components/icons/Filter' import {Filter_Stroke2_Corner0_Rounded as Filter} from '#/components/icons/Filter'
import {Group3_Stroke2_Corner0_Rounded as Group} from '#/components/icons/Group' import {Group3_Stroke2_Corner0_Rounded as Group} from '#/components/icons/Group'
import {Person_Stroke2_Corner0_Rounded as Person} from '#/components/icons/Person' import {Person_Stroke2_Corner0_Rounded as Person} from '#/components/icons/Person'
@@ -199,6 +200,21 @@ export function ModerationScreenInner({
a.overflow_hidden, a.overflow_hidden,
t.atoms.bg_contrast_25, t.atoms.bg_contrast_25,
]}> ]}>
<Link
label={_(msg`View your default post interaction settings`)}
testID="interactionSettingsBtn"
to="/moderation/interaction-settings">
{state => (
<SubItem
title={_(msg`Interaction settings`)}
icon={EditBig}
style={[
(state.hovered || state.pressed) && [t.atoms.bg_contrast_50],
]}
/>
)}
</Link>
<Divider />
<Button <Button
testID="mutedWordsBtn" testID="mutedWordsBtn"
label={_(msg`Open muted words and tags settings`)} label={_(msg`Open muted words and tags settings`)}
@@ -0,0 +1,127 @@
import React from 'react'
import {View} from 'react-native'
import {msg, Trans} from '@lingui/macro'
import {useLingui} from '@lingui/react'
import deepEqual from 'lodash.isequal'
import {logger} from '#/logger'
import {usePostInteractionSettingsMutation} from '#/state/queries/post-interaction-settings'
import {createPostgateRecord} from '#/state/queries/postgate/util'
import {
usePreferencesQuery,
UsePreferencesQueryResponse,
} from '#/state/queries/preferences'
import {
threadgateAllowUISettingToAllowRecordValue,
threadgateRecordToAllowUISetting,
} from '#/state/queries/threadgate'
import * as Toast from '#/view/com/util/Toast'
import {atoms as a, useGutters} from '#/alf'
import {Admonition} from '#/components/Admonition'
import {PostInteractionSettingsForm} from '#/components/dialogs/PostInteractionSettingsDialog'
import * as Layout from '#/components/Layout'
import {Loader} from '#/components/Loader'
export function Screen() {
const gutters = useGutters(['base'])
const {data: preferences} = usePreferencesQuery()
return (
<Layout.Screen testID="ModerationInteractionSettingsScreen">
<Layout.Header.Outer>
<Layout.Header.BackButton />
<Layout.Header.Content>
<Layout.Header.TitleText>
<Trans>Post Interaction Settings</Trans>
</Layout.Header.TitleText>
</Layout.Header.Content>
<Layout.Header.Slot />
</Layout.Header.Outer>
<Layout.Content>
<View style={[gutters, a.gap_xl]}>
<Admonition type="tip">
<Trans>
The following settings will be used as your defaults when creating
new posts. You can edit these for a specific post from the
composer.
</Trans>
</Admonition>
{preferences ? (
<Inner preferences={preferences} />
) : (
<View style={[gutters, a.justify_center, a.align_center]}>
<Loader size="xl" />
</View>
)}
</View>
</Layout.Content>
</Layout.Screen>
)
}
function Inner({preferences}: {preferences: UsePreferencesQueryResponse}) {
const {_} = useLingui()
const {mutateAsync: setPostInteractionSettings, isPending} =
usePostInteractionSettingsMutation()
const [error, setError] = React.useState<string | undefined>(undefined)
const allowUI = React.useMemo(() => {
return threadgateRecordToAllowUISetting({
$type: 'app.bsky.feed.threadgate',
post: '',
createdAt: new Date().toString(),
allow: preferences.postInteractionSettings.threadgateAllowRules,
})
}, [preferences.postInteractionSettings.threadgateAllowRules])
const postgate = React.useMemo(() => {
return createPostgateRecord({
post: '',
embeddingRules:
preferences.postInteractionSettings.postgateEmbeddingRules,
})
}, [preferences.postInteractionSettings.postgateEmbeddingRules])
const [maybeEditedAllowUI, setAllowUI] = React.useState(allowUI)
const [maybeEditedPostgate, setEditedPostgate] = React.useState(postgate)
const wasEdited = React.useMemo(() => {
return (
!deepEqual(allowUI, maybeEditedAllowUI) ||
!deepEqual(postgate.embeddingRules, maybeEditedPostgate.embeddingRules)
)
}, [postgate, allowUI, maybeEditedAllowUI, maybeEditedPostgate])
const onSave = React.useCallback(async () => {
setError('')
try {
await setPostInteractionSettings({
threadgateAllowRules:
threadgateAllowUISettingToAllowRecordValue(maybeEditedAllowUI),
postgateEmbeddingRules: maybeEditedPostgate.embeddingRules ?? [],
})
Toast.show(_(msg`Settings saved`))
} catch (e: any) {
logger.error(`Failed to save post interaction settings`, {
context: 'ModerationInteractionSettingsScreen',
safeMessage: e.message,
})
setError(_(msg`Failed to save settings. Please try again.`))
}
}, [_, maybeEditedPostgate, maybeEditedAllowUI, setPostInteractionSettings])
return (
<>
<PostInteractionSettingsForm
canSave={wasEdited}
isSaving={isPending}
onSave={onSave}
postgate={maybeEditedPostgate}
onChangePostgate={setEditedPostgate}
threadgateAllowUISettings={maybeEditedAllowUI}
onChangeThreadgateAllowUISettings={setAllowUI}
/>
{error && <Admonition type="error">{error}</Admonition>}
</>
)
}
+1 -3
View File
@@ -53,9 +53,7 @@ export function Layout({children}: React.PropsWithChildren<{}>) {
aria-role="dialog" aria-role="dialog"
aria-label={dialogLabel} aria-label={dialogLabel}
accessibilityLabel={dialogLabel} accessibilityLabel={dialogLabel}
accessibilityHint={_( accessibilityHint={_(msg`Customizes your Bluesky experience`)}
msg`The following steps will help customize your Bluesky experience.`,
)}
style={[ style={[
// @ts-ignore web only -prf // @ts-ignore web only -prf
isWeb ? a.fixed : a.absolute, isWeb ? a.fixed : a.absolute,
+1 -1
View File
@@ -205,7 +205,7 @@ export function StepFinished() {
setActiveStarterPack(undefined) setActiveStarterPack(undefined)
setHasCheckedForStarterPack(true) setHasCheckedForStarterPack(true)
startProgressGuide( startProgressGuide(
gate('new_postonboarding') ? 'follow-10' : 'like-10-and-follow-7', gate('old_postonboarding') ? 'like-10-and-follow-7' : 'follow-10',
) )
dispatch({type: 'finish'}) dispatch({type: 'finish'})
onboardDispatch({type: 'finish'}) onboardDispatch({type: 'finish'})
@@ -3,7 +3,6 @@ import {Apple_Stroke2_Corner0_Rounded as Apple} from '#/components/icons/Apple'
import {At_Stroke2_Corner0_Rounded as At} from '#/components/icons/At' import {At_Stroke2_Corner0_Rounded as At} from '#/components/icons/At'
import {Atom_Stroke2_Corner0_Rounded as Atom} from '#/components/icons/Atom' import {Atom_Stroke2_Corner0_Rounded as Atom} from '#/components/icons/Atom'
import {Celebrate_Stroke2_Corner0_Rounded as Celebrate} from '#/components/icons/Celebrate' import {Celebrate_Stroke2_Corner0_Rounded as Celebrate} from '#/components/icons/Celebrate'
import {Coffee_Stroke2_Corner0_Rounded as Coffee} from '#/components/icons/Coffee'
import { import {
EmojiArc_Stroke2_Corner0_Rounded as EmojiArc, EmojiArc_Stroke2_Corner0_Rounded as EmojiArc,
EmojiHeartEyes_Stroke2_Corner0_Rounded as EmojiHeartEyes, EmojiHeartEyes_Stroke2_Corner0_Rounded as EmojiHeartEyes,
@@ -13,8 +12,6 @@ import {GameController_Stroke2_Corner0_Rounded as GameController} from '#/compon
import {Lab_Stroke2_Corner0_Rounded as Lab} from '#/components/icons/Lab' import {Lab_Stroke2_Corner0_Rounded as Lab} from '#/components/icons/Lab'
import {Leaf_Stroke2_Corner0_Rounded as Leaf} from '#/components/icons/Leaf' import {Leaf_Stroke2_Corner0_Rounded as Leaf} from '#/components/icons/Leaf'
import {MusicNote_Stroke2_Corner0_Rounded as MusicNote} from '#/components/icons/MusicNote' import {MusicNote_Stroke2_Corner0_Rounded as MusicNote} from '#/components/icons/MusicNote'
import {PiggyBank_Stroke2_Corner0_Rounded as PiggyBank} from '#/components/icons/PiggyBank'
import {Poop_Stroke2_Corner0_Rounded as Poop} from '#/components/icons/Poop'
import {Rose_Stroke2_Corner0_Rounded as Rose} from '#/components/icons/Rose' import {Rose_Stroke2_Corner0_Rounded as Rose} from '#/components/icons/Rose'
import {Shaka_Stroke2_Corner0_Rounded as Shaka} from '#/components/icons/Shaka' import {Shaka_Stroke2_Corner0_Rounded as Shaka} from '#/components/icons/Shaka'
import {UFO_Stroke2_Corner0_Rounded as UFO} from '#/components/icons/UFO' import {UFO_Stroke2_Corner0_Rounded as UFO} from '#/components/icons/UFO'
@@ -33,7 +30,6 @@ export const emojiNames = [
'apple', 'apple',
'atom', 'atom',
'celebrate', 'celebrate',
'coffee',
'gameController', 'gameController',
'leaf', 'leaf',
'musicNote', 'musicNote',
@@ -43,8 +39,6 @@ export const emojiNames = [
'zap', 'zap',
'explosion', 'explosion',
'lab', 'lab',
'piggyBank',
'poop',
] as const ] as const
export type EmojiName = (typeof emojiNames)[number] export type EmojiName = (typeof emojiNames)[number]
@@ -81,10 +75,6 @@ export const emojiItems: Record<EmojiName, Emoji> = {
name: 'celebrate', name: 'celebrate',
component: Celebrate, component: Celebrate,
}, },
coffee: {
name: 'coffee',
component: Coffee,
},
gameController: { gameController: {
name: 'gameController', name: 'gameController',
component: GameController, component: GameController,
@@ -121,14 +111,6 @@ export const emojiItems: Record<EmojiName, Emoji> = {
name: 'lab', name: 'lab',
component: Lab, component: Lab,
}, },
piggyBank: {
name: 'piggyBank',
component: PiggyBank,
},
poop: {
name: 'poop',
component: Poop,
},
} }
export const avatarColors = [ export const avatarColors = [
+1 -1
View File
@@ -60,7 +60,7 @@ export function ErrorState({error}: {error: string}) {
color="secondary" color="secondary"
variant="solid" variant="solid"
label={_(msg`Go Back`)} label={_(msg`Go Back`)}
accessibilityHint="Return to previous page" accessibilityHint="Returns to previous page"
onPress={onPressBack}> onPress={onPressBack}>
<ButtonText> <ButtonText>
<Trans>Go Back</Trans> <Trans>Go Back</Trans>
@@ -1,4 +1,5 @@
import {View} from 'react-native' import {View} from 'react-native'
import {AppBskyUnspeccedDefs} from '@atproto/api'
import {Trans} from '@lingui/macro' import {Trans} from '@lingui/macro'
import {logEvent} from '#/lib/statsig/statsig' import {logEvent} from '#/lib/statsig/statsig'
@@ -27,6 +28,7 @@ function Inner() {
const gutters = useGutters([0, 'compact']) const gutters = useGutters([0, 'compact'])
const {data: trending, error, isLoading} = useTrendingTopics() const {data: trending, error, isLoading} = useTrendingTopics()
const noRecs = !isLoading && !error && !trending?.suggested?.length const noRecs = !isLoading && !error && !trending?.suggested?.length
const allFeeds = trending?.suggested && isAllFeeds(trending.suggested)
return error || noRecs ? null : ( return error || noRecs ? null : (
<> <>
@@ -50,9 +52,17 @@ function Inner() {
<Trans>Recommended</Trans> <Trans>Recommended</Trans>
</Text> </Text>
</View> </View>
{!allFeeds ? (
<Text style={[t.atoms.text_contrast_high, a.leading_snug]}>
<Trans>
Content from across the network we think you might like.
</Trans>
</Text>
) : (
<Text style={[t.atoms.text_contrast_high, a.leading_snug]}> <Text style={[t.atoms.text_contrast_high, a.leading_snug]}>
<Trans>Feeds we think you might like.</Trans> <Trans>Feeds we think you might like.</Trans>
</Text> </Text>
)}
</View> </View>
</View> </View>
@@ -98,3 +108,10 @@ function Inner() {
</> </>
) )
} }
function isAllFeeds(topics: AppBskyUnspeccedDefs.TrendingTopic[]) {
return topics.every(topic => {
const segments = topic.link.split('/').slice(1)
return segments[0] === 'profile' && segments[2] === 'feed'
})
}
+12 -1
View File
@@ -7,6 +7,7 @@ import {NativeStackScreenProps} from '@react-navigation/native-stack'
import {appVersion, BUNDLE_DATE, bundleInfo} from '#/lib/app-info' import {appVersion, BUNDLE_DATE, bundleInfo} from '#/lib/app-info'
import {STATUS_PAGE_URL} from '#/lib/constants' import {STATUS_PAGE_URL} from '#/lib/constants'
import {CommonNavigatorParams} from '#/lib/routes/types' import {CommonNavigatorParams} from '#/lib/routes/types'
import {useDevModeEnabled} from '#/state/preferences/dev-mode'
import * as Toast from '#/view/com/util/Toast' import * as Toast from '#/view/com/util/Toast'
import * as SettingsList from '#/screens/Settings/components/SettingsList' import * as SettingsList from '#/screens/Settings/components/SettingsList'
import {CodeLines_Stroke2_Corner2_Rounded as CodeLinesIcon} from '#/components/icons/CodeLines' import {CodeLines_Stroke2_Corner2_Rounded as CodeLinesIcon} from '#/components/icons/CodeLines'
@@ -18,6 +19,7 @@ import * as Layout from '#/components/Layout'
type Props = NativeStackScreenProps<CommonNavigatorParams, 'AboutSettings'> type Props = NativeStackScreenProps<CommonNavigatorParams, 'AboutSettings'>
export function AboutSettingsScreen({}: Props) { export function AboutSettingsScreen({}: Props) {
const {_} = useLingui() const {_} = useLingui()
const [devModeEnabled, setDevModeEnabled] = useDevModeEnabled()
return ( return (
<Layout.Screen> <Layout.Screen>
@@ -65,7 +67,16 @@ export function AboutSettingsScreen({}: Props) {
</SettingsList.LinkItem> </SettingsList.LinkItem>
<SettingsList.PressableItem <SettingsList.PressableItem
label={_(msg`Version ${appVersion}`)} label={_(msg`Version ${appVersion}`)}
accessibilityHint={_(msg`Copy build version to clipboard`)} accessibilityHint={_(msg`Copies build version to clipboard`)}
onLongPress={() => {
const newDevModeEnabled = !devModeEnabled
setDevModeEnabled(newDevModeEnabled)
Toast.show(
newDevModeEnabled
? _(msg`Developer mode enabled`)
: _(msg`Developer mode disabled`),
)
}}
onPress={() => { onPress={() => {
setStringAsync( setStringAsync(
`Build version: ${appVersion}; Bundle info: ${bundleInfo}; Bundle date: ${BUNDLE_DATE}; Platform: ${Platform.OS}; Platform version: ${Platform.Version}`, `Build version: ${appVersion}; Bundle info: ${bundleInfo}; Bundle date: ${BUNDLE_DATE}; Platform: ${Platform.OS}; Platform version: ${Platform.Version}`,
+1 -1
View File
@@ -124,7 +124,7 @@ export function AccountSettingsScreen({}: Props) {
</SettingsList.PressableItem> </SettingsList.PressableItem>
<SettingsList.PressableItem <SettingsList.PressableItem
label={_(msg`Handle`)} label={_(msg`Handle`)}
accessibilityHint={_(msg`Open change handle dialog`)} accessibilityHint={_(msg`Opens change handle dialog`)}
onPress={() => changeHandleControl.open()}> onPress={() => changeHandleControl.open()}>
<SettingsList.ItemIcon icon={AtIcon} /> <SettingsList.ItemIcon icon={AtIcon} />
<SettingsList.ItemText> <SettingsList.ItemText>
@@ -213,7 +213,7 @@ function AppIcon({icon, size = 50}: {icon: AppIconSet; size: number}) {
return ( return (
<PressableScale <PressableScale
accessibilityLabel={icon.name} accessibilityLabel={icon.name}
accessibilityHint={_(msg`Tap to change app icon`)} accessibilityHint={_(msg`Changes app icon`)}
targetScale={0.95} targetScale={0.95}
onPress={() => { onPress={() => {
if (isAndroid) { if (isAndroid) {
+3 -3
View File
@@ -101,7 +101,7 @@ export function SettingsScreen({}: Props) {
<SettingsList.PressableItem <SettingsList.PressableItem
label={_(msg`Switch account`)} label={_(msg`Switch account`)}
accessibilityHint={_( accessibilityHint={_(
msg`Show other accounts you can switch to`, msg`Shows other accounts you can switch to`,
)} )}
onPress={() => { onPress={() => {
if (!reducedMotion) { if (!reducedMotion) {
@@ -205,7 +205,7 @@ export function SettingsScreen({}: Props) {
<SettingsList.PressableItem <SettingsList.PressableItem
onPress={() => Linking.openURL(HELP_DESK_URL)} onPress={() => Linking.openURL(HELP_DESK_URL)}
label={_(msg`Help`)} label={_(msg`Help`)}
accessibilityHint={_(msg`Open helpdesk in browser`)}> accessibilityHint={_(msg`Opens helpdesk in browser`)}>
<SettingsList.ItemIcon icon={CircleQuestionIcon} /> <SettingsList.ItemIcon icon={CircleQuestionIcon} />
<SettingsList.ItemText> <SettingsList.ItemText>
<Trans>Help</Trans> <Trans>Help</Trans>
@@ -421,7 +421,7 @@ function AccountRow({
<View style={[{width: 28}]} /> <View style={[{width: 28}]} />
)} )}
<SettingsList.ItemText> <SettingsList.ItemText>
<Trans>{sanitizeHandle(account.handle, '@')}</Trans> {sanitizeHandle(account.handle, '@')}
</SettingsList.ItemText> </SettingsList.ItemText>
{pendingDid === account.did && <SettingsList.ItemIcon icon={Loader} />} {pendingDid === account.did && <SettingsList.ItemIcon icon={Loader} />}
</SettingsList.PressableItem> </SettingsList.PressableItem>
@@ -17,8 +17,8 @@ import {useMutation, useQueryClient} from '@tanstack/react-query'
import {HITSLOP_10} from '#/lib/constants' import {HITSLOP_10} from '#/lib/constants'
import {cleanError} from '#/lib/strings/errors' import {cleanError} from '#/lib/strings/errors'
import {createFullHandle, validateServiceHandle} from '#/lib/strings/handles'
import {sanitizeHandle} from '#/lib/strings/handles' import {sanitizeHandle} from '#/lib/strings/handles'
import {createFullHandle, validateHandle} from '#/lib/strings/handles'
import {useFetchDid, useUpdateHandleMutation} from '#/state/queries/handle' import {useFetchDid, useUpdateHandleMutation} from '#/state/queries/handle'
import {RQKEY as RQKEY_PROFILE} from '#/state/queries/profile' import {RQKEY as RQKEY_PROFILE} from '#/state/queries/profile'
import {useServiceQuery} from '#/state/queries/service' import {useServiceQuery} from '#/state/queries/service'
@@ -172,7 +172,7 @@ function ProvidedHandlePage({
const host = serviceInfo.availableUserDomains[0] const host = serviceInfo.availableUserDomains[0]
const validation = useMemo( const validation = useMemo(
() => validateHandle(subdomain, host, true), () => validateServiceHandle(subdomain, host),
[subdomain, host], [subdomain, host],
) )
@@ -537,7 +537,7 @@ function OwnHandlePage({goToServiceHandle}: {goToServiceHandle: () => void}) {
<Button <Button
label={_(msg`Use default provider`)} label={_(msg`Use default provider`)}
accessibilityHint={_(msg`Go back to previous page`)} accessibilityHint={_(msg`Returns to previous page`)}
onPress={goToServiceHandle} onPress={goToServiceHandle}
variant="outline" variant="outline"
color="secondary" color="secondary"
+3 -3
View File
@@ -7,7 +7,7 @@ import {logEvent} from '#/lib/statsig/statsig'
import { import {
createFullHandle, createFullHandle,
maxServiceHandleLength, maxServiceHandleLength,
validateHandle, validateServiceHandle,
} from '#/lib/strings/handles' } from '#/lib/strings/handles'
import {useAgent} from '#/state/session' import {useAgent} from '#/state/session'
import {ScreenTransition} from '#/screens/Login/ScreenTransition' import {ScreenTransition} from '#/screens/Login/ScreenTransition'
@@ -37,7 +37,7 @@ export function StepHandle() {
value: handle, value: handle,
}) })
const newValidCheck = validateHandle(handle, state.userDomain) const newValidCheck = validateServiceHandle(handle, state.userDomain)
if (!newValidCheck.overall) { if (!newValidCheck.overall) {
return return
} }
@@ -97,7 +97,7 @@ export function StepHandle() {
}) })
}, [dispatch, state.activeStep]) }, [dispatch, state.activeStep])
const validCheck = validateHandle(draftValue, state.userDomain, true) const validCheck = validateServiceHandle(draftValue, state.userDomain)
return ( return (
<ScreenTransition> <ScreenTransition>
<View style={[a.gap_lg]}> <View style={[a.gap_lg]}>
+1 -1
View File
@@ -285,7 +285,7 @@ function WizardInner({
<Layout.Header.Outer> <Layout.Header.Outer>
<Layout.Header.BackButton <Layout.Header.BackButton
label={_(msg`Back`)} label={_(msg`Back`)}
accessibilityHint={_(msg`Go back to the previous step`)} accessibilityHint={_(msg`Returns to the previous step`)}
onPress={evt => { onPress={evt => {
if (state.currentStep !== 'Details') { if (state.currentStep !== 'Details') {
evt.preventDefault() evt.preventDefault()
+4 -2
View File
@@ -806,7 +806,9 @@ function Overlay({
: _(msg`Follow ${handle}`) : _(msg`Follow ${handle}`)
} }
accessibilityHint={ accessibilityHint={
profile.viewer?.following ? _(msg`Unfollow user`) : '' profile.viewer?.following
? _(msg`Unfollows the user`)
: ''
} }
size="small" size="small"
variant="solid" variant="solid"
@@ -936,7 +938,7 @@ function ExpandableRichTextView({
/> />
{constrained && !screenReaderEnabled && ( {constrained && !screenReaderEnabled && (
<Pressable <Pressable
accessibilityHint={_(msg`Tap to expand or collapse post text.`)} accessibilityHint={_(msg`Expands or collapses post text`)}
accessibilityLabel={expanded ? _(msg`Read less`) : _(msg`Read more`)} accessibilityLabel={expanded ? _(msg`Read less`) : _(msg`Read more`)}
hitSlop={HITSLOP_20} hitSlop={HITSLOP_20}
onPress={() => setExpanded(prev => !prev)} onPress={() => setExpanded(prev => !prev)}
+9
View File
@@ -0,0 +1,9 @@
import {device, useStorage} from '#/storage'
export function useDevModeEnabled() {
const [devModeEnabled = false, setDevModeEnabled] = useStorage(device, [
'devMode',
])
return [devModeEnabled, setDevModeEnabled] as const
}
@@ -0,0 +1,20 @@
import {AppBskyActorDefs} from '@atproto/api'
import {useMutation, useQueryClient} from '@tanstack/react-query'
import {preferencesQueryKey} from '#/state/queries/preferences'
import {useAgent} from '#/state/session'
export function usePostInteractionSettingsMutation() {
const qc = useQueryClient()
const agent = useAgent()
return useMutation({
async mutationFn(props: AppBskyActorDefs.PostInteractionSettingsPref) {
await agent.setPostInteractionSettings(props)
},
async onSuccess() {
await qc.invalidateQueries({
queryKey: preferencesQueryKey,
})
},
})
}
+4
View File
@@ -39,4 +39,8 @@ export const DEFAULT_LOGGED_OUT_PREFERENCES: UsePreferencesQueryResponse = {
activeProgressGuide: undefined, activeProgressGuide: undefined,
nuxs: [], nuxs: [],
}, },
postInteractionSettings: {
threadgateAllowRules: undefined,
postgateEmbeddingRules: [],
},
} }
+9 -1
View File
@@ -11,6 +11,7 @@ import {
Un$Typed, Un$Typed,
} from '@atproto/api' } from '@atproto/api'
import { import {
keepPreviousData,
QueryClient, QueryClient,
useMutation, useMutation,
useQuery, useQuery,
@@ -84,7 +85,13 @@ export function useProfileQuery({
}) })
} }
export function useProfilesQuery({handles}: {handles: string[]}) { export function useProfilesQuery({
handles,
maintainData,
}: {
handles: string[]
maintainData?: boolean
}) {
const agent = useAgent() const agent = useAgent()
return useQuery({ return useQuery({
staleTime: STALE.MINUTES.FIVE, staleTime: STALE.MINUTES.FIVE,
@@ -93,6 +100,7 @@ export function useProfilesQuery({handles}: {handles: string[]}) {
const res = await agent.getProfiles({actors: handles}) const res = await agent.getProfiles({actors: handles})
return res.data return res.data
}, },
placeholderData: maintainData ? keepPreviousData : undefined,
}) })
} }
+1
View File
@@ -4,3 +4,4 @@ export type ThreadgateAllowUISetting =
| {type: 'mention'} | {type: 'mention'}
| {type: 'following'} | {type: 'following'}
| {type: 'list'; list: string} | {type: 'list'; list: string}
| {type: 'followers'}
+4
View File
@@ -46,6 +46,8 @@ export function threadgateRecordToAllowUISetting(
setting = {type: 'following'} setting = {type: 'following'}
} else if (AppBskyFeedThreadgate.isListRule(allow)) { } else if (AppBskyFeedThreadgate.isListRule(allow)) {
setting = {type: 'list', list: allow.list} setting = {type: 'list', list: allow.list}
} else if (AppBskyFeedThreadgate.isFollowerRule(allow)) {
setting = {type: 'followers'}
} }
return setting return setting
}) })
@@ -76,6 +78,8 @@ export function threadgateAllowUISettingToAllowRecordValue(
allow.push({$type: 'app.bsky.feed.threadgate#mentionRule'}) allow.push({$type: 'app.bsky.feed.threadgate#mentionRule'})
} else if (rule.type === 'following') { } else if (rule.type === 'following') {
allow.push({$type: 'app.bsky.feed.threadgate#followingRule'}) allow.push({$type: 'app.bsky.feed.threadgate#followingRule'})
} else if (rule.type === 'followers') {
allow.push({$type: 'app.bsky.feed.threadgate#followerRule'})
} else if (rule.type === 'list') { } else if (rule.type === 'list') {
allow.push({ allow.push({
$type: 'app.bsky.feed.threadgate#listRule', $type: 'app.bsky.feed.threadgate#listRule',
+3 -16
View File
@@ -1,6 +1,5 @@
import React from 'react' import React from 'react'
import {useGate} from '#/lib/statsig/statsig'
import {useLanguagePrefs} from '#/state/preferences/languages' import {useLanguagePrefs} from '#/state/preferences/languages'
import {useServiceConfigQuery} from '#/state/queries/service-config' import {useServiceConfigQuery} from '#/state/queries/service-config'
import {device} from '#/storage' import {device} from '#/storage'
@@ -14,7 +13,6 @@ const Context = React.createContext<Context>({
}) })
export function Provider({children}: React.PropsWithChildren<{}>) { export function Provider({children}: React.PropsWithChildren<{}>) {
const gate = useGate()
const langPrefs = useLanguagePrefs() const langPrefs = useLanguagePrefs()
const {data: config, isLoading: isInitialLoad} = useServiceConfigQuery() const {data: config, isLoading: isInitialLoad} = useServiceConfigQuery()
const ctx = React.useMemo<Context>(() => { const ctx = React.useMemo<Context>(() => {
@@ -45,23 +43,12 @@ export function Provider({children}: React.PropsWithChildren<{}>) {
* the server, we can exit early. * the server, we can exit early.
*/ */
const enabled = Boolean(config?.topicsEnabled) const enabled = Boolean(config?.topicsEnabled)
if (!enabled) {
// cache for next reload
device.set(['trendingBetaEnabled'], enabled)
return {enabled: false}
}
/*
* Service is enabled, but also check statsig in case we're rolling back.
*/
const gateEnabled = gate('trending_topics_beta')
const _enabled = enabled && gateEnabled
// update cache // update cache
device.set(['trendingBetaEnabled'], _enabled) device.set(['trendingBetaEnabled'], enabled)
return {enabled: _enabled} return {enabled}
}, [isInitialLoad, config, gate, langPrefs.contentLanguages]) }, [isInitialLoad, config, langPrefs.contentLanguages])
return <Context.Provider value={ctx}>{children}</Context.Provider> return <Context.Provider value={ctx}>{children}</Context.Provider>
} }
+69 -3
View File
@@ -1,5 +1,5 @@
import {useCallback, useEffect, useState} from 'react'
import {MMKV} from 'react-native-mmkv' import {MMKV} from 'react-native-mmkv'
import {Did} from '@atproto/api'
import {Account, Device} from '#/storage/schema' import {Account, Device} from '#/storage/schema'
@@ -65,6 +65,72 @@ export class Storage<Scopes extends unknown[], Schema> {
removeMany<Key extends keyof Schema>(scopes: [...Scopes], keys: Key[]) { removeMany<Key extends keyof Schema>(scopes: [...Scopes], keys: Key[]) {
keys.forEach(key => this.remove([...scopes, key])) keys.forEach(key => this.remove([...scopes, key]))
} }
/**
* Fires a callback when the storage associated with a given key changes
*
* @returns Listener - call `remove()` to stop listening
*/
addOnValueChangedListener<Key extends keyof Schema>(
scopes: [...Scopes, Key],
callback: () => void,
) {
return this.store.addOnValueChangedListener(key => {
if (key === scopes.join(this.sep)) {
callback()
}
})
}
}
type StorageSchema<T extends Storage<any, any>> = T extends Storage<
any,
infer U
>
? U
: never
type StorageScopes<T extends Storage<any, any>> = T extends Storage<
infer S,
any
>
? S
: never
/**
* Hook to use a storage instance. Acts like a useState hook, but persists the
* value in storage.
*/
export function useStorage<
Store extends Storage<any, any>,
Key extends keyof StorageSchema<Store>,
>(
storage: Store,
scopes: [...StorageScopes<Store>, Key],
): [
StorageSchema<Store>[Key] | undefined,
(data: StorageSchema<Store>[Key]) => void,
] {
type Schema = StorageSchema<Store>
const [value, setValue] = useState<Schema[Key] | undefined>(() =>
storage.get(scopes),
)
useEffect(() => {
const sub = storage.addOnValueChangedListener(scopes, () => {
setValue(storage.get(scopes))
})
return () => sub.remove()
}, [storage, scopes])
const setter = useCallback(
(data: Schema[Key]) => {
setValue(data)
storage.set(scopes, data)
},
[storage, scopes],
)
return [value, setter] as const
} }
/** /**
@@ -77,10 +143,10 @@ export const device = new Storage<[], Device>({id: 'bsky_device'})
/** /**
* Account data that's specific to the account on this device * Account data that's specific to the account on this device
*/ */
export const account = new Storage<[Did], Account>({id: 'bsky_account'}) export const account = new Storage<[string], Account>({id: 'bsky_account'})
if (__DEV__ && typeof window !== 'undefined') { if (__DEV__ && typeof window !== 'undefined') {
// @ts-ignore // @ts-expect-error - dev global
window.bsky_storage = { window.bsky_storage = {
device, device,
account, account,
+2
View File
@@ -9,8 +9,10 @@ export type Device = {
countryCode: string | undefined countryCode: string | undefined
} }
trendingBetaEnabled: boolean trendingBetaEnabled: boolean
devMode: boolean
} }
export type Account = { export type Account = {
searchTermHistory?: string[] searchTermHistory?: string[]
searchAccountHistory?: string[]
} }
+33
View File
@@ -187,6 +187,7 @@ input:focus {
animation: rotate 500ms linear infinite; animation: rotate 500ms linear infinite;
} }
/* animations for atoms */
@keyframes fadeIn { @keyframes fadeIn {
from { from {
opacity: 0; opacity: 0;
@@ -205,6 +206,38 @@ input:focus {
} }
} }
@keyframes zoomIn {
from {
transform: scale(0.95);
}
to {
transform: scale(1);
}
}
@keyframes slideInLeft {
from {
transform: translateX(-100%);
}
to {
transform: translateX(0);
}
}
@keyframes slideOutLeft {
from {
transform: translateX(0);
}
to {
transform: translateX(-100%);
}
}
/* animating radix dropdowns requires knowing the data attributes */
.dropdown-menu-transform-origin > * {
transform-origin: var(--radix-dropdown-menu-content-transform-origin);
}
.force-no-clicks > *, .force-no-clicks > *,
.force-no-clicks * { .force-no-clicks * {
pointer-events: none !important; pointer-events: none !important;
+10 -2
View File
@@ -83,6 +83,7 @@ import {
useLanguagePrefs, useLanguagePrefs,
useLanguagePrefsApi, useLanguagePrefsApi,
} from '#/state/preferences/languages' } from '#/state/preferences/languages'
import {usePreferencesQuery} from '#/state/queries/preferences'
import {useProfileQuery} from '#/state/queries/profile' import {useProfileQuery} from '#/state/queries/profile'
import {Gif} from '#/state/queries/tenor' import {Gif} from '#/state/queries/tenor'
import {useAgent, useSession} from '#/state/session' import {useAgent, useSession} from '#/state/session'
@@ -169,6 +170,7 @@ export const ComposePost = ({
const discardPromptControl = Prompt.usePromptControl() const discardPromptControl = Prompt.usePromptControl()
const {closeAllDialogs} = useDialogStateControlContext() const {closeAllDialogs} = useDialogStateControlContext()
const {closeAllModals} = useModalControls() const {closeAllModals} = useModalControls()
const {data: preferences} = usePreferencesQuery()
const [isKeyboardVisible] = useIsKeyboardVisible({iosUseWillEvents: true}) const [isKeyboardVisible] = useIsKeyboardVisible({iosUseWillEvents: true})
const [isPublishing, setIsPublishing] = useState(false) const [isPublishing, setIsPublishing] = useState(false)
@@ -177,7 +179,13 @@ export const ComposePost = ({
const [composerState, composerDispatch] = useReducer( const [composerState, composerDispatch] = useReducer(
composerReducer, composerReducer,
{initImageUris, initQuoteUri: initQuote?.uri, initText, initMention}, {
initImageUris,
initQuoteUri: initQuote?.uri,
initText,
initMention,
initInteractionSettings: preferences?.postInteractionSettings,
},
createComposerState, createComposerState,
) )
@@ -1233,7 +1241,7 @@ function ComposerFooter({
onPress={onEmojiButtonPress} onPress={onEmojiButtonPress}
style={a.p_sm} style={a.p_sm}
label={_(msg`Open emoji picker`)} label={_(msg`Open emoji picker`)}
accessibilityHint={_(msg`Open emoji picker`)} accessibilityHint={_(msg`Opens emoji picker`)}
variant="ghost" variant="ghost"
shape="round" shape="round"
color="primary"> color="primary">
+1 -1
View File
@@ -70,7 +70,7 @@ export function ComposerReplyTo({replyTo}: {replyTo: ComposerOptsPostRef}) {
msg`Expand or collapse the full post you are replying to`, msg`Expand or collapse the full post you are replying to`,
)} )}
accessibilityHint={_( accessibilityHint={_(
msg`Expand or collapse the full post you are replying to`, msg`Expands or collapses the full post you are replying to`,
)}> )}>
<PreviewableUserAvatar <PreviewableUserAvatar
size={50} size={50}
+21 -4
View File
@@ -1,5 +1,10 @@
import {ImagePickerAsset} from 'expo-image-picker' import {ImagePickerAsset} from 'expo-image-picker'
import {AppBskyFeedPostgate, AppBskyRichtextFacet, RichText} from '@atproto/api' import {
AppBskyFeedPostgate,
AppBskyRichtextFacet,
BskyPreferences,
RichText,
} from '@atproto/api'
import {nanoid} from 'nanoid/non-secure' import {nanoid} from 'nanoid/non-secure'
import {SelfLabel} from '#/lib/moderation' import {SelfLabel} from '#/lib/moderation'
@@ -13,7 +18,7 @@ import {
import {ComposerImage, createInitialImages} from '#/state/gallery' import {ComposerImage, createInitialImages} from '#/state/gallery'
import {createPostgateRecord} from '#/state/queries/postgate/util' import {createPostgateRecord} from '#/state/queries/postgate/util'
import {Gif} from '#/state/queries/tenor' import {Gif} from '#/state/queries/tenor'
import {threadgateViewToAllowUISetting} from '#/state/queries/threadgate' import {threadgateRecordToAllowUISetting} from '#/state/queries/threadgate'
import {ThreadgateAllowUISetting} from '#/state/queries/threadgate' import {ThreadgateAllowUISetting} from '#/state/queries/threadgate'
import {ComposerOpts} from '#/state/shell/composer' import {ComposerOpts} from '#/state/shell/composer'
import { import {
@@ -477,11 +482,15 @@ export function createComposerState({
initMention, initMention,
initImageUris, initImageUris,
initQuoteUri, initQuoteUri,
initInteractionSettings,
}: { }: {
initText: string | undefined initText: string | undefined
initMention: string | undefined initMention: string | undefined
initImageUris: ComposerOpts['imageUris'] initImageUris: ComposerOpts['imageUris']
initQuoteUri: string | undefined initQuoteUri: string | undefined
initInteractionSettings:
| BskyPreferences['postInteractionSettings']
| undefined
}): ComposerState { }): ComposerState {
let media: ImagesMedia | undefined let media: ImagesMedia | undefined
if (initImageUris?.length) { if (initImageUris?.length) {
@@ -591,8 +600,16 @@ export function createComposerState({
}, },
}, },
], ],
postgate: createPostgateRecord({post: ''}), postgate: createPostgateRecord({
threadgate: threadgateViewToAllowUISetting(undefined), post: '',
embeddingRules: initInteractionSettings?.postgateEmbeddingRules || [],
}),
threadgate: threadgateRecordToAllowUISetting({
$type: 'app.bsky.feed.threadgate',
post: '',
createdAt: new Date().toString(),
allow: initInteractionSettings?.threadgateAllowRules,
}),
}, },
} }
} }
@@ -135,7 +135,7 @@ export function EmojiPicker({state, close, pinToTop}: IProps) {
<Pressable <Pressable
accessible accessible
accessibilityLabel={_(msg`Close emoji picker`)} accessibilityLabel={_(msg`Close emoji picker`)}
accessibilityHint={_(msg`Tap to close the emoji picker`)} accessibilityHint={_(msg`Closes the emoji picker`)}
onPress={close} onPress={close}
style={[a.fixed, a.inset_0]} style={[a.fixed, a.inset_0]}
/> />
@@ -171,7 +171,7 @@ export function EmojiPicker({state, close, pinToTop}: IProps) {
<Pressable <Pressable
accessible accessible
accessibilityLabel={_(msg`Close emoji picker`)} accessibilityLabel={_(msg`Close emoji picker`)}
accessibilityHint={_(msg`Tap to close the emoji picker`)} accessibilityHint={_(msg`Closes the emoji picker`)}
onPress={close} onPress={close}
style={[a.fixed, a.inset_0]} style={[a.fixed, a.inset_0]}
/> />
+1
View File
@@ -120,6 +120,7 @@ export function ModalsContainer() {
} }
handleIndicatorStyle={{backgroundColor: pal.text.color}} handleIndicatorStyle={{backgroundColor: pal.text.color}}
handleStyle={[styles.handle, pal.view]} handleStyle={[styles.handle, pal.view]}
backgroundStyle={pal.view}
onChange={onBottomSheetChange}> onChange={onBottomSheetChange}>
{element} {element}
</BottomSheet> </BottomSheet>
+7 -2
View File
@@ -242,6 +242,11 @@ let PostThreadItemLoaded = ({
return makeProfileLink(post.author, 'post', urip.rkey, 'quotes') return makeProfileLink(post.author, 'post', urip.rkey, 'quotes')
}, [post.uri, post.author]) }, [post.uri, post.author])
const quotesTitle = _(msg`Quotes of this post`) const quotesTitle = _(msg`Quotes of this post`)
const onlyFollowersCanReply = !!threadgateRecord?.allow?.find(
rule => rule.$type === 'app.bsky.feed.threadgate#followerRule',
)
const showFollowButton =
currentAccount?.did !== post.author.did && !onlyFollowersCanReply
const translatorUrl = getTranslatorLink( const translatorUrl = getTranslatorLink(
record?.text || '', record?.text || '',
@@ -344,7 +349,7 @@ let PostThreadItemLoaded = ({
</Text> </Text>
</Link> </Link>
</View> </View>
{currentAccount?.did !== post.author.did && ( {showFollowButton && (
<View> <View>
<PostThreadFollowBtn did={post.author.did} /> <PostThreadFollowBtn did={post.author.did} />
</View> </View>
@@ -806,7 +811,7 @@ function BackdatedPostIndicator({post}: {post: AppBskyFeedDefs.PostView}) {
<Button <Button
label={_(msg`Archived post`)} label={_(msg`Archived post`)}
accessibilityHint={_( accessibilityHint={_(
msg`Show information about when this post was created`, msg`Shows information about when this post was created`,
)} )}
onPress={e => { onPress={e => {
e.preventDefault() e.preventDefault()
+36 -1
View File
@@ -6,11 +6,12 @@ import {useQueryClient} from '@tanstack/react-query'
import {HITSLOP_20} from '#/lib/constants' import {HITSLOP_20} from '#/lib/constants'
import {makeProfileLink} from '#/lib/routes/links' import {makeProfileLink} from '#/lib/routes/links'
import {shareUrl} from '#/lib/sharing' import {shareText, shareUrl} from '#/lib/sharing'
import {toShareUrl} from '#/lib/strings/url-helpers' import {toShareUrl} from '#/lib/strings/url-helpers'
import {logger} from '#/logger' import {logger} from '#/logger'
import {Shadow} from '#/state/cache/types' import {Shadow} from '#/state/cache/types'
import {useModalControls} from '#/state/modals' import {useModalControls} from '#/state/modals'
import {useDevModeEnabled} from '#/state/preferences/dev-mode'
import { import {
RQKEY as profileQueryKey, RQKEY as profileQueryKey,
useProfileBlockMutationQueue, useProfileBlockMutationQueue,
@@ -52,6 +53,7 @@ let ProfileMenu = ({
const isBlocked = profile.viewer?.blocking || profile.viewer?.blockedBy const isBlocked = profile.viewer?.blocking || profile.viewer?.blockedBy
const isFollowingBlockedAccount = isFollowing && isBlocked const isFollowingBlockedAccount = isFollowing && isBlocked
const isLabelerAndNotBlocked = !!profile.associated?.labeler && !isBlocked const isLabelerAndNotBlocked = !!profile.associated?.labeler && !isBlocked
const [devModeEnabled] = useDevModeEnabled()
const [queueMute, queueUnmute] = useProfileMuteMutationQueue(profile) const [queueMute, queueUnmute] = useProfileMuteMutationQueue(profile)
const [queueBlock, queueUnblock] = useProfileBlockMutationQueue(profile) const [queueBlock, queueUnblock] = useProfileBlockMutationQueue(profile)
@@ -167,6 +169,14 @@ let ProfileMenu = ({
reportDialogControl.open() reportDialogControl.open()
}, [reportDialogControl]) }, [reportDialogControl])
const onPressShareATUri = React.useCallback(() => {
shareText(`at://${profile.did}`)
}, [profile.did])
const onPressShareDID = React.useCallback(() => {
shareText(profile.did)
}, [profile.did])
return ( return (
<EventStopper onKeyDown={false}> <EventStopper onKeyDown={false}>
<Menu.Root> <Menu.Root>
@@ -308,6 +318,31 @@ let ProfileMenu = ({
</Menu.Group> </Menu.Group>
</> </>
)} )}
{devModeEnabled ? (
<>
<Menu.Divider />
<Menu.Group>
<Menu.Item
testID="profileHeaderDropdownShareATURIBtn"
label={_(msg`Copy at:// URI`)}
onPress={onPressShareATUri}>
<Menu.ItemText>
<Trans>Copy at:// URI</Trans>
</Menu.ItemText>
<Menu.ItemIcon icon={Share} />
</Menu.Item>
<Menu.Item
testID="profileHeaderDropdownShareDIDBtn"
label={_(msg`Copy DID`)}
onPress={onPressShareDID}>
<Menu.ItemText>
<Trans>Copy DID</Trans>
</Menu.ItemText>
<Menu.ItemIcon icon={Share} />
</Menu.Item>
</Menu.Group>
</>
) : null}
</Menu.Outer> </Menu.Outer>
</Menu.Root> </Menu.Root>
+7 -1
View File
@@ -14,6 +14,7 @@ import {useLingui} from '@lingui/react'
import {usePalette} from '#/lib/hooks/usePalette' import {usePalette} from '#/lib/hooks/usePalette'
import {useTheme} from '#/lib/ThemeContext' import {useTheme} from '#/lib/ThemeContext'
import * as Layout from '#/components/Layout'
import {Text} from '../text/Text' import {Text} from '../text/Text'
export function ErrorMessage({ export function ErrorMessage({
@@ -31,9 +32,13 @@ export function ErrorMessage({
const pal = usePalette('error') const pal = usePalette('error')
const {_} = useLingui() const {_} = useLingui()
return ( return (
<Layout.Center>
<View testID="errorMessageView" style={[styles.outer, pal.view, style]}> <View testID="errorMessageView" style={[styles.outer, pal.view, style]}>
<View <View
style={[styles.errorIcon, {backgroundColor: theme.palette.error.icon}]}> style={[
styles.errorIcon,
{backgroundColor: theme.palette.error.icon},
]}>
<FontAwesomeIcon <FontAwesomeIcon
icon="exclamation" icon="exclamation"
style={pal.text as FontAwesomeIconStyle} style={pal.text as FontAwesomeIconStyle}
@@ -64,6 +69,7 @@ export function ErrorMessage({
</TouchableOpacity> </TouchableOpacity>
)} )}
</View> </View>
</Layout.Center>
) )
} }
+3 -1
View File
@@ -293,7 +293,9 @@ const DropdownItems = ({
onPress={() => onPressItem(index)} onPress={() => onPressItem(index)}
accessibilityRole="button" accessibilityRole="button"
accessibilityLabel={item.label} accessibilityLabel={item.label}
accessibilityHint={_(msg`Option ${index + 1} of ${numItems}`)}> accessibilityHint={_(
msg`Selects option ${index + 1} of ${numItems}`,
)}>
{item.icon && ( {item.icon && (
<FontAwesomeIcon <FontAwesomeIcon
style={styles.icon} style={styles.icon}
@@ -21,7 +21,7 @@ import {useOpenLink} from '#/lib/hooks/useOpenLink'
import {getCurrentRoute} from '#/lib/routes/helpers' import {getCurrentRoute} from '#/lib/routes/helpers'
import {makeProfileLink} from '#/lib/routes/links' import {makeProfileLink} from '#/lib/routes/links'
import {CommonNavigatorParams, NavigationProp} from '#/lib/routes/types' import {CommonNavigatorParams, NavigationProp} from '#/lib/routes/types'
import {shareUrl} from '#/lib/sharing' import {shareText, shareUrl} from '#/lib/sharing'
import {logEvent} from '#/lib/statsig/statsig' import {logEvent} from '#/lib/statsig/statsig'
import {richTextToString} from '#/lib/strings/rich-text-helpers' import {richTextToString} from '#/lib/strings/rich-text-helpers'
import {toShareUrl} from '#/lib/strings/url-helpers' import {toShareUrl} from '#/lib/strings/url-helpers'
@@ -33,6 +33,7 @@ import {useProfileShadow} from '#/state/cache/profile-shadow'
import {useFeedFeedbackContext} from '#/state/feed-feedback' import {useFeedFeedbackContext} from '#/state/feed-feedback'
import {useLanguagePrefs} from '#/state/preferences' import {useLanguagePrefs} from '#/state/preferences'
import {useHiddenPosts, useHiddenPostsApi} from '#/state/preferences' import {useHiddenPosts, useHiddenPostsApi} from '#/state/preferences'
import {useDevModeEnabled} from '#/state/preferences/dev-mode'
import {usePinnedPostMutation} from '#/state/queries/pinned-post' import {usePinnedPostMutation} from '#/state/queries/pinned-post'
import { import {
usePostDeleteMutation, usePostDeleteMutation,
@@ -122,6 +123,7 @@ let PostDropdownMenuItems = ({
const hideReplyConfirmControl = useDialogControl() const hideReplyConfirmControl = useDialogControl()
const {mutateAsync: toggleReplyVisibility} = const {mutateAsync: toggleReplyVisibility} =
useToggleReplyVisibilityMutation() useToggleReplyVisibilityMutation()
const [devModeEnabled] = useDevModeEnabled()
const postUri = post.uri const postUri = post.uri
const postCid = post.cid const postCid = post.cid
@@ -366,6 +368,14 @@ let PostDropdownMenuItems = ({
} }
}, [_, queueBlock]) }, [_, queueBlock])
const onShareATURI = useCallback(() => {
shareText(postUri)
}, [postUri])
const onShareAuthorDID = useCallback(() => {
shareText(postAuthor.did)
}, [postAuthor.did])
return ( return (
<> <>
<Menu.Outer> <Menu.Outer>
@@ -647,6 +657,28 @@ let PostDropdownMenuItems = ({
</> </>
)} )}
</Menu.Group> </Menu.Group>
{devModeEnabled ? (
<>
<Menu.Divider />
<Menu.Group>
<Menu.Item
testID="postAtUriShareBtn"
label={_(msg`Copy post at:// URI`)}
onPress={onShareATURI}>
<Menu.ItemText>{_(msg`Copy post at:// URI`)}</Menu.ItemText>
<Menu.ItemIcon icon={Share} position="right" />
</Menu.Item>
<Menu.Item
testID="postAuthorDIDShareBtn"
label={_(msg`Copy author DID`)}
onPress={onShareAuthorDID}>
<Menu.ItemText>{_(msg`Copy author DID`)}</Menu.ItemText>
<Menu.ItemIcon icon={Share} position="right" />
</Menu.Item>
</Menu.Group>
</>
) : null}
</> </>
)} )}
</Menu.Outer> </Menu.Outer>
+2 -2
View File
@@ -196,7 +196,7 @@ export function AutoSizedImage({
onPressIn={onPressIn} onPressIn={onPressIn}
// alt here is what screen readers actually use // alt here is what screen readers actually use
accessibilityLabel={image.alt} accessibilityLabel={image.alt}
accessibilityHint={_(msg`Tap to view full image`)} accessibilityHint={_(msg`Views full image`)}
style={[ style={[
a.w_full, a.w_full,
a.rounded_md, a.rounded_md,
@@ -218,7 +218,7 @@ export function AutoSizedImage({
onPressIn={onPressIn} onPressIn={onPressIn}
// alt here is what screen readers actually use // alt here is what screen readers actually use
accessibilityLabel={image.alt} accessibilityLabel={image.alt}
accessibilityHint={_(msg`Tap to view full image`)} accessibilityHint={_(msg`Views full image`)}
style={[a.h_full]}> style={[a.h_full]}>
{contents} {contents}
</Pressable> </Pressable>
+12 -2
View File
@@ -26,6 +26,7 @@ import {makeProfileLink} from '#/lib/routes/links'
import {shareUrl} from '#/lib/sharing' import {shareUrl} from '#/lib/sharing'
import {useGate} from '#/lib/statsig/statsig' import {useGate} from '#/lib/statsig/statsig'
import {toShareUrl} from '#/lib/strings/url-helpers' import {toShareUrl} from '#/lib/strings/url-helpers'
import {useProfileShadow} from '#/state/cache/profile-shadow'
import {Shadow} from '#/state/cache/types' import {Shadow} from '#/state/cache/types'
import {useFeedFeedbackContext} from '#/state/feed-feedback' import {useFeedFeedbackContext} from '#/state/feed-feedback'
import { import {
@@ -94,6 +95,15 @@ let PostCtrls = ({
post.author.viewer?.blockingByList, post.author.viewer?.blockingByList,
) )
const shadowedAuthor = useProfileShadow(post.author)
const followersCanReply = !!threadgateRecord?.allow?.find(
rule => rule.$type === 'app.bsky.feed.threadgate#followerRule',
)
const canOverrideReplyDisabled =
followersCanReply &&
shadowedAuthor.viewer?.following?.startsWith('at://did')
const replyDisabled = post.viewer?.replyDisabled && !canOverrideReplyDisabled
const shouldShowLoggedOutWarning = React.useMemo(() => { const shouldShowLoggedOutWarning = React.useMemo(() => {
return ( return (
post.author.did !== currentAccount?.did && post.author.did !== currentAccount?.did &&
@@ -247,13 +257,13 @@ let PostCtrls = ({
<View <View
style={[ style={[
big ? a.align_center : [a.flex_1, a.align_start, {marginLeft: -6}], big ? a.align_center : [a.flex_1, a.align_start, {marginLeft: -6}],
post.viewer?.replyDisabled ? {opacity: 0.5} : undefined, replyDisabled ? {opacity: 0.5} : undefined,
]}> ]}>
<Pressable <Pressable
testID="replyBtn" testID="replyBtn"
style={btnStyle} style={btnStyle}
onPress={() => { onPress={() => {
if (!post.viewer?.replyDisabled) { if (!replyDisabled) {
playHaptic('Light') playHaptic('Light')
requireAuth(() => onPressReply()) requireAuth(() => onPressReply())
} }
@@ -56,7 +56,7 @@ function PlaceholderOverlay({
<Pressable <Pressable
accessibilityRole="button" accessibilityRole="button"
accessibilityLabel={_(msg`Play Video`)} accessibilityLabel={_(msg`Play Video`)}
accessibilityHint={_(msg`Play Video`)} accessibilityHint={_(msg`Plays the video`)}
onPress={onPress} onPress={onPress}
style={[styles.overlayContainer]}> style={[styles.overlayContainer]}>
{!isPlayerActive ? ( {!isPlayerActive ? (
+1 -1
View File
@@ -39,7 +39,7 @@ function PlaybackControls({
return ( return (
<Pressable <Pressable
accessibilityRole="button" accessibilityRole="button"
accessibilityHint={_(msg`Play or pause the GIF`)} accessibilityHint={_(msg`Plays or pauses the GIF`)}
accessibilityLabel={isPlaying ? _(msg`Pause`) : _(msg`Play`)} accessibilityLabel={isPlaying ? _(msg`Pause`) : _(msg`Play`)}
style={[ style={[
a.absolute, a.absolute,
@@ -132,13 +132,13 @@ function VideoControls({
onPress={enterFullscreen} onPress={enterFullscreen}
style={a.flex_1} style={a.flex_1}
accessibilityLabel={_(msg`Video`)} accessibilityLabel={_(msg`Video`)}
accessibilityHint={_(msg`Tap to enter full screen`)} accessibilityHint={_(msg`Enters full screen`)}
accessibilityRole="button" accessibilityRole="button"
/> />
<ControlButton <ControlButton
onPress={togglePlayback} onPress={togglePlayback}
label={isPlaying ? _(msg`Pause`) : _(msg`Play`)} label={isPlaying ? _(msg`Pause`) : _(msg`Play`)}
accessibilityHint={_(msg`Tap to play or pause`)} accessibilityHint={_(msg`Plays or pauses the video`)}
style={{left: 6}}> style={{left: 6}}>
{isPlaying ? ( {isPlaying ? (
<PauseIcon width={13} fill={t.palette.white} /> <PauseIcon width={13} fill={t.palette.white} />
@@ -155,7 +155,7 @@ function VideoControls({
? _(msg({message: `Unmute`, context: 'video'})) ? _(msg({message: `Unmute`, context: 'video'}))
: _(msg({message: `Mute`, context: 'video'})) : _(msg({message: `Mute`, context: 'video'}))
} }
accessibilityHint={_(msg`Tap to toggle sound`)} accessibilityHint={_(msg`Toggles the sound`)}
style={{right: 6}}> style={{right: 6}}>
{muted ? ( {muted ? (
<MuteIcon width={13} fill={t.palette.white} /> <MuteIcon width={13} fill={t.palette.white} />
+1 -1
View File
@@ -1007,7 +1007,7 @@ function ErrorScreen({error}: {error: string}) {
<Button <Button
type="default" type="default"
accessibilityLabel={_(msg`Go back`)} accessibilityLabel={_(msg`Go back`)}
accessibilityHint={_(msg`Return to previous page`)} accessibilityHint={_(msg`Returns to previous page`)}
onPress={onPressBack} onPress={onPressBack}
style={{flexShrink: 1}}> style={{flexShrink: 1}}>
<Text type="button" style={pal.text}> <Text type="button" style={pal.text}>
+181 -229
View File
@@ -1,4 +1,4 @@
import React from 'react' import React, {useCallback, useLayoutEffect, useMemo} from 'react'
import { import {
ActivityIndicator, ActivityIndicator,
Image, Image,
@@ -10,7 +10,6 @@ import {
View, View,
} from 'react-native' } from 'react-native'
import {ScrollView as RNGHScrollView} from 'react-native-gesture-handler' import {ScrollView as RNGHScrollView} from 'react-native-gesture-handler'
import RNPickerSelect from 'react-native-picker-select'
import {AppBskyActorDefs, AppBskyFeedDefs, moderateProfile} from '@atproto/api' import {AppBskyActorDefs, AppBskyFeedDefs, moderateProfile} from '@atproto/api'
import { import {
FontAwesomeIcon, FontAwesomeIcon,
@@ -18,11 +17,10 @@ import {
} from '@fortawesome/react-native-fontawesome' } from '@fortawesome/react-native-fontawesome'
import {msg, Trans} from '@lingui/macro' import {msg, Trans} from '@lingui/macro'
import {useLingui} from '@lingui/react' import {useLingui} from '@lingui/react'
import AsyncStorage from '@react-native-async-storage/async-storage'
import {useFocusEffect, useNavigation} from '@react-navigation/native' import {useFocusEffect, useNavigation} from '@react-navigation/native'
import {APP_LANGUAGES, LANGUAGES} from '#/lib/../locale/languages' import {APP_LANGUAGES, LANGUAGES} from '#/lib/../locale/languages'
import {createHitslop} from '#/lib/constants' import {createHitslop, HITSLOP_20} from '#/lib/constants'
import {HITSLOP_10} from '#/lib/constants' import {HITSLOP_10} from '#/lib/constants'
import {useNonReactiveCallback} from '#/lib/hooks/useNonReactiveCallback' import {useNonReactiveCallback} from '#/lib/hooks/useNonReactiveCallback'
import {usePalette} from '#/lib/hooks/usePalette' import {usePalette} from '#/lib/hooks/usePalette'
@@ -37,7 +35,6 @@ import {
import {sanitizeDisplayName} from '#/lib/strings/display-names' import {sanitizeDisplayName} from '#/lib/strings/display-names'
import {augmentSearchQuery} from '#/lib/strings/helpers' import {augmentSearchQuery} from '#/lib/strings/helpers'
import {languageName} from '#/locale/helpers' import {languageName} from '#/locale/helpers'
import {logger} from '#/logger'
import {isNative, isWeb} from '#/platform/detection' import {isNative, isWeb} from '#/platform/detection'
import {listenSoftReset} from '#/state/events' import {listenSoftReset} from '#/state/events'
import {useLanguagePrefs} from '#/state/preferences/languages' import {useLanguagePrefs} from '#/state/preferences/languages'
@@ -45,9 +42,9 @@ import {useModerationOpts} from '#/state/preferences/moderation-opts'
import {useActorAutocompleteQuery} from '#/state/queries/actor-autocomplete' import {useActorAutocompleteQuery} from '#/state/queries/actor-autocomplete'
import {useActorSearch} from '#/state/queries/actor-search' import {useActorSearch} from '#/state/queries/actor-search'
import {usePopularFeedsSearch} from '#/state/queries/feed' import {usePopularFeedsSearch} from '#/state/queries/feed'
import {useProfilesQuery} from '#/state/queries/profile'
import {useSearchPostsQuery} from '#/state/queries/search-posts' import {useSearchPostsQuery} from '#/state/queries/search-posts'
import {useSession} from '#/state/session' import {useSession} from '#/state/session'
import {useSetDrawerOpen} from '#/state/shell'
import {useSetMinimalShellMode} from '#/state/shell' import {useSetMinimalShellMode} from '#/state/shell'
import {Pager} from '#/view/com/pager/Pager' import {Pager} from '#/view/com/pager/Pager'
import {TabBar} from '#/view/com/pager/TabBar' import {TabBar} from '#/view/com/pager/TabBar'
@@ -61,17 +58,24 @@ import {SearchLinkCard, SearchProfileCard} from '#/view/shell/desktop/Search'
import {makeSearchQuery, parseSearchQuery} from '#/screens/Search/utils' import {makeSearchQuery, parseSearchQuery} from '#/screens/Search/utils'
import { import {
atoms as a, atoms as a,
native,
platform,
tokens, tokens,
useBreakpoints, useBreakpoints,
useTheme as useThemeNew, useTheme,
web, web,
} from '#/alf' } from '#/alf'
import {Button, ButtonIcon, ButtonText} from '#/components/Button' import {Button, ButtonIcon, ButtonText} from '#/components/Button'
import * as FeedCard from '#/components/FeedCard' import * as FeedCard from '#/components/FeedCard'
import {SearchInput} from '#/components/forms/SearchInput' import {SearchInput} from '#/components/forms/SearchInput'
import {ChevronBottom_Stroke2_Corner0_Rounded as ChevronDown} from '#/components/icons/Chevron' import {
import {Menu_Stroke2_Corner0_Rounded as Menu} from '#/components/icons/Menu' ChevronBottom_Stroke2_Corner0_Rounded as ChevronDownIcon,
ChevronTopBottom_Stroke2_Corner0_Rounded as ChevronUpDownIcon,
} from '#/components/icons/Chevron'
import {Earth_Stroke2_Corner0_Rounded as EarthIcon} from '#/components/icons/Globe'
import * as Layout from '#/components/Layout' import * as Layout from '#/components/Layout'
import * as Menu from '#/components/Menu'
import {account, useStorage} from '#/storage'
function Loader() { function Loader() {
return ( return (
@@ -278,7 +282,7 @@ let SearchScreenFeedsResults = ({
query: string query: string
active: boolean active: boolean
}): React.ReactNode => { }): React.ReactNode => {
const t = useThemeNew() const t = useTheme()
const {_} = useLingui() const {_} = useLingui()
const {data: results, isFetched} = usePopularFeedsSearch({ const {data: results, isFetched} = usePopularFeedsSearch({
@@ -323,27 +327,17 @@ function SearchLanguageDropdown({
value: string value: string
onChange(value: string): void onChange(value: string): void
}) { }) {
const t = useThemeNew()
const {_} = useLingui() const {_} = useLingui()
const {appLanguage, contentLanguages} = useLanguagePrefs() const {appLanguage, contentLanguages} = useLanguagePrefs()
const items = React.useMemo(() => { const languages = useMemo(() => {
return [ return LANGUAGES.filter(
{
label: _(msg`Any language`),
inputLabel: _(msg`Any language`),
value: '',
key: '*',
},
].concat(
LANGUAGES.filter(
(lang, index, self) => (lang, index, self) =>
Boolean(lang.code2) && // reduce to the code2 varieties Boolean(lang.code2) && // reduce to the code2 varieties
index === self.findIndex(t => t.code2 === lang.code2), // remove dupes (which will happen) index === self.findIndex(t => t.code2 === lang.code2), // remove dupes (which will happen)
) )
.map(l => ({ .map(l => ({
label: languageName(l, appLanguage), label: languageName(l, appLanguage),
inputLabel: languageName(l, appLanguage),
value: l.code2, value: l.code2,
key: l.code2 + l.code3, key: l.code2 + l.code3,
})) }))
@@ -360,66 +354,68 @@ function SearchLanguageDropdown({
if (bIsCommon && !aIsCommon) return 1 if (bIsCommon && !aIsCommon) return 1
// fall back to alphabetical // fall back to alphabetical
return a.label.localeCompare(b.label) return a.label.localeCompare(b.label)
}), })
) }, [appLanguage, contentLanguages])
}, [_, appLanguage, contentLanguages])
const style = { const currentLanguageLabel =
backgroundColor: t.atoms.bg_contrast_25.backgroundColor, languages.find(lang => lang.value === value)?.label ?? _(msg`All languages`)
color: t.atoms.text.color,
fontSize: a.text_xs.fontSize,
fontFamily: 'inherit',
fontWeight: a.font_bold.fontWeight,
paddingHorizontal: 14,
paddingRight: 32,
paddingVertical: 8,
borderRadius: a.rounded_full.borderRadius,
borderWidth: a.border.borderWidth,
borderColor: t.atoms.border_contrast_low.borderColor,
}
return ( return (
<RNPickerSelect <Menu.Root>
darkTheme={t.scheme === 'dark'} <Menu.Trigger
placeholder={{}} label={_(
value={value} msg`Filter search by language (currently: ${currentLanguageLabel})`,
onValueChange={onChange} )}>
items={items} {({props}) => (
Icon={() => ( <Button
<ChevronDown fill={t.atoms.text_contrast_low.color} size="sm" /> {...props}
)} label={props.accessibilityLabel}
useNativeAndroidPickerStyle={false} size="small"
style={{ color={platform({native: 'primary', default: 'secondary'})}
iconContainer: { variant={platform({native: 'ghost', default: 'solid'})}
pointerEvents: 'none', style={native([
right: a.px_sm.paddingRight, a.py_sm,
top: 0, a.px_sm,
bottom: 0, {marginRight: tokens.space.sm * -1},
display: 'flex', ])}>
justifyContent: 'center', <ButtonIcon icon={EarthIcon} />
}, <ButtonText>{currentLanguageLabel}</ButtonText>
inputAndroid: { <ButtonIcon
...style, icon={platform({
paddingVertical: 2, native: ChevronUpDownIcon,
}, default: ChevronDownIcon,
inputIOS: { })}
...style,
},
inputWeb: web({
...style,
cursor: 'pointer',
// @ts-ignore web only
'-moz-appearance': 'none',
'-webkit-appearance': 'none',
appearance: 'none',
outline: 0,
borderWidth: 0,
overflow: 'hidden',
whiteSpace: 'nowrap',
textOverflow: 'ellipsis',
}),
}}
/> />
</Button>
)}
</Menu.Trigger>
<Menu.Outer
// HACKFIX: Currently there is no height limit for Radix dropdowns,
// so if it's too tall it just goes off screen. TODO: fix internally -sfn
style={web({maxHeight: '70vh'})}>
<Menu.LabelText>
<Trans>Filter search by language</Trans>
</Menu.LabelText>
<Menu.Item label={_(msg`All languages`)} onPress={() => onChange('')}>
<Menu.ItemText>
<Trans>All languages</Trans>
</Menu.ItemText>
<Menu.ItemRadio selected={value === ''} />
</Menu.Item>
<Menu.Divider />
<Menu.Group>
{languages.map(lang => (
<Menu.Item
key={lang.key}
label={lang.label}
onPress={() => onChange(lang.value)}>
<Menu.ItemText>{lang.label}</Menu.ItemText>
<Menu.ItemRadio selected={value === lang.value} />
</Menu.Item>
))}
</Menu.Group>
</Menu.Outer>
</Menu.Root>
) )
} }
@@ -534,12 +530,7 @@ let SearchScreenInner = ({
<Pager <Pager
onPageSelected={onPageSelected} onPageSelected={onPageSelected}
renderTabBar={props => ( renderTabBar={props => (
<Layout.Center <Layout.Center style={[a.z_10, web([a.sticky, {top: headerHeight}])]}>
style={[
a.z_10,
web([a.sticky]),
{top: isWeb ? headerHeight : undefined},
]}>
<TabBar items={sections.map(section => section.title)} {...props} /> <TabBar items={sections.map(section => section.title)} {...props} />
</Layout.Center> </Layout.Center>
)} )}
@@ -597,13 +588,13 @@ SearchScreenInner = React.memo(SearchScreenInner)
export function SearchScreen( export function SearchScreen(
props: NativeStackScreenProps<SearchTabNavigatorParams, 'Search'>, props: NativeStackScreenProps<SearchTabNavigatorParams, 'Search'>,
) { ) {
const t = useThemeNew() const t = useTheme()
const {gtMobile} = useBreakpoints() const {gtMobile} = useBreakpoints()
const navigation = useNavigation<NavigationProp>() const navigation = useNavigation<NavigationProp>()
const textInput = React.useRef<TextInput>(null) const textInput = React.useRef<TextInput>(null)
const {_} = useLingui() const {_} = useLingui()
const setDrawerOpen = useSetDrawerOpen()
const setMinimalShellMode = useSetMinimalShellMode() const setMinimalShellMode = useSetMinimalShellMode()
const {currentAccount} = useSession()
// Query terms // Query terms
const queryParam = props.route?.params?.q ?? '' const queryParam = props.route?.params?.q ?? ''
@@ -612,20 +603,72 @@ export function SearchScreen(
useActorAutocompleteQuery(searchText, true) useActorAutocompleteQuery(searchText, true)
const [showAutocomplete, setShowAutocomplete] = React.useState(false) const [showAutocomplete, setShowAutocomplete] = React.useState(false)
const [searchHistory, setSearchHistory] = React.useState<string[]>([])
const [selectedProfiles, setSelectedProfiles] = React.useState< const [termHistory = [], setTermHistory] = useStorage(account, [
AppBskyActorDefs.ProfileViewBasic[] currentAccount?.did ?? 'pwi',
>([]) 'searchTermHistory',
] as const)
const [accountHistory = [], setAccountHistory] = useStorage(account, [
currentAccount?.did ?? 'pwi',
'searchAccountHistory',
])
const {data: accountHistoryProfiles} = useProfilesQuery({
handles: accountHistory,
maintainData: true,
})
const updateSearchHistory = useCallback(
async (item: string) => {
if (!item) return
const newSearchHistory = [
item,
...termHistory.filter(search => search !== item),
].slice(0, 6)
setTermHistory(newSearchHistory)
},
[termHistory, setTermHistory],
)
const updateProfileHistory = useCallback(
async (item: AppBskyActorDefs.ProfileViewBasic) => {
const newAccountHistory = [
item.did,
...accountHistory.filter(p => p !== item.did),
].slice(0, 5)
setAccountHistory(newAccountHistory)
},
[accountHistory, setAccountHistory],
)
const deleteSearchHistoryItem = useCallback(
async (item: string) => {
setTermHistory(termHistory.filter(search => search !== item))
},
[termHistory, setTermHistory],
)
const deleteProfileHistoryItem = useCallback(
async (item: AppBskyActorDefs.ProfileViewBasic) => {
setAccountHistory(accountHistory.filter(p => p !== item.did))
},
[accountHistory, setAccountHistory],
)
const {params, query, queryWithParams} = useQueryManager({ const {params, query, queryWithParams} = useQueryManager({
initialQuery: queryParam, initialQuery: queryParam,
}) })
const showFilters = Boolean(queryWithParams && !showAutocomplete) const showFilters = Boolean(queryWithParams && !showAutocomplete)
/*
* Arbitrary sizing, so guess and check, used for sticky header alignment and // web only - measure header height for sticky positioning
* sizing. const [headerHeight, setHeaderHeight] = React.useState(0)
*/ const headerRef = React.useRef(null)
const headerHeight = 60 + (showFilters ? 40 : 0) useLayoutEffect(() => {
if (isWeb) {
if (!headerRef.current) return
const measurement = (headerRef.current as Element).getBoundingClientRect()
setHeaderHeight(measurement.height)
}
}, [])
useFocusEffect( useFocusEffect(
useNonReactiveCallback(() => { useNonReactiveCallback(() => {
@@ -635,30 +678,6 @@ export function SearchScreen(
}), }),
) )
React.useEffect(() => {
const loadSearchHistory = async () => {
try {
const history = await AsyncStorage.getItem('searchHistory')
if (history !== null) {
setSearchHistory(JSON.parse(history))
}
const profiles = await AsyncStorage.getItem('selectedProfiles')
if (profiles !== null) {
setSelectedProfiles(JSON.parse(profiles))
}
} catch (e: any) {
logger.error('Failed to load search history', {message: e})
}
}
loadSearchHistory()
}, [])
const onPressMenu = React.useCallback(() => {
textInput.current?.blur()
setDrawerOpen(true)
}, [setDrawerOpen])
const onPressClearQuery = React.useCallback(() => { const onPressClearQuery = React.useCallback(() => {
scrollToTopWeb() scrollToTopWeb()
setSearchText('') setSearchText('')
@@ -670,57 +689,6 @@ export function SearchScreen(
setSearchText(text) setSearchText(text)
}, []) }, [])
const updateSearchHistory = React.useCallback(
async (newQuery: string) => {
newQuery = newQuery.trim()
if (newQuery) {
let newHistory = [
newQuery,
...searchHistory.filter(q => q !== newQuery),
]
if (newHistory.length > 5) {
newHistory = newHistory.slice(0, 5)
}
setSearchHistory(newHistory)
try {
await AsyncStorage.setItem(
'searchHistory',
JSON.stringify(newHistory),
)
} catch (e: any) {
logger.error('Failed to save search history', {message: e})
}
}
},
[searchHistory, setSearchHistory],
)
const updateSelectedProfiles = React.useCallback(
async (profile: AppBskyActorDefs.ProfileViewBasic) => {
let newProfiles = [
profile,
...selectedProfiles.filter(p => p.did !== profile.did),
]
if (newProfiles.length > 5) {
newProfiles = newProfiles.slice(0, 5)
}
setSelectedProfiles(newProfiles)
try {
await AsyncStorage.setItem(
'selectedProfiles',
JSON.stringify(newProfiles),
)
} catch (e: any) {
logger.error('Failed to save selected profiles', {message: e})
}
},
[selectedProfiles, setSelectedProfiles],
)
const navigateToItem = React.useCallback( const navigateToItem = React.useCallback(
(item: string) => { (item: string) => {
scrollToTopWeb() scrollToTopWeb()
@@ -774,10 +742,10 @@ export function SearchScreen(
(profile: AppBskyActorDefs.ProfileViewBasic) => { (profile: AppBskyActorDefs.ProfileViewBasic) => {
// Slight delay to avoid updating during push nav animation. // Slight delay to avoid updating during push nav animation.
setTimeout(() => { setTimeout(() => {
updateSelectedProfiles(profile) updateProfileHistory(profile)
}, 400) }, 400)
}, },
[updateSelectedProfiles], [updateProfileHistory],
) )
const onSoftReset = React.useCallback(() => { const onSoftReset = React.useCallback(() => {
@@ -798,36 +766,6 @@ export function SearchScreen(
}, [onSoftReset, setMinimalShellMode]), }, [onSoftReset, setMinimalShellMode]),
) )
const handleRemoveHistoryItem = React.useCallback(
(itemToRemove: string) => {
const updatedHistory = searchHistory.filter(item => item !== itemToRemove)
setSearchHistory(updatedHistory)
AsyncStorage.setItem(
'searchHistory',
JSON.stringify(updatedHistory),
).catch(e => {
logger.error('Failed to update search history', {message: e})
})
},
[searchHistory],
)
const handleRemoveProfile = React.useCallback(
(profileToRemove: AppBskyActorDefs.ProfileViewBasic) => {
const updatedProfiles = selectedProfiles.filter(
profile => profile.did !== profileToRemove.did,
)
setSelectedProfiles(updatedProfiles)
AsyncStorage.setItem(
'selectedProfiles',
JSON.stringify(updatedProfiles),
).catch(e => {
logger.error('Failed to update selected profiles', {message: e})
})
},
[selectedProfiles],
)
const onSearchInputFocus = React.useCallback(() => { const onSearchInputFocus = React.useCallback(() => {
if (isWeb) { if (isWeb) {
// Prevent a jump on iPad by ensuring that // Prevent a jump on iPad by ensuring that
@@ -843,33 +781,46 @@ export function SearchScreen(
return ( return (
<Layout.Screen testID="searchScreen"> <Layout.Screen testID="searchScreen">
<View <View
ref={headerRef}
onLayout={evt => {
if (isWeb) setHeaderHeight(evt.nativeEvent.layout.height)
}}
style={[ style={[
a.relative,
a.z_10,
web({ web({
height: headerHeight,
position: 'sticky', position: 'sticky',
top: 0, top: 0,
zIndex: 1,
}), }),
]}> ]}>
<Layout.Center> <Layout.Center style={t.atoms.bg}>
<View style={[a.p_md, a.pb_sm, a.gap_sm, t.atoms.bg]}> {!gtMobile && (
<View style={[a.flex_row, a.gap_sm]}> <View
{!gtMobile && !showAutocomplete && ( // HACK: shift up search input. we can't remove the top padding
<Button // on the search input because it messes up the layout animation
testID="viewHeaderBackOrMenuBtn" // if we add it only when the header is hidden
onPress={onPressMenu} style={{marginBottom: tokens.space.xs * -1}}>
hitSlop={HITSLOP_10} <Layout.Header.Outer noBottomBorder>
label={_(msg`Menu`)} <Layout.Header.MenuButton />
accessibilityHint={_( <Layout.Header.Content align="left">
msg`Access navigation links and settings`, <Layout.Header.TitleText>
<Trans>Search</Trans>
</Layout.Header.TitleText>
</Layout.Header.Content>
{showFilters ? (
<SearchLanguageDropdown
value={params.lang}
onChange={params.setLang}
/>
) : (
<Layout.Header.Slot />
)} )}
size="large" </Layout.Header.Outer>
variant="solid" </View>
color="secondary"
shape="square">
<ButtonIcon icon={Menu} size="lg" />
</Button>
)} )}
<View style={[a.px_md, a.pt_sm, a.pb_sm, a.overflow_hidden]}>
<View style={[a.gap_sm]}>
<View style={[a.w_full, a.flex_row, a.align_stretch, a.gap_xs]}>
<View style={[a.flex_1]}> <View style={[a.flex_1]}>
<SearchInput <SearchInput
ref={textInput} ref={textInput}
@@ -878,6 +829,8 @@ export function SearchScreen(
onChangeText={onChangeText} onChangeText={onChangeText}
onClearText={onPressClearQuery} onClearText={onPressClearQuery}
onSubmitEditing={onSubmit} onSubmitEditing={onSubmit}
placeholder={_(msg`Search for posts, users, or feeds`)}
hitSlop={{...HITSLOP_20, top: 0}}
/> />
</View> </View>
{showAutocomplete && ( {showAutocomplete && (
@@ -896,7 +849,7 @@ export function SearchScreen(
)} )}
</View> </View>
{showFilters && ( {showFilters && gtMobile && (
<View <View
style={[ style={[
a.flex_row, a.flex_row,
@@ -904,15 +857,14 @@ export function SearchScreen(
a.justify_between, a.justify_between,
a.gap_sm, a.gap_sm,
]}> ]}>
<View style={[{width: 140}]}>
<SearchLanguageDropdown <SearchLanguageDropdown
value={params.lang} value={params.lang}
onChange={params.setLang} onChange={params.setLang}
/> />
</View> </View>
</View>
)} )}
</View> </View>
</View>
</Layout.Center> </Layout.Center>
</View> </View>
@@ -932,12 +884,12 @@ export function SearchScreen(
/> />
) : ( ) : (
<SearchHistory <SearchHistory
searchHistory={searchHistory} searchHistory={termHistory}
selectedProfiles={selectedProfiles} selectedProfiles={accountHistoryProfiles?.profiles || []}
onItemClick={handleHistoryItemClick} onItemClick={handleHistoryItemClick}
onProfileClick={handleProfileClick} onProfileClick={handleProfileClick}
onRemoveItemClick={handleRemoveHistoryItem} onRemoveItemClick={deleteSearchHistoryItem}
onRemoveProfileClick={handleRemoveProfile} onRemoveProfileClick={deleteProfileHistoryItem}
/> />
)} )}
</View> </View>
@@ -1087,7 +1039,7 @@ function SearchHistory({
accessibilityRole="button" accessibilityRole="button"
accessibilityLabel={_(msg`Remove profile`)} accessibilityLabel={_(msg`Remove profile`)}
accessibilityHint={_( accessibilityHint={_(
msg`Remove profile from search history`, msg`Removes profile from search history`,
)} )}
onPress={() => onRemoveProfileClick(profile)} onPress={() => onRemoveProfileClick(profile)}
hitSlop={createHitslop(6)} hitSlop={createHitslop(6)}
+19 -14
View File
@@ -5,6 +5,7 @@ import {useFocusGuards} from '@radix-ui/react-focus-guards'
import {FocusScope} from '@radix-ui/react-focus-scope' import {FocusScope} from '@radix-ui/react-focus-scope'
import {RemoveScrollBar} from 'react-remove-scroll-bar' import {RemoveScrollBar} from 'react-remove-scroll-bar'
import {useA11y} from '#/state/a11y'
import {useModals} from '#/state/modals' import {useModals} from '#/state/modals'
import {ComposerOpts, useComposerState} from '#/state/shell/composer' import {ComposerOpts, useComposerState} from '#/state/shell/composer'
import { import {
@@ -12,7 +13,7 @@ import {
EmojiPickerPosition, EmojiPickerPosition,
EmojiPickerState, EmojiPickerState,
} from '#/view/com/composer/text-input/web/EmojiPicker.web' } from '#/view/com/composer/text-input/web/EmojiPicker.web'
import {useBreakpoints, useTheme} from '#/alf' import {atoms as a, flatten, useBreakpoints, useTheme} from '#/alf'
import {ComposePost, useComposerCancelRef} from '../com/composer/Composer' import {ComposePost, useComposerCancelRef} from '../com/composer/Composer'
const BOTTOM_BAR_HEIGHT = 61 const BOTTOM_BAR_HEIGHT = 61
@@ -41,6 +42,7 @@ function Inner({state}: {state: ComposerOpts}) {
const {isModalActive} = useModals() const {isModalActive} = useModals()
const t = useTheme() const t = useTheme()
const {gtMobile} = useBreakpoints() const {gtMobile} = useBreakpoints()
const {reduceMotionEnabled} = useA11y()
const [pickerState, setPickerState] = React.useState<EmojiPickerState>({ const [pickerState, setPickerState] = React.useState<EmojiPickerState>({
isOpen: false, isOpen: false,
pos: {top: 0, left: 0, right: 0, bottom: 0, nextFocusRef: null}, pos: {top: 0, left: 0, right: 0, bottom: 0, nextFocusRef: null},
@@ -71,17 +73,15 @@ function Inner({state}: {state: ComposerOpts}) {
<DismissableLayer <DismissableLayer
role="dialog" role="dialog"
aria-modal aria-modal
style={{ style={flatten([
position: 'fixed', {position: 'fixed'},
top: 0, a.inset_0,
left: 0, {backgroundColor: '#000c'},
width: '100%', a.flex,
height: '100%', a.flex_col,
backgroundColor: '#000c', a.align_center,
display: 'flex', !reduceMotionEnabled && a.fade_in,
flexDirection: 'column', ])}
alignItems: 'center',
}}
onFocusOutside={evt => evt.preventDefault()} onFocusOutside={evt => evt.preventDefault()}
onInteractOutside={evt => evt.preventDefault()} onInteractOutside={evt => evt.preventDefault()}
onDismiss={() => { onDismiss={() => {
@@ -96,6 +96,11 @@ function Inner({state}: {state: ComposerOpts}) {
!gtMobile && styles.containerMobile, !gtMobile && styles.containerMobile,
t.atoms.bg, t.atoms.bg,
t.atoms.border_contrast_medium, t.atoms.border_contrast_medium,
!reduceMotionEnabled && [
a.zoom_fade_in,
{animationDelay: 0.1},
{animationFillMode: 'backwards'},
],
]}> ]}>
<ComposePost <ComposePost
cancelRef={ref} cancelRef={ref}
@@ -123,14 +128,14 @@ const styles = StyleSheet.create({
borderRadius: 8, borderRadius: 8,
marginBottom: 0, marginBottom: 0,
borderWidth: 1, borderWidth: 1,
// @ts-ignore web only // @ts-expect-error web only
maxHeight: 'calc(100% - (40px * 2))', maxHeight: 'calc(100% - (40px * 2))',
overflow: 'hidden', overflow: 'hidden',
}, },
containerMobile: { containerMobile: {
borderRadius: 0, borderRadius: 0,
marginBottom: BOTTOM_BAR_HEIGHT, marginBottom: BOTTOM_BAR_HEIGHT,
// @ts-ignore web only // @ts-expect-error web only
maxHeight: `calc(100% - ${BOTTOM_BAR_HEIGHT}px)`, maxHeight: `calc(100% - ${BOTTOM_BAR_HEIGHT}px)`,
}, },
}) })
+5 -2
View File
@@ -33,7 +33,7 @@ import {LoadingPlaceholder} from '#/view/com/util/LoadingPlaceholder'
import {PressableWithHover} from '#/view/com/util/PressableWithHover' import {PressableWithHover} from '#/view/com/util/PressableWithHover'
import {UserAvatar} from '#/view/com/util/UserAvatar' import {UserAvatar} from '#/view/com/util/UserAvatar'
import {NavSignupCard} from '#/view/shell/NavSignupCard' import {NavSignupCard} from '#/view/shell/NavSignupCard'
import {atoms as a, tokens, useBreakpoints, useTheme} from '#/alf' import {atoms as a, tokens, useBreakpoints, useTheme, web} from '#/alf'
import {Button, ButtonIcon, ButtonText} from '#/components/Button' import {Button, ButtonIcon, ButtonText} from '#/components/Button'
import {DialogControlProps} from '#/components/Dialog' import {DialogControlProps} from '#/components/Dialog'
import {ArrowBoxLeft_Stroke2_Corner0_Rounded as LeaveIcon} from '#/components/icons/ArrowBoxLeft' import {ArrowBoxLeft_Stroke2_Corner0_Rounded as LeaveIcon} from '#/components/icons/ArrowBoxLeft'
@@ -235,7 +235,10 @@ function SwitchMenuItems({
closeEverything() closeEverything()
} }
return ( return (
<Menu.Outer> <Menu.Outer
// HACKFIX: Currently there is no height limit for Radix dropdowns,
// so if it's too tall it just goes off screen. TODO: fix internally -sfn
style={web({maxHeight: '70vh'})}>
{accounts && accounts.length > 0 && ( {accounts && accounts.length > 0 && (
<> <>
<Menu.Group> <Menu.Group>
+30 -9
View File
@@ -1,4 +1,4 @@
import React, {useEffect} from 'react' import {useEffect, useLayoutEffect, useState} from 'react'
import {StyleSheet, TouchableWithoutFeedback, View} from 'react-native' import {StyleSheet, TouchableWithoutFeedback, View} from 'react-native'
import {msg} from '@lingui/macro' import {msg} from '@lingui/macro'
import {useLingui} from '@lingui/react' import {useLingui} from '@lingui/react'
@@ -33,6 +33,20 @@ function ShellInner() {
const closeAllActiveElements = useCloseAllActiveElements() const closeAllActiveElements = useCloseAllActiveElements()
const {_} = useLingui() const {_} = useLingui()
const showDrawer = !isDesktop && isDrawerOpen const showDrawer = !isDesktop && isDrawerOpen
const [showDrawerDelayedExit, setShowDrawerDelayedExit] = useState(showDrawer)
useLayoutEffect(() => {
if (showDrawer !== showDrawerDelayedExit) {
if (showDrawer) {
setShowDrawerDelayedExit(true)
} else {
const timeout = setTimeout(() => {
setShowDrawerDelayedExit(false)
}, 160)
return () => clearTimeout(timeout)
}
}
}, [showDrawer, showDrawerDelayedExit])
useComposerKeyboardShortcut() useComposerKeyboardShortcut()
useIntentHandler() useIntentHandler()
@@ -56,7 +70,7 @@ function ShellInner() {
<Lightbox /> <Lightbox />
<PortalOutlet /> <PortalOutlet />
{showDrawer && ( {showDrawerDelayedExit && (
<> <>
<RemoveScrollBar /> <RemoveScrollBar />
<TouchableWithoutFeedback <TouchableWithoutFeedback
@@ -66,20 +80,27 @@ function ShellInner() {
setDrawerOpen(false) setDrawerOpen(false)
} }
}} }}
accessibilityLabel={_(msg`Close navigation footer`)} accessibilityLabel={_(msg`Close drawer menu`)}
accessibilityHint={_(msg`Closes bottom navigation bar`)}> accessibilityHint="">
<View <View
style={[ style={[
styles.drawerMask, styles.drawerMask,
{ {
backgroundColor: select(t.name, { backgroundColor: showDrawer
? select(t.name, {
light: 'rgba(0, 57, 117, 0.1)', light: 'rgba(0, 57, 117, 0.1)',
dark: 'rgba(1, 82, 168, 0.1)', dark: 'rgba(1, 82, 168, 0.1)',
dim: 'rgba(10, 13, 16, 0.8)', dim: 'rgba(10, 13, 16, 0.8)',
}), })
: 'transparent',
}, },
a.transition_color,
]}>
<View
style={[
styles.drawerContainer,
showDrawer ? a.slide_in_left : a.slide_out_left,
]}> ]}>
<View style={styles.drawerContainer}>
<DrawerContent /> <DrawerContent />
</View> </View>
</View> </View>
@@ -109,7 +130,6 @@ const styles = StyleSheet.create({
backgroundColor: colors.black, // TODO backgroundColor: colors.black, // TODO
}, },
drawerMask: { drawerMask: {
// @ts-ignore web only
position: 'fixed', position: 'fixed',
width: '100%', width: '100%',
height: '100%', height: '100%',
@@ -118,10 +138,11 @@ const styles = StyleSheet.create({
}, },
drawerContainer: { drawerContainer: {
display: 'flex', display: 'flex',
// @ts-ignore web only
position: 'fixed', position: 'fixed',
top: 0, top: 0,
left: 0, left: 0,
height: '100%', height: '100%',
width: 330,
maxWidth: '80%',
}, },
}) })
+1 -1
View File
@@ -3,7 +3,7 @@
"compilerOptions": { "compilerOptions": {
"jsx": "react-jsx", "jsx": "react-jsx",
"module": "esnext", "module": "esnext",
"types": ["node"], "types": ["node", "jest"],
"paths": { "paths": {
"#/*": ["./src/*"], "#/*": ["./src/*"],
"lib/*": ["./src/lib/*"], "lib/*": ["./src/lib/*"],
+1 -1
View File
@@ -277,7 +277,7 @@
multiformats "^9.9.0" multiformats "^9.9.0"
zod "^3.23.8" zod "^3.23.8"
"@atproto/lexicon@^0.4.7": "@atproto/lexicon@^0.4.4", "@atproto/lexicon@^0.4.7":
version "0.4.7" version "0.4.7"
resolved "https://registry.yarnpkg.com/@atproto/lexicon/-/lexicon-0.4.7.tgz#f5d31615c21bcfd3e655f1e4f11a40a62fea9f86" resolved "https://registry.yarnpkg.com/@atproto/lexicon/-/lexicon-0.4.7.tgz#f5d31615c21bcfd3e655f1e4f11a40a62fea9f86"
integrity sha512-/x6h3tAiDNzSi4eXtC8ke65B7UzsagtlGRHmUD95698x5lBRpDnpizj0fZWTZVYed5qnOmz/ZEue+v3wDmO61g== integrity sha512-/x6h3tAiDNzSi4eXtC8ke65B7UzsagtlGRHmUD95698x5lBRpDnpizj0fZWTZVYed5qnOmz/ZEue+v3wDmO61g==