From 88846ca36d2231df8e65a665ab4530761ab9e6ed Mon Sep 17 00:00:00 2001 From: Hailey Date: Mon, 26 Feb 2024 16:48:32 -0800 Subject: [PATCH 01/43] =?UTF-8?q?fix=20reversed=20icons=20in=20validator?= =?UTF-8?q?=20=F0=9F=A4=A6=20(#2991)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/view/com/auth/create/Step2.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/view/com/auth/create/Step2.tsx b/src/view/com/auth/create/Step2.tsx index a3892030..5c262977 100644 --- a/src/view/com/auth/create/Step2.tsx +++ b/src/view/com/auth/create/Step2.tsx @@ -133,8 +133,8 @@ function IsValidIcon({valid}: {valid: boolean}) { const t = useTheme() if (!valid) { - return + return } - return + return } From 832582df23bb2d2b0009d24a6c2bef7a5a388e8f Mon Sep 17 00:00:00 2001 From: Hailey Date: Mon, 26 Feb 2024 16:54:05 -0800 Subject: [PATCH 02/43] Adjust `windowSize` on `PostThread` `FlatList` (#2989) * adjust window size, cells batching period * rm batching period change --- src/view/com/post-thread/PostThread.tsx | 1 + 1 file changed, 1 insertion(+) diff --git a/src/view/com/post-thread/PostThread.tsx b/src/view/com/post-thread/PostThread.tsx index 434f018f..a7ee42a9 100644 --- a/src/view/com/post-thread/PostThread.tsx +++ b/src/view/com/post-thread/PostThread.tsx @@ -437,6 +437,7 @@ function PostThreadLoaded({ // @ts-ignore our .web version only -prf desktopFixedHeight removeClippedSubviews={isAndroid ? false : undefined} + windowSize={11} /> ) } From 9b11fc720f1714c7cfba76daaf3cefaf0ae97ae6 Mon Sep 17 00:00:00 2001 From: Steve Klabnik Date: Mon, 26 Feb 2024 19:24:14 -0600 Subject: [PATCH 03/43] Remove invite codes from README (#2988) Invite codes aren't needed anymore! Thanks to https://bsky.app/profile/shreyanjain.net/post/3kmdulzeibc2o for pointing this out to me. --- README.md | 2 -- 1 file changed, 2 deletions(-) diff --git a/README.md b/README.md index 0cbfe773..49c4b016 100644 --- a/README.md +++ b/README.md @@ -65,8 +65,6 @@ If you discover any security issues, please send an email to security@bsky.app. Bluesky is an open social network built on the AT Protocol, a flexible technology that will never lock developers out of the ecosystems that they help build. With atproto, third-party can be as seamless as first-party through custom feeds, federated services, clients, and more. -If you're a developer interested in building on atproto, we'd love to email you a Bluesky invite code. Simply share your GitHub (or similar) profile with us via [this form](https://forms.gle/BF21oxVNZiDjDhXF9). - ## License (MIT) See [./LICENSE](./LICENSE) for the full license. From 0311288dd76026cf1bab5302b01637bdeb9c07e2 Mon Sep 17 00:00:00 2001 From: Eric Bailey Date: Mon, 26 Feb 2024 19:24:36 -0600 Subject: [PATCH 04/43] Fix dark butterfly on android splash (#2993) --- src/Splash.tsx | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/src/Splash.tsx b/src/Splash.tsx index b2381f92..42a21c08 100644 --- a/src/Splash.tsx +++ b/src/Splash.tsx @@ -181,6 +181,8 @@ export function Splash(props: React.PropsWithChildren) { const logoAnimations = reduceMotion === true ? reducedLogoAnimation : logoAnimation + // special off-spec color for dark mode + const logoBg = isDarkMode ? '#0F1824' : '#fff' return ( @@ -232,7 +234,7 @@ export function Splash(props: React.PropsWithChildren) { }, ]}> @@ -253,7 +255,7 @@ export function Splash(props: React.PropsWithChildren) { transform: [{translateY: -(insets.top / 2)}, {scale: 0.1}], // scale from 1000px to 100px }, ]}> - + }> {!isAnimationComplete && ( @@ -261,10 +263,7 @@ export function Splash(props: React.PropsWithChildren) { style={[ StyleSheet.absoluteFillObject, { - backgroundColor: isDarkMode - ? // special off-spec color for dark mode - '#0F1824' - : '#fff', + backgroundColor: logoBg, }, ]} /> From a8925bac8616dccadc016304e98091d54f838042 Mon Sep 17 00:00:00 2001 From: dan Date: Tue, 27 Feb 2024 01:25:25 +0000 Subject: [PATCH 05/43] Remove side borders on mobile web list (#2994) --- src/view/com/util/List.web.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/view/com/util/List.web.tsx b/src/view/com/util/List.web.tsx index 29bad2db..936bac19 100644 --- a/src/view/com/util/List.web.tsx +++ b/src/view/com/util/List.web.tsx @@ -172,7 +172,7 @@ function ListImpl( ( const isSafari = /^((?!chrome|android).)*safari/i.test(navigator.userAgent) const styles = StyleSheet.create({ - contentContainer: { + sideBorders: { borderLeftWidth: 1, borderRightWidth: 1, }, From e9ad3f552d072ed2c818bcb28a90b46ee2027af7 Mon Sep 17 00:00:00 2001 From: Hailey Date: Mon, 26 Feb 2024 17:26:41 -0800 Subject: [PATCH 06/43] Bump version to 1.70 (wait for release) (#2987) --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 5c31f10f..3f007a23 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "bsky.app", - "version": "1.69.0", + "version": "1.70.0", "private": true, "engines": { "node": ">=18" From 771999761e9a69d4f884c1c75cf20fde5d149791 Mon Sep 17 00:00:00 2001 From: Vinayak Kulkarni Date: Tue, 27 Feb 2024 07:05:06 +0530 Subject: [PATCH 07/43] feat(nvm): add support for nvm & minor actions housekeeping (#2979) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * feat: add `.nvmrc` for specifying node version Co-Authored-By: Evandro Leopoldino Gonçalves * chore(deps): bump setup-node to v4 * build: use node-version-file instead of hardcoded 18.x * chore(deps): bump nvm version * fix: checkout before install 🎉 --------- Co-authored-by: Evandro Leopoldino Gonçalves --- .github/workflows/build-submit-android.yml | 4 ++-- .github/workflows/build-submit-ios.yml | 4 ++-- .github/workflows/lint.yml | 8 ++++---- .nvmrc | 1 + Dockerfile | 2 +- bskyweb/README.md | 6 +++--- 6 files changed, 13 insertions(+), 12 deletions(-) create mode 100644 .nvmrc diff --git a/.github/workflows/build-submit-android.yml b/.github/workflows/build-submit-android.yml index 051e9515..6fa177fb 100644 --- a/.github/workflows/build-submit-android.yml +++ b/.github/workflows/build-submit-android.yml @@ -26,9 +26,9 @@ jobs: uses: actions/checkout@v4 - name: 🔧 Setup Node - uses: actions/setup-node@v3 + uses: actions/setup-node@v4 with: - node-version: 18.x + node-version-file: .nvmrc cache: yarn - name: 🔨 Setup EAS diff --git a/.github/workflows/build-submit-ios.yml b/.github/workflows/build-submit-ios.yml index 0fd691bb..b6767806 100644 --- a/.github/workflows/build-submit-ios.yml +++ b/.github/workflows/build-submit-ios.yml @@ -28,9 +28,9 @@ jobs: uses: actions/checkout@v4 - name: 🔧 Setup Node - uses: actions/setup-node@v3 + uses: actions/setup-node@v4 with: - node-version: 18.x + node-version-file: .nvmrc cache: yarn - name: 🔨 Setup EAS diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index 508da536..9aa55ca0 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -32,12 +32,12 @@ jobs: name: Run tests runs-on: ubuntu-latest steps: - - name: Install node 18 - uses: actions/setup-node@v4 - with: - node-version: 18 - name: Check out Git repository uses: actions/checkout@v3 + - name: Install node + uses: actions/setup-node@v4 + with: + node-version-file: .nvmrc - name: Yarn install uses: Wandalen/wretry.action@master with: diff --git a/.nvmrc b/.nvmrc new file mode 100644 index 00000000..3c032078 --- /dev/null +++ b/.nvmrc @@ -0,0 +1 @@ +18 diff --git a/Dockerfile b/Dockerfile index 47afa61a..fcd2413c 100644 --- a/Dockerfile +++ b/Dockerfile @@ -23,7 +23,7 @@ COPY . . RUN mkdir --parents $NVM_DIR && \ wget \ --output-document=/tmp/nvm-install.sh \ - https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.3/install.sh && \ + https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.7/install.sh && \ bash /tmp/nvm-install.sh RUN \. "$NVM_DIR/nvm.sh" && \ diff --git a/bskyweb/README.md b/bskyweb/README.md index c8efe044..640c30f4 100644 --- a/bskyweb/README.md +++ b/bskyweb/README.md @@ -6,9 +6,9 @@ To build the SPA bundle (`bundle.web.js`), first get a JavaScript development environment set up. Either follow the top-level README, or something quick like: - # install nodejs 18 (specifically) - nvm install 18 - nvm use 18 + # install nodejs + nvm install + nvm use npm install --global yarn # setup tools and deps (in top level of this repo) From 3ec4e034b79950b0d2ce43b6048dee3dd37c3747 Mon Sep 17 00:00:00 2001 From: dan Date: Tue, 27 Feb 2024 02:33:23 +0000 Subject: [PATCH 08/43] Fix imprecise header height calculation (#2995) * Remove dead code * Fix header height calculation --- src/view/com/feeds/FeedPage.tsx | 19 +++++-------------- 1 file changed, 5 insertions(+), 14 deletions(-) diff --git a/src/view/com/feeds/FeedPage.tsx b/src/view/com/feeds/FeedPage.tsx index 60814e83..2aacdb89 100644 --- a/src/view/com/feeds/FeedPage.tsx +++ b/src/view/com/feeds/FeedPage.tsx @@ -200,21 +200,12 @@ export function FeedPage({ function useHeaderOffset() { const {isDesktop, isTablet} = useWebMediaQueries() const {fontScale} = useWindowDimensions() - const {hasSession} = useSession() if (isDesktop || isTablet) { return 0 } - if (hasSession) { - const navBarPad = 16 - const navBarText = 21 * fontScale - const tabBarPad = 20 + 3 // nav bar padding + border - const tabBarText = 16 * fontScale - const magic = 7 * fontScale - return navBarPad + navBarText + tabBarPad + tabBarText + magic - } else { - const navBarPad = 16 - const navBarText = 21 * fontScale - const magic = 4 * fontScale - return navBarPad + navBarText + magic - } + const navBarHeight = 42 + const tabBarPad = 10 + 10 + 3 // padding + border + const normalLineHeight = 1.2 + const tabBarText = 16 * normalLineHeight * fontScale + return navBarHeight + tabBarPad + tabBarText } From 1a349216612d3c36edef47cac6bbd4b72a34ab38 Mon Sep 17 00:00:00 2001 From: dan Date: Tue, 27 Feb 2024 03:56:25 +0000 Subject: [PATCH 09/43] Tweak tabbar sizing on web (#2996) --- src/view/com/pager/TabBar.tsx | 49 ++++++++++++++++++----------------- 1 file changed, 25 insertions(+), 24 deletions(-) diff --git a/src/view/com/pager/TabBar.tsx b/src/view/com/pager/TabBar.tsx index dadcfceb..3204bb23 100644 --- a/src/view/com/pager/TabBar.tsx +++ b/src/view/com/pager/TabBar.tsx @@ -4,7 +4,6 @@ import {Text} from '../util/text/Text' import {PressableWithHover} from '../util/PressableWithHover' import {usePalette} from 'lib/hooks/usePalette' import {useWebMediaQueries} from 'lib/hooks/useWebMediaQueries' -import {isWeb} from 'platform/detection' import {DraggableScrollView} from './DraggableScrollView' export interface TabBarProps { @@ -32,13 +31,15 @@ export function TabBar({ [indicatorColor, pal], ) const {isDesktop, isTablet} = useWebMediaQueries() + const styles = isDesktop || isTablet ? desktopStyles : mobileStyles // scrolls to the selected item when the page changes useEffect(() => { scrollElRef.current?.scrollTo({ - x: itemXs[selectedPage] || 0, + x: + (itemXs[selectedPage] || 0) - styles.contentContainer.paddingHorizontal, }) - }, [scrollElRef, itemXs, selectedPage]) + }, [scrollElRef, itemXs, selectedPage, styles]) const onPressItem = useCallback( (index: number) => { @@ -63,8 +64,6 @@ export function TabBar({ [], ) - const styles = isDesktop || isTablet ? desktopStyles : mobileStyles - return ( onItemLayout(e, i)} - style={[styles.item, selected && indicatorStyle]} + style={styles.item} hoverStyle={pal.viewLight} onPress={() => onPressItem(i)}> - - {item} - + + + {item} + + ) })} @@ -103,18 +104,18 @@ const desktopStyles = StyleSheet.create({ width: 598, }, contentContainer: { - columnGap: 8, - marginLeft: 14, - paddingRight: 14, + paddingHorizontal: 0, backgroundColor: 'transparent', }, item: { paddingTop: 14, + paddingHorizontal: 14, + justifyContent: 'center', + }, + itemInner: { paddingBottom: 12, - paddingHorizontal: 10, borderBottomWidth: 3, borderBottomColor: 'transparent', - justifyContent: 'center', }, }) @@ -123,17 +124,17 @@ const mobileStyles = StyleSheet.create({ flexDirection: 'row', }, contentContainer: { - columnGap: isWeb ? 0 : 20, - marginLeft: isWeb ? 0 : 18, - paddingRight: isWeb ? 0 : 36, backgroundColor: 'transparent', + paddingHorizontal: 8, }, item: { paddingTop: 10, - paddingBottom: 10, - paddingHorizontal: isWeb ? 8 : 0, - borderBottomWidth: 3, - borderBottomColor: 'transparent', + paddingHorizontal: 10, justifyContent: 'center', }, + itemInner: { + paddingBottom: 10, + borderBottomWidth: 3, + borderBottomColor: 'transparent', + }, }) From c8582924e2421e5383050c4f60a80d2e74287c07 Mon Sep 17 00:00:00 2001 From: Hailey Date: Mon, 26 Feb 2024 20:19:06 -0800 Subject: [PATCH 10/43] Scale back sentry logs for trivial events (#2997) * scale back sentry logs * update migrate log tests --- src/lib/api/index.ts | 6 +++--- src/screens/Onboarding/state.ts | 2 +- src/state/persisted/__tests__/migrate.test.ts | 6 +++--- src/state/persisted/index.ts | 6 +++--- src/state/persisted/legacy.ts | 8 ++++---- src/state/session/index.tsx | 18 +++++++++--------- src/view/com/auth/login/LoginForm.tsx | 2 +- 7 files changed, 24 insertions(+), 24 deletions(-) diff --git a/src/lib/api/index.ts b/src/lib/api/index.ts index 440dfa5e..5fb7fe50 100644 --- a/src/lib/api/index.ts +++ b/src/lib/api/index.ts @@ -104,18 +104,18 @@ export async function post(agent: BskyAgent, opts: PostOpts) { // add image embed if present if (opts.images?.length) { - logger.info(`Uploading images`, { + logger.debug(`Uploading images`, { count: opts.images.length, }) const images: AppBskyEmbedImages.Image[] = [] for (const image of opts.images) { opts.onStateChange?.(`Uploading image #${images.length + 1}...`) - logger.info(`Compressing image`) + logger.debug(`Compressing image`) await image.compress() const path = image.compressed?.path ?? image.path const {width, height} = image.compressed || image - logger.info(`Uploading image`) + logger.debug(`Uploading image`) const res = await uploadBlob(agent, path, 'image/jpeg') images.push({ image: res.data.blob, diff --git a/src/screens/Onboarding/state.ts b/src/screens/Onboarding/state.ts index bd8205ca..969edbdd 100644 --- a/src/screens/Onboarding/state.ts +++ b/src/screens/Onboarding/state.ts @@ -232,7 +232,7 @@ export function reducer( }) if (s.activeStep !== state.activeStep) { - logger.info(`onboarding: step changed`, {activeStep: state.activeStep}) + logger.debug(`onboarding: step changed`, {activeStep: state.activeStep}) } return state diff --git a/src/state/persisted/__tests__/migrate.test.ts b/src/state/persisted/__tests__/migrate.test.ts index e4b55d5d..97767e27 100644 --- a/src/state/persisted/__tests__/migrate.test.ts +++ b/src/state/persisted/__tests__/migrate.test.ts @@ -26,7 +26,7 @@ test('migrate: fresh install', async () => { expect(AsyncStorage.getItem).toHaveBeenCalledWith('root') expect(read).toHaveBeenCalledTimes(1) - expect(logger.info).toHaveBeenCalledWith( + expect(logger.debug).toHaveBeenCalledWith( 'persisted state: no migration needed', ) }) @@ -38,7 +38,7 @@ test('migrate: fresh install, existing new storage', async () => { expect(AsyncStorage.getItem).toHaveBeenCalledWith('root') expect(read).toHaveBeenCalledTimes(1) - expect(logger.info).toHaveBeenCalledWith( + expect(logger.debug).toHaveBeenCalledWith( 'persisted state: no migration needed', ) }) @@ -68,7 +68,7 @@ test('migrate: has legacy data', async () => { await migrate() expect(write).toHaveBeenCalledWith(transform(fixtures.LEGACY_DATA_DUMP)) - expect(logger.info).toHaveBeenCalledWith( + expect(logger.debug).toHaveBeenCalledWith( 'persisted state: migrated legacy storage', ) }) diff --git a/src/state/persisted/index.ts b/src/state/persisted/index.ts index 2f34c2db..f57172d2 100644 --- a/src/state/persisted/index.ts +++ b/src/state/persisted/index.ts @@ -19,7 +19,7 @@ const _emitter = new EventEmitter() * the Provider. */ export async function init() { - logger.info('persisted state: initializing') + logger.debug('persisted state: initializing') broadcast.onmessage = onBroadcastMessage @@ -27,11 +27,11 @@ export async function init() { await migrate() // migrate old store const stored = await store.read() // check for new store if (!stored) { - logger.info('persisted state: initializing default storage') + logger.debug('persisted state: initializing default storage') await store.write(defaults) // opt: init new store } _state = stored || defaults // return new store - logger.log('persisted state: initialized') + logger.debug('persisted state: initialized') } catch (e) { logger.error('persisted state: failed to load root state from storage', { message: e, diff --git a/src/state/persisted/legacy.ts b/src/state/persisted/legacy.ts index cce080c8..fd94a96a 100644 --- a/src/state/persisted/legacy.ts +++ b/src/state/persisted/legacy.ts @@ -121,7 +121,7 @@ export function transform(legacy: Partial): Schema { * local storage AND old storage exists. */ export async function migrate() { - logger.info('persisted state: check need to migrate') + logger.debug('persisted state: check need to migrate') try { const rawLegacyData = await AsyncStorage.getItem( @@ -131,7 +131,7 @@ export async function migrate() { const alreadyMigrated = Boolean(newData) if (!alreadyMigrated && rawLegacyData) { - logger.info('persisted state: migrating legacy storage') + logger.debug('persisted state: migrating legacy storage') const legacyData = JSON.parse(rawLegacyData) const newData = transform(legacyData) @@ -139,14 +139,14 @@ export async function migrate() { if (validate.success) { await write(newData) - logger.info('persisted state: migrated legacy storage') + logger.debug('persisted state: migrated legacy storage') } else { logger.error('persisted state: legacy data failed validation', { message: validate.error, }) } } else { - logger.info('persisted state: no migration needed') + logger.debug('persisted state: no migration needed') } } catch (e: any) { logger.error(e, { diff --git a/src/state/session/index.tsx b/src/state/session/index.tsx index bd3b157b..46628318 100644 --- a/src/state/session/index.tsx +++ b/src/state/session/index.tsx @@ -133,7 +133,7 @@ function createPersistSessionHandler( accessJwt: session?.accessJwt, } - logger.info(`session: persistSession`, { + logger.debug(`session: persistSession`, { event, deactivated: refreshedAccount.deactivated, }) @@ -320,7 +320,7 @@ export function Provider({children}: React.PropsWithChildren<{}>) { ) const logout = React.useCallback(async () => { - logger.info(`session: logout`) + logger.debug(`session: logout`) clearCurrentAccount() setStateAndPersist(s => { return { @@ -374,7 +374,7 @@ export function Provider({children}: React.PropsWithChildren<{}>) { } if (canReusePrevSession) { - logger.info(`session: attempting to reuse previous session`) + logger.debug(`session: attempting to reuse previous session`) agent.session = prevSession __globalAgent = agent @@ -384,7 +384,7 @@ export function Provider({children}: React.PropsWithChildren<{}>) { if (prevSession.deactivated) { // don't attempt to resume // use will be taken to the deactivated screen - logger.info(`session: reusing session for deactivated account`) + logger.debug(`session: reusing session for deactivated account`) return } @@ -410,7 +410,7 @@ export function Provider({children}: React.PropsWithChildren<{}>) { __globalAgent = PUBLIC_BSKY_AGENT }) } else { - logger.info(`session: attempting to resume using previous session`) + logger.debug(`session: attempting to resume using previous session`) try { const freshAccount = await resumeSessionWithFreshAccount() @@ -431,7 +431,7 @@ export function Provider({children}: React.PropsWithChildren<{}>) { } async function resumeSessionWithFreshAccount(): Promise { - logger.info(`session: resumeSessionWithFreshAccount`) + logger.debug(`session: resumeSessionWithFreshAccount`) await networkRetry(1, () => agent.resumeSession(prevSession)) @@ -552,11 +552,11 @@ export function Provider({children}: React.PropsWithChildren<{}>) { return persisted.onUpdate(() => { const session = persisted.get('session') - logger.info(`session: persisted onUpdate`, {}) + logger.debug(`session: persisted onUpdate`, {}) if (session.currentAccount && session.currentAccount.refreshJwt) { if (session.currentAccount?.did !== state.currentAccount?.did) { - logger.info(`session: persisted onUpdate, switching accounts`, { + logger.debug(`session: persisted onUpdate, switching accounts`, { from: { did: state.currentAccount?.did, handle: state.currentAccount?.handle, @@ -569,7 +569,7 @@ export function Provider({children}: React.PropsWithChildren<{}>) { initSession(session.currentAccount) } else { - logger.info(`session: persisted onUpdate, updating session`, {}) + logger.debug(`session: persisted onUpdate, updating session`, {}) /* * Use updated session in this tab's agent. Do not call diff --git a/src/view/com/auth/login/LoginForm.tsx b/src/view/com/auth/login/LoginForm.tsx index e480de7a..fdba9f20 100644 --- a/src/view/com/auth/login/LoginForm.tsx +++ b/src/view/com/auth/login/LoginForm.tsx @@ -107,7 +107,7 @@ export const LoginForm = ({ const errMsg = e.toString() setIsProcessing(false) if (errMsg.includes('Authentication Required')) { - logger.info('Failed to login due to invalid credentials', { + logger.debug('Failed to login due to invalid credentials', { error: errMsg, }) setError(_(msg`Invalid username or password`)) From 58aaad704aa971c5ebbf5a5f330a2e2129b557f6 Mon Sep 17 00:00:00 2001 From: Eric Bailey Date: Mon, 26 Feb 2024 22:33:48 -0600 Subject: [PATCH 11/43] Add tags and mute words (#2968) * Add bare minimum hashtags support (#2804) * Add bare minimum hashtags support As atproto/api already parses hashtags, this is as simple as hooking it up like link segments. This is "bare minimum" because: - Opening hashtag "#foo" is actually just a search for "foo" right now to work around #2491. - There is no integration in the composer. This hasn't stopped people from using hashtags already, and can be added later. - This change itself only had to hook things up - thank you for having already put the hashtag parsing in place. * Remove workaround for hash search not working now that it's fixed * Add RichTextTag and TagMenu * Sketch * Remove hackfix * Some cleanup * Sketch web * Mobile design * Mobile handling of tags search * Web only * Fix navigation woes * Use new callback * Hook it up * Integrate muted tags * Fix dropdown styles * Type error * Use close callback * Fix styles * Cleanup, install latest sdk * Quick muted words screen * Targets * Dir structure * Icons, list view * Move to dialog * Add removal confirmation * Swap copy * Improve checkboxees * Update matching, add tests * Moderate embeds * Create global dialogs concept again to prevent flashing * Add access from moderation screen * Highlight tags on native * Add web highlighting * Add close to web modal * Adjust close color * Rename toggles and adjust logic * Icon update * Load states * Improve regex * Improve regex * Improve regex * Revert link test * Hyphenated words * Improve matching * Enhance * Some tweaks * Muted words modal changes * Handle invalid handles, handle long tags * Remove main regex * Better test * Space/punct check drop to includes * Lowercase post text before comparison * Add better real world test case --------- Co-authored-by: Kisaragi Hiu --- .../checkThick_stroke2_corner0_rounded.svg | 1 + .../clipboard_stroke2_corner2_rounded.svg | 1 + ...gnifyingGlass2_stroke2_corner0_rounded.svg | 1 + assets/icons/mute_stroke2_corner0_rounded.svg | 1 + .../pageText_stroke2_corner0_rounded.svg | 1 + bskyweb/templates/base.html | 5 + package.json | 2 +- src/Navigation.tsx | 3 +- src/alf/atoms.ts | 4 + src/components/Dialog/index.web.tsx | 2 +- src/components/RichText.tsx | 103 +++- src/components/TagMenu/index.tsx | 279 +++++++++ src/components/TagMenu/index.web.tsx | 127 ++++ src/components/dialogs/Context.tsx | 29 + src/components/dialogs/MutedWords.tsx | 328 ++++++++++ src/components/forms/TextField.tsx | 2 +- src/components/forms/Toggle.tsx | 34 +- src/components/icons/Check.tsx | 4 + src/components/icons/Clipboard.tsx | 5 + src/components/icons/Group3.tsx | 2 +- src/components/icons/MagnifyingGlass2.tsx | 5 + src/components/icons/Mute.tsx | 5 + src/components/icons/PageText.tsx | 5 + src/components/icons/Person.tsx | 5 + .../__tests__/moderatePost_wrapped.test.ts | 578 ++++++++++++++++++ src/lib/moderatePost_wrapped.ts | 156 ++++- src/lib/moderation.ts | 7 + src/lib/routes/links.ts | 10 + src/lib/routes/types.ts | 1 + src/state/dialogs/index.tsx | 3 +- src/state/queries/preferences/const.ts | 2 + src/state/queries/preferences/index.ts | 49 +- .../com/composer/text-input/TextInput.tsx | 3 +- .../com/composer/text-input/TextInput.web.tsx | 2 + .../composer/text-input/web/TagDecorator.ts | 83 +++ src/view/com/post-thread/PostThreadItem.tsx | 6 +- src/view/com/post/Post.tsx | 2 + src/view/com/posts/FeedItem.tsx | 2 + .../com/util/forms/NativeDropdown.web.tsx | 5 + src/view/com/util/forms/PostDropdownBtn.tsx | 16 + src/view/com/util/post-embeds/QuoteEmbed.tsx | 2 + src/view/com/util/text/RichText.tsx | 66 ++ src/view/icons/index.tsx | 2 + src/view/screens/Moderation.tsx | 23 +- src/view/screens/Search/Search.tsx | 27 +- src/view/shell/index.tsx | 2 + src/view/shell/index.web.tsx | 2 + web/index.html | 5 + yarn.lock | 14 + 49 files changed, 1983 insertions(+), 39 deletions(-) create mode 100644 assets/icons/checkThick_stroke2_corner0_rounded.svg create mode 100644 assets/icons/clipboard_stroke2_corner2_rounded.svg create mode 100644 assets/icons/magnifyingGlass2_stroke2_corner0_rounded.svg create mode 100644 assets/icons/mute_stroke2_corner0_rounded.svg create mode 100644 assets/icons/pageText_stroke2_corner0_rounded.svg create mode 100644 src/components/TagMenu/index.tsx create mode 100644 src/components/TagMenu/index.web.tsx create mode 100644 src/components/dialogs/Context.tsx create mode 100644 src/components/dialogs/MutedWords.tsx create mode 100644 src/components/icons/Clipboard.tsx create mode 100644 src/components/icons/MagnifyingGlass2.tsx create mode 100644 src/components/icons/Mute.tsx create mode 100644 src/components/icons/PageText.tsx create mode 100644 src/components/icons/Person.tsx create mode 100644 src/lib/__tests__/moderatePost_wrapped.test.ts create mode 100644 src/view/com/composer/text-input/web/TagDecorator.ts diff --git a/assets/icons/checkThick_stroke2_corner0_rounded.svg b/assets/icons/checkThick_stroke2_corner0_rounded.svg new file mode 100644 index 00000000..54af3e85 --- /dev/null +++ b/assets/icons/checkThick_stroke2_corner0_rounded.svg @@ -0,0 +1 @@ + diff --git a/assets/icons/clipboard_stroke2_corner2_rounded.svg b/assets/icons/clipboard_stroke2_corner2_rounded.svg new file mode 100644 index 00000000..f403cfb9 --- /dev/null +++ b/assets/icons/clipboard_stroke2_corner2_rounded.svg @@ -0,0 +1 @@ + diff --git a/assets/icons/magnifyingGlass2_stroke2_corner0_rounded.svg b/assets/icons/magnifyingGlass2_stroke2_corner0_rounded.svg new file mode 100644 index 00000000..2759aaf2 --- /dev/null +++ b/assets/icons/magnifyingGlass2_stroke2_corner0_rounded.svg @@ -0,0 +1 @@ + diff --git a/assets/icons/mute_stroke2_corner0_rounded.svg b/assets/icons/mute_stroke2_corner0_rounded.svg new file mode 100644 index 00000000..8ebecb39 --- /dev/null +++ b/assets/icons/mute_stroke2_corner0_rounded.svg @@ -0,0 +1 @@ + diff --git a/assets/icons/pageText_stroke2_corner0_rounded.svg b/assets/icons/pageText_stroke2_corner0_rounded.svg new file mode 100644 index 00000000..826a36cd --- /dev/null +++ b/assets/icons/pageText_stroke2_corner0_rounded.svg @@ -0,0 +1 @@ + diff --git a/bskyweb/templates/base.html b/bskyweb/templates/base.html index e29e4032..50fb9a2f 100644 --- a/bskyweb/templates/base.html +++ b/bskyweb/templates/base.html @@ -205,6 +205,11 @@ [data-tooltip]:hover::before { display:block; } + + /* NativeDropdown component */ + .nativeDropdown-item:focus { + outline: none; + } {% include "scripts.html" %} diff --git a/package.json b/package.json index 3f007a23..3d151603 100644 --- a/package.json +++ b/package.json @@ -43,7 +43,7 @@ "nuke": "rm -rf ./node_modules && rm -rf ./ios && rm -rf ./android" }, "dependencies": { - "@atproto/api": "^0.9.5", + "@atproto/api": "^0.10.0", "@bam.tech/react-native-image-resizer": "^3.0.4", "@braintree/sanitize-url": "^6.0.2", "@emoji-mart/react": "^1.1.1", diff --git a/src/Navigation.tsx b/src/Navigation.tsx index 6ca4212e..dfbe816f 100644 --- a/src/Navigation.tsx +++ b/src/Navigation.tsx @@ -497,7 +497,8 @@ const LINKING = { }, ]) } else { - return buildStateObject('Flat', name, params) + const res = buildStateObject('Flat', name, params) + return res } }, } diff --git a/src/alf/atoms.ts b/src/alf/atoms.ts index 18f492d6..fff3a4d8 100644 --- a/src/alf/atoms.ts +++ b/src/alf/atoms.ts @@ -1,3 +1,4 @@ +import {web, native} from '#/alf/util/platform' import * as tokens from '#/alf/tokens' export const atoms = { @@ -113,6 +114,9 @@ export const atoms = { flex_wrap: { flexWrap: 'wrap', }, + flex_0: { + flex: web('0 0 auto') || (native(0) as number), + }, flex_1: { flex: 1, }, diff --git a/src/components/Dialog/index.web.tsx b/src/components/Dialog/index.web.tsx index 79441fb5..fa29fbd6 100644 --- a/src/components/Dialog/index.web.tsx +++ b/src/components/Dialog/index.web.tsx @@ -188,7 +188,7 @@ export function Close() { + + ) : null} + + + + + )} + + + + ) +} diff --git a/src/components/TagMenu/index.web.tsx b/src/components/TagMenu/index.web.tsx new file mode 100644 index 00000000..930e47a1 --- /dev/null +++ b/src/components/TagMenu/index.web.tsx @@ -0,0 +1,127 @@ +import React from 'react' +import {msg} from '@lingui/macro' +import {useLingui} from '@lingui/react' +import {useNavigation} from '@react-navigation/native' + +import {isInvalidHandle} from '#/lib/strings/handles' +import {EventStopper} from '#/view/com/util/EventStopper' +import {NativeDropdown} from '#/view/com/util/forms/NativeDropdown' +import {NavigationProp} from '#/lib/routes/types' +import { + usePreferencesQuery, + useUpsertMutedWordsMutation, + useRemoveMutedWordMutation, +} from '#/state/queries/preferences' + +export function useTagMenuControl() {} + +export function TagMenu({ + children, + tag, + authorHandle, +}: React.PropsWithChildren<{ + tag: string + authorHandle?: string +}>) { + const sanitizedTag = tag.replace(/^#/, '') + const {_} = useLingui() + const navigation = useNavigation() + const {data: preferences} = usePreferencesQuery() + const {mutateAsync: upsertMutedWord, variables: optimisticUpsert} = + useUpsertMutedWordsMutation() + const {mutateAsync: removeMutedWord, variables: optimisticRemove} = + useRemoveMutedWordMutation() + const isMuted = Boolean( + (preferences?.mutedWords?.find( + m => m.value === sanitizedTag && m.targets.includes('tag'), + ) ?? + optimisticUpsert?.find( + m => m.value === sanitizedTag && m.targets.includes('tag'), + )) && + !(optimisticRemove?.value === sanitizedTag), + ) + + const dropdownItems = React.useMemo(() => { + return [ + { + label: _(msg`See ${tag} posts`), + onPress() { + navigation.navigate('Search', { + q: tag, + }) + }, + testID: 'tagMenuSearch', + icon: { + ios: { + name: 'magnifyingglass', + }, + android: '', + web: 'magnifying-glass', + }, + }, + authorHandle && + !isInvalidHandle(authorHandle) && { + label: _(msg`See ${tag} posts by this user`), + onPress() { + navigation.navigate({ + name: 'Search', + params: { + q: tag + (authorHandle ? ` from:${authorHandle}` : ''), + }, + }) + }, + testID: 'tagMenuSeachByUser', + icon: { + ios: { + name: 'magnifyingglass', + }, + android: '', + web: ['far', 'user'], + }, + }, + preferences && { + label: 'separator', + }, + preferences && { + label: isMuted ? _(msg`Unmute ${tag}`) : _(msg`Mute ${tag}`), + onPress() { + if (isMuted) { + removeMutedWord({value: sanitizedTag, targets: ['tag']}) + } else { + upsertMutedWord([{value: sanitizedTag, targets: ['tag']}]) + } + }, + testID: 'tagMenuMute', + icon: { + ios: { + name: 'speaker.slash', + }, + android: 'ic_menu_sort_alphabetically', + web: isMuted ? 'eye' : ['far', 'eye-slash'], + }, + }, + ].filter(Boolean) + }, [ + _, + authorHandle, + isMuted, + navigation, + preferences, + tag, + sanitizedTag, + upsertMutedWord, + removeMutedWord, + ]) + + return ( + + + {children} + + + ) +} diff --git a/src/components/dialogs/Context.tsx b/src/components/dialogs/Context.tsx new file mode 100644 index 00000000..d86c90a9 --- /dev/null +++ b/src/components/dialogs/Context.tsx @@ -0,0 +1,29 @@ +import React from 'react' + +import * as Dialog from '#/components/Dialog' + +type Control = Dialog.DialogOuterProps['control'] + +type ControlsContext = { + mutedWordsDialogControl: Control +} + +const ControlsContext = React.createContext({ + mutedWordsDialogControl: {} as Control, +}) + +export function useGlobalDialogsControlContext() { + return React.useContext(ControlsContext) +} + +export function Provider({children}: React.PropsWithChildren<{}>) { + const mutedWordsDialogControl = Dialog.useDialogControl() + const ctx = React.useMemo( + () => ({mutedWordsDialogControl}), + [mutedWordsDialogControl], + ) + + return ( + {children} + ) +} diff --git a/src/components/dialogs/MutedWords.tsx b/src/components/dialogs/MutedWords.tsx new file mode 100644 index 00000000..138cc533 --- /dev/null +++ b/src/components/dialogs/MutedWords.tsx @@ -0,0 +1,328 @@ +import React from 'react' +import {View} from 'react-native' +import {msg, Trans} from '@lingui/macro' +import {useLingui} from '@lingui/react' +import {AppBskyActorDefs} from '@atproto/api' + +import { + usePreferencesQuery, + useUpsertMutedWordsMutation, + useRemoveMutedWordMutation, +} from '#/state/queries/preferences' +import {isNative} from '#/platform/detection' +import {atoms as a, useTheme, useBreakpoints, ViewStyleProp} from '#/alf' +import {Text} from '#/components/Typography' +import {Button, ButtonIcon, ButtonText} from '#/components/Button' +import {PlusLarge_Stroke2_Corner0_Rounded as Plus} from '#/components/icons/Plus' +import {TimesLarge_Stroke2_Corner0_Rounded as X} from '#/components/icons/Times' +import {Hashtag_Stroke2_Corner0_Rounded as Hashtag} from '#/components/icons/Hashtag' +import {PageText_Stroke2_Corner0_Rounded as PageText} from '#/components/icons/PageText' +import {Divider} from '#/components/Divider' +import {Loader} from '#/components/Loader' +import {logger} from '#/logger' +import * as Dialog from '#/components/Dialog' +import * as Toggle from '#/components/forms/Toggle' +import * as Prompt from '#/components/Prompt' + +import {useGlobalDialogsControlContext} from '#/components/dialogs/Context' + +export function MutedWordsDialog() { + const {mutedWordsDialogControl: control} = useGlobalDialogsControlContext() + return ( + + + + + ) +} + +function MutedWordsInner({}: {control: Dialog.DialogOuterProps['control']}) { + const t = useTheme() + const {_} = useLingui() + const {gtMobile} = useBreakpoints() + const { + isLoading: isPreferencesLoading, + data: preferences, + error: preferencesError, + } = usePreferencesQuery() + const {isPending, mutateAsync: addMutedWord} = useUpsertMutedWordsMutation() + const [field, setField] = React.useState('') + const [options, setOptions] = React.useState(['content']) + const [_error, setError] = React.useState('') + + const submit = React.useCallback(async () => { + const value = field.trim() + const targets = ['tag', options.includes('content') && 'content'].filter( + Boolean, + ) as AppBskyActorDefs.MutedWord['targets'] + + if (!value || !targets.length) return + + try { + await addMutedWord([{value, targets}]) + setField('') + } catch (e: any) { + logger.error(`Failed to save muted word`, {message: e.message}) + setError(e.message) + } + }, [field, options, addMutedWord, setField]) + + return ( + + + Add muted words and tags + + + + Posts can be muted based on their text, their tags, or both. + + + + + + + + + + + + + + Mute in text & tags + + + + + + + + + + + + Mute in tags only + + + + + + + + + + + + + We recommend avoiding common words that appear in many posts, since + it can result in no posts being shown. + + + + + + + + + Your muted words + + + {isPreferencesLoading ? ( + + ) : preferencesError || !preferences ? ( + + + + We're sorry, but we weren't able to load your muted words at + this time. Please try again. + + + + ) : preferences.mutedWords.length ? ( + [...preferences.mutedWords] + .reverse() + .map((word, i) => ( + + )) + ) : ( + + + You haven't muted any words or tags yet + + + )} + + + {isNative && } + + + + ) +} + +function MutedWordRow({ + style, + word, +}: ViewStyleProp & {word: AppBskyActorDefs.MutedWord}) { + const t = useTheme() + const {_} = useLingui() + const {isPending, mutateAsync: removeMutedWord} = useRemoveMutedWordMutation() + const control = Prompt.usePromptControl() + + const remove = React.useCallback(async () => { + control.close() + removeMutedWord(word) + }, [removeMutedWord, word, control]) + + return ( + <> + + + Are you sure? + + + + This will delete {word.value} from your muted words. You can always + add it back later. + + + + + + Nevermind + + + + + Remove + + + + + + + + {word.value} + + + + {word.targets.map(target => ( + + + {target === 'content' ? _(msg`text`) : _(msg`tag`)} + + + ))} + + + + + + ) +} + +function TargetToggle({children}: React.PropsWithChildren<{}>) { + const t = useTheme() + const ctx = Toggle.useItemContext() + const {gtMobile} = useBreakpoints() + return ( + + {children} + + ) +} diff --git a/src/components/forms/TextField.tsx b/src/components/forms/TextField.tsx index ebf2e475..a781bdd1 100644 --- a/src/components/forms/TextField.tsx +++ b/src/components/forms/TextField.tsx @@ -72,7 +72,7 @@ export function Root({children, isInvalid = false}: RootProps) { return ( inputRef.current?.focus(), onMouseOver: onHoverIn, diff --git a/src/components/forms/Toggle.tsx b/src/components/forms/Toggle.tsx index 9369423f..140740f7 100644 --- a/src/components/forms/Toggle.tsx +++ b/src/components/forms/Toggle.tsx @@ -5,6 +5,7 @@ import {HITSLOP_10} from 'lib/constants' import {useTheme, atoms as a, web, native, flatten, ViewStyleProp} from '#/alf' import {Text} from '#/components/Typography' import {useInteractionState} from '#/components/hooks/useInteractionState' +import {CheckThick_Stroke2_Corner0_Rounded as Checkmark} from '#/components/icons/Check' export type ItemState = { name: string @@ -331,15 +332,14 @@ export function createSharedToggleStyles({ export function Checkbox() { const t = useTheme() const {selected, hovered, focused, disabled, isInvalid} = useItemContext() - const {baseStyles, baseHoverStyles, indicatorStyles} = - createSharedToggleStyles({ - theme: t, - hovered, - focused, - selected, - disabled, - isInvalid, - }) + const {baseStyles, baseHoverStyles} = createSharedToggleStyles({ + theme: t, + hovered, + focused, + selected, + disabled, + isInvalid, + }) return ( - {selected ? ( - - ) : null} + {selected ? : null} ) } diff --git a/src/components/icons/Check.tsx b/src/components/icons/Check.tsx index 24316c78..fe9883ba 100644 --- a/src/components/icons/Check.tsx +++ b/src/components/icons/Check.tsx @@ -3,3 +3,7 @@ import {createSinglePathSVG} from './TEMPLATE' export const Check_Stroke2_Corner0_Rounded = createSinglePathSVG({ path: 'M21.59 3.193a1 1 0 0 1 .217 1.397l-11.706 16a1 1 0 0 1-1.429.193l-6.294-5a1 1 0 1 1 1.244-1.566l5.48 4.353 11.09-15.16a1 1 0 0 1 1.398-.217Z', }) + +export const CheckThick_Stroke2_Corner0_Rounded = createSinglePathSVG({ + path: 'M21.474 2.98a2.5 2.5 0 0 1 .545 3.494l-10.222 14a2.5 2.5 0 0 1-3.528.52L2.49 16.617a2.5 2.5 0 0 1 3.018-3.986l3.75 2.84L17.98 3.525a2.5 2.5 0 0 1 3.493-.545Z', +}) diff --git a/src/components/icons/Clipboard.tsx b/src/components/icons/Clipboard.tsx new file mode 100644 index 00000000..0135992b --- /dev/null +++ b/src/components/icons/Clipboard.tsx @@ -0,0 +1,5 @@ +import {createSinglePathSVG} from './TEMPLATE' + +export const Clipboard_Stroke2_Corner2_Rounded = createSinglePathSVG({ + path: 'M8.17 4A3.001 3.001 0 0 1 11 2h2c1.306 0 2.418.835 2.83 2H17a3 3 0 0 1 3 3v12a3 3 0 0 1-3 3H7a3 3 0 0 1-3-3V7a3 3 0 0 1 3-3h1.17ZM8 6H7a1 1 0 0 0-1 1v12a1 1 0 0 0 1 1h10a1 1 0 0 0 1-1V7a1 1 0 0 0-1-1h-1v1a1 1 0 0 1-1 1H9a1 1 0 0 1-1-1V6Zm6 0V5a1 1 0 0 0-1-1h-2a1 1 0 0 0-1 1v1h4Z', +}) diff --git a/src/components/icons/Group3.tsx b/src/components/icons/Group3.tsx index 2bb16ba8..9e5ab889 100644 --- a/src/components/icons/Group3.tsx +++ b/src/components/icons/Group3.tsx @@ -1,5 +1,5 @@ import {createSinglePathSVG} from './TEMPLATE' export const Group3_Stroke2_Corner0_Rounded = createSinglePathSVG({ - path: 'M17 16H21.1456C20.8246 11.4468 17.7199 9.48509 15.0001 10.1147M10 4C10 5.65685 8.65685 7 7 7C5.34315 7 4 5.65685 4 4C4 2.34315 5.34315 1 7 1C8.65685 1 10 2.34315 10 4ZM18.5 4.5C18.5 5.88071 17.3807 7 16 7C14.6193 7 13.5 5.88071 13.5 4.5C13.5 3.11929 14.6193 2 16 2C17.3807 2 18.5 3.11929 18.5 4.5ZM1 17H13C12.3421 7.66667 1.65792 7.66667 1 17Z', + path: 'M8 5a2 2 0 1 0 0 4 2 2 0 0 0 0-4ZM4 7a4 4 0 1 1 8 0 4 4 0 0 1-8 0Zm13-1a1.5 1.5 0 1 0 0 3 1.5 1.5 0 0 0 0-3Zm-3.5 1.5a3.5 3.5 0 1 1 7 0 3.5 3.5 0 0 1-7 0Zm5.826 7.376c-.919-.779-2.052-1.03-3.1-.787a1 1 0 0 1-.451-1.949c1.671-.386 3.45.028 4.844 1.211 1.397 1.185 2.348 3.084 2.524 5.579a1 1 0 0 1-.997 1.07H18a1 1 0 1 1 0-2h3.007c-.29-1.47-.935-2.49-1.681-3.124ZM3.126 19h9.747c-.61-3.495-2.867-5-4.873-5-2.006 0-4.263 1.505-4.873 5ZM8 12c3.47 0 6.64 2.857 6.998 7.93A1 1 0 0 1 14 21H2a1 1 0 0 1-.998-1.07C1.36 14.857 4.53 12 8 12Z', }) diff --git a/src/components/icons/MagnifyingGlass2.tsx b/src/components/icons/MagnifyingGlass2.tsx new file mode 100644 index 00000000..3ca40340 --- /dev/null +++ b/src/components/icons/MagnifyingGlass2.tsx @@ -0,0 +1,5 @@ +import {createSinglePathSVG} from './TEMPLATE' + +export const MagnifyingGlass2_Stroke2_Corner0_Rounded = createSinglePathSVG({ + path: 'M11 5a6 6 0 1 0 0 12 6 6 0 0 0 0-12Zm-8 6a8 8 0 1 1 14.32 4.906l3.387 3.387a1 1 0 0 1-1.414 1.414l-3.387-3.387A8 8 0 0 1 3 11Z', +}) diff --git a/src/components/icons/Mute.tsx b/src/components/icons/Mute.tsx new file mode 100644 index 00000000..00657078 --- /dev/null +++ b/src/components/icons/Mute.tsx @@ -0,0 +1,5 @@ +import {createSinglePathSVG} from './TEMPLATE' + +export const Mute_Stroke2_Corner0_Rounded = createSinglePathSVG({ + path: 'M20.707 3.293a1 1 0 0 1 0 1.414l-16 16a1 1 0 0 1-1.414-1.414l2.616-2.616A1.998 1.998 0 0 1 5 15V9a2 2 0 0 1 2-2h2.697l5.748-3.832A1 1 0 0 1 17 4v1.586l2.293-2.293a1 1 0 0 1 1.414 0ZM15 7.586 7.586 15H7V9h2.697a2 2 0 0 0 1.11-.336L15 5.87v1.717Zm2 3.657-2 2v4.888l-2.933-1.955-1.442 1.442 4.82 3.214A1 1 0 0 0 17 20v-8.757Z', +}) diff --git a/src/components/icons/PageText.tsx b/src/components/icons/PageText.tsx new file mode 100644 index 00000000..25fbde33 --- /dev/null +++ b/src/components/icons/PageText.tsx @@ -0,0 +1,5 @@ +import {createSinglePathSVG} from './TEMPLATE' + +export const PageText_Stroke2_Corner0_Rounded = createSinglePathSVG({ + path: 'M5 2a1 1 0 0 0-1 1v18a1 1 0 0 0 1 1h14a1 1 0 0 0 1-1V3a1 1 0 0 0-1-1H5Zm1 18V4h12v16H6Zm3-6a1 1 0 1 0 0 2h2a1 1 0 1 0 0-2H9Zm-1-3a1 1 0 0 1 1-1h6a1 1 0 1 1 0 2H9a1 1 0 0 1-1-1Zm1-5a1 1 0 0 0 0 2h6a1 1 0 1 0 0-2H9Z', +}) diff --git a/src/components/icons/Person.tsx b/src/components/icons/Person.tsx new file mode 100644 index 00000000..6d09148c --- /dev/null +++ b/src/components/icons/Person.tsx @@ -0,0 +1,5 @@ +import {createSinglePathSVG} from './TEMPLATE' + +export const Person_Stroke2_Corner0_Rounded = createSinglePathSVG({ + path: 'M12 4a2.5 2.5 0 1 0 0 5 2.5 2.5 0 0 0 0-5ZM7.5 6.5a4.5 4.5 0 1 1 9 0 4.5 4.5 0 0 1-9 0ZM5.678 19h12.644c-.71-2.909-3.092-5-6.322-5s-5.613 2.091-6.322 5Zm-2.174.906C3.917 15.521 7.242 12 12 12c4.758 0 8.083 3.521 8.496 7.906A1 1 0 0 1 19.5 21h-15a1 1 0 0 1-.996-1.094Z', +}) diff --git a/src/lib/__tests__/moderatePost_wrapped.test.ts b/src/lib/__tests__/moderatePost_wrapped.test.ts new file mode 100644 index 00000000..1d907963 --- /dev/null +++ b/src/lib/__tests__/moderatePost_wrapped.test.ts @@ -0,0 +1,578 @@ +import {describe, it, expect} from '@jest/globals' +import {RichText} from '@atproto/api' + +import {hasMutedWord} from '../moderatePost_wrapped' + +describe(`hasMutedWord`, () => { + describe(`tags`, () => { + it(`match: outline tag`, () => { + const rt = new RichText({ + text: `This is a post #inlineTag`, + }) + rt.detectFacetsWithoutResolution() + + const match = hasMutedWord( + [{value: 'outlineTag', targets: ['tag']}], + rt.text, + rt.facets, + ['outlineTag'], + ) + + expect(match).toBe(true) + }) + + it(`match: inline tag`, () => { + const rt = new RichText({ + text: `This is a post #inlineTag`, + }) + rt.detectFacetsWithoutResolution() + + const match = hasMutedWord( + [{value: 'inlineTag', targets: ['tag']}], + rt.text, + rt.facets, + ['outlineTag'], + ) + + expect(match).toBe(true) + }) + + it(`match: content target matches inline tag`, () => { + const rt = new RichText({ + text: `This is a post #inlineTag`, + }) + rt.detectFacetsWithoutResolution() + + const match = hasMutedWord( + [{value: 'inlineTag', targets: ['content']}], + rt.text, + rt.facets, + ['outlineTag'], + ) + + expect(match).toBe(true) + }) + + it(`no match: only tag targets`, () => { + const rt = new RichText({ + text: `This is a post`, + }) + rt.detectFacetsWithoutResolution() + + const match = hasMutedWord( + [{value: 'inlineTag', targets: ['tag']}], + rt.text, + rt.facets, + [], + ) + + expect(match).toBe(false) + }) + }) + + describe(`early exits`, () => { + it(`match: single character 希`, () => { + /** + * @see https://bsky.app/profile/mukuuji.bsky.social/post/3klji4fvsdk2c + */ + const rt = new RichText({ + text: `改善希望です`, + }) + rt.detectFacetsWithoutResolution() + + const match = hasMutedWord( + [{value: '希', targets: ['content']}], + rt.text, + rt.facets, + [], + ) + + expect(match).toBe(true) + }) + + it(`no match: long muted word, short post`, () => { + const rt = new RichText({ + text: `hey`, + }) + rt.detectFacetsWithoutResolution() + + const match = hasMutedWord( + [{value: 'politics', targets: ['content']}], + rt.text, + rt.facets, + [], + ) + + expect(match).toBe(false) + }) + + it(`match: exact text`, () => { + const rt = new RichText({ + text: `javascript`, + }) + rt.detectFacetsWithoutResolution() + + const match = hasMutedWord( + [{value: 'javascript', targets: ['content']}], + rt.text, + rt.facets, + [], + ) + + expect(match).toBe(true) + }) + }) + + describe(`general content`, () => { + it(`match: word within post`, () => { + const rt = new RichText({ + text: `This is a post about javascript`, + }) + rt.detectFacetsWithoutResolution() + + const match = hasMutedWord( + [{value: 'javascript', targets: ['content']}], + rt.text, + rt.facets, + [], + ) + + expect(match).toBe(true) + }) + + it(`no match: partial word`, () => { + const rt = new RichText({ + text: `Use your brain, Eric`, + }) + rt.detectFacetsWithoutResolution() + + const match = hasMutedWord( + [{value: 'ai', targets: ['content']}], + rt.text, + rt.facets, + [], + ) + + expect(match).toBe(false) + }) + + it(`match: multiline`, () => { + const rt = new RichText({ + text: `Use your\n\tbrain, Eric`, + }) + rt.detectFacetsWithoutResolution() + + const match = hasMutedWord( + [{value: 'brain', targets: ['content']}], + rt.text, + rt.facets, + [], + ) + + expect(match).toBe(true) + }) + + it(`match: :)`, () => { + const rt = new RichText({ + text: `So happy :)`, + }) + rt.detectFacetsWithoutResolution() + + const match = hasMutedWord( + [{value: `:)`, targets: ['content']}], + rt.text, + rt.facets, + [], + ) + + expect(match).toBe(true) + }) + }) + + describe(`punctuation semi-fuzzy`, () => { + describe(`yay!`, () => { + const rt = new RichText({ + text: `We're federating, yay!`, + }) + rt.detectFacetsWithoutResolution() + + it(`match: yay!`, () => { + const match = hasMutedWord( + [{value: 'yay!', targets: ['content']}], + rt.text, + rt.facets, + [], + ) + + expect(match).toBe(true) + }) + + it(`match: yay`, () => { + const match = hasMutedWord( + [{value: 'yay', targets: ['content']}], + rt.text, + rt.facets, + [], + ) + + expect(match).toBe(true) + }) + }) + + describe(`y!ppee!!`, () => { + const rt = new RichText({ + text: `We're federating, y!ppee!!`, + }) + rt.detectFacetsWithoutResolution() + + it(`match: y!ppee`, () => { + const match = hasMutedWord( + [{value: 'y!ppee', targets: ['content']}], + rt.text, + rt.facets, + [], + ) + + expect(match).toBe(true) + }) + + // single exclamation point, source has double + it(`no match: y!ppee!`, () => { + const match = hasMutedWord( + [{value: 'y!ppee!', targets: ['content']}], + rt.text, + rt.facets, + [], + ) + + expect(match).toBe(true) + }) + }) + + describe(`Why so S@assy?`, () => { + const rt = new RichText({ + text: `Why so S@assy?`, + }) + rt.detectFacetsWithoutResolution() + + it(`match: S@assy`, () => { + const match = hasMutedWord( + [{value: 'S@assy', targets: ['content']}], + rt.text, + rt.facets, + [], + ) + + expect(match).toBe(true) + }) + + it(`match: s@assy`, () => { + const match = hasMutedWord( + [{value: 's@assy', targets: ['content']}], + rt.text, + rt.facets, + [], + ) + + expect(match).toBe(true) + }) + }) + + describe(`New York Times`, () => { + const rt = new RichText({ + text: `New York Times`, + }) + rt.detectFacetsWithoutResolution() + + // case insensitive + it(`match: new york times`, () => { + const match = hasMutedWord( + [{value: 'new york times', targets: ['content']}], + rt.text, + rt.facets, + [], + ) + + expect(match).toBe(true) + }) + }) + + describe(`!command`, () => { + const rt = new RichText({ + text: `Idk maybe a bot !command`, + }) + rt.detectFacetsWithoutResolution() + + it(`match: !command`, () => { + const match = hasMutedWord( + [{value: `!command`, targets: ['content']}], + rt.text, + rt.facets, + [], + ) + + expect(match).toBe(true) + }) + + it(`match: command`, () => { + const match = hasMutedWord( + [{value: `command`, targets: ['content']}], + rt.text, + rt.facets, + [], + ) + + expect(match).toBe(true) + }) + + it(`no match: !command`, () => { + const rt = new RichText({ + text: `Idk maybe a bot command`, + }) + rt.detectFacetsWithoutResolution() + + const match = hasMutedWord( + [{value: `!command`, targets: ['content']}], + rt.text, + rt.facets, + [], + ) + + expect(match).toBe(false) + }) + }) + + describe(`e/acc`, () => { + const rt = new RichText({ + text: `I'm e/acc pilled`, + }) + rt.detectFacetsWithoutResolution() + + it(`match: e/acc`, () => { + const match = hasMutedWord( + [{value: `e/acc`, targets: ['content']}], + rt.text, + rt.facets, + [], + ) + + expect(match).toBe(true) + }) + + it(`match: acc`, () => { + const match = hasMutedWord( + [{value: `acc`, targets: ['content']}], + rt.text, + rt.facets, + [], + ) + + expect(match).toBe(true) + }) + }) + + describe(`super-bad`, () => { + const rt = new RichText({ + text: `I'm super-bad`, + }) + rt.detectFacetsWithoutResolution() + + it(`match: super-bad`, () => { + const match = hasMutedWord( + [{value: `super-bad`, targets: ['content']}], + rt.text, + rt.facets, + [], + ) + + expect(match).toBe(true) + }) + + it(`match: super`, () => { + const match = hasMutedWord( + [{value: `super`, targets: ['content']}], + rt.text, + rt.facets, + [], + ) + + expect(match).toBe(true) + }) + + it(`match: super bad`, () => { + const match = hasMutedWord( + [{value: `super bad`, targets: ['content']}], + rt.text, + rt.facets, + [], + ) + + expect(match).toBe(true) + }) + + it(`match: superbad`, () => { + const match = hasMutedWord( + [{value: `superbad`, targets: ['content']}], + rt.text, + rt.facets, + [], + ) + + expect(match).toBe(false) + }) + }) + + describe(`idk_what_this_would_be`, () => { + const rt = new RichText({ + text: `Weird post with idk_what_this_would_be`, + }) + rt.detectFacetsWithoutResolution() + + it(`match: idk what this would be`, () => { + const match = hasMutedWord( + [{value: `idk what this would be`, targets: ['content']}], + rt.text, + rt.facets, + [], + ) + + expect(match).toBe(true) + }) + + it(`no match: idk what this would be for`, () => { + // extra word + const match = hasMutedWord( + [{value: `idk what this would be for`, targets: ['content']}], + rt.text, + rt.facets, + [], + ) + + expect(match).toBe(false) + }) + + it(`match: idk`, () => { + // extra word + const match = hasMutedWord( + [{value: `idk`, targets: ['content']}], + rt.text, + rt.facets, + [], + ) + + expect(match).toBe(true) + }) + + it(`match: idkwhatthiswouldbe`, () => { + const match = hasMutedWord( + [{value: `idkwhatthiswouldbe`, targets: ['content']}], + rt.text, + rt.facets, + [], + ) + + expect(match).toBe(false) + }) + }) + + describe(`parentheses`, () => { + const rt = new RichText({ + text: `Post with context(iykyk)`, + }) + rt.detectFacetsWithoutResolution() + + it(`match: context(iykyk)`, () => { + const match = hasMutedWord( + [{value: `context(iykyk)`, targets: ['content']}], + rt.text, + rt.facets, + [], + ) + + expect(match).toBe(true) + }) + + it(`match: context`, () => { + const match = hasMutedWord( + [{value: `context`, targets: ['content']}], + rt.text, + rt.facets, + [], + ) + + expect(match).toBe(true) + }) + + it(`match: iykyk`, () => { + const match = hasMutedWord( + [{value: `iykyk`, targets: ['content']}], + rt.text, + rt.facets, + [], + ) + + expect(match).toBe(true) + }) + + it(`match: (iykyk)`, () => { + const match = hasMutedWord( + [{value: `(iykyk)`, targets: ['content']}], + rt.text, + rt.facets, + [], + ) + + expect(match).toBe(true) + }) + }) + + describe(`🦋`, () => { + const rt = new RichText({ + text: `Post with 🦋`, + }) + rt.detectFacetsWithoutResolution() + + it(`match: 🦋`, () => { + const match = hasMutedWord( + [{value: `🦋`, targets: ['content']}], + rt.text, + rt.facets, + [], + ) + + expect(match).toBe(true) + }) + }) + }) + + describe(`phrases`, () => { + describe(`I like turtles, or how I learned to stop worrying and love the internet.`, () => { + const rt = new RichText({ + text: `I like turtles, or how I learned to stop worrying and love the internet.`, + }) + rt.detectFacetsWithoutResolution() + + it(`match: stop worrying`, () => { + const match = hasMutedWord( + [{value: 'stop worrying', targets: ['content']}], + rt.text, + rt.facets, + [], + ) + + expect(match).toBe(true) + }) + + it(`match: turtles, or how`, () => { + const match = hasMutedWord( + [{value: 'turtles, or how', targets: ['content']}], + rt.text, + rt.facets, + [], + ) + + expect(match).toBe(true) + }) + }) + }) +}) diff --git a/src/lib/moderatePost_wrapped.ts b/src/lib/moderatePost_wrapped.ts index 2195b230..862f2de6 100644 --- a/src/lib/moderatePost_wrapped.ts +++ b/src/lib/moderatePost_wrapped.ts @@ -2,18 +2,122 @@ import { AppBskyEmbedRecord, AppBskyEmbedRecordWithMedia, moderatePost, + AppBskyActorDefs, + AppBskyFeedPost, + AppBskyRichtextFacet, + AppBskyEmbedImages, } from '@atproto/api' type ModeratePost = typeof moderatePost type Options = Parameters[1] & { hiddenPosts?: string[] + mutedWords?: AppBskyActorDefs.MutedWord[] +} + +const REGEX = { + LEADING_TRAILING_PUNCTUATION: /(?:^\p{P}+|\p{P}+$)/gu, + ESCAPE: /[[\]{}()*+?.\\^$|\s]/g, + SEPARATORS: /[\/\-\–\—\(\)\[\]\_]+/g, + WORD_BOUNDARY: /[\s\n\t\r\f\v]+?/g, +} + +export function hasMutedWord( + mutedWords: AppBskyActorDefs.MutedWord[], + text: string, + facets?: AppBskyRichtextFacet.Main[], + outlineTags?: string[], +) { + const tags = ([] as string[]) + .concat(outlineTags || []) + .concat( + facets + ?.filter(facet => { + return facet.features.find(feature => + AppBskyRichtextFacet.isTag(feature), + ) + }) + .map(t => t.features[0].tag as string) || [], + ) + .map(t => t.toLowerCase()) + + for (const mute of mutedWords) { + const mutedWord = mute.value.toLowerCase() + const postText = text.toLowerCase() + + // `content` applies to tags as well + if (tags.includes(mutedWord)) return true + // rest of the checks are for `content` only + if (!mute.targets.includes('content')) continue + // single character, has to use includes + if (mutedWord.length === 1 && postText.includes(mutedWord)) return true + // too long + if (mutedWord.length > postText.length) continue + // exact match + if (mutedWord === postText) return true + // any muted phrase with space or punctuation + if (/(?:\s|\p{P})+?/u.test(mutedWord) && postText.includes(mutedWord)) + return true + + // check individual character groups + const words = postText.split(REGEX.WORD_BOUNDARY) + for (const word of words) { + if (word === mutedWord) return true + + // compare word without leading/trailing punctuation, but allow internal + // punctuation (such as `s@ssy`) + const wordTrimmedPunctuation = word.replace( + REGEX.LEADING_TRAILING_PUNCTUATION, + '', + ) + + if (mutedWord === wordTrimmedPunctuation) return true + if (mutedWord.length > wordTrimmedPunctuation.length) continue + + // handle hyphenated, slash separated words, etc + if (REGEX.SEPARATORS.test(wordTrimmedPunctuation)) { + // check against full normalized phrase + const wordNormalizedSeparators = wordTrimmedPunctuation.replace( + REGEX.SEPARATORS, + ' ', + ) + const mutedWordNormalizedSeparators = mutedWord.replace( + REGEX.SEPARATORS, + ' ', + ) + // hyphenated (or other sep) to spaced words + if (wordNormalizedSeparators === mutedWordNormalizedSeparators) + return true + + /* Disabled for now e.g. `super-cool` to `supercool` + const wordNormalizedCompressed = wordNormalizedSeparators.replace( + REGEX.WORD_BOUNDARY, + '', + ) + const mutedWordNormalizedCompressed = + mutedWordNormalizedSeparators.replace(/\s+?/g, '') + // hyphenated (or other sep) to non-hyphenated contiguous word + if (mutedWordNormalizedCompressed === wordNormalizedCompressed) + return true + */ + + // then individual parts of separated phrases/words + const wordParts = wordTrimmedPunctuation.split(REGEX.SEPARATORS) + for (const wp of wordParts) { + // still retain internal punctuation + if (wp === mutedWord) return true + } + } + } + } + + return false } export function moderatePost_wrapped( subject: Parameters[0], opts: Options, ) { - const {hiddenPosts = [], ...options} = opts + const {hiddenPosts = [], mutedWords = [], ...options} = opts const moderations = moderatePost(subject, options) if (hiddenPosts.includes(subject.uri)) { @@ -29,15 +133,65 @@ export function moderatePost_wrapped( } } + if (AppBskyFeedPost.isRecord(subject.record)) { + let muted = hasMutedWord( + mutedWords, + subject.record.text, + subject.record.facets || [], + subject.record.tags || [], + ) + + if ( + subject.record.embed && + AppBskyEmbedImages.isMain(subject.record.embed) + ) { + for (const image of subject.record.embed.images) { + muted = muted || hasMutedWord(mutedWords, image.alt, [], []) + } + } + + if (muted) { + moderations.content.filter = true + moderations.content.blur = true + if (!moderations.content.cause) { + moderations.content.cause = { + // @ts-ignore Temporary extension to the moderation system -prf + type: 'muted-word', + source: {type: 'user'}, + priority: 1, + } + } + } + } + if (subject.embed) { let embedHidden = false if (AppBskyEmbedRecord.isViewRecord(subject.embed.record)) { embedHidden = hiddenPosts.includes(subject.embed.record.uri) + + if (AppBskyFeedPost.isRecord(subject.embed.record.value)) { + embedHidden = + embedHidden || + hasMutedWord( + mutedWords, + subject.embed.record.value.text, + subject.embed.record.value.facets, + subject.embed.record.value.tags, + ) + + if (AppBskyEmbedImages.isMain(subject.embed.record.value.embed)) { + for (const image of subject.embed.record.value.embed.images) { + embedHidden = + embedHidden || hasMutedWord(mutedWords, image.alt, [], []) + } + } + } } if ( AppBskyEmbedRecordWithMedia.isView(subject.embed) && AppBskyEmbedRecord.isViewRecord(subject.embed.record.record) ) { + // TODO what embedHidden = hiddenPosts.includes(subject.embed.record.record.uri) } if (embedHidden) { diff --git a/src/lib/moderation.ts b/src/lib/moderation.ts index bf19c208..b6ebb47a 100644 --- a/src/lib/moderation.ts +++ b/src/lib/moderation.ts @@ -67,6 +67,13 @@ export function describeModerationCause( description: 'You have hidden this post', } } + // @ts-ignore Temporary extension to the moderation system -prf + if (cause.type === 'muted-word') { + return { + name: 'Post hidden by muted word', + description: `You've chosen to hide a word or tag within this post.`, + } + } return cause.labelDef.strings[context].en } diff --git a/src/lib/routes/links.ts b/src/lib/routes/links.ts index 538f30cd..9dfdab90 100644 --- a/src/lib/routes/links.ts +++ b/src/lib/routes/links.ts @@ -25,3 +25,13 @@ export function makeCustomFeedLink( export function makeListLink(did: string, rkey: string, ...segments: string[]) { return [`/profile`, did, 'lists', rkey, ...segments].join('/') } + +export function makeTagLink(did: string) { + return `/search?q=${encodeURIComponent(did)}` +} + +export function makeSearchLink(props: {query: string; from?: 'me' | string}) { + return `/search?q=${encodeURIComponent( + props.query + (props.from ? ` from:${props.from}` : ''), + )}` +} diff --git a/src/lib/routes/types.ts b/src/lib/routes/types.ts index 0fb36fa7..0ec09f61 100644 --- a/src/lib/routes/types.ts +++ b/src/lib/routes/types.ts @@ -33,6 +33,7 @@ export type CommonNavigatorParams = { PreferencesFollowingFeed: undefined PreferencesThreads: undefined PreferencesExternalEmbeds: undefined + Search: {q?: string} } export type BottomTabNavigatorParams = CommonNavigatorParams & { diff --git a/src/state/dialogs/index.tsx b/src/state/dialogs/index.tsx index 4cafaa08..ae762bd9 100644 --- a/src/state/dialogs/index.tsx +++ b/src/state/dialogs/index.tsx @@ -1,5 +1,6 @@ import React from 'react' import {DialogControlProps} from '#/components/Dialog' +import {Provider as GlobalDialogsProvider} from '#/components/dialogs/Context' const DialogContext = React.createContext<{ activeDialogs: React.MutableRefObject< @@ -37,7 +38,7 @@ export function Provider({children}: React.PropsWithChildren<{}>) { return ( - {children} + {children} ) diff --git a/src/state/queries/preferences/const.ts b/src/state/queries/preferences/const.ts index 2d9d0299..25d28499 100644 --- a/src/state/queries/preferences/const.ts +++ b/src/state/queries/preferences/const.ts @@ -49,4 +49,6 @@ export const DEFAULT_LOGGED_OUT_PREFERENCES: UsePreferencesQueryResponse = { threadViewPrefs: DEFAULT_THREAD_VIEW_PREFS, userAge: 13, // TODO(pwi) interests: {tags: []}, + mutedWords: [], + hiddenPosts: [], } diff --git a/src/state/queries/preferences/index.ts b/src/state/queries/preferences/index.ts index 632d31a1..07198de7 100644 --- a/src/state/queries/preferences/index.ts +++ b/src/state/queries/preferences/index.ts @@ -1,6 +1,10 @@ import {useMemo} from 'react' import {useQuery, useMutation, useQueryClient} from '@tanstack/react-query' -import {LabelPreference, BskyFeedViewPreference} from '@atproto/api' +import { + LabelPreference, + BskyFeedViewPreference, + AppBskyActorDefs, +} from '@atproto/api' import {track} from '#/lib/analytics/analytics' import {getAge} from '#/lib/strings/time' @@ -108,6 +112,7 @@ export function useModerationOpts() { return { ...moderationOpts, hiddenPosts, + mutedWords: prefs.data.mutedWords || [], } }, [currentAccount?.did, prefs.data, hiddenPosts]) return opts @@ -278,3 +283,45 @@ export function useUnpinFeedMutation() { }, }) } + +export function useUpsertMutedWordsMutation() { + const queryClient = useQueryClient() + + return useMutation({ + mutationFn: async (mutedWords: AppBskyActorDefs.MutedWord[]) => { + await getAgent().upsertMutedWords(mutedWords) + // triggers a refetch + await queryClient.invalidateQueries({ + queryKey: preferencesQueryKey, + }) + }, + }) +} + +export function useUpdateMutedWordMutation() { + const queryClient = useQueryClient() + + return useMutation({ + mutationFn: async (mutedWord: AppBskyActorDefs.MutedWord) => { + await getAgent().updateMutedWord(mutedWord) + // triggers a refetch + await queryClient.invalidateQueries({ + queryKey: preferencesQueryKey, + }) + }, + }) +} + +export function useRemoveMutedWordMutation() { + const queryClient = useQueryClient() + + return useMutation({ + mutationFn: async (mutedWord: AppBskyActorDefs.MutedWord) => { + await getAgent().removeMutedWord(mutedWord) + // triggers a refetch + await queryClient.invalidateQueries({ + queryKey: preferencesQueryKey, + }) + }, + }) +} diff --git a/src/view/com/composer/text-input/TextInput.tsx b/src/view/com/composer/text-input/TextInput.tsx index 17f9513b..20be585c 100644 --- a/src/view/com/composer/text-input/TextInput.tsx +++ b/src/view/com/composer/text-input/TextInput.tsx @@ -190,12 +190,11 @@ export const TextInput = forwardRef(function TextInputImpl( let i = 0 return Array.from(richtext.segments()).map(segment => { - const isTag = AppBskyRichtextFacet.isTag(segment.facet?.features?.[0]) return ( {segment.text} diff --git a/src/view/com/composer/text-input/TextInput.web.tsx b/src/view/com/composer/text-input/TextInput.web.tsx index 199f1f74..c62d1120 100644 --- a/src/view/com/composer/text-input/TextInput.web.tsx +++ b/src/view/com/composer/text-input/TextInput.web.tsx @@ -23,6 +23,7 @@ import {Portal} from '#/components/Portal' import {Text} from '../../util/text/Text' import {Trans} from '@lingui/macro' import Animated, {FadeIn, FadeOut} from 'react-native-reanimated' +import {TagDecorator} from './web/TagDecorator' export interface TextInputRef { focus: () => void @@ -67,6 +68,7 @@ export const TextInput = React.forwardRef(function TextInputImpl( () => [ Document, LinkDecorator, + TagDecorator, Mention.configure({ HTMLAttributes: { class: 'mention', diff --git a/src/view/com/composer/text-input/web/TagDecorator.ts b/src/view/com/composer/text-input/web/TagDecorator.ts new file mode 100644 index 00000000..d820ec3f --- /dev/null +++ b/src/view/com/composer/text-input/web/TagDecorator.ts @@ -0,0 +1,83 @@ +/** + * TipTap is a stateful rich-text editor, which is extremely useful + * when you _want_ it to be stateful formatting such as bold and italics. + * + * However we also use "stateless" behaviors, specifically for URLs + * where the text itself drives the formatting. + * + * This plugin uses a regex to detect URIs and then applies + * link decorations (a with the "autolink") class. That avoids + * adding any stateful formatting to TipTap's document model. + * + * We then run the URI detection again when constructing the + * RichText object from TipTap's output and merge their features into + * the facet-set. + */ + +import {Mark} from '@tiptap/core' +import {Plugin, PluginKey} from '@tiptap/pm/state' +import {Node as ProsemirrorNode} from '@tiptap/pm/model' +import {Decoration, DecorationSet} from '@tiptap/pm/view' + +function getDecorations(doc: ProsemirrorNode) { + const decorations: Decoration[] = [] + + doc.descendants((node, pos) => { + if (node.isText && node.text) { + const regex = /(?:^|\s)(#[^\d\s]\S*)(?=\s)?/g + const textContent = node.textContent + + let match + while ((match = regex.exec(textContent))) { + const [matchedString, tag] = match + + if (tag.length > 66) continue + + const [trailingPunc = ''] = tag.match(/\p{P}+$/u) || [] + + const from = match.index + matchedString.indexOf(tag) + const to = from + (tag.length - trailingPunc.length) + + decorations.push( + Decoration.inline(pos + from, pos + to, { + class: 'autolink', + }), + ) + } + } + }) + + return DecorationSet.create(doc, decorations) +} + +const tagDecoratorPlugin: Plugin = new Plugin({ + key: new PluginKey('link-decorator'), + + state: { + init: (_, {doc}) => getDecorations(doc), + apply: (transaction, decorationSet) => { + if (transaction.docChanged) { + return getDecorations(transaction.doc) + } + return decorationSet.map(transaction.mapping, transaction.doc) + }, + }, + + props: { + decorations(state) { + return tagDecoratorPlugin.getState(state) + }, + }, +}) + +export const TagDecorator = Mark.create({ + name: 'tag-decorator', + priority: 1000, + keepOnSplit: false, + inclusive() { + return true + }, + addProseMirrorPlugins() { + return [tagDecoratorPlugin] + }, +}) diff --git a/src/view/com/post-thread/PostThreadItem.tsx b/src/view/com/post-thread/PostThreadItem.tsx index ebd73983..949fcfea 100644 --- a/src/view/com/post-thread/PostThreadItem.tsx +++ b/src/view/com/post-thread/PostThreadItem.tsx @@ -327,9 +327,11 @@ let PostThreadItemLoaded = ({ styles.postTextLargeContainer, ]}> ) : undefined} @@ -521,9 +523,11 @@ let PostThreadItemLoaded = ({ {richText?.text ? ( ) : undefined} diff --git a/src/view/com/post/Post.tsx b/src/view/com/post/Post.tsx index aec916ad..5fa4da84 100644 --- a/src/view/com/post/Post.tsx +++ b/src/view/com/post/Post.tsx @@ -184,10 +184,12 @@ function PostInner({ {richText.text ? ( ) : undefined} diff --git a/src/view/com/posts/FeedItem.tsx b/src/view/com/posts/FeedItem.tsx index 6f64de18..47a964ab 100644 --- a/src/view/com/posts/FeedItem.tsx +++ b/src/view/com/posts/FeedItem.tsx @@ -347,10 +347,12 @@ let PostContent = ({ {richText.text ? ( ) : undefined} diff --git a/src/view/com/util/forms/NativeDropdown.web.tsx b/src/view/com/util/forms/NativeDropdown.web.tsx index 9e9888ad..052e7ca1 100644 --- a/src/view/com/util/forms/NativeDropdown.web.tsx +++ b/src/view/com/util/forms/NativeDropdown.web.tsx @@ -21,6 +21,7 @@ export const DropdownMenuItem = (props: ItemProps & {testID?: string}) => { return ( ) : null} {embed && } diff --git a/src/view/com/util/text/RichText.tsx b/src/view/com/util/text/RichText.tsx index b6d46122..0ec3f318 100644 --- a/src/view/com/util/text/RichText.tsx +++ b/src/view/com/util/text/RichText.tsx @@ -7,6 +7,9 @@ import {lh} from 'lib/styles' import {toShortUrl} from 'lib/strings/url-helpers' import {useTheme, TypographyVariant} from 'lib/ThemeContext' import {usePalette} from 'lib/hooks/usePalette' +import {makeTagLink} from 'lib/routes/links' +import {TagMenu, useTagMenuControl} from '#/components/TagMenu' +import {isNative} from '#/platform/detection' const WORD_WRAP = {wordWrap: 1} @@ -82,6 +85,7 @@ export function RichText({ for (const segment of richText.segments()) { const link = segment.link const mention = segment.mention + const tag = segment.tag if ( !noLinks && mention && @@ -115,6 +119,21 @@ export function RichText({ />, ) } + } else if ( + !noLinks && + tag && + AppBskyRichtextFacet.validateTag(tag).success + ) { + els.push( + , + ) } else { els.push(segment.text) } @@ -133,3 +152,50 @@ export function RichText({ ) } + +function RichTextTag({ + text: tag, + type, + style, + lineHeightStyle, + selectable, +}: { + text: string + type?: TypographyVariant + style?: StyleProp + lineHeightStyle?: TextStyle + selectable?: boolean +}) { + const pal = usePalette('default') + const control = useTagMenuControl() + + const open = React.useCallback(() => { + control.open() + }, [control]) + + return ( + + + {isNative ? ( + + ) : ( + + {tag} + + )} + + + ) +} diff --git a/src/view/icons/index.tsx b/src/view/icons/index.tsx index b7bbf160..ede1e633 100644 --- a/src/view/icons/index.tsx +++ b/src/view/icons/index.tsx @@ -103,6 +103,7 @@ import {faUsersSlash} from '@fortawesome/free-solid-svg-icons/faUsersSlash' import {faX} from '@fortawesome/free-solid-svg-icons/faX' import {faXmark} from '@fortawesome/free-solid-svg-icons/faXmark' import {faChevronDown} from '@fortawesome/free-solid-svg-icons/faChevronDown' +import {faFilter} from '@fortawesome/free-solid-svg-icons/faFilter' library.add( faAddressCard, @@ -208,4 +209,5 @@ library.add( faX, faXmark, faChevronDown, + faFilter, ) diff --git a/src/view/screens/Moderation.tsx b/src/view/screens/Moderation.tsx index 8f1fe75b..928766c3 100644 --- a/src/view/screens/Moderation.tsx +++ b/src/view/screens/Moderation.tsx @@ -31,6 +31,7 @@ import { useProfileUpdateMutation, } from '#/state/queries/profile' import {ScrollView} from '../com/util/Views' +import {useGlobalDialogsControlContext} from '#/components/dialogs/Context' type Props = NativeStackScreenProps export function ModerationScreen({}: Props) { @@ -40,6 +41,7 @@ export function ModerationScreen({}: Props) { const {screen, track} = useAnalytics() const {isTabletOrDesktop} = useWebMediaQueries() const {openModal} = useModalControls() + const {mutedWordsDialogControl} = useGlobalDialogsControlContext() useFocusEffect( React.useCallback(() => { @@ -69,8 +71,8 @@ export function ModerationScreen({}: Props) { style={[styles.linkCard, pal.view]} onPress={onPressContentFiltering} accessibilityRole="tab" - accessibilityHint="Content filtering" - accessibilityLabel=""> + accessibilityHint="" + accessibilityLabel={_(msg`Open content filtering settings`)}> Content filtering + mutedWordsDialogControl.open()} + accessibilityRole="tab" + accessibilityHint="" + accessibilityLabel={_(msg`Open muted words settings`)}> + + + + + Muted words & tags + + , ) { + const navigation = useNavigation() const theme = useTheme() const textInput = React.useRef(null) const {_} = useLingui() @@ -472,6 +474,27 @@ export function SearchScreen( React.useState(false) const [searchHistory, setSearchHistory] = React.useState([]) + /** + * The Search screen's `q` param + */ + const queryParam = props.route?.params?.q + + /** + * If `true`, this means we received new instructions from the router. This + * is handled in a effect, and used to update the value of `query` locally + * within this screen. + */ + const routeParamsMismatch = queryParam && queryParam !== query + + React.useEffect(() => { + if (queryParam && routeParamsMismatch) { + // reset immediately and let local state take over + navigation.setParams({q: ''}) + // update query for next search + setQuery(queryParam) + } + }, [queryParam, routeParamsMismatch, navigation]) + React.useEffect(() => { const loadSearchHistory = async () => { try { @@ -774,6 +797,8 @@ export function SearchScreen( )} + ) : routeParamsMismatch ? ( + ) : ( )} diff --git a/src/view/shell/index.tsx b/src/view/shell/index.tsx index 6b0cc680..d895d885 100644 --- a/src/view/shell/index.tsx +++ b/src/view/shell/index.tsx @@ -29,6 +29,7 @@ import {useSession} from '#/state/session' import {useCloseAnyActiveElement} from '#/state/util' import * as notifications from 'lib/notifications/notifications' import {Outlet as PortalOutlet} from '#/components/Portal' +import {MutedWordsDialog} from '#/components/dialogs/MutedWords' function ShellInner() { const isDrawerOpen = useIsDrawerOpen() @@ -94,6 +95,7 @@ function ShellInner() { + diff --git a/src/view/shell/index.web.tsx b/src/view/shell/index.web.tsx index 97c06550..71dccb8c 100644 --- a/src/view/shell/index.web.tsx +++ b/src/view/shell/index.web.tsx @@ -16,6 +16,7 @@ import {useIsDrawerOpen, useSetDrawerOpen} from '#/state/shell' import {useCloseAllActiveElements} from '#/state/util' import {useWebBodyScrollLock} from '#/lib/hooks/useWebBodyScrollLock' import {Outlet as PortalOutlet} from '#/components/Portal' +import {MutedWordsDialog} from '#/components/dialogs/MutedWords' function ShellInner() { const isDrawerOpen = useIsDrawerOpen() @@ -40,6 +41,7 @@ function ShellInner() { + {!isDesktop && isDrawerOpen && ( diff --git a/web/index.html b/web/index.html index 992e69e0..78090591 100644 --- a/web/index.html +++ b/web/index.html @@ -209,6 +209,11 @@ [data-tooltip]:hover::before { display:block; } + + /* NativeDropdown component */ + .nativeDropdown-item:focus { + outline: none; + } diff --git a/yarn.lock b/yarn.lock index a85ea79b..3cec585b 100644 --- a/yarn.lock +++ b/yarn.lock @@ -34,6 +34,20 @@ jsonpointer "^5.0.0" leven "^3.1.0" +"@atproto/api@^0.10.0": + version "0.10.0" + resolved "https://registry.yarnpkg.com/@atproto/api/-/api-0.10.0.tgz#ca34dfa8f9b1e6ba021094c40cb0ff3c4c254044" + integrity sha512-TSVCHh3UUZLtNzh141JwLicfYTc7TvVFvQJSWeOZLHr3Sk+9hqEY+9Itaqp1DAW92r4i25ChaMc/50sg4etAWQ== + dependencies: + "@atproto/common-web" "^0.2.3" + "@atproto/lexicon" "^0.3.1" + "@atproto/syntax" "^0.1.5" + "@atproto/xrpc" "^0.4.1" + multiformats "^9.9.0" + tlds "^1.234.0" + typed-emitter "^2.1.0" + zod "^3.21.4" + "@atproto/api@^0.9.5": version "0.9.5" resolved "https://registry.yarnpkg.com/@atproto/api/-/api-0.9.5.tgz#630e5d9520bba38d0cd348c8028ddbb73bd074f8" From c8d02a791a84a243b290b3a1479aa6ac097a51fa Mon Sep 17 00:00:00 2001 From: Hailey Date: Tue, 27 Feb 2024 10:01:29 -0800 Subject: [PATCH 12/43] Log to Sentry whenever users encounter Bluesky feed errors (#2999) --- src/lib/constants.ts | 6 ++++ src/state/queries/post-feed.ts | 57 ++++++++++++++++++++++++---------- 2 files changed, 46 insertions(+), 17 deletions(-) diff --git a/src/lib/constants.ts b/src/lib/constants.ts index c8e5273d..e8684439 100644 --- a/src/lib/constants.ts +++ b/src/lib/constants.ts @@ -75,3 +75,9 @@ export const HITSLOP_20 = createHitslop(20) export const HITSLOP_30 = createHitslop(30) export const BACK_HITSLOP = HITSLOP_30 export const MAX_POST_LINES = 25 + +export const BSKY_FEED_OWNER_DIDS = [ + 'did:plc:z72i7hdynmk6r22z27h6tvur', + 'did:plc:vpkhqolt662uhesyj6nxm7ys', + 'did:plc:q6gjnaw2blty4crticxkmujt', +] diff --git a/src/state/queries/post-feed.ts b/src/state/queries/post-feed.ts index 40399395..220aac37 100644 --- a/src/state/queries/post-feed.ts +++ b/src/state/queries/post-feed.ts @@ -1,6 +1,11 @@ import React, {useCallback, useEffect, useRef} from 'react' import {AppState} from 'react-native' -import {AppBskyFeedDefs, AppBskyFeedPost, PostModeration} from '@atproto/api' +import { + AppBskyFeedDefs, + AppBskyFeedPost, + AtUri, + PostModeration, +} from '@atproto/api' import { useInfiniteQuery, InfiniteData, @@ -29,6 +34,7 @@ import {KnownError} from '#/view/com/posts/FeedErrorMessage' import {embedViewRecordToPostView, getEmbeddedPost} from './util' import {useModerationOpts} from './preferences' import {queryClient} from 'lib/react-query' +import {BSKY_FEED_OWNER_DIDS} from 'lib/constants' type ActorDid = string type AuthorFilter = @@ -137,24 +143,41 @@ export function usePostFeedQuery( cursor: undefined, } - const res = await api.fetch({cursor, limit: PAGE_SIZE}) - precacheFeedPostProfiles(queryClient, res.feed) + try { + const res = await api.fetch({cursor, limit: PAGE_SIZE}) + precacheFeedPostProfiles(queryClient, res.feed) - /* - * If this is a public view, we need to check if posts fail moderation. - * If all fail, we throw an error. If only some fail, we continue and let - * moderations happen later, which results in some posts being shown and - * some not. - */ - if (!getAgent().session) { - assertSomePostsPassModeration(res.feed) - } + /* + * If this is a public view, we need to check if posts fail moderation. + * If all fail, we throw an error. If only some fail, we continue and let + * moderations happen later, which results in some posts being shown and + * some not. + */ + if (!getAgent().session) { + assertSomePostsPassModeration(res.feed) + } - return { - api, - cursor: res.cursor, - feed: res.feed, - fetchedAt: Date.now(), + return { + api, + cursor: res.cursor, + feed: res.feed, + fetchedAt: Date.now(), + } + } catch (e) { + const feedDescParts = feedDesc.split('|') + const feedOwnerDid = new AtUri(feedDescParts[1]).hostname + + if ( + feedDescParts[0] === 'feedgen' && + BSKY_FEED_OWNER_DIDS.includes(feedOwnerDid) + ) { + logger.error(`Bluesky feed may be offline: ${feedOwnerDid}`, { + feedDesc, + jsError: e, + }) + } + + throw e } }, initialPageParam: undefined, From 2a04546c7305b9bf03ea6cd26ce728ed773e2673 Mon Sep 17 00:00:00 2001 From: Hailey Date: Tue, 27 Feb 2024 10:35:38 -0800 Subject: [PATCH 13/43] Intent handler (#2992) * Handle URL params * Add resources * Add other params * refactor for scope * modify the pr to support intents rather than utm remove linebreak remove linebreak handle web adjust path check to work on web add a short delay for opening the composer setup compose intent, move to `intents` directory fix intent logic ignore incoming intents in the navigation router * refactor --------- Co-authored-by: Eric Bailey --- app.config.js | 4 ++ package.json | 1 + src/App.native.tsx | 2 + src/App.web.tsx | 2 + src/Navigation.tsx | 8 +++- src/lib/hooks/useIntentHandler.ts | 64 +++++++++++++++++++++++++++++++ yarn.lock | 8 ++++ 7 files changed, 88 insertions(+), 1 deletion(-) create mode 100644 src/lib/hooks/useIntentHandler.ts diff --git a/app.config.js b/app.config.js index e710420b..5bbe864a 100644 --- a/app.config.js +++ b/app.config.js @@ -89,6 +89,10 @@ module.exports = function (config) { scheme: 'https', host: 'bsky.app', }, + { + scheme: 'http', + host: 'localhost:19006', + }, ], category: ['BROWSABLE', 'DEFAULT'], }, diff --git a/package.json b/package.json index 3d151603..4051849b 100644 --- a/package.json +++ b/package.json @@ -109,6 +109,7 @@ "expo-image": "~1.10.3", "expo-image-manipulator": "^11.8.0", "expo-image-picker": "~14.7.1", + "expo-linking": "^6.2.2", "expo-localization": "~14.8.2", "expo-media-library": "~15.9.1", "expo-notifications": "~0.27.3", diff --git a/src/App.native.tsx b/src/App.native.tsx index 1284154f..f08a6235 100644 --- a/src/App.native.tsx +++ b/src/App.native.tsx @@ -45,6 +45,7 @@ import {Splash} from '#/Splash' import {Provider as PortalProvider} from '#/components/Portal' import {msg} from '@lingui/macro' import {useLingui} from '@lingui/react' +import {useIntentHandler} from 'lib/hooks/useIntentHandler' SplashScreen.preventAutoHideAsync() @@ -53,6 +54,7 @@ function InnerApp() { const {resumeSession} = useSessionApi() const theme = useColorModeTheme() const {_} = useLingui() + useIntentHandler() // init useEffect(() => { diff --git a/src/App.web.tsx b/src/App.web.tsx index f10bb194..6ac32a01 100644 --- a/src/App.web.tsx +++ b/src/App.web.tsx @@ -32,11 +32,13 @@ import { import {Provider as UnreadNotifsProvider} from 'state/queries/notifications/unread' import * as persisted from '#/state/persisted' import {Provider as PortalProvider} from '#/components/Portal' +import {useIntentHandler} from 'lib/hooks/useIntentHandler' function InnerApp() { const {isInitialLoad, currentAccount} = useSession() const {resumeSession} = useSessionApi() const theme = useColorModeTheme() + useIntentHandler() // init useEffect(() => { diff --git a/src/Navigation.tsx b/src/Navigation.tsx index dfbe816f..0aeeeb6a 100644 --- a/src/Navigation.tsx +++ b/src/Navigation.tsx @@ -460,7 +460,8 @@ const FlatNavigator = () => { */ const LINKING = { - prefixes: ['bsky://', 'https://bsky.app'], + // TODO figure out what we are going to use + prefixes: ['bsky://', 'bluesky://', 'https://bsky.app'], getPathFromState(state: State) { // find the current node in the navigation tree @@ -478,6 +479,11 @@ const LINKING = { }, getStateFromPath(path: string) { + // Any time we receive a url that starts with `intent/` we want to ignore it here. It will be handled in the + // intent handler hook. We should check for the trailing slash, because if there isn't one then it isn't a valid + // intent + if (path.includes('intent/')) return + const [name, params] = router.matchPath(path) if (isNative) { if (name === 'Search') { diff --git a/src/lib/hooks/useIntentHandler.ts b/src/lib/hooks/useIntentHandler.ts new file mode 100644 index 00000000..249e6898 --- /dev/null +++ b/src/lib/hooks/useIntentHandler.ts @@ -0,0 +1,64 @@ +import React from 'react' +import * as Linking from 'expo-linking' +import {isNative} from 'platform/detection' +import {useComposerControls} from 'state/shell' +import {useSession} from 'state/session' + +type IntentType = 'compose' + +export function useIntentHandler() { + const incomingUrl = Linking.useURL() + const composeIntent = useComposeIntent() + + React.useEffect(() => { + const handleIncomingURL = (url: string) => { + const urlp = new URL(url) + const [_, intentTypeNative, intentTypeWeb] = urlp.pathname.split('/') + + // On native, our links look like bluesky://intent/SomeIntent, so we have to check the hostname for the + // intent check. On web, we have to check the first part of the path since we have an actual hostname + const intentType = isNative ? intentTypeNative : intentTypeWeb + const isIntent = isNative + ? urlp.hostname === 'intent' + : intentTypeNative === 'intent' + const params = urlp.searchParams + + if (!isIntent) return + + switch (intentType as IntentType) { + case 'compose': { + composeIntent({ + text: params.get('text'), + imageUris: params.get('imageUris'), + }) + } + } + } + + if (incomingUrl) handleIncomingURL(incomingUrl) + }, [incomingUrl, composeIntent]) +} + +function useComposeIntent() { + const {openComposer} = useComposerControls() + const {hasSession} = useSession() + + return React.useCallback( + ({ + // eslint-disable-next-line @typescript-eslint/no-unused-vars + text, + // eslint-disable-next-line @typescript-eslint/no-unused-vars + imageUris, + }: { + text: string | null + imageUris: string | null // unused for right now, will be used later with intents + }) => { + if (!hasSession) return + + setTimeout(() => { + openComposer({}) // will pass in values to the composer here in the share extension + }, 500) + }, + [openComposer, hasSession], + ) +} diff --git a/yarn.lock b/yarn.lock index 3cec585b..a62ff2f8 100644 --- a/yarn.lock +++ b/yarn.lock @@ -11739,6 +11739,14 @@ expo-keep-awake@~12.8.1: resolved "https://registry.yarnpkg.com/expo-keep-awake/-/expo-keep-awake-12.8.1.tgz#3c8df9d86c265741b5e7bdd36965aa0c6fc17df0" integrity sha512-P/VZFV02Rzgj13skMwH+ceGOGZSEdaUu5n7pCS3wThh2LppZjPJ7sBxUwyzeLa3DXEVUtwLZi+BiQ91wPwy9Gg== +expo-linking@^6.2.2: + version "6.2.2" + resolved "https://registry.yarnpkg.com/expo-linking/-/expo-linking-6.2.2.tgz#b7e148068ae49fd9ad814428c16fdf7a236e8aca" + integrity sha512-FEe6lP4f7xFT/vjoHRG+tt6EPVtkEGaWNK1smpaUevmNdyCJKqW0PDB8o8sfG6y7fly8ULe8qg3HhKh5J7aqUQ== + dependencies: + expo-constants "~15.4.3" + invariant "^2.2.4" + expo-localization@~14.8.2: version "14.8.2" resolved "https://registry.yarnpkg.com/expo-localization/-/expo-localization-14.8.2.tgz#e0bbed2293265834d21a1c58d3a5f8d265bd04ae" From 6717f8f11e69d12bcde3e5601ed02281b927c378 Mon Sep 17 00:00:00 2001 From: Hailey Date: Tue, 27 Feb 2024 13:31:44 -0800 Subject: [PATCH 14/43] Compile locale before build on CI, fix the google-services.json variable for android builds (#3001) * compile intl before building, fix android json var * update intl:build --- .github/workflows/build-submit-android.yml | 6 +++++- .github/workflows/build-submit-ios.yml | 3 +++ package.json | 2 +- 3 files changed, 9 insertions(+), 2 deletions(-) diff --git a/.github/workflows/build-submit-android.yml b/.github/workflows/build-submit-android.yml index 6fa177fb..8cbd9098 100644 --- a/.github/workflows/build-submit-android.yml +++ b/.github/workflows/build-submit-android.yml @@ -49,10 +49,14 @@ jobs: - name: ⚙️ Install dependencies run: yarn install + - name: 🔤 Compile translations + run: yarn intl:build + - name: ✏️ Write environment variables run: | + export json='${{ secrets.GOOGLE_SERVICES_TOKEN }}' echo "${{ secrets.ENV_TOKEN }}" > .env - echo "${{ secrets.GOOGLE_SERVICES_TOKEN }}" > google-services.json + echo "$json" > google-services.json - name: 🏗️ EAS Build run: yarn use-build-number eas build -p android --profile production --local --output build.aab --non-interactive diff --git a/.github/workflows/build-submit-ios.yml b/.github/workflows/build-submit-ios.yml index b6767806..f5188b4b 100644 --- a/.github/workflows/build-submit-ios.yml +++ b/.github/workflows/build-submit-ios.yml @@ -60,6 +60,9 @@ jobs: # change unless the yarn version changes as well. key: ${{ runner.os }}-pods-${{ hashFiles('yarn.lock') }} + - name: 🔤 Compile translations + run: yarn intl:build + - name: ✏️ Write environment variables run: | echo "${{ secrets.ENV_TOKEN }}" > .env diff --git a/package.json b/package.json index 4051849b..2d520b4b 100644 --- a/package.json +++ b/package.json @@ -36,7 +36,7 @@ "perf:test:measure": "NODE_ENV=test flashlight test --bundleId xyz.blueskyweb.app --testCommand 'yarn perf:test' --duration 150000 --resultsFilePath .perf/results.json", "perf:test:results": "NODE_ENV=test flashlight report .perf/results.json", "perf:measure": "NODE_ENV=test flashlight measure", - "intl:build": "yarn intl:check && yarn intl:compile", + "intl:build": "yarn intl:extract && yarn intl:compile", "intl:check": "yarn intl:extract && git diff-index -G'(^[^\\*# /])|(^#\\w)|(^\\s+[^\\*#/])' HEAD || (echo '\n⚠️ i18n detected un-extracted translations\n' && exit 1)", "intl:extract": "lingui extract", "intl:compile": "lingui compile", From 978bcc1ba9cb426c8da34a970a79a023936e3dbc Mon Sep 17 00:00:00 2001 From: Eric Bailey Date: Tue, 27 Feb 2024 16:04:49 -0600 Subject: [PATCH 15/43] Tags menu/muted words improvements (#3002) * Fix translations * Handle loooong words * Truncate on desktop web, revert mobile changes * Break the words * Small enough for mobile web * Fix alignment on mobile web * Clarify --- src/components/TagMenu/index.web.tsx | 17 +++++++++++---- src/components/dialogs/MutedWords.tsx | 16 ++++++++++++-- src/lib/strings/helpers.ts | 21 +++++++++++++++++-- src/view/com/util/forms/NativeDropdown.tsx | 3 ++- .../com/util/forms/NativeDropdown.web.tsx | 7 +++++-- 5 files changed, 53 insertions(+), 11 deletions(-) diff --git a/src/components/TagMenu/index.web.tsx b/src/components/TagMenu/index.web.tsx index 930e47a1..31187112 100644 --- a/src/components/TagMenu/index.web.tsx +++ b/src/components/TagMenu/index.web.tsx @@ -12,6 +12,8 @@ import { useUpsertMutedWordsMutation, useRemoveMutedWordMutation, } from '#/state/queries/preferences' +import {enforceLen} from '#/lib/strings/helpers' +import {web} from '#/alf' export function useTagMenuControl() {} @@ -40,11 +42,12 @@ export function TagMenu({ )) && !(optimisticRemove?.value === sanitizedTag), ) + const truncatedTag = enforceLen(tag, 15, true, 'middle') const dropdownItems = React.useMemo(() => { return [ { - label: _(msg`See ${tag} posts`), + label: _(msg`See ${truncatedTag} posts`), onPress() { navigation.navigate('Search', { q: tag, @@ -61,7 +64,7 @@ export function TagMenu({ }, authorHandle && !isInvalidHandle(authorHandle) && { - label: _(msg`See ${tag} posts by this user`), + label: _(msg`See ${truncatedTag} posts by user`), onPress() { navigation.navigate({ name: 'Search', @@ -83,7 +86,9 @@ export function TagMenu({ label: 'separator', }, preferences && { - label: isMuted ? _(msg`Unmute ${tag}`) : _(msg`Mute ${tag}`), + label: isMuted + ? _(msg`Unmute ${truncatedTag}`) + : _(msg`Mute ${truncatedTag}`), onPress() { if (isMuted) { removeMutedWord({value: sanitizedTag, targets: ['tag']}) @@ -108,6 +113,7 @@ export function TagMenu({ navigation, preferences, tag, + truncatedTag, sanitizedTag, upsertMutedWord, removeMutedWord, @@ -119,7 +125,10 @@ export function TagMenu({ accessibilityLabel={_(msg`Click here to open tag menu for ${tag}`)} accessibilityHint="" // @ts-ignore - items={dropdownItems}> + items={dropdownItems} + triggerStyle={web({ + textAlign: 'left', + })}> {children} diff --git a/src/components/dialogs/MutedWords.tsx b/src/components/dialogs/MutedWords.tsx index 138cc533..7c0d4fbc 100644 --- a/src/components/dialogs/MutedWords.tsx +++ b/src/components/dialogs/MutedWords.tsx @@ -10,7 +10,7 @@ import { useRemoveMutedWordMutation, } from '#/state/queries/preferences' import {isNative} from '#/platform/detection' -import {atoms as a, useTheme, useBreakpoints, ViewStyleProp} from '#/alf' +import {atoms as a, useTheme, useBreakpoints, ViewStyleProp, web} from '#/alf' import {Text} from '#/components/Typography' import {Button, ButtonIcon, ButtonText} from '#/components/Button' import {PlusLarge_Stroke2_Corner0_Rounded as Plus} from '#/components/icons/Plus' @@ -260,9 +260,21 @@ function MutedWordRow({ a.align_center, a.justify_between, a.rounded_md, + a.gap_md, style, ]}> - + {word.value} diff --git a/src/lib/strings/helpers.ts b/src/lib/strings/helpers.ts index e2abe901..de4562d2 100644 --- a/src/lib/strings/helpers.ts +++ b/src/lib/strings/helpers.ts @@ -8,10 +8,27 @@ export function pluralize(n: number, base: string, plural?: string): string { return base + 's' } -export function enforceLen(str: string, len: number, ellipsis = false): string { +export function enforceLen( + str: string, + len: number, + ellipsis = false, + mode: 'end' | 'middle' = 'end', +): string { str = str || '' if (str.length > len) { - return str.slice(0, len) + (ellipsis ? '...' : '') + if (ellipsis) { + if (mode === 'end') { + return str.slice(0, len) + '…' + } else if (mode === 'middle') { + const half = Math.floor(len / 2) + return str.slice(0, half) + '…' + str.slice(-half) + } else { + // fallback + return str.slice(0, len) + } + } else { + return str.slice(0, len) + } } return str } diff --git a/src/view/com/util/forms/NativeDropdown.tsx b/src/view/com/util/forms/NativeDropdown.tsx index 08228506..0a47569f 100644 --- a/src/view/com/util/forms/NativeDropdown.tsx +++ b/src/view/com/util/forms/NativeDropdown.tsx @@ -1,7 +1,7 @@ import React from 'react' import {FontAwesomeIcon} from '@fortawesome/react-native-fontawesome' import * as DropdownMenu from 'zeego/dropdown-menu' -import {Pressable, StyleSheet, Platform, View} from 'react-native' +import {Pressable, StyleSheet, Platform, View, ViewStyle} from 'react-native' import {IconProp} from '@fortawesome/fontawesome-svg-core' import {MenuItemCommonProps} from 'zeego/lib/typescript/menu' import {usePalette} from 'lib/hooks/usePalette' @@ -151,6 +151,7 @@ type Props = { testID?: string accessibilityLabel?: string accessibilityHint?: string + triggerStyle?: ViewStyle } /* The `NativeDropdown` function uses native iOS and Android dropdown menus. diff --git a/src/view/com/util/forms/NativeDropdown.web.tsx b/src/view/com/util/forms/NativeDropdown.web.tsx index 052e7ca1..6abeb16c 100644 --- a/src/view/com/util/forms/NativeDropdown.web.tsx +++ b/src/view/com/util/forms/NativeDropdown.web.tsx @@ -1,7 +1,7 @@ import React from 'react' import {FontAwesomeIcon} from '@fortawesome/react-native-fontawesome' import * as DropdownMenu from '@radix-ui/react-dropdown-menu' -import {Pressable, StyleSheet, View, Text} from 'react-native' +import {Pressable, StyleSheet, View, Text, ViewStyle} from 'react-native' import {IconProp} from '@fortawesome/fontawesome-svg-core' import {MenuItemCommonProps} from 'zeego/lib/typescript/menu' import {usePalette} from 'lib/hooks/usePalette' @@ -53,6 +53,7 @@ type Props = { testID?: string accessibilityLabel?: string accessibilityHint?: string + triggerStyle?: ViewStyle } export function NativeDropdown({ @@ -61,6 +62,7 @@ export function NativeDropdown({ testID, accessibilityLabel, accessibilityHint, + triggerStyle, }: React.PropsWithChildren) { const pal = usePalette('default') const theme = useTheme() @@ -120,7 +122,8 @@ export function NativeDropdown({ accessibilityLabel={accessibilityLabel} accessibilityHint={accessibilityHint} onPress={() => setOpen(o => !o)} - hitSlop={HITSLOP_10}> + hitSlop={HITSLOP_10} + style={triggerStyle}> {children} From ac726497a475f7492ee0269851979817b17d98c2 Mon Sep 17 00:00:00 2001 From: dan Date: Tue, 27 Feb 2024 22:55:25 +0000 Subject: [PATCH 16/43] Show tab bar on desktop web (#2998) * Show tabbar on desktop * Make bottom border always 1px * Don't hide/show navbar when switching tabs * two rows WIP * Top bar tweaks * Make scroll adjustement native-only * Add new web scroll behavior --- src/view/com/feeds/FeedPage.tsx | 70 +----------------- src/view/com/home/HomeHeader.tsx | 11 --- src/view/com/home/HomeHeaderLayout.web.tsx | 46 +++++++++++- src/view/com/home/HomeHeaderLayoutMobile.tsx | 1 - src/view/com/pager/TabBar.tsx | 78 ++++++++++++++++++-- src/view/com/util/MainScrollProvider.tsx | 16 +++- 6 files changed, 134 insertions(+), 88 deletions(-) diff --git a/src/view/com/feeds/FeedPage.tsx b/src/view/com/feeds/FeedPage.tsx index 2aacdb89..e6b5d1fb 100644 --- a/src/view/com/feeds/FeedPage.tsx +++ b/src/view/com/feeds/FeedPage.tsx @@ -1,30 +1,24 @@ import React from 'react' -import { - FontAwesomeIcon, - FontAwesomeIconStyle, -} from '@fortawesome/react-native-fontawesome' import {useNavigation} from '@react-navigation/native' import {useAnalytics} from 'lib/analytics/analytics' import {useQueryClient} from '@tanstack/react-query' import {RQKEY as FEED_RQKEY} from '#/state/queries/post-feed' import {MainScrollProvider} from '../util/MainScrollProvider' -import {usePalette} from 'lib/hooks/usePalette' import {useWebMediaQueries} from 'lib/hooks/useWebMediaQueries' import {useSetMinimalShellMode} from '#/state/shell' import {FeedDescriptor, FeedParams} from '#/state/queries/post-feed' import {ComposeIcon2} from 'lib/icons' -import {colors, s} from 'lib/styles' +import {s} from 'lib/styles' import {View, useWindowDimensions} from 'react-native' import {ListMethods} from '../util/List' import {Feed} from '../posts/Feed' -import {TextLink} from '../util/Link' import {FAB} from '../util/fab/FAB' import {LoadLatestBtn} from '../util/load-latest/LoadLatestBtn' import {msg} from '@lingui/macro' import {useLingui} from '@lingui/react' import {useSession} from '#/state/session' import {useComposerControls} from '#/state/shell/composer' -import {listenSoftReset, emitSoftReset} from '#/state/events' +import {listenSoftReset} from '#/state/events' import {truncateAndInvalidate} from '#/state/queries/util' import {TabState, getTabState, getRootNavigation} from '#/lib/routes/helpers' import {isNative} from '#/platform/detection' @@ -47,10 +41,8 @@ export function FeedPage({ renderEndOfFeed?: () => JSX.Element }) { const {hasSession} = useSession() - const pal = usePalette('default') const {_} = useLingui() const navigation = useNavigation() - const {isDesktop} = useWebMediaQueries() const queryClient = useQueryClient() const {openComposer} = useComposerControls() const [isScrolledDown, setIsScrolledDown] = React.useState(false) @@ -99,63 +91,6 @@ export function FeedPage({ setHasNew(false) }, [scrollToTop, feed, queryClient, setHasNew]) - const ListHeaderComponent = React.useCallback(() => { - if (isDesktop) { - return ( - - - Bluesky{' '} - {hasNew && ( - - )} - - } - onPress={emitSoftReset} - /> - {hasSession && ( - - } - /> - )} - - ) - } - return <> - }, [isDesktop, pal.view, pal.text, pal.textLight, hasNew, _, hasSession]) - return ( @@ -171,7 +106,6 @@ export function FeedPage({ onHasNew={setHasNew} renderEmptyState={renderEmptyState} renderEndOfFeed={renderEndOfFeed} - ListHeaderComponent={ListHeaderComponent} headerOffset={headerOffset} /> diff --git a/src/view/com/home/HomeHeader.tsx b/src/view/com/home/HomeHeader.tsx index 5ffa31f3..3df3858b 100644 --- a/src/view/com/home/HomeHeader.tsx +++ b/src/view/com/home/HomeHeader.tsx @@ -1,7 +1,6 @@ import React from 'react' import {RenderTabBarFnProps} from 'view/com/pager/Pager' import {HomeHeaderLayout} from './HomeHeaderLayout' -import {useWebMediaQueries} from 'lib/hooks/useWebMediaQueries' import {usePinnedFeedsInfos} from '#/state/queries/feed' import {useNavigation} from '@react-navigation/native' import {NavigationProp} from 'lib/routes/types' @@ -11,16 +10,6 @@ import {usePalette} from '#/lib/hooks/usePalette' export function HomeHeader( props: RenderTabBarFnProps & {testID?: string; onPressSelected: () => void}, -) { - const {isDesktop} = useWebMediaQueries() - if (isDesktop) { - return null - } - return -} - -export function HomeHeaderInner( - props: RenderTabBarFnProps & {testID?: string; onPressSelected: () => void}, ) { const navigation = useNavigation() const {feeds, hasPinnedCustom} = usePinnedFeedsInfos() diff --git a/src/view/com/home/HomeHeaderLayout.web.tsx b/src/view/com/home/HomeHeaderLayout.web.tsx index 47cb0023..fbb55e6b 100644 --- a/src/view/com/home/HomeHeaderLayout.web.tsx +++ b/src/view/com/home/HomeHeaderLayout.web.tsx @@ -1,11 +1,20 @@ import React from 'react' -import {StyleSheet} from 'react-native' +import {StyleSheet, View} from 'react-native' import Animated from 'react-native-reanimated' import {usePalette} from 'lib/hooks/usePalette' import {useWebMediaQueries} from 'lib/hooks/useWebMediaQueries' import {HomeHeaderLayoutMobile} from './HomeHeaderLayoutMobile' import {useMinimalShellMode} from 'lib/hooks/useMinimalShellMode' import {useShellLayout} from '#/state/shell/shell-layout' +import {Logo} from '#/view/icons/Logo' +import {Link, TextLink} from '../util/Link' +import { + FontAwesomeIcon, + FontAwesomeIconStyle, +} from '@fortawesome/react-native-fontawesome' +import {useLingui} from '@lingui/react' +import {msg} from '@lingui/macro' +import {CogIcon} from '#/lib/icons' export function HomeHeaderLayout({children}: {children: React.ReactNode}) { const {isMobile} = useWebMediaQueries() @@ -20,6 +29,7 @@ function HomeHeaderLayoutTablet({children}: {children: React.ReactNode}) { const pal = usePalette('default') const {headerMinimalShellTransform} = useMinimalShellMode() const {headerHeight} = useShellLayout() + const {_} = useLingui() return ( // @ts-ignore the type signature for transform wrong here, translateX and translateY need to be in separate objects -prf @@ -28,12 +38,44 @@ function HomeHeaderLayoutTablet({children}: {children: React.ReactNode}) { onLayout={e => { headerHeight.value = e.nativeEvent.layout.height }}> + + + } + /> + + + + + {children} ) } const styles = StyleSheet.create({ + topBar: { + flexDirection: 'row', + justifyContent: 'space-between', + alignItems: 'center', + paddingHorizontal: 18, + paddingVertical: 8, + marginTop: 8, + width: '100%', + }, tabBar: { // @ts-ignore Web only position: 'sticky', @@ -42,7 +84,7 @@ const styles = StyleSheet.create({ left: 'calc(50% - 300px)', width: 600, top: 0, - flexDirection: 'row', + flexDirection: 'column', alignItems: 'center', borderLeftWidth: 1, borderRightWidth: 1, diff --git a/src/view/com/home/HomeHeaderLayoutMobile.tsx b/src/view/com/home/HomeHeaderLayoutMobile.tsx index 6c4b911f..f51efb7b 100644 --- a/src/view/com/home/HomeHeaderLayoutMobile.tsx +++ b/src/view/com/home/HomeHeaderLayoutMobile.tsx @@ -103,7 +103,6 @@ const styles = StyleSheet.create({ right: 0, top: 0, flexDirection: 'column', - borderBottomWidth: 1, }, topBar: { flexDirection: 'row', diff --git a/src/view/com/pager/TabBar.tsx b/src/view/com/pager/TabBar.tsx index 3204bb23..ff8acd60 100644 --- a/src/view/com/pager/TabBar.tsx +++ b/src/view/com/pager/TabBar.tsx @@ -5,6 +5,7 @@ import {PressableWithHover} from '../util/PressableWithHover' import {usePalette} from 'lib/hooks/usePalette' import {useWebMediaQueries} from 'lib/hooks/useWebMediaQueries' import {DraggableScrollView} from './DraggableScrollView' +import {isNative} from '#/platform/detection' export interface TabBarProps { testID?: string @@ -15,6 +16,10 @@ export interface TabBarProps { onPressSelected?: (index: number) => void } +// How much of the previous/next item we're showing +// to give the user a hint there's more to scroll. +const OFFSCREEN_ITEM_WIDTH = 20 + export function TabBar({ testID, selectedPage, @@ -25,6 +30,7 @@ export function TabBar({ }: TabBarProps) { const pal = usePalette('default') const scrollElRef = useRef(null) + const itemRefs = useRef>([]) const [itemXs, setItemXs] = useState([]) const indicatorStyle = useMemo( () => ({borderBottomColor: indicatorColor || pal.colors.link}), @@ -33,12 +39,58 @@ export function TabBar({ const {isDesktop, isTablet} = useWebMediaQueries() const styles = isDesktop || isTablet ? desktopStyles : mobileStyles - // scrolls to the selected item when the page changes useEffect(() => { - scrollElRef.current?.scrollTo({ - x: - (itemXs[selectedPage] || 0) - styles.contentContainer.paddingHorizontal, - }) + if (isNative) { + // On native, the primary interaction is swiping. + // We adjust the scroll little by little on every tab change. + // Scroll into view but keep the end of the previous item visible. + let x = itemXs[selectedPage] || 0 + x = Math.max(0, x - OFFSCREEN_ITEM_WIDTH) + scrollElRef.current?.scrollTo({x}) + } else { + // On the web, the primary interaction is tapping. + // Scrolling under tap feels disorienting so only adjust the scroll offset + // when tapping on an item out of view--and we adjust by almost an entire page. + const parent = scrollElRef?.current?.getScrollableNode?.() + if (!parent) { + return + } + const parentRect = parent.getBoundingClientRect() + if (!parentRect) { + return + } + const { + left: parentLeft, + right: parentRight, + width: parentWidth, + } = parentRect + const child = itemRefs.current[selectedPage] + if (!child) { + return + } + const childRect = child.getBoundingClientRect?.() + if (!childRect) { + return + } + const {left: childLeft, right: childRight, width: childWidth} = childRect + let dx = 0 + if (childRight >= parentRight) { + dx += childRight - parentRight + dx += parentWidth - childWidth - OFFSCREEN_ITEM_WIDTH + } else if (childLeft <= parentLeft) { + dx -= parentLeft - childLeft + dx -= parentWidth - childWidth - OFFSCREEN_ITEM_WIDTH + } + let x = parent.scrollLeft + dx + x = Math.max(0, x) + x = Math.min(x, parent.scrollWidth - parentWidth) + if (dx !== 0) { + parent.scroll({ + left: x, + behavior: 'smooth', + }) + } + } }, [scrollElRef, itemXs, selectedPage, styles]) const onPressItem = useCallback( @@ -78,6 +130,7 @@ export function TabBar({ (itemRefs.current[i] = node)} onLayout={e => onItemLayout(e, i)} style={styles.item} hoverStyle={pal.viewLight} @@ -94,6 +147,7 @@ export function TabBar({ ) })} + ) } @@ -117,6 +171,13 @@ const desktopStyles = StyleSheet.create({ borderBottomWidth: 3, borderBottomColor: 'transparent', }, + outerBottomBorder: { + position: 'absolute', + left: 0, + right: 0, + bottom: -1, + borderBottomWidth: 1, + }, }) const mobileStyles = StyleSheet.create({ @@ -137,4 +198,11 @@ const mobileStyles = StyleSheet.create({ borderBottomWidth: 3, borderBottomColor: 'transparent', }, + outerBottomBorder: { + position: 'absolute', + left: 0, + right: 0, + bottom: -1, + borderBottomWidth: 1, + }, }) diff --git a/src/view/com/util/MainScrollProvider.tsx b/src/view/com/util/MainScrollProvider.tsx index 2c90e33f..01b8a954 100644 --- a/src/view/com/util/MainScrollProvider.tsx +++ b/src/view/com/util/MainScrollProvider.tsx @@ -20,12 +20,14 @@ export function MainScrollProvider({children}: {children: React.ReactNode}) { const setMode = useSetMinimalShellMode() const startDragOffset = useSharedValue(null) const startMode = useSharedValue(null) + const didJustRestoreScroll = useSharedValue(false) useEffect(() => { if (isWeb) { return listenToForcedWindowScroll(() => { startDragOffset.value = null startMode.value = null + didJustRestoreScroll.value = true }) } }) @@ -86,6 +88,11 @@ export function MainScrollProvider({children}: {children: React.ReactNode}) { mode.value = newValue } } else { + if (didJustRestoreScroll.value) { + didJustRestoreScroll.value = false + // Don't hide/show navbar based on scroll restoratoin. + return + } // On the web, we don't try to follow the drag because we don't know when it ends. // Instead, show/hide immediately based on whether we're scrolling up or down. const dy = e.contentOffset.y - (startDragOffset.value ?? 0) @@ -98,7 +105,14 @@ export function MainScrollProvider({children}: {children: React.ReactNode}) { } } }, - [headerHeight, mode, setMode, startDragOffset, startMode], + [ + headerHeight, + mode, + setMode, + startDragOffset, + startMode, + didJustRestoreScroll, + ], ) return ( From d451f82f54974b7b3da1477a7e1f221628860f62 Mon Sep 17 00:00:00 2001 From: Hailey Date: Tue, 27 Feb 2024 15:22:03 -0800 Subject: [PATCH 17/43] Share Extension/Intents (#2587) * add native ios code outside of ios project * helper script * going to be a lot of these commits to squash...backing up * save * start of an expo plugin * create info.plist * copy the view controller * maybe working * working * wait working now * working plugin * use current scheme * update intent path * use better params * support text in uri * build * use better encoding * handle images * cleanup ios plugin * android * move bash script to /scripts * handle cases where loaded data is uiimage rather than uri * remove unnecessary logic, allow more than 4 images and just take first 4 * android build plugin * limit images to four on android * use js for plugins, no need to build * revert changes to app config * use correct scheme on android * android readme * move ios extension to /modules * remove unnecessary event * revert typo * plugin readme * scripts readme * add configurable scheme to .env, default to `bluesky` * remove debug * revert .gitignore change * add comment about updating .env to app.config.js for those modifying scheme * modify .env * update android module to use the proper url * update ios extension * remove comment * parse and validate incoming image uris * fix types * rm oops * fix a few typos --- app.config.js | 1 + modules/Share-with-Bluesky/Info.plist | 41 +++++ .../Share-with-Bluesky.entitlements | 10 ++ .../ShareViewController.swift | 153 ++++++++++++++++++ .../expo-receive-android-intents/README.md | 8 + .../android/.gitignore | 15 ++ .../android/build.gradle | 92 +++++++++++ .../android/src/main/AndroidManifest.xml | 2 + .../ExpoReceiveAndroidIntentsModule.kt | 119 ++++++++++++++ .../expo-module.config.json | 6 + package.json | 3 +- plugins/shareExtension/README.md | 22 +++ plugins/shareExtension/withAppEntitlements.js | 13 ++ .../withExtensionEntitlements.js | 33 ++++ .../shareExtension/withExtensionInfoPlist.js | 39 +++++ .../withExtensionViewController.js | 31 ++++ plugins/shareExtension/withIntentFilters.js | 89 ++++++++++ plugins/shareExtension/withShareExtensions.js | 47 ++++++ plugins/shareExtension/withXcodeTarget.js | 55 +++++++ scripts/README.md | 5 + scripts/updateExtensions.sh | 10 ++ src/lib/hooks/useIntentHandler.ts | 35 +++- src/state/models/media/gallery.ts | 25 ++- src/state/shell/composer.tsx | 2 + src/view/com/composer/Composer.tsx | 11 +- src/view/shell/Composer.tsx | 2 + src/view/shell/Composer.web.tsx | 3 +- 27 files changed, 860 insertions(+), 12 deletions(-) create mode 100644 modules/Share-with-Bluesky/Info.plist create mode 100644 modules/Share-with-Bluesky/Share-with-Bluesky.entitlements create mode 100644 modules/Share-with-Bluesky/ShareViewController.swift create mode 100644 modules/expo-receive-android-intents/README.md create mode 100644 modules/expo-receive-android-intents/android/.gitignore create mode 100644 modules/expo-receive-android-intents/android/build.gradle create mode 100644 modules/expo-receive-android-intents/android/src/main/AndroidManifest.xml create mode 100644 modules/expo-receive-android-intents/android/src/main/java/xyz/blueskyweb/app/exporeceiveandroidintents/ExpoReceiveAndroidIntentsModule.kt create mode 100644 modules/expo-receive-android-intents/expo-module.config.json create mode 100644 plugins/shareExtension/README.md create mode 100644 plugins/shareExtension/withAppEntitlements.js create mode 100644 plugins/shareExtension/withExtensionEntitlements.js create mode 100644 plugins/shareExtension/withExtensionInfoPlist.js create mode 100644 plugins/shareExtension/withExtensionViewController.js create mode 100644 plugins/shareExtension/withIntentFilters.js create mode 100644 plugins/shareExtension/withShareExtensions.js create mode 100644 plugins/shareExtension/withXcodeTarget.js create mode 100644 scripts/README.md create mode 100755 scripts/updateExtensions.sh diff --git a/app.config.js b/app.config.js index 5bbe864a..fa9735dc 100644 --- a/app.config.js +++ b/app.config.js @@ -141,6 +141,7 @@ module.exports = function (config) { }, ], './plugins/withAndroidManifestPlugin.js', + './plugins/shareExtension/withShareExtensions.js', ].filter(Boolean), extra: { eas: { diff --git a/modules/Share-with-Bluesky/Info.plist b/modules/Share-with-Bluesky/Info.plist new file mode 100644 index 00000000..90fe9234 --- /dev/null +++ b/modules/Share-with-Bluesky/Info.plist @@ -0,0 +1,41 @@ + + + + + NSExtension + + NSExtensionPrincipalClass + $(PRODUCT_MODULE_NAME).ShareViewController + NSExtensionAttributes + + NSExtensionActivationRule + + NSExtensionActivationSupportsText + + NSExtensionActivationSupportsWebURLWithMaxCount + 1 + NSExtensionActivationSupportsImageWithMaxCount + 10 + + + NSExtensionPointIdentifier + com.apple.share-services + + MainAppScheme + bluesky + CFBundleName + $(PRODUCT_NAME) + CFBundleDisplayName + Extension + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleVersion + $(CURRENT_PROJECT_VERSION) + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundlePackageType + $(PRODUCT_BUNDLE_PACKAGE_TYPE) + CFBundleShortVersionString + $(MARKETING_VERSION) + + diff --git a/modules/Share-with-Bluesky/Share-with-Bluesky.entitlements b/modules/Share-with-Bluesky/Share-with-Bluesky.entitlements new file mode 100644 index 00000000..22ca9157 --- /dev/null +++ b/modules/Share-with-Bluesky/Share-with-Bluesky.entitlements @@ -0,0 +1,10 @@ + + + + + com.apple.security.application-groups + + group.xyz.blueskyweb.app + + + diff --git a/modules/Share-with-Bluesky/ShareViewController.swift b/modules/Share-with-Bluesky/ShareViewController.swift new file mode 100644 index 00000000..a16a290b --- /dev/null +++ b/modules/Share-with-Bluesky/ShareViewController.swift @@ -0,0 +1,153 @@ +import UIKit + +class ShareViewController: UIViewController { + // This allows other forks to use this extension while also changing their + // scheme. + let appScheme = Bundle.main.object(forInfoDictionaryKey: "MainAppScheme") as? String ?? "bluesky" + + // + override func viewDidAppear(_ animated: Bool) { + super.viewDidAppear(animated) + + guard let extensionItem = extensionContext?.inputItems.first as? NSExtensionItem, + let attachments = extensionItem.attachments, + let firstAttachment = extensionItem.attachments?.first + else { + self.completeRequest() + return + } + + Task { + if firstAttachment.hasItemConformingToTypeIdentifier("public.text") { + await self.handleText(item: firstAttachment) + } else if firstAttachment.hasItemConformingToTypeIdentifier("public.url") { + await self.handleUrl(item: firstAttachment) + } else if firstAttachment.hasItemConformingToTypeIdentifier("public.image") { + await self.handleImages(items: attachments) + } else { + self.completeRequest() + } + } + } + + private func handleText(item: NSItemProvider) async -> Void { + do { + if let data = try await item.loadItem(forTypeIdentifier: "public.text") as? String { + if let encoded = data.addingPercentEncoding(withAllowedCharacters: .urlHostAllowed), + let url = URL(string: "\(self.appScheme)://intent/compose?text=\(encoded)") + { + _ = self.openURL(url) + } + } + self.completeRequest() + } catch { + self.completeRequest() + } + } + + private func handleUrl(item: NSItemProvider) async -> Void { + do { + if let data = try await item.loadItem(forTypeIdentifier: "public.url") as? URL { + if let encoded = data.absoluteString.addingPercentEncoding(withAllowedCharacters: .urlHostAllowed), + let url = URL(string: "\(self.appScheme)://intent/compose?text=\(encoded)") + { + _ = self.openURL(url) + } + } + self.completeRequest() + } catch { + self.completeRequest() + } + } + + private func handleImages(items: [NSItemProvider]) async -> Void { + let firstFourItems: [NSItemProvider] + if items.count < 4 { + firstFourItems = items + } else { + firstFourItems = Array(items[0...3]) + } + + var valid = true + var imageUris = "" + + for (index, item) in firstFourItems.enumerated() { + var imageUriInfo: String? = nil + + do { + if let dataUri = try await item.loadItem(forTypeIdentifier: "public.image") as? URL { + // We need to duplicate this image, since we don't have access to the outgoing temp directory + // We also will get the image dimensions here, sinze RN makes it difficult to get those dimensions for local files + let data = try Data(contentsOf: dataUri) + let image = UIImage(data: data) + imageUriInfo = self.saveImageWithInfo(image) + } else if let image = try await item.loadItem(forTypeIdentifier: "public.image") as? UIImage { + imageUriInfo = self.saveImageWithInfo(image) + } + } catch { + valid = false + } + + if let imageUriInfo = imageUriInfo { + imageUris.append(imageUriInfo) + if index < items.count - 1 { + imageUris.append(",") + } + } else { + valid = false + } + } + + if valid, + let encoded = imageUris.addingPercentEncoding(withAllowedCharacters: .urlHostAllowed), + let url = URL(string: "\(self.appScheme)://intent/compose?imageUris=\(encoded)") + { + _ = self.openURL(url) + } + + self.completeRequest() + } + + private func saveImageWithInfo(_ image: UIImage?) -> String? { + guard let image = image else { + return nil + } + + do { + // Saving this file to the bundle group's directory lets us access it from + // inside of the app. Otherwise, we wouldn't have access even though the + // extension does. + if let dir = FileManager() + .containerURL( + forSecurityApplicationGroupIdentifier: "group.\(Bundle.main.bundleIdentifier?.replacingOccurrences(of: ".Share-with-Bluesky", with: "") ?? "")") + { + let filePath = "\(dir.absoluteString)\(ProcessInfo.processInfo.globallyUniqueString).jpeg" + + if let newUri = URL(string: filePath), + let jpegData = image.jpegData(compressionQuality: 1) + { + try jpegData.write(to: newUri) + return "\(newUri.absoluteString)|\(image.size.width)|\(image.size.height)" + } + } + return nil + } catch { + return nil + } + } + + private func completeRequest() -> Void { + self.extensionContext?.completeRequest(returningItems: nil) + } + + @objc func openURL(_ url: URL) -> Bool { + var responder: UIResponder? = self + while responder != nil { + if let application = responder as? UIApplication { + return application.perform(#selector(openURL(_:)), with: url) != nil + } + responder = responder?.next + } + return false + } +} diff --git a/modules/expo-receive-android-intents/README.md b/modules/expo-receive-android-intents/README.md new file mode 100644 index 00000000..7e850686 --- /dev/null +++ b/modules/expo-receive-android-intents/README.md @@ -0,0 +1,8 @@ +# Expo Receive Android Intents + +This module handles incoming intents on Android. Handled intents are `text/plain` and `image/*` (single or multiple). +The module handles saving images to the app's filesystem for access within the app, limiting the selection of images +to a max of four, and handling intent types. No JS code is required for this module, and it is no-op on non-android +platforms. + +No installation is required. Gradle will automatically add this module on build. diff --git a/modules/expo-receive-android-intents/android/.gitignore b/modules/expo-receive-android-intents/android/.gitignore new file mode 100644 index 00000000..877b87e9 --- /dev/null +++ b/modules/expo-receive-android-intents/android/.gitignore @@ -0,0 +1,15 @@ +# OSX +# +.DS_Store + +# Android/IntelliJ +# +build/ +.idea +.gradle +local.properties +*.iml +*.hprof + +# Bundle artifacts +*.jsbundle diff --git a/modules/expo-receive-android-intents/android/build.gradle b/modules/expo-receive-android-intents/android/build.gradle new file mode 100644 index 00000000..3712dda4 --- /dev/null +++ b/modules/expo-receive-android-intents/android/build.gradle @@ -0,0 +1,92 @@ +apply plugin: 'com.android.library' +apply plugin: 'kotlin-android' +apply plugin: 'maven-publish' + +group = 'xyz.blueskyweb.app.exporeceiveandroidintents' +version = '0.4.1' + +buildscript { + def expoModulesCorePlugin = new File(project(":expo-modules-core").projectDir.absolutePath, "ExpoModulesCorePlugin.gradle") + if (expoModulesCorePlugin.exists()) { + apply from: expoModulesCorePlugin + applyKotlinExpoModulesCorePlugin() + } + + // Simple helper that allows the root project to override versions declared by this library. + ext.safeExtGet = { prop, fallback -> + rootProject.ext.has(prop) ? rootProject.ext.get(prop) : fallback + } + + // Ensures backward compatibility + ext.getKotlinVersion = { + if (ext.has("kotlinVersion")) { + ext.kotlinVersion() + } else { + ext.safeExtGet("kotlinVersion", "1.8.10") + } + } + + repositories { + mavenCentral() + } + + dependencies { + classpath("org.jetbrains.kotlin:kotlin-gradle-plugin:${getKotlinVersion()}") + } +} + +afterEvaluate { + publishing { + publications { + release(MavenPublication) { + from components.release + } + } + repositories { + maven { + url = mavenLocal().url + } + } + } +} + +android { + compileSdkVersion safeExtGet("compileSdkVersion", 33) + + def agpVersion = com.android.Version.ANDROID_GRADLE_PLUGIN_VERSION + if (agpVersion.tokenize('.')[0].toInteger() < 8) { + compileOptions { + sourceCompatibility JavaVersion.VERSION_11 + targetCompatibility JavaVersion.VERSION_11 + } + + kotlinOptions { + jvmTarget = JavaVersion.VERSION_11.majorVersion + } + } + + namespace "xyz.blueskyweb.app.exporeceiveandroidintents" + defaultConfig { + minSdkVersion safeExtGet("minSdkVersion", 21) + targetSdkVersion safeExtGet("targetSdkVersion", 34) + versionCode 1 + versionName "0.4.1" + } + lintOptions { + abortOnError false + } + publishing { + singleVariant("release") { + withSourcesJar() + } + } +} + +repositories { + mavenCentral() +} + +dependencies { + implementation project(':expo-modules-core') + implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:${getKotlinVersion()}" +} diff --git a/modules/expo-receive-android-intents/android/src/main/AndroidManifest.xml b/modules/expo-receive-android-intents/android/src/main/AndroidManifest.xml new file mode 100644 index 00000000..bdae66c8 --- /dev/null +++ b/modules/expo-receive-android-intents/android/src/main/AndroidManifest.xml @@ -0,0 +1,2 @@ + + diff --git a/modules/expo-receive-android-intents/android/src/main/java/xyz/blueskyweb/app/exporeceiveandroidintents/ExpoReceiveAndroidIntentsModule.kt b/modules/expo-receive-android-intents/android/src/main/java/xyz/blueskyweb/app/exporeceiveandroidintents/ExpoReceiveAndroidIntentsModule.kt new file mode 100644 index 00000000..c2e17fb8 --- /dev/null +++ b/modules/expo-receive-android-intents/android/src/main/java/xyz/blueskyweb/app/exporeceiveandroidintents/ExpoReceiveAndroidIntentsModule.kt @@ -0,0 +1,119 @@ +package xyz.blueskyweb.app.exporeceiveandroidintents + +import android.content.Intent +import android.graphics.Bitmap +import android.net.Uri +import android.os.Build +import android.provider.MediaStore +import androidx.core.net.toUri +import expo.modules.kotlin.modules.Module +import expo.modules.kotlin.modules.ModuleDefinition +import java.io.File +import java.io.FileOutputStream +import java.net.URLEncoder + +class ExpoReceiveAndroidIntentsModule : Module() { + override fun definition() = ModuleDefinition { + Name("ExpoReceiveAndroidIntents") + + OnNewIntent { + handleIntent(it) + } + } + + private fun handleIntent(intent: Intent?) { + if(appContext.currentActivity == null || intent == null) return + + if (intent.action == Intent.ACTION_SEND) { + if (intent.type == "text/plain") { + handleTextIntent(intent) + } else if (intent.type.toString().startsWith("image/")) { + handleImageIntent(intent) + } + } else if (intent.action == Intent.ACTION_SEND_MULTIPLE) { + if (intent.type.toString().startsWith("image/")) { + handleImagesIntent(intent) + } + } + } + + private fun handleTextIntent(intent: Intent) { + intent.getStringExtra(Intent.EXTRA_TEXT)?.let { + val encoded = URLEncoder.encode(it, "UTF-8") + "bluesky://intent/compose?text=${encoded}".toUri().let { uri -> + val newIntent = Intent(Intent.ACTION_VIEW, uri) + appContext.currentActivity?.startActivity(newIntent) + } + } + } + + private fun handleImageIntent(intent: Intent) { + val uri = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) { + intent.getParcelableExtra(Intent.EXTRA_STREAM, Uri::class.java) + } else { + intent.getParcelableExtra(Intent.EXTRA_STREAM) + } + if (uri == null) return + + handleImageIntents(listOf(uri)) + } + + private fun handleImagesIntent(intent: Intent) { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) { + intent.getParcelableArrayListExtra(Intent.EXTRA_STREAM, Uri::class.java)?.let { + handleImageIntents(it.filterIsInstance().take(4)) + } + } else { + intent.getParcelableArrayListExtra(Intent.EXTRA_STREAM)?.let { + handleImageIntents(it.filterIsInstance().take(4)) + } + } + } + + private fun handleImageIntents(uris: List) { + var allParams = "" + + uris.forEachIndexed { index, uri -> + val info = getImageInfo(uri) + val params = buildUriData(info) + allParams = "${allParams}${params}" + + if (index < uris.count() - 1) { + allParams = "${allParams}," + } + } + + val encoded = URLEncoder.encode(allParams, "UTF-8") + + "bluesky://intent/compose?imageUris=${encoded}".toUri().let { + val newIntent = Intent(Intent.ACTION_VIEW, it) + appContext.currentActivity?.startActivity(newIntent) + } + } + + private fun getImageInfo(uri: Uri): Map { + val bitmap = MediaStore.Images.Media.getBitmap(appContext.currentActivity?.contentResolver, uri) + // We have to save this so that we can access it later when uploading the image. + // createTempFile will automatically place a unique string between "img" and "temp.jpeg" + val file = File.createTempFile("img", "temp.jpeg", appContext.currentActivity?.cacheDir) + val out = FileOutputStream(file) + bitmap.compress(Bitmap.CompressFormat.JPEG, 100, out) + out.flush() + out.close() + + return mapOf( + "width" to bitmap.width, + "height" to bitmap.height, + "path" to file.path.toString() + ) + } + + // We will pas the width and height to the app here, since getting measurements + // on the RN side is a bit more involved, and we already have them here anyway. + private fun buildUriData(info: Map): String { + val path = info.getValue("path") + val width = info.getValue("width") + val height = info.getValue("height") + return "file://${path}|${width}|${height}" + } +} diff --git a/modules/expo-receive-android-intents/expo-module.config.json b/modules/expo-receive-android-intents/expo-module.config.json new file mode 100644 index 00000000..8f01fb6c --- /dev/null +++ b/modules/expo-receive-android-intents/expo-module.config.json @@ -0,0 +1,6 @@ +{ + "platforms": ["android"], + "android": { + "modules": ["xyz.blueskyweb.app.exporeceiveandroidintents.ExpoReceiveAndroidIntentsModule"] + } +} diff --git a/package.json b/package.json index 2d520b4b..e9dd9202 100644 --- a/package.json +++ b/package.json @@ -40,7 +40,8 @@ "intl:check": "yarn intl:extract && git diff-index -G'(^[^\\*# /])|(^#\\w)|(^\\s+[^\\*#/])' HEAD || (echo '\n⚠️ i18n detected un-extracted translations\n' && exit 1)", "intl:extract": "lingui extract", "intl:compile": "lingui compile", - "nuke": "rm -rf ./node_modules && rm -rf ./ios && rm -rf ./android" + "nuke": "rm -rf ./node_modules && rm -rf ./ios && rm -rf ./android", + "update-extensions": "scripts/updateExtensions.sh" }, "dependencies": { "@atproto/api": "^0.10.0", diff --git a/plugins/shareExtension/README.md b/plugins/shareExtension/README.md new file mode 100644 index 00000000..2b57e624 --- /dev/null +++ b/plugins/shareExtension/README.md @@ -0,0 +1,22 @@ +# Share extension plugin for Expo + +This plugin handles moving the necessary files into their respective iOS and Android targets and updating the build +phases, plists, manifests, etc. + +## Steps + +### ios + +1. Update entitlements +2. Set the app group to group. +3. Add the extension plist +4. Add the view controller +5. Update the xcode project's build phases + +### android + +1. Update the manifest with the intents the app can receive + +## Credits + +Adapted from https://github.com/andrew-levy/react-native-safari-extension and https://github.com/timedtext/expo-config-plugin-ios-share-extension/blob/master/src/withShareExtensionXcodeTarget.ts diff --git a/plugins/shareExtension/withAppEntitlements.js b/plugins/shareExtension/withAppEntitlements.js new file mode 100644 index 00000000..6f9136c3 --- /dev/null +++ b/plugins/shareExtension/withAppEntitlements.js @@ -0,0 +1,13 @@ +const {withEntitlementsPlist} = require('@expo/config-plugins') + +const withAppEntitlements = config => { + // eslint-disable-next-line no-shadow + return withEntitlementsPlist(config, async config => { + config.modResults['com.apple.security.application-groups'] = [ + `group.${config.ios.bundleIdentifier}`, + ] + return config + }) +} + +module.exports = {withAppEntitlements} diff --git a/plugins/shareExtension/withExtensionEntitlements.js b/plugins/shareExtension/withExtensionEntitlements.js new file mode 100644 index 00000000..e6bbf9d2 --- /dev/null +++ b/plugins/shareExtension/withExtensionEntitlements.js @@ -0,0 +1,33 @@ +const {withInfoPlist} = require('@expo/config-plugins') +const plist = require('@expo/plist') +const path = require('path') +const fs = require('fs') + +const withExtensionEntitlements = (config, {extensionName}) => { + // eslint-disable-next-line no-shadow + return withInfoPlist(config, config => { + const extensionEntitlementsPath = path.join( + config.modRequest.platformProjectRoot, + extensionName, + `${extensionName}.entitlements`, + ) + + const shareExtensionEntitlements = { + 'com.apple.security.application-groups': [ + `group.${config.ios?.bundleIdentifier}`, + ], + } + + fs.mkdirSync(path.dirname(extensionEntitlementsPath), { + recursive: true, + }) + fs.writeFileSync( + extensionEntitlementsPath, + plist.default.build(shareExtensionEntitlements), + ) + + return config + }) +} + +module.exports = {withExtensionEntitlements} diff --git a/plugins/shareExtension/withExtensionInfoPlist.js b/plugins/shareExtension/withExtensionInfoPlist.js new file mode 100644 index 00000000..9afc4d5f --- /dev/null +++ b/plugins/shareExtension/withExtensionInfoPlist.js @@ -0,0 +1,39 @@ +const {withInfoPlist} = require('@expo/config-plugins') +const plist = require('@expo/plist') +const path = require('path') +const fs = require('fs') + +const withExtensionInfoPlist = (config, {extensionName}) => { + // eslint-disable-next-line no-shadow + return withInfoPlist(config, config => { + const plistPath = path.join( + config.modRequest.projectRoot, + 'modules', + extensionName, + 'Info.plist', + ) + const targetPath = path.join( + config.modRequest.platformProjectRoot, + extensionName, + 'Info.plist', + ) + + const extPlist = plist.default.parse(fs.readFileSync(plistPath).toString()) + + extPlist.MainAppScheme = config.scheme + extPlist.CFBundleName = '$(PRODUCT_NAME)' + extPlist.CFBundleDisplayName = 'Extension' + extPlist.CFBundleIdentifier = '$(PRODUCT_BUNDLE_IDENTIFIER)' + extPlist.CFBundleVersion = '$(CURRENT_PROJECT_VERSION)' + extPlist.CFBundleExecutable = '$(EXECUTABLE_NAME)' + extPlist.CFBundlePackageType = '$(PRODUCT_BUNDLE_PACKAGE_TYPE)' + extPlist.CFBundleShortVersionString = '$(MARKETING_VERSION)' + + fs.mkdirSync(path.dirname(targetPath), {recursive: true}) + fs.writeFileSync(targetPath, plist.default.build(extPlist)) + + return config + }) +} + +module.exports = {withExtensionInfoPlist} diff --git a/plugins/shareExtension/withExtensionViewController.js b/plugins/shareExtension/withExtensionViewController.js new file mode 100644 index 00000000..cd29bea7 --- /dev/null +++ b/plugins/shareExtension/withExtensionViewController.js @@ -0,0 +1,31 @@ +const {withXcodeProject} = require('@expo/config-plugins') +const path = require('path') +const fs = require('fs') + +const withExtensionViewController = ( + config, + {controllerName, extensionName}, +) => { + // eslint-disable-next-line no-shadow + return withXcodeProject(config, config => { + const controllerPath = path.join( + config.modRequest.projectRoot, + 'modules', + extensionName, + `${controllerName}.swift`, + ) + + const targetPath = path.join( + config.modRequest.platformProjectRoot, + extensionName, + `${controllerName}.swift`, + ) + + fs.mkdirSync(path.dirname(targetPath), {recursive: true}) + fs.copyFileSync(controllerPath, targetPath) + + return config + }) +} + +module.exports = {withExtensionViewController} diff --git a/plugins/shareExtension/withIntentFilters.js b/plugins/shareExtension/withIntentFilters.js new file mode 100644 index 00000000..605fcfd0 --- /dev/null +++ b/plugins/shareExtension/withIntentFilters.js @@ -0,0 +1,89 @@ +const {withAndroidManifest} = require('@expo/config-plugins') + +const withIntentFilters = config => { + // eslint-disable-next-line no-shadow + return withAndroidManifest(config, config => { + const intents = [ + { + action: [ + { + $: { + 'android:name': 'android.intent.action.SEND', + }, + }, + ], + category: [ + { + $: { + 'android:name': 'android.intent.category.DEFAULT', + }, + }, + ], + data: [ + { + $: { + 'android:mimeType': 'image/*', + }, + }, + ], + }, + { + action: [ + { + $: { + 'android:name': 'android.intent.action.SEND', + }, + }, + ], + category: [ + { + $: { + 'android:name': 'android.intent.category.DEFAULT', + }, + }, + ], + data: [ + { + $: { + 'android:mimeType': 'text/plain', + }, + }, + ], + }, + { + action: [ + { + $: { + 'android:name': 'android.intent.action.SEND_MULTIPLE', + }, + }, + ], + category: [ + { + $: { + 'android:name': 'android.intent.category.DEFAULT', + }, + }, + ], + data: [ + { + $: { + 'android:mimeType': 'image/*', + }, + }, + ], + }, + ] + + const intentFilter = + config.modResults.manifest.application?.[0].activity?.[0]['intent-filter'] + + if (intentFilter) { + intentFilter.push(...intents) + } + + return config + }) +} + +module.exports = {withIntentFilters} diff --git a/plugins/shareExtension/withShareExtensions.js b/plugins/shareExtension/withShareExtensions.js new file mode 100644 index 00000000..55a26c75 --- /dev/null +++ b/plugins/shareExtension/withShareExtensions.js @@ -0,0 +1,47 @@ +const {withPlugins} = require('@expo/config-plugins') +const {withAppEntitlements} = require('./withAppEntitlements') +const {withXcodeTarget} = require('./withXcodeTarget') +const {withExtensionEntitlements} = require('./withExtensionEntitlements') +const {withExtensionInfoPlist} = require('./withExtensionInfoPlist') +const {withExtensionViewController} = require('./withExtensionViewController') +const {withIntentFilters} = require('./withIntentFilters') + +const SHARE_EXTENSION_NAME = 'Share-with-Bluesky' +const SHARE_EXTENSION_CONTROLLER_NAME = 'ShareViewController' + +const withShareExtensions = config => { + return withPlugins(config, [ + // IOS + withAppEntitlements, + [ + withExtensionEntitlements, + { + extensionName: SHARE_EXTENSION_NAME, + }, + ], + [ + withExtensionInfoPlist, + { + extensionName: SHARE_EXTENSION_NAME, + }, + ], + [ + withExtensionViewController, + { + extensionName: SHARE_EXTENSION_NAME, + controllerName: SHARE_EXTENSION_CONTROLLER_NAME, + }, + ], + [ + withXcodeTarget, + { + extensionName: SHARE_EXTENSION_NAME, + controllerName: SHARE_EXTENSION_CONTROLLER_NAME, + }, + ], + // Android + withIntentFilters, + ]) +} + +module.exports = withShareExtensions diff --git a/plugins/shareExtension/withXcodeTarget.js b/plugins/shareExtension/withXcodeTarget.js new file mode 100644 index 00000000..4f43c092 --- /dev/null +++ b/plugins/shareExtension/withXcodeTarget.js @@ -0,0 +1,55 @@ +const {withXcodeProject} = require('@expo/config-plugins') + +const withXcodeTarget = (config, {extensionName, controllerName}) => { + // eslint-disable-next-line no-shadow + return withXcodeProject(config, config => { + const pbxProject = config.modResults + + const target = pbxProject.addTarget( + extensionName, + 'app_extension', + extensionName, + ) + pbxProject.addBuildPhase([], 'PBXSourcesBuildPhase', 'Sources', target.uuid) + pbxProject.addBuildPhase( + [], + 'PBXResourcesBuildPhase', + 'Resources', + target.uuid, + ) + const pbxGroupKey = pbxProject.pbxCreateGroup(extensionName, extensionName) + pbxProject.addFile(`${extensionName}/Info.plist`, pbxGroupKey) + pbxProject.addSourceFile( + `${extensionName}/${controllerName}.swift`, + {target: target.uuid}, + pbxGroupKey, + ) + + var configurations = pbxProject.pbxXCBuildConfigurationSection() + for (var key in configurations) { + if (typeof configurations[key].buildSettings !== 'undefined') { + var buildSettingsObj = configurations[key].buildSettings + if ( + typeof buildSettingsObj.PRODUCT_NAME !== 'undefined' && + buildSettingsObj.PRODUCT_NAME === `"${extensionName}"` + ) { + buildSettingsObj.CLANG_ENABLE_MODULES = 'YES' + buildSettingsObj.INFOPLIST_FILE = `"${extensionName}/Info.plist"` + buildSettingsObj.CODE_SIGN_ENTITLEMENTS = `"${extensionName}/${extensionName}.entitlements"` + buildSettingsObj.CODE_SIGN_STYLE = 'Automatic' + buildSettingsObj.CURRENT_PROJECT_VERSION = `"${config.ios?.buildNumber}"` + buildSettingsObj.GENERATE_INFOPLIST_FILE = 'YES' + buildSettingsObj.MARKETING_VERSION = `"${config.version}"` + buildSettingsObj.PRODUCT_BUNDLE_IDENTIFIER = `"${config.ios?.bundleIdentifier}.${extensionName}"` + buildSettingsObj.SWIFT_EMIT_LOC_STRINGS = 'YES' + buildSettingsObj.SWIFT_VERSION = '5.0' + buildSettingsObj.TARGETED_DEVICE_FAMILY = `"1,2"` + } + } + } + + return config + }) +} + +module.exports = {withXcodeTarget} diff --git a/scripts/README.md b/scripts/README.md new file mode 100644 index 00000000..99d6236f --- /dev/null +++ b/scripts/README.md @@ -0,0 +1,5 @@ +# Tool Scripts + +## updateExtensions.sh + +Updates the extensions in `/modules` with the current iOS/Android project changes. diff --git a/scripts/updateExtensions.sh b/scripts/updateExtensions.sh new file mode 100755 index 00000000..f4e462b7 --- /dev/null +++ b/scripts/updateExtensions.sh @@ -0,0 +1,10 @@ +#!/bin/bash +IOS_SHARE_EXTENSION_DIRECTORY="./ios/Share-with-Bluesky" +MODULES_DIRECTORY="./modules" + +if [ ! -d $IOS_SHARE_EXTENSION_DIRECTORY ]; then + echo "$IOS_SHARE_EXTENSION_DIRECTORY not found inside of your iOS project." + exit 1 +else + cp -R $IOS_SHARE_EXTENSION_DIRECTORY $MODULES_DIRECTORY +fi diff --git a/src/lib/hooks/useIntentHandler.ts b/src/lib/hooks/useIntentHandler.ts index 249e6898..de9a96da 100644 --- a/src/lib/hooks/useIntentHandler.ts +++ b/src/lib/hooks/useIntentHandler.ts @@ -6,6 +6,8 @@ import {useSession} from 'state/session' type IntentType = 'compose' +const VALID_IMAGE_REGEX = /^[\w.:\-_/]+\|\d+(\.\d+)?\|\d+(\.\d+)?$/ + export function useIntentHandler() { const incomingUrl = Linking.useURL() const composeIntent = useComposeIntent() @@ -29,7 +31,7 @@ export function useIntentHandler() { case 'compose': { composeIntent({ text: params.get('text'), - imageUris: params.get('imageUris'), + imageUrisStr: params.get('imageUris'), }) } } @@ -45,18 +47,39 @@ function useComposeIntent() { return React.useCallback( ({ - // eslint-disable-next-line @typescript-eslint/no-unused-vars text, - // eslint-disable-next-line @typescript-eslint/no-unused-vars - imageUris, + imageUrisStr, }: { text: string | null - imageUris: string | null // unused for right now, will be used later with intents + imageUrisStr: string | null // unused for right now, will be used later with intents }) => { if (!hasSession) return + const imageUris = imageUrisStr + ?.split(',') + .filter(part => { + // For some security, we're going to filter out any image uri that is external. We don't want someone to + // be able to provide some link like "bluesky://intent/compose?imageUris=https://IHaveYourIpNow.com/image.jpeg + // and we load that image + if (part.includes('https://') || part.includes('http://')) { + return false + } + // We also should just filter out cases that don't have all the info we need + if (!VALID_IMAGE_REGEX.test(part)) { + return false + } + return true + }) + .map(part => { + const [uri, width, height] = part.split('|') + return {uri, width: Number(width), height: Number(height)} + }) + setTimeout(() => { - openComposer({}) // will pass in values to the composer here in the share extension + openComposer({ + text: text ?? undefined, + imageUris: isNative ? imageUris : undefined, + }) }, 500) }, [openComposer, hasSession], diff --git a/src/state/models/media/gallery.ts b/src/state/models/media/gallery.ts index 04023bf8..9c8c1301 100644 --- a/src/state/models/media/gallery.ts +++ b/src/state/models/media/gallery.ts @@ -4,11 +4,21 @@ import {Image as RNImage} from 'react-native-image-crop-picker' import {openPicker} from 'lib/media/picker' import {getImageDim} from 'lib/media/manip' +interface InitialImageUri { + uri: string + width: number + height: number +} + export class GalleryModel { images: ImageModel[] = [] - constructor() { + constructor(uris?: {uri: string; width: number; height: number}[]) { makeAutoObservable(this) + + if (uris) { + this.addFromUris(uris) + } } get isEmpty() { @@ -23,7 +33,7 @@ export class GalleryModel { return this.images.some(image => image.altText.trim() === '') } - async add(image_: Omit) { + *add(image_: Omit) { if (this.size >= 4) { return } @@ -86,4 +96,15 @@ export class GalleryModel { }), ) } + + async addFromUris(uris: InitialImageUri[]) { + for (const uriObj of uris) { + this.add({ + mime: 'image/jpeg', + height: uriObj.height, + width: uriObj.width, + path: uriObj.uri, + }) + } + } } diff --git a/src/state/shell/composer.tsx b/src/state/shell/composer.tsx index 696a3c5b..c9dbfbea 100644 --- a/src/state/shell/composer.tsx +++ b/src/state/shell/composer.tsx @@ -38,6 +38,8 @@ export interface ComposerOpts { quote?: ComposerOptsQuote mention?: string // handle of user to mention openPicker?: (pos: DOMRect | undefined) => void + text?: string + imageUris?: {uri: string; width: number; height: number}[] } type StateContext = ComposerOpts | undefined diff --git a/src/view/com/composer/Composer.tsx b/src/view/com/composer/Composer.tsx index 1ed6b98a..2855d423 100644 --- a/src/view/com/composer/Composer.tsx +++ b/src/view/com/composer/Composer.tsx @@ -71,6 +71,8 @@ export const ComposePost = observer(function ComposePost({ quote: initQuote, mention: initMention, openPicker, + text: initText, + imageUris: initImageUris, }: Props) { const {currentAccount} = useSession() const {data: currentProfile} = useProfileQuery({did: currentAccount!.did}) @@ -91,7 +93,9 @@ export const ComposePost = observer(function ComposePost({ const [error, setError] = useState('') const [richtext, setRichText] = useState( new RichText({ - text: initMention + text: initText + ? initText + : initMention ? insertMentionAt( `@${initMention}`, initMention.length + 1, @@ -110,7 +114,10 @@ export const ComposePost = observer(function ComposePost({ const [labels, setLabels] = useState([]) const [threadgate, setThreadgate] = useState([]) const [suggestedLinks, setSuggestedLinks] = useState>(new Set()) - const gallery = useMemo(() => new GalleryModel(), []) + const gallery = useMemo( + () => new GalleryModel(initImageUris), + [initImageUris], + ) const onClose = useCallback(() => { closeComposer() }, [closeComposer]) diff --git a/src/view/shell/Composer.tsx b/src/view/shell/Composer.tsx index d37ff4fb..1937fcb6 100644 --- a/src/view/shell/Composer.tsx +++ b/src/view/shell/Composer.tsx @@ -55,6 +55,8 @@ export const Composer = observer(function ComposerImpl({ onPost={state.onPost} quote={state.quote} mention={state.mention} + text={state.text} + imageUris={state.imageUris} /> ) diff --git a/src/view/shell/Composer.web.tsx b/src/view/shell/Composer.web.tsx index 99e659d6..00233f66 100644 --- a/src/view/shell/Composer.web.tsx +++ b/src/view/shell/Composer.web.tsx @@ -9,7 +9,7 @@ import {useWebBodyScrollLock} from '#/lib/hooks/useWebBodyScrollLock' import { EmojiPicker, EmojiPickerState, -} from 'view/com/composer/text-input/web/EmojiPicker.web.tsx' +} from 'view/com/composer/text-input/web/EmojiPicker.web' const BOTTOM_BAR_HEIGHT = 61 @@ -69,6 +69,7 @@ export function Composer({}: {winHeight: number}) { onPost={state.onPost} mention={state.mention} openPicker={onOpenPicker} + text={state.text} /> From 6bd68e5321f25565eb89dfcae71e1932501c28f3 Mon Sep 17 00:00:00 2001 From: dan Date: Wed, 28 Feb 2024 00:19:13 +0000 Subject: [PATCH 18/43] Fix keys within a slice (#3005) Co-authored-by: Hailey --- src/state/queries/post-feed.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/state/queries/post-feed.ts b/src/state/queries/post-feed.ts index 220aac37..c295ffcb 100644 --- a/src/state/queries/post-feed.ts +++ b/src/state/queries/post-feed.ts @@ -276,7 +276,7 @@ export function usePostFeedQuery( .success ) { return { - _reactKey: `${slice._reactKey}-${i}`, + _reactKey: `${slice._reactKey}-${i}-${item.post.uri}`, uri: item.post.uri, post: item.post, record: item.post.record, From 603f3c0be972e013900264d706e2d28b87a93122 Mon Sep 17 00:00:00 2001 From: dan Date: Wed, 28 Feb 2024 00:48:54 +0000 Subject: [PATCH 19/43] Safeguard posts from clobbered state (#3006) --- src/view/com/post-thread/PostThreadItem.tsx | 2 ++ src/view/com/posts/FeedItem.tsx | 2 ++ 2 files changed, 4 insertions(+) diff --git a/src/view/com/post-thread/PostThreadItem.tsx b/src/view/com/post-thread/PostThreadItem.tsx index 949fcfea..9522ea6a 100644 --- a/src/view/com/post-thread/PostThreadItem.tsx +++ b/src/view/com/post-thread/PostThreadItem.tsx @@ -94,6 +94,8 @@ export function PostThreadItem({ if (richText && moderation) { return ( Date: Wed, 28 Feb 2024 01:35:25 +0000 Subject: [PATCH 20/43] Remove dangerous derived state from RichText (#3007) * Remove facet resolution from RichText * Remove derived state --- src/components/RichText.tsx | 25 ++++------------------- src/view/screens/Storybook/Typography.tsx | 6 ++++-- 2 files changed, 8 insertions(+), 23 deletions(-) diff --git a/src/components/RichText.tsx b/src/components/RichText.tsx index 22391cb2..3d5f0802 100644 --- a/src/components/RichText.tsx +++ b/src/components/RichText.tsx @@ -7,7 +7,6 @@ import {atoms as a, TextStyleProp, flatten, useTheme, web, native} from '#/alf' import {InlineLink} from '#/components/Link' import {Text, TextProps} from '#/components/Typography' import {toShortUrl} from 'lib/strings/url-helpers' -import {getAgent} from '#/state/session' import {TagMenu, useTagMenuControl} from '#/components/TagMenu' import {isNative} from '#/platform/detection' import {useInteractionState} from '#/components/hooks/useInteractionState' @@ -20,7 +19,6 @@ export function RichText({ style, numberOfLines, disableLinks, - resolveFacets = false, selectable, enableTags = false, authorHandle, @@ -30,31 +28,16 @@ export function RichText({ testID?: string numberOfLines?: number disableLinks?: boolean - resolveFacets?: boolean enableTags?: boolean authorHandle?: string }) { - const detected = React.useRef(false) - const [richText, setRichText] = React.useState(() => - value instanceof RichTextAPI ? value : new RichTextAPI({text: value}), + const richText = React.useMemo( + () => + value instanceof RichTextAPI ? value : new RichTextAPI({text: value}), + [value], ) const styles = [a.leading_snug, flatten(style)] - React.useEffect(() => { - if (!resolveFacets) return - - async function detectFacets() { - const rt = new RichTextAPI({text: richText.text}) - await rt.detectFacets(getAgent()) - setRichText(rt) - } - - if (!detected.current) { - detected.current = true - detectFacets() - } - }, [richText, setRichText, resolveFacets]) - const {text, facets} = richText if (!facets?.length) { diff --git a/src/view/screens/Storybook/Typography.tsx b/src/view/screens/Storybook/Typography.tsx index 8ee4270b..f0d67c52 100644 --- a/src/view/screens/Storybook/Typography.tsx +++ b/src/view/screens/Storybook/Typography.tsx @@ -22,12 +22,14 @@ export function Typography() { atoms.text_2xs From 23347a832d48dc3b56d67cc7477e5d5ae4de4bd7 Mon Sep 17 00:00:00 2001 From: Paul Frazee Date: Tue, 27 Feb 2024 17:35:52 -0800 Subject: [PATCH 21/43] Update po files --- src/locale/locales/ca/messages.po | 367 +++++++++++++++++++-------- src/locale/locales/de/messages.po | 367 +++++++++++++++++++-------- src/locale/locales/en/messages.po | 367 +++++++++++++++++++-------- src/locale/locales/es/messages.po | 367 +++++++++++++++++++-------- src/locale/locales/fr/messages.po | 367 +++++++++++++++++++-------- src/locale/locales/hi/messages.po | 367 +++++++++++++++++++-------- src/locale/locales/id/messages.po | 367 +++++++++++++++++++-------- src/locale/locales/it/messages.po | 367 +++++++++++++++++++-------- src/locale/locales/ja/messages.po | 367 +++++++++++++++++++-------- src/locale/locales/ko/messages.po | 367 +++++++++++++++++++-------- src/locale/locales/pt-BR/messages.po | 367 +++++++++++++++++++-------- src/locale/locales/uk/messages.po | 367 +++++++++++++++++++-------- src/locale/locales/zh-CN/messages.po | 367 +++++++++++++++++++-------- 13 files changed, 3458 insertions(+), 1313 deletions(-) diff --git a/src/locale/locales/ca/messages.po b/src/locale/locales/ca/messages.po index 9f7f853c..927599ab 100644 --- a/src/locale/locales/ca/messages.po +++ b/src/locale/locales/ca/messages.po @@ -91,7 +91,7 @@ msgid "A new version of the app is available. Please update to continue using th msgstr "Hi ha una nova versió d'aquesta aplicació. Actualitza-la per continuar." #: src/view/com/util/ViewHeader.tsx:83 -#: src/view/screens/Search/Search.tsx:624 +#: src/view/screens/Search/Search.tsx:647 msgid "Access navigation links and settings" msgstr "Accedeix als enllaços de navegació i configuració" @@ -142,6 +142,7 @@ msgstr "Compte desbloquejat" msgid "Account unmuted" msgstr "Compte no silenciat" +#: src/components/dialogs/MutedWords.tsx:147 #: src/view/com/auth/onboarding/RecommendedFeedsItem.tsx:150 #: src/view/com/modals/ListAddRemoveUsers.tsx:264 #: src/view/com/modals/UserAddRemoveLists.tsx:219 @@ -183,14 +184,22 @@ msgstr "Afegeix detalls" msgid "Add details to report" msgstr "Afegeix detalls a l'informe" -#: src/view/com/composer/Composer.tsx:446 +#: src/view/com/composer/Composer.tsx:453 msgid "Add link card" msgstr "Afegeix una targeta a l'enllaç" -#: src/view/com/composer/Composer.tsx:451 +#: src/view/com/composer/Composer.tsx:458 msgid "Add link card:" msgstr "Afegeix una targeta a l'enllaç:" +#: src/components/dialogs/MutedWords.tsx:140 +msgid "Add mute word for configured settings" +msgstr "" + +#: src/components/dialogs/MutedWords.tsx:74 +msgid "Add muted words and tags" +msgstr "" + #: src/view/com/modals/ChangeHandle.tsx:417 msgid "Add the following DNS record to your domain:" msgstr "Afegeix el següent registre DNS al teu domini:" @@ -310,7 +319,7 @@ msgstr "Configuració de la contrasenya d'aplicació" msgid "App Passwords" msgstr "Contrasenyes de l'aplicació" -#: src/view/com/util/forms/PostDropdownBtn.tsx:279 +#: src/view/com/util/forms/PostDropdownBtn.tsx:295 msgid "Appeal content warning" msgstr "Advertència d'apel·lació sobre el contingut" @@ -337,15 +346,16 @@ msgstr "Aparença" msgid "Are you sure you want to delete the app password \"{name}\"?" msgstr "Confirmes que vols eliminar la contrasenya de l'aplicació \"{name}\"?" -#: src/view/com/composer/Composer.tsx:143 +#: src/view/com/composer/Composer.tsx:150 msgid "Are you sure you'd like to discard this draft?" msgstr "Confirmes que vols descartar aquest esborrany?" +#: src/components/dialogs/MutedWords.tsx:233 #: src/view/screens/ProfileList.tsx:365 msgid "Are you sure?" msgstr "Ho confirmes?" -#: src/view/com/util/forms/PostDropdownBtn.tsx:262 +#: src/view/com/util/forms/PostDropdownBtn.tsx:278 msgid "Are you sure? This cannot be undone." msgstr "Ho confirmes? Aquesta acció no es pot desfer." @@ -367,15 +377,15 @@ msgstr "Nuesa artística o no eròtica." #: src/view/com/auth/login/LoginForm.tsx:259 #: src/view/com/auth/login/SetNewPasswordForm.tsx:179 #: src/view/com/modals/report/InputIssueDetails.tsx:46 -#: src/view/com/post-thread/PostThread.tsx:471 -#: src/view/com/post-thread/PostThread.tsx:521 -#: src/view/com/post-thread/PostThread.tsx:529 +#: src/view/com/post-thread/PostThread.tsx:472 +#: src/view/com/post-thread/PostThread.tsx:522 +#: src/view/com/post-thread/PostThread.tsx:530 #: src/view/com/profile/ProfileHeader.tsx:649 #: src/view/com/util/ViewHeader.tsx:81 msgid "Back" msgstr "Endarrere" -#: src/view/com/post-thread/PostThread.tsx:479 +#: src/view/com/post-thread/PostThread.tsx:480 msgctxt "action" msgid "Back" msgstr "Endarrere" @@ -423,7 +433,7 @@ msgstr "Bloqueja la llista" msgid "Blocked" msgstr "Bloquejada" -#: src/view/screens/Moderation.tsx:123 +#: src/view/screens/Moderation.tsx:142 msgid "Blocked accounts" msgstr "Comptes bloquejats" @@ -482,7 +492,7 @@ msgstr "Bluesky és públic." msgid "Bluesky uses invites to build a healthier community. If you don't know anybody with an invite, you can sign up for the waitlist and we'll send one soon." msgstr "Bluesky utilitza les invitacions per construir una comunitat saludable. Si no coneixes ningú amb invitacions, pots apuntar-te a la llista d'espera i te n'enviarem una aviat." -#: src/view/screens/Moderation.tsx:226 +#: src/view/screens/Moderation.tsx:245 msgid "Bluesky will not show your profile and posts to logged-out users. Other apps may not honor this request. This does not make your account private." msgstr "Bluesky no mostrarà el teu perfil ni les publicacions als usuaris que no estiguin registrats. Altres aplicacions poden no seguir aquesta demanda. Això no fa que el teu compte sigui privat." @@ -534,8 +544,8 @@ msgid "Can only contain letters, numbers, spaces, dashes, and underscores. Must msgstr "Només pot tenir lletres, números, espais, guions i guions baixos. Ha de tenir almenys 4 caràcters i no més de 32." #: src/components/Prompt.tsx:91 -#: src/view/com/composer/Composer.tsx:300 -#: src/view/com/composer/Composer.tsx:305 +#: src/view/com/composer/Composer.tsx:307 +#: src/view/com/composer/Composer.tsx:312 #: src/view/com/modals/ChangeEmail.tsx:218 #: src/view/com/modals/ChangeEmail.tsx:220 #: src/view/com/modals/ChangePassword.tsx:265 @@ -549,7 +559,7 @@ msgstr "Només pot tenir lletres, números, espais, guions i guions baixos. Ha d #: src/view/com/modals/VerifyEmail.tsx:247 #: src/view/com/modals/VerifyEmail.tsx:253 #: src/view/com/modals/Waitlist.tsx:142 -#: src/view/screens/Search/Search.tsx:693 +#: src/view/screens/Search/Search.tsx:716 #: src/view/shell/desktop/Search.tsx:238 msgid "Cancel" msgstr "Cancel·la" @@ -704,7 +714,7 @@ msgid "Clear all storage data (restart after this)" msgstr "Esborra totes les dades emmagatzemades (i després reinicia)" #: src/view/com/util/forms/SearchInput.tsx:88 -#: src/view/screens/Search/Search.tsx:674 +#: src/view/screens/Search/Search.tsx:697 msgid "Clear search query" msgstr "Esborra la cerca" @@ -712,6 +722,11 @@ msgstr "Esborra la cerca" msgid "click here" msgstr "clica aquí" +#: src/components/RichText.tsx:189 +#: src/components/TagMenu/index.web.tsx:125 +msgid "Click here to open tag menu for {tag}" +msgstr "" + #: src/screens/Onboarding/index.tsx:35 msgid "Climate" msgstr "" @@ -742,11 +757,15 @@ msgstr "Tanca la imatge" msgid "Close image viewer" msgstr "Tanca el visor d'imatges" -#: src/view/shell/index.web.tsx:49 +#: src/view/shell/index.web.tsx:51 msgid "Close navigation footer" msgstr "Tanca el peu de la navegació" -#: src/view/shell/index.web.tsx:50 +#: src/components/TagMenu/index.tsx:266 +msgid "Close this dialog" +msgstr "" + +#: src/view/shell/index.web.tsx:52 msgid "Closes bottom navigation bar" msgstr "Tanca la barra de navegació inferior" @@ -754,7 +773,7 @@ msgstr "Tanca la barra de navegació inferior" msgid "Closes password update alert" msgstr "Tanca l'alerta d'actualització de contrasenya" -#: src/view/com/composer/Composer.tsx:302 +#: src/view/com/composer/Composer.tsx:309 msgid "Closes post composer and discards post draft" msgstr "Tanca l'editor de la publicació i descarta l'esborrany" @@ -787,7 +806,7 @@ msgstr "" msgid "Complete the challenge" msgstr "" -#: src/view/com/composer/Composer.tsx:417 +#: src/view/com/composer/Composer.tsx:424 msgid "Compose posts up to {MAX_GRAPHEME_LENGTH} characters in length" msgstr "Crea publicacions de fins a {MAX_GRAPHEME_LENGTH} caràcters" @@ -851,7 +870,7 @@ msgstr "Connectant…" msgid "Contact support" msgstr "Contacta amb suport" -#: src/view/screens/Moderation.tsx:81 +#: src/view/screens/Moderation.tsx:83 msgid "Content filtering" msgstr "Filtre de contingut" @@ -917,7 +936,7 @@ msgstr "Número de versió copiat en memòria" #: src/view/com/modals/AddAppPasswords.tsx:76 #: src/view/com/modals/InviteCodes.tsx:152 -#: src/view/com/util/forms/PostDropdownBtn.tsx:141 +#: src/view/com/util/forms/PostDropdownBtn.tsx:143 msgid "Copied to clipboard" msgstr "Copiat en memòria" @@ -933,7 +952,7 @@ msgstr "Copia" msgid "Copy link to list" msgstr "Copia l'enllaç a la llista" -#: src/view/com/util/forms/PostDropdownBtn.tsx:182 +#: src/view/com/util/forms/PostDropdownBtn.tsx:184 msgid "Copy link to post" msgstr "Copia l'enllaç a la publicació" @@ -941,7 +960,7 @@ msgstr "Copia l'enllaç a la publicació" msgid "Copy link to profile" msgstr "Copia l'enllaç al perfil" -#: src/view/com/util/forms/PostDropdownBtn.tsx:168 +#: src/view/com/util/forms/PostDropdownBtn.tsx:170 msgid "Copy post text" msgstr "Copia el text de la publicació" @@ -997,7 +1016,7 @@ msgstr "Creat per <0/>" msgid "Created by you" msgstr "Creat per tu" -#: src/view/com/composer/Composer.tsx:448 +#: src/view/com/composer/Composer.tsx:455 msgid "Creates a card with a thumbnail. The card links to {url}" msgstr "Crea una targeta amb una minuatura. La targeta enllaça a {url}" @@ -1074,11 +1093,11 @@ msgstr "Elimina el meu compte" msgid "Delete My Account…" msgstr "" -#: src/view/com/util/forms/PostDropdownBtn.tsx:257 +#: src/view/com/util/forms/PostDropdownBtn.tsx:273 msgid "Delete post" msgstr "Elimina la publicació" -#: src/view/com/util/forms/PostDropdownBtn.tsx:261 +#: src/view/com/util/forms/PostDropdownBtn.tsx:277 msgid "Delete this post?" msgstr "Vols eliminar aquesta publicació?" @@ -1105,7 +1124,7 @@ msgstr "Descripció" #~ msgid "Developer Tools" #~ msgstr "Eines de desenvolupador" -#: src/view/com/composer/Composer.tsx:211 +#: src/view/com/composer/Composer.tsx:218 msgid "Did you want to say anything?" msgstr "Vols dir alguna cosa?" @@ -1113,15 +1132,15 @@ msgstr "Vols dir alguna cosa?" msgid "Dim" msgstr "" -#: src/view/com/composer/Composer.tsx:144 +#: src/view/com/composer/Composer.tsx:151 msgid "Discard" msgstr "Descarta" -#: src/view/com/composer/Composer.tsx:138 +#: src/view/com/composer/Composer.tsx:145 msgid "Discard draft" msgstr "Descarta l'esborrany" -#: src/view/screens/Moderation.tsx:207 +#: src/view/screens/Moderation.tsx:226 msgid "Discourage apps from showing my account to logged-out users" msgstr "Evita que les aplicacions mostrin el meu compte als usuaris no connectats" @@ -1200,7 +1219,7 @@ msgstr "" msgid "Download CAR file" msgstr "" -#: src/view/com/composer/text-input/TextInput.web.tsx:247 +#: src/view/com/composer/text-input/TextInput.web.tsx:249 msgid "Drop to add images" msgstr "" @@ -1272,6 +1291,7 @@ msgstr "Edita el perfil" msgid "Edit Profile" msgstr "Edita el perfil" +#: src/view/com/home/HomeHeaderLayout.web.tsx:59 #: src/view/screens/Feeds.tsx:355 msgid "Edit Saved Feeds" msgstr "Edita els meus canals guardats" @@ -1354,6 +1374,11 @@ msgstr "Fi del canal" msgid "Enter a name for this App Password" msgstr "Posa un nom a aquesta contrasenya d'aplicació" +#: src/components/dialogs/MutedWords.tsx:87 +#: src/components/dialogs/MutedWords.tsx:88 +msgid "Enter a word or tag" +msgstr "" + #: src/view/com/modals/VerifyEmail.tsx:105 msgid "Enter Confirmation Code" msgstr "Entra el codi de confirmació" @@ -1407,7 +1432,7 @@ msgstr "Introdueix el teu usuari i contrasenya" msgid "Error receiving captcha response." msgstr "" -#: src/view/screens/Search/Search.tsx:109 +#: src/view/screens/Search/Search.tsx:110 msgid "Error:" msgstr "Error:" @@ -1478,7 +1503,7 @@ msgstr "No s'ha pogut crear la contrasenya d'aplicació" msgid "Failed to create the list. Check your internet connection and try again." msgstr "No s'ha pogut crear la llista. Comprova la teva connexió a internet i torna-ho a provar." -#: src/view/com/util/forms/PostDropdownBtn.tsx:108 +#: src/view/com/util/forms/PostDropdownBtn.tsx:110 msgid "Failed to delete post, please try again" msgstr "No s'ha pogut esborrar la publicació, torna-ho a provar" @@ -1500,8 +1525,8 @@ msgid "Feed offline" msgstr "Canal fora de línia" #: src/view/com/feeds/FeedPage.tsx:143 -msgid "Feed Preferences" -msgstr "Preferències del canal" +#~ msgid "Feed Preferences" +#~ msgstr "Preferències del canal" #: src/view/shell/desktop/RightNav.tsx:61 #: src/view/shell/Drawer.tsx:311 @@ -1541,11 +1566,11 @@ msgstr "" msgid "Find accounts to follow" msgstr "Troba comptes per seguir" -#: src/view/screens/Search/Search.tsx:439 +#: src/view/screens/Search/Search.tsx:440 msgid "Find users on Bluesky" msgstr "Troba usuaris a Bluesky" -#: src/view/screens/Search/Search.tsx:437 +#: src/view/screens/Search/Search.tsx:438 msgid "Find users with the search tool on the right" msgstr "Troba usuaris amb l'eina de cerca de la dreta" @@ -1646,6 +1671,7 @@ msgid "Following {0}" msgstr "Seguint {0}" #: src/Navigation.tsx:248 +#: src/view/com/home/HomeHeaderLayout.web.tsx:45 #: src/view/com/home/HomeHeaderLayoutMobile.tsx:83 #: src/view/screens/PreferencesFollowingFeed.tsx:104 #: src/view/screens/Settings/index.tsx:543 @@ -1685,7 +1711,7 @@ msgstr "He oblidat la contrasenya" msgid "Forgot Password" msgstr "He oblidat la contrasenya" -#: src/view/com/posts/FeedItem.tsx:187 +#: src/view/com/posts/FeedItem.tsx:189 msgctxt "from-feed" msgid "From <0/>" msgstr "De <0/>" @@ -1718,7 +1744,7 @@ msgstr "Ves enrere" msgid "Go back to previous step" msgstr "" -#: src/view/screens/Search/Search.tsx:724 +#: src/view/screens/Search/Search.tsx:747 #: src/view/shell/desktop/Search.tsx:262 msgid "Go to @{queryMaybeHandle}" msgstr "Vés a @{queryMaybeHandle}" @@ -1735,6 +1761,10 @@ msgstr "Ves al següent" msgid "Handle" msgstr "Identificador" +#: src/components/RichText.tsx:188 +msgid "Hashtag: {tag}" +msgstr "" + #: src/view/com/auth/create/CreateAccount.tsx:208 msgid "Having trouble?" msgstr "Tens problemes?" @@ -1773,7 +1803,7 @@ msgctxt "action" msgid "Hide" msgstr "Amaga" -#: src/view/com/util/forms/PostDropdownBtn.tsx:216 +#: src/view/com/util/forms/PostDropdownBtn.tsx:232 msgid "Hide post" msgstr "Amaga l'entrada" @@ -1782,7 +1812,7 @@ msgstr "Amaga l'entrada" msgid "Hide the content" msgstr "Amaga el contingut" -#: src/view/com/util/forms/PostDropdownBtn.tsx:220 +#: src/view/com/util/forms/PostDropdownBtn.tsx:236 msgid "Hide this post?" msgstr "Vols amagar aquesta entrada?" @@ -1936,7 +1966,7 @@ msgstr "Introdueix la teva contrasenya" msgid "Input your user handle" msgstr "Introdueix el teu identificador d'usuari" -#: src/view/com/post-thread/PostThreadItem.tsx:224 +#: src/view/com/post-thread/PostThreadItem.tsx:226 msgid "Invalid or unsupported post record" msgstr "Registre de publicació no vàlid o no admès" @@ -2038,7 +2068,7 @@ msgstr "Més informació" msgid "Learn more about this warning" msgstr "Més informació d'aquesta advertència" -#: src/view/screens/Moderation.tsx:243 +#: src/view/screens/Moderation.tsx:262 msgid "Learn more about what is public on Bluesky." msgstr "Més informació sobre què és públic a Bluesky." @@ -2118,7 +2148,7 @@ msgstr "li ha agradat la teva publicació" msgid "Likes" msgstr "M'agrades" -#: src/view/com/post-thread/PostThreadItem.tsx:181 +#: src/view/com/post-thread/PostThreadItem.tsx:183 msgid "Likes on this post" msgstr "M'agrades a aquesta publicació" @@ -2175,7 +2205,7 @@ msgstr "Carrega més publicacions" msgid "Load new notifications" msgstr "Carrega noves notificacions" -#: src/view/com/feeds/FeedPage.tsx:181 +#: src/view/com/feeds/FeedPage.tsx:115 #: src/view/screens/Profile.tsx:440 #: src/view/screens/ProfileFeed.tsx:495 #: src/view/screens/ProfileList.tsx:681 @@ -2201,7 +2231,7 @@ msgstr "Registre" msgid "Log out" msgstr "" -#: src/view/screens/Moderation.tsx:136 +#: src/view/screens/Moderation.tsx:155 msgid "Logged-out visibility" msgstr "Visibilitat pels usuaris no connectats" @@ -2216,6 +2246,10 @@ msgstr "Accedeix a un compte que no està llistat" msgid "Make sure this is where you intend to go!" msgstr "Assegura't que és aquí on vols anar!" +#: src/components/dialogs/MutedWords.tsx:71 +msgid "Manage your muted words and tags" +msgstr "" + #: src/view/com/auth/create/Step2.tsx:118 msgid "May not be longer than 253 characters" msgstr "" @@ -2237,7 +2271,7 @@ msgid "Mentioned users" msgstr "Usuaris mencionats" #: src/view/com/util/ViewHeader.tsx:81 -#: src/view/screens/Search/Search.tsx:623 +#: src/view/screens/Search/Search.tsx:646 msgid "Menu" msgstr "Menú" @@ -2250,7 +2284,7 @@ msgid "Message from server: {0}" msgstr "Missatge del servidor: {0}" #: src/Navigation.tsx:115 -#: src/view/screens/Moderation.tsx:64 +#: src/view/screens/Moderation.tsx:66 #: src/view/screens/Settings/index.tsx:625 #: src/view/shell/desktop/LeftNav.tsx:397 #: src/view/shell/Drawer.tsx:511 @@ -2281,7 +2315,7 @@ msgstr "S'ha creat la llista de moderació" msgid "Moderation list updated" msgstr "S'ha actualitzat la llista de moderació" -#: src/view/screens/Moderation.tsx:95 +#: src/view/screens/Moderation.tsx:114 msgid "Moderation lists" msgstr "Llistes de moderació" @@ -2308,7 +2342,7 @@ msgstr "Més canals" msgid "More options" msgstr "Més opcions" -#: src/view/com/util/forms/PostDropdownBtn.tsx:299 +#: src/view/com/util/forms/PostDropdownBtn.tsx:315 msgid "More post options" msgstr "Més opcions de publicació" @@ -2320,6 +2354,14 @@ msgstr "Respostes amb més m'agrada primer" msgid "Must be at least 3 characters" msgstr "" +#: src/components/TagMenu/index.tsx:253 +msgid "Mute" +msgstr "" + +#: src/components/TagMenu/index.web.tsx:91 +msgid "Mute {truncatedTag}" +msgstr "" + #: src/view/com/profile/ProfileHeader.tsx:327 msgid "Mute Account" msgstr "Silenciar el compte" @@ -2328,6 +2370,18 @@ msgstr "Silenciar el compte" msgid "Mute accounts" msgstr "Silencia els comptes" +#: src/components/TagMenu/index.tsx:211 +msgid "Mute all {tag} posts" +msgstr "" + +#: src/components/dialogs/MutedWords.tsx:131 +msgid "Mute in tags only" +msgstr "" + +#: src/components/dialogs/MutedWords.tsx:116 +msgid "Mute in text & tags" +msgstr "" + #: src/view/screens/ProfileList.tsx:491 msgid "Mute list" msgstr "Silencia la llista" @@ -2340,15 +2394,27 @@ msgstr "Vols silenciar aquests comptes?" msgid "Mute this List" msgstr "Silencia aquesta llista" -#: src/view/com/util/forms/PostDropdownBtn.tsx:200 +#: src/components/dialogs/MutedWords.tsx:109 +msgid "Mute this word in post text and tags" +msgstr "" + +#: src/components/dialogs/MutedWords.tsx:124 +msgid "Mute this word in tags only" +msgstr "" + +#: src/view/com/util/forms/PostDropdownBtn.tsx:202 msgid "Mute thread" msgstr "Silencia el fil de debat" +#: src/view/com/util/forms/PostDropdownBtn.tsx:216 +msgid "Mute words & tags" +msgstr "" + #: src/view/com/lists/ListCard.tsx:102 msgid "Muted" msgstr "Silenciada" -#: src/view/screens/Moderation.tsx:109 +#: src/view/screens/Moderation.tsx:128 msgid "Muted accounts" msgstr "Comptes silenciats" @@ -2361,6 +2427,10 @@ msgstr "Comptes silenciats" msgid "Muted accounts have their posts removed from your feed and from your notifications. Mutes are completely private." msgstr "Les publicacions dels comptes silenciats seran eliminats del teu canal i de les teves notificacions. Silenciar comptes és completament privat." +#: src/view/screens/Moderation.tsx:100 +msgid "Muted words & tags" +msgstr "" + #: src/view/screens/ProfileList.tsx:277 msgid "Muting is private. Muted accounts can interact with you, but you will not see their posts or receive notifications from them." msgstr "Silenciar és privat. Els comptes silenciats poden interactuar amb tu, però tu no veuràs les seves publicacions ni rebràs notificacions seves." @@ -2424,6 +2494,10 @@ msgstr "No perdis mai accés als teus seguidors ni a les teves dades." msgid "Never lose access to your followers or data." msgstr "" +#: src/components/dialogs/MutedWords.tsx:244 +msgid "Nevermind" +msgstr "" + #: src/view/screens/Lists.tsx:76 msgctxt "action" msgid "New" @@ -2445,7 +2519,7 @@ msgstr "Nova contrasenya" msgid "New Password" msgstr "" -#: src/view/com/feeds/FeedPage.tsx:192 +#: src/view/com/feeds/FeedPage.tsx:126 msgctxt "action" msgid "New post" msgstr "Nova publicació" @@ -2534,8 +2608,8 @@ msgid "No results found for \"{query}\"" msgstr "No s'han trobat resultats per \"{query}\"" #: src/view/com/modals/ListAddRemoveUsers.tsx:127 -#: src/view/screens/Search/Search.tsx:280 -#: src/view/screens/Search/Search.tsx:308 +#: src/view/screens/Search/Search.tsx:281 +#: src/view/screens/Search/Search.tsx:309 msgid "No results found for {query}" msgstr "No s'han trobat resultats per {query}" @@ -2561,7 +2635,7 @@ msgstr "No s'ha trobat" msgid "Not right now" msgstr "Ara mateix no" -#: src/view/screens/Moderation.tsx:233 +#: src/view/screens/Moderation.tsx:252 msgid "Note: Bluesky is an open and public network. This setting only limits the visibility of your content on the Bluesky app and website, and other apps may not respect this setting. Your content may still be shown to logged-out users by other apps and websites." msgstr "Nota: Bluesky és una xarxa oberta i pública. Aquesta configuració tan sols limita el teu contingut a l'aplicació de Bluesky i a la web, altres aplicacions poden no respectar-ho. El teu contingut pot ser mostrat a usuaris no connectats per altres aplicacions i webs." @@ -2599,7 +2673,7 @@ msgstr "Respostes més antigues primer" msgid "Onboarding reset" msgstr "Restableix la incorporació" -#: src/view/com/composer/Composer.tsx:375 +#: src/view/com/composer/Composer.tsx:382 msgid "One or more images is missing alt text." msgstr "Falta el text alternatiu a una o més imatges." @@ -2616,8 +2690,12 @@ msgstr "Ostres!" msgid "Open" msgstr "" -#: src/view/com/composer/Composer.tsx:470 -#: src/view/com/composer/Composer.tsx:471 +#: src/view/screens/Moderation.tsx:75 +msgid "Open content filtering settings" +msgstr "" + +#: src/view/com/composer/Composer.tsx:477 +#: src/view/com/composer/Composer.tsx:478 msgid "Open emoji picker" msgstr "Obre el selector d'emojis" @@ -2625,6 +2703,10 @@ msgstr "Obre el selector d'emojis" msgid "Open links with in-app browser" msgstr "Obre els enllaços al navegador de l'aplicació" +#: src/view/screens/Moderation.tsx:92 +msgid "Open muted words settings" +msgstr "" + #: src/view/com/home/HomeHeaderLayoutMobile.tsx:49 msgid "Open navigation" msgstr "Obre la navegació" @@ -2701,6 +2783,7 @@ msgstr "Obre la configuració de la moderació" msgid "Opens password reset form" msgstr "Obre el formulari de restabliment de la contrasenya" +#: src/view/com/home/HomeHeaderLayout.web.tsx:60 #: src/view/screens/Feeds.tsx:356 msgid "Opens screen to edit Saved Feeds" msgstr "Obre pantalla per editar els canals desats" @@ -2879,7 +2962,7 @@ msgstr "Digues-nos per què creus que s'ha aplicat incorrectament l'advertència msgid "Please Verify Your Email" msgstr "Verifica el teu correu" -#: src/view/com/composer/Composer.tsx:215 +#: src/view/com/composer/Composer.tsx:222 msgid "Please wait for your link card to finish loading" msgstr "Espera que es generi la targeta de l'enllaç" @@ -2891,8 +2974,8 @@ msgstr "" msgid "Porn" msgstr "Pornografia" -#: src/view/com/composer/Composer.tsx:350 -#: src/view/com/composer/Composer.tsx:358 +#: src/view/com/composer/Composer.tsx:357 +#: src/view/com/composer/Composer.tsx:365 msgctxt "action" msgid "Post" msgstr "Publica" @@ -2908,7 +2991,7 @@ msgstr "Publicació" #~ msgid "Post" #~ msgstr "Publicació" -#: src/view/com/post-thread/PostThreadItem.tsx:173 +#: src/view/com/post-thread/PostThreadItem.tsx:175 msgid "Post by {0}" msgstr "Publicació per {0}" @@ -2918,11 +3001,11 @@ msgstr "Publicació per {0}" msgid "Post by @{0}" msgstr "Publicació per @{0}" -#: src/view/com/util/forms/PostDropdownBtn.tsx:88 +#: src/view/com/util/forms/PostDropdownBtn.tsx:90 msgid "Post deleted" msgstr "Publicació eliminada" -#: src/view/com/post-thread/PostThread.tsx:461 +#: src/view/com/post-thread/PostThread.tsx:462 msgid "Post hidden" msgstr "Publicació oculta" @@ -2934,14 +3017,22 @@ msgstr "Idioma de la publicació" msgid "Post Languages" msgstr "Idiomes de les publicacions" -#: src/view/com/post-thread/PostThread.tsx:513 +#: src/view/com/post-thread/PostThread.tsx:514 msgid "Post not found" msgstr "Publicació no trobada" +#: src/components/TagMenu/index.tsx:257 +msgid "posts" +msgstr "" + #: src/view/screens/Profile.tsx:180 msgid "Posts" msgstr "Publicacions" +#: src/components/dialogs/MutedWords.tsx:77 +msgid "Posts can be muted based on their text, their tags, or both." +msgstr "" + #: src/view/com/posts/FeedErrorMessage.tsx:64 msgid "Posts hidden" msgstr "Publicacions amagades" @@ -3006,11 +3097,11 @@ msgstr "Llistes d'usuaris per silenciar o bloquejar en massa, públiques i per c msgid "Public, shareable lists which can drive feeds." msgstr "Llistes que poden nodrir canals, públiques i per compartir." -#: src/view/com/composer/Composer.tsx:335 +#: src/view/com/composer/Composer.tsx:342 msgid "Publish post" msgstr "Publica" -#: src/view/com/composer/Composer.tsx:335 +#: src/view/com/composer/Composer.tsx:342 msgid "Publish reply" msgstr "Publica la resposta" @@ -3048,6 +3139,7 @@ msgstr "Canals recomanats" msgid "Recommended Users" msgstr "Usuaris recomanats" +#: src/components/dialogs/MutedWords.tsx:249 #: src/view/com/modals/ListAddRemoveUsers.tsx:264 #: src/view/com/modals/SelfLabel.tsx:83 #: src/view/com/modals/UserAddRemoveLists.tsx:219 @@ -3085,6 +3177,10 @@ msgstr "Elimina la imatge" msgid "Remove image preview" msgstr "Elimina la visualització prèvia de la imatge" +#: src/components/dialogs/MutedWords.tsx:294 +msgid "Remove mute word from your list" +msgstr "" + #: src/view/com/modals/Repost.tsx:47 msgid "Remove repost" msgstr "Elimina la republicació" @@ -3119,7 +3215,7 @@ msgstr "Respostes" msgid "Replies to this thread are disabled" msgstr "Les respostes a aquest fil de debat estan deshabilitades" -#: src/view/com/composer/Composer.tsx:348 +#: src/view/com/composer/Composer.tsx:355 msgctxt "action" msgid "Reply" msgstr "Respon" @@ -3129,7 +3225,7 @@ msgid "Reply Filters" msgstr "Filtres de resposta" #: src/view/com/post/Post.tsx:167 -#: src/view/com/posts/FeedItem.tsx:285 +#: src/view/com/posts/FeedItem.tsx:287 msgctxt "description" msgid "Reply to <0/>" msgstr "Resposta a <0/>" @@ -3151,7 +3247,7 @@ msgid "Report List" msgstr "Informa de la llista" #: src/view/com/modals/report/SendReportButton.tsx:37 -#: src/view/com/util/forms/PostDropdownBtn.tsx:239 +#: src/view/com/util/forms/PostDropdownBtn.tsx:255 msgid "Report post" msgstr "Informa de la publicació" @@ -3180,7 +3276,7 @@ msgstr "Republica o cita la publicació" msgid "Reposted By" msgstr "" -#: src/view/com/posts/FeedItem.tsx:205 +#: src/view/com/posts/FeedItem.tsx:207 msgid "Reposted by {0}" msgstr "" @@ -3188,7 +3284,7 @@ msgstr "" #~ msgid "Reposted by {0})" #~ msgstr "Republicada per {0}" -#: src/view/com/posts/FeedItem.tsx:222 +#: src/view/com/posts/FeedItem.tsx:224 msgid "Reposted by <0/>" msgstr "Republicada per <0/>" @@ -3196,7 +3292,7 @@ msgstr "Republicada per <0/>" msgid "reposted your post" msgstr "ha republicat la teva publicació" -#: src/view/com/post-thread/PostThreadItem.tsx:186 +#: src/view/com/post-thread/PostThreadItem.tsx:188 msgid "Reposts of this post" msgstr "Republicacions d'aquesta publicació" @@ -3347,9 +3443,9 @@ msgstr "Desplaça't cap a dalt" #: src/view/com/modals/ListAddRemoveUsers.tsx:75 #: src/view/com/util/forms/SearchInput.tsx:67 #: src/view/com/util/forms/SearchInput.tsx:79 -#: src/view/screens/Search/Search.tsx:418 -#: src/view/screens/Search/Search.tsx:645 -#: src/view/screens/Search/Search.tsx:663 +#: src/view/screens/Search/Search.tsx:419 +#: src/view/screens/Search/Search.tsx:668 +#: src/view/screens/Search/Search.tsx:686 #: src/view/shell/bottom-bar/BottomBar.tsx:159 #: src/view/shell/desktop/LeftNav.tsx:324 #: src/view/shell/desktop/Search.tsx:214 @@ -3359,11 +3455,19 @@ msgstr "Desplaça't cap a dalt" msgid "Search" msgstr "Cerca" -#: src/view/screens/Search/Search.tsx:712 +#: src/view/screens/Search/Search.tsx:735 #: src/view/shell/desktop/Search.tsx:255 msgid "Search for \"{query}\"" msgstr "Cerca per \"{query}\"" +#: src/components/TagMenu/index.tsx:145 +msgid "Search for all posts by @{authorHandle} with tag {tag}" +msgstr "" + +#: src/components/TagMenu/index.tsx:90 +msgid "Search for all posts with tag {tag}" +msgstr "" + #: src/view/com/auth/LoggedOut.tsx:104 #: src/view/com/auth/LoggedOut.tsx:105 #: src/view/com/modals/ListAddRemoveUsers.tsx:70 @@ -3374,6 +3478,22 @@ msgstr "Cerca usuaris" msgid "Security Step Required" msgstr "Es requereix un pas de seguretat" +#: src/components/TagMenu/index.web.tsx:50 +msgid "See {truncatedTag} posts" +msgstr "" + +#: src/components/TagMenu/index.web.tsx:67 +msgid "See {truncatedTag} posts by user" +msgstr "" + +#: src/components/TagMenu/index.tsx:128 +msgid "See <0>{tag} posts" +msgstr "" + +#: src/components/TagMenu/index.tsx:189 +msgid "See <0>{tag} posts by this user" +msgstr "" + #: src/view/screens/SavedFeeds.tsx:163 msgid "See this guide" msgstr "Consulta aquesta guia" @@ -3583,7 +3703,7 @@ msgid "Share" msgstr "Comparteix" #: src/view/com/profile/ProfileHeader.tsx:295 -#: src/view/com/util/forms/PostDropdownBtn.tsx:182 +#: src/view/com/util/forms/PostDropdownBtn.tsx:184 #: src/view/screens/ProfileList.tsx:418 msgid "Share" msgstr "Comparteix" @@ -3616,9 +3736,9 @@ msgstr "Mostra els incrustats de {0}" msgid "Show follows similar to {0}" msgstr "Mostra seguidors semblants a {0}" -#: src/view/com/post-thread/PostThreadItem.tsx:532 -#: src/view/com/post/Post.tsx:196 -#: src/view/com/posts/FeedItem.tsx:359 +#: src/view/com/post-thread/PostThreadItem.tsx:538 +#: src/view/com/post/Post.tsx:198 +#: src/view/com/posts/FeedItem.tsx:363 msgid "Show More" msgstr "Mostra més" @@ -3786,7 +3906,7 @@ msgstr "" msgid "Something went wrong. Check your email and try again." msgstr "Alguna cosa ha fallat. Comprova el teu correu i torna-ho a provar." -#: src/App.native.tsx:61 +#: src/App.native.tsx:63 msgid "Sorry! Your session expired. Please log in again." msgstr "La teva sessió ha caducat. Torna a inciar-la." @@ -3844,7 +3964,7 @@ msgstr "" msgid "Subscribe to this list" msgstr "Subscriure's a la llista" -#: src/view/screens/Search/Search.tsx:373 +#: src/view/screens/Search/Search.tsx:374 msgid "Suggested Follows" msgstr "Usuaris suggerits per seguir" @@ -3888,6 +4008,14 @@ msgstr "Sistema" msgid "System log" msgstr "Registres del sistema" +#: src/components/dialogs/MutedWords.tsx:288 +msgid "tag" +msgstr "" + +#: src/components/TagMenu/index.tsx:74 +msgid "Tag menu: {tag}" +msgstr "" + #: src/view/com/modals/crop-image/CropImage.web.tsx:112 msgid "Tall" msgstr "Alt" @@ -3911,6 +4039,10 @@ msgstr "Condicions" msgid "Terms of Service" msgstr "Condicions del servei" +#: src/components/dialogs/MutedWords.tsx:288 +msgid "text" +msgstr "" + #: src/view/com/modals/AppealLabel.tsx:70 #: src/view/com/modals/report/InputIssueDetails.tsx:51 msgid "Text input field" @@ -3936,7 +4068,7 @@ msgstr "La política de drets d'autoria ha estat traslladada a <0/>" msgid "The following steps will help customize your Bluesky experience." msgstr "" -#: src/view/com/post-thread/PostThread.tsx:516 +#: src/view/com/post-thread/PostThread.tsx:517 msgid "The post may have been deleted." msgstr "És possible que la publicació s'hagi esborrat." @@ -4113,7 +4245,7 @@ msgstr "Aquesta llista està buida!" msgid "This name is already in use" msgstr "Aquest nom ja està en ús" -#: src/view/com/post-thread/PostThreadItem.tsx:123 +#: src/view/com/post-thread/PostThreadItem.tsx:125 msgid "This post has been deleted." msgstr "Aquesta publicació ha estat esborrada." @@ -4137,7 +4269,11 @@ msgstr "" msgid "This warning is only available for posts with media attached." msgstr "Aquesta advertència només està disponible per publicacions amb contingut adjuntat." -#: src/view/com/util/forms/PostDropdownBtn.tsx:221 +#: src/components/dialogs/MutedWords.tsx:236 +msgid "This will delete {0} from your muted words. You can always add it back later." +msgstr "" + +#: src/view/com/util/forms/PostDropdownBtn.tsx:237 msgid "This will hide this post from your feeds." msgstr "Això amagarà aquesta publicació dels teus canals." @@ -4154,6 +4290,10 @@ msgstr "Mode fils de debat" msgid "Threads Preferences" msgstr "Preferències dels fils de debat" +#: src/components/dialogs/MutedWords.tsx:95 +msgid "Toggle between muted word options." +msgstr "" + #: src/view/com/util/forms/DropdownButton.tsx:246 msgid "Toggle dropdown" msgstr "Commuta el menú desplegable" @@ -4162,9 +4302,9 @@ msgstr "Commuta el menú desplegable" msgid "Transformations" msgstr "Transformacions" -#: src/view/com/post-thread/PostThreadItem.tsx:679 -#: src/view/com/post-thread/PostThreadItem.tsx:681 -#: src/view/com/util/forms/PostDropdownBtn.tsx:154 +#: src/view/com/post-thread/PostThreadItem.tsx:685 +#: src/view/com/post-thread/PostThreadItem.tsx:687 +#: src/view/com/util/forms/PostDropdownBtn.tsx:156 msgid "Translate" msgstr "Tradueix" @@ -4233,15 +4373,24 @@ msgstr "No compleixes les condicions per crear un compte." msgid "Unlike" msgstr "Desfés el m'agrada" +#: src/components/TagMenu/index.tsx:253 #: src/view/screens/ProfileList.tsx:597 msgid "Unmute" msgstr "Deixa de silenciar" +#: src/components/TagMenu/index.web.tsx:90 +msgid "Unmute {truncatedTag}" +msgstr "" + #: src/view/com/profile/ProfileHeader.tsx:326 msgid "Unmute Account" msgstr "Deixa de silenciar el compte" -#: src/view/com/util/forms/PostDropdownBtn.tsx:200 +#: src/components/TagMenu/index.tsx:210 +msgid "Unmute all {tag} posts" +msgstr "" + +#: src/view/com/util/forms/PostDropdownBtn.tsx:202 msgid "Unmute thread" msgstr "Deixa de silenciar el fil de debat" @@ -4438,6 +4587,10 @@ msgstr "" msgid "We ran out of posts from your follows. Here's the latest from <0/>." msgstr "Ja no hi ha més publicacions dels usuaris que segueixes. Aquí n'hi ha altres de <0/>." +#: src/components/dialogs/MutedWords.tsx:161 +msgid "We recommend avoiding common words that appear in many posts, since it can result in no posts being shown." +msgstr "" + #: src/screens/Onboarding/StepAlgoFeeds/index.tsx:124 msgid "We recommend our \"Discover\" feed:" msgstr "" @@ -4466,7 +4619,11 @@ msgstr "Ens fa molta il·lusió que t'uneixis a nosaltres!" msgid "We're sorry, but we were unable to resolve this list. If this persists, please contact the list creator, @{handleOrDid}." msgstr "Ho sentim, però no hem pogut resoldre aquesta llista. Si això continua, posa't en contacte amb el creador de la llista, @{handleOrDid}." -#: src/view/screens/Search/Search.tsx:253 +#: src/components/dialogs/MutedWords.tsx:182 +msgid "We're sorry, but we weren't able to load your muted words at this time. Please try again." +msgstr "" + +#: src/view/screens/Search/Search.tsx:254 msgid "We're sorry, but your search could not be completed. Please try again in a few minutes." msgstr "Ens sap greu, però la teva cerca no s'ha pogut fer. Prova-ho d'aquí una estona." @@ -4490,7 +4647,7 @@ msgstr "Quin problema hi ha amb {collectionName}?" #~ msgstr "¿Qué sigue?" #: src/view/com/auth/SplashScreen.tsx:59 -#: src/view/com/composer/Composer.tsx:279 +#: src/view/com/composer/Composer.tsx:286 msgid "What's up?" msgstr "Què hi ha de nou" @@ -4511,11 +4668,11 @@ msgstr "Qui hi pot respondre" msgid "Wide" msgstr "Amplada" -#: src/view/com/composer/Composer.tsx:415 +#: src/view/com/composer/Composer.tsx:422 msgid "Write post" msgstr "Escriu una publicació" -#: src/view/com/composer/Composer.tsx:278 +#: src/view/com/composer/Composer.tsx:285 #: src/view/com/composer/Prompt.tsx:33 msgid "Write your reply" msgstr "Escriu la teva resposta" @@ -4576,7 +4733,7 @@ msgstr "No tens cap canal desat!" msgid "You don't have any saved feeds." msgstr "No tens cap canal desat." -#: src/view/com/post-thread/PostThread.tsx:464 +#: src/view/com/post-thread/PostThread.tsx:465 msgid "You have blocked the author or you have been blocked by the author." msgstr "Has bloquejat l'autor o has estat bloquejat per ell." @@ -4616,6 +4773,10 @@ msgstr "Encara no has creat cap contrasenya d'aplicació. Pots fer-ho amb el bot msgid "You have not muted any accounts yet. To mute an account, go to their profile and selected \"Mute account\" from the menu on their account." msgstr "Encara no has silenciat cap compte. Per fer-ho, vés al seu perfil i selecciona \"Silencia compte\" en el menú del seu compte." +#: src/components/dialogs/MutedWords.tsx:202 +msgid "You haven't muted any words or tags yet" +msgstr "" + #: src/view/com/modals/ContentFilteringSettings.tsx:175 msgid "You must be 18 or older to enable adult content." msgstr "Has de tenir 18 anys o més per habilitar el contingut per a adults." @@ -4624,11 +4785,11 @@ msgstr "Has de tenir 18 anys o més per habilitar el contingut per a adults." msgid "You must be 18 years or older to enable adult content" msgstr "" -#: src/view/com/util/forms/PostDropdownBtn.tsx:127 +#: src/view/com/util/forms/PostDropdownBtn.tsx:129 msgid "You will no longer receive notifications for this thread" msgstr "Ja no rebràs més notificacions d'aquest debat" -#: src/view/com/util/forms/PostDropdownBtn.tsx:130 +#: src/view/com/util/forms/PostDropdownBtn.tsx:132 msgid "You will now receive notifications for this thread" msgstr "Ara rebràs notificacions d'aquest debat" @@ -4718,11 +4879,15 @@ msgstr "El teu identificador complet serà <0>@{0}" #~ msgid "Your invite codes are hidden when logged in using an App Password" #~ msgstr "Els teus codis d'invitació no es mostren quan has iniciat sessió amb una contrasenya d'aplicació" +#: src/components/dialogs/MutedWords.tsx:173 +msgid "Your muted words" +msgstr "" + #: src/view/com/modals/ChangePassword.tsx:155 msgid "Your password has been changed successfully!" msgstr "" -#: src/view/com/composer/Composer.tsx:267 +#: src/view/com/composer/Composer.tsx:274 msgid "Your post has been published" msgstr "S'ha publicat" @@ -4737,7 +4902,7 @@ msgstr "Les teves publicacions, m'agrades i bloquejos són públics. Els comptes msgid "Your profile" msgstr "El teu perfil" -#: src/view/com/composer/Composer.tsx:266 +#: src/view/com/composer/Composer.tsx:273 msgid "Your reply has been published" msgstr "S'ha publicat a teva resposta" diff --git a/src/locale/locales/de/messages.po b/src/locale/locales/de/messages.po index a4b0a8cb..1c418803 100644 --- a/src/locale/locales/de/messages.po +++ b/src/locale/locales/de/messages.po @@ -76,7 +76,7 @@ msgid "A new version of the app is available. Please update to continue using th msgstr "Eine neue Version der App ist verfügbar. Bitte aktualisiere die App, um sie weiter nutzen zu können." #: src/view/com/util/ViewHeader.tsx:83 -#: src/view/screens/Search/Search.tsx:624 +#: src/view/screens/Search/Search.tsx:647 msgid "Access navigation links and settings" msgstr "" @@ -127,6 +127,7 @@ msgstr "" msgid "Account unmuted" msgstr "" +#: src/components/dialogs/MutedWords.tsx:147 #: src/view/com/auth/onboarding/RecommendedFeedsItem.tsx:150 #: src/view/com/modals/ListAddRemoveUsers.tsx:264 #: src/view/com/modals/UserAddRemoveLists.tsx:219 @@ -168,14 +169,22 @@ msgstr "Details hinzufügen" msgid "Add details to report" msgstr "Details zum Report hinzufügen" -#: src/view/com/composer/Composer.tsx:446 +#: src/view/com/composer/Composer.tsx:453 msgid "Add link card" msgstr "Link-Karte hinzufügen" -#: src/view/com/composer/Composer.tsx:451 +#: src/view/com/composer/Composer.tsx:458 msgid "Add link card:" msgstr "Link-Karte hinzufügen:" +#: src/components/dialogs/MutedWords.tsx:140 +msgid "Add mute word for configured settings" +msgstr "" + +#: src/components/dialogs/MutedWords.tsx:74 +msgid "Add muted words and tags" +msgstr "" + #: src/view/com/modals/ChangeHandle.tsx:417 msgid "Add the following DNS record to your domain:" msgstr "Füge den folgenden DNS-Eintrag zu deiner Domain hinzu:" @@ -299,7 +308,7 @@ msgstr "" msgid "App Passwords" msgstr "App-Passwörter" -#: src/view/com/util/forms/PostDropdownBtn.tsx:279 +#: src/view/com/util/forms/PostDropdownBtn.tsx:295 msgid "Appeal content warning" msgstr "" @@ -323,15 +332,16 @@ msgstr "Erscheinungsbild" msgid "Are you sure you want to delete the app password \"{name}\"?" msgstr "Bist du sicher, dass du das App-Passwort \"{name}\" löschen möchtest?" -#: src/view/com/composer/Composer.tsx:143 +#: src/view/com/composer/Composer.tsx:150 msgid "Are you sure you'd like to discard this draft?" msgstr "Bist du sicher, dass du diesen Entwurf verwerfen möchtest?" +#: src/components/dialogs/MutedWords.tsx:233 #: src/view/screens/ProfileList.tsx:365 msgid "Are you sure?" msgstr "Bist du sicher?" -#: src/view/com/util/forms/PostDropdownBtn.tsx:262 +#: src/view/com/util/forms/PostDropdownBtn.tsx:278 msgid "Are you sure? This cannot be undone." msgstr "Bist du sicher? Dies kann nicht rückgängig gemacht werden." @@ -353,15 +363,15 @@ msgstr "Künstlerische oder nicht-erotische Nacktheit." #: src/view/com/auth/login/LoginForm.tsx:259 #: src/view/com/auth/login/SetNewPasswordForm.tsx:179 #: src/view/com/modals/report/InputIssueDetails.tsx:46 -#: src/view/com/post-thread/PostThread.tsx:471 -#: src/view/com/post-thread/PostThread.tsx:521 -#: src/view/com/post-thread/PostThread.tsx:529 +#: src/view/com/post-thread/PostThread.tsx:472 +#: src/view/com/post-thread/PostThread.tsx:522 +#: src/view/com/post-thread/PostThread.tsx:530 #: src/view/com/profile/ProfileHeader.tsx:649 #: src/view/com/util/ViewHeader.tsx:81 msgid "Back" msgstr "Zurück" -#: src/view/com/post-thread/PostThread.tsx:479 +#: src/view/com/post-thread/PostThread.tsx:480 msgctxt "action" msgid "Back" msgstr "" @@ -409,7 +419,7 @@ msgstr "" msgid "Blocked" msgstr "" -#: src/view/screens/Moderation.tsx:123 +#: src/view/screens/Moderation.tsx:142 msgid "Blocked accounts" msgstr "Blockierte Konten" @@ -468,7 +478,7 @@ msgstr "Bluesky ist öffentlich." msgid "Bluesky uses invites to build a healthier community. If you don't know anybody with an invite, you can sign up for the waitlist and we'll send one soon." msgstr "Bluesky nutzt Einladungen, um eine gesündere Community aufzubauen. Wenn du niemanden kennst, der eine Einladung hat, kannst du dich auf die Warteliste setzen lassen und wir schicken dir bald eine zu." -#: src/view/screens/Moderation.tsx:226 +#: src/view/screens/Moderation.tsx:245 msgid "Bluesky will not show your profile and posts to logged-out users. Other apps may not honor this request. This does not make your account private." msgstr "Bluesky zeigt dein Profil und deine Beiträge nicht für abgemeldete Nutzer an. Andere Apps kommen dieser Aufforderung möglicherweise nicht nach." @@ -520,8 +530,8 @@ msgid "Can only contain letters, numbers, spaces, dashes, and underscores. Must msgstr "Darf nur Buchstaben, Zahlen, Leerzeichen, Bindestriche und Unterstriche enthalten. Muss mindestens 4 Zeichen lang sein, darf aber nicht länger als 32 Zeichen sein." #: src/components/Prompt.tsx:91 -#: src/view/com/composer/Composer.tsx:300 -#: src/view/com/composer/Composer.tsx:305 +#: src/view/com/composer/Composer.tsx:307 +#: src/view/com/composer/Composer.tsx:312 #: src/view/com/modals/ChangeEmail.tsx:218 #: src/view/com/modals/ChangeEmail.tsx:220 #: src/view/com/modals/ChangePassword.tsx:265 @@ -535,7 +545,7 @@ msgstr "Darf nur Buchstaben, Zahlen, Leerzeichen, Bindestriche und Unterstriche #: src/view/com/modals/VerifyEmail.tsx:247 #: src/view/com/modals/VerifyEmail.tsx:253 #: src/view/com/modals/Waitlist.tsx:142 -#: src/view/screens/Search/Search.tsx:693 +#: src/view/screens/Search/Search.tsx:716 #: src/view/shell/desktop/Search.tsx:238 msgid "Cancel" msgstr "Abbrechen" @@ -686,7 +696,7 @@ msgid "Clear all storage data (restart after this)" msgstr "Alle Speicherdaten löschen (danach neu starten)" #: src/view/com/util/forms/SearchInput.tsx:88 -#: src/view/screens/Search/Search.tsx:674 +#: src/view/screens/Search/Search.tsx:697 msgid "Clear search query" msgstr "Suchanfrage löschen" @@ -694,6 +704,11 @@ msgstr "Suchanfrage löschen" msgid "click here" msgstr "" +#: src/components/RichText.tsx:189 +#: src/components/TagMenu/index.web.tsx:125 +msgid "Click here to open tag menu for {tag}" +msgstr "" + #: src/screens/Onboarding/index.tsx:35 msgid "Climate" msgstr "" @@ -724,11 +739,15 @@ msgstr "Bild schließen" msgid "Close image viewer" msgstr "" -#: src/view/shell/index.web.tsx:49 +#: src/view/shell/index.web.tsx:51 msgid "Close navigation footer" msgstr "" -#: src/view/shell/index.web.tsx:50 +#: src/components/TagMenu/index.tsx:266 +msgid "Close this dialog" +msgstr "" + +#: src/view/shell/index.web.tsx:52 msgid "Closes bottom navigation bar" msgstr "" @@ -736,7 +755,7 @@ msgstr "" msgid "Closes password update alert" msgstr "" -#: src/view/com/composer/Composer.tsx:302 +#: src/view/com/composer/Composer.tsx:309 msgid "Closes post composer and discards post draft" msgstr "" @@ -769,7 +788,7 @@ msgstr "" msgid "Complete the challenge" msgstr "" -#: src/view/com/composer/Composer.tsx:417 +#: src/view/com/composer/Composer.tsx:424 msgid "Compose posts up to {MAX_GRAPHEME_LENGTH} characters in length" msgstr "" @@ -833,7 +852,7 @@ msgstr "Verbinden..." msgid "Contact support" msgstr "" -#: src/view/screens/Moderation.tsx:81 +#: src/view/screens/Moderation.tsx:83 msgid "Content filtering" msgstr "Inhaltsfilterung" @@ -899,7 +918,7 @@ msgstr "" #: src/view/com/modals/AddAppPasswords.tsx:76 #: src/view/com/modals/InviteCodes.tsx:152 -#: src/view/com/util/forms/PostDropdownBtn.tsx:141 +#: src/view/com/util/forms/PostDropdownBtn.tsx:143 msgid "Copied to clipboard" msgstr "" @@ -915,7 +934,7 @@ msgstr "Kopieren" msgid "Copy link to list" msgstr "Link zur Liste kopieren" -#: src/view/com/util/forms/PostDropdownBtn.tsx:182 +#: src/view/com/util/forms/PostDropdownBtn.tsx:184 msgid "Copy link to post" msgstr "Link zum Beitrag kopieren" @@ -923,7 +942,7 @@ msgstr "Link zum Beitrag kopieren" msgid "Copy link to profile" msgstr "Link zum Profil kopieren" -#: src/view/com/util/forms/PostDropdownBtn.tsx:168 +#: src/view/com/util/forms/PostDropdownBtn.tsx:170 msgid "Copy post text" msgstr "" @@ -979,7 +998,7 @@ msgstr "" msgid "Created by you" msgstr "" -#: src/view/com/composer/Composer.tsx:448 +#: src/view/com/composer/Composer.tsx:455 msgid "Creates a card with a thumbnail. The card links to {url}" msgstr "" @@ -1056,11 +1075,11 @@ msgstr "Mein Konto löschen" msgid "Delete My Account…" msgstr "" -#: src/view/com/util/forms/PostDropdownBtn.tsx:257 +#: src/view/com/util/forms/PostDropdownBtn.tsx:273 msgid "Delete post" msgstr "Beitrag löschen" -#: src/view/com/util/forms/PostDropdownBtn.tsx:261 +#: src/view/com/util/forms/PostDropdownBtn.tsx:277 msgid "Delete this post?" msgstr "Diesen Beitrag löschen?" @@ -1083,7 +1102,7 @@ msgstr "Beschreibung" #~ msgid "Developer Tools" #~ msgstr "Entwickler-Tools" -#: src/view/com/composer/Composer.tsx:211 +#: src/view/com/composer/Composer.tsx:218 msgid "Did you want to say anything?" msgstr "" @@ -1091,15 +1110,15 @@ msgstr "" msgid "Dim" msgstr "" -#: src/view/com/composer/Composer.tsx:144 +#: src/view/com/composer/Composer.tsx:151 msgid "Discard" msgstr "Verwerfen" -#: src/view/com/composer/Composer.tsx:138 +#: src/view/com/composer/Composer.tsx:145 msgid "Discard draft" msgstr "Entwurf verwerfen" -#: src/view/screens/Moderation.tsx:207 +#: src/view/screens/Moderation.tsx:226 msgid "Discourage apps from showing my account to logged-out users" msgstr "Apps daran hindern, abgemeldeten Nutzern mein Konto zu zeigen" @@ -1178,7 +1197,7 @@ msgstr "" msgid "Download CAR file" msgstr "" -#: src/view/com/composer/text-input/TextInput.web.tsx:247 +#: src/view/com/composer/text-input/TextInput.web.tsx:249 msgid "Drop to add images" msgstr "" @@ -1250,6 +1269,7 @@ msgstr "Profil bearbeiten" msgid "Edit Profile" msgstr "Profil bearbeiten" +#: src/view/com/home/HomeHeaderLayout.web.tsx:59 #: src/view/screens/Feeds.tsx:355 msgid "Edit Saved Feeds" msgstr "Gespeicherte Feeds bearbeiten" @@ -1332,6 +1352,11 @@ msgstr "Ende des Feeds" msgid "Enter a name for this App Password" msgstr "" +#: src/components/dialogs/MutedWords.tsx:87 +#: src/components/dialogs/MutedWords.tsx:88 +msgid "Enter a word or tag" +msgstr "" + #: src/view/com/modals/VerifyEmail.tsx:105 msgid "Enter Confirmation Code" msgstr "" @@ -1381,7 +1406,7 @@ msgstr "Gib deinen Benutzernamen und dein Passwort ein" msgid "Error receiving captcha response." msgstr "" -#: src/view/screens/Search/Search.tsx:109 +#: src/view/screens/Search/Search.tsx:110 msgid "Error:" msgstr "Fehler:" @@ -1452,7 +1477,7 @@ msgstr "" msgid "Failed to create the list. Check your internet connection and try again." msgstr "" -#: src/view/com/util/forms/PostDropdownBtn.tsx:108 +#: src/view/com/util/forms/PostDropdownBtn.tsx:110 msgid "Failed to delete post, please try again" msgstr "" @@ -1474,8 +1499,8 @@ msgid "Feed offline" msgstr "Feed offline" #: src/view/com/feeds/FeedPage.tsx:143 -msgid "Feed Preferences" -msgstr "Feed-Einstellungen" +#~ msgid "Feed Preferences" +#~ msgstr "Feed-Einstellungen" #: src/view/shell/desktop/RightNav.tsx:61 #: src/view/shell/Drawer.tsx:311 @@ -1523,11 +1548,11 @@ msgstr "" msgid "Find accounts to follow" msgstr "" -#: src/view/screens/Search/Search.tsx:439 +#: src/view/screens/Search/Search.tsx:440 msgid "Find users on Bluesky" msgstr "Nutzer auf Bluesky finden" -#: src/view/screens/Search/Search.tsx:437 +#: src/view/screens/Search/Search.tsx:438 msgid "Find users with the search tool on the right" msgstr "Finde Nutzer mit der Suchfunktion auf der rechten Seite" @@ -1624,6 +1649,7 @@ msgid "Following {0}" msgstr "" #: src/Navigation.tsx:248 +#: src/view/com/home/HomeHeaderLayout.web.tsx:45 #: src/view/com/home/HomeHeaderLayoutMobile.tsx:83 #: src/view/screens/PreferencesFollowingFeed.tsx:104 #: src/view/screens/Settings/index.tsx:543 @@ -1663,7 +1689,7 @@ msgstr "Passwort vergessen" msgid "Forgot Password" msgstr "Passwort vergessen" -#: src/view/com/posts/FeedItem.tsx:187 +#: src/view/com/posts/FeedItem.tsx:189 msgctxt "from-feed" msgid "From <0/>" msgstr "" @@ -1696,7 +1722,7 @@ msgstr "Gehe zurück" msgid "Go back to previous step" msgstr "" -#: src/view/screens/Search/Search.tsx:724 +#: src/view/screens/Search/Search.tsx:747 #: src/view/shell/desktop/Search.tsx:262 msgid "Go to @{queryMaybeHandle}" msgstr "" @@ -1713,6 +1739,10 @@ msgstr "Gehe zum nächsten" msgid "Handle" msgstr "Handle" +#: src/components/RichText.tsx:188 +msgid "Hashtag: {tag}" +msgstr "" + #: src/view/com/auth/create/CreateAccount.tsx:208 msgid "Having trouble?" msgstr "" @@ -1751,7 +1781,7 @@ msgctxt "action" msgid "Hide" msgstr "" -#: src/view/com/util/forms/PostDropdownBtn.tsx:216 +#: src/view/com/util/forms/PostDropdownBtn.tsx:232 msgid "Hide post" msgstr "Beitrag ausblenden" @@ -1760,7 +1790,7 @@ msgstr "Beitrag ausblenden" msgid "Hide the content" msgstr "" -#: src/view/com/util/forms/PostDropdownBtn.tsx:220 +#: src/view/com/util/forms/PostDropdownBtn.tsx:236 msgid "Hide this post?" msgstr "Diesen Beitrag ausblenden?" @@ -1909,7 +1939,7 @@ msgstr "" msgid "Input your user handle" msgstr "" -#: src/view/com/post-thread/PostThreadItem.tsx:224 +#: src/view/com/post-thread/PostThreadItem.tsx:226 msgid "Invalid or unsupported post record" msgstr "" @@ -2011,7 +2041,7 @@ msgstr "Mehr erfahren" msgid "Learn more about this warning" msgstr "Erfahre mehr über diese Warnung" -#: src/view/screens/Moderation.tsx:243 +#: src/view/screens/Moderation.tsx:262 msgid "Learn more about what is public on Bluesky." msgstr "Erfahre mehr darüber, was auf Bluesky öffentlich ist." @@ -2087,7 +2117,7 @@ msgstr "" msgid "Likes" msgstr "" -#: src/view/com/post-thread/PostThreadItem.tsx:181 +#: src/view/com/post-thread/PostThreadItem.tsx:183 msgid "Likes on this post" msgstr "" @@ -2144,7 +2174,7 @@ msgstr "Mehr Beiträge laden" msgid "Load new notifications" msgstr "Neue Benachrichtigungen laden" -#: src/view/com/feeds/FeedPage.tsx:181 +#: src/view/com/feeds/FeedPage.tsx:115 #: src/view/screens/Profile.tsx:440 #: src/view/screens/ProfileFeed.tsx:495 #: src/view/screens/ProfileList.tsx:681 @@ -2170,7 +2200,7 @@ msgstr "" msgid "Log out" msgstr "" -#: src/view/screens/Moderation.tsx:136 +#: src/view/screens/Moderation.tsx:155 msgid "Logged-out visibility" msgstr "" @@ -2182,6 +2212,10 @@ msgstr "Anmeldung bei einem Konto, das nicht aufgelistet ist" msgid "Make sure this is where you intend to go!" msgstr "Vergewissere dich, dass du auch wirklich dorthin gehen willst!" +#: src/components/dialogs/MutedWords.tsx:71 +msgid "Manage your muted words and tags" +msgstr "" + #: src/view/com/auth/create/Step2.tsx:118 msgid "May not be longer than 253 characters" msgstr "" @@ -2203,7 +2237,7 @@ msgid "Mentioned users" msgstr "Erwähnte Benutzer" #: src/view/com/util/ViewHeader.tsx:81 -#: src/view/screens/Search/Search.tsx:623 +#: src/view/screens/Search/Search.tsx:646 msgid "Menu" msgstr "Menü" @@ -2212,7 +2246,7 @@ msgid "Message from server: {0}" msgstr "Nachricht vom Server: {0}" #: src/Navigation.tsx:115 -#: src/view/screens/Moderation.tsx:64 +#: src/view/screens/Moderation.tsx:66 #: src/view/screens/Settings/index.tsx:625 #: src/view/shell/desktop/LeftNav.tsx:397 #: src/view/shell/Drawer.tsx:511 @@ -2243,7 +2277,7 @@ msgstr "" msgid "Moderation list updated" msgstr "" -#: src/view/screens/Moderation.tsx:95 +#: src/view/screens/Moderation.tsx:114 msgid "Moderation lists" msgstr "Moderationslisten" @@ -2270,7 +2304,7 @@ msgstr "Mehr Feeds" msgid "More options" msgstr "Mehr Optionen" -#: src/view/com/util/forms/PostDropdownBtn.tsx:299 +#: src/view/com/util/forms/PostDropdownBtn.tsx:315 msgid "More post options" msgstr "" @@ -2282,6 +2316,14 @@ msgstr "" msgid "Must be at least 3 characters" msgstr "" +#: src/components/TagMenu/index.tsx:253 +msgid "Mute" +msgstr "" + +#: src/components/TagMenu/index.web.tsx:91 +msgid "Mute {truncatedTag}" +msgstr "" + #: src/view/com/profile/ProfileHeader.tsx:327 msgid "Mute Account" msgstr "Konto stummschalten" @@ -2290,6 +2332,18 @@ msgstr "Konto stummschalten" msgid "Mute accounts" msgstr "Konten stummschalten" +#: src/components/TagMenu/index.tsx:211 +msgid "Mute all {tag} posts" +msgstr "" + +#: src/components/dialogs/MutedWords.tsx:131 +msgid "Mute in tags only" +msgstr "" + +#: src/components/dialogs/MutedWords.tsx:116 +msgid "Mute in text & tags" +msgstr "" + #: src/view/screens/ProfileList.tsx:491 msgid "Mute list" msgstr "" @@ -2302,15 +2356,27 @@ msgstr "Diese Konten stummschalten?" msgid "Mute this List" msgstr "" -#: src/view/com/util/forms/PostDropdownBtn.tsx:200 +#: src/components/dialogs/MutedWords.tsx:109 +msgid "Mute this word in post text and tags" +msgstr "" + +#: src/components/dialogs/MutedWords.tsx:124 +msgid "Mute this word in tags only" +msgstr "" + +#: src/view/com/util/forms/PostDropdownBtn.tsx:202 msgid "Mute thread" msgstr "Thread stummschalten" +#: src/view/com/util/forms/PostDropdownBtn.tsx:216 +msgid "Mute words & tags" +msgstr "" + #: src/view/com/lists/ListCard.tsx:102 msgid "Muted" msgstr "" -#: src/view/screens/Moderation.tsx:109 +#: src/view/screens/Moderation.tsx:128 msgid "Muted accounts" msgstr "Stummgeschaltete Konten" @@ -2323,6 +2389,10 @@ msgstr "Stummgeschaltete Konten" msgid "Muted accounts have their posts removed from your feed and from your notifications. Mutes are completely private." msgstr "Bei stummgeschalteten Konten werden ihre Beiträge aus deinem Feed und deinen Benachrichtigungen entfernt. Stummschaltungen sind völlig privat." +#: src/view/screens/Moderation.tsx:100 +msgid "Muted words & tags" +msgstr "" + #: src/view/screens/ProfileList.tsx:277 msgid "Muting is private. Muted accounts can interact with you, but you will not see their posts or receive notifications from them." msgstr "Stummschaltung ist privat. Stummgeschaltete Konten können mit dir interagieren, aber du siehst ihre Beiträge nicht und erhältst keine Benachrichtigungen von ihnen." @@ -2386,6 +2456,10 @@ msgstr "Verliere nie den Zugriff auf deine Follower und Daten." msgid "Never lose access to your followers or data." msgstr "" +#: src/components/dialogs/MutedWords.tsx:244 +msgid "Nevermind" +msgstr "" + #: src/view/screens/Lists.tsx:76 msgctxt "action" msgid "New" @@ -2407,7 +2481,7 @@ msgstr "" msgid "New Password" msgstr "" -#: src/view/com/feeds/FeedPage.tsx:192 +#: src/view/com/feeds/FeedPage.tsx:126 msgctxt "action" msgid "New post" msgstr "" @@ -2492,8 +2566,8 @@ msgid "No results found for \"{query}\"" msgstr "Keine Ergebnisse für \"{query}\" gefunden" #: src/view/com/modals/ListAddRemoveUsers.tsx:127 -#: src/view/screens/Search/Search.tsx:280 -#: src/view/screens/Search/Search.tsx:308 +#: src/view/screens/Search/Search.tsx:281 +#: src/view/screens/Search/Search.tsx:309 msgid "No results found for {query}" msgstr "Keine Ergebnisse für {query} gefunden" @@ -2519,7 +2593,7 @@ msgstr "" msgid "Not right now" msgstr "" -#: src/view/screens/Moderation.tsx:233 +#: src/view/screens/Moderation.tsx:252 msgid "Note: Bluesky is an open and public network. This setting only limits the visibility of your content on the Bluesky app and website, and other apps may not respect this setting. Your content may still be shown to logged-out users by other apps and websites." msgstr "Hinweis: Bluesky ist ein offenes und öffentliches Netzwerk. Diese Einstellung schränkt lediglich die Sichtbarkeit deiner Inhalte in der Bluesky-App und auf der Website ein. Andere Apps respektieren diese Einstellung möglicherweise nicht. Deine Inhalte werden abgemeldeten Nutzern möglicherweise weiterhin in anderen Apps und Websites angezeigt." @@ -2557,7 +2631,7 @@ msgstr "" msgid "Onboarding reset" msgstr "" -#: src/view/com/composer/Composer.tsx:375 +#: src/view/com/composer/Composer.tsx:382 msgid "One or more images is missing alt text." msgstr "Bei einem oder mehreren Bildern fehlt der Alt-Text." @@ -2574,8 +2648,12 @@ msgstr "" msgid "Open" msgstr "" -#: src/view/com/composer/Composer.tsx:470 -#: src/view/com/composer/Composer.tsx:471 +#: src/view/screens/Moderation.tsx:75 +msgid "Open content filtering settings" +msgstr "" + +#: src/view/com/composer/Composer.tsx:477 +#: src/view/com/composer/Composer.tsx:478 msgid "Open emoji picker" msgstr "" @@ -2583,6 +2661,10 @@ msgstr "" msgid "Open links with in-app browser" msgstr "" +#: src/view/screens/Moderation.tsx:92 +msgid "Open muted words settings" +msgstr "" + #: src/view/com/home/HomeHeaderLayoutMobile.tsx:49 msgid "Open navigation" msgstr "Navigation öffnen" @@ -2659,6 +2741,7 @@ msgstr "Öffnet die Moderationseinstellungen" msgid "Opens password reset form" msgstr "" +#: src/view/com/home/HomeHeaderLayout.web.tsx:60 #: src/view/screens/Feeds.tsx:356 msgid "Opens screen to edit Saved Feeds" msgstr "" @@ -2834,7 +2917,7 @@ msgstr "Bitte teile uns mit, warum du denkst, dass diese Inhaltswarnung falsch a msgid "Please Verify Your Email" msgstr "" -#: src/view/com/composer/Composer.tsx:215 +#: src/view/com/composer/Composer.tsx:222 msgid "Please wait for your link card to finish loading" msgstr "" @@ -2846,8 +2929,8 @@ msgstr "" msgid "Porn" msgstr "" -#: src/view/com/composer/Composer.tsx:350 -#: src/view/com/composer/Composer.tsx:358 +#: src/view/com/composer/Composer.tsx:357 +#: src/view/com/composer/Composer.tsx:365 msgctxt "action" msgid "Post" msgstr "" @@ -2857,7 +2940,7 @@ msgctxt "description" msgid "Post" msgstr "Beitrag" -#: src/view/com/post-thread/PostThreadItem.tsx:173 +#: src/view/com/post-thread/PostThreadItem.tsx:175 msgid "Post by {0}" msgstr "" @@ -2867,11 +2950,11 @@ msgstr "" msgid "Post by @{0}" msgstr "" -#: src/view/com/util/forms/PostDropdownBtn.tsx:88 +#: src/view/com/util/forms/PostDropdownBtn.tsx:90 msgid "Post deleted" msgstr "" -#: src/view/com/post-thread/PostThread.tsx:461 +#: src/view/com/post-thread/PostThread.tsx:462 msgid "Post hidden" msgstr "Beitrag ausgeblendet" @@ -2883,14 +2966,22 @@ msgstr "Beitragssprache" msgid "Post Languages" msgstr "Beitragssprachen" -#: src/view/com/post-thread/PostThread.tsx:513 +#: src/view/com/post-thread/PostThread.tsx:514 msgid "Post not found" msgstr "Beitrag nicht gefunden" +#: src/components/TagMenu/index.tsx:257 +msgid "posts" +msgstr "" + #: src/view/screens/Profile.tsx:180 msgid "Posts" msgstr "Beiträge" +#: src/components/dialogs/MutedWords.tsx:77 +msgid "Posts can be muted based on their text, their tags, or both." +msgstr "" + #: src/view/com/posts/FeedErrorMessage.tsx:64 msgid "Posts hidden" msgstr "" @@ -2955,11 +3046,11 @@ msgstr "Öffentliche, gemeinsam nutzbare Listen von Nutzern, die du stummschalte msgid "Public, shareable lists which can drive feeds." msgstr "Öffentliche, gemeinsam nutzbare Listen, die Feeds steuern können." -#: src/view/com/composer/Composer.tsx:335 +#: src/view/com/composer/Composer.tsx:342 msgid "Publish post" msgstr "" -#: src/view/com/composer/Composer.tsx:335 +#: src/view/com/composer/Composer.tsx:342 msgid "Publish reply" msgstr "" @@ -2993,6 +3084,7 @@ msgstr "Empfohlene Feeds" msgid "Recommended Users" msgstr "Empfohlene Nutzer" +#: src/components/dialogs/MutedWords.tsx:249 #: src/view/com/modals/ListAddRemoveUsers.tsx:264 #: src/view/com/modals/SelfLabel.tsx:83 #: src/view/com/modals/UserAddRemoveLists.tsx:219 @@ -3030,6 +3122,10 @@ msgstr "Bild entfernen" msgid "Remove image preview" msgstr "Bildvorschau entfernen" +#: src/components/dialogs/MutedWords.tsx:294 +msgid "Remove mute word from your list" +msgstr "" + #: src/view/com/modals/Repost.tsx:47 msgid "Remove repost" msgstr "" @@ -3064,7 +3160,7 @@ msgstr "Antworten" msgid "Replies to this thread are disabled" msgstr "Antworten auf diesen Thread sind deaktiviert" -#: src/view/com/composer/Composer.tsx:348 +#: src/view/com/composer/Composer.tsx:355 msgctxt "action" msgid "Reply" msgstr "" @@ -3074,7 +3170,7 @@ msgid "Reply Filters" msgstr "Antwortfilter" #: src/view/com/post/Post.tsx:167 -#: src/view/com/posts/FeedItem.tsx:285 +#: src/view/com/posts/FeedItem.tsx:287 msgctxt "description" msgid "Reply to <0/>" msgstr "" @@ -3096,7 +3192,7 @@ msgid "Report List" msgstr "Liste melden" #: src/view/com/modals/report/SendReportButton.tsx:37 -#: src/view/com/util/forms/PostDropdownBtn.tsx:239 +#: src/view/com/util/forms/PostDropdownBtn.tsx:255 msgid "Report post" msgstr "Beitrag melden" @@ -3121,11 +3217,11 @@ msgstr "" msgid "Reposted By" msgstr "" -#: src/view/com/posts/FeedItem.tsx:205 +#: src/view/com/posts/FeedItem.tsx:207 msgid "Reposted by {0}" msgstr "" -#: src/view/com/posts/FeedItem.tsx:222 +#: src/view/com/posts/FeedItem.tsx:224 msgid "Reposted by <0/>" msgstr "" @@ -3133,7 +3229,7 @@ msgstr "" msgid "reposted your post" msgstr "" -#: src/view/com/post-thread/PostThreadItem.tsx:186 +#: src/view/com/post-thread/PostThreadItem.tsx:188 msgid "Reposts of this post" msgstr "" @@ -3284,9 +3380,9 @@ msgstr "" #: src/view/com/modals/ListAddRemoveUsers.tsx:75 #: src/view/com/util/forms/SearchInput.tsx:67 #: src/view/com/util/forms/SearchInput.tsx:79 -#: src/view/screens/Search/Search.tsx:418 -#: src/view/screens/Search/Search.tsx:645 -#: src/view/screens/Search/Search.tsx:663 +#: src/view/screens/Search/Search.tsx:419 +#: src/view/screens/Search/Search.tsx:668 +#: src/view/screens/Search/Search.tsx:686 #: src/view/shell/bottom-bar/BottomBar.tsx:159 #: src/view/shell/desktop/LeftNav.tsx:324 #: src/view/shell/desktop/Search.tsx:214 @@ -3296,11 +3392,19 @@ msgstr "" msgid "Search" msgstr "Suche" -#: src/view/screens/Search/Search.tsx:712 +#: src/view/screens/Search/Search.tsx:735 #: src/view/shell/desktop/Search.tsx:255 msgid "Search for \"{query}\"" msgstr "" +#: src/components/TagMenu/index.tsx:145 +msgid "Search for all posts by @{authorHandle} with tag {tag}" +msgstr "" + +#: src/components/TagMenu/index.tsx:90 +msgid "Search for all posts with tag {tag}" +msgstr "" + #: src/view/com/auth/LoggedOut.tsx:104 #: src/view/com/auth/LoggedOut.tsx:105 #: src/view/com/modals/ListAddRemoveUsers.tsx:70 @@ -3311,6 +3415,22 @@ msgstr "Nach Nutzern suchen" msgid "Security Step Required" msgstr "Sicherheitsschritt erforderlich" +#: src/components/TagMenu/index.web.tsx:50 +msgid "See {truncatedTag} posts" +msgstr "" + +#: src/components/TagMenu/index.web.tsx:67 +msgid "See {truncatedTag} posts by user" +msgstr "" + +#: src/components/TagMenu/index.tsx:128 +msgid "See <0>{tag} posts" +msgstr "" + +#: src/components/TagMenu/index.tsx:189 +msgid "See <0>{tag} posts by this user" +msgstr "" + #: src/view/screens/SavedFeeds.tsx:163 msgid "See this guide" msgstr "" @@ -3520,7 +3640,7 @@ msgid "Share" msgstr "" #: src/view/com/profile/ProfileHeader.tsx:295 -#: src/view/com/util/forms/PostDropdownBtn.tsx:182 +#: src/view/com/util/forms/PostDropdownBtn.tsx:184 #: src/view/screens/ProfileList.tsx:418 msgid "Share" msgstr "Teilen" @@ -3553,9 +3673,9 @@ msgstr "" msgid "Show follows similar to {0}" msgstr "" -#: src/view/com/post-thread/PostThreadItem.tsx:532 -#: src/view/com/post/Post.tsx:196 -#: src/view/com/posts/FeedItem.tsx:359 +#: src/view/com/post-thread/PostThreadItem.tsx:538 +#: src/view/com/post/Post.tsx:198 +#: src/view/com/posts/FeedItem.tsx:363 msgid "Show More" msgstr "" @@ -3723,7 +3843,7 @@ msgstr "" msgid "Something went wrong. Check your email and try again." msgstr "" -#: src/App.native.tsx:61 +#: src/App.native.tsx:63 msgid "Sorry! Your session expired. Please log in again." msgstr "" @@ -3781,7 +3901,7 @@ msgstr "" msgid "Subscribe to this list" msgstr "Abonniere diese Liste" -#: src/view/screens/Search/Search.tsx:373 +#: src/view/screens/Search/Search.tsx:374 msgid "Suggested Follows" msgstr "Vorgeschlagene Follower" @@ -3825,6 +3945,14 @@ msgstr "" msgid "System log" msgstr "Systemprotokoll" +#: src/components/dialogs/MutedWords.tsx:288 +msgid "tag" +msgstr "" + +#: src/components/TagMenu/index.tsx:74 +msgid "Tag menu: {tag}" +msgstr "" + #: src/view/com/modals/crop-image/CropImage.web.tsx:112 msgid "Tall" msgstr "Groß" @@ -3848,6 +3976,10 @@ msgstr "Bedingungen" msgid "Terms of Service" msgstr "Nutzungsbedingungen" +#: src/components/dialogs/MutedWords.tsx:288 +msgid "text" +msgstr "" + #: src/view/com/modals/AppealLabel.tsx:70 #: src/view/com/modals/report/InputIssueDetails.tsx:51 msgid "Text input field" @@ -3873,7 +4005,7 @@ msgstr "" msgid "The following steps will help customize your Bluesky experience." msgstr "" -#: src/view/com/post-thread/PostThread.tsx:516 +#: src/view/com/post-thread/PostThread.tsx:517 msgid "The post may have been deleted." msgstr "Möglicherweise wurde der Post gelöscht." @@ -4039,7 +4171,7 @@ msgstr "" msgid "This name is already in use" msgstr "" -#: src/view/com/post-thread/PostThreadItem.tsx:123 +#: src/view/com/post-thread/PostThreadItem.tsx:125 msgid "This post has been deleted." msgstr "Dieser Beitrag wurde gelöscht." @@ -4063,7 +4195,11 @@ msgstr "" msgid "This warning is only available for posts with media attached." msgstr "Diese Warnung ist nur für Beiträge mit angehängten Medien verfügbar." -#: src/view/com/util/forms/PostDropdownBtn.tsx:221 +#: src/components/dialogs/MutedWords.tsx:236 +msgid "This will delete {0} from your muted words. You can always add it back later." +msgstr "" + +#: src/view/com/util/forms/PostDropdownBtn.tsx:237 msgid "This will hide this post from your feeds." msgstr "Dadurch wird dieser Beitrag aus deinen Feeds ausgeblendet." @@ -4080,6 +4216,10 @@ msgstr "" msgid "Threads Preferences" msgstr "" +#: src/components/dialogs/MutedWords.tsx:95 +msgid "Toggle between muted word options." +msgstr "" + #: src/view/com/util/forms/DropdownButton.tsx:246 msgid "Toggle dropdown" msgstr "" @@ -4088,9 +4228,9 @@ msgstr "" msgid "Transformations" msgstr "" -#: src/view/com/post-thread/PostThreadItem.tsx:679 -#: src/view/com/post-thread/PostThreadItem.tsx:681 -#: src/view/com/util/forms/PostDropdownBtn.tsx:154 +#: src/view/com/post-thread/PostThreadItem.tsx:685 +#: src/view/com/post-thread/PostThreadItem.tsx:687 +#: src/view/com/util/forms/PostDropdownBtn.tsx:156 msgid "Translate" msgstr "Übersetzen" @@ -4155,15 +4295,24 @@ msgstr "Leider erfüllst du nicht die Voraussetzungen, um einen Account zu erste msgid "Unlike" msgstr "" +#: src/components/TagMenu/index.tsx:253 #: src/view/screens/ProfileList.tsx:597 msgid "Unmute" msgstr "" +#: src/components/TagMenu/index.web.tsx:90 +msgid "Unmute {truncatedTag}" +msgstr "" + #: src/view/com/profile/ProfileHeader.tsx:326 msgid "Unmute Account" msgstr "" -#: src/view/com/util/forms/PostDropdownBtn.tsx:200 +#: src/components/TagMenu/index.tsx:210 +msgid "Unmute all {tag} posts" +msgstr "" + +#: src/view/com/util/forms/PostDropdownBtn.tsx:202 msgid "Unmute thread" msgstr "" @@ -4364,6 +4513,10 @@ msgstr "" #~ msgid "We recommend \"For You\" by Skygaze:" #~ msgstr "" +#: src/components/dialogs/MutedWords.tsx:161 +msgid "We recommend avoiding common words that appear in many posts, since it can result in no posts being shown." +msgstr "" + #: src/screens/Onboarding/StepAlgoFeeds/index.tsx:124 msgid "We recommend our \"Discover\" feed:" msgstr "" @@ -4392,7 +4545,11 @@ msgstr "Wir freuen uns sehr, dass du dabei bist!" msgid "We're sorry, but we were unable to resolve this list. If this persists, please contact the list creator, @{handleOrDid}." msgstr "" -#: src/view/screens/Search/Search.tsx:253 +#: src/components/dialogs/MutedWords.tsx:182 +msgid "We're sorry, but we weren't able to load your muted words at this time. Please try again." +msgstr "" + +#: src/view/screens/Search/Search.tsx:254 msgid "We're sorry, but your search could not be completed. Please try again in a few minutes." msgstr "Es tut uns leid, aber deine Suche konnte nicht abgeschlossen werden. Bitte versuche es in ein paar Minuten erneut." @@ -4413,7 +4570,7 @@ msgid "What is the issue with this {collectionName}?" msgstr "" #: src/view/com/auth/SplashScreen.tsx:59 -#: src/view/com/composer/Composer.tsx:279 +#: src/view/com/composer/Composer.tsx:286 msgid "What's up?" msgstr "Was gibt's?" @@ -4434,11 +4591,11 @@ msgstr "Wer antworten kann" msgid "Wide" msgstr "Breit" -#: src/view/com/composer/Composer.tsx:415 +#: src/view/com/composer/Composer.tsx:422 msgid "Write post" msgstr "Beitrag verfassen" -#: src/view/com/composer/Composer.tsx:278 +#: src/view/com/composer/Composer.tsx:285 #: src/view/com/composer/Prompt.tsx:33 msgid "Write your reply" msgstr "Schreibe deine Antwort" @@ -4503,7 +4660,7 @@ msgstr "Du hast keine gespeicherten Feeds!" msgid "You don't have any saved feeds." msgstr "Du hast keine gespeicherten Feeds." -#: src/view/com/post-thread/PostThread.tsx:464 +#: src/view/com/post-thread/PostThread.tsx:465 msgid "You have blocked the author or you have been blocked by the author." msgstr "Du hast den Verfasser blockiert oder du wurdest vom Verfasser blockiert." @@ -4543,6 +4700,10 @@ msgstr "Du hast noch keine App-Passwörter erstellt. Du kannst eines erstellen, msgid "You have not muted any accounts yet. To mute an account, go to their profile and selected \"Mute account\" from the menu on their account." msgstr "" +#: src/components/dialogs/MutedWords.tsx:202 +msgid "You haven't muted any words or tags yet" +msgstr "" + #: src/view/com/modals/ContentFilteringSettings.tsx:175 msgid "You must be 18 or older to enable adult content." msgstr "" @@ -4551,11 +4712,11 @@ msgstr "" msgid "You must be 18 years or older to enable adult content" msgstr "" -#: src/view/com/util/forms/PostDropdownBtn.tsx:127 +#: src/view/com/util/forms/PostDropdownBtn.tsx:129 msgid "You will no longer receive notifications for this thread" msgstr "" -#: src/view/com/util/forms/PostDropdownBtn.tsx:130 +#: src/view/com/util/forms/PostDropdownBtn.tsx:132 msgid "You will now receive notifications for this thread" msgstr "" @@ -4641,11 +4802,15 @@ msgstr "" #~ msgid "Your invite codes are hidden when logged in using an App Password" #~ msgstr "Deine Einladungscodes werden ausgeblendet, wenn du dich mit einem App-Passwort anmeldest" +#: src/components/dialogs/MutedWords.tsx:173 +msgid "Your muted words" +msgstr "" + #: src/view/com/modals/ChangePassword.tsx:155 msgid "Your password has been changed successfully!" msgstr "" -#: src/view/com/composer/Composer.tsx:267 +#: src/view/com/composer/Composer.tsx:274 msgid "Your post has been published" msgstr "" @@ -4660,7 +4825,7 @@ msgstr "Deine Beiträge, Likes und Blockierungen sind öffentlich. Stummschaltun msgid "Your profile" msgstr "Dein Profil" -#: src/view/com/composer/Composer.tsx:266 +#: src/view/com/composer/Composer.tsx:273 msgid "Your reply has been published" msgstr "" diff --git a/src/locale/locales/en/messages.po b/src/locale/locales/en/messages.po index b9449905..cc40e1f0 100644 --- a/src/locale/locales/en/messages.po +++ b/src/locale/locales/en/messages.po @@ -76,7 +76,7 @@ msgid "A new version of the app is available. Please update to continue using th msgstr "" #: src/view/com/util/ViewHeader.tsx:83 -#: src/view/screens/Search/Search.tsx:624 +#: src/view/screens/Search/Search.tsx:647 msgid "Access navigation links and settings" msgstr "" @@ -127,6 +127,7 @@ msgstr "" msgid "Account unmuted" msgstr "" +#: src/components/dialogs/MutedWords.tsx:147 #: src/view/com/auth/onboarding/RecommendedFeedsItem.tsx:150 #: src/view/com/modals/ListAddRemoveUsers.tsx:264 #: src/view/com/modals/UserAddRemoveLists.tsx:219 @@ -168,14 +169,22 @@ msgstr "" msgid "Add details to report" msgstr "" -#: src/view/com/composer/Composer.tsx:446 +#: src/view/com/composer/Composer.tsx:453 msgid "Add link card" msgstr "" -#: src/view/com/composer/Composer.tsx:451 +#: src/view/com/composer/Composer.tsx:458 msgid "Add link card:" msgstr "" +#: src/components/dialogs/MutedWords.tsx:140 +msgid "Add mute word for configured settings" +msgstr "" + +#: src/components/dialogs/MutedWords.tsx:74 +msgid "Add muted words and tags" +msgstr "" + #: src/view/com/modals/ChangeHandle.tsx:417 msgid "Add the following DNS record to your domain:" msgstr "" @@ -299,7 +308,7 @@ msgstr "" msgid "App Passwords" msgstr "" -#: src/view/com/util/forms/PostDropdownBtn.tsx:279 +#: src/view/com/util/forms/PostDropdownBtn.tsx:295 msgid "Appeal content warning" msgstr "" @@ -323,15 +332,16 @@ msgstr "" msgid "Are you sure you want to delete the app password \"{name}\"?" msgstr "" -#: src/view/com/composer/Composer.tsx:143 +#: src/view/com/composer/Composer.tsx:150 msgid "Are you sure you'd like to discard this draft?" msgstr "" +#: src/components/dialogs/MutedWords.tsx:233 #: src/view/screens/ProfileList.tsx:365 msgid "Are you sure?" msgstr "" -#: src/view/com/util/forms/PostDropdownBtn.tsx:262 +#: src/view/com/util/forms/PostDropdownBtn.tsx:278 msgid "Are you sure? This cannot be undone." msgstr "" @@ -353,15 +363,15 @@ msgstr "" #: src/view/com/auth/login/LoginForm.tsx:259 #: src/view/com/auth/login/SetNewPasswordForm.tsx:179 #: src/view/com/modals/report/InputIssueDetails.tsx:46 -#: src/view/com/post-thread/PostThread.tsx:471 -#: src/view/com/post-thread/PostThread.tsx:521 -#: src/view/com/post-thread/PostThread.tsx:529 +#: src/view/com/post-thread/PostThread.tsx:472 +#: src/view/com/post-thread/PostThread.tsx:522 +#: src/view/com/post-thread/PostThread.tsx:530 #: src/view/com/profile/ProfileHeader.tsx:649 #: src/view/com/util/ViewHeader.tsx:81 msgid "Back" msgstr "" -#: src/view/com/post-thread/PostThread.tsx:479 +#: src/view/com/post-thread/PostThread.tsx:480 msgctxt "action" msgid "Back" msgstr "" @@ -409,7 +419,7 @@ msgstr "" msgid "Blocked" msgstr "" -#: src/view/screens/Moderation.tsx:123 +#: src/view/screens/Moderation.tsx:142 msgid "Blocked accounts" msgstr "" @@ -468,7 +478,7 @@ msgstr "" msgid "Bluesky uses invites to build a healthier community. If you don't know anybody with an invite, you can sign up for the waitlist and we'll send one soon." msgstr "" -#: src/view/screens/Moderation.tsx:226 +#: src/view/screens/Moderation.tsx:245 msgid "Bluesky will not show your profile and posts to logged-out users. Other apps may not honor this request. This does not make your account private." msgstr "" @@ -520,8 +530,8 @@ msgid "Can only contain letters, numbers, spaces, dashes, and underscores. Must msgstr "" #: src/components/Prompt.tsx:91 -#: src/view/com/composer/Composer.tsx:300 -#: src/view/com/composer/Composer.tsx:305 +#: src/view/com/composer/Composer.tsx:307 +#: src/view/com/composer/Composer.tsx:312 #: src/view/com/modals/ChangeEmail.tsx:218 #: src/view/com/modals/ChangeEmail.tsx:220 #: src/view/com/modals/ChangePassword.tsx:265 @@ -535,7 +545,7 @@ msgstr "" #: src/view/com/modals/VerifyEmail.tsx:247 #: src/view/com/modals/VerifyEmail.tsx:253 #: src/view/com/modals/Waitlist.tsx:142 -#: src/view/screens/Search/Search.tsx:693 +#: src/view/screens/Search/Search.tsx:716 #: src/view/shell/desktop/Search.tsx:238 msgid "Cancel" msgstr "" @@ -686,7 +696,7 @@ msgid "Clear all storage data (restart after this)" msgstr "" #: src/view/com/util/forms/SearchInput.tsx:88 -#: src/view/screens/Search/Search.tsx:674 +#: src/view/screens/Search/Search.tsx:697 msgid "Clear search query" msgstr "" @@ -694,6 +704,11 @@ msgstr "" msgid "click here" msgstr "" +#: src/components/RichText.tsx:189 +#: src/components/TagMenu/index.web.tsx:125 +msgid "Click here to open tag menu for {tag}" +msgstr "" + #: src/screens/Onboarding/index.tsx:35 msgid "Climate" msgstr "" @@ -724,11 +739,15 @@ msgstr "" msgid "Close image viewer" msgstr "" -#: src/view/shell/index.web.tsx:49 +#: src/view/shell/index.web.tsx:51 msgid "Close navigation footer" msgstr "" -#: src/view/shell/index.web.tsx:50 +#: src/components/TagMenu/index.tsx:266 +msgid "Close this dialog" +msgstr "" + +#: src/view/shell/index.web.tsx:52 msgid "Closes bottom navigation bar" msgstr "" @@ -736,7 +755,7 @@ msgstr "" msgid "Closes password update alert" msgstr "" -#: src/view/com/composer/Composer.tsx:302 +#: src/view/com/composer/Composer.tsx:309 msgid "Closes post composer and discards post draft" msgstr "" @@ -769,7 +788,7 @@ msgstr "" msgid "Complete the challenge" msgstr "" -#: src/view/com/composer/Composer.tsx:417 +#: src/view/com/composer/Composer.tsx:424 msgid "Compose posts up to {MAX_GRAPHEME_LENGTH} characters in length" msgstr "" @@ -833,7 +852,7 @@ msgstr "" msgid "Contact support" msgstr "" -#: src/view/screens/Moderation.tsx:81 +#: src/view/screens/Moderation.tsx:83 msgid "Content filtering" msgstr "" @@ -899,7 +918,7 @@ msgstr "" #: src/view/com/modals/AddAppPasswords.tsx:76 #: src/view/com/modals/InviteCodes.tsx:152 -#: src/view/com/util/forms/PostDropdownBtn.tsx:141 +#: src/view/com/util/forms/PostDropdownBtn.tsx:143 msgid "Copied to clipboard" msgstr "" @@ -915,7 +934,7 @@ msgstr "" msgid "Copy link to list" msgstr "" -#: src/view/com/util/forms/PostDropdownBtn.tsx:182 +#: src/view/com/util/forms/PostDropdownBtn.tsx:184 msgid "Copy link to post" msgstr "" @@ -923,7 +942,7 @@ msgstr "" msgid "Copy link to profile" msgstr "" -#: src/view/com/util/forms/PostDropdownBtn.tsx:168 +#: src/view/com/util/forms/PostDropdownBtn.tsx:170 msgid "Copy post text" msgstr "" @@ -979,7 +998,7 @@ msgstr "" msgid "Created by you" msgstr "" -#: src/view/com/composer/Composer.tsx:448 +#: src/view/com/composer/Composer.tsx:455 msgid "Creates a card with a thumbnail. The card links to {url}" msgstr "" @@ -1056,11 +1075,11 @@ msgstr "" msgid "Delete My Account…" msgstr "" -#: src/view/com/util/forms/PostDropdownBtn.tsx:257 +#: src/view/com/util/forms/PostDropdownBtn.tsx:273 msgid "Delete post" msgstr "" -#: src/view/com/util/forms/PostDropdownBtn.tsx:261 +#: src/view/com/util/forms/PostDropdownBtn.tsx:277 msgid "Delete this post?" msgstr "" @@ -1083,7 +1102,7 @@ msgstr "" #~ msgid "Developer Tools" #~ msgstr "" -#: src/view/com/composer/Composer.tsx:211 +#: src/view/com/composer/Composer.tsx:218 msgid "Did you want to say anything?" msgstr "" @@ -1091,15 +1110,15 @@ msgstr "" msgid "Dim" msgstr "" -#: src/view/com/composer/Composer.tsx:144 +#: src/view/com/composer/Composer.tsx:151 msgid "Discard" msgstr "" -#: src/view/com/composer/Composer.tsx:138 +#: src/view/com/composer/Composer.tsx:145 msgid "Discard draft" msgstr "" -#: src/view/screens/Moderation.tsx:207 +#: src/view/screens/Moderation.tsx:226 msgid "Discourage apps from showing my account to logged-out users" msgstr "" @@ -1178,7 +1197,7 @@ msgstr "" msgid "Download CAR file" msgstr "" -#: src/view/com/composer/text-input/TextInput.web.tsx:247 +#: src/view/com/composer/text-input/TextInput.web.tsx:249 msgid "Drop to add images" msgstr "" @@ -1250,6 +1269,7 @@ msgstr "" msgid "Edit Profile" msgstr "" +#: src/view/com/home/HomeHeaderLayout.web.tsx:59 #: src/view/screens/Feeds.tsx:355 msgid "Edit Saved Feeds" msgstr "" @@ -1332,6 +1352,11 @@ msgstr "" msgid "Enter a name for this App Password" msgstr "" +#: src/components/dialogs/MutedWords.tsx:87 +#: src/components/dialogs/MutedWords.tsx:88 +msgid "Enter a word or tag" +msgstr "" + #: src/view/com/modals/VerifyEmail.tsx:105 msgid "Enter Confirmation Code" msgstr "" @@ -1381,7 +1406,7 @@ msgstr "" msgid "Error receiving captcha response." msgstr "" -#: src/view/screens/Search/Search.tsx:109 +#: src/view/screens/Search/Search.tsx:110 msgid "Error:" msgstr "" @@ -1452,7 +1477,7 @@ msgstr "" msgid "Failed to create the list. Check your internet connection and try again." msgstr "" -#: src/view/com/util/forms/PostDropdownBtn.tsx:108 +#: src/view/com/util/forms/PostDropdownBtn.tsx:110 msgid "Failed to delete post, please try again" msgstr "" @@ -1474,8 +1499,8 @@ msgid "Feed offline" msgstr "" #: src/view/com/feeds/FeedPage.tsx:143 -msgid "Feed Preferences" -msgstr "" +#~ msgid "Feed Preferences" +#~ msgstr "" #: src/view/shell/desktop/RightNav.tsx:61 #: src/view/shell/Drawer.tsx:311 @@ -1523,11 +1548,11 @@ msgstr "" msgid "Find accounts to follow" msgstr "" -#: src/view/screens/Search/Search.tsx:439 +#: src/view/screens/Search/Search.tsx:440 msgid "Find users on Bluesky" msgstr "" -#: src/view/screens/Search/Search.tsx:437 +#: src/view/screens/Search/Search.tsx:438 msgid "Find users with the search tool on the right" msgstr "" @@ -1624,6 +1649,7 @@ msgid "Following {0}" msgstr "" #: src/Navigation.tsx:248 +#: src/view/com/home/HomeHeaderLayout.web.tsx:45 #: src/view/com/home/HomeHeaderLayoutMobile.tsx:83 #: src/view/screens/PreferencesFollowingFeed.tsx:104 #: src/view/screens/Settings/index.tsx:543 @@ -1663,7 +1689,7 @@ msgstr "" msgid "Forgot Password" msgstr "" -#: src/view/com/posts/FeedItem.tsx:187 +#: src/view/com/posts/FeedItem.tsx:189 msgctxt "from-feed" msgid "From <0/>" msgstr "" @@ -1696,7 +1722,7 @@ msgstr "" msgid "Go back to previous step" msgstr "" -#: src/view/screens/Search/Search.tsx:724 +#: src/view/screens/Search/Search.tsx:747 #: src/view/shell/desktop/Search.tsx:262 msgid "Go to @{queryMaybeHandle}" msgstr "" @@ -1713,6 +1739,10 @@ msgstr "" msgid "Handle" msgstr "" +#: src/components/RichText.tsx:188 +msgid "Hashtag: {tag}" +msgstr "" + #: src/view/com/auth/create/CreateAccount.tsx:208 msgid "Having trouble?" msgstr "" @@ -1751,7 +1781,7 @@ msgctxt "action" msgid "Hide" msgstr "" -#: src/view/com/util/forms/PostDropdownBtn.tsx:216 +#: src/view/com/util/forms/PostDropdownBtn.tsx:232 msgid "Hide post" msgstr "" @@ -1760,7 +1790,7 @@ msgstr "" msgid "Hide the content" msgstr "" -#: src/view/com/util/forms/PostDropdownBtn.tsx:220 +#: src/view/com/util/forms/PostDropdownBtn.tsx:236 msgid "Hide this post?" msgstr "" @@ -1909,7 +1939,7 @@ msgstr "" msgid "Input your user handle" msgstr "" -#: src/view/com/post-thread/PostThreadItem.tsx:224 +#: src/view/com/post-thread/PostThreadItem.tsx:226 msgid "Invalid or unsupported post record" msgstr "" @@ -2011,7 +2041,7 @@ msgstr "" msgid "Learn more about this warning" msgstr "" -#: src/view/screens/Moderation.tsx:243 +#: src/view/screens/Moderation.tsx:262 msgid "Learn more about what is public on Bluesky." msgstr "" @@ -2087,7 +2117,7 @@ msgstr "" msgid "Likes" msgstr "" -#: src/view/com/post-thread/PostThreadItem.tsx:181 +#: src/view/com/post-thread/PostThreadItem.tsx:183 msgid "Likes on this post" msgstr "" @@ -2144,7 +2174,7 @@ msgstr "" msgid "Load new notifications" msgstr "" -#: src/view/com/feeds/FeedPage.tsx:181 +#: src/view/com/feeds/FeedPage.tsx:115 #: src/view/screens/Profile.tsx:440 #: src/view/screens/ProfileFeed.tsx:495 #: src/view/screens/ProfileList.tsx:681 @@ -2170,7 +2200,7 @@ msgstr "" msgid "Log out" msgstr "" -#: src/view/screens/Moderation.tsx:136 +#: src/view/screens/Moderation.tsx:155 msgid "Logged-out visibility" msgstr "" @@ -2182,6 +2212,10 @@ msgstr "" msgid "Make sure this is where you intend to go!" msgstr "" +#: src/components/dialogs/MutedWords.tsx:71 +msgid "Manage your muted words and tags" +msgstr "" + #: src/view/com/auth/create/Step2.tsx:118 msgid "May not be longer than 253 characters" msgstr "" @@ -2203,7 +2237,7 @@ msgid "Mentioned users" msgstr "" #: src/view/com/util/ViewHeader.tsx:81 -#: src/view/screens/Search/Search.tsx:623 +#: src/view/screens/Search/Search.tsx:646 msgid "Menu" msgstr "" @@ -2212,7 +2246,7 @@ msgid "Message from server: {0}" msgstr "" #: src/Navigation.tsx:115 -#: src/view/screens/Moderation.tsx:64 +#: src/view/screens/Moderation.tsx:66 #: src/view/screens/Settings/index.tsx:625 #: src/view/shell/desktop/LeftNav.tsx:397 #: src/view/shell/Drawer.tsx:511 @@ -2243,7 +2277,7 @@ msgstr "" msgid "Moderation list updated" msgstr "" -#: src/view/screens/Moderation.tsx:95 +#: src/view/screens/Moderation.tsx:114 msgid "Moderation lists" msgstr "" @@ -2270,7 +2304,7 @@ msgstr "" msgid "More options" msgstr "" -#: src/view/com/util/forms/PostDropdownBtn.tsx:299 +#: src/view/com/util/forms/PostDropdownBtn.tsx:315 msgid "More post options" msgstr "" @@ -2282,6 +2316,14 @@ msgstr "" msgid "Must be at least 3 characters" msgstr "" +#: src/components/TagMenu/index.tsx:253 +msgid "Mute" +msgstr "" + +#: src/components/TagMenu/index.web.tsx:91 +msgid "Mute {truncatedTag}" +msgstr "" + #: src/view/com/profile/ProfileHeader.tsx:327 msgid "Mute Account" msgstr "" @@ -2290,6 +2332,18 @@ msgstr "" msgid "Mute accounts" msgstr "" +#: src/components/TagMenu/index.tsx:211 +msgid "Mute all {tag} posts" +msgstr "" + +#: src/components/dialogs/MutedWords.tsx:131 +msgid "Mute in tags only" +msgstr "" + +#: src/components/dialogs/MutedWords.tsx:116 +msgid "Mute in text & tags" +msgstr "" + #: src/view/screens/ProfileList.tsx:491 msgid "Mute list" msgstr "" @@ -2302,15 +2356,27 @@ msgstr "" msgid "Mute this List" msgstr "" -#: src/view/com/util/forms/PostDropdownBtn.tsx:200 +#: src/components/dialogs/MutedWords.tsx:109 +msgid "Mute this word in post text and tags" +msgstr "" + +#: src/components/dialogs/MutedWords.tsx:124 +msgid "Mute this word in tags only" +msgstr "" + +#: src/view/com/util/forms/PostDropdownBtn.tsx:202 msgid "Mute thread" msgstr "" +#: src/view/com/util/forms/PostDropdownBtn.tsx:216 +msgid "Mute words & tags" +msgstr "" + #: src/view/com/lists/ListCard.tsx:102 msgid "Muted" msgstr "" -#: src/view/screens/Moderation.tsx:109 +#: src/view/screens/Moderation.tsx:128 msgid "Muted accounts" msgstr "" @@ -2323,6 +2389,10 @@ msgstr "" msgid "Muted accounts have their posts removed from your feed and from your notifications. Mutes are completely private." msgstr "" +#: src/view/screens/Moderation.tsx:100 +msgid "Muted words & tags" +msgstr "" + #: src/view/screens/ProfileList.tsx:277 msgid "Muting is private. Muted accounts can interact with you, but you will not see their posts or receive notifications from them." msgstr "" @@ -2386,6 +2456,10 @@ msgstr "" msgid "Never lose access to your followers or data." msgstr "" +#: src/components/dialogs/MutedWords.tsx:244 +msgid "Nevermind" +msgstr "" + #: src/view/screens/Lists.tsx:76 msgctxt "action" msgid "New" @@ -2407,7 +2481,7 @@ msgstr "" msgid "New Password" msgstr "" -#: src/view/com/feeds/FeedPage.tsx:192 +#: src/view/com/feeds/FeedPage.tsx:126 msgctxt "action" msgid "New post" msgstr "" @@ -2492,8 +2566,8 @@ msgid "No results found for \"{query}\"" msgstr "" #: src/view/com/modals/ListAddRemoveUsers.tsx:127 -#: src/view/screens/Search/Search.tsx:280 -#: src/view/screens/Search/Search.tsx:308 +#: src/view/screens/Search/Search.tsx:281 +#: src/view/screens/Search/Search.tsx:309 msgid "No results found for {query}" msgstr "" @@ -2519,7 +2593,7 @@ msgstr "" msgid "Not right now" msgstr "" -#: src/view/screens/Moderation.tsx:233 +#: src/view/screens/Moderation.tsx:252 msgid "Note: Bluesky is an open and public network. This setting only limits the visibility of your content on the Bluesky app and website, and other apps may not respect this setting. Your content may still be shown to logged-out users by other apps and websites." msgstr "" @@ -2557,7 +2631,7 @@ msgstr "" msgid "Onboarding reset" msgstr "" -#: src/view/com/composer/Composer.tsx:375 +#: src/view/com/composer/Composer.tsx:382 msgid "One or more images is missing alt text." msgstr "" @@ -2574,8 +2648,12 @@ msgstr "" msgid "Open" msgstr "" -#: src/view/com/composer/Composer.tsx:470 -#: src/view/com/composer/Composer.tsx:471 +#: src/view/screens/Moderation.tsx:75 +msgid "Open content filtering settings" +msgstr "" + +#: src/view/com/composer/Composer.tsx:477 +#: src/view/com/composer/Composer.tsx:478 msgid "Open emoji picker" msgstr "" @@ -2583,6 +2661,10 @@ msgstr "" msgid "Open links with in-app browser" msgstr "" +#: src/view/screens/Moderation.tsx:92 +msgid "Open muted words settings" +msgstr "" + #: src/view/com/home/HomeHeaderLayoutMobile.tsx:49 msgid "Open navigation" msgstr "" @@ -2659,6 +2741,7 @@ msgstr "" msgid "Opens password reset form" msgstr "" +#: src/view/com/home/HomeHeaderLayout.web.tsx:60 #: src/view/screens/Feeds.tsx:356 msgid "Opens screen to edit Saved Feeds" msgstr "" @@ -2839,7 +2922,7 @@ msgstr "" msgid "Please Verify Your Email" msgstr "" -#: src/view/com/composer/Composer.tsx:215 +#: src/view/com/composer/Composer.tsx:222 msgid "Please wait for your link card to finish loading" msgstr "" @@ -2851,8 +2934,8 @@ msgstr "" msgid "Porn" msgstr "" -#: src/view/com/composer/Composer.tsx:350 -#: src/view/com/composer/Composer.tsx:358 +#: src/view/com/composer/Composer.tsx:357 +#: src/view/com/composer/Composer.tsx:365 msgctxt "action" msgid "Post" msgstr "" @@ -2862,7 +2945,7 @@ msgctxt "description" msgid "Post" msgstr "" -#: src/view/com/post-thread/PostThreadItem.tsx:173 +#: src/view/com/post-thread/PostThreadItem.tsx:175 msgid "Post by {0}" msgstr "" @@ -2872,11 +2955,11 @@ msgstr "" msgid "Post by @{0}" msgstr "" -#: src/view/com/util/forms/PostDropdownBtn.tsx:88 +#: src/view/com/util/forms/PostDropdownBtn.tsx:90 msgid "Post deleted" msgstr "" -#: src/view/com/post-thread/PostThread.tsx:461 +#: src/view/com/post-thread/PostThread.tsx:462 msgid "Post hidden" msgstr "" @@ -2888,14 +2971,22 @@ msgstr "" msgid "Post Languages" msgstr "" -#: src/view/com/post-thread/PostThread.tsx:513 +#: src/view/com/post-thread/PostThread.tsx:514 msgid "Post not found" msgstr "" +#: src/components/TagMenu/index.tsx:257 +msgid "posts" +msgstr "" + #: src/view/screens/Profile.tsx:180 msgid "Posts" msgstr "" +#: src/components/dialogs/MutedWords.tsx:77 +msgid "Posts can be muted based on their text, their tags, or both." +msgstr "" + #: src/view/com/posts/FeedErrorMessage.tsx:64 msgid "Posts hidden" msgstr "" @@ -2960,11 +3051,11 @@ msgstr "" msgid "Public, shareable lists which can drive feeds." msgstr "" -#: src/view/com/composer/Composer.tsx:335 +#: src/view/com/composer/Composer.tsx:342 msgid "Publish post" msgstr "" -#: src/view/com/composer/Composer.tsx:335 +#: src/view/com/composer/Composer.tsx:342 msgid "Publish reply" msgstr "" @@ -2998,6 +3089,7 @@ msgstr "" msgid "Recommended Users" msgstr "" +#: src/components/dialogs/MutedWords.tsx:249 #: src/view/com/modals/ListAddRemoveUsers.tsx:264 #: src/view/com/modals/SelfLabel.tsx:83 #: src/view/com/modals/UserAddRemoveLists.tsx:219 @@ -3035,6 +3127,10 @@ msgstr "" msgid "Remove image preview" msgstr "" +#: src/components/dialogs/MutedWords.tsx:294 +msgid "Remove mute word from your list" +msgstr "" + #: src/view/com/modals/Repost.tsx:47 msgid "Remove repost" msgstr "" @@ -3069,7 +3165,7 @@ msgstr "" msgid "Replies to this thread are disabled" msgstr "" -#: src/view/com/composer/Composer.tsx:348 +#: src/view/com/composer/Composer.tsx:355 msgctxt "action" msgid "Reply" msgstr "" @@ -3079,7 +3175,7 @@ msgid "Reply Filters" msgstr "" #: src/view/com/post/Post.tsx:167 -#: src/view/com/posts/FeedItem.tsx:285 +#: src/view/com/posts/FeedItem.tsx:287 msgctxt "description" msgid "Reply to <0/>" msgstr "" @@ -3101,7 +3197,7 @@ msgid "Report List" msgstr "" #: src/view/com/modals/report/SendReportButton.tsx:37 -#: src/view/com/util/forms/PostDropdownBtn.tsx:239 +#: src/view/com/util/forms/PostDropdownBtn.tsx:255 msgid "Report post" msgstr "" @@ -3126,11 +3222,11 @@ msgstr "" msgid "Reposted By" msgstr "" -#: src/view/com/posts/FeedItem.tsx:205 +#: src/view/com/posts/FeedItem.tsx:207 msgid "Reposted by {0}" msgstr "" -#: src/view/com/posts/FeedItem.tsx:222 +#: src/view/com/posts/FeedItem.tsx:224 msgid "Reposted by <0/>" msgstr "" @@ -3138,7 +3234,7 @@ msgstr "" msgid "reposted your post" msgstr "" -#: src/view/com/post-thread/PostThreadItem.tsx:186 +#: src/view/com/post-thread/PostThreadItem.tsx:188 msgid "Reposts of this post" msgstr "" @@ -3289,9 +3385,9 @@ msgstr "" #: src/view/com/modals/ListAddRemoveUsers.tsx:75 #: src/view/com/util/forms/SearchInput.tsx:67 #: src/view/com/util/forms/SearchInput.tsx:79 -#: src/view/screens/Search/Search.tsx:418 -#: src/view/screens/Search/Search.tsx:645 -#: src/view/screens/Search/Search.tsx:663 +#: src/view/screens/Search/Search.tsx:419 +#: src/view/screens/Search/Search.tsx:668 +#: src/view/screens/Search/Search.tsx:686 #: src/view/shell/bottom-bar/BottomBar.tsx:159 #: src/view/shell/desktop/LeftNav.tsx:324 #: src/view/shell/desktop/Search.tsx:214 @@ -3301,11 +3397,19 @@ msgstr "" msgid "Search" msgstr "" -#: src/view/screens/Search/Search.tsx:712 +#: src/view/screens/Search/Search.tsx:735 #: src/view/shell/desktop/Search.tsx:255 msgid "Search for \"{query}\"" msgstr "" +#: src/components/TagMenu/index.tsx:145 +msgid "Search for all posts by @{authorHandle} with tag {tag}" +msgstr "" + +#: src/components/TagMenu/index.tsx:90 +msgid "Search for all posts with tag {tag}" +msgstr "" + #: src/view/com/auth/LoggedOut.tsx:104 #: src/view/com/auth/LoggedOut.tsx:105 #: src/view/com/modals/ListAddRemoveUsers.tsx:70 @@ -3316,6 +3420,22 @@ msgstr "" msgid "Security Step Required" msgstr "" +#: src/components/TagMenu/index.web.tsx:50 +msgid "See {truncatedTag} posts" +msgstr "" + +#: src/components/TagMenu/index.web.tsx:67 +msgid "See {truncatedTag} posts by user" +msgstr "" + +#: src/components/TagMenu/index.tsx:128 +msgid "See <0>{tag} posts" +msgstr "" + +#: src/components/TagMenu/index.tsx:189 +msgid "See <0>{tag} posts by this user" +msgstr "" + #: src/view/screens/SavedFeeds.tsx:163 msgid "See this guide" msgstr "" @@ -3525,7 +3645,7 @@ msgid "Share" msgstr "" #: src/view/com/profile/ProfileHeader.tsx:295 -#: src/view/com/util/forms/PostDropdownBtn.tsx:182 +#: src/view/com/util/forms/PostDropdownBtn.tsx:184 #: src/view/screens/ProfileList.tsx:418 msgid "Share" msgstr "" @@ -3558,9 +3678,9 @@ msgstr "" msgid "Show follows similar to {0}" msgstr "" -#: src/view/com/post-thread/PostThreadItem.tsx:532 -#: src/view/com/post/Post.tsx:196 -#: src/view/com/posts/FeedItem.tsx:359 +#: src/view/com/post-thread/PostThreadItem.tsx:538 +#: src/view/com/post/Post.tsx:198 +#: src/view/com/posts/FeedItem.tsx:363 msgid "Show More" msgstr "" @@ -3728,7 +3848,7 @@ msgstr "" msgid "Something went wrong. Check your email and try again." msgstr "" -#: src/App.native.tsx:61 +#: src/App.native.tsx:63 msgid "Sorry! Your session expired. Please log in again." msgstr "" @@ -3786,7 +3906,7 @@ msgstr "" msgid "Subscribe to this list" msgstr "" -#: src/view/screens/Search/Search.tsx:373 +#: src/view/screens/Search/Search.tsx:374 msgid "Suggested Follows" msgstr "" @@ -3830,6 +3950,14 @@ msgstr "" msgid "System log" msgstr "" +#: src/components/dialogs/MutedWords.tsx:288 +msgid "tag" +msgstr "" + +#: src/components/TagMenu/index.tsx:74 +msgid "Tag menu: {tag}" +msgstr "" + #: src/view/com/modals/crop-image/CropImage.web.tsx:112 msgid "Tall" msgstr "" @@ -3853,6 +3981,10 @@ msgstr "" msgid "Terms of Service" msgstr "" +#: src/components/dialogs/MutedWords.tsx:288 +msgid "text" +msgstr "" + #: src/view/com/modals/AppealLabel.tsx:70 #: src/view/com/modals/report/InputIssueDetails.tsx:51 msgid "Text input field" @@ -3878,7 +4010,7 @@ msgstr "" msgid "The following steps will help customize your Bluesky experience." msgstr "" -#: src/view/com/post-thread/PostThread.tsx:516 +#: src/view/com/post-thread/PostThread.tsx:517 msgid "The post may have been deleted." msgstr "" @@ -4044,7 +4176,7 @@ msgstr "" msgid "This name is already in use" msgstr "" -#: src/view/com/post-thread/PostThreadItem.tsx:123 +#: src/view/com/post-thread/PostThreadItem.tsx:125 msgid "This post has been deleted." msgstr "" @@ -4068,7 +4200,11 @@ msgstr "" msgid "This warning is only available for posts with media attached." msgstr "" -#: src/view/com/util/forms/PostDropdownBtn.tsx:221 +#: src/components/dialogs/MutedWords.tsx:236 +msgid "This will delete {0} from your muted words. You can always add it back later." +msgstr "" + +#: src/view/com/util/forms/PostDropdownBtn.tsx:237 msgid "This will hide this post from your feeds." msgstr "" @@ -4085,6 +4221,10 @@ msgstr "" msgid "Threads Preferences" msgstr "" +#: src/components/dialogs/MutedWords.tsx:95 +msgid "Toggle between muted word options." +msgstr "" + #: src/view/com/util/forms/DropdownButton.tsx:246 msgid "Toggle dropdown" msgstr "" @@ -4093,9 +4233,9 @@ msgstr "" msgid "Transformations" msgstr "" -#: src/view/com/post-thread/PostThreadItem.tsx:679 -#: src/view/com/post-thread/PostThreadItem.tsx:681 -#: src/view/com/util/forms/PostDropdownBtn.tsx:154 +#: src/view/com/post-thread/PostThreadItem.tsx:685 +#: src/view/com/post-thread/PostThreadItem.tsx:687 +#: src/view/com/util/forms/PostDropdownBtn.tsx:156 msgid "Translate" msgstr "" @@ -4160,15 +4300,24 @@ msgstr "" msgid "Unlike" msgstr "" +#: src/components/TagMenu/index.tsx:253 #: src/view/screens/ProfileList.tsx:597 msgid "Unmute" msgstr "" +#: src/components/TagMenu/index.web.tsx:90 +msgid "Unmute {truncatedTag}" +msgstr "" + #: src/view/com/profile/ProfileHeader.tsx:326 msgid "Unmute Account" msgstr "" -#: src/view/com/util/forms/PostDropdownBtn.tsx:200 +#: src/components/TagMenu/index.tsx:210 +msgid "Unmute all {tag} posts" +msgstr "" + +#: src/view/com/util/forms/PostDropdownBtn.tsx:202 msgid "Unmute thread" msgstr "" @@ -4369,6 +4518,10 @@ msgstr "" #~ msgid "We recommend \"For You\" by Skygaze:" #~ msgstr "" +#: src/components/dialogs/MutedWords.tsx:161 +msgid "We recommend avoiding common words that appear in many posts, since it can result in no posts being shown." +msgstr "" + #: src/screens/Onboarding/StepAlgoFeeds/index.tsx:124 msgid "We recommend our \"Discover\" feed:" msgstr "" @@ -4397,7 +4550,11 @@ msgstr "" msgid "We're sorry, but we were unable to resolve this list. If this persists, please contact the list creator, @{handleOrDid}." msgstr "" -#: src/view/screens/Search/Search.tsx:253 +#: src/components/dialogs/MutedWords.tsx:182 +msgid "We're sorry, but we weren't able to load your muted words at this time. Please try again." +msgstr "" + +#: src/view/screens/Search/Search.tsx:254 msgid "We're sorry, but your search could not be completed. Please try again in a few minutes." msgstr "" @@ -4418,7 +4575,7 @@ msgid "What is the issue with this {collectionName}?" msgstr "" #: src/view/com/auth/SplashScreen.tsx:59 -#: src/view/com/composer/Composer.tsx:279 +#: src/view/com/composer/Composer.tsx:286 msgid "What's up?" msgstr "" @@ -4439,11 +4596,11 @@ msgstr "" msgid "Wide" msgstr "" -#: src/view/com/composer/Composer.tsx:415 +#: src/view/com/composer/Composer.tsx:422 msgid "Write post" msgstr "" -#: src/view/com/composer/Composer.tsx:278 +#: src/view/com/composer/Composer.tsx:285 #: src/view/com/composer/Prompt.tsx:33 msgid "Write your reply" msgstr "" @@ -4508,7 +4665,7 @@ msgstr "" msgid "You don't have any saved feeds." msgstr "" -#: src/view/com/post-thread/PostThread.tsx:464 +#: src/view/com/post-thread/PostThread.tsx:465 msgid "You have blocked the author or you have been blocked by the author." msgstr "" @@ -4548,6 +4705,10 @@ msgstr "" msgid "You have not muted any accounts yet. To mute an account, go to their profile and selected \"Mute account\" from the menu on their account." msgstr "" +#: src/components/dialogs/MutedWords.tsx:202 +msgid "You haven't muted any words or tags yet" +msgstr "" + #: src/view/com/modals/ContentFilteringSettings.tsx:175 msgid "You must be 18 or older to enable adult content." msgstr "" @@ -4556,11 +4717,11 @@ msgstr "" msgid "You must be 18 years or older to enable adult content" msgstr "" -#: src/view/com/util/forms/PostDropdownBtn.tsx:127 +#: src/view/com/util/forms/PostDropdownBtn.tsx:129 msgid "You will no longer receive notifications for this thread" msgstr "" -#: src/view/com/util/forms/PostDropdownBtn.tsx:130 +#: src/view/com/util/forms/PostDropdownBtn.tsx:132 msgid "You will now receive notifications for this thread" msgstr "" @@ -4646,11 +4807,15 @@ msgstr "" #~ msgid "Your invite codes are hidden when logged in using an App Password" #~ msgstr "" +#: src/components/dialogs/MutedWords.tsx:173 +msgid "Your muted words" +msgstr "" + #: src/view/com/modals/ChangePassword.tsx:155 msgid "Your password has been changed successfully!" msgstr "" -#: src/view/com/composer/Composer.tsx:267 +#: src/view/com/composer/Composer.tsx:274 msgid "Your post has been published" msgstr "" @@ -4665,7 +4830,7 @@ msgstr "" msgid "Your profile" msgstr "" -#: src/view/com/composer/Composer.tsx:266 +#: src/view/com/composer/Composer.tsx:273 msgid "Your reply has been published" msgstr "" diff --git a/src/locale/locales/es/messages.po b/src/locale/locales/es/messages.po index b0689cb5..fed1beb6 100644 --- a/src/locale/locales/es/messages.po +++ b/src/locale/locales/es/messages.po @@ -76,7 +76,7 @@ msgid "A new version of the app is available. Please update to continue using th msgstr "Ya está disponible una nueva versión de la aplicación. Actualízala para seguir utilizándola." #: src/view/com/util/ViewHeader.tsx:83 -#: src/view/screens/Search/Search.tsx:624 +#: src/view/screens/Search/Search.tsx:647 msgid "Access navigation links and settings" msgstr "" @@ -127,6 +127,7 @@ msgstr "" msgid "Account unmuted" msgstr "" +#: src/components/dialogs/MutedWords.tsx:147 #: src/view/com/auth/onboarding/RecommendedFeedsItem.tsx:150 #: src/view/com/modals/ListAddRemoveUsers.tsx:264 #: src/view/com/modals/UserAddRemoveLists.tsx:219 @@ -168,14 +169,22 @@ msgstr "Agregar detalles" msgid "Add details to report" msgstr "Agregar detalles al informe" -#: src/view/com/composer/Composer.tsx:446 +#: src/view/com/composer/Composer.tsx:453 msgid "Add link card" msgstr "Agregar una tarjeta de enlace" -#: src/view/com/composer/Composer.tsx:451 +#: src/view/com/composer/Composer.tsx:458 msgid "Add link card:" msgstr "Agregar una tarjeta de enlace:" +#: src/components/dialogs/MutedWords.tsx:140 +msgid "Add mute word for configured settings" +msgstr "" + +#: src/components/dialogs/MutedWords.tsx:74 +msgid "Add muted words and tags" +msgstr "" + #: src/view/com/modals/ChangeHandle.tsx:417 msgid "Add the following DNS record to your domain:" msgstr "Añade el siguiente registro DNS a tu dominio:" @@ -299,7 +308,7 @@ msgstr "" msgid "App Passwords" msgstr "Contraseñas de la app" -#: src/view/com/util/forms/PostDropdownBtn.tsx:279 +#: src/view/com/util/forms/PostDropdownBtn.tsx:295 msgid "Appeal content warning" msgstr "Aviso sobre el contenido del recurso" @@ -323,15 +332,16 @@ msgstr "Aspecto exterior" msgid "Are you sure you want to delete the app password \"{name}\"?" msgstr "¿Estás seguro de que quieres eliminar la contraseña de la app \"{name}\"?" -#: src/view/com/composer/Composer.tsx:143 +#: src/view/com/composer/Composer.tsx:150 msgid "Are you sure you'd like to discard this draft?" msgstr "¿Estás seguro de que quieres descartar este borrador?" +#: src/components/dialogs/MutedWords.tsx:233 #: src/view/screens/ProfileList.tsx:365 msgid "Are you sure?" msgstr "¿Estás seguro?" -#: src/view/com/util/forms/PostDropdownBtn.tsx:262 +#: src/view/com/util/forms/PostDropdownBtn.tsx:278 msgid "Are you sure? This cannot be undone." msgstr "¿Estás seguro? Esto no puede deshacerse." @@ -353,15 +363,15 @@ msgstr "Desnudez artística o no erótica." #: src/view/com/auth/login/LoginForm.tsx:259 #: src/view/com/auth/login/SetNewPasswordForm.tsx:179 #: src/view/com/modals/report/InputIssueDetails.tsx:46 -#: src/view/com/post-thread/PostThread.tsx:471 -#: src/view/com/post-thread/PostThread.tsx:521 -#: src/view/com/post-thread/PostThread.tsx:529 +#: src/view/com/post-thread/PostThread.tsx:472 +#: src/view/com/post-thread/PostThread.tsx:522 +#: src/view/com/post-thread/PostThread.tsx:530 #: src/view/com/profile/ProfileHeader.tsx:649 #: src/view/com/util/ViewHeader.tsx:81 msgid "Back" msgstr "Regresar" -#: src/view/com/post-thread/PostThread.tsx:479 +#: src/view/com/post-thread/PostThread.tsx:480 msgctxt "action" msgid "Back" msgstr "" @@ -409,7 +419,7 @@ msgstr "" msgid "Blocked" msgstr "" -#: src/view/screens/Moderation.tsx:123 +#: src/view/screens/Moderation.tsx:142 msgid "Blocked accounts" msgstr "Cuentas bloqueadas" @@ -468,7 +478,7 @@ msgstr "Bluesky es público." msgid "Bluesky uses invites to build a healthier community. If you don't know anybody with an invite, you can sign up for the waitlist and we'll send one soon." msgstr "Bluesky utiliza las invitaciones para construir una comunidad más saludable. Si no conoces a nadie con una invitación, puedes apuntarte a la lista de espera y te enviaremos una en breve." -#: src/view/screens/Moderation.tsx:226 +#: src/view/screens/Moderation.tsx:245 msgid "Bluesky will not show your profile and posts to logged-out users. Other apps may not honor this request. This does not make your account private." msgstr "Bluesky no mostrará tu perfil ni tus publicaciones a los usuarios que hayan cerrado sesión. Es posible que otras aplicaciones no acepten esta solicitud. Esto no hace que tu cuenta sea privada." @@ -520,8 +530,8 @@ msgid "Can only contain letters, numbers, spaces, dashes, and underscores. Must msgstr "Sólo puede contener letras, números, espacios, guiones y guiones bajos. Debe tener al menos 4 caracteres, pero no más de 32." #: src/components/Prompt.tsx:91 -#: src/view/com/composer/Composer.tsx:300 -#: src/view/com/composer/Composer.tsx:305 +#: src/view/com/composer/Composer.tsx:307 +#: src/view/com/composer/Composer.tsx:312 #: src/view/com/modals/ChangeEmail.tsx:218 #: src/view/com/modals/ChangeEmail.tsx:220 #: src/view/com/modals/ChangePassword.tsx:265 @@ -535,7 +545,7 @@ msgstr "Sólo puede contener letras, números, espacios, guiones y guiones bajos #: src/view/com/modals/VerifyEmail.tsx:247 #: src/view/com/modals/VerifyEmail.tsx:253 #: src/view/com/modals/Waitlist.tsx:142 -#: src/view/screens/Search/Search.tsx:693 +#: src/view/screens/Search/Search.tsx:716 #: src/view/shell/desktop/Search.tsx:238 msgid "Cancel" msgstr "Cancelar" @@ -686,7 +696,7 @@ msgid "Clear all storage data (restart after this)" msgstr "Borrar todos los datos de almacenamiento (reiniciar después de esto)" #: src/view/com/util/forms/SearchInput.tsx:88 -#: src/view/screens/Search/Search.tsx:674 +#: src/view/screens/Search/Search.tsx:697 msgid "Clear search query" msgstr "Borrar consulta de búsqueda" @@ -694,6 +704,11 @@ msgstr "Borrar consulta de búsqueda" msgid "click here" msgstr "" +#: src/components/RichText.tsx:189 +#: src/components/TagMenu/index.web.tsx:125 +msgid "Click here to open tag menu for {tag}" +msgstr "" + #: src/screens/Onboarding/index.tsx:35 msgid "Climate" msgstr "" @@ -724,11 +739,15 @@ msgstr "Cerrar la imagen" msgid "Close image viewer" msgstr "Cerrar el visor de imagen" -#: src/view/shell/index.web.tsx:49 +#: src/view/shell/index.web.tsx:51 msgid "Close navigation footer" msgstr "Cerrar el pie de página de navegación" -#: src/view/shell/index.web.tsx:50 +#: src/components/TagMenu/index.tsx:266 +msgid "Close this dialog" +msgstr "" + +#: src/view/shell/index.web.tsx:52 msgid "Closes bottom navigation bar" msgstr "" @@ -736,7 +755,7 @@ msgstr "" msgid "Closes password update alert" msgstr "" -#: src/view/com/composer/Composer.tsx:302 +#: src/view/com/composer/Composer.tsx:309 msgid "Closes post composer and discards post draft" msgstr "" @@ -769,7 +788,7 @@ msgstr "" msgid "Complete the challenge" msgstr "" -#: src/view/com/composer/Composer.tsx:417 +#: src/view/com/composer/Composer.tsx:424 msgid "Compose posts up to {MAX_GRAPHEME_LENGTH} characters in length" msgstr "" @@ -833,7 +852,7 @@ msgstr "Conectando..." msgid "Contact support" msgstr "" -#: src/view/screens/Moderation.tsx:81 +#: src/view/screens/Moderation.tsx:83 msgid "Content filtering" msgstr "Filtro de contenido" @@ -899,7 +918,7 @@ msgstr "" #: src/view/com/modals/AddAppPasswords.tsx:76 #: src/view/com/modals/InviteCodes.tsx:152 -#: src/view/com/util/forms/PostDropdownBtn.tsx:141 +#: src/view/com/util/forms/PostDropdownBtn.tsx:143 msgid "Copied to clipboard" msgstr "" @@ -915,7 +934,7 @@ msgstr "Copiar" msgid "Copy link to list" msgstr "Copia el enlace a la lista" -#: src/view/com/util/forms/PostDropdownBtn.tsx:182 +#: src/view/com/util/forms/PostDropdownBtn.tsx:184 msgid "Copy link to post" msgstr "Copia el enlace a la publicación" @@ -923,7 +942,7 @@ msgstr "Copia el enlace a la publicación" msgid "Copy link to profile" msgstr "Copia el enlace al perfil" -#: src/view/com/util/forms/PostDropdownBtn.tsx:168 +#: src/view/com/util/forms/PostDropdownBtn.tsx:170 msgid "Copy post text" msgstr "Copiar el texto de la publicación" @@ -979,7 +998,7 @@ msgstr "" msgid "Created by you" msgstr "" -#: src/view/com/composer/Composer.tsx:448 +#: src/view/com/composer/Composer.tsx:455 msgid "Creates a card with a thumbnail. The card links to {url}" msgstr "" @@ -1056,11 +1075,11 @@ msgstr "Borrar mi cuenta" msgid "Delete My Account…" msgstr "" -#: src/view/com/util/forms/PostDropdownBtn.tsx:257 +#: src/view/com/util/forms/PostDropdownBtn.tsx:273 msgid "Delete post" msgstr "Borrar una publicación" -#: src/view/com/util/forms/PostDropdownBtn.tsx:261 +#: src/view/com/util/forms/PostDropdownBtn.tsx:277 msgid "Delete this post?" msgstr "¿Borrar esta publicación?" @@ -1083,7 +1102,7 @@ msgstr "Descripción" #~ msgid "Developer Tools" #~ msgstr "Herramientas de desarrollador" -#: src/view/com/composer/Composer.tsx:211 +#: src/view/com/composer/Composer.tsx:218 msgid "Did you want to say anything?" msgstr "¿Quieres decir algo?" @@ -1091,15 +1110,15 @@ msgstr "¿Quieres decir algo?" msgid "Dim" msgstr "" -#: src/view/com/composer/Composer.tsx:144 +#: src/view/com/composer/Composer.tsx:151 msgid "Discard" msgstr "Descartar" -#: src/view/com/composer/Composer.tsx:138 +#: src/view/com/composer/Composer.tsx:145 msgid "Discard draft" msgstr "Descartar el borrador" -#: src/view/screens/Moderation.tsx:207 +#: src/view/screens/Moderation.tsx:226 msgid "Discourage apps from showing my account to logged-out users" msgstr "Evitar que las aplicaciones muestren mi cuenta a los usuarios desconectados" @@ -1178,7 +1197,7 @@ msgstr "" msgid "Download CAR file" msgstr "" -#: src/view/com/composer/text-input/TextInput.web.tsx:247 +#: src/view/com/composer/text-input/TextInput.web.tsx:249 msgid "Drop to add images" msgstr "" @@ -1250,6 +1269,7 @@ msgstr "Editar el perfil" msgid "Edit Profile" msgstr "Editar el perfil" +#: src/view/com/home/HomeHeaderLayout.web.tsx:59 #: src/view/screens/Feeds.tsx:355 msgid "Edit Saved Feeds" msgstr "Editar mis noticias guardadas" @@ -1332,6 +1352,11 @@ msgstr "Fin de noticias" msgid "Enter a name for this App Password" msgstr "" +#: src/components/dialogs/MutedWords.tsx:87 +#: src/components/dialogs/MutedWords.tsx:88 +msgid "Enter a word or tag" +msgstr "" + #: src/view/com/modals/VerifyEmail.tsx:105 msgid "Enter Confirmation Code" msgstr "" @@ -1381,7 +1406,7 @@ msgstr "Introduce tu nombre de usuario y contraseña" msgid "Error receiving captcha response." msgstr "" -#: src/view/screens/Search/Search.tsx:109 +#: src/view/screens/Search/Search.tsx:110 msgid "Error:" msgstr "Error:" @@ -1452,7 +1477,7 @@ msgstr "" msgid "Failed to create the list. Check your internet connection and try again." msgstr "" -#: src/view/com/util/forms/PostDropdownBtn.tsx:108 +#: src/view/com/util/forms/PostDropdownBtn.tsx:110 msgid "Failed to delete post, please try again" msgstr "" @@ -1474,8 +1499,8 @@ msgid "Feed offline" msgstr "Noticias fuera de línea" #: src/view/com/feeds/FeedPage.tsx:143 -msgid "Feed Preferences" -msgstr "Preferencias de noticias" +#~ msgid "Feed Preferences" +#~ msgstr "Preferencias de noticias" #: src/view/shell/desktop/RightNav.tsx:61 #: src/view/shell/Drawer.tsx:311 @@ -1523,11 +1548,11 @@ msgstr "" msgid "Find accounts to follow" msgstr "" -#: src/view/screens/Search/Search.tsx:439 +#: src/view/screens/Search/Search.tsx:440 msgid "Find users on Bluesky" msgstr "Encontrar usuarios en Bluesky" -#: src/view/screens/Search/Search.tsx:437 +#: src/view/screens/Search/Search.tsx:438 msgid "Find users with the search tool on the right" msgstr "Encuentra usuarios con la herramienta de búsqueda de la derecha" @@ -1624,6 +1649,7 @@ msgid "Following {0}" msgstr "" #: src/Navigation.tsx:248 +#: src/view/com/home/HomeHeaderLayout.web.tsx:45 #: src/view/com/home/HomeHeaderLayoutMobile.tsx:83 #: src/view/screens/PreferencesFollowingFeed.tsx:104 #: src/view/screens/Settings/index.tsx:543 @@ -1663,7 +1689,7 @@ msgstr "Olvidé mi contraseña" msgid "Forgot Password" msgstr "Olvidé mi contraseña" -#: src/view/com/posts/FeedItem.tsx:187 +#: src/view/com/posts/FeedItem.tsx:189 msgctxt "from-feed" msgid "From <0/>" msgstr "" @@ -1696,7 +1722,7 @@ msgstr "Regresar" msgid "Go back to previous step" msgstr "" -#: src/view/screens/Search/Search.tsx:724 +#: src/view/screens/Search/Search.tsx:747 #: src/view/shell/desktop/Search.tsx:262 msgid "Go to @{queryMaybeHandle}" msgstr "" @@ -1713,6 +1739,10 @@ msgstr "Ir al siguiente" msgid "Handle" msgstr "Identificador" +#: src/components/RichText.tsx:188 +msgid "Hashtag: {tag}" +msgstr "" + #: src/view/com/auth/create/CreateAccount.tsx:208 msgid "Having trouble?" msgstr "" @@ -1751,7 +1781,7 @@ msgctxt "action" msgid "Hide" msgstr "" -#: src/view/com/util/forms/PostDropdownBtn.tsx:216 +#: src/view/com/util/forms/PostDropdownBtn.tsx:232 msgid "Hide post" msgstr "Ocultar publicación" @@ -1760,7 +1790,7 @@ msgstr "Ocultar publicación" msgid "Hide the content" msgstr "" -#: src/view/com/util/forms/PostDropdownBtn.tsx:220 +#: src/view/com/util/forms/PostDropdownBtn.tsx:236 msgid "Hide this post?" msgstr "¿Ocultar esta publicación?" @@ -1909,7 +1939,7 @@ msgstr "" msgid "Input your user handle" msgstr "" -#: src/view/com/post-thread/PostThreadItem.tsx:224 +#: src/view/com/post-thread/PostThreadItem.tsx:226 msgid "Invalid or unsupported post record" msgstr "" @@ -2011,7 +2041,7 @@ msgstr "Aprender más" msgid "Learn more about this warning" msgstr "Aprender más acerca de esta advertencia" -#: src/view/screens/Moderation.tsx:243 +#: src/view/screens/Moderation.tsx:262 msgid "Learn more about what is public on Bluesky." msgstr "Más información sobre lo que es público en Bluesky." @@ -2087,7 +2117,7 @@ msgstr "" msgid "Likes" msgstr "Cantidad de «Me gusta»" -#: src/view/com/post-thread/PostThreadItem.tsx:181 +#: src/view/com/post-thread/PostThreadItem.tsx:183 msgid "Likes on this post" msgstr "" @@ -2144,7 +2174,7 @@ msgstr "Cargar más publicaciones" msgid "Load new notifications" msgstr "Cargar notificaciones nuevas" -#: src/view/com/feeds/FeedPage.tsx:181 +#: src/view/com/feeds/FeedPage.tsx:115 #: src/view/screens/Profile.tsx:440 #: src/view/screens/ProfileFeed.tsx:495 #: src/view/screens/ProfileList.tsx:681 @@ -2170,7 +2200,7 @@ msgstr "" msgid "Log out" msgstr "" -#: src/view/screens/Moderation.tsx:136 +#: src/view/screens/Moderation.tsx:155 msgid "Logged-out visibility" msgstr "Visibilidad de desconexión" @@ -2182,6 +2212,10 @@ msgstr "Acceder a una cuenta que no está en la lista" msgid "Make sure this is where you intend to go!" msgstr "¡Asegúrate de que es aquí a donde pretendes ir!" +#: src/components/dialogs/MutedWords.tsx:71 +msgid "Manage your muted words and tags" +msgstr "" + #: src/view/com/auth/create/Step2.tsx:118 msgid "May not be longer than 253 characters" msgstr "" @@ -2203,7 +2237,7 @@ msgid "Mentioned users" msgstr "Usuarios mencionados" #: src/view/com/util/ViewHeader.tsx:81 -#: src/view/screens/Search/Search.tsx:623 +#: src/view/screens/Search/Search.tsx:646 msgid "Menu" msgstr "Menú" @@ -2212,7 +2246,7 @@ msgid "Message from server: {0}" msgstr "Mensaje del servidor: {0}" #: src/Navigation.tsx:115 -#: src/view/screens/Moderation.tsx:64 +#: src/view/screens/Moderation.tsx:66 #: src/view/screens/Settings/index.tsx:625 #: src/view/shell/desktop/LeftNav.tsx:397 #: src/view/shell/Drawer.tsx:511 @@ -2243,7 +2277,7 @@ msgstr "" msgid "Moderation list updated" msgstr "" -#: src/view/screens/Moderation.tsx:95 +#: src/view/screens/Moderation.tsx:114 msgid "Moderation lists" msgstr "Listas de moderación" @@ -2270,7 +2304,7 @@ msgstr "Más canales de noticias" msgid "More options" msgstr "Más opciones" -#: src/view/com/util/forms/PostDropdownBtn.tsx:299 +#: src/view/com/util/forms/PostDropdownBtn.tsx:315 msgid "More post options" msgstr "" @@ -2282,6 +2316,14 @@ msgstr "" msgid "Must be at least 3 characters" msgstr "" +#: src/components/TagMenu/index.tsx:253 +msgid "Mute" +msgstr "" + +#: src/components/TagMenu/index.web.tsx:91 +msgid "Mute {truncatedTag}" +msgstr "" + #: src/view/com/profile/ProfileHeader.tsx:327 msgid "Mute Account" msgstr "Silenciar la cuenta" @@ -2290,6 +2332,18 @@ msgstr "Silenciar la cuenta" msgid "Mute accounts" msgstr "Silenciar las cuentas" +#: src/components/TagMenu/index.tsx:211 +msgid "Mute all {tag} posts" +msgstr "" + +#: src/components/dialogs/MutedWords.tsx:131 +msgid "Mute in tags only" +msgstr "" + +#: src/components/dialogs/MutedWords.tsx:116 +msgid "Mute in text & tags" +msgstr "" + #: src/view/screens/ProfileList.tsx:491 msgid "Mute list" msgstr "Silenciar la lista" @@ -2302,15 +2356,27 @@ msgstr "¿Silenciar estas cuentas?" msgid "Mute this List" msgstr "" -#: src/view/com/util/forms/PostDropdownBtn.tsx:200 +#: src/components/dialogs/MutedWords.tsx:109 +msgid "Mute this word in post text and tags" +msgstr "" + +#: src/components/dialogs/MutedWords.tsx:124 +msgid "Mute this word in tags only" +msgstr "" + +#: src/view/com/util/forms/PostDropdownBtn.tsx:202 msgid "Mute thread" msgstr "Silenciar el hilo" +#: src/view/com/util/forms/PostDropdownBtn.tsx:216 +msgid "Mute words & tags" +msgstr "" + #: src/view/com/lists/ListCard.tsx:102 msgid "Muted" msgstr "" -#: src/view/screens/Moderation.tsx:109 +#: src/view/screens/Moderation.tsx:128 msgid "Muted accounts" msgstr "Cuentas silenciadas" @@ -2323,6 +2389,10 @@ msgstr "Cuentas silenciadas" msgid "Muted accounts have their posts removed from your feed and from your notifications. Mutes are completely private." msgstr "Las cuentas silenciadas eliminan sus publicaciones de tu canal de noticias y de tus notificaciones. Las cuentas silenciadas son completamente privadas." +#: src/view/screens/Moderation.tsx:100 +msgid "Muted words & tags" +msgstr "" + #: src/view/screens/ProfileList.tsx:277 msgid "Muting is private. Muted accounts can interact with you, but you will not see their posts or receive notifications from them." msgstr "Silenciar es privado. Las cuentas silenciadas pueden interactuar contigo, pero no verás sus publicaciones ni recibirás notificaciones suyas." @@ -2386,6 +2456,10 @@ msgstr "No pierdas nunca el acceso a tus seguidores y datos." msgid "Never lose access to your followers or data." msgstr "" +#: src/components/dialogs/MutedWords.tsx:244 +msgid "Nevermind" +msgstr "" + #: src/view/screens/Lists.tsx:76 msgctxt "action" msgid "New" @@ -2407,7 +2481,7 @@ msgstr "" msgid "New Password" msgstr "" -#: src/view/com/feeds/FeedPage.tsx:192 +#: src/view/com/feeds/FeedPage.tsx:126 msgctxt "action" msgid "New post" msgstr "" @@ -2492,8 +2566,8 @@ msgid "No results found for \"{query}\"" msgstr "No se han encontrado resultados para \"{query}\"" #: src/view/com/modals/ListAddRemoveUsers.tsx:127 -#: src/view/screens/Search/Search.tsx:280 -#: src/view/screens/Search/Search.tsx:308 +#: src/view/screens/Search/Search.tsx:281 +#: src/view/screens/Search/Search.tsx:309 msgid "No results found for {query}" msgstr "No se han encontrado resultados para {query}" @@ -2519,7 +2593,7 @@ msgstr "" msgid "Not right now" msgstr "" -#: src/view/screens/Moderation.tsx:233 +#: src/view/screens/Moderation.tsx:252 msgid "Note: Bluesky is an open and public network. This setting only limits the visibility of your content on the Bluesky app and website, and other apps may not respect this setting. Your content may still be shown to logged-out users by other apps and websites." msgstr "Nota: Bluesky es una red abierta y pública. Esta configuración sólo limita la visibilidad de tu contenido en la aplicación y el sitio web de Bluesky, y es posible que otras aplicaciones no respeten esta configuración. Otras aplicaciones y sitios web pueden seguir mostrando tu contenido a los usuarios que hayan cerrado sesión." @@ -2557,7 +2631,7 @@ msgstr "" msgid "Onboarding reset" msgstr "" -#: src/view/com/composer/Composer.tsx:375 +#: src/view/com/composer/Composer.tsx:382 msgid "One or more images is missing alt text." msgstr "Falta el texto alternativo en una o varias imágenes." @@ -2574,8 +2648,12 @@ msgstr "" msgid "Open" msgstr "" -#: src/view/com/composer/Composer.tsx:470 -#: src/view/com/composer/Composer.tsx:471 +#: src/view/screens/Moderation.tsx:75 +msgid "Open content filtering settings" +msgstr "" + +#: src/view/com/composer/Composer.tsx:477 +#: src/view/com/composer/Composer.tsx:478 msgid "Open emoji picker" msgstr "" @@ -2583,6 +2661,10 @@ msgstr "" msgid "Open links with in-app browser" msgstr "" +#: src/view/screens/Moderation.tsx:92 +msgid "Open muted words settings" +msgstr "" + #: src/view/com/home/HomeHeaderLayoutMobile.tsx:49 msgid "Open navigation" msgstr "Abrir navegación" @@ -2659,6 +2741,7 @@ msgstr "Abre la configuración de moderación" msgid "Opens password reset form" msgstr "" +#: src/view/com/home/HomeHeaderLayout.web.tsx:60 #: src/view/screens/Feeds.tsx:356 msgid "Opens screen to edit Saved Feeds" msgstr "" @@ -2834,7 +2917,7 @@ msgstr "Por favor, dinos por qué crees que esta advertencia de contenido se ha msgid "Please Verify Your Email" msgstr "" -#: src/view/com/composer/Composer.tsx:215 +#: src/view/com/composer/Composer.tsx:222 msgid "Please wait for your link card to finish loading" msgstr "Por favor, espera a que tu tarjeta de enlace termine de cargarse" @@ -2846,8 +2929,8 @@ msgstr "" msgid "Porn" msgstr "" -#: src/view/com/composer/Composer.tsx:350 -#: src/view/com/composer/Composer.tsx:358 +#: src/view/com/composer/Composer.tsx:357 +#: src/view/com/composer/Composer.tsx:365 msgctxt "action" msgid "Post" msgstr "" @@ -2857,7 +2940,7 @@ msgctxt "description" msgid "Post" msgstr "Publicación" -#: src/view/com/post-thread/PostThreadItem.tsx:173 +#: src/view/com/post-thread/PostThreadItem.tsx:175 msgid "Post by {0}" msgstr "" @@ -2867,11 +2950,11 @@ msgstr "" msgid "Post by @{0}" msgstr "" -#: src/view/com/util/forms/PostDropdownBtn.tsx:88 +#: src/view/com/util/forms/PostDropdownBtn.tsx:90 msgid "Post deleted" msgstr "" -#: src/view/com/post-thread/PostThread.tsx:461 +#: src/view/com/post-thread/PostThread.tsx:462 msgid "Post hidden" msgstr "Publicación oculta" @@ -2883,14 +2966,22 @@ msgstr "Lenguaje de la publicación" msgid "Post Languages" msgstr "Lenguajes de la publicación" -#: src/view/com/post-thread/PostThread.tsx:513 +#: src/view/com/post-thread/PostThread.tsx:514 msgid "Post not found" msgstr "Publicación no encontrada" +#: src/components/TagMenu/index.tsx:257 +msgid "posts" +msgstr "" + #: src/view/screens/Profile.tsx:180 msgid "Posts" msgstr "Publicaciones" +#: src/components/dialogs/MutedWords.tsx:77 +msgid "Posts can be muted based on their text, their tags, or both." +msgstr "" + #: src/view/com/posts/FeedErrorMessage.tsx:64 msgid "Posts hidden" msgstr "" @@ -2955,11 +3046,11 @@ msgstr "Listas públicas y compartibles de usuarios para silenciar o bloquear en msgid "Public, shareable lists which can drive feeds." msgstr "Listas públicas y compartibles que pueden impulsar las noticias." -#: src/view/com/composer/Composer.tsx:335 +#: src/view/com/composer/Composer.tsx:342 msgid "Publish post" msgstr "" -#: src/view/com/composer/Composer.tsx:335 +#: src/view/com/composer/Composer.tsx:342 msgid "Publish reply" msgstr "" @@ -2993,6 +3084,7 @@ msgstr "Canales de noticias recomendados" msgid "Recommended Users" msgstr "Usuarios recomendados" +#: src/components/dialogs/MutedWords.tsx:249 #: src/view/com/modals/ListAddRemoveUsers.tsx:264 #: src/view/com/modals/SelfLabel.tsx:83 #: src/view/com/modals/UserAddRemoveLists.tsx:219 @@ -3030,6 +3122,10 @@ msgstr "Eliminar la imagen" msgid "Remove image preview" msgstr "Eliminar la vista previa de la imagen" +#: src/components/dialogs/MutedWords.tsx:294 +msgid "Remove mute word from your list" +msgstr "" + #: src/view/com/modals/Repost.tsx:47 msgid "Remove repost" msgstr "" @@ -3064,7 +3160,7 @@ msgstr "Respuestas" msgid "Replies to this thread are disabled" msgstr "Las respuestas a este hilo están desactivadas" -#: src/view/com/composer/Composer.tsx:348 +#: src/view/com/composer/Composer.tsx:355 msgctxt "action" msgid "Reply" msgstr "" @@ -3074,7 +3170,7 @@ msgid "Reply Filters" msgstr "Filtros de respuestas" #: src/view/com/post/Post.tsx:167 -#: src/view/com/posts/FeedItem.tsx:285 +#: src/view/com/posts/FeedItem.tsx:287 msgctxt "description" msgid "Reply to <0/>" msgstr "" @@ -3096,7 +3192,7 @@ msgid "Report List" msgstr "Informe de la lista" #: src/view/com/modals/report/SendReportButton.tsx:37 -#: src/view/com/util/forms/PostDropdownBtn.tsx:239 +#: src/view/com/util/forms/PostDropdownBtn.tsx:255 msgid "Report post" msgstr "Informe de la publicación" @@ -3121,11 +3217,11 @@ msgstr "Volver a publicar o citar publicación" msgid "Reposted By" msgstr "Vuelto a publicar por" -#: src/view/com/posts/FeedItem.tsx:205 +#: src/view/com/posts/FeedItem.tsx:207 msgid "Reposted by {0}" msgstr "Vuelto a publicar por {0}" -#: src/view/com/posts/FeedItem.tsx:222 +#: src/view/com/posts/FeedItem.tsx:224 msgid "Reposted by <0/>" msgstr "Vuelto a publicar por <0/>" @@ -3133,7 +3229,7 @@ msgstr "Vuelto a publicar por <0/>" msgid "reposted your post" msgstr "" -#: src/view/com/post-thread/PostThreadItem.tsx:186 +#: src/view/com/post-thread/PostThreadItem.tsx:188 msgid "Reposts of this post" msgstr "" @@ -3284,9 +3380,9 @@ msgstr "" #: src/view/com/modals/ListAddRemoveUsers.tsx:75 #: src/view/com/util/forms/SearchInput.tsx:67 #: src/view/com/util/forms/SearchInput.tsx:79 -#: src/view/screens/Search/Search.tsx:418 -#: src/view/screens/Search/Search.tsx:645 -#: src/view/screens/Search/Search.tsx:663 +#: src/view/screens/Search/Search.tsx:419 +#: src/view/screens/Search/Search.tsx:668 +#: src/view/screens/Search/Search.tsx:686 #: src/view/shell/bottom-bar/BottomBar.tsx:159 #: src/view/shell/desktop/LeftNav.tsx:324 #: src/view/shell/desktop/Search.tsx:214 @@ -3296,11 +3392,19 @@ msgstr "" msgid "Search" msgstr "Buscar" -#: src/view/screens/Search/Search.tsx:712 +#: src/view/screens/Search/Search.tsx:735 #: src/view/shell/desktop/Search.tsx:255 msgid "Search for \"{query}\"" msgstr "" +#: src/components/TagMenu/index.tsx:145 +msgid "Search for all posts by @{authorHandle} with tag {tag}" +msgstr "" + +#: src/components/TagMenu/index.tsx:90 +msgid "Search for all posts with tag {tag}" +msgstr "" + #: src/view/com/auth/LoggedOut.tsx:104 #: src/view/com/auth/LoggedOut.tsx:105 #: src/view/com/modals/ListAddRemoveUsers.tsx:70 @@ -3311,6 +3415,22 @@ msgstr "Buscar usuarios" msgid "Security Step Required" msgstr "Se requiere un paso de seguridad" +#: src/components/TagMenu/index.web.tsx:50 +msgid "See {truncatedTag} posts" +msgstr "" + +#: src/components/TagMenu/index.web.tsx:67 +msgid "See {truncatedTag} posts by user" +msgstr "" + +#: src/components/TagMenu/index.tsx:128 +msgid "See <0>{tag} posts" +msgstr "" + +#: src/components/TagMenu/index.tsx:189 +msgid "See <0>{tag} posts by this user" +msgstr "" + #: src/view/screens/SavedFeeds.tsx:163 msgid "See this guide" msgstr "" @@ -3520,7 +3640,7 @@ msgid "Share" msgstr "" #: src/view/com/profile/ProfileHeader.tsx:295 -#: src/view/com/util/forms/PostDropdownBtn.tsx:182 +#: src/view/com/util/forms/PostDropdownBtn.tsx:184 #: src/view/screens/ProfileList.tsx:418 msgid "Share" msgstr "Compartir" @@ -3553,9 +3673,9 @@ msgstr "" msgid "Show follows similar to {0}" msgstr "" -#: src/view/com/post-thread/PostThreadItem.tsx:532 -#: src/view/com/post/Post.tsx:196 -#: src/view/com/posts/FeedItem.tsx:359 +#: src/view/com/post-thread/PostThreadItem.tsx:538 +#: src/view/com/post/Post.tsx:198 +#: src/view/com/posts/FeedItem.tsx:363 msgid "Show More" msgstr "" @@ -3723,7 +3843,7 @@ msgstr "" msgid "Something went wrong. Check your email and try again." msgstr "" -#: src/App.native.tsx:61 +#: src/App.native.tsx:63 msgid "Sorry! Your session expired. Please log in again." msgstr "" @@ -3781,7 +3901,7 @@ msgstr "" msgid "Subscribe to this list" msgstr "Suscribirse a esta lista" -#: src/view/screens/Search/Search.tsx:373 +#: src/view/screens/Search/Search.tsx:374 msgid "Suggested Follows" msgstr "Usuarios sugeridos a seguir" @@ -3825,6 +3945,14 @@ msgstr "" msgid "System log" msgstr "Bitácora del sistema" +#: src/components/dialogs/MutedWords.tsx:288 +msgid "tag" +msgstr "" + +#: src/components/TagMenu/index.tsx:74 +msgid "Tag menu: {tag}" +msgstr "" + #: src/view/com/modals/crop-image/CropImage.web.tsx:112 msgid "Tall" msgstr "Alto" @@ -3848,6 +3976,10 @@ msgstr "Condiciones" msgid "Terms of Service" msgstr "Condiciones de servicio" +#: src/components/dialogs/MutedWords.tsx:288 +msgid "text" +msgstr "" + #: src/view/com/modals/AppealLabel.tsx:70 #: src/view/com/modals/report/InputIssueDetails.tsx:51 msgid "Text input field" @@ -3873,7 +4005,7 @@ msgstr "La Política de derechos de autor se han trasladado a <0/>" msgid "The following steps will help customize your Bluesky experience." msgstr "" -#: src/view/com/post-thread/PostThread.tsx:516 +#: src/view/com/post-thread/PostThread.tsx:517 msgid "The post may have been deleted." msgstr "Es posible que se haya borrado la publicación." @@ -4039,7 +4171,7 @@ msgstr "" msgid "This name is already in use" msgstr "" -#: src/view/com/post-thread/PostThreadItem.tsx:123 +#: src/view/com/post-thread/PostThreadItem.tsx:125 msgid "This post has been deleted." msgstr "Esta publicación ha sido eliminada." @@ -4063,7 +4195,11 @@ msgstr "" msgid "This warning is only available for posts with media attached." msgstr "Esta advertencia sólo está disponible para las publicaciones con medios adjuntos." -#: src/view/com/util/forms/PostDropdownBtn.tsx:221 +#: src/components/dialogs/MutedWords.tsx:236 +msgid "This will delete {0} from your muted words. You can always add it back later." +msgstr "" + +#: src/view/com/util/forms/PostDropdownBtn.tsx:237 msgid "This will hide this post from your feeds." msgstr "Esto ocultará esta entrada de tus contenidos." @@ -4080,6 +4216,10 @@ msgstr "Modo con hilos" msgid "Threads Preferences" msgstr "" +#: src/components/dialogs/MutedWords.tsx:95 +msgid "Toggle between muted word options." +msgstr "" + #: src/view/com/util/forms/DropdownButton.tsx:246 msgid "Toggle dropdown" msgstr "Conmutar el menú desplegable" @@ -4088,9 +4228,9 @@ msgstr "Conmutar el menú desplegable" msgid "Transformations" msgstr "Transformaciones" -#: src/view/com/post-thread/PostThreadItem.tsx:679 -#: src/view/com/post-thread/PostThreadItem.tsx:681 -#: src/view/com/util/forms/PostDropdownBtn.tsx:154 +#: src/view/com/post-thread/PostThreadItem.tsx:685 +#: src/view/com/post-thread/PostThreadItem.tsx:687 +#: src/view/com/util/forms/PostDropdownBtn.tsx:156 msgid "Translate" msgstr "Traducir" @@ -4155,15 +4295,24 @@ msgstr "Lamentablemente, no cumples los requisitos para crear una cuenta." msgid "Unlike" msgstr "" +#: src/components/TagMenu/index.tsx:253 #: src/view/screens/ProfileList.tsx:597 msgid "Unmute" msgstr "" +#: src/components/TagMenu/index.web.tsx:90 +msgid "Unmute {truncatedTag}" +msgstr "" + #: src/view/com/profile/ProfileHeader.tsx:326 msgid "Unmute Account" msgstr "Desactivar la opción de silenciar la cuenta" -#: src/view/com/util/forms/PostDropdownBtn.tsx:200 +#: src/components/TagMenu/index.tsx:210 +msgid "Unmute all {tag} posts" +msgstr "" + +#: src/view/com/util/forms/PostDropdownBtn.tsx:202 msgid "Unmute thread" msgstr "Desactivar la opción de silenciar el hilo" @@ -4364,6 +4513,10 @@ msgstr "" #~ msgid "We recommend \"For You\" by Skygaze:" #~ msgstr "" +#: src/components/dialogs/MutedWords.tsx:161 +msgid "We recommend avoiding common words that appear in many posts, since it can result in no posts being shown." +msgstr "" + #: src/screens/Onboarding/StepAlgoFeeds/index.tsx:124 msgid "We recommend our \"Discover\" feed:" msgstr "" @@ -4392,7 +4545,11 @@ msgstr "¡Nos hace mucha ilusión que te unas a nosotros!" msgid "We're sorry, but we were unable to resolve this list. If this persists, please contact the list creator, @{handleOrDid}." msgstr "" -#: src/view/screens/Search/Search.tsx:253 +#: src/components/dialogs/MutedWords.tsx:182 +msgid "We're sorry, but we weren't able to load your muted words at this time. Please try again." +msgstr "" + +#: src/view/screens/Search/Search.tsx:254 msgid "We're sorry, but your search could not be completed. Please try again in a few minutes." msgstr "Lo sentimos, pero no se ha podido completar tu búsqueda. Vuelve a intentarlo dentro de unos minutos." @@ -4413,7 +4570,7 @@ msgid "What is the issue with this {collectionName}?" msgstr "¿Cuál es el problema con esta {collectionName}?" #: src/view/com/auth/SplashScreen.tsx:59 -#: src/view/com/composer/Composer.tsx:279 +#: src/view/com/composer/Composer.tsx:286 msgid "What's up?" msgstr "¿Qué hay de nuevo?" @@ -4434,11 +4591,11 @@ msgstr "Quién puede responder" msgid "Wide" msgstr "Ancho" -#: src/view/com/composer/Composer.tsx:415 +#: src/view/com/composer/Composer.tsx:422 msgid "Write post" msgstr "Redactar una publicación" -#: src/view/com/composer/Composer.tsx:278 +#: src/view/com/composer/Composer.tsx:285 #: src/view/com/composer/Prompt.tsx:33 msgid "Write your reply" msgstr "Redactar tu respuesta" @@ -4503,7 +4660,7 @@ msgstr "¡No tienes ninguna noticia guardada!" msgid "You don't have any saved feeds." msgstr "No tienes ninguna noticia guardada." -#: src/view/com/post-thread/PostThread.tsx:464 +#: src/view/com/post-thread/PostThread.tsx:465 msgid "You have blocked the author or you have been blocked by the author." msgstr "Has bloqueado al autor o has sido bloqueado por el autor." @@ -4543,6 +4700,10 @@ msgstr "Aún no has creado ninguna contraseña de aplicación. Puedes crear una msgid "You have not muted any accounts yet. To mute an account, go to their profile and selected \"Mute account\" from the menu on their account." msgstr "Aún no has silenciado ninguna cuenta. Para silenciar una cuenta, ve a su perfil y selecciona \"Silenciar cuenta\" en el menú de su cuenta." +#: src/components/dialogs/MutedWords.tsx:202 +msgid "You haven't muted any words or tags yet" +msgstr "" + #: src/view/com/modals/ContentFilteringSettings.tsx:175 msgid "You must be 18 or older to enable adult content." msgstr "" @@ -4551,11 +4712,11 @@ msgstr "" msgid "You must be 18 years or older to enable adult content" msgstr "" -#: src/view/com/util/forms/PostDropdownBtn.tsx:127 +#: src/view/com/util/forms/PostDropdownBtn.tsx:129 msgid "You will no longer receive notifications for this thread" msgstr "" -#: src/view/com/util/forms/PostDropdownBtn.tsx:130 +#: src/view/com/util/forms/PostDropdownBtn.tsx:132 msgid "You will now receive notifications for this thread" msgstr "" @@ -4641,11 +4802,15 @@ msgstr "" #~ msgid "Your invite codes are hidden when logged in using an App Password" #~ msgstr "Tus códigos de invitación están ocultos cuando inicias sesión con una contraseña de la app" +#: src/components/dialogs/MutedWords.tsx:173 +msgid "Your muted words" +msgstr "" + #: src/view/com/modals/ChangePassword.tsx:155 msgid "Your password has been changed successfully!" msgstr "" -#: src/view/com/composer/Composer.tsx:267 +#: src/view/com/composer/Composer.tsx:274 msgid "Your post has been published" msgstr "" @@ -4660,7 +4825,7 @@ msgstr "Tus publicaciones, Me gustas y bloqueos son públicos. Las cuentas silen msgid "Your profile" msgstr "Tu perfil" -#: src/view/com/composer/Composer.tsx:266 +#: src/view/com/composer/Composer.tsx:273 msgid "Your reply has been published" msgstr "" diff --git a/src/locale/locales/fr/messages.po b/src/locale/locales/fr/messages.po index 8a78424e..44b9fb9a 100644 --- a/src/locale/locales/fr/messages.po +++ b/src/locale/locales/fr/messages.po @@ -80,7 +80,7 @@ msgid "A new version of the app is available. Please update to continue using th msgstr "Une nouvelle version de l’application est disponible. Veuillez faire la mise à jour pour continuer à utiliser l’application." #: src/view/com/util/ViewHeader.tsx:83 -#: src/view/screens/Search/Search.tsx:624 +#: src/view/screens/Search/Search.tsx:647 msgid "Access navigation links and settings" msgstr "Accède aux liens de navigation et aux paramètres" @@ -131,6 +131,7 @@ msgstr "Compte débloqué" msgid "Account unmuted" msgstr "Compte démasqué" +#: src/components/dialogs/MutedWords.tsx:147 #: src/view/com/auth/onboarding/RecommendedFeedsItem.tsx:150 #: src/view/com/modals/ListAddRemoveUsers.tsx:264 #: src/view/com/modals/UserAddRemoveLists.tsx:219 @@ -172,14 +173,22 @@ msgstr "Ajouter des détails" msgid "Add details to report" msgstr "Ajouter des détails au rapport" -#: src/view/com/composer/Composer.tsx:446 +#: src/view/com/composer/Composer.tsx:453 msgid "Add link card" msgstr "Ajouter une carte de lien" -#: src/view/com/composer/Composer.tsx:451 +#: src/view/com/composer/Composer.tsx:458 msgid "Add link card:" msgstr "Ajouter une carte de lien :" +#: src/components/dialogs/MutedWords.tsx:140 +msgid "Add mute word for configured settings" +msgstr "" + +#: src/components/dialogs/MutedWords.tsx:74 +msgid "Add muted words and tags" +msgstr "" + #: src/view/com/modals/ChangeHandle.tsx:417 msgid "Add the following DNS record to your domain:" msgstr "Ajoutez l’enregistrement DNS suivant à votre domaine :" @@ -303,7 +312,7 @@ msgstr "Paramètres de mot de passe d’application" msgid "App Passwords" msgstr "Mots de passe d’application" -#: src/view/com/util/forms/PostDropdownBtn.tsx:279 +#: src/view/com/util/forms/PostDropdownBtn.tsx:295 msgid "Appeal content warning" msgstr "Faire appel de l’avertissement sur le contenu" @@ -327,15 +336,16 @@ msgstr "Affichage" msgid "Are you sure you want to delete the app password \"{name}\"?" msgstr "Êtes-vous sûr de vouloir supprimer le mot de passe de l’application « {name} » ?" -#: src/view/com/composer/Composer.tsx:143 +#: src/view/com/composer/Composer.tsx:150 msgid "Are you sure you'd like to discard this draft?" msgstr "Êtes-vous sûr de vouloir rejeter ce brouillon ?" +#: src/components/dialogs/MutedWords.tsx:233 #: src/view/screens/ProfileList.tsx:365 msgid "Are you sure?" msgstr "Vous confirmez ?" -#: src/view/com/util/forms/PostDropdownBtn.tsx:262 +#: src/view/com/util/forms/PostDropdownBtn.tsx:278 msgid "Are you sure? This cannot be undone." msgstr "Vous confirmez ? Cela ne pourra pas être annulé." @@ -357,15 +367,15 @@ msgstr "Nudité artistique ou non érotique." #: src/view/com/auth/login/LoginForm.tsx:259 #: src/view/com/auth/login/SetNewPasswordForm.tsx:179 #: src/view/com/modals/report/InputIssueDetails.tsx:46 -#: src/view/com/post-thread/PostThread.tsx:471 -#: src/view/com/post-thread/PostThread.tsx:521 -#: src/view/com/post-thread/PostThread.tsx:529 +#: src/view/com/post-thread/PostThread.tsx:472 +#: src/view/com/post-thread/PostThread.tsx:522 +#: src/view/com/post-thread/PostThread.tsx:530 #: src/view/com/profile/ProfileHeader.tsx:649 #: src/view/com/util/ViewHeader.tsx:81 msgid "Back" msgstr "Arrière" -#: src/view/com/post-thread/PostThread.tsx:479 +#: src/view/com/post-thread/PostThread.tsx:480 msgctxt "action" msgid "Back" msgstr "Retour" @@ -413,7 +423,7 @@ msgstr "Bloquer cette liste" msgid "Blocked" msgstr "Bloqué" -#: src/view/screens/Moderation.tsx:123 +#: src/view/screens/Moderation.tsx:142 msgid "Blocked accounts" msgstr "Comptes bloqués" @@ -472,7 +482,7 @@ msgstr "Bluesky est public." msgid "Bluesky uses invites to build a healthier community. If you don't know anybody with an invite, you can sign up for the waitlist and we'll send one soon." msgstr "Bluesky distribue des invitations pour construire une communauté plus saine. Si personne ne peut vous donner une invitation, vous pouvez vous inscrire sur notre liste d’attente et nous vous en enverrons une bientôt." -#: src/view/screens/Moderation.tsx:226 +#: src/view/screens/Moderation.tsx:245 msgid "Bluesky will not show your profile and posts to logged-out users. Other apps may not honor this request. This does not make your account private." msgstr "Bluesky n’affichera pas votre profil et vos messages à des personnes non connectées. Il est possible que d’autres applications n’honorent pas cette demande. Cela ne privatise pas votre compte." @@ -524,8 +534,8 @@ msgid "Can only contain letters, numbers, spaces, dashes, and underscores. Must msgstr "Ne peut contenir que des lettres, des chiffres, des espaces, des tirets et des tirets bas. La longueur doit être d’au moins 4 caractères, mais pas plus de 32." #: src/components/Prompt.tsx:91 -#: src/view/com/composer/Composer.tsx:300 -#: src/view/com/composer/Composer.tsx:305 +#: src/view/com/composer/Composer.tsx:307 +#: src/view/com/composer/Composer.tsx:312 #: src/view/com/modals/ChangeEmail.tsx:218 #: src/view/com/modals/ChangeEmail.tsx:220 #: src/view/com/modals/ChangePassword.tsx:265 @@ -539,7 +549,7 @@ msgstr "Ne peut contenir que des lettres, des chiffres, des espaces, des tirets #: src/view/com/modals/VerifyEmail.tsx:247 #: src/view/com/modals/VerifyEmail.tsx:253 #: src/view/com/modals/Waitlist.tsx:142 -#: src/view/screens/Search/Search.tsx:693 +#: src/view/screens/Search/Search.tsx:716 #: src/view/shell/desktop/Search.tsx:238 msgid "Cancel" msgstr "Annuler" @@ -690,7 +700,7 @@ msgid "Clear all storage data (restart after this)" msgstr "Effacer toutes les données de stockage (redémarrer ensuite)" #: src/view/com/util/forms/SearchInput.tsx:88 -#: src/view/screens/Search/Search.tsx:674 +#: src/view/screens/Search/Search.tsx:697 msgid "Clear search query" msgstr "Effacer la recherche" @@ -698,6 +708,11 @@ msgstr "Effacer la recherche" msgid "click here" msgstr "cliquez ici" +#: src/components/RichText.tsx:189 +#: src/components/TagMenu/index.web.tsx:125 +msgid "Click here to open tag menu for {tag}" +msgstr "" + #: src/screens/Onboarding/index.tsx:35 msgid "Climate" msgstr "" @@ -728,11 +743,15 @@ msgstr "Fermer l’image" msgid "Close image viewer" msgstr "Fermer la visionneuse d’images" -#: src/view/shell/index.web.tsx:49 +#: src/view/shell/index.web.tsx:51 msgid "Close navigation footer" msgstr "Fermer le pied de page de navigation" -#: src/view/shell/index.web.tsx:50 +#: src/components/TagMenu/index.tsx:266 +msgid "Close this dialog" +msgstr "" + +#: src/view/shell/index.web.tsx:52 msgid "Closes bottom navigation bar" msgstr "Ferme la barre de navigation du bas" @@ -740,7 +759,7 @@ msgstr "Ferme la barre de navigation du bas" msgid "Closes password update alert" msgstr "Ferme la notification de mise à jour du mot de passe" -#: src/view/com/composer/Composer.tsx:302 +#: src/view/com/composer/Composer.tsx:309 msgid "Closes post composer and discards post draft" msgstr "Ferme la fenêtre de rédaction et supprime le brouillon" @@ -773,7 +792,7 @@ msgstr "" msgid "Complete the challenge" msgstr "" -#: src/view/com/composer/Composer.tsx:417 +#: src/view/com/composer/Composer.tsx:424 msgid "Compose posts up to {MAX_GRAPHEME_LENGTH} characters in length" msgstr "Permet d’écrire des messages de {MAX_GRAPHEME_LENGTH} caractères maximum" @@ -837,7 +856,7 @@ msgstr "Connexion…" msgid "Contact support" msgstr "" -#: src/view/screens/Moderation.tsx:81 +#: src/view/screens/Moderation.tsx:83 msgid "Content filtering" msgstr "Filtrage du contenu" @@ -903,7 +922,7 @@ msgstr "Version de build copiée dans le presse-papier" #: src/view/com/modals/AddAppPasswords.tsx:76 #: src/view/com/modals/InviteCodes.tsx:152 -#: src/view/com/util/forms/PostDropdownBtn.tsx:141 +#: src/view/com/util/forms/PostDropdownBtn.tsx:143 msgid "Copied to clipboard" msgstr "Copié dans le presse-papier" @@ -919,7 +938,7 @@ msgstr "Copie" msgid "Copy link to list" msgstr "Copier le lien vers la liste" -#: src/view/com/util/forms/PostDropdownBtn.tsx:182 +#: src/view/com/util/forms/PostDropdownBtn.tsx:184 msgid "Copy link to post" msgstr "Copier le lien vers le post" @@ -927,7 +946,7 @@ msgstr "Copier le lien vers le post" msgid "Copy link to profile" msgstr "Copier le lien vers le profil" -#: src/view/com/util/forms/PostDropdownBtn.tsx:168 +#: src/view/com/util/forms/PostDropdownBtn.tsx:170 msgid "Copy post text" msgstr "Copier le texte du post" @@ -983,7 +1002,7 @@ msgstr "Créée par <0/>" msgid "Created by you" msgstr "Créée par vous" -#: src/view/com/composer/Composer.tsx:448 +#: src/view/com/composer/Composer.tsx:455 msgid "Creates a card with a thumbnail. The card links to {url}" msgstr "Crée une carte avec une miniature. La carte pointe vers {url}" @@ -1060,11 +1079,11 @@ msgstr "Supprimer mon compte" msgid "Delete My Account…" msgstr "" -#: src/view/com/util/forms/PostDropdownBtn.tsx:257 +#: src/view/com/util/forms/PostDropdownBtn.tsx:273 msgid "Delete post" msgstr "Supprimer le post" -#: src/view/com/util/forms/PostDropdownBtn.tsx:261 +#: src/view/com/util/forms/PostDropdownBtn.tsx:277 msgid "Delete this post?" msgstr "Supprimer ce post ?" @@ -1087,7 +1106,7 @@ msgstr "Description" #~ msgid "Developer Tools" #~ msgstr "Outils de dév" -#: src/view/com/composer/Composer.tsx:211 +#: src/view/com/composer/Composer.tsx:218 msgid "Did you want to say anything?" msgstr "Vous vouliez dire quelque chose ?" @@ -1095,15 +1114,15 @@ msgstr "Vous vouliez dire quelque chose ?" msgid "Dim" msgstr "" -#: src/view/com/composer/Composer.tsx:144 +#: src/view/com/composer/Composer.tsx:151 msgid "Discard" msgstr "Ignorer" -#: src/view/com/composer/Composer.tsx:138 +#: src/view/com/composer/Composer.tsx:145 msgid "Discard draft" msgstr "Ignorer le brouillon" -#: src/view/screens/Moderation.tsx:207 +#: src/view/screens/Moderation.tsx:226 msgid "Discourage apps from showing my account to logged-out users" msgstr "Empêcher les applis de montrer mon compte aux personnes non connectées" @@ -1182,7 +1201,7 @@ msgstr "" msgid "Download CAR file" msgstr "" -#: src/view/com/composer/text-input/TextInput.web.tsx:247 +#: src/view/com/composer/text-input/TextInput.web.tsx:249 msgid "Drop to add images" msgstr "" @@ -1254,6 +1273,7 @@ msgstr "Modifier le profil" msgid "Edit Profile" msgstr "Modifier le profil" +#: src/view/com/home/HomeHeaderLayout.web.tsx:59 #: src/view/screens/Feeds.tsx:355 msgid "Edit Saved Feeds" msgstr "Modifier les fils d’actu enregistrés" @@ -1336,6 +1356,11 @@ msgstr "Fin du fil d’actu" msgid "Enter a name for this App Password" msgstr "Entrer un nom pour ce mot de passe d’application" +#: src/components/dialogs/MutedWords.tsx:87 +#: src/components/dialogs/MutedWords.tsx:88 +msgid "Enter a word or tag" +msgstr "" + #: src/view/com/modals/VerifyEmail.tsx:105 msgid "Enter Confirmation Code" msgstr "Entrer un code de confirmation" @@ -1385,7 +1410,7 @@ msgstr "Entrez votre pseudo et votre mot de passe" msgid "Error receiving captcha response." msgstr "" -#: src/view/screens/Search/Search.tsx:109 +#: src/view/screens/Search/Search.tsx:110 msgid "Error:" msgstr "Erreur :" @@ -1456,7 +1481,7 @@ msgstr "Échec de la création du mot de passe d’application." msgid "Failed to create the list. Check your internet connection and try again." msgstr "Échec de la création de la liste. Vérifiez votre connexion Internet et réessayez." -#: src/view/com/util/forms/PostDropdownBtn.tsx:108 +#: src/view/com/util/forms/PostDropdownBtn.tsx:110 msgid "Failed to delete post, please try again" msgstr "Échec de la suppression du post, veuillez réessayer" @@ -1478,8 +1503,8 @@ msgid "Feed offline" msgstr "Fil d’actu hors ligne" #: src/view/com/feeds/FeedPage.tsx:143 -msgid "Feed Preferences" -msgstr "Préférences en matière de fil d’actu" +#~ msgid "Feed Preferences" +#~ msgstr "Préférences en matière de fil d’actu" #: src/view/shell/desktop/RightNav.tsx:61 #: src/view/shell/Drawer.tsx:311 @@ -1527,11 +1552,11 @@ msgstr "" msgid "Find accounts to follow" msgstr "Trouver des comptes à suivre" -#: src/view/screens/Search/Search.tsx:439 +#: src/view/screens/Search/Search.tsx:440 msgid "Find users on Bluesky" msgstr "Trouver des comptes sur Bluesky" -#: src/view/screens/Search/Search.tsx:437 +#: src/view/screens/Search/Search.tsx:438 msgid "Find users with the search tool on the right" msgstr "Trouvez des comptes à l’aide de l’outil de recherche, à droite" @@ -1628,6 +1653,7 @@ msgid "Following {0}" msgstr "Suit {0}" #: src/Navigation.tsx:248 +#: src/view/com/home/HomeHeaderLayout.web.tsx:45 #: src/view/com/home/HomeHeaderLayoutMobile.tsx:83 #: src/view/screens/PreferencesFollowingFeed.tsx:104 #: src/view/screens/Settings/index.tsx:543 @@ -1667,7 +1693,7 @@ msgstr "Mot de passe oublié" msgid "Forgot Password" msgstr "Mot de passe oublié" -#: src/view/com/posts/FeedItem.tsx:187 +#: src/view/com/posts/FeedItem.tsx:189 msgctxt "from-feed" msgid "From <0/>" msgstr "Tiré de <0/>" @@ -1700,7 +1726,7 @@ msgstr "Retour" msgid "Go back to previous step" msgstr "" -#: src/view/screens/Search/Search.tsx:724 +#: src/view/screens/Search/Search.tsx:747 #: src/view/shell/desktop/Search.tsx:262 msgid "Go to @{queryMaybeHandle}" msgstr "" @@ -1717,6 +1743,10 @@ msgstr "Aller à la suite" msgid "Handle" msgstr "Pseudo" +#: src/components/RichText.tsx:188 +msgid "Hashtag: {tag}" +msgstr "" + #: src/view/com/auth/create/CreateAccount.tsx:208 msgid "Having trouble?" msgstr "" @@ -1755,7 +1785,7 @@ msgctxt "action" msgid "Hide" msgstr "Cacher" -#: src/view/com/util/forms/PostDropdownBtn.tsx:216 +#: src/view/com/util/forms/PostDropdownBtn.tsx:232 msgid "Hide post" msgstr "Cacher ce post" @@ -1764,7 +1794,7 @@ msgstr "Cacher ce post" msgid "Hide the content" msgstr "Cacher ce contenu" -#: src/view/com/util/forms/PostDropdownBtn.tsx:220 +#: src/view/com/util/forms/PostDropdownBtn.tsx:236 msgid "Hide this post?" msgstr "Cacher ce post ?" @@ -1913,7 +1943,7 @@ msgstr "Entrez votre mot de passe" msgid "Input your user handle" msgstr "Entrez votre pseudo" -#: src/view/com/post-thread/PostThreadItem.tsx:224 +#: src/view/com/post-thread/PostThreadItem.tsx:226 msgid "Invalid or unsupported post record" msgstr "Enregistrement de post invalide ou non pris en charge" @@ -2015,7 +2045,7 @@ msgstr "En savoir plus" msgid "Learn more about this warning" msgstr "En savoir plus sur cet avertissement" -#: src/view/screens/Moderation.tsx:243 +#: src/view/screens/Moderation.tsx:262 msgid "Learn more about what is public on Bluesky." msgstr "En savoir plus sur ce qui est public sur Bluesky." @@ -2091,7 +2121,7 @@ msgstr "liké votre post" msgid "Likes" msgstr "Likes" -#: src/view/com/post-thread/PostThreadItem.tsx:181 +#: src/view/com/post-thread/PostThreadItem.tsx:183 msgid "Likes on this post" msgstr "Likes sur ce post" @@ -2148,7 +2178,7 @@ msgstr "Charger plus d’articles" msgid "Load new notifications" msgstr "Charger les nouvelles notifications" -#: src/view/com/feeds/FeedPage.tsx:181 +#: src/view/com/feeds/FeedPage.tsx:115 #: src/view/screens/Profile.tsx:440 #: src/view/screens/ProfileFeed.tsx:495 #: src/view/screens/ProfileList.tsx:681 @@ -2174,7 +2204,7 @@ msgstr "Journaux" msgid "Log out" msgstr "" -#: src/view/screens/Moderation.tsx:136 +#: src/view/screens/Moderation.tsx:155 msgid "Logged-out visibility" msgstr "Visibilité déconnectée" @@ -2186,6 +2216,10 @@ msgstr "Se connecter à un compte qui n’est pas listé" msgid "Make sure this is where you intend to go!" msgstr "Assurez-vous que c’est bien là que vous avez l’intention d’aller !" +#: src/components/dialogs/MutedWords.tsx:71 +msgid "Manage your muted words and tags" +msgstr "" + #: src/view/com/auth/create/Step2.tsx:118 msgid "May not be longer than 253 characters" msgstr "" @@ -2207,7 +2241,7 @@ msgid "Mentioned users" msgstr "Comptes mentionnés" #: src/view/com/util/ViewHeader.tsx:81 -#: src/view/screens/Search/Search.tsx:623 +#: src/view/screens/Search/Search.tsx:646 msgid "Menu" msgstr "Menu" @@ -2216,7 +2250,7 @@ msgid "Message from server: {0}" msgstr "Message du serveur : {0}" #: src/Navigation.tsx:115 -#: src/view/screens/Moderation.tsx:64 +#: src/view/screens/Moderation.tsx:66 #: src/view/screens/Settings/index.tsx:625 #: src/view/shell/desktop/LeftNav.tsx:397 #: src/view/shell/Drawer.tsx:511 @@ -2247,7 +2281,7 @@ msgstr "Liste de modération créée" msgid "Moderation list updated" msgstr "Liste de modération mise à jour" -#: src/view/screens/Moderation.tsx:95 +#: src/view/screens/Moderation.tsx:114 msgid "Moderation lists" msgstr "Listes de modération" @@ -2274,7 +2308,7 @@ msgstr "Plus de fils d’actu" msgid "More options" msgstr "Plus d’options" -#: src/view/com/util/forms/PostDropdownBtn.tsx:299 +#: src/view/com/util/forms/PostDropdownBtn.tsx:315 msgid "More post options" msgstr "Plus d’options de post" @@ -2286,6 +2320,14 @@ msgstr "Réponses les plus likées en premier" msgid "Must be at least 3 characters" msgstr "" +#: src/components/TagMenu/index.tsx:253 +msgid "Mute" +msgstr "" + +#: src/components/TagMenu/index.web.tsx:91 +msgid "Mute {truncatedTag}" +msgstr "" + #: src/view/com/profile/ProfileHeader.tsx:327 msgid "Mute Account" msgstr "Masquer le compte" @@ -2294,6 +2336,18 @@ msgstr "Masquer le compte" msgid "Mute accounts" msgstr "Masquer les comptes" +#: src/components/TagMenu/index.tsx:211 +msgid "Mute all {tag} posts" +msgstr "" + +#: src/components/dialogs/MutedWords.tsx:131 +msgid "Mute in tags only" +msgstr "" + +#: src/components/dialogs/MutedWords.tsx:116 +msgid "Mute in text & tags" +msgstr "" + #: src/view/screens/ProfileList.tsx:491 msgid "Mute list" msgstr "Masquer la liste" @@ -2306,15 +2360,27 @@ msgstr "Masquer ces comptes ?" msgid "Mute this List" msgstr "Masquer cette liste" -#: src/view/com/util/forms/PostDropdownBtn.tsx:200 +#: src/components/dialogs/MutedWords.tsx:109 +msgid "Mute this word in post text and tags" +msgstr "" + +#: src/components/dialogs/MutedWords.tsx:124 +msgid "Mute this word in tags only" +msgstr "" + +#: src/view/com/util/forms/PostDropdownBtn.tsx:202 msgid "Mute thread" msgstr "Masquer ce fil de discussion" +#: src/view/com/util/forms/PostDropdownBtn.tsx:216 +msgid "Mute words & tags" +msgstr "" + #: src/view/com/lists/ListCard.tsx:102 msgid "Muted" msgstr "" -#: src/view/screens/Moderation.tsx:109 +#: src/view/screens/Moderation.tsx:128 msgid "Muted accounts" msgstr "Comptes masqués" @@ -2327,6 +2393,10 @@ msgstr "Comptes masqués" msgid "Muted accounts have their posts removed from your feed and from your notifications. Mutes are completely private." msgstr "Les comptes masqués voient leurs posts supprimés de votre fil d’actualité et de vos notifications. Cette option est totalement privée." +#: src/view/screens/Moderation.tsx:100 +msgid "Muted words & tags" +msgstr "" + #: src/view/screens/ProfileList.tsx:277 msgid "Muting is private. Muted accounts can interact with you, but you will not see their posts or receive notifications from them." msgstr "Ce que vous masquez reste privé. Les comptes masqués peuvent interagir avec vous, mais vous ne verrez pas leurs posts et ne recevrez pas de notifications de leur part." @@ -2390,6 +2460,10 @@ msgstr "Ne perdez jamais l’accès à vos followers et à vos données." msgid "Never lose access to your followers or data." msgstr "" +#: src/components/dialogs/MutedWords.tsx:244 +msgid "Nevermind" +msgstr "" + #: src/view/screens/Lists.tsx:76 msgctxt "action" msgid "New" @@ -2411,7 +2485,7 @@ msgstr "Nouveau mot de passe" msgid "New Password" msgstr "" -#: src/view/com/feeds/FeedPage.tsx:192 +#: src/view/com/feeds/FeedPage.tsx:126 msgctxt "action" msgid "New post" msgstr "Nouveau post" @@ -2496,8 +2570,8 @@ msgid "No results found for \"{query}\"" msgstr "Aucun résultat trouvé pour « {query} »" #: src/view/com/modals/ListAddRemoveUsers.tsx:127 -#: src/view/screens/Search/Search.tsx:280 -#: src/view/screens/Search/Search.tsx:308 +#: src/view/screens/Search/Search.tsx:281 +#: src/view/screens/Search/Search.tsx:309 msgid "No results found for {query}" msgstr "Aucun résultat trouvé pour {query}" @@ -2523,7 +2597,7 @@ msgstr "Introuvable" msgid "Not right now" msgstr "Pas maintenant" -#: src/view/screens/Moderation.tsx:233 +#: src/view/screens/Moderation.tsx:252 msgid "Note: Bluesky is an open and public network. This setting only limits the visibility of your content on the Bluesky app and website, and other apps may not respect this setting. Your content may still be shown to logged-out users by other apps and websites." msgstr "Remarque : Bluesky est un réseau ouvert et public. Ce paramètre limite uniquement la visibilité de votre contenu sur l’application et le site Web de Bluesky, et d’autres applications peuvent ne pas respecter ce paramètre. Votre contenu peut toujours être montré aux personnes non connectées par d’autres applications et sites Web." @@ -2561,7 +2635,7 @@ msgstr "Plus anciennes réponses en premier" msgid "Onboarding reset" msgstr "Réinitialiser le didacticiel" -#: src/view/com/composer/Composer.tsx:375 +#: src/view/com/composer/Composer.tsx:382 msgid "One or more images is missing alt text." msgstr "Une ou plusieurs images n’ont pas de texte alt." @@ -2578,8 +2652,12 @@ msgstr "Oups !" msgid "Open" msgstr "" -#: src/view/com/composer/Composer.tsx:470 -#: src/view/com/composer/Composer.tsx:471 +#: src/view/screens/Moderation.tsx:75 +msgid "Open content filtering settings" +msgstr "" + +#: src/view/com/composer/Composer.tsx:477 +#: src/view/com/composer/Composer.tsx:478 msgid "Open emoji picker" msgstr "Ouvrir le sélecteur d’emoji" @@ -2587,6 +2665,10 @@ msgstr "Ouvrir le sélecteur d’emoji" msgid "Open links with in-app browser" msgstr "" +#: src/view/screens/Moderation.tsx:92 +msgid "Open muted words settings" +msgstr "" + #: src/view/com/home/HomeHeaderLayoutMobile.tsx:49 msgid "Open navigation" msgstr "Navigation ouverte" @@ -2663,6 +2745,7 @@ msgstr "Ouvre les paramètres de modération" msgid "Opens password reset form" msgstr "Ouvre le formulaire de réinitialisation du mot de passe" +#: src/view/com/home/HomeHeaderLayout.web.tsx:60 #: src/view/screens/Feeds.tsx:356 msgid "Opens screen to edit Saved Feeds" msgstr "Ouvre l’écran pour modifier les fils d’actu enregistrés" @@ -2838,7 +2921,7 @@ msgstr "Dites-nous donc pourquoi vous pensez que cet avertissement de contenu a msgid "Please Verify Your Email" msgstr "Veuillez vérifier votre e-mail" -#: src/view/com/composer/Composer.tsx:215 +#: src/view/com/composer/Composer.tsx:222 msgid "Please wait for your link card to finish loading" msgstr "Veuillez patienter le temps que votre carte de lien soit chargée" @@ -2850,8 +2933,8 @@ msgstr "" msgid "Porn" msgstr "Porno" -#: src/view/com/composer/Composer.tsx:350 -#: src/view/com/composer/Composer.tsx:358 +#: src/view/com/composer/Composer.tsx:357 +#: src/view/com/composer/Composer.tsx:365 msgctxt "action" msgid "Post" msgstr "Poster" @@ -2861,7 +2944,7 @@ msgctxt "description" msgid "Post" msgstr "Post" -#: src/view/com/post-thread/PostThreadItem.tsx:173 +#: src/view/com/post-thread/PostThreadItem.tsx:175 msgid "Post by {0}" msgstr "Post de {0}" @@ -2871,11 +2954,11 @@ msgstr "Post de {0}" msgid "Post by @{0}" msgstr "Post de @{0}" -#: src/view/com/util/forms/PostDropdownBtn.tsx:88 +#: src/view/com/util/forms/PostDropdownBtn.tsx:90 msgid "Post deleted" msgstr "Post supprimé" -#: src/view/com/post-thread/PostThread.tsx:461 +#: src/view/com/post-thread/PostThread.tsx:462 msgid "Post hidden" msgstr "Post caché" @@ -2887,14 +2970,22 @@ msgstr "Langue du post" msgid "Post Languages" msgstr "Langues du post" -#: src/view/com/post-thread/PostThread.tsx:513 +#: src/view/com/post-thread/PostThread.tsx:514 msgid "Post not found" msgstr "Post introuvable" +#: src/components/TagMenu/index.tsx:257 +msgid "posts" +msgstr "" + #: src/view/screens/Profile.tsx:180 msgid "Posts" msgstr "Posts" +#: src/components/dialogs/MutedWords.tsx:77 +msgid "Posts can be muted based on their text, their tags, or both." +msgstr "" + #: src/view/com/posts/FeedErrorMessage.tsx:64 msgid "Posts hidden" msgstr "Posts cachés" @@ -2959,11 +3050,11 @@ msgstr "Listes publiques et partageables de comptes à masquer ou à bloquer." msgid "Public, shareable lists which can drive feeds." msgstr "Les listes publiques et partageables qui peuvent alimenter les fils d’actu." -#: src/view/com/composer/Composer.tsx:335 +#: src/view/com/composer/Composer.tsx:342 msgid "Publish post" msgstr "Publier le post" -#: src/view/com/composer/Composer.tsx:335 +#: src/view/com/composer/Composer.tsx:342 msgid "Publish reply" msgstr "Publier la réponse" @@ -2997,6 +3088,7 @@ msgstr "Fils d’actu recommandés" msgid "Recommended Users" msgstr "Comptes recommandés" +#: src/components/dialogs/MutedWords.tsx:249 #: src/view/com/modals/ListAddRemoveUsers.tsx:264 #: src/view/com/modals/SelfLabel.tsx:83 #: src/view/com/modals/UserAddRemoveLists.tsx:219 @@ -3034,6 +3126,10 @@ msgstr "Supprimer l’image" msgid "Remove image preview" msgstr "Supprimer l’aperçu d’image" +#: src/components/dialogs/MutedWords.tsx:294 +msgid "Remove mute word from your list" +msgstr "" + #: src/view/com/modals/Repost.tsx:47 msgid "Remove repost" msgstr "Supprimer le repost" @@ -3068,7 +3164,7 @@ msgstr "Réponses" msgid "Replies to this thread are disabled" msgstr "Les réponses à ce fil de discussion sont désactivées" -#: src/view/com/composer/Composer.tsx:348 +#: src/view/com/composer/Composer.tsx:355 msgctxt "action" msgid "Reply" msgstr "Répondre" @@ -3078,7 +3174,7 @@ msgid "Reply Filters" msgstr "Filtres de réponse" #: src/view/com/post/Post.tsx:167 -#: src/view/com/posts/FeedItem.tsx:285 +#: src/view/com/posts/FeedItem.tsx:287 msgctxt "description" msgid "Reply to <0/>" msgstr "Réponse à <0/>" @@ -3100,7 +3196,7 @@ msgid "Report List" msgstr "Signaler la liste" #: src/view/com/modals/report/SendReportButton.tsx:37 -#: src/view/com/util/forms/PostDropdownBtn.tsx:239 +#: src/view/com/util/forms/PostDropdownBtn.tsx:255 msgid "Report post" msgstr "Signaler le post" @@ -3125,11 +3221,11 @@ msgstr "Republier ou citer" msgid "Reposted By" msgstr "Republié par" -#: src/view/com/posts/FeedItem.tsx:205 +#: src/view/com/posts/FeedItem.tsx:207 msgid "Reposted by {0}" msgstr "Republié par {0}" -#: src/view/com/posts/FeedItem.tsx:222 +#: src/view/com/posts/FeedItem.tsx:224 msgid "Reposted by <0/>" msgstr "Republié par <0/>" @@ -3137,7 +3233,7 @@ msgstr "Republié par <0/>" msgid "reposted your post" msgstr "a republié votre post" -#: src/view/com/post-thread/PostThreadItem.tsx:186 +#: src/view/com/post-thread/PostThreadItem.tsx:188 msgid "Reposts of this post" msgstr "Reposts de ce post" @@ -3288,9 +3384,9 @@ msgstr "Remonter en haut" #: src/view/com/modals/ListAddRemoveUsers.tsx:75 #: src/view/com/util/forms/SearchInput.tsx:67 #: src/view/com/util/forms/SearchInput.tsx:79 -#: src/view/screens/Search/Search.tsx:418 -#: src/view/screens/Search/Search.tsx:645 -#: src/view/screens/Search/Search.tsx:663 +#: src/view/screens/Search/Search.tsx:419 +#: src/view/screens/Search/Search.tsx:668 +#: src/view/screens/Search/Search.tsx:686 #: src/view/shell/bottom-bar/BottomBar.tsx:159 #: src/view/shell/desktop/LeftNav.tsx:324 #: src/view/shell/desktop/Search.tsx:214 @@ -3300,11 +3396,19 @@ msgstr "Remonter en haut" msgid "Search" msgstr "Recherche" -#: src/view/screens/Search/Search.tsx:712 +#: src/view/screens/Search/Search.tsx:735 #: src/view/shell/desktop/Search.tsx:255 msgid "Search for \"{query}\"" msgstr "" +#: src/components/TagMenu/index.tsx:145 +msgid "Search for all posts by @{authorHandle} with tag {tag}" +msgstr "" + +#: src/components/TagMenu/index.tsx:90 +msgid "Search for all posts with tag {tag}" +msgstr "" + #: src/view/com/auth/LoggedOut.tsx:104 #: src/view/com/auth/LoggedOut.tsx:105 #: src/view/com/modals/ListAddRemoveUsers.tsx:70 @@ -3315,6 +3419,22 @@ msgstr "Rechercher des comptes" msgid "Security Step Required" msgstr "Étape de sécurité requise" +#: src/components/TagMenu/index.web.tsx:50 +msgid "See {truncatedTag} posts" +msgstr "" + +#: src/components/TagMenu/index.web.tsx:67 +msgid "See {truncatedTag} posts by user" +msgstr "" + +#: src/components/TagMenu/index.tsx:128 +msgid "See <0>{tag} posts" +msgstr "" + +#: src/components/TagMenu/index.tsx:189 +msgid "See <0>{tag} posts by this user" +msgstr "" + #: src/view/screens/SavedFeeds.tsx:163 msgid "See this guide" msgstr "Voir ce guide" @@ -3524,7 +3644,7 @@ msgid "Share" msgstr "Partager" #: src/view/com/profile/ProfileHeader.tsx:295 -#: src/view/com/util/forms/PostDropdownBtn.tsx:182 +#: src/view/com/util/forms/PostDropdownBtn.tsx:184 #: src/view/screens/ProfileList.tsx:418 msgid "Share" msgstr "Partager" @@ -3557,9 +3677,9 @@ msgstr "Afficher les intégrations de {0}" msgid "Show follows similar to {0}" msgstr "Afficher les suivis similaires à {0}" -#: src/view/com/post-thread/PostThreadItem.tsx:532 -#: src/view/com/post/Post.tsx:196 -#: src/view/com/posts/FeedItem.tsx:359 +#: src/view/com/post-thread/PostThreadItem.tsx:538 +#: src/view/com/post/Post.tsx:198 +#: src/view/com/posts/FeedItem.tsx:363 msgid "Show More" msgstr "Voir plus" @@ -3727,7 +3847,7 @@ msgstr "" msgid "Something went wrong. Check your email and try again." msgstr "Quelque chose n’a pas marché. Vérifiez vos e-mails et réessayez." -#: src/App.native.tsx:61 +#: src/App.native.tsx:63 msgid "Sorry! Your session expired. Please log in again." msgstr "Désolé ! Votre session a expiré. Essayez de vous reconnecter." @@ -3785,7 +3905,7 @@ msgstr "" msgid "Subscribe to this list" msgstr "S’abonner à cette liste" -#: src/view/screens/Search/Search.tsx:373 +#: src/view/screens/Search/Search.tsx:374 msgid "Suggested Follows" msgstr "Suivis suggérés" @@ -3829,6 +3949,14 @@ msgstr "Système" msgid "System log" msgstr "Journal système" +#: src/components/dialogs/MutedWords.tsx:288 +msgid "tag" +msgstr "" + +#: src/components/TagMenu/index.tsx:74 +msgid "Tag menu: {tag}" +msgstr "" + #: src/view/com/modals/crop-image/CropImage.web.tsx:112 msgid "Tall" msgstr "Grand" @@ -3852,6 +3980,10 @@ msgstr "Conditions générales" msgid "Terms of Service" msgstr "Conditions d’utilisation" +#: src/components/dialogs/MutedWords.tsx:288 +msgid "text" +msgstr "" + #: src/view/com/modals/AppealLabel.tsx:70 #: src/view/com/modals/report/InputIssueDetails.tsx:51 msgid "Text input field" @@ -3877,7 +4009,7 @@ msgstr "Notre politique de droits d’auteur a été déplacée vers <0/>" msgid "The following steps will help customize your Bluesky experience." msgstr "" -#: src/view/com/post-thread/PostThread.tsx:516 +#: src/view/com/post-thread/PostThread.tsx:517 msgid "The post may have been deleted." msgstr "Ce post a peut-être été supprimé." @@ -4043,7 +4175,7 @@ msgstr "Cette liste est vide !" msgid "This name is already in use" msgstr "Ce nom est déjà utilisé" -#: src/view/com/post-thread/PostThreadItem.tsx:123 +#: src/view/com/post-thread/PostThreadItem.tsx:125 msgid "This post has been deleted." msgstr "Ce post a été supprimé." @@ -4067,7 +4199,11 @@ msgstr "" msgid "This warning is only available for posts with media attached." msgstr "Cet avertissement n’est disponible que pour les messages contenant des médias." -#: src/view/com/util/forms/PostDropdownBtn.tsx:221 +#: src/components/dialogs/MutedWords.tsx:236 +msgid "This will delete {0} from your muted words. You can always add it back later." +msgstr "" + +#: src/view/com/util/forms/PostDropdownBtn.tsx:237 msgid "This will hide this post from your feeds." msgstr "Cela va masquer ce post de vos fils d’actu." @@ -4084,6 +4220,10 @@ msgstr "Mode arborescent" msgid "Threads Preferences" msgstr "Préférences de fils de discussion" +#: src/components/dialogs/MutedWords.tsx:95 +msgid "Toggle between muted word options." +msgstr "" + #: src/view/com/util/forms/DropdownButton.tsx:246 msgid "Toggle dropdown" msgstr "Activer le menu déroulant" @@ -4092,9 +4232,9 @@ msgstr "Activer le menu déroulant" msgid "Transformations" msgstr "Transformations" -#: src/view/com/post-thread/PostThreadItem.tsx:679 -#: src/view/com/post-thread/PostThreadItem.tsx:681 -#: src/view/com/util/forms/PostDropdownBtn.tsx:154 +#: src/view/com/post-thread/PostThreadItem.tsx:685 +#: src/view/com/post-thread/PostThreadItem.tsx:687 +#: src/view/com/util/forms/PostDropdownBtn.tsx:156 msgid "Translate" msgstr "Traduire" @@ -4159,15 +4299,24 @@ msgstr "Malheureusement, vous ne remplissez pas les conditions requises pour cr msgid "Unlike" msgstr "Déliker" +#: src/components/TagMenu/index.tsx:253 #: src/view/screens/ProfileList.tsx:597 msgid "Unmute" msgstr "Réafficher" +#: src/components/TagMenu/index.web.tsx:90 +msgid "Unmute {truncatedTag}" +msgstr "" + #: src/view/com/profile/ProfileHeader.tsx:326 msgid "Unmute Account" msgstr "Réafficher ce compte" -#: src/view/com/util/forms/PostDropdownBtn.tsx:200 +#: src/components/TagMenu/index.tsx:210 +msgid "Unmute all {tag} posts" +msgstr "" + +#: src/view/com/util/forms/PostDropdownBtn.tsx:202 msgid "Unmute thread" msgstr "Réafficher ce fil de discussion" @@ -4368,6 +4517,10 @@ msgstr "" #~ msgid "We recommend \"For You\" by Skygaze:" #~ msgstr "" +#: src/components/dialogs/MutedWords.tsx:161 +msgid "We recommend avoiding common words that appear in many posts, since it can result in no posts being shown." +msgstr "" + #: src/screens/Onboarding/StepAlgoFeeds/index.tsx:124 msgid "We recommend our \"Discover\" feed:" msgstr "" @@ -4396,7 +4549,11 @@ msgstr "Nous sommes ravis de vous accueillir !" msgid "We're sorry, but we were unable to resolve this list. If this persists, please contact the list creator, @{handleOrDid}." msgstr "Nous sommes désolés, mais nous n’avons pas pu charger cette liste. Si cela persiste, veuillez contacter l’origine de la liste, @{handleOrDid}." -#: src/view/screens/Search/Search.tsx:253 +#: src/components/dialogs/MutedWords.tsx:182 +msgid "We're sorry, but we weren't able to load your muted words at this time. Please try again." +msgstr "" + +#: src/view/screens/Search/Search.tsx:254 msgid "We're sorry, but your search could not be completed. Please try again in a few minutes." msgstr "Nous sommes désolés, mais votre recherche a été annulée. Veuillez réessayer dans quelques minutes." @@ -4417,7 +4574,7 @@ msgid "What is the issue with this {collectionName}?" msgstr "Quel est le problème avec cette {collectionName} ?" #: src/view/com/auth/SplashScreen.tsx:59 -#: src/view/com/composer/Composer.tsx:279 +#: src/view/com/composer/Composer.tsx:286 msgid "What's up?" msgstr "Quoi de neuf ?" @@ -4438,11 +4595,11 @@ msgstr "Qui peut répondre ?" msgid "Wide" msgstr "Large" -#: src/view/com/composer/Composer.tsx:415 +#: src/view/com/composer/Composer.tsx:422 msgid "Write post" msgstr "Rédiger un post" -#: src/view/com/composer/Composer.tsx:278 +#: src/view/com/composer/Composer.tsx:285 #: src/view/com/composer/Prompt.tsx:33 msgid "Write your reply" msgstr "Rédigez votre réponse" @@ -4507,7 +4664,7 @@ msgstr "Vous n’avez encore aucun fil enregistré !" msgid "You don't have any saved feeds." msgstr "Vous n’avez encore aucun fil enregistré." -#: src/view/com/post-thread/PostThread.tsx:464 +#: src/view/com/post-thread/PostThread.tsx:465 msgid "You have blocked the author or you have been blocked by the author." msgstr "Vous avez bloqué cet auteur ou vous avez été bloqué par celui-ci." @@ -4547,6 +4704,10 @@ msgstr "Vous n’avez encore créé aucun mot de passe pour l’appli. Vous pouv msgid "You have not muted any accounts yet. To mute an account, go to their profile and selected \"Mute account\" from the menu on their account." msgstr "Vous n’avez encore masqué aucun compte. Pour désactiver un compte, allez sur son profil et sélectionnez « Masquer le compte » dans le menu de son compte." +#: src/components/dialogs/MutedWords.tsx:202 +msgid "You haven't muted any words or tags yet" +msgstr "" + #: src/view/com/modals/ContentFilteringSettings.tsx:175 msgid "You must be 18 or older to enable adult content." msgstr "Vous devez avoir 18 ans ou plus pour activer le contenu pour adultes." @@ -4555,11 +4716,11 @@ msgstr "Vous devez avoir 18 ans ou plus pour activer le contenu pour adultes." msgid "You must be 18 years or older to enable adult content" msgstr "" -#: src/view/com/util/forms/PostDropdownBtn.tsx:127 +#: src/view/com/util/forms/PostDropdownBtn.tsx:129 msgid "You will no longer receive notifications for this thread" msgstr "Vous ne recevrez plus de notifications pour ce fil de discussion" -#: src/view/com/util/forms/PostDropdownBtn.tsx:130 +#: src/view/com/util/forms/PostDropdownBtn.tsx:132 msgid "You will now receive notifications for this thread" msgstr "Vous recevrez désormais des notifications pour ce fil de discussion" @@ -4645,11 +4806,15 @@ msgstr "Votre pseudo complet sera <0>@{0}" #~ msgid "Your invite codes are hidden when logged in using an App Password" #~ msgstr "Vos codes d’invitation sont cachés lorsque vous êtes connecté à l’aide d’un mot de passe d’application." +#: src/components/dialogs/MutedWords.tsx:173 +msgid "Your muted words" +msgstr "" + #: src/view/com/modals/ChangePassword.tsx:155 msgid "Your password has been changed successfully!" msgstr "" -#: src/view/com/composer/Composer.tsx:267 +#: src/view/com/composer/Composer.tsx:274 msgid "Your post has been published" msgstr "Votre post a été publié" @@ -4664,7 +4829,7 @@ msgstr "Vos posts, les likes et les blocages sont publics. Les silences (comptes msgid "Your profile" msgstr "Votre profil" -#: src/view/com/composer/Composer.tsx:266 +#: src/view/com/composer/Composer.tsx:273 msgid "Your reply has been published" msgstr "Votre réponse a été publiée" diff --git a/src/locale/locales/hi/messages.po b/src/locale/locales/hi/messages.po index 53bcdbe3..7d852d0b 100644 --- a/src/locale/locales/hi/messages.po +++ b/src/locale/locales/hi/messages.po @@ -80,7 +80,7 @@ msgid "A new version of the app is available. Please update to continue using th msgstr "ऐप का एक नया संस्करण उपलब्ध है. कृपया ऐप का उपयोग जारी रखने के लिए अपडेट करें।" #: src/view/com/util/ViewHeader.tsx:83 -#: src/view/screens/Search/Search.tsx:624 +#: src/view/screens/Search/Search.tsx:647 msgid "Access navigation links and settings" msgstr "" @@ -131,6 +131,7 @@ msgstr "" msgid "Account unmuted" msgstr "" +#: src/components/dialogs/MutedWords.tsx:147 #: src/view/com/auth/onboarding/RecommendedFeedsItem.tsx:150 #: src/view/com/modals/ListAddRemoveUsers.tsx:264 #: src/view/com/modals/UserAddRemoveLists.tsx:219 @@ -172,14 +173,22 @@ msgstr "विवरण जोड़ें" msgid "Add details to report" msgstr "रिपोर्ट करने के लिए विवरण जोड़ें" -#: src/view/com/composer/Composer.tsx:446 +#: src/view/com/composer/Composer.tsx:453 msgid "Add link card" msgstr "लिंक कार्ड जोड़ें" -#: src/view/com/composer/Composer.tsx:451 +#: src/view/com/composer/Composer.tsx:458 msgid "Add link card:" msgstr "लिंक कार्ड जोड़ें:" +#: src/components/dialogs/MutedWords.tsx:140 +msgid "Add mute word for configured settings" +msgstr "" + +#: src/components/dialogs/MutedWords.tsx:74 +msgid "Add muted words and tags" +msgstr "" + #: src/view/com/modals/ChangeHandle.tsx:417 msgid "Add the following DNS record to your domain:" msgstr "अपने डोमेन में निम्नलिखित DNS रिकॉर्ड जोड़ें:" @@ -303,7 +312,7 @@ msgstr "" msgid "App Passwords" msgstr "ऐप पासवर्ड" -#: src/view/com/util/forms/PostDropdownBtn.tsx:279 +#: src/view/com/util/forms/PostDropdownBtn.tsx:295 msgid "Appeal content warning" msgstr "" @@ -327,15 +336,16 @@ msgstr "दिखावट" msgid "Are you sure you want to delete the app password \"{name}\"?" msgstr "क्या आप वाकई ऐप पासवर्ड \"{name}\" हटाना चाहते हैं?" -#: src/view/com/composer/Composer.tsx:143 +#: src/view/com/composer/Composer.tsx:150 msgid "Are you sure you'd like to discard this draft?" msgstr "क्या आप वाकई इस ड्राफ्ट को हटाना करना चाहेंगे?" +#: src/components/dialogs/MutedWords.tsx:233 #: src/view/screens/ProfileList.tsx:365 msgid "Are you sure?" msgstr "क्या आप वास्तव में इसे करना चाहते हैं?" -#: src/view/com/util/forms/PostDropdownBtn.tsx:262 +#: src/view/com/util/forms/PostDropdownBtn.tsx:278 msgid "Are you sure? This cannot be undone." msgstr "क्या आप वास्तव में इसे करना चाहते हैं? इसे असंपादित नहीं किया जा सकता है।" @@ -357,15 +367,15 @@ msgstr "कलात्मक या गैर-कामुक नग्नत #: src/view/com/auth/login/LoginForm.tsx:259 #: src/view/com/auth/login/SetNewPasswordForm.tsx:179 #: src/view/com/modals/report/InputIssueDetails.tsx:46 -#: src/view/com/post-thread/PostThread.tsx:471 -#: src/view/com/post-thread/PostThread.tsx:521 -#: src/view/com/post-thread/PostThread.tsx:529 +#: src/view/com/post-thread/PostThread.tsx:472 +#: src/view/com/post-thread/PostThread.tsx:522 +#: src/view/com/post-thread/PostThread.tsx:530 #: src/view/com/profile/ProfileHeader.tsx:649 #: src/view/com/util/ViewHeader.tsx:81 msgid "Back" msgstr "वापस" -#: src/view/com/post-thread/PostThread.tsx:479 +#: src/view/com/post-thread/PostThread.tsx:480 msgctxt "action" msgid "Back" msgstr "" @@ -413,7 +423,7 @@ msgstr "" msgid "Blocked" msgstr "" -#: src/view/screens/Moderation.tsx:123 +#: src/view/screens/Moderation.tsx:142 msgid "Blocked accounts" msgstr "ब्लॉक किए गए खाते" @@ -472,7 +482,7 @@ msgstr "Bluesky सार्वजनिक है।।" msgid "Bluesky uses invites to build a healthier community. If you don't know anybody with an invite, you can sign up for the waitlist and we'll send one soon." msgstr "ब्लूस्की एक स्वस्थ समुदाय बनाने के लिए आमंत्रित करता है। यदि आप किसी को आमंत्रित नहीं करते हैं, तो आप प्रतीक्षा सूची के लिए साइन अप कर सकते हैं और हम जल्द ही एक भेज देंगे।।" -#: src/view/screens/Moderation.tsx:226 +#: src/view/screens/Moderation.tsx:245 msgid "Bluesky will not show your profile and posts to logged-out users. Other apps may not honor this request. This does not make your account private." msgstr "" @@ -524,8 +534,8 @@ msgid "Can only contain letters, numbers, spaces, dashes, and underscores. Must msgstr "केवल अक्षर, संख्या, रिक्त स्थान, डैश और अंडरस्कोर हो सकते हैं। कम से कम 4 अक्षर लंबा होना चाहिए, लेकिन 32 अक्षरों से अधिक लंबा नहीं होना चाहिए।।" #: src/components/Prompt.tsx:91 -#: src/view/com/composer/Composer.tsx:300 -#: src/view/com/composer/Composer.tsx:305 +#: src/view/com/composer/Composer.tsx:307 +#: src/view/com/composer/Composer.tsx:312 #: src/view/com/modals/ChangeEmail.tsx:218 #: src/view/com/modals/ChangeEmail.tsx:220 #: src/view/com/modals/ChangePassword.tsx:265 @@ -539,7 +549,7 @@ msgstr "केवल अक्षर, संख्या, रिक्त स् #: src/view/com/modals/VerifyEmail.tsx:247 #: src/view/com/modals/VerifyEmail.tsx:253 #: src/view/com/modals/Waitlist.tsx:142 -#: src/view/screens/Search/Search.tsx:693 +#: src/view/screens/Search/Search.tsx:716 #: src/view/shell/desktop/Search.tsx:238 msgid "Cancel" msgstr "कैंसिल" @@ -690,7 +700,7 @@ msgid "Clear all storage data (restart after this)" msgstr "" #: src/view/com/util/forms/SearchInput.tsx:88 -#: src/view/screens/Search/Search.tsx:674 +#: src/view/screens/Search/Search.tsx:697 msgid "Clear search query" msgstr "खोज क्वेरी साफ़ करें" @@ -698,6 +708,11 @@ msgstr "खोज क्वेरी साफ़ करें" msgid "click here" msgstr "" +#: src/components/RichText.tsx:189 +#: src/components/TagMenu/index.web.tsx:125 +msgid "Click here to open tag menu for {tag}" +msgstr "" + #: src/screens/Onboarding/index.tsx:35 msgid "Climate" msgstr "" @@ -728,11 +743,15 @@ msgstr "छवि बंद करें" msgid "Close image viewer" msgstr "छवि बंद करें" -#: src/view/shell/index.web.tsx:49 +#: src/view/shell/index.web.tsx:51 msgid "Close navigation footer" msgstr "नेविगेशन पाद बंद करें" -#: src/view/shell/index.web.tsx:50 +#: src/components/TagMenu/index.tsx:266 +msgid "Close this dialog" +msgstr "" + +#: src/view/shell/index.web.tsx:52 msgid "Closes bottom navigation bar" msgstr "" @@ -740,7 +759,7 @@ msgstr "" msgid "Closes password update alert" msgstr "" -#: src/view/com/composer/Composer.tsx:302 +#: src/view/com/composer/Composer.tsx:309 msgid "Closes post composer and discards post draft" msgstr "" @@ -773,7 +792,7 @@ msgstr "" msgid "Complete the challenge" msgstr "" -#: src/view/com/composer/Composer.tsx:417 +#: src/view/com/composer/Composer.tsx:424 msgid "Compose posts up to {MAX_GRAPHEME_LENGTH} characters in length" msgstr "" @@ -837,7 +856,7 @@ msgstr "कनेक्टिंग ..।" msgid "Contact support" msgstr "" -#: src/view/screens/Moderation.tsx:81 +#: src/view/screens/Moderation.tsx:83 msgid "Content filtering" msgstr "सामग्री फ़िल्टरिंग" @@ -903,7 +922,7 @@ msgstr "" #: src/view/com/modals/AddAppPasswords.tsx:76 #: src/view/com/modals/InviteCodes.tsx:152 -#: src/view/com/util/forms/PostDropdownBtn.tsx:141 +#: src/view/com/util/forms/PostDropdownBtn.tsx:143 msgid "Copied to clipboard" msgstr "" @@ -919,7 +938,7 @@ msgstr "कॉपी" msgid "Copy link to list" msgstr "" -#: src/view/com/util/forms/PostDropdownBtn.tsx:182 +#: src/view/com/util/forms/PostDropdownBtn.tsx:184 msgid "Copy link to post" msgstr "" @@ -927,7 +946,7 @@ msgstr "" msgid "Copy link to profile" msgstr "" -#: src/view/com/util/forms/PostDropdownBtn.tsx:168 +#: src/view/com/util/forms/PostDropdownBtn.tsx:170 msgid "Copy post text" msgstr "पोस्ट टेक्स्ट कॉपी करें" @@ -983,7 +1002,7 @@ msgstr "" msgid "Created by you" msgstr "" -#: src/view/com/composer/Composer.tsx:448 +#: src/view/com/composer/Composer.tsx:455 msgid "Creates a card with a thumbnail. The card links to {url}" msgstr "" @@ -1060,11 +1079,11 @@ msgstr "मेरा खाता हटाएं" msgid "Delete My Account…" msgstr "" -#: src/view/com/util/forms/PostDropdownBtn.tsx:257 +#: src/view/com/util/forms/PostDropdownBtn.tsx:273 msgid "Delete post" msgstr "पोस्ट को हटाएं" -#: src/view/com/util/forms/PostDropdownBtn.tsx:261 +#: src/view/com/util/forms/PostDropdownBtn.tsx:277 msgid "Delete this post?" msgstr "इस पोस्ट को डीलीट करें?" @@ -1087,7 +1106,7 @@ msgstr "विवरण" #~ msgid "Developer Tools" #~ msgstr "डेवलपर उपकरण" -#: src/view/com/composer/Composer.tsx:211 +#: src/view/com/composer/Composer.tsx:218 msgid "Did you want to say anything?" msgstr "" @@ -1095,15 +1114,15 @@ msgstr "" msgid "Dim" msgstr "" -#: src/view/com/composer/Composer.tsx:144 +#: src/view/com/composer/Composer.tsx:151 msgid "Discard" msgstr "" -#: src/view/com/composer/Composer.tsx:138 +#: src/view/com/composer/Composer.tsx:145 msgid "Discard draft" msgstr "ड्राफ्ट हटाएं" -#: src/view/screens/Moderation.tsx:207 +#: src/view/screens/Moderation.tsx:226 msgid "Discourage apps from showing my account to logged-out users" msgstr "" @@ -1182,7 +1201,7 @@ msgstr "" msgid "Download CAR file" msgstr "" -#: src/view/com/composer/text-input/TextInput.web.tsx:247 +#: src/view/com/composer/text-input/TextInput.web.tsx:249 msgid "Drop to add images" msgstr "" @@ -1254,6 +1273,7 @@ msgstr "मेरी प्रोफ़ाइल संपादित करे msgid "Edit Profile" msgstr "मेरी प्रोफ़ाइल संपादित करें" +#: src/view/com/home/HomeHeaderLayout.web.tsx:59 #: src/view/screens/Feeds.tsx:355 msgid "Edit Saved Feeds" msgstr "एडिट सेव्ड फीड" @@ -1336,6 +1356,11 @@ msgstr "" msgid "Enter a name for this App Password" msgstr "" +#: src/components/dialogs/MutedWords.tsx:87 +#: src/components/dialogs/MutedWords.tsx:88 +msgid "Enter a word or tag" +msgstr "" + #: src/view/com/modals/VerifyEmail.tsx:105 msgid "Enter Confirmation Code" msgstr "" @@ -1385,7 +1410,7 @@ msgstr "अपने यूज़रनेम और पासवर्ड द msgid "Error receiving captcha response." msgstr "" -#: src/view/screens/Search/Search.tsx:109 +#: src/view/screens/Search/Search.tsx:110 msgid "Error:" msgstr "" @@ -1456,7 +1481,7 @@ msgstr "" msgid "Failed to create the list. Check your internet connection and try again." msgstr "" -#: src/view/com/util/forms/PostDropdownBtn.tsx:108 +#: src/view/com/util/forms/PostDropdownBtn.tsx:110 msgid "Failed to delete post, please try again" msgstr "" @@ -1478,8 +1503,8 @@ msgid "Feed offline" msgstr "फ़ीड ऑफ़लाइन है" #: src/view/com/feeds/FeedPage.tsx:143 -msgid "Feed Preferences" -msgstr "फ़ीड प्राथमिकता" +#~ msgid "Feed Preferences" +#~ msgstr "फ़ीड प्राथमिकता" #: src/view/shell/desktop/RightNav.tsx:61 #: src/view/shell/Drawer.tsx:311 @@ -1527,11 +1552,11 @@ msgstr "" msgid "Find accounts to follow" msgstr "" -#: src/view/screens/Search/Search.tsx:439 +#: src/view/screens/Search/Search.tsx:440 msgid "Find users on Bluesky" msgstr "" -#: src/view/screens/Search/Search.tsx:437 +#: src/view/screens/Search/Search.tsx:438 msgid "Find users with the search tool on the right" msgstr "" @@ -1628,6 +1653,7 @@ msgid "Following {0}" msgstr "" #: src/Navigation.tsx:248 +#: src/view/com/home/HomeHeaderLayout.web.tsx:45 #: src/view/com/home/HomeHeaderLayoutMobile.tsx:83 #: src/view/screens/PreferencesFollowingFeed.tsx:104 #: src/view/screens/Settings/index.tsx:543 @@ -1667,7 +1693,7 @@ msgstr "पासवर्ड भूल गए" msgid "Forgot Password" msgstr "पासवर्ड भूल गए" -#: src/view/com/posts/FeedItem.tsx:187 +#: src/view/com/posts/FeedItem.tsx:189 msgctxt "from-feed" msgid "From <0/>" msgstr "" @@ -1700,7 +1726,7 @@ msgstr "वापस जाओ" msgid "Go back to previous step" msgstr "" -#: src/view/screens/Search/Search.tsx:724 +#: src/view/screens/Search/Search.tsx:747 #: src/view/shell/desktop/Search.tsx:262 msgid "Go to @{queryMaybeHandle}" msgstr "" @@ -1717,6 +1743,10 @@ msgstr "अगला" msgid "Handle" msgstr "हैंडल" +#: src/components/RichText.tsx:188 +msgid "Hashtag: {tag}" +msgstr "" + #: src/view/com/auth/create/CreateAccount.tsx:208 msgid "Having trouble?" msgstr "" @@ -1755,7 +1785,7 @@ msgctxt "action" msgid "Hide" msgstr "" -#: src/view/com/util/forms/PostDropdownBtn.tsx:216 +#: src/view/com/util/forms/PostDropdownBtn.tsx:232 msgid "Hide post" msgstr "" @@ -1764,7 +1794,7 @@ msgstr "" msgid "Hide the content" msgstr "" -#: src/view/com/util/forms/PostDropdownBtn.tsx:220 +#: src/view/com/util/forms/PostDropdownBtn.tsx:236 msgid "Hide this post?" msgstr "" @@ -1913,7 +1943,7 @@ msgstr "" msgid "Input your user handle" msgstr "" -#: src/view/com/post-thread/PostThreadItem.tsx:224 +#: src/view/com/post-thread/PostThreadItem.tsx:226 msgid "Invalid or unsupported post record" msgstr "" @@ -2015,7 +2045,7 @@ msgstr "अधिक जानें" msgid "Learn more about this warning" msgstr "इस चेतावनी के बारे में अधिक जानें" -#: src/view/screens/Moderation.tsx:243 +#: src/view/screens/Moderation.tsx:262 msgid "Learn more about what is public on Bluesky." msgstr "" @@ -2091,7 +2121,7 @@ msgstr "" msgid "Likes" msgstr "" -#: src/view/com/post-thread/PostThreadItem.tsx:181 +#: src/view/com/post-thread/PostThreadItem.tsx:183 msgid "Likes on this post" msgstr "" @@ -2148,7 +2178,7 @@ msgstr "अधिक पोस्ट लोड करें" msgid "Load new notifications" msgstr "नई सूचनाएं लोड करें" -#: src/view/com/feeds/FeedPage.tsx:181 +#: src/view/com/feeds/FeedPage.tsx:115 #: src/view/screens/Profile.tsx:440 #: src/view/screens/ProfileFeed.tsx:495 #: src/view/screens/ProfileList.tsx:681 @@ -2174,7 +2204,7 @@ msgstr "" msgid "Log out" msgstr "" -#: src/view/screens/Moderation.tsx:136 +#: src/view/screens/Moderation.tsx:155 msgid "Logged-out visibility" msgstr "" @@ -2186,6 +2216,10 @@ msgstr "उस खाते में लॉग इन करें जो स msgid "Make sure this is where you intend to go!" msgstr "यह सुनिश्चित करने के लिए कि आप कहाँ जाना चाहते हैं!" +#: src/components/dialogs/MutedWords.tsx:71 +msgid "Manage your muted words and tags" +msgstr "" + #: src/view/com/auth/create/Step2.tsx:118 msgid "May not be longer than 253 characters" msgstr "" @@ -2207,7 +2241,7 @@ msgid "Mentioned users" msgstr "" #: src/view/com/util/ViewHeader.tsx:81 -#: src/view/screens/Search/Search.tsx:623 +#: src/view/screens/Search/Search.tsx:646 msgid "Menu" msgstr "मेनू" @@ -2216,7 +2250,7 @@ msgid "Message from server: {0}" msgstr "" #: src/Navigation.tsx:115 -#: src/view/screens/Moderation.tsx:64 +#: src/view/screens/Moderation.tsx:66 #: src/view/screens/Settings/index.tsx:625 #: src/view/shell/desktop/LeftNav.tsx:397 #: src/view/shell/Drawer.tsx:511 @@ -2247,7 +2281,7 @@ msgstr "" msgid "Moderation list updated" msgstr "" -#: src/view/screens/Moderation.tsx:95 +#: src/view/screens/Moderation.tsx:114 msgid "Moderation lists" msgstr "मॉडरेशन सूचियाँ" @@ -2274,7 +2308,7 @@ msgstr "अधिक फ़ीड" msgid "More options" msgstr "अधिक विकल्प" -#: src/view/com/util/forms/PostDropdownBtn.tsx:299 +#: src/view/com/util/forms/PostDropdownBtn.tsx:315 msgid "More post options" msgstr "पोस्ट विकल्प" @@ -2286,6 +2320,14 @@ msgstr "" msgid "Must be at least 3 characters" msgstr "" +#: src/components/TagMenu/index.tsx:253 +msgid "Mute" +msgstr "" + +#: src/components/TagMenu/index.web.tsx:91 +msgid "Mute {truncatedTag}" +msgstr "" + #: src/view/com/profile/ProfileHeader.tsx:327 msgid "Mute Account" msgstr "खाता म्यूट करें" @@ -2294,6 +2336,18 @@ msgstr "खाता म्यूट करें" msgid "Mute accounts" msgstr "खातों को म्यूट करें" +#: src/components/TagMenu/index.tsx:211 +msgid "Mute all {tag} posts" +msgstr "" + +#: src/components/dialogs/MutedWords.tsx:131 +msgid "Mute in tags only" +msgstr "" + +#: src/components/dialogs/MutedWords.tsx:116 +msgid "Mute in text & tags" +msgstr "" + #: src/view/screens/ProfileList.tsx:491 msgid "Mute list" msgstr "" @@ -2306,15 +2360,27 @@ msgstr "इन खातों को म्यूट करें?" msgid "Mute this List" msgstr "" -#: src/view/com/util/forms/PostDropdownBtn.tsx:200 +#: src/components/dialogs/MutedWords.tsx:109 +msgid "Mute this word in post text and tags" +msgstr "" + +#: src/components/dialogs/MutedWords.tsx:124 +msgid "Mute this word in tags only" +msgstr "" + +#: src/view/com/util/forms/PostDropdownBtn.tsx:202 msgid "Mute thread" msgstr "थ्रेड म्यूट करें" +#: src/view/com/util/forms/PostDropdownBtn.tsx:216 +msgid "Mute words & tags" +msgstr "" + #: src/view/com/lists/ListCard.tsx:102 msgid "Muted" msgstr "" -#: src/view/screens/Moderation.tsx:109 +#: src/view/screens/Moderation.tsx:128 msgid "Muted accounts" msgstr "म्यूट किए गए खाते" @@ -2327,6 +2393,10 @@ msgstr "म्यूट किए गए खाते" msgid "Muted accounts have their posts removed from your feed and from your notifications. Mutes are completely private." msgstr "म्यूट किए गए खातों की पोस्ट आपके फ़ीड और आपकी सूचनाओं से हटा दी जाती हैं। म्यूट पूरी तरह से निजी हैं." +#: src/view/screens/Moderation.tsx:100 +msgid "Muted words & tags" +msgstr "" + #: src/view/screens/ProfileList.tsx:277 msgid "Muting is private. Muted accounts can interact with you, but you will not see their posts or receive notifications from them." msgstr "म्यूट करना निजी है. म्यूट किए गए खाते आपके साथ इंटरैक्ट कर सकते हैं, लेकिन आप उनकी पोस्ट नहीं देखेंगे या उनसे सूचनाएं प्राप्त नहीं करेंगे।" @@ -2390,6 +2460,10 @@ msgstr "अपने फ़ॉलोअर्स और डेटा तक प msgid "Never lose access to your followers or data." msgstr "" +#: src/components/dialogs/MutedWords.tsx:244 +msgid "Nevermind" +msgstr "" + #: src/view/screens/Lists.tsx:76 msgctxt "action" msgid "New" @@ -2411,7 +2485,7 @@ msgstr "" msgid "New Password" msgstr "" -#: src/view/com/feeds/FeedPage.tsx:192 +#: src/view/com/feeds/FeedPage.tsx:126 msgctxt "action" msgid "New post" msgstr "" @@ -2496,8 +2570,8 @@ msgid "No results found for \"{query}\"" msgstr "\"{query}\" के लिए कोई परिणाम नहीं मिला" #: src/view/com/modals/ListAddRemoveUsers.tsx:127 -#: src/view/screens/Search/Search.tsx:280 -#: src/view/screens/Search/Search.tsx:308 +#: src/view/screens/Search/Search.tsx:281 +#: src/view/screens/Search/Search.tsx:309 msgid "No results found for {query}" msgstr "{query} के लिए कोई परिणाम नहीं मिला\"" @@ -2523,7 +2597,7 @@ msgstr "" msgid "Not right now" msgstr "" -#: src/view/screens/Moderation.tsx:233 +#: src/view/screens/Moderation.tsx:252 msgid "Note: Bluesky is an open and public network. This setting only limits the visibility of your content on the Bluesky app and website, and other apps may not respect this setting. Your content may still be shown to logged-out users by other apps and websites." msgstr "" @@ -2561,7 +2635,7 @@ msgstr "" msgid "Onboarding reset" msgstr "" -#: src/view/com/composer/Composer.tsx:375 +#: src/view/com/composer/Composer.tsx:382 msgid "One or more images is missing alt text." msgstr "एक या अधिक छवियाँ alt पाठ याद आती हैं।।" @@ -2578,8 +2652,12 @@ msgstr "" msgid "Open" msgstr "" -#: src/view/com/composer/Composer.tsx:470 -#: src/view/com/composer/Composer.tsx:471 +#: src/view/screens/Moderation.tsx:75 +msgid "Open content filtering settings" +msgstr "" + +#: src/view/com/composer/Composer.tsx:477 +#: src/view/com/composer/Composer.tsx:478 msgid "Open emoji picker" msgstr "" @@ -2587,6 +2665,10 @@ msgstr "" msgid "Open links with in-app browser" msgstr "" +#: src/view/screens/Moderation.tsx:92 +msgid "Open muted words settings" +msgstr "" + #: src/view/com/home/HomeHeaderLayoutMobile.tsx:49 msgid "Open navigation" msgstr "ओपन नेविगेशन" @@ -2663,6 +2745,7 @@ msgstr "मॉडरेशन सेटिंग्स खोलें" msgid "Opens password reset form" msgstr "" +#: src/view/com/home/HomeHeaderLayout.web.tsx:60 #: src/view/screens/Feeds.tsx:356 msgid "Opens screen to edit Saved Feeds" msgstr "" @@ -2842,7 +2925,7 @@ msgstr "" msgid "Please Verify Your Email" msgstr "" -#: src/view/com/composer/Composer.tsx:215 +#: src/view/com/composer/Composer.tsx:222 msgid "Please wait for your link card to finish loading" msgstr "" @@ -2854,8 +2937,8 @@ msgstr "" msgid "Porn" msgstr "" -#: src/view/com/composer/Composer.tsx:350 -#: src/view/com/composer/Composer.tsx:358 +#: src/view/com/composer/Composer.tsx:357 +#: src/view/com/composer/Composer.tsx:365 msgctxt "action" msgid "Post" msgstr "" @@ -2865,7 +2948,7 @@ msgctxt "description" msgid "Post" msgstr "पोस्ट" -#: src/view/com/post-thread/PostThreadItem.tsx:173 +#: src/view/com/post-thread/PostThreadItem.tsx:175 msgid "Post by {0}" msgstr "" @@ -2875,11 +2958,11 @@ msgstr "" msgid "Post by @{0}" msgstr "" -#: src/view/com/util/forms/PostDropdownBtn.tsx:88 +#: src/view/com/util/forms/PostDropdownBtn.tsx:90 msgid "Post deleted" msgstr "" -#: src/view/com/post-thread/PostThread.tsx:461 +#: src/view/com/post-thread/PostThread.tsx:462 msgid "Post hidden" msgstr "छुपा पोस्ट" @@ -2891,14 +2974,22 @@ msgstr "पोस्ट भाषा" msgid "Post Languages" msgstr "पोस्ट भाषा" -#: src/view/com/post-thread/PostThread.tsx:513 +#: src/view/com/post-thread/PostThread.tsx:514 msgid "Post not found" msgstr "पोस्ट नहीं मिला" +#: src/components/TagMenu/index.tsx:257 +msgid "posts" +msgstr "" + #: src/view/screens/Profile.tsx:180 msgid "Posts" msgstr "" +#: src/components/dialogs/MutedWords.tsx:77 +msgid "Posts can be muted based on their text, their tags, or both." +msgstr "" + #: src/view/com/posts/FeedErrorMessage.tsx:64 msgid "Posts hidden" msgstr "" @@ -2963,11 +3054,11 @@ msgstr "" msgid "Public, shareable lists which can drive feeds." msgstr "सार्वजनिक, साझा करने योग्य सूचियाँ जो फ़ीड चला सकती हैं।" -#: src/view/com/composer/Composer.tsx:335 +#: src/view/com/composer/Composer.tsx:342 msgid "Publish post" msgstr "" -#: src/view/com/composer/Composer.tsx:335 +#: src/view/com/composer/Composer.tsx:342 msgid "Publish reply" msgstr "" @@ -3001,6 +3092,7 @@ msgstr "अनुशंसित फ़ीड" msgid "Recommended Users" msgstr "अनुशंसित लोग" +#: src/components/dialogs/MutedWords.tsx:249 #: src/view/com/modals/ListAddRemoveUsers.tsx:264 #: src/view/com/modals/SelfLabel.tsx:83 #: src/view/com/modals/UserAddRemoveLists.tsx:219 @@ -3038,6 +3130,10 @@ msgstr "छवि निकालें" msgid "Remove image preview" msgstr "छवि पूर्वावलोकन निकालें" +#: src/components/dialogs/MutedWords.tsx:294 +msgid "Remove mute word from your list" +msgstr "" + #: src/view/com/modals/Repost.tsx:47 msgid "Remove repost" msgstr "" @@ -3072,7 +3168,7 @@ msgstr "" msgid "Replies to this thread are disabled" msgstr "" -#: src/view/com/composer/Composer.tsx:348 +#: src/view/com/composer/Composer.tsx:355 msgctxt "action" msgid "Reply" msgstr "" @@ -3082,7 +3178,7 @@ msgid "Reply Filters" msgstr "फिल्टर" #: src/view/com/post/Post.tsx:167 -#: src/view/com/posts/FeedItem.tsx:285 +#: src/view/com/posts/FeedItem.tsx:287 msgctxt "description" msgid "Reply to <0/>" msgstr "" @@ -3104,7 +3200,7 @@ msgid "Report List" msgstr "रिपोर्ट सूची" #: src/view/com/modals/report/SendReportButton.tsx:37 -#: src/view/com/util/forms/PostDropdownBtn.tsx:239 +#: src/view/com/util/forms/PostDropdownBtn.tsx:255 msgid "Report post" msgstr "रिपोर्ट पोस्ट" @@ -3129,11 +3225,11 @@ msgstr "पोस्ट दोबारा पोस्ट करें या msgid "Reposted By" msgstr "द्वारा दोबारा पोस्ट किया गया" -#: src/view/com/posts/FeedItem.tsx:205 +#: src/view/com/posts/FeedItem.tsx:207 msgid "Reposted by {0}" msgstr "" -#: src/view/com/posts/FeedItem.tsx:222 +#: src/view/com/posts/FeedItem.tsx:224 msgid "Reposted by <0/>" msgstr "" @@ -3141,7 +3237,7 @@ msgstr "" msgid "reposted your post" msgstr "" -#: src/view/com/post-thread/PostThreadItem.tsx:186 +#: src/view/com/post-thread/PostThreadItem.tsx:188 msgid "Reposts of this post" msgstr "" @@ -3292,9 +3388,9 @@ msgstr "" #: src/view/com/modals/ListAddRemoveUsers.tsx:75 #: src/view/com/util/forms/SearchInput.tsx:67 #: src/view/com/util/forms/SearchInput.tsx:79 -#: src/view/screens/Search/Search.tsx:418 -#: src/view/screens/Search/Search.tsx:645 -#: src/view/screens/Search/Search.tsx:663 +#: src/view/screens/Search/Search.tsx:419 +#: src/view/screens/Search/Search.tsx:668 +#: src/view/screens/Search/Search.tsx:686 #: src/view/shell/bottom-bar/BottomBar.tsx:159 #: src/view/shell/desktop/LeftNav.tsx:324 #: src/view/shell/desktop/Search.tsx:214 @@ -3304,11 +3400,19 @@ msgstr "" msgid "Search" msgstr "खोज" -#: src/view/screens/Search/Search.tsx:712 +#: src/view/screens/Search/Search.tsx:735 #: src/view/shell/desktop/Search.tsx:255 msgid "Search for \"{query}\"" msgstr "" +#: src/components/TagMenu/index.tsx:145 +msgid "Search for all posts by @{authorHandle} with tag {tag}" +msgstr "" + +#: src/components/TagMenu/index.tsx:90 +msgid "Search for all posts with tag {tag}" +msgstr "" + #: src/view/com/auth/LoggedOut.tsx:104 #: src/view/com/auth/LoggedOut.tsx:105 #: src/view/com/modals/ListAddRemoveUsers.tsx:70 @@ -3319,6 +3423,22 @@ msgstr "" msgid "Security Step Required" msgstr "सुरक्षा चरण आवश्यक" +#: src/components/TagMenu/index.web.tsx:50 +msgid "See {truncatedTag} posts" +msgstr "" + +#: src/components/TagMenu/index.web.tsx:67 +msgid "See {truncatedTag} posts by user" +msgstr "" + +#: src/components/TagMenu/index.tsx:128 +msgid "See <0>{tag} posts" +msgstr "" + +#: src/components/TagMenu/index.tsx:189 +msgid "See <0>{tag} posts by this user" +msgstr "" + #: src/view/screens/SavedFeeds.tsx:163 msgid "See this guide" msgstr "" @@ -3528,7 +3648,7 @@ msgid "Share" msgstr "" #: src/view/com/profile/ProfileHeader.tsx:295 -#: src/view/com/util/forms/PostDropdownBtn.tsx:182 +#: src/view/com/util/forms/PostDropdownBtn.tsx:184 #: src/view/screens/ProfileList.tsx:418 msgid "Share" msgstr "शेयर" @@ -3561,9 +3681,9 @@ msgstr "" msgid "Show follows similar to {0}" msgstr "" -#: src/view/com/post-thread/PostThreadItem.tsx:532 -#: src/view/com/post/Post.tsx:196 -#: src/view/com/posts/FeedItem.tsx:359 +#: src/view/com/post-thread/PostThreadItem.tsx:538 +#: src/view/com/post/Post.tsx:198 +#: src/view/com/posts/FeedItem.tsx:363 msgid "Show More" msgstr "" @@ -3731,7 +3851,7 @@ msgstr "" msgid "Something went wrong. Check your email and try again." msgstr "" -#: src/App.native.tsx:61 +#: src/App.native.tsx:63 msgid "Sorry! Your session expired. Please log in again." msgstr "" @@ -3789,7 +3909,7 @@ msgstr "" msgid "Subscribe to this list" msgstr "इस सूची को सब्सक्राइब करें" -#: src/view/screens/Search/Search.tsx:373 +#: src/view/screens/Search/Search.tsx:374 msgid "Suggested Follows" msgstr "अनुशंसित लोग" @@ -3833,6 +3953,14 @@ msgstr "प्रणाली" msgid "System log" msgstr "सिस्टम लॉग" +#: src/components/dialogs/MutedWords.tsx:288 +msgid "tag" +msgstr "" + +#: src/components/TagMenu/index.tsx:74 +msgid "Tag menu: {tag}" +msgstr "" + #: src/view/com/modals/crop-image/CropImage.web.tsx:112 msgid "Tall" msgstr "लंबा" @@ -3856,6 +3984,10 @@ msgstr "शर्तें" msgid "Terms of Service" msgstr "सेवा की शर्तें" +#: src/components/dialogs/MutedWords.tsx:288 +msgid "text" +msgstr "" + #: src/view/com/modals/AppealLabel.tsx:70 #: src/view/com/modals/report/InputIssueDetails.tsx:51 msgid "Text input field" @@ -3881,7 +4013,7 @@ msgstr "कॉपीराइट नीति को <0/> पर स्थान msgid "The following steps will help customize your Bluesky experience." msgstr "" -#: src/view/com/post-thread/PostThread.tsx:516 +#: src/view/com/post-thread/PostThread.tsx:517 msgid "The post may have been deleted." msgstr "हो सकता है कि यह पोस्ट हटा दी गई हो।" @@ -4047,7 +4179,7 @@ msgstr "" msgid "This name is already in use" msgstr "" -#: src/view/com/post-thread/PostThreadItem.tsx:123 +#: src/view/com/post-thread/PostThreadItem.tsx:125 msgid "This post has been deleted." msgstr "इस पोस्ट को हटा दिया गया है।।" @@ -4071,7 +4203,11 @@ msgstr "" msgid "This warning is only available for posts with media attached." msgstr "यह चेतावनी केवल मीडिया संलग्न पोस्ट के लिए उपलब्ध है।" -#: src/view/com/util/forms/PostDropdownBtn.tsx:221 +#: src/components/dialogs/MutedWords.tsx:236 +msgid "This will delete {0} from your muted words. You can always add it back later." +msgstr "" + +#: src/view/com/util/forms/PostDropdownBtn.tsx:237 msgid "This will hide this post from your feeds." msgstr "" @@ -4088,6 +4224,10 @@ msgstr "थ्रेड मोड" msgid "Threads Preferences" msgstr "" +#: src/components/dialogs/MutedWords.tsx:95 +msgid "Toggle between muted word options." +msgstr "" + #: src/view/com/util/forms/DropdownButton.tsx:246 msgid "Toggle dropdown" msgstr "ड्रॉपडाउन टॉगल करें" @@ -4096,9 +4236,9 @@ msgstr "ड्रॉपडाउन टॉगल करें" msgid "Transformations" msgstr "परिवर्तन" -#: src/view/com/post-thread/PostThreadItem.tsx:679 -#: src/view/com/post-thread/PostThreadItem.tsx:681 -#: src/view/com/util/forms/PostDropdownBtn.tsx:154 +#: src/view/com/post-thread/PostThreadItem.tsx:685 +#: src/view/com/post-thread/PostThreadItem.tsx:687 +#: src/view/com/util/forms/PostDropdownBtn.tsx:156 msgid "Translate" msgstr "अनुवाद" @@ -4163,15 +4303,24 @@ msgstr "" msgid "Unlike" msgstr "" +#: src/components/TagMenu/index.tsx:253 #: src/view/screens/ProfileList.tsx:597 msgid "Unmute" msgstr "" +#: src/components/TagMenu/index.web.tsx:90 +msgid "Unmute {truncatedTag}" +msgstr "" + #: src/view/com/profile/ProfileHeader.tsx:326 msgid "Unmute Account" msgstr "अनम्यूट खाता" -#: src/view/com/util/forms/PostDropdownBtn.tsx:200 +#: src/components/TagMenu/index.tsx:210 +msgid "Unmute all {tag} posts" +msgstr "" + +#: src/view/com/util/forms/PostDropdownBtn.tsx:202 msgid "Unmute thread" msgstr "थ्रेड को अनम्यूट करें" @@ -4372,6 +4521,10 @@ msgstr "" #~ msgid "We recommend \"For You\" by Skygaze:" #~ msgstr "" +#: src/components/dialogs/MutedWords.tsx:161 +msgid "We recommend avoiding common words that appear in many posts, since it can result in no posts being shown." +msgstr "" + #: src/screens/Onboarding/StepAlgoFeeds/index.tsx:124 msgid "We recommend our \"Discover\" feed:" msgstr "" @@ -4400,7 +4553,11 @@ msgstr "हम आपके हमारी सेवा में शामि msgid "We're sorry, but we were unable to resolve this list. If this persists, please contact the list creator, @{handleOrDid}." msgstr "" -#: src/view/screens/Search/Search.tsx:253 +#: src/components/dialogs/MutedWords.tsx:182 +msgid "We're sorry, but we weren't able to load your muted words at this time. Please try again." +msgstr "" + +#: src/view/screens/Search/Search.tsx:254 msgid "We're sorry, but your search could not be completed. Please try again in a few minutes." msgstr "" @@ -4421,7 +4578,7 @@ msgid "What is the issue with this {collectionName}?" msgstr "इस {collectionName} के साथ क्या मुद्दा है?" #: src/view/com/auth/SplashScreen.tsx:59 -#: src/view/com/composer/Composer.tsx:279 +#: src/view/com/composer/Composer.tsx:286 msgid "What's up?" msgstr "" @@ -4442,11 +4599,11 @@ msgstr "" msgid "Wide" msgstr "चौड़ा" -#: src/view/com/composer/Composer.tsx:415 +#: src/view/com/composer/Composer.tsx:422 msgid "Write post" msgstr "पोस्ट लिखो" -#: src/view/com/composer/Composer.tsx:278 +#: src/view/com/composer/Composer.tsx:285 #: src/view/com/composer/Prompt.tsx:33 msgid "Write your reply" msgstr "अपना जवाब दें" @@ -4511,7 +4668,7 @@ msgstr "" msgid "You don't have any saved feeds." msgstr "आपके पास कोई सहेजी गई फ़ीड नहीं है." -#: src/view/com/post-thread/PostThread.tsx:464 +#: src/view/com/post-thread/PostThread.tsx:465 msgid "You have blocked the author or you have been blocked by the author." msgstr "आपने लेखक को अवरुद्ध किया है या आपने लेखक द्वारा अवरुद्ध किया है।।" @@ -4551,6 +4708,10 @@ msgstr "आपने अभी तक कोई ऐप पासवर्ड न msgid "You have not muted any accounts yet. To mute an account, go to their profile and selected \"Mute account\" from the menu on their account." msgstr "आपने अभी तक कोई खाता म्यूट नहीं किया है. किसी खाते को म्यूट करने के लिए, उनकी प्रोफ़ाइल पर जाएं और उनके खाते के मेनू से \"खाता म्यूट करें\" चुनें।" +#: src/components/dialogs/MutedWords.tsx:202 +msgid "You haven't muted any words or tags yet" +msgstr "" + #: src/view/com/modals/ContentFilteringSettings.tsx:175 msgid "You must be 18 or older to enable adult content." msgstr "" @@ -4559,11 +4720,11 @@ msgstr "" msgid "You must be 18 years or older to enable adult content" msgstr "" -#: src/view/com/util/forms/PostDropdownBtn.tsx:127 +#: src/view/com/util/forms/PostDropdownBtn.tsx:129 msgid "You will no longer receive notifications for this thread" msgstr "" -#: src/view/com/util/forms/PostDropdownBtn.tsx:130 +#: src/view/com/util/forms/PostDropdownBtn.tsx:132 msgid "You will now receive notifications for this thread" msgstr "" @@ -4649,11 +4810,15 @@ msgstr "" #~ msgid "Your invite codes are hidden when logged in using an App Password" #~ msgstr "" +#: src/components/dialogs/MutedWords.tsx:173 +msgid "Your muted words" +msgstr "" + #: src/view/com/modals/ChangePassword.tsx:155 msgid "Your password has been changed successfully!" msgstr "" -#: src/view/com/composer/Composer.tsx:267 +#: src/view/com/composer/Composer.tsx:274 msgid "Your post has been published" msgstr "" @@ -4668,7 +4833,7 @@ msgstr "आपकी पोस्ट, पसंद और ब्लॉक सा msgid "Your profile" msgstr "आपकी प्रोफ़ाइल" -#: src/view/com/composer/Composer.tsx:266 +#: src/view/com/composer/Composer.tsx:273 msgid "Your reply has been published" msgstr "" diff --git a/src/locale/locales/id/messages.po b/src/locale/locales/id/messages.po index 5697638a..4135b9f1 100644 --- a/src/locale/locales/id/messages.po +++ b/src/locale/locales/id/messages.po @@ -92,7 +92,7 @@ msgid "A new version of the app is available. Please update to continue using th msgstr "Versi baru dari aplikasi ini telah tersedia. Harap perbarui untuk terus menggunakan aplikasi." #: src/view/com/util/ViewHeader.tsx:83 -#: src/view/screens/Search/Search.tsx:624 +#: src/view/screens/Search/Search.tsx:647 msgid "Access navigation links and settings" msgstr "Akses tautan navigasi dan pengaturan" @@ -143,6 +143,7 @@ msgstr "Akun batal diblokir" msgid "Account unmuted" msgstr "Akun batal dibisukan" +#: src/components/dialogs/MutedWords.tsx:147 #: src/view/com/auth/onboarding/RecommendedFeedsItem.tsx:150 #: src/view/com/modals/ListAddRemoveUsers.tsx:264 #: src/view/com/modals/UserAddRemoveLists.tsx:219 @@ -184,14 +185,22 @@ msgstr "Tambahkan detail" msgid "Add details to report" msgstr "Tambahkan detail ke laporan" -#: src/view/com/composer/Composer.tsx:446 +#: src/view/com/composer/Composer.tsx:453 msgid "Add link card" msgstr "Tambahkan kartu tautan" -#: src/view/com/composer/Composer.tsx:451 +#: src/view/com/composer/Composer.tsx:458 msgid "Add link card:" msgstr "Tambahkan kartu tautan:" +#: src/components/dialogs/MutedWords.tsx:140 +msgid "Add mute word for configured settings" +msgstr "" + +#: src/components/dialogs/MutedWords.tsx:74 +msgid "Add muted words and tags" +msgstr "" + #: src/view/com/modals/ChangeHandle.tsx:417 msgid "Add the following DNS record to your domain:" msgstr "Tambahkan DNS record berikut ke domain Anda:" @@ -315,7 +324,7 @@ msgstr "Pengaturan kata sandi aplikasi" msgid "App Passwords" msgstr "Kata sandi Aplikasi" -#: src/view/com/util/forms/PostDropdownBtn.tsx:279 +#: src/view/com/util/forms/PostDropdownBtn.tsx:295 msgid "Appeal content warning" msgstr "Ajukan banding peringatan konten" @@ -342,15 +351,16 @@ msgstr "Tampilan" msgid "Are you sure you want to delete the app password \"{name}\"?" msgstr "Anda yakin untuk menghapus kata sandi aplikasi \"{name}\"?" -#: src/view/com/composer/Composer.tsx:143 +#: src/view/com/composer/Composer.tsx:150 msgid "Are you sure you'd like to discard this draft?" msgstr "Anda yakin untuk membuang draf ini?" +#: src/components/dialogs/MutedWords.tsx:233 #: src/view/screens/ProfileList.tsx:365 msgid "Are you sure?" msgstr "Anda yakin?" -#: src/view/com/util/forms/PostDropdownBtn.tsx:262 +#: src/view/com/util/forms/PostDropdownBtn.tsx:278 msgid "Are you sure? This cannot be undone." msgstr "Anda yakin? Ini tidak dapat dibatalkan." @@ -372,15 +382,15 @@ msgstr "Ketelanjangan artistik atau non-erotis." #: src/view/com/auth/login/LoginForm.tsx:259 #: src/view/com/auth/login/SetNewPasswordForm.tsx:179 #: src/view/com/modals/report/InputIssueDetails.tsx:46 -#: src/view/com/post-thread/PostThread.tsx:471 -#: src/view/com/post-thread/PostThread.tsx:521 -#: src/view/com/post-thread/PostThread.tsx:529 +#: src/view/com/post-thread/PostThread.tsx:472 +#: src/view/com/post-thread/PostThread.tsx:522 +#: src/view/com/post-thread/PostThread.tsx:530 #: src/view/com/profile/ProfileHeader.tsx:649 #: src/view/com/util/ViewHeader.tsx:81 msgid "Back" msgstr "Kembali" -#: src/view/com/post-thread/PostThread.tsx:479 +#: src/view/com/post-thread/PostThread.tsx:480 msgctxt "action" msgid "Back" msgstr "Kembali" @@ -428,7 +438,7 @@ msgstr "Blokir Daftar ini" msgid "Blocked" msgstr "Diblokir" -#: src/view/screens/Moderation.tsx:123 +#: src/view/screens/Moderation.tsx:142 msgid "Blocked accounts" msgstr "Akun yang diblokir" @@ -487,7 +497,7 @@ msgstr "Bluesky bersifat publik." msgid "Bluesky uses invites to build a healthier community. If you don't know anybody with an invite, you can sign up for the waitlist and we'll send one soon." msgstr "Bluesky menggunakan undangan untuk membangun komunitas yang sehat. Jika Anda tidak tahu orang lain yang memiliki undangan, Anda bisa mendaftar di daftar tunggu dan kami akan segera mengirimkan undangannya." -#: src/view/screens/Moderation.tsx:226 +#: src/view/screens/Moderation.tsx:245 msgid "Bluesky will not show your profile and posts to logged-out users. Other apps may not honor this request. This does not make your account private." msgstr "Bluesky tidak akan menampilkan profil dan postingan Anda ke pengguna yang tidak login. Aplikasi lain mungkin tidak menghormati permintaan ini. Ini tidak membuat akun Anda menjadi privat." @@ -539,8 +549,8 @@ msgid "Can only contain letters, numbers, spaces, dashes, and underscores. Must msgstr "Hanya dapat terdiri dari huruf, angka, spasi, tanda hubung dan garis bawah. Minimal 4 karakter, namun tidak boleh lebih dari 32 karakter." #: src/components/Prompt.tsx:91 -#: src/view/com/composer/Composer.tsx:300 -#: src/view/com/composer/Composer.tsx:305 +#: src/view/com/composer/Composer.tsx:307 +#: src/view/com/composer/Composer.tsx:312 #: src/view/com/modals/ChangeEmail.tsx:218 #: src/view/com/modals/ChangeEmail.tsx:220 #: src/view/com/modals/ChangePassword.tsx:265 @@ -554,7 +564,7 @@ msgstr "Hanya dapat terdiri dari huruf, angka, spasi, tanda hubung dan garis baw #: src/view/com/modals/VerifyEmail.tsx:247 #: src/view/com/modals/VerifyEmail.tsx:253 #: src/view/com/modals/Waitlist.tsx:142 -#: src/view/screens/Search/Search.tsx:693 +#: src/view/screens/Search/Search.tsx:716 #: src/view/shell/desktop/Search.tsx:238 msgid "Cancel" msgstr "Batal" @@ -711,7 +721,7 @@ msgid "Clear all storage data (restart after this)" msgstr "Hapus semua data penyimpanan (mulai ulang setelah ini)" #: src/view/com/util/forms/SearchInput.tsx:88 -#: src/view/screens/Search/Search.tsx:674 +#: src/view/screens/Search/Search.tsx:697 msgid "Clear search query" msgstr "Hapus kueri pencarian" @@ -719,6 +729,11 @@ msgstr "Hapus kueri pencarian" msgid "click here" msgstr "klik di sini" +#: src/components/RichText.tsx:189 +#: src/components/TagMenu/index.web.tsx:125 +msgid "Click here to open tag menu for {tag}" +msgstr "" + #: src/screens/Onboarding/index.tsx:35 msgid "Climate" msgstr "" @@ -749,11 +764,15 @@ msgstr "Tutup gambar" msgid "Close image viewer" msgstr "Tutup penampil gambar" -#: src/view/shell/index.web.tsx:49 +#: src/view/shell/index.web.tsx:51 msgid "Close navigation footer" msgstr "Tutup footer navigasi" -#: src/view/shell/index.web.tsx:50 +#: src/components/TagMenu/index.tsx:266 +msgid "Close this dialog" +msgstr "" + +#: src/view/shell/index.web.tsx:52 msgid "Closes bottom navigation bar" msgstr "Menutup bilah navigasi bawah" @@ -761,7 +780,7 @@ msgstr "Menutup bilah navigasi bawah" msgid "Closes password update alert" msgstr "Menutup peringatan pembaruan kata sandi" -#: src/view/com/composer/Composer.tsx:302 +#: src/view/com/composer/Composer.tsx:309 msgid "Closes post composer and discards post draft" msgstr "Menutup penyusun postingan dan membuang draf" @@ -794,7 +813,7 @@ msgstr "" msgid "Complete the challenge" msgstr "" -#: src/view/com/composer/Composer.tsx:417 +#: src/view/com/composer/Composer.tsx:424 msgid "Compose posts up to {MAX_GRAPHEME_LENGTH} characters in length" msgstr "Buat postingan dengan panjang hingga {MAX_GRAPHEME_LENGTH} karakter" @@ -858,7 +877,7 @@ msgstr "Menghubungkan..." msgid "Contact support" msgstr "" -#: src/view/screens/Moderation.tsx:81 +#: src/view/screens/Moderation.tsx:83 msgid "Content filtering" msgstr "Penyaring Konten" @@ -924,7 +943,7 @@ msgstr "Menyalin versi build ke papan klip" #: src/view/com/modals/AddAppPasswords.tsx:76 #: src/view/com/modals/InviteCodes.tsx:152 -#: src/view/com/util/forms/PostDropdownBtn.tsx:141 +#: src/view/com/util/forms/PostDropdownBtn.tsx:143 msgid "Copied to clipboard" msgstr "Disalin ke papan klip" @@ -940,7 +959,7 @@ msgstr "Salin" msgid "Copy link to list" msgstr "Salin tautan ke daftar" -#: src/view/com/util/forms/PostDropdownBtn.tsx:182 +#: src/view/com/util/forms/PostDropdownBtn.tsx:184 msgid "Copy link to post" msgstr "Salin tautan ke postingan" @@ -948,7 +967,7 @@ msgstr "Salin tautan ke postingan" msgid "Copy link to profile" msgstr "Salin tautan ke profil" -#: src/view/com/util/forms/PostDropdownBtn.tsx:168 +#: src/view/com/util/forms/PostDropdownBtn.tsx:170 msgid "Copy post text" msgstr "Salin teks postingan" @@ -1004,7 +1023,7 @@ msgstr "Dibuat oleh <0/>" msgid "Created by you" msgstr "Dibuat oleh Anda" -#: src/view/com/composer/Composer.tsx:448 +#: src/view/com/composer/Composer.tsx:455 msgid "Creates a card with a thumbnail. The card links to {url}" msgstr "Buat kartu dengan gambar kecil. Tautan kartu ke {url}" @@ -1085,11 +1104,11 @@ msgstr "Hapus akun saya" msgid "Delete My Account…" msgstr "" -#: src/view/com/util/forms/PostDropdownBtn.tsx:257 +#: src/view/com/util/forms/PostDropdownBtn.tsx:273 msgid "Delete post" msgstr "Hapus postingan" -#: src/view/com/util/forms/PostDropdownBtn.tsx:261 +#: src/view/com/util/forms/PostDropdownBtn.tsx:277 msgid "Delete this post?" msgstr "Hapus postingan ini?" @@ -1116,7 +1135,7 @@ msgstr "Deskripsi" #~ msgid "Developer Tools" #~ msgstr "Alat Pengembang" -#: src/view/com/composer/Composer.tsx:211 +#: src/view/com/composer/Composer.tsx:218 msgid "Did you want to say anything?" msgstr "Apakah Anda ingin mengatakan sesuatu?" @@ -1124,15 +1143,15 @@ msgstr "Apakah Anda ingin mengatakan sesuatu?" msgid "Dim" msgstr "" -#: src/view/com/composer/Composer.tsx:144 +#: src/view/com/composer/Composer.tsx:151 msgid "Discard" msgstr "Buang" -#: src/view/com/composer/Composer.tsx:138 +#: src/view/com/composer/Composer.tsx:145 msgid "Discard draft" msgstr "Buang draf" -#: src/view/screens/Moderation.tsx:207 +#: src/view/screens/Moderation.tsx:226 msgid "Discourage apps from showing my account to logged-out users" msgstr "Cegah aplikasi untuk menampilkan akun saya ke pengguna yang tidak login" @@ -1211,7 +1230,7 @@ msgstr "" msgid "Download CAR file" msgstr "" -#: src/view/com/composer/text-input/TextInput.web.tsx:247 +#: src/view/com/composer/text-input/TextInput.web.tsx:249 msgid "Drop to add images" msgstr "" @@ -1283,6 +1302,7 @@ msgstr "Edit profil" msgid "Edit Profile" msgstr "Edit Profil" +#: src/view/com/home/HomeHeaderLayout.web.tsx:59 #: src/view/screens/Feeds.tsx:355 msgid "Edit Saved Feeds" msgstr "Edit Feed Tersimpan" @@ -1365,6 +1385,11 @@ msgstr "Akhir feed" msgid "Enter a name for this App Password" msgstr "Masukkan nama untuk Sandi Aplikasi ini" +#: src/components/dialogs/MutedWords.tsx:87 +#: src/components/dialogs/MutedWords.tsx:88 +msgid "Enter a word or tag" +msgstr "" + #: src/view/com/modals/VerifyEmail.tsx:105 msgid "Enter Confirmation Code" msgstr "Masukkan Kode Konfirmasi" @@ -1418,7 +1443,7 @@ msgstr "Masukkan nama pengguna dan kata sandi Anda" msgid "Error receiving captcha response." msgstr "" -#: src/view/screens/Search/Search.tsx:109 +#: src/view/screens/Search/Search.tsx:110 msgid "Error:" msgstr "Eror:" @@ -1489,7 +1514,7 @@ msgstr "Gagal membuat kata sandi aplikasi." msgid "Failed to create the list. Check your internet connection and try again." msgstr "Gagal membuat daftar. Periksa koneksi internet Anda dan coba lagi." -#: src/view/com/util/forms/PostDropdownBtn.tsx:108 +#: src/view/com/util/forms/PostDropdownBtn.tsx:110 msgid "Failed to delete post, please try again" msgstr "Gagal menghapus postingan, silakan coba lagi" @@ -1511,8 +1536,8 @@ msgid "Feed offline" msgstr "Feed offline" #: src/view/com/feeds/FeedPage.tsx:143 -msgid "Feed Preferences" -msgstr "Preferensi Feed" +#~ msgid "Feed Preferences" +#~ msgstr "Preferensi Feed" #: src/view/shell/desktop/RightNav.tsx:61 #: src/view/shell/Drawer.tsx:311 @@ -1560,11 +1585,11 @@ msgstr "" msgid "Find accounts to follow" msgstr "Temukan akun untuk diikuti" -#: src/view/screens/Search/Search.tsx:439 +#: src/view/screens/Search/Search.tsx:440 msgid "Find users on Bluesky" msgstr "Temukan pengguna di Bluesky" -#: src/view/screens/Search/Search.tsx:437 +#: src/view/screens/Search/Search.tsx:438 msgid "Find users with the search tool on the right" msgstr "Temukan pengguna dengan alat pencarian di sebelah kanan" @@ -1668,6 +1693,7 @@ msgid "Following {0}" msgstr "Mengikuti {0}" #: src/Navigation.tsx:248 +#: src/view/com/home/HomeHeaderLayout.web.tsx:45 #: src/view/com/home/HomeHeaderLayoutMobile.tsx:83 #: src/view/screens/PreferencesFollowingFeed.tsx:104 #: src/view/screens/Settings/index.tsx:543 @@ -1707,7 +1733,7 @@ msgstr "Lupa kata sandi" msgid "Forgot Password" msgstr "Lupa Kata Sandi" -#: src/view/com/posts/FeedItem.tsx:187 +#: src/view/com/posts/FeedItem.tsx:189 msgctxt "from-feed" msgid "From <0/>" msgstr "Dari <0/>" @@ -1740,7 +1766,7 @@ msgstr "Kembali" msgid "Go back to previous step" msgstr "" -#: src/view/screens/Search/Search.tsx:724 +#: src/view/screens/Search/Search.tsx:747 #: src/view/shell/desktop/Search.tsx:262 msgid "Go to @{queryMaybeHandle}" msgstr "" @@ -1757,6 +1783,10 @@ msgstr "Berikutnya" msgid "Handle" msgstr "Handle" +#: src/components/RichText.tsx:188 +msgid "Hashtag: {tag}" +msgstr "" + #: src/view/com/auth/create/CreateAccount.tsx:208 msgid "Having trouble?" msgstr "" @@ -1799,7 +1829,7 @@ msgctxt "action" msgid "Hide" msgstr "Sembunyikan" -#: src/view/com/util/forms/PostDropdownBtn.tsx:216 +#: src/view/com/util/forms/PostDropdownBtn.tsx:232 msgid "Hide post" msgstr "Sembunyikan postingan" @@ -1808,7 +1838,7 @@ msgstr "Sembunyikan postingan" msgid "Hide the content" msgstr "Sembunyikan konten" -#: src/view/com/util/forms/PostDropdownBtn.tsx:220 +#: src/view/com/util/forms/PostDropdownBtn.tsx:236 msgid "Hide this post?" msgstr "Sembunyikan postingan ini?" @@ -1969,7 +1999,7 @@ msgstr "Masukkan kata sandi Anda" msgid "Input your user handle" msgstr "Masukkan handle pengguna Anda" -#: src/view/com/post-thread/PostThreadItem.tsx:224 +#: src/view/com/post-thread/PostThreadItem.tsx:226 msgid "Invalid or unsupported post record" msgstr "Catatan posting tidak valid atau tidak didukung" @@ -2071,7 +2101,7 @@ msgstr "Pelajari Lebih Lanjut" msgid "Learn more about this warning" msgstr "Pelajari lebih lanjut tentang peringatan ini" -#: src/view/screens/Moderation.tsx:243 +#: src/view/screens/Moderation.tsx:262 msgid "Learn more about what is public on Bluesky." msgstr "Pelajari lebih lanjut tentang apa yang publik di Bluesky." @@ -2155,7 +2185,7 @@ msgstr "menyukai postingan Anda" msgid "Likes" msgstr "Suka" -#: src/view/com/post-thread/PostThreadItem.tsx:181 +#: src/view/com/post-thread/PostThreadItem.tsx:183 msgid "Likes on this post" msgstr "Suka pada postingan ini" @@ -2212,7 +2242,7 @@ msgstr "Muat postingan lainnya" msgid "Load new notifications" msgstr "Muat notifikasi baru" -#: src/view/com/feeds/FeedPage.tsx:181 +#: src/view/com/feeds/FeedPage.tsx:115 #: src/view/screens/Profile.tsx:440 #: src/view/screens/ProfileFeed.tsx:495 #: src/view/screens/ProfileList.tsx:681 @@ -2238,7 +2268,7 @@ msgstr "Catatan" msgid "Log out" msgstr "" -#: src/view/screens/Moderation.tsx:136 +#: src/view/screens/Moderation.tsx:155 msgid "Logged-out visibility" msgstr "Visibilitas pengguna yang tidak login" @@ -2253,6 +2283,10 @@ msgstr "Masuk ke akun yang tidak ada di daftar" msgid "Make sure this is where you intend to go!" msgstr "Pastikan ini adalah website yang Anda tuju!" +#: src/components/dialogs/MutedWords.tsx:71 +msgid "Manage your muted words and tags" +msgstr "" + #: src/view/com/auth/create/Step2.tsx:118 msgid "May not be longer than 253 characters" msgstr "" @@ -2274,7 +2308,7 @@ msgid "Mentioned users" msgstr "Pengguna yang disebutkan" #: src/view/com/util/ViewHeader.tsx:81 -#: src/view/screens/Search/Search.tsx:623 +#: src/view/screens/Search/Search.tsx:646 msgid "Menu" msgstr "Menu" @@ -2286,7 +2320,7 @@ msgid "Message from server: {0}" msgstr "Pesan dari server: {0}" #: src/Navigation.tsx:115 -#: src/view/screens/Moderation.tsx:64 +#: src/view/screens/Moderation.tsx:66 #: src/view/screens/Settings/index.tsx:625 #: src/view/shell/desktop/LeftNav.tsx:397 #: src/view/shell/Drawer.tsx:511 @@ -2317,7 +2351,7 @@ msgstr "Daftar moderasi dibuat" msgid "Moderation list updated" msgstr "Daftar moderasi diperbarui" -#: src/view/screens/Moderation.tsx:95 +#: src/view/screens/Moderation.tsx:114 msgid "Moderation lists" msgstr "Daftar moderasi" @@ -2344,7 +2378,7 @@ msgstr "Feed lainnya" msgid "More options" msgstr "Pilihan lainnya" -#: src/view/com/util/forms/PostDropdownBtn.tsx:299 +#: src/view/com/util/forms/PostDropdownBtn.tsx:315 msgid "More post options" msgstr "Opsi posting lainnya" @@ -2356,6 +2390,14 @@ msgstr "Balasan yang paling disukai lebih dulu" msgid "Must be at least 3 characters" msgstr "" +#: src/components/TagMenu/index.tsx:253 +msgid "Mute" +msgstr "" + +#: src/components/TagMenu/index.web.tsx:91 +msgid "Mute {truncatedTag}" +msgstr "" + #: src/view/com/profile/ProfileHeader.tsx:327 msgid "Mute Account" msgstr "Bisukan Akun" @@ -2364,6 +2406,18 @@ msgstr "Bisukan Akun" msgid "Mute accounts" msgstr "Bisukan akun" +#: src/components/TagMenu/index.tsx:211 +msgid "Mute all {tag} posts" +msgstr "" + +#: src/components/dialogs/MutedWords.tsx:131 +msgid "Mute in tags only" +msgstr "" + +#: src/components/dialogs/MutedWords.tsx:116 +msgid "Mute in text & tags" +msgstr "" + #: src/view/screens/ProfileList.tsx:491 msgid "Mute list" msgstr "Daftar akun yang dibisukan" @@ -2376,15 +2430,27 @@ msgstr "Bisukan akun ini?" msgid "Mute this List" msgstr "Bisukan Daftar ini" -#: src/view/com/util/forms/PostDropdownBtn.tsx:200 +#: src/components/dialogs/MutedWords.tsx:109 +msgid "Mute this word in post text and tags" +msgstr "" + +#: src/components/dialogs/MutedWords.tsx:124 +msgid "Mute this word in tags only" +msgstr "" + +#: src/view/com/util/forms/PostDropdownBtn.tsx:202 msgid "Mute thread" msgstr "Bisukan utasan" +#: src/view/com/util/forms/PostDropdownBtn.tsx:216 +msgid "Mute words & tags" +msgstr "" + #: src/view/com/lists/ListCard.tsx:102 msgid "Muted" msgstr "Dibisukan" -#: src/view/screens/Moderation.tsx:109 +#: src/view/screens/Moderation.tsx:128 msgid "Muted accounts" msgstr "Akun yang dibisukan" @@ -2397,6 +2463,10 @@ msgstr "Akun yang Dibisukan" msgid "Muted accounts have their posts removed from your feed and from your notifications. Mutes are completely private." msgstr "Postingan dari akun yang dibisukan akan dihilangkan dari feed dan notifikasi Anda. Pembisuan ini bersifat privat." +#: src/view/screens/Moderation.tsx:100 +msgid "Muted words & tags" +msgstr "" + #: src/view/screens/ProfileList.tsx:277 msgid "Muting is private. Muted accounts can interact with you, but you will not see their posts or receive notifications from them." msgstr "Pembisuan akun bersifat privat. Akun yang dibisukan tetap dapat berinteraksi dengan Anda, namun Anda tidak akan melihat postingan atau notifikasi dari mereka." @@ -2460,6 +2530,10 @@ msgstr "Tidak akan lagi kehilangan akses ke data dan pengikut Anda." msgid "Never lose access to your followers or data." msgstr "" +#: src/components/dialogs/MutedWords.tsx:244 +msgid "Nevermind" +msgstr "" + #: src/view/screens/Lists.tsx:76 msgctxt "action" msgid "New" @@ -2481,7 +2555,7 @@ msgstr "Kata sandi baru" msgid "New Password" msgstr "" -#: src/view/com/feeds/FeedPage.tsx:192 +#: src/view/com/feeds/FeedPage.tsx:126 msgctxt "action" msgid "New post" msgstr "Postingan baru" @@ -2569,8 +2643,8 @@ msgid "No results found for \"{query}\"" msgstr "Tidak ada hasil ditemukan untuk \"{query}\"" #: src/view/com/modals/ListAddRemoveUsers.tsx:127 -#: src/view/screens/Search/Search.tsx:280 -#: src/view/screens/Search/Search.tsx:308 +#: src/view/screens/Search/Search.tsx:281 +#: src/view/screens/Search/Search.tsx:309 msgid "No results found for {query}" msgstr "Tidak ada hasil ditemukan untuk {query}" @@ -2596,7 +2670,7 @@ msgstr "Tidak ditemukan" msgid "Not right now" msgstr "Jangan sekarang" -#: src/view/screens/Moderation.tsx:233 +#: src/view/screens/Moderation.tsx:252 msgid "Note: Bluesky is an open and public network. This setting only limits the visibility of your content on the Bluesky app and website, and other apps may not respect this setting. Your content may still be shown to logged-out users by other apps and websites." msgstr "Catatan: Bluesky merupakan jaringan terbuka dan publik. Pengaturan ini hanya akan membatasi visibilitas konten Anda pada aplikasi dan website Bluesky, dan aplikasi lain mungkin tidak mengindahkan pengaturan ini. Konten Anda mungkin tetap ditampilkan kepada pengguna yang tidak login oleh aplikasi dan website lain." @@ -2634,7 +2708,7 @@ msgstr "Balasan terlama terlebih dahulu" msgid "Onboarding reset" msgstr "Atur ulang orientasi" -#: src/view/com/composer/Composer.tsx:375 +#: src/view/com/composer/Composer.tsx:382 msgid "One or more images is missing alt text." msgstr "Satu atau lebih gambar belum ada teks alt." @@ -2651,8 +2725,12 @@ msgstr "Uups!" msgid "Open" msgstr "" -#: src/view/com/composer/Composer.tsx:470 -#: src/view/com/composer/Composer.tsx:471 +#: src/view/screens/Moderation.tsx:75 +msgid "Open content filtering settings" +msgstr "" + +#: src/view/com/composer/Composer.tsx:477 +#: src/view/com/composer/Composer.tsx:478 msgid "Open emoji picker" msgstr "Buka pemilih emoji" @@ -2660,6 +2738,10 @@ msgstr "Buka pemilih emoji" msgid "Open links with in-app browser" msgstr "Buka tautan dengan browser dalam aplikasi" +#: src/view/screens/Moderation.tsx:92 +msgid "Open muted words settings" +msgstr "" + #: src/view/com/home/HomeHeaderLayoutMobile.tsx:49 msgid "Open navigation" msgstr "Buka navigasi" @@ -2736,6 +2818,7 @@ msgstr "Buka pengaturan moderasi" msgid "Opens password reset form" msgstr "Membuka formulir pengaturan ulang kata sandi" +#: src/view/com/home/HomeHeaderLayout.web.tsx:60 #: src/view/screens/Feeds.tsx:356 msgid "Opens screen to edit Saved Feeds" msgstr "Membuka layar untuk mengedit Umpan Tersimpan" @@ -2918,7 +3001,7 @@ msgstr "Mohon beri tahu kami mengapa menurut Anda peringatan konten ini salah di msgid "Please Verify Your Email" msgstr "Mohon Verifikasi Email Anda" -#: src/view/com/composer/Composer.tsx:215 +#: src/view/com/composer/Composer.tsx:222 msgid "Please wait for your link card to finish loading" msgstr "Harap tunggu hingga kartu tautan Anda selesai dimuat" @@ -2930,8 +3013,8 @@ msgstr "" msgid "Porn" msgstr "Pornografi" -#: src/view/com/composer/Composer.tsx:350 -#: src/view/com/composer/Composer.tsx:358 +#: src/view/com/composer/Composer.tsx:357 +#: src/view/com/composer/Composer.tsx:365 msgctxt "action" msgid "Post" msgstr "Posting" @@ -2944,7 +3027,7 @@ msgstr "Posting" #~ msgid "Post" #~ msgstr "Posting" -#: src/view/com/post-thread/PostThreadItem.tsx:173 +#: src/view/com/post-thread/PostThreadItem.tsx:175 msgid "Post by {0}" msgstr "Postingan oleh {0}" @@ -2954,11 +3037,11 @@ msgstr "Postingan oleh {0}" msgid "Post by @{0}" msgstr "Postingan oleh @{0}" -#: src/view/com/util/forms/PostDropdownBtn.tsx:88 +#: src/view/com/util/forms/PostDropdownBtn.tsx:90 msgid "Post deleted" msgstr "Postingan dihapus" -#: src/view/com/post-thread/PostThread.tsx:461 +#: src/view/com/post-thread/PostThread.tsx:462 msgid "Post hidden" msgstr "Postingan disembunyikan" @@ -2970,14 +3053,22 @@ msgstr "Bahasa postingan" msgid "Post Languages" msgstr "Bahasa Postingan" -#: src/view/com/post-thread/PostThread.tsx:513 +#: src/view/com/post-thread/PostThread.tsx:514 msgid "Post not found" msgstr "Postingan tidak ditemukan" +#: src/components/TagMenu/index.tsx:257 +msgid "posts" +msgstr "" + #: src/view/screens/Profile.tsx:180 msgid "Posts" msgstr "Postingan" +#: src/components/dialogs/MutedWords.tsx:77 +msgid "Posts can be muted based on their text, their tags, or both." +msgstr "" + #: src/view/com/posts/FeedErrorMessage.tsx:64 msgid "Posts hidden" msgstr "Postingan disembunyikan" @@ -3042,11 +3133,11 @@ msgstr "Daftar publik yang dapat dibagikan oleh pengguna untuk dibisukan atau di msgid "Public, shareable lists which can drive feeds." msgstr "Publik, daftar yang dapat dibagikan dan dapat berimbas ke feed." -#: src/view/com/composer/Composer.tsx:335 +#: src/view/com/composer/Composer.tsx:342 msgid "Publish post" msgstr "Publikasikan postingan" -#: src/view/com/composer/Composer.tsx:335 +#: src/view/com/composer/Composer.tsx:342 msgid "Publish reply" msgstr "Publikasikan balasan" @@ -3083,6 +3174,7 @@ msgstr "Feed Direkomendasikan" msgid "Recommended Users" msgstr "Pengguna Direkomendasikan" +#: src/components/dialogs/MutedWords.tsx:249 #: src/view/com/modals/ListAddRemoveUsers.tsx:264 #: src/view/com/modals/SelfLabel.tsx:83 #: src/view/com/modals/UserAddRemoveLists.tsx:219 @@ -3120,6 +3212,10 @@ msgstr "Hapus gambar" msgid "Remove image preview" msgstr "Hapus pratinjau gambar" +#: src/components/dialogs/MutedWords.tsx:294 +msgid "Remove mute word from your list" +msgstr "" + #: src/view/com/modals/Repost.tsx:47 msgid "Remove repost" msgstr "Hapus postingan ulang" @@ -3154,7 +3250,7 @@ msgstr "Balasan" msgid "Replies to this thread are disabled" msgstr "Balasan ke utas ini dinonaktifkan" -#: src/view/com/composer/Composer.tsx:348 +#: src/view/com/composer/Composer.tsx:355 msgctxt "action" msgid "Reply" msgstr "Balas" @@ -3164,7 +3260,7 @@ msgid "Reply Filters" msgstr "Penyaring Balasan" #: src/view/com/post/Post.tsx:167 -#: src/view/com/posts/FeedItem.tsx:285 +#: src/view/com/posts/FeedItem.tsx:287 msgctxt "description" msgid "Reply to <0/>" msgstr "Balas ke <0/>" @@ -3186,7 +3282,7 @@ msgid "Report List" msgstr "Laporkan Daftar" #: src/view/com/modals/report/SendReportButton.tsx:37 -#: src/view/com/util/forms/PostDropdownBtn.tsx:239 +#: src/view/com/util/forms/PostDropdownBtn.tsx:255 msgid "Report post" msgstr "Laporkan postingan" @@ -3215,7 +3311,7 @@ msgstr "Posting ulang atau kutip postingan" msgid "Reposted By" msgstr "" -#: src/view/com/posts/FeedItem.tsx:205 +#: src/view/com/posts/FeedItem.tsx:207 msgid "Reposted by {0}" msgstr "" @@ -3223,7 +3319,7 @@ msgstr "" #~ msgid "Reposted by {0})" #~ msgstr "Diposting ulang oleh {0})" -#: src/view/com/posts/FeedItem.tsx:222 +#: src/view/com/posts/FeedItem.tsx:224 msgid "Reposted by <0/>" msgstr "Diposting ulang oleh <0/>" @@ -3231,7 +3327,7 @@ msgstr "Diposting ulang oleh <0/>" msgid "reposted your post" msgstr "posting ulang posting Anda" -#: src/view/com/post-thread/PostThreadItem.tsx:186 +#: src/view/com/post-thread/PostThreadItem.tsx:188 msgid "Reposts of this post" msgstr "Posting ulang postingan ini" @@ -3382,9 +3478,9 @@ msgstr "Gulir ke atas" #: src/view/com/modals/ListAddRemoveUsers.tsx:75 #: src/view/com/util/forms/SearchInput.tsx:67 #: src/view/com/util/forms/SearchInput.tsx:79 -#: src/view/screens/Search/Search.tsx:418 -#: src/view/screens/Search/Search.tsx:645 -#: src/view/screens/Search/Search.tsx:663 +#: src/view/screens/Search/Search.tsx:419 +#: src/view/screens/Search/Search.tsx:668 +#: src/view/screens/Search/Search.tsx:686 #: src/view/shell/bottom-bar/BottomBar.tsx:159 #: src/view/shell/desktop/LeftNav.tsx:324 #: src/view/shell/desktop/Search.tsx:214 @@ -3394,11 +3490,19 @@ msgstr "Gulir ke atas" msgid "Search" msgstr "Cari" -#: src/view/screens/Search/Search.tsx:712 +#: src/view/screens/Search/Search.tsx:735 #: src/view/shell/desktop/Search.tsx:255 msgid "Search for \"{query}\"" msgstr "" +#: src/components/TagMenu/index.tsx:145 +msgid "Search for all posts by @{authorHandle} with tag {tag}" +msgstr "" + +#: src/components/TagMenu/index.tsx:90 +msgid "Search for all posts with tag {tag}" +msgstr "" + #: src/view/com/auth/LoggedOut.tsx:104 #: src/view/com/auth/LoggedOut.tsx:105 #: src/view/com/modals/ListAddRemoveUsers.tsx:70 @@ -3409,6 +3513,22 @@ msgstr "Cari pengguna" msgid "Security Step Required" msgstr "Langkah Keamanan Diperlukan" +#: src/components/TagMenu/index.web.tsx:50 +msgid "See {truncatedTag} posts" +msgstr "" + +#: src/components/TagMenu/index.web.tsx:67 +msgid "See {truncatedTag} posts by user" +msgstr "" + +#: src/components/TagMenu/index.tsx:128 +msgid "See <0>{tag} posts" +msgstr "" + +#: src/components/TagMenu/index.tsx:189 +msgid "See <0>{tag} posts by this user" +msgstr "" + #: src/view/screens/SavedFeeds.tsx:163 msgid "See this guide" msgstr "Lihat panduan ini" @@ -3625,7 +3745,7 @@ msgid "Share" msgstr "Bagikan" #: src/view/com/profile/ProfileHeader.tsx:295 -#: src/view/com/util/forms/PostDropdownBtn.tsx:182 +#: src/view/com/util/forms/PostDropdownBtn.tsx:184 #: src/view/screens/ProfileList.tsx:418 msgid "Share" msgstr "Bagikan" @@ -3658,9 +3778,9 @@ msgstr "Tampilkan embed dari {0}" msgid "Show follows similar to {0}" msgstr "Tampilkan berikut ini mirip dengan {0}" -#: src/view/com/post-thread/PostThreadItem.tsx:532 -#: src/view/com/post/Post.tsx:196 -#: src/view/com/posts/FeedItem.tsx:359 +#: src/view/com/post-thread/PostThreadItem.tsx:538 +#: src/view/com/post/Post.tsx:198 +#: src/view/com/posts/FeedItem.tsx:363 msgid "Show More" msgstr "Tampilkan Lebih Lanjut" @@ -3828,7 +3948,7 @@ msgstr "" msgid "Something went wrong. Check your email and try again." msgstr "Ada yang tidak beres. Periksa email Anda dan coba lagi." -#: src/App.native.tsx:61 +#: src/App.native.tsx:63 msgid "Sorry! Your session expired. Please log in again." msgstr "Maaf! Sesi Anda telah berakhir. Silakan masuk lagi." @@ -3890,7 +4010,7 @@ msgstr "" msgid "Subscribe to this list" msgstr "Langganan ke daftar ini" -#: src/view/screens/Search/Search.tsx:373 +#: src/view/screens/Search/Search.tsx:374 msgid "Suggested Follows" msgstr "Saran untuk Diikuti" @@ -3934,6 +4054,14 @@ msgstr "Sistem" msgid "System log" msgstr "Log sistem" +#: src/components/dialogs/MutedWords.tsx:288 +msgid "tag" +msgstr "" + +#: src/components/TagMenu/index.tsx:74 +msgid "Tag menu: {tag}" +msgstr "" + #: src/view/com/modals/crop-image/CropImage.web.tsx:112 msgid "Tall" msgstr "Tinggi" @@ -3957,6 +4085,10 @@ msgstr "Ketentuan" msgid "Terms of Service" msgstr "Ketentuan Layanan" +#: src/components/dialogs/MutedWords.tsx:288 +msgid "text" +msgstr "" + #: src/view/com/modals/AppealLabel.tsx:70 #: src/view/com/modals/report/InputIssueDetails.tsx:51 msgid "Text input field" @@ -3982,7 +4114,7 @@ msgstr "Kebijakan Hak Cipta telah dipindahkan ke <0/>" msgid "The following steps will help customize your Bluesky experience." msgstr "" -#: src/view/com/post-thread/PostThread.tsx:516 +#: src/view/com/post-thread/PostThread.tsx:517 msgid "The post may have been deleted." msgstr "Postingan mungkin telah dihapus." @@ -4162,7 +4294,7 @@ msgstr "Daftar ini kosong!" msgid "This name is already in use" msgstr "Nama ini sudah digunakan" -#: src/view/com/post-thread/PostThreadItem.tsx:123 +#: src/view/com/post-thread/PostThreadItem.tsx:125 msgid "This post has been deleted." msgstr "Postingan ini telah dihapus." @@ -4186,7 +4318,11 @@ msgstr "" msgid "This warning is only available for posts with media attached." msgstr "Peringatan ini hanya tersedia untuk postingan dengan lampiran media." -#: src/view/com/util/forms/PostDropdownBtn.tsx:221 +#: src/components/dialogs/MutedWords.tsx:236 +msgid "This will delete {0} from your muted words. You can always add it back later." +msgstr "" + +#: src/view/com/util/forms/PostDropdownBtn.tsx:237 msgid "This will hide this post from your feeds." msgstr "Ini akan menyembunyikan postingan ini dari feed Anda." @@ -4203,6 +4339,10 @@ msgstr "Mode Utasan" msgid "Threads Preferences" msgstr "Preferensi Utas" +#: src/components/dialogs/MutedWords.tsx:95 +msgid "Toggle between muted word options." +msgstr "" + #: src/view/com/util/forms/DropdownButton.tsx:246 msgid "Toggle dropdown" msgstr "Beralih dropdown" @@ -4211,9 +4351,9 @@ msgstr "Beralih dropdown" msgid "Transformations" msgstr "Transformasi" -#: src/view/com/post-thread/PostThreadItem.tsx:679 -#: src/view/com/post-thread/PostThreadItem.tsx:681 -#: src/view/com/util/forms/PostDropdownBtn.tsx:154 +#: src/view/com/post-thread/PostThreadItem.tsx:685 +#: src/view/com/post-thread/PostThreadItem.tsx:687 +#: src/view/com/util/forms/PostDropdownBtn.tsx:156 msgid "Translate" msgstr "Terjemahkan" @@ -4281,15 +4421,24 @@ msgstr "Sayangnya, Anda tidak memenuhi syarat untuk membuat akun." msgid "Unlike" msgstr "Tidak suka" +#: src/components/TagMenu/index.tsx:253 #: src/view/screens/ProfileList.tsx:597 msgid "Unmute" msgstr "Bunyikan" +#: src/components/TagMenu/index.web.tsx:90 +msgid "Unmute {truncatedTag}" +msgstr "" + #: src/view/com/profile/ProfileHeader.tsx:326 msgid "Unmute Account" msgstr "Bunyikan Akun" -#: src/view/com/util/forms/PostDropdownBtn.tsx:200 +#: src/components/TagMenu/index.tsx:210 +msgid "Unmute all {tag} posts" +msgstr "" + +#: src/view/com/util/forms/PostDropdownBtn.tsx:202 msgid "Unmute thread" msgstr "Bunyikan utasan" @@ -4494,6 +4643,10 @@ msgstr "" #~ msgid "We recommend \"For You\" by Skygaze:" #~ msgstr "" +#: src/components/dialogs/MutedWords.tsx:161 +msgid "We recommend avoiding common words that appear in many posts, since it can result in no posts being shown." +msgstr "" + #: src/screens/Onboarding/StepAlgoFeeds/index.tsx:124 msgid "We recommend our \"Discover\" feed:" msgstr "" @@ -4522,7 +4675,11 @@ msgstr "Kami sangat senang Anda bergabung dengan kami!" msgid "We're sorry, but we were unable to resolve this list. If this persists, please contact the list creator, @{handleOrDid}." msgstr "Mohon maaf, kami tidak dapat menyelesaikan daftar ini. Jika hal ini terus berlanjut, silakan hubungi pembuat daftar, @{handleOrDid}." -#: src/view/screens/Search/Search.tsx:253 +#: src/components/dialogs/MutedWords.tsx:182 +msgid "We're sorry, but we weren't able to load your muted words at this time. Please try again." +msgstr "" + +#: src/view/screens/Search/Search.tsx:254 msgid "We're sorry, but your search could not be completed. Please try again in a few minutes." msgstr "Maaf, pencarian Anda tidak dapat dilakukan. Mohon coba lagi dalam beberapa menit." @@ -4546,7 +4703,7 @@ msgstr "Apa yang bermasalah dengan {collectionName}?" #~ msgstr "Apa selanjutnya?" #: src/view/com/auth/SplashScreen.tsx:59 -#: src/view/com/composer/Composer.tsx:279 +#: src/view/com/composer/Composer.tsx:286 msgid "What's up?" msgstr "Apa kabar?" @@ -4567,11 +4724,11 @@ msgstr "Siapa yang dapat membalas" msgid "Wide" msgstr "Lebar" -#: src/view/com/composer/Composer.tsx:415 +#: src/view/com/composer/Composer.tsx:422 msgid "Write post" msgstr "Tulis postingan" -#: src/view/com/composer/Composer.tsx:278 +#: src/view/com/composer/Composer.tsx:285 #: src/view/com/composer/Prompt.tsx:33 msgid "Write your reply" msgstr "Tulis balasan Anda" @@ -4640,7 +4797,7 @@ msgstr "Anda tidak memiliki feed yang disimpan!" msgid "You don't have any saved feeds." msgstr "Anda tidak memiliki feed yang disimpan." -#: src/view/com/post-thread/PostThread.tsx:464 +#: src/view/com/post-thread/PostThread.tsx:465 msgid "You have blocked the author or you have been blocked by the author." msgstr "Anda telah memblokir atau diblokir oleh penulis ini." @@ -4680,6 +4837,10 @@ msgstr "Anda belum membuat kata sandi aplikasi. Anda dapat membuatnya dengan men msgid "You have not muted any accounts yet. To mute an account, go to their profile and selected \"Mute account\" from the menu on their account." msgstr "Anda belum membisukan akun lain. Untuk membisukan akun, kunjungi profil mereka dan pilih \"Bisukan akun\" pada menu di akun mereka." +#: src/components/dialogs/MutedWords.tsx:202 +msgid "You haven't muted any words or tags yet" +msgstr "" + #: src/view/com/modals/ContentFilteringSettings.tsx:175 msgid "You must be 18 or older to enable adult content." msgstr "Anda harus berusia 18 tahun atau lebih untuk mengaktifkan konten dewasa." @@ -4688,11 +4849,11 @@ msgstr "Anda harus berusia 18 tahun atau lebih untuk mengaktifkan konten dewasa. msgid "You must be 18 years or older to enable adult content" msgstr "" -#: src/view/com/util/forms/PostDropdownBtn.tsx:127 +#: src/view/com/util/forms/PostDropdownBtn.tsx:129 msgid "You will no longer receive notifications for this thread" msgstr "Anda tidak akan lagi menerima notifikasi untuk utas ini" -#: src/view/com/util/forms/PostDropdownBtn.tsx:130 +#: src/view/com/util/forms/PostDropdownBtn.tsx:132 msgid "You will now receive notifications for this thread" msgstr "Anda sekarang akan menerima notifikasi untuk utas ini" @@ -4782,11 +4943,15 @@ msgstr "Handle lengkap Anda akan menjadi <0>@{0}" #~ msgid "Your invite codes are hidden when logged in using an App Password" #~ msgstr "Kode undangan Anda disembunyikan saat masuk menggunakan Kata Sandi Aplikasi" +#: src/components/dialogs/MutedWords.tsx:173 +msgid "Your muted words" +msgstr "" + #: src/view/com/modals/ChangePassword.tsx:155 msgid "Your password has been changed successfully!" msgstr "" -#: src/view/com/composer/Composer.tsx:267 +#: src/view/com/composer/Composer.tsx:274 msgid "Your post has been published" msgstr "Postingan Anda telah dipublikasikan" @@ -4801,7 +4966,7 @@ msgstr "Postingan, suka, dan blokir Anda bersifat publik. Bisukan bersifat priva msgid "Your profile" msgstr "Profil Anda" -#: src/view/com/composer/Composer.tsx:266 +#: src/view/com/composer/Composer.tsx:273 msgid "Your reply has been published" msgstr "Balasan Anda telah dipublikasikan" diff --git a/src/locale/locales/it/messages.po b/src/locale/locales/it/messages.po index bfa796a4..ac09dc10 100644 --- a/src/locale/locales/it/messages.po +++ b/src/locale/locales/it/messages.po @@ -84,7 +84,7 @@ msgid "A new version of the app is available. Please update to continue using th msgstr "È disponibile una nuova versione dell'app. Aggiorna per continuare a utilizzarla." #: src/view/com/util/ViewHeader.tsx:83 -#: src/view/screens/Search/Search.tsx:624 +#: src/view/screens/Search/Search.tsx:647 msgid "Access navigation links and settings" msgstr "Accedi alle impostazioni di navigazione" @@ -135,6 +135,7 @@ msgstr "Account sbloccato" msgid "Account unmuted" msgstr "Account non silenziato" +#: src/components/dialogs/MutedWords.tsx:147 #: src/view/com/auth/onboarding/RecommendedFeedsItem.tsx:150 #: src/view/com/modals/ListAddRemoveUsers.tsx:264 #: src/view/com/modals/UserAddRemoveLists.tsx:219 @@ -176,14 +177,22 @@ msgstr "Aggiungi i dettagli" msgid "Add details to report" msgstr "Aggiungi dettagli da segnalare" -#: src/view/com/composer/Composer.tsx:446 +#: src/view/com/composer/Composer.tsx:453 msgid "Add link card" msgstr "Aggiungi la scheda collegata al link" -#: src/view/com/composer/Composer.tsx:451 +#: src/view/com/composer/Composer.tsx:458 msgid "Add link card:" msgstr "Aggiungi la scheda relazionata al link:" +#: src/components/dialogs/MutedWords.tsx:140 +msgid "Add mute word for configured settings" +msgstr "" + +#: src/components/dialogs/MutedWords.tsx:74 +msgid "Add muted words and tags" +msgstr "" + #: src/view/com/modals/ChangeHandle.tsx:417 msgid "Add the following DNS record to your domain:" msgstr "Aggiungi il seguente record DNS al tuo dominio:" @@ -303,7 +312,7 @@ msgstr "Impostazioni della password dell'app" msgid "App Passwords" msgstr "Passwords dell'App" -#: src/view/com/util/forms/PostDropdownBtn.tsx:279 +#: src/view/com/util/forms/PostDropdownBtn.tsx:295 msgid "Appeal content warning" msgstr "Ricorso contro l'avviso sui contenuti" @@ -330,15 +339,16 @@ msgstr "Aspetto" msgid "Are you sure you want to delete the app password \"{name}\"?" msgstr "Conferma di voler eliminare la password dell'app \"{name}\"?" -#: src/view/com/composer/Composer.tsx:143 +#: src/view/com/composer/Composer.tsx:150 msgid "Are you sure you'd like to discard this draft?" msgstr "Conferma di voler eliminare questa bozza?" +#: src/components/dialogs/MutedWords.tsx:233 #: src/view/screens/ProfileList.tsx:365 msgid "Are you sure?" msgstr "Confermi?" -#: src/view/com/util/forms/PostDropdownBtn.tsx:262 +#: src/view/com/util/forms/PostDropdownBtn.tsx:278 msgid "Are you sure? This cannot be undone." msgstr "Vuoi proseguire? Questa operazione non può essere annullata." @@ -360,15 +370,15 @@ msgstr "Nudità artistica o non erotica." #: src/view/com/auth/login/LoginForm.tsx:259 #: src/view/com/auth/login/SetNewPasswordForm.tsx:179 #: src/view/com/modals/report/InputIssueDetails.tsx:46 -#: src/view/com/post-thread/PostThread.tsx:471 -#: src/view/com/post-thread/PostThread.tsx:521 -#: src/view/com/post-thread/PostThread.tsx:529 +#: src/view/com/post-thread/PostThread.tsx:472 +#: src/view/com/post-thread/PostThread.tsx:522 +#: src/view/com/post-thread/PostThread.tsx:530 #: src/view/com/profile/ProfileHeader.tsx:649 #: src/view/com/util/ViewHeader.tsx:81 msgid "Back" msgstr "Indietro" -#: src/view/com/post-thread/PostThread.tsx:479 +#: src/view/com/post-thread/PostThread.tsx:480 msgctxt "action" msgid "Back" msgstr "Indietro" @@ -416,7 +426,7 @@ msgstr "Blocca questa Lista" msgid "Blocked" msgstr "Bloccato" -#: src/view/screens/Moderation.tsx:123 +#: src/view/screens/Moderation.tsx:142 msgid "Blocked accounts" msgstr "Accounts bloccati" @@ -475,7 +485,7 @@ msgstr "Bluesky è pubblico." msgid "Bluesky uses invites to build a healthier community. If you don't know anybody with an invite, you can sign up for the waitlist and we'll send one soon." msgstr "Bluesky utilizza gli inviti per costruire una comunità più sana. Se non conosci nessuno con un invito, puoi iscriverti alla lista d'attesa e te ne invieremo uno al più presto." -#: src/view/screens/Moderation.tsx:226 +#: src/view/screens/Moderation.tsx:245 msgid "Bluesky will not show your profile and posts to logged-out users. Other apps may not honor this request. This does not make your account private." msgstr "Bluesky non mostrerà il tuo profilo e i tuoi post agli utenti disconnessi. Altre app potrebbero non rispettare questa richiesta. Questo non rende il tuo account privato." @@ -527,8 +537,8 @@ msgid "Can only contain letters, numbers, spaces, dashes, and underscores. Must msgstr "Può contenere solo lettere, numeri, spazi, trattini e trattini bassi. Deve contenere almeno 4 caratteri, ma non più di 32 caratteri." #: src/components/Prompt.tsx:91 -#: src/view/com/composer/Composer.tsx:300 -#: src/view/com/composer/Composer.tsx:305 +#: src/view/com/composer/Composer.tsx:307 +#: src/view/com/composer/Composer.tsx:312 #: src/view/com/modals/ChangeEmail.tsx:218 #: src/view/com/modals/ChangeEmail.tsx:220 #: src/view/com/modals/ChangePassword.tsx:265 @@ -542,7 +552,7 @@ msgstr "Può contenere solo lettere, numeri, spazi, trattini e trattini bassi. D #: src/view/com/modals/VerifyEmail.tsx:247 #: src/view/com/modals/VerifyEmail.tsx:253 #: src/view/com/modals/Waitlist.tsx:142 -#: src/view/screens/Search/Search.tsx:693 +#: src/view/screens/Search/Search.tsx:716 #: src/view/shell/desktop/Search.tsx:238 msgid "Cancel" msgstr "Cancella" @@ -695,7 +705,7 @@ msgid "Clear all storage data (restart after this)" msgstr "Cancella tutti i dati in archivio (poi ricomincia)" #: src/view/com/util/forms/SearchInput.tsx:88 -#: src/view/screens/Search/Search.tsx:674 +#: src/view/screens/Search/Search.tsx:697 msgid "Clear search query" msgstr "Annulla la ricerca" @@ -703,6 +713,11 @@ msgstr "Annulla la ricerca" msgid "click here" msgstr "clicca qui" +#: src/components/RichText.tsx:189 +#: src/components/TagMenu/index.web.tsx:125 +msgid "Click here to open tag menu for {tag}" +msgstr "" + #: src/screens/Onboarding/index.tsx:35 msgid "Climate" msgstr "" @@ -733,11 +748,15 @@ msgstr "Chiudi l'immagine" msgid "Close image viewer" msgstr "Chiudi il visualizzatore di immagini" -#: src/view/shell/index.web.tsx:49 +#: src/view/shell/index.web.tsx:51 msgid "Close navigation footer" msgstr "Chiudi la navigazione del footer" -#: src/view/shell/index.web.tsx:50 +#: src/components/TagMenu/index.tsx:266 +msgid "Close this dialog" +msgstr "" + +#: src/view/shell/index.web.tsx:52 msgid "Closes bottom navigation bar" msgstr "Chiude la barra di navigazione in basso" @@ -745,7 +764,7 @@ msgstr "Chiude la barra di navigazione in basso" msgid "Closes password update alert" msgstr "Chiude l'avviso di aggiornamento della password" -#: src/view/com/composer/Composer.tsx:302 +#: src/view/com/composer/Composer.tsx:309 msgid "Closes post composer and discards post draft" msgstr "Chiude l'editore del post ed elimina la bozza del post" @@ -778,7 +797,7 @@ msgstr "" msgid "Complete the challenge" msgstr "" -#: src/view/com/composer/Composer.tsx:417 +#: src/view/com/composer/Composer.tsx:424 msgid "Compose posts up to {MAX_GRAPHEME_LENGTH} characters in length" msgstr "Componi un post fino a {MAX_GRAPHEME_LENGTH} caratteri" @@ -842,7 +861,7 @@ msgstr "Connessione in corso..." msgid "Contact support" msgstr "Contatta il supporto" -#: src/view/screens/Moderation.tsx:81 +#: src/view/screens/Moderation.tsx:83 msgid "Content filtering" msgstr "Filtro dei contenuti" @@ -908,7 +927,7 @@ msgstr "Versione di build copiata nella clipboard" #: src/view/com/modals/AddAppPasswords.tsx:76 #: src/view/com/modals/InviteCodes.tsx:152 -#: src/view/com/util/forms/PostDropdownBtn.tsx:141 +#: src/view/com/util/forms/PostDropdownBtn.tsx:143 msgid "Copied to clipboard" msgstr "Copiato nel clipboard" @@ -924,7 +943,7 @@ msgstr "Copia" msgid "Copy link to list" msgstr "Copia il link alla lista" -#: src/view/com/util/forms/PostDropdownBtn.tsx:182 +#: src/view/com/util/forms/PostDropdownBtn.tsx:184 msgid "Copy link to post" msgstr "Copia il link al post" @@ -932,7 +951,7 @@ msgstr "Copia il link al post" msgid "Copy link to profile" msgstr "Copia il link al profilo" -#: src/view/com/util/forms/PostDropdownBtn.tsx:168 +#: src/view/com/util/forms/PostDropdownBtn.tsx:170 msgid "Copy post text" msgstr "Copia il testo del post" @@ -988,7 +1007,7 @@ msgstr "Creato da <0/>" msgid "Created by you" msgstr "Creato da te" -#: src/view/com/composer/Composer.tsx:448 +#: src/view/com/composer/Composer.tsx:455 msgid "Creates a card with a thumbnail. The card links to {url}" msgstr "Crea una scheda con una miniatura. La scheda si collega a {url}" @@ -1065,11 +1084,11 @@ msgstr "Cancella il mio account" msgid "Delete My Account…" msgstr "" -#: src/view/com/util/forms/PostDropdownBtn.tsx:257 +#: src/view/com/util/forms/PostDropdownBtn.tsx:273 msgid "Delete post" msgstr "Elimina il post" -#: src/view/com/util/forms/PostDropdownBtn.tsx:261 +#: src/view/com/util/forms/PostDropdownBtn.tsx:277 msgid "Delete this post?" msgstr "Elimina questo post?" @@ -1095,7 +1114,7 @@ msgstr "Descrizione" #~ msgid "Developer Tools" #~ msgstr "Strumenti per sviluppatori" -#: src/view/com/composer/Composer.tsx:211 +#: src/view/com/composer/Composer.tsx:218 msgid "Did you want to say anything?" msgstr "Volevi dire qualcosa?" @@ -1103,15 +1122,15 @@ msgstr "Volevi dire qualcosa?" msgid "Dim" msgstr "" -#: src/view/com/composer/Composer.tsx:144 +#: src/view/com/composer/Composer.tsx:151 msgid "Discard" msgstr "Scartare" -#: src/view/com/composer/Composer.tsx:138 +#: src/view/com/composer/Composer.tsx:145 msgid "Discard draft" msgstr "Scarta la bozza" -#: src/view/screens/Moderation.tsx:207 +#: src/view/screens/Moderation.tsx:226 msgid "Discourage apps from showing my account to logged-out users" msgstr "Scoraggia le app dal mostrare il mio account agli utenti disconnessi" @@ -1190,7 +1209,7 @@ msgstr "" msgid "Download CAR file" msgstr "" -#: src/view/com/composer/text-input/TextInput.web.tsx:247 +#: src/view/com/composer/text-input/TextInput.web.tsx:249 msgid "Drop to add images" msgstr "" @@ -1262,6 +1281,7 @@ msgstr "Modifica il profilo" msgid "Edit Profile" msgstr "Modifica il Profilo" +#: src/view/com/home/HomeHeaderLayout.web.tsx:59 #: src/view/screens/Feeds.tsx:355 msgid "Edit Saved Feeds" msgstr "Modifica i feeds memorizzati" @@ -1344,6 +1364,11 @@ msgstr "Fine del feed" msgid "Enter a name for this App Password" msgstr "Inserisci un nome per questa password dell'app" +#: src/components/dialogs/MutedWords.tsx:87 +#: src/components/dialogs/MutedWords.tsx:88 +msgid "Enter a word or tag" +msgstr "" + #: src/view/com/modals/VerifyEmail.tsx:105 msgid "Enter Confirmation Code" msgstr "Inserire il codice di conferma" @@ -1396,7 +1421,7 @@ msgstr "Inserisci il tuo nome di utente e la tua password" msgid "Error receiving captcha response." msgstr "" -#: src/view/screens/Search/Search.tsx:109 +#: src/view/screens/Search/Search.tsx:110 msgid "Error:" msgstr "Errore:" @@ -1467,7 +1492,7 @@ msgstr "Impossibile creare la password dell'app." msgid "Failed to create the list. Check your internet connection and try again." msgstr "Impossibile creare l'elenco. Controlla la connessione Internet e riprova." -#: src/view/com/util/forms/PostDropdownBtn.tsx:108 +#: src/view/com/util/forms/PostDropdownBtn.tsx:110 msgid "Failed to delete post, please try again" msgstr "Non possiamo eliminare il post, riprova di nuovo" @@ -1489,8 +1514,8 @@ msgid "Feed offline" msgstr "Feed offline" #: src/view/com/feeds/FeedPage.tsx:143 -msgid "Feed Preferences" -msgstr "Preferenze del feed" +#~ msgid "Feed Preferences" +#~ msgstr "Preferenze del feed" #: src/view/shell/desktop/RightNav.tsx:61 #: src/view/shell/Drawer.tsx:311 @@ -1530,11 +1555,11 @@ msgstr "" msgid "Find accounts to follow" msgstr "Trova account da seguire" -#: src/view/screens/Search/Search.tsx:439 +#: src/view/screens/Search/Search.tsx:440 msgid "Find users on Bluesky" msgstr "Trova utenti su Bluesky" -#: src/view/screens/Search/Search.tsx:437 +#: src/view/screens/Search/Search.tsx:438 msgid "Find users with the search tool on the right" msgstr "Trova gli utenti con lo strumento di ricerca sulla destra" @@ -1634,6 +1659,7 @@ msgid "Following {0}" msgstr "Seguiti {0}" #: src/Navigation.tsx:248 +#: src/view/com/home/HomeHeaderLayout.web.tsx:45 #: src/view/com/home/HomeHeaderLayoutMobile.tsx:83 #: src/view/screens/PreferencesFollowingFeed.tsx:104 #: src/view/screens/Settings/index.tsx:543 @@ -1673,7 +1699,7 @@ msgstr "Ho dimenticato il password" msgid "Forgot Password" msgstr "Ho dimenticato il Password" -#: src/view/com/posts/FeedItem.tsx:187 +#: src/view/com/posts/FeedItem.tsx:189 msgctxt "from-feed" msgid "From <0/>" msgstr "Da <0/>" @@ -1706,7 +1732,7 @@ msgstr "Torna Indietro" msgid "Go back to previous step" msgstr "" -#: src/view/screens/Search/Search.tsx:724 +#: src/view/screens/Search/Search.tsx:747 #: src/view/shell/desktop/Search.tsx:262 msgid "Go to @{queryMaybeHandle}" msgstr "Vai a @{queryMaybeHandle}" @@ -1723,6 +1749,10 @@ msgstr "Seguente" msgid "Handle" msgstr "Nome Utente" +#: src/components/RichText.tsx:188 +msgid "Hashtag: {tag}" +msgstr "" + #: src/view/com/auth/create/CreateAccount.tsx:208 msgid "Having trouble?" msgstr "Ci sono problemi?" @@ -1761,7 +1791,7 @@ msgctxt "action" msgid "Hide" msgstr "Nascondi" -#: src/view/com/util/forms/PostDropdownBtn.tsx:216 +#: src/view/com/util/forms/PostDropdownBtn.tsx:232 msgid "Hide post" msgstr "Nascondi il messaggio" @@ -1770,7 +1800,7 @@ msgstr "Nascondi il messaggio" msgid "Hide the content" msgstr "Nascondere il contenuto" -#: src/view/com/util/forms/PostDropdownBtn.tsx:220 +#: src/view/com/util/forms/PostDropdownBtn.tsx:236 msgid "Hide this post?" msgstr "Vuoi nascondere questo post?" @@ -1922,7 +1952,7 @@ msgstr "Inserisci la tua password" msgid "Input your user handle" msgstr "Inserisci il tuo identificatore" -#: src/view/com/post-thread/PostThreadItem.tsx:224 +#: src/view/com/post-thread/PostThreadItem.tsx:226 msgid "Invalid or unsupported post record" msgstr "Protocollo del post non valido o non supportato" @@ -2024,7 +2054,7 @@ msgstr "Ulteriori Informazioni" msgid "Learn more about this warning" msgstr "Ulteriori informazioni su questo avviso" -#: src/view/screens/Moderation.tsx:243 +#: src/view/screens/Moderation.tsx:262 msgid "Learn more about what is public on Bluesky." msgstr "Scopri cosa è pubblico su Bluesky." @@ -2104,7 +2134,7 @@ msgstr "è piaciuto il tuo post" msgid "Likes" msgstr "Mi piace" -#: src/view/com/post-thread/PostThreadItem.tsx:181 +#: src/view/com/post-thread/PostThreadItem.tsx:183 msgid "Likes on this post" msgstr "Mi Piace in questo post" @@ -2161,7 +2191,7 @@ msgstr "Carica più post" msgid "Load new notifications" msgstr "Carica più notifiche" -#: src/view/com/feeds/FeedPage.tsx:181 +#: src/view/com/feeds/FeedPage.tsx:115 #: src/view/screens/Profile.tsx:440 #: src/view/screens/ProfileFeed.tsx:495 #: src/view/screens/ProfileList.tsx:681 @@ -2187,7 +2217,7 @@ msgstr "Log" msgid "Log out" msgstr "" -#: src/view/screens/Moderation.tsx:136 +#: src/view/screens/Moderation.tsx:155 msgid "Logged-out visibility" msgstr "Visibilità degli utenti non connettati" @@ -2202,6 +2232,10 @@ msgstr "Accedi all'account che non è nella lista" msgid "Make sure this is where you intend to go!" msgstr "Assicurati che questo sia dove intendi andare!" +#: src/components/dialogs/MutedWords.tsx:71 +msgid "Manage your muted words and tags" +msgstr "" + #: src/view/com/auth/create/Step2.tsx:118 msgid "May not be longer than 253 characters" msgstr "" @@ -2223,7 +2257,7 @@ msgid "Mentioned users" msgstr "Utenti menzionati" #: src/view/com/util/ViewHeader.tsx:81 -#: src/view/screens/Search/Search.tsx:623 +#: src/view/screens/Search/Search.tsx:646 msgid "Menu" msgstr "Menù" @@ -2235,7 +2269,7 @@ msgid "Message from server: {0}" msgstr "Messaggio dal server: {0}" #: src/Navigation.tsx:115 -#: src/view/screens/Moderation.tsx:64 +#: src/view/screens/Moderation.tsx:66 #: src/view/screens/Settings/index.tsx:625 #: src/view/shell/desktop/LeftNav.tsx:397 #: src/view/shell/Drawer.tsx:511 @@ -2266,7 +2300,7 @@ msgstr "Lista di moderazione creata" msgid "Moderation list updated" msgstr "Lista di moderazione aggiornata" -#: src/view/screens/Moderation.tsx:95 +#: src/view/screens/Moderation.tsx:114 msgid "Moderation lists" msgstr "Liste di moderazione" @@ -2293,7 +2327,7 @@ msgstr "Altri feed" msgid "More options" msgstr "Altre opzioni" -#: src/view/com/util/forms/PostDropdownBtn.tsx:299 +#: src/view/com/util/forms/PostDropdownBtn.tsx:315 msgid "More post options" msgstr "Altre impostazioni per il post" @@ -2305,6 +2339,14 @@ msgstr "Dai priorità alle risposte con più likes" msgid "Must be at least 3 characters" msgstr "" +#: src/components/TagMenu/index.tsx:253 +msgid "Mute" +msgstr "" + +#: src/components/TagMenu/index.web.tsx:91 +msgid "Mute {truncatedTag}" +msgstr "" + #: src/view/com/profile/ProfileHeader.tsx:327 msgid "Mute Account" msgstr "Silenziare Account" @@ -2313,6 +2355,18 @@ msgstr "Silenziare Account" msgid "Mute accounts" msgstr "Silenziare accounts" +#: src/components/TagMenu/index.tsx:211 +msgid "Mute all {tag} posts" +msgstr "" + +#: src/components/dialogs/MutedWords.tsx:131 +msgid "Mute in tags only" +msgstr "" + +#: src/components/dialogs/MutedWords.tsx:116 +msgid "Mute in text & tags" +msgstr "" + #: src/view/screens/ProfileList.tsx:491 msgid "Mute list" msgstr "Silenziare la lista" @@ -2325,15 +2379,27 @@ msgstr "Vuoi silenziare queste liste?" msgid "Mute this List" msgstr "Silenzia questa Lista" -#: src/view/com/util/forms/PostDropdownBtn.tsx:200 +#: src/components/dialogs/MutedWords.tsx:109 +msgid "Mute this word in post text and tags" +msgstr "" + +#: src/components/dialogs/MutedWords.tsx:124 +msgid "Mute this word in tags only" +msgstr "" + +#: src/view/com/util/forms/PostDropdownBtn.tsx:202 msgid "Mute thread" msgstr "Silenzia questa discussione" +#: src/view/com/util/forms/PostDropdownBtn.tsx:216 +msgid "Mute words & tags" +msgstr "" + #: src/view/com/lists/ListCard.tsx:102 msgid "Muted" msgstr "Silenziato" -#: src/view/screens/Moderation.tsx:109 +#: src/view/screens/Moderation.tsx:128 msgid "Muted accounts" msgstr "Account silenziato" @@ -2346,6 +2412,10 @@ msgstr "Accounts Silenziati" msgid "Muted accounts have their posts removed from your feed and from your notifications. Mutes are completely private." msgstr "I post degli account silenziati verranno rimossi dal tuo feed e dalle tue notifiche. Silenziare è completamente privato." +#: src/view/screens/Moderation.tsx:100 +msgid "Muted words & tags" +msgstr "" + #: src/view/screens/ProfileList.tsx:277 msgid "Muting is private. Muted accounts can interact with you, but you will not see their posts or receive notifications from them." msgstr "Silenziare un account è privato. Gli account silenziati possono interagire con te, ma non vedrai i loro post né riceverai le loro notifiche." @@ -2409,6 +2479,10 @@ msgstr "Non perdere mai l'accesso ai tuoi follower e ai tuoi dati." msgid "Never lose access to your followers or data." msgstr "" +#: src/components/dialogs/MutedWords.tsx:244 +msgid "Nevermind" +msgstr "" + #: src/view/screens/Lists.tsx:76 msgctxt "action" msgid "New" @@ -2430,7 +2504,7 @@ msgstr "Nuovo Password" msgid "New Password" msgstr "" -#: src/view/com/feeds/FeedPage.tsx:192 +#: src/view/com/feeds/FeedPage.tsx:126 msgctxt "action" msgid "New post" msgstr "Nuovo Post" @@ -2518,8 +2592,8 @@ msgid "No results found for \"{query}\"" msgstr "Nessun risultato trovato per \"{query}\"" #: src/view/com/modals/ListAddRemoveUsers.tsx:127 -#: src/view/screens/Search/Search.tsx:280 -#: src/view/screens/Search/Search.tsx:308 +#: src/view/screens/Search/Search.tsx:281 +#: src/view/screens/Search/Search.tsx:309 msgid "No results found for {query}" msgstr "Nessun risultato trovato per {query}" @@ -2545,7 +2619,7 @@ msgstr "Non trovato" msgid "Not right now" msgstr "Non adesso" -#: src/view/screens/Moderation.tsx:233 +#: src/view/screens/Moderation.tsx:252 msgid "Note: Bluesky is an open and public network. This setting only limits the visibility of your content on the Bluesky app and website, and other apps may not respect this setting. Your content may still be shown to logged-out users by other apps and websites." msgstr "Nota: Bluesky è una rete aperta e pubblica. Questa impostazione limita solo la visibilità dei tuoi contenuti sull'app e sul sito Web di Bluesky e altre app potrebbero non rispettare questa impostazione. I tuoi contenuti potrebbero comunque essere mostrati agli utenti disconnessi da altre app e siti web." @@ -2583,7 +2657,7 @@ msgstr "Prima le risposte più vecchie" msgid "Onboarding reset" msgstr "Reimpostazione dell'onboarding" -#: src/view/com/composer/Composer.tsx:375 +#: src/view/com/composer/Composer.tsx:382 msgid "One or more images is missing alt text." msgstr "A una o più immagini manca il testo alternativo." @@ -2600,8 +2674,12 @@ msgstr "Ops!" msgid "Open" msgstr "" -#: src/view/com/composer/Composer.tsx:470 -#: src/view/com/composer/Composer.tsx:471 +#: src/view/screens/Moderation.tsx:75 +msgid "Open content filtering settings" +msgstr "" + +#: src/view/com/composer/Composer.tsx:477 +#: src/view/com/composer/Composer.tsx:478 msgid "Open emoji picker" msgstr "Apri il selettore emoji" @@ -2609,6 +2687,10 @@ msgstr "Apri il selettore emoji" msgid "Open links with in-app browser" msgstr "Apri i links con il navigatore della app" +#: src/view/screens/Moderation.tsx:92 +msgid "Open muted words settings" +msgstr "" + #: src/view/com/home/HomeHeaderLayoutMobile.tsx:49 msgid "Open navigation" msgstr "Apri la navigazione" @@ -2685,6 +2767,7 @@ msgstr "Apre le impostazioni di moderazione" msgid "Opens password reset form" msgstr "Apre il modulo di reimpostazione della password" +#: src/view/com/home/HomeHeaderLayout.web.tsx:60 #: src/view/screens/Feeds.tsx:356 msgid "Opens screen to edit Saved Feeds" msgstr "Apre la schermata per modificare i feed salvati" @@ -2863,7 +2946,7 @@ msgstr "Spiegaci perché ritieni che questo avviso sui contenuti sia stato appli msgid "Please Verify Your Email" msgstr "Verifica la tua email" -#: src/view/com/composer/Composer.tsx:215 +#: src/view/com/composer/Composer.tsx:222 msgid "Please wait for your link card to finish loading" msgstr "Attendi il caricamento della scheda di collegamento" @@ -2875,8 +2958,8 @@ msgstr "" msgid "Porn" msgstr "Porno" -#: src/view/com/composer/Composer.tsx:350 -#: src/view/com/composer/Composer.tsx:358 +#: src/view/com/composer/Composer.tsx:357 +#: src/view/com/composer/Composer.tsx:365 msgctxt "action" msgid "Post" msgstr "Post" @@ -2889,7 +2972,7 @@ msgstr "Post" #~ msgid "Post" #~ msgstr "Publicació" -#: src/view/com/post-thread/PostThreadItem.tsx:173 +#: src/view/com/post-thread/PostThreadItem.tsx:175 msgid "Post by {0}" msgstr "Pubblicato da {0}" @@ -2899,11 +2982,11 @@ msgstr "Pubblicato da {0}" msgid "Post by @{0}" msgstr "Pubblicato da @{0}" -#: src/view/com/util/forms/PostDropdownBtn.tsx:88 +#: src/view/com/util/forms/PostDropdownBtn.tsx:90 msgid "Post deleted" msgstr "Post eliminato" -#: src/view/com/post-thread/PostThread.tsx:461 +#: src/view/com/post-thread/PostThread.tsx:462 msgid "Post hidden" msgstr "Post nascosto" @@ -2915,14 +2998,22 @@ msgstr "Lingua del post" msgid "Post Languages" msgstr "Lingue del post" -#: src/view/com/post-thread/PostThread.tsx:513 +#: src/view/com/post-thread/PostThread.tsx:514 msgid "Post not found" msgstr "Post non trovato" +#: src/components/TagMenu/index.tsx:257 +msgid "posts" +msgstr "" + #: src/view/screens/Profile.tsx:180 msgid "Posts" msgstr "Post" +#: src/components/dialogs/MutedWords.tsx:77 +msgid "Posts can be muted based on their text, their tags, or both." +msgstr "" + #: src/view/com/posts/FeedErrorMessage.tsx:64 msgid "Posts hidden" msgstr "Post nascosto" @@ -2987,11 +3078,11 @@ msgstr "Elenchi pubblici e condivisibili di utenti da disattivare o bloccare in msgid "Public, shareable lists which can drive feeds." msgstr "Elenchi pubblici e condivisibili che possono gestire i feeds." -#: src/view/com/composer/Composer.tsx:335 +#: src/view/com/composer/Composer.tsx:342 msgid "Publish post" msgstr "Pubblica il post" -#: src/view/com/composer/Composer.tsx:335 +#: src/view/com/composer/Composer.tsx:342 msgid "Publish reply" msgstr "Pubblica la risposta" @@ -3028,6 +3119,7 @@ msgstr "Feeds consigliati" msgid "Recommended Users" msgstr "Utenti consigliati" +#: src/components/dialogs/MutedWords.tsx:249 #: src/view/com/modals/ListAddRemoveUsers.tsx:264 #: src/view/com/modals/SelfLabel.tsx:83 #: src/view/com/modals/UserAddRemoveLists.tsx:219 @@ -3065,6 +3157,10 @@ msgstr "Rimuovi l'immagine" msgid "Remove image preview" msgstr "Rimuovi l'anteprima dell'immagine" +#: src/components/dialogs/MutedWords.tsx:294 +msgid "Remove mute word from your list" +msgstr "" + #: src/view/com/modals/Repost.tsx:47 msgid "Remove repost" msgstr "Rimuovi la ripubblicazione" @@ -3099,7 +3195,7 @@ msgstr "Risposte" msgid "Replies to this thread are disabled" msgstr "Le risposte a questo thread sono disabilitate" -#: src/view/com/composer/Composer.tsx:348 +#: src/view/com/composer/Composer.tsx:355 msgctxt "action" msgid "Reply" msgstr "Rispondi" @@ -3109,7 +3205,7 @@ msgid "Reply Filters" msgstr "Filtri di risposta" #: src/view/com/post/Post.tsx:167 -#: src/view/com/posts/FeedItem.tsx:285 +#: src/view/com/posts/FeedItem.tsx:287 msgctxt "description" msgid "Reply to <0/>" msgstr "Rispondi a <0/>" @@ -3131,7 +3227,7 @@ msgid "Report List" msgstr "Segnala la lista" #: src/view/com/modals/report/SendReportButton.tsx:37 -#: src/view/com/util/forms/PostDropdownBtn.tsx:239 +#: src/view/com/util/forms/PostDropdownBtn.tsx:255 msgid "Report post" msgstr "Segnala il post" @@ -3160,7 +3256,7 @@ msgstr "Ripubblicare o citare il post" msgid "Reposted By" msgstr "" -#: src/view/com/posts/FeedItem.tsx:205 +#: src/view/com/posts/FeedItem.tsx:207 msgid "Reposted by {0}" msgstr "" @@ -3168,7 +3264,7 @@ msgstr "" #~ msgid "Reposted by {0})" #~ msgstr "Ripubblicato da {0})" -#: src/view/com/posts/FeedItem.tsx:222 +#: src/view/com/posts/FeedItem.tsx:224 msgid "Reposted by <0/>" msgstr "Ripubblicato da <0/>" @@ -3176,7 +3272,7 @@ msgstr "Ripubblicato da <0/>" msgid "reposted your post" msgstr "ripubblicato il tuo post" -#: src/view/com/post-thread/PostThreadItem.tsx:186 +#: src/view/com/post-thread/PostThreadItem.tsx:188 msgid "Reposts of this post" msgstr "Ripubblicazione di questo post" @@ -3327,9 +3423,9 @@ msgstr "Scorri verso l'alto" #: src/view/com/modals/ListAddRemoveUsers.tsx:75 #: src/view/com/util/forms/SearchInput.tsx:67 #: src/view/com/util/forms/SearchInput.tsx:79 -#: src/view/screens/Search/Search.tsx:418 -#: src/view/screens/Search/Search.tsx:645 -#: src/view/screens/Search/Search.tsx:663 +#: src/view/screens/Search/Search.tsx:419 +#: src/view/screens/Search/Search.tsx:668 +#: src/view/screens/Search/Search.tsx:686 #: src/view/shell/bottom-bar/BottomBar.tsx:159 #: src/view/shell/desktop/LeftNav.tsx:324 #: src/view/shell/desktop/Search.tsx:214 @@ -3339,11 +3435,19 @@ msgstr "Scorri verso l'alto" msgid "Search" msgstr "Cerca" -#: src/view/screens/Search/Search.tsx:712 +#: src/view/screens/Search/Search.tsx:735 #: src/view/shell/desktop/Search.tsx:255 msgid "Search for \"{query}\"" msgstr "Cerca \"{query}\"" +#: src/components/TagMenu/index.tsx:145 +msgid "Search for all posts by @{authorHandle} with tag {tag}" +msgstr "" + +#: src/components/TagMenu/index.tsx:90 +msgid "Search for all posts with tag {tag}" +msgstr "" + #: src/view/com/auth/LoggedOut.tsx:104 #: src/view/com/auth/LoggedOut.tsx:105 #: src/view/com/modals/ListAddRemoveUsers.tsx:70 @@ -3354,6 +3458,22 @@ msgstr "Cerca utenti" msgid "Security Step Required" msgstr "Passaggio di sicurezza obbligatorio" +#: src/components/TagMenu/index.web.tsx:50 +msgid "See {truncatedTag} posts" +msgstr "" + +#: src/components/TagMenu/index.web.tsx:67 +msgid "See {truncatedTag} posts by user" +msgstr "" + +#: src/components/TagMenu/index.tsx:128 +msgid "See <0>{tag} posts" +msgstr "" + +#: src/components/TagMenu/index.tsx:189 +msgid "See <0>{tag} posts by this user" +msgstr "" + #: src/view/screens/SavedFeeds.tsx:163 msgid "See this guide" msgstr "Consulta questa guida" @@ -3562,7 +3682,7 @@ msgid "Share" msgstr "Condividi" #: src/view/com/profile/ProfileHeader.tsx:295 -#: src/view/com/util/forms/PostDropdownBtn.tsx:182 +#: src/view/com/util/forms/PostDropdownBtn.tsx:184 #: src/view/screens/ProfileList.tsx:418 msgid "Share" msgstr "Condividi" @@ -3595,9 +3715,9 @@ msgstr "Mostra incorporamenti di {0}" msgid "Show follows similar to {0}" msgstr "Mostra follows simile a {0}" -#: src/view/com/post-thread/PostThreadItem.tsx:532 -#: src/view/com/post/Post.tsx:196 -#: src/view/com/posts/FeedItem.tsx:359 +#: src/view/com/post-thread/PostThreadItem.tsx:538 +#: src/view/com/post/Post.tsx:198 +#: src/view/com/posts/FeedItem.tsx:363 msgid "Show More" msgstr "Mostra di più" @@ -3765,7 +3885,7 @@ msgstr "" msgid "Something went wrong. Check your email and try again." msgstr "Qualcosa è andato storto. Controlla la tua email e riprova." -#: src/App.native.tsx:61 +#: src/App.native.tsx:63 msgid "Sorry! Your session expired. Please log in again." msgstr "Scusa! La tua sessione è scaduta. Per favore accedi di nuovo." @@ -3823,7 +3943,7 @@ msgstr "" msgid "Subscribe to this list" msgstr "Iscriviti alla lista" -#: src/view/screens/Search/Search.tsx:373 +#: src/view/screens/Search/Search.tsx:374 msgid "Suggested Follows" msgstr "Followers suggeriti" @@ -3867,6 +3987,14 @@ msgstr "Sistema" msgid "System log" msgstr "Registro di sistema" +#: src/components/dialogs/MutedWords.tsx:288 +msgid "tag" +msgstr "" + +#: src/components/TagMenu/index.tsx:74 +msgid "Tag menu: {tag}" +msgstr "" + #: src/view/com/modals/crop-image/CropImage.web.tsx:112 msgid "Tall" msgstr "Alto" @@ -3890,6 +4018,10 @@ msgstr "Termini" msgid "Terms of Service" msgstr "Termini di servizio" +#: src/components/dialogs/MutedWords.tsx:288 +msgid "text" +msgstr "" + #: src/view/com/modals/AppealLabel.tsx:70 #: src/view/com/modals/report/InputIssueDetails.tsx:51 msgid "Text input field" @@ -3915,7 +4047,7 @@ msgstr "La politica sul copyright è stata spostata a <0/>" msgid "The following steps will help customize your Bluesky experience." msgstr "" -#: src/view/com/post-thread/PostThread.tsx:516 +#: src/view/com/post-thread/PostThread.tsx:517 msgid "The post may have been deleted." msgstr "Il post potrebbe essere stato cancellato." @@ -4090,7 +4222,7 @@ msgstr "La lista è vuota!" msgid "This name is already in use" msgstr "Questo nome è già in uso" -#: src/view/com/post-thread/PostThreadItem.tsx:123 +#: src/view/com/post-thread/PostThreadItem.tsx:125 msgid "This post has been deleted." msgstr "Questo post è stato cancellato." @@ -4114,7 +4246,11 @@ msgstr "" msgid "This warning is only available for posts with media attached." msgstr "Questo avviso è disponibile solo per i post con contenuti multimediali allegati." -#: src/view/com/util/forms/PostDropdownBtn.tsx:221 +#: src/components/dialogs/MutedWords.tsx:236 +msgid "This will delete {0} from your muted words. You can always add it back later." +msgstr "" + +#: src/view/com/util/forms/PostDropdownBtn.tsx:237 msgid "This will hide this post from your feeds." msgstr "Questo nasconderà il post dai tuoi feeds." @@ -4131,6 +4267,10 @@ msgstr "Modalità discussione" msgid "Threads Preferences" msgstr "Preferenze per le discussioni" +#: src/components/dialogs/MutedWords.tsx:95 +msgid "Toggle between muted word options." +msgstr "" + #: src/view/com/util/forms/DropdownButton.tsx:246 msgid "Toggle dropdown" msgstr "Attiva/disattiva il menu a discesa" @@ -4139,9 +4279,9 @@ msgstr "Attiva/disattiva il menu a discesa" msgid "Transformations" msgstr "Trasformazioni" -#: src/view/com/post-thread/PostThreadItem.tsx:679 -#: src/view/com/post-thread/PostThreadItem.tsx:681 -#: src/view/com/util/forms/PostDropdownBtn.tsx:154 +#: src/view/com/post-thread/PostThreadItem.tsx:685 +#: src/view/com/post-thread/PostThreadItem.tsx:687 +#: src/view/com/util/forms/PostDropdownBtn.tsx:156 msgid "Translate" msgstr "Tradurre" @@ -4209,15 +4349,24 @@ msgstr "Sfortunatamente, non soddisfi i requisiti per creare un account." msgid "Unlike" msgstr "Togli Mi piace" +#: src/components/TagMenu/index.tsx:253 #: src/view/screens/ProfileList.tsx:597 msgid "Unmute" msgstr "Riattiva" +#: src/components/TagMenu/index.web.tsx:90 +msgid "Unmute {truncatedTag}" +msgstr "" + #: src/view/com/profile/ProfileHeader.tsx:326 msgid "Unmute Account" msgstr "Riattiva questo account" -#: src/view/com/util/forms/PostDropdownBtn.tsx:200 +#: src/components/TagMenu/index.tsx:210 +msgid "Unmute all {tag} posts" +msgstr "" + +#: src/view/com/util/forms/PostDropdownBtn.tsx:202 msgid "Unmute thread" msgstr "Riattiva questa discussione" @@ -4414,6 +4563,10 @@ msgstr "" msgid "We ran out of posts from your follows. Here's the latest from <0/>." msgstr "Abbiamo esaurito i posts dei tuoi follower. Ecco le ultime novità da <0/>." +#: src/components/dialogs/MutedWords.tsx:161 +msgid "We recommend avoiding common words that appear in many posts, since it can result in no posts being shown." +msgstr "" + #: src/screens/Onboarding/StepAlgoFeeds/index.tsx:124 msgid "We recommend our \"Discover\" feed:" msgstr "" @@ -4442,7 +4595,11 @@ msgstr "Siamo felici che tu ti unisca a noi!" msgid "We're sorry, but we were unable to resolve this list. If this persists, please contact the list creator, @{handleOrDid}." msgstr "Siamo spiacenti, ma non siamo riusciti a risolvere questa lista. Se il problema persiste, contatta il creatore della lista, @{handleOrDid}." -#: src/view/screens/Search/Search.tsx:253 +#: src/components/dialogs/MutedWords.tsx:182 +msgid "We're sorry, but we weren't able to load your muted words at this time. Please try again." +msgstr "" + +#: src/view/screens/Search/Search.tsx:254 msgid "We're sorry, but your search could not be completed. Please try again in a few minutes." msgstr "Siamo spiacenti, ma non è stato possibile completare la ricerca. Riprova tra qualche minuto." @@ -4466,7 +4623,7 @@ msgstr "Qual è il problema con questo {collectionName}?" #~ msgstr "¿Qué sigue?" #: src/view/com/auth/SplashScreen.tsx:59 -#: src/view/com/composer/Composer.tsx:279 +#: src/view/com/composer/Composer.tsx:286 msgid "What's up?" msgstr "Come va?" @@ -4487,11 +4644,11 @@ msgstr "Chi può rispondere" msgid "Wide" msgstr "Largo" -#: src/view/com/composer/Composer.tsx:415 +#: src/view/com/composer/Composer.tsx:422 msgid "Write post" msgstr "Scrivi un post" -#: src/view/com/composer/Composer.tsx:278 +#: src/view/com/composer/Composer.tsx:285 #: src/view/com/composer/Prompt.tsx:33 msgid "Write your reply" msgstr "Scrivi la tua risposta" @@ -4551,7 +4708,7 @@ msgstr "Non hai salvato nessun feed!" msgid "You don't have any saved feeds." msgstr "Non hai salvato nessun feed." -#: src/view/com/post-thread/PostThread.tsx:464 +#: src/view/com/post-thread/PostThread.tsx:465 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." @@ -4591,6 +4748,10 @@ msgstr "Non hai ancora creato alcuna password per l'app. Puoi crearne uno premen msgid "You have not muted any accounts yet. To mute an account, go to their profile and selected \"Mute account\" from the menu on their account." msgstr "Non hai ancora disattivato alcun account. Per disattivare un account, vai al suo profilo e seleziona \"Disattiva account\" dal menu del account." +#: src/components/dialogs/MutedWords.tsx:202 +msgid "You haven't muted any words or tags yet" +msgstr "" + #: src/view/com/modals/ContentFilteringSettings.tsx:175 msgid "You must be 18 or older to enable adult content." msgstr "Devi avere almeno 18 anni per abilitare i contenuti per adulti." @@ -4599,11 +4760,11 @@ msgstr "Devi avere almeno 18 anni per abilitare i contenuti per adulti." msgid "You must be 18 years or older to enable adult content" msgstr "" -#: src/view/com/util/forms/PostDropdownBtn.tsx:127 +#: src/view/com/util/forms/PostDropdownBtn.tsx:129 msgid "You will no longer receive notifications for this thread" msgstr "Non riceverai più notifiche per questo filo di discussione" -#: src/view/com/util/forms/PostDropdownBtn.tsx:130 +#: src/view/com/util/forms/PostDropdownBtn.tsx:132 msgid "You will now receive notifications for this thread" msgstr "Adesso riceverai le notifiche per questa discussione" @@ -4691,11 +4852,15 @@ msgstr "Il tuo nome di utente completo sarà <0>@{0}" #~ msgid "Your invite codes are hidden when logged in using an App Password" #~ msgstr "I tuoi codici di invito vengono celati quando accedi utilizzando una password per l'app" +#: src/components/dialogs/MutedWords.tsx:173 +msgid "Your muted words" +msgstr "" + #: src/view/com/modals/ChangePassword.tsx:155 msgid "Your password has been changed successfully!" msgstr "" -#: src/view/com/composer/Composer.tsx:267 +#: src/view/com/composer/Composer.tsx:274 msgid "Your post has been published" msgstr "Il tuo post è stato pubblicato" @@ -4710,7 +4875,7 @@ msgstr "I tuoi post, i tuoi Mi piace e i tuoi blocchi sono pubblici. I conti sil msgid "Your profile" msgstr "Il tuo profilo" -#: src/view/com/composer/Composer.tsx:266 +#: src/view/com/composer/Composer.tsx:273 msgid "Your reply has been published" msgstr "La tua risposta è stata pubblicata" diff --git a/src/locale/locales/ja/messages.po b/src/locale/locales/ja/messages.po index a0ad5ffb..21f2e5e0 100644 --- a/src/locale/locales/ja/messages.po +++ b/src/locale/locales/ja/messages.po @@ -93,7 +93,7 @@ msgid "A new version of the app is available. Please update to continue using th msgstr "新しいバージョンのアプリが利用可能です。継続して使用するためにはアップデートしてください。" #: src/view/com/util/ViewHeader.tsx:83 -#: src/view/screens/Search/Search.tsx:624 +#: src/view/screens/Search/Search.tsx:647 msgid "Access navigation links and settings" msgstr "ナビゲーションリンクと設定にアクセス" @@ -144,6 +144,7 @@ msgstr "アカウントのブロックを解除しました" msgid "Account unmuted" msgstr "アカウントのミュートを解除しました" +#: src/components/dialogs/MutedWords.tsx:147 #: src/view/com/auth/onboarding/RecommendedFeedsItem.tsx:150 #: src/view/com/modals/ListAddRemoveUsers.tsx:264 #: src/view/com/modals/UserAddRemoveLists.tsx:219 @@ -185,14 +186,22 @@ msgstr "詳細を追加" msgid "Add details to report" msgstr "レポートに詳細を追加" -#: src/view/com/composer/Composer.tsx:446 +#: src/view/com/composer/Composer.tsx:453 msgid "Add link card" msgstr "リンクカードを追加" -#: src/view/com/composer/Composer.tsx:451 +#: src/view/com/composer/Composer.tsx:458 msgid "Add link card:" msgstr "リンクカードを追加:" +#: src/components/dialogs/MutedWords.tsx:140 +msgid "Add mute word for configured settings" +msgstr "" + +#: src/components/dialogs/MutedWords.tsx:74 +msgid "Add muted words and tags" +msgstr "" + #: src/view/com/modals/ChangeHandle.tsx:417 msgid "Add the following DNS record to your domain:" msgstr "次のDNSレコードをドメインに追加してください:" @@ -316,7 +325,7 @@ msgstr "アプリパスワードの設定" msgid "App Passwords" msgstr "アプリパスワード" -#: src/view/com/util/forms/PostDropdownBtn.tsx:279 +#: src/view/com/util/forms/PostDropdownBtn.tsx:295 msgid "Appeal content warning" msgstr "コンテンツの警告に異議を申し立てる" @@ -344,15 +353,16 @@ msgstr "背景" msgid "Are you sure you want to delete the app password \"{name}\"?" msgstr "アプリパスワード「{name}」を本当に削除しますか?" -#: src/view/com/composer/Composer.tsx:143 +#: src/view/com/composer/Composer.tsx:150 msgid "Are you sure you'd like to discard this draft?" msgstr "本当にこの下書きを破棄しますか?" +#: src/components/dialogs/MutedWords.tsx:233 #: src/view/screens/ProfileList.tsx:365 msgid "Are you sure?" msgstr "本当によろしいですか?" -#: src/view/com/util/forms/PostDropdownBtn.tsx:262 +#: src/view/com/util/forms/PostDropdownBtn.tsx:278 msgid "Are you sure? This cannot be undone." msgstr "本当によろしいですか?これは元に戻せません。" @@ -374,15 +384,15 @@ msgstr "芸術的または性的ではないヌード。" #: src/view/com/auth/login/LoginForm.tsx:259 #: src/view/com/auth/login/SetNewPasswordForm.tsx:179 #: src/view/com/modals/report/InputIssueDetails.tsx:46 -#: src/view/com/post-thread/PostThread.tsx:471 -#: src/view/com/post-thread/PostThread.tsx:521 -#: src/view/com/post-thread/PostThread.tsx:529 +#: src/view/com/post-thread/PostThread.tsx:472 +#: src/view/com/post-thread/PostThread.tsx:522 +#: src/view/com/post-thread/PostThread.tsx:530 #: src/view/com/profile/ProfileHeader.tsx:649 #: src/view/com/util/ViewHeader.tsx:81 msgid "Back" msgstr "戻る" -#: src/view/com/post-thread/PostThread.tsx:479 +#: src/view/com/post-thread/PostThread.tsx:480 msgctxt "action" msgid "Back" msgstr "戻る" @@ -430,7 +440,7 @@ msgstr "このリストをブロック" msgid "Blocked" msgstr "ブロックされています" -#: src/view/screens/Moderation.tsx:123 +#: src/view/screens/Moderation.tsx:142 msgid "Blocked accounts" msgstr "ブロック中のアカウント" @@ -489,7 +499,7 @@ msgstr "Blueskyはパブリックです。" msgid "Bluesky uses invites to build a healthier community. If you don't know anybody with an invite, you can sign up for the waitlist and we'll send one soon." msgstr "Blueskyはより健全なコミュニティーを構築するために招待状を使用します。招待状をお持ちでない場合、Waitlistにお申し込みいただくと招待状をお送りします。" -#: src/view/screens/Moderation.tsx:226 +#: src/view/screens/Moderation.tsx:245 msgid "Bluesky will not show your profile and posts to logged-out users. Other apps may not honor this request. This does not make your account private." msgstr "Blueskyはログアウトしたユーザーにあなたのプロフィールや投稿を表示しません。他のアプリはこのリクエストに応じない場合があります。この設定はあなたのアカウントを非公開にするものではありません。" @@ -541,8 +551,8 @@ msgid "Can only contain letters, numbers, spaces, dashes, and underscores. Must msgstr "英数字、スペース、ハイフン、アンダースコアのみが使用可能です。長さは4文字以上32文字以下である必要があります。" #: src/components/Prompt.tsx:91 -#: src/view/com/composer/Composer.tsx:300 -#: src/view/com/composer/Composer.tsx:305 +#: src/view/com/composer/Composer.tsx:307 +#: src/view/com/composer/Composer.tsx:312 #: src/view/com/modals/ChangeEmail.tsx:218 #: src/view/com/modals/ChangeEmail.tsx:220 #: src/view/com/modals/ChangePassword.tsx:265 @@ -556,7 +566,7 @@ msgstr "英数字、スペース、ハイフン、アンダースコアのみが #: src/view/com/modals/VerifyEmail.tsx:247 #: src/view/com/modals/VerifyEmail.tsx:253 #: src/view/com/modals/Waitlist.tsx:142 -#: src/view/screens/Search/Search.tsx:693 +#: src/view/screens/Search/Search.tsx:716 #: src/view/shell/desktop/Search.tsx:238 msgid "Cancel" msgstr "キャンセル" @@ -715,7 +725,7 @@ msgid "Clear all storage data (restart after this)" msgstr "すべてのストレージデータをクリア(この後再起動します)" #: src/view/com/util/forms/SearchInput.tsx:88 -#: src/view/screens/Search/Search.tsx:674 +#: src/view/screens/Search/Search.tsx:697 msgid "Clear search query" msgstr "検索クエリをクリア" @@ -723,6 +733,11 @@ msgstr "検索クエリをクリア" msgid "click here" msgstr "こちらをクリック" +#: src/components/RichText.tsx:189 +#: src/components/TagMenu/index.web.tsx:125 +msgid "Click here to open tag menu for {tag}" +msgstr "" + #: src/screens/Onboarding/index.tsx:35 msgid "Climate" msgstr "気象" @@ -753,11 +768,15 @@ msgstr "画像を閉じる" msgid "Close image viewer" msgstr "画像ビューアを閉じる" -#: src/view/shell/index.web.tsx:49 +#: src/view/shell/index.web.tsx:51 msgid "Close navigation footer" msgstr "ナビゲーションフッターを閉じる" -#: src/view/shell/index.web.tsx:50 +#: src/components/TagMenu/index.tsx:266 +msgid "Close this dialog" +msgstr "" + +#: src/view/shell/index.web.tsx:52 msgid "Closes bottom navigation bar" msgstr "下部のナビゲーションバーを閉じる" @@ -765,7 +784,7 @@ msgstr "下部のナビゲーションバーを閉じる" msgid "Closes password update alert" msgstr "パスワード更新アラートを閉じる" -#: src/view/com/composer/Composer.tsx:302 +#: src/view/com/composer/Composer.tsx:309 msgid "Closes post composer and discards post draft" msgstr "投稿の編集画面を閉じ、下書きを削除する" @@ -798,7 +817,7 @@ msgstr "初期設定を完了してアカウントを使い始める" msgid "Complete the challenge" msgstr "" -#: src/view/com/composer/Composer.tsx:417 +#: src/view/com/composer/Composer.tsx:424 msgid "Compose posts up to {MAX_GRAPHEME_LENGTH} characters in length" msgstr "{MAX_GRAPHEME_LENGTH}文字までの投稿を作成" @@ -862,7 +881,7 @@ msgstr "接続中..." msgid "Contact support" msgstr "サポートに連絡" -#: src/view/screens/Moderation.tsx:81 +#: src/view/screens/Moderation.tsx:83 msgid "Content filtering" msgstr "コンテンツのフィルタリング" @@ -928,7 +947,7 @@ msgstr "ビルドバージョンをクリップボードにコピーしました #: src/view/com/modals/AddAppPasswords.tsx:76 #: src/view/com/modals/InviteCodes.tsx:152 -#: src/view/com/util/forms/PostDropdownBtn.tsx:141 +#: src/view/com/util/forms/PostDropdownBtn.tsx:143 msgid "Copied to clipboard" msgstr "クリップボードにコピーしました" @@ -944,7 +963,7 @@ msgstr "コピー" msgid "Copy link to list" msgstr "リストへのリンクをコピー" -#: src/view/com/util/forms/PostDropdownBtn.tsx:182 +#: src/view/com/util/forms/PostDropdownBtn.tsx:184 msgid "Copy link to post" msgstr "投稿へのリンクをコピー" @@ -952,7 +971,7 @@ msgstr "投稿へのリンクをコピー" msgid "Copy link to profile" msgstr "プロフィールへのリンクをコピー" -#: src/view/com/util/forms/PostDropdownBtn.tsx:168 +#: src/view/com/util/forms/PostDropdownBtn.tsx:170 msgid "Copy post text" msgstr "投稿のテキストをコピー" @@ -1008,7 +1027,7 @@ msgstr "作成者:<0/>" msgid "Created by you" msgstr "作成者:あなた" -#: src/view/com/composer/Composer.tsx:448 +#: src/view/com/composer/Composer.tsx:455 msgid "Creates a card with a thumbnail. The card links to {url}" msgstr "サムネイル付きのカードを作成します。そのカードは次のアドレスへリンクします:{url}" @@ -1089,11 +1108,11 @@ msgstr "マイアカウントを削除" msgid "Delete My Account…" msgstr "マイアカウントを削除…" -#: src/view/com/util/forms/PostDropdownBtn.tsx:257 +#: src/view/com/util/forms/PostDropdownBtn.tsx:273 msgid "Delete post" msgstr "投稿を削除" -#: src/view/com/util/forms/PostDropdownBtn.tsx:261 +#: src/view/com/util/forms/PostDropdownBtn.tsx:277 msgid "Delete this post?" msgstr "この投稿を削除しますか?" @@ -1120,7 +1139,7 @@ msgstr "説明" #~ msgid "Developer Tools" #~ msgstr "開発者ツール" -#: src/view/com/composer/Composer.tsx:211 +#: src/view/com/composer/Composer.tsx:218 msgid "Did you want to say anything?" msgstr "なにか言いたいことはあった?" @@ -1128,15 +1147,15 @@ msgstr "なにか言いたいことはあった?" msgid "Dim" msgstr "グレー" -#: src/view/com/composer/Composer.tsx:144 +#: src/view/com/composer/Composer.tsx:151 msgid "Discard" msgstr "破棄" -#: src/view/com/composer/Composer.tsx:138 +#: src/view/com/composer/Composer.tsx:145 msgid "Discard draft" msgstr "下書きを破棄" -#: src/view/screens/Moderation.tsx:207 +#: src/view/screens/Moderation.tsx:226 msgid "Discourage apps from showing my account to logged-out users" msgstr "アプリがログアウトしたユーザーに自分のアカウントを表示しないようにする" @@ -1215,7 +1234,7 @@ msgstr "" msgid "Download CAR file" msgstr "" -#: src/view/com/composer/text-input/TextInput.web.tsx:247 +#: src/view/com/composer/text-input/TextInput.web.tsx:249 msgid "Drop to add images" msgstr "ドロップして画像を追加する" @@ -1287,6 +1306,7 @@ msgstr "プロフィールを編集" msgid "Edit Profile" msgstr "プロフィールを編集" +#: src/view/com/home/HomeHeaderLayout.web.tsx:59 #: src/view/screens/Feeds.tsx:355 msgid "Edit Saved Feeds" msgstr "保存されたフィードを編集" @@ -1369,6 +1389,11 @@ msgstr "フィードの終わり" msgid "Enter a name for this App Password" msgstr "このアプリパスワードの名前を入力" +#: src/components/dialogs/MutedWords.tsx:87 +#: src/components/dialogs/MutedWords.tsx:88 +msgid "Enter a word or tag" +msgstr "" + #: src/view/com/modals/VerifyEmail.tsx:105 msgid "Enter Confirmation Code" msgstr "確認コードを入力してください" @@ -1422,7 +1447,7 @@ msgstr "ユーザー名とパスワードを入力してください" msgid "Error receiving captcha response." msgstr "" -#: src/view/screens/Search/Search.tsx:109 +#: src/view/screens/Search/Search.tsx:110 msgid "Error:" msgstr "エラー:" @@ -1493,7 +1518,7 @@ msgstr "アプリパスワードの作成に失敗しました。" msgid "Failed to create the list. Check your internet connection and try again." msgstr "リストの作成に失敗しました。インターネットへの接続を確認の上、もう一度お試しください。" -#: src/view/com/util/forms/PostDropdownBtn.tsx:108 +#: src/view/com/util/forms/PostDropdownBtn.tsx:110 msgid "Failed to delete post, please try again" msgstr "投稿の削除に失敗しました。もう一度お試しください。" @@ -1515,8 +1540,8 @@ msgid "Feed offline" msgstr "フィードはオフラインです" #: src/view/com/feeds/FeedPage.tsx:143 -msgid "Feed Preferences" -msgstr "フィードの設定" +#~ msgid "Feed Preferences" +#~ msgstr "フィードの設定" #: src/view/shell/desktop/RightNav.tsx:61 #: src/view/shell/Drawer.tsx:311 @@ -1564,11 +1589,11 @@ msgstr "最後に" msgid "Find accounts to follow" msgstr "フォローするアカウントを探す" -#: src/view/screens/Search/Search.tsx:439 +#: src/view/screens/Search/Search.tsx:440 msgid "Find users on Bluesky" msgstr "Blueskyでユーザーを検索" -#: src/view/screens/Search/Search.tsx:437 +#: src/view/screens/Search/Search.tsx:438 msgid "Find users with the search tool on the right" msgstr "右側の検索ツールでユーザーを検索" @@ -1673,6 +1698,7 @@ msgid "Following {0}" msgstr "{0}をフォローしています" #: src/Navigation.tsx:248 +#: src/view/com/home/HomeHeaderLayout.web.tsx:45 #: src/view/com/home/HomeHeaderLayoutMobile.tsx:83 #: src/view/screens/PreferencesFollowingFeed.tsx:104 #: src/view/screens/Settings/index.tsx:543 @@ -1712,7 +1738,7 @@ msgstr "パスワードを忘れた" msgid "Forgot Password" msgstr "パスワードを忘れた" -#: src/view/com/posts/FeedItem.tsx:187 +#: src/view/com/posts/FeedItem.tsx:189 msgctxt "from-feed" msgid "From <0/>" msgstr "<0/>から" @@ -1745,7 +1771,7 @@ msgstr "戻る" msgid "Go back to previous step" msgstr "前のステップに戻る" -#: src/view/screens/Search/Search.tsx:724 +#: src/view/screens/Search/Search.tsx:747 #: src/view/shell/desktop/Search.tsx:262 msgid "Go to @{queryMaybeHandle}" msgstr "@{queryMaybeHandle}へ" @@ -1762,6 +1788,10 @@ msgstr "次へ" msgid "Handle" msgstr "ハンドル" +#: src/components/RichText.tsx:188 +msgid "Hashtag: {tag}" +msgstr "" + #: src/view/com/auth/create/CreateAccount.tsx:208 msgid "Having trouble?" msgstr "何か問題が発生しましたか?" @@ -1804,7 +1834,7 @@ msgctxt "action" msgid "Hide" msgstr "非表示" -#: src/view/com/util/forms/PostDropdownBtn.tsx:216 +#: src/view/com/util/forms/PostDropdownBtn.tsx:232 msgid "Hide post" msgstr "投稿を非表示" @@ -1813,7 +1843,7 @@ msgstr "投稿を非表示" msgid "Hide the content" msgstr "コンテンツを非表示" -#: src/view/com/util/forms/PostDropdownBtn.tsx:220 +#: src/view/com/util/forms/PostDropdownBtn.tsx:236 msgid "Hide this post?" msgstr "この投稿を非表示にしますか?" @@ -1975,7 +2005,7 @@ msgstr "あなたのパスワードを入力" msgid "Input your user handle" msgstr "あなたのユーザーハンドルを入力" -#: src/view/com/post-thread/PostThreadItem.tsx:224 +#: src/view/com/post-thread/PostThreadItem.tsx:226 msgid "Invalid or unsupported post record" msgstr "無効またはサポートされていない投稿のレコード" @@ -2077,7 +2107,7 @@ msgstr "詳細" msgid "Learn more about this warning" msgstr "この警告の詳細" -#: src/view/screens/Moderation.tsx:243 +#: src/view/screens/Moderation.tsx:262 msgid "Learn more about what is public on Bluesky." msgstr "Blueskyで公開されている内容はこちらを参照してください。" @@ -2161,7 +2191,7 @@ msgstr "あなたの投稿がいいねされました" msgid "Likes" msgstr "いいね" -#: src/view/com/post-thread/PostThreadItem.tsx:181 +#: src/view/com/post-thread/PostThreadItem.tsx:183 msgid "Likes on this post" msgstr "この投稿をいいねする" @@ -2222,7 +2252,7 @@ msgstr "投稿をさらにロード" msgid "Load new notifications" msgstr "最新の通知をロード" -#: src/view/com/feeds/FeedPage.tsx:181 +#: src/view/com/feeds/FeedPage.tsx:115 #: src/view/screens/Profile.tsx:440 #: src/view/screens/ProfileFeed.tsx:495 #: src/view/screens/ProfileList.tsx:681 @@ -2252,7 +2282,7 @@ msgstr "ログアウト" #~ msgid "Logged-out users" #~ msgstr "ログアウトしたユーザー" -#: src/view/screens/Moderation.tsx:136 +#: src/view/screens/Moderation.tsx:155 msgid "Logged-out visibility" msgstr "ログアウトしたユーザーからの可視性" @@ -2268,6 +2298,10 @@ msgstr "リストにないアカウントにログイン" msgid "Make sure this is where you intend to go!" msgstr "意図した場所であることを確認してください!" +#: src/components/dialogs/MutedWords.tsx:71 +msgid "Manage your muted words and tags" +msgstr "" + #: src/view/com/auth/create/Step2.tsx:118 msgid "May not be longer than 253 characters" msgstr "" @@ -2289,7 +2323,7 @@ msgid "Mentioned users" msgstr "メンションされたユーザー" #: src/view/com/util/ViewHeader.tsx:81 -#: src/view/screens/Search/Search.tsx:623 +#: src/view/screens/Search/Search.tsx:646 msgid "Menu" msgstr "メニュー" @@ -2302,7 +2336,7 @@ msgid "Message from server: {0}" msgstr "サーバーからのメッセージ:{0}" #: src/Navigation.tsx:115 -#: src/view/screens/Moderation.tsx:64 +#: src/view/screens/Moderation.tsx:66 #: src/view/screens/Settings/index.tsx:625 #: src/view/shell/desktop/LeftNav.tsx:397 #: src/view/shell/Drawer.tsx:511 @@ -2333,7 +2367,7 @@ msgstr "モデレーションリストを作成しました" msgid "Moderation list updated" msgstr "モデレーションリストを更新しました" -#: src/view/screens/Moderation.tsx:95 +#: src/view/screens/Moderation.tsx:114 msgid "Moderation lists" msgstr "モデレーションリスト" @@ -2360,7 +2394,7 @@ msgstr "その他のフィード" msgid "More options" msgstr "その他のオプション" -#: src/view/com/util/forms/PostDropdownBtn.tsx:299 +#: src/view/com/util/forms/PostDropdownBtn.tsx:315 msgid "More post options" msgstr "そのほかの投稿のオプション" @@ -2372,6 +2406,14 @@ msgstr "いいねの数が多い順に返信を表示" msgid "Must be at least 3 characters" msgstr "" +#: src/components/TagMenu/index.tsx:253 +msgid "Mute" +msgstr "" + +#: src/components/TagMenu/index.web.tsx:91 +msgid "Mute {truncatedTag}" +msgstr "" + #: src/view/com/profile/ProfileHeader.tsx:327 msgid "Mute Account" msgstr "アカウントをミュート" @@ -2380,6 +2422,18 @@ msgstr "アカウントをミュート" msgid "Mute accounts" msgstr "アカウントをミュート" +#: src/components/TagMenu/index.tsx:211 +msgid "Mute all {tag} posts" +msgstr "" + +#: src/components/dialogs/MutedWords.tsx:131 +msgid "Mute in tags only" +msgstr "" + +#: src/components/dialogs/MutedWords.tsx:116 +msgid "Mute in text & tags" +msgstr "" + #: src/view/screens/ProfileList.tsx:491 msgid "Mute list" msgstr "リストをミュート" @@ -2392,15 +2446,27 @@ msgstr "これらのアカウントをミュートしますか?" msgid "Mute this List" msgstr "このリストをミュート" -#: src/view/com/util/forms/PostDropdownBtn.tsx:200 +#: src/components/dialogs/MutedWords.tsx:109 +msgid "Mute this word in post text and tags" +msgstr "" + +#: src/components/dialogs/MutedWords.tsx:124 +msgid "Mute this word in tags only" +msgstr "" + +#: src/view/com/util/forms/PostDropdownBtn.tsx:202 msgid "Mute thread" msgstr "スレッドをミュート" +#: src/view/com/util/forms/PostDropdownBtn.tsx:216 +msgid "Mute words & tags" +msgstr "" + #: src/view/com/lists/ListCard.tsx:102 msgid "Muted" msgstr "ミュートされています" -#: src/view/screens/Moderation.tsx:109 +#: src/view/screens/Moderation.tsx:128 msgid "Muted accounts" msgstr "ミュート中のアカウント" @@ -2413,6 +2479,10 @@ msgstr "ミュート中のアカウント" msgid "Muted accounts have their posts removed from your feed and from your notifications. Mutes are completely private." msgstr "ミュート中のアカウントの投稿は、フィードや通知から取り除かれます。ミュートの設定は完全に非公開です。" +#: src/view/screens/Moderation.tsx:100 +msgid "Muted words & tags" +msgstr "" + #: src/view/screens/ProfileList.tsx:277 msgid "Muting is private. Muted accounts can interact with you, but you will not see their posts or receive notifications from them." msgstr "ミュートの設定は非公開です。ミュート中のアカウントはあなたと引き続き関わることができますが、そのアカウントの投稿や通知を受信することはできません。" @@ -2476,6 +2546,10 @@ msgstr "フォロワーやデータへのアクセスを失うことはありま msgid "Never lose access to your followers or data." msgstr "フォロワーやデータへのアクセスを失うことはありません。" +#: src/components/dialogs/MutedWords.tsx:244 +msgid "Nevermind" +msgstr "" + #: src/view/screens/Lists.tsx:76 msgctxt "action" msgid "New" @@ -2497,7 +2571,7 @@ msgstr "新しいパスワード" msgid "New Password" msgstr "新しいパスワード" -#: src/view/com/feeds/FeedPage.tsx:192 +#: src/view/com/feeds/FeedPage.tsx:126 msgctxt "action" msgid "New post" msgstr "新しい投稿" @@ -2586,8 +2660,8 @@ msgid "No results found for \"{query}\"" msgstr "「{query}」の検索結果はありません" #: src/view/com/modals/ListAddRemoveUsers.tsx:127 -#: src/view/screens/Search/Search.tsx:280 -#: src/view/screens/Search/Search.tsx:308 +#: src/view/screens/Search/Search.tsx:281 +#: src/view/screens/Search/Search.tsx:309 msgid "No results found for {query}" msgstr "「{query}」の検索結果はありません" @@ -2617,7 +2691,7 @@ msgstr "今はしない" #~ msgid "Note: Bluesky is an open and public network, and enabling this will not make your profile private or limit the ability of logged in users to see your posts. This setting only limits the visibility of posts on the Bluesky app and website; third-party apps that display Bluesky content may not respect this setting, and could show your content to logged-out users." #~ msgstr "注記:Blueskyはオープンでパブリックなネットワークであり、この設定を有効にしてもログインしているユーザーはあなたのプロフィールや投稿を制限なく閲覧できます。この設定はBlueskyのアプリおよびウェブサイト上のみでのあなたのコンテンツの可視性を制限するものです。Blueskyのコンテンツを表示するサードパーティーのアプリやウェブサイトなどはこの設定を尊重しない場合があり、ログアウトしたユーザーに対しあなたのコンテンツが表示される可能性があります。" -#: src/view/screens/Moderation.tsx:233 +#: src/view/screens/Moderation.tsx:252 msgid "Note: Bluesky is an open and public network. This setting only limits the visibility of your content on the Bluesky app and website, and other apps may not respect this setting. Your content may still be shown to logged-out users by other apps and websites." msgstr "注記:Blueskyはオープンでパブリックなネットワークです。この設定はBlueskyのアプリおよびウェブサイト上のみでのあなたのコンテンツの可視性を制限するものであり、他のアプリではこの設定を尊重しない場合があります。他のアプリやウェブサイトでは、ログアウトしたユーザーにあなたのコンテンツが表示される場合があります。" @@ -2655,7 +2729,7 @@ msgstr "古い順に返信を表示" msgid "Onboarding reset" msgstr "オンボーディングのリセット" -#: src/view/com/composer/Composer.tsx:375 +#: src/view/com/composer/Composer.tsx:382 msgid "One or more images is missing alt text." msgstr "1つもしくは複数の画像にALTテキストがありません。" @@ -2672,8 +2746,12 @@ msgstr "おっと!" msgid "Open" msgstr "開かれています" -#: src/view/com/composer/Composer.tsx:470 -#: src/view/com/composer/Composer.tsx:471 +#: src/view/screens/Moderation.tsx:75 +msgid "Open content filtering settings" +msgstr "" + +#: src/view/com/composer/Composer.tsx:477 +#: src/view/com/composer/Composer.tsx:478 msgid "Open emoji picker" msgstr "絵文字を入力" @@ -2681,6 +2759,10 @@ msgstr "絵文字を入力" msgid "Open links with in-app browser" msgstr "アプリ内ブラウザーでリンクを開く" +#: src/view/screens/Moderation.tsx:92 +msgid "Open muted words settings" +msgstr "" + #: src/view/com/home/HomeHeaderLayoutMobile.tsx:49 msgid "Open navigation" msgstr "ナビゲーションを開く" @@ -2757,6 +2839,7 @@ msgstr "モデレーションの設定を開く" msgid "Opens password reset form" msgstr "パスワードリセットのフォームを開く" +#: src/view/com/home/HomeHeaderLayout.web.tsx:60 #: src/view/screens/Feeds.tsx:356 msgid "Opens screen to edit Saved Feeds" msgstr "保存されたフィードの編集画面を開く" @@ -2941,7 +3024,7 @@ msgstr "このコンテンツに対する警告が誤って適用されたと思 msgid "Please Verify Your Email" msgstr "メールアドレスを確認してください" -#: src/view/com/composer/Composer.tsx:215 +#: src/view/com/composer/Composer.tsx:222 msgid "Please wait for your link card to finish loading" msgstr "リンクカードがロードされるまでお待ちください" @@ -2953,8 +3036,8 @@ msgstr "政治" msgid "Porn" msgstr "ポルノ" -#: src/view/com/composer/Composer.tsx:350 -#: src/view/com/composer/Composer.tsx:358 +#: src/view/com/composer/Composer.tsx:357 +#: src/view/com/composer/Composer.tsx:365 msgctxt "action" msgid "Post" msgstr "投稿" @@ -2970,7 +3053,7 @@ msgstr "投稿" #~ msgid "Post" #~ msgstr "投稿" -#: src/view/com/post-thread/PostThreadItem.tsx:173 +#: src/view/com/post-thread/PostThreadItem.tsx:175 msgid "Post by {0}" msgstr "{0}による投稿" @@ -2980,11 +3063,11 @@ msgstr "{0}による投稿" msgid "Post by @{0}" msgstr "@{0}による投稿" -#: src/view/com/util/forms/PostDropdownBtn.tsx:88 +#: src/view/com/util/forms/PostDropdownBtn.tsx:90 msgid "Post deleted" msgstr "投稿を削除" -#: src/view/com/post-thread/PostThread.tsx:461 +#: src/view/com/post-thread/PostThread.tsx:462 msgid "Post hidden" msgstr "投稿を非表示" @@ -2996,14 +3079,22 @@ msgstr "投稿の言語" msgid "Post Languages" msgstr "投稿の言語" -#: src/view/com/post-thread/PostThread.tsx:513 +#: src/view/com/post-thread/PostThread.tsx:514 msgid "Post not found" msgstr "投稿が見つかりません" +#: src/components/TagMenu/index.tsx:257 +msgid "posts" +msgstr "" + #: src/view/screens/Profile.tsx:180 msgid "Posts" msgstr "投稿" +#: src/components/dialogs/MutedWords.tsx:77 +msgid "Posts can be muted based on their text, their tags, or both." +msgstr "" + #: src/view/com/posts/FeedErrorMessage.tsx:64 msgid "Posts hidden" msgstr "非表示の投稿" @@ -3068,11 +3159,11 @@ msgstr "ユーザーを一括でミュートまたはブロックする、公開 msgid "Public, shareable lists which can drive feeds." msgstr "フィードとして利用できる、公開された共有可能なリスト。" -#: src/view/com/composer/Composer.tsx:335 +#: src/view/com/composer/Composer.tsx:342 msgid "Publish post" msgstr "投稿を公開" -#: src/view/com/composer/Composer.tsx:335 +#: src/view/com/composer/Composer.tsx:342 msgid "Publish reply" msgstr "返信を公開" @@ -3110,6 +3201,7 @@ msgstr "おすすめのフィード" msgid "Recommended Users" msgstr "おすすめのユーザー" +#: src/components/dialogs/MutedWords.tsx:249 #: src/view/com/modals/ListAddRemoveUsers.tsx:264 #: src/view/com/modals/SelfLabel.tsx:83 #: src/view/com/modals/UserAddRemoveLists.tsx:219 @@ -3147,6 +3239,10 @@ msgstr "イメージを削除" msgid "Remove image preview" msgstr "イメージプレビューを削除" +#: src/components/dialogs/MutedWords.tsx:294 +msgid "Remove mute word from your list" +msgstr "" + #: src/view/com/modals/Repost.tsx:47 msgid "Remove repost" msgstr "リポストを削除" @@ -3181,7 +3277,7 @@ msgstr "返信" msgid "Replies to this thread are disabled" msgstr "このスレッドへの返信はできません" -#: src/view/com/composer/Composer.tsx:348 +#: src/view/com/composer/Composer.tsx:355 msgctxt "action" msgid "Reply" msgstr "返信" @@ -3191,7 +3287,7 @@ msgid "Reply Filters" msgstr "返信のフィルター" #: src/view/com/post/Post.tsx:167 -#: src/view/com/posts/FeedItem.tsx:285 +#: src/view/com/posts/FeedItem.tsx:287 msgctxt "description" msgid "Reply to <0/>" msgstr "<0/>に返信" @@ -3213,7 +3309,7 @@ msgid "Report List" msgstr "リストを報告" #: src/view/com/modals/report/SendReportButton.tsx:37 -#: src/view/com/util/forms/PostDropdownBtn.tsx:239 +#: src/view/com/util/forms/PostDropdownBtn.tsx:255 msgid "Report post" msgstr "投稿を報告" @@ -3242,7 +3338,7 @@ msgstr "リポストまたは引用" msgid "Reposted By" msgstr "リポストしたユーザー" -#: src/view/com/posts/FeedItem.tsx:205 +#: src/view/com/posts/FeedItem.tsx:207 msgid "Reposted by {0}" msgstr "{0}にリポストされた" @@ -3250,7 +3346,7 @@ msgstr "{0}にリポストされた" #~ msgid "Reposted by {0})" #~ msgstr "{0}によるリポスト" -#: src/view/com/posts/FeedItem.tsx:222 +#: src/view/com/posts/FeedItem.tsx:224 msgid "Reposted by <0/>" msgstr "<0/>によるリポスト" @@ -3258,7 +3354,7 @@ msgstr "<0/>によるリポスト" msgid "reposted your post" msgstr "あなたの投稿はリポストされました" -#: src/view/com/post-thread/PostThreadItem.tsx:186 +#: src/view/com/post-thread/PostThreadItem.tsx:188 msgid "Reposts of this post" msgstr "この投稿をリポスト" @@ -3409,9 +3505,9 @@ msgstr "一番上までスクロール" #: src/view/com/modals/ListAddRemoveUsers.tsx:75 #: src/view/com/util/forms/SearchInput.tsx:67 #: src/view/com/util/forms/SearchInput.tsx:79 -#: src/view/screens/Search/Search.tsx:418 -#: src/view/screens/Search/Search.tsx:645 -#: src/view/screens/Search/Search.tsx:663 +#: src/view/screens/Search/Search.tsx:419 +#: src/view/screens/Search/Search.tsx:668 +#: src/view/screens/Search/Search.tsx:686 #: src/view/shell/bottom-bar/BottomBar.tsx:159 #: src/view/shell/desktop/LeftNav.tsx:324 #: src/view/shell/desktop/Search.tsx:214 @@ -3421,11 +3517,19 @@ msgstr "一番上までスクロール" msgid "Search" msgstr "検索" -#: src/view/screens/Search/Search.tsx:712 +#: src/view/screens/Search/Search.tsx:735 #: src/view/shell/desktop/Search.tsx:255 msgid "Search for \"{query}\"" msgstr "「{query}」を検索" +#: src/components/TagMenu/index.tsx:145 +msgid "Search for all posts by @{authorHandle} with tag {tag}" +msgstr "" + +#: src/components/TagMenu/index.tsx:90 +msgid "Search for all posts with tag {tag}" +msgstr "" + #: src/view/screens/Search/Search.tsx:390 #~ msgid "Search for posts and users." #~ msgstr "投稿とユーザーを検索します。" @@ -3440,6 +3544,22 @@ msgstr "ユーザーを検索" msgid "Security Step Required" msgstr "必要なセキュリティの手順" +#: src/components/TagMenu/index.web.tsx:50 +msgid "See {truncatedTag} posts" +msgstr "" + +#: src/components/TagMenu/index.web.tsx:67 +msgid "See {truncatedTag} posts by user" +msgstr "" + +#: src/components/TagMenu/index.tsx:128 +msgid "See <0>{tag} posts" +msgstr "" + +#: src/components/TagMenu/index.tsx:189 +msgid "See <0>{tag} posts by this user" +msgstr "" + #: src/view/screens/SavedFeeds.tsx:163 msgid "See this guide" msgstr "ガイドを見る" @@ -3657,7 +3777,7 @@ msgid "Share" msgstr "共有" #: src/view/com/profile/ProfileHeader.tsx:295 -#: src/view/com/util/forms/PostDropdownBtn.tsx:182 +#: src/view/com/util/forms/PostDropdownBtn.tsx:184 #: src/view/screens/ProfileList.tsx:418 msgid "Share" msgstr "共有" @@ -3690,9 +3810,9 @@ msgstr "{0}による埋め込みを表示" msgid "Show follows similar to {0}" msgstr "{0}に似たおすすめのフォロー候補を表示" -#: src/view/com/post-thread/PostThreadItem.tsx:532 -#: src/view/com/post/Post.tsx:196 -#: src/view/com/posts/FeedItem.tsx:359 +#: src/view/com/post-thread/PostThreadItem.tsx:538 +#: src/view/com/post/Post.tsx:198 +#: src/view/com/posts/FeedItem.tsx:363 msgid "Show More" msgstr "さらに表示" @@ -3860,7 +3980,7 @@ msgstr "ソフトウェア開発" msgid "Something went wrong. Check your email and try again." msgstr "なんらかの問題が発生しました。メールアドレスを確認し、もう一度お試しください。" -#: src/App.native.tsx:61 +#: src/App.native.tsx:63 msgid "Sorry! Your session expired. Please log in again." msgstr "申し訳ありません!セッションの有効期限が切れました。もう一度ログインしてください。" @@ -3926,7 +4046,7 @@ msgstr "このリストに登録" #~ msgid "Subscribed" #~ msgstr "登録済み" -#: src/view/screens/Search/Search.tsx:373 +#: src/view/screens/Search/Search.tsx:374 msgid "Suggested Follows" msgstr "おすすめのフォロー" @@ -3970,6 +4090,14 @@ msgstr "システム" msgid "System log" msgstr "システムログ" +#: src/components/dialogs/MutedWords.tsx:288 +msgid "tag" +msgstr "" + +#: src/components/TagMenu/index.tsx:74 +msgid "Tag menu: {tag}" +msgstr "" + #: src/view/com/modals/crop-image/CropImage.web.tsx:112 msgid "Tall" msgstr "トール" @@ -3993,6 +4121,10 @@ msgstr "条件" msgid "Terms of Service" msgstr "利用規約" +#: src/components/dialogs/MutedWords.tsx:288 +msgid "text" +msgstr "" + #: src/view/com/modals/AppealLabel.tsx:70 #: src/view/com/modals/report/InputIssueDetails.tsx:51 msgid "Text input field" @@ -4018,7 +4150,7 @@ msgstr "著作権ポリシーは<0/>に移動しました" msgid "The following steps will help customize your Bluesky experience." msgstr "次の手順であなたのBlueskyでの体験をカスタマイズできます。" -#: src/view/com/post-thread/PostThread.tsx:516 +#: src/view/com/post-thread/PostThread.tsx:517 msgid "The post may have been deleted." msgstr "投稿が削除された可能性があります。" @@ -4200,7 +4332,7 @@ msgstr "このリストは空です!" msgid "This name is already in use" msgstr "この名前はすでに使用中です" -#: src/view/com/post-thread/PostThreadItem.tsx:123 +#: src/view/com/post-thread/PostThreadItem.tsx:125 msgid "This post has been deleted." msgstr "この投稿は削除されました。" @@ -4224,7 +4356,11 @@ msgstr "このユーザーは、あなたがミュートした<0/>リストに msgid "This warning is only available for posts with media attached." msgstr "この警告は、メディアが添付されている投稿にのみ使用できます。" -#: src/view/com/util/forms/PostDropdownBtn.tsx:221 +#: src/components/dialogs/MutedWords.tsx:236 +msgid "This will delete {0} from your muted words. You can always add it back later." +msgstr "" + +#: src/view/com/util/forms/PostDropdownBtn.tsx:237 msgid "This will hide this post from your feeds." msgstr "この投稿をあなたのフィードにおいて非表示にします。" @@ -4241,6 +4377,10 @@ msgstr "スレッドモード" msgid "Threads Preferences" msgstr "スレッドの設定" +#: src/components/dialogs/MutedWords.tsx:95 +msgid "Toggle between muted word options." +msgstr "" + #: src/view/com/util/forms/DropdownButton.tsx:246 msgid "Toggle dropdown" msgstr "ドロップダウンをトグル" @@ -4249,9 +4389,9 @@ msgstr "ドロップダウンをトグル" msgid "Transformations" msgstr "変換" -#: src/view/com/post-thread/PostThreadItem.tsx:679 -#: src/view/com/post-thread/PostThreadItem.tsx:681 -#: src/view/com/util/forms/PostDropdownBtn.tsx:154 +#: src/view/com/post-thread/PostThreadItem.tsx:685 +#: src/view/com/post-thread/PostThreadItem.tsx:687 +#: src/view/com/util/forms/PostDropdownBtn.tsx:156 msgid "Translate" msgstr "翻訳" @@ -4320,15 +4460,24 @@ msgstr "残念ながら、アカウントを作成するための要件を満た msgid "Unlike" msgstr "いいねを外す" +#: src/components/TagMenu/index.tsx:253 #: src/view/screens/ProfileList.tsx:597 msgid "Unmute" msgstr "ミュートを解除" +#: src/components/TagMenu/index.web.tsx:90 +msgid "Unmute {truncatedTag}" +msgstr "" + #: src/view/com/profile/ProfileHeader.tsx:326 msgid "Unmute Account" msgstr "アカウントのミュートを解除" -#: src/view/com/util/forms/PostDropdownBtn.tsx:200 +#: src/components/TagMenu/index.tsx:210 +msgid "Unmute all {tag} posts" +msgstr "" + +#: src/view/com/util/forms/PostDropdownBtn.tsx:202 msgid "Unmute thread" msgstr "スレッドのミュートを解除" @@ -4533,6 +4682,10 @@ msgstr "あなたのフォロー中のユーザーの投稿を読み終わりま #~ msgid "We recommend \"For You\" by Skygaze:" #~ msgstr "Skygazeによる「For You」フィードがおすすめ:" +#: src/components/dialogs/MutedWords.tsx:161 +msgid "We recommend avoiding common words that appear in many posts, since it can result in no posts being shown." +msgstr "" + #: src/screens/Onboarding/StepAlgoFeeds/index.tsx:124 msgid "We recommend our \"Discover\" feed:" msgstr "我々の「Discover」フィードがおすすめ:" @@ -4561,7 +4714,11 @@ msgstr "私たちはあなたが参加してくれることをとても楽しみ msgid "We're sorry, but we were unable to resolve this list. If this persists, please contact the list creator, @{handleOrDid}." msgstr "大変申し訳ありませんが、このリストを解決できませんでした。それでもこの問題が解決しない場合は、作成者の@{handleOrDid}までお問い合わせください。" -#: src/view/screens/Search/Search.tsx:253 +#: src/components/dialogs/MutedWords.tsx:182 +msgid "We're sorry, but we weren't able to load your muted words at this time. Please try again." +msgstr "" + +#: src/view/screens/Search/Search.tsx:254 msgid "We're sorry, but your search could not be completed. Please try again in a few minutes." msgstr "大変申し訳ありませんが、検索を完了できませんでした。数分後に再試行してください。" @@ -4582,7 +4739,7 @@ msgid "What is the issue with this {collectionName}?" msgstr "この{collectionName}の問題は何ですか?" #: src/view/com/auth/SplashScreen.tsx:59 -#: src/view/com/composer/Composer.tsx:279 +#: src/view/com/composer/Composer.tsx:286 msgid "What's up?" msgstr "最近どう?" @@ -4603,11 +4760,11 @@ msgstr "返信できるユーザー" msgid "Wide" msgstr "ワイド" -#: src/view/com/composer/Composer.tsx:415 +#: src/view/com/composer/Composer.tsx:422 msgid "Write post" msgstr "投稿を書く" -#: src/view/com/composer/Composer.tsx:278 +#: src/view/com/composer/Composer.tsx:285 #: src/view/com/composer/Prompt.tsx:33 msgid "Write your reply" msgstr "返信を書く" @@ -4676,7 +4833,7 @@ msgstr "保存されたフィードがありません!" msgid "You don't have any saved feeds." msgstr "保存されたフィードがありません。" -#: src/view/com/post-thread/PostThread.tsx:464 +#: src/view/com/post-thread/PostThread.tsx:465 msgid "You have blocked the author or you have been blocked by the author." msgstr "あなたが投稿者をブロックしているか、または投稿者によってあなたはブロックされています。" @@ -4716,6 +4873,10 @@ msgstr "アプリパスワードはまだ作成されていません。下のボ msgid "You have not muted any accounts yet. To mute an account, go to their profile and selected \"Mute account\" from the menu on their account." msgstr "ミュートしているアカウントはまだありません。アカウントをミュートするには、プロフィールに移動し、アカウントメニューから「アカウントをミュート」を選択します。" +#: src/components/dialogs/MutedWords.tsx:202 +msgid "You haven't muted any words or tags yet" +msgstr "" + #: src/view/com/modals/ContentFilteringSettings.tsx:175 msgid "You must be 18 or older to enable adult content." msgstr "成人向けコンテンツを有効にするには、18歳以上である必要があります。" @@ -4724,11 +4885,11 @@ msgstr "成人向けコンテンツを有効にするには、18歳以上であ msgid "You must be 18 years or older to enable adult content" msgstr "成人向けコンテンツを有効にするには、18歳以上である必要があります。" -#: src/view/com/util/forms/PostDropdownBtn.tsx:127 +#: src/view/com/util/forms/PostDropdownBtn.tsx:129 msgid "You will no longer receive notifications for this thread" msgstr "これ以降、このスレッドに関する通知を受け取ることはできなくなります" -#: src/view/com/util/forms/PostDropdownBtn.tsx:130 +#: src/view/com/util/forms/PostDropdownBtn.tsx:132 msgid "You will now receive notifications for this thread" msgstr "これ以降、このスレッドに関する通知を受け取ることができます" @@ -4818,11 +4979,15 @@ msgstr "フルハンドルは<0>@{0}になります" #~ msgid "Your invite codes are hidden when logged in using an App Password" #~ msgstr "アプリパスワードを使用してログインすると、招待コードは非表示になります。" +#: src/components/dialogs/MutedWords.tsx:173 +msgid "Your muted words" +msgstr "" + #: src/view/com/modals/ChangePassword.tsx:155 msgid "Your password has been changed successfully!" msgstr "パスワードの変更が完了しました!" -#: src/view/com/composer/Composer.tsx:267 +#: src/view/com/composer/Composer.tsx:274 msgid "Your post has been published" msgstr "投稿を公開しました" @@ -4841,7 +5006,7 @@ msgstr "あなたのプロフィール" #~ msgid "Your profile and posts will not be visible to people visiting the Bluesky app or website without having an account and being logged in." #~ msgstr "あなたのプロフィールと投稿は、アカウントを持っておらずログインしていない状態でBlueskyのアプリまたはウェブサイトを訪問する人々には表示されません。" -#: src/view/com/composer/Composer.tsx:266 +#: src/view/com/composer/Composer.tsx:273 msgid "Your reply has been published" msgstr "返信を公開しました" diff --git a/src/locale/locales/ko/messages.po b/src/locale/locales/ko/messages.po index 7ef971ac..b70ba169 100644 --- a/src/locale/locales/ko/messages.po +++ b/src/locale/locales/ko/messages.po @@ -76,7 +76,7 @@ msgid "A new version of the app is available. Please update to continue using th msgstr "새 버전의 앱을 사용할 수 있습니다. 앱을 계속 사용하려면 업데이트하세요." #: src/view/com/util/ViewHeader.tsx:83 -#: src/view/screens/Search/Search.tsx:624 +#: src/view/screens/Search/Search.tsx:647 msgid "Access navigation links and settings" msgstr "탐색 링크 및 설정으로 이동합니다" @@ -127,6 +127,7 @@ msgstr "계정 차단 해제됨" msgid "Account unmuted" msgstr "계정 언뮤트됨" +#: src/components/dialogs/MutedWords.tsx:147 #: src/view/com/auth/onboarding/RecommendedFeedsItem.tsx:150 #: src/view/com/modals/ListAddRemoveUsers.tsx:264 #: src/view/com/modals/UserAddRemoveLists.tsx:219 @@ -168,14 +169,22 @@ msgstr "세부 정보 추가" msgid "Add details to report" msgstr "신고 세부 정보 추가" -#: src/view/com/composer/Composer.tsx:446 +#: src/view/com/composer/Composer.tsx:453 msgid "Add link card" msgstr "링크 카드 추가" -#: src/view/com/composer/Composer.tsx:451 +#: src/view/com/composer/Composer.tsx:458 msgid "Add link card:" msgstr "링크 카드 추가:" +#: src/components/dialogs/MutedWords.tsx:140 +msgid "Add mute word for configured settings" +msgstr "" + +#: src/components/dialogs/MutedWords.tsx:74 +msgid "Add muted words and tags" +msgstr "" + #: src/view/com/modals/ChangeHandle.tsx:417 msgid "Add the following DNS record to your domain:" msgstr "도메인에 다음 DNS 레코드를 추가하세요:" @@ -295,7 +304,7 @@ msgstr "앱 비밀번호 설정" msgid "App Passwords" msgstr "앱 비밀번호" -#: src/view/com/util/forms/PostDropdownBtn.tsx:279 +#: src/view/com/util/forms/PostDropdownBtn.tsx:295 msgid "Appeal content warning" msgstr "콘텐츠 경고 이의신청" @@ -319,15 +328,16 @@ msgstr "모양" msgid "Are you sure you want to delete the app password \"{name}\"?" msgstr "앱 비밀번호 \"{name}\"을(를) 삭제하시겠습니까?" -#: src/view/com/composer/Composer.tsx:143 +#: src/view/com/composer/Composer.tsx:150 msgid "Are you sure you'd like to discard this draft?" msgstr "이 초안을 삭제하시겠습니까?" +#: src/components/dialogs/MutedWords.tsx:233 #: src/view/screens/ProfileList.tsx:365 msgid "Are you sure?" msgstr "정말인가요?" -#: src/view/com/util/forms/PostDropdownBtn.tsx:262 +#: src/view/com/util/forms/PostDropdownBtn.tsx:278 msgid "Are you sure? This cannot be undone." msgstr "정말인가요? 되돌릴 수 없습니다." @@ -349,15 +359,15 @@ msgstr "선정적이지 않거나 예술적인 노출." #: src/view/com/auth/login/LoginForm.tsx:259 #: src/view/com/auth/login/SetNewPasswordForm.tsx:179 #: src/view/com/modals/report/InputIssueDetails.tsx:46 -#: src/view/com/post-thread/PostThread.tsx:471 -#: src/view/com/post-thread/PostThread.tsx:521 -#: src/view/com/post-thread/PostThread.tsx:529 +#: src/view/com/post-thread/PostThread.tsx:472 +#: src/view/com/post-thread/PostThread.tsx:522 +#: src/view/com/post-thread/PostThread.tsx:530 #: src/view/com/profile/ProfileHeader.tsx:649 #: src/view/com/util/ViewHeader.tsx:81 msgid "Back" msgstr "뒤로" -#: src/view/com/post-thread/PostThread.tsx:479 +#: src/view/com/post-thread/PostThread.tsx:480 msgctxt "action" msgid "Back" msgstr "뒤로" @@ -405,7 +415,7 @@ msgstr "이 리스트 차단" msgid "Blocked" msgstr "차단됨" -#: src/view/screens/Moderation.tsx:123 +#: src/view/screens/Moderation.tsx:142 msgid "Blocked accounts" msgstr "차단한 계정" @@ -464,7 +474,7 @@ msgstr "Bluesky는 공개적입니다." msgid "Bluesky uses invites to build a healthier community. If you don't know anybody with an invite, you can sign up for the waitlist and we'll send one soon." msgstr "Bluesky는 더 건강한 커뮤니티를 구축하기 위해 초대 방식을 사용합니다. 초대해 준 사람이 없는 경우 대기자 명단에 등록하면 곧 초대를 보내겠습니다." -#: src/view/screens/Moderation.tsx:226 +#: src/view/screens/Moderation.tsx:245 msgid "Bluesky will not show your profile and posts to logged-out users. Other apps may not honor this request. This does not make your account private." msgstr "로그아웃한 사용자에게 내 프로필과 게시물을 표시하지 않습니다. 다른 앱에서는 이 설정을 따르지 않을 수 있습니다. 내 계정을 비공개로 전환하지는 않습니다." @@ -516,8 +526,8 @@ msgid "Can only contain letters, numbers, spaces, dashes, and underscores. Must msgstr "글자, 숫자, 공백, 대시, 밑줄만 포함할 수 있습니다. 길이는 4자 이상이어야 하고 32자를 넘지 않아야 합니다." #: src/components/Prompt.tsx:91 -#: src/view/com/composer/Composer.tsx:300 -#: src/view/com/composer/Composer.tsx:305 +#: src/view/com/composer/Composer.tsx:307 +#: src/view/com/composer/Composer.tsx:312 #: src/view/com/modals/ChangeEmail.tsx:218 #: src/view/com/modals/ChangeEmail.tsx:220 #: src/view/com/modals/ChangePassword.tsx:265 @@ -531,7 +541,7 @@ msgstr "글자, 숫자, 공백, 대시, 밑줄만 포함할 수 있습니다. #: src/view/com/modals/VerifyEmail.tsx:247 #: src/view/com/modals/VerifyEmail.tsx:253 #: src/view/com/modals/Waitlist.tsx:142 -#: src/view/screens/Search/Search.tsx:693 +#: src/view/screens/Search/Search.tsx:716 #: src/view/shell/desktop/Search.tsx:238 msgid "Cancel" msgstr "취소" @@ -678,7 +688,7 @@ msgid "Clear all storage data (restart after this)" msgstr "모든 스토리지 데이터 지우기 (이후 다시 시작)" #: src/view/com/util/forms/SearchInput.tsx:88 -#: src/view/screens/Search/Search.tsx:674 +#: src/view/screens/Search/Search.tsx:697 msgid "Clear search query" msgstr "검색어 지우기" @@ -686,6 +696,11 @@ msgstr "검색어 지우기" msgid "click here" msgstr "이곳을 클릭" +#: src/components/RichText.tsx:189 +#: src/components/TagMenu/index.web.tsx:125 +msgid "Click here to open tag menu for {tag}" +msgstr "" + #: src/screens/Onboarding/index.tsx:35 msgid "Climate" msgstr "기후" @@ -716,11 +731,15 @@ msgstr "이미지 닫기" msgid "Close image viewer" msgstr "이미지 뷰어 닫기" -#: src/view/shell/index.web.tsx:49 +#: src/view/shell/index.web.tsx:51 msgid "Close navigation footer" msgstr "탐색 푸터 닫기" -#: src/view/shell/index.web.tsx:50 +#: src/components/TagMenu/index.tsx:266 +msgid "Close this dialog" +msgstr "" + +#: src/view/shell/index.web.tsx:52 msgid "Closes bottom navigation bar" msgstr "하단 탐색 막대를 닫습니다" @@ -728,7 +747,7 @@ msgstr "하단 탐색 막대를 닫습니다" msgid "Closes password update alert" msgstr "비밀번호 변경 알림을 닫습니다" -#: src/view/com/composer/Composer.tsx:302 +#: src/view/com/composer/Composer.tsx:309 msgid "Closes post composer and discards post draft" msgstr "게시물 작성 상자를 닫고 게시물 초안을 삭제합니다" @@ -761,7 +780,7 @@ msgstr "온보딩 완료 후 계정 사용 시작" msgid "Complete the challenge" msgstr "" -#: src/view/com/composer/Composer.tsx:417 +#: src/view/com/composer/Composer.tsx:424 msgid "Compose posts up to {MAX_GRAPHEME_LENGTH} characters in length" msgstr "최대 {MAX_GRAPHEME_LENGTH}자 길이까지 글을 작성할 수 있습니다" @@ -825,7 +844,7 @@ msgstr "연결 중…" msgid "Contact support" msgstr "지원에 연락하기" -#: src/view/screens/Moderation.tsx:81 +#: src/view/screens/Moderation.tsx:83 msgid "Content filtering" msgstr "콘텐츠 필터링" @@ -891,7 +910,7 @@ msgstr "빌드 버전 클립보드에 복사됨" #: src/view/com/modals/AddAppPasswords.tsx:76 #: src/view/com/modals/InviteCodes.tsx:152 -#: src/view/com/util/forms/PostDropdownBtn.tsx:141 +#: src/view/com/util/forms/PostDropdownBtn.tsx:143 msgid "Copied to clipboard" msgstr "클립보드에 복사됨" @@ -907,7 +926,7 @@ msgstr "복사" msgid "Copy link to list" msgstr "리스트 링크 복사" -#: src/view/com/util/forms/PostDropdownBtn.tsx:182 +#: src/view/com/util/forms/PostDropdownBtn.tsx:184 msgid "Copy link to post" msgstr "게시물 링크 복사" @@ -915,7 +934,7 @@ msgstr "게시물 링크 복사" msgid "Copy link to profile" msgstr "프로필 링크 복사" -#: src/view/com/util/forms/PostDropdownBtn.tsx:168 +#: src/view/com/util/forms/PostDropdownBtn.tsx:170 msgid "Copy post text" msgstr "게시물 텍스트 복사" @@ -971,7 +990,7 @@ msgstr "<0/> 님이 만듦" msgid "Created by you" msgstr "내가 만듦" -#: src/view/com/composer/Composer.tsx:448 +#: src/view/com/composer/Composer.tsx:455 msgid "Creates a card with a thumbnail. The card links to {url}" msgstr "미리보기 이미지가 있는 카드를 만듭니다. 카드가 {url}(으)로 연결됩니다" @@ -1048,11 +1067,11 @@ msgstr "내 계정 삭제" msgid "Delete My Account…" msgstr "" -#: src/view/com/util/forms/PostDropdownBtn.tsx:257 +#: src/view/com/util/forms/PostDropdownBtn.tsx:273 msgid "Delete post" msgstr "게시물 삭제" -#: src/view/com/util/forms/PostDropdownBtn.tsx:261 +#: src/view/com/util/forms/PostDropdownBtn.tsx:277 msgid "Delete this post?" msgstr "이 게시물을 삭제하시겠습니까?" @@ -1075,7 +1094,7 @@ msgstr "설명" #~ msgid "Developer Tools" #~ msgstr "개발자 도구" -#: src/view/com/composer/Composer.tsx:211 +#: src/view/com/composer/Composer.tsx:218 msgid "Did you want to say anything?" msgstr "하고 싶은 말이 있나요?" @@ -1083,15 +1102,15 @@ msgstr "하고 싶은 말이 있나요?" msgid "Dim" msgstr "" -#: src/view/com/composer/Composer.tsx:144 +#: src/view/com/composer/Composer.tsx:151 msgid "Discard" msgstr "삭제" -#: src/view/com/composer/Composer.tsx:138 +#: src/view/com/composer/Composer.tsx:145 msgid "Discard draft" msgstr "초안 삭제" -#: src/view/screens/Moderation.tsx:207 +#: src/view/screens/Moderation.tsx:226 msgid "Discourage apps from showing my account to logged-out users" msgstr "앱이 로그아웃한 사용자에게 내 계정을 표시하지 않도록 설정하기" @@ -1170,7 +1189,7 @@ msgstr "" msgid "Download CAR file" msgstr "" -#: src/view/com/composer/text-input/TextInput.web.tsx:247 +#: src/view/com/composer/text-input/TextInput.web.tsx:249 msgid "Drop to add images" msgstr "드롭하여 이미지 추가" @@ -1242,6 +1261,7 @@ msgstr "프로필 편집" msgid "Edit Profile" msgstr "프로필 편집" +#: src/view/com/home/HomeHeaderLayout.web.tsx:59 #: src/view/screens/Feeds.tsx:355 msgid "Edit Saved Feeds" msgstr "저장된 피드 편집" @@ -1324,6 +1344,11 @@ msgstr "피드 끝" msgid "Enter a name for this App Password" msgstr "이 앱 비밀번호의 이름을 입력하세요" +#: src/components/dialogs/MutedWords.tsx:87 +#: src/components/dialogs/MutedWords.tsx:88 +msgid "Enter a word or tag" +msgstr "" + #: src/view/com/modals/VerifyEmail.tsx:105 msgid "Enter Confirmation Code" msgstr "확인 코드 입력" @@ -1373,7 +1398,7 @@ msgstr "사용자 이름 및 비밀번호 입력" msgid "Error receiving captcha response." msgstr "" -#: src/view/screens/Search/Search.tsx:109 +#: src/view/screens/Search/Search.tsx:110 msgid "Error:" msgstr "오류:" @@ -1444,7 +1469,7 @@ msgstr "앱 비밀번호를 만들지 못했습니다." msgid "Failed to create the list. Check your internet connection and try again." msgstr "리스트를 만들지 못했습니다. 인터넷 연결을 확인한 후 다시 시도하세요." -#: src/view/com/util/forms/PostDropdownBtn.tsx:108 +#: src/view/com/util/forms/PostDropdownBtn.tsx:110 msgid "Failed to delete post, please try again" msgstr "게시물을 삭제하지 못했습니다. 다시 시도해 주세요" @@ -1466,8 +1491,8 @@ msgid "Feed offline" msgstr "피드 오프라인" #: src/view/com/feeds/FeedPage.tsx:143 -msgid "Feed Preferences" -msgstr "피드 설정" +#~ msgid "Feed Preferences" +#~ msgstr "피드 설정" #: src/view/shell/desktop/RightNav.tsx:61 #: src/view/shell/Drawer.tsx:311 @@ -1507,11 +1532,11 @@ msgstr "마무리 중" msgid "Find accounts to follow" msgstr "팔로우할 계정 찾아보기" -#: src/view/screens/Search/Search.tsx:439 +#: src/view/screens/Search/Search.tsx:440 msgid "Find users on Bluesky" msgstr "Bluesky에서 사용자 찾기" -#: src/view/screens/Search/Search.tsx:437 +#: src/view/screens/Search/Search.tsx:438 msgid "Find users with the search tool on the right" msgstr "오른쪽의 검색 도구로 사용자 찾기" @@ -1608,6 +1633,7 @@ msgid "Following {0}" msgstr "{0} 팔로우 중" #: src/Navigation.tsx:248 +#: src/view/com/home/HomeHeaderLayout.web.tsx:45 #: src/view/com/home/HomeHeaderLayoutMobile.tsx:83 #: src/view/screens/PreferencesFollowingFeed.tsx:104 #: src/view/screens/Settings/index.tsx:543 @@ -1647,7 +1673,7 @@ msgstr "비밀번호 분실" msgid "Forgot Password" msgstr "비밀번호 분실" -#: src/view/com/posts/FeedItem.tsx:187 +#: src/view/com/posts/FeedItem.tsx:189 msgctxt "from-feed" msgid "From <0/>" msgstr "<0/>에서" @@ -1680,7 +1706,7 @@ msgstr "뒤로" msgid "Go back to previous step" msgstr "이전 단계로 돌아가기" -#: src/view/screens/Search/Search.tsx:724 +#: src/view/screens/Search/Search.tsx:747 #: src/view/shell/desktop/Search.tsx:262 msgid "Go to @{queryMaybeHandle}" msgstr "@{queryMaybeHandle}(으)로 이동" @@ -1697,6 +1723,10 @@ msgstr "다음" msgid "Handle" msgstr "핸들" +#: src/components/RichText.tsx:188 +msgid "Hashtag: {tag}" +msgstr "" + #: src/view/com/auth/create/CreateAccount.tsx:208 msgid "Having trouble?" msgstr "문제가 있나요?" @@ -1735,7 +1765,7 @@ msgctxt "action" msgid "Hide" msgstr "숨기기" -#: src/view/com/util/forms/PostDropdownBtn.tsx:216 +#: src/view/com/util/forms/PostDropdownBtn.tsx:232 msgid "Hide post" msgstr "게시물 숨기기" @@ -1744,7 +1774,7 @@ msgstr "게시물 숨기기" msgid "Hide the content" msgstr "콘텐츠 숨기기" -#: src/view/com/util/forms/PostDropdownBtn.tsx:220 +#: src/view/com/util/forms/PostDropdownBtn.tsx:236 msgid "Hide this post?" msgstr "이 게시물을 숨기시겠습니까?" @@ -1893,7 +1923,7 @@ msgstr "비밀번호를 입력합니다" msgid "Input your user handle" msgstr "사용자 핸들을 입력합니다" -#: src/view/com/post-thread/PostThreadItem.tsx:224 +#: src/view/com/post-thread/PostThreadItem.tsx:226 msgid "Invalid or unsupported post record" msgstr "유효하지 않거나 지원되지 않는 게시물 기록" @@ -1995,7 +2025,7 @@ msgstr "더 알아보기" msgid "Learn more about this warning" msgstr "이 경고에 대해 더 알아보기" -#: src/view/screens/Moderation.tsx:243 +#: src/view/screens/Moderation.tsx:262 msgid "Learn more about what is public on Bluesky." msgstr "Bluesky에서 공개되는 항목에 대해 자세히 알아보세요." @@ -2071,7 +2101,7 @@ msgstr "님이 내 게시물을 좋아합니다" msgid "Likes" msgstr "좋아요" -#: src/view/com/post-thread/PostThreadItem.tsx:181 +#: src/view/com/post-thread/PostThreadItem.tsx:183 msgid "Likes on this post" msgstr "이 게시물을 좋아요 표시합니다" @@ -2128,7 +2158,7 @@ msgstr "더 많은 게시물 불러오기" msgid "Load new notifications" msgstr "새 알림 불러오기" -#: src/view/com/feeds/FeedPage.tsx:181 +#: src/view/com/feeds/FeedPage.tsx:115 #: src/view/screens/Profile.tsx:440 #: src/view/screens/ProfileFeed.tsx:495 #: src/view/screens/ProfileList.tsx:681 @@ -2154,7 +2184,7 @@ msgstr "로그" msgid "Log out" msgstr "로그아웃" -#: src/view/screens/Moderation.tsx:136 +#: src/view/screens/Moderation.tsx:155 msgid "Logged-out visibility" msgstr "로그아웃 표시" @@ -2166,6 +2196,10 @@ msgstr "목록에 없는 계정으로 로그인" msgid "Make sure this is where you intend to go!" msgstr "이곳이 당신이 가고자 하는 곳인지 확인하세요!" +#: src/components/dialogs/MutedWords.tsx:71 +msgid "Manage your muted words and tags" +msgstr "" + #: src/view/com/auth/create/Step2.tsx:118 msgid "May not be longer than 253 characters" msgstr "" @@ -2187,7 +2221,7 @@ msgid "Mentioned users" msgstr "멘션한 사용자" #: src/view/com/util/ViewHeader.tsx:81 -#: src/view/screens/Search/Search.tsx:623 +#: src/view/screens/Search/Search.tsx:646 msgid "Menu" msgstr "메뉴" @@ -2196,7 +2230,7 @@ msgid "Message from server: {0}" msgstr "서버에서 보낸 메시지: {0}" #: src/Navigation.tsx:115 -#: src/view/screens/Moderation.tsx:64 +#: src/view/screens/Moderation.tsx:66 #: src/view/screens/Settings/index.tsx:625 #: src/view/shell/desktop/LeftNav.tsx:397 #: src/view/shell/Drawer.tsx:511 @@ -2227,7 +2261,7 @@ msgstr "검토 리스트 생성됨" msgid "Moderation list updated" msgstr "검토 리스트 업데이트됨" -#: src/view/screens/Moderation.tsx:95 +#: src/view/screens/Moderation.tsx:114 msgid "Moderation lists" msgstr "검토 리스트" @@ -2254,7 +2288,7 @@ msgstr "피드 더 보기" msgid "More options" msgstr "옵션 더 보기" -#: src/view/com/util/forms/PostDropdownBtn.tsx:299 +#: src/view/com/util/forms/PostDropdownBtn.tsx:315 msgid "More post options" msgstr "게시물 옵션 더 보기" @@ -2266,6 +2300,14 @@ msgstr "좋아요 많은 순" msgid "Must be at least 3 characters" msgstr "" +#: src/components/TagMenu/index.tsx:253 +msgid "Mute" +msgstr "" + +#: src/components/TagMenu/index.web.tsx:91 +msgid "Mute {truncatedTag}" +msgstr "" + #: src/view/com/profile/ProfileHeader.tsx:327 msgid "Mute Account" msgstr "계정 뮤트" @@ -2274,6 +2316,18 @@ msgstr "계정 뮤트" msgid "Mute accounts" msgstr "계정 뮤트" +#: src/components/TagMenu/index.tsx:211 +msgid "Mute all {tag} posts" +msgstr "" + +#: src/components/dialogs/MutedWords.tsx:131 +msgid "Mute in tags only" +msgstr "" + +#: src/components/dialogs/MutedWords.tsx:116 +msgid "Mute in text & tags" +msgstr "" + #: src/view/screens/ProfileList.tsx:491 msgid "Mute list" msgstr "리스트 뮤트" @@ -2286,15 +2340,27 @@ msgstr "이 계정들을 뮤트하시겠습니까?" msgid "Mute this List" msgstr "이 리스트 뮤트" -#: src/view/com/util/forms/PostDropdownBtn.tsx:200 +#: src/components/dialogs/MutedWords.tsx:109 +msgid "Mute this word in post text and tags" +msgstr "" + +#: src/components/dialogs/MutedWords.tsx:124 +msgid "Mute this word in tags only" +msgstr "" + +#: src/view/com/util/forms/PostDropdownBtn.tsx:202 msgid "Mute thread" msgstr "스레드 뮤트" +#: src/view/com/util/forms/PostDropdownBtn.tsx:216 +msgid "Mute words & tags" +msgstr "" + #: src/view/com/lists/ListCard.tsx:102 msgid "Muted" msgstr "뮤트됨" -#: src/view/screens/Moderation.tsx:109 +#: src/view/screens/Moderation.tsx:128 msgid "Muted accounts" msgstr "뮤트한 계정" @@ -2307,6 +2373,10 @@ msgstr "뮤트한 계정" msgid "Muted accounts have their posts removed from your feed and from your notifications. Mutes are completely private." msgstr "계정을 뮤트하면 피드와 알림에서 해당 계정의 게시물이 사라집니다. 뮤트 목록은 완전히 비공개로 유지됩니다." +#: src/view/screens/Moderation.tsx:100 +msgid "Muted words & tags" +msgstr "" + #: src/view/screens/ProfileList.tsx:277 msgid "Muting is private. Muted accounts can interact with you, but you will not see their posts or receive notifications from them." msgstr "뮤트 목록은 비공개입니다. 뮤트한 계정은 나와 상호작용할 수 있지만 해당 계정의 게시물을 보거나 해당 계정으로부터 알림을 받을 수 없습니다." @@ -2370,6 +2440,10 @@ msgstr "팔로워와 데이터에 대한 접근 권한을 잃지 않습니다." msgid "Never lose access to your followers or data." msgstr "팔로워 또는 데이터에 대한 접근 권한을 잃지 않습니다." +#: src/components/dialogs/MutedWords.tsx:244 +msgid "Nevermind" +msgstr "" + #: src/view/screens/Lists.tsx:76 msgctxt "action" msgid "New" @@ -2391,7 +2465,7 @@ msgstr "새 비밀번호" msgid "New Password" msgstr "" -#: src/view/com/feeds/FeedPage.tsx:192 +#: src/view/com/feeds/FeedPage.tsx:126 msgctxt "action" msgid "New post" msgstr "새 게시물" @@ -2476,8 +2550,8 @@ msgid "No results found for \"{query}\"" msgstr "\"{query}\"에 대한 결과를 찾을 수 없습니다" #: src/view/com/modals/ListAddRemoveUsers.tsx:127 -#: src/view/screens/Search/Search.tsx:280 -#: src/view/screens/Search/Search.tsx:308 +#: src/view/screens/Search/Search.tsx:281 +#: src/view/screens/Search/Search.tsx:309 msgid "No results found for {query}" msgstr "{query}에 대한 결과를 찾을 수 없습니다" @@ -2503,7 +2577,7 @@ msgstr "찾을 수 없음" msgid "Not right now" msgstr "나중에 하기" -#: src/view/screens/Moderation.tsx:233 +#: src/view/screens/Moderation.tsx:252 msgid "Note: Bluesky is an open and public network. This setting only limits the visibility of your content on the Bluesky app and website, and other apps may not respect this setting. Your content may still be shown to logged-out users by other apps and websites." msgstr "참고: Bluesky는 개방형 공개 네트워크입니다. 이 설정은 Bluesky 앱과 웹사이트에서만 내 콘텐츠가 표시되는 것을 제한하며, 다른 앱에서는 이 설정을 준수하지 않을 수 있습니다. 다른 앱과 웹사이트에서는 로그아웃한 사용자에게 내 콘텐츠가 계속 표시될 수 있습니다." @@ -2541,7 +2615,7 @@ msgstr "오래된 순" msgid "Onboarding reset" msgstr "온보딩 재설정" -#: src/view/com/composer/Composer.tsx:375 +#: src/view/com/composer/Composer.tsx:382 msgid "One or more images is missing alt text." msgstr "하나 이상의 이미지에 대체 텍스트가 누락되었습니다." @@ -2558,8 +2632,12 @@ msgstr "이런!" msgid "Open" msgstr "공개성" -#: src/view/com/composer/Composer.tsx:470 -#: src/view/com/composer/Composer.tsx:471 +#: src/view/screens/Moderation.tsx:75 +msgid "Open content filtering settings" +msgstr "" + +#: src/view/com/composer/Composer.tsx:477 +#: src/view/com/composer/Composer.tsx:478 msgid "Open emoji picker" msgstr "이모티콘 선택기 열기" @@ -2567,6 +2645,10 @@ msgstr "이모티콘 선택기 열기" msgid "Open links with in-app browser" msgstr "링크를 인앱 브라우저로 엽니다" +#: src/view/screens/Moderation.tsx:92 +msgid "Open muted words settings" +msgstr "" + #: src/view/com/home/HomeHeaderLayoutMobile.tsx:49 msgid "Open navigation" msgstr "내비게이션 열기" @@ -2643,6 +2725,7 @@ msgstr "검토 설정을 엽니다" msgid "Opens password reset form" msgstr "비밀번호 재설정 양식을 엽니다" +#: src/view/com/home/HomeHeaderLayout.web.tsx:60 #: src/view/screens/Feeds.tsx:356 msgid "Opens screen to edit Saved Feeds" msgstr "저장된 피드를 편집할 수 있는 화면을 엽니다" @@ -2818,7 +2901,7 @@ msgstr "이 콘텐츠 경고가 잘못 적용되었다고 생각하는 이유를 msgid "Please Verify Your Email" msgstr "이메일 인증하기" -#: src/view/com/composer/Composer.tsx:215 +#: src/view/com/composer/Composer.tsx:222 msgid "Please wait for your link card to finish loading" msgstr "링크 카드를 완전히 불러올 때까지 기다려주세요" @@ -2830,8 +2913,8 @@ msgstr "정치" msgid "Porn" msgstr "포르노" -#: src/view/com/composer/Composer.tsx:350 -#: src/view/com/composer/Composer.tsx:358 +#: src/view/com/composer/Composer.tsx:357 +#: src/view/com/composer/Composer.tsx:365 msgctxt "action" msgid "Post" msgstr "게시하기" @@ -2841,7 +2924,7 @@ msgctxt "description" msgid "Post" msgstr "게시물" -#: src/view/com/post-thread/PostThreadItem.tsx:173 +#: src/view/com/post-thread/PostThreadItem.tsx:175 msgid "Post by {0}" msgstr "{0} 님의 게시물" @@ -2851,11 +2934,11 @@ msgstr "{0} 님의 게시물" msgid "Post by @{0}" msgstr "@{0} 님의 게시물" -#: src/view/com/util/forms/PostDropdownBtn.tsx:88 +#: src/view/com/util/forms/PostDropdownBtn.tsx:90 msgid "Post deleted" msgstr "게시물 삭제됨" -#: src/view/com/post-thread/PostThread.tsx:461 +#: src/view/com/post-thread/PostThread.tsx:462 msgid "Post hidden" msgstr "게시물 숨김" @@ -2867,14 +2950,22 @@ msgstr "게시물 언어" msgid "Post Languages" msgstr "게시물 언어" -#: src/view/com/post-thread/PostThread.tsx:513 +#: src/view/com/post-thread/PostThread.tsx:514 msgid "Post not found" msgstr "게시물을 찾을 수 없음" +#: src/components/TagMenu/index.tsx:257 +msgid "posts" +msgstr "" + #: src/view/screens/Profile.tsx:180 msgid "Posts" msgstr "게시물" +#: src/components/dialogs/MutedWords.tsx:77 +msgid "Posts can be muted based on their text, their tags, or both." +msgstr "" + #: src/view/com/posts/FeedErrorMessage.tsx:64 msgid "Posts hidden" msgstr "게시물 숨겨짐" @@ -2939,11 +3030,11 @@ msgstr "일괄 뮤트하거나 차단할 수 있는 공개적이고 공유 가 msgid "Public, shareable lists which can drive feeds." msgstr "피드를 탐색할 수 있는 공개적이고 공유 가능한 목록입니다." -#: src/view/com/composer/Composer.tsx:335 +#: src/view/com/composer/Composer.tsx:342 msgid "Publish post" msgstr "게시물 게시하기" -#: src/view/com/composer/Composer.tsx:335 +#: src/view/com/composer/Composer.tsx:342 msgid "Publish reply" msgstr "답글 게시하기" @@ -2977,6 +3068,7 @@ msgstr "추천 피드" msgid "Recommended Users" msgstr "추천 사용자" +#: src/components/dialogs/MutedWords.tsx:249 #: src/view/com/modals/ListAddRemoveUsers.tsx:264 #: src/view/com/modals/SelfLabel.tsx:83 #: src/view/com/modals/UserAddRemoveLists.tsx:219 @@ -3014,6 +3106,10 @@ msgstr "이미지 제거" msgid "Remove image preview" msgstr "이미지 미리보기 제거" +#: src/components/dialogs/MutedWords.tsx:294 +msgid "Remove mute word from your list" +msgstr "" + #: src/view/com/modals/Repost.tsx:47 msgid "Remove repost" msgstr "재게시를 취소합니다" @@ -3048,7 +3144,7 @@ msgstr "답글" msgid "Replies to this thread are disabled" msgstr "이 스레드에 대한 답글이 비활성화됩니다." -#: src/view/com/composer/Composer.tsx:348 +#: src/view/com/composer/Composer.tsx:355 msgctxt "action" msgid "Reply" msgstr "답글" @@ -3058,7 +3154,7 @@ msgid "Reply Filters" msgstr "답글 필터" #: src/view/com/post/Post.tsx:167 -#: src/view/com/posts/FeedItem.tsx:285 +#: src/view/com/posts/FeedItem.tsx:287 msgctxt "description" msgid "Reply to <0/>" msgstr "<0/> 님에게 보내는 답글" @@ -3080,7 +3176,7 @@ msgid "Report List" msgstr "리스트 신고" #: src/view/com/modals/report/SendReportButton.tsx:37 -#: src/view/com/util/forms/PostDropdownBtn.tsx:239 +#: src/view/com/util/forms/PostDropdownBtn.tsx:255 msgid "Report post" msgstr "게시물 신고" @@ -3105,11 +3201,11 @@ msgstr "재게시 또는 게시물 인용" msgid "Reposted By" msgstr "재게시한 사용자" -#: src/view/com/posts/FeedItem.tsx:205 +#: src/view/com/posts/FeedItem.tsx:207 msgid "Reposted by {0}" msgstr "{0} 님이 재게시함" -#: src/view/com/posts/FeedItem.tsx:222 +#: src/view/com/posts/FeedItem.tsx:224 msgid "Reposted by <0/>" msgstr "<0/> 님이 재게시함" @@ -3117,7 +3213,7 @@ msgstr "<0/> 님이 재게시함" msgid "reposted your post" msgstr "님이 내 게시물을 재게시했습니다" -#: src/view/com/post-thread/PostThreadItem.tsx:186 +#: src/view/com/post-thread/PostThreadItem.tsx:188 msgid "Reposts of this post" msgstr "이 게시물의 재게시" @@ -3268,9 +3364,9 @@ msgstr "맨 위로 스크롤" #: src/view/com/modals/ListAddRemoveUsers.tsx:75 #: src/view/com/util/forms/SearchInput.tsx:67 #: src/view/com/util/forms/SearchInput.tsx:79 -#: src/view/screens/Search/Search.tsx:418 -#: src/view/screens/Search/Search.tsx:645 -#: src/view/screens/Search/Search.tsx:663 +#: src/view/screens/Search/Search.tsx:419 +#: src/view/screens/Search/Search.tsx:668 +#: src/view/screens/Search/Search.tsx:686 #: src/view/shell/bottom-bar/BottomBar.tsx:159 #: src/view/shell/desktop/LeftNav.tsx:324 #: src/view/shell/desktop/Search.tsx:214 @@ -3280,11 +3376,19 @@ msgstr "맨 위로 스크롤" msgid "Search" msgstr "검색" -#: src/view/screens/Search/Search.tsx:712 +#: src/view/screens/Search/Search.tsx:735 #: src/view/shell/desktop/Search.tsx:255 msgid "Search for \"{query}\"" msgstr "\"{query}\"에 대한 검색 결과" +#: src/components/TagMenu/index.tsx:145 +msgid "Search for all posts by @{authorHandle} with tag {tag}" +msgstr "" + +#: src/components/TagMenu/index.tsx:90 +msgid "Search for all posts with tag {tag}" +msgstr "" + #: src/view/com/auth/LoggedOut.tsx:104 #: src/view/com/auth/LoggedOut.tsx:105 #: src/view/com/modals/ListAddRemoveUsers.tsx:70 @@ -3295,6 +3399,22 @@ msgstr "사용자 검색하기" msgid "Security Step Required" msgstr "보안 단계 필요" +#: src/components/TagMenu/index.web.tsx:50 +msgid "See {truncatedTag} posts" +msgstr "" + +#: src/components/TagMenu/index.web.tsx:67 +msgid "See {truncatedTag} posts by user" +msgstr "" + +#: src/components/TagMenu/index.tsx:128 +msgid "See <0>{tag} posts" +msgstr "" + +#: src/components/TagMenu/index.tsx:189 +msgid "See <0>{tag} posts by this user" +msgstr "" + #: src/view/screens/SavedFeeds.tsx:163 msgid "See this guide" msgstr "이 가이드" @@ -3500,7 +3620,7 @@ msgid "Share" msgstr "공유" #: src/view/com/profile/ProfileHeader.tsx:295 -#: src/view/com/util/forms/PostDropdownBtn.tsx:182 +#: src/view/com/util/forms/PostDropdownBtn.tsx:184 #: src/view/screens/ProfileList.tsx:418 msgid "Share" msgstr "공유" @@ -3533,9 +3653,9 @@ msgstr "{0} 임베드 표시" msgid "Show follows similar to {0}" msgstr "{0} 님과 비슷한 팔로우 표시" -#: src/view/com/post-thread/PostThreadItem.tsx:532 -#: src/view/com/post/Post.tsx:196 -#: src/view/com/posts/FeedItem.tsx:359 +#: src/view/com/post-thread/PostThreadItem.tsx:538 +#: src/view/com/post/Post.tsx:198 +#: src/view/com/posts/FeedItem.tsx:363 msgid "Show More" msgstr "더 보기" @@ -3703,7 +3823,7 @@ msgstr "소프트웨어 개발" msgid "Something went wrong. Check your email and try again." msgstr "문제가 발생했습니다. 이메일을 확인한 후 다시 시도하세요." -#: src/App.native.tsx:61 +#: src/App.native.tsx:63 msgid "Sorry! Your session expired. Please log in again." msgstr "죄송합니다. 세션이 만료되었습니다. 다시 로그인해 주세요." @@ -3761,7 +3881,7 @@ msgstr "{0} 피드 구독하기" msgid "Subscribe to this list" msgstr "이 리스트 구독하기" -#: src/view/screens/Search/Search.tsx:373 +#: src/view/screens/Search/Search.tsx:374 msgid "Suggested Follows" msgstr "팔로우 추천" @@ -3805,6 +3925,14 @@ msgstr "시스템" msgid "System log" msgstr "시스템 로그" +#: src/components/dialogs/MutedWords.tsx:288 +msgid "tag" +msgstr "" + +#: src/components/TagMenu/index.tsx:74 +msgid "Tag menu: {tag}" +msgstr "" + #: src/view/com/modals/crop-image/CropImage.web.tsx:112 msgid "Tall" msgstr "세로" @@ -3828,6 +3956,10 @@ msgstr "이용약관" msgid "Terms of Service" msgstr "서비스 이용약관" +#: src/components/dialogs/MutedWords.tsx:288 +msgid "text" +msgstr "" + #: src/view/com/modals/AppealLabel.tsx:70 #: src/view/com/modals/report/InputIssueDetails.tsx:51 msgid "Text input field" @@ -3853,7 +3985,7 @@ msgstr "저작권 정책을 <0/>(으)로 이동했습니다" msgid "The following steps will help customize your Bluesky experience." msgstr "다음 단계는 Bluesky 환경을 맞춤 설정하는 데 도움이 됩니다." -#: src/view/com/post-thread/PostThread.tsx:516 +#: src/view/com/post-thread/PostThread.tsx:517 msgid "The post may have been deleted." msgstr "게시물이 삭제되었을 수 있습니다." @@ -4019,7 +4151,7 @@ msgstr "이 리스트는 비어 있습니다." msgid "This name is already in use" msgstr "이 이름은 이미 사용 중입니다" -#: src/view/com/post-thread/PostThreadItem.tsx:123 +#: src/view/com/post-thread/PostThreadItem.tsx:125 msgid "This post has been deleted." msgstr "이 게시물은 삭제되었습니다." @@ -4043,7 +4175,11 @@ msgstr "" msgid "This warning is only available for posts with media attached." msgstr "이 경고는 미디어가 첨부된 게시물에만 사용할 수 있습니다." -#: src/view/com/util/forms/PostDropdownBtn.tsx:221 +#: src/components/dialogs/MutedWords.tsx:236 +msgid "This will delete {0} from your muted words. You can always add it back later." +msgstr "" + +#: src/view/com/util/forms/PostDropdownBtn.tsx:237 msgid "This will hide this post from your feeds." msgstr "피드에서 이 게시물을 숨깁니다." @@ -4060,6 +4196,10 @@ msgstr "스레드 모드" msgid "Threads Preferences" msgstr "스레드 설정" +#: src/components/dialogs/MutedWords.tsx:95 +msgid "Toggle between muted word options." +msgstr "" + #: src/view/com/util/forms/DropdownButton.tsx:246 msgid "Toggle dropdown" msgstr "드롭다운 열기 및 닫기" @@ -4068,9 +4208,9 @@ msgstr "드롭다운 열기 및 닫기" msgid "Transformations" msgstr "변형" -#: src/view/com/post-thread/PostThreadItem.tsx:679 -#: src/view/com/post-thread/PostThreadItem.tsx:681 -#: src/view/com/util/forms/PostDropdownBtn.tsx:154 +#: src/view/com/post-thread/PostThreadItem.tsx:685 +#: src/view/com/post-thread/PostThreadItem.tsx:687 +#: src/view/com/util/forms/PostDropdownBtn.tsx:156 msgid "Translate" msgstr "번역" @@ -4135,15 +4275,24 @@ msgstr "아쉽지만 계정을 만들 수 있는 요건을 충족하지 못했 msgid "Unlike" msgstr "좋아요 취소" +#: src/components/TagMenu/index.tsx:253 #: src/view/screens/ProfileList.tsx:597 msgid "Unmute" msgstr "언뮤트" +#: src/components/TagMenu/index.web.tsx:90 +msgid "Unmute {truncatedTag}" +msgstr "" + #: src/view/com/profile/ProfileHeader.tsx:326 msgid "Unmute Account" msgstr "계정 언뮤트" -#: src/view/com/util/forms/PostDropdownBtn.tsx:200 +#: src/components/TagMenu/index.tsx:210 +msgid "Unmute all {tag} posts" +msgstr "" + +#: src/view/com/util/forms/PostDropdownBtn.tsx:202 msgid "Unmute thread" msgstr "스레드 언뮤트" @@ -4340,6 +4489,10 @@ msgstr "즐거운 시간 되시기 바랍니다. Bluesky의 다음 특징을 기 msgid "We ran out of posts from your follows. Here's the latest from <0/>." msgstr "팔로우한 사용자의 게시물이 부족합니다. 대신 <0/>의 최신 게시물을 표시합니다." +#: src/components/dialogs/MutedWords.tsx:161 +msgid "We recommend avoiding common words that appear in many posts, since it can result in no posts being shown." +msgstr "" + #: src/screens/Onboarding/StepAlgoFeeds/index.tsx:124 msgid "We recommend our \"Discover\" feed:" msgstr "\"Discover\" 피드를 권장합니다:" @@ -4368,7 +4521,11 @@ msgstr "당신과 함께하게 되어 정말 기쁘네요!" msgid "We're sorry, but we were unable to resolve this list. If this persists, please contact the list creator, @{handleOrDid}." msgstr "죄송하지만 이 리스트를 불러올 수 없습니다. 이 문제가 계속되면 리스트 작성자인 @{handleOrDid}에게 문의하세요." -#: src/view/screens/Search/Search.tsx:253 +#: src/components/dialogs/MutedWords.tsx:182 +msgid "We're sorry, but we weren't able to load your muted words at this time. Please try again." +msgstr "" + +#: src/view/screens/Search/Search.tsx:254 msgid "We're sorry, but your search could not be completed. Please try again in a few minutes." msgstr "죄송하지만 검색을 완료할 수 없습니다. 몇 분 후에 다시 시도해 주세요." @@ -4389,7 +4546,7 @@ msgid "What is the issue with this {collectionName}?" msgstr "이 {collectionName}에 어떤 문제가 있나요?" #: src/view/com/auth/SplashScreen.tsx:59 -#: src/view/com/composer/Composer.tsx:279 +#: src/view/com/composer/Composer.tsx:286 msgid "What's up?" msgstr "무슨 일이 일어나고 있나요?" @@ -4410,11 +4567,11 @@ msgstr "답글을 달 수 있는 사람" msgid "Wide" msgstr "가로" -#: src/view/com/composer/Composer.tsx:415 +#: src/view/com/composer/Composer.tsx:422 msgid "Write post" msgstr "게시물 작성" -#: src/view/com/composer/Composer.tsx:278 +#: src/view/com/composer/Composer.tsx:285 #: src/view/com/composer/Prompt.tsx:33 msgid "Write your reply" msgstr "답글 작성하기" @@ -4471,7 +4628,7 @@ msgstr "저장된 피드가 없습니다!" msgid "You don't have any saved feeds." msgstr "저장된 피드가 없습니다." -#: src/view/com/post-thread/PostThread.tsx:464 +#: src/view/com/post-thread/PostThread.tsx:465 msgid "You have blocked the author or you have been blocked by the author." msgstr "작성자를 차단했거나 작성자가 나를 차단했습니다." @@ -4511,6 +4668,10 @@ msgstr "아직 앱 비밀번호를 생성하지 않았습니다. 아래 버튼 msgid "You have not muted any accounts yet. To mute an account, go to their profile and selected \"Mute account\" from the menu on their account." msgstr "아직 어떤 계정도 뮤트하지 않았습니다. 계정을 뮤트하려면 해당 계정의 프로필로 이동하여 계정 메뉴에서 \"계정 뮤트\"를 선택하세요." +#: src/components/dialogs/MutedWords.tsx:202 +msgid "You haven't muted any words or tags yet" +msgstr "" + #: src/view/com/modals/ContentFilteringSettings.tsx:175 msgid "You must be 18 or older to enable adult content." msgstr "성인 콘텐츠를 활성화하려면 18세 이상이어야 합니다." @@ -4519,11 +4680,11 @@ msgstr "성인 콘텐츠를 활성화하려면 18세 이상이어야 합니다." msgid "You must be 18 years or older to enable adult content" msgstr "성인 콘텐츠를 사용하려면 만 18세 이상이어야 합니다." -#: src/view/com/util/forms/PostDropdownBtn.tsx:127 +#: src/view/com/util/forms/PostDropdownBtn.tsx:129 msgid "You will no longer receive notifications for this thread" msgstr "이 스레드에 대한 알림을 더 이상 받지 않습니다" -#: src/view/com/util/forms/PostDropdownBtn.tsx:130 +#: src/view/com/util/forms/PostDropdownBtn.tsx:132 msgid "You will now receive notifications for this thread" msgstr "이제 이 스레드에 대한 알림을 받습니다" @@ -4609,11 +4770,15 @@ msgstr "내 전체 핸들: <0>@{0}" #~ msgid "Your invite codes are hidden when logged in using an App Password" #~ msgstr "앱 비밀번호를 사용하여 로그인하면 초대 코드가 숨겨집니다" +#: src/components/dialogs/MutedWords.tsx:173 +msgid "Your muted words" +msgstr "" + #: src/view/com/modals/ChangePassword.tsx:155 msgid "Your password has been changed successfully!" msgstr "" -#: src/view/com/composer/Composer.tsx:267 +#: src/view/com/composer/Composer.tsx:274 msgid "Your post has been published" msgstr "게시물을 게시했습니다" @@ -4628,7 +4793,7 @@ msgstr "게시물, 좋아요, 차단 목록은 공개됩니다. 뮤트 목록은 msgid "Your profile" msgstr "내 프로필" -#: src/view/com/composer/Composer.tsx:266 +#: src/view/com/composer/Composer.tsx:273 msgid "Your reply has been published" msgstr "내 답글을 게시했습니다" diff --git a/src/locale/locales/pt-BR/messages.po b/src/locale/locales/pt-BR/messages.po index 9178214d..ff5d7e55 100644 --- a/src/locale/locales/pt-BR/messages.po +++ b/src/locale/locales/pt-BR/messages.po @@ -76,7 +76,7 @@ msgid "A new version of the app is available. Please update to continue using th msgstr "Uma nova versão do aplicativo está disponível. Por favor, atualize para continuar usando o aplicativo." #: src/view/com/util/ViewHeader.tsx:83 -#: src/view/screens/Search/Search.tsx:624 +#: src/view/screens/Search/Search.tsx:647 msgid "Access navigation links and settings" msgstr "Acessar links de navegação e configurações" @@ -127,6 +127,7 @@ msgstr "Conta desbloqueada" msgid "Account unmuted" msgstr "Conta dessilenciada" +#: src/components/dialogs/MutedWords.tsx:147 #: src/view/com/auth/onboarding/RecommendedFeedsItem.tsx:150 #: src/view/com/modals/ListAddRemoveUsers.tsx:264 #: src/view/com/modals/UserAddRemoveLists.tsx:219 @@ -168,14 +169,22 @@ msgstr "Adicionar detalhes" msgid "Add details to report" msgstr "Adicionar detalhes à denúncia" -#: src/view/com/composer/Composer.tsx:446 +#: src/view/com/composer/Composer.tsx:453 msgid "Add link card" msgstr "Adicionar prévia de link" -#: src/view/com/composer/Composer.tsx:451 +#: src/view/com/composer/Composer.tsx:458 msgid "Add link card:" msgstr "Adicionar prévia de link:" +#: src/components/dialogs/MutedWords.tsx:140 +msgid "Add mute word for configured settings" +msgstr "" + +#: src/components/dialogs/MutedWords.tsx:74 +msgid "Add muted words and tags" +msgstr "" + #: src/view/com/modals/ChangeHandle.tsx:417 msgid "Add the following DNS record to your domain:" msgstr "Adicione o seguinte registro DNS ao seu domínio:" @@ -299,7 +308,7 @@ msgstr "Configurações de Senha de Aplicativo" msgid "App Passwords" msgstr "Senhas de Aplicativos" -#: src/view/com/util/forms/PostDropdownBtn.tsx:279 +#: src/view/com/util/forms/PostDropdownBtn.tsx:295 msgid "Appeal content warning" msgstr "Contestar aviso de conteúdo" @@ -323,15 +332,16 @@ msgstr "Aparência" msgid "Are you sure you want to delete the app password \"{name}\"?" msgstr "Tem certeza de que deseja excluir a senha do aplicativo \"{name}\"?" -#: src/view/com/composer/Composer.tsx:143 +#: src/view/com/composer/Composer.tsx:150 msgid "Are you sure you'd like to discard this draft?" msgstr "Tem certeza que deseja descartar este rascunho?" +#: src/components/dialogs/MutedWords.tsx:233 #: src/view/screens/ProfileList.tsx:365 msgid "Are you sure?" msgstr "Tem certeza?" -#: src/view/com/util/forms/PostDropdownBtn.tsx:262 +#: src/view/com/util/forms/PostDropdownBtn.tsx:278 msgid "Are you sure? This cannot be undone." msgstr "Tem certeza? Esta ação não poderá ser desfeita." @@ -353,15 +363,15 @@ msgstr "Nudez artística ou não erótica." #: src/view/com/auth/login/LoginForm.tsx:259 #: src/view/com/auth/login/SetNewPasswordForm.tsx:179 #: src/view/com/modals/report/InputIssueDetails.tsx:46 -#: src/view/com/post-thread/PostThread.tsx:471 -#: src/view/com/post-thread/PostThread.tsx:521 -#: src/view/com/post-thread/PostThread.tsx:529 +#: src/view/com/post-thread/PostThread.tsx:472 +#: src/view/com/post-thread/PostThread.tsx:522 +#: src/view/com/post-thread/PostThread.tsx:530 #: src/view/com/profile/ProfileHeader.tsx:649 #: src/view/com/util/ViewHeader.tsx:81 msgid "Back" msgstr "Voltar" -#: src/view/com/post-thread/PostThread.tsx:479 +#: src/view/com/post-thread/PostThread.tsx:480 msgctxt "action" msgid "Back" msgstr "Voltar" @@ -409,7 +419,7 @@ msgstr "Bloquear esta Lista" msgid "Blocked" msgstr "Bloqueado" -#: src/view/screens/Moderation.tsx:123 +#: src/view/screens/Moderation.tsx:142 msgid "Blocked accounts" msgstr "Contas bloqueadas" @@ -468,7 +478,7 @@ msgstr "Bluesky é público." msgid "Bluesky uses invites to build a healthier community. If you don't know anybody with an invite, you can sign up for the waitlist and we'll send one soon." msgstr "O Bluesky usa convites para criar uma comunidade mais saudável. Se você não conhece ninguém que tenha um convite, inscreva-se na lista de espera e em breve enviaremos um para você." -#: src/view/screens/Moderation.tsx:226 +#: src/view/screens/Moderation.tsx:245 msgid "Bluesky will not show your profile and posts to logged-out users. Other apps may not honor this request. This does not make your account private." msgstr "O Bluesky não mostrará seu perfil e publicações para usuários desconectados. Outros aplicativos podem não honrar esta solicitação. Isso não torna a sua conta privada." @@ -520,8 +530,8 @@ msgid "Can only contain letters, numbers, spaces, dashes, and underscores. Must msgstr "Só pode conter letras, números, espaços, traços e sublinhados. Deve ter pelo menos 4 caracteres, mas não mais de 32 caracteres." #: src/components/Prompt.tsx:91 -#: src/view/com/composer/Composer.tsx:300 -#: src/view/com/composer/Composer.tsx:305 +#: src/view/com/composer/Composer.tsx:307 +#: src/view/com/composer/Composer.tsx:312 #: src/view/com/modals/ChangeEmail.tsx:218 #: src/view/com/modals/ChangeEmail.tsx:220 #: src/view/com/modals/ChangePassword.tsx:265 @@ -535,7 +545,7 @@ msgstr "Só pode conter letras, números, espaços, traços e sublinhados. Deve #: src/view/com/modals/VerifyEmail.tsx:247 #: src/view/com/modals/VerifyEmail.tsx:253 #: src/view/com/modals/Waitlist.tsx:142 -#: src/view/screens/Search/Search.tsx:693 +#: src/view/screens/Search/Search.tsx:716 #: src/view/shell/desktop/Search.tsx:238 msgid "Cancel" msgstr "Cancelar" @@ -686,7 +696,7 @@ msgid "Clear all storage data (restart after this)" msgstr "Limpar todos os dados de armazenamento (reinicie em seguida)" #: src/view/com/util/forms/SearchInput.tsx:88 -#: src/view/screens/Search/Search.tsx:674 +#: src/view/screens/Search/Search.tsx:697 msgid "Clear search query" msgstr "Limpar busca" @@ -694,6 +704,11 @@ msgstr "Limpar busca" msgid "click here" msgstr "clique aqui" +#: src/components/RichText.tsx:189 +#: src/components/TagMenu/index.web.tsx:125 +msgid "Click here to open tag menu for {tag}" +msgstr "" + #: src/screens/Onboarding/index.tsx:35 msgid "Climate" msgstr "Clima e tempo" @@ -724,11 +739,15 @@ msgstr "Fechar imagem" msgid "Close image viewer" msgstr "Fechar visualizador de imagens" -#: src/view/shell/index.web.tsx:49 +#: src/view/shell/index.web.tsx:51 msgid "Close navigation footer" msgstr "Fechar o painel de navegação" -#: src/view/shell/index.web.tsx:50 +#: src/components/TagMenu/index.tsx:266 +msgid "Close this dialog" +msgstr "" + +#: src/view/shell/index.web.tsx:52 msgid "Closes bottom navigation bar" msgstr "Fecha barra de navegação inferior" @@ -736,7 +755,7 @@ msgstr "Fecha barra de navegação inferior" msgid "Closes password update alert" msgstr "Fecha alerta de troca de senha" -#: src/view/com/composer/Composer.tsx:302 +#: src/view/com/composer/Composer.tsx:309 msgid "Closes post composer and discards post draft" msgstr "Fecha o editor de post e descarta o rascunho" @@ -769,7 +788,7 @@ msgstr "Completar e começar a usar sua conta" msgid "Complete the challenge" msgstr "" -#: src/view/com/composer/Composer.tsx:417 +#: src/view/com/composer/Composer.tsx:424 msgid "Compose posts up to {MAX_GRAPHEME_LENGTH} characters in length" msgstr "Escreva posts de até {MAX_GRAPHEME_LENGTH} caracteres" @@ -833,7 +852,7 @@ msgstr "Conectando..." msgid "Contact support" msgstr "Contatar suporte" -#: src/view/screens/Moderation.tsx:81 +#: src/view/screens/Moderation.tsx:83 msgid "Content filtering" msgstr "Filtragem do conteúdo" @@ -899,7 +918,7 @@ msgstr "Versão do aplicativo copiada" #: src/view/com/modals/AddAppPasswords.tsx:76 #: src/view/com/modals/InviteCodes.tsx:152 -#: src/view/com/util/forms/PostDropdownBtn.tsx:141 +#: src/view/com/util/forms/PostDropdownBtn.tsx:143 msgid "Copied to clipboard" msgstr "Copiado" @@ -915,7 +934,7 @@ msgstr "Copiar" msgid "Copy link to list" msgstr "Copiar link da lista" -#: src/view/com/util/forms/PostDropdownBtn.tsx:182 +#: src/view/com/util/forms/PostDropdownBtn.tsx:184 msgid "Copy link to post" msgstr "Copiar link do post" @@ -923,7 +942,7 @@ msgstr "Copiar link do post" msgid "Copy link to profile" msgstr "Copiar link do perfil" -#: src/view/com/util/forms/PostDropdownBtn.tsx:168 +#: src/view/com/util/forms/PostDropdownBtn.tsx:170 msgid "Copy post text" msgstr "Copiar texto do post" @@ -979,7 +998,7 @@ msgstr "Criado por <0/>" msgid "Created by you" msgstr "Criado por você" -#: src/view/com/composer/Composer.tsx:448 +#: src/view/com/composer/Composer.tsx:455 msgid "Creates a card with a thumbnail. The card links to {url}" msgstr "Cria uma prévia com miniatura. A prévia faz um link para {url}" @@ -1056,11 +1075,11 @@ msgstr "Excluir minha conta" msgid "Delete My Account…" msgstr "Excluir minha conta…" -#: src/view/com/util/forms/PostDropdownBtn.tsx:257 +#: src/view/com/util/forms/PostDropdownBtn.tsx:273 msgid "Delete post" msgstr "Excluir post" -#: src/view/com/util/forms/PostDropdownBtn.tsx:261 +#: src/view/com/util/forms/PostDropdownBtn.tsx:277 msgid "Delete this post?" msgstr "Excluir este post?" @@ -1083,7 +1102,7 @@ msgstr "Descrição" #~ msgid "Developer Tools" #~ msgstr "Ferramentas de Desenvolvedor" -#: src/view/com/composer/Composer.tsx:211 +#: src/view/com/composer/Composer.tsx:218 msgid "Did you want to say anything?" msgstr "Você gostaria de dizer alguma coisa?" @@ -1091,15 +1110,15 @@ msgstr "Você gostaria de dizer alguma coisa?" msgid "Dim" msgstr "Menos escuro" -#: src/view/com/composer/Composer.tsx:144 +#: src/view/com/composer/Composer.tsx:151 msgid "Discard" msgstr "Descartar" -#: src/view/com/composer/Composer.tsx:138 +#: src/view/com/composer/Composer.tsx:145 msgid "Discard draft" msgstr "Descartar rascunho" -#: src/view/screens/Moderation.tsx:207 +#: src/view/screens/Moderation.tsx:226 msgid "Discourage apps from showing my account to logged-out users" msgstr "Desencorajar aplicativos a mostrar minha conta para usuários deslogados" @@ -1178,7 +1197,7 @@ msgstr "" msgid "Download CAR file" msgstr "" -#: src/view/com/composer/text-input/TextInput.web.tsx:247 +#: src/view/com/composer/text-input/TextInput.web.tsx:249 msgid "Drop to add images" msgstr "Solte para adicionar imagens" @@ -1250,6 +1269,7 @@ msgstr "Editar perfil" msgid "Edit Profile" msgstr "Editar Perfil" +#: src/view/com/home/HomeHeaderLayout.web.tsx:59 #: src/view/screens/Feeds.tsx:355 msgid "Edit Saved Feeds" msgstr "Editar Feeds Salvos" @@ -1332,6 +1352,11 @@ msgstr "Fim do feed" msgid "Enter a name for this App Password" msgstr "Insira um nome para esta Senha de Aplicativo" +#: src/components/dialogs/MutedWords.tsx:87 +#: src/components/dialogs/MutedWords.tsx:88 +msgid "Enter a word or tag" +msgstr "" + #: src/view/com/modals/VerifyEmail.tsx:105 msgid "Enter Confirmation Code" msgstr "Insira o código de confirmação" @@ -1381,7 +1406,7 @@ msgstr "Digite seu nome de usuário e senha" msgid "Error receiving captcha response." msgstr "" -#: src/view/screens/Search/Search.tsx:109 +#: src/view/screens/Search/Search.tsx:110 msgid "Error:" msgstr "Erro:" @@ -1452,7 +1477,7 @@ msgstr "Não foi possível criar senha de aplicativo." msgid "Failed to create the list. Check your internet connection and try again." msgstr "Não foi possível criar a lista. Por favor tente novamente." -#: src/view/com/util/forms/PostDropdownBtn.tsx:108 +#: src/view/com/util/forms/PostDropdownBtn.tsx:110 msgid "Failed to delete post, please try again" msgstr "Não foi possível excluir o post, por favor tente novamente." @@ -1474,8 +1499,8 @@ msgid "Feed offline" msgstr "Feed offline" #: src/view/com/feeds/FeedPage.tsx:143 -msgid "Feed Preferences" -msgstr "Preferências de Feeds" +#~ msgid "Feed Preferences" +#~ msgstr "Preferências de Feeds" #: src/view/shell/desktop/RightNav.tsx:61 #: src/view/shell/Drawer.tsx:311 @@ -1523,11 +1548,11 @@ msgstr "Finalizando" msgid "Find accounts to follow" msgstr "Encontre contas para seguir" -#: src/view/screens/Search/Search.tsx:439 +#: src/view/screens/Search/Search.tsx:440 msgid "Find users on Bluesky" msgstr "Encontrar usuários no Bluesky" -#: src/view/screens/Search/Search.tsx:437 +#: src/view/screens/Search/Search.tsx:438 msgid "Find users with the search tool on the right" msgstr "Encontre usuários com a ferramenta de busca à direita" @@ -1624,6 +1649,7 @@ msgid "Following {0}" msgstr "Seguindo {0}" #: src/Navigation.tsx:248 +#: src/view/com/home/HomeHeaderLayout.web.tsx:45 #: src/view/com/home/HomeHeaderLayoutMobile.tsx:83 #: src/view/screens/PreferencesFollowingFeed.tsx:104 #: src/view/screens/Settings/index.tsx:543 @@ -1663,7 +1689,7 @@ msgstr "Esqueci a senha" msgid "Forgot Password" msgstr "Esqueci a Senha" -#: src/view/com/posts/FeedItem.tsx:187 +#: src/view/com/posts/FeedItem.tsx:189 msgctxt "from-feed" msgid "From <0/>" msgstr "Por <0/>" @@ -1696,7 +1722,7 @@ msgstr "Voltar" msgid "Go back to previous step" msgstr "Voltar para o passo anterior" -#: src/view/screens/Search/Search.tsx:724 +#: src/view/screens/Search/Search.tsx:747 #: src/view/shell/desktop/Search.tsx:262 msgid "Go to @{queryMaybeHandle}" msgstr "Ir para @{queryMaybleHandle}" @@ -1713,6 +1739,10 @@ msgstr "Próximo" msgid "Handle" msgstr "Usuário" +#: src/components/RichText.tsx:188 +msgid "Hashtag: {tag}" +msgstr "" + #: src/view/com/auth/create/CreateAccount.tsx:208 msgid "Having trouble?" msgstr "Precisa de ajuda?" @@ -1751,7 +1781,7 @@ msgctxt "action" msgid "Hide" msgstr "Esconder" -#: src/view/com/util/forms/PostDropdownBtn.tsx:216 +#: src/view/com/util/forms/PostDropdownBtn.tsx:232 msgid "Hide post" msgstr "Ocultar post" @@ -1760,7 +1790,7 @@ msgstr "Ocultar post" msgid "Hide the content" msgstr "Esconder o conteúdo" -#: src/view/com/util/forms/PostDropdownBtn.tsx:220 +#: src/view/com/util/forms/PostDropdownBtn.tsx:236 msgid "Hide this post?" msgstr "Ocultar este post?" @@ -1909,7 +1939,7 @@ msgstr "Insira sua senha" msgid "Input your user handle" msgstr "Insira o usuário" -#: src/view/com/post-thread/PostThreadItem.tsx:224 +#: src/view/com/post-thread/PostThreadItem.tsx:226 msgid "Invalid or unsupported post record" msgstr "Post inválido" @@ -2011,7 +2041,7 @@ msgstr "Saiba Mais" msgid "Learn more about this warning" msgstr "Saiba mais sobre este aviso" -#: src/view/screens/Moderation.tsx:243 +#: src/view/screens/Moderation.tsx:262 msgid "Learn more about what is public on Bluesky." msgstr "Saiba mais sobre o que é público no Bluesky." @@ -2087,7 +2117,7 @@ msgstr "curtiu seu post" msgid "Likes" msgstr "Curtidas" -#: src/view/com/post-thread/PostThreadItem.tsx:181 +#: src/view/com/post-thread/PostThreadItem.tsx:183 msgid "Likes on this post" msgstr "Curtidas neste post" @@ -2144,7 +2174,7 @@ msgstr "Carregar mais posts" msgid "Load new notifications" msgstr "Carregar novas notificações" -#: src/view/com/feeds/FeedPage.tsx:181 +#: src/view/com/feeds/FeedPage.tsx:115 #: src/view/screens/Profile.tsx:440 #: src/view/screens/ProfileFeed.tsx:495 #: src/view/screens/ProfileList.tsx:681 @@ -2170,7 +2200,7 @@ msgstr "Registros" msgid "Log out" msgstr "Sair" -#: src/view/screens/Moderation.tsx:136 +#: src/view/screens/Moderation.tsx:155 msgid "Logged-out visibility" msgstr "Visibilidade do seu perfil" @@ -2182,6 +2212,10 @@ msgstr "Fazer login em uma conta que não está listada" msgid "Make sure this is where you intend to go!" msgstr "Certifique-se de onde está indo!" +#: src/components/dialogs/MutedWords.tsx:71 +msgid "Manage your muted words and tags" +msgstr "" + #: src/view/com/auth/create/Step2.tsx:118 msgid "May not be longer than 253 characters" msgstr "" @@ -2203,7 +2237,7 @@ msgid "Mentioned users" msgstr "Usuários mencionados" #: src/view/com/util/ViewHeader.tsx:81 -#: src/view/screens/Search/Search.tsx:623 +#: src/view/screens/Search/Search.tsx:646 msgid "Menu" msgstr "Menu" @@ -2212,7 +2246,7 @@ msgid "Message from server: {0}" msgstr "Mensagem do servidor: {0}" #: src/Navigation.tsx:115 -#: src/view/screens/Moderation.tsx:64 +#: src/view/screens/Moderation.tsx:66 #: src/view/screens/Settings/index.tsx:625 #: src/view/shell/desktop/LeftNav.tsx:397 #: src/view/shell/Drawer.tsx:511 @@ -2243,7 +2277,7 @@ msgstr "Lista de moderação criada" msgid "Moderation list updated" msgstr "Lista de moderação criada" -#: src/view/screens/Moderation.tsx:95 +#: src/view/screens/Moderation.tsx:114 msgid "Moderation lists" msgstr "Listas de moderação" @@ -2270,7 +2304,7 @@ msgstr "Mais feeds" msgid "More options" msgstr "Mais opções" -#: src/view/com/util/forms/PostDropdownBtn.tsx:299 +#: src/view/com/util/forms/PostDropdownBtn.tsx:315 msgid "More post options" msgstr "Mais opções do post" @@ -2282,6 +2316,14 @@ msgstr "Respostas mais curtidas primeiro" msgid "Must be at least 3 characters" msgstr "" +#: src/components/TagMenu/index.tsx:253 +msgid "Mute" +msgstr "" + +#: src/components/TagMenu/index.web.tsx:91 +msgid "Mute {truncatedTag}" +msgstr "" + #: src/view/com/profile/ProfileHeader.tsx:327 msgid "Mute Account" msgstr "Silenciar Conta" @@ -2290,6 +2332,18 @@ msgstr "Silenciar Conta" msgid "Mute accounts" msgstr "Silenciar contas" +#: src/components/TagMenu/index.tsx:211 +msgid "Mute all {tag} posts" +msgstr "" + +#: src/components/dialogs/MutedWords.tsx:131 +msgid "Mute in tags only" +msgstr "" + +#: src/components/dialogs/MutedWords.tsx:116 +msgid "Mute in text & tags" +msgstr "" + #: src/view/screens/ProfileList.tsx:491 msgid "Mute list" msgstr "Lista de moderação" @@ -2302,15 +2356,27 @@ msgstr "Silenciar estas contas?" msgid "Mute this List" msgstr "Silenciar esta lista" -#: src/view/com/util/forms/PostDropdownBtn.tsx:200 +#: src/components/dialogs/MutedWords.tsx:109 +msgid "Mute this word in post text and tags" +msgstr "" + +#: src/components/dialogs/MutedWords.tsx:124 +msgid "Mute this word in tags only" +msgstr "" + +#: src/view/com/util/forms/PostDropdownBtn.tsx:202 msgid "Mute thread" msgstr "Silenciar thread" +#: src/view/com/util/forms/PostDropdownBtn.tsx:216 +msgid "Mute words & tags" +msgstr "" + #: src/view/com/lists/ListCard.tsx:102 msgid "Muted" msgstr "Silenciada" -#: src/view/screens/Moderation.tsx:109 +#: src/view/screens/Moderation.tsx:128 msgid "Muted accounts" msgstr "Contas silenciadas" @@ -2323,6 +2389,10 @@ msgstr "Contas Silenciadas" msgid "Muted accounts have their posts removed from your feed and from your notifications. Mutes are completely private." msgstr "Contas silenciadas não aparecem no seu feed ou nas suas notificações. Suas contas silenciadas são completamente privadas." +#: src/view/screens/Moderation.tsx:100 +msgid "Muted words & tags" +msgstr "" + #: src/view/screens/ProfileList.tsx:277 msgid "Muting is private. Muted accounts can interact with you, but you will not see their posts or receive notifications from them." msgstr "Silenciar é privado. Contas silenciadas podem interagir com você, mas você não verá postagens ou receber notificações delas." @@ -2386,6 +2456,10 @@ msgstr "Nunca perca o acesso aos seus seguidores e dados." msgid "Never lose access to your followers or data." msgstr "Nunca perca o acesso aos seus seguidores ou dados." +#: src/components/dialogs/MutedWords.tsx:244 +msgid "Nevermind" +msgstr "" + #: src/view/screens/Lists.tsx:76 msgctxt "action" msgid "New" @@ -2407,7 +2481,7 @@ msgstr "Nova senha" msgid "New Password" msgstr "Nova Senha" -#: src/view/com/feeds/FeedPage.tsx:192 +#: src/view/com/feeds/FeedPage.tsx:126 msgctxt "action" msgid "New post" msgstr "Novo post" @@ -2492,8 +2566,8 @@ msgid "No results found for \"{query}\"" msgstr "Nenhum resultado encontrado para \"{query}\"" #: src/view/com/modals/ListAddRemoveUsers.tsx:127 -#: src/view/screens/Search/Search.tsx:280 -#: src/view/screens/Search/Search.tsx:308 +#: src/view/screens/Search/Search.tsx:281 +#: src/view/screens/Search/Search.tsx:309 msgid "No results found for {query}" msgstr "Nenhum resultado encontrado para {query}" @@ -2519,7 +2593,7 @@ msgstr "Não encontrado" msgid "Not right now" msgstr "Agora não" -#: src/view/screens/Moderation.tsx:233 +#: src/view/screens/Moderation.tsx:252 msgid "Note: Bluesky is an open and public network. This setting only limits the visibility of your content on the Bluesky app and website, and other apps may not respect this setting. Your content may still be shown to logged-out users by other apps and websites." msgstr "Nota: o Bluesky é uma rede aberta e pública. Esta configuração limita somente a visibilidade do seu conteúdo no site e aplicativo do Bluesky, e outros aplicativos podem não respeitar esta configuração. Seu conteúdo ainda poderá ser exibido para usuários deslogados por outros aplicativos e sites." @@ -2557,7 +2631,7 @@ msgstr "Respostas mais antigas primeiro" msgid "Onboarding reset" msgstr "Resetar tutoriais" -#: src/view/com/composer/Composer.tsx:375 +#: src/view/com/composer/Composer.tsx:382 msgid "One or more images is missing alt text." msgstr "Uma ou mais imagens estão sem texto alternativo." @@ -2574,8 +2648,12 @@ msgstr "Opa!" msgid "Open" msgstr "Abrir" -#: src/view/com/composer/Composer.tsx:470 -#: src/view/com/composer/Composer.tsx:471 +#: src/view/screens/Moderation.tsx:75 +msgid "Open content filtering settings" +msgstr "" + +#: src/view/com/composer/Composer.tsx:477 +#: src/view/com/composer/Composer.tsx:478 msgid "Open emoji picker" msgstr "Abrir seletor de emojis" @@ -2583,6 +2661,10 @@ msgstr "Abrir seletor de emojis" msgid "Open links with in-app browser" msgstr "Abrir links no navegador interno" +#: src/view/screens/Moderation.tsx:92 +msgid "Open muted words settings" +msgstr "" + #: src/view/com/home/HomeHeaderLayoutMobile.tsx:49 msgid "Open navigation" msgstr "Abrir navegação" @@ -2659,6 +2741,7 @@ msgstr "Abre configurações de moderação" msgid "Opens password reset form" msgstr "Abre o formulário de redefinição de senha" +#: src/view/com/home/HomeHeaderLayout.web.tsx:60 #: src/view/screens/Feeds.tsx:356 msgid "Opens screen to edit Saved Feeds" msgstr "Abre a tela para editar feeds salvos" @@ -2839,7 +2922,7 @@ msgstr "Por favor, diga-nos por que você acha que este aviso de conteúdo foi a msgid "Please Verify Your Email" msgstr "Por favor, verifique seu e-mail" -#: src/view/com/composer/Composer.tsx:215 +#: src/view/com/composer/Composer.tsx:222 msgid "Please wait for your link card to finish loading" msgstr "Aguarde até que a prévia de link termine de carregar" @@ -2851,8 +2934,8 @@ msgstr "Política" msgid "Porn" msgstr "Pornografia" -#: src/view/com/composer/Composer.tsx:350 -#: src/view/com/composer/Composer.tsx:358 +#: src/view/com/composer/Composer.tsx:357 +#: src/view/com/composer/Composer.tsx:365 msgctxt "action" msgid "Post" msgstr "Postar" @@ -2862,7 +2945,7 @@ msgctxt "description" msgid "Post" msgstr "Post" -#: src/view/com/post-thread/PostThreadItem.tsx:173 +#: src/view/com/post-thread/PostThreadItem.tsx:175 msgid "Post by {0}" msgstr "Post por {0}" @@ -2872,11 +2955,11 @@ msgstr "Post por {0}" msgid "Post by @{0}" msgstr "Post por @{0}" -#: src/view/com/util/forms/PostDropdownBtn.tsx:88 +#: src/view/com/util/forms/PostDropdownBtn.tsx:90 msgid "Post deleted" msgstr "Post excluído" -#: src/view/com/post-thread/PostThread.tsx:461 +#: src/view/com/post-thread/PostThread.tsx:462 msgid "Post hidden" msgstr "Post oculto" @@ -2888,14 +2971,22 @@ msgstr "Idioma do post" msgid "Post Languages" msgstr "Idiomas do Post" -#: src/view/com/post-thread/PostThread.tsx:513 +#: src/view/com/post-thread/PostThread.tsx:514 msgid "Post not found" msgstr "Post não encontrado" +#: src/components/TagMenu/index.tsx:257 +msgid "posts" +msgstr "" + #: src/view/screens/Profile.tsx:180 msgid "Posts" msgstr "Posts" +#: src/components/dialogs/MutedWords.tsx:77 +msgid "Posts can be muted based on their text, their tags, or both." +msgstr "" + #: src/view/com/posts/FeedErrorMessage.tsx:64 msgid "Posts hidden" msgstr "Posts ocultados" @@ -2960,11 +3051,11 @@ msgstr "Listas públicas e compartilháveis para silenciar ou bloquear usuários msgid "Public, shareable lists which can drive feeds." msgstr "Listas públicas e compartilháveis que geram feeds." -#: src/view/com/composer/Composer.tsx:335 +#: src/view/com/composer/Composer.tsx:342 msgid "Publish post" msgstr "Publicar post" -#: src/view/com/composer/Composer.tsx:335 +#: src/view/com/composer/Composer.tsx:342 msgid "Publish reply" msgstr "Publicar resposta" @@ -2998,6 +3089,7 @@ msgstr "Feeds Recomendados" msgid "Recommended Users" msgstr "Usuários Recomendados" +#: src/components/dialogs/MutedWords.tsx:249 #: src/view/com/modals/ListAddRemoveUsers.tsx:264 #: src/view/com/modals/SelfLabel.tsx:83 #: src/view/com/modals/UserAddRemoveLists.tsx:219 @@ -3035,6 +3127,10 @@ msgstr "Remover imagem" msgid "Remove image preview" msgstr "Remover visualização da imagem" +#: src/components/dialogs/MutedWords.tsx:294 +msgid "Remove mute word from your list" +msgstr "" + #: src/view/com/modals/Repost.tsx:47 msgid "Remove repost" msgstr "Desfazer repost" @@ -3069,7 +3165,7 @@ msgstr "Respostas" msgid "Replies to this thread are disabled" msgstr "Respostas para esta thread estão desativadas" -#: src/view/com/composer/Composer.tsx:348 +#: src/view/com/composer/Composer.tsx:355 msgctxt "action" msgid "Reply" msgstr "Responder" @@ -3079,7 +3175,7 @@ msgid "Reply Filters" msgstr "Filtros de Resposta" #: src/view/com/post/Post.tsx:167 -#: src/view/com/posts/FeedItem.tsx:285 +#: src/view/com/posts/FeedItem.tsx:287 msgctxt "description" msgid "Reply to <0/>" msgstr "Responder <0/>" @@ -3101,7 +3197,7 @@ msgid "Report List" msgstr "Denunciar Lista" #: src/view/com/modals/report/SendReportButton.tsx:37 -#: src/view/com/util/forms/PostDropdownBtn.tsx:239 +#: src/view/com/util/forms/PostDropdownBtn.tsx:255 msgid "Report post" msgstr "Denunciar post" @@ -3126,11 +3222,11 @@ msgstr "Repostar ou citar um post" msgid "Reposted By" msgstr "Repostado Por" -#: src/view/com/posts/FeedItem.tsx:205 +#: src/view/com/posts/FeedItem.tsx:207 msgid "Reposted by {0}" msgstr "Repostado por {0}" -#: src/view/com/posts/FeedItem.tsx:222 +#: src/view/com/posts/FeedItem.tsx:224 msgid "Reposted by <0/>" msgstr "Repostado por <0/>" @@ -3138,7 +3234,7 @@ msgstr "Repostado por <0/>" msgid "reposted your post" msgstr "repostou seu post" -#: src/view/com/post-thread/PostThreadItem.tsx:186 +#: src/view/com/post-thread/PostThreadItem.tsx:188 msgid "Reposts of this post" msgstr "Reposts" @@ -3289,9 +3385,9 @@ msgstr "Ir para o topo" #: src/view/com/modals/ListAddRemoveUsers.tsx:75 #: src/view/com/util/forms/SearchInput.tsx:67 #: src/view/com/util/forms/SearchInput.tsx:79 -#: src/view/screens/Search/Search.tsx:418 -#: src/view/screens/Search/Search.tsx:645 -#: src/view/screens/Search/Search.tsx:663 +#: src/view/screens/Search/Search.tsx:419 +#: src/view/screens/Search/Search.tsx:668 +#: src/view/screens/Search/Search.tsx:686 #: src/view/shell/bottom-bar/BottomBar.tsx:159 #: src/view/shell/desktop/LeftNav.tsx:324 #: src/view/shell/desktop/Search.tsx:214 @@ -3301,11 +3397,19 @@ msgstr "Ir para o topo" msgid "Search" msgstr "Buscar" -#: src/view/screens/Search/Search.tsx:712 +#: src/view/screens/Search/Search.tsx:735 #: src/view/shell/desktop/Search.tsx:255 msgid "Search for \"{query}\"" msgstr "Pesquisar por \"{query}\"" +#: src/components/TagMenu/index.tsx:145 +msgid "Search for all posts by @{authorHandle} with tag {tag}" +msgstr "" + +#: src/components/TagMenu/index.tsx:90 +msgid "Search for all posts with tag {tag}" +msgstr "" + #: src/view/com/auth/LoggedOut.tsx:104 #: src/view/com/auth/LoggedOut.tsx:105 #: src/view/com/modals/ListAddRemoveUsers.tsx:70 @@ -3316,6 +3420,22 @@ msgstr "Buscar usuários" msgid "Security Step Required" msgstr "Passo de Segurança Necessário" +#: src/components/TagMenu/index.web.tsx:50 +msgid "See {truncatedTag} posts" +msgstr "" + +#: src/components/TagMenu/index.web.tsx:67 +msgid "See {truncatedTag} posts by user" +msgstr "" + +#: src/components/TagMenu/index.tsx:128 +msgid "See <0>{tag} posts" +msgstr "" + +#: src/components/TagMenu/index.tsx:189 +msgid "See <0>{tag} posts by this user" +msgstr "" + #: src/view/screens/SavedFeeds.tsx:163 msgid "See this guide" msgstr "Veja o guia" @@ -3525,7 +3645,7 @@ msgid "Share" msgstr "Compartilhar" #: src/view/com/profile/ProfileHeader.tsx:295 -#: src/view/com/util/forms/PostDropdownBtn.tsx:182 +#: src/view/com/util/forms/PostDropdownBtn.tsx:184 #: src/view/screens/ProfileList.tsx:418 msgid "Share" msgstr "Compartilhar" @@ -3558,9 +3678,9 @@ msgstr "Mostrar anexos de {0}" msgid "Show follows similar to {0}" msgstr "Mostrar usuários parecidos com {0}" -#: src/view/com/post-thread/PostThreadItem.tsx:532 -#: src/view/com/post/Post.tsx:196 -#: src/view/com/posts/FeedItem.tsx:359 +#: src/view/com/post-thread/PostThreadItem.tsx:538 +#: src/view/com/post/Post.tsx:198 +#: src/view/com/posts/FeedItem.tsx:363 msgid "Show More" msgstr "Mostrar Mais" @@ -3728,7 +3848,7 @@ msgstr "Desenvolvimento de software" msgid "Something went wrong. Check your email and try again." msgstr "Algo deu errado. Verifique seu e-mail e tente novamente." -#: src/App.native.tsx:61 +#: src/App.native.tsx:63 msgid "Sorry! Your session expired. Please log in again." msgstr "Opa! Sua sessão expirou. Por favor, entre novamente." @@ -3786,7 +3906,7 @@ msgstr "Increver-se no feed {0}" msgid "Subscribe to this list" msgstr "Inscreva-se nesta lista" -#: src/view/screens/Search/Search.tsx:373 +#: src/view/screens/Search/Search.tsx:374 msgid "Suggested Follows" msgstr "Sugestões de Seguidores" @@ -3830,6 +3950,14 @@ msgstr "Sistema" msgid "System log" msgstr "Log do sistema" +#: src/components/dialogs/MutedWords.tsx:288 +msgid "tag" +msgstr "" + +#: src/components/TagMenu/index.tsx:74 +msgid "Tag menu: {tag}" +msgstr "" + #: src/view/com/modals/crop-image/CropImage.web.tsx:112 msgid "Tall" msgstr "Alto" @@ -3853,6 +3981,10 @@ msgstr "Termos" msgid "Terms of Service" msgstr "Termos de Serviço" +#: src/components/dialogs/MutedWords.tsx:288 +msgid "text" +msgstr "" + #: src/view/com/modals/AppealLabel.tsx:70 #: src/view/com/modals/report/InputIssueDetails.tsx:51 msgid "Text input field" @@ -3878,7 +4010,7 @@ msgstr "A Política de Direitos Autorais foi movida para <0/>" msgid "The following steps will help customize your Bluesky experience." msgstr "Os seguintes passos vão ajudar a customizar sua experiência no Bluesky." -#: src/view/com/post-thread/PostThread.tsx:516 +#: src/view/com/post-thread/PostThread.tsx:517 msgid "The post may have been deleted." msgstr "O post pode ter sido excluído." @@ -4044,7 +4176,7 @@ msgstr "Esta lista está vazia!" msgid "This name is already in use" msgstr "Você já tem uma senha com esse nome" -#: src/view/com/post-thread/PostThreadItem.tsx:123 +#: src/view/com/post-thread/PostThreadItem.tsx:125 msgid "This post has been deleted." msgstr "Este post foi excluído." @@ -4068,7 +4200,11 @@ msgstr "Este usuário está incluído na lista <0/>, que você silenciou." msgid "This warning is only available for posts with media attached." msgstr "Este aviso só está disponível para publicações com mídia anexada." -#: src/view/com/util/forms/PostDropdownBtn.tsx:221 +#: src/components/dialogs/MutedWords.tsx:236 +msgid "This will delete {0} from your muted words. You can always add it back later." +msgstr "" + +#: src/view/com/util/forms/PostDropdownBtn.tsx:237 msgid "This will hide this post from your feeds." msgstr "Isso ocultará este post de seus feeds." @@ -4085,6 +4221,10 @@ msgstr "Visualização de Threads" msgid "Threads Preferences" msgstr "Preferências das Threads" +#: src/components/dialogs/MutedWords.tsx:95 +msgid "Toggle between muted word options." +msgstr "" + #: src/view/com/util/forms/DropdownButton.tsx:246 msgid "Toggle dropdown" msgstr "Alternar menu suspenso" @@ -4093,9 +4233,9 @@ msgstr "Alternar menu suspenso" msgid "Transformations" msgstr "Transformações" -#: src/view/com/post-thread/PostThreadItem.tsx:679 -#: src/view/com/post-thread/PostThreadItem.tsx:681 -#: src/view/com/util/forms/PostDropdownBtn.tsx:154 +#: src/view/com/post-thread/PostThreadItem.tsx:685 +#: src/view/com/post-thread/PostThreadItem.tsx:687 +#: src/view/com/util/forms/PostDropdownBtn.tsx:156 msgid "Translate" msgstr "Traduzir" @@ -4160,15 +4300,24 @@ msgstr "Infelizmente, você não atende aos requisitos para criar uma conta." msgid "Unlike" msgstr "Descurtir" +#: src/components/TagMenu/index.tsx:253 #: src/view/screens/ProfileList.tsx:597 msgid "Unmute" msgstr "Dessilenciar" +#: src/components/TagMenu/index.web.tsx:90 +msgid "Unmute {truncatedTag}" +msgstr "" + #: src/view/com/profile/ProfileHeader.tsx:326 msgid "Unmute Account" msgstr "Dessilenciar conta" -#: src/view/com/util/forms/PostDropdownBtn.tsx:200 +#: src/components/TagMenu/index.tsx:210 +msgid "Unmute all {tag} posts" +msgstr "" + +#: src/view/com/util/forms/PostDropdownBtn.tsx:202 msgid "Unmute thread" msgstr "Dessilenciar thread" @@ -4369,6 +4518,10 @@ msgstr "Não temos mais posts de quem você segue. Aqui estão os mais novos de #~ msgid "We recommend \"For You\" by Skygaze:" #~ msgstr "Recomendamos o \"Para você\", do Skygaze:" +#: src/components/dialogs/MutedWords.tsx:161 +msgid "We recommend avoiding common words that appear in many posts, since it can result in no posts being shown." +msgstr "" + #: src/screens/Onboarding/StepAlgoFeeds/index.tsx:124 msgid "We recommend our \"Discover\" feed:" msgstr "Recomendamos nosso feed \"Discover\":" @@ -4397,7 +4550,11 @@ msgstr "Estamos muito felizes em recebê-lo!" msgid "We're sorry, but we were unable to resolve this list. If this persists, please contact the list creator, @{handleOrDid}." msgstr "Tivemos um problema ao exibir esta lista. Se continuar acontecendo, contate o criador da lista: @{handleOrDid}." -#: src/view/screens/Search/Search.tsx:253 +#: src/components/dialogs/MutedWords.tsx:182 +msgid "We're sorry, but we weren't able to load your muted words at this time. Please try again." +msgstr "" + +#: src/view/screens/Search/Search.tsx:254 msgid "We're sorry, but your search could not be completed. Please try again in a few minutes." msgstr "Lamentamos, mas sua busca não pôde ser concluída. Por favor, tente novamente em alguns minutos." @@ -4418,7 +4575,7 @@ msgid "What is the issue with this {collectionName}?" msgstr "Qual é o problema com este {collectionName}?" #: src/view/com/auth/SplashScreen.tsx:59 -#: src/view/com/composer/Composer.tsx:279 +#: src/view/com/composer/Composer.tsx:286 msgid "What's up?" msgstr "E aí?" @@ -4439,11 +4596,11 @@ msgstr "Quem pode responder" msgid "Wide" msgstr "Largo" -#: src/view/com/composer/Composer.tsx:415 +#: src/view/com/composer/Composer.tsx:422 msgid "Write post" msgstr "Escrever post" -#: src/view/com/composer/Composer.tsx:278 +#: src/view/com/composer/Composer.tsx:285 #: src/view/com/composer/Prompt.tsx:33 msgid "Write your reply" msgstr "Escreva sua resposta" @@ -4508,7 +4665,7 @@ msgstr "Você não tem feeds salvos!" msgid "You don't have any saved feeds." msgstr "Você não tem feeds salvos." -#: src/view/com/post-thread/PostThread.tsx:464 +#: src/view/com/post-thread/PostThread.tsx:465 msgid "You have blocked the author or you have been blocked by the author." msgstr "Você bloqueou esta conta ou foi bloqueado por ela." @@ -4548,6 +4705,10 @@ msgstr "Você ainda não criou nenhuma senha de aplicativo. Você pode criar uma msgid "You have not muted any accounts yet. To mute an account, go to their profile and selected \"Mute account\" from the menu on their account." msgstr "Você ainda não silenciou nenhuma conta. Para silenciar uma conta, acesse um perfil e selecione \"Silenciar conta\" no menu." +#: src/components/dialogs/MutedWords.tsx:202 +msgid "You haven't muted any words or tags yet" +msgstr "" + #: src/view/com/modals/ContentFilteringSettings.tsx:175 msgid "You must be 18 or older to enable adult content." msgstr "Você precisa ser maior de idade para habilitar conteúdo adulto." @@ -4556,11 +4717,11 @@ msgstr "Você precisa ser maior de idade para habilitar conteúdo adulto." msgid "You must be 18 years or older to enable adult content" msgstr "Você precisa ser maior de idade para habilitar conteúdo adulto." -#: src/view/com/util/forms/PostDropdownBtn.tsx:127 +#: src/view/com/util/forms/PostDropdownBtn.tsx:129 msgid "You will no longer receive notifications for this thread" msgstr "Você não vai mais receber notificações desta thread" -#: src/view/com/util/forms/PostDropdownBtn.tsx:130 +#: src/view/com/util/forms/PostDropdownBtn.tsx:132 msgid "You will now receive notifications for this thread" msgstr "Você vai receber notificações desta thread" @@ -4646,11 +4807,15 @@ msgstr "Seu usuário completo será <0>@{0}" #~ msgid "Your invite codes are hidden when logged in using an App Password" #~ msgstr "Seus códigos de convite estão ocultos quando conectado com uma Senha do Aplicativo" +#: src/components/dialogs/MutedWords.tsx:173 +msgid "Your muted words" +msgstr "" + #: src/view/com/modals/ChangePassword.tsx:155 msgid "Your password has been changed successfully!" msgstr "Sua senha foi alterada com sucesso!" -#: src/view/com/composer/Composer.tsx:267 +#: src/view/com/composer/Composer.tsx:274 msgid "Your post has been published" msgstr "Seu post foi publicado" @@ -4665,7 +4830,7 @@ msgstr "Suas postagens, curtidas e bloqueios são públicos. Silenciamentos são msgid "Your profile" msgstr "Seu perfil" -#: src/view/com/composer/Composer.tsx:266 +#: src/view/com/composer/Composer.tsx:273 msgid "Your reply has been published" msgstr "Sua resposta foi publicada" diff --git a/src/locale/locales/uk/messages.po b/src/locale/locales/uk/messages.po index 169b1feb..8f978261 100644 --- a/src/locale/locales/uk/messages.po +++ b/src/locale/locales/uk/messages.po @@ -118,7 +118,7 @@ msgid "A new version of the app is available. Please update to continue using th msgstr "Доступна нова версія. Будь ласка, оновіть застосунок, щоб продовжити ним користуватися." #: src/view/com/util/ViewHeader.tsx:83 -#: src/view/screens/Search/Search.tsx:624 +#: src/view/screens/Search/Search.tsx:647 msgid "Access navigation links and settings" msgstr "" @@ -169,6 +169,7 @@ msgstr "" msgid "Account unmuted" msgstr "" +#: src/components/dialogs/MutedWords.tsx:147 #: src/view/com/auth/onboarding/RecommendedFeedsItem.tsx:150 #: src/view/com/modals/ListAddRemoveUsers.tsx:264 #: src/view/com/modals/UserAddRemoveLists.tsx:219 @@ -210,14 +211,22 @@ msgstr "Додайте подробиці" msgid "Add details to report" msgstr "Додайте подробиці до скарги" -#: src/view/com/composer/Composer.tsx:446 +#: src/view/com/composer/Composer.tsx:453 msgid "Add link card" msgstr "Додати попередній перегляд" -#: src/view/com/composer/Composer.tsx:451 +#: src/view/com/composer/Composer.tsx:458 msgid "Add link card:" msgstr "Додати попередній перегляд:" +#: src/components/dialogs/MutedWords.tsx:140 +msgid "Add mute word for configured settings" +msgstr "" + +#: src/components/dialogs/MutedWords.tsx:74 +msgid "Add muted words and tags" +msgstr "" + #: src/view/com/modals/ChangeHandle.tsx:417 msgid "Add the following DNS record to your domain:" msgstr "Додайте наступний DNS-запис до вашого домену:" @@ -341,7 +350,7 @@ msgstr "" msgid "App Passwords" msgstr "Паролі для застосунків" -#: src/view/com/util/forms/PostDropdownBtn.tsx:279 +#: src/view/com/util/forms/PostDropdownBtn.tsx:295 msgid "Appeal content warning" msgstr "Оскаржити попередження про вміст" @@ -373,15 +382,16 @@ msgstr "Оформлення" msgid "Are you sure you want to delete the app password \"{name}\"?" msgstr "Ви дійсно хочете видалити пароль для застосунку \"{name}\"?" -#: src/view/com/composer/Composer.tsx:143 +#: src/view/com/composer/Composer.tsx:150 msgid "Are you sure you'd like to discard this draft?" msgstr "Ви дійсно бажаєте видалити цю чернетку?" +#: src/components/dialogs/MutedWords.tsx:233 #: src/view/screens/ProfileList.tsx:365 msgid "Are you sure?" msgstr "Ви впевнені?" -#: src/view/com/util/forms/PostDropdownBtn.tsx:262 +#: src/view/com/util/forms/PostDropdownBtn.tsx:278 msgid "Are you sure? This cannot be undone." msgstr "Ви впевнені? Це не можна буде скасувати." @@ -407,15 +417,15 @@ msgstr "Художня або нееротична оголеність." #: src/view/com/auth/login/LoginForm.tsx:259 #: src/view/com/auth/login/SetNewPasswordForm.tsx:179 #: src/view/com/modals/report/InputIssueDetails.tsx:46 -#: src/view/com/post-thread/PostThread.tsx:471 -#: src/view/com/post-thread/PostThread.tsx:521 -#: src/view/com/post-thread/PostThread.tsx:529 +#: src/view/com/post-thread/PostThread.tsx:472 +#: src/view/com/post-thread/PostThread.tsx:522 +#: src/view/com/post-thread/PostThread.tsx:530 #: src/view/com/profile/ProfileHeader.tsx:649 #: src/view/com/util/ViewHeader.tsx:81 msgid "Back" msgstr "Назад" -#: src/view/com/post-thread/PostThread.tsx:479 +#: src/view/com/post-thread/PostThread.tsx:480 msgctxt "action" msgid "Back" msgstr "" @@ -463,7 +473,7 @@ msgstr "" msgid "Blocked" msgstr "" -#: src/view/screens/Moderation.tsx:123 +#: src/view/screens/Moderation.tsx:142 msgid "Blocked accounts" msgstr "Заблоковані облікові записи" @@ -522,7 +532,7 @@ msgstr "Bluesky публічний." msgid "Bluesky uses invites to build a healthier community. If you don't know anybody with an invite, you can sign up for the waitlist and we'll send one soon." msgstr "Bluesky використовує систему запрошень для створення здоровішої спільноти. Якщо Ви не знаєте когось хто має запрошення, ви можете записатися до черги очікування і ми скоро надішлемо вам код запрошення." -#: src/view/screens/Moderation.tsx:226 +#: src/view/screens/Moderation.tsx:245 msgid "Bluesky will not show your profile and posts to logged-out users. Other apps may not honor this request. This does not make your account private." msgstr "Bluesky не буде показувати ваш профіль і повідомлення відвідувачам без облікового запису. Інші застосунки можуть не слідувати цьому запиту. Це не робить ваш обліковий запис приватним." @@ -574,8 +584,8 @@ msgid "Can only contain letters, numbers, spaces, dashes, and underscores. Must msgstr "Може містити лише літери, цифри, пробіли, дефіси та знаки підкреслення, і мати довжину від 4 до 32 символів." #: src/components/Prompt.tsx:91 -#: src/view/com/composer/Composer.tsx:300 -#: src/view/com/composer/Composer.tsx:305 +#: src/view/com/composer/Composer.tsx:307 +#: src/view/com/composer/Composer.tsx:312 #: src/view/com/modals/ChangeEmail.tsx:218 #: src/view/com/modals/ChangeEmail.tsx:220 #: src/view/com/modals/ChangePassword.tsx:265 @@ -589,7 +599,7 @@ msgstr "Може містити лише літери, цифри, пробіл #: src/view/com/modals/VerifyEmail.tsx:247 #: src/view/com/modals/VerifyEmail.tsx:253 #: src/view/com/modals/Waitlist.tsx:142 -#: src/view/screens/Search/Search.tsx:693 +#: src/view/screens/Search/Search.tsx:716 #: src/view/shell/desktop/Search.tsx:238 msgid "Cancel" msgstr "Скасувати" @@ -752,7 +762,7 @@ msgid "Clear all storage data (restart after this)" msgstr "" #: src/view/com/util/forms/SearchInput.tsx:88 -#: src/view/screens/Search/Search.tsx:674 +#: src/view/screens/Search/Search.tsx:697 msgid "Clear search query" msgstr "Очистити пошуковий запит" @@ -760,6 +770,11 @@ msgstr "Очистити пошуковий запит" msgid "click here" msgstr "" +#: src/components/RichText.tsx:189 +#: src/components/TagMenu/index.web.tsx:125 +msgid "Click here to open tag menu for {tag}" +msgstr "" + #: src/screens/Onboarding/index.tsx:35 msgid "Climate" msgstr "" @@ -790,11 +805,15 @@ msgstr "Закрити зображення" msgid "Close image viewer" msgstr "Закрити перегляд зображення" -#: src/view/shell/index.web.tsx:49 +#: src/view/shell/index.web.tsx:51 msgid "Close navigation footer" msgstr "Закрити панель навігації" -#: src/view/shell/index.web.tsx:50 +#: src/components/TagMenu/index.tsx:266 +msgid "Close this dialog" +msgstr "" + +#: src/view/shell/index.web.tsx:52 msgid "Closes bottom navigation bar" msgstr "" @@ -802,7 +821,7 @@ msgstr "" msgid "Closes password update alert" msgstr "" -#: src/view/com/composer/Composer.tsx:302 +#: src/view/com/composer/Composer.tsx:309 msgid "Closes post composer and discards post draft" msgstr "" @@ -835,7 +854,7 @@ msgstr "" msgid "Complete the challenge" msgstr "" -#: src/view/com/composer/Composer.tsx:417 +#: src/view/com/composer/Composer.tsx:424 msgid "Compose posts up to {MAX_GRAPHEME_LENGTH} characters in length" msgstr "" @@ -899,7 +918,7 @@ msgstr "З’єднання..." msgid "Contact support" msgstr "" -#: src/view/screens/Moderation.tsx:81 +#: src/view/screens/Moderation.tsx:83 msgid "Content filtering" msgstr "Фільтрування вмісту" @@ -965,7 +984,7 @@ msgstr "" #: src/view/com/modals/AddAppPasswords.tsx:76 #: src/view/com/modals/InviteCodes.tsx:152 -#: src/view/com/util/forms/PostDropdownBtn.tsx:141 +#: src/view/com/util/forms/PostDropdownBtn.tsx:143 msgid "Copied to clipboard" msgstr "" @@ -981,7 +1000,7 @@ msgstr "Скопіювати" msgid "Copy link to list" msgstr "Скопіювати посилання" -#: src/view/com/util/forms/PostDropdownBtn.tsx:182 +#: src/view/com/util/forms/PostDropdownBtn.tsx:184 msgid "Copy link to post" msgstr "Скопіювати посилання" @@ -989,7 +1008,7 @@ msgstr "Скопіювати посилання" msgid "Copy link to profile" msgstr "Скопіювати посилання" -#: src/view/com/util/forms/PostDropdownBtn.tsx:168 +#: src/view/com/util/forms/PostDropdownBtn.tsx:170 msgid "Copy post text" msgstr "Скопіювати текст" @@ -1045,7 +1064,7 @@ msgstr "" msgid "Created by you" msgstr "" -#: src/view/com/composer/Composer.tsx:448 +#: src/view/com/composer/Composer.tsx:455 msgid "Creates a card with a thumbnail. The card links to {url}" msgstr "" @@ -1126,11 +1145,11 @@ msgstr "Видалити мій обліковий запис" msgid "Delete My Account…" msgstr "" -#: src/view/com/util/forms/PostDropdownBtn.tsx:257 +#: src/view/com/util/forms/PostDropdownBtn.tsx:273 msgid "Delete post" msgstr "Видалити пост" -#: src/view/com/util/forms/PostDropdownBtn.tsx:261 +#: src/view/com/util/forms/PostDropdownBtn.tsx:277 msgid "Delete this post?" msgstr "Видалити цей пост?" @@ -1157,7 +1176,7 @@ msgstr "Опис" #~ msgid "Developer Tools" #~ msgstr "Інструменти розробника" -#: src/view/com/composer/Composer.tsx:211 +#: src/view/com/composer/Composer.tsx:218 msgid "Did you want to say anything?" msgstr "Порожній пост. Ви хотіли щось написати?" @@ -1165,15 +1184,15 @@ msgstr "Порожній пост. Ви хотіли щось написати?" msgid "Dim" msgstr "" -#: src/view/com/composer/Composer.tsx:144 +#: src/view/com/composer/Composer.tsx:151 msgid "Discard" msgstr "Видалити" -#: src/view/com/composer/Composer.tsx:138 +#: src/view/com/composer/Composer.tsx:145 msgid "Discard draft" msgstr "Відкинути чернетку" -#: src/view/screens/Moderation.tsx:207 +#: src/view/screens/Moderation.tsx:226 msgid "Discourage apps from showing my account to logged-out users" msgstr "Попросити застосунки не показувати мій обліковий запис без входу" @@ -1252,7 +1271,7 @@ msgstr "" msgid "Download CAR file" msgstr "" -#: src/view/com/composer/text-input/TextInput.web.tsx:247 +#: src/view/com/composer/text-input/TextInput.web.tsx:249 msgid "Drop to add images" msgstr "" @@ -1324,6 +1343,7 @@ msgstr "Редагувати профіль" msgid "Edit Profile" msgstr "Редагувати профіль" +#: src/view/com/home/HomeHeaderLayout.web.tsx:59 #: src/view/screens/Feeds.tsx:355 msgid "Edit Saved Feeds" msgstr "Редагувати збережені стрічки" @@ -1406,6 +1426,11 @@ msgstr "Кінець стрічки" msgid "Enter a name for this App Password" msgstr "" +#: src/components/dialogs/MutedWords.tsx:87 +#: src/components/dialogs/MutedWords.tsx:88 +msgid "Enter a word or tag" +msgstr "" + #: src/view/com/modals/VerifyEmail.tsx:105 msgid "Enter Confirmation Code" msgstr "" @@ -1459,7 +1484,7 @@ msgstr "Введіть псевдонім та пароль" msgid "Error receiving captcha response." msgstr "" -#: src/view/screens/Search/Search.tsx:109 +#: src/view/screens/Search/Search.tsx:110 msgid "Error:" msgstr "Помилка:" @@ -1530,7 +1555,7 @@ msgstr "" msgid "Failed to create the list. Check your internet connection and try again." msgstr "" -#: src/view/com/util/forms/PostDropdownBtn.tsx:108 +#: src/view/com/util/forms/PostDropdownBtn.tsx:110 msgid "Failed to delete post, please try again" msgstr "" @@ -1552,8 +1577,8 @@ msgid "Feed offline" msgstr "Стрічка не працює" #: src/view/com/feeds/FeedPage.tsx:143 -msgid "Feed Preferences" -msgstr "Налаштування стрічки" +#~ msgid "Feed Preferences" +#~ msgstr "Налаштування стрічки" #: src/view/shell/desktop/RightNav.tsx:61 #: src/view/shell/Drawer.tsx:311 @@ -1601,11 +1626,11 @@ msgstr "" msgid "Find accounts to follow" msgstr "" -#: src/view/screens/Search/Search.tsx:439 +#: src/view/screens/Search/Search.tsx:440 msgid "Find users on Bluesky" msgstr "Знайти користувачів у Bluesky" -#: src/view/screens/Search/Search.tsx:437 +#: src/view/screens/Search/Search.tsx:438 msgid "Find users with the search tool on the right" msgstr "Знайти користувачів за допомогою поля пошуку справа вгорі" @@ -1714,6 +1739,7 @@ msgid "Following {0}" msgstr "" #: src/Navigation.tsx:248 +#: src/view/com/home/HomeHeaderLayout.web.tsx:45 #: src/view/com/home/HomeHeaderLayoutMobile.tsx:83 #: src/view/screens/PreferencesFollowingFeed.tsx:104 #: src/view/screens/Settings/index.tsx:543 @@ -1753,7 +1779,7 @@ msgstr "Забули пароль" msgid "Forgot Password" msgstr "Забули пароль" -#: src/view/com/posts/FeedItem.tsx:187 +#: src/view/com/posts/FeedItem.tsx:189 msgctxt "from-feed" msgid "From <0/>" msgstr "" @@ -1786,7 +1812,7 @@ msgstr "Назад" msgid "Go back to previous step" msgstr "" -#: src/view/screens/Search/Search.tsx:724 +#: src/view/screens/Search/Search.tsx:747 #: src/view/shell/desktop/Search.tsx:262 msgid "Go to @{queryMaybeHandle}" msgstr "" @@ -1803,6 +1829,10 @@ msgstr "Далі" msgid "Handle" msgstr "Псевдонім" +#: src/components/RichText.tsx:188 +msgid "Hashtag: {tag}" +msgstr "" + #: src/view/com/auth/create/CreateAccount.tsx:208 msgid "Having trouble?" msgstr "" @@ -1845,7 +1875,7 @@ msgctxt "action" msgid "Hide" msgstr "" -#: src/view/com/util/forms/PostDropdownBtn.tsx:216 +#: src/view/com/util/forms/PostDropdownBtn.tsx:232 msgid "Hide post" msgstr "Приховати пост" @@ -1854,7 +1884,7 @@ msgstr "Приховати пост" msgid "Hide the content" msgstr "" -#: src/view/com/util/forms/PostDropdownBtn.tsx:220 +#: src/view/com/util/forms/PostDropdownBtn.tsx:236 msgid "Hide this post?" msgstr "Приховати цей пост?" @@ -2029,7 +2059,7 @@ msgstr "" msgid "Input your user handle" msgstr "" -#: src/view/com/post-thread/PostThreadItem.tsx:224 +#: src/view/com/post-thread/PostThreadItem.tsx:226 msgid "Invalid or unsupported post record" msgstr "" @@ -2131,7 +2161,7 @@ msgstr "Дізнатися більше" msgid "Learn more about this warning" msgstr "Дізнатися більше про це попередження" -#: src/view/screens/Moderation.tsx:243 +#: src/view/screens/Moderation.tsx:262 msgid "Learn more about what is public on Bluesky." msgstr "Дізнатися більше про те, що є публічним в Bluesky." @@ -2215,7 +2245,7 @@ msgstr "" msgid "Likes" msgstr "Вподобання" -#: src/view/com/post-thread/PostThreadItem.tsx:181 +#: src/view/com/post-thread/PostThreadItem.tsx:183 msgid "Likes on this post" msgstr "" @@ -2280,7 +2310,7 @@ msgstr "Завантажити більше постів" msgid "Load new notifications" msgstr "Завантажити нові сповіщення" -#: src/view/com/feeds/FeedPage.tsx:181 +#: src/view/com/feeds/FeedPage.tsx:115 #: src/view/screens/Profile.tsx:440 #: src/view/screens/ProfileFeed.tsx:495 #: src/view/screens/ProfileList.tsx:681 @@ -2310,7 +2340,7 @@ msgstr "" #~ msgid "Logged-out users" #~ msgstr "" -#: src/view/screens/Moderation.tsx:136 +#: src/view/screens/Moderation.tsx:155 msgid "Logged-out visibility" msgstr "Видимість для користувачів без облікового запису" @@ -2326,6 +2356,10 @@ msgstr "Увійти до облікового запису, якого нема msgid "Make sure this is where you intend to go!" msgstr "Переконайтеся, що це дійсно той сайт, що ви збираєтеся відвідати!" +#: src/components/dialogs/MutedWords.tsx:71 +msgid "Manage your muted words and tags" +msgstr "" + #: src/view/com/auth/create/Step2.tsx:118 msgid "May not be longer than 253 characters" msgstr "" @@ -2347,7 +2381,7 @@ msgid "Mentioned users" msgstr "Згадані користувачі" #: src/view/com/util/ViewHeader.tsx:81 -#: src/view/screens/Search/Search.tsx:623 +#: src/view/screens/Search/Search.tsx:646 msgid "Menu" msgstr "Меню" @@ -2360,7 +2394,7 @@ msgid "Message from server: {0}" msgstr "" #: src/Navigation.tsx:115 -#: src/view/screens/Moderation.tsx:64 +#: src/view/screens/Moderation.tsx:66 #: src/view/screens/Settings/index.tsx:625 #: src/view/shell/desktop/LeftNav.tsx:397 #: src/view/shell/Drawer.tsx:511 @@ -2391,7 +2425,7 @@ msgstr "" msgid "Moderation list updated" msgstr "" -#: src/view/screens/Moderation.tsx:95 +#: src/view/screens/Moderation.tsx:114 msgid "Moderation lists" msgstr "Списки для модерації" @@ -2418,7 +2452,7 @@ msgstr "Більше стрічок" msgid "More options" msgstr "Додаткові опції" -#: src/view/com/util/forms/PostDropdownBtn.tsx:299 +#: src/view/com/util/forms/PostDropdownBtn.tsx:315 msgid "More post options" msgstr "" @@ -2430,6 +2464,14 @@ msgstr "За кількістю вподобань" msgid "Must be at least 3 characters" msgstr "" +#: src/components/TagMenu/index.tsx:253 +msgid "Mute" +msgstr "" + +#: src/components/TagMenu/index.web.tsx:91 +msgid "Mute {truncatedTag}" +msgstr "" + #: src/view/com/profile/ProfileHeader.tsx:327 msgid "Mute Account" msgstr "Ігнорувати обліковий запис" @@ -2438,6 +2480,18 @@ msgstr "Ігнорувати обліковий запис" msgid "Mute accounts" msgstr "Ігнорувати облікові записи" +#: src/components/TagMenu/index.tsx:211 +msgid "Mute all {tag} posts" +msgstr "" + +#: src/components/dialogs/MutedWords.tsx:131 +msgid "Mute in tags only" +msgstr "" + +#: src/components/dialogs/MutedWords.tsx:116 +msgid "Mute in text & tags" +msgstr "" + #: src/view/screens/ProfileList.tsx:491 msgid "Mute list" msgstr "Ігнорувати список" @@ -2450,15 +2504,27 @@ msgstr "Ігнорувати ці облікові записи?" msgid "Mute this List" msgstr "" -#: src/view/com/util/forms/PostDropdownBtn.tsx:200 +#: src/components/dialogs/MutedWords.tsx:109 +msgid "Mute this word in post text and tags" +msgstr "" + +#: src/components/dialogs/MutedWords.tsx:124 +msgid "Mute this word in tags only" +msgstr "" + +#: src/view/com/util/forms/PostDropdownBtn.tsx:202 msgid "Mute thread" msgstr "Ігнорувати пост" +#: src/view/com/util/forms/PostDropdownBtn.tsx:216 +msgid "Mute words & tags" +msgstr "" + #: src/view/com/lists/ListCard.tsx:102 msgid "Muted" msgstr "" -#: src/view/screens/Moderation.tsx:109 +#: src/view/screens/Moderation.tsx:128 msgid "Muted accounts" msgstr "Ігноровані облікові записи" @@ -2471,6 +2537,10 @@ msgstr "Ігноровані облікові записи" msgid "Muted accounts have their posts removed from your feed and from your notifications. Mutes are completely private." msgstr "Ігноровані облікові записи автоматично вилучаються із вашої стрічки та сповіщень. Ігнорування є повністю приватним." +#: src/view/screens/Moderation.tsx:100 +msgid "Muted words & tags" +msgstr "" + #: src/view/screens/ProfileList.tsx:277 msgid "Muting is private. Muted accounts can interact with you, but you will not see their posts or receive notifications from them." msgstr "Ігнорування є приватним. Ігноровані користувачі можуть взаємодіяти з вами, але ви не бачитимете їх пости і не отримуватимете від них сповіщень." @@ -2538,6 +2608,10 @@ msgstr "Ніколи не втрачайте доступ до ваших дан msgid "Never lose access to your followers or data." msgstr "" +#: src/components/dialogs/MutedWords.tsx:244 +msgid "Nevermind" +msgstr "" + #: src/view/screens/Lists.tsx:76 msgctxt "action" msgid "New" @@ -2559,7 +2633,7 @@ msgstr "" msgid "New Password" msgstr "" -#: src/view/com/feeds/FeedPage.tsx:192 +#: src/view/com/feeds/FeedPage.tsx:126 msgctxt "action" msgid "New post" msgstr "" @@ -2653,8 +2727,8 @@ msgstr "Нічого не знайдено за запитом «{query}»" #~ msgstr "" #: src/view/com/modals/ListAddRemoveUsers.tsx:127 -#: src/view/screens/Search/Search.tsx:280 -#: src/view/screens/Search/Search.tsx:308 +#: src/view/screens/Search/Search.tsx:281 +#: src/view/screens/Search/Search.tsx:309 msgid "No results found for {query}" msgstr "Нічого не знайдено за запитом «{query}»" @@ -2688,7 +2762,7 @@ msgstr "" #~ msgid "Note: Bluesky is an open and public network, and enabling this will not make your profile private or limit the ability of logged in users to see your posts. This setting only limits the visibility of posts on the Bluesky app and website; third-party apps that display Bluesky content may not respect this setting, and could show your content to logged-out users." #~ msgstr "" -#: src/view/screens/Moderation.tsx:233 +#: src/view/screens/Moderation.tsx:252 msgid "Note: Bluesky is an open and public network. This setting only limits the visibility of your content on the Bluesky app and website, and other apps may not respect this setting. Your content may still be shown to logged-out users by other apps and websites." msgstr "Примітка: Bluesky є відкритою і публічною мережею. Цей параметр обмежує видимість вашого вмісту лише у застосунках і на сайті Bluesky, але інші застосунки можуть цього не дотримуватися. Ваш вміст все ще може бути показаний відвідувачам без облікового запису іншими застосунками і вебсайтами." @@ -2730,7 +2804,7 @@ msgstr "Спочатку найдавніші" msgid "Onboarding reset" msgstr "" -#: src/view/com/composer/Composer.tsx:375 +#: src/view/com/composer/Composer.tsx:382 msgid "One or more images is missing alt text." msgstr "Для одного або кількох зображень відсутній альтернативний текст." @@ -2747,8 +2821,12 @@ msgstr "" msgid "Open" msgstr "" -#: src/view/com/composer/Composer.tsx:470 -#: src/view/com/composer/Composer.tsx:471 +#: src/view/screens/Moderation.tsx:75 +msgid "Open content filtering settings" +msgstr "" + +#: src/view/com/composer/Composer.tsx:477 +#: src/view/com/composer/Composer.tsx:478 msgid "Open emoji picker" msgstr "Емоджі" @@ -2756,6 +2834,10 @@ msgstr "Емоджі" msgid "Open links with in-app browser" msgstr "" +#: src/view/screens/Moderation.tsx:92 +msgid "Open muted words settings" +msgstr "" + #: src/view/com/home/HomeHeaderLayoutMobile.tsx:49 msgid "Open navigation" msgstr "Відкрити навігацію" @@ -2832,6 +2914,7 @@ msgstr "Відкриває налаштування модерації" msgid "Opens password reset form" msgstr "" +#: src/view/com/home/HomeHeaderLayout.web.tsx:60 #: src/view/screens/Feeds.tsx:356 msgid "Opens screen to edit Saved Feeds" msgstr "" @@ -3016,7 +3099,7 @@ msgstr "Будь ласка, вкажіть чому ви вважаєте що msgid "Please Verify Your Email" msgstr "" -#: src/view/com/composer/Composer.tsx:215 +#: src/view/com/composer/Composer.tsx:222 msgid "Please wait for your link card to finish loading" msgstr "Будь ласка, зачекайте доки завершиться створення попереднього перегляду для посилання" @@ -3028,8 +3111,8 @@ msgstr "" msgid "Porn" msgstr "" -#: src/view/com/composer/Composer.tsx:350 -#: src/view/com/composer/Composer.tsx:358 +#: src/view/com/composer/Composer.tsx:357 +#: src/view/com/composer/Composer.tsx:365 msgctxt "action" msgid "Post" msgstr "" @@ -3045,7 +3128,7 @@ msgstr "" #~ msgid "Post" #~ msgstr "Пост" -#: src/view/com/post-thread/PostThreadItem.tsx:173 +#: src/view/com/post-thread/PostThreadItem.tsx:175 msgid "Post by {0}" msgstr "" @@ -3055,11 +3138,11 @@ msgstr "" msgid "Post by @{0}" msgstr "" -#: src/view/com/util/forms/PostDropdownBtn.tsx:88 +#: src/view/com/util/forms/PostDropdownBtn.tsx:90 msgid "Post deleted" msgstr "" -#: src/view/com/post-thread/PostThread.tsx:461 +#: src/view/com/post-thread/PostThread.tsx:462 msgid "Post hidden" msgstr "Пост приховано" @@ -3071,14 +3154,22 @@ msgstr "Мова посту" msgid "Post Languages" msgstr "Мови посту" -#: src/view/com/post-thread/PostThread.tsx:513 +#: src/view/com/post-thread/PostThread.tsx:514 msgid "Post not found" msgstr "Пост не знайдено" +#: src/components/TagMenu/index.tsx:257 +msgid "posts" +msgstr "" + #: src/view/screens/Profile.tsx:180 msgid "Posts" msgstr "Пости" +#: src/components/dialogs/MutedWords.tsx:77 +msgid "Posts can be muted based on their text, their tags, or both." +msgstr "" + #: src/view/com/posts/FeedErrorMessage.tsx:64 msgid "Posts hidden" msgstr "" @@ -3143,11 +3234,11 @@ msgstr "Публічні, поширювані списки користувач msgid "Public, shareable lists which can drive feeds." msgstr "Публічні, поширювані списки для створення стрічок." -#: src/view/com/composer/Composer.tsx:335 +#: src/view/com/composer/Composer.tsx:342 msgid "Publish post" msgstr "" -#: src/view/com/composer/Composer.tsx:335 +#: src/view/com/composer/Composer.tsx:342 msgid "Publish reply" msgstr "" @@ -3190,6 +3281,7 @@ msgstr "Рекомендовані стрічки" msgid "Recommended Users" msgstr "Рекомендовані користувачі" +#: src/components/dialogs/MutedWords.tsx:249 #: src/view/com/modals/ListAddRemoveUsers.tsx:264 #: src/view/com/modals/SelfLabel.tsx:83 #: src/view/com/modals/UserAddRemoveLists.tsx:219 @@ -3227,6 +3319,10 @@ msgstr "Вилучити зображення" msgid "Remove image preview" msgstr "Вилучити попередній перегляд зображення" +#: src/components/dialogs/MutedWords.tsx:294 +msgid "Remove mute word from your list" +msgstr "" + #: src/view/com/modals/Repost.tsx:47 msgid "Remove repost" msgstr "" @@ -3261,7 +3357,7 @@ msgstr "Відповіді" msgid "Replies to this thread are disabled" msgstr "Відповіді до цього посту вимкнено" -#: src/view/com/composer/Composer.tsx:348 +#: src/view/com/composer/Composer.tsx:355 msgctxt "action" msgid "Reply" msgstr "" @@ -3271,7 +3367,7 @@ msgid "Reply Filters" msgstr "Які відповіді показувати" #: src/view/com/post/Post.tsx:167 -#: src/view/com/posts/FeedItem.tsx:285 +#: src/view/com/posts/FeedItem.tsx:287 msgctxt "description" msgid "Reply to <0/>" msgstr "" @@ -3293,7 +3389,7 @@ msgid "Report List" msgstr "Поскаржитись на список" #: src/view/com/modals/report/SendReportButton.tsx:37 -#: src/view/com/util/forms/PostDropdownBtn.tsx:239 +#: src/view/com/util/forms/PostDropdownBtn.tsx:255 msgid "Report post" msgstr "Поскаржитись на пост" @@ -3322,7 +3418,7 @@ msgstr "Репостити або цитувати" msgid "Reposted By" msgstr "" -#: src/view/com/posts/FeedItem.tsx:205 +#: src/view/com/posts/FeedItem.tsx:207 msgid "Reposted by {0}" msgstr "" @@ -3330,7 +3426,7 @@ msgstr "" #~ msgid "Reposted by {0})" #~ msgstr "" -#: src/view/com/posts/FeedItem.tsx:222 +#: src/view/com/posts/FeedItem.tsx:224 msgid "Reposted by <0/>" msgstr "" @@ -3338,7 +3434,7 @@ msgstr "" msgid "reposted your post" msgstr "" -#: src/view/com/post-thread/PostThreadItem.tsx:186 +#: src/view/com/post-thread/PostThreadItem.tsx:188 msgid "Reposts of this post" msgstr "" @@ -3501,9 +3597,9 @@ msgstr "" #: src/view/com/modals/ListAddRemoveUsers.tsx:75 #: src/view/com/util/forms/SearchInput.tsx:67 #: src/view/com/util/forms/SearchInput.tsx:79 -#: src/view/screens/Search/Search.tsx:418 -#: src/view/screens/Search/Search.tsx:645 -#: src/view/screens/Search/Search.tsx:663 +#: src/view/screens/Search/Search.tsx:419 +#: src/view/screens/Search/Search.tsx:668 +#: src/view/screens/Search/Search.tsx:686 #: src/view/shell/bottom-bar/BottomBar.tsx:159 #: src/view/shell/desktop/LeftNav.tsx:324 #: src/view/shell/desktop/Search.tsx:214 @@ -3513,11 +3609,19 @@ msgstr "" msgid "Search" msgstr "Пошук" -#: src/view/screens/Search/Search.tsx:712 +#: src/view/screens/Search/Search.tsx:735 #: src/view/shell/desktop/Search.tsx:255 msgid "Search for \"{query}\"" msgstr "" +#: src/components/TagMenu/index.tsx:145 +msgid "Search for all posts by @{authorHandle} with tag {tag}" +msgstr "" + +#: src/components/TagMenu/index.tsx:90 +msgid "Search for all posts with tag {tag}" +msgstr "" + #: src/view/screens/Search/Search.tsx:390 #~ msgid "Search for posts and users." #~ msgstr "" @@ -3532,6 +3636,22 @@ msgstr "Пошук користувачів" msgid "Security Step Required" msgstr "Потрібен код підтвердження" +#: src/components/TagMenu/index.web.tsx:50 +msgid "See {truncatedTag} posts" +msgstr "" + +#: src/components/TagMenu/index.web.tsx:67 +msgid "See {truncatedTag} posts by user" +msgstr "" + +#: src/components/TagMenu/index.tsx:128 +msgid "See <0>{tag} posts" +msgstr "" + +#: src/components/TagMenu/index.tsx:189 +msgid "See <0>{tag} posts by this user" +msgstr "" + #: src/view/screens/SavedFeeds.tsx:163 msgid "See this guide" msgstr "" @@ -3749,7 +3869,7 @@ msgid "Share" msgstr "" #: src/view/com/profile/ProfileHeader.tsx:295 -#: src/view/com/util/forms/PostDropdownBtn.tsx:182 +#: src/view/com/util/forms/PostDropdownBtn.tsx:184 #: src/view/screens/ProfileList.tsx:418 msgid "Share" msgstr "Поширити" @@ -3786,9 +3906,9 @@ msgstr "Показати вбудування з {0}" msgid "Show follows similar to {0}" msgstr "" -#: src/view/com/post-thread/PostThreadItem.tsx:532 -#: src/view/com/post/Post.tsx:196 -#: src/view/com/posts/FeedItem.tsx:359 +#: src/view/com/post-thread/PostThreadItem.tsx:538 +#: src/view/com/post/Post.tsx:198 +#: src/view/com/posts/FeedItem.tsx:363 msgid "Show More" msgstr "" @@ -3956,7 +4076,7 @@ msgstr "" msgid "Something went wrong. Check your email and try again." msgstr "" -#: src/App.native.tsx:61 +#: src/App.native.tsx:63 msgid "Sorry! Your session expired. Please log in again." msgstr "" @@ -4022,7 +4142,7 @@ msgstr "Підписатися на цей список" #~ msgid "Subscribed" #~ msgstr "" -#: src/view/screens/Search/Search.tsx:373 +#: src/view/screens/Search/Search.tsx:374 msgid "Suggested Follows" msgstr "Пропоновані підписки" @@ -4066,6 +4186,14 @@ msgstr "" msgid "System log" msgstr "Системний журнал" +#: src/components/dialogs/MutedWords.tsx:288 +msgid "tag" +msgstr "" + +#: src/components/TagMenu/index.tsx:74 +msgid "Tag menu: {tag}" +msgstr "" + #: src/view/com/modals/crop-image/CropImage.web.tsx:112 msgid "Tall" msgstr "Високе" @@ -4089,6 +4217,10 @@ msgstr "Умови" msgid "Terms of Service" msgstr "Умови Використання" +#: src/components/dialogs/MutedWords.tsx:288 +msgid "text" +msgstr "" + #: src/view/com/modals/AppealLabel.tsx:70 #: src/view/com/modals/report/InputIssueDetails.tsx:51 msgid "Text input field" @@ -4114,7 +4246,7 @@ msgstr "Політику захисту авторського права пер msgid "The following steps will help customize your Bluesky experience." msgstr "" -#: src/view/com/post-thread/PostThread.tsx:516 +#: src/view/com/post-thread/PostThread.tsx:517 msgid "The post may have been deleted." msgstr "Можливо цей пост було видалено." @@ -4296,7 +4428,7 @@ msgstr "" msgid "This name is already in use" msgstr "" -#: src/view/com/post-thread/PostThreadItem.tsx:123 +#: src/view/com/post-thread/PostThreadItem.tsx:125 msgid "This post has been deleted." msgstr "Цей пост було видалено." @@ -4320,7 +4452,11 @@ msgstr "" msgid "This warning is only available for posts with media attached." msgstr "Це попередження доступне тільки для записів з прикріпленими медіа-файлами." -#: src/view/com/util/forms/PostDropdownBtn.tsx:221 +#: src/components/dialogs/MutedWords.tsx:236 +msgid "This will delete {0} from your muted words. You can always add it back later." +msgstr "" + +#: src/view/com/util/forms/PostDropdownBtn.tsx:237 msgid "This will hide this post from your feeds." msgstr "Це приховає цей пост із вашої стрічки." @@ -4337,6 +4473,10 @@ msgstr "Режим гілок" msgid "Threads Preferences" msgstr "" +#: src/components/dialogs/MutedWords.tsx:95 +msgid "Toggle between muted word options." +msgstr "" + #: src/view/com/util/forms/DropdownButton.tsx:246 msgid "Toggle dropdown" msgstr "Розкрити/сховати" @@ -4345,9 +4485,9 @@ msgstr "Розкрити/сховати" msgid "Transformations" msgstr "Редагування" -#: src/view/com/post-thread/PostThreadItem.tsx:679 -#: src/view/com/post-thread/PostThreadItem.tsx:681 -#: src/view/com/util/forms/PostDropdownBtn.tsx:154 +#: src/view/com/post-thread/PostThreadItem.tsx:685 +#: src/view/com/post-thread/PostThreadItem.tsx:687 +#: src/view/com/util/forms/PostDropdownBtn.tsx:156 msgid "Translate" msgstr "Перекласти" @@ -4416,15 +4556,24 @@ msgstr "На жаль, ви не відповідаєте вимогам для msgid "Unlike" msgstr "" +#: src/components/TagMenu/index.tsx:253 #: src/view/screens/ProfileList.tsx:597 msgid "Unmute" msgstr "" +#: src/components/TagMenu/index.web.tsx:90 +msgid "Unmute {truncatedTag}" +msgstr "" + #: src/view/com/profile/ProfileHeader.tsx:326 msgid "Unmute Account" msgstr "Перестати ігнорувати" -#: src/view/com/util/forms/PostDropdownBtn.tsx:200 +#: src/components/TagMenu/index.tsx:210 +msgid "Unmute all {tag} posts" +msgstr "" + +#: src/view/com/util/forms/PostDropdownBtn.tsx:202 msgid "Unmute thread" msgstr "Перестати ігнорувати" @@ -4633,6 +4782,10 @@ msgstr "" #~ msgid "We recommend \"For You\" by Skygaze:" #~ msgstr "" +#: src/components/dialogs/MutedWords.tsx:161 +msgid "We recommend avoiding common words that appear in many posts, since it can result in no posts being shown." +msgstr "" + #: src/screens/Onboarding/StepAlgoFeeds/index.tsx:124 msgid "We recommend our \"Discover\" feed:" msgstr "" @@ -4669,7 +4822,11 @@ msgstr "Ми дуже раді, що ви приєдналися!" msgid "We're sorry, but we were unable to resolve this list. If this persists, please contact the list creator, @{handleOrDid}." msgstr "" -#: src/view/screens/Search/Search.tsx:253 +#: src/components/dialogs/MutedWords.tsx:182 +msgid "We're sorry, but we weren't able to load your muted words at this time. Please try again." +msgstr "" + +#: src/view/screens/Search/Search.tsx:254 msgid "We're sorry, but your search could not be completed. Please try again in a few minutes." msgstr "Даруйте, нам не вдалося виконати пошук за вашим запитом. Будь ласка, спробуйте ще раз через кілька хвилин." @@ -4690,7 +4847,7 @@ msgid "What is the issue with this {collectionName}?" msgstr "Яка проблема з {collectionName}?" #: src/view/com/auth/SplashScreen.tsx:59 -#: src/view/com/composer/Composer.tsx:279 +#: src/view/com/composer/Composer.tsx:286 msgid "What's up?" msgstr "Як справи?" @@ -4715,11 +4872,11 @@ msgstr "Хто може відповідати" msgid "Wide" msgstr "Широке" -#: src/view/com/composer/Composer.tsx:415 +#: src/view/com/composer/Composer.tsx:422 msgid "Write post" msgstr "Написати пост" -#: src/view/com/composer/Composer.tsx:278 +#: src/view/com/composer/Composer.tsx:285 #: src/view/com/composer/Prompt.tsx:33 msgid "Write your reply" msgstr "Написати відповідь" @@ -4788,7 +4945,7 @@ msgstr "У вас немає збережених стрічок!" msgid "You don't have any saved feeds." msgstr "У вас немає збережених стрічок." -#: src/view/com/post-thread/PostThread.tsx:464 +#: src/view/com/post-thread/PostThread.tsx:465 msgid "You have blocked the author or you have been blocked by the author." msgstr "Ви заблокували автора або автор заблокував вас." @@ -4828,6 +4985,10 @@ msgstr "Ви ще не створили жодного пароля для за msgid "You have not muted any accounts yet. To mute an account, go to their profile and selected \"Mute account\" from the menu on their account." msgstr "Ви ще не ігноруєте жодного облікового запису. Щоб ігнорувати когось, перейдіть до їх профілю та виберіть опцію \"Ігнорувати\" у меню їх облікового запису." +#: src/components/dialogs/MutedWords.tsx:202 +msgid "You haven't muted any words or tags yet" +msgstr "" + #: src/view/com/modals/ContentFilteringSettings.tsx:175 msgid "You must be 18 or older to enable adult content." msgstr "" @@ -4836,11 +4997,11 @@ msgstr "" msgid "You must be 18 years or older to enable adult content" msgstr "" -#: src/view/com/util/forms/PostDropdownBtn.tsx:127 +#: src/view/com/util/forms/PostDropdownBtn.tsx:129 msgid "You will no longer receive notifications for this thread" msgstr "" -#: src/view/com/util/forms/PostDropdownBtn.tsx:130 +#: src/view/com/util/forms/PostDropdownBtn.tsx:132 msgid "You will now receive notifications for this thread" msgstr "" @@ -4930,11 +5091,15 @@ msgstr "" #~ msgid "Your invite codes are hidden when logged in using an App Password" #~ msgstr "Ваші коди запрошення приховано, якщо ви увійшли за допомогою пароля для застосунків" +#: src/components/dialogs/MutedWords.tsx:173 +msgid "Your muted words" +msgstr "" + #: src/view/com/modals/ChangePassword.tsx:155 msgid "Your password has been changed successfully!" msgstr "" -#: src/view/com/composer/Composer.tsx:267 +#: src/view/com/composer/Composer.tsx:274 msgid "Your post has been published" msgstr "" @@ -4961,7 +5126,7 @@ msgstr "Ваш профіль" #~ msgid "Your profile and posts will not be visible to people visiting the Bluesky app or website without having an account and being logged in." #~ msgstr "" -#: src/view/com/composer/Composer.tsx:266 +#: src/view/com/composer/Composer.tsx:273 msgid "Your reply has been published" msgstr "" diff --git a/src/locale/locales/zh-CN/messages.po b/src/locale/locales/zh-CN/messages.po index aa7b24c9..c4447af2 100644 --- a/src/locale/locales/zh-CN/messages.po +++ b/src/locale/locales/zh-CN/messages.po @@ -76,7 +76,7 @@ msgid "A new version of the app is available. Please update to continue using th msgstr "App 新版本已发布,请更新以继续使用。" #: src/view/com/util/ViewHeader.tsx:83 -#: src/view/screens/Search/Search.tsx:624 +#: src/view/screens/Search/Search.tsx:647 msgid "Access navigation links and settings" msgstr "访问导航链接及设置" @@ -127,6 +127,7 @@ msgstr "已取消屏蔽账户" msgid "Account unmuted" msgstr "已取消隐藏账户" +#: src/components/dialogs/MutedWords.tsx:147 #: src/view/com/auth/onboarding/RecommendedFeedsItem.tsx:150 #: src/view/com/modals/ListAddRemoveUsers.tsx:264 #: src/view/com/modals/UserAddRemoveLists.tsx:219 @@ -168,14 +169,22 @@ msgstr "添加细节" msgid "Add details to report" msgstr "补充反馈详细内容" -#: src/view/com/composer/Composer.tsx:446 +#: src/view/com/composer/Composer.tsx:453 msgid "Add link card" msgstr "添加链接卡片" -#: src/view/com/composer/Composer.tsx:451 +#: src/view/com/composer/Composer.tsx:458 msgid "Add link card:" msgstr "添加链接卡片:" +#: src/components/dialogs/MutedWords.tsx:140 +msgid "Add mute word for configured settings" +msgstr "" + +#: src/components/dialogs/MutedWords.tsx:74 +msgid "Add muted words and tags" +msgstr "" + #: src/view/com/modals/ChangeHandle.tsx:417 msgid "Add the following DNS record to your domain:" msgstr "将以下DNS记录添加到你的域名:" @@ -295,7 +304,7 @@ msgstr "App 专用密码设置" msgid "App Passwords" msgstr "App 专用密码" -#: src/view/com/util/forms/PostDropdownBtn.tsx:279 +#: src/view/com/util/forms/PostDropdownBtn.tsx:295 msgid "Appeal content warning" msgstr "申诉内容警告" @@ -319,15 +328,16 @@ msgstr "外观" msgid "Are you sure you want to delete the app password \"{name}\"?" msgstr "你确定要删除这条 App 专用密码 \"{name}\"?" -#: src/view/com/composer/Composer.tsx:143 +#: src/view/com/composer/Composer.tsx:150 msgid "Are you sure you'd like to discard this draft?" msgstr "你确定要丢弃此草稿吗?" +#: src/components/dialogs/MutedWords.tsx:233 #: src/view/screens/ProfileList.tsx:365 msgid "Are you sure?" msgstr "你确定吗?" -#: src/view/com/util/forms/PostDropdownBtn.tsx:262 +#: src/view/com/util/forms/PostDropdownBtn.tsx:278 msgid "Are you sure? This cannot be undone." msgstr "你确定吗?此操作无法撤销。" @@ -349,15 +359,15 @@ msgstr "艺术作品或非色情的裸体。" #: src/view/com/auth/login/LoginForm.tsx:259 #: src/view/com/auth/login/SetNewPasswordForm.tsx:179 #: src/view/com/modals/report/InputIssueDetails.tsx:46 -#: src/view/com/post-thread/PostThread.tsx:471 -#: src/view/com/post-thread/PostThread.tsx:521 -#: src/view/com/post-thread/PostThread.tsx:529 +#: src/view/com/post-thread/PostThread.tsx:472 +#: src/view/com/post-thread/PostThread.tsx:522 +#: src/view/com/post-thread/PostThread.tsx:530 #: src/view/com/profile/ProfileHeader.tsx:649 #: src/view/com/util/ViewHeader.tsx:81 msgid "Back" msgstr "返回" -#: src/view/com/post-thread/PostThread.tsx:479 +#: src/view/com/post-thread/PostThread.tsx:480 msgctxt "action" msgid "Back" msgstr "返回" @@ -405,7 +415,7 @@ msgstr "屏蔽这个列表" msgid "Blocked" msgstr "已屏蔽" -#: src/view/screens/Moderation.tsx:123 +#: src/view/screens/Moderation.tsx:142 msgid "Blocked accounts" msgstr "已屏蔽账户" @@ -464,7 +474,7 @@ msgstr "Bluesky 为公众而生。" msgid "Bluesky uses invites to build a healthier community. If you don't know anybody with an invite, you can sign up for the waitlist and we'll send one soon." msgstr "Bluesky 使用邀请制来打造更健康的社群环境。 如果你不认识拥有邀请码的人,你可以先填写并提交候补列表,我们会尽快审核并发送邀请码。" -#: src/view/screens/Moderation.tsx:226 +#: src/view/screens/Moderation.tsx:245 msgid "Bluesky will not show your profile and posts to logged-out users. Other apps may not honor this request. This does not make your account private." msgstr "Bluesky 不会向未登录的用户显示你的个人资料和帖子。但其他应用可能不会遵照此请求,这无法确保你的账户隐私。" @@ -516,8 +526,8 @@ msgid "Can only contain letters, numbers, spaces, dashes, and underscores. Must msgstr "只能包含字母、数字、空格、破折号及下划线。 长度必须至少 4 个字符,但不超过 32 个字符。" #: src/components/Prompt.tsx:91 -#: src/view/com/composer/Composer.tsx:300 -#: src/view/com/composer/Composer.tsx:305 +#: src/view/com/composer/Composer.tsx:307 +#: src/view/com/composer/Composer.tsx:312 #: src/view/com/modals/ChangeEmail.tsx:218 #: src/view/com/modals/ChangeEmail.tsx:220 #: src/view/com/modals/ChangePassword.tsx:265 @@ -531,7 +541,7 @@ msgstr "只能包含字母、数字、空格、破折号及下划线。 长度 #: src/view/com/modals/VerifyEmail.tsx:247 #: src/view/com/modals/VerifyEmail.tsx:253 #: src/view/com/modals/Waitlist.tsx:142 -#: src/view/screens/Search/Search.tsx:693 +#: src/view/screens/Search/Search.tsx:716 #: src/view/shell/desktop/Search.tsx:238 msgid "Cancel" msgstr "取消" @@ -678,7 +688,7 @@ msgid "Clear all storage data (restart after this)" msgstr "清除所有数据(并重启)" #: src/view/com/util/forms/SearchInput.tsx:88 -#: src/view/screens/Search/Search.tsx:674 +#: src/view/screens/Search/Search.tsx:697 msgid "Clear search query" msgstr "清除搜索历史记录" @@ -686,6 +696,11 @@ msgstr "清除搜索历史记录" msgid "click here" msgstr "点击这里" +#: src/components/RichText.tsx:189 +#: src/components/TagMenu/index.web.tsx:125 +msgid "Click here to open tag menu for {tag}" +msgstr "" + #: src/screens/Onboarding/index.tsx:35 msgid "Climate" msgstr "气象" @@ -716,11 +731,15 @@ msgstr "关闭图片" msgid "Close image viewer" msgstr "关闭图片查看器" -#: src/view/shell/index.web.tsx:49 +#: src/view/shell/index.web.tsx:51 msgid "Close navigation footer" msgstr "关闭导航页脚" -#: src/view/shell/index.web.tsx:50 +#: src/components/TagMenu/index.tsx:266 +msgid "Close this dialog" +msgstr "" + +#: src/view/shell/index.web.tsx:52 msgid "Closes bottom navigation bar" msgstr "关闭底栏" @@ -728,7 +747,7 @@ msgstr "关闭底栏" msgid "Closes password update alert" msgstr "关闭密码更新警告" -#: src/view/com/composer/Composer.tsx:302 +#: src/view/com/composer/Composer.tsx:309 msgid "Closes post composer and discards post draft" msgstr "关闭帖子编辑页并丢弃草稿" @@ -761,7 +780,7 @@ msgstr "完成引导并开始使用你的账户" msgid "Complete the challenge" msgstr "" -#: src/view/com/composer/Composer.tsx:417 +#: src/view/com/composer/Composer.tsx:424 msgid "Compose posts up to {MAX_GRAPHEME_LENGTH} characters in length" msgstr "撰写帖子的长度最多为 {MAX_GRAPHEME_LENGTH} 个字符" @@ -825,7 +844,7 @@ msgstr "连接中..." msgid "Contact support" msgstr "联系支持" -#: src/view/screens/Moderation.tsx:81 +#: src/view/screens/Moderation.tsx:83 msgid "Content filtering" msgstr "内容过滤" @@ -891,7 +910,7 @@ msgstr "已复制构建版本号至剪贴板" #: src/view/com/modals/AddAppPasswords.tsx:76 #: src/view/com/modals/InviteCodes.tsx:152 -#: src/view/com/util/forms/PostDropdownBtn.tsx:141 +#: src/view/com/util/forms/PostDropdownBtn.tsx:143 msgid "Copied to clipboard" msgstr "已复制至剪贴板" @@ -907,7 +926,7 @@ msgstr "复制" msgid "Copy link to list" msgstr "复制列表链接" -#: src/view/com/util/forms/PostDropdownBtn.tsx:182 +#: src/view/com/util/forms/PostDropdownBtn.tsx:184 msgid "Copy link to post" msgstr "复制帖子链接" @@ -915,7 +934,7 @@ msgstr "复制帖子链接" msgid "Copy link to profile" msgstr "复制个人资料链接" -#: src/view/com/util/forms/PostDropdownBtn.tsx:168 +#: src/view/com/util/forms/PostDropdownBtn.tsx:170 msgid "Copy post text" msgstr "复制帖子文字" @@ -971,7 +990,7 @@ msgstr "由 <0/> 创建" msgid "Created by you" msgstr "由你创建" -#: src/view/com/composer/Composer.tsx:448 +#: src/view/com/composer/Composer.tsx:455 msgid "Creates a card with a thumbnail. The card links to {url}" msgstr "创建带有缩略图的卡片。该卡片链接到 {url}" @@ -1048,11 +1067,11 @@ msgstr "删除我的账户" msgid "Delete My Account…" msgstr "删除我的账户…" -#: src/view/com/util/forms/PostDropdownBtn.tsx:257 +#: src/view/com/util/forms/PostDropdownBtn.tsx:273 msgid "Delete post" msgstr "删除帖子" -#: src/view/com/util/forms/PostDropdownBtn.tsx:261 +#: src/view/com/util/forms/PostDropdownBtn.tsx:277 msgid "Delete this post?" msgstr "删除这条帖子?" @@ -1075,7 +1094,7 @@ msgstr "描述" #~ msgid "Developer Tools" #~ msgstr "开发者工具" -#: src/view/com/composer/Composer.tsx:211 +#: src/view/com/composer/Composer.tsx:218 msgid "Did you want to say anything?" msgstr "有什么想说的吗?" @@ -1083,15 +1102,15 @@ msgstr "有什么想说的吗?" msgid "Dim" msgstr "暗淡" -#: src/view/com/composer/Composer.tsx:144 +#: src/view/com/composer/Composer.tsx:151 msgid "Discard" msgstr "丢弃" -#: src/view/com/composer/Composer.tsx:138 +#: src/view/com/composer/Composer.tsx:145 msgid "Discard draft" msgstr "丢弃草稿" -#: src/view/screens/Moderation.tsx:207 +#: src/view/screens/Moderation.tsx:226 msgid "Discourage apps from showing my account to logged-out users" msgstr "阻止应用向未登录用户显示我的账户" @@ -1170,7 +1189,7 @@ msgstr "" msgid "Download CAR file" msgstr "" -#: src/view/com/composer/text-input/TextInput.web.tsx:247 +#: src/view/com/composer/text-input/TextInput.web.tsx:249 msgid "Drop to add images" msgstr "拖放即可添加图片" @@ -1242,6 +1261,7 @@ msgstr "编辑资料" msgid "Edit Profile" msgstr "编辑资料" +#: src/view/com/home/HomeHeaderLayout.web.tsx:59 #: src/view/screens/Feeds.tsx:355 msgid "Edit Saved Feeds" msgstr "编辑保存的信息流" @@ -1324,6 +1344,11 @@ msgstr "结束信息流" msgid "Enter a name for this App Password" msgstr "为此 App 专用密码命名" +#: src/components/dialogs/MutedWords.tsx:87 +#: src/components/dialogs/MutedWords.tsx:88 +msgid "Enter a word or tag" +msgstr "" + #: src/view/com/modals/VerifyEmail.tsx:105 msgid "Enter Confirmation Code" msgstr "输入验证码" @@ -1373,7 +1398,7 @@ msgstr "输入你的用户名和密码" msgid "Error receiving captcha response." msgstr "" -#: src/view/screens/Search/Search.tsx:109 +#: src/view/screens/Search/Search.tsx:110 msgid "Error:" msgstr "错误:" @@ -1444,7 +1469,7 @@ msgstr "创建 App 专用密码失败。" msgid "Failed to create the list. Check your internet connection and try again." msgstr "无法创建列表。请检查你的互联网连接并重试。" -#: src/view/com/util/forms/PostDropdownBtn.tsx:108 +#: src/view/com/util/forms/PostDropdownBtn.tsx:110 msgid "Failed to delete post, please try again" msgstr "无法删除帖子,请重试" @@ -1466,8 +1491,8 @@ msgid "Feed offline" msgstr "信息流已离线" #: src/view/com/feeds/FeedPage.tsx:143 -msgid "Feed Preferences" -msgstr "信息流首选项" +#~ msgid "Feed Preferences" +#~ msgstr "信息流首选项" #: src/view/shell/desktop/RightNav.tsx:61 #: src/view/shell/Drawer.tsx:311 @@ -1511,11 +1536,11 @@ msgstr "最终确定" msgid "Find accounts to follow" msgstr "寻找一些账户关注" -#: src/view/screens/Search/Search.tsx:439 +#: src/view/screens/Search/Search.tsx:440 msgid "Find users on Bluesky" msgstr "寻找一些正在使用 Bluesky 的用户" -#: src/view/screens/Search/Search.tsx:437 +#: src/view/screens/Search/Search.tsx:438 msgid "Find users with the search tool on the right" msgstr "使用右侧的工具来搜索用户" @@ -1612,6 +1637,7 @@ msgid "Following {0}" msgstr "正在关注 {0}" #: src/Navigation.tsx:248 +#: src/view/com/home/HomeHeaderLayout.web.tsx:45 #: src/view/com/home/HomeHeaderLayoutMobile.tsx:83 #: src/view/screens/PreferencesFollowingFeed.tsx:104 #: src/view/screens/Settings/index.tsx:543 @@ -1651,7 +1677,7 @@ msgstr "忘记密码" msgid "Forgot Password" msgstr "忘记密码" -#: src/view/com/posts/FeedItem.tsx:187 +#: src/view/com/posts/FeedItem.tsx:189 msgctxt "from-feed" msgid "From <0/>" msgstr "来自 <0/>" @@ -1684,7 +1710,7 @@ msgstr "返回" msgid "Go back to previous step" msgstr "返回上一步" -#: src/view/screens/Search/Search.tsx:724 +#: src/view/screens/Search/Search.tsx:747 #: src/view/shell/desktop/Search.tsx:262 msgid "Go to @{queryMaybeHandle}" msgstr "转到 @{queryMaybeHandle}" @@ -1701,6 +1727,10 @@ msgstr "转到下一个" msgid "Handle" msgstr "用户识别符" +#: src/components/RichText.tsx:188 +msgid "Hashtag: {tag}" +msgstr "" + #: src/view/com/auth/create/CreateAccount.tsx:208 msgid "Having trouble?" msgstr "任何疑问?" @@ -1739,7 +1769,7 @@ msgctxt "action" msgid "Hide" msgstr "隐藏" -#: src/view/com/util/forms/PostDropdownBtn.tsx:216 +#: src/view/com/util/forms/PostDropdownBtn.tsx:232 msgid "Hide post" msgstr "隐藏帖子" @@ -1748,7 +1778,7 @@ msgstr "隐藏帖子" msgid "Hide the content" msgstr "隐藏内容" -#: src/view/com/util/forms/PostDropdownBtn.tsx:220 +#: src/view/com/util/forms/PostDropdownBtn.tsx:236 msgid "Hide this post?" msgstr "隐藏这条帖子?" @@ -1897,7 +1927,7 @@ msgstr "输入你的密码" msgid "Input your user handle" msgstr "输入你的用户识别符" -#: src/view/com/post-thread/PostThreadItem.tsx:224 +#: src/view/com/post-thread/PostThreadItem.tsx:226 msgid "Invalid or unsupported post record" msgstr "帖子记录无效或不受支持" @@ -1999,7 +2029,7 @@ msgstr "了解详情" msgid "Learn more about this warning" msgstr "了解关于这个警告的更多详情" -#: src/view/screens/Moderation.tsx:243 +#: src/view/screens/Moderation.tsx:262 msgid "Learn more about what is public on Bluesky." msgstr "了解有关 Bluesky 公开内容的更多详情。" @@ -2075,7 +2105,7 @@ msgstr "点赞你的帖子" msgid "Likes" msgstr "点赞" -#: src/view/com/post-thread/PostThreadItem.tsx:181 +#: src/view/com/post-thread/PostThreadItem.tsx:183 msgid "Likes on this post" msgstr "点赞这条帖子" @@ -2132,7 +2162,7 @@ msgstr "加载更多帖子" msgid "Load new notifications" msgstr "加载新的通知" -#: src/view/com/feeds/FeedPage.tsx:181 +#: src/view/com/feeds/FeedPage.tsx:115 #: src/view/screens/Profile.tsx:440 #: src/view/screens/ProfileFeed.tsx:495 #: src/view/screens/ProfileList.tsx:681 @@ -2158,7 +2188,7 @@ msgstr "日志" msgid "Log out" msgstr "登出" -#: src/view/screens/Moderation.tsx:136 +#: src/view/screens/Moderation.tsx:155 msgid "Logged-out visibility" msgstr "未登录用户可见性" @@ -2170,6 +2200,10 @@ msgstr "登录未列出的账户" msgid "Make sure this is where you intend to go!" msgstr "请确认!" +#: src/components/dialogs/MutedWords.tsx:71 +msgid "Manage your muted words and tags" +msgstr "" + #: src/view/com/auth/create/Step2.tsx:118 msgid "May not be longer than 253 characters" msgstr "" @@ -2191,7 +2225,7 @@ msgid "Mentioned users" msgstr "提到的用户" #: src/view/com/util/ViewHeader.tsx:81 -#: src/view/screens/Search/Search.tsx:623 +#: src/view/screens/Search/Search.tsx:646 msgid "Menu" msgstr "菜单" @@ -2200,7 +2234,7 @@ msgid "Message from server: {0}" msgstr "来自服务器的信息:{0}" #: src/Navigation.tsx:115 -#: src/view/screens/Moderation.tsx:64 +#: src/view/screens/Moderation.tsx:66 #: src/view/screens/Settings/index.tsx:625 #: src/view/shell/desktop/LeftNav.tsx:397 #: src/view/shell/Drawer.tsx:511 @@ -2231,7 +2265,7 @@ msgstr "限制列表已创建" msgid "Moderation list updated" msgstr "限制列表已更新" -#: src/view/screens/Moderation.tsx:95 +#: src/view/screens/Moderation.tsx:114 msgid "Moderation lists" msgstr "限制列表" @@ -2258,7 +2292,7 @@ msgstr "更多信息流" msgid "More options" msgstr "更多选项" -#: src/view/com/util/forms/PostDropdownBtn.tsx:299 +#: src/view/com/util/forms/PostDropdownBtn.tsx:315 msgid "More post options" msgstr "更多帖子选项" @@ -2270,6 +2304,14 @@ msgstr "最多点赞优先" msgid "Must be at least 3 characters" msgstr "" +#: src/components/TagMenu/index.tsx:253 +msgid "Mute" +msgstr "" + +#: src/components/TagMenu/index.web.tsx:91 +msgid "Mute {truncatedTag}" +msgstr "" + #: src/view/com/profile/ProfileHeader.tsx:327 msgid "Mute Account" msgstr "隐藏账户" @@ -2278,6 +2320,18 @@ msgstr "隐藏账户" msgid "Mute accounts" msgstr "隐藏账户" +#: src/components/TagMenu/index.tsx:211 +msgid "Mute all {tag} posts" +msgstr "" + +#: src/components/dialogs/MutedWords.tsx:131 +msgid "Mute in tags only" +msgstr "" + +#: src/components/dialogs/MutedWords.tsx:116 +msgid "Mute in text & tags" +msgstr "" + #: src/view/screens/ProfileList.tsx:491 msgid "Mute list" msgstr "隐藏列表" @@ -2290,15 +2344,27 @@ msgstr "隐藏这些账户?" msgid "Mute this List" msgstr "隐藏这个列表" -#: src/view/com/util/forms/PostDropdownBtn.tsx:200 +#: src/components/dialogs/MutedWords.tsx:109 +msgid "Mute this word in post text and tags" +msgstr "" + +#: src/components/dialogs/MutedWords.tsx:124 +msgid "Mute this word in tags only" +msgstr "" + +#: src/view/com/util/forms/PostDropdownBtn.tsx:202 msgid "Mute thread" msgstr "隐藏讨论串" +#: src/view/com/util/forms/PostDropdownBtn.tsx:216 +msgid "Mute words & tags" +msgstr "" + #: src/view/com/lists/ListCard.tsx:102 msgid "Muted" msgstr "已隐藏" -#: src/view/screens/Moderation.tsx:109 +#: src/view/screens/Moderation.tsx:128 msgid "Muted accounts" msgstr "已隐藏账户" @@ -2311,6 +2377,10 @@ msgstr "已隐藏账户" msgid "Muted accounts have their posts removed from your feed and from your notifications. Mutes are completely private." msgstr "已隐藏的账户将不会在你的通知或时间线中显示,被隐藏账户将不会收到通知。" +#: src/view/screens/Moderation.tsx:100 +msgid "Muted words & tags" +msgstr "" + #: src/view/screens/ProfileList.tsx:277 msgid "Muting is private. Muted accounts can interact with you, but you will not see their posts or receive notifications from them." msgstr "被隐藏的账户将不会得知你已将他隐藏,已隐藏的账户将不会在你的通知或时间线中显示。" @@ -2374,6 +2444,10 @@ msgstr "永远不会失去对你的关注者和数据的访问。" msgid "Never lose access to your followers or data." msgstr "永远不会失去对你的关注者或数据的访问。" +#: src/components/dialogs/MutedWords.tsx:244 +msgid "Nevermind" +msgstr "" + #: src/view/screens/Lists.tsx:76 msgctxt "action" msgid "New" @@ -2395,7 +2469,7 @@ msgstr "新密码" msgid "New Password" msgstr "新密码" -#: src/view/com/feeds/FeedPage.tsx:192 +#: src/view/com/feeds/FeedPage.tsx:126 msgctxt "action" msgid "New post" msgstr "新帖子" @@ -2480,8 +2554,8 @@ msgid "No results found for \"{query}\"" msgstr "未找到\"{query}\"的结果" #: src/view/com/modals/ListAddRemoveUsers.tsx:127 -#: src/view/screens/Search/Search.tsx:280 -#: src/view/screens/Search/Search.tsx:308 +#: src/view/screens/Search/Search.tsx:281 +#: src/view/screens/Search/Search.tsx:309 msgid "No results found for {query}" msgstr "未找到 {query} 的结果" @@ -2507,7 +2581,7 @@ msgstr "未找到" msgid "Not right now" msgstr "不是现在" -#: src/view/screens/Moderation.tsx:233 +#: src/view/screens/Moderation.tsx:252 msgid "Note: Bluesky is an open and public network. This setting only limits the visibility of your content on the Bluesky app and website, and other apps may not respect this setting. Your content may still be shown to logged-out users by other apps and websites." msgstr "注意:Bluesky 是一个开放的公共网络。此设置项仅限制你的内容在 Bluesky 应用和网站上的可见性,其他应用可能不尊从此设置项,仍可能会向未登录的用户显示你的动态。" @@ -2545,7 +2619,7 @@ msgstr "最旧的回复优先" msgid "Onboarding reset" msgstr "重新开始引导流程" -#: src/view/com/composer/Composer.tsx:375 +#: src/view/com/composer/Composer.tsx:382 msgid "One or more images is missing alt text." msgstr "至少有一张图片缺失了替代文字。" @@ -2562,8 +2636,12 @@ msgstr "Oops!" msgid "Open" msgstr "打开" -#: src/view/com/composer/Composer.tsx:470 -#: src/view/com/composer/Composer.tsx:471 +#: src/view/screens/Moderation.tsx:75 +msgid "Open content filtering settings" +msgstr "" + +#: src/view/com/composer/Composer.tsx:477 +#: src/view/com/composer/Composer.tsx:478 msgid "Open emoji picker" msgstr "打开 emoji 选择器" @@ -2571,6 +2649,10 @@ msgstr "打开 emoji 选择器" msgid "Open links with in-app browser" msgstr "在内置浏览器中打开链接" +#: src/view/screens/Moderation.tsx:92 +msgid "Open muted words settings" +msgstr "" + #: src/view/com/home/HomeHeaderLayoutMobile.tsx:49 msgid "Open navigation" msgstr "打开导航" @@ -2647,6 +2729,7 @@ msgstr "打开限制设置" msgid "Opens password reset form" msgstr "打开密码重置申请" +#: src/view/com/home/HomeHeaderLayout.web.tsx:60 #: src/view/screens/Feeds.tsx:356 msgid "Opens screen to edit Saved Feeds" msgstr "打开用于编辑已保存信息流的界面" @@ -2822,7 +2905,7 @@ msgstr "请告诉我们你认为此内容警告被错误设置的原因!" msgid "Please Verify Your Email" msgstr "请验证你的电子邮箱" -#: src/view/com/composer/Composer.tsx:215 +#: src/view/com/composer/Composer.tsx:222 msgid "Please wait for your link card to finish loading" msgstr "请等待你的链接卡片加载完成" @@ -2834,8 +2917,8 @@ msgstr "政治" msgid "Porn" msgstr "色情内容" -#: src/view/com/composer/Composer.tsx:350 -#: src/view/com/composer/Composer.tsx:358 +#: src/view/com/composer/Composer.tsx:357 +#: src/view/com/composer/Composer.tsx:365 msgctxt "action" msgid "Post" msgstr "发布" @@ -2845,7 +2928,7 @@ msgctxt "description" msgid "Post" msgstr "发布" -#: src/view/com/post-thread/PostThreadItem.tsx:173 +#: src/view/com/post-thread/PostThreadItem.tsx:175 msgid "Post by {0}" msgstr "发布者 {0}" @@ -2855,11 +2938,11 @@ msgstr "发布者 {0}" msgid "Post by @{0}" msgstr "发布者 @{0}" -#: src/view/com/util/forms/PostDropdownBtn.tsx:88 +#: src/view/com/util/forms/PostDropdownBtn.tsx:90 msgid "Post deleted" msgstr "已删除帖子" -#: src/view/com/post-thread/PostThread.tsx:461 +#: src/view/com/post-thread/PostThread.tsx:462 msgid "Post hidden" msgstr "已隐藏帖子" @@ -2871,14 +2954,22 @@ msgstr "帖子语言" msgid "Post Languages" msgstr "帖子语言" -#: src/view/com/post-thread/PostThread.tsx:513 +#: src/view/com/post-thread/PostThread.tsx:514 msgid "Post not found" msgstr "无法找到帖子" +#: src/components/TagMenu/index.tsx:257 +msgid "posts" +msgstr "" + #: src/view/screens/Profile.tsx:180 msgid "Posts" msgstr "帖子" +#: src/components/dialogs/MutedWords.tsx:77 +msgid "Posts can be muted based on their text, their tags, or both." +msgstr "" + #: src/view/com/posts/FeedErrorMessage.tsx:64 msgid "Posts hidden" msgstr "已隐藏帖子" @@ -2943,11 +3034,11 @@ msgstr "公开且可共享的批量隐藏或屏蔽列表。" msgid "Public, shareable lists which can drive feeds." msgstr "公开且可共享的列表,可作为信息流使用。" -#: src/view/com/composer/Composer.tsx:335 +#: src/view/com/composer/Composer.tsx:342 msgid "Publish post" msgstr "发布帖子" -#: src/view/com/composer/Composer.tsx:335 +#: src/view/com/composer/Composer.tsx:342 msgid "Publish reply" msgstr "发布回复" @@ -2981,6 +3072,7 @@ msgstr "推荐信息流" msgid "Recommended Users" msgstr "推荐的用户" +#: src/components/dialogs/MutedWords.tsx:249 #: src/view/com/modals/ListAddRemoveUsers.tsx:264 #: src/view/com/modals/SelfLabel.tsx:83 #: src/view/com/modals/UserAddRemoveLists.tsx:219 @@ -3018,6 +3110,10 @@ msgstr "删除图片" msgid "Remove image preview" msgstr "删除图片预览" +#: src/components/dialogs/MutedWords.tsx:294 +msgid "Remove mute word from your list" +msgstr "" + #: src/view/com/modals/Repost.tsx:47 msgid "Remove repost" msgstr "删除转发" @@ -3052,7 +3148,7 @@ msgstr "回复" msgid "Replies to this thread are disabled" msgstr "对此讨论串的回复已被禁用" -#: src/view/com/composer/Composer.tsx:348 +#: src/view/com/composer/Composer.tsx:355 msgctxt "action" msgid "Reply" msgstr "回复" @@ -3062,7 +3158,7 @@ msgid "Reply Filters" msgstr "回复过滤器" #: src/view/com/post/Post.tsx:167 -#: src/view/com/posts/FeedItem.tsx:285 +#: src/view/com/posts/FeedItem.tsx:287 msgctxt "description" msgid "Reply to <0/>" msgstr "回复 <0/>" @@ -3084,7 +3180,7 @@ msgid "Report List" msgstr "举报列表" #: src/view/com/modals/report/SendReportButton.tsx:37 -#: src/view/com/util/forms/PostDropdownBtn.tsx:239 +#: src/view/com/util/forms/PostDropdownBtn.tsx:255 msgid "Report post" msgstr "举报帖子" @@ -3109,11 +3205,11 @@ msgstr "转发或引用帖子" msgid "Reposted By" msgstr "转发" -#: src/view/com/posts/FeedItem.tsx:205 +#: src/view/com/posts/FeedItem.tsx:207 msgid "Reposted by {0}" msgstr "由 {0} 转发" -#: src/view/com/posts/FeedItem.tsx:222 +#: src/view/com/posts/FeedItem.tsx:224 msgid "Reposted by <0/>" msgstr "由 <0/> 转发" @@ -3121,7 +3217,7 @@ msgstr "由 <0/> 转发" msgid "reposted your post" msgstr "转发你的帖子" -#: src/view/com/post-thread/PostThreadItem.tsx:186 +#: src/view/com/post-thread/PostThreadItem.tsx:188 msgid "Reposts of this post" msgstr "转发这条帖子" @@ -3272,9 +3368,9 @@ msgstr "滚动到顶部" #: src/view/com/modals/ListAddRemoveUsers.tsx:75 #: src/view/com/util/forms/SearchInput.tsx:67 #: src/view/com/util/forms/SearchInput.tsx:79 -#: src/view/screens/Search/Search.tsx:418 -#: src/view/screens/Search/Search.tsx:645 -#: src/view/screens/Search/Search.tsx:663 +#: src/view/screens/Search/Search.tsx:419 +#: src/view/screens/Search/Search.tsx:668 +#: src/view/screens/Search/Search.tsx:686 #: src/view/shell/bottom-bar/BottomBar.tsx:159 #: src/view/shell/desktop/LeftNav.tsx:324 #: src/view/shell/desktop/Search.tsx:214 @@ -3284,11 +3380,19 @@ msgstr "滚动到顶部" msgid "Search" msgstr "搜索" -#: src/view/screens/Search/Search.tsx:712 +#: src/view/screens/Search/Search.tsx:735 #: src/view/shell/desktop/Search.tsx:255 msgid "Search for \"{query}\"" msgstr "搜索 \"{query}\"" +#: src/components/TagMenu/index.tsx:145 +msgid "Search for all posts by @{authorHandle} with tag {tag}" +msgstr "" + +#: src/components/TagMenu/index.tsx:90 +msgid "Search for all posts with tag {tag}" +msgstr "" + #: src/view/com/auth/LoggedOut.tsx:104 #: src/view/com/auth/LoggedOut.tsx:105 #: src/view/com/modals/ListAddRemoveUsers.tsx:70 @@ -3299,6 +3403,22 @@ msgstr "搜索用户" msgid "Security Step Required" msgstr "所需的安全步骤" +#: src/components/TagMenu/index.web.tsx:50 +msgid "See {truncatedTag} posts" +msgstr "" + +#: src/components/TagMenu/index.web.tsx:67 +msgid "See {truncatedTag} posts by user" +msgstr "" + +#: src/components/TagMenu/index.tsx:128 +msgid "See <0>{tag} posts" +msgstr "" + +#: src/components/TagMenu/index.tsx:189 +msgid "See <0>{tag} posts by this user" +msgstr "" + #: src/view/screens/SavedFeeds.tsx:163 msgid "See this guide" msgstr "查看指南" @@ -3504,7 +3624,7 @@ msgid "Share" msgstr "分享" #: src/view/com/profile/ProfileHeader.tsx:295 -#: src/view/com/util/forms/PostDropdownBtn.tsx:182 +#: src/view/com/util/forms/PostDropdownBtn.tsx:184 #: src/view/screens/ProfileList.tsx:418 msgid "Share" msgstr "分享" @@ -3537,9 +3657,9 @@ msgstr "显示来自 {0} 的嵌入内容" msgid "Show follows similar to {0}" msgstr "显示类似于 {0} 的关注者" -#: src/view/com/post-thread/PostThreadItem.tsx:532 -#: src/view/com/post/Post.tsx:196 -#: src/view/com/posts/FeedItem.tsx:359 +#: src/view/com/post-thread/PostThreadItem.tsx:538 +#: src/view/com/post/Post.tsx:198 +#: src/view/com/posts/FeedItem.tsx:363 msgid "Show More" msgstr "显示更多" @@ -3707,7 +3827,7 @@ msgstr "程序开发" msgid "Something went wrong. Check your email and try again." msgstr "出了点问题,请检查你的电子邮箱并重试。" -#: src/App.native.tsx:61 +#: src/App.native.tsx:63 msgid "Sorry! Your session expired. Please log in again." msgstr "很抱歉,你的会话已过期,请重新登录。" @@ -3765,7 +3885,7 @@ msgstr "订阅 {0} 信息流" msgid "Subscribe to this list" msgstr "订阅这个列表" -#: src/view/screens/Search/Search.tsx:373 +#: src/view/screens/Search/Search.tsx:374 msgid "Suggested Follows" msgstr "推荐的关注者" @@ -3809,6 +3929,14 @@ msgstr "系统" msgid "System log" msgstr "系统日志" +#: src/components/dialogs/MutedWords.tsx:288 +msgid "tag" +msgstr "" + +#: src/components/TagMenu/index.tsx:74 +msgid "Tag menu: {tag}" +msgstr "" + #: src/view/com/modals/crop-image/CropImage.web.tsx:112 msgid "Tall" msgstr "高" @@ -3832,6 +3960,10 @@ msgstr "条款" msgid "Terms of Service" msgstr "服务条款" +#: src/components/dialogs/MutedWords.tsx:288 +msgid "text" +msgstr "" + #: src/view/com/modals/AppealLabel.tsx:70 #: src/view/com/modals/report/InputIssueDetails.tsx:51 msgid "Text input field" @@ -3857,7 +3989,7 @@ msgstr "版权许可已迁移至 <0/>" msgid "The following steps will help customize your Bluesky experience." msgstr "以下步骤将帮助定制你的 Bluesky 体验。" -#: src/view/com/post-thread/PostThread.tsx:516 +#: src/view/com/post-thread/PostThread.tsx:517 msgid "The post may have been deleted." msgstr "此帖子似乎已被删除。" @@ -4023,7 +4155,7 @@ msgstr "此列表为空!" msgid "This name is already in use" msgstr "该名称已被使用" -#: src/view/com/post-thread/PostThreadItem.tsx:123 +#: src/view/com/post-thread/PostThreadItem.tsx:125 msgid "This post has been deleted." msgstr "此帖已被删除。" @@ -4047,7 +4179,11 @@ msgstr "此用户包含在你已隐藏的 <0/> 列表中。" msgid "This warning is only available for posts with media attached." msgstr "此警告仅适用于附带媒体的帖子。" -#: src/view/com/util/forms/PostDropdownBtn.tsx:221 +#: src/components/dialogs/MutedWords.tsx:236 +msgid "This will delete {0} from your muted words. You can always add it back later." +msgstr "" + +#: src/view/com/util/forms/PostDropdownBtn.tsx:237 msgid "This will hide this post from your feeds." msgstr "这将在你的信息流中隐藏此帖子。" @@ -4064,6 +4200,10 @@ msgstr "分层模式" msgid "Threads Preferences" msgstr "讨论串首选项" +#: src/components/dialogs/MutedWords.tsx:95 +msgid "Toggle between muted word options." +msgstr "" + #: src/view/com/util/forms/DropdownButton.tsx:246 msgid "Toggle dropdown" msgstr "切换下拉菜单" @@ -4072,9 +4212,9 @@ msgstr "切换下拉菜单" msgid "Transformations" msgstr "转换" -#: src/view/com/post-thread/PostThreadItem.tsx:679 -#: src/view/com/post-thread/PostThreadItem.tsx:681 -#: src/view/com/util/forms/PostDropdownBtn.tsx:154 +#: src/view/com/post-thread/PostThreadItem.tsx:685 +#: src/view/com/post-thread/PostThreadItem.tsx:687 +#: src/view/com/util/forms/PostDropdownBtn.tsx:156 msgid "Translate" msgstr "翻译" @@ -4139,15 +4279,24 @@ msgstr "很遗憾,你不符合创建账户的要求。" msgid "Unlike" msgstr "取消喜欢" +#: src/components/TagMenu/index.tsx:253 #: src/view/screens/ProfileList.tsx:597 msgid "Unmute" msgstr "取消隐藏" +#: src/components/TagMenu/index.web.tsx:90 +msgid "Unmute {truncatedTag}" +msgstr "" + #: src/view/com/profile/ProfileHeader.tsx:326 msgid "Unmute Account" msgstr "取消隐藏账户" -#: src/view/com/util/forms/PostDropdownBtn.tsx:200 +#: src/components/TagMenu/index.tsx:210 +msgid "Unmute all {tag} posts" +msgstr "" + +#: src/view/com/util/forms/PostDropdownBtn.tsx:202 msgid "Unmute thread" msgstr "取消隐藏讨论串" @@ -4344,6 +4493,10 @@ msgstr "我们希望你在此度过愉快的时光。请记住,Bluesky 是:" msgid "We ran out of posts from your follows. Here's the latest from <0/>." msgstr "我们已经看完了你关注的帖子。这是来自 <0/> 的最新消息。" +#: src/components/dialogs/MutedWords.tsx:161 +msgid "We recommend avoiding common words that appear in many posts, since it can result in no posts being shown." +msgstr "" + #: src/screens/Onboarding/StepAlgoFeeds/index.tsx:124 msgid "We recommend our \"Discover\" feed:" msgstr "我们推荐我们的 \"Discover\" 信息流:" @@ -4372,7 +4525,11 @@ msgstr "我们非常高兴你加入我们!" msgid "We're sorry, but we were unable to resolve this list. If this persists, please contact the list creator, @{handleOrDid}." msgstr "很抱歉,我们无法解析此列表。如果问题持续发生,请联系列表创建者,@{handleOrDid}。" -#: src/view/screens/Search/Search.tsx:253 +#: src/components/dialogs/MutedWords.tsx:182 +msgid "We're sorry, but we weren't able to load your muted words at this time. Please try again." +msgstr "" + +#: src/view/screens/Search/Search.tsx:254 msgid "We're sorry, but your search could not be completed. Please try again in a few minutes." msgstr "很抱歉,无法完成你的搜索。请稍后再试。" @@ -4393,7 +4550,7 @@ msgid "What is the issue with this {collectionName}?" msgstr "这个 {collectionName} 有什么问题?" #: src/view/com/auth/SplashScreen.tsx:59 -#: src/view/com/composer/Composer.tsx:279 +#: src/view/com/composer/Composer.tsx:286 msgid "What's up?" msgstr "发生了什么新鲜事?" @@ -4414,11 +4571,11 @@ msgstr "谁可以回复" msgid "Wide" msgstr "宽" -#: src/view/com/composer/Composer.tsx:415 +#: src/view/com/composer/Composer.tsx:422 msgid "Write post" msgstr "撰写帖子" -#: src/view/com/composer/Composer.tsx:278 +#: src/view/com/composer/Composer.tsx:285 #: src/view/com/composer/Prompt.tsx:33 msgid "Write your reply" msgstr "撰写你的回复" @@ -4475,7 +4632,7 @@ msgstr "你目前还没有任何保存的信息流!" msgid "You don't have any saved feeds." msgstr "你目前还没有任何保存的信息流。" -#: src/view/com/post-thread/PostThread.tsx:464 +#: src/view/com/post-thread/PostThread.tsx:465 msgid "You have blocked the author or you have been blocked by the author." msgstr "你已屏蔽该作者,或你已被该作者屏蔽。" @@ -4515,6 +4672,10 @@ msgstr "你尚未创建任何 App 专用密码,可以通过点击下面的按 msgid "You have not muted any accounts yet. To mute an account, go to their profile and selected \"Mute account\" from the menu on their account." msgstr "你还没有隐藏任何账号。要隐藏账号,请转到其个人资料并在其账号上的菜单中选择 \"隐藏账号\"。" +#: src/components/dialogs/MutedWords.tsx:202 +msgid "You haven't muted any words or tags yet" +msgstr "" + #: src/view/com/modals/ContentFilteringSettings.tsx:175 msgid "You must be 18 or older to enable adult content." msgstr "你必须年满18岁及以上才能启用成人内容。" @@ -4523,11 +4684,11 @@ msgstr "你必须年满18岁及以上才能启用成人内容。" msgid "You must be 18 years or older to enable adult content" msgstr "你必须年满18岁及以上才能启用成人内容" -#: src/view/com/util/forms/PostDropdownBtn.tsx:127 +#: src/view/com/util/forms/PostDropdownBtn.tsx:129 msgid "You will no longer receive notifications for this thread" msgstr "你将不再收到这条讨论串的通知" -#: src/view/com/util/forms/PostDropdownBtn.tsx:130 +#: src/view/com/util/forms/PostDropdownBtn.tsx:132 msgid "You will now receive notifications for this thread" msgstr "你将收到这条讨论串的通知" @@ -4613,11 +4774,15 @@ msgstr "你的完整用户识别符将修改为 <0>@{0}" #~ msgid "Your invite codes are hidden when logged in using an App Password" #~ msgstr "在使用 App 专用密码登录时,你的邀请码将被隐藏" +#: src/components/dialogs/MutedWords.tsx:173 +msgid "Your muted words" +msgstr "" + #: src/view/com/modals/ChangePassword.tsx:155 msgid "Your password has been changed successfully!" msgstr "你的密码已更改成功!" -#: src/view/com/composer/Composer.tsx:267 +#: src/view/com/composer/Composer.tsx:274 msgid "Your post has been published" msgstr "你的帖子已发送" @@ -4632,7 +4797,7 @@ msgstr "你的帖子、点赞和屏蔽是公开可见的,而隐藏不可见。 msgid "Your profile" msgstr "你的个人资料" -#: src/view/com/composer/Composer.tsx:266 +#: src/view/com/composer/Composer.tsx:273 msgid "Your reply has been published" msgstr "你的回复已发送" From 259468b7d5595766f19137d848ad05079a308037 Mon Sep 17 00:00:00 2001 From: Paul Frazee Date: Tue, 27 Feb 2024 18:29:59 -0800 Subject: [PATCH 22/43] Change application group to group.app.bsky --- modules/Share-with-Bluesky/Share-with-Bluesky.entitlements | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/Share-with-Bluesky/Share-with-Bluesky.entitlements b/modules/Share-with-Bluesky/Share-with-Bluesky.entitlements index 22ca9157..d2253d31 100644 --- a/modules/Share-with-Bluesky/Share-with-Bluesky.entitlements +++ b/modules/Share-with-Bluesky/Share-with-Bluesky.entitlements @@ -4,7 +4,7 @@ com.apple.security.application-groups - group.xyz.blueskyweb.app + group.app.bsky From ed2e6d654e4736b0b15ba4dafd062f850b329774 Mon Sep 17 00:00:00 2001 From: Hailey Date: Tue, 27 Feb 2024 18:34:09 -0800 Subject: [PATCH 23/43] Fix entitlements (#3008) --- plugins/shareExtension/withExtensionEntitlements.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/shareExtension/withExtensionEntitlements.js b/plugins/shareExtension/withExtensionEntitlements.js index e6bbf9d2..ffb767b5 100644 --- a/plugins/shareExtension/withExtensionEntitlements.js +++ b/plugins/shareExtension/withExtensionEntitlements.js @@ -14,7 +14,7 @@ const withExtensionEntitlements = (config, {extensionName}) => { const shareExtensionEntitlements = { 'com.apple.security.application-groups': [ - `group.${config.ios?.bundleIdentifier}`, + `group.bsky.app`, ], } From 622d0daad6171ce2fc1c4d7b1f89e04364924c57 Mon Sep 17 00:00:00 2001 From: Paul Frazee Date: Tue, 27 Feb 2024 18:41:53 -0800 Subject: [PATCH 24/43] More entitlement fixes --- plugins/shareExtension/withAppEntitlements.js | 2 +- plugins/shareExtension/withExtensionEntitlements.js | 4 +--- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/plugins/shareExtension/withAppEntitlements.js b/plugins/shareExtension/withAppEntitlements.js index 6f9136c3..e6909154 100644 --- a/plugins/shareExtension/withAppEntitlements.js +++ b/plugins/shareExtension/withAppEntitlements.js @@ -4,7 +4,7 @@ const withAppEntitlements = config => { // eslint-disable-next-line no-shadow return withEntitlementsPlist(config, async config => { config.modResults['com.apple.security.application-groups'] = [ - `group.${config.ios.bundleIdentifier}`, + `group.bsky.app`, ] return config }) diff --git a/plugins/shareExtension/withExtensionEntitlements.js b/plugins/shareExtension/withExtensionEntitlements.js index ffb767b5..f647c97c 100644 --- a/plugins/shareExtension/withExtensionEntitlements.js +++ b/plugins/shareExtension/withExtensionEntitlements.js @@ -13,9 +13,7 @@ const withExtensionEntitlements = (config, {extensionName}) => { ) const shareExtensionEntitlements = { - 'com.apple.security.application-groups': [ - `group.bsky.app`, - ], + 'com.apple.security.application-groups': [`group.bsky.app`], } fs.mkdirSync(path.dirname(extensionEntitlementsPath), { From 00ac76d0fe8f85704f5bd429caf6faa61d01e215 Mon Sep 17 00:00:00 2001 From: Paul Frazee Date: Tue, 27 Feb 2024 19:40:22 -0800 Subject: [PATCH 25/43] Fix group id --- plugins/shareExtension/withAppEntitlements.js | 2 +- plugins/shareExtension/withExtensionEntitlements.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/plugins/shareExtension/withAppEntitlements.js b/plugins/shareExtension/withAppEntitlements.js index e6909154..4ce81ea6 100644 --- a/plugins/shareExtension/withAppEntitlements.js +++ b/plugins/shareExtension/withAppEntitlements.js @@ -4,7 +4,7 @@ const withAppEntitlements = config => { // eslint-disable-next-line no-shadow return withEntitlementsPlist(config, async config => { config.modResults['com.apple.security.application-groups'] = [ - `group.bsky.app`, + `group.app.bsky`, ] return config }) diff --git a/plugins/shareExtension/withExtensionEntitlements.js b/plugins/shareExtension/withExtensionEntitlements.js index f647c97c..7bee79d1 100644 --- a/plugins/shareExtension/withExtensionEntitlements.js +++ b/plugins/shareExtension/withExtensionEntitlements.js @@ -13,7 +13,7 @@ const withExtensionEntitlements = (config, {extensionName}) => { ) const shareExtensionEntitlements = { - 'com.apple.security.application-groups': [`group.bsky.app`], + 'com.apple.security.application-groups': [`group.app.bsky`], } fs.mkdirSync(path.dirname(extensionEntitlementsPath), { From c4d30a0b7fb3e73b208a01d0f62130535d549392 Mon Sep 17 00:00:00 2001 From: Hailey Date: Tue, 27 Feb 2024 19:48:04 -0800 Subject: [PATCH 26/43] =?UTF-8?q?please=20=F0=9F=99=8F=20(#3010)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- plugins/shareExtension/withXcodeTarget.js | 1 + 1 file changed, 1 insertion(+) diff --git a/plugins/shareExtension/withXcodeTarget.js b/plugins/shareExtension/withXcodeTarget.js index 4f43c092..69462469 100644 --- a/plugins/shareExtension/withXcodeTarget.js +++ b/plugins/shareExtension/withXcodeTarget.js @@ -44,6 +44,7 @@ const withXcodeTarget = (config, {extensionName, controllerName}) => { buildSettingsObj.SWIFT_EMIT_LOC_STRINGS = 'YES' buildSettingsObj.SWIFT_VERSION = '5.0' buildSettingsObj.TARGETED_DEVICE_FAMILY = `"1,2"` + buildSettingsObj.DEVELOPMENT_TEAM = 'B3LX46C5HS' } } } From 2a60faf4fef206ba4817c59eec46989af4a9f905 Mon Sep 17 00:00:00 2001 From: Hailey Date: Tue, 27 Feb 2024 20:34:11 -0800 Subject: [PATCH 27/43] add dev team (#3011) --- plugins/shareExtension/withXcodeTarget.js | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/plugins/shareExtension/withXcodeTarget.js b/plugins/shareExtension/withXcodeTarget.js index 69462469..ce70b392 100644 --- a/plugins/shareExtension/withXcodeTarget.js +++ b/plugins/shareExtension/withXcodeTarget.js @@ -49,6 +49,13 @@ const withXcodeTarget = (config, {extensionName, controllerName}) => { } } + pbxProject.addTargetAttribute( + 'DevelopmentTeam', + 'B3LX46C5HS', + extensionName, + ) + pbxProject.addTargetAttribute('DevelopmentTeam', 'B3LX46C5HS') + return config }) } From ffeef8fd49da590a4b5f7bb8b0418ec3b94709c9 Mon Sep 17 00:00:00 2001 From: Hailey Date: Tue, 27 Feb 2024 20:54:12 -0800 Subject: [PATCH 28/43] update config (#3012) --- app.config.js | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/app.config.js b/app.config.js index fa9735dc..2a1100b9 100644 --- a/app.config.js +++ b/app.config.js @@ -145,6 +145,18 @@ module.exports = function (config) { ].filter(Boolean), extra: { eas: { + build: { + experimental: { + ios: { + appExtensions: [ + { + targetName: 'Share-with-Bluesky', + bundleIdentifier: 'xyz.blueskyweb.app.Share-with-Bluesky', + }, + ], + }, + }, + }, projectId: '55bd077a-d905-4184-9c7f-94789ba0f302', }, }, From ba667af80e8c23603b23a03f11d05e8b3324f9ca Mon Sep 17 00:00:00 2001 From: Hailey Date: Tue, 27 Feb 2024 21:09:59 -0800 Subject: [PATCH 29/43] add entitlements (#3013) --- app.config.js | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/app.config.js b/app.config.js index 2a1100b9..04b186bf 100644 --- a/app.config.js +++ b/app.config.js @@ -65,6 +65,9 @@ module.exports = function (config) { ...SPLASH_CONFIG, dark: DARK_SPLASH_CONFIG, }, + entitlements: { + 'com.apple.security.application-groups': 'group.app.bsky', + }, }, androidStatusBar: { barStyle: 'dark-content', @@ -152,6 +155,9 @@ module.exports = function (config) { { targetName: 'Share-with-Bluesky', bundleIdentifier: 'xyz.blueskyweb.app.Share-with-Bluesky', + entitlements: { + 'com.apple.security.application-groups': 'group.app.bsky', + }, }, ], }, From e2ae534fde4a351ac4c8ebf18a492f0fc6ab7abc Mon Sep 17 00:00:00 2001 From: Paul Frazee Date: Tue, 27 Feb 2024 21:11:48 -0800 Subject: [PATCH 30/43] Fix app config --- app.config.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/app.config.js b/app.config.js index 04b186bf..a18addcc 100644 --- a/app.config.js +++ b/app.config.js @@ -156,7 +156,9 @@ module.exports = function (config) { targetName: 'Share-with-Bluesky', bundleIdentifier: 'xyz.blueskyweb.app.Share-with-Bluesky', entitlements: { - 'com.apple.security.application-groups': 'group.app.bsky', + 'com.apple.security.application-groups': [ + 'group.app.bsky', + ], }, }, ], From 88c66c4bc52336bc8f32c99eb178b0769c4bfe67 Mon Sep 17 00:00:00 2001 From: Hailey Date: Wed, 28 Feb 2024 07:58:13 -0800 Subject: [PATCH 31/43] fix app group in native code (#3014) --- modules/Share-with-Bluesky/ShareViewController.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/Share-with-Bluesky/ShareViewController.swift b/modules/Share-with-Bluesky/ShareViewController.swift index a16a290b..4c1d635c 100644 --- a/modules/Share-with-Bluesky/ShareViewController.swift +++ b/modules/Share-with-Bluesky/ShareViewController.swift @@ -119,7 +119,7 @@ class ShareViewController: UIViewController { // extension does. if let dir = FileManager() .containerURL( - forSecurityApplicationGroupIdentifier: "group.\(Bundle.main.bundleIdentifier?.replacingOccurrences(of: ".Share-with-Bluesky", with: "") ?? "")") + forSecurityApplicationGroupIdentifier: "group.app.bsky") { let filePath = "\(dir.absoluteString)\(ProcessInfo.processInfo.globallyUniqueString).jpeg" From 0dd3f9432b061359492f18eda84638f26863f640 Mon Sep 17 00:00:00 2001 From: dan Date: Wed, 28 Feb 2024 16:04:51 +0000 Subject: [PATCH 32/43] Fix wrong feed being shown (#3015) --- src/state/queries/feed.ts | 127 ++++++++++++------------------- src/view/com/home/HomeHeader.tsx | 15 +++- src/view/screens/Home.tsx | 5 +- src/view/shell/desktop/Feeds.tsx | 6 +- 4 files changed, 68 insertions(+), 85 deletions(-) diff --git a/src/state/queries/feed.ts b/src/state/queries/feed.ts index 67294ece..1fa92c29 100644 --- a/src/state/queries/feed.ts +++ b/src/state/queries/feed.ts @@ -1,11 +1,9 @@ -import React from 'react' import { useQuery, useInfiniteQuery, InfiniteData, QueryKey, useMutation, - useQueryClient, } from '@tanstack/react-query' import { AtUri, @@ -15,7 +13,6 @@ import { AppBskyUnspeccedGetPopularFeedGenerators, } from '@atproto/api' -import {logger} from '#/logger' import {router} from '#/routes' import {sanitizeDisplayName} from '#/lib/strings/display-names' import {sanitizeHandle} from '#/lib/strings/handles' @@ -219,83 +216,59 @@ const FOLLOWING_FEED_STUB: FeedSourceInfo = { likeUri: '', } -export function usePinnedFeedsInfos(): { - feeds: FeedSourceInfo[] - hasPinnedCustom: boolean - isLoading: boolean -} { - const queryClient = useQueryClient() - const [tabs, setTabs] = React.useState([ - FOLLOWING_FEED_STUB, - ]) - const [isLoading, setLoading] = React.useState(true) - const {data: preferences} = usePreferencesQuery() +export function usePinnedFeedsInfos() { + const {data: preferences, isLoading: isLoadingPrefs} = usePreferencesQuery() + const pinnedUris = preferences?.feeds?.pinned ?? [] - const hasPinnedCustom = React.useMemo(() => { - return tabs.some(tab => tab !== FOLLOWING_FEED_STUB) - }, [tabs]) + return useQuery({ + staleTime: STALE.INFINITY, + enabled: !isLoadingPrefs, + queryKey: ['pinnedFeedsInfos', pinnedUris.join(',')], + queryFn: async () => { + let resolved = new Map() - React.useEffect(() => { - if (!preferences?.feeds?.pinned) return - const uris = preferences.feeds.pinned - - async function fetchFeedInfo() { - const reqs = [] - - for (const uri of uris) { - const cached = queryClient.getQueryData( - feedSourceInfoQueryKey({uri}), - ) - - if (cached) { - reqs.push(cached) - } else { - reqs.push( - (async () => { - // these requests can fail, need to filter those out - try { - return await queryClient.fetchQuery({ - staleTime: STALE.SECONDS.FIFTEEN, - queryKey: feedSourceInfoQueryKey({uri}), - queryFn: async () => { - const type = getFeedTypeFromUri(uri) - - if (type === 'feed') { - const res = - await getAgent().app.bsky.feed.getFeedGenerator({ - feed: uri, - }) - return hydrateFeedGenerator(res.data.view) - } else { - const res = await getAgent().app.bsky.graph.getList({ - list: uri, - limit: 1, - }) - return hydrateList(res.data.list) - } - }, - }) - } catch (e) { - // expected failure - logger.info(`usePinnedFeedsInfos: failed to fetch ${uri}`, { - error: e, - }) - } - })(), - ) - } + // Get all feeds. We can do this in a batch. + const feedUris = pinnedUris.filter( + uri => getFeedTypeFromUri(uri) === 'feed', + ) + let feedsPromise = Promise.resolve() + if (feedUris.length > 0) { + feedsPromise = getAgent() + .app.bsky.feed.getFeedGenerators({ + feeds: feedUris, + }) + .then(res => { + for (let feedView of res.data.feeds) { + resolved.set(feedView.uri, hydrateFeedGenerator(feedView)) + } + }) } - const views = (await Promise.all(reqs)).filter( - Boolean, - ) as FeedSourceInfo[] + // Get all lists. This currently has to be done individually. + const listUris = pinnedUris.filter( + uri => getFeedTypeFromUri(uri) === 'list', + ) + const listsPromises = listUris.map(listUri => + getAgent() + .app.bsky.graph.getList({ + list: listUri, + limit: 1, + }) + .then(res => { + const listView = res.data.list + resolved.set(listView.uri, hydrateList(listView)) + }), + ) - setTabs([FOLLOWING_FEED_STUB].concat(views)) - setLoading(false) - } - - fetchFeedInfo() - }, [queryClient, setTabs, preferences?.feeds?.pinned]) - - return {feeds: tabs, hasPinnedCustom, isLoading} + // The returned result will have the original order. + const result = [FOLLOWING_FEED_STUB] + await Promise.allSettled([feedsPromise, ...listsPromises]) + for (let pinnedUri of pinnedUris) { + if (resolved.has(pinnedUri)) { + result.push(resolved.get(pinnedUri)) + } + } + return result + }, + }) } diff --git a/src/view/com/home/HomeHeader.tsx b/src/view/com/home/HomeHeader.tsx index 3df3858b..bbd16465 100644 --- a/src/view/com/home/HomeHeader.tsx +++ b/src/view/com/home/HomeHeader.tsx @@ -1,7 +1,7 @@ import React from 'react' import {RenderTabBarFnProps} from 'view/com/pager/Pager' import {HomeHeaderLayout} from './HomeHeaderLayout' -import {usePinnedFeedsInfos} from '#/state/queries/feed' +import {FeedSourceInfo} from '#/state/queries/feed' import {useNavigation} from '@react-navigation/native' import {NavigationProp} from 'lib/routes/types' import {isWeb} from 'platform/detection' @@ -9,15 +9,22 @@ import {TabBar} from '../pager/TabBar' import {usePalette} from '#/lib/hooks/usePalette' export function HomeHeader( - props: RenderTabBarFnProps & {testID?: string; onPressSelected: () => void}, + props: RenderTabBarFnProps & { + testID?: string + onPressSelected: () => void + feeds: FeedSourceInfo[] + }, ) { + const {feeds} = props const navigation = useNavigation() - const {feeds, hasPinnedCustom} = usePinnedFeedsInfos() const pal = usePalette('default') + const hasPinnedCustom = React.useMemo(() => { + return feeds.some(tab => tab.uri !== '') + }, [feeds]) + const items = React.useMemo(() => { const pinnedNames = feeds.map(f => f.displayName) - if (!hasPinnedCustom) { return pinnedNames.concat('Feeds ✨') } diff --git a/src/view/screens/Home.tsx b/src/view/screens/Home.tsx index 856c237f..8f2f9618 100644 --- a/src/view/screens/Home.tsx +++ b/src/view/screens/Home.tsx @@ -21,7 +21,7 @@ import {useSelectedFeed, useSetSelectedFeed} from '#/state/shell/selected-feed' type Props = NativeStackScreenProps export function HomeScreen(props: Props) { const {data: preferences} = usePreferencesQuery() - const {feeds: pinnedFeedInfos, isLoading: isPinnedFeedsLoading} = + const {data: pinnedFeedInfos, isLoading: isPinnedFeedsLoading} = usePinnedFeedsInfos() if (preferences && pinnedFeedInfos && !isPinnedFeedsLoading) { return ( @@ -124,10 +124,11 @@ function HomeScreenReady({ onSelect={props.onSelect} testID="homeScreenFeedTabs" onPressSelected={onPressSelected} + feeds={pinnedFeedInfos} /> ) }, - [onPressSelected], + [onPressSelected, pinnedFeedInfos], ) const renderFollowingEmptyState = React.useCallback(() => { diff --git a/src/view/shell/desktop/Feeds.tsx b/src/view/shell/desktop/Feeds.tsx index c3b1caa3..f447490b 100644 --- a/src/view/shell/desktop/Feeds.tsx +++ b/src/view/shell/desktop/Feeds.tsx @@ -15,7 +15,7 @@ import {emitSoftReset} from '#/state/events' export function DesktopFeeds() { const pal = usePalette('default') const {_} = useLingui() - const {feeds: pinnedFeedInfos} = usePinnedFeedsInfos() + const {data: pinnedFeedInfos} = usePinnedFeedsInfos() const selectedFeed = useSelectedFeed() const setSelectedFeed = useSetSelectedFeed() const navigation = useNavigation() @@ -25,7 +25,9 @@ export function DesktopFeeds() { } return getCurrentRoute(state) }) - + if (!pinnedFeedInfos) { + return null + } return ( {pinnedFeedInfos.map(feedInfo => { From d679ae7dbb5d76bf5441239e1c9314cb229c1a0f Mon Sep 17 00:00:00 2001 From: dan Date: Wed, 28 Feb 2024 16:08:11 +0000 Subject: [PATCH 33/43] Use selected feed for window title on Home (#3016) --- src/view/screens/Home.tsx | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/view/screens/Home.tsx b/src/view/screens/Home.tsx index 8f2f9618..7ad9beb5 100644 --- a/src/view/screens/Home.tsx +++ b/src/view/screens/Home.tsx @@ -17,6 +17,7 @@ import {UsePreferencesQueryResponse} from '#/state/queries/preferences/types' import {emitSoftReset} from '#/state/events' import {useSession} from '#/state/session' import {useSelectedFeed, useSetSelectedFeed} from '#/state/shell/selected-feed' +import {useSetTitle} from '#/lib/hooks/useSetTitle' type Props = NativeStackScreenProps export function HomeScreen(props: Props) { @@ -66,6 +67,8 @@ function HomeScreenReady({ const selectedIndex = Math.max(0, maybeFoundIndex) const selectedFeed = allFeeds[selectedIndex] + useSetTitle(pinnedFeedInfos[selectedIndex]?.displayName) + const pagerRef = React.useRef(null) const lastPagerReportedIndexRef = React.useRef(selectedIndex) React.useLayoutEffect(() => { From 5cb45f9c16d1152bb84a02ccfac87a930cbbadda Mon Sep 17 00:00:00 2001 From: Hailey Date: Wed, 28 Feb 2024 08:31:04 -0800 Subject: [PATCH 34/43] fix collissions in uitextview (#3017) --- .../ios/RNUITextView.swift | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/modules/react-native-ui-text-view/ios/RNUITextView.swift b/modules/react-native-ui-text-view/ios/RNUITextView.swift index 9c21d45b..d51ee4e5 100644 --- a/modules/react-native-ui-text-view/ios/RNUITextView.swift +++ b/modules/react-native-ui-text-view/ios/RNUITextView.swift @@ -108,14 +108,27 @@ class RNUITextView: UIView { fractionOfDistanceBetweenInsertionPoints: nil ) + var lastUpperOffset: Int = 0 for child in self.reactSubviews() { if let child = child as? RNUITextViewChild, let childText = child.text { let fullText = self.textView.attributedText.string - let range = fullText.range(of: childText) - + + // We want to skip over the children we have already checked, otherwise we could run into + // collisions of similar strings (i.e. links that get shortened to the same hostname but + // different paths) + let startIndex = fullText.index(fullText.startIndex, offsetBy: lastUpperOffset) + let range = fullText.range(of: childText, options: [], range: startIndex..= lowerBound.utf16Offset(in: fullText) && charIndex <= upperBound.utf16Offset(in: fullText) { + let lowerOffset = lowerBound.utf16Offset(in: fullText) + let upperOffset = upperBound.utf16Offset(in: fullText) + + if charIndex >= lowerOffset, + charIndex <= upperOffset + { return child + } else { + lastUpperOffset = upperOffset } } } From 0c3d55db6ff03cf38b5033c0ae9851e8cd5ea5f7 Mon Sep 17 00:00:00 2001 From: Eric Bailey Date: Wed, 28 Feb 2024 10:38:31 -0600 Subject: [PATCH 35/43] Improve muted word matching (#3018) * Use name params * Add language exception matching --- .../__tests__/moderatePost_wrapped.test.ts | 481 +++++++++--------- src/lib/moderatePost_wrapped.ts | 80 ++- 2 files changed, 313 insertions(+), 248 deletions(-) diff --git a/src/lib/__tests__/moderatePost_wrapped.test.ts b/src/lib/__tests__/moderatePost_wrapped.test.ts index 1d907963..c35c1ef7 100644 --- a/src/lib/__tests__/moderatePost_wrapped.test.ts +++ b/src/lib/__tests__/moderatePost_wrapped.test.ts @@ -11,12 +11,12 @@ describe(`hasMutedWord`, () => { }) rt.detectFacetsWithoutResolution() - const match = hasMutedWord( - [{value: 'outlineTag', targets: ['tag']}], - rt.text, - rt.facets, - ['outlineTag'], - ) + const match = hasMutedWord({ + mutedWords: [{value: 'outlineTag', targets: ['tag']}], + text: rt.text, + facets: rt.facets, + outlineTags: ['outlineTag'], + }) expect(match).toBe(true) }) @@ -27,12 +27,12 @@ describe(`hasMutedWord`, () => { }) rt.detectFacetsWithoutResolution() - const match = hasMutedWord( - [{value: 'inlineTag', targets: ['tag']}], - rt.text, - rt.facets, - ['outlineTag'], - ) + const match = hasMutedWord({ + mutedWords: [{value: 'inlineTag', targets: ['tag']}], + text: rt.text, + facets: rt.facets, + outlineTags: ['outlineTag'], + }) expect(match).toBe(true) }) @@ -43,12 +43,12 @@ describe(`hasMutedWord`, () => { }) rt.detectFacetsWithoutResolution() - const match = hasMutedWord( - [{value: 'inlineTag', targets: ['content']}], - rt.text, - rt.facets, - ['outlineTag'], - ) + const match = hasMutedWord({ + mutedWords: [{value: 'inlineTag', targets: ['content']}], + text: rt.text, + facets: rt.facets, + outlineTags: ['outlineTag'], + }) expect(match).toBe(true) }) @@ -59,12 +59,12 @@ describe(`hasMutedWord`, () => { }) rt.detectFacetsWithoutResolution() - const match = hasMutedWord( - [{value: 'inlineTag', targets: ['tag']}], - rt.text, - rt.facets, - [], - ) + const match = hasMutedWord({ + mutedWords: [{value: 'inlineTag', targets: ['tag']}], + text: rt.text, + facets: rt.facets, + outlineTags: [], + }) expect(match).toBe(false) }) @@ -80,12 +80,12 @@ describe(`hasMutedWord`, () => { }) rt.detectFacetsWithoutResolution() - const match = hasMutedWord( - [{value: '希', targets: ['content']}], - rt.text, - rt.facets, - [], - ) + const match = hasMutedWord({ + mutedWords: [{value: '希', targets: ['content']}], + text: rt.text, + facets: rt.facets, + outlineTags: [], + }) expect(match).toBe(true) }) @@ -96,12 +96,12 @@ describe(`hasMutedWord`, () => { }) rt.detectFacetsWithoutResolution() - const match = hasMutedWord( - [{value: 'politics', targets: ['content']}], - rt.text, - rt.facets, - [], - ) + const match = hasMutedWord({ + mutedWords: [{value: 'politics', targets: ['content']}], + text: rt.text, + facets: rt.facets, + outlineTags: [], + }) expect(match).toBe(false) }) @@ -112,12 +112,12 @@ describe(`hasMutedWord`, () => { }) rt.detectFacetsWithoutResolution() - const match = hasMutedWord( - [{value: 'javascript', targets: ['content']}], - rt.text, - rt.facets, - [], - ) + const match = hasMutedWord({ + mutedWords: [{value: 'javascript', targets: ['content']}], + text: rt.text, + facets: rt.facets, + outlineTags: [], + }) expect(match).toBe(true) }) @@ -130,12 +130,12 @@ describe(`hasMutedWord`, () => { }) rt.detectFacetsWithoutResolution() - const match = hasMutedWord( - [{value: 'javascript', targets: ['content']}], - rt.text, - rt.facets, - [], - ) + const match = hasMutedWord({ + mutedWords: [{value: 'javascript', targets: ['content']}], + text: rt.text, + facets: rt.facets, + outlineTags: [], + }) expect(match).toBe(true) }) @@ -146,12 +146,12 @@ describe(`hasMutedWord`, () => { }) rt.detectFacetsWithoutResolution() - const match = hasMutedWord( - [{value: 'ai', targets: ['content']}], - rt.text, - rt.facets, - [], - ) + const match = hasMutedWord({ + mutedWords: [{value: 'ai', targets: ['content']}], + text: rt.text, + facets: rt.facets, + outlineTags: [], + }) expect(match).toBe(false) }) @@ -162,12 +162,12 @@ describe(`hasMutedWord`, () => { }) rt.detectFacetsWithoutResolution() - const match = hasMutedWord( - [{value: 'brain', targets: ['content']}], - rt.text, - rt.facets, - [], - ) + const match = hasMutedWord({ + mutedWords: [{value: 'brain', targets: ['content']}], + text: rt.text, + facets: rt.facets, + outlineTags: [], + }) expect(match).toBe(true) }) @@ -178,12 +178,12 @@ describe(`hasMutedWord`, () => { }) rt.detectFacetsWithoutResolution() - const match = hasMutedWord( - [{value: `:)`, targets: ['content']}], - rt.text, - rt.facets, - [], - ) + const match = hasMutedWord({ + mutedWords: [{value: `:)`, targets: ['content']}], + text: rt.text, + facets: rt.facets, + outlineTags: [], + }) expect(match).toBe(true) }) @@ -197,23 +197,23 @@ describe(`hasMutedWord`, () => { rt.detectFacetsWithoutResolution() it(`match: yay!`, () => { - const match = hasMutedWord( - [{value: 'yay!', targets: ['content']}], - rt.text, - rt.facets, - [], - ) + const match = hasMutedWord({ + mutedWords: [{value: 'yay!', targets: ['content']}], + text: rt.text, + facets: rt.facets, + outlineTags: [], + }) expect(match).toBe(true) }) it(`match: yay`, () => { - const match = hasMutedWord( - [{value: 'yay', targets: ['content']}], - rt.text, - rt.facets, - [], - ) + const match = hasMutedWord({ + mutedWords: [{value: 'yay', targets: ['content']}], + text: rt.text, + facets: rt.facets, + outlineTags: [], + }) expect(match).toBe(true) }) @@ -226,24 +226,24 @@ describe(`hasMutedWord`, () => { rt.detectFacetsWithoutResolution() it(`match: y!ppee`, () => { - const match = hasMutedWord( - [{value: 'y!ppee', targets: ['content']}], - rt.text, - rt.facets, - [], - ) + const match = hasMutedWord({ + mutedWords: [{value: 'y!ppee', targets: ['content']}], + text: rt.text, + facets: rt.facets, + outlineTags: [], + }) expect(match).toBe(true) }) // single exclamation point, source has double it(`no match: y!ppee!`, () => { - const match = hasMutedWord( - [{value: 'y!ppee!', targets: ['content']}], - rt.text, - rt.facets, - [], - ) + const match = hasMutedWord({ + mutedWords: [{value: 'y!ppee!', targets: ['content']}], + text: rt.text, + facets: rt.facets, + outlineTags: [], + }) expect(match).toBe(true) }) @@ -256,23 +256,23 @@ describe(`hasMutedWord`, () => { rt.detectFacetsWithoutResolution() it(`match: S@assy`, () => { - const match = hasMutedWord( - [{value: 'S@assy', targets: ['content']}], - rt.text, - rt.facets, - [], - ) + const match = hasMutedWord({ + mutedWords: [{value: 'S@assy', targets: ['content']}], + text: rt.text, + facets: rt.facets, + outlineTags: [], + }) expect(match).toBe(true) }) it(`match: s@assy`, () => { - const match = hasMutedWord( - [{value: 's@assy', targets: ['content']}], - rt.text, - rt.facets, - [], - ) + const match = hasMutedWord({ + mutedWords: [{value: 's@assy', targets: ['content']}], + text: rt.text, + facets: rt.facets, + outlineTags: [], + }) expect(match).toBe(true) }) @@ -286,12 +286,12 @@ describe(`hasMutedWord`, () => { // case insensitive it(`match: new york times`, () => { - const match = hasMutedWord( - [{value: 'new york times', targets: ['content']}], - rt.text, - rt.facets, - [], - ) + const match = hasMutedWord({ + mutedWords: [{value: 'new york times', targets: ['content']}], + text: rt.text, + facets: rt.facets, + outlineTags: [], + }) expect(match).toBe(true) }) @@ -304,23 +304,23 @@ describe(`hasMutedWord`, () => { rt.detectFacetsWithoutResolution() it(`match: !command`, () => { - const match = hasMutedWord( - [{value: `!command`, targets: ['content']}], - rt.text, - rt.facets, - [], - ) + const match = hasMutedWord({ + mutedWords: [{value: `!command`, targets: ['content']}], + text: rt.text, + facets: rt.facets, + outlineTags: [], + }) expect(match).toBe(true) }) it(`match: command`, () => { - const match = hasMutedWord( - [{value: `command`, targets: ['content']}], - rt.text, - rt.facets, - [], - ) + const match = hasMutedWord({ + mutedWords: [{value: `command`, targets: ['content']}], + text: rt.text, + facets: rt.facets, + outlineTags: [], + }) expect(match).toBe(true) }) @@ -331,12 +331,12 @@ describe(`hasMutedWord`, () => { }) rt.detectFacetsWithoutResolution() - const match = hasMutedWord( - [{value: `!command`, targets: ['content']}], - rt.text, - rt.facets, - [], - ) + const match = hasMutedWord({ + mutedWords: [{value: `!command`, targets: ['content']}], + text: rt.text, + facets: rt.facets, + outlineTags: [], + }) expect(match).toBe(false) }) @@ -349,23 +349,23 @@ describe(`hasMutedWord`, () => { rt.detectFacetsWithoutResolution() it(`match: e/acc`, () => { - const match = hasMutedWord( - [{value: `e/acc`, targets: ['content']}], - rt.text, - rt.facets, - [], - ) + const match = hasMutedWord({ + mutedWords: [{value: `e/acc`, targets: ['content']}], + text: rt.text, + facets: rt.facets, + outlineTags: [], + }) expect(match).toBe(true) }) it(`match: acc`, () => { - const match = hasMutedWord( - [{value: `acc`, targets: ['content']}], - rt.text, - rt.facets, - [], - ) + const match = hasMutedWord({ + mutedWords: [{value: `acc`, targets: ['content']}], + text: rt.text, + facets: rt.facets, + outlineTags: [], + }) expect(match).toBe(true) }) @@ -378,45 +378,45 @@ describe(`hasMutedWord`, () => { rt.detectFacetsWithoutResolution() it(`match: super-bad`, () => { - const match = hasMutedWord( - [{value: `super-bad`, targets: ['content']}], - rt.text, - rt.facets, - [], - ) + const match = hasMutedWord({ + mutedWords: [{value: `super-bad`, targets: ['content']}], + text: rt.text, + facets: rt.facets, + outlineTags: [], + }) expect(match).toBe(true) }) it(`match: super`, () => { - const match = hasMutedWord( - [{value: `super`, targets: ['content']}], - rt.text, - rt.facets, - [], - ) + const match = hasMutedWord({ + mutedWords: [{value: `super`, targets: ['content']}], + text: rt.text, + facets: rt.facets, + outlineTags: [], + }) expect(match).toBe(true) }) it(`match: super bad`, () => { - const match = hasMutedWord( - [{value: `super bad`, targets: ['content']}], - rt.text, - rt.facets, - [], - ) + const match = hasMutedWord({ + mutedWords: [{value: `super bad`, targets: ['content']}], + text: rt.text, + facets: rt.facets, + outlineTags: [], + }) expect(match).toBe(true) }) it(`match: superbad`, () => { - const match = hasMutedWord( - [{value: `superbad`, targets: ['content']}], - rt.text, - rt.facets, - [], - ) + const match = hasMutedWord({ + mutedWords: [{value: `superbad`, targets: ['content']}], + text: rt.text, + facets: rt.facets, + outlineTags: [], + }) expect(match).toBe(false) }) @@ -429,47 +429,49 @@ describe(`hasMutedWord`, () => { rt.detectFacetsWithoutResolution() it(`match: idk what this would be`, () => { - const match = hasMutedWord( - [{value: `idk what this would be`, targets: ['content']}], - rt.text, - rt.facets, - [], - ) + const match = hasMutedWord({ + mutedWords: [{value: `idk what this would be`, targets: ['content']}], + text: rt.text, + facets: rt.facets, + outlineTags: [], + }) expect(match).toBe(true) }) it(`no match: idk what this would be for`, () => { // extra word - const match = hasMutedWord( - [{value: `idk what this would be for`, targets: ['content']}], - rt.text, - rt.facets, - [], - ) + const match = hasMutedWord({ + mutedWords: [ + {value: `idk what this would be for`, targets: ['content']}, + ], + text: rt.text, + facets: rt.facets, + outlineTags: [], + }) expect(match).toBe(false) }) it(`match: idk`, () => { // extra word - const match = hasMutedWord( - [{value: `idk`, targets: ['content']}], - rt.text, - rt.facets, - [], - ) + const match = hasMutedWord({ + mutedWords: [{value: `idk`, targets: ['content']}], + text: rt.text, + facets: rt.facets, + outlineTags: [], + }) expect(match).toBe(true) }) it(`match: idkwhatthiswouldbe`, () => { - const match = hasMutedWord( - [{value: `idkwhatthiswouldbe`, targets: ['content']}], - rt.text, - rt.facets, - [], - ) + const match = hasMutedWord({ + mutedWords: [{value: `idkwhatthiswouldbe`, targets: ['content']}], + text: rt.text, + facets: rt.facets, + outlineTags: [], + }) expect(match).toBe(false) }) @@ -482,45 +484,45 @@ describe(`hasMutedWord`, () => { rt.detectFacetsWithoutResolution() it(`match: context(iykyk)`, () => { - const match = hasMutedWord( - [{value: `context(iykyk)`, targets: ['content']}], - rt.text, - rt.facets, - [], - ) + const match = hasMutedWord({ + mutedWords: [{value: `context(iykyk)`, targets: ['content']}], + text: rt.text, + facets: rt.facets, + outlineTags: [], + }) expect(match).toBe(true) }) it(`match: context`, () => { - const match = hasMutedWord( - [{value: `context`, targets: ['content']}], - rt.text, - rt.facets, - [], - ) + const match = hasMutedWord({ + mutedWords: [{value: `context`, targets: ['content']}], + text: rt.text, + facets: rt.facets, + outlineTags: [], + }) expect(match).toBe(true) }) it(`match: iykyk`, () => { - const match = hasMutedWord( - [{value: `iykyk`, targets: ['content']}], - rt.text, - rt.facets, - [], - ) + const match = hasMutedWord({ + mutedWords: [{value: `iykyk`, targets: ['content']}], + text: rt.text, + facets: rt.facets, + outlineTags: [], + }) expect(match).toBe(true) }) it(`match: (iykyk)`, () => { - const match = hasMutedWord( - [{value: `(iykyk)`, targets: ['content']}], - rt.text, - rt.facets, - [], - ) + const match = hasMutedWord({ + mutedWords: [{value: `(iykyk)`, targets: ['content']}], + text: rt.text, + facets: rt.facets, + outlineTags: [], + }) expect(match).toBe(true) }) @@ -533,12 +535,12 @@ describe(`hasMutedWord`, () => { rt.detectFacetsWithoutResolution() it(`match: 🦋`, () => { - const match = hasMutedWord( - [{value: `🦋`, targets: ['content']}], - rt.text, - rt.facets, - [], - ) + const match = hasMutedWord({ + mutedWords: [{value: `🦋`, targets: ['content']}], + text: rt.text, + facets: rt.facets, + outlineTags: [], + }) expect(match).toBe(true) }) @@ -553,23 +555,46 @@ describe(`hasMutedWord`, () => { rt.detectFacetsWithoutResolution() it(`match: stop worrying`, () => { - const match = hasMutedWord( - [{value: 'stop worrying', targets: ['content']}], - rt.text, - rt.facets, - [], - ) + const match = hasMutedWord({ + mutedWords: [{value: 'stop worrying', targets: ['content']}], + text: rt.text, + facets: rt.facets, + outlineTags: [], + }) expect(match).toBe(true) }) it(`match: turtles, or how`, () => { - const match = hasMutedWord( - [{value: 'turtles, or how', targets: ['content']}], - rt.text, - rt.facets, - [], - ) + const match = hasMutedWord({ + mutedWords: [{value: 'turtles, or how', targets: ['content']}], + text: rt.text, + facets: rt.facets, + outlineTags: [], + }) + + expect(match).toBe(true) + }) + }) + }) + + describe(`languages without spaces`, () => { + // I love turtles, or how I learned to stop worrying and love the internet + describe(`私はカメが好きです、またはどのようにして心配するのをやめてインターネットを愛するようになったのか`, () => { + const rt = new RichText({ + text: `私はカメが好きです、またはどのようにして心配するのをやめてインターネットを愛するようになったのか`, + }) + rt.detectFacetsWithoutResolution() + + // internet + it(`match: インターネット`, () => { + const match = hasMutedWord({ + mutedWords: [{value: 'インターネット', targets: ['content']}], + text: rt.text, + facets: rt.facets, + outlineTags: [], + languages: ['ja'], + }) expect(match).toBe(true) }) diff --git a/src/lib/moderatePost_wrapped.ts b/src/lib/moderatePost_wrapped.ts index 862f2de6..428dbabf 100644 --- a/src/lib/moderatePost_wrapped.ts +++ b/src/lib/moderatePost_wrapped.ts @@ -21,12 +21,34 @@ const REGEX = { WORD_BOUNDARY: /[\s\n\t\r\f\v]+?/g, } -export function hasMutedWord( - mutedWords: AppBskyActorDefs.MutedWord[], - text: string, - facets?: AppBskyRichtextFacet.Main[], - outlineTags?: string[], -) { +/** + * List of 2-letter lang codes for languages that either don't use spaces, or + * don't use spaces in a way conducive to word-based filtering. + * + * For these, we use a simple `String.includes` to check for a match. + */ +const LANGUAGE_EXCEPTIONS = [ + 'ja', // Japanese + 'zh', // Chinese + 'ko', // Korean + 'th', // Thai + 'vi', // Vietnamese +] + +export function hasMutedWord({ + mutedWords, + text, + facets, + outlineTags, + languages, +}: { + mutedWords: AppBskyActorDefs.MutedWord[] + text: string + facets?: AppBskyRichtextFacet.Main[] + outlineTags?: string[] + languages?: string[] +}) { + const exception = LANGUAGE_EXCEPTIONS.includes(languages?.[0] || '') const tags = ([] as string[]) .concat(outlineTags || []) .concat( @@ -48,8 +70,9 @@ export function hasMutedWord( if (tags.includes(mutedWord)) return true // rest of the checks are for `content` only if (!mute.targets.includes('content')) continue - // single character, has to use includes - if (mutedWord.length === 1 && postText.includes(mutedWord)) return true + // single character or other exception, has to use includes + if ((mutedWord.length === 1 || exception) && postText.includes(mutedWord)) + return true // too long if (mutedWord.length > postText.length) continue // exact match @@ -134,19 +157,28 @@ export function moderatePost_wrapped( } if (AppBskyFeedPost.isRecord(subject.record)) { - let muted = hasMutedWord( + let muted = hasMutedWord({ mutedWords, - subject.record.text, - subject.record.facets || [], - subject.record.tags || [], - ) + text: subject.record.text, + facets: subject.record.facets || [], + outlineTags: subject.record.tags || [], + languages: subject.record.langs, + }) if ( subject.record.embed && AppBskyEmbedImages.isMain(subject.record.embed) ) { for (const image of subject.record.embed.images) { - muted = muted || hasMutedWord(mutedWords, image.alt, [], []) + muted = + muted || + hasMutedWord({ + mutedWords, + text: image.alt, + facets: [], + outlineTags: [], + languages: subject.record.langs, + }) } } @@ -172,17 +204,25 @@ export function moderatePost_wrapped( if (AppBskyFeedPost.isRecord(subject.embed.record.value)) { embedHidden = embedHidden || - hasMutedWord( + hasMutedWord({ mutedWords, - subject.embed.record.value.text, - subject.embed.record.value.facets, - subject.embed.record.value.tags, - ) + text: subject.embed.record.value.text, + facets: subject.embed.record.value.facets, + outlineTags: subject.embed.record.value.tags, + languages: subject.embed.record.value.langs, + }) if (AppBskyEmbedImages.isMain(subject.embed.record.value.embed)) { for (const image of subject.embed.record.value.embed.images) { embedHidden = - embedHidden || hasMutedWord(mutedWords, image.alt, [], []) + embedHidden || + hasMutedWord({ + mutedWords, + text: image.alt, + facets: [], + outlineTags: [], + languages: subject.embed.record.value.langs, + }) } } } From d2c6edacb6464b52513dbe467c8b5713abd6a9fc Mon Sep 17 00:00:00 2001 From: Eric Bailey Date: Wed, 28 Feb 2024 13:27:54 -0600 Subject: [PATCH 36/43] Protect against non functions being passed to close callback (#3019) --- src/components/Dialog/index.tsx | 15 ++++++++++++--- src/components/Dialog/index.web.tsx | 2 +- src/components/Dialog/types.ts | 12 ++++++------ src/components/Prompt.tsx | 2 +- .../StepModeration/AdultContentEnabledPref.tsx | 2 +- 5 files changed, 21 insertions(+), 12 deletions(-) diff --git a/src/components/Dialog/index.tsx b/src/components/Dialog/index.tsx index 27f43afd..5c035027 100644 --- a/src/components/Dialog/index.tsx +++ b/src/components/Dialog/index.tsx @@ -11,6 +11,7 @@ import {useSafeAreaInsets} from 'react-native-safe-area-context' import {useTheme, atoms as a, flatten} from '#/alf' import {Portal} from '#/components/Portal' import {createInput} from '#/components/forms/TextField' +import {logger} from '#/logger' import { DialogOuterProps, @@ -56,7 +57,7 @@ export function Outer({ ) const close = React.useCallback(cb => { - if (cb) { + if (cb && typeof cb === 'function') { closeCallback.current = cb } sheet.current?.close() @@ -74,8 +75,16 @@ export function Outer({ const onChange = React.useCallback( (index: number) => { if (index === -1) { - closeCallback.current?.() - closeCallback.current = undefined + try { + closeCallback.current?.() + } catch (e: any) { + logger.error(`Dialog closeCallback failed`, { + message: e.message, + }) + } finally { + closeCallback.current = undefined + } + onClose?.() setOpenIndex(-1) } diff --git a/src/components/Dialog/index.web.tsx b/src/components/Dialog/index.web.tsx index fa29fbd6..ff05fed9 100644 --- a/src/components/Dialog/index.web.tsx +++ b/src/components/Dialog/index.web.tsx @@ -190,7 +190,7 @@ export function Close() { variant="ghost" color="secondary" shape="round" - onPress={close} + onPress={() => close()} label={_(msg`Close active dialog`)}> diff --git a/src/components/Dialog/types.ts b/src/components/Dialog/types.ts index 75ba825a..161c0373 100644 --- a/src/components/Dialog/types.ts +++ b/src/components/Dialog/types.ts @@ -6,8 +6,13 @@ import {ViewStyleProp} from '#/alf' type A11yProps = Required +export type DialogControlProps = { + open: (options?: DialogControlOpenOptions) => void + close: (callback?: () => void) => void +} + export type DialogContextProps = { - close: () => void + close: DialogControlProps['close'] } export type DialogControlOpenOptions = { @@ -20,11 +25,6 @@ export type DialogControlOpenOptions = { index?: number } -export type DialogControlProps = { - open: (options?: DialogControlOpenOptions) => void - close: (callback?: () => void) => void -} - export type DialogOuterProps = { control: { ref: React.RefObject diff --git a/src/components/Prompt.tsx b/src/components/Prompt.tsx index 41167910..8e55bd83 100644 --- a/src/components/Prompt.tsx +++ b/src/components/Prompt.tsx @@ -89,7 +89,7 @@ export function Cancel({ color="secondary" size="small" label={_(msg`Cancel`)} - onPress={close}> + onPress={() => close()}> {children} ) diff --git a/src/screens/Onboarding/StepModeration/AdultContentEnabledPref.tsx b/src/screens/Onboarding/StepModeration/AdultContentEnabledPref.tsx index b38b3df1..360025c0 100644 --- a/src/screens/Onboarding/StepModeration/AdultContentEnabledPref.tsx +++ b/src/screens/Onboarding/StepModeration/AdultContentEnabledPref.tsx @@ -114,7 +114,7 @@ export function AdultContentEnabledPref({ - OK + prompt.close()}>OK From 60eb6e23d1349949d9399dc02c98fca4c4d0777a Mon Sep 17 00:00:00 2001 From: Hailey Date: Wed, 28 Feb 2024 11:35:59 -0800 Subject: [PATCH 37/43] close open dialogs when deep linking to composer (#3020) --- src/lib/hooks/useIntentHandler.ts | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/lib/hooks/useIntentHandler.ts b/src/lib/hooks/useIntentHandler.ts index de9a96da..d1e2de31 100644 --- a/src/lib/hooks/useIntentHandler.ts +++ b/src/lib/hooks/useIntentHandler.ts @@ -3,6 +3,7 @@ import * as Linking from 'expo-linking' import {isNative} from 'platform/detection' import {useComposerControls} from 'state/shell' import {useSession} from 'state/session' +import {useCloseAllActiveElements} from 'state/util' type IntentType = 'compose' @@ -42,6 +43,7 @@ export function useIntentHandler() { } function useComposeIntent() { + const closeAllActiveElements = useCloseAllActiveElements() const {openComposer} = useComposerControls() const {hasSession} = useSession() @@ -55,6 +57,8 @@ function useComposeIntent() { }) => { if (!hasSession) return + closeAllActiveElements() + const imageUris = imageUrisStr ?.split(',') .filter(part => { @@ -82,6 +86,6 @@ function useComposeIntent() { }) }, 500) }, - [openComposer, hasSession], + [hasSession, closeAllActiveElements, openComposer], ) } From a697b39c48cca4565adacd99697822fa2db898a2 Mon Sep 17 00:00:00 2001 From: Hailey Date: Wed, 28 Feb 2024 11:46:19 -0800 Subject: [PATCH 38/43] add alf dialogs to useCloseAllActiveElements (#3021) --- src/state/util.ts | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/src/state/util.ts b/src/state/util.ts index 57f4331b..7b49b5b4 100644 --- a/src/state/util.ts +++ b/src/state/util.ts @@ -3,6 +3,7 @@ import {useLightboxControls} from './lightbox' import {useModalControls} from './modals' import {useComposerControls} from './shell/composer' import {useSetDrawerOpen} from './shell/drawer-open' +import {useDialogStateControlContext} from 'state/dialogs' /** * returns true if something was closed @@ -35,11 +36,19 @@ export function useCloseAllActiveElements() { const {closeLightbox} = useLightboxControls() const {closeAllModals} = useModalControls() const {closeComposer} = useComposerControls() + const {closeAllDialogs: closeAlfDialogs} = useDialogStateControlContext() const setDrawerOpen = useSetDrawerOpen() return useCallback(() => { closeLightbox() closeAllModals() closeComposer() + closeAlfDialogs() setDrawerOpen(false) - }, [closeLightbox, closeAllModals, closeComposer, setDrawerOpen]) + }, [ + closeLightbox, + closeAllModals, + closeComposer, + closeAlfDialogs, + setDrawerOpen, + ]) } From c7de733dff2d9b293d7f93de88f688e33db54b22 Mon Sep 17 00:00:00 2001 From: Hailey Date: Wed, 28 Feb 2024 13:28:27 -0800 Subject: [PATCH 39/43] always use utf8 offsets (#3024) --- modules/react-native-ui-text-view/ios/RNUITextView.swift | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/modules/react-native-ui-text-view/ios/RNUITextView.swift b/modules/react-native-ui-text-view/ios/RNUITextView.swift index d51ee4e5..3fb55873 100644 --- a/modules/react-native-ui-text-view/ios/RNUITextView.swift +++ b/modules/react-native-ui-text-view/ios/RNUITextView.swift @@ -108,7 +108,7 @@ class RNUITextView: UIView { fractionOfDistanceBetweenInsertionPoints: nil ) - var lastUpperOffset: Int = 0 + var lastUpperBound: String.Index? = nil for child in self.reactSubviews() { if let child = child as? RNUITextViewChild, let childText = child.text { let fullText = self.textView.attributedText.string @@ -116,8 +116,7 @@ class RNUITextView: UIView { // We want to skip over the children we have already checked, otherwise we could run into // collisions of similar strings (i.e. links that get shortened to the same hostname but // different paths) - let startIndex = fullText.index(fullText.startIndex, offsetBy: lastUpperOffset) - let range = fullText.range(of: childText, options: [], range: startIndex.. Date: Wed, 28 Feb 2024 15:30:08 -0800 Subject: [PATCH 40/43] Add /intent/compose to bskyweb (#3026) --- bskyweb/cmd/bskyweb/server.go | 1 + 1 file changed, 1 insertion(+) diff --git a/bskyweb/cmd/bskyweb/server.go b/bskyweb/cmd/bskyweb/server.go index f4da22ca..f13d568b 100644 --- a/bskyweb/cmd/bskyweb/server.go +++ b/bskyweb/cmd/bskyweb/server.go @@ -202,6 +202,7 @@ func serve(cctx *cli.Context) error { e.GET("/support/tos", server.WebGeneric) e.GET("/support/community-guidelines", server.WebGeneric) e.GET("/support/copyright", server.WebGeneric) + e.GET("/intent/compose", server.WebGeneric) // profile endpoints; only first populates info e.GET("/profile/:handleOrDID", server.WebProfile) From 7fd13cacfea4e9e4609ac2cfa11749544fc2f8f8 Mon Sep 17 00:00:00 2001 From: Hailey Date: Wed, 28 Feb 2024 15:38:54 -0800 Subject: [PATCH 41/43] Remove `Platform.select()` (#3027) --- src/alf/util/platform.ts | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/src/alf/util/platform.ts b/src/alf/util/platform.ts index 544f5480..294e08a8 100644 --- a/src/alf/util/platform.ts +++ b/src/alf/util/platform.ts @@ -1,25 +1,25 @@ -import {Platform} from 'react-native' +import {isAndroid, isIOS, isNative, isWeb} from 'platform/detection' export function web(value: any) { - return Platform.select({ - web: value, - }) + if (isWeb) { + return value + } } export function ios(value: any) { - return Platform.select({ - ios: value, - }) + if (isIOS) { + return value + } } export function android(value: any) { - return Platform.select({ - android: value, - }) + if (isAndroid) { + return value + } } export function native(value: any) { - return Platform.select({ - native: value, - }) + if (isNative) { + return value + } } From 2440975bd224e4c39b633b21c461cb8b8d3c1f9b Mon Sep 17 00:00:00 2001 From: Eric Bailey Date: Wed, 28 Feb 2024 20:06:26 -0600 Subject: [PATCH 42/43] Integrate new dialogs into old back handling (#3023) --- src/components/Dialog/context.ts | 13 +++++++++---- src/components/Dialog/index.tsx | 8 ++++++-- src/components/Dialog/index.web.tsx | 8 ++++++-- src/components/Dialog/types.ts | 19 +++++++++++++++---- src/state/dialogs/index.tsx | 28 ++++++++++++++++++++++------ src/state/util.ts | 8 ++++++-- 6 files changed, 64 insertions(+), 20 deletions(-) diff --git a/src/components/Dialog/context.ts b/src/components/Dialog/context.ts index f0c7c983..eb717d8e 100644 --- a/src/components/Dialog/context.ts +++ b/src/components/Dialog/context.ts @@ -3,7 +3,7 @@ import React from 'react' import {useDialogStateContext} from '#/state/dialogs' import { DialogContextProps, - DialogControlProps, + DialogControlRefProps, DialogOuterProps, } from '#/components/Dialog/types' @@ -17,7 +17,7 @@ export function useDialogContext() { export function useDialogControl(): DialogOuterProps['control'] { const id = React.useId() - const control = React.useRef({ + const control = React.useRef({ open: () => {}, close: () => {}, }) @@ -32,8 +32,13 @@ export function useDialogControl(): DialogOuterProps['control'] { }, [id, activeDialogs]) return { + id, ref: control, - open: () => control.current.open(), - close: cb => control.current.close(cb), + open: () => { + control.current.open() + }, + close: cb => { + control.current.close(cb) + }, } } diff --git a/src/components/Dialog/index.tsx b/src/components/Dialog/index.tsx index 5c035027..6dfc24f3 100644 --- a/src/components/Dialog/index.tsx +++ b/src/components/Dialog/index.tsx @@ -12,6 +12,7 @@ import {useTheme, atoms as a, flatten} from '#/alf' import {Portal} from '#/components/Portal' import {createInput} from '#/components/forms/TextField' import {logger} from '#/logger' +import {useDialogStateContext} from '#/state/dialogs' import { DialogOuterProps, @@ -37,6 +38,7 @@ export function Outer({ const hasSnapPoints = !!sheetOptions.snapPoints const insets = useSafeAreaInsets() const closeCallback = React.useRef<() => void>() + const {openDialogs} = useDialogStateContext() /* * Used to manage open/closed, but index is otherwise handled internally by `BottomSheet` @@ -50,10 +52,11 @@ export function Outer({ const open = React.useCallback( ({index} = {}) => { + openDialogs.current.add(control.id) // can be set to any index of `snapPoints`, but `0` is the first i.e. "open" setOpenIndex(index || 0) }, - [setOpenIndex], + [setOpenIndex, openDialogs, control.id], ) const close = React.useCallback(cb => { @@ -85,11 +88,12 @@ export function Outer({ closeCallback.current = undefined } + openDialogs.current.delete(control.id) onClose?.() setOpenIndex(-1) } }, - [onClose, setOpenIndex], + [onClose, setOpenIndex, openDialogs, control.id], ) const context = React.useMemo(() => ({close}), [close]) diff --git a/src/components/Dialog/index.web.tsx b/src/components/Dialog/index.web.tsx index ff05fed9..32163e73 100644 --- a/src/components/Dialog/index.web.tsx +++ b/src/components/Dialog/index.web.tsx @@ -12,6 +12,7 @@ import {DialogOuterProps, DialogInnerProps} from '#/components/Dialog/types' import {Context} from '#/components/Dialog/context' import {Button, ButtonIcon} from '#/components/Button' import {TimesLarge_Stroke2_Corner0_Rounded as X} from '#/components/icons/Times' +import {useDialogStateContext} from '#/state/dialogs' export {useDialogControl, useDialogContext} from '#/components/Dialog/context' export * from '#/components/Dialog/types' @@ -29,18 +30,21 @@ export function Outer({ const {gtMobile} = useBreakpoints() const [isOpen, setIsOpen] = React.useState(false) const [isVisible, setIsVisible] = React.useState(true) + const {openDialogs} = useDialogStateContext() const open = React.useCallback(() => { setIsOpen(true) - }, [setIsOpen]) + openDialogs.current.add(control.id) + }, [setIsOpen, openDialogs, control.id]) const close = React.useCallback(async () => { setIsVisible(false) await new Promise(resolve => setTimeout(resolve, 150)) setIsOpen(false) setIsVisible(true) + openDialogs.current.delete(control.id) onClose?.() - }, [onClose, setIsOpen]) + }, [onClose, setIsOpen, openDialogs, control.id]) useImperativeHandle( control.ref, diff --git a/src/components/Dialog/types.ts b/src/components/Dialog/types.ts index 161c0373..78dfedf5 100644 --- a/src/components/Dialog/types.ts +++ b/src/components/Dialog/types.ts @@ -6,11 +6,24 @@ import {ViewStyleProp} from '#/alf' type A11yProps = Required -export type DialogControlProps = { +/** + * Mutated by useImperativeHandle to provide a public API for controlling the + * dialog. The methods here will actually become the handlers defined within + * the `Dialog.Outer` component. + */ +export type DialogControlRefProps = { open: (options?: DialogControlOpenOptions) => void close: (callback?: () => void) => void } +/** + * The return type of the useDialogControl hook. + */ +export type DialogControlProps = DialogControlRefProps & { + id: string + ref: React.RefObject +} + export type DialogContextProps = { close: DialogControlProps['close'] } @@ -26,9 +39,7 @@ export type DialogControlOpenOptions = { } export type DialogOuterProps = { - control: { - ref: React.RefObject - } & DialogControlProps + control: DialogControlProps onClose?: () => void nativeOptions?: { sheet?: Omit diff --git a/src/state/dialogs/index.tsx b/src/state/dialogs/index.tsx index ae762bd9..9fc70c17 100644 --- a/src/state/dialogs/index.tsx +++ b/src/state/dialogs/index.tsx @@ -1,21 +1,32 @@ import React from 'react' -import {DialogControlProps} from '#/components/Dialog' +import {DialogControlRefProps} from '#/components/Dialog' import {Provider as GlobalDialogsProvider} from '#/components/dialogs/Context' const DialogContext = React.createContext<{ + /** + * The currently active `useDialogControl` hooks. + */ activeDialogs: React.MutableRefObject< - Map> + Map> > + /** + * The currently open dialogs, referenced by their IDs, generated from + * `useId`. + */ + openDialogs: React.MutableRefObject> }>({ activeDialogs: { current: new Map(), }, + openDialogs: { + current: new Set(), + }, }) const DialogControlContext = React.createContext<{ - closeAllDialogs(): void + closeAllDialogs(): boolean }>({ - closeAllDialogs: () => {}, + closeAllDialogs: () => false, }) export function useDialogStateContext() { @@ -28,13 +39,18 @@ export function useDialogStateControlContext() { export function Provider({children}: React.PropsWithChildren<{}>) { const activeDialogs = React.useRef< - Map> + Map> >(new Map()) + const openDialogs = React.useRef>(new Set()) + const closeAllDialogs = React.useCallback(() => { activeDialogs.current.forEach(dialog => dialog.current.close()) + return openDialogs.current.size > 0 }, []) - const context = React.useMemo(() => ({activeDialogs}), []) + + const context = React.useMemo(() => ({activeDialogs, openDialogs}), []) const controls = React.useMemo(() => ({closeAllDialogs}), [closeAllDialogs]) + return ( diff --git a/src/state/util.ts b/src/state/util.ts index 7b49b5b4..f65d14a8 100644 --- a/src/state/util.ts +++ b/src/state/util.ts @@ -3,7 +3,7 @@ import {useLightboxControls} from './lightbox' import {useModalControls} from './modals' import {useComposerControls} from './shell/composer' import {useSetDrawerOpen} from './shell/drawer-open' -import {useDialogStateControlContext} from 'state/dialogs' +import {useDialogStateControlContext} from '#/state/dialogs' /** * returns true if something was closed @@ -13,6 +13,7 @@ export function useCloseAnyActiveElement() { const {closeLightbox} = useLightboxControls() const {closeModal} = useModalControls() const {closeComposer} = useComposerControls() + const {closeAllDialogs} = useDialogStateControlContext() const setDrawerOpen = useSetDrawerOpen() return useCallback(() => { if (closeLightbox()) { @@ -24,9 +25,12 @@ export function useCloseAnyActiveElement() { if (closeComposer()) { return true } + if (closeAllDialogs()) { + return true + } setDrawerOpen(false) return false - }, [closeLightbox, closeModal, closeComposer, setDrawerOpen]) + }, [closeLightbox, closeModal, closeComposer, setDrawerOpen, closeAllDialogs]) } /** From a35976cdc9b6467ad8b6e0c4ff46ba684fee9064 Mon Sep 17 00:00:00 2001 From: Hailey Date: Wed, 28 Feb 2024 18:41:23 -0800 Subject: [PATCH 43/43] Don't mute your own posts (#3037) * Don't mute your own posts. * fix and add tests --- .../__tests__/moderatePost_wrapped.test.ts | 89 +++++++++++++++++++ src/lib/moderatePost_wrapped.ts | 9 ++ 2 files changed, 98 insertions(+) diff --git a/src/lib/__tests__/moderatePost_wrapped.test.ts b/src/lib/__tests__/moderatePost_wrapped.test.ts index c35c1ef7..45566281 100644 --- a/src/lib/__tests__/moderatePost_wrapped.test.ts +++ b/src/lib/__tests__/moderatePost_wrapped.test.ts @@ -16,6 +16,7 @@ describe(`hasMutedWord`, () => { text: rt.text, facets: rt.facets, outlineTags: ['outlineTag'], + isOwnPost: false, }) expect(match).toBe(true) @@ -32,6 +33,7 @@ describe(`hasMutedWord`, () => { text: rt.text, facets: rt.facets, outlineTags: ['outlineTag'], + isOwnPost: false, }) expect(match).toBe(true) @@ -48,6 +50,7 @@ describe(`hasMutedWord`, () => { text: rt.text, facets: rt.facets, outlineTags: ['outlineTag'], + isOwnPost: false, }) expect(match).toBe(true) @@ -64,6 +67,7 @@ describe(`hasMutedWord`, () => { text: rt.text, facets: rt.facets, outlineTags: [], + isOwnPost: false, }) expect(match).toBe(false) @@ -85,6 +89,7 @@ describe(`hasMutedWord`, () => { text: rt.text, facets: rt.facets, outlineTags: [], + isOwnPost: false, }) expect(match).toBe(true) @@ -101,6 +106,7 @@ describe(`hasMutedWord`, () => { text: rt.text, facets: rt.facets, outlineTags: [], + isOwnPost: false, }) expect(match).toBe(false) @@ -117,6 +123,7 @@ describe(`hasMutedWord`, () => { text: rt.text, facets: rt.facets, outlineTags: [], + isOwnPost: false, }) expect(match).toBe(true) @@ -135,6 +142,7 @@ describe(`hasMutedWord`, () => { text: rt.text, facets: rt.facets, outlineTags: [], + isOwnPost: false, }) expect(match).toBe(true) @@ -151,6 +159,7 @@ describe(`hasMutedWord`, () => { text: rt.text, facets: rt.facets, outlineTags: [], + isOwnPost: false, }) expect(match).toBe(false) @@ -167,6 +176,7 @@ describe(`hasMutedWord`, () => { text: rt.text, facets: rt.facets, outlineTags: [], + isOwnPost: false, }) expect(match).toBe(true) @@ -183,6 +193,7 @@ describe(`hasMutedWord`, () => { text: rt.text, facets: rt.facets, outlineTags: [], + isOwnPost: false, }) expect(match).toBe(true) @@ -202,6 +213,7 @@ describe(`hasMutedWord`, () => { text: rt.text, facets: rt.facets, outlineTags: [], + isOwnPost: false, }) expect(match).toBe(true) @@ -213,6 +225,7 @@ describe(`hasMutedWord`, () => { text: rt.text, facets: rt.facets, outlineTags: [], + isOwnPost: false, }) expect(match).toBe(true) @@ -231,6 +244,7 @@ describe(`hasMutedWord`, () => { text: rt.text, facets: rt.facets, outlineTags: [], + isOwnPost: false, }) expect(match).toBe(true) @@ -243,6 +257,7 @@ describe(`hasMutedWord`, () => { text: rt.text, facets: rt.facets, outlineTags: [], + isOwnPost: false, }) expect(match).toBe(true) @@ -261,6 +276,7 @@ describe(`hasMutedWord`, () => { text: rt.text, facets: rt.facets, outlineTags: [], + isOwnPost: false, }) expect(match).toBe(true) @@ -272,6 +288,7 @@ describe(`hasMutedWord`, () => { text: rt.text, facets: rt.facets, outlineTags: [], + isOwnPost: false, }) expect(match).toBe(true) @@ -291,6 +308,7 @@ describe(`hasMutedWord`, () => { text: rt.text, facets: rt.facets, outlineTags: [], + isOwnPost: false, }) expect(match).toBe(true) @@ -309,6 +327,7 @@ describe(`hasMutedWord`, () => { text: rt.text, facets: rt.facets, outlineTags: [], + isOwnPost: false, }) expect(match).toBe(true) @@ -320,6 +339,7 @@ describe(`hasMutedWord`, () => { text: rt.text, facets: rt.facets, outlineTags: [], + isOwnPost: false, }) expect(match).toBe(true) @@ -336,6 +356,7 @@ describe(`hasMutedWord`, () => { text: rt.text, facets: rt.facets, outlineTags: [], + isOwnPost: false, }) expect(match).toBe(false) @@ -354,6 +375,7 @@ describe(`hasMutedWord`, () => { text: rt.text, facets: rt.facets, outlineTags: [], + isOwnPost: false, }) expect(match).toBe(true) @@ -365,6 +387,7 @@ describe(`hasMutedWord`, () => { text: rt.text, facets: rt.facets, outlineTags: [], + isOwnPost: false, }) expect(match).toBe(true) @@ -383,6 +406,7 @@ describe(`hasMutedWord`, () => { text: rt.text, facets: rt.facets, outlineTags: [], + isOwnPost: false, }) expect(match).toBe(true) @@ -394,6 +418,7 @@ describe(`hasMutedWord`, () => { text: rt.text, facets: rt.facets, outlineTags: [], + isOwnPost: false, }) expect(match).toBe(true) @@ -405,6 +430,7 @@ describe(`hasMutedWord`, () => { text: rt.text, facets: rt.facets, outlineTags: [], + isOwnPost: false, }) expect(match).toBe(true) @@ -416,6 +442,7 @@ describe(`hasMutedWord`, () => { text: rt.text, facets: rt.facets, outlineTags: [], + isOwnPost: false, }) expect(match).toBe(false) @@ -434,6 +461,7 @@ describe(`hasMutedWord`, () => { text: rt.text, facets: rt.facets, outlineTags: [], + isOwnPost: false, }) expect(match).toBe(true) @@ -448,6 +476,7 @@ describe(`hasMutedWord`, () => { text: rt.text, facets: rt.facets, outlineTags: [], + isOwnPost: false, }) expect(match).toBe(false) @@ -460,6 +489,7 @@ describe(`hasMutedWord`, () => { text: rt.text, facets: rt.facets, outlineTags: [], + isOwnPost: false, }) expect(match).toBe(true) @@ -471,6 +501,7 @@ describe(`hasMutedWord`, () => { text: rt.text, facets: rt.facets, outlineTags: [], + isOwnPost: false, }) expect(match).toBe(false) @@ -489,6 +520,7 @@ describe(`hasMutedWord`, () => { text: rt.text, facets: rt.facets, outlineTags: [], + isOwnPost: false, }) expect(match).toBe(true) @@ -500,6 +532,7 @@ describe(`hasMutedWord`, () => { text: rt.text, facets: rt.facets, outlineTags: [], + isOwnPost: false, }) expect(match).toBe(true) @@ -511,6 +544,7 @@ describe(`hasMutedWord`, () => { text: rt.text, facets: rt.facets, outlineTags: [], + isOwnPost: false, }) expect(match).toBe(true) @@ -522,6 +556,7 @@ describe(`hasMutedWord`, () => { text: rt.text, facets: rt.facets, outlineTags: [], + isOwnPost: false, }) expect(match).toBe(true) @@ -540,6 +575,7 @@ describe(`hasMutedWord`, () => { text: rt.text, facets: rt.facets, outlineTags: [], + isOwnPost: false, }) expect(match).toBe(true) @@ -560,6 +596,7 @@ describe(`hasMutedWord`, () => { text: rt.text, facets: rt.facets, outlineTags: [], + isOwnPost: false, }) expect(match).toBe(true) @@ -571,6 +608,7 @@ describe(`hasMutedWord`, () => { text: rt.text, facets: rt.facets, outlineTags: [], + isOwnPost: false, }) expect(match).toBe(true) @@ -594,10 +632,61 @@ describe(`hasMutedWord`, () => { facets: rt.facets, outlineTags: [], languages: ['ja'], + isOwnPost: false, }) expect(match).toBe(true) }) }) }) + + describe(`doesn't mute own post`, () => { + it(`does mute if it isn't own post`, () => { + const rt = new RichText({ + text: `Mute words!`, + }) + + const match = hasMutedWord({ + mutedWords: [{value: 'words', targets: ['content']}], + text: rt.text, + facets: rt.facets, + outlineTags: [], + isOwnPost: false, + }) + + expect(match).toBe(true) + }) + + it(`doesn't mute own post when muted word is in text`, () => { + const rt = new RichText({ + text: `Mute words!`, + }) + + const match = hasMutedWord({ + mutedWords: [{value: 'words', targets: ['content']}], + text: rt.text, + facets: rt.facets, + outlineTags: [], + isOwnPost: true, + }) + + expect(match).toBe(false) + }) + + it(`doesn't mute own post when muted word is in tags`, () => { + const rt = new RichText({ + text: `Mute #words!`, + }) + + const match = hasMutedWord({ + mutedWords: [{value: 'words', targets: ['tags']}], + text: rt.text, + facets: rt.facets, + outlineTags: [], + isOwnPost: true, + }) + + expect(match).toBe(false) + }) + }) }) diff --git a/src/lib/moderatePost_wrapped.ts b/src/lib/moderatePost_wrapped.ts index 428dbabf..92543b42 100644 --- a/src/lib/moderatePost_wrapped.ts +++ b/src/lib/moderatePost_wrapped.ts @@ -41,13 +41,17 @@ export function hasMutedWord({ facets, outlineTags, languages, + isOwnPost, }: { mutedWords: AppBskyActorDefs.MutedWord[] text: string facets?: AppBskyRichtextFacet.Main[] outlineTags?: string[] languages?: string[] + isOwnPost: boolean }) { + if (isOwnPost) return false + const exception = LANGUAGE_EXCEPTIONS.includes(languages?.[0] || '') const tags = ([] as string[]) .concat(outlineTags || []) @@ -142,6 +146,7 @@ export function moderatePost_wrapped( ) { const {hiddenPosts = [], mutedWords = [], ...options} = opts const moderations = moderatePost(subject, options) + const isOwnPost = subject.author.did === opts.userDid if (hiddenPosts.includes(subject.uri)) { moderations.content.filter = true @@ -163,6 +168,7 @@ export function moderatePost_wrapped( facets: subject.record.facets || [], outlineTags: subject.record.tags || [], languages: subject.record.langs, + isOwnPost, }) if ( @@ -178,6 +184,7 @@ export function moderatePost_wrapped( facets: [], outlineTags: [], languages: subject.record.langs, + isOwnPost, }) } } @@ -210,6 +217,7 @@ export function moderatePost_wrapped( facets: subject.embed.record.value.facets, outlineTags: subject.embed.record.value.tags, languages: subject.embed.record.value.langs, + isOwnPost, }) if (AppBskyEmbedImages.isMain(subject.embed.record.value.embed)) { @@ -222,6 +230,7 @@ export function moderatePost_wrapped( facets: [], outlineTags: [], languages: subject.embed.record.value.langs, + isOwnPost, }) } }